From: Ferruh Yigit Date: Thu, 16 Feb 2017 14:57:42 +0000 (+0000) Subject: test: move unit tests to separate directory X-Git-Tag: spdx-start~4450 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=7d3b1ec47fae5b2d972e05d0ee37bb7a1731b085;p=dpdk.git test: move unit tests to separate directory This is to logically group unit tests into their own folder, separating them from "app" folder. Hopefully this will make the unit test in DPDK more visible. Following binaries moved to "test" folder: cmdline-test test-acl test-pipeline test <-- various DPDK unit tests Signed-off-by: Ferruh Yigit Acked-by: Bruce Richardson --- diff --git a/GNUmakefile b/GNUmakefile index 00fe0db713..b1a5b761ab 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -40,6 +40,6 @@ export RTE_SDK # directory list # -ROOTDIRS-y := buildtools lib drivers app +ROOTDIRS-y := buildtools lib drivers app test include $(RTE_SDK)/mk/rte.sdkroot.mk diff --git a/MAINTAINERS b/MAINTAINERS index 24e0effe91..5030c1c113 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -87,28 +87,28 @@ F: lib/librte_eal/common/* F: lib/librte_eal/common/include/* F: lib/librte_eal/common/include/generic/ F: doc/guides/prog_guide/env_abstraction_layer.rst -F: app/test/test_alarm.c -F: app/test/test_atomic.c -F: app/test/test_byteorder.c -F: app/test/test_common.c -F: app/test/test_cpuflags.c -F: app/test/test_cycles.c -F: app/test/test_debug.c -F: app/test/test_devargs.c -F: app/test/test_eal* -F: app/test/test_errno.c -F: app/test/test_interrupts.c -F: app/test/test_logs.c -F: app/test/test_memcpy* -F: app/test/test_pci.c -F: app/test/test_pci_sysfs/ -F: app/test/test_per_lcore.c -F: app/test/test_prefetch.c -F: app/test/test_rwlock.c -F: app/test/test_spinlock.c -F: app/test/test_string_fns.c -F: app/test/test_tailq.c -F: app/test/test_version.c +F: test/test/test_alarm.c +F: test/test/test_atomic.c +F: test/test/test_byteorder.c +F: test/test/test_common.c +F: test/test/test_cpuflags.c +F: test/test/test_cycles.c +F: test/test/test_debug.c +F: test/test/test_devargs.c +F: test/test/test_eal* +F: test/test/test_errno.c +F: test/test/test_interrupts.c +F: test/test/test_logs.c +F: test/test/test_memcpy* +F: test/test/test_pci.c +F: test/test/test_pci_sysfs/ +F: test/test/test_per_lcore.c +F: test/test/test_prefetch.c +F: test/test/test_rwlock.c +F: test/test/test_spinlock.c +F: test/test/test_string_fns.c +F: test/test/test_tailq.c +F: test/test/test_version.c Memory Allocation M: Sergio Gonzalez Monroy @@ -118,10 +118,10 @@ F: lib/librte_eal/common/*malloc* F: lib/librte_eal/common/eal_common_mem* F: lib/librte_eal/common/eal_hugepages.h F: doc/guides/prog_guide/env_abstraction_layer.rst -F: app/test/test_func_reentrancy.c -F: app/test/test_malloc.c -F: app/test/test_memory.c -F: app/test/test_memzone.c +F: test/test/test_func_reentrancy.c +F: test/test/test_malloc.c +F: test/test/test_memory.c +F: test/test/test_memzone.c Keep alive M: Remy Horton @@ -134,7 +134,7 @@ Secondary process M: Sergio Gonzalez Monroy K: RTE_PROC_ F: doc/guides/prog_guide/multi_proc_support.rst -F: app/test/test_mp_secondary.c +F: test/test/test_mp_secondary.c F: examples/multi_process/ F: doc/guides/sample_app_ug/multi_process.rst @@ -222,21 +222,21 @@ Memory pool M: Olivier Matz F: lib/librte_mempool/ F: doc/guides/prog_guide/mempool_lib.rst -F: app/test/test_mempool* -F: app/test/test_func_reentrancy.c +F: test/test/test_mempool* +F: test/test/test_func_reentrancy.c Ring queue M: Olivier Matz F: lib/librte_ring/ F: doc/guides/prog_guide/ring_lib.rst -F: app/test/test_ring* -F: app/test/test_func_reentrancy.c +F: test/test/test_ring* +F: test/test/test_func_reentrancy.c Packet buffer M: Olivier Matz F: lib/librte_mbuf/ F: doc/guides/prog_guide/mbuf_lib.rst -F: app/test/test_mbuf.c +F: test/test/test_mbuf.c Ethernet API M: Thomas Monjalon @@ -250,7 +250,7 @@ F: lib/librte_ether/rte_flow* Crypto API M: Declan Doherty F: lib/librte_cryptodev/ -F: app/test/test_cryptodev* +F: test/test/test_cryptodev* F: examples/l2fwd-crypto/ @@ -263,7 +263,7 @@ Link bonding M: Declan Doherty F: drivers/net/bonding/ F: doc/guides/prog_guide/link_bonding_poll_mode_drv_lib.rst -F: app/test/test_link_bonding* +F: test/test/test_link_bonding* F: examples/bond/ Linux KNI @@ -271,7 +271,7 @@ M: Ferruh Yigit F: lib/librte_eal/linuxapp/kni/ F: lib/librte_kni/ F: doc/guides/prog_guide/kernel_nic_interface.rst -F: app/test/test_kni.c +F: test/test/test_kni.c F: examples/kni/ F: doc/guides/sample_app_ug/kernel_nic_interface.rst @@ -416,8 +416,8 @@ Ring PMD M: Bruce Richardson F: drivers/net/ring/ F: doc/guides/nics/pcap_ring.rst -F: app/test/test_pmd_ring.c -F: app/test/test_pmd_ring_perf.c +F: test/test/test_pmd_ring.c +F: test/test/test_pmd_ring_perf.c Null Networking PMD M: Tetsuya Mukawa @@ -503,7 +503,7 @@ Distributor M: Bruce Richardson F: lib/librte_distributor/ F: doc/guides/prog_guide/packet_distrib_lib.rst -F: app/test/test_distributor* +F: test/test/test_distributor* F: examples/distributor/ F: doc/guides/sample_app_ug/dist_app.rst @@ -511,7 +511,7 @@ Reorder M: Reshma Pattan F: lib/librte_reorder/ F: doc/guides/prog_guide/reorder_lib.rst -F: app/test/test_reorder* +F: test/test/test_reorder* F: examples/packet_ordering/ F: doc/guides/sample_app_ug/packet_ordering.rst @@ -519,8 +519,8 @@ Hierarchical scheduler M: Cristian Dumitrescu F: lib/librte_sched/ F: doc/guides/prog_guide/qos_framework.rst -F: app/test/test_red.c -F: app/test/test_sched.c +F: test/test/test_red.c +F: test/test/test_sched.c F: examples/qos_sched/ F: doc/guides/sample_app_ug/qos_scheduler.rst @@ -539,8 +539,8 @@ F: lib/librte_pipeline/ F: lib/librte_port/ F: lib/librte_table/ F: doc/guides/prog_guide/packet_framework.rst -F: app/test/test_table* -F: app/test-pipeline/ +F: test/test/test_table* +F: test/test-pipeline/ F: doc/guides/sample_app_ug/test_pipeline.rst F: examples/ip_pipeline/ F: doc/guides/sample_app_ug/ip_pipeline.rst @@ -553,8 +553,8 @@ ACL M: Konstantin Ananyev F: lib/librte_acl/ F: doc/guides/prog_guide/packet_classif_access_ctrl.rst -F: app/test-acl/ -F: app/test/test_acl.* +F: test/test-acl/ +F: test/test/test_acl.* F: examples/l3fwd-acl/ F: doc/guides/sample_app_ug/l3_forward_access_ctrl.rst @@ -563,7 +563,7 @@ M: Byron Marohn M: Pablo de Lara Guarch F: lib/librte_efd/ F: doc/guides/prog_guide/efd_lib.rst -F: app/test/test_efd* +F: test/test/test_efd* F: examples/server_node_efd/ F: doc/guides/sample_app_ug/server_node_efd.rst @@ -572,22 +572,22 @@ M: Bruce Richardson M: Pablo de Lara F: lib/librte_hash/ F: doc/guides/prog_guide/hash_lib.rst -F: app/test/test_*hash* -F: app/test/test_func_reentrancy.c +F: test/test/test_*hash* +F: test/test/test_func_reentrancy.c LPM M: Bruce Richardson F: lib/librte_lpm/ F: doc/guides/prog_guide/lpm* -F: app/test/test_lpm* -F: app/test/test_func_reentrancy.c -F: app/test/test_xmmt_ops.h +F: test/test/test_lpm* +F: test/test/test_func_reentrancy.c +F: test/test/test_xmmt_ops.h Traffic metering M: Cristian Dumitrescu F: lib/librte_meter/ F: doc/guides/sample_app_ug/qos_scheduler.rst -F: app/test/test_meter.c +F: test/test/test_meter.c F: examples/qos_meter/ F: doc/guides/sample_app_ug/qos_metering.rst @@ -602,20 +602,20 @@ F: lib/librte_cfgfile/ Interactive command line M: Olivier Matz F: lib/librte_cmdline/ -F: app/cmdline_test/ -F: app/test/test_cmdline* +F: test/cmdline_test/ +F: test/test/test_cmdline* F: examples/cmdline/ F: doc/guides/sample_app_ug/cmd_line.rst Key/Value parsing M: Olivier Matz F: lib/librte_kvargs/ -F: app/test/test_kvargs.c +F: test/test/test_kvargs.c Power management F: lib/librte_power/ F: doc/guides/prog_guide/power_man.rst -F: app/test/test_power* +F: test/test/test_power* F: examples/l3fwd-power/ F: doc/guides/sample_app_ug/l3_forward_power_man.rst F: examples/vm_power_manager/ @@ -625,7 +625,7 @@ Timers M: Robert Sanford F: lib/librte_timer/ F: doc/guides/prog_guide/timer_lib.rst -F: app/test/test_timer* +F: test/test/test_timer* F: examples/timer/ F: doc/guides/sample_app_ug/timer.rst @@ -640,18 +640,20 @@ Test Applications ----------------- Unit tests framework -F: app/test/autotest* -F: app/test/commands.c -F: app/test/packet_burst_generator.c -F: app/test/packet_burst_generator.h -F: app/test/process.h -F: app/test/resource.* -F: app/test/test.c -F: app/test/test.h -F: app/test/test_pmd_perf.c -F: app/test/test_resource.c -F: app/test/virtual_pmd.c -F: app/test/virtual_pmd.h +F: test/Makefile +F: test/test/Makefile +F: test/test/autotest* +F: test/test/commands.c +F: test/test/packet_burst_generator.c +F: test/test/packet_burst_generator.h +F: test/test/process.h +F: test/test/resource.* +F: test/test/test.c +F: test/test/test.h +F: test/test/test_pmd_perf.c +F: test/test/test_resource.c +F: test/test/virtual_pmd.c +F: test/test/virtual_pmd.h Driver testing tool M: Jingjing Wu diff --git a/app/Makefile b/app/Makefile index 1a974a57da..4b3a4487e0 100644 --- a/app/Makefile +++ b/app/Makefile @@ -31,12 +31,8 @@ include $(RTE_SDK)/mk/rte.vars.mk -DIRS-$(CONFIG_RTE_APP_TEST) += test -DIRS-$(CONFIG_RTE_LIBRTE_ACL) += test-acl -DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += test-pipeline DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd DIRS-$(CONFIG_RTE_APP_CRYPTO_PERF) += test-crypto-perf -DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_test DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += proc_info DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += pdump diff --git a/app/cmdline_test/Makefile b/app/cmdline_test/Makefile deleted file mode 100644 index c6169f56dd..0000000000 --- a/app/cmdline_test/Makefile +++ /dev/null @@ -1,55 +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 $(RTE_SDK)/mk/rte.vars.mk - -ifeq ($(CONFIG_RTE_LIBRTE_CMDLINE),y) - -# -# library name -# -APP = cmdline_test - -# -# all sources are stored in SRCS-y -# -SRCS-y += cmdline_test.c -SRCS-y += commands.c - -CFLAGS += -O3 -CFLAGS += $(WERROR_FLAGS) - -# this application needs libraries first -DEPDIRS-y += lib drivers - -include $(RTE_SDK)/mk/rte.app.mk - -endif diff --git a/app/cmdline_test/cmdline_test.c b/app/cmdline_test/cmdline_test.c deleted file mode 100644 index 716b5f1685..0000000000 --- a/app/cmdline_test/cmdline_test.c +++ /dev/null @@ -1,64 +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "cmdline_test.h" - -int -main(int __attribute__((unused)) argc, char __attribute__((unused)) ** argv) -{ - struct cmdline *cl; - - cl = cmdline_stdin_new(main_ctx, "CMDLINE_TEST>>"); - if (cl == NULL) { - return -1; - } - cmdline_interact(cl); - cmdline_stdin_exit(cl); - - return 0; -} diff --git a/app/cmdline_test/cmdline_test.h b/app/cmdline_test/cmdline_test.h deleted file mode 100644 index 1c9af122fe..0000000000 --- a/app/cmdline_test/cmdline_test.h +++ /dev/null @@ -1,39 +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 _CMDLINE_TEST_H_ -#define _CMDLINE_TEST_H_ - -extern cmdline_parse_ctx_t main_ctx[]; - -#endif diff --git a/app/cmdline_test/cmdline_test.py b/app/cmdline_test/cmdline_test.py deleted file mode 100755 index 229f71f3e3..0000000000 --- a/app/cmdline_test/cmdline_test.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python - -# 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. - -# Script that runs cmdline_test app and feeds keystrokes into it. -from __future__ import print_function -import cmdline_test_data -import os -import pexpect -import sys - - -# -# function to run test -# -def runTest(child, test): - child.send(test["Sequence"]) - if test["Result"] is None: - return 0 - child.expect(test["Result"], 1) - - -# -# history test is a special case -# -# This test does the following: -# 1) fills the history with garbage up to its full capacity -# (just enough to remove last entry) -# 2) scrolls back history to the very beginning -# 3) checks if the output is as expected, that is, the first -# number in the sequence (not the last entry before it) -# -# This is a self-contained test, it needs only a pexpect child -# -def runHistoryTest(child): - # find out history size - child.sendline(cmdline_test_data.CMD_GET_BUFSIZE) - child.expect("History buffer size: \\d+", timeout=1) - history_size = int(child.after[len(cmdline_test_data.BUFSIZE_TEMPLATE):]) - i = 0 - - # fill the history with numbers - while i < history_size / 10: - # add 1 to prevent from parsing as octals - child.send("1" + str(i).zfill(8) + cmdline_test_data.ENTER) - # the app will simply print out the number - child.expect(str(i + 100000000), timeout=1) - i += 1 - # scroll back history - child.send(cmdline_test_data.UP * (i + 2) + cmdline_test_data.ENTER) - child.expect("100000000", timeout=1) - -# the path to cmdline_test executable is supplied via command-line. -if len(sys.argv) < 2: - print("Error: please supply cmdline_test app path") - sys.exit(1) - -test_app_path = sys.argv[1] - -if not os.path.exists(test_app_path): - print("Error: please supply cmdline_test app path") - sys.exit(1) - -child = pexpect.spawn(test_app_path) - -print("Running command-line tests...") -for test in cmdline_test_data.tests: - testname = (test["Name"] + ":").ljust(30) - try: - runTest(child, test) - print(testname, "PASS") - except: - print(testname, "FAIL") - print(child) - sys.exit(1) - -# since last test quits the app, run new instance -child = pexpect.spawn(test_app_path) - -testname = ("History fill test:").ljust(30) -try: - runHistoryTest(child) - print(testname, "PASS") -except: - print(testname, "FAIL") - print(child) - sys.exit(1) -child.close() -sys.exit(0) diff --git a/app/cmdline_test/cmdline_test_data.py b/app/cmdline_test/cmdline_test_data.py deleted file mode 100644 index 28dfefe158..0000000000 --- a/app/cmdline_test/cmdline_test_data.py +++ /dev/null @@ -1,310 +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. - -# collection of static data - -# keycode constants -CTRL_A = chr(1) -CTRL_B = chr(2) -CTRL_C = chr(3) -CTRL_D = chr(4) -CTRL_E = chr(5) -CTRL_F = chr(6) -CTRL_K = chr(11) -CTRL_L = chr(12) -CTRL_N = chr(14) -CTRL_P = chr(16) -CTRL_W = chr(23) -CTRL_Y = chr(25) -ALT_B = chr(27) + chr(98) -ALT_D = chr(27) + chr(100) -ALT_F = chr(27) + chr(102) -ALT_BKSPACE = chr(27) + chr(127) -DEL = chr(27) + chr(91) + chr(51) + chr(126) -TAB = chr(9) -HELP = chr(63) -BKSPACE = chr(127) -RIGHT = chr(27) + chr(91) + chr(67) -DOWN = chr(27) + chr(91) + chr(66) -LEFT = chr(27) + chr(91) + chr(68) -UP = chr(27) + chr(91) + chr(65) -ENTER2 = '\r' -ENTER = '\n' - -# expected result constants -NOT_FOUND = "Command not found" -BAD_ARG = "Bad arguments" -AMBIG = "Ambiguous command" -CMD1 = "Command 1 parsed!" -CMD2 = "Command 2 parsed!" -SINGLE = "Single word command parsed!" -SINGLE_LONG = "Single long word command parsed!" -AUTO1 = "Autocomplete command 1 parsed!" -AUTO2 = "Autocomplete command 2 parsed!" - -# misc defines -CMD_QUIT = "quit" -CMD_GET_BUFSIZE = "get_history_bufsize" -BUFSIZE_TEMPLATE = "History buffer size: " -PROMPT = "CMDLINE_TEST>>" - -# test defines -# each test tests progressively diverse set of keys. this way for example -# if we want to use some key sequence in the test, we first need to test -# that it itself does what it is expected to do. Most of the tests are -# designed that way. -# -# example: "arrows & delete test 1". we enter a partially valid command, -# then move 3 chars left and use delete three times. this way we get to -# know that "delete", "left" and "ctrl+B" all work (because if any of -# them fails, the whole test will fail and next tests won't be run). -# -# each test consists of name, character sequence to send to child, -# and expected output (if any). - -tests = [ - # test basic commands - {"Name": "command test 1", - "Sequence": "ambiguous first" + ENTER, - "Result": CMD1}, - {"Name": "command test 2", - "Sequence": "ambiguous second" + ENTER, - "Result": CMD2}, - {"Name": "command test 3", - "Sequence": "ambiguous ambiguous" + ENTER, - "Result": AMBIG}, - {"Name": "command test 4", - "Sequence": "ambiguous ambiguous2" + ENTER, - "Result": AMBIG}, - - {"Name": "invalid command test 1", - "Sequence": "ambiguous invalid" + ENTER, - "Result": BAD_ARG}, - # test invalid commands - {"Name": "invalid command test 2", - "Sequence": "invalid" + ENTER, - "Result": NOT_FOUND}, - {"Name": "invalid command test 3", - "Sequence": "ambiguousinvalid" + ENTER2, - "Result": NOT_FOUND}, - - # test arrows and deletes - {"Name": "arrows & delete test 1", - "Sequence": "singlebad" + LEFT*2 + CTRL_B + DEL*3 + ENTER, - "Result": SINGLE}, - {"Name": "arrows & delete test 2", - "Sequence": "singlebad" + LEFT*5 + RIGHT + CTRL_F + DEL*3 + ENTER, - "Result": SINGLE}, - - # test backspace - {"Name": "backspace test", - "Sequence": "singlebad" + BKSPACE*3 + ENTER, - "Result": SINGLE}, - - # test goto left and goto right - {"Name": "goto left test", - "Sequence": "biguous first" + CTRL_A + "am" + ENTER, - "Result": CMD1}, - {"Name": "goto right test", - "Sequence": "biguous fir" + CTRL_A + "am" + CTRL_E + "st" + ENTER, - "Result": CMD1}, - - # test goto words - {"Name": "goto left word test", - "Sequence": "ambiguous st" + ALT_B + "fir" + ENTER, - "Result": CMD1}, - {"Name": "goto right word test", - "Sequence": "ambig first" + CTRL_A + ALT_F + "uous" + ENTER, - "Result": CMD1}, - - # test removing words - {"Name": "remove left word 1", - "Sequence": "single invalid" + CTRL_W + ENTER, - "Result": SINGLE}, - {"Name": "remove left word 2", - "Sequence": "single invalid" + ALT_BKSPACE + ENTER, - "Result": SINGLE}, - {"Name": "remove right word", - "Sequence": "single invalid" + ALT_B + ALT_D + ENTER, - "Result": SINGLE}, - - # test kill buffer (copy and paste) - {"Name": "killbuffer test 1", - "Sequence": "ambiguous" + CTRL_A + CTRL_K + " first" + CTRL_A + - CTRL_Y + ENTER, - "Result": CMD1}, - {"Name": "killbuffer test 2", - "Sequence": "ambiguous" + CTRL_A + CTRL_K + CTRL_Y*26 + ENTER, - "Result": NOT_FOUND}, - - # test newline - {"Name": "newline test", - "Sequence": "invalid" + CTRL_C + "single" + ENTER, - "Result": SINGLE}, - - # test redisplay (nothing should really happen) - {"Name": "redisplay test", - "Sequence": "single" + CTRL_L + ENTER, - "Result": SINGLE}, - - # test autocomplete - {"Name": "autocomplete test 1", - "Sequence": "si" + TAB + ENTER, - "Result": SINGLE}, - {"Name": "autocomplete test 2", - "Sequence": "si" + TAB + "_" + TAB + ENTER, - "Result": SINGLE_LONG}, - {"Name": "autocomplete test 3", - "Sequence": "in" + TAB + ENTER, - "Result": NOT_FOUND}, - {"Name": "autocomplete test 4", - "Sequence": "am" + TAB + ENTER, - "Result": BAD_ARG}, - {"Name": "autocomplete test 5", - "Sequence": "am" + TAB + "fir" + TAB + ENTER, - "Result": CMD1}, - {"Name": "autocomplete test 6", - "Sequence": "am" + TAB + "fir" + TAB + TAB + ENTER, - "Result": CMD1}, - {"Name": "autocomplete test 7", - "Sequence": "am" + TAB + "fir" + TAB + " " + TAB + ENTER, - "Result": CMD1}, - {"Name": "autocomplete test 8", - "Sequence": "am" + TAB + " am" + TAB + " " + ENTER, - "Result": AMBIG}, - {"Name": "autocomplete test 9", - "Sequence": "am" + TAB + "inv" + TAB + ENTER, - "Result": BAD_ARG}, - {"Name": "autocomplete test 10", - "Sequence": "au" + TAB + ENTER, - "Result": NOT_FOUND}, - {"Name": "autocomplete test 11", - "Sequence": "au" + TAB + "1" + ENTER, - "Result": AUTO1}, - {"Name": "autocomplete test 12", - "Sequence": "au" + TAB + "2" + ENTER, - "Result": AUTO2}, - {"Name": "autocomplete test 13", - "Sequence": "au" + TAB + "2" + TAB + ENTER, - "Result": AUTO2}, - {"Name": "autocomplete test 14", - "Sequence": "au" + TAB + "2 " + TAB + ENTER, - "Result": AUTO2}, - {"Name": "autocomplete test 15", - "Sequence": "24" + TAB + ENTER, - "Result": "24"}, - - # test history - {"Name": "history test 1", - "Sequence": "invalid" + ENTER + "single" + ENTER + "invalid" + - ENTER + UP + CTRL_P + ENTER, - "Result": SINGLE}, - {"Name": "history test 2", - "Sequence": "invalid" + ENTER + "ambiguous first" + ENTER + "invalid" + - ENTER + "single" + ENTER + UP * 3 + CTRL_N + DOWN + ENTER, - "Result": SINGLE}, - - # - # tests that improve coverage - # - - # empty space tests - {"Name": "empty space test 1", - "Sequence": RIGHT + LEFT + CTRL_B + CTRL_F + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 2", - "Sequence": BKSPACE + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 3", - "Sequence": CTRL_E*2 + CTRL_A*2 + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 4", - "Sequence": ALT_F*2 + ALT_B*2 + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 5", - "Sequence": " " + CTRL_E*2 + CTRL_A*2 + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 6", - "Sequence": " " + CTRL_A + ALT_F*2 + ALT_B*2 + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 7", - "Sequence": " " + CTRL_A + CTRL_D + CTRL_E + CTRL_D + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 8", - "Sequence": " space" + CTRL_W*2 + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 9", - "Sequence": " space" + ALT_BKSPACE*2 + ENTER, - "Result": PROMPT}, - {"Name": "empty space test 10", - "Sequence": " space " + CTRL_A + ALT_D*3 + ENTER, - "Result": PROMPT}, - - # non-printable char tests - {"Name": "non-printable test 1", - "Sequence": chr(27) + chr(47) + ENTER, - "Result": PROMPT}, - {"Name": "non-printable test 2", - "Sequence": chr(27) + chr(128) + ENTER*7, - "Result": PROMPT}, - {"Name": "non-printable test 3", - "Sequence": chr(27) + chr(91) + chr(127) + ENTER*6, - "Result": PROMPT}, - - # miscellaneous tests - {"Name": "misc test 1", - "Sequence": ENTER, - "Result": PROMPT}, - {"Name": "misc test 2", - "Sequence": "single #comment" + ENTER, - "Result": SINGLE}, - {"Name": "misc test 3", - "Sequence": "#empty line" + ENTER, - "Result": PROMPT}, - {"Name": "misc test 4", - "Sequence": " single " + ENTER, - "Result": SINGLE}, - {"Name": "misc test 5", - "Sequence": "single#" + ENTER, - "Result": SINGLE}, - {"Name": "misc test 6", - "Sequence": 'a' * 257 + ENTER, - "Result": NOT_FOUND}, - {"Name": "misc test 7", - "Sequence": "clear_history" + UP*5 + DOWN*5 + ENTER, - "Result": PROMPT}, - {"Name": "misc test 8", - "Sequence": "a" + HELP + CTRL_C, - "Result": PROMPT}, - {"Name": "misc test 9", - "Sequence": CTRL_D*3, - "Result": None}, -] diff --git a/app/cmdline_test/commands.c b/app/cmdline_test/commands.c deleted file mode 100644 index 404f51af6f..0000000000 --- a/app/cmdline_test/commands.c +++ /dev/null @@ -1,389 +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 -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "cmdline_test.h" - -/*** quit ***/ -/* exit application */ - -struct cmd_quit_result { - cmdline_fixed_string_t quit; -}; - -static void -cmd_quit_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_quit(cl); -} - -cmdline_parse_token_string_t cmd_quit_tok = - TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, - "quit"); - -cmdline_parse_inst_t cmd_quit = { - .f = cmd_quit_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "exit application", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_quit_tok, - NULL, - }, -}; - - - -/*** single ***/ -/* a simple single-word command */ - -struct cmd_single_result { - cmdline_fixed_string_t single; -}; - -static void -cmd_single_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_printf(cl, "Single word command parsed!\n"); -} - -cmdline_parse_token_string_t cmd_single_tok = - TOKEN_STRING_INITIALIZER(struct cmd_single_result, single, - "single"); - -cmdline_parse_inst_t cmd_single = { - .f = cmd_single_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "a simple single-word command", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_single_tok, - NULL, - }, -}; - - - -/*** single_long ***/ -/* a variant of "single" command. useful to test autocomplete */ - -struct cmd_single_long_result { - cmdline_fixed_string_t single_long; -}; - -static void -cmd_single_long_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_printf(cl, "Single long word command parsed!\n"); -} - -cmdline_parse_token_string_t cmd_single_long_tok = - TOKEN_STRING_INITIALIZER(struct cmd_single_long_result, single_long, - "single_long"); - -cmdline_parse_inst_t cmd_single_long = { - .f = cmd_single_long_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "a variant of \"single\" command, useful to test autocomplete", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_single_long_tok, - NULL, - }, -}; - - - -/*** autocomplete_1 ***/ -/* first command to test autocomplete when multiple commands have chars - * in common but none should complete due to ambiguity - */ - -struct cmd_autocomplete_1_result { - cmdline_fixed_string_t token; -}; - -static void -cmd_autocomplete_1_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_printf(cl, "Autocomplete command 1 parsed!\n"); -} - -cmdline_parse_token_string_t cmd_autocomplete_1_tok = - TOKEN_STRING_INITIALIZER(struct cmd_autocomplete_1_result, token, - "autocomplete_1"); - -cmdline_parse_inst_t cmd_autocomplete_1 = { - .f = cmd_autocomplete_1_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "first ambiguous autocomplete command", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_autocomplete_1_tok, - NULL, - }, -}; - - - -/*** autocomplete_2 ***/ -/* second command to test autocomplete when multiple commands have chars - * in common but none should complete due to ambiguity - */ - -struct cmd_autocomplete_2_result { - cmdline_fixed_string_t token; -}; - -static void -cmd_autocomplete_2_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_printf(cl, "Autocomplete command 2 parsed!\n"); -} - -cmdline_parse_token_string_t cmd_autocomplete_2_tok = - TOKEN_STRING_INITIALIZER(struct cmd_autocomplete_2_result, token, - "autocomplete_2"); - -cmdline_parse_inst_t cmd_autocomplete_2 = { - .f = cmd_autocomplete_2_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "second ambiguous autocomplete command", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_autocomplete_2_tok, - NULL, - }, -}; - - - -/*** number command ***/ -/* a command that simply returns whatever (uint32) number is supplied to it */ - -struct cmd_num_result { - unsigned num; -}; - -static void -cmd_num_parsed(void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - unsigned result = ((struct cmd_num_result*)parsed_result)->num; - cmdline_printf(cl, "%u\n", result); -} - -cmdline_parse_token_num_t cmd_num_tok = - TOKEN_NUM_INITIALIZER(struct cmd_num_result, num, UINT32); - -cmdline_parse_inst_t cmd_num = { - .f = cmd_num_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "a command that simply returns whatever number is entered", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_num_tok, - NULL, - }, -}; - - - -/*** ambiguous first|ambiguous ***/ -/* first command used to test command ambiguity */ - -struct cmd_ambig_result_1 { - cmdline_fixed_string_t common_part; - cmdline_fixed_string_t ambig_part; -}; - -static void -cmd_ambig_1_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_printf(cl, "Command 1 parsed!\n"); -} - -cmdline_parse_token_string_t cmd_ambig_common_1 = - TOKEN_STRING_INITIALIZER(struct cmd_ambig_result_1, common_part, - "ambiguous"); -cmdline_parse_token_string_t cmd_ambig_ambig_1 = - TOKEN_STRING_INITIALIZER(struct cmd_ambig_result_1, ambig_part, - "first#ambiguous#ambiguous2"); - -cmdline_parse_inst_t cmd_ambig_1 = { - .f = cmd_ambig_1_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "first command used to test command ambiguity", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_ambig_common_1, - (void*)&cmd_ambig_ambig_1, - NULL, - }, -}; - - - -/*** ambiguous second|ambiguous ***/ -/* second command used to test command ambiguity */ - -struct cmd_ambig_result_2 { - cmdline_fixed_string_t common_part; - cmdline_fixed_string_t ambig_part; -}; - -static void -cmd_ambig_2_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_printf(cl, "Command 2 parsed!\n"); -} - -cmdline_parse_token_string_t cmd_ambig_common_2 = - TOKEN_STRING_INITIALIZER(struct cmd_ambig_result_2, common_part, - "ambiguous"); -cmdline_parse_token_string_t cmd_ambig_ambig_2 = - TOKEN_STRING_INITIALIZER(struct cmd_ambig_result_2, ambig_part, - "second#ambiguous#ambiguous2"); - -cmdline_parse_inst_t cmd_ambig_2 = { - .f = cmd_ambig_2_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "second command used to test command ambiguity", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_ambig_common_2, - (void*)&cmd_ambig_ambig_2, - NULL, - }, -}; - - - -/*** get_history_bufsize ***/ -/* command that displays total space in history buffer - * this will be useful for testing history (to fill it up just enough to - * remove the last entry, we need to know how big it is). - */ - -struct cmd_get_history_bufsize_result { - cmdline_fixed_string_t str; -}; - -static void -cmd_get_history_bufsize_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_printf(cl, "History buffer size: %zu\n", - sizeof(cl->rdl.history_buf)); -} - -cmdline_parse_token_string_t cmd_get_history_bufsize_tok = - TOKEN_STRING_INITIALIZER(struct cmd_get_history_bufsize_result, str, - "get_history_bufsize"); - -cmdline_parse_inst_t cmd_get_history_bufsize = { - .f = cmd_get_history_bufsize_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "command that displays total space in history buffer", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_get_history_bufsize_tok, - NULL, - }, -}; - - - -/*** clear_history ***/ -/* clears history buffer */ - -struct cmd_clear_history_result { - cmdline_fixed_string_t str; -}; - -static void -cmd_clear_history_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - rdline_clear_history(&cl->rdl); -} - -cmdline_parse_token_string_t cmd_clear_history_tok = - TOKEN_STRING_INITIALIZER(struct cmd_clear_history_result, str, - "clear_history"); - -cmdline_parse_inst_t cmd_clear_history = { - .f = cmd_clear_history_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "clear command history", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_clear_history_tok, - NULL, - }, -}; - - - -/****************/ - -cmdline_parse_ctx_t main_ctx[] = { - (cmdline_parse_inst_t *)&cmd_quit, - (cmdline_parse_inst_t *)&cmd_ambig_1, - (cmdline_parse_inst_t *)&cmd_ambig_2, - (cmdline_parse_inst_t *)&cmd_single, - (cmdline_parse_inst_t *)&cmd_single_long, - (cmdline_parse_inst_t *)&cmd_num, - (cmdline_parse_inst_t *)&cmd_get_history_bufsize, - (cmdline_parse_inst_t *)&cmd_clear_history, - (cmdline_parse_inst_t *)&cmd_autocomplete_1, - (cmdline_parse_inst_t *)&cmd_autocomplete_2, - NULL, -}; diff --git a/app/test-acl/Makefile b/app/test-acl/Makefile deleted file mode 100644 index 43dfdcbd51..0000000000 --- a/app/test-acl/Makefile +++ /dev/null @@ -1,48 +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 $(RTE_SDK)/mk/rte.vars.mk - -ifeq ($(CONFIG_RTE_LIBRTE_ACL),y) - -APP = testacl - -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/test-acl/main.c b/app/test-acl/main.c deleted file mode 100644 index 1b2b1760e1..0000000000 --- a/app/test-acl/main.c +++ /dev/null @@ -1,1125 +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 -#include -#include - -#include -#include -#include -#include - -#define PRINT_USAGE_START "%s [EAL options]\n" - -#define RTE_LOGTYPE_TESTACL RTE_LOGTYPE_USER1 - -#define APP_NAME "TESTACL" - -#define GET_CB_FIELD(in, fd, base, lim, dlm) do { \ - unsigned long val; \ - char *end_fld; \ - errno = 0; \ - val = strtoul((in), &end_fld, (base)); \ - if (errno != 0 || end_fld[0] != (dlm) || val > (lim)) \ - return -EINVAL; \ - (fd) = (typeof(fd))val; \ - (in) = end_fld + 1; \ -} while (0) - -#define OPT_RULE_FILE "rulesf" -#define OPT_TRACE_FILE "tracef" -#define OPT_RULE_NUM "rulenum" -#define OPT_TRACE_NUM "tracenum" -#define OPT_TRACE_STEP "tracestep" -#define OPT_SEARCH_ALG "alg" -#define OPT_BLD_CATEGORIES "bldcat" -#define OPT_RUN_CATEGORIES "runcat" -#define OPT_MAX_SIZE "maxsize" -#define OPT_ITER_NUM "iter" -#define OPT_VERBOSE "verbose" -#define OPT_IPV6 "ipv6" - -#define TRACE_DEFAULT_NUM 0x10000 -#define TRACE_STEP_MAX 0x1000 -#define TRACE_STEP_DEF 0x100 - -#define RULE_NUM 0x10000 - -enum { - DUMP_NONE, - DUMP_SEARCH, - DUMP_PKT, - DUMP_MAX -}; - -struct acl_alg { - const char *name; - enum rte_acl_classify_alg alg; -}; - -static const struct acl_alg acl_alg[] = { - { - .name = "scalar", - .alg = RTE_ACL_CLASSIFY_SCALAR, - }, - { - .name = "sse", - .alg = RTE_ACL_CLASSIFY_SSE, - }, - { - .name = "avx2", - .alg = RTE_ACL_CLASSIFY_AVX2, - }, - { - .name = "neon", - .alg = RTE_ACL_CLASSIFY_NEON, - }, - { - .name = "altivec", - .alg = RTE_ACL_CLASSIFY_ALTIVEC, - }, -}; - -static struct { - const char *prgname; - const char *rule_file; - const char *trace_file; - size_t max_size; - uint32_t bld_categories; - uint32_t run_categories; - uint32_t nb_rules; - uint32_t nb_traces; - uint32_t trace_step; - uint32_t trace_sz; - uint32_t iter_num; - uint32_t verbose; - uint32_t ipv6; - struct acl_alg alg; - uint32_t used_traces; - void *traces; - struct rte_acl_ctx *acx; -} config = { - .bld_categories = 3, - .run_categories = 1, - .nb_rules = RULE_NUM, - .nb_traces = TRACE_DEFAULT_NUM, - .trace_step = TRACE_STEP_DEF, - .iter_num = 1, - .verbose = DUMP_MAX, - .alg = { - .name = "default", - .alg = RTE_ACL_CLASSIFY_DEFAULT, - }, - .ipv6 = 0 -}; - -static struct rte_acl_param prm = { - .name = APP_NAME, - .socket_id = SOCKET_ID_ANY, -}; - -/* - * Rule and trace formats definitions. - */ - -struct ipv4_5tuple { - uint8_t proto; - uint32_t ip_src; - uint32_t ip_dst; - uint16_t port_src; - uint16_t port_dst; -}; - -enum { - PROTO_FIELD_IPV4, - SRC_FIELD_IPV4, - DST_FIELD_IPV4, - SRCP_FIELD_IPV4, - DSTP_FIELD_IPV4, - NUM_FIELDS_IPV4 -}; - -/* - * That effectively defines order of IPV4VLAN classifications: - * - PROTO - * - VLAN (TAG and DOMAIN) - * - SRC IP ADDRESS - * - DST IP ADDRESS - * - PORTS (SRC and DST) - */ -enum { - RTE_ACL_IPV4VLAN_PROTO, - RTE_ACL_IPV4VLAN_VLAN, - RTE_ACL_IPV4VLAN_SRC, - RTE_ACL_IPV4VLAN_DST, - RTE_ACL_IPV4VLAN_PORTS, - RTE_ACL_IPV4VLAN_NUM -}; - -struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = PROTO_FIELD_IPV4, - .input_index = RTE_ACL_IPV4VLAN_PROTO, - .offset = offsetof(struct ipv4_5tuple, proto), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = SRC_FIELD_IPV4, - .input_index = RTE_ACL_IPV4VLAN_SRC, - .offset = offsetof(struct ipv4_5tuple, ip_src), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = DST_FIELD_IPV4, - .input_index = RTE_ACL_IPV4VLAN_DST, - .offset = offsetof(struct ipv4_5tuple, ip_dst), - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = SRCP_FIELD_IPV4, - .input_index = RTE_ACL_IPV4VLAN_PORTS, - .offset = offsetof(struct ipv4_5tuple, port_src), - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = DSTP_FIELD_IPV4, - .input_index = RTE_ACL_IPV4VLAN_PORTS, - .offset = offsetof(struct ipv4_5tuple, port_dst), - }, -}; - -#define IPV6_ADDR_LEN 16 -#define IPV6_ADDR_U16 (IPV6_ADDR_LEN / sizeof(uint16_t)) -#define IPV6_ADDR_U32 (IPV6_ADDR_LEN / sizeof(uint32_t)) - -struct ipv6_5tuple { - uint8_t proto; - uint32_t ip_src[IPV6_ADDR_U32]; - uint32_t ip_dst[IPV6_ADDR_U32]; - uint16_t port_src; - uint16_t port_dst; -}; - -enum { - PROTO_FIELD_IPV6, - SRC1_FIELD_IPV6, - SRC2_FIELD_IPV6, - SRC3_FIELD_IPV6, - SRC4_FIELD_IPV6, - DST1_FIELD_IPV6, - DST2_FIELD_IPV6, - DST3_FIELD_IPV6, - DST4_FIELD_IPV6, - SRCP_FIELD_IPV6, - DSTP_FIELD_IPV6, - NUM_FIELDS_IPV6 -}; - -struct rte_acl_field_def ipv6_defs[NUM_FIELDS_IPV6] = { - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = PROTO_FIELD_IPV6, - .input_index = PROTO_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, proto), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = SRC1_FIELD_IPV6, - .input_index = SRC1_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, ip_src[0]), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = SRC2_FIELD_IPV6, - .input_index = SRC2_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, ip_src[1]), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = SRC3_FIELD_IPV6, - .input_index = SRC3_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, ip_src[2]), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = SRC4_FIELD_IPV6, - .input_index = SRC4_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, ip_src[3]), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = DST1_FIELD_IPV6, - .input_index = DST1_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, ip_dst[0]), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = DST2_FIELD_IPV6, - .input_index = DST2_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, ip_dst[1]), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = DST3_FIELD_IPV6, - .input_index = DST3_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, ip_dst[2]), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = DST4_FIELD_IPV6, - .input_index = DST4_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, ip_dst[3]), - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = SRCP_FIELD_IPV6, - .input_index = SRCP_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, port_src), - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = DSTP_FIELD_IPV6, - .input_index = SRCP_FIELD_IPV6, - .offset = offsetof(struct ipv6_5tuple, port_dst), - }, -}; - - -enum { - CB_FLD_SRC_ADDR, - CB_FLD_DST_ADDR, - CB_FLD_SRC_PORT_LOW, - CB_FLD_SRC_PORT_DLM, - CB_FLD_SRC_PORT_HIGH, - CB_FLD_DST_PORT_LOW, - CB_FLD_DST_PORT_DLM, - CB_FLD_DST_PORT_HIGH, - CB_FLD_PROTO, - CB_FLD_NUM, -}; - -enum { - CB_TRC_SRC_ADDR, - CB_TRC_DST_ADDR, - CB_TRC_SRC_PORT, - CB_TRC_DST_PORT, - CB_TRC_PROTO, - CB_TRC_NUM, -}; - -RTE_ACL_RULE_DEF(acl_rule, RTE_ACL_MAX_FIELDS); - -static const char cb_port_delim[] = ":"; - -static char line[LINE_MAX]; - -#define dump_verbose(lvl, fh, fmt, args...) do { \ - if ((lvl) <= (int32_t)config.verbose) \ - fprintf(fh, fmt, ##args); \ -} while (0) - - -/* - * Parse ClassBench input trace (test vectors and expected results) file. - * Expected format: - * \ - * - */ -static int -parse_cb_ipv4_trace(char *str, struct ipv4_5tuple *v) -{ - int i; - char *s, *sp, *in[CB_TRC_NUM]; - static const char *dlm = " \t\n"; - - s = str; - for (i = 0; i != RTE_DIM(in); i++) { - in[i] = strtok_r(s, dlm, &sp); - if (in[i] == NULL) - return -EINVAL; - s = NULL; - } - - GET_CB_FIELD(in[CB_TRC_SRC_ADDR], v->ip_src, 0, UINT32_MAX, 0); - GET_CB_FIELD(in[CB_TRC_DST_ADDR], v->ip_dst, 0, UINT32_MAX, 0); - GET_CB_FIELD(in[CB_TRC_SRC_PORT], v->port_src, 0, UINT16_MAX, 0); - GET_CB_FIELD(in[CB_TRC_DST_PORT], v->port_dst, 0, UINT16_MAX, 0); - GET_CB_FIELD(in[CB_TRC_PROTO], v->proto, 0, UINT8_MAX, 0); - - /* convert to network byte order. */ - v->ip_src = rte_cpu_to_be_32(v->ip_src); - v->ip_dst = rte_cpu_to_be_32(v->ip_dst); - v->port_src = rte_cpu_to_be_16(v->port_src); - v->port_dst = rte_cpu_to_be_16(v->port_dst); - - return 0; -} - -/* - * Parses IPV6 address, exepcts the following format: - * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX (where X - is a hexedecimal digit). - */ -static int -parse_ipv6_addr(const char *in, const char **end, uint32_t v[IPV6_ADDR_U32], - char dlm) -{ - uint32_t addr[IPV6_ADDR_U16]; - - GET_CB_FIELD(in, addr[0], 16, UINT16_MAX, ':'); - GET_CB_FIELD(in, addr[1], 16, UINT16_MAX, ':'); - GET_CB_FIELD(in, addr[2], 16, UINT16_MAX, ':'); - GET_CB_FIELD(in, addr[3], 16, UINT16_MAX, ':'); - GET_CB_FIELD(in, addr[4], 16, UINT16_MAX, ':'); - GET_CB_FIELD(in, addr[5], 16, UINT16_MAX, ':'); - GET_CB_FIELD(in, addr[6], 16, UINT16_MAX, ':'); - GET_CB_FIELD(in, addr[7], 16, UINT16_MAX, dlm); - - *end = in; - - v[0] = (addr[0] << 16) + addr[1]; - v[1] = (addr[2] << 16) + addr[3]; - v[2] = (addr[4] << 16) + addr[5]; - v[3] = (addr[6] << 16) + addr[7]; - - return 0; -} - -static int -parse_cb_ipv6_addr_trace(const char *in, uint32_t v[IPV6_ADDR_U32]) -{ - int32_t rc; - const char *end; - - rc = parse_ipv6_addr(in, &end, v, 0); - if (rc != 0) - return rc; - - v[0] = rte_cpu_to_be_32(v[0]); - v[1] = rte_cpu_to_be_32(v[1]); - v[2] = rte_cpu_to_be_32(v[2]); - v[3] = rte_cpu_to_be_32(v[3]); - - return 0; -} - -/* - * Parse ClassBench input trace (test vectors and expected results) file. - * Expected format: - * \ - * - */ -static int -parse_cb_ipv6_trace(char *str, struct ipv6_5tuple *v) -{ - int32_t i, rc; - char *s, *sp, *in[CB_TRC_NUM]; - static const char *dlm = " \t\n"; - - s = str; - for (i = 0; i != RTE_DIM(in); i++) { - in[i] = strtok_r(s, dlm, &sp); - if (in[i] == NULL) - return -EINVAL; - s = NULL; - } - - /* get ip6 src address. */ - rc = parse_cb_ipv6_addr_trace(in[CB_TRC_SRC_ADDR], v->ip_src); - if (rc != 0) - return rc; - - /* get ip6 dst address. */ - rc = parse_cb_ipv6_addr_trace(in[CB_TRC_DST_ADDR], v->ip_dst); - if (rc != 0) - return rc; - - GET_CB_FIELD(in[CB_TRC_SRC_PORT], v->port_src, 0, UINT16_MAX, 0); - GET_CB_FIELD(in[CB_TRC_DST_PORT], v->port_dst, 0, UINT16_MAX, 0); - GET_CB_FIELD(in[CB_TRC_PROTO], v->proto, 0, UINT8_MAX, 0); - - /* convert to network byte order. */ - v->port_src = rte_cpu_to_be_16(v->port_src); - v->port_dst = rte_cpu_to_be_16(v->port_dst); - - return 0; -} - -static void -tracef_init(void) -{ - static const char name[] = APP_NAME; - FILE *f; - size_t sz; - uint32_t n; - struct ipv4_5tuple *v; - struct ipv6_5tuple *w; - - sz = config.nb_traces * (config.ipv6 ? sizeof(*w) : sizeof(*v)); - config.traces = rte_zmalloc_socket(name, sz, RTE_CACHE_LINE_SIZE, - SOCKET_ID_ANY); - if (config.traces == NULL) - rte_exit(EXIT_FAILURE, "Cannot allocate %zu bytes for " - "requested %u number of trace records\n", - sz, config.nb_traces); - - f = fopen(config.trace_file, "r"); - if (f == NULL) - rte_exit(-EINVAL, "failed to open file: %s\n", - config.trace_file); - - v = config.traces; - w = config.traces; - for (n = 0; n != config.nb_traces; n++) { - - if (fgets(line, sizeof(line), f) == NULL) - break; - - if (config.ipv6) { - if (parse_cb_ipv6_trace(line, w + n) != 0) - rte_exit(EXIT_FAILURE, - "%s: failed to parse ipv6 trace " - "record at line %u\n", - config.trace_file, n + 1); - } else { - if (parse_cb_ipv4_trace(line, v + n) != 0) - rte_exit(EXIT_FAILURE, - "%s: failed to parse ipv4 trace " - "record at line %u\n", - config.trace_file, n + 1); - } - } - - config.used_traces = n; - fclose(f); -} - -static int -parse_ipv6_net(const char *in, struct rte_acl_field field[4]) -{ - int32_t rc; - const char *mp; - uint32_t i, m, v[4]; - const uint32_t nbu32 = sizeof(uint32_t) * CHAR_BIT; - - /* get address. */ - rc = parse_ipv6_addr(in, &mp, v, '/'); - if (rc != 0) - return rc; - - /* get mask. */ - GET_CB_FIELD(mp, m, 0, CHAR_BIT * sizeof(v), 0); - - /* put all together. */ - for (i = 0; i != RTE_DIM(v); i++) { - if (m >= (i + 1) * nbu32) - field[i].mask_range.u32 = nbu32; - else - field[i].mask_range.u32 = m > (i * nbu32) ? - m - (i * 32) : 0; - - field[i].value.u32 = v[i]; - } - - return 0; -} - - -static int -parse_cb_ipv6_rule(char *str, struct acl_rule *v) -{ - int i, rc; - char *s, *sp, *in[CB_FLD_NUM]; - static const char *dlm = " \t\n"; - - /* - * Skip leading '@' - */ - if (strchr(str, '@') != str) - return -EINVAL; - - s = str + 1; - - for (i = 0; i != RTE_DIM(in); i++) { - in[i] = strtok_r(s, dlm, &sp); - if (in[i] == NULL) - return -EINVAL; - s = NULL; - } - - rc = parse_ipv6_net(in[CB_FLD_SRC_ADDR], v->field + SRC1_FIELD_IPV6); - if (rc != 0) { - RTE_LOG(ERR, TESTACL, - "failed to read source address/mask: %s\n", - in[CB_FLD_SRC_ADDR]); - return rc; - } - - rc = parse_ipv6_net(in[CB_FLD_DST_ADDR], v->field + DST1_FIELD_IPV6); - if (rc != 0) { - RTE_LOG(ERR, TESTACL, - "failed to read destination address/mask: %s\n", - in[CB_FLD_DST_ADDR]); - return rc; - } - - /* source port. */ - GET_CB_FIELD(in[CB_FLD_SRC_PORT_LOW], - v->field[SRCP_FIELD_IPV6].value.u16, - 0, UINT16_MAX, 0); - GET_CB_FIELD(in[CB_FLD_SRC_PORT_HIGH], - v->field[SRCP_FIELD_IPV6].mask_range.u16, - 0, UINT16_MAX, 0); - - if (strncmp(in[CB_FLD_SRC_PORT_DLM], cb_port_delim, - sizeof(cb_port_delim)) != 0) - return -EINVAL; - - /* destination port. */ - GET_CB_FIELD(in[CB_FLD_DST_PORT_LOW], - v->field[DSTP_FIELD_IPV6].value.u16, - 0, UINT16_MAX, 0); - GET_CB_FIELD(in[CB_FLD_DST_PORT_HIGH], - v->field[DSTP_FIELD_IPV6].mask_range.u16, - 0, UINT16_MAX, 0); - - if (strncmp(in[CB_FLD_DST_PORT_DLM], cb_port_delim, - sizeof(cb_port_delim)) != 0) - return -EINVAL; - - GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV6].value.u8, - 0, UINT8_MAX, '/'); - GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV6].mask_range.u8, - 0, UINT8_MAX, 0); - - return 0; -} - -static int -parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len) -{ - uint8_t a, b, c, d, m; - - GET_CB_FIELD(in, a, 0, UINT8_MAX, '.'); - GET_CB_FIELD(in, b, 0, UINT8_MAX, '.'); - GET_CB_FIELD(in, c, 0, UINT8_MAX, '.'); - GET_CB_FIELD(in, d, 0, UINT8_MAX, '/'); - GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0); - - addr[0] = IPv4(a, b, c, d); - mask_len[0] = m; - - return 0; -} -/* - * Parse ClassBench rules file. - * Expected format: - * '@''/' \ - * '/' \ - * ":" \ - * ":" \ - * '/' - */ -static int -parse_cb_ipv4_rule(char *str, struct acl_rule *v) -{ - int i, rc; - char *s, *sp, *in[CB_FLD_NUM]; - static const char *dlm = " \t\n"; - - /* - * Skip leading '@' - */ - if (strchr(str, '@') != str) - return -EINVAL; - - s = str + 1; - - for (i = 0; i != RTE_DIM(in); i++) { - in[i] = strtok_r(s, dlm, &sp); - if (in[i] == NULL) - return -EINVAL; - s = NULL; - } - - rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR], - &v->field[SRC_FIELD_IPV4].value.u32, - &v->field[SRC_FIELD_IPV4].mask_range.u32); - if (rc != 0) { - RTE_LOG(ERR, TESTACL, - "failed to read source address/mask: %s\n", - in[CB_FLD_SRC_ADDR]); - return rc; - } - - rc = parse_ipv4_net(in[CB_FLD_DST_ADDR], - &v->field[DST_FIELD_IPV4].value.u32, - &v->field[DST_FIELD_IPV4].mask_range.u32); - if (rc != 0) { - RTE_LOG(ERR, TESTACL, - "failed to read destination address/mask: %s\n", - in[CB_FLD_DST_ADDR]); - return rc; - } - - /* source port. */ - GET_CB_FIELD(in[CB_FLD_SRC_PORT_LOW], - v->field[SRCP_FIELD_IPV4].value.u16, - 0, UINT16_MAX, 0); - GET_CB_FIELD(in[CB_FLD_SRC_PORT_HIGH], - v->field[SRCP_FIELD_IPV4].mask_range.u16, - 0, UINT16_MAX, 0); - - if (strncmp(in[CB_FLD_SRC_PORT_DLM], cb_port_delim, - sizeof(cb_port_delim)) != 0) - return -EINVAL; - - /* destination port. */ - GET_CB_FIELD(in[CB_FLD_DST_PORT_LOW], - v->field[DSTP_FIELD_IPV4].value.u16, - 0, UINT16_MAX, 0); - GET_CB_FIELD(in[CB_FLD_DST_PORT_HIGH], - v->field[DSTP_FIELD_IPV4].mask_range.u16, - 0, UINT16_MAX, 0); - - if (strncmp(in[CB_FLD_DST_PORT_DLM], cb_port_delim, - sizeof(cb_port_delim)) != 0) - return -EINVAL; - - GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV4].value.u8, - 0, UINT8_MAX, '/'); - GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV4].mask_range.u8, - 0, UINT8_MAX, 0); - - return 0; -} - -typedef int (*parse_5tuple)(char *text, struct acl_rule *rule); - -static int -add_cb_rules(FILE *f, struct rte_acl_ctx *ctx) -{ - int rc; - uint32_t n; - struct acl_rule v; - parse_5tuple parser; - - memset(&v, 0, sizeof(v)); - parser = (config.ipv6 != 0) ? parse_cb_ipv6_rule : parse_cb_ipv4_rule; - - for (n = 1; fgets(line, sizeof(line), f) != NULL; n++) { - - rc = parser(line, &v); - if (rc != 0) { - RTE_LOG(ERR, TESTACL, "line %u: parse_cb_ipv4vlan_rule" - " failed, error code: %d (%s)\n", - n, rc, strerror(-rc)); - return rc; - } - - v.data.category_mask = RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, - typeof(v.data.category_mask)); - v.data.priority = RTE_ACL_MAX_PRIORITY - n; - v.data.userdata = n; - - rc = rte_acl_add_rules(ctx, (struct rte_acl_rule *)&v, 1); - if (rc != 0) { - RTE_LOG(ERR, TESTACL, "line %u: failed to add rules " - "into ACL context, error code: %d (%s)\n", - n, rc, strerror(-rc)); - return rc; - } - } - - return 0; -} - -static void -acx_init(void) -{ - int ret; - FILE *f; - struct rte_acl_config cfg; - - memset(&cfg, 0, sizeof(cfg)); - - /* setup ACL build config. */ - if (config.ipv6) { - cfg.num_fields = RTE_DIM(ipv6_defs); - memcpy(&cfg.defs, ipv6_defs, sizeof(ipv6_defs)); - } else { - cfg.num_fields = RTE_DIM(ipv4_defs); - memcpy(&cfg.defs, ipv4_defs, sizeof(ipv4_defs)); - } - cfg.num_categories = config.bld_categories; - cfg.max_size = config.max_size; - - /* setup ACL creation parameters. */ - prm.rule_size = RTE_ACL_RULE_SZ(cfg.num_fields); - prm.max_rule_num = config.nb_rules; - - config.acx = rte_acl_create(&prm); - if (config.acx == NULL) - rte_exit(rte_errno, "failed to create ACL context\n"); - - /* set default classify method for this context. */ - if (config.alg.alg != RTE_ACL_CLASSIFY_DEFAULT) { - ret = rte_acl_set_ctx_classify(config.acx, config.alg.alg); - if (ret != 0) - rte_exit(ret, "failed to setup %s method " - "for ACL context\n", config.alg.name); - } - - /* add ACL rules. */ - f = fopen(config.rule_file, "r"); - if (f == NULL) - rte_exit(-EINVAL, "failed to open file %s\n", - config.rule_file); - - ret = add_cb_rules(f, config.acx); - if (ret != 0) - rte_exit(ret, "failed to add rules into ACL context\n"); - - fclose(f); - - /* perform build. */ - ret = rte_acl_build(config.acx, &cfg); - - dump_verbose(DUMP_NONE, stdout, - "rte_acl_build(%u) finished with %d\n", - config.bld_categories, ret); - - rte_acl_dump(config.acx); - - if (ret != 0) - rte_exit(ret, "failed to build search context\n"); -} - -static uint32_t -search_ip5tuples_once(uint32_t categories, uint32_t step, const char *alg) -{ - int ret; - uint32_t i, j, k, n, r; - const uint8_t *data[step], *v; - uint32_t results[step * categories]; - - v = config.traces; - for (i = 0; i != config.used_traces; i += n) { - - n = RTE_MIN(step, config.used_traces - i); - - for (j = 0; j != n; j++) { - data[j] = v; - v += config.trace_sz; - } - - ret = rte_acl_classify(config.acx, data, results, - n, categories); - - if (ret != 0) - rte_exit(ret, "classify for ipv%c_5tuples returns %d\n", - config.ipv6 ? '6' : '4', ret); - - for (r = 0, j = 0; j != n; j++) { - for (k = 0; k != categories; k++, r++) { - dump_verbose(DUMP_PKT, stdout, - "ipv%c_5tuple: %u, category: %u, " - "result: %u\n", - config.ipv6 ? '6' : '4', - i + j + 1, k, results[r] - 1); - } - - } - } - - dump_verbose(DUMP_SEARCH, stdout, - "%s(%u, %u, %s) returns %u\n", __func__, - categories, step, alg, i); - return i; -} - -static int -search_ip5tuples(__attribute__((unused)) void *arg) -{ - uint64_t pkt, start, tm; - uint32_t i, lcore; - - lcore = rte_lcore_id(); - start = rte_rdtsc(); - pkt = 0; - - for (i = 0; i != config.iter_num; i++) { - pkt += search_ip5tuples_once(config.run_categories, - config.trace_step, config.alg.name); - } - - tm = rte_rdtsc() - start; - dump_verbose(DUMP_NONE, stdout, - "%s @lcore %u: %" PRIu32 " iterations, %" PRIu64 " pkts, %" - PRIu32 " categories, %" PRIu64 " cycles, %#Lf cycles/pkt\n", - __func__, lcore, i, pkt, config.run_categories, - tm, (pkt == 0) ? 0 : (long double)tm / pkt); - - return 0; -} - -static unsigned long -get_ulong_opt(const char *opt, const char *name, size_t min, size_t max) -{ - unsigned long val; - char *end; - - errno = 0; - val = strtoul(opt, &end, 0); - if (errno != 0 || end[0] != 0 || val > max || val < min) - rte_exit(-EINVAL, "invalid value: \"%s\" for option: %s\n", - opt, name); - return val; -} - -static void -get_alg_opt(const char *opt, const char *name) -{ - uint32_t i; - - for (i = 0; i != RTE_DIM(acl_alg); i++) { - if (strcmp(opt, acl_alg[i].name) == 0) { - config.alg = acl_alg[i]; - return; - } - } - - rte_exit(-EINVAL, "invalid value: \"%s\" for option: %s\n", - opt, name); -} - -static void -print_usage(const char *prgname) -{ - uint32_t i, n, rc; - char buf[PATH_MAX]; - - n = 0; - buf[0] = 0; - - for (i = 0; i < RTE_DIM(acl_alg) - 1; i++) { - rc = snprintf(buf + n, sizeof(buf) - n, "%s|", - acl_alg[i].name); - if (rc > sizeof(buf) - n) - break; - n += rc; - } - - snprintf(buf + n, sizeof(buf) - n, "%s", acl_alg[i].name); - - fprintf(stdout, - PRINT_USAGE_START - "--" OPT_RULE_FILE "=\n" - "[--" OPT_TRACE_FILE "=]\n" - "[--" OPT_RULE_NUM - "=]\n" - "[--" OPT_TRACE_NUM - "=]\n" - "[--" OPT_TRACE_STEP - "=]\n" - "[--" OPT_BLD_CATEGORIES - "=]\n" - "[--" OPT_RUN_CATEGORIES - "= " - "should be either 1 or multiple of %zu, " - "but not greater then %u]\n" - "[--" OPT_MAX_SIZE - "= " - "leave 0 for default behaviour]\n" - "[--" OPT_ITER_NUM "=]\n" - "[--" OPT_VERBOSE "=]\n" - "[--" OPT_SEARCH_ALG "=%s]\n" - "[--" OPT_IPV6 "=]\n", - prgname, RTE_ACL_RESULTS_MULTIPLIER, - (uint32_t)RTE_ACL_MAX_CATEGORIES, - buf); -} - -static void -dump_config(FILE *f) -{ - fprintf(f, "%s:\n", __func__); - fprintf(f, "%s:%s\n", OPT_RULE_FILE, config.rule_file); - fprintf(f, "%s:%s\n", OPT_TRACE_FILE, config.trace_file); - fprintf(f, "%s:%u\n", OPT_RULE_NUM, config.nb_rules); - fprintf(f, "%s:%u\n", OPT_TRACE_NUM, config.nb_traces); - fprintf(f, "%s:%u\n", OPT_TRACE_STEP, config.trace_step); - fprintf(f, "%s:%u\n", OPT_BLD_CATEGORIES, config.bld_categories); - fprintf(f, "%s:%u\n", OPT_RUN_CATEGORIES, config.run_categories); - fprintf(f, "%s:%zu\n", OPT_MAX_SIZE, config.max_size); - fprintf(f, "%s:%u\n", OPT_ITER_NUM, config.iter_num); - fprintf(f, "%s:%u\n", OPT_VERBOSE, config.verbose); - fprintf(f, "%s:%u(%s)\n", OPT_SEARCH_ALG, config.alg.alg, - config.alg.name); - fprintf(f, "%s:%u\n", OPT_IPV6, config.ipv6); -} - -static void -check_config(void) -{ - if (config.rule_file == NULL) { - print_usage(config.prgname); - rte_exit(-EINVAL, "mandatory option %s is not specified\n", - OPT_RULE_FILE); - } -} - - -static void -get_input_opts(int argc, char **argv) -{ - static struct option lgopts[] = { - {OPT_RULE_FILE, 1, 0, 0}, - {OPT_TRACE_FILE, 1, 0, 0}, - {OPT_TRACE_NUM, 1, 0, 0}, - {OPT_RULE_NUM, 1, 0, 0}, - {OPT_MAX_SIZE, 1, 0, 0}, - {OPT_TRACE_STEP, 1, 0, 0}, - {OPT_BLD_CATEGORIES, 1, 0, 0}, - {OPT_RUN_CATEGORIES, 1, 0, 0}, - {OPT_ITER_NUM, 1, 0, 0}, - {OPT_VERBOSE, 1, 0, 0}, - {OPT_SEARCH_ALG, 1, 0, 0}, - {OPT_IPV6, 0, 0, 0}, - {NULL, 0, 0, 0} - }; - - int opt, opt_idx; - - while ((opt = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) { - - if (opt != 0) { - print_usage(config.prgname); - rte_exit(-EINVAL, "unknown option: %c", opt); - } - - if (strcmp(lgopts[opt_idx].name, OPT_RULE_FILE) == 0) { - config.rule_file = optarg; - } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_FILE) == 0) { - config.trace_file = optarg; - } else if (strcmp(lgopts[opt_idx].name, OPT_RULE_NUM) == 0) { - config.nb_rules = get_ulong_opt(optarg, - lgopts[opt_idx].name, 1, RTE_ACL_MAX_INDEX + 1); - } else if (strcmp(lgopts[opt_idx].name, OPT_MAX_SIZE) == 0) { - config.max_size = get_ulong_opt(optarg, - lgopts[opt_idx].name, 0, SIZE_MAX); - } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_NUM) == 0) { - config.nb_traces = get_ulong_opt(optarg, - lgopts[opt_idx].name, 1, UINT32_MAX); - } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_STEP) == 0) { - config.trace_step = get_ulong_opt(optarg, - lgopts[opt_idx].name, 1, TRACE_STEP_MAX); - } else if (strcmp(lgopts[opt_idx].name, - OPT_BLD_CATEGORIES) == 0) { - config.bld_categories = get_ulong_opt(optarg, - lgopts[opt_idx].name, 1, - RTE_ACL_MAX_CATEGORIES); - } else if (strcmp(lgopts[opt_idx].name, - OPT_RUN_CATEGORIES) == 0) { - config.run_categories = get_ulong_opt(optarg, - lgopts[opt_idx].name, 1, - RTE_ACL_MAX_CATEGORIES); - } else if (strcmp(lgopts[opt_idx].name, OPT_ITER_NUM) == 0) { - config.iter_num = get_ulong_opt(optarg, - lgopts[opt_idx].name, 1, INT32_MAX); - } else if (strcmp(lgopts[opt_idx].name, OPT_VERBOSE) == 0) { - config.verbose = get_ulong_opt(optarg, - lgopts[opt_idx].name, DUMP_NONE, DUMP_MAX); - } else if (strcmp(lgopts[opt_idx].name, - OPT_SEARCH_ALG) == 0) { - get_alg_opt(optarg, lgopts[opt_idx].name); - } else if (strcmp(lgopts[opt_idx].name, OPT_IPV6) == 0) { - config.ipv6 = 1; - } - } - config.trace_sz = config.ipv6 ? sizeof(struct ipv6_5tuple) : - sizeof(struct ipv4_5tuple); - -} - -int -main(int argc, char **argv) -{ - int ret; - uint32_t lcore; - - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_panic("Cannot init EAL\n"); - - argc -= ret; - argv += ret; - - config.prgname = argv[0]; - - get_input_opts(argc, argv); - dump_config(stdout); - check_config(); - - acx_init(); - - if (config.trace_file != NULL) - tracef_init(); - - RTE_LCORE_FOREACH_SLAVE(lcore) - rte_eal_remote_launch(search_ip5tuples, NULL, lcore); - - search_ip5tuples(NULL); - - rte_eal_mp_wait_lcore(); - - rte_acl_free(config.acx); - return 0; -} diff --git a/app/test-pipeline/Makefile b/app/test-pipeline/Makefile deleted file mode 100644 index 4bab6dc6c4..0000000000 --- a/app/test-pipeline/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# BSD LICENSE -# -# Copyright(c) 2010-2015 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_PIPELINE),y) - -# -# library name -# -APP = testpipeline - -CFLAGS += -O3 -CFLAGS += $(WERROR_FLAGS) - -# -# all source are stored in SRCS-y -# -SRCS-y := main.c -SRCS-y += config.c -SRCS-y += init.c -SRCS-y += runtime.c -SRCS-y += pipeline_stub.c -SRCS-y += pipeline_hash.c -SRCS-y += pipeline_lpm.c -SRCS-y += pipeline_lpm_ipv6.c - -# include ACL lib if available -SRCS-$(CONFIG_RTE_LIBRTE_ACL) += pipeline_acl.c - -# this application needs libraries first -DEPDIRS-y += lib drivers - -include $(RTE_SDK)/mk/rte.app.mk - -endif diff --git a/app/test-pipeline/config.c b/app/test-pipeline/config.c deleted file mode 100644 index dd80ed6991..0000000000 --- a/app/test-pipeline/config.c +++ /dev/null @@ -1,264 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "main.h" - -struct app_params app; - -static const char usage[] = "\n"; - -void -app_print_usage(void) -{ - printf(usage); -} - -static int -app_parse_port_mask(const char *arg) -{ - char *end = NULL; - uint64_t port_mask; - uint32_t i; - - if (arg[0] == '\0') - return -1; - - port_mask = strtoul(arg, &end, 16); - if ((end == NULL) || (*end != '\0')) - return -2; - - if (port_mask == 0) - return -3; - - app.n_ports = 0; - for (i = 0; i < 64; i++) { - if ((port_mask & (1LLU << i)) == 0) - continue; - - if (app.n_ports >= APP_MAX_PORTS) - return -4; - - app.ports[app.n_ports] = i; - app.n_ports++; - } - - if (!rte_is_power_of_2(app.n_ports)) - return -5; - - return 0; -} - -struct { - const char *name; - uint32_t value; -} app_args_table[] = { - {"none", e_APP_PIPELINE_NONE}, - {"stub", e_APP_PIPELINE_STUB}, - {"hash-8-ext", e_APP_PIPELINE_HASH_KEY8_EXT}, - {"hash-8-lru", e_APP_PIPELINE_HASH_KEY8_LRU}, - {"hash-16-ext", e_APP_PIPELINE_HASH_KEY16_EXT}, - {"hash-16-lru", e_APP_PIPELINE_HASH_KEY16_LRU}, - {"hash-32-ext", e_APP_PIPELINE_HASH_KEY32_EXT}, - {"hash-32-lru", e_APP_PIPELINE_HASH_KEY32_LRU}, - {"hash-spec-8-ext", e_APP_PIPELINE_HASH_SPEC_KEY8_EXT}, - {"hash-spec-8-lru", e_APP_PIPELINE_HASH_SPEC_KEY8_LRU}, - {"hash-spec-16-ext", e_APP_PIPELINE_HASH_SPEC_KEY16_EXT}, - {"hash-spec-16-lru", e_APP_PIPELINE_HASH_SPEC_KEY16_LRU}, - {"hash-spec-32-ext", e_APP_PIPELINE_HASH_SPEC_KEY32_EXT}, - {"hash-spec-32-lru", e_APP_PIPELINE_HASH_SPEC_KEY32_LRU}, - {"acl", e_APP_PIPELINE_ACL}, - {"lpm", e_APP_PIPELINE_LPM}, - {"lpm-ipv6", e_APP_PIPELINE_LPM_IPV6}, - {"hash-cuckoo-8", e_APP_PIPELINE_HASH_CUCKOO_KEY8}, - {"hash-cuckoo-16", e_APP_PIPELINE_HASH_CUCKOO_KEY16}, - {"hash-cuckoo-32", e_APP_PIPELINE_HASH_CUCKOO_KEY32}, - {"hash-cuckoo-48", e_APP_PIPELINE_HASH_CUCKOO_KEY48}, - {"hash-cuckoo-64", e_APP_PIPELINE_HASH_CUCKOO_KEY64}, - {"hash-cuckoo-80", e_APP_PIPELINE_HASH_CUCKOO_KEY80}, - {"hash-cuckoo-96", e_APP_PIPELINE_HASH_CUCKOO_KEY96}, - {"hash-cuckoo-112", e_APP_PIPELINE_HASH_CUCKOO_KEY112}, - {"hash-cuckoo-128", e_APP_PIPELINE_HASH_CUCKOO_KEY128}, -}; - -int -app_parse_args(int argc, char **argv) -{ - int opt, ret; - char **argvopt; - int option_index; - char *prgname = argv[0]; - static struct option lgopts[] = { - {"none", 0, 0, 0}, - {"stub", 0, 0, 0}, - {"hash-8-ext", 0, 0, 0}, - {"hash-8-lru", 0, 0, 0}, - {"hash-16-ext", 0, 0, 0}, - {"hash-16-lru", 0, 0, 0}, - {"hash-32-ext", 0, 0, 0}, - {"hash-32-lru", 0, 0, 0}, - {"hash-spec-8-ext", 0, 0, 0}, - {"hash-spec-8-lru", 0, 0, 0}, - {"hash-spec-16-ext", 0, 0, 0}, - {"hash-spec-16-lru", 0, 0, 0}, - {"hash-spec-32-ext", 0, 0, 0}, - {"hash-spec-32-lru", 0, 0, 0}, - {"acl", 0, 0, 0}, - {"lpm", 0, 0, 0}, - {"lpm-ipv6", 0, 0, 0}, - {"hash-cuckoo-8", 0, 0, 0}, - {"hash-cuckoo-16", 0, 0, 0}, - {"hash-cuckoo-32", 0, 0, 0}, - {"hash-cuckoo-48", 0, 0, 0}, - {"hash-cuckoo-64", 0, 0, 0}, - {"hash-cuckoo-80", 0, 0, 0}, - {"hash-cuckoo-96", 0, 0, 0}, - {"hash-cuckoo-112", 0, 0, 0}, - {"hash-cuckoo-128", 0, 0, 0}, - {NULL, 0, 0, 0} - }; - uint32_t lcores[3], n_lcores, lcore_id, pipeline_type_provided; - - /* EAL args */ - n_lcores = 0; - for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { - if (rte_lcore_is_enabled(lcore_id) == 0) - continue; - - if (n_lcores >= 3) { - RTE_LOG(ERR, USER1, "Number of cores must be 3\n"); - app_print_usage(); - return -1; - } - - lcores[n_lcores] = lcore_id; - n_lcores++; - } - - if (n_lcores != 3) { - RTE_LOG(ERR, USER1, "Number of cores must be 3\n"); - app_print_usage(); - return -1; - } - - app.core_rx = lcores[0]; - app.core_worker = lcores[1]; - app.core_tx = lcores[2]; - - /* Non-EAL args */ - argvopt = argv; - - app.pipeline_type = e_APP_PIPELINE_HASH_KEY16_LRU; - pipeline_type_provided = 0; - - while ((opt = getopt_long(argc, argvopt, "p:", - lgopts, &option_index)) != EOF) { - switch (opt) { - case 'p': - if (app_parse_port_mask(optarg) < 0) { - app_print_usage(); - return -1; - } - break; - - case 0: /* long options */ - if (!pipeline_type_provided) { - uint32_t i; - - for (i = 0; i < e_APP_PIPELINES; i++) { - if (!strcmp(lgopts[option_index].name, - app_args_table[i].name)) { - app.pipeline_type = - app_args_table[i].value; - pipeline_type_provided = 1; - break; - } - } - - break; - } - - app_print_usage(); - return -1; - - default: - return -1; - } - } - - if (optind >= 0) - argv[optind - 1] = prgname; - - ret = optind - 1; - optind = 0; /* reset getopt lib */ - return ret; -} diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c deleted file mode 100644 index aef082fc3a..0000000000 --- a/app/test-pipeline/init.c +++ /dev/null @@ -1,280 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "main.h" - -struct app_params app = { - /* Ports*/ - .n_ports = APP_MAX_PORTS, - .port_rx_ring_size = 128, - .port_tx_ring_size = 512, - - /* Rings */ - .ring_rx_size = 128, - .ring_tx_size = 128, - - /* Buffer pool */ - .pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM, - .pool_size = 32 * 1024, - .pool_cache_size = 256, - - /* Burst sizes */ - .burst_size_rx_read = 64, - .burst_size_rx_write = 64, - .burst_size_worker_read = 64, - .burst_size_worker_write = 64, - .burst_size_tx_read = 64, - .burst_size_tx_write = 64, -}; - -static struct rte_eth_conf port_conf = { - .rxmode = { - .split_hdr_size = 0, - .header_split = 0, /* Header Split disabled */ - .hw_ip_checksum = 1, /* IP checksum offload enabled */ - .hw_vlan_filter = 0, /* VLAN filtering disabled */ - .jumbo_frame = 0, /* Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /* CRC stripped by hardware */ - }, - .rx_adv_conf = { - .rss_conf = { - .rss_key = NULL, - .rss_hf = ETH_RSS_IP, - }, - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, -}; - -static struct rte_eth_rxconf rx_conf = { - .rx_thresh = { - .pthresh = 8, - .hthresh = 8, - .wthresh = 4, - }, - .rx_free_thresh = 64, - .rx_drop_en = 0, -}; - -static struct rte_eth_txconf tx_conf = { - .tx_thresh = { - .pthresh = 36, - .hthresh = 0, - .wthresh = 0, - }, - .tx_free_thresh = 0, - .tx_rs_thresh = 0, -}; - -static void -app_init_mbuf_pools(void) -{ - /* Init the buffer pool */ - RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n"); - app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size, - app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id()); - if (app.pool == NULL) - rte_panic("Cannot create mbuf pool\n"); -} - -static void -app_init_rings(void) -{ - uint32_t i; - - for (i = 0; i < app.n_ports; i++) { - char name[32]; - - snprintf(name, sizeof(name), "app_ring_rx_%u", i); - - app.rings_rx[i] = rte_ring_create( - name, - app.ring_rx_size, - rte_socket_id(), - RING_F_SP_ENQ | RING_F_SC_DEQ); - - if (app.rings_rx[i] == NULL) - rte_panic("Cannot create RX ring %u\n", i); - } - - for (i = 0; i < app.n_ports; i++) { - char name[32]; - - snprintf(name, sizeof(name), "app_ring_tx_%u", i); - - app.rings_tx[i] = rte_ring_create( - name, - app.ring_tx_size, - rte_socket_id(), - RING_F_SP_ENQ | RING_F_SC_DEQ); - - if (app.rings_tx[i] == NULL) - rte_panic("Cannot create TX ring %u\n", i); - } - -} - -static void -app_ports_check_link(void) -{ - uint32_t all_ports_up, i; - - all_ports_up = 1; - - for (i = 0; i < app.n_ports; i++) { - struct rte_eth_link link; - uint8_t port; - - port = (uint8_t) app.ports[i]; - memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(port, &link); - RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n", - port, - link.link_speed / 1000, - link.link_status ? "UP" : "DOWN"); - - if (link.link_status == ETH_LINK_DOWN) - all_ports_up = 0; - } - - if (all_ports_up == 0) - rte_panic("Some NIC ports are DOWN\n"); -} - -static void -app_init_ports(void) -{ - uint32_t i; - - /* Init NIC ports, then start the ports */ - for (i = 0; i < app.n_ports; i++) { - uint8_t port; - int ret; - - port = (uint8_t) app.ports[i]; - RTE_LOG(INFO, USER1, "Initializing NIC port %u ...\n", port); - - /* Init port */ - ret = rte_eth_dev_configure( - port, - 1, - 1, - &port_conf); - if (ret < 0) - rte_panic("Cannot init NIC port %u (%d)\n", port, ret); - - rte_eth_promiscuous_enable(port); - - /* Init RX queues */ - ret = rte_eth_rx_queue_setup( - port, - 0, - app.port_rx_ring_size, - rte_eth_dev_socket_id(port), - &rx_conf, - app.pool); - if (ret < 0) - rte_panic("Cannot init RX for port %u (%d)\n", - (uint32_t) port, ret); - - /* Init TX queues */ - ret = rte_eth_tx_queue_setup( - port, - 0, - app.port_tx_ring_size, - rte_eth_dev_socket_id(port), - &tx_conf); - if (ret < 0) - rte_panic("Cannot init TX for port %u (%d)\n", - (uint32_t) port, ret); - - /* Start port */ - ret = rte_eth_dev_start(port); - if (ret < 0) - rte_panic("Cannot start port %u (%d)\n", port, ret); - } - - app_ports_check_link(); -} - -void -app_init(void) -{ - app_init_mbuf_pools(); - app_init_rings(); - app_init_ports(); - - RTE_LOG(INFO, USER1, "Initialization completed\n"); -} diff --git a/app/test-pipeline/main.c b/app/test-pipeline/main.c deleted file mode 100644 index 71ab6ad985..0000000000 --- a/app/test-pipeline/main.c +++ /dev/null @@ -1,188 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "main.h" - -int -main(int argc, char **argv) -{ - uint32_t lcore; - int ret; - - /* Init EAL */ - ret = rte_eal_init(argc, argv); - if (ret < 0) - return -1; - argc -= ret; - argv += ret; - - /* Parse application arguments (after the EAL ones) */ - ret = app_parse_args(argc, argv); - if (ret < 0) { - app_print_usage(); - return -1; - } - - /* Init */ - app_init(); - - /* Launch per-lcore init on every lcore */ - rte_eal_mp_remote_launch(app_lcore_main_loop, NULL, CALL_MASTER); - RTE_LCORE_FOREACH_SLAVE(lcore) { - if (rte_eal_wait_lcore(lcore) < 0) - return -1; - } - - return 0; -} - -int -app_lcore_main_loop(__attribute__((unused)) void *arg) -{ - unsigned lcore; - - lcore = rte_lcore_id(); - - if (lcore == app.core_rx) { - switch (app.pipeline_type) { - case e_APP_PIPELINE_ACL: - app_main_loop_rx(); - return 0; - - default: - app_main_loop_rx_metadata(); - return 0; - } - } - - if (lcore == app.core_worker) { - switch (app.pipeline_type) { - case e_APP_PIPELINE_STUB: - app_main_loop_worker_pipeline_stub(); - return 0; - - case e_APP_PIPELINE_HASH_KEY8_EXT: - case e_APP_PIPELINE_HASH_KEY8_LRU: - case e_APP_PIPELINE_HASH_KEY16_EXT: - case e_APP_PIPELINE_HASH_KEY16_LRU: - case e_APP_PIPELINE_HASH_KEY32_EXT: - case e_APP_PIPELINE_HASH_KEY32_LRU: - case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT: - case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU: - case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT: - case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU: - case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT: - case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU: - /* cases for cuckoo hash table types */ - case e_APP_PIPELINE_HASH_CUCKOO_KEY8: - case e_APP_PIPELINE_HASH_CUCKOO_KEY16: - case e_APP_PIPELINE_HASH_CUCKOO_KEY32: - case e_APP_PIPELINE_HASH_CUCKOO_KEY48: - case e_APP_PIPELINE_HASH_CUCKOO_KEY64: - case e_APP_PIPELINE_HASH_CUCKOO_KEY80: - case e_APP_PIPELINE_HASH_CUCKOO_KEY96: - case e_APP_PIPELINE_HASH_CUCKOO_KEY112: - case e_APP_PIPELINE_HASH_CUCKOO_KEY128: - app_main_loop_worker_pipeline_hash(); - return 0; - - case e_APP_PIPELINE_ACL: -#ifndef RTE_LIBRTE_ACL - rte_exit(EXIT_FAILURE, "ACL not present in build\n"); -#else - app_main_loop_worker_pipeline_acl(); - return 0; -#endif - - case e_APP_PIPELINE_LPM: - app_main_loop_worker_pipeline_lpm(); - return 0; - - case e_APP_PIPELINE_LPM_IPV6: - app_main_loop_worker_pipeline_lpm_ipv6(); - return 0; - - case e_APP_PIPELINE_NONE: - default: - app_main_loop_worker(); - return 0; - } - } - - if (lcore == app.core_tx) { - app_main_loop_tx(); - return 0; - } - - return 0; -} diff --git a/app/test-pipeline/main.h b/app/test-pipeline/main.h deleted file mode 100644 index 3685849278..0000000000 --- a/app/test-pipeline/main.h +++ /dev/null @@ -1,152 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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. - */ - -#ifndef _MAIN_H_ -#define _MAIN_H_ - -#ifndef APP_MBUF_ARRAY_SIZE -#define APP_MBUF_ARRAY_SIZE 256 -#endif - -struct app_mbuf_array { - struct rte_mbuf *array[APP_MBUF_ARRAY_SIZE]; - uint16_t n_mbufs; -}; - -#ifndef APP_MAX_PORTS -#define APP_MAX_PORTS 4 -#endif - -struct app_params { - /* CPU cores */ - uint32_t core_rx; - uint32_t core_worker; - uint32_t core_tx; - - /* Ports*/ - uint32_t ports[APP_MAX_PORTS]; - uint32_t n_ports; - uint32_t port_rx_ring_size; - uint32_t port_tx_ring_size; - - /* Rings */ - struct rte_ring *rings_rx[APP_MAX_PORTS]; - struct rte_ring *rings_tx[APP_MAX_PORTS]; - uint32_t ring_rx_size; - uint32_t ring_tx_size; - - /* Internal buffers */ - struct app_mbuf_array mbuf_rx; - struct app_mbuf_array mbuf_tx[APP_MAX_PORTS]; - - /* Buffer pool */ - struct rte_mempool *pool; - uint32_t pool_buffer_size; - uint32_t pool_size; - uint32_t pool_cache_size; - - /* Burst sizes */ - uint32_t burst_size_rx_read; - uint32_t burst_size_rx_write; - uint32_t burst_size_worker_read; - uint32_t burst_size_worker_write; - uint32_t burst_size_tx_read; - uint32_t burst_size_tx_write; - - /* App behavior */ - uint32_t pipeline_type; -} __rte_cache_aligned; - -extern struct app_params app; - -int app_parse_args(int argc, char **argv); -void app_print_usage(void); -void app_init(void); -int app_lcore_main_loop(void *arg); - -/* Pipeline */ -enum { - e_APP_PIPELINE_NONE = 0, - e_APP_PIPELINE_STUB, - - e_APP_PIPELINE_HASH_KEY8_EXT, - e_APP_PIPELINE_HASH_KEY8_LRU, - e_APP_PIPELINE_HASH_KEY16_EXT, - e_APP_PIPELINE_HASH_KEY16_LRU, - e_APP_PIPELINE_HASH_KEY32_EXT, - e_APP_PIPELINE_HASH_KEY32_LRU, - - e_APP_PIPELINE_HASH_SPEC_KEY8_EXT, - e_APP_PIPELINE_HASH_SPEC_KEY8_LRU, - e_APP_PIPELINE_HASH_SPEC_KEY16_EXT, - e_APP_PIPELINE_HASH_SPEC_KEY16_LRU, - e_APP_PIPELINE_HASH_SPEC_KEY32_EXT, - e_APP_PIPELINE_HASH_SPEC_KEY32_LRU, - - e_APP_PIPELINE_ACL, - e_APP_PIPELINE_LPM, - e_APP_PIPELINE_LPM_IPV6, - - e_APP_PIPELINE_HASH_CUCKOO_KEY8, - e_APP_PIPELINE_HASH_CUCKOO_KEY16, - e_APP_PIPELINE_HASH_CUCKOO_KEY32, - e_APP_PIPELINE_HASH_CUCKOO_KEY48, - e_APP_PIPELINE_HASH_CUCKOO_KEY64, - e_APP_PIPELINE_HASH_CUCKOO_KEY80, - e_APP_PIPELINE_HASH_CUCKOO_KEY96, - e_APP_PIPELINE_HASH_CUCKOO_KEY112, - e_APP_PIPELINE_HASH_CUCKOO_KEY128, - e_APP_PIPELINES -}; - -void app_main_loop_rx(void); -void app_main_loop_rx_metadata(void); -uint64_t test_hash(void *key, uint32_t key_size, uint64_t seed); - -void app_main_loop_worker(void); -void app_main_loop_worker_pipeline_stub(void); -void app_main_loop_worker_pipeline_hash(void); -void app_main_loop_worker_pipeline_acl(void); -void app_main_loop_worker_pipeline_lpm(void); -void app_main_loop_worker_pipeline_lpm_ipv6(void); - -void app_main_loop_tx(void); - -#define APP_FLUSH 0 -#ifndef APP_FLUSH -#define APP_FLUSH 0x3FF -#endif - -#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset)) - -#endif /* _MAIN_H_ */ diff --git a/app/test-pipeline/pipeline_acl.c b/app/test-pipeline/pipeline_acl.c deleted file mode 100644 index 22d5f362a7..0000000000 --- a/app/test-pipeline/pipeline_acl.c +++ /dev/null @@ -1,277 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "main.h" - -enum { - PROTO_FIELD_IPV4, - SRC_FIELD_IPV4, - DST_FIELD_IPV4, - SRCP_FIELD_IPV4, - DSTP_FIELD_IPV4, - NUM_FIELDS_IPV4 -}; - -/* - * Here we define the 'shape' of the data we're searching for, - * by defining the meta-data of the ACL rules. - * in this case, we're defining 5 tuples. IP addresses, ports, - * and protocol. - */ -struct rte_acl_field_def ipv4_field_formats[NUM_FIELDS_IPV4] = { - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = PROTO_FIELD_IPV4, - .input_index = PROTO_FIELD_IPV4, - .offset = sizeof(struct ether_hdr) + - offsetof(struct ipv4_hdr, next_proto_id), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = SRC_FIELD_IPV4, - .input_index = SRC_FIELD_IPV4, - .offset = sizeof(struct ether_hdr) + - offsetof(struct ipv4_hdr, src_addr), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = DST_FIELD_IPV4, - .input_index = DST_FIELD_IPV4, - .offset = sizeof(struct ether_hdr) + - offsetof(struct ipv4_hdr, dst_addr), - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = SRCP_FIELD_IPV4, - .input_index = SRCP_FIELD_IPV4, - .offset = sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr), - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = DSTP_FIELD_IPV4, - .input_index = SRCP_FIELD_IPV4, - .offset = sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr) + - sizeof(uint16_t), - }, -}; - - - -void -app_main_loop_worker_pipeline_acl(void) { - struct rte_pipeline_params pipeline_params = { - .name = "pipeline", - .socket_id = rte_socket_id(), - }; - - struct rte_pipeline *p; - uint32_t port_in_id[APP_MAX_PORTS]; - uint32_t port_out_id[APP_MAX_PORTS]; - uint32_t table_id; - uint32_t i; - - RTE_LOG(INFO, USER1, - "Core %u is doing work (pipeline with ACL table)\n", - rte_lcore_id()); - - /* Pipeline configuration */ - p = rte_pipeline_create(&pipeline_params); - if (p == NULL) - rte_panic("Unable to configure the pipeline\n"); - - /* Input port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_reader_params port_ring_params = { - .ring = app.rings_rx[i], - }; - - struct rte_pipeline_port_in_params port_params = { - .ops = &rte_port_ring_reader_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - .burst_size = app.burst_size_worker_read, - }; - - if (rte_pipeline_port_in_create(p, &port_params, - &port_in_id[i])) - rte_panic("Unable to configure input port for " - "ring %d\n", i); - } - - /* Output port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_writer_params port_ring_params = { - .ring = app.rings_tx[i], - .tx_burst_sz = app.burst_size_worker_write, - }; - - struct rte_pipeline_port_out_params port_params = { - .ops = &rte_port_ring_writer_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - }; - - if (rte_pipeline_port_out_create(p, &port_params, - &port_out_id[i])) - rte_panic("Unable to configure output port for " - "ring %d\n", i); - } - - /* Table configuration */ - { - struct rte_table_acl_params table_acl_params = { - .name = "test", /* unique identifier for acl contexts */ - .n_rules = 1 << 5, - .n_rule_fields = DIM(ipv4_field_formats), - }; - - /* Copy in the rule meta-data defined above into the params */ - memcpy(table_acl_params.field_format, ipv4_field_formats, - sizeof(ipv4_field_formats)); - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_acl_ops, - .arg_create = &table_acl_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the ACL table\n"); - } - - /* Interconnecting ports and tables */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], - table_id)) - rte_panic("Unable to connect input port %u to " - "table %u\n", port_in_id[i], table_id); - - /* Add entries to tables */ - for (i = 0; i < app.n_ports; i++) { - struct rte_pipeline_table_entry table_entry = { - .action = RTE_PIPELINE_ACTION_PORT, - {.port_id = port_out_id[i & (app.n_ports - 1)]}, - }; - struct rte_table_acl_rule_add_params rule_params; - struct rte_pipeline_table_entry *entry_ptr; - int key_found, ret; - - memset(&rule_params, 0, sizeof(rule_params)); - - /* Set the rule values */ - rule_params.field_value[SRC_FIELD_IPV4].value.u32 = 0; - rule_params.field_value[SRC_FIELD_IPV4].mask_range.u32 = 0; - rule_params.field_value[DST_FIELD_IPV4].value.u32 = - i << (24 - __builtin_popcount(app.n_ports - 1)); - rule_params.field_value[DST_FIELD_IPV4].mask_range.u32 = - 8 + __builtin_popcount(app.n_ports - 1); - rule_params.field_value[SRCP_FIELD_IPV4].value.u16 = 0; - rule_params.field_value[SRCP_FIELD_IPV4].mask_range.u16 = - UINT16_MAX; - rule_params.field_value[DSTP_FIELD_IPV4].value.u16 = 0; - rule_params.field_value[DSTP_FIELD_IPV4].mask_range.u16 = - UINT16_MAX; - rule_params.field_value[PROTO_FIELD_IPV4].value.u8 = 0; - rule_params.field_value[PROTO_FIELD_IPV4].mask_range.u8 = 0; - - rule_params.priority = 0; - - uint32_t dst_addr = rule_params.field_value[DST_FIELD_IPV4]. - value.u32; - uint32_t dst_mask = - rule_params.field_value[DST_FIELD_IPV4].mask_range.u32; - - printf("Adding rule to ACL table (IPv4 destination = " - "%u.%u.%u.%u/%u => port out = %u)\n", - (dst_addr & 0xFF000000) >> 24, - (dst_addr & 0x00FF0000) >> 16, - (dst_addr & 0x0000FF00) >> 8, - dst_addr & 0x000000FF, - dst_mask, - table_entry.port_id); - - /* For ACL, add needs an rte_table_acl_rule_add_params struct */ - ret = rte_pipeline_table_entry_add(p, table_id, &rule_params, - &table_entry, &key_found, &entry_ptr); - if (ret < 0) - rte_panic("Unable to add entry to table %u (%d)\n", - table_id, ret); - } - - /* Enable input ports */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_enable(p, port_in_id[i])) - rte_panic("Unable to enable input port %u\n", - port_in_id[i]); - - /* Check pipeline consistency */ - if (rte_pipeline_check(p) < 0) - rte_panic("Pipeline consistency check failed\n"); - - /* Run-time */ -#if APP_FLUSH == 0 - for ( ; ; ) - rte_pipeline_run(p); -#else - for (i = 0; ; i++) { - rte_pipeline_run(p); - - if ((i & APP_FLUSH) == 0) - rte_pipeline_flush(p); - } -#endif -} diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c deleted file mode 100644 index 10d28695ef..0000000000 --- a/app/test-pipeline/pipeline_hash.c +++ /dev/null @@ -1,552 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "main.h" - -static void -translate_options(uint32_t *special, uint32_t *ext, uint32_t *key_size) -{ - switch (app.pipeline_type) { - case e_APP_PIPELINE_HASH_KEY8_EXT: - *special = 0; *ext = 1; *key_size = 8; return; - case e_APP_PIPELINE_HASH_KEY8_LRU: - *special = 0; *ext = 0; *key_size = 8; return; - case e_APP_PIPELINE_HASH_KEY16_EXT: - *special = 0; *ext = 1; *key_size = 16; return; - case e_APP_PIPELINE_HASH_KEY16_LRU: - *special = 0; *ext = 0; *key_size = 16; return; - case e_APP_PIPELINE_HASH_KEY32_EXT: - *special = 0; *ext = 1; *key_size = 32; return; - case e_APP_PIPELINE_HASH_KEY32_LRU: - *special = 0; *ext = 0; *key_size = 32; return; - - case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT: - *special = 1; *ext = 1; *key_size = 8; return; - case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU: - *special = 1; *ext = 0; *key_size = 8; return; - case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT: - *special = 1; *ext = 1; *key_size = 16; return; - case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU: - *special = 1; *ext = 0; *key_size = 16; return; - case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT: - *special = 1; *ext = 1; *key_size = 32; return; - case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU: - *special = 1; *ext = 0; *key_size = 32; return; - - case e_APP_PIPELINE_HASH_CUCKOO_KEY8: - *special = 0; *ext = 0; *key_size = 8; return; - case e_APP_PIPELINE_HASH_CUCKOO_KEY16: - *special = 0; *ext = 0; *key_size = 16; return; - case e_APP_PIPELINE_HASH_CUCKOO_KEY32: - *special = 0; *ext = 0; *key_size = 32; return; - case e_APP_PIPELINE_HASH_CUCKOO_KEY48: - *special = 0; *ext = 0; *key_size = 48; return; - case e_APP_PIPELINE_HASH_CUCKOO_KEY64: - *special = 0; *ext = 0; *key_size = 64; return; - case e_APP_PIPELINE_HASH_CUCKOO_KEY80: - *special = 0; *ext = 0; *key_size = 80; return; - case e_APP_PIPELINE_HASH_CUCKOO_KEY96: - *special = 0; *ext = 0; *key_size = 96; return; - case e_APP_PIPELINE_HASH_CUCKOO_KEY112: - *special = 0; *ext = 0; *key_size = 112; return; - case e_APP_PIPELINE_HASH_CUCKOO_KEY128: - *special = 0; *ext = 0; *key_size = 128; return; - - default: - rte_panic("Invalid hash table type or key size\n"); - } -} -void -app_main_loop_worker_pipeline_hash(void) { - struct rte_pipeline_params pipeline_params = { - .name = "pipeline", - .socket_id = rte_socket_id(), - }; - - struct rte_pipeline *p; - uint32_t port_in_id[APP_MAX_PORTS]; - uint32_t port_out_id[APP_MAX_PORTS]; - uint32_t table_id; - uint32_t i; - uint32_t special, ext, key_size; - - translate_options(&special, &ext, &key_size); - - RTE_LOG(INFO, USER1, "Core %u is doing work " - "(pipeline with hash table, %s, %s, %d-byte key)\n", - rte_lcore_id(), - special ? "specialized" : "non-specialized", - ext ? "extendible bucket" : "LRU", - key_size); - - /* Pipeline configuration */ - p = rte_pipeline_create(&pipeline_params); - if (p == NULL) - rte_panic("Unable to configure the pipeline\n"); - - /* Input port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_reader_params port_ring_params = { - .ring = app.rings_rx[i], - }; - - struct rte_pipeline_port_in_params port_params = { - .ops = &rte_port_ring_reader_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - .burst_size = app.burst_size_worker_read, - }; - - if (rte_pipeline_port_in_create(p, &port_params, - &port_in_id[i])) - rte_panic("Unable to configure input port for " - "ring %d\n", i); - } - - /* Output port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_writer_params port_ring_params = { - .ring = app.rings_tx[i], - .tx_burst_sz = app.burst_size_worker_write, - }; - - struct rte_pipeline_port_out_params port_params = { - .ops = &rte_port_ring_writer_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - }; - - if (rte_pipeline_port_out_create(p, &port_params, - &port_out_id[i])) - rte_panic("Unable to configure output port for " - "ring %d\n", i); - } - - /* Table configuration */ - switch (app.pipeline_type) { - case e_APP_PIPELINE_HASH_KEY8_EXT: - case e_APP_PIPELINE_HASH_KEY16_EXT: - case e_APP_PIPELINE_HASH_KEY32_EXT: - { - struct rte_table_hash_ext_params table_hash_params = { - .key_size = key_size, - .n_keys = 1 << 24, - .n_buckets = 1 << 22, - .n_buckets_ext = 1 << 21, - .f_hash = test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_ext_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table\n"); - } - break; - - case e_APP_PIPELINE_HASH_KEY8_LRU: - case e_APP_PIPELINE_HASH_KEY16_LRU: - case e_APP_PIPELINE_HASH_KEY32_LRU: - { - struct rte_table_hash_lru_params table_hash_params = { - .key_size = key_size, - .n_keys = 1 << 24, - .n_buckets = 1 << 22, - .f_hash = test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_lru_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table\n"); - } - break; - - case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT: - { - struct rte_table_hash_key8_ext_params table_hash_params = { - .n_entries = 1 << 24, - .n_entries_ext = 1 << 23, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .f_hash = test_hash, - .seed = 0, - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_key8_ext_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table\n"); - } - break; - - case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU: - { - struct rte_table_hash_key8_lru_params table_hash_params = { - .n_entries = 1 << 24, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .f_hash = test_hash, - .seed = 0, - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_key8_lru_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table\n"); - } - break; - - case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT: - { - struct rte_table_hash_key16_ext_params table_hash_params = { - .n_entries = 1 << 24, - .n_entries_ext = 1 << 23, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .f_hash = test_hash, - .seed = 0, - .key_mask = NULL, - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_key16_ext_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table)\n"); - } - break; - - case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU: - { - struct rte_table_hash_key16_lru_params table_hash_params = { - .n_entries = 1 << 24, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .f_hash = test_hash, - .seed = 0, - .key_mask = NULL, - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_key16_lru_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table\n"); - } - break; - - case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT: - { - struct rte_table_hash_key32_ext_params table_hash_params = { - .n_entries = 1 << 24, - .n_entries_ext = 1 << 23, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .f_hash = test_hash, - .seed = 0, - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_key32_ext_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table\n"); - } - break; - - - case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU: - { - struct rte_table_hash_key32_lru_params table_hash_params = { - .n_entries = 1 << 24, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .f_hash = test_hash, - .seed = 0, - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_key32_lru_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table\n"); - } - break; - - case e_APP_PIPELINE_HASH_CUCKOO_KEY8: - case e_APP_PIPELINE_HASH_CUCKOO_KEY16: - case e_APP_PIPELINE_HASH_CUCKOO_KEY32: - case e_APP_PIPELINE_HASH_CUCKOO_KEY48: - case e_APP_PIPELINE_HASH_CUCKOO_KEY64: - case e_APP_PIPELINE_HASH_CUCKOO_KEY80: - case e_APP_PIPELINE_HASH_CUCKOO_KEY96: - case e_APP_PIPELINE_HASH_CUCKOO_KEY112: - case e_APP_PIPELINE_HASH_CUCKOO_KEY128: - { - char hash_name[RTE_HASH_NAMESIZE]; - - snprintf(hash_name, sizeof(hash_name), "RTE_TH_CUCKOO_%d", - app.pipeline_type); - - struct rte_table_hash_cuckoo_params table_hash_params = { - .key_size = key_size, - .n_keys = (1 << 24) + 1, - .f_hash = test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .name = hash_name, - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_hash_cuckoo_dosig_ops, - .arg_create = &table_hash_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the hash table\n"); - } - break; - - default: - rte_panic("Invalid hash table type or key size\n"); - } - - /* Interconnecting ports and tables */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], - table_id)) - rte_panic("Unable to connect input port %u to " - "table %u\n", port_in_id[i], table_id); - - /* Add entries to tables */ - for (i = 0; i < (1 << 24); i++) { - struct rte_pipeline_table_entry entry = { - .action = RTE_PIPELINE_ACTION_PORT, - {.port_id = port_out_id[i & (app.n_ports - 1)]}, - }; - struct rte_pipeline_table_entry *entry_ptr; - uint8_t key[32]; - uint32_t *k32 = (uint32_t *) key; - int key_found, status; - - memset(key, 0, sizeof(key)); - k32[0] = rte_be_to_cpu_32(i); - - status = rte_pipeline_table_entry_add(p, table_id, key, &entry, - &key_found, &entry_ptr); - if (status < 0) - rte_panic("Unable to add entry to table %u (%d)\n", - table_id, status); - } - - /* Enable input ports */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_enable(p, port_in_id[i])) - rte_panic("Unable to enable input port %u\n", - port_in_id[i]); - - /* Check pipeline consistency */ - if (rte_pipeline_check(p) < 0) - rte_panic("Pipeline consistency check failed\n"); - - /* Run-time */ -#if APP_FLUSH == 0 - for ( ; ; ) - rte_pipeline_run(p); -#else - for (i = 0; ; i++) { - rte_pipeline_run(p); - - if ((i & APP_FLUSH) == 0) - rte_pipeline_flush(p); - } -#endif -} - -uint64_t test_hash( - void *key, - __attribute__((unused)) uint32_t key_size, - __attribute__((unused)) uint64_t seed) -{ - uint32_t *k32 = (uint32_t *) key; - uint32_t ip_dst = rte_be_to_cpu_32(k32[0]); - uint64_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30); - - return signature; -} - -void -app_main_loop_rx_metadata(void) { - uint32_t i, j; - int ret; - - RTE_LOG(INFO, USER1, "Core %u is doing RX (with meta-data)\n", - rte_lcore_id()); - - for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) { - uint16_t n_mbufs; - - n_mbufs = rte_eth_rx_burst( - app.ports[i], - 0, - app.mbuf_rx.array, - app.burst_size_rx_read); - - if (n_mbufs == 0) - continue; - - for (j = 0; j < n_mbufs; j++) { - struct rte_mbuf *m; - uint8_t *m_data, *key; - struct ipv4_hdr *ip_hdr; - struct ipv6_hdr *ipv6_hdr; - uint32_t ip_dst; - uint8_t *ipv6_dst; - uint32_t *signature, *k32; - - m = app.mbuf_rx.array[j]; - m_data = rte_pktmbuf_mtod(m, uint8_t *); - signature = RTE_MBUF_METADATA_UINT32_PTR(m, - APP_METADATA_OFFSET(0)); - key = RTE_MBUF_METADATA_UINT8_PTR(m, - APP_METADATA_OFFSET(32)); - - if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) { - ip_hdr = (struct ipv4_hdr *) - &m_data[sizeof(struct ether_hdr)]; - ip_dst = ip_hdr->dst_addr; - - k32 = (uint32_t *) key; - k32[0] = ip_dst & 0xFFFFFF00; - } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) { - ipv6_hdr = (struct ipv6_hdr *) - &m_data[sizeof(struct ether_hdr)]; - ipv6_dst = ipv6_hdr->dst_addr; - - memcpy(key, ipv6_dst, 16); - } else - continue; - - *signature = test_hash(key, 0, 0); - } - - do { - ret = rte_ring_sp_enqueue_bulk( - app.rings_rx[i], - (void **) app.mbuf_rx.array, - n_mbufs); - } while (ret < 0); - } -} diff --git a/app/test-pipeline/pipeline_lpm.c b/app/test-pipeline/pipeline_lpm.c deleted file mode 100644 index ecea6b3b80..0000000000 --- a/app/test-pipeline/pipeline_lpm.c +++ /dev/null @@ -1,202 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "main.h" - -#ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s -#define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256 -#endif - -void -app_main_loop_worker_pipeline_lpm(void) { - struct rte_pipeline_params pipeline_params = { - .name = "pipeline", - .socket_id = rte_socket_id(), - }; - - struct rte_pipeline *p; - uint32_t port_in_id[APP_MAX_PORTS]; - uint32_t port_out_id[APP_MAX_PORTS]; - uint32_t table_id; - uint32_t i; - - RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with " - "LPM table)\n", rte_lcore_id()); - - /* Pipeline configuration */ - p = rte_pipeline_create(&pipeline_params); - if (p == NULL) - rte_panic("Unable to configure the pipeline\n"); - - /* Input port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_reader_params port_ring_params = { - .ring = app.rings_rx[i], - }; - - struct rte_pipeline_port_in_params port_params = { - .ops = &rte_port_ring_reader_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - .burst_size = app.burst_size_worker_read, - }; - - if (rte_pipeline_port_in_create(p, &port_params, - &port_in_id[i])) - rte_panic("Unable to configure input port for " - "ring %d\n", i); - } - - /* Output port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_writer_params port_ring_params = { - .ring = app.rings_tx[i], - .tx_burst_sz = app.burst_size_worker_write, - }; - - struct rte_pipeline_port_out_params port_params = { - .ops = &rte_port_ring_writer_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - }; - - if (rte_pipeline_port_out_create(p, &port_params, - &port_out_id[i])) - rte_panic("Unable to configure output port for " - "ring %d\n", i); - } - - /* Table configuration */ - { - struct rte_table_lpm_params table_lpm_params = { - .name = "LPM", - .n_rules = 1 << 24, - .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s, - .flags = 0, - .entry_unique_size = - sizeof(struct rte_pipeline_table_entry), - .offset = APP_METADATA_OFFSET(32), - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_lpm_ops, - .arg_create = &table_lpm_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the LPM table\n"); - } - - /* Interconnecting ports and tables */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], - table_id)) - rte_panic("Unable to connect input port %u to " - "table %u\n", port_in_id[i], table_id); - - /* Add entries to tables */ - for (i = 0; i < app.n_ports; i++) { - struct rte_pipeline_table_entry entry = { - .action = RTE_PIPELINE_ACTION_PORT, - {.port_id = port_out_id[i & (app.n_ports - 1)]}, - }; - - struct rte_table_lpm_key key = { - .ip = i << (24 - __builtin_popcount(app.n_ports - 1)), - .depth = 8 + __builtin_popcount(app.n_ports - 1), - }; - - struct rte_pipeline_table_entry *entry_ptr; - - int key_found, status; - - printf("Adding rule to LPM table (IPv4 destination = %" - PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8 - " => port out = %" PRIu32 ")\n", - (key.ip & 0xFF000000) >> 24, - (key.ip & 0x00FF0000) >> 16, - (key.ip & 0x0000FF00) >> 8, - key.ip & 0x000000FF, - key.depth, - i); - - status = rte_pipeline_table_entry_add(p, table_id, &key, &entry, - &key_found, &entry_ptr); - if (status < 0) - rte_panic("Unable to add entry to table %u (%d)\n", - table_id, status); - } - - /* Enable input ports */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_enable(p, port_in_id[i])) - rte_panic("Unable to enable input port %u\n", - port_in_id[i]); - - /* Check pipeline consistency */ - if (rte_pipeline_check(p) < 0) - rte_panic("Pipeline consistency check failed\n"); - - /* Run-time */ -#if APP_FLUSH == 0 - for ( ; ; ) - rte_pipeline_run(p); -#else - for (i = 0; ; i++) { - rte_pipeline_run(p); - - if ((i & APP_FLUSH) == 0) - rte_pipeline_flush(p); - } -#endif -} diff --git a/app/test-pipeline/pipeline_lpm_ipv6.c b/app/test-pipeline/pipeline_lpm_ipv6.c deleted file mode 100644 index 3352e89df7..0000000000 --- a/app/test-pipeline/pipeline_lpm_ipv6.c +++ /dev/null @@ -1,200 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "main.h" - -void -app_main_loop_worker_pipeline_lpm_ipv6(void) { - struct rte_pipeline_params pipeline_params = { - .name = "pipeline", - .socket_id = rte_socket_id(), - }; - - struct rte_pipeline *p; - uint32_t port_in_id[APP_MAX_PORTS]; - uint32_t port_out_id[APP_MAX_PORTS]; - uint32_t table_id; - uint32_t i; - - RTE_LOG(INFO, USER1, - "Core %u is doing work (pipeline with IPv6 LPM table)\n", - rte_lcore_id()); - - /* Pipeline configuration */ - p = rte_pipeline_create(&pipeline_params); - if (p == NULL) - rte_panic("Unable to configure the pipeline\n"); - - /* Input port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_reader_params port_ring_params = { - .ring = app.rings_rx[i], - }; - - struct rte_pipeline_port_in_params port_params = { - .ops = &rte_port_ring_reader_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - .burst_size = app.burst_size_worker_read, - }; - - if (rte_pipeline_port_in_create(p, &port_params, - &port_in_id[i])) - rte_panic("Unable to configure input port for " - "ring %d\n", i); - } - - /* Output port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_writer_params port_ring_params = { - .ring = app.rings_tx[i], - .tx_burst_sz = app.burst_size_worker_write, - }; - - struct rte_pipeline_port_out_params port_params = { - .ops = &rte_port_ring_writer_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - }; - - if (rte_pipeline_port_out_create(p, &port_params, - &port_out_id[i])) - rte_panic("Unable to configure output port for " - "ring %d\n", i); - } - - /* Table configuration */ - { - struct rte_table_lpm_ipv6_params table_lpm_ipv6_params = { - .name = "LPM", - .n_rules = 1 << 24, - .number_tbl8s = 1 << 21, - .entry_unique_size = - sizeof(struct rte_pipeline_table_entry), - .offset = APP_METADATA_OFFSET(32), - }; - - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_lpm_ipv6_ops, - .arg_create = &table_lpm_ipv6_params, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id)) - rte_panic("Unable to configure the IPv6 LPM table\n"); - } - - /* Interconnecting ports and tables */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], - table_id)) - rte_panic("Unable to connect input port %u to " - "table %u\n", port_in_id[i], table_id); - - /* Add entries to tables */ - for (i = 0; i < app.n_ports; i++) { - struct rte_pipeline_table_entry entry = { - .action = RTE_PIPELINE_ACTION_PORT, - {.port_id = port_out_id[i & (app.n_ports - 1)]}, - }; - - struct rte_table_lpm_ipv6_key key; - struct rte_pipeline_table_entry *entry_ptr; - uint32_t ip; - int key_found, status; - - key.depth = 8 + __builtin_popcount(app.n_ports - 1); - - ip = rte_bswap32(i << (24 - - __builtin_popcount(app.n_ports - 1))); - memcpy(key.ip, &ip, sizeof(uint32_t)); - - printf("Adding rule to IPv6 LPM table (IPv6 destination = " - "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:" - "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%u => " - "port out = %u)\n", - key.ip[0], key.ip[1], key.ip[2], key.ip[3], - key.ip[4], key.ip[5], key.ip[6], key.ip[7], - key.ip[8], key.ip[9], key.ip[10], key.ip[11], - key.ip[12], key.ip[13], key.ip[14], key.ip[15], - key.depth, i); - - status = rte_pipeline_table_entry_add(p, table_id, &key, &entry, - &key_found, &entry_ptr); - if (status < 0) - rte_panic("Unable to add entry to table %u (%d)\n", - table_id, status); - } - - /* Enable input ports */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_enable(p, port_in_id[i])) - rte_panic("Unable to enable input port %u\n", - port_in_id[i]); - - /* Check pipeline consistency */ - if (rte_pipeline_check(p) < 0) - rte_panic("Pipeline consistency check failed\n"); - - /* Run-time */ -#if APP_FLUSH == 0 - for ( ; ; ) - rte_pipeline_run(p); -#else - for (i = 0; ; i++) { - rte_pipeline_run(p); - - if ((i & APP_FLUSH) == 0) - rte_pipeline_flush(p); - } -#endif -} diff --git a/app/test-pipeline/pipeline_stub.c b/app/test-pipeline/pipeline_stub.c deleted file mode 100644 index ba710ca6ae..0000000000 --- a/app/test-pipeline/pipeline_stub.c +++ /dev/null @@ -1,164 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include -#include - -#include -#include -#include -#include - -#include "main.h" - -void -app_main_loop_worker_pipeline_stub(void) { - struct rte_pipeline_params pipeline_params = { - .name = "pipeline", - .socket_id = rte_socket_id(), - }; - - struct rte_pipeline *p; - uint32_t port_in_id[APP_MAX_PORTS]; - uint32_t port_out_id[APP_MAX_PORTS]; - uint32_t table_id[APP_MAX_PORTS]; - uint32_t i; - - RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with stub " - "tables)\n", rte_lcore_id()); - - /* Pipeline configuration */ - p = rte_pipeline_create(&pipeline_params); - if (p == NULL) - rte_panic("Unable to configure the pipeline\n"); - - /* Input port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_reader_params port_ring_params = { - .ring = app.rings_rx[i], - }; - - struct rte_pipeline_port_in_params port_params = { - .ops = &rte_port_ring_reader_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - .burst_size = app.burst_size_worker_read, - }; - - if (rte_pipeline_port_in_create(p, &port_params, - &port_in_id[i])) - rte_panic("Unable to configure input port for " - "ring %d\n", i); - } - - /* Output port configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_port_ring_writer_params port_ring_params = { - .ring = app.rings_tx[i], - .tx_burst_sz = app.burst_size_worker_write, - }; - - struct rte_pipeline_port_out_params port_params = { - .ops = &rte_port_ring_writer_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - }; - - if (rte_pipeline_port_out_create(p, &port_params, - &port_out_id[i])) - rte_panic("Unable to configure output port for " - "ring %d\n", i); - } - - /* Table configuration */ - for (i = 0; i < app.n_ports; i++) { - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_stub_ops, - .arg_create = NULL, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id[i])) - rte_panic("Unable to configure table %u\n", i); - } - - /* Interconnecting ports and tables */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], - table_id[i])) - rte_panic("Unable to connect input port %u to " - "table %u\n", port_in_id[i], table_id[i]); - - /* Add entries to tables */ - for (i = 0; i < app.n_ports; i++) { - struct rte_pipeline_table_entry entry = { - .action = RTE_PIPELINE_ACTION_PORT, - {.port_id = port_out_id[i ^ 1]}, - }; - struct rte_pipeline_table_entry *default_entry_ptr; - - if (rte_pipeline_table_default_entry_add(p, table_id[i], &entry, - &default_entry_ptr)) - rte_panic("Unable to add default entry to table %u\n", - table_id[i]); - } - - /* Enable input ports */ - for (i = 0; i < app.n_ports; i++) - if (rte_pipeline_port_in_enable(p, port_in_id[i])) - rte_panic("Unable to enable input port %u\n", - port_in_id[i]); - - /* Check pipeline consistency */ - if (rte_pipeline_check(p) < 0) - rte_panic("Pipeline consistency check failed\n"); - - /* Run-time */ -#if APP_FLUSH == 0 - for ( ; ; ) - rte_pipeline_run(p); -#else - for (i = 0; ; i++) { - rte_pipeline_run(p); - - if ((i & APP_FLUSH) == 0) - rte_pipeline_flush(p); - } -#endif -} diff --git a/app/test-pipeline/runtime.c b/app/test-pipeline/runtime.c deleted file mode 100644 index 42a6142c42..0000000000 --- a/app/test-pipeline/runtime.c +++ /dev/null @@ -1,184 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "main.h" - -void -app_main_loop_rx(void) { - uint32_t i; - int ret; - - RTE_LOG(INFO, USER1, "Core %u is doing RX\n", rte_lcore_id()); - - for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) { - uint16_t n_mbufs; - - n_mbufs = rte_eth_rx_burst( - app.ports[i], - 0, - app.mbuf_rx.array, - app.burst_size_rx_read); - - if (n_mbufs == 0) - continue; - - do { - ret = rte_ring_sp_enqueue_bulk( - app.rings_rx[i], - (void **) app.mbuf_rx.array, - n_mbufs); - } while (ret < 0); - } -} - -void -app_main_loop_worker(void) { - struct app_mbuf_array *worker_mbuf; - uint32_t i; - - RTE_LOG(INFO, USER1, "Core %u is doing work (no pipeline)\n", - rte_lcore_id()); - - worker_mbuf = rte_malloc_socket(NULL, sizeof(struct app_mbuf_array), - RTE_CACHE_LINE_SIZE, rte_socket_id()); - if (worker_mbuf == NULL) - rte_panic("Worker thread: cannot allocate buffer space\n"); - - for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) { - int ret; - - ret = rte_ring_sc_dequeue_bulk( - app.rings_rx[i], - (void **) worker_mbuf->array, - app.burst_size_worker_read); - - if (ret == -ENOENT) - continue; - - do { - ret = rte_ring_sp_enqueue_bulk( - app.rings_tx[i ^ 1], - (void **) worker_mbuf->array, - app.burst_size_worker_write); - } while (ret < 0); - } -} - -void -app_main_loop_tx(void) { - uint32_t i; - - RTE_LOG(INFO, USER1, "Core %u is doing TX\n", rte_lcore_id()); - - for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) { - uint16_t n_mbufs, n_pkts; - int ret; - - n_mbufs = app.mbuf_tx[i].n_mbufs; - - ret = rte_ring_sc_dequeue_bulk( - app.rings_tx[i], - (void **) &app.mbuf_tx[i].array[n_mbufs], - app.burst_size_tx_read); - - if (ret == -ENOENT) - continue; - - n_mbufs += app.burst_size_tx_read; - - if (n_mbufs < app.burst_size_tx_write) { - app.mbuf_tx[i].n_mbufs = n_mbufs; - continue; - } - - n_pkts = rte_eth_tx_burst( - app.ports[i], - 0, - app.mbuf_tx[i].array, - n_mbufs); - - if (n_pkts < n_mbufs) { - uint16_t k; - - for (k = n_pkts; k < n_mbufs; k++) { - struct rte_mbuf *pkt_to_free; - - pkt_to_free = app.mbuf_tx[i].array[k]; - rte_pktmbuf_free(pkt_to_free); - } - } - - app.mbuf_tx[i].n_mbufs = 0; - } -} diff --git a/app/test/Makefile b/app/test/Makefile deleted file mode 100644 index 1a5e03dc68..0000000000 --- a/app/test/Makefile +++ /dev/null @@ -1,253 +0,0 @@ -# BSD LICENSE -# -# Copyright(c) 2010-2017 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_APP_TEST),y) - -# default rule -all: - -# 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_ and end_ -# for referencing by the C code. -# -# Parameters: , -define linked_resource -SRCS-y += $(1).res.o -$(1).res.o: $(2) - @ echo ' MKRES $$@' - $Q [ "$$( 3: - testlist = sys.argv[3].split(',') - testlist = [test.lower() for test in testlist] - if testlist[0].startswith('-'): - testlist[0] = testlist[0].lstrip('-') - test_blacklist = testlist - else: - test_whitelist = testlist - -cmdline = "%s -c f -n 4" % (sys.argv[1]) - -print(cmdline) - -runner = autotest_runner.AutotestRunner(cmdline, target, test_blacklist, - test_whitelist) - -for test_group in autotest_data.parallel_test_group_list: - runner.add_parallel_test_group(test_group) - -for test_group in autotest_data.non_parallel_test_group_list: - runner.add_non_parallel_test_group(test_group) - -num_fails = runner.run_all_tests() - -sys.exit(num_fails) diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py deleted file mode 100644 index 0cd598bda4..0000000000 --- a/app/test/autotest_data.py +++ /dev/null @@ -1,469 +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. - -# Test data for autotests - -from glob import glob -from autotest_test_funcs import * - - -# quick and dirty function to find out number of sockets -def num_sockets(): - result = len(glob("/sys/devices/system/node/node*")) - if result == 0: - return 1 - return result - - -# Assign given number to each socket -# e.g. 32 becomes 32,32 or 32,32,32,32 -def per_sockets(num): - return ",".join([str(num)] * num_sockets()) - -# groups of tests that can be run in parallel -# the grouping has been found largely empirically -parallel_test_group_list = [ - { - "Prefix": "group_1", - "Memory": per_sockets(8), - "Tests": - [ - { - "Name": "Cycles autotest", - "Command": "cycles_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Timer autotest", - "Command": "timer_autotest", - "Func": timer_autotest, - "Report": None, - }, - { - "Name": "Debug autotest", - "Command": "debug_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Errno autotest", - "Command": "errno_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Meter autotest", - "Command": "meter_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Common autotest", - "Command": "common_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Resource autotest", - "Command": "resource_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "group_2", - "Memory": "16", - "Tests": - [ - { - "Name": "Memory autotest", - "Command": "memory_autotest", - "Func": memory_autotest, - "Report": None, - }, - { - "Name": "Read/write lock autotest", - "Command": "rwlock_autotest", - "Func": rwlock_autotest, - "Report": None, - }, - { - "Name": "Logs autotest", - "Command": "logs_autotest", - "Func": logs_autotest, - "Report": None, - }, - { - "Name": "CPU flags autotest", - "Command": "cpuflags_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Version autotest", - "Command": "version_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "EAL filesystem autotest", - "Command": "eal_fs_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "EAL flags autotest", - "Command": "eal_flags_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Hash autotest", - "Command": "hash_autotest", - "Func": default_autotest, - "Report": None, - }, - ], - }, - { - "Prefix": "group_3", - "Memory": per_sockets(512), - "Tests": - [ - { - "Name": "LPM autotest", - "Command": "lpm_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "LPM6 autotest", - "Command": "lpm6_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Memcpy autotest", - "Command": "memcpy_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Memzone autotest", - "Command": "memzone_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "String autotest", - "Command": "string_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Alarm autotest", - "Command": "alarm_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "group_4", - "Memory": per_sockets(128), - "Tests": - [ - { - "Name": "PCI autotest", - "Command": "pci_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Malloc autotest", - "Command": "malloc_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Multi-process autotest", - "Command": "multiprocess_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Mbuf autotest", - "Command": "mbuf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Per-lcore autotest", - "Command": "per_lcore_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Ring autotest", - "Command": "ring_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "group_5", - "Memory": "32", - "Tests": - [ - { - "Name": "Spinlock autotest", - "Command": "spinlock_autotest", - "Func": spinlock_autotest, - "Report": None, - }, - { - "Name": "Byte order autotest", - "Command": "byteorder_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "TAILQ autotest", - "Command": "tailq_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Command-line autotest", - "Command": "cmdline_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Interrupts autotest", - "Command": "interrupt_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "group_6", - "Memory": per_sockets(512), - "Tests": - [ - { - "Name": "Function reentrancy autotest", - "Command": "func_reentrancy_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Mempool autotest", - "Command": "mempool_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Atomics autotest", - "Command": "atomic_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Prefetch autotest", - "Command": "prefetch_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Red autotest", - "Command": "red_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "group_7", - "Memory": "64", - "Tests": - [ - { - "Name": "PMD ring autotest", - "Command": "ring_pmd_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Access list control autotest", - "Command": "acl_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Sched autotest", - "Command": "sched_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, -] - -# tests that should not be run when any other tests are running -non_parallel_test_group_list = [ - - { - "Prefix": "kni", - "Memory": "512", - "Tests": - [ - { - "Name": "KNI autotest", - "Command": "kni_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "mempool_perf", - "Memory": per_sockets(256), - "Tests": - [ - { - "Name": "Mempool performance autotest", - "Command": "mempool_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "memcpy_perf", - "Memory": per_sockets(512), - "Tests": - [ - { - "Name": "Memcpy performance autotest", - "Command": "memcpy_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "hash_perf", - "Memory": per_sockets(512), - "Tests": - [ - { - "Name": "Hash performance autotest", - "Command": "hash_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "power", - "Memory": "16", - "Tests": - [ - { - "Name": "Power autotest", - "Command": "power_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "power_acpi_cpufreq", - "Memory": "16", - "Tests": - [ - { - "Name": "Power ACPI cpufreq autotest", - "Command": "power_acpi_cpufreq_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "power_kvm_vm", - "Memory": "16", - "Tests": - [ - { - "Name": "Power KVM VM autotest", - "Command": "power_kvm_vm_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - { - "Prefix": "timer_perf", - "Memory": per_sockets(512), - "Tests": - [ - { - "Name": "Timer performance autotest", - "Command": "timer_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, - - # - # Please always make sure that ring_perf is the last test! - # - { - "Prefix": "ring_perf", - "Memory": per_sockets(512), - "Tests": - [ - { - "Name": "Ring performance autotest", - "Command": "ring_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - ] - }, -] diff --git a/app/test/autotest_runner.py b/app/test/autotest_runner.py deleted file mode 100644 index fc882ec05c..0000000000 --- a/app/test/autotest_runner.py +++ /dev/null @@ -1,428 +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. - -# The main logic behind running autotests in parallel - -import StringIO -import csv -import multiprocessing -import pexpect -import re -import subprocess -import sys -import time - -# wait for prompt - - -def wait_prompt(child): - try: - child.sendline() - result = child.expect(["RTE>>", pexpect.TIMEOUT, pexpect.EOF], - timeout=120) - except: - return False - if result == 0: - return True - else: - return False - -# run a test group -# each result tuple in results list consists of: -# result value (0 or -1) -# result string -# test name -# total test run time (double) -# raw test log -# test report (if not available, should be None) -# -# this function needs to be outside AutotestRunner class -# because otherwise Pool won't work (or rather it will require -# quite a bit of effort to make it work). - - -def run_test_group(cmdline, test_group): - results = [] - child = None - start_time = time.time() - startuplog = None - - # run test app - try: - # prepare logging of init - startuplog = StringIO.StringIO() - - print >>startuplog, "\n%s %s\n" % ("=" * 20, test_group["Prefix"]) - print >>startuplog, "\ncmdline=%s" % cmdline - - child = pexpect.spawn(cmdline, logfile=startuplog) - - # wait for target to boot - if not wait_prompt(child): - child.close() - - results.append((-1, - "Fail [No prompt]", - "Start %s" % test_group["Prefix"], - time.time() - start_time, - startuplog.getvalue(), - None)) - - # mark all tests as failed - for test in test_group["Tests"]: - results.append((-1, "Fail [No prompt]", test["Name"], - time.time() - start_time, "", None)) - # exit test - return results - - except: - results.append((-1, - "Fail [Can't run]", - "Start %s" % test_group["Prefix"], - time.time() - start_time, - startuplog.getvalue(), - None)) - - # mark all tests as failed - for t in test_group["Tests"]: - results.append((-1, "Fail [Can't run]", t["Name"], - time.time() - start_time, "", None)) - # exit test - return results - - # startup was successful - results.append((0, "Success", "Start %s" % test_group["Prefix"], - time.time() - start_time, startuplog.getvalue(), None)) - - # parse the binary for available test commands - binary = cmdline.split()[0] - stripped = 'not stripped' not in subprocess.check_output(['file', binary]) - if not stripped: - symbols = subprocess.check_output(['nm', binary]).decode('utf-8') - avail_cmds = re.findall('test_register_(\w+)', symbols) - - # run all tests in test group - for test in test_group["Tests"]: - - # create log buffer for each test - # in multiprocessing environment, the logging would be - # interleaved and will create a mess, hence the buffering - logfile = StringIO.StringIO() - child.logfile = logfile - - result = () - - # make a note when the test started - start_time = time.time() - - try: - # print test name to log buffer - print >>logfile, "\n%s %s\n" % ("-" * 20, test["Name"]) - - # run test function associated with the test - if stripped or test["Command"] in avail_cmds: - result = test["Func"](child, test["Command"]) - else: - result = (0, "Skipped [Not Available]") - - # make a note when the test was finished - end_time = time.time() - - # append test data to the result tuple - result += (test["Name"], end_time - start_time, - logfile.getvalue()) - - # call report function, if any defined, and supply it with - # target and complete log for test run - if test["Report"]: - report = test["Report"](self.target, log) - - # append report to results tuple - result += (report,) - else: - # report is None - result += (None,) - except: - # make a note when the test crashed - end_time = time.time() - - # mark test as failed - result = (-1, "Fail [Crash]", test["Name"], - end_time - start_time, logfile.getvalue(), None) - finally: - # append the results to the results list - results.append(result) - - # regardless of whether test has crashed, try quitting it - try: - child.sendline("quit") - child.close() - # if the test crashed, just do nothing instead - except: - # nop - pass - - # return test results - return results - - -# class representing an instance of autotests run -class AutotestRunner: - cmdline = "" - parallel_test_groups = [] - non_parallel_test_groups = [] - logfile = None - csvwriter = None - target = "" - start = None - n_tests = 0 - fails = 0 - log_buffers = [] - blacklist = [] - whitelist = [] - - def __init__(self, cmdline, target, blacklist, whitelist): - self.cmdline = cmdline - self.target = target - self.blacklist = blacklist - self.whitelist = whitelist - - # log file filename - logfile = "%s.log" % target - csvfile = "%s.csv" % target - - self.logfile = open(logfile, "w") - csvfile = open(csvfile, "w") - self.csvwriter = csv.writer(csvfile) - - # prepare results table - self.csvwriter.writerow(["test_name", "test_result", "result_str"]) - - # set up cmdline string - def __get_cmdline(self, test): - cmdline = self.cmdline - - # append memory limitations for each test - # otherwise tests won't run in parallel - if "i686" not in self.target: - cmdline += " --socket-mem=%s" % test["Memory"] - else: - # affinitize startup so that tests don't fail on i686 - cmdline = "taskset 1 " + cmdline - cmdline += " -m " + str(sum(map(int, test["Memory"].split(",")))) - - # set group prefix for autotest group - # otherwise they won't run in parallel - cmdline += " --file-prefix=%s" % test["Prefix"] - - return cmdline - - def add_parallel_test_group(self, test_group): - self.parallel_test_groups.append(test_group) - - def add_non_parallel_test_group(self, test_group): - self.non_parallel_test_groups.append(test_group) - - def __process_results(self, results): - # this iterates over individual test results - for i, result in enumerate(results): - - # increase total number of tests that were run - # do not include "start" test - if i > 0: - self.n_tests += 1 - - # unpack result tuple - test_result, result_str, test_name, \ - test_time, log, report = result - - # get total run time - cur_time = time.time() - total_time = int(cur_time - self.start) - - # print results, test run time and total time since start - result = ("%s:" % test_name).ljust(30) - result += result_str.ljust(29) - result += "[%02dm %02ds]" % (test_time / 60, test_time % 60) - - # don't print out total time every line, it's the same anyway - if i == len(results) - 1: - print(result, - "[%02dm %02ds]" % (total_time / 60, total_time % 60)) - else: - print(result) - - # if test failed and it wasn't a "start" test - if test_result < 0 and not i == 0: - self.fails += 1 - - # collect logs - self.log_buffers.append(log) - - # create report if it exists - if report: - try: - f = open("%s_%s_report.rst" % - (self.target, test_name), "w") - except IOError: - print("Report for %s could not be created!" % test_name) - else: - with f: - f.write(report) - - # write test result to CSV file - if i != 0: - self.csvwriter.writerow([test_name, test_result, result_str]) - - # this function iterates over test groups and removes each - # test that is not in whitelist/blacklist - def __filter_groups(self, test_groups): - groups_to_remove = [] - - # filter out tests from parallel test groups - for i, test_group in enumerate(test_groups): - - # iterate over a copy so that we could safely delete individual - # tests - for test in test_group["Tests"][:]: - test_id = test["Command"] - - # dump tests are specified in full e.g. "Dump_mempool" - if "_autotest" in test_id: - test_id = test_id[:-len("_autotest")] - - # filter out blacklisted/whitelisted tests - if self.blacklist and test_id in self.blacklist: - test_group["Tests"].remove(test) - continue - if self.whitelist and test_id not in self.whitelist: - test_group["Tests"].remove(test) - continue - - # modify or remove original group - if len(test_group["Tests"]) > 0: - test_groups[i] = test_group - else: - # remember which groups should be deleted - # put the numbers backwards so that we start - # deleting from the end, not from the beginning - groups_to_remove.insert(0, i) - - # remove test groups that need to be removed - for i in groups_to_remove: - del test_groups[i] - - return test_groups - - # iterate over test groups and run tests associated with them - def run_all_tests(self): - # filter groups - self.parallel_test_groups = \ - self.__filter_groups(self.parallel_test_groups) - self.non_parallel_test_groups = \ - self.__filter_groups(self.non_parallel_test_groups) - - # create a pool of worker threads - pool = multiprocessing.Pool(processes=1) - - results = [] - - # whatever happens, try to save as much logs as possible - try: - - # create table header - print("") - print("Test name".ljust(30), "Test result".ljust(29), - "Test".center(9), "Total".center(9)) - print("=" * 80) - - # make a note of tests start time - self.start = time.time() - - # assign worker threads to run test groups - for test_group in self.parallel_test_groups: - result = pool.apply_async(run_test_group, - [self.__get_cmdline(test_group), - test_group]) - results.append(result) - - # iterate while we have group execution results to get - while len(results) > 0: - - # iterate over a copy to be able to safely delete results - # this iterates over a list of group results - for group_result in results[:]: - - # if the thread hasn't finished yet, continue - if not group_result.ready(): - continue - - res = group_result.get() - - self.__process_results(res) - - # remove result from results list once we're done with it - results.remove(group_result) - - # run non_parallel tests. they are run one by one, synchronously - for test_group in self.non_parallel_test_groups: - group_result = run_test_group( - self.__get_cmdline(test_group), test_group) - - self.__process_results(group_result) - - # get total run time - cur_time = time.time() - total_time = int(cur_time - self.start) - - # print out summary - print("=" * 80) - print("Total run time: %02dm %02ds" % (total_time / 60, - total_time % 60)) - if self.fails != 0: - print("Number of failed tests: %s" % str(self.fails)) - - # write summary to logfile - self.logfile.write("Summary\n") - self.logfile.write("Target: ".ljust(15) + "%s\n" % self.target) - self.logfile.write("Tests: ".ljust(15) + "%i\n" % self.n_tests) - self.logfile.write("Failed tests: ".ljust( - 15) + "%i\n" % self.fails) - except: - print("Exception occurred") - print(sys.exc_info()) - self.fails = 1 - - # drop logs from all executions to a logfile - for buf in self.log_buffers: - self.logfile.write(buf.replace("\r", "")) - - return self.fails diff --git a/app/test/autotest_test_funcs.py b/app/test/autotest_test_funcs.py deleted file mode 100644 index 1c5f3909ea..0000000000 --- a/app/test/autotest_test_funcs.py +++ /dev/null @@ -1,302 +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. - -# Test functions - -import pexpect - -# default autotest, used to run most tests -# waits for "Test OK" - - -def default_autotest(child, test_name): - child.sendline(test_name) - result = child.expect(["Test OK", "Test Failed", - "Command not found", pexpect.TIMEOUT], timeout=900) - if result == 1: - return -1, "Fail" - elif result == 2: - return -1, "Fail [Not found]" - elif result == 3: - return -1, "Fail [Timeout]" - return 0, "Success" - -# autotest used to run dump commands -# just fires the command - - -def dump_autotest(child, test_name): - child.sendline(test_name) - return 0, "Success" - -# memory autotest -# reads output and waits for Test OK - - -def memory_autotest(child, test_name): - child.sendline(test_name) - regexp = "phys:0x[0-9a-f]*, len:([0-9]*), virt:0x[0-9a-f]*, " \ - "socket_id:[0-9]*" - index = child.expect([regexp, pexpect.TIMEOUT], timeout=180) - if index != 0: - return -1, "Fail [Timeout]" - size = int(child.match.groups()[0], 16) - if size <= 0: - return -1, "Fail [Bad size]" - index = child.expect(["Test OK", "Test Failed", - pexpect.TIMEOUT], timeout=10) - if index == 1: - return -1, "Fail" - elif index == 2: - return -1, "Fail [Timeout]" - return 0, "Success" - - -def spinlock_autotest(child, test_name): - i = 0 - ir = 0 - child.sendline(test_name) - while True: - index = child.expect(["Test OK", - "Test Failed", - "Hello from core ([0-9]*) !", - "Hello from within recursive locks " - "from ([0-9]*) !", - pexpect.TIMEOUT], timeout=5) - # ok - if index == 0: - break - - # message, check ordering - elif index == 2: - if int(child.match.groups()[0]) < i: - return -1, "Fail [Bad order]" - i = int(child.match.groups()[0]) - elif index == 3: - if int(child.match.groups()[0]) < ir: - return -1, "Fail [Bad order]" - ir = int(child.match.groups()[0]) - - # fail - elif index == 4: - return -1, "Fail [Timeout]" - elif index == 1: - return -1, "Fail" - - return 0, "Success" - - -def rwlock_autotest(child, test_name): - i = 0 - child.sendline(test_name) - while True: - index = child.expect(["Test OK", - "Test Failed", - "Hello from core ([0-9]*) !", - "Global write lock taken on master " - "core ([0-9]*)", - pexpect.TIMEOUT], timeout=10) - # ok - if index == 0: - if i != 0xffff: - return -1, "Fail [Message is missing]" - break - - # message, check ordering - elif index == 2: - if int(child.match.groups()[0]) < i: - return -1, "Fail [Bad order]" - i = int(child.match.groups()[0]) - - # must be the last message, check ordering - elif index == 3: - i = 0xffff - - elif index == 4: - return -1, "Fail [Timeout]" - - # fail - else: - return -1, "Fail" - - return 0, "Success" - - -def logs_autotest(child, test_name): - child.sendline(test_name) - - log_list = [ - "TESTAPP1: error message", - "TESTAPP1: critical message", - "TESTAPP2: critical message", - "TESTAPP1: error message", - ] - - for log_msg in log_list: - index = child.expect([log_msg, - "Test OK", - "Test Failed", - pexpect.TIMEOUT], timeout=10) - - if index == 3: - return -1, "Fail [Timeout]" - # not ok - elif index != 0: - return -1, "Fail" - - index = child.expect(["Test OK", - "Test Failed", - pexpect.TIMEOUT], timeout=10) - - return 0, "Success" - - -def timer_autotest(child, test_name): - child.sendline(test_name) - - index = child.expect(["Start timer stress tests", - "Test Failed", - pexpect.TIMEOUT], timeout=5) - - if index == 1: - return -1, "Fail" - elif index == 2: - return -1, "Fail [Timeout]" - - index = child.expect(["Start timer stress tests 2", - "Test Failed", - pexpect.TIMEOUT], timeout=5) - - if index == 1: - return -1, "Fail" - elif index == 2: - return -1, "Fail [Timeout]" - - index = child.expect(["Start timer basic tests", - "Test Failed", - pexpect.TIMEOUT], timeout=5) - - if index == 1: - return -1, "Fail" - elif index == 2: - return -1, "Fail [Timeout]" - - lcore_tim0 = -1 - lcore_tim1 = -1 - lcore_tim2 = -1 - lcore_tim3 = -1 - - while True: - index = child.expect(["TESTTIMER: ([0-9]*): callback id=([0-9]*) " - "count=([0-9]*) on core ([0-9]*)", - "Test OK", - "Test Failed", - pexpect.TIMEOUT], timeout=10) - - if index == 1: - break - - if index == 2: - return -1, "Fail" - elif index == 3: - return -1, "Fail [Timeout]" - - try: - id = int(child.match.groups()[1]) - cnt = int(child.match.groups()[2]) - lcore = int(child.match.groups()[3]) - except: - return -1, "Fail [Cannot parse]" - - # timer0 always expires on the same core when cnt < 20 - if id == 0: - if lcore_tim0 == -1: - lcore_tim0 = lcore - elif lcore != lcore_tim0 and cnt < 20: - return -1, "Fail [lcore != lcore_tim0 (%d, %d)]" \ - % (lcore, lcore_tim0) - if cnt > 21: - return -1, "Fail [tim0 cnt > 21]" - - # timer1 each time expires on a different core - if id == 1: - if lcore == lcore_tim1: - return -1, "Fail [lcore == lcore_tim1 (%d, %d)]" \ - % (lcore, lcore_tim1) - lcore_tim1 = lcore - if cnt > 10: - return -1, "Fail [tim1 cnt > 30]" - - # timer0 always expires on the same core - if id == 2: - if lcore_tim2 == -1: - lcore_tim2 = lcore - elif lcore != lcore_tim2: - return -1, "Fail [lcore != lcore_tim2 (%d, %d)]" \ - % (lcore, lcore_tim2) - if cnt > 30: - return -1, "Fail [tim2 cnt > 30]" - - # timer0 always expires on the same core - if id == 3: - if lcore_tim3 == -1: - lcore_tim3 = lcore - elif lcore != lcore_tim3: - return -1, "Fail [lcore_tim3 changed (%d -> %d)]" \ - % (lcore, lcore_tim3) - if cnt > 30: - return -1, "Fail [tim3 cnt > 30]" - - # must be 2 different cores - if lcore_tim0 == lcore_tim3: - return -1, "Fail [lcore_tim0 (%d) == lcore_tim3 (%d)]" \ - % (lcore_tim0, lcore_tim3) - - return 0, "Success" - - -def ring_autotest(child, test_name): - child.sendline(test_name) - index = child.expect(["Test OK", "Test Failed", - pexpect.TIMEOUT], timeout=2) - if index == 1: - return -1, "Fail" - elif index == 2: - return -1, "Fail [Timeout]" - - child.sendline("set_watermark test 100") - child.sendline("dump_ring test") - index = child.expect([" watermark=100", - pexpect.TIMEOUT], timeout=1) - if index != 0: - return -1, "Fail [Bad watermark]" - - return 0, "Success" diff --git a/app/test/commands.c b/app/test/commands.c deleted file mode 100644 index 2df46b054e..0000000000 --- a/app/test/commands.c +++ /dev/null @@ -1,453 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * Copyright(c) 2014 6WIND S.A. - * 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 -#include -#include -#include -#include -#include -#include -#ifndef __linux__ -#ifndef __FreeBSD__ -#include -#endif -#endif -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/****************/ - -static struct test_commands_list commands_list = - TAILQ_HEAD_INITIALIZER(commands_list); - -void -add_test_command(struct test_command *t) -{ - TAILQ_INSERT_TAIL(&commands_list, t, next); -} - -struct cmd_autotest_result { - cmdline_fixed_string_t autotest; -}; - -static void cmd_autotest_parsed(void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct test_command *t; - struct cmd_autotest_result *res = parsed_result; - int ret = 0; - - TAILQ_FOREACH(t, &commands_list, next) { - if (!strcmp(res->autotest, t->command)) - ret = t->callback(); - } - - if (ret == 0) - printf("Test OK\n"); - else - printf("Test Failed\n"); - fflush(stdout); -} - -cmdline_parse_token_string_t cmd_autotest_autotest = - TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest, - ""); - -cmdline_parse_inst_t cmd_autotest = { - .f = cmd_autotest_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "launch autotest", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_autotest_autotest, - NULL, - }, -}; - -/****************/ - -struct cmd_dump_result { - cmdline_fixed_string_t dump; -}; - -static void -dump_struct_sizes(void) -{ -#define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t)); - DUMP_SIZE(struct rte_mbuf); - DUMP_SIZE(struct rte_mempool); - DUMP_SIZE(struct rte_ring); -#undef DUMP_SIZE -} - -static void cmd_dump_parsed(void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_dump_result *res = parsed_result; - - if (!strcmp(res->dump, "dump_physmem")) - rte_dump_physmem_layout(stdout); - else if (!strcmp(res->dump, "dump_memzone")) - rte_memzone_dump(stdout); - else if (!strcmp(res->dump, "dump_struct_sizes")) - dump_struct_sizes(); - else if (!strcmp(res->dump, "dump_ring")) - rte_ring_list_dump(stdout); - else if (!strcmp(res->dump, "dump_mempool")) - rte_mempool_list_dump(stdout); - else if (!strcmp(res->dump, "dump_devargs")) - rte_eal_devargs_dump(stdout); -} - -cmdline_parse_token_string_t cmd_dump_dump = - TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, - "dump_physmem#dump_memzone#" - "dump_struct_sizes#dump_ring#dump_mempool#" - "dump_devargs"); - -cmdline_parse_inst_t cmd_dump = { - .f = cmd_dump_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "dump status", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_dump_dump, - NULL, - }, -}; - -/****************/ - -struct cmd_dump_one_result { - cmdline_fixed_string_t dump; - cmdline_fixed_string_t name; -}; - -static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_dump_one_result *res = parsed_result; - - if (!strcmp(res->dump, "dump_ring")) { - struct rte_ring *r; - r = rte_ring_lookup(res->name); - if (r == NULL) { - cmdline_printf(cl, "Cannot find ring\n"); - return; - } - rte_ring_dump(stdout, r); - } - else if (!strcmp(res->dump, "dump_mempool")) { - struct rte_mempool *mp; - mp = rte_mempool_lookup(res->name); - if (mp == NULL) { - cmdline_printf(cl, "Cannot find mempool\n"); - return; - } - rte_mempool_dump(stdout, mp); - } -} - -cmdline_parse_token_string_t cmd_dump_one_dump = - TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump, - "dump_ring#dump_mempool"); - -cmdline_parse_token_string_t cmd_dump_one_name = - TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL); - -cmdline_parse_inst_t cmd_dump_one = { - .f = cmd_dump_one_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "dump one ring/mempool: dump_ring|dump_mempool ", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_dump_one_dump, - (void *)&cmd_dump_one_name, - NULL, - }, -}; - -/****************/ - -struct cmd_set_ring_result { - cmdline_fixed_string_t set; - cmdline_fixed_string_t name; - uint32_t value; -}; - -static void cmd_set_ring_parsed(void *parsed_result, struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_set_ring_result *res = parsed_result; - struct rte_ring *r; - int ret; - - r = rte_ring_lookup(res->name); - if (r == NULL) { - cmdline_printf(cl, "Cannot find ring\n"); - return; - } - - if (!strcmp(res->set, "set_watermark")) { - ret = rte_ring_set_water_mark(r, res->value); - if (ret != 0) - cmdline_printf(cl, "Cannot set water mark\n"); - } -} - -cmdline_parse_token_string_t cmd_set_ring_set = - TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, set, - "set_watermark"); - -cmdline_parse_token_string_t cmd_set_ring_name = - TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, name, NULL); - -cmdline_parse_token_num_t cmd_set_ring_value = - TOKEN_NUM_INITIALIZER(struct cmd_set_ring_result, value, UINT32); - -cmdline_parse_inst_t cmd_set_ring = { - .f = cmd_set_ring_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "set watermark: " - "set_watermark ", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_set_ring_set, - (void *)&cmd_set_ring_name, - (void *)&cmd_set_ring_value, - NULL, - }, -}; - -/****************/ - -struct cmd_quit_result { - cmdline_fixed_string_t quit; -}; - -static void -cmd_quit_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_quit(cl); -} - -cmdline_parse_token_string_t cmd_quit_quit = - TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, - "quit"); - -cmdline_parse_inst_t cmd_quit = { - .f = cmd_quit_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "exit application", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_quit_quit, - NULL, - }, -}; - -/****************/ - -struct cmd_set_rxtx_result { - cmdline_fixed_string_t set; - cmdline_fixed_string_t mode; -}; - -static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_set_rxtx_result *res = parsed_result; - if (test_set_rxtx_conf(res->mode) < 0) - cmdline_printf(cl, "Cannot find such mode\n"); -} - -cmdline_parse_token_string_t cmd_set_rxtx_set = - TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set, - "set_rxtx_mode"); - -cmdline_parse_token_string_t cmd_set_rxtx_mode = - TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL); - -cmdline_parse_inst_t cmd_set_rxtx = { - .f = cmd_set_rxtx_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "set rxtx routine: " - "set_rxtx ", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_set_rxtx_set, - (void *)&cmd_set_rxtx_mode, - NULL, - }, -}; - -/****************/ - -struct cmd_set_rxtx_anchor { - cmdline_fixed_string_t set; - cmdline_fixed_string_t type; -}; - -static void -cmd_set_rxtx_anchor_parsed(void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_set_rxtx_anchor *res = parsed_result; - if (test_set_rxtx_anchor(res->type) < 0) - cmdline_printf(cl, "Cannot find such anchor\n"); -} - -cmdline_parse_token_string_t cmd_set_rxtx_anchor_set = - TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, set, - "set_rxtx_anchor"); - -cmdline_parse_token_string_t cmd_set_rxtx_anchor_type = - TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, type, NULL); - -cmdline_parse_inst_t cmd_set_rxtx_anchor = { - .f = cmd_set_rxtx_anchor_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "set rxtx anchor: " - "set_rxtx_anchor ", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_set_rxtx_anchor_set, - (void *)&cmd_set_rxtx_anchor_type, - NULL, - }, -}; - -/****************/ - -/* for stream control */ -struct cmd_set_rxtx_sc { - cmdline_fixed_string_t set; - cmdline_fixed_string_t type; -}; - -static void -cmd_set_rxtx_sc_parsed(void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_set_rxtx_sc *res = parsed_result; - if (test_set_rxtx_sc(res->type) < 0) - cmdline_printf(cl, "Cannot find such stream control\n"); -} - -cmdline_parse_token_string_t cmd_set_rxtx_sc_set = - TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set, - "set_rxtx_sc"); - -cmdline_parse_token_string_t cmd_set_rxtx_sc_type = - TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL); - -cmdline_parse_inst_t cmd_set_rxtx_sc = { - .f = cmd_set_rxtx_sc_parsed, /* function to call */ - .data = NULL, /* 2nd arg of func */ - .help_str = "set rxtx stream control: " - "set_rxtx_sc ", - .tokens = { /* token list, NULL terminated */ - (void *)&cmd_set_rxtx_sc_set, - (void *)&cmd_set_rxtx_sc_type, - NULL, - }, -}; - -/****************/ - - -cmdline_parse_ctx_t main_ctx[] = { - (cmdline_parse_inst_t *)&cmd_autotest, - (cmdline_parse_inst_t *)&cmd_dump, - (cmdline_parse_inst_t *)&cmd_dump_one, - (cmdline_parse_inst_t *)&cmd_set_ring, - (cmdline_parse_inst_t *)&cmd_quit, - (cmdline_parse_inst_t *)&cmd_set_rxtx, - (cmdline_parse_inst_t *)&cmd_set_rxtx_anchor, - (cmdline_parse_inst_t *)&cmd_set_rxtx_sc, - NULL, -}; - -int commands_init(void) -{ - struct test_command *t; - char *commands, *ptr; - int commands_len = 0; - - TAILQ_FOREACH(t, &commands_list, next) { - commands_len += strlen(t->command) + 1; - } - - commands = malloc(commands_len + 1); - if (!commands) - return -1; - - ptr = commands; - TAILQ_FOREACH(t, &commands_list, next) { - ptr += sprintf(ptr, "%s#", t->command); - } - ptr--; - ptr[0] = '\0'; - - cmd_autotest_autotest.string_data.str = commands; - return 0; -} diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c deleted file mode 100644 index a93c3b5999..0000000000 --- a/app/test/packet_burst_generator.c +++ /dev/null @@ -1,285 +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 -#include - -#include "packet_burst_generator.h" - -#define UDP_SRC_PORT 1024 -#define UDP_DST_PORT 1024 - - -#define IP_DEFTTL 64 /* from RFC 1340. */ -#define IP_VERSION 0x40 -#define IP_HDRLEN 0x05 /* default IP header length == five 32-bits words. */ -#define IP_VHL_DEF (IP_VERSION | IP_HDRLEN) - -static void -copy_buf_to_pkt_segs(void *buf, unsigned len, struct rte_mbuf *pkt, - unsigned offset) -{ - struct rte_mbuf *seg; - void *seg_buf; - unsigned copy_len; - - seg = pkt; - while (offset >= seg->data_len) { - offset -= seg->data_len; - seg = seg->next; - } - copy_len = seg->data_len - offset; - seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset); - while (len > copy_len) { - rte_memcpy(seg_buf, buf, (size_t) copy_len); - len -= copy_len; - buf = ((char *) buf + copy_len); - seg = seg->next; - seg_buf = rte_pktmbuf_mtod(seg, void *); - } - rte_memcpy(seg_buf, buf, (size_t) len); -} - -static inline void -copy_buf_to_pkt(void *buf, unsigned len, struct rte_mbuf *pkt, unsigned offset) -{ - if (offset + len <= pkt->data_len) { - rte_memcpy(rte_pktmbuf_mtod_offset(pkt, char *, offset), buf, - (size_t) len); - return; - } - copy_buf_to_pkt_segs(buf, len, pkt, offset); -} - -void -initialize_eth_header(struct ether_hdr *eth_hdr, struct ether_addr *src_mac, - struct ether_addr *dst_mac, uint16_t ether_type, - uint8_t vlan_enabled, uint16_t van_id) -{ - ether_addr_copy(dst_mac, ð_hdr->d_addr); - ether_addr_copy(src_mac, ð_hdr->s_addr); - - if (vlan_enabled) { - struct vlan_hdr *vhdr = (struct vlan_hdr *)((uint8_t *)eth_hdr + - sizeof(struct ether_hdr)); - - eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_VLAN); - - vhdr->eth_proto = rte_cpu_to_be_16(ether_type); - vhdr->vlan_tci = van_id; - } else { - eth_hdr->ether_type = rte_cpu_to_be_16(ether_type); - } -} - -void -initialize_arp_header(struct arp_hdr *arp_hdr, struct ether_addr *src_mac, - struct ether_addr *dst_mac, uint32_t src_ip, uint32_t dst_ip, - uint32_t opcode) -{ - arp_hdr->arp_hrd = rte_cpu_to_be_16(ARP_HRD_ETHER); - arp_hdr->arp_pro = rte_cpu_to_be_16(ETHER_TYPE_IPv4); - arp_hdr->arp_hln = ETHER_ADDR_LEN; - arp_hdr->arp_pln = sizeof(uint32_t); - arp_hdr->arp_op = rte_cpu_to_be_16(opcode); - ether_addr_copy(src_mac, &arp_hdr->arp_data.arp_sha); - arp_hdr->arp_data.arp_sip = src_ip; - ether_addr_copy(dst_mac, &arp_hdr->arp_data.arp_tha); - arp_hdr->arp_data.arp_tip = dst_ip; -} - -uint16_t -initialize_udp_header(struct udp_hdr *udp_hdr, uint16_t src_port, - uint16_t dst_port, uint16_t pkt_data_len) -{ - uint16_t pkt_len; - - pkt_len = (uint16_t) (pkt_data_len + sizeof(struct udp_hdr)); - - udp_hdr->src_port = rte_cpu_to_be_16(src_port); - udp_hdr->dst_port = rte_cpu_to_be_16(dst_port); - udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len); - udp_hdr->dgram_cksum = 0; /* No UDP checksum. */ - - return pkt_len; -} - - -uint16_t -initialize_ipv6_header(struct ipv6_hdr *ip_hdr, uint8_t *src_addr, - uint8_t *dst_addr, uint16_t pkt_data_len) -{ - ip_hdr->vtc_flow = 0; - ip_hdr->payload_len = pkt_data_len; - ip_hdr->proto = IPPROTO_UDP; - ip_hdr->hop_limits = IP_DEFTTL; - - rte_memcpy(ip_hdr->src_addr, src_addr, sizeof(ip_hdr->src_addr)); - rte_memcpy(ip_hdr->dst_addr, dst_addr, sizeof(ip_hdr->dst_addr)); - - return (uint16_t) (pkt_data_len + sizeof(struct ipv6_hdr)); -} - -uint16_t -initialize_ipv4_header(struct ipv4_hdr *ip_hdr, uint32_t src_addr, - uint32_t dst_addr, uint16_t pkt_data_len) -{ - uint16_t pkt_len; - unaligned_uint16_t *ptr16; - uint32_t ip_cksum; - - /* - * Initialize IP header. - */ - pkt_len = (uint16_t) (pkt_data_len + sizeof(struct ipv4_hdr)); - - ip_hdr->version_ihl = IP_VHL_DEF; - ip_hdr->type_of_service = 0; - ip_hdr->fragment_offset = 0; - ip_hdr->time_to_live = IP_DEFTTL; - ip_hdr->next_proto_id = IPPROTO_UDP; - ip_hdr->packet_id = 0; - ip_hdr->total_length = rte_cpu_to_be_16(pkt_len); - ip_hdr->src_addr = rte_cpu_to_be_32(src_addr); - ip_hdr->dst_addr = rte_cpu_to_be_32(dst_addr); - - /* - * Compute IP header checksum. - */ - ptr16 = (unaligned_uint16_t *)ip_hdr; - ip_cksum = 0; - ip_cksum += ptr16[0]; ip_cksum += ptr16[1]; - ip_cksum += ptr16[2]; ip_cksum += ptr16[3]; - ip_cksum += ptr16[4]; - ip_cksum += ptr16[6]; ip_cksum += ptr16[7]; - ip_cksum += ptr16[8]; ip_cksum += ptr16[9]; - - /* - * Reduce 32 bit checksum to 16 bits and complement it. - */ - ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) + - (ip_cksum & 0x0000FFFF); - ip_cksum %= 65536; - ip_cksum = (~ip_cksum) & 0x0000FFFF; - if (ip_cksum == 0) - ip_cksum = 0xFFFF; - ip_hdr->hdr_checksum = (uint16_t) ip_cksum; - - return pkt_len; -} - - - -/* - * The maximum number of segments per packet is used when creating - * scattered transmit packets composed of a list of mbufs. - */ -#define RTE_MAX_SEGS_PER_PKT 255 /**< pkt.nb_segs is a 8-bit unsigned char. */ - - -int -generate_packet_burst(struct rte_mempool *mp, struct rte_mbuf **pkts_burst, - struct ether_hdr *eth_hdr, uint8_t vlan_enabled, void *ip_hdr, - uint8_t ipv4, struct udp_hdr *udp_hdr, int nb_pkt_per_burst, - uint8_t pkt_len, uint8_t nb_pkt_segs) -{ - int i, nb_pkt = 0; - size_t eth_hdr_size; - - struct rte_mbuf *pkt_seg; - struct rte_mbuf *pkt; - - for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) { - pkt = rte_pktmbuf_alloc(mp); - if (pkt == NULL) { -nomore_mbuf: - if (nb_pkt == 0) - return -1; - break; - } - - pkt->data_len = pkt_len; - pkt_seg = pkt; - for (i = 1; i < nb_pkt_segs; i++) { - pkt_seg->next = rte_pktmbuf_alloc(mp); - if (pkt_seg->next == NULL) { - pkt->nb_segs = i; - rte_pktmbuf_free(pkt); - goto nomore_mbuf; - } - pkt_seg = pkt_seg->next; - pkt_seg->data_len = pkt_len; - } - pkt_seg->next = NULL; /* Last segment of packet. */ - - /* - * Copy headers in first packet segment(s). - */ - if (vlan_enabled) - eth_hdr_size = sizeof(struct ether_hdr) + sizeof(struct vlan_hdr); - else - eth_hdr_size = sizeof(struct ether_hdr); - - copy_buf_to_pkt(eth_hdr, eth_hdr_size, pkt, 0); - - if (ipv4) { - copy_buf_to_pkt(ip_hdr, sizeof(struct ipv4_hdr), pkt, eth_hdr_size); - copy_buf_to_pkt(udp_hdr, sizeof(*udp_hdr), pkt, eth_hdr_size + - sizeof(struct ipv4_hdr)); - } else { - copy_buf_to_pkt(ip_hdr, sizeof(struct ipv6_hdr), pkt, eth_hdr_size); - copy_buf_to_pkt(udp_hdr, sizeof(*udp_hdr), pkt, eth_hdr_size + - sizeof(struct ipv6_hdr)); - } - - /* - * Complete first mbuf of packet and append it to the - * burst of packets to be transmitted. - */ - pkt->nb_segs = nb_pkt_segs; - pkt->pkt_len = pkt_len; - pkt->l2_len = eth_hdr_size; - - if (ipv4) { - pkt->vlan_tci = ETHER_TYPE_IPv4; - pkt->l3_len = sizeof(struct ipv4_hdr); - } else { - pkt->vlan_tci = ETHER_TYPE_IPv6; - pkt->l3_len = sizeof(struct ipv6_hdr); - } - - pkts_burst[nb_pkt] = pkt; - } - - return nb_pkt; -} diff --git a/app/test/packet_burst_generator.h b/app/test/packet_burst_generator.h deleted file mode 100644 index edc104417b..0000000000 --- a/app/test/packet_burst_generator.h +++ /dev/null @@ -1,88 +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 PACKET_BURST_GENERATOR_H_ -#define PACKET_BURST_GENERATOR_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include - - -#define IPV4_ADDR(a, b, c, d)(((a & 0xff) << 24) | ((b & 0xff) << 16) | \ - ((c & 0xff) << 8) | (d & 0xff)) - -#define PACKET_BURST_GEN_PKT_LEN 60 -#define PACKET_BURST_GEN_PKT_LEN_128 128 - -void -initialize_eth_header(struct ether_hdr *eth_hdr, struct ether_addr *src_mac, - struct ether_addr *dst_mac, uint16_t ether_type, - uint8_t vlan_enabled, uint16_t van_id); - -void -initialize_arp_header(struct arp_hdr *arp_hdr, struct ether_addr *src_mac, - struct ether_addr *dst_mac, uint32_t src_ip, uint32_t dst_ip, - uint32_t opcode); - -uint16_t -initialize_udp_header(struct udp_hdr *udp_hdr, uint16_t src_port, - uint16_t dst_port, uint16_t pkt_data_len); - - -uint16_t -initialize_ipv6_header(struct ipv6_hdr *ip_hdr, uint8_t *src_addr, - uint8_t *dst_addr, uint16_t pkt_data_len); - -uint16_t -initialize_ipv4_header(struct ipv4_hdr *ip_hdr, uint32_t src_addr, - uint32_t dst_addr, uint16_t pkt_data_len); - -int -generate_packet_burst(struct rte_mempool *mp, struct rte_mbuf **pkts_burst, - struct ether_hdr *eth_hdr, uint8_t vlan_enabled, void *ip_hdr, - uint8_t ipv4, struct udp_hdr *udp_hdr, int nb_pkt_per_burst, - uint8_t pkt_len, uint8_t nb_pkt_segs); - -#ifdef __cplusplus -} -#endif - - -#endif /* PACKET_BURST_GENERATOR_H_ */ diff --git a/app/test/process.h b/app/test/process.h deleted file mode 100644 index 4f8d121162..0000000000 --- a/app/test/process.h +++ /dev/null @@ -1,103 +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 _PROCESS_H_ -#define _PROCESS_H_ - -#ifdef RTE_EXEC_ENV_BSDAPP -#define self "curproc" -#define exe "file" -#else -#define self "self" -#define exe "exe" -#endif - -/* - * launches a second copy of the test process using the given argv parameters, - * which should include argv[0] as the process name. To identify in the - * subprocess the source of the call, the env_value parameter is set in the - * environment as $RTE_TEST - */ -static inline int -process_dup(const char *const argv[], int numargs, const char *env_value) -{ - int num; -#ifdef RTE_LIBRTE_XEN_DOM0 - char *argv_cpy[numargs + 2]; -#else - char *argv_cpy[numargs + 1]; -#endif - int i, fd, status; - char path[32]; - - pid_t pid = fork(); - if (pid < 0) - return -1; - else if (pid == 0) { - /* make a copy of the arguments to be passed to exec */ - for (i = 0; i < numargs; i++) - argv_cpy[i] = strdup(argv[i]); -#ifdef RTE_LIBRTE_XEN_DOM0 - argv_cpy[i] = strdup("--xen-dom0"); - argv_cpy[i + 1] = NULL; - num = numargs + 1; -#else - argv_cpy[i] = NULL; - num = numargs; -#endif - - /* close all open file descriptors, check /proc/self/fd to only - * call close on open fds. Exclude fds 0, 1 and 2*/ - for (fd = getdtablesize(); fd > 2; fd-- ) { - snprintf(path, sizeof(path), "/proc/" exe "/fd/%d", fd); - if (access(path, F_OK) == 0) - close(fd); - } - printf("Running binary with argv[]:"); - for (i = 0; i < num; i++) - printf("'%s' ", argv_cpy[i]); - printf("\n"); - - /* set the environment variable */ - if (setenv(RECURSIVE_ENV_VAR, env_value, 1) != 0) - rte_panic("Cannot export environment variable\n"); - if (execv("/proc/" self "/" exe, argv_cpy) < 0) - rte_panic("Cannot exec\n"); - } - /* parent process does a wait */ - while (wait(&status) != pid) - ; - return status; -} - -#endif /* _PROCESS_H_ */ diff --git a/app/test/resource.c b/app/test/resource.c deleted file mode 100644 index 0e2b62cd8b..0000000000 --- a/app/test/resource.c +++ /dev/null @@ -1,305 +0,0 @@ -/*- - * 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 -#include -#include -#include - -#include - -#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 -#include - -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 deleted file mode 100644 index 1e96122133..0000000000 --- a/app/test/resource.h +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * 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 -#include -#include - -#include -#include - -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_ and end_ 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.c b/app/test/test.c deleted file mode 100644 index cd0e784589..0000000000 --- a/app/test/test.c +++ /dev/null @@ -1,237 +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef RTE_LIBRTE_CMDLINE -#include -#include -#include -#include -extern cmdline_parse_ctx_t main_ctx[]; -#endif - -#include -#include -#include -#include -#include -#include -#ifdef RTE_LIBRTE_TIMER -#include -#endif - -#include "test.h" - -#define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1 - -const char *prgname; /* to be set to argv[0] */ - -static const char *recursive_call; /* used in linuxapp for MP and other tests */ - -static int -no_action(void){ return 0; } - -static int -do_recursive_call(void) -{ - unsigned i; - struct { - const char *env_var; - int (*action_fn)(void); - } actions[] = { - { "run_secondary_instances", test_mp_secondary }, - { "test_missing_c_flag", no_action }, - { "test_master_lcore_flag", no_action }, - { "test_invalid_n_flag", no_action }, - { "test_no_hpet_flag", no_action }, - { "test_whitelist_flag", no_action }, - { "test_invalid_b_flag", no_action }, - { "test_invalid_vdev_flag", no_action }, - { "test_invalid_r_flag", no_action }, -#ifdef RTE_LIBRTE_XEN_DOM0 - { "test_dom0_misc_flags", no_action }, -#else - { "test_misc_flags", no_action }, -#endif - { "test_memory_flags", no_action }, - { "test_file_prefix", no_action }, - { "test_no_huge_flag", no_action }, - }; - - if (recursive_call == NULL) - return -1; - for (i = 0; i < sizeof(actions)/sizeof(actions[0]); i++) { - if (strcmp(actions[i].env_var, recursive_call) == 0) - return (actions[i].action_fn)(); - } - printf("ERROR - missing action to take for %s\n", recursive_call); - return -1; -} - -int -main(int argc, char **argv) -{ -#ifdef RTE_LIBRTE_CMDLINE - struct cmdline *cl; -#endif - int ret; - - ret = rte_eal_init(argc, argv); - if (ret < 0) - return -1; - -#ifdef RTE_LIBRTE_TIMER - rte_timer_subsystem_init(); -#endif - - if (commands_init() < 0) - return -1; - - argv += ret; - - prgname = argv[0]; - - if ((recursive_call = getenv(RECURSIVE_ENV_VAR)) != NULL) - return do_recursive_call(); - -#ifdef RTE_LIBEAL_USE_HPET - if (rte_eal_hpet_init(1) < 0) -#endif - RTE_LOG(INFO, APP, - "HPET is not enabled, using TSC as default timer\n"); - - -#ifdef RTE_LIBRTE_CMDLINE - cl = cmdline_stdin_new(main_ctx, "RTE>>"); - if (cl == NULL) { - return -1; - } - cmdline_interact(cl); - cmdline_stdin_exit(cl); -#endif - - return 0; -} - - -int -unit_test_suite_runner(struct unit_test_suite *suite) -{ - int test_success; - unsigned total = 0, executed = 0, skipped = 0, succeeded = 0, failed = 0; - - if (suite->suite_name) { - printf(" + ------------------------------------------------------- +\n"); - printf(" + Test Suite : %s\n", suite->suite_name); - } - - if (suite->setup) - if (suite->setup() != 0) - goto suite_summary; - - printf(" + ------------------------------------------------------- +\n"); - - while (suite->unit_test_cases[total].testcase) { - if (!suite->unit_test_cases[total].enabled) { - skipped++; - total++; - continue; - } else { - executed++; - } - - /* run test case setup */ - if (suite->unit_test_cases[total].setup) - test_success = suite->unit_test_cases[total].setup(); - else - test_success = TEST_SUCCESS; - - if (test_success == TEST_SUCCESS) { - /* run the test case */ - test_success = suite->unit_test_cases[total].testcase(); - if (test_success == TEST_SUCCESS) - succeeded++; - else - failed++; - } else { - failed++; - } - - /* run the test case teardown */ - if (suite->unit_test_cases[total].teardown) - suite->unit_test_cases[total].teardown(); - - if (test_success == TEST_SUCCESS) - printf(" + TestCase [%2d] : %s\n", total, - suite->unit_test_cases[total].success_msg ? - suite->unit_test_cases[total].success_msg : - "passed"); - else - printf(" + TestCase [%2d] : %s\n", total, - suite->unit_test_cases[total].fail_msg ? - suite->unit_test_cases[total].fail_msg : - "failed"); - - total++; - } - - /* Run test suite teardown */ - if (suite->teardown) - suite->teardown(); - - goto suite_summary; - -suite_summary: - printf(" + ------------------------------------------------------- +\n"); - printf(" + Test Suite Summary \n"); - printf(" + Tests Total : %2d\n", total); - printf(" + Tests Skipped : %2d\n", skipped); - printf(" + Tests Executed : %2d\n", executed); - printf(" + Tests Passed : %2d\n", succeeded); - printf(" + Tests Failed : %2d\n", failed); - printf(" + ------------------------------------------------------- +\n"); - - if (failed) - return -1; - - return 0; -} diff --git a/app/test/test.h b/app/test/test.h deleted file mode 100644 index 82831f4e6c..0000000000 --- a/app/test/test.h +++ /dev/null @@ -1,267 +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 _TEST_H_ -#define _TEST_H_ - -#include -#include - -#include -#include - -#define TEST_SUCCESS (0) -#define TEST_FAILED (-1) - -/* Before including test.h file you can define - * TEST_TRACE_FAILURE(_file, _line, _func) macro to better trace/debug test - * failures. Mostly useful in test development phase. */ -#ifndef TEST_TRACE_FAILURE -# define TEST_TRACE_FAILURE(_file, _line, _func) -#endif - -#define TEST_ASSERT(cond, msg, ...) do { \ - if (!(cond)) { \ - 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_EQUAL(a, b, msg, ...) do { \ - if (!(a == 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 (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: " \ - 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 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)) { \ - 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_SUCCESS(val, msg, ...) do { \ - typeof(val) _val = (val); \ - if (!(_val == 0)) { \ - printf("TestCase %s() line %d failed (err %d): " \ - msg "\n", __func__, __LINE__, _val, \ - ##__VA_ARGS__); \ - TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ - return TEST_FAILED; \ - } \ -} while (0) - -#define TEST_ASSERT_FAIL(val, msg, ...) do { \ - if (!(val != 0)) { \ - 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_NULL(val, msg, ...) do { \ - if (!(val == NULL)) { \ - 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_NULL(val, msg, ...) do { \ - if (!(val != NULL)) { \ - printf("TestCase %s() line %d failed: " \ - msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ - TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ - return TEST_FAILED; \ - } \ -} while (0) - -struct unit_test_case { - int (*setup)(void); - void (*teardown)(void); - int (*testcase)(void); - const char *success_msg; - const char *fail_msg; - unsigned enabled; -}; - -#define TEST_CASE(fn) { NULL, NULL, fn, #fn " succeeded", #fn " failed", 1 } - -#define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, name " succeeded", \ - name " failed", 1 } - -#define TEST_CASE_ST(setup, teardown, testcase) \ - { setup, teardown, testcase, #testcase " succeeded", \ - #testcase " failed ", 1 } - - -#define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, #fn " succeeded", \ - #fn " failed", 0 } - -#define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \ - { setup, teardown, testcase, #testcase " succeeded", \ - #testcase " failed ", 0 } - -#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); - void (*teardown)(void); - struct unit_test_case unit_test_cases[]; -}; - -int unit_test_suite_runner(struct unit_test_suite *suite); - -#define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE" - -#include -#include - -extern const char *prgname; - -int commands_init(void); - -int test_pci(void); -int test_pci_run; - -int test_mp_secondary(void); - -int test_set_rxtx_conf(cmdline_fixed_string_t mode); -int test_set_rxtx_anchor(cmdline_fixed_string_t type); -int test_set_rxtx_sc(cmdline_fixed_string_t type); - -typedef int (test_callback)(void); -TAILQ_HEAD(test_commands_list, test_command); -struct test_command { - TAILQ_ENTRY(test_command) next; - const char *command; - test_callback *callback; -}; - -void add_test_command(struct test_command *t); - -/* Register a test function with its command string */ -#define REGISTER_TEST_COMMAND(cmd, func) \ - static struct test_command test_struct_##cmd = { \ - .command = RTE_STR(cmd), \ - .callback = func, \ - }; \ - static void __attribute__((constructor, used)) \ - test_register_##cmd(void) \ - { \ - add_test_command(&test_struct_##cmd); \ - } - -#endif diff --git a/app/test/test_acl.c b/app/test/test_acl.c deleted file mode 100644 index c6b511fb19..0000000000 --- a/app/test/test_acl.c +++ /dev/null @@ -1,1652 +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 -#include - -#include "test.h" - -#include -#include -#include -#include -#include -#include - -#include "test_acl.h" - -#define BIT_SIZEOF(x) (sizeof(x) * CHAR_BIT) - -#define LEN RTE_ACL_MAX_CATEGORIES - -RTE_ACL_RULE_DEF(acl_ipv4vlan_rule, RTE_ACL_IPV4VLAN_NUM_FIELDS); - -struct rte_acl_param acl_param = { - .name = "acl_ctx", - .socket_id = SOCKET_ID_ANY, - .rule_size = RTE_ACL_IPV4VLAN_RULE_SZ, - .max_rule_num = 0x30000, -}; - -struct rte_acl_ipv4vlan_rule acl_rule = { - .data = { .priority = 1, .category_mask = 0xff }, - .src_port_low = 0, - .src_port_high = UINT16_MAX, - .dst_port_low = 0, - .dst_port_high = UINT16_MAX, -}; - -const uint32_t ipv4_7tuple_layout[RTE_ACL_IPV4VLAN_NUM] = { - offsetof(struct ipv4_7tuple, proto), - offsetof(struct ipv4_7tuple, vlan), - offsetof(struct ipv4_7tuple, ip_src), - offsetof(struct ipv4_7tuple, ip_dst), - offsetof(struct ipv4_7tuple, port_src), -}; - - -/* byteswap to cpu or network order */ -static void -bswap_test_data(struct ipv4_7tuple *data, int len, int to_be) -{ - int i; - - for (i = 0; i < len; i++) { - - if (to_be) { - /* swap all bytes so that they are in network order */ - data[i].ip_dst = rte_cpu_to_be_32(data[i].ip_dst); - data[i].ip_src = rte_cpu_to_be_32(data[i].ip_src); - data[i].port_dst = rte_cpu_to_be_16(data[i].port_dst); - data[i].port_src = rte_cpu_to_be_16(data[i].port_src); - data[i].vlan = rte_cpu_to_be_16(data[i].vlan); - data[i].domain = rte_cpu_to_be_16(data[i].domain); - } else { - data[i].ip_dst = rte_be_to_cpu_32(data[i].ip_dst); - data[i].ip_src = rte_be_to_cpu_32(data[i].ip_src); - data[i].port_dst = rte_be_to_cpu_16(data[i].port_dst); - data[i].port_src = rte_be_to_cpu_16(data[i].port_src); - data[i].vlan = rte_be_to_cpu_16(data[i].vlan); - data[i].domain = rte_be_to_cpu_16(data[i].domain); - } - } -} - -static int -acl_ipv4vlan_check_rule(const struct rte_acl_ipv4vlan_rule *rule) -{ - if (rule->src_port_low > rule->src_port_high || - rule->dst_port_low > rule->dst_port_high || - rule->src_mask_len > BIT_SIZEOF(rule->src_addr) || - rule->dst_mask_len > BIT_SIZEOF(rule->dst_addr)) - return -EINVAL; - return 0; -} - -static void -acl_ipv4vlan_convert_rule(const struct rte_acl_ipv4vlan_rule *ri, - struct acl_ipv4vlan_rule *ro) -{ - ro->data = ri->data; - - ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto; - ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan; - ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain; - ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr; - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr; - ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low; - ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low; - - ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask; - ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask; - ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 = - ri->domain_mask; - ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = - ri->src_mask_len; - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len; - ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 = - ri->src_port_high; - ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 = - ri->dst_port_high; -} - -/* - * Add ipv4vlan rules to an existing ACL context. - * This function is not multi-thread safe. - * - * @param ctx - * ACL context to add patterns to. - * @param rules - * Array of rules to add to the ACL context. - * Note that all fields in rte_acl_ipv4vlan_rule structures are expected - * to be in host byte order. - * @param num - * Number of elements in the input array of rules. - * @return - * - -ENOMEM if there is no space in the ACL context for these rules. - * - -EINVAL if the parameters are invalid. - * - Zero if operation completed successfully. - */ -static int -rte_acl_ipv4vlan_add_rules(struct rte_acl_ctx *ctx, - const struct rte_acl_ipv4vlan_rule *rules, - uint32_t num) -{ - int32_t rc; - uint32_t i; - struct acl_ipv4vlan_rule rv; - - if (ctx == NULL || rules == NULL) - return -EINVAL; - - /* check input rules. */ - for (i = 0; i != num; i++) { - rc = acl_ipv4vlan_check_rule(rules + i); - if (rc != 0) { - RTE_LOG(ERR, ACL, "%s: rule #%u is invalid\n", - __func__, i + 1); - return rc; - } - } - - /* perform conversion to the internal format and add to the context. */ - for (i = 0, rc = 0; i != num && rc == 0; i++) { - acl_ipv4vlan_convert_rule(rules + i, &rv); - rc = rte_acl_add_rules(ctx, (struct rte_acl_rule *)&rv, 1); - } - - return rc; -} - -static void -acl_ipv4vlan_config(struct rte_acl_config *cfg, - const uint32_t layout[RTE_ACL_IPV4VLAN_NUM], - uint32_t num_categories) -{ - static const struct rte_acl_field_def - ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = { - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD, - .input_index = RTE_ACL_IPV4VLAN_PROTO, - }, - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD, - .input_index = RTE_ACL_IPV4VLAN_VLAN, - }, - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD, - .input_index = RTE_ACL_IPV4VLAN_VLAN, - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD, - .input_index = RTE_ACL_IPV4VLAN_SRC, - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = RTE_ACL_IPV4VLAN_DST_FIELD, - .input_index = RTE_ACL_IPV4VLAN_DST, - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD, - .input_index = RTE_ACL_IPV4VLAN_PORTS, - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD, - .input_index = RTE_ACL_IPV4VLAN_PORTS, - }, - }; - - memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs)); - cfg->num_fields = RTE_DIM(ipv4_defs); - - cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_PROTO]; - cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_VLAN]; - cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_VLAN] + - cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size; - cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_SRC]; - cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_DST]; - cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_PORTS]; - cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_PORTS] + - cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size; - - cfg->num_categories = num_categories; -} - -/* - * Analyze set of ipv4vlan rules and build required internal - * run-time structures. - * This function is not multi-thread safe. - * - * @param ctx - * ACL context to build. - * @param layout - * Layout of input data to search through. - * @param num_categories - * Maximum number of categories to use in that build. - * @return - * - -ENOMEM if couldn't allocate enough memory. - * - -EINVAL if the parameters are invalid. - * - Negative error code if operation failed. - * - Zero if operation completed successfully. - */ -static int -rte_acl_ipv4vlan_build(struct rte_acl_ctx *ctx, - const uint32_t layout[RTE_ACL_IPV4VLAN_NUM], - uint32_t num_categories) -{ - struct rte_acl_config cfg; - - if (ctx == NULL || layout == NULL) - return -EINVAL; - - memset(&cfg, 0, sizeof(cfg)); - acl_ipv4vlan_config(&cfg, layout, num_categories); - return rte_acl_build(ctx, &cfg); -} - -/* - * Test scalar and SSE ACL lookup. - */ -static int -test_classify_run(struct rte_acl_ctx *acx) -{ - int ret, i; - uint32_t result, count; - uint32_t results[RTE_DIM(acl_test_data) * RTE_ACL_MAX_CATEGORIES]; - const uint8_t *data[RTE_DIM(acl_test_data)]; - - /* swap all bytes in the data to network order */ - bswap_test_data(acl_test_data, RTE_DIM(acl_test_data), 1); - - /* store pointers to test data */ - for (i = 0; i < (int) RTE_DIM(acl_test_data); i++) - data[i] = (uint8_t *)&acl_test_data[i]; - - /** - * these will run quite a few times, it's necessary to test code paths - * from num=0 to num>8 - */ - for (count = 0; count <= RTE_DIM(acl_test_data); count++) { - ret = rte_acl_classify(acx, data, results, - count, RTE_ACL_MAX_CATEGORIES); - if (ret != 0) { - printf("Line %i: SSE classify failed!\n", __LINE__); - goto err; - } - - /* check if we allow everything we should allow */ - for (i = 0; i < (int) count; i++) { - result = - results[i * RTE_ACL_MAX_CATEGORIES + ACL_ALLOW]; - if (result != acl_test_data[i].allow) { - printf("Line %i: Error in allow results at %i " - "(expected %"PRIu32" got %"PRIu32")!\n", - __LINE__, i, acl_test_data[i].allow, - result); - ret = -EINVAL; - goto err; - } - } - - /* check if we deny everything we should deny */ - for (i = 0; i < (int) count; i++) { - result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_DENY]; - if (result != acl_test_data[i].deny) { - printf("Line %i: Error in deny results at %i " - "(expected %"PRIu32" got %"PRIu32")!\n", - __LINE__, i, acl_test_data[i].deny, - result); - ret = -EINVAL; - goto err; - } - } - } - - /* make a quick check for scalar */ - ret = rte_acl_classify_alg(acx, data, results, - RTE_DIM(acl_test_data), RTE_ACL_MAX_CATEGORIES, - RTE_ACL_CLASSIFY_SCALAR); - if (ret != 0) { - printf("Line %i: scalar classify failed!\n", __LINE__); - goto err; - } - - /* check if we allow everything we should allow */ - for (i = 0; i < (int) RTE_DIM(acl_test_data); i++) { - result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_ALLOW]; - if (result != acl_test_data[i].allow) { - printf("Line %i: Error in allow results at %i " - "(expected %"PRIu32" got %"PRIu32")!\n", - __LINE__, i, acl_test_data[i].allow, - result); - ret = -EINVAL; - goto err; - } - } - - /* check if we deny everything we should deny */ - for (i = 0; i < (int) RTE_DIM(acl_test_data); i++) { - result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_DENY]; - if (result != acl_test_data[i].deny) { - printf("Line %i: Error in deny results at %i " - "(expected %"PRIu32" got %"PRIu32")!\n", - __LINE__, i, acl_test_data[i].deny, - result); - ret = -EINVAL; - goto err; - } - } - - ret = 0; - -err: - /* swap data back to cpu order so that next time tests don't fail */ - bswap_test_data(acl_test_data, RTE_DIM(acl_test_data), 0); - return ret; -} - -static int -test_classify_buid(struct rte_acl_ctx *acx, - const struct rte_acl_ipv4vlan_rule *rules, uint32_t num) -{ - int ret; - - /* add rules to the context */ - ret = rte_acl_ipv4vlan_add_rules(acx, rules, num); - if (ret != 0) { - printf("Line %i: Adding rules to ACL context failed!\n", - __LINE__); - return ret; - } - - /* try building the context */ - ret = rte_acl_ipv4vlan_build(acx, ipv4_7tuple_layout, - RTE_ACL_MAX_CATEGORIES); - if (ret != 0) { - printf("Line %i: Building ACL context failed!\n", __LINE__); - return ret; - } - - return 0; -} - -#define TEST_CLASSIFY_ITER 4 - -/* - * Test scalar and SSE ACL lookup. - */ -static int -test_classify(void) -{ - struct rte_acl_ctx *acx; - int i, ret; - - acx = rte_acl_create(&acl_param); - if (acx == NULL) { - printf("Line %i: Error creating ACL context!\n", __LINE__); - return -1; - } - - ret = 0; - for (i = 0; i != TEST_CLASSIFY_ITER; i++) { - - if ((i & 1) == 0) - rte_acl_reset(acx); - else - rte_acl_reset_rules(acx); - - ret = test_classify_buid(acx, acl_test_rules, - RTE_DIM(acl_test_rules)); - if (ret != 0) { - printf("Line %i, iter: %d: " - "Adding rules to ACL context failed!\n", - __LINE__, i); - break; - } - - ret = test_classify_run(acx); - if (ret != 0) { - printf("Line %i, iter: %d: %s failed!\n", - __LINE__, i, __func__); - break; - } - - /* reset rules and make sure that classify still works ok. */ - rte_acl_reset_rules(acx); - ret = test_classify_run(acx); - if (ret != 0) { - printf("Line %i, iter: %d: %s failed!\n", - __LINE__, i, __func__); - break; - } - } - - rte_acl_free(acx); - return ret; -} - -static int -test_build_ports_range(void) -{ - static const struct rte_acl_ipv4vlan_rule test_rules[] = { - { - /* match all packets. */ - .data = { - .userdata = 1, - .category_mask = ACL_ALLOW_MASK, - .priority = 101, - }, - .src_port_low = 0, - .src_port_high = UINT16_MAX, - .dst_port_low = 0, - .dst_port_high = UINT16_MAX, - }, - { - /* match all packets with dst ports [54-65280]. */ - .data = { - .userdata = 2, - .category_mask = ACL_ALLOW_MASK, - .priority = 102, - }, - .src_port_low = 0, - .src_port_high = UINT16_MAX, - .dst_port_low = 54, - .dst_port_high = 65280, - }, - { - /* match all packets with dst ports [0-52]. */ - .data = { - .userdata = 3, - .category_mask = ACL_ALLOW_MASK, - .priority = 103, - }, - .src_port_low = 0, - .src_port_high = UINT16_MAX, - .dst_port_low = 0, - .dst_port_high = 52, - }, - { - /* match all packets with dst ports [53]. */ - .data = { - .userdata = 4, - .category_mask = ACL_ALLOW_MASK, - .priority = 99, - }, - .src_port_low = 0, - .src_port_high = UINT16_MAX, - .dst_port_low = 53, - .dst_port_high = 53, - }, - { - /* match all packets with dst ports [65279-65535]. */ - .data = { - .userdata = 5, - .category_mask = ACL_ALLOW_MASK, - .priority = 98, - }, - .src_port_low = 0, - .src_port_high = UINT16_MAX, - .dst_port_low = 65279, - .dst_port_high = UINT16_MAX, - }, - }; - - static struct ipv4_7tuple test_data[] = { - { - .proto = 6, - .ip_src = IPv4(10, 1, 1, 1), - .ip_dst = IPv4(192, 168, 0, 33), - .port_dst = 53, - .allow = 1, - }, - { - .proto = 6, - .ip_src = IPv4(127, 84, 33, 1), - .ip_dst = IPv4(1, 2, 3, 4), - .port_dst = 65281, - .allow = 1, - }, - }; - - struct rte_acl_ctx *acx; - int32_t ret, i, j; - uint32_t results[RTE_DIM(test_data)]; - const uint8_t *data[RTE_DIM(test_data)]; - - acx = rte_acl_create(&acl_param); - if (acx == NULL) { - printf("Line %i: Error creating ACL context!\n", __LINE__); - return -1; - } - - /* swap all bytes in the data to network order */ - bswap_test_data(test_data, RTE_DIM(test_data), 1); - - /* store pointers to test data */ - for (i = 0; i != RTE_DIM(test_data); i++) - data[i] = (uint8_t *)&test_data[i]; - - for (i = 0; i != RTE_DIM(test_rules); i++) { - rte_acl_reset(acx); - ret = test_classify_buid(acx, test_rules, i + 1); - if (ret != 0) { - printf("Line %i, iter: %d: " - "Adding rules to ACL context failed!\n", - __LINE__, i); - break; - } - ret = rte_acl_classify(acx, data, results, - RTE_DIM(data), 1); - if (ret != 0) { - printf("Line %i, iter: %d: classify failed!\n", - __LINE__, i); - break; - } - - /* check results */ - for (j = 0; j != RTE_DIM(results); j++) { - if (results[j] != test_data[j].allow) { - printf("Line %i: Error in allow results at %i " - "(expected %"PRIu32" got %"PRIu32")!\n", - __LINE__, j, test_data[j].allow, - results[j]); - ret = -EINVAL; - } - } - } - - bswap_test_data(test_data, RTE_DIM(test_data), 0); - - rte_acl_free(acx); - return ret; -} - -static void -convert_rule(const struct rte_acl_ipv4vlan_rule *ri, - struct acl_ipv4vlan_rule *ro) -{ - ro->data = ri->data; - - ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto; - ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan; - ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain; - ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr; - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr; - ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low; - ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low; - - ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask; - ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask; - ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 = - ri->domain_mask; - ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = - ri->src_mask_len; - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len; - ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 = - ri->src_port_high; - ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 = - ri->dst_port_high; -} - -/* - * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to - * RTE_ACL_FIELD_TYPE_BITMASK. - */ -static void -convert_rule_1(const struct rte_acl_ipv4vlan_rule *ri, - struct acl_ipv4vlan_rule *ro) -{ - uint32_t v; - - convert_rule(ri, ro); - v = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32; - ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = - RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v)); - v = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32; - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = - RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v)); -} - -/* - * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to - * RTE_ACL_FIELD_TYPE_RANGE. - */ -static void -convert_rule_2(const struct rte_acl_ipv4vlan_rule *ri, - struct acl_ipv4vlan_rule *ro) -{ - uint32_t hi, lo, mask; - - convert_rule(ri, ro); - - mask = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32; - mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask)); - lo = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 & mask; - hi = lo + ~mask; - ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = lo; - ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = hi; - - mask = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32; - mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask)); - lo = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 & mask; - hi = lo + ~mask; - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = lo; - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = hi; -} - -/* - * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields. - */ -static void -convert_rule_3(const struct rte_acl_ipv4vlan_rule *ri, - struct acl_ipv4vlan_rule *ro) -{ - struct rte_acl_field t1, t2; - - convert_rule(ri, ro); - - t1 = ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD]; - t2 = ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD]; - - ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD] = - ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD]; - ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD] = - ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD]; - - ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD] = t1; - ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD] = t2; -} - -/* - * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules. - */ -static void -convert_rule_4(const struct rte_acl_ipv4vlan_rule *ri, - struct acl_ipv4vlan_rule *ro) -{ - struct rte_acl_field t; - - convert_rule(ri, ro); - - t = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD]; - ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD] = - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD]; - - ro->field[RTE_ACL_IPV4VLAN_DST_FIELD] = t; -} - -static void -ipv4vlan_config(struct rte_acl_config *cfg, - const uint32_t layout[RTE_ACL_IPV4VLAN_NUM], - uint32_t num_categories) -{ - static const struct rte_acl_field_def - ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = { - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD, - .input_index = RTE_ACL_IPV4VLAN_PROTO, - }, - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD, - .input_index = RTE_ACL_IPV4VLAN_VLAN, - }, - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD, - .input_index = RTE_ACL_IPV4VLAN_VLAN, - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD, - .input_index = RTE_ACL_IPV4VLAN_SRC, - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = RTE_ACL_IPV4VLAN_DST_FIELD, - .input_index = RTE_ACL_IPV4VLAN_DST, - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD, - .input_index = RTE_ACL_IPV4VLAN_PORTS, - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD, - .input_index = RTE_ACL_IPV4VLAN_PORTS, - }, - }; - - memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs)); - cfg->num_fields = RTE_DIM(ipv4_defs); - - cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_PROTO]; - cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_VLAN]; - cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_VLAN] + - cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size; - cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_SRC]; - cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_DST]; - cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_PORTS]; - cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = - layout[RTE_ACL_IPV4VLAN_PORTS] + - cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size; - - cfg->num_categories = num_categories; -} - -static int -convert_rules(struct rte_acl_ctx *acx, - void (*convert)(const struct rte_acl_ipv4vlan_rule *, - struct acl_ipv4vlan_rule *), - const struct rte_acl_ipv4vlan_rule *rules, uint32_t num) -{ - int32_t rc; - uint32_t i; - struct acl_ipv4vlan_rule r; - - for (i = 0; i != num; i++) { - convert(rules + i, &r); - rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1); - if (rc != 0) { - printf("Line %i: Adding rule %u to ACL context " - "failed with error code: %d\n", - __LINE__, i, rc); - return rc; - } - } - - return 0; -} - -static void -convert_config(struct rte_acl_config *cfg) -{ - ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); -} - -/* - * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK. - */ -static void -convert_config_1(struct rte_acl_config *cfg) -{ - ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); - cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK; - cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK; -} - -/* - * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE. - */ -static void -convert_config_2(struct rte_acl_config *cfg) -{ - ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); - cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE; - cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE; -} - -/* - * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions. - */ -static void -convert_config_3(struct rte_acl_config *cfg) -{ - struct rte_acl_field_def t1, t2; - - ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); - - t1 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD]; - t2 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD]; - - /* swap VLAN1 and SRCP rule definition. */ - cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD] = - cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD]; - cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].field_index = t1.field_index; - cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].input_index = t1.input_index; - - /* swap VLAN2 and DSTP rule definition. */ - cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD] = - cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD]; - cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].field_index = t2.field_index; - cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].input_index = t2.input_index; - - cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].type = t1.type; - cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size = t1.size; - cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = t1.offset; - - cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].type = t2.type; - cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].size = t2.size; - cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = t2.offset; -} - -/* - * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions. - */ -static void -convert_config_4(struct rte_acl_config *cfg) -{ - struct rte_acl_field_def t; - - ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); - - t = cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD]; - - cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD] = - cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD]; - cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].field_index = t.field_index; - cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].input_index = t.input_index; - - cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = t.type; - cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].size = t.size; - cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = t.offset; -} - - -static int -build_convert_rules(struct rte_acl_ctx *acx, - void (*config)(struct rte_acl_config *), - size_t max_size) -{ - struct rte_acl_config cfg; - - memset(&cfg, 0, sizeof(cfg)); - config(&cfg); - cfg.max_size = max_size; - return rte_acl_build(acx, &cfg); -} - -static int -test_convert_rules(const char *desc, - void (*config)(struct rte_acl_config *), - void (*convert)(const struct rte_acl_ipv4vlan_rule *, - struct acl_ipv4vlan_rule *)) -{ - struct rte_acl_ctx *acx; - int32_t rc; - uint32_t i; - static const size_t mem_sizes[] = {0, -1}; - - printf("running %s(%s)\n", __func__, desc); - - acx = rte_acl_create(&acl_param); - if (acx == NULL) { - printf("Line %i: Error creating ACL context!\n", __LINE__); - return -1; - } - - rc = convert_rules(acx, convert, acl_test_rules, - RTE_DIM(acl_test_rules)); - if (rc != 0) - printf("Line %i: Error converting ACL rules!\n", __LINE__); - - for (i = 0; rc == 0 && i != RTE_DIM(mem_sizes); i++) { - - rc = build_convert_rules(acx, config, mem_sizes[i]); - if (rc != 0) { - printf("Line %i: Error @ build_convert_rules(%zu)!\n", - __LINE__, mem_sizes[i]); - break; - } - - rc = test_classify_run(acx); - if (rc != 0) - printf("%s failed at line %i, max_size=%zu\n", - __func__, __LINE__, mem_sizes[i]); - } - - rte_acl_free(acx); - return rc; -} - -static int -test_convert(void) -{ - static const struct { - const char *desc; - void (*config)(struct rte_acl_config *); - void (*convert)(const struct rte_acl_ipv4vlan_rule *, - struct acl_ipv4vlan_rule *); - } convert_param[] = { - { - "acl_ipv4vlan_tuple", - convert_config, - convert_rule, - }, - { - "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type " - "for IPv4", - convert_config_1, - convert_rule_1, - }, - { - "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type " - "for IPv4", - convert_config_2, - convert_rule_2, - }, - { - "acl_ipv4vlan_tuple: swap VLAN and PORTs order", - convert_config_3, - convert_rule_3, - }, - { - "acl_ipv4vlan_tuple: swap SRC and DST IPv4 order", - convert_config_4, - convert_rule_4, - }, - }; - - uint32_t i; - int32_t rc; - - for (i = 0; i != RTE_DIM(convert_param); i++) { - rc = test_convert_rules(convert_param[i].desc, - convert_param[i].config, - convert_param[i].convert); - if (rc != 0) { - printf("%s for test-case: %s failed, error code: %d;\n", - __func__, convert_param[i].desc, rc); - return rc; - } - } - - return 0; -} - -/* - * Test wrong layout behavior - * This test supplies the ACL context with invalid layout, which results in - * ACL matching the wrong stuff. However, it should match the wrong stuff - * the right way. We switch around source and destination addresses, - * source and destination ports, and protocol will point to first byte of - * destination port. - */ -static int -test_invalid_layout(void) -{ - struct rte_acl_ctx *acx; - int ret, i; - - uint32_t results[RTE_DIM(invalid_layout_data)]; - const uint8_t *data[RTE_DIM(invalid_layout_data)]; - - const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = { - /* proto points to destination port's first byte */ - offsetof(struct ipv4_7tuple, port_dst), - - 0, /* VLAN not used */ - - /* src and dst addresses are swapped */ - offsetof(struct ipv4_7tuple, ip_dst), - offsetof(struct ipv4_7tuple, ip_src), - - /* - * we can't swap ports here, so we will swap - * them in the data - */ - offsetof(struct ipv4_7tuple, port_src), - }; - - acx = rte_acl_create(&acl_param); - if (acx == NULL) { - printf("Line %i: Error creating ACL context!\n", __LINE__); - return -1; - } - - /* putting a lot of rules into the context results in greater - * coverage numbers. it doesn't matter if they are identical */ - for (i = 0; i < 1000; i++) { - /* add rules to the context */ - ret = rte_acl_ipv4vlan_add_rules(acx, invalid_layout_rules, - RTE_DIM(invalid_layout_rules)); - if (ret != 0) { - printf("Line %i: Adding rules to ACL context failed!\n", - __LINE__); - rte_acl_free(acx); - return -1; - } - } - - /* try building the context */ - ret = rte_acl_ipv4vlan_build(acx, layout, 1); - if (ret != 0) { - printf("Line %i: Building ACL context failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* swap all bytes in the data to network order */ - bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 1); - - /* prepare data */ - for (i = 0; i < (int) RTE_DIM(invalid_layout_data); i++) { - data[i] = (uint8_t *)&invalid_layout_data[i]; - } - - /* classify tuples */ - ret = rte_acl_classify_alg(acx, data, results, - RTE_DIM(results), 1, RTE_ACL_CLASSIFY_SCALAR); - if (ret != 0) { - printf("Line %i: SSE classify failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - for (i = 0; i < (int) RTE_DIM(results); i++) { - if (results[i] != invalid_layout_data[i].allow) { - printf("Line %i: Wrong results at %i " - "(result=%u, should be %u)!\n", - __LINE__, i, results[i], - invalid_layout_data[i].allow); - goto err; - } - } - - /* classify tuples (scalar) */ - ret = rte_acl_classify_alg(acx, data, results, RTE_DIM(results), 1, - RTE_ACL_CLASSIFY_SCALAR); - - if (ret != 0) { - printf("Line %i: Scalar classify failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - for (i = 0; i < (int) RTE_DIM(results); i++) { - if (results[i] != invalid_layout_data[i].allow) { - printf("Line %i: Wrong results at %i " - "(result=%u, should be %u)!\n", - __LINE__, i, results[i], - invalid_layout_data[i].allow); - goto err; - } - } - - rte_acl_free(acx); - - /* swap data back to cpu order so that next time tests don't fail */ - bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0); - - return 0; -err: - - /* swap data back to cpu order so that next time tests don't fail */ - bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0); - - rte_acl_free(acx); - - return -1; -} - -/* - * Test creating and finding ACL contexts, and adding rules - */ -static int -test_create_find_add(void) -{ - struct rte_acl_param param; - struct rte_acl_ctx *acx, *acx2, *tmp; - struct rte_acl_ipv4vlan_rule rules[LEN]; - - const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0}; - - const char *acx_name = "acx"; - const char *acx2_name = "acx2"; - int i, ret; - - /* create two contexts */ - memcpy(¶m, &acl_param, sizeof(param)); - param.max_rule_num = 2; - - param.name = acx_name; - acx = rte_acl_create(¶m); - if (acx == NULL) { - printf("Line %i: Error creating %s!\n", __LINE__, acx_name); - return -1; - } - - param.name = acx2_name; - acx2 = rte_acl_create(¶m); - if (acx2 == NULL || acx2 == acx) { - printf("Line %i: Error creating %s!\n", __LINE__, acx2_name); - rte_acl_free(acx); - return -1; - } - - /* try to create third one, with an existing name */ - param.name = acx_name; - tmp = rte_acl_create(¶m); - if (tmp != acx) { - printf("Line %i: Creating context with existing name " - "test failed!\n", - __LINE__); - if (tmp) - rte_acl_free(tmp); - goto err; - } - - param.name = acx2_name; - tmp = rte_acl_create(¶m); - if (tmp != acx2) { - printf("Line %i: Creating context with existing " - "name test 2 failed!\n", - __LINE__); - if (tmp) - rte_acl_free(tmp); - goto err; - } - - /* try to find existing ACL contexts */ - tmp = rte_acl_find_existing(acx_name); - if (tmp != acx) { - printf("Line %i: Finding %s failed!\n", __LINE__, acx_name); - if (tmp) - rte_acl_free(tmp); - goto err; - } - - tmp = rte_acl_find_existing(acx2_name); - if (tmp != acx2) { - printf("Line %i: Finding %s failed!\n", __LINE__, acx2_name); - if (tmp) - rte_acl_free(tmp); - goto err; - } - - /* try to find non-existing context */ - tmp = rte_acl_find_existing("invalid"); - if (tmp != NULL) { - printf("Line %i: Non-existent ACL context found!\n", __LINE__); - goto err; - } - - /* free context */ - rte_acl_free(acx); - - - /* create valid (but severely limited) acx */ - memcpy(¶m, &acl_param, sizeof(param)); - param.max_rule_num = LEN; - - acx = rte_acl_create(¶m); - if (acx == NULL) { - printf("Line %i: Error creating %s!\n", __LINE__, param.name); - goto err; - } - - /* create dummy acl */ - for (i = 0; i < LEN; i++) { - memcpy(&rules[i], &acl_rule, - sizeof(struct rte_acl_ipv4vlan_rule)); - /* skip zero */ - rules[i].data.userdata = i + 1; - /* one rule per category */ - rules[i].data.category_mask = 1 << i; - } - - /* try filling up the context */ - ret = rte_acl_ipv4vlan_add_rules(acx, rules, LEN); - if (ret != 0) { - printf("Line %i: Adding %i rules to ACL context failed!\n", - __LINE__, LEN); - goto err; - } - - /* try adding to a (supposedly) full context */ - ret = rte_acl_ipv4vlan_add_rules(acx, rules, 1); - if (ret == 0) { - printf("Line %i: Adding rules to full ACL context should" - "have failed!\n", __LINE__); - goto err; - } - - /* try building the context */ - ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES); - if (ret != 0) { - printf("Line %i: Building ACL context failed!\n", __LINE__); - goto err; - } - - rte_acl_free(acx); - rte_acl_free(acx2); - - return 0; -err: - rte_acl_free(acx); - rte_acl_free(acx2); - return -1; -} - -/* - * test various invalid rules - */ -static int -test_invalid_rules(void) -{ - struct rte_acl_ctx *acx; - int ret; - - struct rte_acl_ipv4vlan_rule rule; - - acx = rte_acl_create(&acl_param); - if (acx == NULL) { - printf("Line %i: Error creating ACL context!\n", __LINE__); - return -1; - } - - /* test inverted high/low source and destination ports. - * originally, there was a problem with memory consumption when using - * such rules. - */ - /* create dummy acl */ - memcpy(&rule, &acl_rule, sizeof(struct rte_acl_ipv4vlan_rule)); - rule.data.userdata = 1; - rule.dst_port_low = 0xfff0; - rule.dst_port_high = 0x0010; - - /* add rules to context and try to build it */ - ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1); - if (ret == 0) { - printf("Line %i: Adding rules to ACL context " - "should have failed!\n", __LINE__); - goto err; - } - - rule.dst_port_low = 0x0; - rule.dst_port_high = 0xffff; - rule.src_port_low = 0xfff0; - rule.src_port_high = 0x0010; - - /* add rules to context and try to build it */ - ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1); - if (ret == 0) { - printf("Line %i: Adding rules to ACL context " - "should have failed!\n", __LINE__); - goto err; - } - - rule.dst_port_low = 0x0; - rule.dst_port_high = 0xffff; - rule.src_port_low = 0x0; - rule.src_port_high = 0xffff; - - rule.dst_mask_len = 33; - - /* add rules to context and try to build it */ - ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1); - if (ret == 0) { - printf("Line %i: Adding rules to ACL context " - "should have failed!\n", __LINE__); - goto err; - } - - rule.dst_mask_len = 0; - rule.src_mask_len = 33; - - /* add rules to context and try to build it */ - ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1); - if (ret == 0) { - printf("Line %i: Adding rules to ACL context " - "should have failed!\n", __LINE__); - goto err; - } - - rte_acl_free(acx); - - return 0; - -err: - rte_acl_free(acx); - - return -1; -} - -/* - * test functions by passing invalid or - * non-workable parameters. - * - * we do very limited testing of classify functions here - * because those are performance-critical and - * thus don't do much parameter checking. - */ -static int -test_invalid_parameters(void) -{ - struct rte_acl_param param; - struct rte_acl_ctx *acx; - struct rte_acl_ipv4vlan_rule rule; - int result; - - uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0}; - - - /** - * rte_ac_create() - */ - - /* NULL param */ - acx = rte_acl_create(NULL); - if (acx != NULL) { - printf("Line %i: ACL context creation with NULL param " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* zero rule size */ - memcpy(¶m, &acl_param, sizeof(param)); - param.rule_size = 0; - - acx = rte_acl_create(¶m); - if (acx == NULL) { - printf("Line %i: ACL context creation with zero rule len " - "failed!\n", __LINE__); - return -1; - } else - rte_acl_free(acx); - - /* zero max rule num */ - memcpy(¶m, &acl_param, sizeof(param)); - param.max_rule_num = 0; - - acx = rte_acl_create(¶m); - if (acx == NULL) { - printf("Line %i: ACL context creation with zero rule num " - "failed!\n", __LINE__); - return -1; - } else - rte_acl_free(acx); - - /* invalid NUMA node */ - memcpy(¶m, &acl_param, sizeof(param)); - param.socket_id = RTE_MAX_NUMA_NODES + 1; - - acx = rte_acl_create(¶m); - if (acx != NULL) { - printf("Line %i: ACL context creation with invalid NUMA " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* NULL name */ - memcpy(¶m, &acl_param, sizeof(param)); - param.name = NULL; - - acx = rte_acl_create(¶m); - if (acx != NULL) { - printf("Line %i: ACL context creation with NULL name " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /** - * rte_acl_find_existing - */ - - acx = rte_acl_find_existing(NULL); - if (acx != NULL) { - printf("Line %i: NULL ACL context found!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /** - * rte_acl_ipv4vlan_add_rules - */ - - /* initialize everything */ - memcpy(¶m, &acl_param, sizeof(param)); - acx = rte_acl_create(¶m); - if (acx == NULL) { - printf("Line %i: ACL context creation failed!\n", __LINE__); - return -1; - } - - memcpy(&rule, &acl_rule, sizeof(rule)); - - /* NULL context */ - result = rte_acl_ipv4vlan_add_rules(NULL, &rule, 1); - if (result == 0) { - printf("Line %i: Adding rules with NULL ACL context " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* NULL rule */ - result = rte_acl_ipv4vlan_add_rules(acx, NULL, 1); - if (result == 0) { - printf("Line %i: Adding NULL rule to ACL context " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* zero count (should succeed) */ - result = rte_acl_ipv4vlan_add_rules(acx, &rule, 0); - if (result != 0) { - printf("Line %i: Adding 0 rules to ACL context failed!\n", - __LINE__); - rte_acl_free(acx); - return -1; - } - - /* free ACL context */ - rte_acl_free(acx); - - - /** - * rte_acl_ipv4vlan_build - */ - - /* reinitialize context */ - memcpy(¶m, &acl_param, sizeof(param)); - acx = rte_acl_create(¶m); - if (acx == NULL) { - printf("Line %i: ACL context creation failed!\n", __LINE__); - return -1; - } - - /* NULL context */ - result = rte_acl_ipv4vlan_build(NULL, layout, 1); - if (result == 0) { - printf("Line %i: Building with NULL context " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* NULL layout */ - result = rte_acl_ipv4vlan_build(acx, NULL, 1); - if (result == 0) { - printf("Line %i: Building with NULL layout " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* zero categories (should not fail) */ - result = rte_acl_ipv4vlan_build(acx, layout, 0); - if (result == 0) { - printf("Line %i: Building with 0 categories should fail!\n", - __LINE__); - rte_acl_free(acx); - return -1; - } - - /* SSE classify test */ - - /* cover zero categories in classify (should not fail) */ - result = rte_acl_classify(acx, NULL, NULL, 0, 0); - if (result != 0) { - printf("Line %i: SSE classify with zero categories " - "failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* cover invalid but positive categories in classify */ - result = rte_acl_classify(acx, NULL, NULL, 0, 3); - if (result == 0) { - printf("Line %i: SSE classify with 3 categories " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* scalar classify test */ - - /* cover zero categories in classify (should not fail) */ - result = rte_acl_classify_alg(acx, NULL, NULL, 0, 0, - RTE_ACL_CLASSIFY_SCALAR); - if (result != 0) { - printf("Line %i: Scalar classify with zero categories " - "failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* cover invalid but positive categories in classify */ - result = rte_acl_classify(acx, NULL, NULL, 0, 3); - if (result == 0) { - printf("Line %i: Scalar classify with 3 categories " - "should have failed!\n", __LINE__); - rte_acl_free(acx); - return -1; - } - - /* free ACL context */ - rte_acl_free(acx); - - - /** - * make sure void functions don't crash with NULL parameters - */ - - rte_acl_free(NULL); - - rte_acl_dump(NULL); - - return 0; -} - -/** - * Various tests that don't test much but improve coverage - */ -static int -test_misc(void) -{ - struct rte_acl_param param; - struct rte_acl_ctx *acx; - - /* create context */ - memcpy(¶m, &acl_param, sizeof(param)); - - acx = rte_acl_create(¶m); - if (acx == NULL) { - printf("Line %i: Error creating ACL context!\n", __LINE__); - return -1; - } - - /* dump context with rules - useful for coverage */ - rte_acl_list_dump(); - - rte_acl_dump(acx); - - rte_acl_free(acx); - - return 0; -} - -static int -test_acl(void) -{ - if (test_invalid_parameters() < 0) - return -1; - if (test_invalid_rules() < 0) - return -1; - if (test_create_find_add() < 0) - return -1; - if (test_invalid_layout() < 0) - return -1; - if (test_misc() < 0) - return -1; - if (test_classify() < 0) - return -1; - if (test_build_ports_range() < 0) - return -1; - if (test_convert() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(acl_autotest, test_acl); diff --git a/app/test/test_acl.h b/app/test/test_acl.h deleted file mode 100644 index 421f3109b3..0000000000 --- a/app/test/test_acl.h +++ /dev/null @@ -1,692 +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 TEST_ACL_H_ -#define TEST_ACL_H_ - -struct ipv4_7tuple { - uint16_t vlan; - uint16_t domain; - uint8_t proto; - uint32_t ip_src; - uint32_t ip_dst; - uint16_t port_src; - uint16_t port_dst; - uint32_t allow; - uint32_t deny; -}; - -/** - * Legacy support for 7-tuple IPv4 and VLAN rule. - * This structure and corresponding API is deprecated. - */ -struct rte_acl_ipv4vlan_rule { - struct rte_acl_rule_data data; /**< Miscellaneous data for the rule. */ - uint8_t proto; /**< IPv4 protocol ID. */ - uint8_t proto_mask; /**< IPv4 protocol ID mask. */ - uint16_t vlan; /**< VLAN ID. */ - uint16_t vlan_mask; /**< VLAN ID mask. */ - uint16_t domain; /**< VLAN domain. */ - uint16_t domain_mask; /**< VLAN domain mask. */ - uint32_t src_addr; /**< IPv4 source address. */ - uint32_t src_mask_len; /**< IPv4 source address mask. */ - uint32_t dst_addr; /**< IPv4 destination address. */ - uint32_t dst_mask_len; /**< IPv4 destination address mask. */ - uint16_t src_port_low; /**< L4 source port low. */ - uint16_t src_port_high; /**< L4 source port high. */ - uint16_t dst_port_low; /**< L4 destination port low. */ - uint16_t dst_port_high; /**< L4 destination port high. */ -}; - -/** - * Specifies fields layout inside rte_acl_rule for rte_acl_ipv4vlan_rule. - */ -enum { - RTE_ACL_IPV4VLAN_PROTO_FIELD, - RTE_ACL_IPV4VLAN_VLAN1_FIELD, - RTE_ACL_IPV4VLAN_VLAN2_FIELD, - RTE_ACL_IPV4VLAN_SRC_FIELD, - RTE_ACL_IPV4VLAN_DST_FIELD, - RTE_ACL_IPV4VLAN_SRCP_FIELD, - RTE_ACL_IPV4VLAN_DSTP_FIELD, - RTE_ACL_IPV4VLAN_NUM_FIELDS -}; - -/** - * Macro to define rule size for rte_acl_ipv4vlan_rule. - */ -#define RTE_ACL_IPV4VLAN_RULE_SZ \ - RTE_ACL_RULE_SZ(RTE_ACL_IPV4VLAN_NUM_FIELDS) - -/* - * That effectively defines order of IPV4VLAN classifications: - * - PROTO - * - VLAN (TAG and DOMAIN) - * - SRC IP ADDRESS - * - DST IP ADDRESS - * - PORTS (SRC and DST) - */ -enum { - RTE_ACL_IPV4VLAN_PROTO, - RTE_ACL_IPV4VLAN_VLAN, - RTE_ACL_IPV4VLAN_SRC, - RTE_ACL_IPV4VLAN_DST, - RTE_ACL_IPV4VLAN_PORTS, - RTE_ACL_IPV4VLAN_NUM -}; - -/* rules for invalid layout test */ -struct rte_acl_ipv4vlan_rule invalid_layout_rules[] = { - /* test src and dst address */ - { - .data = {.userdata = 1, .category_mask = 1}, - .src_addr = IPv4(10,0,0,0), - .src_mask_len = 24, - }, - { - .data = {.userdata = 2, .category_mask = 1}, - .dst_addr = IPv4(10,0,0,0), - .dst_mask_len = 24, - }, - /* test src and dst ports */ - { - .data = {.userdata = 3, .category_mask = 1}, - .dst_port_low = 100, - .dst_port_high = 100, - }, - { - .data = {.userdata = 4, .category_mask = 1}, - .src_port_low = 100, - .src_port_high = 100, - }, - /* test proto */ - { - .data = {.userdata = 5, .category_mask = 1}, - .proto = 0xf, - .proto_mask = 0xf - }, - { - .data = {.userdata = 6, .category_mask = 1}, - .dst_port_low = 0xf, - .dst_port_high = 0xf, - } -}; - -/* these might look odd because they don't match up the rules. This is - * intentional, as the invalid layout test presumes returning the correct - * results using the wrong data layout. - */ -struct ipv4_7tuple invalid_layout_data[] = { - {.ip_src = IPv4(10,0,1,0)}, /* should not match */ - {.ip_src = IPv4(10,0,0,1), .allow = 2}, /* should match 2 */ - {.port_src = 100, .allow = 4}, /* should match 4 */ - {.port_dst = 0xf, .allow = 6}, /* should match 6 */ -}; - -#define ACL_ALLOW 0 -#define ACL_DENY 1 -#define ACL_ALLOW_MASK 0x1 -#define ACL_DENY_MASK 0x2 - -/* ruleset for ACL unit test */ -struct rte_acl_ipv4vlan_rule acl_test_rules[] = { -/* destination IP addresses */ - /* matches all packets traveling to 192.168.0.0/16 */ - { - .data = {.userdata = 1, .category_mask = ACL_ALLOW_MASK, - .priority = 230}, - .dst_addr = IPv4(192,168,0,0), - .dst_mask_len = 16, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets traveling to 192.168.1.0/24 */ - { - .data = {.userdata = 2, .category_mask = ACL_ALLOW_MASK, - .priority = 330}, - .dst_addr = IPv4(192,168,1,0), - .dst_mask_len = 24, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets traveling to 192.168.1.50 */ - { - .data = {.userdata = 3, .category_mask = ACL_DENY_MASK, - .priority = 230}, - .dst_addr = IPv4(192,168,1,50), - .dst_mask_len = 32, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - -/* source IP addresses */ - /* matches all packets traveling from 10.0.0.0/8 */ - { - .data = {.userdata = 4, .category_mask = ACL_ALLOW_MASK, - .priority = 240}, - .src_addr = IPv4(10,0,0,0), - .src_mask_len = 8, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets traveling from 10.1.1.0/24 */ - { - .data = {.userdata = 5, .category_mask = ACL_ALLOW_MASK, - .priority = 340}, - .src_addr = IPv4(10,1,1,0), - .src_mask_len = 24, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets traveling from 10.1.1.1 */ - { - .data = {.userdata = 6, .category_mask = ACL_DENY_MASK, - .priority = 240}, - .src_addr = IPv4(10,1,1,1), - .src_mask_len = 32, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - -/* VLAN tag */ - /* matches all packets with lower 7 bytes of VLAN tag equal to 0x64 */ - { - .data = {.userdata = 7, .category_mask = ACL_ALLOW_MASK, - .priority = 260}, - .vlan = 0x64, - .vlan_mask = 0x7f, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets with VLAN tags that have 0x5 in them */ - { - .data = {.userdata = 8, .category_mask = ACL_ALLOW_MASK, - .priority = 260}, - .vlan = 0x5, - .vlan_mask = 0x5, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets with VLAN tag 5 */ - { - .data = {.userdata = 9, .category_mask = ACL_DENY_MASK, - .priority = 360}, - .vlan = 0x5, - .vlan_mask = 0xffff, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - -/* VLAN domain */ - /* matches all packets with lower 7 bytes of domain equal to 0x64 */ - { - .data = {.userdata = 10, .category_mask = ACL_ALLOW_MASK, - .priority = 250}, - .domain = 0x64, - .domain_mask = 0x7f, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets with domains that have 0x5 in them */ - { - .data = {.userdata = 11, .category_mask = ACL_ALLOW_MASK, - .priority = 350}, - .domain = 0x5, - .domain_mask = 0x5, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets with domain 5 */ - { - .data = {.userdata = 12, .category_mask = ACL_DENY_MASK, - .priority = 350}, - .domain = 0x5, - .domain_mask = 0xffff, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - -/* destination port */ - /* matches everything with dst port 80 */ - { - .data = {.userdata = 13, .category_mask = ACL_ALLOW_MASK, - .priority = 310}, - .dst_port_low = 80, - .dst_port_high = 80, - .src_port_low = 0, - .src_port_high = 0xffff, - }, - /* matches everything with dst port 22-1023 */ - { - .data = {.userdata = 14, .category_mask = ACL_ALLOW_MASK, - .priority = 210}, - .dst_port_low = 22, - .dst_port_high = 1023, - .src_port_low = 0, - .src_port_high = 0xffff, - }, - /* matches everything with dst port 1020 */ - { - .data = {.userdata = 15, .category_mask = ACL_DENY_MASK, - .priority = 310}, - .dst_port_low = 1020, - .dst_port_high = 1020, - .src_port_low = 0, - .src_port_high = 0xffff, - }, - /* matches everything with dst portrange 1000-2000 */ - { - .data = {.userdata = 16, .category_mask = ACL_DENY_MASK, - .priority = 210}, - .dst_port_low = 1000, - .dst_port_high = 2000, - .src_port_low = 0, - .src_port_high = 0xffff, - }, - -/* source port */ - /* matches everything with src port 80 */ - { - .data = {.userdata = 17, .category_mask = ACL_ALLOW_MASK, - .priority = 320}, - .src_port_low = 80, - .src_port_high = 80, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches everything with src port 22-1023 */ - { - .data = {.userdata = 18, .category_mask = ACL_ALLOW_MASK, - .priority = 220}, - .src_port_low = 22, - .src_port_high = 1023, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches everything with src port 1020 */ - { - .data = {.userdata = 19, .category_mask = ACL_DENY_MASK, - .priority = 320}, - .src_port_low = 1020, - .src_port_high = 1020, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches everything with src portrange 1000-2000 */ - { - .data = {.userdata = 20, .category_mask = ACL_DENY_MASK, - .priority = 220}, - .src_port_low = 1000, - .src_port_high = 2000, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - -/* protocol number */ - /* matches all packets with protocol number either 0x64 or 0xE4 */ - { - .data = {.userdata = 21, .category_mask = ACL_ALLOW_MASK, - .priority = 270}, - .proto = 0x64, - .proto_mask = 0x7f, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets with protocol that have 0x5 in them */ - { - .data = {.userdata = 22, .category_mask = ACL_ALLOW_MASK, - .priority = 1}, - .proto = 0x5, - .proto_mask = 0x5, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - /* matches all packets with protocol 5 */ - { - .data = {.userdata = 23, .category_mask = ACL_DENY_MASK, - .priority = 370}, - .proto = 0x5, - .proto_mask = 0xff, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 0, - .dst_port_high = 0xffff, - }, - -/* rules combining various fields */ - { - .data = {.userdata = 24, .category_mask = ACL_ALLOW_MASK, - .priority = 400}, - /** make sure that unmasked bytes don't fail! */ - .dst_addr = IPv4(1,2,3,4), - .dst_mask_len = 16, - .src_addr = IPv4(5,6,7,8), - .src_mask_len = 24, - .proto = 0x5, - .proto_mask = 0xff, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 22, - .dst_port_high = 1024, - .vlan = 0x8100, - .vlan_mask = 0xffff, - .domain = 0x64, - .domain_mask = 0xffff, - }, - { - .data = {.userdata = 25, .category_mask = ACL_DENY_MASK, - .priority = 400}, - .dst_addr = IPv4(5,6,7,8), - .dst_mask_len = 24, - .src_addr = IPv4(1,2,3,4), - .src_mask_len = 16, - .proto = 0x5, - .proto_mask = 0xff, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 22, - .dst_port_high = 1024, - .vlan = 0x8100, - .vlan_mask = 0xffff, - .domain = 0x64, - .domain_mask = 0xffff, - }, - { - .data = {.userdata = 26, .category_mask = ACL_ALLOW_MASK, - .priority = 500}, - .dst_addr = IPv4(1,2,3,4), - .dst_mask_len = 8, - .src_addr = IPv4(5,6,7,8), - .src_mask_len = 32, - .proto = 0x5, - .proto_mask = 0xff, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 22, - .dst_port_high = 1024, - .vlan = 0x64, - .vlan_mask = 0xffff, - }, - { - .data = {.userdata = 27, .category_mask = ACL_DENY_MASK, - .priority = 500}, - .dst_addr = IPv4(5,6,7,8), - .dst_mask_len = 32, - .src_addr = IPv4(1,2,3,4), - .src_mask_len = 8, - .proto = 0x5, - .proto_mask = 0xff, - .src_port_low = 0, - .src_port_high = 0xffff, - .dst_port_low = 22, - .dst_port_high = 1024, - .vlan = 0x64, - .vlan_mask = 0xffff, - }, -}; - -/* data for ACL unit test */ -struct ipv4_7tuple acl_test_data[] = { -/* testing single rule aspects */ - {.ip_src = IPv4(10,0,0,0), .allow = 4}, /* should match 4 */ - {.ip_src = IPv4(10,1,1,2), .allow = 5}, /* should match 5 */ - {.ip_src = IPv4(10,1,1,1), .allow = 5, - .deny = 6}, /* should match 5, 6 */ - {.ip_dst = IPv4(10,0,0,0)}, /* should not match */ - {.ip_dst = IPv4(10,1,1,2)}, /* should not match */ - {.ip_dst = IPv4(10,1,1,1)}, /* should not match */ - - {.ip_src = IPv4(192,168,2,50)}, /* should not match */ - {.ip_src = IPv4(192,168,1,2)}, /* should not match */ - {.ip_src = IPv4(192,168,1,50)}, /* should not match */ - {.ip_dst = IPv4(192,168,2,50), .allow = 1}, /* should match 1 */ - {.ip_dst = IPv4(192,168,1,49), .allow = 2}, /* should match 2 */ - {.ip_dst = IPv4(192,168,1,50), .allow = 2, - .deny = 3}, /* should match 2, 3 */ - - {.vlan = 0x64, .allow = 7}, /* should match 7 */ - {.vlan = 0xfE4, .allow = 7}, /* should match 7 */ - {.vlan = 0xE2}, /* should not match */ - {.vlan = 0xD, .allow = 8}, /* should match 8 */ - {.vlan = 0x6}, /* should not match */ - {.vlan = 0x5, .allow = 8, .deny = 9}, /* should match 8, 9 */ - - {.domain = 0x64, .allow = 10}, /* should match 10 */ - {.domain = 0xfE4, .allow = 10}, /* should match 10 */ - {.domain = 0xE2}, /* should not match */ - {.domain = 0xD, .allow = 11}, /* should match 11 */ - {.domain = 0x6}, /* should not match */ - {.domain = 0x5, .allow = 11, .deny = 12}, /* should match 11, 12 */ - - {.port_dst = 80, .allow = 13}, /* should match 13 */ - {.port_dst = 79, .allow = 14}, /* should match 14 */ - {.port_dst = 81, .allow = 14}, /* should match 14 */ - {.port_dst = 21}, /* should not match */ - {.port_dst = 1024, .deny = 16}, /* should match 16 */ - {.port_dst = 1020, .allow = 14, .deny = 15}, /* should match 14, 15 */ - - {.port_src = 80, .allow = 17}, /* should match 17 */ - {.port_src = 79, .allow = 18}, /* should match 18 */ - {.port_src = 81, .allow = 18}, /* should match 18 */ - {.port_src = 21}, /* should not match */ - {.port_src = 1024, .deny = 20}, /* should match 20 */ - {.port_src = 1020, .allow = 18, .deny = 19}, /* should match 18, 19 */ - - {.proto = 0x64, .allow = 21}, /* should match 21 */ - {.proto = 0xE4, .allow = 21}, /* should match 21 */ - {.proto = 0xE2}, /* should not match */ - {.proto = 0xD, .allow = 22}, /* should match 22 */ - {.proto = 0x6}, /* should not match */ - {.proto = 0x5, .allow = 22, .deny = 23}, /* should match 22, 23 */ - -/* testing matching multiple rules at once */ - {.vlan = 0x5, .ip_src = IPv4(10,1,1,1), - .allow = 5, .deny = 9}, /* should match 5, 9 */ - {.vlan = 0x5, .ip_src = IPv4(192,168,2,50), - .allow = 8, .deny = 9}, /* should match 8, 9 */ - {.vlan = 0x55, .ip_src = IPv4(192,168,1,49), - .allow = 8}, /* should match 8 */ - {.port_dst = 80, .port_src = 1024, - .allow = 13, .deny = 20}, /* should match 13,20 */ - {.port_dst = 79, .port_src = 1024, - .allow = 14, .deny = 20}, /* should match 14,20 */ - {.proto = 0x5, .ip_dst = IPv4(192,168,2,50), - .allow = 1, .deny = 23}, /* should match 1, 23 */ - - {.proto = 0x5, .ip_dst = IPv4(192,168,1,50), - .allow = 2, .deny = 23}, /* should match 2, 23 */ - {.vlan = 0x64, .domain = 0x5, - .allow = 11, .deny = 12}, /* should match 11, 12 */ - {.proto = 0x5, .port_src = 80, - .allow = 17, .deny = 23}, /* should match 17, 23 */ - {.proto = 0x5, .port_dst = 80, - .allow = 13, .deny = 23}, /* should match 13, 23 */ - {.proto = 0x51, .port_src = 5000}, /* should not match */ - {.ip_src = IPv4(192,168,1,50), - .ip_dst = IPv4(10,0,0,0), - .proto = 0x51, - .port_src = 5000, - .port_dst = 5000}, /* should not match */ - -/* test full packet rules */ - { - .ip_dst = IPv4(1,2,100,200), - .ip_src = IPv4(5,6,7,254), - .proto = 0x5, - .vlan = 0x8100, - .domain = 0x64, - .port_src = 12345, - .port_dst = 80, - .allow = 24, - .deny = 23 - }, /* should match 23, 24 */ - { - .ip_dst = IPv4(5,6,7,254), - .ip_src = IPv4(1,2,100,200), - .proto = 0x5, - .vlan = 0x8100, - .domain = 0x64, - .port_src = 12345, - .port_dst = 80, - .allow = 13, - .deny = 25 - }, /* should match 13, 25 */ - { - .ip_dst = IPv4(1,10,20,30), - .ip_src = IPv4(5,6,7,8), - .proto = 0x5, - .vlan = 0x64, - .port_src = 12345, - .port_dst = 80, - .allow = 26, - .deny = 23 - }, /* should match 23, 26 */ - { - .ip_dst = IPv4(5,6,7,8), - .ip_src = IPv4(1,10,20,30), - .proto = 0x5, - .vlan = 0x64, - .port_src = 12345, - .port_dst = 80, - .allow = 13, - .deny = 27 - }, /* should match 13, 27 */ - { - .ip_dst = IPv4(2,2,3,4), - .ip_src = IPv4(4,6,7,8), - .proto = 0x5, - .vlan = 0x64, - .port_src = 12345, - .port_dst = 80, - .allow = 13, - .deny = 23 - }, /* should match 13, 23 */ - { - .ip_dst = IPv4(1,2,3,4), - .ip_src = IPv4(4,6,7,8), - .proto = 0x5, - .vlan = 0x64, - .port_src = 12345, - .port_dst = 80, - .allow = 13, - .deny = 23 - }, /* should match 13, 23 */ - - -/* visual separator! */ - { - .ip_dst = IPv4(1,2,100,200), - .ip_src = IPv4(5,6,7,254), - .proto = 0x55, - .vlan = 0x8000, - .domain = 0x6464, - .port_src = 12345, - .port_dst = 8080, - .allow = 10 - }, /* should match 10 */ - { - .ip_dst = IPv4(5,6,7,254), - .ip_src = IPv4(1,2,100,200), - .proto = 0x55, - .vlan = 0x8100, - .domain = 0x6464, - .port_src = 12345, - .port_dst = 180, - .allow = 10 - }, /* should match 10 */ - { - .ip_dst = IPv4(1,10,20,30), - .ip_src = IPv4(5,6,7,8), - .proto = 0x55, - .vlan = 0x64, - .port_src = 12345, - .port_dst = 180, - .allow = 7 - }, /* should match 7 */ - { - .ip_dst = IPv4(5,6,7,8), - .ip_src = IPv4(1,10,20,30), - .proto = 0x55, - .vlan = 0x64, - .port_src = 12345, - .port_dst = 180, - .allow = 7 - }, /* should match 7 */ - { - .ip_dst = IPv4(2,2,3,4), - .ip_src = IPv4(4,6,7,8), - .proto = 0x55, - .vlan = 0x64, - .port_src = 12345, - .port_dst = 180, - .allow = 7 - }, /* should match 7 */ - { - .ip_dst = IPv4(1,2,3,4), - .ip_src = IPv4(4,6,7,8), - .proto = 0x50, - .vlan = 0x6466, - .port_src = 12345, - .port_dst = 12345, - }, /* should not match */ -}; - -#endif /* TEST_ACL_H_ */ diff --git a/app/test/test_alarm.c b/app/test/test_alarm.c deleted file mode 100644 index ecb2f6d457..0000000000 --- a/app/test/test_alarm.c +++ /dev/null @@ -1,256 +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 -#include - -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define US_PER_MS 1000 - -#define RTE_TEST_ALARM_TIMEOUT 10 /* ms */ -#define RTE_TEST_CHECK_PERIOD 3 /* ms */ - -static volatile int flag; - -static void -test_alarm_callback(void *cb_arg) -{ - flag = 1; - printf("Callback setting flag - OK. [cb_arg = %p]\n", cb_arg); -} - -static rte_atomic32_t cb_count; - -static void -test_multi_cb(void *arg) -{ - rte_atomic32_inc(&cb_count); - printf("In %s - arg = %p\n", __func__, arg); -} - -static volatile int recursive_error = 0; - -static void -test_remove_in_callback(void *arg) -{ - printf("In %s - arg = %p\n", __func__, arg); - if (rte_eal_alarm_cancel(test_remove_in_callback, arg) || - rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1)) { - printf("Error - cancelling callback from within function succeeded!\n"); - recursive_error = 1; - } - flag = (int)((uintptr_t)arg); -} - -static volatile int flag_2; - -static void -test_remove_in_callback_2(void *arg) -{ - if (rte_eal_alarm_cancel(test_remove_in_callback_2, arg) || rte_eal_alarm_cancel(test_remove_in_callback_2, (void *)-1)) { - printf("Error - cancelling callback of test_remove_in_callback_2\n"); - return; - } - flag_2 = 1; -} - -static int -test_multi_alarms(void) -{ - int rm_count = 0; - cb_count.cnt = 0; - - printf("Expect 6 callbacks in order...\n"); - /* add two alarms in order */ - 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(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(65); - if (cb_count.cnt != 6) { - printf("Missing callbacks\n"); - /* remove any callbacks that might remain */ - rte_eal_alarm_cancel(test_multi_cb, (void *)-1); - return -1; - } - - cb_count.cnt = 0; - printf("Expect only callbacks with args 1 and 3...\n"); - /* Add 3 flags, then delete one */ - 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(35); - if (cb_count.cnt != 2 || rm_count != 1) { - printf("Error: invalid flags count or alarm removal failure" - " - flags value = %d, expected = %d\n", - (int)cb_count.cnt, 2); - /* remove any callbacks that might remain */ - rte_eal_alarm_cancel(test_multi_cb, (void *)-1); - return -1; - } - - 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(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"); - rte_eal_alarm_cancel(test_multi_cb, (void *) -1); - return -1; - } - rm_count = rte_eal_alarm_cancel(test_multi_cb, (void *) -1); - if (rm_count != 3) { - printf("Error removing all pending alarm callbacks\n"); - return -1; - } - - /* Test that we cannot cancel an alarm from within the callback itself - * Also test that we can cancel head-of-line callbacks ok.*/ - flag = 0; - recursive_error = 0; - 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(15); - if (flag != 0) { - printf("Error, cancelling head-of-list leads to premature callback\n"); - return -1; - } - rte_delay_ms(10); - if (flag != 2) { - printf("Error - expected callback not called\n"); - rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1); - return -1; - } - if (recursive_error == 1) - return -1; - - /* 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(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"); - return -1; - } - rm_count = rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1); - if (rm_count != 2) { - printf("Error, cannot cancel all for the same callback\n"); - return -1; - } - - return 0; -} - -static int -test_alarm(void) -{ - int count = 0; - - /* check if the callback will be called */ - printf("check if the callback will be called\n"); - flag = 0; - if (rte_eal_alarm_set(RTE_TEST_ALARM_TIMEOUT * US_PER_MS, - test_alarm_callback, NULL) < 0) { - printf("fail to set alarm callback\n"); - return -1; - } - while (flag == 0 && count ++ < 6) - rte_delay_ms(RTE_TEST_CHECK_PERIOD); - - if (flag == 0){ - printf("Callback not called\n"); - return -1; - } - - /* check if it will fail to set alarm with wrong us value */ - printf("check if it will fail to set alarm with wrong ms values\n"); - if (rte_eal_alarm_set(0, test_alarm_callback, - NULL) >= 0) { - printf("should not be successful with 0 us value\n"); - return -1; - } - if (rte_eal_alarm_set(UINT64_MAX - 1, test_alarm_callback, - NULL) >= 0) { - printf("should not be successful with (UINT64_MAX-1) us value\n"); - return -1; - } - - /* check if it will fail to set alarm with null callback parameter */ - printf("check if it will fail to set alarm with null callback parameter\n"); - if (rte_eal_alarm_set(RTE_TEST_ALARM_TIMEOUT, NULL, NULL) >= 0) { - printf("should not be successful to set alarm with null callback parameter\n"); - return -1; - } - - /* check if it will fail to remove alarm with null callback parameter */ - printf("check if it will fail to remove alarm with null callback parameter\n"); - if (rte_eal_alarm_cancel(NULL, NULL) == 0) { - printf("should not be successful to remove alarm with null callback parameter"); - return -1; - } - - if (test_multi_alarms() != 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(alarm_autotest, test_alarm); diff --git a/app/test/test_atomic.c b/app/test/test_atomic.c deleted file mode 100644 index b5e7e1b78f..0000000000 --- a/app/test/test_atomic.c +++ /dev/null @@ -1,377 +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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * Atomic Variables - * ================ - * - * - The main test function performs three subtests. The first test - * checks that the usual inc/dec/add/sub functions are working - * correctly: - * - * - Initialize 16-bit, 32-bit and 64-bit atomic variables to specific - * values. - * - * - These variables are incremented and decremented on each core at - * the same time in ``test_atomic_usual()``. - * - * - The function checks that once all lcores finish their function, - * the value of the atomic variables are still the same. - * - * - The second test verifies the behavior of "test and set" functions. - * - * - Initialize 16-bit, 32-bit and 64-bit atomic variables to zero. - * - * - Invoke ``test_atomic_tas()`` on each lcore: before doing anything - * else. The cores are waiting a synchro using ``while - * (rte_atomic32_read(&val) == 0)`` which is triggered by the main test - * function. Then all cores do a - * ``rte_atomicXX_test_and_set()`` at the same time. If it is successful, - * it increments another atomic counter. - * - * - The main function checks that the atomic counter was incremented - * twice only (one for 16-bit, one for 32-bit and one for 64-bit values). - * - * - Test "add/sub and return" - * - * - Initialize 16-bit, 32-bit and 64-bit atomic variables to zero. - * - * - Invoke ``test_atomic_addsub_return()`` on each lcore. Before doing - * anything else, the cores are waiting a synchro. Each lcore does - * this operation several times:: - * - * tmp = rte_atomicXX_add_return(&a, 1); - * atomic_add(&count, tmp); - * tmp = rte_atomicXX_sub_return(&a, 1); - * atomic_sub(&count, tmp+1); - * - * - At the end of the test, the *count* value must be 0. - */ - -#define NUM_ATOMIC_TYPES 3 - -#define N 10000 - -static rte_atomic16_t a16; -static rte_atomic32_t a32; -static rte_atomic64_t a64; -static rte_atomic64_t count; -static rte_atomic32_t synchro; - -static int -test_atomic_usual(__attribute__((unused)) void *arg) -{ - unsigned i; - - while (rte_atomic32_read(&synchro) == 0) - ; - - for (i = 0; i < N; i++) - rte_atomic16_inc(&a16); - for (i = 0; i < N; i++) - rte_atomic16_dec(&a16); - for (i = 0; i < (N / 5); i++) - rte_atomic16_add(&a16, 5); - for (i = 0; i < (N / 5); i++) - rte_atomic16_sub(&a16, 5); - - for (i = 0; i < N; i++) - rte_atomic32_inc(&a32); - for (i = 0; i < N; i++) - rte_atomic32_dec(&a32); - for (i = 0; i < (N / 5); i++) - rte_atomic32_add(&a32, 5); - for (i = 0; i < (N / 5); i++) - rte_atomic32_sub(&a32, 5); - - for (i = 0; i < N; i++) - rte_atomic64_inc(&a64); - for (i = 0; i < N; i++) - rte_atomic64_dec(&a64); - for (i = 0; i < (N / 5); i++) - rte_atomic64_add(&a64, 5); - for (i = 0; i < (N / 5); i++) - rte_atomic64_sub(&a64, 5); - - return 0; -} - -static int -test_atomic_tas(__attribute__((unused)) void *arg) -{ - while (rte_atomic32_read(&synchro) == 0) - ; - - if (rte_atomic16_test_and_set(&a16)) - rte_atomic64_inc(&count); - if (rte_atomic32_test_and_set(&a32)) - rte_atomic64_inc(&count); - if (rte_atomic64_test_and_set(&a64)) - rte_atomic64_inc(&count); - - return 0; -} - -static int -test_atomic_addsub_and_return(__attribute__((unused)) void *arg) -{ - uint32_t tmp16; - uint32_t tmp32; - uint64_t tmp64; - unsigned i; - - while (rte_atomic32_read(&synchro) == 0) - ; - - for (i = 0; i < N; i++) { - tmp16 = rte_atomic16_add_return(&a16, 1); - rte_atomic64_add(&count, tmp16); - - tmp16 = rte_atomic16_sub_return(&a16, 1); - rte_atomic64_sub(&count, tmp16+1); - - tmp32 = rte_atomic32_add_return(&a32, 1); - rte_atomic64_add(&count, tmp32); - - tmp32 = rte_atomic32_sub_return(&a32, 1); - rte_atomic64_sub(&count, tmp32+1); - - tmp64 = rte_atomic64_add_return(&a64, 1); - rte_atomic64_add(&count, tmp64); - - tmp64 = rte_atomic64_sub_return(&a64, 1); - rte_atomic64_sub(&count, tmp64+1); - } - - return 0; -} - -/* - * rte_atomic32_inc_and_test() would increase a 32 bits counter by one and then - * test if that counter is equal to 0. It would return true if the counter is 0 - * and false if the counter is not 0. rte_atomic64_inc_and_test() could do the - * same thing but for a 64 bits counter. - * Here checks that if the 32/64 bits counter is equal to 0 after being atomically - * increased by one. If it is, increase the variable of "count" by one which would - * be checked as the result later. - * - */ -static int -test_atomic_inc_and_test(__attribute__((unused)) void *arg) -{ - while (rte_atomic32_read(&synchro) == 0) - ; - - if (rte_atomic16_inc_and_test(&a16)) { - rte_atomic64_inc(&count); - } - if (rte_atomic32_inc_and_test(&a32)) { - rte_atomic64_inc(&count); - } - if (rte_atomic64_inc_and_test(&a64)) { - rte_atomic64_inc(&count); - } - - return 0; -} - -/* - * rte_atomicXX_dec_and_test() should decrease a 32 bits counter by one and then - * test if that counter is equal to 0. It should return true if the counter is 0 - * and false if the counter is not 0. - * This test checks if the counter is equal to 0 after being atomically - * decreased by one. If it is, increase the value of "count" by one which is to - * be checked as the result later. - */ -static int -test_atomic_dec_and_test(__attribute__((unused)) void *arg) -{ - while (rte_atomic32_read(&synchro) == 0) - ; - - if (rte_atomic16_dec_and_test(&a16)) - rte_atomic64_inc(&count); - - if (rte_atomic32_dec_and_test(&a32)) - rte_atomic64_inc(&count); - - if (rte_atomic64_dec_and_test(&a64)) - rte_atomic64_inc(&count); - - return 0; -} - -static int -test_atomic(void) -{ - rte_atomic16_init(&a16); - rte_atomic32_init(&a32); - rte_atomic64_init(&a64); - rte_atomic64_init(&count); - rte_atomic32_init(&synchro); - - rte_atomic16_set(&a16, 1UL << 10); - rte_atomic32_set(&a32, 1UL << 10); - rte_atomic64_set(&a64, 1ULL << 33); - - printf("usual inc/dec/add/sub functions\n"); - - rte_eal_mp_remote_launch(test_atomic_usual, NULL, SKIP_MASTER); - rte_atomic32_set(&synchro, 1); - rte_eal_mp_wait_lcore(); - rte_atomic32_set(&synchro, 0); - - if (rte_atomic16_read(&a16) != 1UL << 10) { - printf("Atomic16 usual functions failed\n"); - return -1; - } - - if (rte_atomic32_read(&a32) != 1UL << 10) { - printf("Atomic32 usual functions failed\n"); - return -1; - } - - if (rte_atomic64_read(&a64) != 1ULL << 33) { - printf("Atomic64 usual functions failed\n"); - return -1; - } - - printf("test and set\n"); - - rte_atomic64_set(&a64, 0); - rte_atomic32_set(&a32, 0); - rte_atomic16_set(&a16, 0); - rte_atomic64_set(&count, 0); - rte_eal_mp_remote_launch(test_atomic_tas, NULL, SKIP_MASTER); - rte_atomic32_set(&synchro, 1); - rte_eal_mp_wait_lcore(); - rte_atomic32_set(&synchro, 0); - - if (rte_atomic64_read(&count) != NUM_ATOMIC_TYPES) { - printf("Atomic test and set failed\n"); - return -1; - } - - printf("add/sub and return\n"); - - rte_atomic64_set(&a64, 0); - rte_atomic32_set(&a32, 0); - rte_atomic16_set(&a16, 0); - rte_atomic64_set(&count, 0); - rte_eal_mp_remote_launch(test_atomic_addsub_and_return, NULL, - SKIP_MASTER); - rte_atomic32_set(&synchro, 1); - rte_eal_mp_wait_lcore(); - rte_atomic32_set(&synchro, 0); - - if (rte_atomic64_read(&count) != 0) { - printf("Atomic add/sub+return failed\n"); - return -1; - } - - /* - * Set a64, a32 and a16 with the same value of minus "number of slave - * lcores", launch all slave lcores to atomically increase by one and - * test them respectively. - * Each lcore should have only one chance to increase a64 by one and - * then check if it is equal to 0, but there should be only one lcore - * that finds that it is 0. It is similar for a32 and a16. - * Then a variable of "count", initialized to zero, is increased by - * one if a64, a32 or a16 is 0 after being increased and tested - * atomically. - * We can check if "count" is finally equal to 3 to see if all slave - * lcores performed "atomic inc and test" right. - */ - printf("inc and test\n"); - - rte_atomic64_clear(&a64); - rte_atomic32_clear(&a32); - rte_atomic16_clear(&a16); - rte_atomic32_clear(&synchro); - rte_atomic64_clear(&count); - - rte_atomic64_set(&a64, (int64_t)(1 - (int64_t)rte_lcore_count())); - rte_atomic32_set(&a32, (int32_t)(1 - (int32_t)rte_lcore_count())); - rte_atomic16_set(&a16, (int16_t)(1 - (int16_t)rte_lcore_count())); - rte_eal_mp_remote_launch(test_atomic_inc_and_test, NULL, SKIP_MASTER); - rte_atomic32_set(&synchro, 1); - rte_eal_mp_wait_lcore(); - rte_atomic32_clear(&synchro); - - if (rte_atomic64_read(&count) != NUM_ATOMIC_TYPES) { - printf("Atomic inc and test failed %d\n", (int)count.cnt); - return -1; - } - - /* - * Same as above, but this time we set the values to "number of slave - * lcores", and decrement instead of increment. - */ - printf("dec and test\n"); - - rte_atomic32_clear(&synchro); - rte_atomic64_clear(&count); - - rte_atomic64_set(&a64, (int64_t)(rte_lcore_count() - 1)); - rte_atomic32_set(&a32, (int32_t)(rte_lcore_count() - 1)); - rte_atomic16_set(&a16, (int16_t)(rte_lcore_count() - 1)); - rte_eal_mp_remote_launch(test_atomic_dec_and_test, NULL, SKIP_MASTER); - rte_atomic32_set(&synchro, 1); - rte_eal_mp_wait_lcore(); - rte_atomic32_clear(&synchro); - - if (rte_atomic64_read(&count) != NUM_ATOMIC_TYPES) { - printf("Atomic dec and test failed\n"); - return -1; - } - - return 0; -} - -REGISTER_TEST_COMMAND(atomic_autotest, test_atomic); diff --git a/app/test/test_byteorder.c b/app/test/test_byteorder.c deleted file mode 100644 index 8ae311420b..0000000000 --- a/app/test/test_byteorder.c +++ /dev/null @@ -1,95 +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 -#include -#include -#include - -#include - -#include "test.h" - -static volatile uint16_t u16 = 0x1337; -static volatile uint32_t u32 = 0xdeadbeefUL; -static volatile uint64_t u64 = 0xdeadcafebabefaceULL; - -/* - * Byteorder functions - * =================== - * - * - check that optimized byte swap functions are working for each - * size (16, 32, 64 bits) - */ - -static int -test_byteorder(void) -{ - uint16_t res_u16; - uint32_t res_u32; - uint64_t res_u64; - - res_u16 = rte_bswap16(u16); - printf("%"PRIx16" -> %"PRIx16"\n", u16, res_u16); - if (res_u16 != 0x3713) - return -1; - - res_u32 = rte_bswap32(u32); - printf("%"PRIx32" -> %"PRIx32"\n", u32, res_u32); - if (res_u32 != 0xefbeaddeUL) - return -1; - - res_u64 = rte_bswap64(u64); - printf("%"PRIx64" -> %"PRIx64"\n", u64, res_u64); - if (res_u64 != 0xcefabebafecaaddeULL) - return -1; - - res_u16 = rte_bswap16(0x1337); - printf("const %"PRIx16" -> %"PRIx16"\n", 0x1337, res_u16); - if (res_u16 != 0x3713) - return -1; - - res_u32 = rte_bswap32(0xdeadbeefUL); - printf("const %"PRIx32" -> %"PRIx32"\n", (uint32_t) 0xdeadbeef, res_u32); - if (res_u32 != 0xefbeaddeUL) - return -1; - - res_u64 = rte_bswap64(0xdeadcafebabefaceULL); - printf("const %"PRIx64" -> %"PRIx64"\n", (uint64_t) 0xdeadcafebabefaceULL, res_u64); - if (res_u64 != 0xcefabebafecaaddeULL) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(byteorder_autotest, test_byteorder); diff --git a/app/test/test_cmdline.c b/app/test/test_cmdline.c deleted file mode 100644 index 38c7256f82..0000000000 --- a/app/test/test_cmdline.c +++ /dev/null @@ -1,92 +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 - -#include "test.h" -#include "test_cmdline.h" - -static int -test_cmdline(void) -{ - printf("Testind parsing ethernet addresses...\n"); - if (test_parse_etheraddr_valid() < 0) - return -1; - if (test_parse_etheraddr_invalid_data() < 0) - return -1; - if (test_parse_etheraddr_invalid_param() < 0) - return -1; - printf("Testind parsing port lists...\n"); - if (test_parse_portlist_valid() < 0) - return -1; - if (test_parse_portlist_invalid_data() < 0) - return -1; - if (test_parse_portlist_invalid_param() < 0) - return -1; - printf("Testind parsing numbers...\n"); - if (test_parse_num_valid() < 0) - return -1; - if (test_parse_num_invalid_data() < 0) - return -1; - if (test_parse_num_invalid_param() < 0) - return -1; - printf("Testing parsing IP addresses...\n"); - if (test_parse_ipaddr_valid() < 0) - return -1; - if (test_parse_ipaddr_invalid_data() < 0) - return -1; - if (test_parse_ipaddr_invalid_param() < 0) - return -1; - printf("Testing parsing strings...\n"); - if (test_parse_string_valid() < 0) - return -1; - if (test_parse_string_invalid_data() < 0) - return -1; - if (test_parse_string_invalid_param() < 0) - return -1; - printf("Testing circular buffer...\n"); - if (test_cirbuf_char() < 0) - return -1; - if (test_cirbuf_string() < 0) - return -1; - if (test_cirbuf_align() < 0) - return -1; - if (test_cirbuf_invalid_param() < 0) - return -1; - printf("Testing library functions...\n"); - if (test_cmdline_lib() < 0) - return -1; - return 0; -} - -REGISTER_TEST_COMMAND(cmdline_autotest, test_cmdline); diff --git a/app/test/test_cmdline.h b/app/test/test_cmdline.h deleted file mode 100644 index 0ee91c1739..0000000000 --- a/app/test/test_cmdline.h +++ /dev/null @@ -1,73 +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 TEST_CMDLINE_H_ -#define TEST_CMDLINE_H_ - -#define CMDLINE_TEST_BUFSIZE 64 - -/* cmdline_parse_num tests */ -int test_parse_num_valid(void); -int test_parse_num_invalid_data(void); -int test_parse_num_invalid_param(void); - -/* cmdline_parse_etheraddr tests */ -int test_parse_etheraddr_valid(void); -int test_parse_etheraddr_invalid_data(void); -int test_parse_etheraddr_invalid_param(void); - -/* cmdline_parse_portlist tests */ -int test_parse_portlist_valid(void); -int test_parse_portlist_invalid_data(void); -int test_parse_portlist_invalid_param(void); - -/* cmdline_parse_ipaddr tests */ -int test_parse_ipaddr_valid(void); -int test_parse_ipaddr_invalid_data(void); -int test_parse_ipaddr_invalid_param(void); - -/* cmdline_parse_string tests */ -int test_parse_string_valid(void); -int test_parse_string_invalid_data(void); -int test_parse_string_invalid_param(void); - -/* cmdline_cirbuf tests */ -int test_cirbuf_invalid_param(void); -int test_cirbuf_char(void); -int test_cirbuf_string(void); -int test_cirbuf_align(void); - -/* test the rest of the library */ -int test_cmdline_lib(void); - -#endif /* TEST_CMDLINE_H_ */ diff --git a/app/test/test_cmdline_cirbuf.c b/app/test/test_cmdline_cirbuf.c deleted file mode 100644 index 87f83cc6d9..0000000000 --- a/app/test/test_cmdline_cirbuf.c +++ /dev/null @@ -1,1330 +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 -#include -#include - -#include - -#include - -#include "test_cmdline.h" - -/* different length strings */ -#define CIRBUF_STR_HEAD " HEAD" -#define CIRBUF_STR_TAIL "TAIL" - -/* miscelaneous tests - they make bullseye happy */ -static int -test_cirbuf_string_misc(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - char tmp[CMDLINE_TEST_BUFSIZE]; - - /* initialize buffers */ - memset(buf, 0, sizeof(buf)); - memset(tmp, 0, sizeof(tmp)); - - /* - * initialize circular buffer - */ - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* - * add strings to head and tail, but read only tail - * this results in read operation that does not transcend - * from buffer end to buffer beginning (in other words, - * strlen <= cb->maxlen - cb->end) - */ - - /* add string to head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to add string to head!\n"); - return -1; - } - /* add string to tail */ - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to add string to head!\n"); - return -1; - } - /* read string from tail */ - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to get string from tail!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) { - printf("Error: tail strings do not match!\n"); - return -1; - } - /* clear buffers */ - memset(tmp, 0, sizeof(tmp)); - memset(buf, 0, sizeof(buf)); - - - - /* - * add a string to buffer when start/end is at end of buffer - */ - - /* - * reinitialize circular buffer with start at the end of cirbuf - */ - if (cirbuf_init(&cb, buf, CMDLINE_TEST_BUFSIZE - 2, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - - /* add string to tail */ - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to add string to tail!\n"); - return -1; - } - /* read string from tail */ - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to get string from tail!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) { - printf("Error: tail strings do not match!\n"); - return -1; - } - /* clear tmp buffer */ - memset(tmp, 0, sizeof(tmp)); - - - /* add string to head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to add string to head!\n"); - return -1; - } - /* read string from tail */ - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to get string from head!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) { - printf("Error: headstrings do not match!\n"); - return -1; - } - - return 0; -} - -/* test adding and deleting strings */ -static int -test_cirbuf_string_add_del(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - char tmp[CMDLINE_TEST_BUFSIZE]; - - /* initialize buffers */ - memset(buf, 0, sizeof(buf)); - memset(tmp, 0, sizeof(tmp)); - - /* - * initialize circular buffer - */ - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* add string to head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to add string to head!\n"); - return -1; - } - /* read string from head */ - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to get string from head!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) { - printf("Error: head strings do not match!\n"); - return -1; - } - /* clear tmp buffer */ - memset(tmp, 0, sizeof(tmp)); - /* read string from tail */ - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to get string from head!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) { - printf("Error: head strings do not match!\n"); - return -1; - } - /* delete string from head*/ - if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_HEAD)) < 0) { - printf("Error: failed to delete string from head!\n"); - return -1; - } - /* verify string was deleted */ - if (cirbuf_del_head_safe(&cb) == 0) { - printf("Error: buffer should have been empty!\n"); - return -1; - } - /* clear tmp buffer */ - memset(tmp, 0, sizeof(tmp)); - - - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* add string to tail */ - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to add string to tail!\n"); - return -1; - } - /* get string from tail */ - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to get string from tail!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) { - printf("Error: tail strings do not match!\n"); - return -1; - } - /* clear tmp buffer */ - memset(tmp, 0, sizeof(tmp)); - /* get string from head */ - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to get string from tail!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) { - printf("Error: tail strings do not match!\n"); - return -1; - } - /* delete string from tail */ - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL)) < 0) { - printf("Error: failed to delete string from tail!\n"); - return -1; - } - /* verify string was deleted */ - if (cirbuf_del_tail_safe(&cb) == 0) { - printf("Error: buffer should have been empty!\n"); - return -1; - } - - return 0; -} - -/* test adding from head and deleting from tail, and vice versa */ -static int -test_cirbuf_string_add_del_reverse(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - char tmp[CMDLINE_TEST_BUFSIZE]; - - /* initialize buffers */ - memset(buf, 0, sizeof(buf)); - memset(tmp, 0, sizeof(tmp)); - - /* - * initialize circular buffer - */ - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* add string to head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to add string to head!\n"); - return -1; - } - /* delete string from tail */ - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_HEAD)) < 0) { - printf("Error: failed to delete string from tail!\n"); - return -1; - } - /* verify string was deleted */ - if (cirbuf_del_tail_safe(&cb) == 0) { - printf("Error: buffer should have been empty!\n"); - return -1; - } - /* clear tmp buffer */ - memset(tmp, 0, sizeof(tmp)); - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* add string to tail */ - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to add string to tail!\n"); - return -1; - } - /* delete string from head */ - if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_TAIL)) < 0) { - printf("Error: failed to delete string from head!\n"); - return -1; - } - /* verify string was deleted */ - if (cirbuf_del_head_safe(&cb) == 0) { - printf("Error: buffer should have been empty!\n"); - return -1; - } - - return 0; -} - -/* try to write more than available */ -static int -test_cirbuf_string_add_boundaries(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - unsigned i; - - /* initialize buffers */ - memset(buf, 0, sizeof(buf)); - - /* - * initialize circular buffer - */ - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* fill the buffer from tail */ - for (i = 0; i < CMDLINE_TEST_BUFSIZE - sizeof(CIRBUF_STR_TAIL) + 1; i++) - cirbuf_add_tail_safe(&cb, 't'); - - /* try adding a string to tail */ - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) - > 0) { - printf("Error: buffer should have been full!\n"); - return -1; - } - /* try adding a string to head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) - > 0) { - printf("Error: buffer should have been full!\n"); - return -1; - } - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* fill the buffer from head */ - for (i = 0; i < CMDLINE_TEST_BUFSIZE - sizeof(CIRBUF_STR_HEAD) + 1; i++) - cirbuf_add_head_safe(&cb, 'h'); - - /* try adding a string to head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) - > 0) { - printf("Error: buffer should have been full!\n"); - return -1; - } - /* try adding a string to tail */ - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) - > 0) { - printf("Error: buffer should have been full!\n"); - return -1; - } - - return 0; -} - -/* try to read/delete more than written */ -static int -test_cirbuf_string_get_del_boundaries(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - char tmp[CMDLINE_TEST_BUFSIZE]; - - /* initialize buffers */ - memset(buf, 0, sizeof(buf)); - memset(tmp, 0, sizeof(tmp)); - - /* - * initialize circular buffer - */ - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - - /* add string to head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to add string to head!\n"); - return -1; - } - /* read more than written (head) */ - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) + 1) - != sizeof(CIRBUF_STR_HEAD)) { - printf("Error: unexpected result when reading too much data!\n"); - return -1; - } - /* read more than written (tail) */ - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) + 1) - != sizeof(CIRBUF_STR_HEAD)) { - printf("Error: unexpected result when reading too much data!\n"); - return -1; - } - /* delete more than written (head) */ - if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_HEAD) + 1) == 0) { - printf("Error: unexpected result when deleting too much data!\n"); - return -1; - } - /* delete more than written (tail) */ - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_HEAD) + 1) == 0) { - printf("Error: unexpected result when deleting too much data!\n"); - return -1; - } - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* add string to tail */ - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) - != (sizeof(CIRBUF_STR_TAIL))) { - printf("Error: failed to add string to tail!\n"); - return -1; - } - /* read more than written (tail) */ - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL) + 1) - != sizeof(CIRBUF_STR_TAIL)) { - printf("Error: unexpected result when reading too much data!\n"); - return -1; - } - /* read more than written (head) */ - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_TAIL) + 1) - != sizeof(CIRBUF_STR_TAIL)) { - printf("Error: unexpected result when reading too much data!\n"); - return -1; - } - /* delete more than written (tail) */ - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL) + 1) == 0) { - printf("Error: unexpected result when deleting too much data!\n"); - return -1; - } - /* delete more than written (head) */ - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL) + 1) == 0) { - printf("Error: unexpected result when deleting too much data!\n"); - return -1; - } - - return 0; -} - -/* try to read/delete less than written */ -static int -test_cirbuf_string_get_del_partial(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - char tmp[CMDLINE_TEST_BUFSIZE]; - char tmp2[CMDLINE_TEST_BUFSIZE]; - - /* initialize buffers */ - memset(buf, 0, sizeof(buf)); - memset(tmp, 0, sizeof(tmp)); - memset(tmp2, 0, sizeof(tmp)); - - snprintf(tmp2, sizeof(tmp2), "%s", CIRBUF_STR_HEAD); - - /* - * initialize circular buffer - */ - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* add string to head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) - != (sizeof(CIRBUF_STR_HEAD))) { - printf("Error: failed to add string to head!\n"); - return -1; - } - /* read less than written (head) */ - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1) - != sizeof(CIRBUF_STR_HEAD) - 1) { - printf("Error: unexpected result when reading from head!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, tmp2, sizeof(CIRBUF_STR_HEAD) - 1) != 0) { - printf("Error: strings mismatch!\n"); - return -1; - } - memset(tmp, 0, sizeof(tmp)); - /* read less than written (tail) */ - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1) - != sizeof(CIRBUF_STR_HEAD) - 1) { - printf("Error: unexpected result when reading from tail!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 1) != 0) { - printf("Error: strings mismatch!\n"); - return -1; - } - - /* - * verify correct deletion - */ - - /* clear buffer */ - memset(tmp, 0, sizeof(tmp)); - - /* delete less than written (head) */ - if (cirbuf_del_buf_head(&cb, 1) != 0) { - printf("Error: delete from head failed!\n"); - return -1; - } - /* read from head */ - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1) - != sizeof(CIRBUF_STR_HEAD) - 1) { - printf("Error: unexpected result when reading from head!\n"); - return -1; - } - /* since we deleted from head, first char should be deleted */ - if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 1) != 0) { - printf("Error: strings mismatch!\n"); - return -1; - } - /* clear buffer */ - memset(tmp, 0, sizeof(tmp)); - - /* delete less than written (tail) */ - if (cirbuf_del_buf_tail(&cb, 1) != 0) { - printf("Error: delete from tail failed!\n"); - return -1; - } - /* read from tail */ - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 2) - != sizeof(CIRBUF_STR_HEAD) - 2) { - printf("Error: unexpected result when reading from head!\n"); - return -1; - } - /* since we deleted from tail, last char should be deleted */ - if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 2) != 0) { - printf("Error: strings mismatch!\n"); - return -1; - } - - return 0; -} - -/* test cmdline_cirbuf char add/del functions */ -static int -test_cirbuf_char_add_del(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - char tmp[CMDLINE_TEST_BUFSIZE]; - - /* clear buffer */ - memset(buf, 0, sizeof(buf)); - memset(tmp, 0, sizeof(tmp)); - - /* - * initialize circular buffer - */ - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* - * try to delete something from cirbuf. since it's empty, - * these should fail. - */ - if (cirbuf_del_head_safe(&cb) == 0) { - printf("Error: deleting from empty cirbuf head succeeded!\n"); - return -1; - } - if (cirbuf_del_tail_safe(&cb) == 0) { - printf("Error: deleting from empty cirbuf tail succeeded!\n"); - return -1; - } - - /* - * add, verify and delete. these should pass. - */ - if (cirbuf_add_head_safe(&cb,'h') < 0) { - printf("Error: adding to cirbuf head failed!\n"); - return -1; - } - if (cirbuf_get_head(&cb) != 'h') { - printf("Error: wrong head content!\n"); - return -1; - } - if (cirbuf_del_head_safe(&cb) < 0) { - printf("Error: deleting from cirbuf head failed!\n"); - return -1; - } - if (cirbuf_add_tail_safe(&cb,'t') < 0) { - printf("Error: adding to cirbuf tail failed!\n"); - return -1; - } - if (cirbuf_get_tail(&cb) != 't') { - printf("Error: wrong tail content!\n"); - return -1; - } - if (cirbuf_del_tail_safe(&cb) < 0) { - printf("Error: deleting from cirbuf tail failed!\n"); - return -1; - } - /* do the same for unsafe versions. those are void. */ - cirbuf_add_head(&cb,'h'); - if (cirbuf_get_head(&cb) != 'h') { - printf("Error: wrong head content!\n"); - return -1; - } - cirbuf_del_head(&cb); - - /* test if char has been deleted. we can't call cirbuf_get_head - * because it's unsafe, but we can call cirbuf_get_buf_head. - */ - if (cirbuf_get_buf_head(&cb, tmp, 1) > 0) { - printf("Error: buffer should have been empty!\n"); - return -1; - } - - cirbuf_add_tail(&cb,'t'); - if (cirbuf_get_tail(&cb) != 't') { - printf("Error: wrong tail content!\n"); - return -1; - } - cirbuf_del_tail(&cb); - - /* test if char has been deleted. we can't call cirbuf_get_tail - * because it's unsafe, but we can call cirbuf_get_buf_tail. - */ - if (cirbuf_get_buf_tail(&cb, tmp, 1) > 0) { - printf("Error: buffer should have been empty!\n"); - return -1; - } - - return 0; -} - -/* test filling up buffer with chars */ -static int -test_cirbuf_char_fill(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - unsigned i; - - /* clear buffer */ - memset(buf, 0, sizeof(buf)); - - /* - * initialize circular buffer - */ - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* - * fill the buffer from head or tail, verify contents, test boundaries - * and clear the buffer - */ - - /* fill the buffer from tail */ - for (i = 0; i < CMDLINE_TEST_BUFSIZE; i++) - cirbuf_add_tail_safe(&cb, 't'); - /* verify that contents of the buffer are what they are supposed to be */ - for (i = 0; i < sizeof(buf); i++) { - if (buf[i] != 't') { - printf("Error: wrong content in buffer!\n"); - return -1; - } - } - /* try to add to a full buffer from tail */ - if (cirbuf_add_tail_safe(&cb, 't') == 0) { - printf("Error: buffer should have been full!\n"); - return -1; - } - /* try to add to a full buffer from head */ - if (cirbuf_add_head_safe(&cb, 'h') == 0) { - printf("Error: buffer should have been full!\n"); - return -1; - } - /* delete buffer from tail */ - for(i = 0; i < CMDLINE_TEST_BUFSIZE; i++) - cirbuf_del_tail_safe(&cb); - /* try to delete from an empty buffer */ - if (cirbuf_del_tail_safe(&cb) >= 0) { - printf("Error: buffer should have been empty!\n"); - return -1; - } - - /* fill the buffer from head */ - for (i = 0; i < CMDLINE_TEST_BUFSIZE; i++) - cirbuf_add_head_safe(&cb, 'h'); - /* verify that contents of the buffer are what they are supposed to be */ - for (i = 0; i < sizeof(buf); i++) { - if (buf[i] != 'h') { - printf("Error: wrong content in buffer!\n"); - return -1; - } - } - /* try to add to a full buffer from head */ - if (cirbuf_add_head_safe(&cb,'h') >= 0) { - printf("Error: buffer should have been full!\n"); - return -1; - } - /* try to add to a full buffer from tail */ - if (cirbuf_add_tail_safe(&cb, 't') == 0) { - printf("Error: buffer should have been full!\n"); - return -1; - } - /* delete buffer from head */ - for(i = 0; i < CMDLINE_TEST_BUFSIZE; i++) - cirbuf_del_head_safe(&cb); - /* try to delete from an empty buffer */ - if (cirbuf_del_head_safe(&cb) >= 0) { - printf("Error: buffer should have been empty!\n"); - return -1; - } - - /* - * fill the buffer from both head and tail, with alternating characters, - * verify contents and clear the buffer - */ - - /* fill half of buffer from tail */ - for (i = 0; i < CMDLINE_TEST_BUFSIZE / 2; i++) - cirbuf_add_tail_safe(&cb, (char) (i % 2 ? 't' : 'T')); - /* fill other half of the buffer from head */ - for (i = 0; i < CMDLINE_TEST_BUFSIZE / 2; i++) - cirbuf_add_head_safe(&cb, (char) (i % 2 ? 'H' : 'h')); /* added in reverse */ - - /* verify that contents of the buffer are what they are supposed to be */ - for (i = 0; i < sizeof(buf) / 2; i++) { - if (buf[i] != (char) (i % 2 ? 't' : 'T')) { - printf("Error: wrong content in buffer at %u!\n", i); - return -1; - } - } - for (i = sizeof(buf) / 2; i < sizeof(buf); i++) { - if (buf[i] != (char) (i % 2 ? 'h' : 'H')) { - printf("Error: wrong content in buffer %u!\n", i); - return -1; - } - } - - return 0; -} - -/* test left alignment */ -static int -test_cirbuf_align_left(void) -{ -#define HALF_OFFSET CMDLINE_TEST_BUFSIZE / 2 -#define SMALL_OFFSET HALF_OFFSET / 2 -/* resulting buffer lengths for each of the test cases */ -#define LEN1 HALF_OFFSET - SMALL_OFFSET - 1 -#define LEN2 HALF_OFFSET + SMALL_OFFSET + 2 -#define LEN3 HALF_OFFSET - SMALL_OFFSET -#define LEN4 HALF_OFFSET + SMALL_OFFSET - 1 - - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - char tmp[CMDLINE_TEST_BUFSIZE]; - unsigned i; - - /* - * align left when start < end and start in left half - */ - - /* - * initialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* push end into left half */ - for (i = 0; i < HALF_OFFSET - 1; i++) - cirbuf_add_tail_safe(&cb, 't'); - - /* push start into left half < end */ - for (i = 0; i < SMALL_OFFSET; i++) - cirbuf_del_head_safe(&cb); - - /* align */ - if (cirbuf_align_left(&cb) < 0) { - printf("Error: alignment failed!\n"); - return -1; - } - - /* verify result */ - if (cb.start != 0 || cb.len != LEN1 || cb.end != cb.len - 1) { - printf("Error: buffer alignment is wrong!\n"); - return -1; - } - - /* - * align left when start > end and start in left half - */ - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* push start into left half */ - for (i = 0; i < HALF_OFFSET + 2; i++) - cirbuf_add_head_safe(&cb, 'h'); - - /* push end into left half > start */ - for (i = 0; i < SMALL_OFFSET; i++) - cirbuf_add_tail_safe(&cb, 't'); - - /* align */ - if (cirbuf_align_left(&cb) < 0) { - printf("Error: alignment failed!\n"); - return -1; - } - - /* verify result */ - if (cb.start != 0 || cb.len != LEN2 || cb.end != cb.len - 1) { - printf("Error: buffer alignment is wrong!"); - return -1; - } - - /* - * align left when start < end and start in right half - */ - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* push start into the right half */ - for (i = 0; i < HALF_OFFSET; i++) - cirbuf_add_head_safe(&cb, 'h'); - - /* push end into left half > start */ - for (i = 0; i < SMALL_OFFSET; i++) - cirbuf_del_tail_safe(&cb); - - /* align */ - if (cirbuf_align_left(&cb) < 0) { - printf("Error: alignment failed!\n"); - return -1; - } - - /* verify result */ - if (cb.start != 0 || cb.len != LEN3 || cb.end != cb.len - 1) { - printf("Error: buffer alignment is wrong!"); - return -1; - } - - /* - * align left when start > end and start in right half - */ - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* push start into the right half */ - for (i = 0; i < HALF_OFFSET - 1; i++) - cirbuf_add_head_safe(&cb, 'h'); - - /* push end into left half < start */ - for (i = 0; i < SMALL_OFFSET; i++) - cirbuf_add_tail_safe(&cb, 't'); - - /* align */ - if (cirbuf_align_left(&cb) < 0) { - printf("Error: alignment failed!\n"); - return -1; - } - - /* verify result */ - if (cb.start != 0 || cb.len != LEN4 || - cb.end != cb.len - 1) { - printf("Error: buffer alignment is wrong!"); - return -1; - } - - /* - * Verify that alignment doesn't corrupt data - */ - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* add string to tail and head */ - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, - sizeof(CIRBUF_STR_HEAD)) < 0 || cirbuf_add_buf_tail(&cb, - CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) < 0) { - printf("Error: failed to add strings!\n"); - return -1; - } - - /* align */ - if (cirbuf_align_left(&cb) < 0) { - printf("Error: alignment failed!\n"); - return -1; - } - - /* get string from head */ - if (cirbuf_get_buf_head(&cb, tmp, - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) { - printf("Error: failed to read string from head!\n"); - return -1; - } - - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL, - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) { - printf("Error: strings mismatch!\n"); - return -1; - } - - /* reset tmp buffer */ - memset(tmp, 0, sizeof(tmp)); - - /* get string from tail */ - if (cirbuf_get_buf_tail(&cb, tmp, - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) { - printf("Error: failed to read string from head!\n"); - return -1; - } - - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL, - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) { - printf("Error: strings mismatch!\n"); - return -1; - } - - return 0; -} - -/* test right alignment */ -static int -test_cirbuf_align_right(void) -{ -#define END_OFFSET CMDLINE_TEST_BUFSIZE - 1 - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - char tmp[CMDLINE_TEST_BUFSIZE]; - unsigned i; - - - /* - * align right when start < end and start in left half - */ - - /* - * initialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to initialize circular buffer!\n"); - return -1; - } - - /* push end into left half */ - for (i = 0; i < HALF_OFFSET - 1; i++) - cirbuf_add_tail_safe(&cb, 't'); - - /* push start into left half < end */ - for (i = 0; i < SMALL_OFFSET; i++) - cirbuf_del_head_safe(&cb); - - /* align */ - cirbuf_align_right(&cb); - - /* verify result */ - if (cb.start != END_OFFSET || cb.len != LEN1 || cb.end != cb.len - 2) { - printf("Error: buffer alignment is wrong!\n"); - return -1; - } - - /* - * align right when start > end and start in left half - */ - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* push start into left half */ - for (i = 0; i < HALF_OFFSET + 2; i++) - cirbuf_add_head_safe(&cb, 'h'); - - /* push end into left half > start */ - for (i = 0; i < SMALL_OFFSET; i++) - cirbuf_add_tail_safe(&cb, 't'); - - /* align */ - cirbuf_align_right(&cb); - - /* verify result */ - if (cb.start != END_OFFSET || cb.len != LEN2 || cb.end != cb.len - 2) { - printf("Error: buffer alignment is wrong!"); - return -1; - } - - /* - * align right when start < end and start in right half - */ - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* push start into the right half */ - for (i = 0; i < HALF_OFFSET; i++) - cirbuf_add_head_safe(&cb, 'h'); - - /* push end into left half > start */ - for (i = 0; i < SMALL_OFFSET; i++) - cirbuf_del_tail_safe(&cb); - - /* align */ - cirbuf_align_right(&cb); - - /* verify result */ - if (cb.end != END_OFFSET || cb.len != LEN3 || cb.start != cb.end - cb.len + 1) { - printf("Error: buffer alignment is wrong!"); - return -1; - } - - /* - * align right when start > end and start in right half - */ - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* push start into the right half */ - for (i = 0; i < HALF_OFFSET - 1; i++) - cirbuf_add_head_safe(&cb, 'h'); - - /* push end into left half < start */ - for (i = 0; i < SMALL_OFFSET; i++) - cirbuf_add_tail_safe(&cb, 't'); - - /* align */ - cirbuf_align_right(&cb); - - /* verify result */ - if (cb.end != END_OFFSET || cb.len != LEN4 || cb.start != cb.end - cb.len + 1) { - printf("Error: buffer alignment is wrong!"); - return -1; - } - - /* - * Verify that alignment doesn't corrupt data - */ - - /* - * reinitialize circular buffer - */ - memset(buf, 0, sizeof(buf)); - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { - printf("Error: failed to reinitialize circular buffer!\n"); - return -1; - } - - /* add string to tail and head */ - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, - sizeof(CIRBUF_STR_TAIL)) < 0 || cirbuf_add_buf_head(&cb, - CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) < 0) { - printf("Error: failed to add strings!\n"); - return -1; - } - - /* align */ - if (cirbuf_align_right(&cb) < 0) { - printf("Error: alignment failed!\n"); - return -1; - } - - /* get string from head */ - if (cirbuf_get_buf_head(&cb, tmp, - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) { - printf("Error: failed to read string from head!\n"); - return -1; - } - - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL, - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) { - printf("Error: strings mismatch!\n"); - return -1; - } - - /* reset tmp buffer */ - memset(tmp, 0, sizeof(tmp)); - - /* get string from tail */ - if (cirbuf_get_buf_tail(&cb, tmp, - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) { - printf("Error: failed to read string from head!\n"); - return -1; - } - /* verify string */ - if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL, - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) { - printf("Error: strings mismatch!\n"); - return -1; - } - - return 0; -} - -/* call functions with invalid parameters */ -int -test_cirbuf_invalid_param(void) -{ - struct cirbuf cb; - char buf[CMDLINE_TEST_BUFSIZE]; - - /* null cirbuf */ - if (cirbuf_init(0, buf, 0, sizeof(buf)) == 0) - return -1; - /* null buffer */ - if (cirbuf_init(&cb, 0, 0, sizeof(buf)) == 0) - return -1; - /* null cirbuf */ - if (cirbuf_add_head_safe(0, 'h') == 0) - return -1; - if (cirbuf_add_tail_safe(0, 't') == 0) - return -1; - if (cirbuf_del_head_safe(0) == 0) - return -1; - if (cirbuf_del_tail_safe(0) == 0) - return -1; - /* null buffer */ - if (cirbuf_add_buf_head(&cb, 0, 0) == 0) - return -1; - if (cirbuf_add_buf_tail(&cb, 0, 0) == 0) - return -1; - /* null cirbuf */ - if (cirbuf_add_buf_head(0, buf, 0) == 0) - return -1; - if (cirbuf_add_buf_tail(0, buf, 0) == 0) - return -1; - /* null size */ - if (cirbuf_add_buf_head(&cb, buf, 0) == 0) - return -1; - if (cirbuf_add_buf_tail(&cb, buf, 0) == 0) - return -1; - /* null cirbuf */ - if (cirbuf_del_buf_head(0, 0) == 0) - return -1; - if (cirbuf_del_buf_tail(0, 0) == 0) - return -1; - /* null size */ - if (cirbuf_del_buf_head(&cb, 0) == 0) - return -1; - if (cirbuf_del_buf_tail(&cb, 0) == 0) - return -1; - /* null cirbuf */ - if (cirbuf_get_buf_head(0, 0, 0) == 0) - return -1; - if (cirbuf_get_buf_tail(0, 0, 0) == 0) - return -1; - /* null buffer */ - if (cirbuf_get_buf_head(&cb, 0, 0) == 0) - return -1; - if (cirbuf_get_buf_tail(&cb, 0, 0) == 0) - return -1; - /* null size, this is valid but should return 0 */ - if (cirbuf_get_buf_head(&cb, buf, 0) != 0) - return -1; - if (cirbuf_get_buf_tail(&cb, buf, 0) != 0) - return -1; - /* null cirbuf */ - if (cirbuf_align_left(0) == 0) - return -1; - if (cirbuf_align_right(0) == 0) - return -1; - - return 0; -} - -/* test cmdline_cirbuf char functions */ -int -test_cirbuf_char(void) -{ - int ret; - - ret = test_cirbuf_char_add_del(); - if (ret < 0) - return -1; - - ret = test_cirbuf_char_fill(); - if (ret < 0) - return -1; - - return 0; -} - -/* test cmdline_cirbuf string functions */ -int -test_cirbuf_string(void) -{ - if (test_cirbuf_string_add_del() < 0) - return -1; - - if (test_cirbuf_string_add_del_reverse() < 0) - return -1; - - if (test_cirbuf_string_add_boundaries() < 0) - return -1; - - if (test_cirbuf_string_get_del_boundaries() < 0) - return -1; - - if (test_cirbuf_string_get_del_partial() < 0) - return -1; - - if (test_cirbuf_string_misc() < 0) - return -1; - - return 0; -} - -/* test cmdline_cirbuf align functions */ -int -test_cirbuf_align(void) -{ - if (test_cirbuf_align_left() < 0) - return -1; - if (test_cirbuf_align_right() < 0) - return -1; - return 0; -} diff --git a/app/test/test_cmdline_etheraddr.c b/app/test/test_cmdline_etheraddr.c deleted file mode 100644 index e4f42317f2..0000000000 --- a/app/test/test_cmdline_etheraddr.c +++ /dev/null @@ -1,247 +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 -#include -#include - -#include -#include - -#include -#include - -#include "test_cmdline.h" - -struct ether_addr_str { - const char * str; - uint64_t address; -}; - -/* valid strings */ -const struct ether_addr_str ether_addr_valid_strs[] = { - {"01:23:45:67:89:AB", 0xAB8967452301ULL}, - {"4567:89AB:CDEF", 0xEFCDAB896745ULL}, -}; - -/* valid strings with various garbage at the end. - * these strings are still valid because parser checks for - * end of token, which is either space chars, null char or - * a hash sign. - */ -const char * ether_addr_garbage_strs[] = { - "00:11:22:33:44:55\0garbage", - "00:11:22:33:44:55#garbage", - "00:11:22:33:44:55 garbage", - "00:11:22:33:44:55\tgarbage", - "00:11:22:33:44:55\ngarbage", - "00:11:22:33:44:55\rgarbage", - "00:11:22:33:44:55#", - "00:11:22:33:44:55 ", - "00:11:22:33:44:55\t", - "00:11:22:33:44:55\n", - "00:11:22:33:44:55\r", -}; -#define GARBAGE_ETHERADDR 0x554433221100ULL /* corresponding address */ - - -const char * ether_addr_invalid_strs[] = { - /* valid chars, invalid syntax */ - "0123:45:67:89:AB", - "01:23:4567:89:AB", - "01:23:45:67:89AB", - "012:345:678:9AB", - "01:23:45:67:89:ABC", - "01:23:45:67:89:A", - "01:23:45:67:89", - "01:23:45:67:89:AB:CD", - /* invalid chars, valid syntax */ - "IN:VA:LI:DC:HA:RS", - "INVA:LIDC:HARS", - /* misc */ - "01 23 45 67 89 AB", - "01.23.45.67.89.AB", - "01,23,45,67,89,AB", - "01:23:45\0:67:89:AB", - "01:23:45#:67:89:AB", - "random invalid text", - "random text", - "", - "\0", - " ", -}; - -#define ETHERADDR_VALID_STRS_SIZE \ - (sizeof(ether_addr_valid_strs) / sizeof(ether_addr_valid_strs[0])) -#define ETHERADDR_GARBAGE_STRS_SIZE \ - (sizeof(ether_addr_garbage_strs) / sizeof(ether_addr_garbage_strs[0])) -#define ETHERADDR_INVALID_STRS_SIZE \ - (sizeof(ether_addr_invalid_strs) / sizeof(ether_addr_invalid_strs[0])) - - - -static int -is_addr_different(const struct ether_addr addr, uint64_t num) -{ - int i; - for (i = 0; i < ETHER_ADDR_LEN; i++, num >>= 8) - if (addr.addr_bytes[i] != (num & 0xFF)) { - return 1; - } - return 0; -} - -/* test invalid parameters */ -int -test_parse_etheraddr_invalid_param(void) -{ - char buf[CMDLINE_TEST_BUFSIZE]; - struct ether_addr result; - int ret = 0; - - /* try all null */ - ret = cmdline_parse_etheraddr(NULL, NULL, NULL, 0); - if (ret != -1) { - printf("Error: parser accepted null parameters!\n"); - return -1; - } - - /* try null buf */ - ret = cmdline_parse_etheraddr(NULL, NULL, (void*)&result, - sizeof(result)); - if (ret != -1) { - printf("Error: parser accepted null string!\n"); - return -1; - } - - /* try null result */ - - /* copy string to buffer */ - snprintf(buf, sizeof(buf), "%s", - ether_addr_valid_strs[0].str); - - ret = cmdline_parse_etheraddr(NULL, buf, NULL, 0); - if (ret == -1) { - printf("Error: parser rejected null result!\n"); - return -1; - } - - /* token is not used in ether_parse anyway so there's no point in - * testing it */ - - /* test help function */ - memset(&buf, 0, sizeof(buf)); - - /* coverage! */ - ret = cmdline_get_help_etheraddr(NULL, buf, sizeof(buf)); - if (ret < 0) { - printf("Error: help function failed with valid parameters!\n"); - return -1; - } - - return 0; -} - -/* test valid parameters but invalid data */ -int -test_parse_etheraddr_invalid_data(void) -{ - int ret = 0; - unsigned i; - struct ether_addr result; - - /* test full strings */ - for (i = 0; i < ETHERADDR_INVALID_STRS_SIZE; i++) { - - memset(&result, 0, sizeof(struct ether_addr)); - - ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i], - (void*)&result, sizeof(result)); - if (ret != -1) { - printf("Error: parsing %s succeeded!\n", - ether_addr_invalid_strs[i]); - return -1; - } - } - - return 0; -} - -/* test valid parameters and data */ -int -test_parse_etheraddr_valid(void) -{ - int ret = 0; - unsigned i; - struct ether_addr result; - - /* test full strings */ - for (i = 0; i < ETHERADDR_VALID_STRS_SIZE; i++) { - - memset(&result, 0, sizeof(struct ether_addr)); - - ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str, - (void*)&result, sizeof(result)); - if (ret < 0) { - printf("Error: parsing %s failed!\n", - ether_addr_valid_strs[i].str); - return -1; - } - if (is_addr_different(result, ether_addr_valid_strs[i].address)) { - printf("Error: parsing %s failed: address mismatch!\n", - ether_addr_valid_strs[i].str); - return -1; - } - } - - /* test garbage strings */ - for (i = 0; i < ETHERADDR_GARBAGE_STRS_SIZE; i++) { - - memset(&result, 0, sizeof(struct ether_addr)); - - ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i], - (void*)&result, sizeof(result)); - if (ret < 0) { - printf("Error: parsing %s failed!\n", - ether_addr_garbage_strs[i]); - return -1; - } - if (is_addr_different(result, GARBAGE_ETHERADDR)) { - printf("Error: parsing %s failed: address mismatch!\n", - ether_addr_garbage_strs[i]); - return -1; - } - } - - return 0; -} diff --git a/app/test/test_cmdline_ipaddr.c b/app/test/test_cmdline_ipaddr.c deleted file mode 100644 index 471d2ff140..0000000000 --- a/app/test/test_cmdline_ipaddr.c +++ /dev/null @@ -1,722 +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 -#include -#include -#include - -#ifndef __linux__ -#ifndef __FreeBSD__ -#include -#else -#include -#endif -#endif - -#include - -#include -#include - -#include "test_cmdline.h" - -#define IP4(a,b,c,d) {((uint32_t)(((a) & 0xff)) | \ - (((b) & 0xff) << 8) | \ - (((c) & 0xff) << 16) | \ - ((d) & 0xff) << 24)} - -#define U16_SWAP(x) \ - (((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)) - -/* create IPv6 address, swapping bytes where needed */ -#ifndef s6_addr16 -# define s6_addr16 __u6_addr.__u6_addr16 -#endif -#define IP6(a,b,c,d,e,f,g,h) .ipv6 = \ - {.s6_addr16 = \ - {U16_SWAP(a),U16_SWAP(b),U16_SWAP(c),U16_SWAP(d),\ - U16_SWAP(e),U16_SWAP(f),U16_SWAP(g),U16_SWAP(h)}} - -/** these are defined in netinet/in.h but not present in linux headers */ -#ifndef NIPQUAD - -#define NIPQUAD_FMT "%u.%u.%u.%u" -#define NIPQUAD(addr) \ - (unsigned)((unsigned char *)&addr)[0], \ - (unsigned)((unsigned char *)&addr)[1], \ - (unsigned)((unsigned char *)&addr)[2], \ - (unsigned)((unsigned char *)&addr)[3] - -#define NIP6_FMT "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x" -#define NIP6(addr) \ - (unsigned)((addr).s6_addr[0]), \ - (unsigned)((addr).s6_addr[1]), \ - (unsigned)((addr).s6_addr[2]), \ - (unsigned)((addr).s6_addr[3]), \ - (unsigned)((addr).s6_addr[4]), \ - (unsigned)((addr).s6_addr[5]), \ - (unsigned)((addr).s6_addr[6]), \ - (unsigned)((addr).s6_addr[7]), \ - (unsigned)((addr).s6_addr[8]), \ - (unsigned)((addr).s6_addr[9]), \ - (unsigned)((addr).s6_addr[10]), \ - (unsigned)((addr).s6_addr[11]), \ - (unsigned)((addr).s6_addr[12]), \ - (unsigned)((addr).s6_addr[13]), \ - (unsigned)((addr).s6_addr[14]), \ - (unsigned)((addr).s6_addr[15]) - -#endif - - - -struct ipaddr_str { - const char * str; - cmdline_ipaddr_t addr; - unsigned flags; -}; - -const struct ipaddr_str ipaddr_valid_strs[] = { - {"0.0.0.0", {AF_INET, {IP4(0,0,0,0)}, 0}, - CMDLINE_IPADDR_V4}, - {"0.0.0.0/0", {AF_INET, {IP4(0,0,0,0)}, 0}, - CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, - {"0.0.0.0/24", {AF_INET, {IP4(0,0,0,0)}, 24}, - CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, - {"192.168.1.0/24", {AF_INET, {IP4(192,168,1,0)}, 24}, - CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, - {"012.34.56.78/24", {AF_INET, {IP4(12,34,56,78)}, 24}, - CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, - {"34.56.78.90/1", {AF_INET, {IP4(34,56,78,90)}, 1}, - CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, - {"::", {AF_INET6, {IP6(0,0,0,0,0,0,0,0)}, 0}, - CMDLINE_IPADDR_V6}, - {"::1", {AF_INET6, {IP6(0,0,0,0,0,0,0,1)}, 0}, - CMDLINE_IPADDR_V6}, - {"::1/32", {AF_INET6, {IP6(0,0,0,0,0,0,0,1)}, 32}, - CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, - {"::/32", {AF_INET6, {IP6(0,0,0,0,0,0,0,0)}, 32}, - CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, - /* RFC5952 requests that only lowercase should be used */ - {"1234:5678:90ab:cdef:4321:8765:BA09:FEDC", {AF_INET6, - {IP6(0x1234,0x5678,0x90AB,0xCDEF,0x4321,0x8765,0xBA09,0xFEDC)}, - 0}, - CMDLINE_IPADDR_V6}, - {"1234::1234/64", {AF_INET6, - {IP6(0x1234,0,0,0,0,0,0,0x1234)}, - 64}, - CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, - {"1234::/64", {AF_INET6, - {IP6(0x1234,0,0,0,0,0,0,0)}, - 64}, - CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, - {"1:1::1/32", {AF_INET6, - {IP6(1,1,0,0,0,0,0,1)}, - 32}, - CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, - {"1:2:3:4::/64", {AF_INET6, - {IP6(1,2,3,4,0,0,0,0)}, - 64}, - CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, - {"::ffff:192.168.1.0/64", {AF_INET6, - {IP6(0,0,0,0,0,0xFFFF,0xC0A8,0x100)}, - 64}, - CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, - /* RFC5952 requests not using :: to skip one block of zeros*/ - {"1::2:3:4:5:6:7", {AF_INET6, - {IP6(1,0,2,3,4,5,6,7)}, - 0}, - CMDLINE_IPADDR_V6}, -}; - -const char * ipaddr_garbage_addr4_strs[] = { - /* IPv4 */ - "192.168.1.0 garbage", - "192.168.1.0\0garbage", - "192.168.1.0#garbage", - "192.168.1.0\tgarbage", - "192.168.1.0\rgarbage", - "192.168.1.0\ngarbage", -}; -#define IPv4_GARBAGE_ADDR IP4(192,168,1,0) - -const char * ipaddr_garbage_addr6_strs[] = { - /* IPv6 */ - "1:2:3:4::8 garbage", - "1:2:3:4::8#garbage", - "1:2:3:4::8\0garbage", - "1:2:3:4::8\rgarbage", - "1:2:3:4::8\ngarbage", - "1:2:3:4::8\tgarbage", -}; -#define IPv6_GARBAGE_ADDR {IP6(1,2,3,4,0,0,0,8)} - -const char * ipaddr_garbage_network4_strs[] = { - /* IPv4 */ - "192.168.1.0/24 garbage", - "192.168.1.0/24\0garbage", - "192.168.1.0/24#garbage", - "192.168.1.0/24\tgarbage", - "192.168.1.0/24\rgarbage", - "192.168.1.0/24\ngarbage", -}; -#define IPv4_GARBAGE_PREFIX 24 - -const char * ipaddr_garbage_network6_strs[] = { - /* IPv6 */ - "1:2:3:4::8/64 garbage", - "1:2:3:4::8/64#garbage", - "1:2:3:4::8/64\0garbage", - "1:2:3:4::8/64\rgarbage", - "1:2:3:4::8/64\ngarbage", - "1:2:3:4::8/64\tgarbage", -}; -#define IPv6_GARBAGE_PREFIX 64 - - - -const char * ipaddr_invalid_strs[] = { - /** IPv4 **/ - - /* invalid numbers */ - "0.0.0.-1", - "0.0.-1.0", - "0.-1.0.0", - "-1.0.0.0", - "0.0.0.-1/24", - "256.123.123.123", - "255.256.123.123", - "255.255.256.123", - "255.255.255.256", - "256.123.123.123/24", - "255.256.123.123/24", - "255.255.256.123/24", - "255.255.255.256/24", - /* invalid network mask */ - "1.2.3.4/33", - "1.2.3.4/33231313", - "1.2.3.4/-1", - "1.2.3.4/24/33", - "1.2.3.4/24/-1", - "1.2.3.4/24/", - /* wrong format */ - "1/24" - "/24" - "123.123.123", - "123.123.123.", - "123.123.123.123.", - "123.123.123..123", - "123.123.123.123.123", - ".123.123.123", - ".123.123.123.123", - "123.123.123/24", - "123.123.123./24", - "123.123.123.123./24", - "123.123.123..123/24", - "123.123.123.123.123/24", - ".123.123.123/24", - ".123.123.123.123/24", - /* invalid characters */ - "123.123.123.12F", - "123.123.12F.123", - "123.12F.123.123", - "12F.123.123.123", - "12J.123.123.123", - "123,123,123,123", - "123!123!123!12F", - "123.123.123.123/4F", - - /** IPv6 **/ - - /* wrong format */ - "::fffff", - "ffff:", - "1:2:3:4:5:6:7:192.168.1.1", - "1234:192.168.1.1:ffff::", - "1:2:3:4:5:6:7:890ab", - "1:2:3:4:5:6:7890a:b", - "1:2:3:4:5:67890:a:b", - "1:2:3:4:56789:0:a:b", - "1:2:3:45678:9:0:a:b", - "1:2:34567:8:9:0:a:b", - "1:23456:7:8:9:0:a:b", - "12345:6:7:8:9:0:a:b", - "1:::2", - "1::::2", - "::fffff/64", - "1::2::3", - "1::2::3/64", - ":1:2", - ":1:2/64", - ":1::2", - ":1::2/64", - "1::2:3:4:5:6:7:8/64", - - /* invalid network mask */ - "1:2:3:4:5:6:7:8/129", - "1:2:3:4:5:6:7:8/-1", - - /* invalid characters */ - "a:b:c:d:e:f:g::", - - /** misc **/ - - /* too long */ - "1234:1234:1234:1234:1234:1234:1234:1234:1234:1234:1234" - "random invalid text", - "", - "\0", - " ", -}; - -#define IPADDR_VALID_STRS_SIZE \ - (sizeof(ipaddr_valid_strs) / sizeof(ipaddr_valid_strs[0])) -#define IPADDR_GARBAGE_ADDR4_STRS_SIZE \ - (sizeof(ipaddr_garbage_addr4_strs) / sizeof(ipaddr_garbage_addr4_strs[0])) -#define IPADDR_GARBAGE_ADDR6_STRS_SIZE \ - (sizeof(ipaddr_garbage_addr6_strs) / sizeof(ipaddr_garbage_addr6_strs[0])) -#define IPADDR_GARBAGE_NETWORK4_STRS_SIZE \ - (sizeof(ipaddr_garbage_network4_strs) / sizeof(ipaddr_garbage_network4_strs[0])) -#define IPADDR_GARBAGE_NETWORK6_STRS_SIZE \ - (sizeof(ipaddr_garbage_network6_strs) / sizeof(ipaddr_garbage_network6_strs[0])) -#define IPADDR_INVALID_STRS_SIZE \ - (sizeof(ipaddr_invalid_strs) / sizeof(ipaddr_invalid_strs[0])) - -static void -dump_addr(cmdline_ipaddr_t addr) -{ - switch (addr.family) { - case AF_INET: - { - printf(NIPQUAD_FMT " prefixlen=%u\n", - NIPQUAD(addr.addr.ipv4.s_addr), addr.prefixlen); - break; - } - case AF_INET6: - { - printf(NIP6_FMT " prefixlen=%u\n", - NIP6(addr.addr.ipv6), addr.prefixlen); - break; - } - default: - printf("Can't dump: unknown address family.\n"); - return; - } -} - - -static int -is_addr_different(cmdline_ipaddr_t addr1, cmdline_ipaddr_t addr2) -{ - if (addr1.family != addr2.family) - return 1; - - if (addr1.prefixlen != addr2.prefixlen) - return 1; - - switch (addr1.family) { - /* IPv4 */ - case AF_INET: - if (memcmp(&addr1.addr.ipv4, &addr2.addr.ipv4, - sizeof(struct in_addr)) != 0) - return 1; - break; - /* IPv6 */ - case AF_INET6: - { - if (memcmp(&addr1.addr.ipv6, &addr2.addr.ipv6, - sizeof(struct in6_addr)) != 0) - return 1; - break; - } - /* thing that should not be */ - default: - return -1; - } - return 0; -} - -static int -can_parse_addr(unsigned addr_flags, unsigned test_flags) -{ - if ((test_flags & addr_flags) == addr_flags) { - /* if we are not trying to parse network addresses */ - if (test_flags < CMDLINE_IPADDR_NETWORK) - return 1; - /* if this is a network address */ - else if (addr_flags & CMDLINE_IPADDR_NETWORK) - return 1; - } - return 0; -} - -int -test_parse_ipaddr_valid(void) -{ - cmdline_parse_token_ipaddr_t token; - char buf[CMDLINE_TEST_BUFSIZE]; - cmdline_ipaddr_t result; - unsigned i; - uint8_t flags; - int ret; - - /* cover all cases in help */ - for (flags = 0x1; flags < 0x8; flags++) { - token.ipaddr_data.flags = flags; - - memset(buf, 0, sizeof(buf)); - - if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)) == -1) { - printf("Error: help rejected valid parameters!\n"); - return -1; - } - } - - /* test valid strings */ - for (i = 0; i < IPADDR_VALID_STRS_SIZE; i++) { - - /* test each valid string against different flags */ - for (flags = 1; flags < 0x8; flags++) { - - /* skip bad flag */ - if (flags == CMDLINE_IPADDR_NETWORK) - continue; - - /* clear out everything */ - memset(buf, 0, sizeof(buf)); - memset(&result, 0, sizeof(result)); - memset(&token, 0, sizeof(token)); - - token.ipaddr_data.flags = flags; - - cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - ipaddr_valid_strs[i].str, (void*)&result, - sizeof(result)); - - /* if should have passed, or should have failed */ - if ((ret < 0) == - (can_parse_addr(ipaddr_valid_strs[i].flags, flags))) { - printf("Error: unexpected behavior when parsing %s as %s!\n", - ipaddr_valid_strs[i].str, buf); - printf("Parsed result: "); - dump_addr(result); - printf("Expected result: "); - dump_addr(ipaddr_valid_strs[i].addr); - return -1; - } - if (ret != -1 && - is_addr_different(result, ipaddr_valid_strs[i].addr)) { - printf("Error: result mismatch when parsing %s as %s!\n", - ipaddr_valid_strs[i].str, buf); - printf("Parsed result: "); - dump_addr(result); - printf("Expected result: "); - dump_addr(ipaddr_valid_strs[i].addr); - return -1; - } - } - } - - /* test garbage ipv4 address strings */ - for (i = 0; i < IPADDR_GARBAGE_ADDR4_STRS_SIZE; i++) { - - struct in_addr tmp = IPv4_GARBAGE_ADDR; - - /* test each valid string against different flags */ - for (flags = 1; flags < 0x8; flags++) { - - /* skip bad flag */ - if (flags == CMDLINE_IPADDR_NETWORK) - continue; - - /* clear out everything */ - memset(buf, 0, sizeof(buf)); - memset(&result, 0, sizeof(result)); - memset(&token, 0, sizeof(token)); - - token.ipaddr_data.flags = flags; - - cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - ipaddr_garbage_addr4_strs[i], (void*)&result, - sizeof(result)); - - /* if should have passed, or should have failed */ - if ((ret < 0) == - (can_parse_addr(CMDLINE_IPADDR_V4, flags))) { - printf("Error: unexpected behavior when parsing %s as %s!\n", - ipaddr_garbage_addr4_strs[i], buf); - return -1; - } - if (ret != -1 && - memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) { - printf("Error: result mismatch when parsing %s as %s!\n", - ipaddr_garbage_addr4_strs[i], buf); - return -1; - } - } - } - - /* test garbage ipv6 address strings */ - for (i = 0; i < IPADDR_GARBAGE_ADDR6_STRS_SIZE; i++) { - - cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR}; - - /* test each valid string against different flags */ - for (flags = 1; flags < 0x8; flags++) { - - /* skip bad flag */ - if (flags == CMDLINE_IPADDR_NETWORK) - continue; - - /* clear out everything */ - memset(buf, 0, sizeof(buf)); - memset(&result, 0, sizeof(result)); - memset(&token, 0, sizeof(token)); - - token.ipaddr_data.flags = flags; - - cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - ipaddr_garbage_addr6_strs[i], (void*)&result, - sizeof(result)); - - /* if should have passed, or should have failed */ - if ((ret < 0) == - (can_parse_addr(CMDLINE_IPADDR_V6, flags))) { - printf("Error: unexpected behavior when parsing %s as %s!\n", - ipaddr_garbage_addr6_strs[i], buf); - return -1; - } - if (ret != -1 && - memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) { - printf("Error: result mismatch when parsing %s as %s!\n", - ipaddr_garbage_addr6_strs[i], buf); - return -1; - } - } - } - - - /* test garbage ipv4 network strings */ - for (i = 0; i < IPADDR_GARBAGE_NETWORK4_STRS_SIZE; i++) { - - struct in_addr tmp = IPv4_GARBAGE_ADDR; - - /* test each valid string against different flags */ - for (flags = 1; flags < 0x8; flags++) { - - /* skip bad flag */ - if (flags == CMDLINE_IPADDR_NETWORK) - continue; - - /* clear out everything */ - memset(buf, 0, sizeof(buf)); - memset(&result, 0, sizeof(result)); - memset(&token, 0, sizeof(token)); - - token.ipaddr_data.flags = flags; - - cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - ipaddr_garbage_network4_strs[i], (void*)&result, - sizeof(result)); - - /* if should have passed, or should have failed */ - if ((ret < 0) == - (can_parse_addr(CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK, flags))) { - printf("Error: unexpected behavior when parsing %s as %s!\n", - ipaddr_garbage_network4_strs[i], buf); - return -1; - } - if (ret != -1 && - memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) { - printf("Error: result mismatch when parsing %s as %s!\n", - ipaddr_garbage_network4_strs[i], buf); - return -1; - } - } - } - - /* test garbage ipv6 address strings */ - for (i = 0; i < IPADDR_GARBAGE_NETWORK6_STRS_SIZE; i++) { - - cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR}; - - /* test each valid string against different flags */ - for (flags = 1; flags < 0x8; flags++) { - - /* skip bad flag */ - if (flags == CMDLINE_IPADDR_NETWORK) - continue; - - /* clear out everything */ - memset(buf, 0, sizeof(buf)); - memset(&result, 0, sizeof(result)); - memset(&token, 0, sizeof(token)); - - token.ipaddr_data.flags = flags; - - cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - ipaddr_garbage_network6_strs[i], (void*)&result, - sizeof(result)); - - /* if should have passed, or should have failed */ - if ((ret < 0) == - (can_parse_addr(CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK, flags))) { - printf("Error: unexpected behavior when parsing %s as %s!\n", - ipaddr_garbage_network6_strs[i], buf); - return -1; - } - if (ret != -1 && - memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) { - printf("Error: result mismatch when parsing %s as %s!\n", - ipaddr_garbage_network6_strs[i], buf); - return -1; - } - } - } - - return 0; -} - -int -test_parse_ipaddr_invalid_data(void) -{ - cmdline_parse_token_ipaddr_t token; - char buf[CMDLINE_TEST_BUFSIZE]; - cmdline_ipaddr_t result; - unsigned i; - uint8_t flags; - int ret; - - memset(&result, 0, sizeof(result)); - - /* test invalid strings */ - for (i = 0; i < IPADDR_INVALID_STRS_SIZE; i++) { - - /* test each valid string against different flags */ - for (flags = 1; flags < 0x8; flags++) { - - /* skip bad flag */ - if (flags == CMDLINE_IPADDR_NETWORK) - continue; - - /* clear out everything */ - memset(buf, 0, sizeof(buf)); - memset(&token, 0, sizeof(token)); - - token.ipaddr_data.flags = flags; - - cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - ipaddr_invalid_strs[i], (void*)&result, - sizeof(result)); - - if (ret != -1) { - printf("Error: parsing %s as %s succeeded!\n", - ipaddr_invalid_strs[i], buf); - printf("Parsed result: "); - dump_addr(result); - return -1; - } - } - } - - return 0; -} - -int -test_parse_ipaddr_invalid_param(void) -{ - cmdline_parse_token_ipaddr_t token; - char buf[CMDLINE_TEST_BUFSIZE]; - cmdline_ipaddr_t result; - - snprintf(buf, sizeof(buf), "1.2.3.4"); - token.ipaddr_data.flags = CMDLINE_IPADDR_V4; - - /* null token */ - if (cmdline_parse_ipaddr(NULL, buf, (void*)&result, - sizeof(result)) != -1) { - printf("Error: parser accepted invalid parameters!\n"); - return -1; - } - /* null buffer */ - if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - NULL, (void*)&result, sizeof(result)) != -1) { - printf("Error: parser accepted invalid parameters!\n"); - return -1; - } - /* empty buffer */ - if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - "", (void*)&result, sizeof(result)) != -1) { - printf("Error: parser accepted invalid parameters!\n"); - return -1; - } - /* null result */ - if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, - buf, NULL, 0) == -1) { - printf("Error: parser rejected null result!\n"); - return -1; - } - - /* null token */ - if (cmdline_get_help_ipaddr(NULL, buf, 0) != -1) { - printf("Error: help accepted invalid parameters!\n"); - return -1; - } - /* null buffer */ - if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, - NULL, 0) != -1) { - printf("Error: help accepted invalid parameters!\n"); - return -1; - } - return 0; -} diff --git a/app/test/test_cmdline_lib.c b/app/test/test_cmdline_lib.c deleted file mode 100644 index 65b823a726..0000000000 --- a/app/test/test_cmdline_lib.c +++ /dev/null @@ -1,263 +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "test_cmdline.h" - -/****************************************************************/ -/* static functions required for some tests */ -static void -valid_buffer(__attribute__((unused))struct rdline *rdl, - __attribute__((unused))const char *buf, - __attribute__((unused)) unsigned int size) -{ -} - -static int -complete_buffer(__attribute__((unused)) struct rdline *rdl, - __attribute__((unused)) const char *buf, - __attribute__((unused)) char *dstbuf, - __attribute__((unused)) unsigned int dstsize, - __attribute__((unused)) int *state) -{ - return 0; -} - -/****************************************************************/ - -static int -test_cmdline_parse_fns(void) -{ - struct cmdline cl; - int i = 0; - char dst[CMDLINE_TEST_BUFSIZE]; - - if (cmdline_parse(NULL, "buffer") >= 0) - goto error; - if (cmdline_parse(&cl, NULL) >= 0) - goto error; - - if (cmdline_complete(NULL, "buffer", &i, dst, sizeof(dst)) >= 0) - goto error; - if (cmdline_complete(&cl, NULL, &i, dst, sizeof(dst)) >= 0) - goto error; - if (cmdline_complete(&cl, "buffer", NULL, dst, sizeof(dst)) >= 0) - goto error; - if (cmdline_complete(&cl, "buffer", &i, NULL, sizeof(dst)) >= 0) - goto error; - - return 0; - -error: - printf("Error: function accepted null parameter!\n"); - return -1; -} - -static int -test_cmdline_rdline_fns(void) -{ - struct rdline rdl; - rdline_write_char_t *wc = &cmdline_write_char; - rdline_validate_t *v = &valid_buffer; - rdline_complete_t *c = &complete_buffer; - - if (rdline_init(NULL, wc, v, c) >= 0) - goto error; - if (rdline_init(&rdl, NULL, v, c) >= 0) - goto error; - if (rdline_init(&rdl, wc, NULL, c) >= 0) - goto error; - if (rdline_init(&rdl, wc, v, NULL) >= 0) - goto error; - if (rdline_char_in(NULL, 0) >= 0) - goto error; - if (rdline_get_buffer(NULL) != NULL) - goto error; - if (rdline_add_history(NULL, "history") >= 0) - goto error; - if (rdline_add_history(&rdl, NULL) >= 0) - goto error; - if (rdline_get_history_item(NULL, 0) != NULL) - goto error; - - /* void functions */ - rdline_newline(NULL, "prompt"); - rdline_newline(&rdl, NULL); - rdline_stop(NULL); - rdline_quit(NULL); - rdline_restart(NULL); - rdline_redisplay(NULL); - rdline_reset(NULL); - rdline_clear_history(NULL); - - return 0; - -error: - printf("Error: function accepted null parameter!\n"); - return -1; -} - -static int -test_cmdline_vt100_fns(void) -{ - if (vt100_parser(NULL, 0) >= 0) { - printf("Error: function accepted null parameter!\n"); - return -1; - } - - /* void functions */ - vt100_init(NULL); - - return 0; -} - -static int -test_cmdline_socket_fns(void) -{ - cmdline_parse_ctx_t ctx; - - if (cmdline_stdin_new(NULL, "prompt") != NULL) - goto error; - if (cmdline_stdin_new(&ctx, NULL) != NULL) - goto error; - if (cmdline_file_new(NULL, "prompt", "/dev/null") != NULL) - goto error; - if (cmdline_file_new(&ctx, NULL, "/dev/null") != NULL) - goto error; - if (cmdline_file_new(&ctx, "prompt", NULL) != NULL) - goto error; - if (cmdline_file_new(&ctx, "prompt", "-/invalid/~/path") != NULL) { - printf("Error: succeeded in opening invalid file for reading!"); - return -1; - } - if (cmdline_file_new(&ctx, "prompt", "/dev/null") == NULL) { - printf("Error: failed to open /dev/null for reading!"); - return -1; - } - - /* void functions */ - cmdline_stdin_exit(NULL); - - return 0; -error: - printf("Error: function accepted null parameter!\n"); - return -1; -} - -static int -test_cmdline_fns(void) -{ - cmdline_parse_ctx_t ctx; - struct cmdline cl, *tmp; - - memset(&ctx, 0, sizeof(ctx)); - tmp = cmdline_new(&ctx, "test", -1, -1); - if (tmp == NULL) - goto error; - - if (cmdline_new(NULL, "prompt", 0, 0) != NULL) - goto error; - if (cmdline_new(&ctx, NULL, 0, 0) != NULL) - goto error; - if (cmdline_in(NULL, "buffer", CMDLINE_TEST_BUFSIZE) >= 0) - goto error; - if (cmdline_in(&cl, NULL, CMDLINE_TEST_BUFSIZE) >= 0) - goto error; - if (cmdline_write_char(NULL, 0) >= 0) - goto error; - - /* void functions */ - cmdline_set_prompt(NULL, "prompt"); - cmdline_free(NULL); - cmdline_printf(NULL, "format"); - /* this should fail as stream handles are invalid */ - cmdline_printf(tmp, "format"); - cmdline_interact(NULL); - cmdline_quit(NULL); - - /* check if void calls change anything when they should fail */ - cl = *tmp; - - cmdline_printf(&cl, NULL); - if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch; - cmdline_set_prompt(&cl, NULL); - if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch; - cmdline_in(&cl, NULL, CMDLINE_TEST_BUFSIZE); - if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch; - - cmdline_free(tmp); - - return 0; - -error: - printf("Error: function accepted null parameter!\n"); - return -1; -mismatch: - printf("Error: data changed!\n"); - return -1; -} - -/* test library functions. the point of these tests is not so much to test - * functions' behaviour as it is to make sure there are no segfaults if - * they are called with invalid parameters. - */ -int -test_cmdline_lib(void) -{ - if (test_cmdline_parse_fns() < 0) - return -1; - if (test_cmdline_rdline_fns() < 0) - return -1; - if (test_cmdline_vt100_fns() < 0) - return -1; - if (test_cmdline_socket_fns() < 0) - return -1; - if (test_cmdline_fns() < 0) - return -1; - return 0; -} diff --git a/app/test/test_cmdline_num.c b/app/test/test_cmdline_num.c deleted file mode 100644 index 04263d39e9..0000000000 --- a/app/test/test_cmdline_num.c +++ /dev/null @@ -1,622 +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 -#include -#include - -#include - -#include -#include - -#include "test_cmdline.h" - -struct num_unsigned_str { - const char * str; - uint64_t result; -}; - -struct num_signed_str { - const char * str; - int64_t result; -}; - -const struct num_unsigned_str num_valid_positive_strs[] = { - /* decimal positive */ - {"0", 0 }, - {"127", INT8_MAX }, - {"128", INT8_MAX + 1 }, - {"255", UINT8_MAX }, - {"256", UINT8_MAX + 1 }, - {"32767", INT16_MAX }, - {"32768", INT16_MAX + 1 }, - {"65535", UINT16_MAX }, - {"65536", UINT16_MAX + 1 }, - {"2147483647", INT32_MAX }, - {"2147483648", INT32_MAX + 1U }, - {"4294967295", UINT32_MAX }, - {"4294967296", UINT32_MAX + 1ULL }, - {"9223372036854775807", INT64_MAX }, - {"9223372036854775808", INT64_MAX + 1ULL}, - {"18446744073709551615", UINT64_MAX }, - /* hexadecimal (no leading zeroes) */ - {"0x0", 0 }, - {"0x7F", INT8_MAX }, - {"0x80", INT8_MAX + 1 }, - {"0xFF", UINT8_MAX }, - {"0x100", UINT8_MAX + 1 }, - {"0x7FFF", INT16_MAX }, - {"0x8000", INT16_MAX + 1 }, - {"0xFFFF", UINT16_MAX }, - {"0x10000", UINT16_MAX + 1 }, - {"0x7FFFFFFF", INT32_MAX }, - {"0x80000000", INT32_MAX + 1U }, - {"0xFFFFFFFF", UINT32_MAX }, - {"0x100000000", UINT32_MAX + 1ULL }, - {"0x7FFFFFFFFFFFFFFF", INT64_MAX }, - {"0x8000000000000000", INT64_MAX + 1ULL}, - {"0xFFFFFFFFFFFFFFFF", UINT64_MAX }, - /* hexadecimal (with leading zeroes) */ - {"0x00", 0 }, - {"0x7F", INT8_MAX }, - {"0x80", INT8_MAX + 1 }, - {"0xFF", UINT8_MAX }, - {"0x0100", UINT8_MAX + 1 }, - {"0x7FFF", INT16_MAX }, - {"0x8000", INT16_MAX + 1 }, - {"0xFFFF", UINT16_MAX }, - {"0x00010000", UINT16_MAX + 1 }, - {"0x7FFFFFFF", INT32_MAX }, - {"0x80000000", INT32_MAX + 1U }, - {"0xFFFFFFFF", UINT32_MAX }, - {"0x0000000100000000", UINT32_MAX + 1ULL }, - {"0x7FFFFFFFFFFFFFFF", INT64_MAX }, - {"0x8000000000000000", INT64_MAX + 1ULL}, - {"0xFFFFFFFFFFFFFFFF", UINT64_MAX }, - /* check all characters */ - {"0x1234567890ABCDEF", 0x1234567890ABCDEFULL }, - {"0x1234567890abcdef", 0x1234567890ABCDEFULL }, - /* binary (no leading zeroes) */ - {"0b0", 0 }, - {"0b1111111", INT8_MAX }, - {"0b10000000", INT8_MAX + 1 }, - {"0b11111111", UINT8_MAX }, - {"0b100000000", UINT8_MAX + 1 }, - {"0b111111111111111", INT16_MAX }, - {"0b1000000000000000", INT16_MAX + 1 }, - {"0b1111111111111111", UINT16_MAX }, - {"0b10000000000000000", UINT16_MAX + 1 }, - {"0b1111111111111111111111111111111", INT32_MAX }, - {"0b10000000000000000000000000000000", INT32_MAX + 1U }, - {"0b11111111111111111111111111111111", UINT32_MAX }, - {"0b100000000000000000000000000000000", UINT32_MAX + 1ULL }, - {"0b111111111111111111111111111111111111111111111111111111111111111", - INT64_MAX }, - {"0b1000000000000000000000000000000000000000000000000000000000000000", - INT64_MAX + 1ULL}, - {"0b1111111111111111111111111111111111111111111111111111111111111111", - UINT64_MAX }, - /* binary (with leading zeroes) */ - {"0b01111111", INT8_MAX }, - {"0b0000000100000000", UINT8_MAX + 1 }, - {"0b0111111111111111", INT16_MAX }, - {"0b00000000000000010000000000000000", UINT16_MAX + 1 }, - {"0b01111111111111111111111111111111", INT32_MAX }, - {"0b0000000000000000000000000000000100000000000000000000000000000000", - UINT32_MAX + 1ULL }, - {"0b0111111111111111111111111111111111111111111111111111111111111111", - INT64_MAX }, - /* octal */ - {"00", 0 }, - {"0177", INT8_MAX }, - {"0200", INT8_MAX + 1 }, - {"0377", UINT8_MAX }, - {"0400", UINT8_MAX + 1 }, - {"077777", INT16_MAX }, - {"0100000", INT16_MAX + 1 }, - {"0177777", UINT16_MAX }, - {"0200000", UINT16_MAX + 1 }, - {"017777777777", INT32_MAX }, - {"020000000000", INT32_MAX + 1U }, - {"037777777777", UINT32_MAX }, - {"040000000000", UINT32_MAX + 1ULL }, - {"0777777777777777777777", INT64_MAX }, - {"01000000000000000000000", INT64_MAX + 1ULL}, - {"01777777777777777777777", UINT64_MAX }, - /* check all numbers */ - {"012345670", 012345670 }, - {"076543210", 076543210 }, -}; - -const struct num_signed_str num_valid_negative_strs[] = { - /* deciman negative */ - {"-128", INT8_MIN }, - {"-129", INT8_MIN - 1 }, - {"-32768", INT16_MIN }, - {"-32769", INT16_MIN - 1 }, - {"-2147483648", INT32_MIN }, - {"-2147483649", INT32_MIN - 1LL }, - {"-9223372036854775808", INT64_MIN }, -}; - -const struct num_unsigned_str num_garbage_positive_strs[] = { - /* valid strings with garbage on the end, should still be valid */ - /* decimal */ - {"9223372036854775807\0garbage", INT64_MAX }, - {"9223372036854775807\tgarbage", INT64_MAX }, - {"9223372036854775807\rgarbage", INT64_MAX }, - {"9223372036854775807\ngarbage", INT64_MAX }, - {"9223372036854775807#garbage", INT64_MAX }, - {"9223372036854775807 garbage", INT64_MAX }, - /* hex */ - {"0x7FFFFFFFFFFFFFFF\0garbage", INT64_MAX }, - {"0x7FFFFFFFFFFFFFFF\tgarbage", INT64_MAX }, - {"0x7FFFFFFFFFFFFFFF\rgarbage", INT64_MAX }, - {"0x7FFFFFFFFFFFFFFF\ngarbage", INT64_MAX }, - {"0x7FFFFFFFFFFFFFFF#garbage", INT64_MAX }, - {"0x7FFFFFFFFFFFFFFF garbage", INT64_MAX }, - /* binary */ - {"0b1111111111111111111111111111111\0garbage", INT32_MAX }, - {"0b1111111111111111111111111111111\rgarbage", INT32_MAX }, - {"0b1111111111111111111111111111111\tgarbage", INT32_MAX }, - {"0b1111111111111111111111111111111\ngarbage", INT32_MAX }, - {"0b1111111111111111111111111111111#garbage", INT32_MAX }, - {"0b1111111111111111111111111111111 garbage", INT32_MAX }, - /* octal */ - {"01777777777777777777777\0garbage", UINT64_MAX }, - {"01777777777777777777777\rgarbage", UINT64_MAX }, - {"01777777777777777777777\tgarbage", UINT64_MAX }, - {"01777777777777777777777\ngarbage", UINT64_MAX }, - {"01777777777777777777777#garbage", UINT64_MAX }, - {"01777777777777777777777 garbage", UINT64_MAX }, -}; - -const struct num_signed_str num_garbage_negative_strs[] = { - /* valid strings with garbage on the end, should still be valid */ - {"-9223372036854775808\0garbage", INT64_MIN }, - {"-9223372036854775808\rgarbage", INT64_MIN }, - {"-9223372036854775808\tgarbage", INT64_MIN }, - {"-9223372036854775808\ngarbage", INT64_MIN }, - {"-9223372036854775808#garbage", INT64_MIN }, - {"-9223372036854775808 garbage", INT64_MIN }, -}; - -const char * num_invalid_strs[] = { - "18446744073709551616", /* out of range unsigned */ - "-9223372036854775809", /* out of range negative signed */ - "0x10000000000000000", /* out of range hex */ - /* out of range binary */ - "0b10000000000000000000000000000000000000000000000000000000000000000", - "020000000000000000000000", /* out of range octal */ - /* wrong chars */ - "0123456239", - "0x1234580AGE", - "0b0111010101g001", - "0b01110101017001", - /* false negative numbers */ - "-12345F623", - "-0x1234580A", - "-0b0111010101", - /* too long (128+ chars) */ - "0b1111000011110000111100001111000011110000111100001111000011110000" - "1111000011110000111100001111000011110000111100001111000011110000", - "1E3", - "0A", - "-B", - "+4", - "1.23G", - "", - " ", - "#", - "\r", - "\t", - "\n", - "\0", -}; - -#define NUM_POSITIVE_STRS_SIZE \ - (sizeof(num_valid_positive_strs) / sizeof(num_valid_positive_strs[0])) -#define NUM_NEGATIVE_STRS_SIZE \ - (sizeof(num_valid_negative_strs) / sizeof(num_valid_negative_strs[0])) -#define NUM_POSITIVE_GARBAGE_STRS_SIZE \ - (sizeof(num_garbage_positive_strs) / sizeof(num_garbage_positive_strs[0])) -#define NUM_NEGATIVE_GARBAGE_STRS_SIZE \ - (sizeof(num_garbage_negative_strs) / sizeof(num_garbage_negative_strs[0])) -#define NUM_INVALID_STRS_SIZE \ - (sizeof(num_invalid_strs) / sizeof(num_invalid_strs[0])) - - - -static int -can_parse_unsigned(uint64_t expected_result, enum cmdline_numtype type) -{ - switch (type) { - case UINT8: - if (expected_result > UINT8_MAX) - return 0; - break; - case UINT16: - if (expected_result > UINT16_MAX) - return 0; - break; - case UINT32: - if (expected_result > UINT32_MAX) - return 0; - break; - case INT8: - if (expected_result > INT8_MAX) - return 0; - break; - case INT16: - if (expected_result > INT16_MAX) - return 0; - break; - case INT32: - if (expected_result > INT32_MAX) - return 0; - break; - case INT64: - if (expected_result > INT64_MAX) - return 0; - break; - default: - return 1; - } - return 1; -} - -static int -can_parse_signed(int64_t expected_result, enum cmdline_numtype type) -{ - switch (type) { - case UINT8: - if (expected_result > UINT8_MAX || expected_result < 0) - return 0; - break; - case UINT16: - if (expected_result > UINT16_MAX || expected_result < 0) - return 0; - break; - case UINT32: - if (expected_result > UINT32_MAX || expected_result < 0) - return 0; - break; - case UINT64: - if (expected_result < 0) - return 0; - case INT8: - if (expected_result > INT8_MAX || expected_result < INT8_MIN) - return 0; - break; - case INT16: - if (expected_result > INT16_MAX || expected_result < INT16_MIN) - return 0; - break; - case INT32: - if (expected_result > INT32_MAX || expected_result < INT32_MIN) - return 0; - break; - default: - return 1; - } - return 1; -} - -/* test invalid parameters */ -int -test_parse_num_invalid_param(void) -{ - char buf[CMDLINE_TEST_BUFSIZE]; - uint32_t result; - cmdline_parse_token_num_t token; - int ret = 0; - - /* set up a token */ - token.num_data.type = UINT32; - - /* copy string to buffer */ - snprintf(buf, sizeof(buf), "%s", - num_valid_positive_strs[0].str); - - /* try all null */ - ret = cmdline_parse_num(NULL, NULL, NULL, 0); - if (ret != -1) { - printf("Error: parser accepted null parameters!\n"); - return -1; - } - - /* try null token */ - ret = cmdline_parse_num(NULL, buf, (void*)&result, sizeof(result)); - if (ret != -1) { - printf("Error: parser accepted null token!\n"); - return -1; - } - - /* try null buf */ - ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, NULL, - (void*)&result, sizeof(result)); - if (ret != -1) { - printf("Error: parser accepted null string!\n"); - return -1; - } - - /* try null result */ - ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, buf, - NULL, 0); - if (ret == -1) { - printf("Error: parser rejected null result!\n"); - return -1; - } - - /* test help function */ - memset(&buf, 0, sizeof(buf)); - - /* try all null */ - ret = cmdline_get_help_num(NULL, NULL, 0); - if (ret != -1) { - printf("Error: help function accepted null parameters!\n"); - return -1; - } - - /* try null token */ - ret = cmdline_get_help_num(NULL, buf, sizeof(buf)); - if (ret != -1) { - printf("Error: help function accepted null token!\n"); - return -1; - } - - /* coverage! */ - ret = cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, buf, sizeof(buf)); - if (ret < 0) { - printf("Error: help function failed with valid parameters!\n"); - return -1; - } - - return 0; -} -/* test valid parameters but invalid data */ -int -test_parse_num_invalid_data(void) -{ - enum cmdline_numtype type; - int ret = 0; - unsigned i; - char buf[CMDLINE_TEST_BUFSIZE]; - uint64_t result; /* pick largest buffer */ - cmdline_parse_token_num_t token; - - /* cycle through all possible parsed types */ - for (type = UINT8; type <= INT64; type++) { - token.num_data.type = type; - - /* test full strings */ - for (i = 0; i < NUM_INVALID_STRS_SIZE; i++) { - - memset(&result, 0, sizeof(uint64_t)); - memset(&buf, 0, sizeof(buf)); - - ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, - num_invalid_strs[i], (void*)&result, sizeof(result)); - if (ret != -1) { - /* get some info about what we are trying to parse */ - cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - printf("Error: parsing %s as %s succeeded!\n", - num_invalid_strs[i], buf); - return -1; - } - } - } - return 0; -} - -/* test valid parameters and data */ -int -test_parse_num_valid(void) -{ - int ret = 0; - enum cmdline_numtype type; - unsigned i; - char buf[CMDLINE_TEST_BUFSIZE]; - uint64_t result; - cmdline_parse_token_num_t token; - - /** valid strings **/ - - /* cycle through all possible parsed types */ - for (type = UINT8; type <= INT64; type++) { - token.num_data.type = type; - - /* test positive strings */ - for (i = 0; i < NUM_POSITIVE_STRS_SIZE; i++) { - result = 0; - memset(&buf, 0, sizeof(buf)); - - cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, - num_valid_positive_strs[i].str, - (void*)&result, sizeof(result)); - - /* if it should have passed but didn't, or if it should have failed but didn't */ - if ((ret < 0) == (can_parse_unsigned(num_valid_positive_strs[i].result, type) > 0)) { - printf("Error: parser behaves unexpectedly when parsing %s as %s!\n", - num_valid_positive_strs[i].str, buf); - return -1; - } - /* check if result matches what it should have matched - * since unsigned numbers don't care about number of bits, we can just convert - * everything to uint64_t without any worries. */ - if (ret > 0 && num_valid_positive_strs[i].result != result) { - printf("Error: parsing %s as %s failed: result mismatch!\n", - num_valid_positive_strs[i].str, buf); - return -1; - } - } - - /* test negative strings */ - for (i = 0; i < NUM_NEGATIVE_STRS_SIZE; i++) { - result = 0; - memset(&buf, 0, sizeof(buf)); - - cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, - num_valid_negative_strs[i].str, - (void*)&result, sizeof(result)); - - /* if it should have passed but didn't, or if it should have failed but didn't */ - if ((ret < 0) == (can_parse_signed(num_valid_negative_strs[i].result, type) > 0)) { - printf("Error: parser behaves unexpectedly when parsing %s as %s!\n", - num_valid_negative_strs[i].str, buf); - return -1; - } - /* check if result matches what it should have matched - * the result is signed in this case, so we have to account for that */ - if (ret > 0) { - /* detect negative */ - switch (type) { - case INT8: - result = (int8_t) result; - break; - case INT16: - result = (int16_t) result; - break; - case INT32: - result = (int32_t) result; - break; - default: - break; - } - if (num_valid_negative_strs[i].result == (int64_t) result) - continue; - printf("Error: parsing %s as %s failed: result mismatch!\n", - num_valid_negative_strs[i].str, buf); - return -1; - } - } - } - - /** garbage strings **/ - - /* cycle through all possible parsed types */ - for (type = UINT8; type <= INT64; type++) { - token.num_data.type = type; - - /* test positive garbage strings */ - for (i = 0; i < NUM_POSITIVE_GARBAGE_STRS_SIZE; i++) { - result = 0; - memset(&buf, 0, sizeof(buf)); - - cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, - num_garbage_positive_strs[i].str, - (void*)&result, sizeof(result)); - - /* if it should have passed but didn't, or if it should have failed but didn't */ - if ((ret < 0) == (can_parse_unsigned(num_garbage_positive_strs[i].result, type) > 0)) { - printf("Error: parser behaves unexpectedly when parsing %s as %s!\n", - num_garbage_positive_strs[i].str, buf); - return -1; - } - /* check if result matches what it should have matched - * since unsigned numbers don't care about number of bits, we can just convert - * everything to uint64_t without any worries. */ - if (ret > 0 && num_garbage_positive_strs[i].result != result) { - printf("Error: parsing %s as %s failed: result mismatch!\n", - num_garbage_positive_strs[i].str, buf); - return -1; - } - } - - /* test negative strings */ - for (i = 0; i < NUM_NEGATIVE_GARBAGE_STRS_SIZE; i++) { - result = 0; - memset(&buf, 0, sizeof(buf)); - - cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, - num_garbage_negative_strs[i].str, - (void*)&result, sizeof(result)); - - /* if it should have passed but didn't, or if it should have failed but didn't */ - if ((ret < 0) == (can_parse_signed(num_garbage_negative_strs[i].result, type) > 0)) { - printf("Error: parser behaves unexpectedly when parsing %s as %s!\n", - num_garbage_negative_strs[i].str, buf); - return -1; - } - /* check if result matches what it should have matched - * the result is signed in this case, so we have to account for that */ - if (ret > 0) { - /* detect negative */ - switch (type) { - case INT8: - if (result & (INT8_MAX + 1)) - result |= 0xFFFFFFFFFFFFFF00ULL; - break; - case INT16: - if (result & (INT16_MAX + 1)) - result |= 0xFFFFFFFFFFFF0000ULL; - break; - case INT32: - if (result & (INT32_MAX + 1ULL)) - result |= 0xFFFFFFFF00000000ULL; - break; - default: - break; - } - if (num_garbage_negative_strs[i].result == (int64_t) result) - continue; - printf("Error: parsing %s as %s failed: result mismatch!\n", - num_garbage_negative_strs[i].str, buf); - return -1; - } - } - } - - memset(&buf, 0, sizeof(buf)); - - /* coverage! */ - cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, - buf, sizeof(buf)); - - return 0; -} diff --git a/app/test/test_cmdline_portlist.c b/app/test/test_cmdline_portlist.c deleted file mode 100644 index b9664b0ed6..0000000000 --- a/app/test/test_cmdline_portlist.c +++ /dev/null @@ -1,250 +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 -#include -#include - -#include -#include - -#include "test_cmdline.h" - -struct portlist_str { - const char * str; - uint32_t portmap; -}; - -/* valid strings */ -const struct portlist_str portlist_valid_strs[] = { - {"0", 0x1U }, - {"0-10", 0x7FFU}, - {"10-20", 0x1FFC00U}, - {"all", UINT32_MAX}, - {"0,1,2,3", 0xFU}, - {"0,1-5", 0x3FU}, - {"0,0,0", 0x1U}, - {"31,0-10,15", 0x800087FFU}, - {"0000", 0x1U}, - {"00,01,02,03", 0xFU}, - {"000,001,002,003", 0xFU}, -}; - -/* valid strings but with garbage at the end. - * these strings should still be valid because parser checks - * for end of token, which is either a space/tab, a newline/return, - * or a hash sign. - */ - -const char * portlist_garbage_strs[] = { - "0-31 garbage", - "0-31#garbage", - "0-31\0garbage", - "0-31\ngarbage", - "0-31\rgarbage", - "0-31\tgarbage", - "0,1,2,3-31 garbage", - "0,1,2,3-31#garbage", - "0,1,2,3-31\0garbage", - "0,1,2,3-31\ngarbage", - "0,1,2,3-31\rgarbage", - "0,1,2,3-31\tgarbage", - "all garbage", - "all#garbage", - "all\0garbage", - "all\ngarbage", - "all\rgarbage", - "all\tgarbage", -}; - -/* invalid strings */ -const char * portlist_invalid_strs[] = { - /* valid syntax, invalid chars */ - "A-B", - "0-S", - "1,2,3,4,Q", - "A-4,3-15", - "0-31invalid", - /* valid chars, invalid syntax */ - "1, 2", - "1- 4", - ",2", - ",2 ", - "-1, 4", - "5-1", - "2-", - /* misc */ - "-" - "a", - "A", - ",", - "#", - " ", - "\0", - "", - /* too long */ - "0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1," - "0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2", -}; - -#define PORTLIST_VALID_STRS_SIZE \ - (sizeof(portlist_valid_strs) / sizeof(portlist_valid_strs[0])) -#define PORTLIST_GARBAGE_STRS_SIZE \ - (sizeof(portlist_garbage_strs) / sizeof(portlist_garbage_strs[0])) -#define PORTLIST_INVALID_STRS_SIZE \ - (sizeof(portlist_invalid_strs) / sizeof(portlist_invalid_strs[0])) - - - - -/* test invalid parameters */ -int -test_parse_portlist_invalid_param(void) -{ - cmdline_portlist_t result; - char buf[CMDLINE_TEST_BUFSIZE]; - int ret; - - memset(&buf, 0, sizeof(buf)); - memset(&result, 0, sizeof(cmdline_portlist_t)); - - /* try all null */ - ret = cmdline_parse_portlist(NULL, NULL, NULL, 0); - if (ret != -1) { - printf("Error: parser accepted null parameters!\n"); - return -1; - } - - /* try null buf */ - ret = cmdline_parse_portlist(NULL, NULL, (void*)&result, - sizeof(result)); - if (ret != -1) { - printf("Error: parser accepted null string!\n"); - return -1; - } - - /* try null result */ - ret = cmdline_parse_portlist(NULL, portlist_valid_strs[0].str, NULL, 0); - if (ret == -1) { - printf("Error: parser rejected null result!\n"); - return -1; - } - - /* token is not used in ether_parse anyway so there's no point in - * testing it */ - - /* test help function */ - - /* coverage! */ - ret = cmdline_get_help_portlist(NULL, buf, sizeof(buf)); - if (ret < 0) { - printf("Error: help function failed with valid parameters!\n"); - return -1; - } - - return 0; -} - -/* test valid parameters but invalid data */ -int -test_parse_portlist_invalid_data(void) -{ - int ret = 0; - unsigned i; - cmdline_portlist_t result; - - /* test invalid strings */ - for (i = 0; i < PORTLIST_INVALID_STRS_SIZE; i++) { - - memset(&result, 0, sizeof(cmdline_portlist_t)); - - ret = cmdline_parse_portlist(NULL, portlist_invalid_strs[i], - (void*)&result, sizeof(result)); - if (ret != -1) { - printf("Error: parsing %s succeeded!\n", - portlist_invalid_strs[i]); - return -1; - } - } - - return 0; -} - -/* test valid parameters and data */ -int -test_parse_portlist_valid(void) -{ - int ret = 0; - unsigned i; - cmdline_portlist_t result; - - /* test full strings */ - for (i = 0; i < PORTLIST_VALID_STRS_SIZE; i++) { - - memset(&result, 0, sizeof(cmdline_portlist_t)); - - ret = cmdline_parse_portlist(NULL, portlist_valid_strs[i].str, - (void*)&result, sizeof(result)); - if (ret < 0) { - printf("Error: parsing %s failed!\n", - portlist_valid_strs[i].str); - return -1; - } - if (result.map != portlist_valid_strs[i].portmap) { - printf("Error: parsing %s failed: map mismatch!\n", - portlist_valid_strs[i].str); - return -1; - } - } - - /* test garbage strings */ - for (i = 0; i < PORTLIST_GARBAGE_STRS_SIZE; i++) { - - memset(&result, 0, sizeof(cmdline_portlist_t)); - - ret = cmdline_parse_portlist(NULL, portlist_garbage_strs[i], - (void*)&result, sizeof(result)); - if (ret < 0) { - printf("Error: parsing %s failed!\n", - portlist_garbage_strs[i]); - return -1; - } - if (result.map != UINT32_MAX) { - printf("Error: parsing %s failed: map mismatch!\n", - portlist_garbage_strs[i]); - return -1; - } - } - - return 0; -} diff --git a/app/test/test_cmdline_string.c b/app/test/test_cmdline_string.c deleted file mode 100644 index c5bb9c0cc1..0000000000 --- a/app/test/test_cmdline_string.c +++ /dev/null @@ -1,412 +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 -#include -#include - -#include -#include - -#include -#include - -#include "test_cmdline.h" - -/* structures needed to run tests */ - -struct string_elt_str { - const char * str; /* parsed string */ - const char * result; /* expected string */ - int idx; /* position at which result is expected to be */ -}; - -struct string_elt_str string_elt_strs[] = { - {"one#two#three", "three", 2}, - {"one#two with spaces#three", "three", 2}, - {"one#two\twith\ttabs#three", "three", 2}, - {"one#two\rwith\rreturns#three", "three", 2}, - {"one#two\nwith\nnewlines#three", "three", 2}, - {"one#two#three", "one", 0}, - {"one#two#three", "two", 1}, - {"one#two\0three", "two", 1}, - {"one#two with spaces#three", "two with spaces", 1}, - {"one#two\twith\ttabs#three", "two\twith\ttabs", 1}, - {"one#two\rwith\rreturns#three", "two\rwith\rreturns", 1}, - {"one#two\nwith\nnewlines#three", "two\nwith\nnewlines", 1}, -}; - -#if (CMDLINE_TEST_BUFSIZE < STR_TOKEN_SIZE) \ -|| (CMDLINE_TEST_BUFSIZE < STR_MULTI_TOKEN_SIZE) -#undef CMDLINE_TEST_BUFSIZE -#define CMDLINE_TEST_BUFSIZE RTE_MAX(STR_TOKEN_SIZE, STR_MULTI_TOKEN_SIZE) -#endif - -struct string_nb_str { - const char * str; /* parsed string */ - int nb_strs; /* expected number of strings in str */ -}; - -struct string_nb_str string_nb_strs[] = { - {"one#two#three", 3}, - {"one", 1}, - {"one# \t two \r # three \n #four", 4}, -}; - - - -struct string_parse_str { - const char * str; /* parsed string */ - const char * fixed_str; /* parsing mode (any, fixed or multi) */ - const char * result; /* expected result */ -}; - -struct string_parse_str string_parse_strs[] = { - {"one", NULL, "one"}, /* any string */ - {"two", "one#two#three", "two"}, /* multiple choice string */ - {"three", "three", "three"}, /* fixed string */ - {"three", "one#two with\rgarbage\tcharacters\n#three", "three"}, - {"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 */ -}; - - - -struct string_invalid_str { - const char * str; /* parsed string */ - const char * fixed_str; /* parsing mode (any, fixed or multi) */ -}; - -struct string_invalid_str string_invalid_strs[] = { - {"invalid", "one"}, /* fixed string */ - {"invalid", "one#two#three"}, /* multiple choice string */ - {"invalid", "invalidone"}, /* string that starts the same */ - {"invalidone", "invalid"}, /* string that starts the same */ - {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" - "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" - "toolong!!!", NULL }, - {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" - "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" - "toolong!!!", "fixed" }, - {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" - "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" - "toolong!!!", "multi#choice#string" }, - {"invalid", - "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" - "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" - "toolong!!!" }, - {"", "invalid"} -}; - - - -const char * string_help_strs[] = { - NULL, - "fixed_str", - "multi#str", -}; - - - -#define STRING_PARSE_STRS_SIZE \ - (sizeof(string_parse_strs) / sizeof(string_parse_strs[0])) -#define STRING_HELP_STRS_SIZE \ - (sizeof(string_help_strs) / sizeof(string_help_strs[0])) -#define STRING_ELT_STRS_SIZE \ - (sizeof(string_elt_strs) / sizeof(string_elt_strs[0])) -#define STRING_NB_STRS_SIZE \ - (sizeof(string_nb_strs) / sizeof(string_nb_strs[0])) -#define STRING_INVALID_STRS_SIZE \ - (sizeof(string_invalid_strs) / sizeof(string_invalid_strs[0])) - -#define SMALL_BUF 8 - -/* test invalid parameters */ -int -test_parse_string_invalid_param(void) -{ - cmdline_parse_token_string_t token; - int result; - char buf[CMDLINE_TEST_BUFSIZE]; - - memset(&token, 0, sizeof(token)); - - snprintf(buf, sizeof(buf), "buffer"); - - /* test null token */ - if (cmdline_get_help_string( - NULL, buf, 0) != -1) { - printf("Error: function accepted null token!\n"); - return -1; - } - if (cmdline_complete_get_elt_string( - NULL, 0, buf, 0) != -1) { - printf("Error: function accepted null token!\n"); - return -1; - } - if (cmdline_complete_get_nb_string(NULL) != -1) { - printf("Error: function accepted null token!\n"); - return -1; - } - if (cmdline_parse_string(NULL, buf, NULL, 0) != -1) { - printf("Error: function accepted null token!\n"); - return -1; - } - /* test null buffer */ - if (cmdline_complete_get_elt_string( - (cmdline_parse_token_hdr_t*)&token, 0, NULL, 0) != -1) { - printf("Error: function accepted null buffer!\n"); - return -1; - } - if (cmdline_parse_string( - (cmdline_parse_token_hdr_t*)&token, NULL, - (void*)&result, sizeof(result)) != -1) { - printf("Error: function accepted null buffer!\n"); - return -1; - } - if (cmdline_get_help_string( - (cmdline_parse_token_hdr_t*)&token, NULL, 0) != -1) { - printf("Error: function accepted null buffer!\n"); - return -1; - } - /* test null result */ - if (cmdline_parse_string( - (cmdline_parse_token_hdr_t*)&token, buf, NULL, 0) == -1) { - printf("Error: function rejected null result!\n"); - return -1; - } - /* test negative index */ - if (cmdline_complete_get_elt_string( - (cmdline_parse_token_hdr_t*)&token, -1, buf, 0) != -1) { - printf("Error: function accepted negative index!\n"); - return -1; - } - return 0; -} - -/* test valid parameters but invalid data */ -int -test_parse_string_invalid_data(void) -{ - cmdline_parse_token_string_t token; - cmdline_parse_token_string_t help_token; - char buf[CMDLINE_TEST_BUFSIZE]; - char help_str[CMDLINE_TEST_BUFSIZE]; - char small_buf[SMALL_BUF]; - unsigned i; - - /* test parsing invalid strings */ - for (i = 0; i < STRING_INVALID_STRS_SIZE; i++) { - memset(&token, 0, sizeof(token)); - memset(buf, 0, sizeof(buf)); - - /* prepare test token data */ - token.string_data.str = string_invalid_strs[i].fixed_str; - - if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token, - string_invalid_strs[i].str, (void*)buf, - sizeof(buf)) != -1) { - memset(help_str, 0, sizeof(help_str)); - memset(&help_token, 0, sizeof(help_token)); - - help_token.string_data.str = string_invalid_strs[i].fixed_str; - - /* get parse type so we can give a good error message */ - cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str, - sizeof(help_str)); - - printf("Error: parsing %s as %s succeeded!\n", - string_invalid_strs[i].str, help_str); - return -1; - } - } - - /* misc tests (big comments signify test cases) */ - memset(&token, 0, sizeof(token)); - memset(small_buf, 0, sizeof(small_buf)); - - /* - * try to get element from a null token - */ - token.string_data.str = NULL; - if (cmdline_complete_get_elt_string( - (cmdline_parse_token_hdr_t*)&token, 1, - buf, sizeof(buf)) != -1) { - printf("Error: getting token from null token string!\n"); - return -1; - } - - /* - * try to get element into a buffer that is too small - */ - token.string_data.str = "too_small_buffer"; - if (cmdline_complete_get_elt_string( - (cmdline_parse_token_hdr_t*)&token, 0, - small_buf, sizeof(small_buf)) != -1) { - printf("Error: writing token into too small a buffer succeeded!\n"); - return -1; - } - - /* - * get help string written into a buffer smaller than help string - * truncation should occur - */ - token.string_data.str = NULL; - if (cmdline_get_help_string( - (cmdline_parse_token_hdr_t*)&token, - small_buf, sizeof(small_buf)) == -1) { - printf("Error: writing help string into too small a buffer failed!\n"); - return -1; - } - /* get help string for "any string" so we can compare it with small_buf */ - cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str, - sizeof(help_str)); - if (strncmp(small_buf, help_str, sizeof(small_buf) - 1)) { - printf("Error: help string mismatch!\n"); - return -1; - } - /* check null terminator */ - if (small_buf[sizeof(small_buf) - 1] != '\0') { - printf("Error: small buffer doesn't have a null terminator!\n"); - return -1; - } - - /* - * try to count tokens in a null token - */ - token.string_data.str = NULL; - if (cmdline_complete_get_nb_string( - (cmdline_parse_token_hdr_t*)&token) != 0) { - printf("Error: getting token count from null token succeeded!\n"); - return -1; - } - - return 0; -} - -/* test valid parameters and data */ -int -test_parse_string_valid(void) -{ - cmdline_parse_token_string_t token; - cmdline_parse_token_string_t help_token; - char buf[CMDLINE_TEST_BUFSIZE]; - char help_str[CMDLINE_TEST_BUFSIZE]; - unsigned i; - - /* test parsing strings */ - for (i = 0; i < STRING_PARSE_STRS_SIZE; i++) { - memset(&token, 0, sizeof(token)); - memset(buf, 0, sizeof(buf)); - - token.string_data.str = string_parse_strs[i].fixed_str; - - if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token, - string_parse_strs[i].str, (void*)buf, - sizeof(buf)) < 0) { - - /* clean help data */ - memset(&help_token, 0, sizeof(help_token)); - memset(help_str, 0, sizeof(help_str)); - - /* prepare help token */ - help_token.string_data.str = string_parse_strs[i].fixed_str; - - /* get help string so that we get an informative error message */ - cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str, - sizeof(help_str)); - - printf("Error: parsing %s as %s failed!\n", - string_parse_strs[i].str, help_str); - return -1; - } - if (strcmp(buf, string_parse_strs[i].result) != 0) { - printf("Error: result mismatch!\n"); - return -1; - } - } - - /* get number of string tokens and verify it's correct */ - for (i = 0; i < STRING_NB_STRS_SIZE; i++) { - memset(&token, 0, sizeof(token)); - - token.string_data.str = string_nb_strs[i].str; - - if (cmdline_complete_get_nb_string( - (cmdline_parse_token_hdr_t*)&token) < - string_nb_strs[i].nb_strs) { - printf("Error: strings count mismatch!\n"); - return -1; - } - } - - /* get token at specified position and verify it's correct */ - for (i = 0; i < STRING_ELT_STRS_SIZE; i++) { - memset(&token, 0, sizeof(token)); - memset(buf, 0, sizeof(buf)); - - token.string_data.str = string_elt_strs[i].str; - - if (cmdline_complete_get_elt_string( - (cmdline_parse_token_hdr_t*)&token, string_elt_strs[i].idx, - buf, sizeof(buf)) < 0) { - printf("Error: getting string element failed!\n"); - return -1; - } - if (strncmp(buf, string_elt_strs[i].result, - sizeof(buf)) != 0) { - printf("Error: result mismatch!\n"); - return -1; - } - } - - /* cover all cases with help strings */ - for (i = 0; i < STRING_HELP_STRS_SIZE; i++) { - memset(&help_token, 0, sizeof(help_token)); - memset(help_str, 0, sizeof(help_str)); - help_token.string_data.str = string_help_strs[i]; - if (cmdline_get_help_string((cmdline_parse_token_hdr_t*)&help_token, - help_str, sizeof(help_str)) < 0) { - printf("Error: help operation failed!\n"); - return -1; - } - } - - return 0; -} diff --git a/app/test/test_common.c b/app/test/test_common.c deleted file mode 100644 index 8effa2f9ed..0000000000 --- a/app/test/test_common.c +++ /dev/null @@ -1,172 +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 -#include -#include -#include - -#include "test.h" - -#define MAX_NUM 1 << 20 - -#define FAIL(x)\ - {printf(x "() test failed!\n");\ - return -1;} - -/* this is really a sanity check */ -static int -test_macros(int __rte_unused unused_parm) -{ -#define SMALLER 0x1000U -#define BIGGER 0x2000U -#define PTR_DIFF BIGGER - SMALLER -#define FAIL_MACRO(x)\ - {printf(#x "() test failed!\n");\ - return -1;} - - uintptr_t unused = 0; - - RTE_SET_USED(unused); - - if ((uintptr_t)RTE_PTR_ADD(SMALLER, PTR_DIFF) != BIGGER) - FAIL_MACRO(RTE_PTR_ADD); - if ((uintptr_t)RTE_PTR_SUB(BIGGER, PTR_DIFF) != SMALLER) - FAIL_MACRO(RTE_PTR_SUB); - if (RTE_PTR_DIFF(BIGGER, SMALLER) != PTR_DIFF) - FAIL_MACRO(RTE_PTR_DIFF); - if (RTE_MAX(SMALLER, BIGGER) != BIGGER) - FAIL_MACRO(RTE_MAX); - if (RTE_MIN(SMALLER, BIGGER) != SMALLER) - FAIL_MACRO(RTE_MIN); - - if (strncmp(RTE_STR(test), "test", sizeof("test"))) - FAIL_MACRO(RTE_STR); - - return 0; -} - -static int -test_misc(void) -{ - char memdump[] = "memdump_test"; - if (rte_bsf32(129)) - FAIL("rte_bsf32"); - - rte_memdump(stdout, "test", memdump, sizeof(memdump)); - rte_hexdump(stdout, "test", memdump, sizeof(memdump)); - - rte_pause(); - - return 0; -} - -static int -test_align(void) -{ -#define FAIL_ALIGN(x, i, p)\ - {printf(x "() test failed: %u %u\n", i, p);\ - return -1;} -#define ERROR_FLOOR(res, i, pow) \ - (res % pow) || /* check if not aligned */ \ - ((res / pow) != (i / pow)) /* check if correct alignment */ -#define ERROR_CEIL(res, i, pow) \ - (res % pow) || /* check if not aligned */ \ - ((i % pow) == 0 ? /* check if ceiling is invoked */ \ - val / pow != i / pow : /* if aligned */ \ - val / pow != (i / pow) + 1) /* if not aligned, hence +1 */ - - uint32_t i, p, val; - - for (i = 1, p = 1; i <= MAX_NUM; i ++) { - if (rte_align32pow2(i) != p) - FAIL_ALIGN("rte_align32pow2", i, p); - if (i == p) - p <<= 1; - } - - for (p = 2; p <= MAX_NUM; p <<= 1) { - - if (!rte_is_power_of_2(p)) - FAIL("rte_is_power_of_2"); - - for (i = 1; i <= MAX_NUM; i++) { - /* align floor */ - if (RTE_ALIGN_FLOOR((uintptr_t)i, p) % p) - FAIL_ALIGN("RTE_ALIGN_FLOOR", i, p); - - val = RTE_PTR_ALIGN_FLOOR((uintptr_t) i, p); - if (ERROR_FLOOR(val, i, p)) - FAIL_ALIGN("RTE_PTR_ALIGN_FLOOR", i, p); - - val = RTE_ALIGN_FLOOR(i, p); - if (ERROR_FLOOR(val, i, p)) - FAIL_ALIGN("RTE_ALIGN_FLOOR", i, p); - - /* align ceiling */ - val = RTE_PTR_ALIGN((uintptr_t) i, p); - if (ERROR_CEIL(val, i, p)) - FAIL_ALIGN("RTE_PTR_ALIGN", i, p); - - val = RTE_ALIGN(i, p); - if (ERROR_CEIL(val, i, p)) - FAIL_ALIGN("RTE_ALIGN", i, p); - - val = RTE_ALIGN_CEIL(i, p); - if (ERROR_CEIL(val, i, p)) - FAIL_ALIGN("RTE_ALIGN_CEIL", i, p); - - val = RTE_PTR_ALIGN_CEIL((uintptr_t)i, p); - if (ERROR_CEIL(val, i, p)) - FAIL_ALIGN("RTE_PTR_ALIGN_CEIL", i, p); - - /* by this point we know that val is aligned to p */ - if (!rte_is_aligned((void*)(uintptr_t) val, p)) - FAIL("rte_is_aligned"); - } - } - return 0; -} - -static int -test_common(void) -{ - int ret = 0; - ret |= test_align(); - ret |= test_macros(0); - ret |= test_misc(); - - return ret; -} - -REGISTER_TEST_COMMAND(common_autotest, test_common); diff --git a/app/test/test_cpuflags.c b/app/test/test_cpuflags.c deleted file mode 100644 index 0e5ebe788a..0000000000 --- a/app/test/test_cpuflags.c +++ /dev/null @@ -1,202 +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 - -#include -#include -#include -#include - -#include "test.h" - - -/* convenience define */ -#define CHECK_FOR_FLAG(x) \ - result = rte_cpu_get_flag_enabled(x); \ - printf("%s\n", cpu_flag_result(result)); \ - if (result == -ENOENT) \ - return -1; - -/* - * Helper function to display result - */ -static inline const char * -cpu_flag_result(int result) -{ - switch (result) { - case 0: - return "NOT PRESENT"; - case 1: - return "OK"; - default: - return "ERROR"; - } -} - - - -/* - * CPUID test - * =========== - * - * - Check flags from different registers with rte_cpu_get_flag_enabled() - * - Check if register and CPUID functions fail properly - */ - -static int -test_cpuflags(void) -{ - int result; - printf("\nChecking for flags from different registers...\n"); - -#ifdef RTE_ARCH_PPC_64 - printf("Check for PPC64:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_PPC64); - - printf("Check for PPC32:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_PPC32); - - printf("Check for VSX:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_VSX); - - printf("Check for DFP:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_DFP); - - printf("Check for FPU:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_FPU); - - printf("Check for SMT:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_SMT); - - printf("Check for MMU:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_MMU); - - printf("Check for ALTIVEC:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_ALTIVEC); - - printf("Check for ARCH_2_06:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_ARCH_2_06); - - printf("Check for ARCH_2_07:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_ARCH_2_07); - - printf("Check for ICACHE_SNOOP:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_ICACHE_SNOOP); -#endif - -#if defined(RTE_ARCH_ARM) - printf("Check for NEON:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_NEON); -#endif - -#if defined(RTE_ARCH_ARM64) - printf("Check for FP:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_FP); - - printf("Check for ASIMD:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_NEON); - - printf("Check for EVTSTRM:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_EVTSTRM); - - printf("Check for AES:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_AES); - - printf("Check for PMULL:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_PMULL); - - printf("Check for SHA1:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_SHA1); - - printf("Check for SHA2:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_SHA2); - - printf("Check for CRC32:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_CRC32); - - printf("Check for ATOMICS:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_ATOMICS); -#endif - -#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) - printf("Check for SSE:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_SSE); - - printf("Check for SSE2:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_SSE2); - - printf("Check for SSE3:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_SSE3); - - printf("Check for SSE4.1:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_SSE4_1); - - printf("Check for SSE4.2:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_SSE4_2); - - printf("Check for AVX:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_AVX); - - printf("Check for AVX2:\t\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_AVX2); - - printf("Check for TRBOBST:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_TRBOBST); - - printf("Check for ENERGY_EFF:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_ENERGY_EFF); - - printf("Check for LAHF_SAHF:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_LAHF_SAHF); - - printf("Check for 1GB_PG:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_1GB_PG); - - printf("Check for INVTSC:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_INVTSC); -#endif - - /* - * Check if invalid data is handled properly - */ - printf("\nCheck for invalid flag:\t"); - result = rte_cpu_get_flag_enabled(RTE_CPUFLAG_NUMFLAGS); - printf("%s\n", cpu_flag_result(result)); - if (result != -ENOENT) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(cpuflags_autotest, test_cpuflags); diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c deleted file mode 100644 index 357a92eafa..0000000000 --- a/app/test/test_cryptodev.c +++ /dev/null @@ -1,8221 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015-2017 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 -#include -#include -#include -#include - -#include -#include -#include - -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER -#include -#include -#endif - -#include "test.h" -#include "test_cryptodev.h" - -#include "test_cryptodev_blockcipher.h" -#include "test_cryptodev_aes_test_vectors.h" -#include "test_cryptodev_des_test_vectors.h" -#include "test_cryptodev_hash_test_vectors.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_zuc_test_vectors.h" -#include "test_cryptodev_zuc_hash_test_vectors.h" -#include "test_cryptodev_gcm_test_vectors.h" -#include "test_cryptodev_hmac_test_vectors.h" - -static enum rte_cryptodev_type gbl_cryptodev_type; - -struct crypto_testsuite_params { - struct rte_mempool *mbuf_pool; - struct rte_mempool *large_mbuf_pool; - struct rte_mempool *op_mpool; - struct rte_cryptodev_config conf; - struct rte_cryptodev_qp_conf qp_conf; - - uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS]; - uint8_t valid_dev_count; -}; - -struct crypto_unittest_params { - struct rte_crypto_sym_xform cipher_xform; - struct rte_crypto_sym_xform auth_xform; - - struct rte_cryptodev_sym_session *sess; - - struct rte_crypto_op *op; - - struct rte_mbuf *obuf, *ibuf; - - uint8_t *digest; -}; - -#define ALIGN_POW2_ROUNDUP(num, align) \ - (((num) + (align) - 1) & ~((align) - 1)) - -/* - * Forward declarations. - */ -static int -test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params, uint8_t *cipher_key, - uint8_t *hmac_key); - -static int -test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, - struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_param, - const uint8_t *cipher, - const uint8_t *digest, - const uint8_t *iv); - -static struct rte_mbuf * -setup_test_string(struct rte_mempool *mpool, - const char *string, size_t len, uint8_t blocksize) -{ - struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); - size_t t_len = len - (blocksize ? (len % blocksize) : 0); - - memset(m->buf_addr, 0, m->buf_len); - if (m) { - char *dst = rte_pktmbuf_append(m, t_len); - - if (!dst) { - rte_pktmbuf_free(m); - return NULL; - } - if (string != NULL) - rte_memcpy(dst, string, t_len); - else - memset(dst, 0, t_len); - } - - return m; -} - -/* Get number of bytes in X bits (rounding up) */ -static uint32_t -ceil_byte_length(uint32_t num_bits) -{ - if (num_bits % 8) - return ((num_bits >> 3) + 1); - else - return (num_bits >> 3); -} - -static struct rte_crypto_op * -process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op) -{ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - printf("Error sending packet for encryption"); - return NULL; - } - - op = NULL; - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) - rte_pause(); - - return op; -} - -static struct crypto_testsuite_params testsuite_params = { NULL }; -static struct crypto_unittest_params unittest_params; - -static int -testsuite_setup(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_cryptodev_info info; - uint32_t i = 0, nb_devs, dev_id; - int ret; - uint16_t qp_id; - - memset(ts_params, 0, sizeof(*ts_params)); - - ts_params->mbuf_pool = rte_mempool_lookup("CRYPTO_MBUFPOOL"); - if (ts_params->mbuf_pool == NULL) { - /* Not already created so create */ - ts_params->mbuf_pool = rte_pktmbuf_pool_create( - "CRYPTO_MBUFPOOL", - NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, - rte_socket_id()); - if (ts_params->mbuf_pool == NULL) { - RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n"); - return TEST_FAILED; - } - } - - ts_params->large_mbuf_pool = rte_mempool_lookup( - "CRYPTO_LARGE_MBUFPOOL"); - if (ts_params->large_mbuf_pool == NULL) { - /* Not already created so create */ - ts_params->large_mbuf_pool = rte_pktmbuf_pool_create( - "CRYPTO_LARGE_MBUFPOOL", - 1, 0, 0, UINT16_MAX, - rte_socket_id()); - if (ts_params->large_mbuf_pool == NULL) { - RTE_LOG(ERR, USER1, - "Can't create CRYPTO_LARGE_MBUFPOOL\n"); - return TEST_FAILED; - } - } - - ts_params->op_mpool = rte_crypto_op_pool_create( - "MBUF_CRYPTO_SYM_OP_POOL", - RTE_CRYPTO_OP_TYPE_SYMMETRIC, - NUM_MBUFS, MBUF_CACHE_SIZE, - DEFAULT_NUM_XFORMS * - sizeof(struct rte_crypto_sym_xform), - rte_socket_id()); - if (ts_params->op_mpool == NULL) { - RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); - return TEST_FAILED; - } - - /* Create 2 AESNI MB devices if required */ - if (gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_MB_PMD) { -#ifndef RTE_LIBRTE_PMD_AESNI_MB - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_MB must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_AESNI_MB_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), NULL); - - TEST_ASSERT(ret == 0, - "Failed to create instance %u of" - " pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - } - } - } - - /* Create 2 AESNI GCM devices if required */ - if (gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_GCM_PMD) { -#ifndef RTE_LIBRTE_PMD_AESNI_GCM - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_GCM must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_AESNI_GCM_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - TEST_ASSERT_SUCCESS(rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD), NULL), - "Failed to create instance %u of" - " pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD)); - } - } - } - - /* Create 2 SNOW 3G devices if required */ - if (gbl_cryptodev_type == RTE_CRYPTODEV_SNOW3G_PMD) { -#ifndef RTE_LIBRTE_PMD_SNOW3G - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_SNOW3G must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_SNOW3G_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - TEST_ASSERT_SUCCESS(rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD), NULL), - "Failed to create instance %u of" - " pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD)); - } - } - } - - /* Create 2 KASUMI devices if required */ - if (gbl_cryptodev_type == RTE_CRYPTODEV_KASUMI_PMD) { -#ifndef RTE_LIBRTE_PMD_KASUMI - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_KASUMI must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - 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( - RTE_STR(CRYPTODEV_NAME_KASUMI_PMD), NULL), - "Failed to create instance %u of" - " pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_KASUMI_PMD)); - } - } - } - - /* Create 2 ZUC devices if required */ - if (gbl_cryptodev_type == RTE_CRYPTODEV_ZUC_PMD) { -#ifndef RTE_LIBRTE_PMD_ZUC - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_ZUC must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_ZUC_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - TEST_ASSERT_SUCCESS(rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_ZUC_PMD), NULL), - "Failed to create instance %u of" - " pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_ZUC_PMD)); - } - } - } - - /* Create 2 NULL devices if required */ - if (gbl_cryptodev_type == RTE_CRYPTODEV_NULL_PMD) { -#ifndef RTE_LIBRTE_PMD_NULL_CRYPTO - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_NULL_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - int dev_id = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_NULL_PMD), NULL); - - TEST_ASSERT(dev_id >= 0, - "Failed to create instance %u of" - " pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_NULL_PMD)); - } - } - } - - /* Create 2 OPENSSL devices if required */ - if (gbl_cryptodev_type == RTE_CRYPTODEV_OPENSSL_PMD) { -#ifndef RTE_LIBRTE_PMD_OPENSSL - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_OPENSSL must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_OPENSSL_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance %u of pmd : %s", i, - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); - } - } - } - - /* Create 2 ARMv8 devices if required */ - if (gbl_cryptodev_type == RTE_CRYPTODEV_ARMV8_PMD) { -#ifndef RTE_LIBRTE_PMD_ARMV8_CRYPTO - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_ARMV8_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance %u of pmd : %s", i, - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); - } - } - } - -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER - if (gbl_cryptodev_type == RTE_CRYPTODEV_SCHEDULER_PMD) { - -#ifndef RTE_LIBRTE_PMD_AESNI_MB - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_MB must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_SCHEDULER_PMD); - if (nb_devs < 1) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD), - NULL); - - TEST_ASSERT(ret == 0, - "Failed to create instance %u of" - " pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)); - } - } -#endif /* RTE_LIBRTE_PMD_CRYPTO_SCHEDULER */ - -#ifndef RTE_LIBRTE_PMD_QAT - if (gbl_cryptodev_type == RTE_CRYPTODEV_QAT_SYM_PMD) { - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " - "in config file to run this testsuite.\n"); - return TEST_FAILED; - } -#endif - - nb_devs = rte_cryptodev_count(); - if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?\n"); - return TEST_FAILED; - } - - /* Create list of valid crypto devs */ - for (i = 0; i < nb_devs; i++) { - rte_cryptodev_info_get(i, &info); - if (info.dev_type == gbl_cryptodev_type) - ts_params->valid_devs[ts_params->valid_dev_count++] = i; - } - - if (ts_params->valid_dev_count < 1) - return TEST_FAILED; - - /* Set up all the qps on the first of the valid devices found */ - - dev_id = ts_params->valid_devs[0]; - - rte_cryptodev_info_get(dev_id, &info); - - ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs; - ts_params->conf.socket_id = SOCKET_ID_ANY; - ts_params->conf.session_mp.nb_objs = info.sym.max_nb_sessions; - - TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, - &ts_params->conf), - "Failed to configure cryptodev %u with %u qps", - dev_id, ts_params->conf.nb_queue_pairs); - - ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; - - for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) { - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - dev_id, qp_id, &ts_params->qp_conf, - rte_cryptodev_socket_id(dev_id)), - "Failed to setup queue pair %u on cryptodev %u", - qp_id, dev_id); - } - - return TEST_SUCCESS; -} - -static void -testsuite_teardown(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - - if (ts_params->mbuf_pool != NULL) { - RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", - 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_avail_count(ts_params->op_mpool)); - } - -} - -static int -ut_setup(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - uint16_t qp_id; - - /* Clear unit test parameters before running test */ - memset(ut_params, 0, sizeof(*ut_params)); - - /* Reconfigure device to default parameters */ - ts_params->conf.socket_id = SOCKET_ID_ANY; - ts_params->conf.session_mp.nb_objs = DEFAULT_NUM_OPS_INFLIGHT; - - TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], - &ts_params->conf), - "Failed to configure cryptodev %u", - ts_params->valid_devs[0]); - - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs ; qp_id++) { - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], qp_id, - &ts_params->qp_conf, - rte_cryptodev_socket_id(ts_params->valid_devs[0])), - "Failed to setup queue pair %u on cryptodev %u", - qp_id, ts_params->valid_devs[0]); - } - - - rte_cryptodev_stats_reset(ts_params->valid_devs[0]); - - /* Start the device */ - TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_devs[0]), - "Failed to start cryptodev %u", - ts_params->valid_devs[0]); - - return TEST_SUCCESS; -} - -static void -ut_teardown(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - struct rte_cryptodev_stats stats; - - /* free crypto session structure */ - if (ut_params->sess) { - rte_cryptodev_sym_session_free(ts_params->valid_devs[0], - ut_params->sess); - ut_params->sess = NULL; - } - - /* free crypto operation structure */ - if (ut_params->op) - rte_crypto_op_free(ut_params->op); - - /* - * free mbuf - both obuf and ibuf are usually the same, - * 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; - } - - if (ts_params->mbuf_pool != NULL) - RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", - rte_mempool_avail_count(ts_params->mbuf_pool)); - - rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats); - - /* Stop the device */ - rte_cryptodev_stop(ts_params->valid_devs[0]); -} - -static int -test_device_configure_invalid_dev_id(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - uint16_t dev_id, num_devs = 0; - - TEST_ASSERT((num_devs = rte_cryptodev_count()) >= 1, - "Need at least %d devices for test", 1); - - /* valid dev_id values */ - dev_id = ts_params->valid_devs[ts_params->valid_dev_count - 1]; - - /* Stop the device in case it's started so it can be configured */ - rte_cryptodev_stop(ts_params->valid_devs[dev_id]); - - TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, &ts_params->conf), - "Failed test for rte_cryptodev_configure: " - "invalid dev_num %u", dev_id); - - /* invalid dev_id values */ - dev_id = num_devs; - - TEST_ASSERT_FAIL(rte_cryptodev_configure(dev_id, &ts_params->conf), - "Failed test for rte_cryptodev_configure: " - "invalid dev_num %u", dev_id); - - dev_id = 0xff; - - TEST_ASSERT_FAIL(rte_cryptodev_configure(dev_id, &ts_params->conf), - "Failed test for rte_cryptodev_configure:" - "invalid dev_num %u", dev_id); - - return TEST_SUCCESS; -} - -static int -test_device_configure_invalid_queue_pair_ids(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - uint16_t orig_nb_qps = ts_params->conf.nb_queue_pairs; - - /* Stop the device in case it's started so it can be configured */ - rte_cryptodev_stop(ts_params->valid_devs[0]); - - /* valid - one queue pairs */ - ts_params->conf.nb_queue_pairs = 1; - - TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], - &ts_params->conf), - "Failed to configure cryptodev: dev_id %u, qp_id %u", - ts_params->valid_devs[0], ts_params->conf.nb_queue_pairs); - - - /* valid - max value queue pairs */ - ts_params->conf.nb_queue_pairs = MAX_NUM_QPS_PER_QAT_DEVICE; - - TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], - &ts_params->conf), - "Failed to configure cryptodev: dev_id %u, qp_id %u", - ts_params->valid_devs[0], ts_params->conf.nb_queue_pairs); - - - /* invalid - zero queue pairs */ - ts_params->conf.nb_queue_pairs = 0; - - TEST_ASSERT_FAIL(rte_cryptodev_configure(ts_params->valid_devs[0], - &ts_params->conf), - "Failed test for rte_cryptodev_configure, dev_id %u," - " invalid qps: %u", - ts_params->valid_devs[0], - ts_params->conf.nb_queue_pairs); - - - /* invalid - max value supported by field queue pairs */ - ts_params->conf.nb_queue_pairs = UINT16_MAX; - - TEST_ASSERT_FAIL(rte_cryptodev_configure(ts_params->valid_devs[0], - &ts_params->conf), - "Failed test for rte_cryptodev_configure, dev_id %u," - " invalid qps: %u", - ts_params->valid_devs[0], - ts_params->conf.nb_queue_pairs); - - - /* invalid - max value + 1 queue pairs */ - ts_params->conf.nb_queue_pairs = MAX_NUM_QPS_PER_QAT_DEVICE + 1; - - TEST_ASSERT_FAIL(rte_cryptodev_configure(ts_params->valid_devs[0], - &ts_params->conf), - "Failed test for rte_cryptodev_configure, dev_id %u," - " invalid qps: %u", - ts_params->valid_devs[0], - ts_params->conf.nb_queue_pairs); - - /* revert to original testsuite value */ - ts_params->conf.nb_queue_pairs = orig_nb_qps; - - return TEST_SUCCESS; -} - -static int -test_queue_pair_descriptor_setup(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_cryptodev_info dev_info; - struct rte_cryptodev_qp_conf qp_conf = { - .nb_descriptors = MAX_NUM_OPS_INFLIGHT - }; - - uint16_t qp_id; - - /* Stop the device in case it's started so it can be configured */ - rte_cryptodev_stop(ts_params->valid_devs[0]); - - - rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); - - ts_params->conf.session_mp.nb_objs = dev_info.sym.max_nb_sessions; - - TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], - &ts_params->conf), "Failed to configure cryptodev %u", - ts_params->valid_devs[0]); - - - /* - * Test various ring sizes on this device. memzones can't be - * freed so are re-used if ring is released and re-created. - */ - qp_conf.nb_descriptors = MIN_NUM_OPS_INFLIGHT; /* min size*/ - - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], qp_id, &qp_conf, - rte_cryptodev_socket_id( - ts_params->valid_devs[0])), - "Failed test for " - "rte_cryptodev_queue_pair_setup: num_inflights " - "%u on qp %u on cryptodev %u", - qp_conf.nb_descriptors, qp_id, - ts_params->valid_devs[0]); - } - - qp_conf.nb_descriptors = (uint32_t)(MAX_NUM_OPS_INFLIGHT / 2); - - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], qp_id, &qp_conf, - rte_cryptodev_socket_id( - ts_params->valid_devs[0])), - "Failed test for" - " rte_cryptodev_queue_pair_setup: num_inflights" - " %u on qp %u on cryptodev %u", - qp_conf.nb_descriptors, qp_id, - ts_params->valid_devs[0]); - } - - qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT; /* valid */ - - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], qp_id, &qp_conf, - rte_cryptodev_socket_id( - ts_params->valid_devs[0])), - "Failed test for " - "rte_cryptodev_queue_pair_setup: num_inflights" - " %u on qp %u on cryptodev %u", - qp_conf.nb_descriptors, qp_id, - ts_params->valid_devs[0]); - } - - /* invalid number of descriptors - max supported + 2 */ - qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT + 2; - - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { - TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], qp_id, &qp_conf, - rte_cryptodev_socket_id( - ts_params->valid_devs[0])), - "Unexpectedly passed test for " - "rte_cryptodev_queue_pair_setup:" - "num_inflights %u on qp %u on cryptodev %u", - qp_conf.nb_descriptors, qp_id, - ts_params->valid_devs[0]); - } - - /* invalid number of descriptors - max value of parameter */ - qp_conf.nb_descriptors = UINT32_MAX-1; - - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { - TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], qp_id, &qp_conf, - rte_cryptodev_socket_id( - ts_params->valid_devs[0])), - "Unexpectedly passed test for " - "rte_cryptodev_queue_pair_setup:" - "num_inflights %u on qp %u on cryptodev %u", - qp_conf.nb_descriptors, qp_id, - ts_params->valid_devs[0]); - } - - qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; - - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], qp_id, &qp_conf, - rte_cryptodev_socket_id( - ts_params->valid_devs[0])), - "Failed test for" - " rte_cryptodev_queue_pair_setup:" - "num_inflights %u on qp %u on cryptodev %u", - qp_conf.nb_descriptors, qp_id, - ts_params->valid_devs[0]); - } - - /* invalid number of descriptors - max supported + 1 */ - qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT + 1; - - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { - TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], qp_id, &qp_conf, - rte_cryptodev_socket_id( - ts_params->valid_devs[0])), - "Unexpectedly passed test for " - "rte_cryptodev_queue_pair_setup:" - "num_inflights %u on qp %u on cryptodev %u", - qp_conf.nb_descriptors, qp_id, - ts_params->valid_devs[0]); - } - - /* test invalid queue pair id */ - qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; /*valid */ - - qp_id = DEFAULT_NUM_QPS_PER_QAT_DEVICE; /*invalid */ - - TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], - qp_id, &qp_conf, - rte_cryptodev_socket_id(ts_params->valid_devs[0])), - "Failed test for rte_cryptodev_queue_pair_setup:" - "invalid qp %u on cryptodev %u", - qp_id, ts_params->valid_devs[0]); - - qp_id = 0xffff; /*invalid*/ - - TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( - ts_params->valid_devs[0], - qp_id, &qp_conf, - rte_cryptodev_socket_id(ts_params->valid_devs[0])), - "Failed test for rte_cryptodev_queue_pair_setup:" - "invalid qp %u on cryptodev %u", - qp_id, ts_params->valid_devs[0]); - - return TEST_SUCCESS; -} - -/* ***** Plaintext data for tests ***** */ - -const char catch_22_quote_1[] = - "There was only one catch and that was Catch-22, which " - "specified that a concern for one's safety in the face of " - "dangers that were real and immediate was the process of a " - "rational mind. Orr was crazy and could be grounded. All he " - "had to do was ask; and as soon as he did, he would no longer " - "be crazy and would have to fly more missions. Orr would be " - "crazy to fly more missions and sane if he didn't, but if he " - "was sane he had to fly them. If he flew them he was crazy " - "and didn't have to; but if he didn't want to he was sane and " - "had to. Yossarian was moved very deeply by the absolute " - "simplicity of this clause of Catch-22 and let out a " - "respectful whistle. \"That's some catch, that Catch-22\", he " - "observed. \"It's the best there is,\" Doc Daneeka agreed."; - -const char catch_22_quote[] = - "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."; - -#define QUOTE_480_BYTES (480) -#define QUOTE_512_BYTES (512) -#define QUOTE_768_BYTES (768) -#define QUOTE_1024_BYTES (1024) - - - -/* ***** SHA1 Hash Tests ***** */ - -#define HMAC_KEY_LENGTH_SHA1 (DIGEST_BYTE_LENGTH_SHA1) - -static uint8_t hmac_sha1_key[] = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD }; - -/* ***** SHA224 Hash Tests ***** */ - -#define HMAC_KEY_LENGTH_SHA224 (DIGEST_BYTE_LENGTH_SHA224) - - -/* ***** AES-CBC Cipher Tests ***** */ - -#define CIPHER_KEY_LENGTH_AES_CBC (16) -#define CIPHER_IV_LENGTH_AES_CBC (CIPHER_KEY_LENGTH_AES_CBC) - -static uint8_t aes_cbc_key[] = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A }; - -static uint8_t aes_cbc_iv[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; - - -/* ***** AES-CBC / HMAC-SHA1 Hash Tests ***** */ - -static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_ciphertext[] = { - 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 -}; - -static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { - 0x9a, 0x4f, 0x88, 0x1b, 0xb6, 0x8f, 0xd8, 0x60, - 0x42, 0x1a, 0x7d, 0x3d, 0xf5, 0x82, 0x80, 0xf1, - 0x18, 0x8c, 0x1d, 0x32 -}; - - -/* Multisession Vector context Test */ -/*Begin Session 0 */ -static uint8_t ms_aes_cbc_key0[] = { - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -static uint8_t ms_aes_cbc_iv0[] = { - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -static const uint8_t ms_aes_cbc_cipher0[] = { - 0x3C, 0xE4, 0xEE, 0x42, 0xB6, 0x9B, 0xC3, 0x38, - 0x5F, 0xAD, 0x54, 0xDC, 0xA8, 0x32, 0x81, 0xDC, - 0x7A, 0x6F, 0x85, 0x58, 0x07, 0x35, 0xED, 0xEB, - 0xAD, 0x79, 0x79, 0x96, 0xD3, 0x0E, 0xA6, 0xD9, - 0xAA, 0x86, 0xA4, 0x8F, 0xB5, 0xD6, 0x6E, 0x6D, - 0x0C, 0x91, 0x2F, 0xC4, 0x67, 0x98, 0x0E, 0xC4, - 0x8D, 0x83, 0x68, 0x69, 0xC4, 0xD3, 0x94, 0x34, - 0xC4, 0x5D, 0x60, 0x55, 0x22, 0x87, 0x8F, 0x6F, - 0x17, 0x8E, 0x75, 0xE4, 0x02, 0xF5, 0x1B, 0x99, - 0xC8, 0x39, 0xA9, 0xAB, 0x23, 0x91, 0x12, 0xED, - 0x08, 0xE7, 0xD9, 0x25, 0x89, 0x24, 0x4F, 0x8D, - 0x68, 0xF3, 0x10, 0x39, 0x0A, 0xEE, 0x45, 0x24, - 0xDF, 0x7A, 0x9D, 0x00, 0x25, 0xE5, 0x35, 0x71, - 0x4E, 0x40, 0x59, 0x6F, 0x0A, 0x13, 0xB3, 0x72, - 0x1D, 0x98, 0x63, 0x94, 0x89, 0xA5, 0x39, 0x8E, - 0xD3, 0x9C, 0x8A, 0x7F, 0x71, 0x2F, 0xC7, 0xCD, - 0x81, 0x05, 0xDC, 0xC0, 0x8D, 0xCE, 0x6D, 0x18, - 0x30, 0xC4, 0x72, 0x51, 0xF0, 0x27, 0xC8, 0xF6, - 0x60, 0x5B, 0x7C, 0xB2, 0xE3, 0x49, 0x0C, 0x29, - 0xC6, 0x9F, 0x39, 0x57, 0x80, 0x55, 0x24, 0x2C, - 0x9B, 0x0F, 0x5A, 0xB3, 0x89, 0x55, 0x31, 0x96, - 0x0D, 0xCD, 0xF6, 0x51, 0x03, 0x2D, 0x89, 0x26, - 0x74, 0x44, 0xD6, 0xE8, 0xDC, 0xEA, 0x44, 0x55, - 0x64, 0x71, 0x9C, 0x9F, 0x5D, 0xBA, 0x39, 0x46, - 0xA8, 0x17, 0xA1, 0x9C, 0x52, 0x9D, 0xBC, 0x6B, - 0x4A, 0x98, 0xE6, 0xEA, 0x33, 0xEC, 0x58, 0xB4, - 0x43, 0xF0, 0x32, 0x45, 0xA4, 0xC1, 0x55, 0xB7, - 0x5D, 0xB5, 0x59, 0xB2, 0xE3, 0x96, 0xFF, 0xA5, - 0xAF, 0xE1, 0x86, 0x1B, 0x42, 0xE6, 0x3B, 0xA0, - 0x90, 0x4A, 0xE8, 0x8C, 0x21, 0x7F, 0x36, 0x1E, - 0x5B, 0x65, 0x25, 0xD1, 0xC1, 0x5A, 0xCA, 0x3D, - 0x10, 0xED, 0x2D, 0x79, 0xD0, 0x0F, 0x58, 0x44, - 0x69, 0x81, 0xF5, 0xD4, 0xC9, 0x0F, 0x90, 0x76, - 0x1F, 0x54, 0xD2, 0xD5, 0x97, 0xCE, 0x2C, 0xE3, - 0xEF, 0xF4, 0xB7, 0xC6, 0x3A, 0x87, 0x7F, 0x83, - 0x2A, 0xAF, 0xCD, 0x90, 0x12, 0xA7, 0x7D, 0x85, - 0x1D, 0x62, 0xD3, 0x85, 0x25, 0x05, 0xDB, 0x45, - 0x92, 0xA3, 0xF6, 0xA2, 0xA8, 0x41, 0xE4, 0x25, - 0x86, 0x87, 0x67, 0x24, 0xEC, 0x89, 0x23, 0x2A, - 0x9B, 0x20, 0x4D, 0x93, 0xEE, 0xE2, 0x2E, 0xC1, - 0x0B, 0x15, 0x33, 0xCF, 0x00, 0xD1, 0x1A, 0xDA, - 0x93, 0xFD, 0x28, 0x21, 0x5B, 0xCF, 0xD1, 0xF3, - 0x5A, 0x81, 0xBA, 0x82, 0x5E, 0x2F, 0x61, 0xB4, - 0x05, 0x71, 0xB5, 0xF4, 0x39, 0x3C, 0x1F, 0x60, - 0x00, 0x7A, 0xC4, 0xF8, 0x35, 0x20, 0x6C, 0x3A, - 0xCC, 0x03, 0x8F, 0x7B, 0xA2, 0xB6, 0x65, 0x8A, - 0xB6, 0x5F, 0xFD, 0x25, 0xD3, 0x5F, 0x92, 0xF9, - 0xAE, 0x17, 0x9B, 0x5E, 0x6E, 0x9A, 0xE4, 0x55, - 0x10, 0x25, 0x07, 0xA4, 0xAF, 0x21, 0x69, 0x13, - 0xD8, 0xFA, 0x31, 0xED, 0xF7, 0xA7, 0xA7, 0x3B, - 0xB8, 0x96, 0x8E, 0x10, 0x86, 0x74, 0xD8, 0xB1, - 0x34, 0x9E, 0x9B, 0x6A, 0x26, 0xA8, 0xD4, 0xD0, - 0xB5, 0xF6, 0xDE, 0xE7, 0xCA, 0x06, 0xDC, 0xA3, - 0x6F, 0xEE, 0x6B, 0x1E, 0xB5, 0x30, 0x99, 0x23, - 0xF9, 0x76, 0xF0, 0xA0, 0xCF, 0x3B, 0x94, 0x7B, - 0x19, 0x8D, 0xA5, 0x0C, 0x18, 0xA6, 0x1D, 0x07, - 0x89, 0xBE, 0x5B, 0x61, 0xE5, 0xF1, 0x42, 0xDB, - 0xD4, 0x2E, 0x02, 0x1F, 0xCE, 0xEF, 0x92, 0xB1, - 0x1B, 0x56, 0x50, 0xF2, 0x16, 0xE5, 0xE7, 0x4F, - 0xFD, 0xBB, 0x3E, 0xD2, 0xFC, 0x3C, 0xC6, 0x0F, - 0xF9, 0x12, 0x4E, 0xCB, 0x1E, 0x0C, 0x15, 0x84, - 0x2A, 0x14, 0x8A, 0x02, 0xE4, 0x7E, 0x95, 0x5B, - 0x86, 0xDB, 0x9B, 0x62, 0x5B, 0x19, 0xD2, 0x17, - 0xFA, 0x13, 0xBB, 0x6B, 0x3F, 0x45, 0x9F, 0xBF -}; - - -static uint8_t ms_hmac_key0[] = { - 0xFF, 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 -}; - -static const uint8_t ms_hmac_digest0[] = { - 0x43, 0x52, 0xED, 0x34, 0xAB, 0x36, 0xB2, 0x51, - 0xFB, 0xA3, 0xA6, 0x7C, 0x38, 0xFC, 0x42, 0x8F, - 0x57, 0x64, 0xAB, 0x81, 0xA7, 0x89, 0xB7, 0x6C, - 0xA0, 0xDC, 0xB9, 0x4D, 0xC4, 0x30, 0xF9, 0xD4, - 0x10, 0x82, 0x55, 0xD0, 0xAB, 0x32, 0xFB, 0x56, - 0x0D, 0xE4, 0x68, 0x3D, 0x76, 0xD0, 0x7B, 0xE4, - 0xA6, 0x2C, 0x34, 0x9E, 0x8C, 0x41, 0xF8, 0x23, - 0x28, 0x1B, 0x3A, 0x90, 0x26, 0x34, 0x47, 0x90 - }; - -/* End Session 0 */ -/* Begin session 1 */ - -static uint8_t ms_aes_cbc_key1[] = { - 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -static uint8_t ms_aes_cbc_iv1[] = { - 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -static const uint8_t ms_aes_cbc_cipher1[] = { - 0x5A, 0x7A, 0x67, 0x5D, 0xB8, 0xE1, 0xDC, 0x71, - 0x39, 0xA8, 0x74, 0x93, 0x9C, 0x4C, 0xFE, 0x23, - 0x61, 0xCD, 0xA4, 0xB3, 0xD9, 0xCE, 0x99, 0x09, - 0x2A, 0x23, 0xF3, 0x29, 0xBF, 0x4C, 0xB4, 0x6A, - 0x1B, 0x6B, 0x73, 0x4D, 0x48, 0x0C, 0xCF, 0x6C, - 0x5E, 0x34, 0x9E, 0x7F, 0xBC, 0x8F, 0xCC, 0x8F, - 0x75, 0x1D, 0x3D, 0x77, 0x10, 0x76, 0xC8, 0xB9, - 0x99, 0x6F, 0xD6, 0x56, 0x75, 0xA9, 0xB2, 0x66, - 0xC2, 0x24, 0x2B, 0x9C, 0xFE, 0x40, 0x8E, 0x43, - 0x20, 0x97, 0x1B, 0xFA, 0xD0, 0xCF, 0x04, 0xAB, - 0xBB, 0xF6, 0x5D, 0xF5, 0xA0, 0x19, 0x7C, 0x23, - 0x5D, 0x80, 0x8C, 0x49, 0xF6, 0x76, 0x88, 0x29, - 0x27, 0x4C, 0x59, 0x2B, 0x43, 0xA6, 0xB2, 0x26, - 0x27, 0x78, 0xBE, 0x1B, 0xE1, 0x4F, 0x5A, 0x1F, - 0xFC, 0x68, 0x08, 0xE7, 0xC4, 0xD1, 0x34, 0x68, - 0xB7, 0x13, 0x14, 0x41, 0x62, 0x6B, 0x1F, 0x77, - 0x0C, 0x68, 0x1D, 0x0D, 0xED, 0x89, 0xAA, 0xD8, - 0x97, 0x02, 0xBA, 0x5E, 0xD4, 0x84, 0x25, 0x97, - 0x03, 0xA5, 0xA6, 0x13, 0x66, 0x02, 0xF4, 0xC3, - 0xF3, 0xD3, 0xCC, 0x95, 0xC3, 0x87, 0x46, 0x90, - 0x1F, 0x6E, 0x14, 0xA8, 0x00, 0xF2, 0x6F, 0xD5, - 0xA1, 0xAD, 0xD5, 0x40, 0xA2, 0x0F, 0x32, 0x7E, - 0x99, 0xA3, 0xF5, 0x53, 0xC3, 0x26, 0xA1, 0x45, - 0x01, 0x88, 0x57, 0x84, 0x3E, 0x7B, 0x4E, 0x0B, - 0x3C, 0xB5, 0x3E, 0x9E, 0xE9, 0x78, 0x77, 0xC5, - 0xC0, 0x89, 0xA8, 0xF8, 0xF1, 0xA5, 0x2D, 0x5D, - 0xF9, 0xC6, 0xFB, 0xCB, 0x05, 0x23, 0xBD, 0x6E, - 0x5E, 0x14, 0xC6, 0x57, 0x73, 0xCF, 0x98, 0xBD, - 0x10, 0x8B, 0x18, 0xA6, 0x01, 0x5B, 0x13, 0xAE, - 0x8E, 0xDE, 0x1F, 0xB5, 0xB7, 0x40, 0x6C, 0xC1, - 0x1E, 0xA1, 0x19, 0x20, 0x9E, 0x95, 0xE0, 0x2F, - 0x1C, 0xF5, 0xD9, 0xD0, 0x2B, 0x1E, 0x82, 0x25, - 0x62, 0xB4, 0xEB, 0xA1, 0x1F, 0xCE, 0x44, 0xA1, - 0xCB, 0x92, 0x01, 0x6B, 0xE4, 0x26, 0x23, 0xE3, - 0xC5, 0x67, 0x35, 0x55, 0xDA, 0xE5, 0x27, 0xEE, - 0x8D, 0x12, 0x84, 0xB7, 0xBA, 0xA7, 0x1C, 0xD6, - 0x32, 0x3F, 0x67, 0xED, 0xFB, 0x5B, 0x8B, 0x52, - 0x46, 0x8C, 0xF9, 0x69, 0xCD, 0xAE, 0x79, 0xAA, - 0x37, 0x78, 0x49, 0xEB, 0xC6, 0x8E, 0x76, 0x63, - 0x84, 0xFF, 0x9D, 0x22, 0x99, 0x51, 0xB7, 0x5E, - 0x83, 0x4C, 0x8B, 0xDF, 0x5A, 0x07, 0xCC, 0xBA, - 0x42, 0xA5, 0x98, 0xB6, 0x47, 0x0E, 0x66, 0xEB, - 0x23, 0x0E, 0xBA, 0x44, 0xA8, 0xAA, 0x20, 0x71, - 0x79, 0x9C, 0x77, 0x5F, 0xF5, 0xFE, 0xEC, 0xEF, - 0xC6, 0x64, 0x3D, 0x84, 0xD0, 0x2B, 0xA7, 0x0A, - 0xC3, 0x72, 0x5B, 0x9C, 0xFA, 0xA8, 0x87, 0x95, - 0x94, 0x11, 0x38, 0xA7, 0x1E, 0x58, 0xE3, 0x73, - 0xC6, 0xC9, 0xD1, 0x7B, 0x92, 0xDB, 0x0F, 0x49, - 0x74, 0xC2, 0xA2, 0x0E, 0x35, 0x57, 0xAC, 0xDB, - 0x9A, 0x1C, 0xCF, 0x5A, 0x32, 0x3E, 0x26, 0x9B, - 0xEC, 0xB3, 0xEF, 0x9C, 0xFE, 0xBE, 0x52, 0xAC, - 0xB1, 0x29, 0xDD, 0xFD, 0x07, 0xE2, 0xEE, 0xED, - 0xE4, 0x46, 0x37, 0xFE, 0xD1, 0xDC, 0xCD, 0x02, - 0xF9, 0x31, 0xB0, 0xFB, 0x36, 0xB7, 0x34, 0xA4, - 0x76, 0xE8, 0x57, 0xBF, 0x99, 0x92, 0xC7, 0xAF, - 0x98, 0x10, 0xE2, 0x70, 0xCA, 0xC9, 0x2B, 0x82, - 0x06, 0x96, 0x88, 0x0D, 0xB3, 0xAC, 0x9E, 0x6D, - 0x43, 0xBC, 0x5B, 0x31, 0xCF, 0x65, 0x8D, 0xA6, - 0xC7, 0xFE, 0x73, 0xE1, 0x54, 0xF7, 0x10, 0xF9, - 0x86, 0xF7, 0xDF, 0xA1, 0xA1, 0xD8, 0xAE, 0x35, - 0xB3, 0x90, 0xDC, 0x6F, 0x43, 0x7A, 0x8B, 0xE0, - 0xFE, 0x8F, 0x33, 0x4D, 0x29, 0x6C, 0x45, 0x53, - 0x73, 0xDD, 0x21, 0x0B, 0x85, 0x30, 0xB5, 0xA5, - 0xF3, 0x5D, 0xEC, 0x79, 0x61, 0x9D, 0x9E, 0xB3 - -}; - -static uint8_t ms_hmac_key1[] = { - 0xFE, 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 -}; - -static const uint8_t ms_hmac_digest1[] = { - 0xCE, 0x6E, 0x5F, 0x77, 0x96, 0x9A, 0xB1, 0x69, - 0x2D, 0x5E, 0xF3, 0x2F, 0x32, 0x10, 0xCB, 0x50, - 0x0E, 0x09, 0x56, 0x25, 0x07, 0x34, 0xC9, 0x20, - 0xEC, 0x13, 0x43, 0x23, 0x5C, 0x08, 0x8B, 0xCD, - 0xDC, 0x86, 0x8C, 0xEE, 0x0A, 0x95, 0x2E, 0xB9, - 0x8C, 0x7B, 0x02, 0x7A, 0xD4, 0xE1, 0x49, 0xB4, - 0x45, 0xB5, 0x52, 0x37, 0xC6, 0xFF, 0xFE, 0xAA, - 0x0A, 0x87, 0xB8, 0x51, 0xF9, 0x2A, 0x01, 0x8F -}; -/* End Session 1 */ -/* Begin Session 2 */ -static uint8_t ms_aes_cbc_key2[] = { - 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -static uint8_t ms_aes_cbc_iv2[] = { - 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -static const uint8_t ms_aes_cbc_cipher2[] = { - 0xBB, 0x3C, 0x68, 0x25, 0xFD, 0xB6, 0xA2, 0x91, - 0x20, 0x56, 0xF6, 0x30, 0x35, 0xFC, 0x9E, 0x97, - 0xF2, 0x90, 0xFC, 0x7E, 0x3E, 0x0A, 0x75, 0xC8, - 0x4C, 0xF2, 0x2D, 0xAC, 0xD3, 0x93, 0xF0, 0xC5, - 0x14, 0x88, 0x8A, 0x23, 0xC2, 0x59, 0x9A, 0x98, - 0x4B, 0xD5, 0x2C, 0xDA, 0x43, 0xA9, 0x34, 0x69, - 0x7C, 0x6D, 0xDB, 0xDC, 0xCB, 0xC0, 0xA0, 0x09, - 0xA7, 0x86, 0x16, 0x4B, 0xBF, 0xA8, 0xB6, 0xCF, - 0x7F, 0x74, 0x1F, 0x22, 0xF0, 0xF6, 0xBB, 0x44, - 0x8B, 0x4C, 0x9E, 0x23, 0xF8, 0x9F, 0xFC, 0x5B, - 0x9E, 0x9C, 0x2A, 0x79, 0x30, 0x8F, 0xBF, 0xA9, - 0x68, 0xA1, 0x20, 0x71, 0x7C, 0x77, 0x22, 0x34, - 0x07, 0xCD, 0xC6, 0xF6, 0x50, 0x0A, 0x08, 0x99, - 0x17, 0x98, 0xE3, 0x93, 0x8A, 0xB0, 0xEE, 0xDF, - 0xC2, 0xBA, 0x3B, 0x44, 0x73, 0xDF, 0xDD, 0xDC, - 0x14, 0x4D, 0x3B, 0xBB, 0x5E, 0x58, 0xC1, 0x26, - 0xA7, 0xAE, 0x47, 0xF3, 0x24, 0x6D, 0x4F, 0xD3, - 0x6E, 0x3E, 0x33, 0xE6, 0x7F, 0xCA, 0x50, 0xAF, - 0x5D, 0x3D, 0xA0, 0xDD, 0xC9, 0xF3, 0x30, 0xD3, - 0x6E, 0x8B, 0x2E, 0x12, 0x24, 0x34, 0xF0, 0xD3, - 0xC7, 0x8D, 0x23, 0x29, 0xAA, 0x05, 0xE1, 0xFA, - 0x2E, 0xF6, 0x8D, 0x37, 0x86, 0xC0, 0x6D, 0x13, - 0x2D, 0x98, 0xF3, 0x52, 0x39, 0x22, 0xCE, 0x38, - 0xC2, 0x1A, 0x72, 0xED, 0xFB, 0xCC, 0xE4, 0x71, - 0x5A, 0x0C, 0x0D, 0x09, 0xF8, 0xE8, 0x1B, 0xBC, - 0x53, 0xC8, 0xD8, 0x8F, 0xE5, 0x98, 0x5A, 0xB1, - 0x06, 0xA6, 0x5B, 0xE6, 0xA2, 0x88, 0x21, 0x9E, - 0x36, 0xC0, 0x34, 0xF9, 0xFB, 0x3B, 0x0A, 0x22, - 0x00, 0x00, 0x39, 0x48, 0x8D, 0x23, 0x74, 0x62, - 0x72, 0x91, 0xE6, 0x36, 0xAA, 0x77, 0x9C, 0x72, - 0x9D, 0xA8, 0xC3, 0xA9, 0xD5, 0x44, 0x72, 0xA6, - 0xB9, 0x28, 0x8F, 0x64, 0x4C, 0x8A, 0x64, 0xE6, - 0x4E, 0xFA, 0xEF, 0x87, 0xDE, 0x7B, 0x22, 0x44, - 0xB0, 0xDF, 0x2E, 0x5F, 0x0B, 0xA5, 0xF2, 0x24, - 0x07, 0x5C, 0x2D, 0x39, 0xB7, 0x3D, 0x8A, 0xE5, - 0x0E, 0x9D, 0x4E, 0x50, 0xED, 0x03, 0x99, 0x8E, - 0xF0, 0x06, 0x55, 0x4E, 0xA2, 0x24, 0xE7, 0x17, - 0x46, 0xDF, 0x6C, 0xCD, 0xC6, 0x44, 0xE8, 0xF9, - 0xB9, 0x1B, 0x36, 0xF6, 0x7F, 0x10, 0xA4, 0x7D, - 0x90, 0xBD, 0xE4, 0xAA, 0xD6, 0x9E, 0x18, 0x9D, - 0x22, 0x35, 0xD6, 0x55, 0x54, 0xAA, 0xF7, 0x22, - 0xA3, 0x3E, 0xEF, 0xC8, 0xA2, 0x34, 0x8D, 0xA9, - 0x37, 0x63, 0xA6, 0xC3, 0x57, 0xCB, 0x0C, 0x49, - 0x7D, 0x02, 0xBE, 0xAA, 0x13, 0x75, 0xB7, 0x4E, - 0x52, 0x62, 0xA5, 0xC2, 0x33, 0xC7, 0x6C, 0x1B, - 0xF6, 0x34, 0xF6, 0x09, 0xA5, 0x0C, 0xC7, 0xA2, - 0x61, 0x48, 0x62, 0x7D, 0x17, 0x15, 0xE3, 0x95, - 0xC8, 0x63, 0xD2, 0xA4, 0x43, 0xA9, 0x49, 0x07, - 0xB2, 0x3B, 0x2B, 0x62, 0x7D, 0xCB, 0x51, 0xB3, - 0x25, 0x33, 0x47, 0x0E, 0x14, 0x67, 0xDC, 0x6A, - 0x9B, 0x51, 0xAC, 0x9D, 0x8F, 0xA2, 0x2B, 0x57, - 0x8C, 0x5C, 0x5F, 0x76, 0x23, 0x92, 0x0F, 0x84, - 0x46, 0x0E, 0x40, 0x85, 0x38, 0x60, 0xFA, 0x61, - 0x20, 0xC5, 0xE3, 0xF1, 0x70, 0xAC, 0x1B, 0xBF, - 0xC4, 0x2B, 0xC5, 0x67, 0xD1, 0x43, 0xC5, 0x17, - 0x74, 0x71, 0x69, 0x6F, 0x82, 0x89, 0x19, 0x8A, - 0x70, 0x43, 0x92, 0x01, 0xC4, 0x63, 0x7E, 0xB1, - 0x59, 0x4E, 0xCD, 0xEA, 0x93, 0xA4, 0x52, 0x53, - 0x9B, 0x61, 0x5B, 0xD2, 0x3E, 0x19, 0x39, 0xB7, - 0x32, 0xEA, 0x8E, 0xF8, 0x1D, 0x76, 0x5C, 0xB2, - 0x73, 0x2D, 0x91, 0xC0, 0x18, 0xED, 0x25, 0x2A, - 0x53, 0x64, 0xF0, 0x92, 0x31, 0x55, 0x21, 0xA8, - 0x24, 0xA9, 0xD1, 0x02, 0xF6, 0x6C, 0x2B, 0x70, - 0xA9, 0x59, 0xC1, 0xD6, 0xC3, 0x57, 0x5B, 0x92 -}; - -static uint8_t ms_hmac_key2[] = { - 0xFC, 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 -}; - -static const uint8_t ms_hmac_digest2[] = { - 0xA5, 0x0F, 0x9C, 0xFB, 0x08, 0x62, 0x59, 0xFF, - 0x80, 0x2F, 0xEB, 0x4B, 0xE1, 0x46, 0x21, 0xD6, - 0x02, 0x98, 0xF2, 0x8E, 0xF4, 0xEC, 0xD4, 0x77, - 0x86, 0x4C, 0x31, 0x28, 0xC8, 0x25, 0x80, 0x27, - 0x3A, 0x72, 0x5D, 0x6A, 0x56, 0x8A, 0xD3, 0x82, - 0xB0, 0xEC, 0x31, 0x6D, 0x8B, 0x6B, 0xB4, 0x24, - 0xE7, 0x62, 0xC1, 0x52, 0xBC, 0x14, 0x1B, 0x8E, - 0xEC, 0x9A, 0xF1, 0x47, 0x80, 0xD2, 0xB0, 0x59 -}; - -/* End Session 2 */ - - -static int -test_AES_CBC_HMAC_SHA1_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_SHA1); - 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_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->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; - - /* Set crypto operation authentication parameters */ - 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; - - /* Set crypto operation cipher parameters */ - 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"); - - /* Validate obuf */ - uint8_t *ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, - 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; -} - -/* ***** AES-CBC / HMAC-SHA512 Hash Tests ***** */ - -#define HMAC_KEY_LENGTH_SHA512 (DIGEST_BYTE_LENGTH_SHA512) - -static uint8_t hmac_sha512_key[] = { - 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 }; - -static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = { - 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 }; - - - -static int -test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params, - uint8_t *cipher_key, - uint8_t *hmac_key); - -static int -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, - const uint8_t *cipher, - const uint8_t *digest, - const uint8_t *iv); - - -static int -test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params, - uint8_t *cipher_key, - uint8_t *hmac_key) -{ - - /* 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 = cipher_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_SHA512_HMAC; - ut_params->auth_xform.auth.key.data = hmac_key; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; - - return TEST_SUCCESS; -} - - -static int -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, - const uint8_t *cipher, - const uint8_t *digest, - const uint8_t *iv) -{ - /* Generate test mbuf data and digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - (const char *) - cipher, - 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, - 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"); - - rte_crypto_op_attach_sym_session(ut_params->op, 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_offset( - ut_params->ibuf, 0); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, 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"); - - /* Validate obuf */ - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "Digest verification failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_mb_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_AESNI_MB_PMD, - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_mb_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_AESNI_MB_PMD, - BLKCIPHER_AUTHONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_mb_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_AESNI_MB_PMD, - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER - -static int -test_AES_cipheronly_scheduler_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_SCHEDULER_PMD, - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_scheduler_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_SCHEDULER_PMD, - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_scheduler_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_SCHEDULER_PMD, - BLKCIPHER_AUTHONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -#endif /* RTE_LIBRTE_PMD_CRYPTO_SCHEDULER */ - -static int -test_AES_chain_openssl_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_OPENSSL_PMD, - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_openssl_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_OPENSSL_PMD, - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_qat_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD, - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_qat_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD, - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_openssl_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_OPENSSL_PMD, - BLKCIPHER_AUTHONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_armv8_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_ARMV8_PMD, - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -/* ***** SNOW 3G Tests ***** */ -static int -create_wireless_algo_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_algorithm algo) -{ - uint8_t hash_key[key_len]; - - struct crypto_unittest_params *ut_params = &unittest_params; - - memcpy(hash_key, key, key_len); - - 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 = 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; - ut_params->auth_xform.auth.add_auth_data_length = aad_len; - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params->auth_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - return 0; -} - -static int -create_wireless_algo_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]; - - struct crypto_unittest_params *ut_params = &unittest_params; - - memcpy(cipher_key, key, key_len); - - /* 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 = 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; - - TEST_HEXDUMP(stdout, "key:", key, key_len); - - /* Create Crypto session */ - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params-> - cipher_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - return 0; -} - -static int -create_wireless_algo_cipher_operation(const uint8_t *iv, const unsigned iv_len, - const unsigned cipher_len, - 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; - unsigned iv_pad_len = 0; - - /* 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 pktmbuf offload"); - - /* 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; - - /* iv */ - 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"); - - memset(sym_op->cipher.iv.data, 0, iv_pad_len); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = iv_pad_len; - - rte_memcpy(sym_op->cipher.iv.data, iv, iv_len); - sym_op->cipher.data.length = cipher_len; - sym_op->cipher.data.offset = cipher_offset; - return 0; -} - -static int -create_wireless_algo_cipher_operation_oop(const uint8_t *iv, const uint8_t iv_len, - const unsigned cipher_len, - 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; - unsigned iv_pad_len = 0; - - /* 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 pktmbuf offload"); - - /* 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 = ut_params->obuf; - - /* iv */ - 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"); - - /* For OOP operation both buffers must have the same size */ - if (ut_params->obuf) - rte_pktmbuf_prepend(ut_params->obuf, iv_pad_len); - - memset(sym_op->cipher.iv.data, 0, iv_pad_len); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = iv_pad_len; - - rte_memcpy(sym_op->cipher.iv.data, iv, iv_len); - sym_op->cipher.data.length = cipher_len; - sym_op->cipher.data.offset = cipher_offset; - return 0; -} - -static int -create_wireless_algo_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]; - - struct crypto_unittest_params *ut_params = &unittest_params; - - memcpy(cipher_auth_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 = auth_op; - 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; - ut_params->auth_xform.auth.digest_length = auth_len; - ut_params->auth_xform.auth.add_auth_data_length = aad_len; - - /* 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 = 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; - - TEST_HEXDUMP(stdout, "key:", key, key_len); - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params->cipher_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - return 0; -} - -static int -create_wireless_algo_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; - - memcpy(auth_cipher_key, key, key_len); - - /* Setup Authentication Parameters */ - 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 = 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; - ut_params->auth_xform.auth.add_auth_data_length = aad_len; - - /* 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 = 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; - - TEST_HEXDUMP(stdout, "key:", key, key_len); - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params->auth_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - return 0; -} - -static int -create_wireless_algo_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; - - struct crypto_unittest_params *ut_params = &unittest_params; - - unsigned aad_buffer_len; - - /* 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 pktmbuf offload"); - - /* 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; - - /* aad */ - /* - * Always allocate the aad up to the block size. - * 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 (8 bytes for KASUMI and 16 bytes for SNOW 3G). - */ - 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, - "no room to prepend aad"); - sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys( - ut_params->ibuf); - sym_op->auth.aad.length = aad_len; - - memset(sym_op->auth.aad.data, 0, aad_buffer_len); - rte_memcpy(sym_op->auth.aad.data, aad, aad_len); - - TEST_HEXDUMP(stdout, "aad:", - sym_op->auth.aad.data, aad_len); - - /* digest */ - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, auth_tag_len); - - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append auth tag"); - ut_params->digest = sym_op->auth.digest.data; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, data_pad_len + aad_len); - sym_op->auth.digest.length = auth_tag_len; - if (op == RTE_CRYPTO_AUTH_OP_GENERATE) - memset(sym_op->auth.digest.data, 0, auth_tag_len); - else - rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len); - - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - - sym_op->auth.data.length = auth_len; - sym_op->auth.data.offset = auth_offset; - - return 0; -} - -static int -create_wireless_algo_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) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - unsigned iv_pad_len = 0; - unsigned aad_buffer_len; - - /* 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 pktmbuf offload"); - /* 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; - - /* digest */ - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, auth_tag_len); - - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append auth tag"); - ut_params->digest = sym_op->auth.digest.data; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, data_pad_len); - sym_op->auth.digest.length = auth_tag_len; - if (op == RTE_CRYPTO_AUTH_OP_GENERATE) - memset(sym_op->auth.digest.data, 0, auth_tag_len); - else - rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len); - - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - - /* aad */ - /* - * Always allocate the aad up to the block size. - * 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 (8 bytes for KASUMI and 16 bytes for SNOW 3G). - */ - 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); - TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, - "no room to prepend aad"); - sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys( - ut_params->ibuf); - sym_op->auth.aad.length = aad_len; - memset(sym_op->auth.aad.data, 0, aad_buffer_len); - rte_memcpy(sym_op->auth.aad.data, aad, aad_len); - TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data, aad_len); - - /* iv */ - 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); - - TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); - memset(sym_op->cipher.iv.data, 0, iv_pad_len); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = iv_pad_len; - rte_memcpy(sym_op->cipher.iv.data, iv, iv_len); - sym_op->cipher.data.length = cipher_len; - sym_op->cipher.data.offset = cipher_offset + auth_offset; - sym_op->auth.data.length = auth_len; - sym_op->auth.data.offset = auth_offset + cipher_offset; - - return 0; -} - -static int -create_wireless_algo_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, - 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; - - unsigned iv_pad_len = 0; - unsigned aad_buffer_len = 0; - - /* 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 pktmbuf offload"); - - /* 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; - - /* digest */ - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, auth_tag_len); - - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append auth tag"); - - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, data_pad_len); - sym_op->auth.digest.length = auth_tag_len; - - memset(sym_op->auth.digest.data, 0, auth_tag_len); - - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - - /* aad */ - /* - * Always allocate the aad up to the block size. - * 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 (8 bytes for KASUMI 16 bytes). - */ - 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); - TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, - "no room to prepend aad"); - sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys( - ut_params->ibuf); - sym_op->auth.aad.length = aad_len; - memset(sym_op->auth.aad.data, 0, aad_buffer_len); - rte_memcpy(sym_op->auth.aad.data, aad, aad_len); - TEST_HEXDUMP(stdout, "aad:", - sym_op->auth.aad.data, aad_len); - - /* iv */ - 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); - TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); - - memset(sym_op->cipher.iv.data, 0, iv_pad_len); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = iv_pad_len; - - rte_memcpy(sym_op->cipher.iv.data, iv, iv_len); - - sym_op->cipher.data.length = cipher_len; - sym_op->cipher.data.offset = auth_offset + cipher_offset; - - sym_op->auth.data.length = auth_len; - sym_op->auth.data.offset = auth_offset + cipher_offset; - - return 0; -} - -static int -test_snow3g_authentication(const struct snow3g_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 SNOW 3G session */ - retval = create_wireless_algo_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_SNOW3G_UIA2); - 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, 16); - plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - memcpy(plaintext, tdata->plaintext.data, plaintext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_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) - 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 + tdata->aad.len; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ut_params->digest, - tdata->digest.data, - DIGEST_BYTE_LENGTH_SNOW3G_UIA2, - "SNOW 3G Generated auth tag not as expected"); - - return 0; -} - -static int -test_snow3g_authentication_verify(const struct snow3g_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 SNOW 3G session */ - retval = create_wireless_algo_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_SNOW3G_UIA2); - 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, 16); - plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - memcpy(plaintext, tdata->plaintext.data, plaintext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_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) - 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_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_wireless_algo_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_wireless_algo_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_wireless_algo_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_wireless_algo_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) -{ - return test_snow3g_authentication(&snow3g_hash_test_case_1); -} - -static int -test_snow3g_hash_generate_test_case_2(void) -{ - return test_snow3g_authentication(&snow3g_hash_test_case_2); -} - -static int -test_snow3g_hash_generate_test_case_3(void) -{ - return test_snow3g_authentication(&snow3g_hash_test_case_3); -} - -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); - -} - -static int -test_snow3g_hash_verify_test_case_2(void) -{ - return test_snow3g_authentication_verify(&snow3g_hash_test_case_2); -} - -static int -test_snow3g_hash_verify_test_case_3(void) -{ - return test_snow3g_authentication_verify(&snow3g_hash_test_case_3); -} - -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_generate_test_case_6(void) -{ - return test_kasumi_authentication(&kasumi_hash_test_case_6); -} - -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_wireless_algo_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_wireless_algo_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_sgl(const struct kasumi_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - - unsigned int plaintext_pad_len; - unsigned int plaintext_len; - - uint8_t buffer[10000]; - const uint8_t *ciphertext; - - struct rte_cryptodev_info dev_info; - - rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); - if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { - printf("Device doesn't support scatter-gather. " - "Test Skipped.\n"); - return 0; - } - - /* Create KASUMI session */ - retval = create_wireless_algo_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; - - 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); - - ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, - plaintext_pad_len, 10, 0); - - pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data); - - /* Create KASUMI operation */ - retval = create_wireless_algo_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_read(ut_params->obuf, tdata->iv.len, - plaintext_len, buffer); - else - ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len, - plaintext_len, buffer); - - /* Validate obuf */ - 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_wireless_algo_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_wireless_algo_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_encryption_oop_sgl(const struct kasumi_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - unsigned int plaintext_pad_len; - unsigned int plaintext_len; - - const uint8_t *ciphertext; - uint8_t buffer[2048]; - - struct rte_cryptodev_info dev_info; - - rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); - if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { - printf("Device doesn't support scatter-gather. " - "Test Skipped.\n"); - return 0; - } - - /* Create KASUMI session */ - retval = create_wireless_algo_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; - - 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); - - ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, - plaintext_pad_len, 10, 0); - ut_params->obuf = create_segmented_mbuf(ts_params->mbuf_pool, - plaintext_pad_len, 3, 0); - - /* Append data which is padded to a multiple */ - /* of the algorithms block size */ - pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data); - - /* Create KASUMI operation */ - retval = create_wireless_algo_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_read(ut_params->obuf, tdata->iv.len, - plaintext_pad_len, buffer); - else - ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len, - plaintext_pad_len, buffer); - - /* 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_wireless_algo_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_wireless_algo_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_wireless_algo_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_wireless_algo_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; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - uint8_t *plaintext, *ciphertext; - unsigned plaintext_pad_len; - unsigned plaintext_len; - - /* Create SNOW 3G session */ - retval = create_wireless_algo_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); - - /* 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); - memcpy(plaintext, tdata->plaintext.data, plaintext_len); - - TEST_HEXDUMP(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_cipher_operation(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, plaintext_len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validDataLenInBits.len, - "SNOW 3G Ciphertext data not as expected"); - return 0; -} - - -static int -test_snow3g_encryption_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; - unsigned plaintext_pad_len; - unsigned plaintext_len; - - /* Create SNOW 3G session */ - retval = create_wireless_algo_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, plaintext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_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, plaintext_len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validDataLenInBits.len, - "SNOW 3G Ciphertext data not as expected"); - return 0; -} - -static int -test_snow3g_encryption_oop_sgl(const struct snow3g_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - unsigned int plaintext_pad_len; - unsigned int plaintext_len; - uint8_t buffer[10000]; - const uint8_t *ciphertext; - - struct rte_cryptodev_info dev_info; - - rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); - if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { - printf("Device doesn't support scatter-gather. " - "Test Skipped.\n"); - return 0; - } - - /* Create SNOW 3G session */ - retval = create_wireless_algo_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; - - 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); - - ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, - plaintext_pad_len, 10, 0); - ut_params->obuf = create_segmented_mbuf(ts_params->mbuf_pool, - plaintext_pad_len, 3, 0); - - 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"); - - pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_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_read(ut_params->obuf, tdata->iv.len, - plaintext_len, buffer); - else - ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len, - plaintext_len, buffer); - - TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validDataLenInBits.len, - "SNOW 3G 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 SNOW 3G session */ - retval = create_wireless_algo_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 + extra_offset); - /* - * 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, (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 SNOW 3G operation */ - retval = create_wireless_algo_cipher_operation_oop(tdata->iv.data, - tdata->iv.len, - tdata->validCipherLenInBits.len, - tdata->validCipherOffsetLenInBits.len + - extra_offset, - 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; - -#ifdef RTE_APP_TEST_DEBUG - 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_BIT_OFFSET( - ciphertext, - expected_ciphertext_shifted, - tdata->validDataLenInBits.len, - extra_offset, - "SNOW 3G 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; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - - uint8_t *plaintext, *ciphertext; - unsigned ciphertext_pad_len; - unsigned ciphertext_len; - - /* Create SNOW 3G session */ - retval = create_wireless_algo_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; - - 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, 16); - 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 SNOW 3G operation */ - retval = create_wireless_algo_cipher_operation(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) - 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->validDataLenInBits.len, - "SNOW 3G Plaintext data not as expected"); - return 0; -} - -static int test_snow3g_decryption_oop(const struct snow3g_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 ciphertext_pad_len; - unsigned ciphertext_len; - - /* Create SNOW 3G session */ - retval = create_wireless_algo_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; - - 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"); - TEST_ASSERT_NOT_NULL(ut_params->obuf, - "Failed to allocate output buffer"); - - /* Clear mbuf payload */ - memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->ibuf)); - - memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->obuf)); - - 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); - - TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, ciphertext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_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) - 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->validDataLenInBits.len, - "SNOW 3G Plaintext data not as expected"); - return 0; -} - -static int -test_snow3g_cipher_auth(const struct snow3g_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 SNOW 3G session */ - retval = create_wireless_algo_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) - 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, 16); - 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 SNOW 3G operation */ - retval = create_wireless_algo_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 - ); - 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; - if (ut_params->obuf) - ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + tdata->iv.len + tdata->aad.len; - else - ciphertext = plaintext; - - TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validDataLenInBits.len, - "SNOW 3G Ciphertext data not as expected"); - - ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + plaintext_pad_len + tdata->aad.len + tdata->iv.len; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ut_params->digest, - tdata->digest.data, - DIGEST_BYTE_LENGTH_SNOW3G_UIA2, - "SNOW 3G Generated auth tag not as expected"); - return 0; -} -static int -test_snow3g_auth_cipher(const struct snow3g_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 SNOW 3G session */ - retval = create_wireless_algo_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) - 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, 16); - 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 SNOW 3G operation */ - retval = create_wireless_algo_auth_cipher_operation( - tdata->digest.len, - tdata->iv.data, tdata->iv.len, - tdata->aad.data, tdata->aad.len, - plaintext_pad_len, - tdata->validCipherLenInBits.len, - tdata->validCipherOffsetLenInBits.len, - tdata->validAuthLenInBits.len, - tdata->validAuthOffsetLenInBits.len, - RTE_CRYPTO_AUTH_SNOW3G_UIA2, - 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; - if (ut_params->obuf) - ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + tdata->aad.len + tdata->iv.len; - else - ciphertext = plaintext; - - ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + plaintext_pad_len + tdata->aad.len + tdata->iv.len; - TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validDataLenInBits.len, - "SNOW 3G Ciphertext data not as expected"); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ut_params->digest, - tdata->digest.data, - DIGEST_BYTE_LENGTH_SNOW3G_UIA2, - "SNOW 3G Generated auth tag not as expected"); - return 0; -} - -static int -test_kasumi_auth_cipher(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_wireless_algo_auth_cipher_session( - ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - RTE_CRYPTO_AUTH_OP_GENERATE, - RTE_CRYPTO_AUTH_KASUMI_F9, - RTE_CRYPTO_CIPHER_KASUMI_F8, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->digest.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, 16); - 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_wireless_algo_auth_cipher_operation(tdata->digest.len, - tdata->iv.data, tdata->iv.len, - tdata->aad.data, tdata->aad.len, - plaintext_pad_len, - tdata->validCipherLenInBits.len, - tdata->validCipherOffsetLenInBits.len, - tdata->validAuthLenInBits.len, - tdata->validAuthOffsetLenInBits.len, - RTE_CRYPTO_AUTH_KASUMI_F9, - 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_src; - if (ut_params->obuf) - ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + tdata->iv.len + tdata->aad.len; - else - ciphertext = plaintext; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validCipherLenInBits.len, - "KASUMI Ciphertext data not as expected"); - ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + plaintext_pad_len + tdata->aad.len + tdata->iv.len; - - /* 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_cipher_auth(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_wireless_algo_cipher_auth_session( - ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - RTE_CRYPTO_AUTH_OP_GENERATE, - RTE_CRYPTO_AUTH_KASUMI_F9, - RTE_CRYPTO_CIPHER_KASUMI_F8, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->digest.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, 16); - 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_wireless_algo_cipher_hash_operation(tdata->digest.data, - tdata->digest.len, tdata->aad.data, - tdata->aad.len, - plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, - RTE_CRYPTO_AUTH_KASUMI_F9, - RTE_CRYPTO_CIPHER_KASUMI_F8, - tdata->iv.data, tdata->iv.len, - tdata->validCipherLenInBits.len, - tdata->validCipherOffsetLenInBits.len, - 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; - if (ut_params->obuf) - ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + tdata->aad.len + tdata->iv.len; - else - ciphertext = plaintext; - - ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + plaintext_pad_len + tdata->aad.len + tdata->iv.len; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validCipherLenInBits.len, - "KASUMI Ciphertext data not as expected"); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ut_params->digest, - tdata->digest.data, - DIGEST_BYTE_LENGTH_SNOW3G_UIA2, - "KASUMI Generated auth tag not as expected"); - return 0; -} - -static int -test_zuc_encryption(const struct zuc_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 ZUC session */ - retval = create_wireless_algo_cipher_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - RTE_CRYPTO_CIPHER_ZUC_EEA3, - 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 ZUC operation */ - retval = create_wireless_algo_cipher_operation(tdata->iv.data, tdata->iv.len, - tdata->plaintext.len, - tdata->validCipherOffsetLenInBits.len, - RTE_CRYPTO_CIPHER_ZUC_EEA3); - 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, - "ZUC Ciphertext data not as expected"); - return 0; -} - -static int -test_zuc_encryption_sgl(const struct zuc_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - - unsigned int plaintext_pad_len; - unsigned int plaintext_len; - const uint8_t *ciphertext; - uint8_t ciphertext_buffer[2048]; - struct rte_cryptodev_info dev_info; - - rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); - if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { - printf("Device doesn't support scatter-gather. " - "Test Skipped.\n"); - return 0; - } - - 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); - - ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, - plaintext_pad_len, 10, 0); - - pktmbuf_write(ut_params->ibuf, 0, plaintext_len, - tdata->plaintext.data); - - /* Create ZUC session */ - retval = create_wireless_algo_cipher_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - RTE_CRYPTO_CIPHER_ZUC_EEA3, - tdata->key.data, tdata->key.len); - if (retval < 0) - return retval; - - /* Clear mbuf payload */ - - pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data); - - /* Create ZUC operation */ - retval = create_wireless_algo_cipher_operation(tdata->iv.data, - tdata->iv.len, tdata->plaintext.len, - tdata->validCipherOffsetLenInBits.len, - RTE_CRYPTO_CIPHER_ZUC_EEA3); - 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_read(ut_params->obuf, - tdata->iv.len, plaintext_len, ciphertext_buffer); - else - ciphertext = rte_pktmbuf_read(ut_params->ibuf, - tdata->iv.len, plaintext_len, ciphertext_buffer); - - /* Validate obuf */ - TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validCipherLenInBits.len, - "ZUC Ciphertext data not as expected"); - - return 0; -} - -static int -test_zuc_authentication(const struct zuc_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 ZUC session */ - retval = create_wireless_algo_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_ZUC_EIA3); - 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 ZUC operation */ - retval = create_wireless_algo_hash_operation(NULL, tdata->digest.len, - tdata->aad.data, tdata->aad.len, - plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, - RTE_CRYPTO_AUTH_ZUC_EIA3, - 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, - "ZUC Generated auth tag not as expected"); - - return 0; -} - -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_sgl(void) -{ - return test_kasumi_encryption_sgl(&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_1_oop_sgl(void) -{ - return test_kasumi_encryption_oop_sgl(&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); -} - -static int -test_snow3g_encryption_test_case_1_oop(void) -{ - return test_snow3g_encryption_oop(&snow3g_test_case_1); -} - -static int -test_snow3g_encryption_test_case_1_oop_sgl(void) -{ - return test_snow3g_encryption_oop_sgl(&snow3g_test_case_1); -} - - -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); -} - -static int -test_snow3g_encryption_test_case_3(void) -{ - return test_snow3g_encryption(&snow3g_test_case_3); -} - -static int -test_snow3g_encryption_test_case_4(void) -{ - return test_snow3g_encryption(&snow3g_test_case_4); -} - -static int -test_snow3g_encryption_test_case_5(void) -{ - return test_snow3g_encryption(&snow3g_test_case_5); -} - -static int -test_snow3g_decryption_test_case_1(void) -{ - return test_snow3g_decryption(&snow3g_test_case_1); -} - -static int -test_snow3g_decryption_test_case_1_oop(void) -{ - return test_snow3g_decryption_oop(&snow3g_test_case_1); -} - -static int -test_snow3g_decryption_test_case_2(void) -{ - return test_snow3g_decryption(&snow3g_test_case_2); -} - -static int -test_snow3g_decryption_test_case_3(void) -{ - return test_snow3g_decryption(&snow3g_test_case_3); -} - -static int -test_snow3g_decryption_test_case_4(void) -{ - return test_snow3g_decryption(&snow3g_test_case_4); -} - -static int -test_snow3g_decryption_test_case_5(void) -{ - return test_snow3g_decryption(&snow3g_test_case_5); -} -static int -test_snow3g_cipher_auth_test_case_1(void) -{ - return test_snow3g_cipher_auth(&snow3g_test_case_3); -} - -static int -test_snow3g_auth_cipher_test_case_1(void) -{ - return test_snow3g_auth_cipher(&snow3g_test_case_6); -} - -static int -test_kasumi_auth_cipher_test_case_1(void) -{ - return test_kasumi_auth_cipher(&kasumi_test_case_3); -} - -static int -test_kasumi_cipher_auth_test_case_1(void) -{ - return test_kasumi_cipher_auth(&kasumi_test_case_6); -} - -static int -test_zuc_encryption_test_case_1(void) -{ - return test_zuc_encryption(&zuc_test_case_1); -} - -static int -test_zuc_encryption_test_case_2(void) -{ - return test_zuc_encryption(&zuc_test_case_2); -} - -static int -test_zuc_encryption_test_case_3(void) -{ - return test_zuc_encryption(&zuc_test_case_3); -} - -static int -test_zuc_encryption_test_case_4(void) -{ - return test_zuc_encryption(&zuc_test_case_4); -} - -static int -test_zuc_encryption_test_case_5(void) -{ - return test_zuc_encryption(&zuc_test_case_5); -} - -static int -test_zuc_encryption_test_case_6_sgl(void) -{ - return test_zuc_encryption_sgl(&zuc_test_case_1); -} - -static int -test_zuc_hash_generate_test_case_1(void) -{ - return test_zuc_authentication(&zuc_hash_test_case_1); -} - -static int -test_zuc_hash_generate_test_case_2(void) -{ - return test_zuc_authentication(&zuc_hash_test_case_2); -} - -static int -test_zuc_hash_generate_test_case_3(void) -{ - return test_zuc_authentication(&zuc_hash_test_case_3); -} - -static int -test_zuc_hash_generate_test_case_4(void) -{ - return test_zuc_authentication(&zuc_hash_test_case_4); -} - -static int -test_zuc_hash_generate_test_case_5(void) -{ - return test_zuc_authentication(&zuc_hash_test_case_5); -} - -static int -test_3DES_chain_qat_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD, - BLKCIPHER_3DES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_DES_cipheronly_qat_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD, - BLKCIPHER_DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_cipheronly_qat_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD, - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_chain_openssl_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_OPENSSL_PMD, - BLKCIPHER_3DES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_cipheronly_openssl_all(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - int status; - - status = test_blockcipher_all_tests(ts_params->mbuf_pool, - ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_OPENSSL_PMD, - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -/* ***** AES-GCM Tests ***** */ - -static int -create_gcm_session(uint8_t dev_id, enum rte_crypto_cipher_operation op, - const uint8_t *key, const uint8_t key_len, - const uint8_t aad_len, const uint8_t auth_len, - enum rte_crypto_auth_operation auth_op) -{ - uint8_t cipher_key[key_len]; - - struct crypto_unittest_params *ut_params = &unittest_params; - - memcpy(cipher_key, key, key_len); - - /* 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_GCM; - ut_params->auth_xform.auth.op = auth_op; - 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; - - 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.algo = RTE_CRYPTO_AUTH_AES_GCM; - - ut_params->auth_xform.auth.digest_length = auth_len; - ut_params->auth_xform.auth.add_auth_data_length = aad_len; - ut_params->auth_xform.auth.key.length = 0; - ut_params->auth_xform.auth.key.data = NULL; - - if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { - ut_params->cipher_xform.next = &ut_params->auth_xform; - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params->cipher_xform); - } else {/* Create Crypto session*/ - ut_params->auth_xform.next = &ut_params->cipher_xform; - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params->auth_xform); - } - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - return 0; -} - -static int -create_gcm_xforms(struct rte_crypto_op *op, - enum rte_crypto_cipher_operation cipher_op, - uint8_t *key, const uint8_t key_len, - const uint8_t aad_len, const uint8_t auth_len, - enum rte_crypto_auth_operation auth_op) -{ - TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(op, 2), - "failed to allocate space for crypto transforms"); - - struct rte_crypto_sym_op *sym_op = op->sym; - - /* Setup Cipher Parameters */ - sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - sym_op->xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_GCM; - sym_op->xform->cipher.op = cipher_op; - sym_op->xform->cipher.key.data = key; - sym_op->xform->cipher.key.length = key_len; - - TEST_HEXDUMP(stdout, "key:", key, key_len); - - /* Setup Authentication Parameters */ - sym_op->xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH; - sym_op->xform->next->auth.algo = RTE_CRYPTO_AUTH_AES_GCM; - sym_op->xform->next->auth.op = auth_op; - sym_op->xform->next->auth.digest_length = auth_len; - sym_op->xform->next->auth.add_auth_data_length = aad_len; - sym_op->xform->next->auth.key.length = 0; - sym_op->xform->next->auth.key.data = NULL; - sym_op->xform->next->next = NULL; - - return 0; -} - -static int -create_gcm_operation(enum rte_crypto_cipher_operation op, - const struct gcm_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - uint8_t *plaintext, *ciphertext; - unsigned int iv_pad_len, aad_pad_len, plaintext_pad_len; - - /* 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"); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* Append aad data */ - aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); - sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - aad_pad_len); - TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, - "no room to append aad"); - - sym_op->auth.aad.length = tdata->aad.len; - sym_op->auth.aad.phys_addr = - rte_pktmbuf_mtophys(ut_params->ibuf); - memcpy(sym_op->auth.aad.data, tdata->aad.data, tdata->aad.len); - TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data, - sym_op->auth.aad.length); - - /* Prepend iv */ - iv_pad_len = RTE_ALIGN_CEIL(tdata->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"); - - memset(sym_op->cipher.iv.data, 0, iv_pad_len); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = tdata->iv.len; - - rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, tdata->iv.len); - TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data, - sym_op->cipher.iv.length); - - /* Append plaintext/ciphertext */ - if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { - plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); - plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext"); - - memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len); - TEST_HEXDUMP(stdout, "plaintext:", plaintext, - tdata->plaintext.len); - - if (ut_params->obuf) { - ciphertext = (uint8_t *)rte_pktmbuf_append( - ut_params->obuf, - plaintext_pad_len + aad_pad_len + - iv_pad_len); - TEST_ASSERT_NOT_NULL(ciphertext, - "no room to append ciphertext"); - - memset(ciphertext + aad_pad_len + iv_pad_len, 0, - tdata->ciphertext.len); - } - } else { - plaintext_pad_len = RTE_ALIGN_CEIL(tdata->ciphertext.len, 16); - ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - TEST_ASSERT_NOT_NULL(ciphertext, - "no room to append ciphertext"); - - memcpy(ciphertext, tdata->ciphertext.data, - tdata->ciphertext.len); - TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, - tdata->ciphertext.len); - - if (ut_params->obuf) { - plaintext = (uint8_t *)rte_pktmbuf_append( - ut_params->obuf, - plaintext_pad_len + aad_pad_len + - iv_pad_len); - TEST_ASSERT_NOT_NULL(plaintext, - "no room to append plaintext"); - - memset(plaintext + aad_pad_len + iv_pad_len, 0, - tdata->plaintext.len); - } - } - - /* Append digest data */ - if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->obuf ? ut_params->obuf : - ut_params->ibuf, - tdata->auth_tag.len); - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append digest"); - memset(sym_op->auth.digest.data, 0, tdata->auth_tag.len); - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->obuf ? ut_params->obuf : - ut_params->ibuf, - plaintext_pad_len + - aad_pad_len + iv_pad_len); - sym_op->auth.digest.length = tdata->auth_tag.len; - } else { - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, tdata->auth_tag.len); - 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, - plaintext_pad_len + aad_pad_len + iv_pad_len); - sym_op->auth.digest.length = tdata->auth_tag.len; - - rte_memcpy(sym_op->auth.digest.data, tdata->auth_tag.data, - tdata->auth_tag.len); - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - } - - sym_op->cipher.data.length = tdata->plaintext.len; - sym_op->cipher.data.offset = aad_pad_len + iv_pad_len; - - sym_op->auth.data.length = tdata->plaintext.len; - sym_op->auth.data.offset = aad_pad_len + iv_pad_len; - - return 0; -} - -static int -test_mb_AES_GCM_authenticated_encryption(const struct gcm_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - uint8_t *ciphertext, *auth_tag; - uint16_t plaintext_pad_len; - uint32_t i; - - /* Create GCM session */ - retval = create_gcm_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_GENERATE); - if (retval < 0) - return retval; - - if (tdata->aad.len > MBUF_SIZE) { - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool); - /* Populate full size of add data */ - for (i = 32; i < GCM_MAX_AAD_LENGTH; i += 32) - memcpy(&tdata->aad.data[i], &tdata->aad.data[0], 32); - } else - 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)); - - /* Create GCM operation */ - retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata); - if (retval < 0) - return retval; - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - ut_params->op->sym->m_src = ut_params->ibuf; - - /* 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"); - - plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); - - if (ut_params->op->sym->m_dst) { - ciphertext = rte_pktmbuf_mtod(ut_params->op->sym->m_dst, - uint8_t *); - auth_tag = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, - uint8_t *, plaintext_pad_len); - } else { - ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, - uint8_t *, - ut_params->op->sym->cipher.data.offset); - auth_tag = ciphertext + plaintext_pad_len; - } - - 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, - tdata->ciphertext.data, - tdata->ciphertext.len, - "GCM Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - tdata->auth_tag.data, - tdata->auth_tag.len, - "GCM Generated auth tag not as expected"); - - return 0; - -} - -static int -test_mb_AES_GCM_authenticated_encryption_test_case_1(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_1); -} - -static int -test_mb_AES_GCM_authenticated_encryption_test_case_2(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_2); -} - -static int -test_mb_AES_GCM_authenticated_encryption_test_case_3(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_3); -} - -static int -test_mb_AES_GCM_authenticated_encryption_test_case_4(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_4); -} - -static int -test_mb_AES_GCM_authenticated_encryption_test_case_5(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_5); -} - -static int -test_mb_AES_GCM_authenticated_encryption_test_case_6(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_6); -} - -static int -test_mb_AES_GCM_authenticated_encryption_test_case_7(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_7); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_256_1(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_1); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_256_2(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_2); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_256_3(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_3); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_256_4(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_4); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_256_5(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_5); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_256_6(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_6); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_256_7(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_7); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_aad_1(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_aad_1); -} - -static int -test_mb_AES_GCM_auth_encryption_test_case_aad_2(void) -{ - return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_aad_2); -} - -static int -test_mb_AES_GCM_authenticated_decryption(const struct gcm_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - uint8_t *plaintext; - uint32_t i; - - /* Create GCM session */ - retval = create_gcm_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_DECRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_VERIFY); - if (retval < 0) - return retval; - - /* alloc mbuf and set payload */ - if (tdata->aad.len > MBUF_SIZE) { - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool); - /* Populate full size of add data */ - for (i = 32; i < GCM_MAX_AAD_LENGTH; i += 32) - memcpy(&tdata->aad.data[i], &tdata->aad.data[0], 32); - } else - 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)); - - /* Create GCM operation */ - retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata); - if (retval < 0) - return retval; - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - ut_params->op->sym->m_src = ut_params->ibuf; - - /* 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"); - - if (ut_params->op->sym->m_dst) - plaintext = rte_pktmbuf_mtod(ut_params->op->sym->m_dst, - uint8_t *); - else - plaintext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, - uint8_t *, - ut_params->op->sym->cipher.data.offset); - - TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - plaintext, - tdata->plaintext.data, - tdata->plaintext.len, - "GCM plaintext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_SUCCESS, - "GCM authentication failed"); - return 0; -} - -static int -test_mb_AES_GCM_authenticated_decryption_test_case_1(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_1); -} - -static int -test_mb_AES_GCM_authenticated_decryption_test_case_2(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_2); -} - -static int -test_mb_AES_GCM_authenticated_decryption_test_case_3(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_3); -} - -static int -test_mb_AES_GCM_authenticated_decryption_test_case_4(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_4); -} - -static int -test_mb_AES_GCM_authenticated_decryption_test_case_5(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_5); -} - -static int -test_mb_AES_GCM_authenticated_decryption_test_case_6(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_6); -} - -static int -test_mb_AES_GCM_authenticated_decryption_test_case_7(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_7); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_256_1(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_1); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_256_2(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_2); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_256_3(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_3); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_256_4(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_4); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_256_5(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_5); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_256_6(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_6); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_256_7(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_7); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_aad_1(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_aad_1); -} - -static int -test_mb_AES_GCM_auth_decryption_test_case_aad_2(void) -{ - return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_aad_2); -} - -static int -test_AES_GCM_authenticated_encryption_oop(const struct gcm_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - uint8_t *ciphertext, *auth_tag; - uint16_t plaintext_pad_len; - - /* Create GCM session */ - retval = create_gcm_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_GENERATE); - 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)); - memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->obuf)); - - /* Create GCM operation */ - retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata); - if (retval < 0) - return retval; - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - ut_params->op->sym->m_src = ut_params->ibuf; - ut_params->op->sym->m_dst = ut_params->obuf; - - /* 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"); - - plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); - - ciphertext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *, - ut_params->op->sym->cipher.data.offset); - auth_tag = ciphertext + plaintext_pad_len; - - 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, - tdata->ciphertext.data, - tdata->ciphertext.len, - "GCM Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - tdata->auth_tag.data, - tdata->auth_tag.len, - "GCM Generated auth tag not as expected"); - - return 0; - -} - -static int -test_mb_AES_GCM_authenticated_encryption_oop(void) -{ - return test_AES_GCM_authenticated_encryption_oop(&gcm_test_case_5); -} - -static int -test_AES_GCM_authenticated_decryption_oop(const struct gcm_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - uint8_t *plaintext; - - /* Create GCM session */ - retval = create_gcm_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_DECRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_VERIFY); - if (retval < 0) - return retval; - - /* alloc mbuf and set payload */ - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - - memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->ibuf)); - memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->obuf)); - - /* Create GCM operation */ - retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata); - if (retval < 0) - return retval; - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - ut_params->op->sym->m_src = ut_params->ibuf; - ut_params->op->sym->m_dst = ut_params->obuf; - - /* 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"); - - plaintext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *, - ut_params->op->sym->cipher.data.offset); - - TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - plaintext, - tdata->plaintext.data, - tdata->plaintext.len, - "GCM plaintext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_SUCCESS, - "GCM authentication failed"); - return 0; -} - -static int -test_mb_AES_GCM_authenticated_decryption_oop(void) -{ - return test_AES_GCM_authenticated_decryption_oop(&gcm_test_case_5); -} - -static int -test_AES_GCM_authenticated_encryption_sessionless( - const struct gcm_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - uint8_t *ciphertext, *auth_tag; - uint16_t plaintext_pad_len; - uint8_t key[tdata->key.len + 1]; - - 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)); - - /* Create GCM operation */ - retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata); - if (retval < 0) - return retval; - - /* Create GCM xforms */ - memcpy(key, tdata->key.data, tdata->key.len); - retval = create_gcm_xforms(ut_params->op, - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - key, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_GENERATE); - if (retval < 0) - return retval; - - ut_params->op->sym->m_src = ut_params->ibuf; - - TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type, - RTE_CRYPTO_SYM_OP_SESSIONLESS, - "crypto op session type not sessionless"); - - /* 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_NOT_NULL(ut_params->op, "failed crypto process"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op status not success"); - - plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); - - ciphertext = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, - ut_params->op->sym->cipher.data.offset); - auth_tag = ciphertext + plaintext_pad_len; - - 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, - tdata->ciphertext.data, - tdata->ciphertext.len, - "GCM Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - tdata->auth_tag.data, - tdata->auth_tag.len, - "GCM Generated auth tag not as expected"); - - return 0; - -} - -static int -test_mb_AES_GCM_authenticated_encryption_sessionless(void) -{ - return test_AES_GCM_authenticated_encryption_sessionless( - &gcm_test_case_5); -} - -static int -test_AES_GCM_authenticated_decryption_sessionless( - const struct gcm_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - uint8_t *plaintext; - uint8_t key[tdata->key.len + 1]; - - /* 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)); - - /* Create GCM operation */ - retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata); - if (retval < 0) - return retval; - - /* Create GCM xforms */ - memcpy(key, tdata->key.data, tdata->key.len); - retval = create_gcm_xforms(ut_params->op, - RTE_CRYPTO_CIPHER_OP_DECRYPT, - key, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_VERIFY); - if (retval < 0) - return retval; - - ut_params->op->sym->m_src = ut_params->ibuf; - - TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type, - RTE_CRYPTO_SYM_OP_SESSIONLESS, - "crypto op session type not sessionless"); - - /* 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_NOT_NULL(ut_params->op, "failed crypto process"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op status not success"); - - plaintext = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, - ut_params->op->sym->cipher.data.offset); - - TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - plaintext, - tdata->plaintext.data, - tdata->plaintext.len, - "GCM plaintext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_SUCCESS, - "GCM authentication failed"); - return 0; -} - -static int -test_mb_AES_GCM_authenticated_decryption_sessionless(void) -{ - return test_AES_GCM_authenticated_decryption_sessionless( - &gcm_test_case_5); -} - -static int -test_stats(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_cryptodev_stats stats; - struct rte_cryptodev *dev; - cryptodev_stats_get_t temp_pfn; - - rte_cryptodev_stats_reset(ts_params->valid_devs[0]); - TEST_ASSERT((rte_cryptodev_stats_get(ts_params->valid_devs[0] + 600, - &stats) == -ENODEV), - "rte_cryptodev_stats_get invalid dev failed"); - TEST_ASSERT((rte_cryptodev_stats_get(ts_params->valid_devs[0], 0) != 0), - "rte_cryptodev_stats_get invalid Param failed"); - dev = &rte_cryptodevs[ts_params->valid_devs[0]]; - temp_pfn = dev->dev_ops->stats_get; - dev->dev_ops->stats_get = (cryptodev_stats_get_t)0; - TEST_ASSERT((rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats) - == -ENOTSUP), - "rte_cryptodev_stats_get invalid Param failed"); - dev->dev_ops->stats_get = temp_pfn; - - /* Test expected values */ - ut_setup(); - test_AES_CBC_HMAC_SHA1_encrypt_digest(); - ut_teardown(); - TEST_ASSERT_SUCCESS(rte_cryptodev_stats_get(ts_params->valid_devs[0], - &stats), - "rte_cryptodev_stats_get failed"); - TEST_ASSERT((stats.enqueued_count == 1), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); - TEST_ASSERT((stats.dequeued_count == 1), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); - TEST_ASSERT((stats.enqueue_err_count == 0), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); - TEST_ASSERT((stats.dequeue_err_count == 0), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); - - /* invalid device but should ignore and not reset device stats*/ - rte_cryptodev_stats_reset(ts_params->valid_devs[0] + 300); - TEST_ASSERT_SUCCESS(rte_cryptodev_stats_get(ts_params->valid_devs[0], - &stats), - "rte_cryptodev_stats_get failed"); - TEST_ASSERT((stats.enqueued_count == 1), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); - - /* check that a valid reset clears stats */ - rte_cryptodev_stats_reset(ts_params->valid_devs[0]); - TEST_ASSERT_SUCCESS(rte_cryptodev_stats_get(ts_params->valid_devs[0], - &stats), - "rte_cryptodev_stats_get failed"); - TEST_ASSERT((stats.enqueued_count == 0), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); - TEST_ASSERT((stats.dequeued_count == 0), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); - - return TEST_SUCCESS; -} - -static int MD5_HMAC_create_session(struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - enum rte_crypto_auth_operation op, - const struct HMAC_MD5_vector *test_case) -{ - uint8_t key[64]; - - memcpy(key, test_case->key.data, test_case->key.len); - - 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_MD5_HMAC; - - ut_params->auth_xform.auth.digest_length = MD5_DIGEST_LEN; - ut_params->auth_xform.auth.add_auth_data_length = 0; - ut_params->auth_xform.auth.key.length = test_case->key.len; - ut_params->auth_xform.auth.key.data = key; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], &ut_params->auth_xform); - - if (ut_params->sess == NULL) - return TEST_FAILED; - - 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)); - - return 0; -} - -static int MD5_HMAC_create_op(struct crypto_unittest_params *ut_params, - const struct HMAC_MD5_vector *test_case, - uint8_t **plaintext) -{ - uint16_t plaintext_pad_len; - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - plaintext_pad_len = RTE_ALIGN_CEIL(test_case->plaintext.len, - 16); - - *plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - memcpy(*plaintext, test_case->plaintext.data, - test_case->plaintext.len); - - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, MD5_DIGEST_LEN); - 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, plaintext_pad_len); - sym_op->auth.digest.length = MD5_DIGEST_LEN; - - if (ut_params->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) { - rte_memcpy(sym_op->auth.digest.data, test_case->auth_tag.data, - test_case->auth_tag.len); - } - - sym_op->auth.data.offset = 0; - sym_op->auth.data.length = test_case->plaintext.len; - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - ut_params->op->sym->m_src = ut_params->ibuf; - - return 0; -} - -static int -test_MD5_HMAC_generate(const struct HMAC_MD5_vector *test_case) -{ - uint16_t plaintext_pad_len; - uint8_t *plaintext, *auth_tag; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - if (MD5_HMAC_create_session(ts_params, ut_params, - RTE_CRYPTO_AUTH_OP_GENERATE, test_case)) - return TEST_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"); - - plaintext_pad_len = RTE_ALIGN_CEIL(test_case->plaintext.len, - 16); - - if (MD5_HMAC_create_op(ut_params, test_case, &plaintext)) - return TEST_FAILED; - - 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"); - - if (ut_params->op->sym->m_dst) { - auth_tag = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, - uint8_t *, plaintext_pad_len); - } else { - auth_tag = plaintext + plaintext_pad_len; - } - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - test_case->auth_tag.data, - test_case->auth_tag.len, - "HMAC_MD5 generated tag not as expected"); - - return TEST_SUCCESS; -} - -static int -test_MD5_HMAC_verify(const struct HMAC_MD5_vector *test_case) -{ - uint8_t *plaintext; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - if (MD5_HMAC_create_session(ts_params, ut_params, - RTE_CRYPTO_AUTH_OP_VERIFY, test_case)) { - return TEST_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"); - - if (MD5_HMAC_create_op(ut_params, test_case, &plaintext)) - return TEST_FAILED; - - 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, - "HMAC_MD5 crypto op processing failed"); - - return TEST_SUCCESS; -} - -static int -test_MD5_HMAC_generate_case_1(void) -{ - return test_MD5_HMAC_generate(&HMAC_MD5_test_case_1); -} - -static int -test_MD5_HMAC_verify_case_1(void) -{ - return test_MD5_HMAC_verify(&HMAC_MD5_test_case_1); -} - -static int -test_MD5_HMAC_generate_case_2(void) -{ - return test_MD5_HMAC_generate(&HMAC_MD5_test_case_2); -} - -static int -test_MD5_HMAC_verify_case_2(void) -{ - return test_MD5_HMAC_verify(&HMAC_MD5_test_case_2); -} - -static int -test_multi_session(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - struct rte_cryptodev_info dev_info; - struct rte_cryptodev_sym_session **sessions; - - uint16_t i; - - test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params, - aes_cbc_key, hmac_sha512_key); - - - rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); - - sessions = rte_malloc(NULL, - (sizeof(struct rte_cryptodev_sym_session *) * - dev_info.sym.max_nb_sessions) + 1, 0); - - /* Create multiple crypto sessions*/ - for (i = 0; i < dev_info.sym.max_nb_sessions; i++) { - sessions[i] = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], - &ut_params->auth_xform); - TEST_ASSERT_NOT_NULL(sessions[i], - "Session creation failed at session number %u", - i); - - /* Attempt to send a request on each session */ - TEST_ASSERT_SUCCESS( test_AES_CBC_HMAC_SHA512_decrypt_perform( - sessions[i], - ut_params, - ts_params, - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, - aes_cbc_iv), - "Failed to perform decrypt on request number %u.", i); - /* free crypto operation structure */ - if (ut_params->op) - rte_crypto_op_free(ut_params->op); - - /* - * free mbuf - both obuf and ibuf are usually the same, - * 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 */ - sessions[i] = rte_cryptodev_sym_session_create(ts_params->valid_devs[0], - &ut_params->auth_xform); - TEST_ASSERT_NULL(sessions[i], - "Session creation succeeded unexpectedly!"); - - for (i = 0; i < dev_info.sym.max_nb_sessions; i++) - rte_cryptodev_sym_session_free(ts_params->valid_devs[0], - sessions[i]); - - rte_free(sessions); - - return TEST_SUCCESS; -} - -struct multi_session_params { - struct crypto_unittest_params ut_params; - uint8_t *cipher_key; - uint8_t *hmac_key; - const uint8_t *cipher; - const uint8_t *digest; - uint8_t *iv; -}; - -#define MB_SESSION_NUMBER 3 - -static int -test_multi_session_random_usage(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_cryptodev_info dev_info; - struct rte_cryptodev_sym_session **sessions; - uint32_t i, j; - struct multi_session_params ut_paramz[] = { - - { - .cipher_key = ms_aes_cbc_key0, - .hmac_key = ms_hmac_key0, - .cipher = ms_aes_cbc_cipher0, - .digest = ms_hmac_digest0, - .iv = ms_aes_cbc_iv0 - }, - { - .cipher_key = ms_aes_cbc_key1, - .hmac_key = ms_hmac_key1, - .cipher = ms_aes_cbc_cipher1, - .digest = ms_hmac_digest1, - .iv = ms_aes_cbc_iv1 - }, - { - .cipher_key = ms_aes_cbc_key2, - .hmac_key = ms_hmac_key2, - .cipher = ms_aes_cbc_cipher2, - .digest = ms_hmac_digest2, - .iv = ms_aes_cbc_iv2 - }, - - }; - - rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); - - sessions = rte_malloc(NULL, - (sizeof(struct rte_cryptodev_sym_session *) - * dev_info.sym.max_nb_sessions) + 1, 0); - - for (i = 0; i < MB_SESSION_NUMBER; i++) { - rte_memcpy(&ut_paramz[i].ut_params, &testsuite_params, - sizeof(struct crypto_unittest_params)); - - test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - &ut_paramz[i].ut_params, - ut_paramz[i].cipher_key, ut_paramz[i].hmac_key); - - /* Create multiple crypto sessions*/ - sessions[i] = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], - &ut_paramz[i].ut_params.auth_xform); - - TEST_ASSERT_NOT_NULL(sessions[i], - "Session creation failed at session number %u", - i); - - } - - srand(time(NULL)); - for (i = 0; i < 40000; i++) { - - j = rand() % MB_SESSION_NUMBER; - - TEST_ASSERT_SUCCESS( - test_AES_CBC_HMAC_SHA512_decrypt_perform( - sessions[j], - &ut_paramz[j].ut_params, - ts_params, ut_paramz[j].cipher, - ut_paramz[j].digest, - ut_paramz[j].iv), - "Failed to perform decrypt on request number %u.", i); - - if (ut_paramz[j].ut_params.op) - rte_crypto_op_free(ut_paramz[j].ut_params.op); - - /* - * free mbuf - both obuf and ibuf are usually the same, - * so check if they point at the same address is necessary, - * to avoid freeing the mbuf twice. - */ - if (ut_paramz[j].ut_params.obuf) { - rte_pktmbuf_free(ut_paramz[j].ut_params.obuf); - if (ut_paramz[j].ut_params.ibuf - == ut_paramz[j].ut_params.obuf) - ut_paramz[j].ut_params.ibuf = 0; - ut_paramz[j].ut_params.obuf = 0; - } - if (ut_paramz[j].ut_params.ibuf) { - rte_pktmbuf_free(ut_paramz[j].ut_params.ibuf); - ut_paramz[j].ut_params.ibuf = 0; - } - } - - for (i = 0; i < MB_SESSION_NUMBER; i++) - rte_cryptodev_sym_session_free(ts_params->valid_devs[0], - sessions[i]); - - rte_free(sessions); - - return TEST_SUCCESS; -} - -static int -test_null_cipher_only_operation(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 = NULL; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_NULL; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - - /* 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"); - - /* 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->cipher.data.offset = 0; - 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_src, uint8_t *), - catch_22_quote, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - return TEST_SUCCESS; -} - -static int -test_null_auth_only_operation(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 HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_NULL; - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - - /* 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; - - sym_op->m_src = ut_params->ibuf; - - sym_op->auth.data.offset = 0; - 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, "no crypto operation returned"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto operation processing failed"); - - return TEST_SUCCESS; -} - -static int -test_null_cipher_auth_operation(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_NULL; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_NULL; - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - - /* 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"); - - /* 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; - - sym_op->m_src = ut_params->ibuf; - - sym_op->cipher.data.offset = 0; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - sym_op->auth.data.offset = 0; - 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, "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_src, uint8_t *), - catch_22_quote, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - return TEST_SUCCESS; -} - -static int -test_null_auth_cipher_operation(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 = NULL; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_NULL; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - - /* 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.algo = RTE_CRYPTO_AUTH_NULL; - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - - /* 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"); - - /* 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; - - sym_op->m_src = ut_params->ibuf; - - sym_op->cipher.data.offset = 0; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - sym_op->auth.data.offset = 0; - 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, "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_src, uint8_t *), - catch_22_quote, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - return TEST_SUCCESS; -} - - -static int -test_null_invalid_operation(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* 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_ENCRYPT; - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], &ut_params->cipher_xform); - TEST_ASSERT_NULL(ut_params->sess, - "Session creation succeeded unexpectedly"); - - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], &ut_params->auth_xform); - TEST_ASSERT_NULL(ut_params->sess, - "Session creation succeeded unexpectedly"); - - return TEST_SUCCESS; -} - - -#define NULL_BURST_LENGTH (32) - -static int -test_null_burst_operation(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - unsigned i, burst_len = NULL_BURST_LENGTH; - - struct rte_crypto_op *burst[NULL_BURST_LENGTH] = { NULL }; - struct rte_crypto_op *burst_dequeued[NULL_BURST_LENGTH] = { NULL }; - - /* 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_NULL; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_NULL; - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - - /* 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"); - - TEST_ASSERT_EQUAL(rte_crypto_op_bulk_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC, burst, burst_len), - burst_len, "failed to generate burst of crypto ops"); - - /* Generate an operation for each mbuf in burst */ - for (i = 0; i < burst_len; i++) { - struct rte_mbuf *m = rte_pktmbuf_alloc(ts_params->mbuf_pool); - - TEST_ASSERT_NOT_NULL(m, "Failed to allocate mbuf"); - - unsigned *data = (unsigned *)rte_pktmbuf_append(m, - sizeof(unsigned)); - *data = i; - - rte_crypto_op_attach_sym_session(burst[i], ut_params->sess); - - burst[i]->sym->m_src = m; - } - - /* Process crypto operation */ - TEST_ASSERT_EQUAL(rte_cryptodev_enqueue_burst(ts_params->valid_devs[0], - 0, burst, burst_len), - burst_len, - "Error enqueuing burst"); - - TEST_ASSERT_EQUAL(rte_cryptodev_dequeue_burst(ts_params->valid_devs[0], - 0, burst_dequeued, burst_len), - burst_len, - "Error dequeuing burst"); - - - for (i = 0; i < burst_len; i++) { - TEST_ASSERT_EQUAL( - *rte_pktmbuf_mtod(burst[i]->sym->m_src, uint32_t *), - *rte_pktmbuf_mtod(burst_dequeued[i]->sym->m_src, - uint32_t *), - "data not as expected"); - - rte_pktmbuf_free(burst[i]->sym->m_src); - rte_crypto_op_free(burst[i]); - } - - return TEST_SUCCESS; -} - -static void -generate_gmac_large_plaintext(uint8_t *data) -{ - uint16_t i; - - for (i = 32; i < GMAC_LARGE_PLAINTEXT_LENGTH; i += 32) - memcpy(&data[i], &data[0], 32); -} - -static int -create_gmac_operation(enum rte_crypto_auth_operation op, - const struct gmac_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - struct rte_crypto_sym_op *sym_op; - - unsigned iv_pad_len; - unsigned aad_pad_len; - - iv_pad_len = RTE_ALIGN_CEIL(tdata->iv.len, 16); - aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); - - /* - * Runtime generate the large plain text instead of use hard code - * plain text vector. It is done to avoid create huge source file - * with the test vector. - */ - if (tdata->aad.len == GMAC_LARGE_PLAINTEXT_LENGTH) - generate_gmac_large_plaintext(tdata->aad.data); - - /* 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"); - - sym_op = ut_params->op->sym; - sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - aad_pad_len); - TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, - "no room to append aad"); - - sym_op->auth.aad.length = tdata->aad.len; - sym_op->auth.aad.phys_addr = - rte_pktmbuf_mtophys(ut_params->ibuf); - memcpy(sym_op->auth.aad.data, tdata->aad.data, tdata->aad.len); - - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, tdata->gmac_tag.len); - 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, aad_pad_len); - sym_op->auth.digest.length = tdata->gmac_tag.len; - - if (op == RTE_CRYPTO_AUTH_OP_VERIFY) { - rte_memcpy(sym_op->auth.digest.data, tdata->gmac_tag.data, - tdata->gmac_tag.len); - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - } - - 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"); - - memset(sym_op->cipher.iv.data, 0, iv_pad_len); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = tdata->iv.len; - - rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, tdata->iv.len); - - TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data, iv_pad_len); - - sym_op->cipher.data.length = 0; - sym_op->cipher.data.offset = 0; - - sym_op->auth.data.offset = 0; - sym_op->auth.data.length = 0; - - return 0; -} - -static int create_gmac_session(uint8_t dev_id, - enum rte_crypto_cipher_operation op, - const struct gmac_test_data *tdata, - enum rte_crypto_auth_operation auth_op) -{ - uint8_t cipher_key[tdata->key.len]; - - struct crypto_unittest_params *ut_params = &unittest_params; - - memcpy(cipher_key, tdata->key.data, tdata->key.len); - - /* For GMAC we 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_GCM; - ut_params->cipher_xform.cipher.op = op; - ut_params->cipher_xform.cipher.key.data = cipher_key; - ut_params->cipher_xform.cipher.key.length = tdata->key.len; - - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_AES_GMAC; - ut_params->auth_xform.auth.op = auth_op; - ut_params->auth_xform.auth.digest_length = tdata->gmac_tag.len; - ut_params->auth_xform.auth.add_auth_data_length = 0; - ut_params->auth_xform.auth.key.length = 0; - ut_params->auth_xform.auth.key.data = NULL; - - ut_params->cipher_xform.next = &ut_params->auth_xform; - - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params->cipher_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - return 0; -} - -static int -test_AES_GMAC_authentication(const struct gmac_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - int retval; - - uint8_t *auth_tag, *p; - uint16_t aad_pad_len; - - TEST_ASSERT_NOT_EQUAL(tdata->gmac_tag.len, 0, - "No GMAC length in the source data"); - - retval = create_gmac_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - tdata, RTE_CRYPTO_AUTH_OP_GENERATE); - - if (retval < 0) - return retval; - - if (tdata->aad.len > MBUF_SIZE) - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool); - else - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - TEST_ASSERT_NOT_NULL(ut_params->ibuf, - "Failed to allocate input buffer in mempool"); - - memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->ibuf)); - - aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); - - p = rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *); - - retval = create_gmac_operation(RTE_CRYPTO_AUTH_OP_GENERATE, - tdata); - - if (retval < 0) - return retval; - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - ut_params->op->sym->m_src = ut_params->ibuf; - - 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"); - - if (ut_params->op->sym->m_dst) { - auth_tag = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, - uint8_t *, aad_pad_len); - } else { - auth_tag = p + aad_pad_len; - } - - TEST_HEXDUMP(stdout, "auth tag:", auth_tag, tdata->gmac_tag.len); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - tdata->gmac_tag.data, - tdata->gmac_tag.len, - "GMAC Generated auth tag not as expected"); - - return 0; -} - -static int -test_AES_GMAC_authentication_test_case_1(void) -{ - return test_AES_GMAC_authentication(&gmac_test_case_1); -} - -static int -test_AES_GMAC_authentication_test_case_2(void) -{ - return test_AES_GMAC_authentication(&gmac_test_case_2); -} - -static int -test_AES_GMAC_authentication_test_case_3(void) -{ - return test_AES_GMAC_authentication(&gmac_test_case_3); -} - -static int -test_AES_GMAC_authentication_test_case_4(void) -{ - return test_AES_GMAC_authentication(&gmac_test_case_4); -} - -static int -test_AES_GMAC_authentication_verify(const struct gmac_test_data *tdata) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - int retval; - - TEST_ASSERT_NOT_EQUAL(tdata->gmac_tag.len, 0, - "No GMAC length in the source data"); - - retval = create_gmac_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_DECRYPT, - tdata, RTE_CRYPTO_AUTH_OP_VERIFY); - - if (retval < 0) - return retval; - - if (tdata->aad.len > MBUF_SIZE) - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool); - else - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - TEST_ASSERT_NOT_NULL(ut_params->ibuf, - "Failed to allocate input buffer in mempool"); - - memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->ibuf)); - - retval = create_gmac_operation(RTE_CRYPTO_AUTH_OP_VERIFY, - tdata); - - if (retval < 0) - return retval; - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - ut_params->op->sym->m_src = ut_params->ibuf; - - 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"); - - return 0; - -} - -static int -test_AES_GMAC_authentication_verify_test_case_1(void) -{ - return test_AES_GMAC_authentication_verify(&gmac_test_case_1); -} - -static int -test_AES_GMAC_authentication_verify_test_case_2(void) -{ - return test_AES_GMAC_authentication_verify(&gmac_test_case_2); -} - -static int -test_AES_GMAC_authentication_verify_test_case_3(void) -{ - return test_AES_GMAC_authentication_verify(&gmac_test_case_3); -} - -static int -test_AES_GMAC_authentication_verify_test_case_4(void) -{ - return test_AES_GMAC_authentication_verify(&gmac_test_case_4); -} - -struct test_crypto_vector { - enum rte_crypto_cipher_algorithm crypto_algo; - - struct { - uint8_t data[64]; - unsigned int len; - } cipher_key; - - struct { - uint8_t data[64]; - unsigned int len; - } iv; - - struct { - const uint8_t *data; - unsigned int len; - } plaintext; - - struct { - const uint8_t *data; - unsigned int len; - } ciphertext; - - enum rte_crypto_auth_algorithm auth_algo; - - struct { - uint8_t data[128]; - unsigned int len; - } auth_key; - - struct { - const uint8_t *data; - unsigned int len; - } aad; - - struct { - uint8_t data[128]; - unsigned int len; - } digest; -}; - -static const struct test_crypto_vector -hmac_sha1_test_crypto_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .plaintext = { - .data = plaintext_hash, - .len = 512 - }, - .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 = { - 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, - 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, - 0x3F, 0x91, 0x64, 0x59 - }, - .len = 20 - } -}; - -static const struct test_crypto_vector -aes128_gmac_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_AES_GMAC, - .crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM, - .aad = { - .data = plaintext_hash, - .len = 512 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B - }, - .len = 12 - }, - .cipher_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA - }, - .len = 16 - }, - .digest = { - .data = { - 0xCA, 0x00, 0x99, 0x8B, 0x30, 0x7E, 0x74, 0x56, - 0x32, 0xA7, 0x87, 0xB5, 0xE9, 0xB2, 0x34, 0x5A - }, - .len = 16 - } -}; - -static const struct test_crypto_vector -aes128cbc_hmac_sha1_test_vector = { - .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 = plaintext_hash, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .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 - } -}; - -static void -data_corruption(uint8_t *data) -{ - data[0] += 1; -} - -static void -tag_corruption(uint8_t *data, unsigned int tag_offset) -{ - data[tag_offset] += 1; -} - -static int -create_auth_session(struct crypto_unittest_params *ut_params, - uint8_t dev_id, - const struct test_crypto_vector *reference, - enum rte_crypto_auth_operation auth_op) -{ - uint8_t auth_key[reference->auth_key.len + 1]; - - memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); - - /* Setup Authentication Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.auth.op = auth_op; - ut_params->auth_xform.next = NULL; - ut_params->auth_xform.auth.algo = reference->auth_algo; - ut_params->auth_xform.auth.key.length = reference->auth_key.len; - ut_params->auth_xform.auth.key.data = auth_key; - ut_params->auth_xform.auth.digest_length = reference->digest.len; - ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params->auth_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - return 0; -} - -static int -create_auth_cipher_session(struct crypto_unittest_params *ut_params, - uint8_t dev_id, - const struct test_crypto_vector *reference, - enum rte_crypto_auth_operation auth_op, - enum rte_crypto_cipher_operation cipher_op) -{ - uint8_t cipher_key[reference->cipher_key.len + 1]; - uint8_t auth_key[reference->auth_key.len + 1]; - - memcpy(cipher_key, reference->cipher_key.data, - reference->cipher_key.len); - memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); - - /* Setup Authentication Parameters */ - 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 = reference->auth_algo; - ut_params->auth_xform.auth.key.length = reference->auth_key.len; - ut_params->auth_xform.auth.key.data = auth_key; - ut_params->auth_xform.auth.digest_length = reference->digest.len; - ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; - - /* 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 = reference->crypto_algo; - ut_params->cipher_xform.cipher.op = cipher_op; - ut_params->cipher_xform.cipher.key.data = cipher_key; - ut_params->cipher_xform.cipher.key.length = reference->cipher_key.len; - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create(dev_id, - &ut_params->auth_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - return 0; -} - -static int -create_auth_operation(struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference, - unsigned int auth_generate) -{ - /* 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 pktmbuf offload"); - - /* 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; - - /* digest */ - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, reference->digest.len); - - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append auth tag"); - - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, reference->plaintext.len); - sym_op->auth.digest.length = reference->digest.len; - - if (auth_generate) - memset(sym_op->auth.digest.data, 0, reference->digest.len); - else - memcpy(sym_op->auth.digest.data, - reference->digest.data, - reference->digest.len); - - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - - sym_op->auth.data.length = reference->plaintext.len; - sym_op->auth.data.offset = 0; - - return 0; -} - -static int -create_auth_GMAC_operation(struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference, - unsigned int auth_generate) -{ - /* 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 pktmbuf offload"); - - /* 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; - - /* aad */ - sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - reference->aad.len); - TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, "no room to append AAD"); - memcpy(sym_op->auth.aad.data, reference->aad.data, reference->aad.len); - - TEST_HEXDUMP(stdout, "AAD:", sym_op->auth.aad.data, reference->aad.len); - - sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->auth.aad.length = reference->aad.len; - - /* digest */ - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, reference->digest.len); - - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append auth tag"); - - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, reference->ciphertext.len); - sym_op->auth.digest.length = reference->digest.len; - - if (auth_generate) - memset(sym_op->auth.digest.data, 0, reference->digest.len); - else - memcpy(sym_op->auth.digest.data, - reference->digest.data, - reference->digest.len); - - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( - ut_params->ibuf, reference->iv.len); - TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); - - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = reference->iv.len; - - memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); - - sym_op->cipher.data.length = 0; - sym_op->cipher.data.offset = 0; - - sym_op->auth.data.length = 0; - sym_op->auth.data.offset = 0; - - return 0; -} - -static int -create_cipher_auth_operation(struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference, - unsigned int auth_generate) -{ - /* 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 pktmbuf offload"); - - /* 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; - - /* digest */ - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, reference->digest.len); - - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append auth tag"); - - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, reference->ciphertext.len); - sym_op->auth.digest.length = reference->digest.len; - - if (auth_generate) - memset(sym_op->auth.digest.data, 0, reference->digest.len); - else - memcpy(sym_op->auth.digest.data, - reference->digest.data, - reference->digest.len); - - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( - ut_params->ibuf, reference->iv.len); - TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); - - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = reference->iv.len; - - memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); - - sym_op->cipher.data.length = reference->ciphertext.len; - sym_op->cipher.data.offset = reference->iv.len; - - sym_op->auth.data.length = reference->ciphertext.len; - sym_op->auth.data.offset = reference->iv.len; - - return 0; -} - -static int -create_auth_verify_operation(struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return create_auth_operation(ts_params, ut_params, reference, 0); -} - -static int -create_auth_verify_GMAC_operation( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return create_auth_GMAC_operation(ts_params, ut_params, reference, 0); -} - -static int -create_cipher_auth_verify_operation(struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return create_cipher_auth_operation(ts_params, ut_params, reference, 0); -} - -static int -test_authentication_verify_fail_when_data_corruption( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference, - unsigned int data_corrupted) -{ - int retval; - - uint8_t *plaintext; - - /* Create session */ - retval = create_auth_session(ut_params, - ts_params->valid_devs[0], - reference, - RTE_CRYPTO_AUTH_OP_VERIFY); - if (retval < 0) - return retval; - - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - TEST_ASSERT_NOT_NULL(ut_params->ibuf, - "Failed to allocate input buffer in mempool"); - - /* clear mbuf payload */ - memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->ibuf)); - - plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - reference->plaintext.len); - TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext"); - memcpy(plaintext, reference->plaintext.data, reference->plaintext.len); - - TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len); - - /* Create operation */ - retval = create_auth_verify_operation(ts_params, ut_params, reference); - - if (retval < 0) - return retval; - - if (data_corrupted) - data_corruption(plaintext); - else - tag_corruption(plaintext, reference->plaintext.len); - - ut_params->op = process_crypto_request(ts_params->valid_devs[0], - ut_params->op); - TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_AUTH_FAILED, - "authentication not failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); - - return 0; -} - -static int -test_authentication_verify_GMAC_fail_when_corruption( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference, - unsigned int data_corrupted) -{ - int retval; - - /* Create session */ - retval = create_auth_cipher_session(ut_params, - ts_params->valid_devs[0], - reference, - RTE_CRYPTO_AUTH_OP_VERIFY, - RTE_CRYPTO_CIPHER_OP_DECRYPT); - if (retval < 0) - return retval; - - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - TEST_ASSERT_NOT_NULL(ut_params->ibuf, - "Failed to allocate input buffer in mempool"); - - /* clear mbuf payload */ - memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->ibuf)); - - /* Create operation */ - retval = create_auth_verify_GMAC_operation(ts_params, - ut_params, - reference); - - if (retval < 0) - return retval; - - if (data_corrupted) - data_corruption(ut_params->op->sym->auth.aad.data); - else - tag_corruption(ut_params->op->sym->auth.aad.data, - reference->aad.len); - - ut_params->op = process_crypto_request(ts_params->valid_devs[0], - ut_params->op); - TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_AUTH_FAILED, - "authentication not failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); - - return 0; -} - -static int -test_authenticated_decryption_fail_when_corruption( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference, - unsigned int data_corrupted) -{ - int retval; - - uint8_t *ciphertext; - - /* Create session */ - retval = create_auth_cipher_session(ut_params, - ts_params->valid_devs[0], - reference, - RTE_CRYPTO_AUTH_OP_VERIFY, - RTE_CRYPTO_CIPHER_OP_DECRYPT); - if (retval < 0) - return retval; - - ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - TEST_ASSERT_NOT_NULL(ut_params->ibuf, - "Failed to allocate input buffer in mempool"); - - /* clear mbuf payload */ - memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->ibuf)); - - ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - reference->ciphertext.len); - TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext"); - memcpy(ciphertext, reference->ciphertext.data, - reference->ciphertext.len); - - /* Create operation */ - retval = create_cipher_auth_verify_operation(ts_params, - ut_params, - reference); - - if (retval < 0) - return retval; - - if (data_corrupted) - data_corruption(ciphertext); - else - tag_corruption(ciphertext, reference->ciphertext.len); - - ut_params->op = process_crypto_request(ts_params->valid_devs[0], - ut_params->op); - - TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_AUTH_FAILED, - "authentication not failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); - - return 0; -} - -static int -create_gcm_operation_SGL(enum rte_crypto_cipher_operation op, - const struct gcm_test_data *tdata, - void *digest_mem, uint64_t digest_phys) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - const unsigned int auth_tag_len = tdata->auth_tag.len; - const unsigned int iv_len = tdata->iv.len; - const unsigned int aad_len = tdata->aad.len; - - unsigned int iv_pad_len = 0; - - /* 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"); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - sym_op->auth.digest.data = digest_mem; - - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append digest"); - - sym_op->auth.digest.phys_addr = digest_phys; - sym_op->auth.digest.length = auth_tag_len; - - if (op == RTE_CRYPTO_CIPHER_OP_DECRYPT) { - rte_memcpy(sym_op->auth.digest.data, tdata->auth_tag.data, - auth_tag_len); - TEST_HEXDUMP(stdout, "digest:", - sym_op->auth.digest.data, - sym_op->auth.digest.length); - } - - 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"); - - memset(sym_op->cipher.iv.data, 0, iv_pad_len); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = iv_len; - - rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, iv_pad_len); - - sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_prepend( - ut_params->ibuf, aad_len); - TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, - "no room to prepend aad"); - sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys( - ut_params->ibuf); - sym_op->auth.aad.length = aad_len; - - memset(sym_op->auth.aad.data, 0, aad_len); - rte_memcpy(sym_op->auth.aad.data, tdata->aad.data, aad_len); - - 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 = tdata->plaintext.len; - sym_op->cipher.data.offset = aad_len + iv_pad_len; - - sym_op->auth.data.offset = aad_len + iv_pad_len; - sym_op->auth.data.length = tdata->plaintext.len; - - return 0; -} - -#define SGL_MAX_NO 16 - -static int -test_AES_GCM_authenticated_encryption_SGL(const struct gcm_test_data *tdata, - const int oop, uint32_t fragsz, uint32_t fragsz_oop) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - struct rte_mbuf *buf, *buf_oop = NULL, *buf_last_oop = NULL; - int retval; - int to_trn = 0; - int to_trn_tbl[SGL_MAX_NO]; - int segs = 1; - unsigned int trn_data = 0; - uint8_t *plaintext, *ciphertext, *auth_tag; - - if (fragsz > tdata->plaintext.len) - fragsz = tdata->plaintext.len; - - uint16_t plaintext_len = fragsz; - uint16_t frag_size_oop = fragsz_oop ? fragsz_oop : fragsz; - - if (fragsz_oop > tdata->plaintext.len) - frag_size_oop = tdata->plaintext.len; - - int ecx = 0; - void *digest_mem = NULL; - - uint32_t prepend_len = ALIGN_POW2_ROUNDUP(tdata->iv.len, 16) - + tdata->aad.len; - - if (tdata->plaintext.len % fragsz != 0) { - if (tdata->plaintext.len / fragsz + 1 > SGL_MAX_NO) - return 1; - } else { - if (tdata->plaintext.len / fragsz > SGL_MAX_NO) - return 1; - } - - /* - * For out-op-place we need to alloc another mbuf - */ - if (oop) { - ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - rte_pktmbuf_append(ut_params->obuf, - frag_size_oop + prepend_len); - buf_oop = ut_params->obuf; - } - - /* Create GCM session */ - retval = create_gcm_session(ts_params->valid_devs[0], - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_GENERATE); - 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 = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_len); - - memcpy(plaintext, tdata->plaintext.data, plaintext_len); - - trn_data += plaintext_len; - - buf = ut_params->ibuf; - - /* - * Loop until no more fragments - */ - - while (trn_data < tdata->plaintext.len) { - ++segs; - to_trn = (tdata->plaintext.len - trn_data < fragsz) ? - (tdata->plaintext.len - trn_data) : fragsz; - - to_trn_tbl[ecx++] = to_trn; - - buf->next = rte_pktmbuf_alloc(ts_params->mbuf_pool); - buf = buf->next; - - memset(rte_pktmbuf_mtod(buf, uint8_t *), 0, - rte_pktmbuf_tailroom(buf)); - - /* OOP */ - if (oop && !fragsz_oop) { - buf_last_oop = buf_oop->next = - rte_pktmbuf_alloc(ts_params->mbuf_pool); - buf_oop = buf_oop->next; - memset(rte_pktmbuf_mtod(buf_oop, uint8_t *), - 0, rte_pktmbuf_tailroom(buf_oop)); - rte_pktmbuf_append(buf_oop, to_trn); - } - - plaintext = (uint8_t *)rte_pktmbuf_append(buf, - to_trn); - - memcpy(plaintext, tdata->plaintext.data + trn_data, - to_trn); - trn_data += to_trn; - if (trn_data == tdata->plaintext.len) { - if (oop) { - if (!fragsz_oop) - digest_mem = rte_pktmbuf_append(buf_oop, - tdata->auth_tag.len); - } else - digest_mem = (uint8_t *)rte_pktmbuf_append(buf, - tdata->auth_tag.len); - } - } - - uint64_t digest_phys = 0; - - ut_params->ibuf->nb_segs = segs; - - segs = 1; - if (fragsz_oop && oop) { - to_trn = 0; - ecx = 0; - - if (frag_size_oop == tdata->plaintext.len) { - digest_mem = rte_pktmbuf_append(ut_params->obuf, - tdata->auth_tag.len); - - digest_phys = rte_pktmbuf_mtophys_offset( - ut_params->obuf, - tdata->plaintext.len + prepend_len); - } - - trn_data = frag_size_oop; - while (trn_data < tdata->plaintext.len) { - ++segs; - to_trn = - (tdata->plaintext.len - trn_data < - frag_size_oop) ? - (tdata->plaintext.len - trn_data) : - frag_size_oop; - - to_trn_tbl[ecx++] = to_trn; - - buf_last_oop = buf_oop->next = - rte_pktmbuf_alloc(ts_params->mbuf_pool); - buf_oop = buf_oop->next; - memset(rte_pktmbuf_mtod(buf_oop, uint8_t *), - 0, rte_pktmbuf_tailroom(buf_oop)); - rte_pktmbuf_append(buf_oop, to_trn); - - trn_data += to_trn; - - if (trn_data == tdata->plaintext.len) { - digest_mem = rte_pktmbuf_append(buf_oop, - tdata->auth_tag.len); - } - } - - ut_params->obuf->nb_segs = segs; - } - - /* - * Place digest at the end of the last buffer - */ - if (!digest_phys) - digest_phys = rte_pktmbuf_mtophys(buf) + to_trn; - if (oop && buf_last_oop) - digest_phys = rte_pktmbuf_mtophys(buf_last_oop) + to_trn; - - if (!digest_mem && !oop) { - digest_mem = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - + tdata->auth_tag.len); - digest_phys = rte_pktmbuf_mtophys_offset(ut_params->ibuf, - tdata->plaintext.len); - } - - /* Create GCM opertaion */ - retval = create_gcm_operation_SGL(RTE_CRYPTO_CIPHER_OP_ENCRYPT, - tdata, digest_mem, digest_phys); - - if (retval < 0) - return retval; - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - ut_params->op->sym->m_src = ut_params->ibuf; - if (oop) - ut_params->op->sym->m_dst = ut_params->obuf; - - /* 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"); - - - ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, - uint8_t *, prepend_len); - if (oop) { - ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, - uint8_t *, prepend_len); - } - - if (fragsz_oop) - fragsz = fragsz_oop; - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ciphertext, - tdata->ciphertext.data, - fragsz, - "GCM Ciphertext data not as expected"); - - buf = ut_params->op->sym->m_src->next; - if (oop) - buf = ut_params->op->sym->m_dst->next; - - unsigned int off = fragsz; - - ecx = 0; - while (buf) { - ciphertext = rte_pktmbuf_mtod(buf, - uint8_t *); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ciphertext, - tdata->ciphertext.data + off, - to_trn_tbl[ecx], - "GCM Ciphertext data not as expected"); - - off += to_trn_tbl[ecx++]; - buf = buf->next; - } - - auth_tag = digest_mem; - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - tdata->auth_tag.data, - tdata->auth_tag.len, - "GCM Generated auth tag not as expected"); - - return 0; -} - -#define IN_PLACE 0 -#define OUT_OF_PLACE 1 - -static int -test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_400B(void) -{ - return test_AES_GCM_authenticated_encryption_SGL( - &gcm_test_case_SGL_1, OUT_OF_PLACE, 400, 400); -} - -static int -test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B(void) -{ - return test_AES_GCM_authenticated_encryption_SGL( - &gcm_test_case_SGL_1, OUT_OF_PLACE, 1500, 2000); -} - -static int -test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg(void) -{ - return test_AES_GCM_authenticated_encryption_SGL( - &gcm_test_case_8, OUT_OF_PLACE, 400, - gcm_test_case_8.plaintext.len); -} - -static int -test_AES_GCM_auth_encrypt_SGL_in_place_1500B(void) -{ - - return test_AES_GCM_authenticated_encryption_SGL( - &gcm_test_case_SGL_1, IN_PLACE, 1500, 0); -} - -static int -test_authentication_verify_fail_when_data_corrupted( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return test_authentication_verify_fail_when_data_corruption( - ts_params, ut_params, reference, 1); -} - -static int -test_authentication_verify_fail_when_tag_corrupted( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return test_authentication_verify_fail_when_data_corruption( - ts_params, ut_params, reference, 0); -} - -static int -test_authentication_verify_GMAC_fail_when_data_corrupted( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return test_authentication_verify_GMAC_fail_when_corruption( - ts_params, ut_params, reference, 1); -} - -static int -test_authentication_verify_GMAC_fail_when_tag_corrupted( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return test_authentication_verify_GMAC_fail_when_corruption( - ts_params, ut_params, reference, 0); -} - -static int -test_authenticated_decryption_fail_when_data_corrupted( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return test_authenticated_decryption_fail_when_corruption( - ts_params, ut_params, reference, 1); -} - -static int -test_authenticated_decryption_fail_when_tag_corrupted( - struct crypto_testsuite_params *ts_params, - struct crypto_unittest_params *ut_params, - const struct test_crypto_vector *reference) -{ - return test_authenticated_decryption_fail_when_corruption( - ts_params, ut_params, reference, 0); -} - -static int -authentication_verify_HMAC_SHA1_fail_data_corrupt(void) -{ - return test_authentication_verify_fail_when_data_corrupted( - &testsuite_params, &unittest_params, - &hmac_sha1_test_crypto_vector); -} - -static int -authentication_verify_HMAC_SHA1_fail_tag_corrupt(void) -{ - return test_authentication_verify_fail_when_tag_corrupted( - &testsuite_params, &unittest_params, - &hmac_sha1_test_crypto_vector); -} - -static int -authentication_verify_AES128_GMAC_fail_data_corrupt(void) -{ - return test_authentication_verify_GMAC_fail_when_data_corrupted( - &testsuite_params, &unittest_params, - &aes128_gmac_test_vector); -} - -static int -authentication_verify_AES128_GMAC_fail_tag_corrupt(void) -{ - return test_authentication_verify_GMAC_fail_when_tag_corrupted( - &testsuite_params, &unittest_params, - &aes128_gmac_test_vector); -} - -static int -auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt(void) -{ - return test_authenticated_decryption_fail_when_data_corrupted( - &testsuite_params, - &unittest_params, - &aes128cbc_hmac_sha1_test_vector); -} - -static int -auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt(void) -{ - return test_authenticated_decryption_fail_when_tag_corrupted( - &testsuite_params, - &unittest_params, - &aes128cbc_hmac_sha1_test_vector); -} - -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER - -/* global AESNI slave IDs for the scheduler test */ -uint8_t aesni_ids[2]; - -static int -test_scheduler_attach_slave_op(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - uint8_t sched_id = ts_params->valid_devs[0]; - uint32_t nb_devs, qp_id, i, nb_devs_attached = 0; - int ret; - struct rte_cryptodev_config config = { - .nb_queue_pairs = 8, - .socket_id = SOCKET_ID_ANY, - .session_mp = { - .nb_objs = 2048, - .cache_size = 256 - } - }; - struct rte_cryptodev_qp_conf qp_conf = {2048}; - - /* create 2 AESNI_MB if necessary */ - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_AESNI_MB_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), NULL); - - TEST_ASSERT(ret == 0, - "Failed to create instance %u of" - " pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - } - } - - /* attach 2 AESNI_MB cdevs */ - for (i = 0; i < rte_cryptodev_count() && nb_devs_attached < 2; - i++) { - struct rte_cryptodev_info info; - - rte_cryptodev_info_get(i, &info); - if (info.dev_type != RTE_CRYPTODEV_AESNI_MB_PMD) - continue; - - ret = rte_cryptodev_configure(i, &config); - TEST_ASSERT(ret == 0, - "Failed to configure device %u of pmd : %s", i, - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - - for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) { - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - i, qp_id, &qp_conf, - rte_cryptodev_socket_id(i)), - "Failed to setup queue pair %u on " - "cryptodev %u", qp_id, i); - } - - ret = rte_cryptodev_scheduler_slave_attach(sched_id, - (uint8_t)i); - - TEST_ASSERT(ret == 0, - "Failed to attach device %u of pmd : %s", i, - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - - aesni_ids[nb_devs_attached] = (uint8_t)i; - - nb_devs_attached++; - } - - return 0; -} - -static int -test_scheduler_detach_slave_op(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - uint8_t sched_id = ts_params->valid_devs[0]; - uint32_t i; - int ret; - - for (i = 0; i < 2; i++) { - ret = rte_cryptodev_scheduler_slave_detach(sched_id, - aesni_ids[i]); - TEST_ASSERT(ret == 0, - "Failed to detach device %u", aesni_ids[i]); - } - - return 0; -} - -static int -test_scheduler_mode_op(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - uint8_t sched_id = ts_params->valid_devs[0]; - struct rte_cryptodev_scheduler_ops op = {0}; - struct rte_cryptodev_scheduler dummy_scheduler = { - .description = "dummy scheduler to test mode", - .name = "dummy scheduler", - .mode = CDEV_SCHED_MODE_USERDEFINED, - .ops = &op - }; - int ret; - - /* set user defined mode */ - ret = rte_cryptodev_scheduler_load_user_scheduler(sched_id, - &dummy_scheduler); - TEST_ASSERT(ret == 0, - "Failed to set cdev %u to user defined mode", sched_id); - - /* set round robin mode */ - ret = rte_crpytodev_scheduler_mode_set(sched_id, - CDEV_SCHED_MODE_ROUNDROBIN); - TEST_ASSERT(ret == 0, - "Failed to set cdev %u to round-robin mode", sched_id); - TEST_ASSERT(rte_crpytodev_scheduler_mode_get(sched_id) == - CDEV_SCHED_MODE_ROUNDROBIN, "Scheduling Mode " - "not match"); - - return 0; -} - -static struct unit_test_suite cryptodev_scheduler_testsuite = { - .suite_name = "Crypto Device Scheduler Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), - TEST_CASE_ST(NULL, NULL, test_scheduler_mode_op), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_chain_scheduler_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_scheduler_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_authonly_scheduler_all), - TEST_CASE_ST(NULL, NULL, test_scheduler_detach_slave_op), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -#endif /* RTE_LIBRTE_PMD_CRYPTO_SCHEDULER */ - -static struct unit_test_suite cryptodev_qat_testsuite = { - .suite_name = "Crypto QAT Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_dev_id), - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_queue_pair_ids), - TEST_CASE_ST(ut_setup, ut_teardown, - test_queue_pair_descriptor_setup), - TEST_CASE_ST(ut_setup, ut_teardown, - test_multi_session), - - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_DES_cipheronly_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_stats), - - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encrypt_SGL_in_place_1500B), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_400B), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_7), - - /** AES GMAC Authentication */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_3), - - /** SNOW 3G encrypt only (UEA2) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_4), - 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), - - /** SNOW 3G decrypt only (UEA2) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_hash_generate_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_hash_generate_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_hash_generate_test_case_3), - 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), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_cipher_auth_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_auth_cipher_test_case_1), - - /** HMAC_MD5 Authentication */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_MD5_HMAC_generate_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_MD5_HMAC_verify_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_MD5_HMAC_generate_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_MD5_HMAC_verify_case_2), - - /** NULL tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_auth_only_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_cipher_only_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_cipher_auth_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_auth_cipher_operation), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_hash_generate_test_case_6), - - /** KASUMI tests */ - 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_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_auth_cipher_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_cipher_auth_test_case_1), - - /** Negative tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_HMAC_SHA1_fail_data_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_HMAC_SHA1_fail_tag_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_AES128_GMAC_fail_data_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_AES128_GMAC_fail_tag_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_aesni_mb_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_AES_chain_mb_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_cipheronly_mb_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_mb_all), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_openssl_testsuite = { - .suite_name = "Crypto Device OPENSSL Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), - TEST_CASE_ST(ut_setup, ut_teardown, - test_multi_session_random_usage), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_chain_openssl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_openssl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_chain_openssl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_openssl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_authonly_openssl_all), - - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_7), - - /** AES GMAC Authentication */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_4), - - /** Scatter-Gather */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg), - - /** Negative tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_HMAC_SHA1_fail_data_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_HMAC_SHA1_fail_tag_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_AES128_GMAC_fail_data_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_AES128_GMAC_fail_tag_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_aesni_gcm_testsuite = { - .suite_name = "Crypto Device AESNI GCM Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_7), - - /** AES GCM Authenticated Encryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_256_7), - - /** AES GCM Authenticated Decryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_256_7), - - /** AES GCM Authenticated Encryption big aad size */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_aad_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_encryption_test_case_aad_2), - - /** AES GCM Authenticated Decryption big aad size */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_aad_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_auth_decryption_test_case_aad_2), - - /** AES GMAC Authentication */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_4), - - /** Negative tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_AES128_GMAC_fail_data_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - authentication_verify_AES128_GMAC_fail_tag_corrupt), - - /** Out of place tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_oop), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_oop), - - /** Session-less tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_sessionless), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_sessionless), - - /** Scatter-Gather */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -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_1_sgl), - 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_encryption_test_case_1_oop_sgl), - - - 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_generate_test_case_6), - 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_CASE_ST(ut_setup, ut_teardown, - test_kasumi_auth_cipher_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_cipher_auth_test_case_1), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; -static struct unit_test_suite cryptodev_sw_snow3g_testsuite = { - .suite_name = "Crypto Device SW SNOW 3G Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - /** SNOW 3G encrypt only (UEA2) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_4), - 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_encryption_test_case_1_oop_sgl), - 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), - - /** SNOW 3G decrypt only (UEA2) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_hash_generate_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - 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_cipher_auth_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_auth_cipher_test_case_1), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_sw_zuc_testsuite = { - .suite_name = "Crypto Device SW ZUC Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - /** ZUC encrypt only (EEA3) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_hash_generate_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_hash_generate_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_hash_generate_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_hash_generate_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_hash_generate_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_encryption_test_case_6_sgl), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_null_testsuite = { - .suite_name = "Crypto Device NULL Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_auth_only_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_cipher_only_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_cipher_auth_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_auth_cipher_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_invalid_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_burst_operation), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_armv8_testsuite = { - .suite_name = "Crypto Device ARMv8 Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_armv8_all), - - /** Negative tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt), - TEST_CASE_ST(ut_setup, ut_teardown, - auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_cryptodev_qat(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_QAT_SYM_PMD; - return unit_test_suite_runner(&cryptodev_qat_testsuite); -} - -static int -test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_MB_PMD; - - return unit_test_suite_runner(&cryptodev_aesni_mb_testsuite); -} - -static int -test_cryptodev_openssl(void) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_OPENSSL_PMD; - - return unit_test_suite_runner(&cryptodev_openssl_testsuite); -} - -static int -test_cryptodev_aesni_gcm(void) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_GCM_PMD; - - return unit_test_suite_runner(&cryptodev_aesni_gcm_testsuite); -} - -static int -test_cryptodev_null(void) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_NULL_PMD; - - return unit_test_suite_runner(&cryptodev_null_testsuite); -} - -static int -test_cryptodev_sw_snow3g(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_SNOW3G_PMD; - - return unit_test_suite_runner(&cryptodev_sw_snow3g_testsuite); -} - -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 int -test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_ZUC_PMD; - - return unit_test_suite_runner(&cryptodev_sw_zuc_testsuite); -} - -static int -test_cryptodev_armv8(void) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_ARMV8_PMD; - - return unit_test_suite_runner(&cryptodev_armv8_testsuite); -} - -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER - -static int -test_cryptodev_scheduler(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_cryptodev_type = RTE_CRYPTODEV_SCHEDULER_PMD; - return unit_test_suite_runner(&cryptodev_scheduler_testsuite); -} - -REGISTER_TEST_COMMAND(cryptodev_scheduler_autotest, test_cryptodev_scheduler); - -#endif - -REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat); -REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb); -REGISTER_TEST_COMMAND(cryptodev_openssl_autotest, test_cryptodev_openssl); -REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_autotest, test_cryptodev_aesni_gcm); -REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null); -REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g); -REGISTER_TEST_COMMAND(cryptodev_sw_kasumi_autotest, test_cryptodev_sw_kasumi); -REGISTER_TEST_COMMAND(cryptodev_sw_zuc_autotest, test_cryptodev_sw_zuc); -REGISTER_TEST_COMMAND(cryptodev_sw_armv8_autotest, test_cryptodev_armv8); diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h deleted file mode 100644 index 67354a955a..0000000000 --- a/app/test/test_cryptodev.h +++ /dev/null @@ -1,212 +0,0 @@ -/*- - * 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. - */ -#ifndef TEST_CRYPTODEV_H_ -#define TEST_CRYPTODEV_H_ - -#define HEX_DUMP 0 - -#define FALSE 0 -#define TRUE 1 - -#define MAX_NUM_OPS_INFLIGHT (4096) -#define MIN_NUM_OPS_INFLIGHT (128) -#define DEFAULT_NUM_OPS_INFLIGHT (128) - -#define MAX_NUM_QPS_PER_QAT_DEVICE (2) -#define DEFAULT_NUM_QPS_PER_QAT_DEVICE (2) -#define DEFAULT_BURST_SIZE (64) -#define DEFAULT_NUM_XFORMS (2) -#define NUM_MBUFS (8191) -#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) - -#define BYTE_LENGTH(x) (x/8) -/* HASH DIGEST LENGTHS */ -#define DIGEST_BYTE_LENGTH_MD5 (BYTE_LENGTH(128)) -#define DIGEST_BYTE_LENGTH_SHA1 (BYTE_LENGTH(160)) -#define DIGEST_BYTE_LENGTH_SHA224 (BYTE_LENGTH(224)) -#define DIGEST_BYTE_LENGTH_SHA256 (BYTE_LENGTH(256)) -#define DIGEST_BYTE_LENGTH_SHA384 (BYTE_LENGTH(384)) -#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 DIGEST_BYTE_LENGTH_AES_GCM (BYTE_LENGTH(128)) - -#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) - -/** - * Write (spread) data from buffer to mbuf data - * - * @param mbuf - * Destination mbuf - * @param offset - * Start offset in mbuf - * @param len - * Number of bytes to copy - * @param buffer - * Continuous source buffer - */ -static inline void -pktmbuf_write(struct rte_mbuf *mbuf, int offset, int len, const uint8_t *buffer) -{ - int n = len; - int l; - struct rte_mbuf *m; - char *dst; - - for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next) - offset -= m->data_len; - - l = m->data_len - offset; - - /* copy data from first segment */ - dst = rte_pktmbuf_mtod_offset(m, char *, offset); - if (len <= l) { - rte_memcpy(dst, buffer, len); - return; - } - - rte_memcpy(dst, buffer, l); - buffer += l; - n -= l; - - for (m = m->next; (m != NULL) && (n > 0); m = m->next) { - dst = rte_pktmbuf_mtod(m, char *); - l = m->data_len; - if (n < l) { - rte_memcpy(dst, buffer, n); - return; - } - rte_memcpy(dst, buffer, l); - buffer += l; - n -= l; - } -} - -static inline uint8_t * -pktmbuf_mtod_offset(struct rte_mbuf *mbuf, int offset) { - struct rte_mbuf *m; - - for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next) - offset -= m->data_len; - - if (m == NULL) { - printf("pktmbuf_mtod_offset: offset out of buffer\n"); - return NULL; - } - return rte_pktmbuf_mtod_offset(m, uint8_t *, offset); -} - -static inline phys_addr_t -pktmbuf_mtophys_offset(struct rte_mbuf *mbuf, int offset) { - struct rte_mbuf *m; - - for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next) - offset -= m->data_len; - - if (m == NULL) { - printf("pktmbuf_mtophys_offset: offset out of buffer\n"); - return 0; - } - return rte_pktmbuf_mtophys_offset(m, offset); -} - -static inline struct rte_mbuf * -create_segmented_mbuf(struct rte_mempool *mbuf_pool, int pkt_len, - int nb_segs, uint8_t pattern) { - - struct rte_mbuf *m = NULL, *mbuf = NULL; - uint8_t *dst; - int data_len = 0; - int i, size; - int t_len; - - if (pkt_len < 1) { - printf("Packet size must be 1 or more (is %d)\n", pkt_len); - return NULL; - } - - if (nb_segs < 1) { - printf("Number of segments must be 1 or more (is %d)\n", - nb_segs); - return NULL; - } - - t_len = pkt_len >= nb_segs ? pkt_len / nb_segs : 1; - size = pkt_len; - - /* Create chained mbuf_src and fill it generated data */ - for (i = 0; size > 0; i++) { - - m = rte_pktmbuf_alloc(mbuf_pool); - if (i == 0) - mbuf = m; - - if (m == NULL) { - printf("Cannot create segment for source mbuf"); - goto fail; - } - - /* Make sure if tailroom is zeroed */ - memset(m->buf_addr, pattern, m->buf_len); - - data_len = size > t_len ? t_len : size; - dst = (uint8_t *)rte_pktmbuf_append(m, data_len); - if (dst == NULL) { - printf("Cannot append %d bytes to the mbuf\n", - data_len); - goto fail; - } - - if (mbuf != m) - rte_pktmbuf_chain(mbuf, m); - - size -= data_len; - - } - return mbuf; - -fail: - if (mbuf) - rte_pktmbuf_free(mbuf); - return NULL; -} - -#endif /* TEST_CRYPTODEV_H_ */ diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h deleted file mode 100644 index f3fbef1aeb..0000000000 --- a/app/test/test_cryptodev_aes_test_vectors.h +++ /dev/null @@ -1,1333 +0,0 @@ -/* - * BSD LICENSE - * - * Copyright(c) 2016-2017 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_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_AES_TEST_VECTORS_H_ - -/* test vectors */ -static const uint8_t plaintext_aes128ctr[] = { - 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 -}; - -static const uint8_t ciphertext64_aes128ctr[] = { - 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 -}; - -static const uint8_t plaintext_aes192ctr[] = { - 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, -}; - -static const uint8_t ciphertext64_aes192ctr[] = { - 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 -}; - -static const uint8_t plaintext_aes256ctr[] = { - 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 -}; - -static const uint8_t ciphertext64_aes256ctr[] = { - 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 -}; - -static const uint8_t plaintext_aes_common[] = { - "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." -}; - -static const uint8_t ciphertext512_aes128cbc[] = { - 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 -}; - -/* AES128-CTR-SHA1 test vector */ -static const struct blockcipher_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 = plaintext_aes128ctr, - .len = 64 - }, - .ciphertext = { - .data = ciphertext64_aes128ctr, - .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 blockcipher_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 = plaintext_aes192ctr, - .len = 64 - }, - .ciphertext = { - .data = ciphertext64_aes192ctr, - .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 blockcipher_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 = plaintext_aes256ctr, - .len = 64 - }, - .ciphertext = { - .data = ciphertext64_aes256ctr, - .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 blockcipher_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 = plaintext_aes_common, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .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 blockcipher_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 = plaintext_aes_common, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .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 blockcipher_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 = plaintext_aes_common, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .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 blockcipher_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 = plaintext_aes_common, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .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 blockcipher_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 = plaintext_aes_common, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .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 blockcipher_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 = plaintext_aes_common, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .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 - } -}; - -static const uint8_t ciphertext512_aes192cbc[] = { - 0x45, 0xEE, 0x9A, 0xEA, 0x3C, 0x03, 0xFC, 0x4C, - 0x84, 0x36, 0xB0, 0xDA, 0xB0, 0xDC, 0xF3, 0x5B, - 0x75, 0xA7, 0xBE, 0x0E, 0xC0, 0x8D, 0x6C, 0xF8, - 0xC1, 0x0F, 0xD0, 0x35, 0x1D, 0x82, 0xAE, 0x7C, - 0x57, 0xC5, 0x7A, 0x55, 0x87, 0x1B, 0xD4, 0x03, - 0x0A, 0x64, 0xC9, 0xE0, 0xF4, 0xC7, 0x6F, 0x57, - 0x52, 0xC6, 0x73, 0xBA, 0x84, 0x0B, 0x5B, 0x89, - 0x21, 0xD2, 0x9B, 0x88, 0x68, 0xF5, 0xA9, 0x7F, - 0x3F, 0x49, 0xEB, 0xF4, 0xD4, 0x52, 0xD2, 0x64, - 0x80, 0xB2, 0x53, 0xDA, 0x19, 0xF6, 0x10, 0x24, - 0x23, 0x26, 0x7A, 0x7C, 0x07, 0x57, 0x4B, 0x0E, - 0x58, 0x49, 0x61, 0xD1, 0xDC, 0x9A, 0x32, 0x6B, - 0x0F, 0x43, 0x9E, 0x4D, 0xB4, 0x07, 0x4E, 0xB3, - 0x51, 0x74, 0xDE, 0x29, 0xBC, 0x98, 0xF9, 0xDF, - 0x78, 0x9A, 0x18, 0x9C, 0xD6, 0x7A, 0x55, 0x7C, - 0xE6, 0x1D, 0x5C, 0x1A, 0x99, 0xD2, 0xC3, 0x7B, - 0x9F, 0x96, 0x74, 0x2D, 0xE0, 0xEF, 0xD1, 0xE3, - 0x08, 0x9F, 0xAF, 0xE6, 0xED, 0xCA, 0xE1, 0xEA, - 0x23, 0x6F, 0x7C, 0x81, 0xA8, 0xC0, 0x5B, 0x8B, - 0x53, 0x90, 0x51, 0x2D, 0x0F, 0xF6, 0x7D, 0xA7, - 0x1C, 0xBD, 0x83, 0x84, 0x54, 0xA4, 0x15, 0xFB, - 0x3E, 0x25, 0xA7, 0x3A, 0x0A, 0x73, 0xD9, 0x88, - 0x6F, 0x80, 0x78, 0x95, 0x7F, 0x60, 0xAA, 0x86, - 0x8A, 0xFC, 0xDF, 0xC1, 0xCB, 0xDE, 0xBB, 0x25, - 0x52, 0x20, 0xC6, 0x79, 0xD4, 0x0F, 0x25, 0xE7, - 0xDB, 0xB2, 0x17, 0xA4, 0x6F, 0x3C, 0x6F, 0x91, - 0xF6, 0x44, 0x1E, 0xB6, 0x85, 0xBC, 0x7A, 0x14, - 0x10, 0x72, 0xBD, 0x16, 0x63, 0x39, 0x9E, 0x7B, - 0x84, 0x5B, 0x17, 0x61, 0xB1, 0x5D, 0x82, 0x0B, - 0x6D, 0x37, 0xD7, 0x79, 0xB8, 0x24, 0x91, 0x30, - 0x82, 0x91, 0x02, 0xB1, 0x18, 0x4B, 0xE0, 0xF4, - 0x13, 0x1B, 0xB2, 0x4C, 0xDA, 0xB8, 0x99, 0x96, - 0x83, 0x2F, 0xBE, 0x53, 0x8D, 0xDE, 0xFA, 0xAD, - 0xF6, 0x5C, 0xDB, 0xE5, 0x66, 0x26, 0x8F, 0x13, - 0x2B, 0x76, 0x47, 0x73, 0xDE, 0x1A, 0x74, 0xA6, - 0x30, 0xAF, 0x42, 0xA0, 0xE5, 0xD2, 0x8F, 0xC2, - 0xED, 0x3E, 0x9E, 0x29, 0x54, 0x3C, 0xDE, 0x9F, - 0x5D, 0x30, 0x2B, 0x63, 0xFB, 0xE3, 0xB1, 0x07, - 0xEE, 0x74, 0x4A, 0xAF, 0xB1, 0x20, 0x8D, 0xEC, - 0xE6, 0x78, 0x16, 0x8D, 0xA4, 0x6E, 0x34, 0x7D, - 0x47, 0xFB, 0x0B, 0xC1, 0x32, 0xD7, 0x0D, 0x6C, - 0x6F, 0x93, 0x9C, 0x5E, 0xEF, 0x1F, 0x9C, 0x45, - 0x80, 0x6B, 0x74, 0xA6, 0x81, 0xF2, 0xF6, 0xFA, - 0xAA, 0x9D, 0x4F, 0xCA, 0xB5, 0x90, 0x59, 0xB0, - 0x3B, 0xF2, 0xF0, 0x75, 0xFD, 0x8A, 0xD8, 0x97, - 0x65, 0x88, 0x56, 0x4C, 0x44, 0xDF, 0x73, 0xF7, - 0x56, 0x9C, 0x48, 0x7E, 0xB0, 0x1F, 0x1D, 0x7D, - 0x6A, 0x11, 0xF5, 0xC2, 0xF4, 0x17, 0xEF, 0x58, - 0xD8, 0x2A, 0xAF, 0x56, 0x2F, 0xCF, 0xEC, 0xA4, - 0x58, 0x8B, 0x60, 0xCE, 0xD4, 0x0F, 0x9C, 0x21, - 0xEC, 0x3E, 0x74, 0x7B, 0x81, 0x3D, 0x69, 0xC6, - 0x5E, 0x12, 0x83, 0xE9, 0xEF, 0x81, 0x58, 0x36, - 0x6A, 0x60, 0x0F, 0x54, 0x28, 0x11, 0xF9, 0x64, - 0x36, 0xAD, 0x79, 0xF5, 0x1C, 0x74, 0xD0, 0xC3, - 0x7B, 0x61, 0xE1, 0x92, 0xB0, 0x13, 0x91, 0x87, - 0x32, 0x1F, 0xF2, 0x5A, 0xDA, 0x25, 0x69, 0xEB, - 0xD7, 0x32, 0x7F, 0xF5, 0x23, 0x21, 0x54, 0x47, - 0x7B, 0x1B, 0x33, 0xB0, 0x3D, 0xF6, 0xE2, 0x7E, - 0x3E, 0xA2, 0x9E, 0xCA, 0x48, 0x0B, 0x4A, 0x29, - 0x81, 0xD4, 0x4E, 0xD5, 0x69, 0xFB, 0xCD, 0x37, - 0x8A, 0xC1, 0x5B, 0x50, 0xFF, 0xB5, 0x7D, 0x43, - 0x0F, 0xAE, 0xA6, 0xC2, 0xE5, 0x8F, 0x45, 0xB2, - 0x85, 0x99, 0x02, 0xA2, 0x9B, 0xBE, 0x90, 0x43, - 0x4F, 0x2F, 0x50, 0xE2, 0x77, 0x62, 0xD9, 0xCC -}; - -/** AES-192-CBC test vector */ -static const struct blockcipher_test_data aes_test_data_10 = { - .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, - 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = plaintext_aes_common, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes192cbc, - .len = 512 - } -}; - -static const uint8_t ciphertext512_aes256cbc[] = { - 0xF3, 0xDD, 0xF0, 0x0B, 0xFF, 0xA2, 0x6A, 0x04, - 0xBE, 0xDA, 0x52, 0xA6, 0xFE, 0x6B, 0xA6, 0xA7, - 0x48, 0x1D, 0x7D, 0x98, 0x65, 0xDB, 0xEF, 0x06, - 0x26, 0xB5, 0x8E, 0xEB, 0x05, 0x0E, 0x77, 0x98, - 0x17, 0x8E, 0xD0, 0xD4, 0x7B, 0x92, 0x8F, 0x5C, - 0xD0, 0x74, 0x5C, 0xA8, 0x4B, 0x54, 0xB6, 0x2F, - 0x83, 0x72, 0x2C, 0xFF, 0x72, 0xE9, 0xE4, 0x15, - 0x4C, 0x32, 0xAF, 0xC8, 0xC9, 0x89, 0x3C, 0x6E, - 0x31, 0xD5, 0xC0, 0x16, 0xC0, 0x31, 0x7D, 0x11, - 0xAB, 0xCB, 0xDE, 0xD2, 0xD6, 0xAA, 0x76, 0x5E, - 0xBA, 0xF6, 0xE2, 0x92, 0xCB, 0x86, 0x07, 0xFA, - 0xD4, 0x9E, 0x83, 0xED, 0xFD, 0xB8, 0x70, 0x54, - 0x6B, 0xBE, 0xEC, 0x72, 0xDD, 0x28, 0x5E, 0x95, - 0x78, 0xA5, 0x28, 0x43, 0x3D, 0x6D, 0xB1, 0xD9, - 0x69, 0x1F, 0xC9, 0x66, 0x0E, 0x32, 0x44, 0x08, - 0xD2, 0xAE, 0x2C, 0x43, 0xF2, 0xD0, 0x7D, 0x26, - 0x70, 0xE5, 0xA1, 0xCA, 0x37, 0xE9, 0x7D, 0xC7, - 0xA3, 0xFA, 0x81, 0x91, 0x64, 0xAA, 0x64, 0x91, - 0x9A, 0x95, 0x2D, 0xC9, 0xF9, 0xCE, 0xFE, 0x9F, - 0xC4, 0xD8, 0x81, 0xBE, 0x57, 0x84, 0xC5, 0x02, - 0xDB, 0x30, 0xC1, 0xD9, 0x0E, 0xA0, 0xA6, 0x00, - 0xD6, 0xF3, 0x52, 0x7E, 0x0D, 0x23, 0x6B, 0x2B, - 0x34, 0x99, 0x1F, 0x70, 0x27, 0x6D, 0x58, 0x84, - 0x93, 0x77, 0xB8, 0x3E, 0xF1, 0x71, 0x58, 0x42, - 0x8B, 0x2B, 0xC8, 0x6D, 0x05, 0x84, 0xFF, 0x4E, - 0x85, 0xEF, 0x4A, 0x9D, 0x91, 0x6A, 0xD5, 0xE1, - 0xAF, 0x01, 0xEB, 0x83, 0x8F, 0x23, 0x7C, 0x7F, - 0x12, 0x91, 0x05, 0xF0, 0x4E, 0xD9, 0x17, 0x62, - 0x75, 0xBB, 0xAC, 0x97, 0xEE, 0x3B, 0x4E, 0xC7, - 0xE5, 0x92, 0xF8, 0x9D, 0x4C, 0xF9, 0xEE, 0x55, - 0x18, 0xBB, 0xCC, 0xB4, 0xF2, 0x59, 0xB9, 0xFC, - 0x7A, 0x0F, 0x98, 0xD4, 0x8B, 0xFE, 0xF7, 0x83, - 0x46, 0xE2, 0x83, 0x33, 0x3E, 0x95, 0x8D, 0x17, - 0x1E, 0x85, 0xF8, 0x8C, 0x51, 0xB0, 0x6C, 0xB5, - 0x5E, 0x95, 0xBA, 0x4B, 0x69, 0x1B, 0x48, 0x69, - 0x0B, 0x8F, 0xA5, 0x18, 0x13, 0xB9, 0x77, 0xD1, - 0x80, 0x32, 0x32, 0x6D, 0x53, 0xA1, 0x95, 0x40, - 0x96, 0x8A, 0xCC, 0xA3, 0x69, 0xF8, 0x9F, 0xB5, - 0x8E, 0xD2, 0x68, 0x07, 0x4F, 0xA7, 0xEC, 0xF8, - 0x20, 0x21, 0x58, 0xF8, 0xD8, 0x9E, 0x5F, 0x40, - 0xBA, 0xB9, 0x76, 0x57, 0x3B, 0x17, 0xAD, 0xEE, - 0xCB, 0xDF, 0x07, 0xC1, 0xDF, 0x66, 0xA8, 0x0D, - 0xC2, 0xCE, 0x8F, 0x79, 0xC3, 0x32, 0xE0, 0x8C, - 0xFE, 0x5A, 0xF3, 0x55, 0x27, 0x73, 0x6F, 0xA1, - 0x54, 0xC6, 0xFC, 0x28, 0x9D, 0xBE, 0x97, 0xB9, - 0x54, 0x97, 0x72, 0x3A, 0x61, 0xAF, 0x6F, 0xDE, - 0xF8, 0x0E, 0xBB, 0x6B, 0x96, 0x84, 0xDD, 0x9B, - 0x62, 0xBA, 0x47, 0xB5, 0xC9, 0x3B, 0x4E, 0x8C, - 0x78, 0x2A, 0xCC, 0x0A, 0x69, 0x54, 0x25, 0x5E, - 0x8B, 0xAC, 0x56, 0xD9, 0xFE, 0x48, 0xBA, 0xCE, - 0xA9, 0xCE, 0xA6, 0x1D, 0xBF, 0x3E, 0x3C, 0x66, - 0x40, 0x71, 0x79, 0xAD, 0x5B, 0x26, 0xAD, 0xBE, - 0x58, 0x13, 0x64, 0x60, 0x7C, 0x05, 0xFC, 0xE3, - 0x51, 0x7A, 0xF2, 0xCC, 0x54, 0x16, 0x2C, 0xA4, - 0xCE, 0x5F, 0x59, 0x12, 0x77, 0xEB, 0xD9, 0x23, - 0xE3, 0x86, 0xFB, 0xD7, 0x48, 0x76, 0x9D, 0xE3, - 0x89, 0x87, 0x39, 0xFA, 0x7B, 0x21, 0x0B, 0x76, - 0xB2, 0xED, 0x1C, 0x27, 0x4B, 0xD5, 0x27, 0x05, - 0x8C, 0x7D, 0x58, 0x6C, 0xCA, 0xA5, 0x54, 0x9A, - 0x0F, 0xCB, 0xE9, 0x88, 0x31, 0xAD, 0x49, 0xEE, - 0x38, 0xFB, 0xC9, 0xFB, 0xB4, 0x7A, 0x00, 0x58, - 0x20, 0x32, 0xD3, 0x53, 0x5A, 0xDD, 0x74, 0x95, - 0x60, 0x59, 0x09, 0xAE, 0x7E, 0xEC, 0x74, 0xA3, - 0xB7, 0x1C, 0x6D, 0xF2, 0xAE, 0x79, 0xA4, 0x7C -}; - -/** AES-256-CBC test vector */ -static const struct blockcipher_test_data aes_test_data_11 = { - .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, - 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0, - 0x37, 0x07, 0xB8, 0x23, 0xA2, 0xA3, 0xB5, 0x8D - }, - .len = 32 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = plaintext_aes_common, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_aes256cbc, - .len = 512 - } -}; - -/** AES-128-CBC SHA256 HMAC test vector (160 bytes) */ -static const struct blockcipher_test_data aes_test_data_12 = { - .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 = plaintext_aes_common, - .len = 160 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .len = 160 - }, - .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 = { - 0x92, 0xEC, 0x65, 0x9A, 0x52, 0xCC, 0x50, 0xA5, - 0xEE, 0x0E, 0xDF, 0x1E, 0xA4, 0xC9, 0xC1, 0x04, - 0xD5, 0xDC, 0x78, 0x90, 0xF4, 0xE3, 0x35, 0x62, - 0xAD, 0x95, 0x45, 0x28, 0x5C, 0xF8, 0x8C, 0x0B - }, - .len = 32, - .truncated_len = 16 - } -}; - -/** AES-128-CBC SHA1 HMAC test vector (160 bytes) */ -static const struct blockcipher_test_data aes_test_data_13 = { - .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 = plaintext_aes_common, - .len = 160 - }, - .ciphertext = { - .data = ciphertext512_aes128cbc, - .len = 160 - }, - .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 = { - 0x4F, 0x16, 0xEA, 0xF7, 0x4A, 0x88, 0xD3, 0xE0, - 0x0E, 0x12, 0x8B, 0xE7, 0x05, 0xD0, 0x86, 0x48, - 0x22, 0x43, 0x30, 0xA7 - }, - .len = 20, - .truncated_len = 12 - } -}; - -static const struct blockcipher_test_case aes_chain_test_cases[] = { - { - .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_1, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_1, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-192-CTR XCBC Encryption Digest", - .test_data = &aes_test_data_2, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", - .test_data = &aes_test_data_2, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-192-CTR XCBC Decryption Digest Verify " - "Scatter Gather", - .test_data = &aes_test_data_2, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | - BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_3, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_3, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "(short buffers)", - .test_data = &aes_test_data_13, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "Scatter Gather", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | - BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify (short buffers)", - .test_data = &aes_test_data_13, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", - .test_data = &aes_test_data_5, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest " - "(short buffers)", - .test_data = &aes_test_data_12, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " - "Verify", - .test_data = &aes_test_data_5, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " - "Verify (short buffers)", - .test_data = &aes_test_data_12, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", - .test_data = &aes_test_data_6, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " - "Sessionless", - .test_data = &aes_test_data_6, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " - "Scatter Gather Sessionless", - .test_data = &aes_test_data_6, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS | - BLOCKCIPHER_TEST_FEATURE_SG | - BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " - "Verify", - .test_data = &aes_test_data_6, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " - "Verify Scatter Gather", - .test_data = &aes_test_data_6, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | - BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC XCBC Encryption Digest", - .test_data = &aes_test_data_7, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", - .test_data = &aes_test_data_7, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "OOP", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify OOP", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", - .test_data = &aes_test_data_8, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " - "Verify", - .test_data = &aes_test_data_8, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", - .test_data = &aes_test_data_9, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " - "Verify", - .test_data = &aes_test_data_9, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "Sessionless", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = - "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify Sessionless", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, -}; - -static const struct blockcipher_test_case aes_cipheronly_test_cases[] = { - { - .test_descr = "AES-128-CBC Encryption", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CBC Decryption", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-192-CBC Encryption", - .test_data = &aes_test_data_10, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-192-CBC Encryption Scater gather", - .test_data = &aes_test_data_10, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | - BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "AES-192-CBC Decryption", - .test_data = &aes_test_data_10, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-256-CBC Encryption", - .test_data = &aes_test_data_11, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-256-CBC Decryption", - .test_data = &aes_test_data_11, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CTR Encryption", - .test_data = &aes_test_data_1, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-128-CTR Decryption", - .test_data = &aes_test_data_1, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-192-CTR Encryption", - .test_data = &aes_test_data_2, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-192-CTR Decryption", - .test_data = &aes_test_data_2, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-256-CTR Encryption", - .test_data = &aes_test_data_3, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "AES-256-CTR Decryption", - .test_data = &aes_test_data_3, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, -}; - -#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c deleted file mode 100644 index da87368a78..0000000000 --- a/app/test/test_cryptodev_blockcipher.c +++ /dev/null @@ -1,683 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015-2017 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 -#include -#include -#include -#include - -#include -#include -#include - -#include "test.h" -#include "test_cryptodev.h" -#include "test_cryptodev_blockcipher.h" -#include "test_cryptodev_aes_test_vectors.h" -#include "test_cryptodev_des_test_vectors.h" -#include "test_cryptodev_hash_test_vectors.h" -#include "test_cryptodev.h" - -static int -test_blockcipher_one_case(const struct blockcipher_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; - struct rte_cryptodev_info dev_info; - - int status = TEST_SUCCESS; - const struct blockcipher_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; - uint8_t src_pattern = 0xa5; - uint8_t dst_pattern = 0xb6; - uint8_t tmp_src_buf[MBUF_SIZE]; - uint8_t tmp_dst_buf[MBUF_SIZE]; - - int nb_segs = 1; - - if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) { - rte_cryptodev_info_get(dev_id, &dev_info); - if (!(dev_info.feature_flags & - RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { - printf("Device doesn't support scatter-gather. " - "Test Skipped.\n"); - return 0; - } - nb_segs = 3; - } - - 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: - case RTE_CRYPTODEV_OPENSSL_PMD: - case RTE_CRYPTODEV_ARMV8_PMD: /* Fall through */ - digest_len = tdata->digest.len; - break; - case RTE_CRYPTODEV_AESNI_MB_PMD: - case RTE_CRYPTODEV_SCHEDULER_PMD: - digest_len = tdata->digest.truncated_len; - break; - default: - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, - "line %u FAILED: %s", - __LINE__, "Unsupported PMD type"); - status = TEST_FAILED; - goto error_exit; - } - - /* preparing data */ - if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) - buf_len += tdata->iv.len; - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) - buf_len += digest_len; - - /* for contiguous mbuf, nb_segs is 1 */ - ibuf = create_segmented_mbuf(mbuf_pool, - tdata->ciphertext.len, nb_segs, src_pattern); - if (ibuf == NULL) { - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, - "line %u FAILED: %s", - __LINE__, "Cannot create source mbuf"); - status = TEST_FAILED; - goto error_exit; - } - - /* only encryption requires plaintext.data input, - * decryption/(digest gen)/(digest verify) use ciphertext.data - * to be computed - */ - if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) - pktmbuf_write(ibuf, 0, tdata->plaintext.len, - tdata->plaintext.data); - else - pktmbuf_write(ibuf, 0, tdata->ciphertext.len, - tdata->ciphertext.data); - - if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { - rte_memcpy(rte_pktmbuf_prepend(ibuf, tdata->iv.len), - tdata->iv.data, tdata->iv.len); - } - buf_p = rte_pktmbuf_append(ibuf, digest_len); - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) - rte_memcpy(buf_p, tdata->digest.data, digest_len); - else - memset(buf_p, 0, digest_len); - - if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { - obuf = rte_pktmbuf_alloc(mbuf_pool); - if (!obuf) { - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - memset(obuf->buf_addr, dst_pattern, obuf->buf_len); - - buf_p = rte_pktmbuf_append(obuf, buf_len); - if (!buf_p) { - snprintf(test_msg, BLOCKCIPHER_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, BLOCKCIPHER_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 & BLOCKCIPHER_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 & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { - uint32_t n_xforms = 0; - - if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) - n_xforms++; - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) - n_xforms++; - - if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) - == NULL) { - snprintf(test_msg, BLOCKCIPHER_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, BLOCKCIPHER_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 == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) { - if (t->feature_mask & BLOCKCIPHER_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 == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) { - if (t->feature_mask & BLOCKCIPHER_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 == BLOCKCIPHER_TEST_OP_ENCRYPT) || - (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) { - if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) - cipher_xform = op->sym->xform; - else - init_xform = cipher_xform; - cipher_xform->next = NULL; - } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) || - (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) { - if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) - auth_xform = op->sym->xform; - else - init_xform = auth_xform; - auth_xform->next = NULL; - } else { - snprintf(test_msg, BLOCKCIPHER_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 & BLOCKCIPHER_TEST_OP_CIPHER) { - cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform->cipher.algo = tdata->crypto_algo; - if (t->op_mask & BLOCKCIPHER_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 & BLOCKCIPHER_TEST_OP_AUTH) { - uint32_t auth_data_offset = 0; - uint32_t digest_offset = tdata->ciphertext.len; - - if (t->op_mask & BLOCKCIPHER_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 & BLOCKCIPHER_TEST_OP_AUTH_GEN) { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - sym_op->auth.digest.data = pktmbuf_mtod_offset - (iobuf, digest_offset); - sym_op->auth.digest.phys_addr = - pktmbuf_mtophys_offset(iobuf, - digest_offset); - } else { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - sym_op->auth.digest.data = pktmbuf_mtod_offset - (sym_op->m_src, digest_offset); - sym_op->auth.digest.phys_addr = - 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 & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { - sess = rte_cryptodev_sym_session_create(dev_id, - init_xform); - if (!sess) { - snprintf(test_msg, BLOCKCIPHER_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); - } - - TEST_HEXDUMP(stdout, "m_src(before):", - sym_op->m_src->buf_addr, sym_op->m_src->buf_len); - rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr, - sym_op->m_src->buf_len); - if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { - TEST_HEXDUMP(stdout, "m_dst(before):", - sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len); - rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr, - sym_op->m_dst->buf_len); - } - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - snprintf(test_msg, BLOCKCIPHER_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, BLOCKCIPHER_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(after):", - sym_op->m_src->buf_addr, sym_op->m_src->buf_len); - if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) - TEST_HEXDUMP(stdout, "m_dst(after):", - sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len); - - /* Verify results */ - if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - else - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { - uint8_t buffer[2048]; - const uint8_t *compare_ref; - uint32_t compare_len; - - if (t->op_mask & BLOCKCIPHER_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(rte_pktmbuf_read(iobuf, tdata->iv.len, compare_len, - buffer), compare_ref, compare_len)) { - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Crypto data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { - uint8_t *auth_res; - - if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) - auth_res = pktmbuf_mtod_offset(iobuf, - tdata->iv.len + tdata->ciphertext.len); - else - auth_res = pktmbuf_mtod_offset(iobuf, - tdata->ciphertext.len); - - if (memcmp(auth_res, tdata->digest.data, digest_len)) { - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Generated " - "digest data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - /* The only parts that should have changed in the buffer are - * plaintext/ciphertext and digest. - * In OOP only the dest buffer should change. - */ - if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { - struct rte_mbuf *mbuf; - uint8_t value; - uint32_t head_unchanged_len = 0, changed_len = 0; - uint32_t i; - - mbuf = sym_op->m_src; - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) { - /* white-box test: PMDs use some of the - * tailroom as temp storage in verify case - */ - head_unchanged_len = rte_pktmbuf_headroom(mbuf) - + rte_pktmbuf_data_len(mbuf); - changed_len = digest_len; - } else { - head_unchanged_len = mbuf->buf_len; - changed_len = 0; - } - - for (i = 0; i < mbuf->buf_len; i++) { - if (i == head_unchanged_len) - i += changed_len; - value = *((uint8_t *)(mbuf->buf_addr)+i); - if (value != tmp_src_buf[i]) { - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, - "line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)", - __LINE__, value, tmp_src_buf[i]); - status = TEST_FAILED; - goto error_exit; - } - } - - mbuf = sym_op->m_dst; - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { - head_unchanged_len = rte_pktmbuf_headroom(mbuf) + - sym_op->auth.data.offset; - changed_len = sym_op->auth.data.length; - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) - changed_len += sym_op->auth.digest.length; - } else { - /* cipher-only */ - head_unchanged_len = rte_pktmbuf_headroom(mbuf) + - sym_op->cipher.data.offset; - changed_len = sym_op->cipher.data.length; - } - - for (i = 0; i < mbuf->buf_len; i++) { - if (i == head_unchanged_len) - i += changed_len; - value = *((uint8_t *)(mbuf->buf_addr)+i); - if (value != tmp_dst_buf[i]) { - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, - "line %u FAILED: OOP dst outer mbuf data " - "(0x%x) not as expected (0x%x)", - __LINE__, value, tmp_dst_buf[i]); - status = TEST_FAILED; - goto error_exit; - } - } - } else { - /* In-place operation */ - struct rte_mbuf *mbuf; - uint8_t value; - uint32_t head_unchanged_len = 0, changed_len = 0; - uint32_t i; - - mbuf = sym_op->m_src; - if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { - head_unchanged_len = rte_pktmbuf_headroom(mbuf) + - sym_op->cipher.data.offset; - changed_len = sym_op->cipher.data.length; - } else { - /* auth-only */ - head_unchanged_len = rte_pktmbuf_headroom(mbuf) + - sym_op->auth.data.offset + - sym_op->auth.data.length; - changed_len = 0; - } - - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) - changed_len += sym_op->auth.digest.length; - - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) { - /* white-box test: PMDs use some of the - * tailroom as temp storage in verify case - */ - if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { - /* This is simplified, not checking digest*/ - changed_len += digest_len*2; - } else { - head_unchanged_len += digest_len; - changed_len += digest_len; - } - } - - for (i = 0; i < mbuf->buf_len; i++) { - if (i == head_unchanged_len) - i += changed_len; - value = *((uint8_t *)(mbuf->buf_addr)+i); - if (value != tmp_src_buf[i]) { - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, - "line %u FAILED: outer mbuf data (0x%x) " - "not as expected (0x%x)", - __LINE__, value, tmp_src_buf[i]); - status = TEST_FAILED; - goto error_exit; - } - } - } - - snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS"); - -error_exit: - if (!(t->feature_mask & BLOCKCIPHER_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_blockcipher_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type, - enum blockcipher_test_type test_type) -{ - int status, overall_status = TEST_SUCCESS; - uint32_t i, test_index = 0; - char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1]; - uint32_t n_test_cases = 0; - uint32_t target_pmd_mask = 0; - const struct blockcipher_test_case *tcs = NULL; - - switch (test_type) { - case BLKCIPHER_AES_CHAIN_TYPE: - n_test_cases = sizeof(aes_chain_test_cases) / - sizeof(aes_chain_test_cases[0]); - tcs = aes_chain_test_cases; - break; - case BLKCIPHER_AES_CIPHERONLY_TYPE: - n_test_cases = sizeof(aes_cipheronly_test_cases) / - sizeof(aes_cipheronly_test_cases[0]); - tcs = aes_cipheronly_test_cases; - break; - case BLKCIPHER_3DES_CHAIN_TYPE: - n_test_cases = sizeof(triple_des_chain_test_cases) / - sizeof(triple_des_chain_test_cases[0]); - tcs = triple_des_chain_test_cases; - break; - case BLKCIPHER_3DES_CIPHERONLY_TYPE: - n_test_cases = sizeof(triple_des_cipheronly_test_cases) / - sizeof(triple_des_cipheronly_test_cases[0]); - tcs = triple_des_cipheronly_test_cases; - break; - case BLKCIPHER_DES_CIPHERONLY_TYPE: - n_test_cases = sizeof(des_cipheronly_test_cases) / - sizeof(des_cipheronly_test_cases[0]); - tcs = des_cipheronly_test_cases; - break; - case BLKCIPHER_AUTHONLY_TYPE: - n_test_cases = sizeof(hash_test_cases) / - sizeof(hash_test_cases[0]); - tcs = hash_test_cases; - break; - default: - break; - } - - switch (cryptodev_type) { - case RTE_CRYPTODEV_AESNI_MB_PMD: - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; - break; - case RTE_CRYPTODEV_QAT_SYM_PMD: - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; - break; - case RTE_CRYPTODEV_OPENSSL_PMD: - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL; - break; - case RTE_CRYPTODEV_ARMV8_PMD: - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8; - break; - case RTE_CRYPTODEV_SCHEDULER_PMD: - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER; - break; - default: - TEST_ASSERT(0, "Unrecognized cryptodev type"); - break; - } - - for (i = 0; i < n_test_cases; i++) { - const struct blockcipher_test_case *tc = &tcs[i]; - - if (!(tc->pmd_mask & target_pmd_mask)) - continue; - - status = test_blockcipher_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 & BLOCKCIPHER_TEST_FEATURE_STOPPER) - break; - } - } - - return overall_status; -} diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h deleted file mode 100644 index 053aaa1cda..0000000000 --- a/app/test/test_cryptodev_blockcipher.h +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2016-2017 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_BLOCKCIPHER_H_ -#define TEST_CRYPTODEV_BLOCKCIPHER_H_ - -#ifndef BLOCKCIPHER_TEST_MSG_LEN -#define BLOCKCIPHER_TEST_MSG_LEN 256 -#endif - -#define BLOCKCIPHER_TEST_OP_ENCRYPT 0x01 -#define BLOCKCIPHER_TEST_OP_DECRYPT 0x02 -#define BLOCKCIPHER_TEST_OP_AUTH_GEN 0x04 -#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY 0x08 - -#define BLOCKCIPHER_TEST_FEATURE_OOP 0x01 -#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS 0x02 -#define BLOCKCIPHER_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ -#define BLOCKCIPHER_TEST_FEATURE_SG 0x08 /* Scatter Gather */ - -#define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL 0x0004 /* SW OPENSSL flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 0x0008 /* ARMv8 flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER 0x0010 /* Scheduler */ - -#define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ - BLOCKCIPHER_TEST_OP_DECRYPT) - -#define BLOCKCIPHER_TEST_OP_AUTH (BLOCKCIPHER_TEST_OP_AUTH_GEN | \ - BLOCKCIPHER_TEST_OP_AUTH_VERIFY) - -#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN (BLOCKCIPHER_TEST_OP_ENCRYPT | \ - BLOCKCIPHER_TEST_OP_AUTH_GEN) - -#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC (BLOCKCIPHER_TEST_OP_DECRYPT | \ - BLOCKCIPHER_TEST_OP_AUTH_VERIFY) - -enum blockcipher_test_type { - BLKCIPHER_AES_CHAIN_TYPE, /* use aes_chain_test_cases[] */ - BLKCIPHER_AES_CIPHERONLY_TYPE, /* use aes_cipheronly_test_cases[] */ - BLKCIPHER_3DES_CHAIN_TYPE, /* use triple_des_chain_test_cases[] */ - BLKCIPHER_3DES_CIPHERONLY_TYPE, /* triple_des_cipheronly_test_cases[] */ - BLKCIPHER_AUTHONLY_TYPE, /* use hash_test_cases[] */ - BLKCIPHER_DES_CIPHERONLY_TYPE /* use des_cipheronly_test_cases[] */ -}; - -struct blockcipher_test_case { - const char *test_descr; /* test description */ - const struct blockcipher_test_data *test_data; - uint8_t op_mask; /* operation mask */ - uint8_t feature_mask; - uint32_t pmd_mask; -}; - -struct blockcipher_test_data { - enum rte_crypto_cipher_algorithm crypto_algo; - - struct { - uint8_t data[64]; - unsigned int len; - } cipher_key; - - struct { - uint8_t data[64] __rte_aligned(16); - unsigned int len; - } iv; - - struct { - const uint8_t *data; - unsigned int len; - } plaintext; - - struct { - const uint8_t *data; - unsigned int len; - } ciphertext; - - enum rte_crypto_auth_algorithm auth_algo; - - struct { - uint8_t data[128]; - unsigned int len; - } auth_key; - - struct { - uint8_t data[128]; - unsigned int len; /* for qat */ - unsigned int truncated_len; /* for mb */ - } digest; -}; - -int -test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type, - enum blockcipher_test_type test_type); - -#endif /* TEST_CRYPTODEV_BLOCKCIPHER_H_ */ diff --git a/app/test/test_cryptodev_des_test_vectors.h b/app/test/test_cryptodev_des_test_vectors.h deleted file mode 100644 index 388d87e182..0000000000 --- a/app/test/test_cryptodev_des_test_vectors.h +++ /dev/null @@ -1,1065 +0,0 @@ -/* - * 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_DES_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_DES_TEST_VECTORS_H_ - -static const uint8_t plaintext_des[] = { - "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." -}; - -static const uint8_t ciphertext512_des128ctr[] = { - 0x13, 0x39, 0x3B, 0xBC, 0x1D, 0xE3, 0x23, 0x09, - 0x9B, 0x08, 0xD1, 0x09, 0x52, 0x93, 0x78, 0x29, - 0x11, 0x21, 0xBA, 0x01, 0x15, 0xCD, 0xEC, 0xAA, - 0x79, 0x77, 0x58, 0xAE, 0xAE, 0xBC, 0x97, 0x33, - 0x94, 0xA9, 0x2D, 0xC0, 0x0A, 0xA9, 0xA4, 0x4B, - 0x19, 0x07, 0x88, 0x06, 0x7E, 0x81, 0x0F, 0xB5, - 0x60, 0xCF, 0xA7, 0xC3, 0x2A, 0x43, 0xFF, 0x16, - 0x3A, 0x5F, 0x11, 0x2D, 0x11, 0x38, 0x37, 0x94, - 0x2A, 0xC8, 0x3D, 0x20, 0xBB, 0x93, 0x95, 0x54, - 0x12, 0xFF, 0x0C, 0x47, 0x89, 0x7D, 0x73, 0xD1, - 0x2E, 0x3A, 0x80, 0x52, 0xA8, 0x92, 0x93, 0x99, - 0x16, 0xB8, 0x12, 0x1B, 0x8B, 0xA8, 0xC1, 0x81, - 0x95, 0x18, 0x82, 0xD6, 0x5A, 0xA7, 0xFE, 0xCF, - 0xC4, 0xAC, 0x85, 0x91, 0x0C, 0x2F, 0x1D, 0x10, - 0x9A, 0x65, 0x07, 0xB0, 0x2E, 0x5A, 0x2D, 0x48, - 0x26, 0xF8, 0x17, 0x7A, 0x53, 0xD6, 0xB8, 0xDF, - 0xB1, 0x10, 0x48, 0x7E, 0x8F, 0xBE, 0x2E, 0xA1, - 0x0D, 0x9E, 0xA9, 0xF1, 0x3B, 0x3B, 0x33, 0xCD, - 0xDC, 0x52, 0x7E, 0xC0, 0x0E, 0xA0, 0xD8, 0xA7, - 0xC6, 0x34, 0x5A, 0xAA, 0x29, 0x8B, 0xA9, 0xAC, - 0x1F, 0x78, 0xAD, 0xEE, 0x34, 0x59, 0x30, 0xFB, - 0x2A, 0x20, 0x3D, 0x4D, 0x30, 0xA7, 0x7D, 0xD8, - 0xA0, 0xC6, 0xA2, 0xD3, 0x9A, 0xFB, 0x50, 0x97, - 0x4D, 0x25, 0xA2, 0x37, 0x51, 0x54, 0xB7, 0xEB, - 0xED, 0x77, 0xDB, 0x94, 0x35, 0x8B, 0x70, 0x95, - 0x4A, 0x00, 0xA7, 0xF1, 0x8A, 0x66, 0x0E, 0xC6, - 0x05, 0x7B, 0x69, 0x05, 0x42, 0x03, 0x96, 0x2C, - 0x55, 0x00, 0x1B, 0xC0, 0x19, 0x4D, 0x0D, 0x2E, - 0xF5, 0x81, 0x11, 0x64, 0xCA, 0xBB, 0xF2, 0x0F, - 0x9C, 0x60, 0xE2, 0xCC, 0x02, 0x6E, 0x83, 0xD5, - 0x24, 0xF4, 0x12, 0x0E, 0x6A, 0xEA, 0x4F, 0x6C, - 0x79, 0x69, 0x65, 0x67, 0xDB, 0xF7, 0xEA, 0x98, - 0x5D, 0x56, 0x98, 0xB7, 0x88, 0xE7, 0x23, 0xC9, - 0x17, 0x32, 0x92, 0x33, 0x5A, 0x0C, 0x15, 0x20, - 0x3B, 0x1C, 0xF9, 0x0F, 0x4D, 0xD1, 0xE8, 0xE6, - 0x9E, 0x5E, 0x24, 0x1B, 0xA4, 0xB8, 0xB9, 0xE9, - 0x2F, 0xFC, 0x89, 0xB4, 0xB9, 0xF4, 0xA6, 0xAD, - 0x55, 0xF4, 0xDF, 0x58, 0x63, 0x25, 0xE3, 0x41, - 0x70, 0xDF, 0x10, 0xE7, 0x13, 0x87, 0x8D, 0xB3, - 0x62, 0x4F, 0xF5, 0x86, 0x85, 0x8F, 0x59, 0xF0, - 0x21, 0x0E, 0x8F, 0x11, 0xAD, 0xBF, 0xDD, 0x61, - 0x68, 0x3F, 0x54, 0x57, 0x49, 0x38, 0xC8, 0x24, - 0x8E, 0x0A, 0xAC, 0xCA, 0x2C, 0x36, 0x3E, 0x5F, - 0x0A, 0xCE, 0xFD, 0x1A, 0x60, 0x63, 0x5A, 0xE6, - 0x06, 0x64, 0xB5, 0x94, 0x3C, 0xC9, 0xAF, 0x7C, - 0xCD, 0x49, 0x10, 0xCF, 0xAF, 0x0E, 0x2E, 0x79, - 0x27, 0xB2, 0x67, 0x02, 0xED, 0xEE, 0x80, 0x77, - 0x7C, 0x6D, 0x4B, 0xDB, 0xCF, 0x8D, 0x68, 0x00, - 0x2E, 0xD9, 0xF0, 0x8E, 0x08, 0xBF, 0xA6, 0x9B, - 0xFE, 0xA4, 0xFB, 0x19, 0x46, 0xAF, 0x1B, 0xA9, - 0xF8, 0x22, 0x81, 0x21, 0x97, 0xFC, 0xC0, 0x8A, - 0x26, 0x58, 0x13, 0x29, 0xB6, 0x69, 0x94, 0x4B, - 0xAB, 0xB3, 0x88, 0x0D, 0xA9, 0x48, 0x0E, 0xE8, - 0x70, 0xFC, 0xA1, 0x21, 0xC4, 0x2C, 0xE5, 0x99, - 0xB4, 0xF1, 0x6F, 0xB2, 0x4B, 0x4B, 0xCD, 0x48, - 0x15, 0x47, 0x2D, 0x72, 0x39, 0x99, 0x9D, 0x24, - 0x0C, 0x8B, 0xDC, 0xA1, 0xEE, 0xF6, 0xF4, 0x73, - 0xC3, 0xB8, 0x0C, 0x23, 0x0D, 0xA7, 0xC4, 0x7D, - 0x27, 0xE2, 0x14, 0x11, 0x53, 0x19, 0xE7, 0xCA, - 0x94, 0x4E, 0x0D, 0x2C, 0xF7, 0x36, 0x47, 0xDB, - 0x77, 0x3C, 0x22, 0xAC, 0xBE, 0xE1, 0x06, 0x55, - 0xE5, 0xDD, 0x8B, 0x65, 0xE8, 0xE9, 0x91, 0x52, - 0x59, 0x97, 0xFC, 0x8C, 0xEE, 0x96, 0x22, 0x60, - 0xEE, 0xBF, 0x82, 0xF0, 0xCA, 0x14, 0xF9, 0xD3 -}; - -static const struct blockcipher_test_data -triple_des128ctr_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .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 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des128ctr, - .len = 512 - } -}; - -static const struct blockcipher_test_data -triple_des128ctr_sha1_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .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 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des128ctr, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1, - .digest = { - .data = { - 0xC3, 0x40, 0xD5, 0xD9, 0x8F, 0x8A, 0xC0, 0xF0, - 0x46, 0x28, 0x02, 0x01, 0xB5, 0xC1, 0x87, 0x4D, - 0xAC, 0xFE, 0x48, 0x76 - }, - .len = 20 - } -}; - -static const struct blockcipher_test_data -triple_des128ctr_hmac_sha1_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .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 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des128ctr, - .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 = { - 0xF1, 0xC1, 0xDB, 0x4D, 0xFA, 0x7F, 0x2F, 0xE5, - 0xF8, 0x49, 0xEA, 0x1D, 0x7F, 0xCB, 0x42, 0x59, - 0xC4, 0x1E, 0xB1, 0x18 - }, - .len = 20 - } -}; - -static const uint8_t ciphertext512_des192ctr[] = { - 0xFF, 0x32, 0x52, 0x97, 0x10, 0xBF, 0x0B, 0x10, - 0x68, 0x0F, 0x4F, 0x56, 0x8B, 0x2C, 0x7B, 0x8E, - 0x39, 0x1E, 0x1A, 0x2F, 0x83, 0xDE, 0x5E, 0x35, - 0xC8, 0x4B, 0xDF, 0xD5, 0xBC, 0x84, 0x50, 0x1A, - 0x02, 0xDF, 0xB3, 0x11, 0xE4, 0xDA, 0xB8, 0x0E, - 0x47, 0xC6, 0x0C, 0x51, 0x09, 0x62, 0x9C, 0x5D, - 0x71, 0x40, 0x49, 0xD8, 0x55, 0xBD, 0x7D, 0x90, - 0x71, 0xC5, 0xF7, 0x07, 0x6F, 0x08, 0x71, 0x2A, - 0xB1, 0x77, 0x9B, 0x0F, 0xA1, 0xB0, 0xD6, 0x10, - 0xB2, 0xE5, 0x31, 0xEC, 0x21, 0x13, 0x89, 0x2A, - 0x09, 0x7E, 0x30, 0xDB, 0xA0, 0xF0, 0xDC, 0xE4, - 0x74, 0x64, 0x39, 0xA3, 0xB0, 0xB1, 0x80, 0x66, - 0x52, 0xD4, 0x4E, 0xC9, 0x5A, 0x52, 0x6A, 0xC7, - 0xB5, 0x2B, 0x61, 0xD5, 0x17, 0xD5, 0xF3, 0xCC, - 0x41, 0x61, 0xD2, 0xA6, 0xF4, 0x51, 0x24, 0x3A, - 0x63, 0x5D, 0x23, 0xB1, 0xF0, 0x22, 0xE7, 0x45, - 0xFA, 0x5F, 0x7E, 0x99, 0x00, 0x11, 0x28, 0x35, - 0xA3, 0xF4, 0x61, 0x94, 0x0E, 0x98, 0xCE, 0x35, - 0xDD, 0x91, 0x1B, 0x0B, 0x4D, 0xEE, 0xFF, 0xFF, - 0x0B, 0xD4, 0xDC, 0x56, 0xFC, 0x71, 0xE9, 0xEC, - 0xE8, 0x36, 0x51, 0xF8, 0x8B, 0x6A, 0xE1, 0x8C, - 0x2B, 0x25, 0x91, 0x91, 0x9B, 0x92, 0x76, 0xB5, - 0x3D, 0x26, 0xA8, 0x53, 0xEA, 0x30, 0x5B, 0x4D, - 0xDA, 0x16, 0xDA, 0x7D, 0x04, 0x88, 0xF5, 0x22, - 0xA8, 0x0C, 0xB9, 0x41, 0xC7, 0x91, 0x64, 0x86, - 0x99, 0x7D, 0x18, 0xB9, 0x67, 0xA2, 0x6E, 0x05, - 0x1A, 0x82, 0x8F, 0xA2, 0xEB, 0x4D, 0x0B, 0x8C, - 0x88, 0x2D, 0xBA, 0x77, 0x87, 0x32, 0x50, 0x3C, - 0x4C, 0xD8, 0xD3, 0x50, 0x39, 0xFA, 0xDF, 0x48, - 0x3E, 0x30, 0xF5, 0x76, 0x06, 0xB0, 0x1A, 0x05, - 0x60, 0x2C, 0xD3, 0xA0, 0x63, 0x1A, 0x19, 0x2D, - 0x6B, 0x76, 0xF2, 0x31, 0x4C, 0xA7, 0xE6, 0x5C, - 0x1B, 0x23, 0x20, 0x41, 0x32, 0xE5, 0x83, 0x47, - 0x04, 0xB6, 0x3E, 0xE0, 0xFD, 0x49, 0x1E, 0x1B, - 0x75, 0x10, 0x11, 0x46, 0xE9, 0xF9, 0x96, 0x9A, - 0xD7, 0x59, 0xFE, 0x38, 0x31, 0xFE, 0x79, 0xC4, - 0xC8, 0x46, 0x88, 0xDE, 0x2E, 0xAE, 0x20, 0xED, - 0x77, 0x50, 0x40, 0x38, 0x26, 0xD3, 0x35, 0xF6, - 0x29, 0x55, 0x6A, 0x6B, 0x38, 0x69, 0xFE, 0x90, - 0x5B, 0xA7, 0xFA, 0x6B, 0x73, 0x4F, 0xB9, 0x5D, - 0xDC, 0x6F, 0x98, 0xC3, 0x6A, 0xC4, 0xB5, 0x09, - 0xC5, 0x84, 0xA5, 0x6A, 0x84, 0xA4, 0xB3, 0x8A, - 0x5F, 0xCA, 0x92, 0x64, 0x9E, 0xC3, 0x0F, 0x84, - 0x8B, 0x2D, 0x48, 0xC6, 0x67, 0xAE, 0x07, 0xE0, - 0x28, 0x38, 0x6D, 0xC4, 0x4D, 0x13, 0x87, 0xE0, - 0xB2, 0x2F, 0xAA, 0xC0, 0xCF, 0x68, 0xD7, 0x9C, - 0xB8, 0x07, 0xE4, 0x51, 0xD7, 0x75, 0x86, 0xFA, - 0x0C, 0x50, 0x74, 0x68, 0x00, 0x64, 0x2A, 0x27, - 0x59, 0xE9, 0x80, 0xEB, 0xC2, 0xA3, 0xFA, 0x58, - 0xCC, 0x03, 0xE7, 0x7B, 0x66, 0x53, 0xFF, 0x90, - 0xA0, 0x85, 0xE2, 0xF8, 0x82, 0xFE, 0xC6, 0x2B, - 0xFF, 0x5E, 0x70, 0x85, 0x34, 0xB7, 0x22, 0x38, - 0xDB, 0xBC, 0x15, 0x30, 0x59, 0xC1, 0x48, 0x42, - 0xE5, 0x38, 0x8D, 0x37, 0x59, 0xDB, 0xA3, 0x20, - 0x17, 0x36, 0x1D, 0x4B, 0xBF, 0x4E, 0xA4, 0x35, - 0xCC, 0xFE, 0xF5, 0x7A, 0x73, 0xB4, 0x6D, 0x20, - 0x1D, 0xC0, 0xE5, 0x21, 0x5C, 0xD2, 0x8A, 0x65, - 0x08, 0xB6, 0x63, 0xAC, 0x9A, 0x1E, 0x3F, 0x3C, - 0xAB, 0xB6, 0x6D, 0x34, 0xB2, 0x3A, 0x08, 0xDA, - 0x29, 0x63, 0xD1, 0xA4, 0x83, 0x52, 0xB0, 0x63, - 0x1B, 0x89, 0x35, 0x57, 0x59, 0x2C, 0x0F, 0x72, - 0x72, 0xFD, 0xA0, 0xAC, 0xDB, 0xB4, 0xA3, 0xA1, - 0x18, 0x10, 0x12, 0x97, 0x99, 0x63, 0x38, 0x98, - 0x96, 0xB5, 0x16, 0x07, 0x4E, 0xE9, 0x2C, 0x97 -}; - -static const struct blockcipher_test_data -triple_des192ctr_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, - 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des192ctr, - .len = 512 - } -}; - -static const struct blockcipher_test_data -triple_des192ctr_sha1_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, - 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des192ctr, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1, - .digest = { - .data = { - 0xEA, 0x62, 0xB9, 0xB2, 0x78, 0x6C, 0x8E, 0xDB, - 0xA3, 0xB6, 0xFF, 0x23, 0x3A, 0x47, 0xD8, 0xC8, - 0xED, 0x5E, 0x20, 0x1D - }, - .len = 20 - } -}; - -static const struct blockcipher_test_data -triple_des192ctr_hmac_sha1_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, - 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des192ctr, - .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 = { - 0x32, 0xD5, 0x19, 0x8F, 0x79, 0x3A, 0xAA, 0x7B, - 0x70, 0x67, 0x4E, 0x63, 0x88, 0xA3, 0x9A, 0x82, - 0x07, 0x33, 0x12, 0x94 - }, - .len = 20 - } -}; - -static const uint8_t ciphertext512_des128cbc[] = { - 0x28, 0x2a, 0xff, 0x15, 0x5c, 0xdf, 0xd9, 0x6b, - 0x54, 0xbc, 0x7b, 0xfb, 0xc5, 0x64, 0x4d, 0xdd, - 0x3e, 0xf2, 0x9e, 0xb7, 0x53, 0x65, 0x37, 0x05, - 0xe0, 0xdf, 0xae, 0xf7, 0xc9, 0x27, 0xe4, 0xec, - 0x11, 0x27, 0xc2, 0x9e, 0x02, 0x4e, 0x03, 0x3b, - 0x33, 0xf2, 0x66, 0x08, 0x24, 0x5f, 0xab, 0xc2, - 0x7e, 0x21, 0x19, 0x5d, 0x51, 0xc3, 0xe2, 0x97, - 0x6f, 0x2e, 0xb4, 0xaa, 0x34, 0x70, 0x88, 0x78, - 0x4e, 0xe7, 0x3d, 0xe1, 0x9f, 0x87, 0x1c, 0x8b, - 0xac, 0x8d, 0xa1, 0x1a, 0xcd, 0xb0, 0xf8, 0xb6, - 0x24, 0x36, 0xe3, 0x8c, 0x07, 0xe7, 0xe4, 0x92, - 0x13, 0x86, 0x6f, 0x13, 0xec, 0x04, 0x5c, 0xe9, - 0xb9, 0xca, 0x45, 0x8a, 0x2c, 0x46, 0xda, 0x54, - 0x1d, 0xb5, 0x81, 0xb1, 0xcd, 0xf3, 0x7d, 0x11, - 0x6b, 0xb3, 0x0a, 0x45, 0xe5, 0x6e, 0x51, 0x3e, - 0x2c, 0xac, 0x7c, 0xbc, 0xa7, 0x7e, 0x22, 0x4d, - 0xe6, 0x02, 0xe3, 0x3f, 0x77, 0xd7, 0x73, 0x72, - 0x0e, 0xfb, 0x42, 0x85, 0x80, 0xdf, 0xa8, 0x91, - 0x60, 0x40, 0x48, 0xcd, 0x1b, 0xd9, 0xbf, 0x2f, - 0xf2, 0xdf, 0xd0, 0xbd, 0x3f, 0x82, 0xce, 0x15, - 0x9d, 0x6e, 0xc6, 0x59, 0x6f, 0x27, 0x0d, 0xf9, - 0x26, 0xe2, 0x11, 0x29, 0x50, 0xc3, 0x0a, 0xb7, - 0xde, 0x9d, 0xe9, 0x55, 0xa1, 0xe9, 0x01, 0x33, - 0x56, 0x51, 0xa7, 0x3a, 0x9e, 0x63, 0xc5, 0x08, - 0x01, 0x3b, 0x03, 0x4b, 0xc6, 0xc4, 0xa1, 0xc0, - 0xc0, 0xd0, 0x0e, 0x48, 0xe5, 0x4c, 0x55, 0x6b, - 0x4a, 0xc1, 0x0a, 0x24, 0x4b, 0xd0, 0x02, 0xf4, - 0x31, 0x63, 0x11, 0xbd, 0xa6, 0x1f, 0xf4, 0xae, - 0x23, 0x5a, 0x40, 0x7e, 0x0e, 0x4e, 0x63, 0x8b, - 0x66, 0x3d, 0x55, 0x46, 0x6e, 0x5c, 0x76, 0xa7, - 0x68, 0x31, 0xce, 0x5d, 0xca, 0xe2, 0xb4, 0xb0, - 0xc1, 0x1f, 0x66, 0x18, 0x75, 0x64, 0x73, 0xa9, - 0x9e, 0xd5, 0x0e, 0x0e, 0xf7, 0x77, 0x61, 0xf8, - 0x89, 0xc6, 0xcf, 0x0c, 0x41, 0xd3, 0x8f, 0xfd, - 0x22, 0x52, 0x4f, 0x94, 0x5c, 0x19, 0x11, 0x3a, - 0xb5, 0x63, 0xe8, 0x81, 0x33, 0x13, 0x54, 0x3c, - 0x93, 0x36, 0xb5, 0x5b, 0x51, 0xaf, 0x51, 0xa2, - 0x08, 0xae, 0x83, 0x15, 0x77, 0x07, 0x28, 0x0d, - 0x98, 0xe1, 0x2f, 0x69, 0x0e, 0xfb, 0x9a, 0x2e, - 0x27, 0x27, 0xb0, 0xd5, 0xce, 0xf8, 0x16, 0x55, - 0xfd, 0xaa, 0xd7, 0x1a, 0x1b, 0x2e, 0x4c, 0x86, - 0x7a, 0x6a, 0x90, 0xf7, 0x0a, 0x07, 0xd3, 0x81, - 0x4b, 0x75, 0x6a, 0x79, 0xdb, 0x63, 0x45, 0x0f, - 0x31, 0x7e, 0xd0, 0x2a, 0x14, 0xff, 0xee, 0xcc, - 0x97, 0x8a, 0x7d, 0x74, 0xbd, 0x9d, 0xaf, 0x00, - 0xdb, 0x7e, 0xf3, 0xe6, 0x22, 0x76, 0x77, 0x58, - 0xba, 0x1c, 0x06, 0x96, 0xfb, 0x6f, 0x41, 0x71, - 0x66, 0x98, 0xae, 0x31, 0x7d, 0x29, 0x18, 0x71, - 0x0e, 0xe4, 0x98, 0x7e, 0x59, 0x5a, 0xc9, 0x78, - 0x9c, 0xfb, 0x6c, 0x81, 0x44, 0xb4, 0x0f, 0x5e, - 0x18, 0x53, 0xb8, 0x6f, 0xbc, 0x3b, 0x15, 0xf0, - 0x10, 0xdd, 0x0d, 0x4b, 0x0a, 0x36, 0x0e, 0xb4, - 0x76, 0x0f, 0x16, 0xa7, 0x5c, 0x9d, 0xcf, 0xb0, - 0x6d, 0x38, 0x02, 0x07, 0x05, 0xe9, 0xe9, 0x46, - 0x08, 0xb8, 0x52, 0xd6, 0xd9, 0x4c, 0x81, 0x63, - 0x1d, 0xe2, 0x5b, 0xd0, 0xf6, 0x5e, 0x1e, 0x81, - 0x48, 0x08, 0x66, 0x3a, 0x85, 0xed, 0x65, 0xfe, - 0xe8, 0x05, 0x7a, 0xe1, 0xe6, 0x12, 0xf2, 0x52, - 0x83, 0xdd, 0x82, 0xbe, 0xf6, 0x34, 0x8a, 0x6f, - 0xc5, 0x83, 0xcd, 0x3f, 0xbe, 0x58, 0x8b, 0x11, - 0x78, 0xdc, 0x0c, 0x83, 0x72, 0x5d, 0x05, 0x2a, - 0x01, 0x29, 0xee, 0x48, 0x9a, 0x67, 0x00, 0x6e, - 0x14, 0x60, 0x2d, 0x00, 0x52, 0x87, 0x98, 0x5e, - 0x43, 0xfe, 0xf1, 0x10, 0x14, 0xf1, 0x91, 0xcc -}; - - -static const uint8_t ciphertext512_des[] = { - 0x1A, 0x46, 0xDB, 0x69, 0x43, 0x45, 0x0F, 0x2F, - 0xDC, 0x27, 0xF9, 0x41, 0x0E, 0x01, 0x58, 0xB4, - 0x5E, 0xCC, 0x13, 0xF5, 0x92, 0x99, 0xE4, 0xF2, - 0xD5, 0xF9, 0x16, 0xFE, 0x0F, 0x7E, 0xDE, 0xA0, - 0xF5, 0x32, 0xFE, 0x20, 0x67, 0x93, 0xCA, 0xE1, - 0x8E, 0x4D, 0x72, 0xA3, 0x50, 0x72, 0x14, 0x15, - 0x70, 0xE7, 0xAB, 0x49, 0x25, 0x88, 0x0E, 0x01, - 0x5C, 0x52, 0x87, 0xE2, 0x27, 0xDC, 0xD4, 0xD1, - 0x14, 0x1B, 0x08, 0x9F, 0x42, 0x48, 0x93, 0xA9, - 0xD1, 0x2F, 0x2C, 0x69, 0x48, 0x16, 0x59, 0xCF, - 0x8B, 0xF6, 0x8B, 0xD9, 0x34, 0xD4, 0xD7, 0xE4, - 0xAE, 0x35, 0xFD, 0xDA, 0x73, 0xBE, 0xDC, 0x6B, - 0x10, 0x90, 0x75, 0x2D, 0x4C, 0x14, 0x37, 0x8B, - 0xC8, 0xC7, 0xDF, 0x6E, 0x6F, 0xED, 0xF3, 0xE3, - 0xD3, 0x21, 0x29, 0xCD, 0x06, 0xB6, 0x5B, 0xF4, - 0xB9, 0xBD, 0x77, 0xA2, 0xF7, 0x91, 0xF4, 0x95, - 0xF0, 0xE0, 0x62, 0x03, 0x46, 0xAE, 0x1B, 0xEB, - 0xE2, 0xA9, 0xCF, 0xB9, 0x0E, 0x3B, 0xB9, 0xDA, - 0x5C, 0x1B, 0x45, 0x3F, 0xDD, 0xCC, 0xCC, 0xB3, - 0xF0, 0xDD, 0x36, 0x26, 0x11, 0x57, 0x97, 0xA7, - 0xF6, 0xF4, 0xE1, 0x4F, 0xBB, 0x31, 0xBB, 0x07, - 0x4B, 0xA3, 0xB4, 0x83, 0xF9, 0x23, 0xA1, 0xCD, - 0x8C, 0x1C, 0x76, 0x92, 0x45, 0xA5, 0xEB, 0x7D, - 0xEB, 0x22, 0x88, 0xB1, 0x9F, 0xFB, 0xE9, 0x06, - 0x8F, 0x67, 0xA6, 0x8A, 0xB7, 0x0B, 0xCD, 0x8F, - 0x34, 0x40, 0x4F, 0x4F, 0xAD, 0xA0, 0xF2, 0xDC, - 0x2C, 0x53, 0xE1, 0xCA, 0xA5, 0x7A, 0x03, 0xEF, - 0x08, 0x00, 0xCC, 0x52, 0xA6, 0xAB, 0x56, 0xD2, - 0xF1, 0xCD, 0xC7, 0xED, 0xBE, 0xCB, 0x78, 0x37, - 0x4B, 0x61, 0xA9, 0xD2, 0x3C, 0x8D, 0xCC, 0xFD, - 0x21, 0xFD, 0x0F, 0xE4, 0x4E, 0x3D, 0x6F, 0x8F, - 0x2A, 0xEC, 0x69, 0xFA, 0x20, 0x50, 0x99, 0x35, - 0xA1, 0xCC, 0x3B, 0xFD, 0xD6, 0xAC, 0xE9, 0xBE, - 0x14, 0xF1, 0xBC, 0x71, 0x70, 0xFE, 0x13, 0xD1, - 0x48, 0xCC, 0xBE, 0x7B, 0xCB, 0xC0, 0x20, 0xD9, - 0x28, 0xD7, 0xD4, 0x0F, 0x66, 0x7A, 0x60, 0xAB, - 0x20, 0xA9, 0x23, 0x41, 0x03, 0x34, 0xC3, 0x63, - 0x91, 0x69, 0x02, 0xD5, 0xBC, 0x41, 0xDA, 0xA8, - 0xD1, 0x48, 0xC9, 0x8E, 0x4F, 0xCD, 0x0F, 0x21, - 0x5B, 0x4D, 0x5F, 0xF5, 0x1B, 0x2A, 0x44, 0x10, - 0x16, 0xA7, 0xFD, 0xC0, 0x55, 0xE1, 0x98, 0xBB, - 0x76, 0xB5, 0xAB, 0x39, 0x6B, 0x9B, 0xAB, 0x85, - 0x45, 0x4B, 0x9C, 0x64, 0x7D, 0x78, 0x3F, 0x61, - 0x22, 0xB1, 0xDE, 0x0E, 0x39, 0x2B, 0x21, 0x26, - 0xE2, 0x1D, 0x5A, 0xD7, 0xAC, 0xDF, 0xD4, 0x12, - 0x69, 0xD1, 0xE8, 0x9B, 0x1A, 0xCE, 0x6C, 0xA0, - 0x3B, 0x23, 0xDC, 0x03, 0x2B, 0x97, 0x16, 0xD0, - 0xD0, 0x46, 0x98, 0x36, 0x53, 0xCE, 0x88, 0x6E, - 0xCA, 0x2C, 0x15, 0x0E, 0x49, 0xED, 0xBE, 0xE5, - 0xBF, 0xBD, 0x7B, 0xC2, 0x21, 0xE1, 0x09, 0xFF, - 0x71, 0xA8, 0xBE, 0x8F, 0xB4, 0x1D, 0x25, 0x5C, - 0x37, 0xCA, 0x26, 0xD2, 0x1E, 0x63, 0xE1, 0x7F, - 0x0D, 0x89, 0x10, 0xEF, 0x78, 0xB0, 0xDB, 0xD0, - 0x72, 0x44, 0x60, 0x1D, 0xCF, 0x7C, 0x25, 0x1A, - 0xBB, 0xC3, 0x92, 0x53, 0x8E, 0x9F, 0x27, 0xC7, - 0xE8, 0x08, 0xFC, 0x5D, 0x50, 0x3E, 0xFC, 0xB0, - 0x00, 0xE2, 0x48, 0xB2, 0x4B, 0xF8, 0xF2, 0xE3, - 0xD3, 0x8B, 0x71, 0x64, 0xB8, 0xF0, 0x6E, 0x4A, - 0x23, 0xA0, 0xA4, 0x88, 0xA4, 0x36, 0x45, 0x6B, - 0x5A, 0xE7, 0x57, 0x65, 0xEA, 0xC9, 0xF8, 0xE8, - 0x7A, 0x80, 0x22, 0x67, 0x1A, 0x05, 0xF2, 0x78, - 0x81, 0x17, 0xCD, 0x87, 0xFB, 0x0D, 0x25, 0x84, - 0x49, 0x06, 0x25, 0xCE, 0xFC, 0x38, 0x06, 0x18, - 0x2E, 0x1D, 0xE1, 0x33, 0x97, 0xB6, 0x7E, 0xAB, -}; - - -static const struct blockcipher_test_data -triple_des128cbc_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_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 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des128cbc, - .len = 512 - } -}; - -static const struct blockcipher_test_data -triple_des128cbc_sha1_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_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 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des128cbc, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1, - .digest = { - .data = { - 0x94, 0x45, 0x7B, 0xDF, 0xFE, 0x80, 0xB9, 0xA6, - 0xA0, 0x7A, 0xE8, 0x93, 0x40, 0x7B, 0x85, 0x02, - 0x1C, 0xD7, 0xE8, 0x87 - }, - .len = 20 - } -}; - -static const struct blockcipher_test_data -triple_des128cbc_hmac_sha1_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_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 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des128cbc, - .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 = { - 0x7E, 0xBA, 0xFF, 0x86, 0x8D, 0x65, 0xCD, 0x08, - 0x76, 0x34, 0x94, 0xE9, 0x9A, 0xCD, 0xB2, 0xBB, - 0xBF, 0x65, 0xF5, 0x42 - }, - .len = 20 - } -}; - -static const uint8_t ciphertext512_des192cbc[] = { - 0xd0, 0xc9, 0xdc, 0x51, 0x29, 0x97, 0x03, 0x64, - 0xcd, 0x22, 0xba, 0x3d, 0x2b, 0xbc, 0x21, 0x37, - 0x7b, 0x1e, 0x29, 0x23, 0xeb, 0x51, 0x6e, 0xac, - 0xbe, 0x5b, 0xd3, 0x67, 0xe0, 0x3f, 0xc3, 0xb5, - 0xe3, 0x04, 0x17, 0x42, 0x2b, 0xaa, 0xdd, 0xd6, - 0x0e, 0x69, 0xd0, 0x8f, 0x8a, 0xfc, 0xb4, 0x55, - 0x67, 0x06, 0x51, 0xbb, 0x00, 0x57, 0xee, 0x95, - 0x28, 0x79, 0x3f, 0xd9, 0x97, 0x2b, 0xb0, 0x02, - 0x35, 0x08, 0xce, 0x7a, 0xc3, 0x43, 0x2c, 0x87, - 0xaa, 0x97, 0x6a, 0xad, 0xf0, 0x26, 0xea, 0x1d, - 0xbb, 0x08, 0xe9, 0x52, 0x11, 0xd3, 0xaf, 0x36, - 0x17, 0x14, 0x21, 0xb2, 0xbc, 0x42, 0x51, 0x33, - 0x27, 0x8c, 0xd8, 0x45, 0xb9, 0x76, 0xa0, 0x11, - 0x24, 0x34, 0xde, 0x4d, 0x13, 0x67, 0x1b, 0xc3, - 0x31, 0x12, 0x66, 0x56, 0x59, 0xd2, 0xb1, 0x8f, - 0xec, 0x1e, 0xc0, 0x10, 0x7a, 0x86, 0xb1, 0x60, - 0xc3, 0x01, 0xd6, 0xa8, 0x55, 0xad, 0x58, 0x63, - 0xca, 0x68, 0xa9, 0x33, 0xe3, 0x93, 0x90, 0x7d, - 0x8f, 0xca, 0xf8, 0x1c, 0xc2, 0x9e, 0xfb, 0xde, - 0x9c, 0xc7, 0xf2, 0x6c, 0xff, 0xcc, 0x39, 0x17, - 0x49, 0x33, 0x0d, 0x7c, 0xed, 0x07, 0x99, 0x91, - 0x91, 0x6c, 0x5f, 0x3f, 0x02, 0x09, 0xdc, 0x70, - 0xf9, 0x3b, 0x8d, 0xaa, 0xf4, 0xbc, 0x0e, 0xec, - 0xf2, 0x26, 0xfb, 0xb2, 0x1c, 0x31, 0xae, 0xc6, - 0x72, 0xe8, 0x0b, 0x75, 0x05, 0x57, 0x58, 0x98, - 0x92, 0x37, 0x27, 0x8e, 0x3b, 0x0c, 0x25, 0xfb, - 0xcf, 0x82, 0x02, 0xd5, 0x0b, 0x1f, 0x89, 0x49, - 0xcd, 0x0f, 0xa1, 0xa7, 0x08, 0x63, 0x56, 0xa7, - 0x1f, 0x80, 0x3a, 0xef, 0x24, 0x89, 0x57, 0x1a, - 0x02, 0xdc, 0x2e, 0x51, 0xbd, 0x4a, 0x10, 0x23, - 0xfc, 0x02, 0x1a, 0x3f, 0x34, 0xbf, 0x1c, 0x98, - 0x1a, 0x40, 0x0a, 0x96, 0x8e, 0x41, 0xd5, 0x09, - 0x55, 0x37, 0xe9, 0x25, 0x11, 0x83, 0xf8, 0xf3, - 0xd4, 0xb0, 0xdb, 0x16, 0xd7, 0x51, 0x7e, 0x94, - 0xf7, 0xb4, 0x26, 0xe0, 0xf4, 0x80, 0x01, 0x65, - 0x51, 0xeb, 0xbc, 0xb0, 0x65, 0x8f, 0xdd, 0xb5, - 0xf7, 0x00, 0xec, 0x40, 0xab, 0x7d, 0x96, 0xcc, - 0x8d, 0xec, 0x89, 0x80, 0x31, 0x39, 0xa2, 0x5c, - 0xb0, 0x55, 0x4c, 0xee, 0xdd, 0x15, 0x2b, 0xa9, - 0x86, 0x4e, 0x23, 0x14, 0x36, 0xc5, 0x57, 0xf5, - 0xe3, 0xe8, 0x89, 0xc9, 0xb7, 0xf8, 0xeb, 0x08, - 0xe5, 0x93, 0x12, 0x5c, 0x0f, 0x79, 0xa1, 0x86, - 0xe4, 0xc2, 0xeb, 0xa6, 0xa0, 0x50, 0x6a, 0xec, - 0xd3, 0xce, 0x50, 0x78, 0x4e, 0x4f, 0x93, 0xd8, - 0xdc, 0xb4, 0xec, 0x02, 0xe9, 0xbd, 0x17, 0x99, - 0x1e, 0x16, 0x4e, 0xd7, 0xb0, 0x07, 0x02, 0x55, - 0x63, 0x24, 0x4f, 0x7b, 0x8f, 0xc5, 0x7a, 0x12, - 0x29, 0xff, 0x5d, 0xc1, 0xe7, 0xae, 0x48, 0xc8, - 0x57, 0x53, 0xe7, 0xcd, 0x10, 0x6c, 0x19, 0xfc, - 0xcc, 0xb9, 0xb1, 0xbe, 0x48, 0x9f, 0x2d, 0x3f, - 0x39, 0x2e, 0xdd, 0x71, 0xde, 0x1b, 0x54, 0xee, - 0x7d, 0x94, 0x8f, 0x27, 0x23, 0xe9, 0x74, 0x92, - 0x14, 0x93, 0x84, 0x65, 0xc9, 0x22, 0x7c, 0xa8, - 0x1b, 0x72, 0x73, 0xb1, 0x23, 0xa0, 0x6b, 0xcc, - 0xb5, 0x22, 0x06, 0x15, 0xe5, 0x96, 0x03, 0x4a, - 0x52, 0x8d, 0x1d, 0xbf, 0x3e, 0x82, 0x45, 0x9c, - 0x75, 0x9e, 0xa9, 0x3a, 0x97, 0xb6, 0x5d, 0xc4, - 0x75, 0x67, 0xa1, 0xf3, 0x0f, 0x7a, 0xfd, 0x71, - 0x58, 0x04, 0xf9, 0xa7, 0xc2, 0x56, 0x74, 0x04, - 0x74, 0x68, 0x6d, 0x8a, 0xf6, 0x6c, 0x5d, 0xd8, - 0xb5, 0xed, 0x70, 0x23, 0x32, 0x4d, 0x75, 0x92, - 0x88, 0x7b, 0x39, 0x37, 0x02, 0x4b, 0xb2, 0x1c, - 0x1f, 0x7e, 0x5b, 0x1b, 0x10, 0xfc, 0x17, 0x21, - 0x66, 0x62, 0x63, 0xc2, 0xcd, 0x16, 0x96, 0x3e -}; - -static const struct blockcipher_test_data -triple_des192cbc_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, - 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des192cbc, - .len = 512 - } -}; - -static const struct blockcipher_test_data -triple_des192cbc_sha1_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, - 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des192cbc, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1, - .digest = { - .data = { - 0x53, 0x27, 0xC0, 0xE6, 0xD6, 0x1B, 0xD6, 0x45, - 0x94, 0x2D, 0xCE, 0x8B, 0x29, 0xA3, 0x52, 0x14, - 0xC1, 0x6B, 0x87, 0x99 - }, - .len = 20 - } -}; - -static const struct blockcipher_test_data -triple_des192cbc_hmac_sha1_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, - 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des192cbc, - .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 = { - 0xBA, 0xAC, 0x74, 0x19, 0x43, 0xB0, 0x72, 0xB8, - 0x08, 0xF5, 0x24, 0xC4, 0x09, 0xBD, 0x48, 0xC1, - 0x3C, 0x50, 0x1C, 0xDD - }, - .len = 20 - } -}; - -static const struct blockcipher_test_data -des_cbc_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_DES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2 - }, - .len = 8 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des, - .len = 512 - }, - .ciphertext = { - .data = ciphertext512_des, - .len = 512 - }, -}; - -static const struct blockcipher_test_case des_cipheronly_test_cases[] = { - { - .test_descr = "DES-CBC Encryption", - .test_data = &des_cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "DES-CBC Decryption", - .test_data = &des_cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - -}; - -static const struct blockcipher_test_case triple_des_chain_test_cases[] = { - { - .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest", - .test_data = &triple_des128cbc_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify", - .test_data = &triple_des128cbc_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CBC SHA1 Encryption Digest", - .test_data = &triple_des128cbc_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "3DES-128-CBC SHA1 Decryption Digest Verify", - .test_data = &triple_des128cbc_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "3DES-192-CBC HMAC-SHA1 Encryption Digest", - .test_data = &triple_des192cbc_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-192-CBC HMAC-SHA1 Decryption Digest Verify", - .test_data = &triple_des192cbc_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-192-CBC SHA1 Encryption Digest", - .test_data = &triple_des192cbc_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "3DES-192-CBC SHA1 Decryption Digest Verify", - .test_data = &triple_des192cbc_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "3DES-128-CTR HMAC-SHA1 Encryption Digest", - .test_data = &triple_des128ctr_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CTR HMAC-SHA1 Decryption Digest Verify", - .test_data = &triple_des128ctr_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CTR SHA1 Encryption Digest", - .test_data = &triple_des128ctr_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "3DES-128-CTR SHA1 Decryption Digest Verify", - .test_data = &triple_des128ctr_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "3DES-192-CTR HMAC-SHA1 Encryption Digest", - .test_data = &triple_des192ctr_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-192-CTR HMAC-SHA1 Decryption Digest Verify", - .test_data = &triple_des192ctr_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-192-CTR SHA1 Encryption Digest", - .test_data = &triple_des192ctr_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "3DES-192-CTR SHA1 Decryption Digest Verify", - .test_data = &triple_des192ctr_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest OOP", - .test_data = &triple_des128cbc_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest" - " Verify OOP", - .test_data = &triple_des128cbc_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest" - " Sessionless", - .test_data = &triple_des128cbc_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = - "3DES-128-CBC HMAC-SHA1 Decryption Digest" - " Verify Sessionless", - .test_data = &triple_des128cbc_hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, -}; - -static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { - { - .test_descr = "3DES-128-CBC Encryption", - .test_data = &triple_des128cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CBC Decryption", - .test_data = &triple_des128cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-192-CBC Encryption", - .test_data = &triple_des192cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-192-CBC Decryption", - .test_data = &triple_des192cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CTR Encryption", - .test_data = &triple_des128ctr_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-128-CTR Decryption", - .test_data = &triple_des128ctr_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-192-CTR Encryption", - .test_data = &triple_des192ctr_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-192-CTR Decryption", - .test_data = &triple_des192ctr_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - } -}; - -#endif /* TEST_CRYPTODEV_DES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h deleted file mode 100644 index 5764edb118..0000000000 --- a/app/test/test_cryptodev_gcm_test_vectors.h +++ /dev/null @@ -1,3051 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015 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_GCM_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ - -#define GMAC_LARGE_PLAINTEXT_LENGTH 65344 -#define GCM_MAX_AAD_LENGTH 65536 -#define GCM_LARGE_AAD_LENGTH 65296 - -static uint8_t gcm_aad_zero_text[GCM_MAX_AAD_LENGTH] = { 0 }; - -static uint8_t gcm_aad_text[GCM_MAX_AAD_LENGTH] = { - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0xf1, 0xe2, 0xd3, 0xc4, 0xb5, 0xa6, 0x97, - 0x88, 0x79, 0x6a, 0x5b, 0x4c, 0x3d, 0x2e, 0x1f }; - - -struct gcm_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; - unsigned len; - } aad; - - struct { - uint8_t data[8096]; - unsigned len; - } plaintext; - - struct { - uint8_t data[8096]; - unsigned len; - } ciphertext; - - struct { - uint8_t data[16]; - unsigned len; - } auth_tag; -}; - -struct gmac_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; - unsigned len; - } aad; - - struct { - uint8_t *data; - unsigned len; - } plaintext; - - struct { - uint8_t data[16]; - unsigned len; - } gmac_tag; - -}; - -/** AES-128 Test Vectors */ -static const struct gcm_test_data gcm_test_case_1 = { - .key = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0x00 }, - .len = 0 - }, - .ciphertext = { - .data = { - 0x00 - }, - .len = 0 - }, - .auth_tag = { - .data = { - 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, - 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, - .len = 16 - } -}; - -/** AES-128 Test Vectors */ -static const struct gcm_test_data gcm_test_case_2 = { - .key = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .len = 16 - }, - .ciphertext = { - .data = { - 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, - 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, - .len = 16 - }, - .auth_tag = { - .data = { - 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, - 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, - .len = 16 - } -}; - -/** AES-128 Test Vectors */ -static const struct gcm_test_data gcm_test_case_3 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 - }, - .len = 64 - }, - .auth_tag = { - .data = { - 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, - 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, - .len = 16 - } -}; - -/** AES-128 Test Vectors */ -static const struct gcm_test_data gcm_test_case_4 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 - }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 8 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 - }, - .len = 60 - }, - .ciphertext = { - .data = { - 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 - }, - .len = 60 - }, - .auth_tag = { - .data = { - 0xA2, 0xA4, 0x35, 0x75, 0xDC, 0xB0, 0x57, 0x74, - 0x07, 0x02, 0x30, 0xC2, 0xE7, 0x52, 0x02, 0x00 - }, - .len = 16 - } - -}; - -/** AES-128 Test Vectors */ -static const struct gcm_test_data gcm_test_case_5 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 - }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_text, - .len = 8 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 - }, - .len = 60 - }, - .ciphertext = { - .data = { - 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 - }, - .len = 60 - }, - .auth_tag = { - .data = { - 0xC5, 0x2D, 0xFB, 0x54, 0xAF, 0xBB, 0x07, 0xA1, - 0x9A, 0xFF, 0xBE, 0xE0, 0x61, 0x4C, 0xE7, 0xA5 - }, - .len = 16 - } - -}; - -/** AES-128 Test Vectors */ -static const struct gcm_test_data gcm_test_case_6 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 - }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 - }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 12 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 - }, - .len = 60 - }, - .ciphertext = { - .data = { - 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 - }, - .len = 60 - }, - .auth_tag = { - .data = { - 0x74, 0xFC, 0xFA, 0x29, 0x3E, 0x60, 0xCC, 0x66, - 0x09, 0xD6, 0xFD, 0x00, 0xC8, 0x86, 0xD5, 0x42 - }, - .len = 16 - } -}; - -/** AES-128 Test Vectors */ -static const struct gcm_test_data gcm_test_case_7 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 - }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 - }, - .len = 12 - }, - .aad = { - .data = gcm_aad_text, - .len = 12 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 - }, - .len = 60 - }, - .ciphertext = { - .data = { - 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 - }, - .len = 60 - }, - .auth_tag = { - .data = { - 0xE9, 0xE4, 0xAB, 0x76, 0xB7, 0xFF, 0xEA, 0xDC, - 0x69, 0x79, 0x38, 0xA2, 0x0D, 0xCA, 0xF5, 0x92 - }, - .len = 16 - } -}; - -static const struct gcm_test_data gcm_test_case_8 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 - }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 - }, - .len = 12 - }, - .aad = { - .data = gcm_aad_text, - .len = 12 - }, - .plaintext = { - .data = { - 0xC5, 0x34, 0x2E, 0x83, 0xEB, 0x4C, 0x02, 0x03, - 0xF7, 0xB2, 0x57, 0x35, 0x26, 0x81, 0x63, 0xAE, - 0x1F, 0xCD, 0x2D, 0x02, 0x91, 0x5A, 0xDB, 0x3A, - 0xF1, 0x38, 0xD8, 0x75, 0x86, 0x20, 0xCC, 0x1E, - 0xE6, 0xDC, 0xFF, 0xB5, 0xEA, 0x0E, 0x18, 0x7A, - 0x86, 0x6C, 0xAB, 0x39, 0x2D, 0x90, 0xAC, 0x77, - 0x5D, 0xED, 0x65, 0xB3, 0x05, 0x29, 0xBB, 0x09, - 0xD0, 0x21, 0x74, 0x6A, 0x67, 0x1C, 0x95, 0x42, - 0x55, 0xAD, 0xC8, 0x91, 0x28, 0xFE, 0x16, 0x9A, - 0xE1, 0xCB, 0xCD, 0x68, 0x3B, 0xDF, 0x3E, 0x3A, - 0x34, 0xFE, 0x9B, 0xFB, 0xF5, 0x15, 0x2A, 0x29, - 0x18, 0x99, 0x24, 0xBF, 0xB6, 0x43, 0xDB, 0xD1, - 0x69, 0x26, 0x1E, 0x31, 0x2C, 0x8C, 0x3C, 0x6B, - 0x7F, 0x06, 0xA6, 0x03, 0xE2, 0x1A, 0x50, 0xFE, - 0x7C, 0x69, 0xE5, 0x5F, 0x35, 0x93, 0xE9, 0x20, - 0x14, 0xB1, 0xCA, 0x61, 0xE7, 0x9C, 0x89, 0x08, - 0xD6, 0xB1, 0xC2, 0x63, 0x1B, 0x86, 0x5E, 0xF1, - 0xF5, 0x23, 0x0E, 0x9B, 0xE5, 0xBD, 0x5D, 0x04, - 0xF7, 0xEF, 0x8E, 0x46, 0xB0, 0x11, 0x4F, 0x69, - 0x62, 0x35, 0x51, 0xB7, 0x24, 0xA2, 0x31, 0xD0, - 0x32, 0x4E, 0xB8, 0x44, 0xC7, 0x59, 0xDE, 0x25, - 0xEA, 0x2D, 0x00, 0x0E, 0xF1, 0x07, 0xBA, 0xBB, - 0x9A, 0xBC, 0x4F, 0x57, 0xB7, 0x13, 0x57, 0xEF, - 0xD9, 0xF6, 0x80, 0x69, 0xEA, 0xE8, 0x47, 0x9C, - 0x51, 0x71, 0xE6, 0x8F, 0x69, 0x29, 0xB4, 0x60, - 0xE8, 0x50, 0xE5, 0xD0, 0x9B, 0xD2, 0x62, 0x6F, - 0x09, 0x5C, 0xD1, 0x4B, 0x85, 0xE2, 0xFD, 0xD3, - 0xEB, 0x28, 0x55, 0x77, 0x97, 0xCA, 0xD6, 0xA8, - 0xDC, 0x35, 0x68, 0xF7, 0x6A, 0xCF, 0x48, 0x3F, - 0x49, 0x31, 0x00, 0x65, 0xB7, 0x31, 0x1A, 0x49, - 0x75, 0xDE, 0xCE, 0x7F, 0x18, 0xB5, 0x31, 0x9A, - 0x64, 0x6D, 0xE5, 0x49, 0x1D, 0x6D, 0xF2, 0x21, - 0x9F, 0xF5, 0xFF, 0x7C, 0x41, 0x30, 0x33, 0x06, - 0x7B, 0xA4, 0xD8, 0x99, 0xF6, 0xCC, 0xDF, 0xC4, - 0x3F, 0xF3, 0xCD, 0xE7, 0x74, 0xC4, 0x4A, 0x19, - 0x5C, 0xCA, 0x42, 0x31, 0xF1, 0x3B, 0x65, 0x1C, - 0x3D, 0x56, 0x08, 0xBE, 0x15, 0x37, 0x23, 0x50, - 0xD6, 0xA3, 0x57, 0x64, 0x25, 0xBE, 0xDA, 0xC2, - 0x4E, 0xF5, 0x1A, 0xAD, 0x6F, 0x43, 0x78, 0x21, - 0xF9, 0x36, 0x39, 0x1F, 0x5F, 0xF7, 0x1B, 0xA0, - 0xEE, 0x8B, 0x4F, 0x8A, 0x9D, 0xD8, 0xED, 0x37, - 0xCE, 0x0D, 0x70, 0xE0, 0x3F, 0xE7, 0x11, 0x30, - 0x17, 0x1D, 0x03, 0x5E, 0xA0, 0x3D, 0x3F, 0x9E, - 0xF5, 0xD3, 0x74, 0x2E, 0xC1, 0xD6, 0xFF, 0xF7, - 0x2E, 0xE7, 0x80, 0x88, 0xCF, 0x0E, 0x7F, 0x12, - 0x71, 0x62, 0xC7, 0xF1, 0xC4, 0x2B, 0x64, 0x5D, - 0x1C, 0x9A, 0xB4, 0xCB, 0xB8, 0x24, 0xB3, 0x0B, - 0x33, 0xF2, 0x8A, 0x8F, 0x76, 0xC8, 0x81, 0xDA, - 0x1A, 0x10, 0xB5, 0xA9, 0xCD, 0xDC, 0x1A, 0x02, - 0xC1, 0xAE, 0x4F, 0x02, 0x1B, 0x13, 0x96, 0x5A, - 0x2E, 0x03, 0xA2, 0x68, 0xB2, 0x29, 0xAC, 0x28, - 0xB8, 0xDC, 0xD5, 0x27, 0x55, 0xEC, 0x43, 0xDC, - 0xB7, 0x49, 0x1D, 0xE1, 0x30, 0x25, 0x81, 0xA6, - 0x90, 0x1F, 0x75, 0xBA, 0x19, 0x1E, 0xF7, 0xC5, - 0x77, 0x35, 0xEE, 0x68, 0x71, 0x22, 0xA0, 0xB4, - 0xCC, 0x99, 0x86, 0x1B, 0x1B, 0xC8, 0x27, 0xFC, - 0x6D, 0x8D, 0xE7, 0x8B, 0xC3, 0x40, 0x3D, 0xA8, - 0xCB, 0x9B, 0xC4, 0x12, 0x07, 0xDD, 0xA1, 0x92, - 0xE5, 0x80, 0x7A, 0xF4, 0xDB, 0x4C, 0xE6, 0xEE, - 0xF9, 0xD5, 0x1C, 0x20, 0x18, 0xD3, 0x8F, 0xDF, - 0x1C, 0xD3, 0x51, 0x4E, 0x0E, 0xED, 0x06, 0x61, - 0xF7, 0xBA, 0x81, 0x3A, 0x2F, 0xEA, 0xED, 0x70, - 0xA9, 0xD9, 0x54, 0x4D, 0xFC, 0x1D, 0x19, 0xEA, - 0xA6, 0x39, 0x8C, 0x6C, 0x78, 0xA8, 0x05, 0xEB, - 0xF2, 0xB5, 0xDE, 0x06, 0x9D, 0x8A, 0x78, 0x2A, - 0xF5, 0x50, 0xA4, 0xBD, 0x9B, 0xDA, 0xCA, 0x66, - 0xC0, 0x23, 0xAB, 0xE8, 0x95, 0x7E, 0xC9, 0xD2, - 0x6F, 0x09, 0xF2, 0x9A, 0x17, 0x89, 0xDA, 0x47, - 0x65, 0x8C, 0x20, 0xFA, 0x4E, 0x86, 0x18, 0xEB, - 0x7C, 0x08, 0xEC, 0x8A, 0x05, 0x54, 0x96, 0xD2, - 0x7A, 0x8A, 0x81, 0x58, 0x75, 0x8C, 0x7B, 0x02, - 0xEE, 0x1F, 0x51, 0x88, 0xD0, 0xD1, 0x90, 0x99, - 0x0C, 0xAE, 0x51, 0x2E, 0x54, 0x3E, 0xB1, 0x7D, - 0xBC, 0xE8, 0x54, 0x93, 0x6D, 0x10, 0x3C, 0xC6, - 0x71, 0xF6, 0xF5, 0x0B, 0x07, 0x0A, 0x6E, 0x59, - 0x20, 0x45, 0x21, 0x7D, 0x37, 0x64, 0x92, 0x09, - 0xA7, 0xE2, 0x34, 0x6F, 0xFC, 0xCC, 0x66, 0x0E, - 0x88, 0x1B, 0x19, 0x86, 0x11, 0xD7, 0x81, 0x25, - 0xF1, 0x8A, 0x03, 0xB7, 0x7A, 0xF0, 0x98, 0x4A, - 0x5C, 0xA1, 0x6D, 0x85, 0xA4, 0x8C, 0x4B, 0x65, - 0x9F, 0x72, 0x64, 0x14, 0xBA, 0x74, 0xEE, 0xA3, - 0x88, 0xFE, 0x1B, 0xCF, 0x11, 0x4F, 0xD1, 0xAC, - 0xFA, 0x14, 0xC3, 0xA7, 0xDD, 0x06, 0x85, 0x4E, - 0x64, 0x06, 0x92, 0x9C, 0xDF, 0x06, 0x09, 0xF1, - 0x4D, 0xE8, 0xF8, 0x2F, 0x69, 0xB6, 0x8A, 0xAF, - 0x25, 0x21, 0xB5, 0x48, 0x59, 0xF8, 0x9D, 0x60, - 0xAE, 0x42, 0x11, 0x7A, 0x68, 0x4D, 0x7E, 0x76, - 0xB0, 0xD2, 0xE3, 0xD9, 0x24, 0x16, 0x20, 0x0A, - 0xEB, 0xE0, 0x68, 0xCB, 0xBC, 0xAB, 0x67, 0xE4, - 0xF3, 0x25, 0x1F, 0xD3, 0x85, 0xA7, 0x1D, 0x7E, - 0x3C, 0x63, 0xCB, 0xC2, 0x50, 0x90, 0x0F, 0x4B, - 0x6E, 0x68, 0x06, 0x84, 0x65, 0xF7, 0xD0, 0xD4, - 0x12, 0xED, 0xFA, 0xC9, 0x40, 0xE2, 0xC0, 0xC9, - 0x46, 0x22, 0x47, 0x5E, 0x6D, 0xC1, 0x63, 0xDB, - 0x51, 0x98, 0xDA, 0x1A, 0xC4, 0xB9, 0xED, 0xE9, - 0x09, 0xB9, 0xCF, 0x91, 0x04, 0x1C, 0x63, 0xD8, - 0xC5, 0xA5, 0xAE, 0x53, 0x7B, 0xA1, 0x29, 0x83, - 0x37, 0xFB, 0xBF, 0x96, 0xBB, 0x24, 0x3D, 0x77, - 0x8C, 0x0F, 0xB3, 0x4B, 0x66, 0x9C, 0x54, 0xBB, - 0xF6, 0xDD, 0xD1, 0xB4, 0xD2, 0xF6, 0xAA, 0xED, - 0x18, 0x56, 0x63, 0x3E, 0x0B, 0xCA, 0xAB, 0x70, - 0xBB, 0x63, 0xEA, 0xB1, 0x00, 0x65, 0x90, 0x18, - 0xB8, 0x63, 0xA2, 0xF2, 0xB6, 0x1E, 0x61, 0x7B, - 0xD5, 0x01, 0xD9, 0x4D, 0xC9, 0x9D, 0x99, 0xC1, - 0x57, 0x9D, 0x6F, 0xAE, 0x64, 0xE4, 0x0C, 0x7E, - 0xFA, 0x15, 0x5E, 0xB6, 0x43, 0xB8, 0x8B, 0x89, - 0x87, 0xCD, 0x4F, 0xAD, 0x30, 0x1E, 0xA5, 0x03, - 0x7A, 0xC2, 0x10, 0x42, 0x14, 0x88, 0xD6, 0x7A, - 0x6D, 0x56, 0x52, 0x2E, 0x8D, 0x1B, 0x5D, 0x36, - 0x27, 0xA0, 0x21, 0x4B, 0x64, 0xF0, 0xC5, 0x41, - 0xAD, 0x05, 0x4A, 0x24, 0xE4, 0x70, 0x88, 0x63, - 0x12, 0xD0, 0xBC, 0x05, 0x38, 0xD9, 0x41, 0x68, - 0x9F, 0x16, 0x9A, 0x54, 0x09, 0x21, 0x64, 0x36, - 0x63, 0x97, 0x3A, 0xB5, 0xE0, 0x25, 0x43, 0x8A, - 0x6A, 0x59, 0x97, 0xC1, 0x31, 0xA5, 0x66, 0xD2, - 0xF0, 0x1C, 0xDF, 0x97, 0x51, 0xD0, 0x61, 0xBA, - 0x55, 0x5F, 0xD7, 0x0D, 0xD4, 0x75, 0x8E, 0x79, - 0x04, 0x75, 0x00, 0xB9, 0xC0, 0x7A, 0x66, 0x05, - 0x9F, 0x2B, 0x44, 0x42, 0x75, 0x0F, 0xD5, 0x15, - 0xD6, 0x16, 0x8F, 0x6C, 0x6E, 0xD4, 0x37, 0xCF, - 0xB4, 0xDA, 0x93, 0x00, 0x11, 0xFB, 0xBE, 0xEE, - 0x3B, 0x6D, 0x1D, 0xBA, 0x33, 0xD1, 0x52, 0x8B, - 0x16, 0x39, 0x42, 0x27, 0xE6, 0x56, 0x4C, 0x41, - 0x91, 0xB0, 0x98, 0xAE, 0x9B, 0x2D, 0x9B, 0x23, - 0x80, 0x4C, 0xEA, 0x98, 0x57, 0x95, 0x28, 0x94, - 0x43, 0xD3, 0x88, 0x12, 0xDF, 0x89, 0x5A, 0x7B, - 0xC5, 0xCB, 0x36, 0x54, 0x65, 0x74, 0xB8, 0x4E, - 0xE2, 0x4D, 0x01, 0xD5, 0x9C, 0x82, 0xB9, 0x1A, - 0x09, 0xD2, 0xCE, 0x04, 0x36, 0xD8, 0x41, 0xAC, - 0x4C, 0xAD, 0xC6, 0x52, 0x91, 0x1A, 0x06, 0x6D, - 0xFC, 0xAB, 0x29, 0x93, 0x87, 0x88, 0xB9, 0x8C, - 0xFA, 0x57, 0x2B, 0x05, 0x03, 0xD0, 0x18, 0xED, - 0x7A, 0x7B, 0x81, 0x6A, 0x97, 0x65, 0x5B, 0x90, - 0xDE, 0xA9, 0xFC, 0x8F, 0xFC, 0xBB, 0x98, 0xD8, - 0xFA, 0x32, 0x3F, 0x3F, 0x7F, 0x74, 0x65, 0x38, - 0xC4, 0x28, 0xEC, 0x27, 0x1F, 0x28, 0x01, 0xB1, - 0xAF, 0x2B, 0x8A, 0x05, 0x38, 0x7B, 0x77, 0xC9, - 0x61, 0x77, 0x34, 0x2C, 0x22, 0xE5, 0xEB, 0xDC, - 0x9D, 0x18, 0x6E, 0x23, 0x25, 0x52, 0x69, 0xB7, - 0x05, 0xDB, 0x66, 0x5D, 0xEA, 0x76, 0x83, 0x82, - 0x97, 0x39, 0xAF, 0xC0, 0x50, 0x81, 0x18, 0x0D, - 0x22, 0xFA, 0xB7, 0x44, 0x5C, 0x3F, 0x69, 0xF3, - 0xAC, 0xC5, 0x63, 0x9F, 0xD8, 0x72, 0x7E, 0x9A, - 0xC2, 0xEB, 0x79, 0xD0, 0x74, 0x65, 0xE8, 0xCA, - 0xFD, 0xA8, 0x7D, 0x23, 0x07, 0x99, 0x3E, 0xAF, - 0xDB, 0x67, 0x10, 0xC0, 0xE5, 0x61, 0x77, 0xC6, - 0x8D, 0xC4, 0x0E, 0xAA, 0x55, 0xE3, 0xC0, 0xC7, - 0xA5, 0x36, 0x28, 0x61, 0xDB, 0x16, 0x96, 0x5E, - 0x01, 0x47, 0x82, 0xE3, 0xEB, 0x20, 0x3F, 0x10, - 0xFA, 0x5A, 0xBC, 0xD3, 0xF9, 0xCE, 0x04, 0x87, - 0x51, 0x07, 0xF9, 0xD0, 0xE7, 0x6D, 0xCB, 0xCC, - 0xC4, 0x15, 0x00, 0xE2, 0xDC, 0x8E, 0x7B, 0x5C, - 0x9A, 0xF2, 0x78, 0x70, 0x4D, 0xA1, 0xAA, 0xB5, - 0x13, 0xCC, 0x71, 0x66, 0x5A, 0x79, 0x13, 0x3B, - 0x12, 0xCD, 0x40, 0x30, 0x5A, 0x49, 0xD4, 0x20, - 0xED, 0xCF, 0x4A, 0x75, 0xE6, 0xD5, 0xDD, 0x0F, - 0xD4, 0xBE, 0x98, 0x9F, 0xD7, 0x1F, 0xC0, 0x02, - 0x31, 0xFA, 0x67, 0x37, 0x25, 0x86, 0x56, 0x85, - 0x2B, 0xA2, 0x57, 0xCD, 0x8E, 0x74, 0xE7, 0x69, - 0xEE, 0x33, 0x5A, 0x3F, 0xCD, 0x1E, 0xE3, 0xB9, - 0xAA, 0x52, 0xF5, 0x22, 0x4E, 0xE3, 0xFF, 0xC8, - 0xE3, 0x13, 0xA3, 0x9A, 0x63, 0x23, 0xC3, 0xD7, - 0xE5, 0x88, 0x3E, 0x0A, 0x4B, 0xA5, 0x01, 0xE6, - 0x13, 0xCF, 0xED, 0xEE, 0x2A, 0x58, 0x09, 0x3F, - 0x2F, 0x28, 0xE7, 0xC4, 0x6B, 0xEC, 0x49, 0x51, - 0x79, 0x8F, 0xD5, 0x19, 0x5D, 0xA5, 0x10, 0xCE, - 0x8E, 0xF6, 0x26, 0x78, 0x7A, 0xA8, 0x11, 0x52, - 0x5F, 0x97, 0x14, 0xC9, 0x29, 0x87, 0xB8, 0xA0, - 0x2D, 0xE6, 0xA7, 0x2A, 0xD4, 0xFF, 0xEB, 0xBA, - 0xFD, 0x58, 0x39, 0x33, 0xB1, 0xCE, 0x0E, 0x78, - 0x67, 0x1E, 0xA1, 0x92, 0x77, 0x63, 0xF8, 0xC0, - 0x02, 0x49, 0x73, 0xC0, 0xA1, 0x26, 0x83, 0x04, - 0x9A, 0x5D, 0x85, 0x68, 0x2A, 0x2F, 0xCB, 0x88, - 0x8D, 0x14, 0xB1, 0x33, 0xFA, 0xFB, 0xE9, 0x05, - 0xBE, 0x24, 0x1A, 0x6B, 0x29, 0x2B, 0x3F, 0x52, - 0x8F, 0xFB, 0xE6, 0x02, 0x77, 0x50, 0x71, 0xDB, - 0xE9, 0x92, 0x3F, 0xE1, 0x20, 0x62, 0x80, 0xAE, - 0xA4, 0x98, 0xC6, 0xCD, 0xE0, 0xB1, 0xC3, 0x33, - 0xB1, 0xC5, 0x91, 0x3C, 0x19, 0x34, 0xA8, 0xD9, - 0xB3, 0x25, 0x69, 0xE3, 0x9C, 0x5F, 0x78, 0xD0, - 0x83, 0x1F, 0xAB, 0x85, 0x13, 0x56, 0x69, 0xB5, - 0x06, 0x47, 0x62, 0x37, 0x27, 0x15, 0x14, 0x05, - 0x4A, 0xF4, 0x6A, 0x68, 0x2A, 0x6A, 0xC3, 0x5A, - 0xDF, 0xB5, 0xAE, 0x2F, 0x8D, 0x8F, 0x21, 0xDB, - 0x33, 0x00, 0x9B, 0xD4, 0xC4, 0x08, 0x3B, 0x81, - 0x63, 0x4C, 0xB0, 0x39, 0x4C, 0x0A, 0xD5, 0x71, - 0x3E, 0x5A, 0x50, 0x58, 0x9C, 0x07, 0x89, 0x79, - 0x79, 0x2F, 0x0B, 0xD9, 0x50, 0xBC, 0xCF, 0x46, - 0x7A, 0x68, 0x5C, 0xBF, 0x1E, 0x49, 0x77, 0x92, - 0x85, 0x11, 0x39, 0xA6, 0x2F, 0xDA, 0x7B, 0xFA, - 0x72, 0x87, 0x06, 0xCD, 0x84, 0x41, 0x20, 0x1B, - 0x66, 0x3F, 0x42, 0x0C, 0x9E, 0x19, 0xD3, 0x18, - 0x57, 0xA0, 0xEE, 0x16, 0x3A, 0xC7, 0xF9, 0xD3, - 0x8B, 0xC9, 0x24, 0x70, 0x70, 0x51, 0x7C, 0x06, - 0x68, 0xD3, 0x29, 0xC9, 0x85, 0x9A, 0x1C, 0xE6, - 0x8C, 0x17, 0xF4, 0x88, 0xDF, 0xEA, 0xFF, 0x44, - 0x8D, 0x54, 0xBE, 0x22, 0x07, 0xA5, 0x7C, 0x0C, - 0xF4, 0x8D, 0xB1, 0x0C, 0x07, 0xED, 0xBD, 0x28, - 0x19, 0xDA, 0x07, 0x71, 0xA8, 0xA1, 0xE0, 0xDD, - 0xEE, 0x08, 0x18, 0xA5, 0xBD, 0xDD, 0x32, 0x0B, - 0x70, 0x1C, 0xD9, 0xEE, 0x19, 0xC2, 0xAE, 0x5C, - 0xE3, 0x02, 0x74, 0x70, 0x96, 0x61, 0xB1, 0x73, - 0x3B, 0xD6, 0x74, 0xC0, 0x82, 0xA9, 0x1F, 0xE0, - 0xF1, 0x22, 0x50, 0xF3, 0x9F, 0xE5, 0x13, 0x92, - 0xFC, 0x0A, 0x1A, 0x3C, 0xB4, 0x46, 0xFB, 0x81, - 0x00, 0x84, 0xA4, 0x5E, 0x6B, 0x8C, 0x25, 0x6E, - 0xD7, 0xB7, 0x3B, 0x01, 0x65, 0xFB, 0x0B, 0x46, - 0x67, 0x27, 0x2D, 0x51, 0xAD, 0xB5, 0xE0, 0x85, - 0xC2, 0x95, 0xA3, 0xE3, 0x68, 0x4D, 0x9E, 0x8C, - 0x11, 0x53, 0xF0, 0xB2, 0x85, 0xFA, 0x52, 0x4E, - 0xEC, 0xF9, 0xB7, 0x3C, 0x89, 0x2C, 0x4D, 0x32, - 0x9A, 0xCB, 0x17, 0xF3, 0x16, 0xBF, 0x44, 0x40, - 0xE9, 0x5E, 0x51, 0x8C, 0x1E, 0x52, 0x0A, 0xC2, - 0xCD, 0xA5, 0xAA, 0x03, 0x27, 0xB0, 0x8F, 0x64, - 0xDB, 0xD7, 0x03, 0x01, 0x8A, 0x24, 0x28, 0x7E, - 0x53, 0x6F, 0x24, 0xFD, 0xAA, 0xE3, 0x78, 0xB6, - 0xA5, 0x5D, 0x5A, 0x67, 0x20, 0xE2, 0xBE, 0x3A, - 0x2B, 0xE7, 0x86, 0x11, 0xDD, 0x96, 0xCB, 0x09, - 0x65, 0xA0, 0x36, 0xF9, 0xB0, 0x20, 0x21, 0x8E, - 0xDB, 0xC0, 0x73, 0xC7, 0x79, 0xD8, 0xDA, 0xC2, - 0x66, 0x13, 0x64, 0x34, 0x0C, 0xE1, 0x22, 0x24, - 0x61, 0x67, 0x08, 0x39, 0x97, 0x3F, 0x33, 0x96, - 0xF2, 0x44, 0x18, 0x75, 0xBB, 0xF5, 0x6A, 0x5C, - 0x2C, 0xAE, 0x2A, 0x79, 0x3D, 0x47, 0x19, 0x53, - 0x50, 0x6C, 0x9F, 0xB3, 0x82, 0x55, 0x09, 0x78, - 0x7B, 0xAD, 0xBC, 0x05, 0x6F, 0xC8, 0x3D, 0xB6, - 0x7B, 0x30, 0xE6, 0xBB, 0x8B, 0xD0, 0x2F, 0xA6, - 0x15, 0xCC, 0x77, 0x8C, 0x21, 0xBA, 0x03, 0xED, - 0x56, 0x85, 0x82, 0x4F, 0x97, 0x8C, 0x59, 0x4F, - 0x53, 0x5A, 0xD2, 0x70, 0xD9, 0x07, 0xB3, 0xBD, - 0x1D, 0x3E, 0x97, 0xD4, 0x7D, 0x93, 0x35, 0xA4, - 0x82, 0x6E, 0xEA, 0x4B, 0xC8, 0x6C, 0xF5, 0xE6, - 0xEB, 0xAF, 0x11, 0xB0, 0xB4, 0x71, 0x8F, 0x7B, - 0xC4, 0x8C, 0xE2, 0x66, 0x51, 0x31, 0x99, 0x01, - 0x5B, 0xE7, 0x48, 0xF8, 0x4C, 0xE3, 0x9A, 0x77, - 0xF1, 0xC6, 0x09, 0xDE, 0x76, 0xD4, 0xE3, 0x5C, - 0xDF, 0xA3, 0xEC, 0x3C, 0x86, 0x7C, 0xA5, 0x3F, - 0x8D, 0x2A, 0xF3, 0x0B, 0x54, 0xB7, 0x54, 0xA2, - 0xC1, 0x69, 0xC0, 0x6F, 0x1C, 0x1C, 0x76, 0xD8, - 0x9F, 0x7A, 0x32, 0xB0, 0xA1, 0xA6, 0x9B, 0xB7, - 0x21, 0x56, 0x28, 0x2D, 0xB6, 0x97, 0x03, 0x5E, - 0x65, 0xE3, 0x74, 0x9A, 0x96, 0x7A, 0xF9, 0xF5, - 0xDD, 0x85, 0xCA, 0x4C, 0xB4, 0x03, 0x6A, 0xCD, - 0xB6, 0x01, 0xDC, 0x8B, 0xD8, 0x73, 0x8F, 0x4D, - 0x7F, 0xD6, 0x71, 0xEC, 0xD7, 0xC6, 0x0B, 0x5F, - 0x09, 0x21, 0xB2, 0x78, 0xA8, 0xAF, 0xAD, 0x2C, - 0xD4, 0x93, 0x9F, 0x71, 0xF7, 0x05, 0x89, 0x42, - 0xC9, 0x15, 0x6F, 0x2D, 0xE0, 0xBA, 0xC3, 0xD6, - 0xBF, 0xAC, 0xF8, 0x24, 0x58, 0x79, 0xA9, 0xC4, - 0xB4, 0x49, 0x3E, 0x0B, 0x9E, 0x5E, 0xE4, 0xA6, - 0x8B, 0xE8, 0xDE, 0xFB, 0x4A, 0xF1, 0x69, 0x9D, - 0x4F, 0x77, 0x83, 0x78, 0x55, 0x19, 0x42, 0x45, - 0xBF, 0xBD, 0xBD, 0x12, 0x0F, 0xEF, 0x8D, 0x04, - 0xD8, 0x5C, 0xF2, 0xC9, 0xF1, 0xA6, 0xE0, 0x3E, - 0x22, 0xA8, 0xA2, 0x5E, 0x66, 0xE9, 0xAB, 0xB4, - 0x71, 0xBE, 0x4B, 0x3F, 0xBE, 0xC4, 0xBA, 0x4A - }, - .len = 2048 - }, - .ciphertext = { - .data = { - 0x5E, 0x86, 0x02, 0x64, 0x32, 0xBF, 0x70, 0xC2, - 0x19, 0x99, 0x7F, 0x47, 0x0D, 0xA4, 0x91, 0xA8, - 0x7A, 0xC0, 0xA5, 0x7E, 0xA8, 0x6C, 0x88, 0x00, - 0xEA, 0xB5, 0x96, 0x6B, 0x25, 0xBD, 0xE7, 0x42, - 0xDB, 0x35, 0xE7, 0x92, 0x2B, 0x00, 0x82, 0x35, - 0xD4, 0x2C, 0xCF, 0x47, 0xC8, 0xB2, 0xB3, 0x57, - 0xF7, 0x24, 0x83, 0x7F, 0xC5, 0x2E, 0xF1, 0xC9, - 0x57, 0x1A, 0xEF, 0xC2, 0x3A, 0x8C, 0x1E, 0x92, - 0x88, 0x05, 0xAF, 0x55, 0xE6, 0x0C, 0xA7, 0x6B, - 0x59, 0x62, 0x32, 0x21, 0xF1, 0xFF, 0xB5, 0x5B, - 0x22, 0x26, 0x6F, 0x0A, 0x36, 0xDC, 0x0D, 0x16, - 0x3B, 0x4E, 0x7C, 0xA3, 0x75, 0x30, 0x3F, 0xB0, - 0x99, 0x38, 0x42, 0x8E, 0x89, 0xA3, 0x7C, 0x99, - 0x2F, 0x0A, 0xA1, 0xC7, 0xFD, 0x2D, 0x21, 0x8F, - 0xBD, 0xD4, 0x11, 0xEA, 0x55, 0xF5, 0x6A, 0x50, - 0x90, 0x3B, 0x60, 0x57, 0xE1, 0x86, 0x1E, 0x50, - 0x28, 0x67, 0x3F, 0xD2, 0xF3, 0xBD, 0xFA, 0xEE, - 0xD6, 0x5A, 0x38, 0x30, 0xA3, 0xDD, 0x78, 0xC4, - 0x37, 0x59, 0x52, 0xC0, 0x92, 0x54, 0xC7, 0x53, - 0xF0, 0xE6, 0xA9, 0x63, 0x1F, 0x9B, 0x97, 0xFB, - 0x40, 0x23, 0xFE, 0x52, 0x6A, 0xF0, 0x3A, 0x94, - 0xEB, 0x6A, 0x9E, 0x8F, 0xC5, 0x05, 0x9C, 0x04, - 0x1B, 0x00, 0x34, 0x96, 0x12, 0xDA, 0x60, 0xC6, - 0xAA, 0x1A, 0x3E, 0xEB, 0x70, 0x17, 0x10, 0xBC, - 0xF5, 0xC2, 0xE2, 0x71, 0xF3, 0xB8, 0x1D, 0xCE, - 0x47, 0x94, 0x21, 0x71, 0x34, 0x8C, 0xCC, 0xDD, - 0x27, 0xCE, 0x6F, 0x68, 0xFF, 0x91, 0x4E, 0xC4, - 0xA0, 0xCA, 0xB0, 0x4F, 0x17, 0x53, 0x73, 0x92, - 0x6C, 0xA8, 0x16, 0x06, 0xE3, 0xD9, 0x92, 0x99, - 0xBE, 0xB0, 0x7D, 0x56, 0xF2, 0x72, 0x30, 0xDA, - 0xC4, 0x4E, 0xF4, 0xA6, 0x8F, 0xD2, 0xC7, 0x8A, - 0xA2, 0xFC, 0xF5, 0x63, 0x17, 0x48, 0x56, 0x4D, - 0xBE, 0x94, 0xFE, 0xF5, 0xB1, 0xA9, 0x96, 0xAB, - 0x3F, 0x2D, 0xD4, 0x15, 0xEE, 0x4F, 0xFA, 0x2C, - 0xBE, 0x91, 0xB7, 0xBC, 0x18, 0xC8, 0xDB, 0x02, - 0x20, 0x29, 0xF1, 0xC1, 0x88, 0x8C, 0x8D, 0xD1, - 0xB3, 0x4E, 0x93, 0x96, 0xDD, 0x22, 0xAB, 0x55, - 0xB5, 0x9F, 0x8B, 0x20, 0xAE, 0xC6, 0x0E, 0x26, - 0xC6, 0xFE, 0x2D, 0x5F, 0x95, 0x89, 0x06, 0x15, - 0x3D, 0x88, 0x16, 0xEC, 0x9B, 0x4A, 0x1B, 0x5D, - 0x2E, 0xB2, 0x13, 0x56, 0x9F, 0x33, 0xB3, 0x45, - 0xBF, 0x5F, 0x25, 0x7E, 0x75, 0x22, 0xD2, 0xE6, - 0x9F, 0xAC, 0x2D, 0xFD, 0x99, 0xC2, 0x9B, 0xFC, - 0xD7, 0x7A, 0x9B, 0x05, 0x30, 0x0F, 0xB7, 0x4A, - 0xFE, 0x24, 0xDD, 0x39, 0x9B, 0xBB, 0x2F, 0xDD, - 0xF9, 0xFB, 0xCA, 0x6C, 0x87, 0xBA, 0x73, 0xD4, - 0x85, 0x7B, 0xB2, 0x6F, 0x5C, 0xD8, 0xFB, 0xE9, - 0x41, 0x24, 0x3A, 0x3B, 0x4F, 0x91, 0x77, 0xA2, - 0x35, 0x78, 0xE5, 0x4C, 0xFE, 0x8B, 0x04, 0x03, - 0xD3, 0x84, 0xA9, 0x1C, 0xA7, 0x7C, 0x45, 0x13, - 0x7D, 0xC5, 0x0A, 0x2F, 0x02, 0xF8, 0x56, 0xD5, - 0x5F, 0x35, 0xED, 0x06, 0xBF, 0x67, 0xBA, 0x51, - 0x02, 0x95, 0x36, 0xF2, 0x9A, 0xBA, 0x9D, 0xF6, - 0xD6, 0x77, 0x50, 0xC9, 0xFC, 0x1E, 0x32, 0xB5, - 0x2F, 0xEA, 0x3C, 0x76, 0xB4, 0xE1, 0xCC, 0x42, - 0xEB, 0x71, 0x79, 0xD3, 0x7D, 0xB7, 0xC0, 0x88, - 0x25, 0x81, 0xE8, 0xC0, 0xB8, 0x38, 0x7E, 0x7B, - 0xFD, 0x18, 0xAB, 0x08, 0xB2, 0x71, 0xA5, 0xAD, - 0xA7, 0xBE, 0x48, 0x5F, 0x86, 0xE2, 0x41, 0x3D, - 0x7C, 0x37, 0x7A, 0xAB, 0xDB, 0xE0, 0x3B, 0x3D, - 0xB6, 0xE8, 0x23, 0x7C, 0xF1, 0x8F, 0xBA, 0xB7, - 0xE9, 0x78, 0x0B, 0xCA, 0x67, 0xA8, 0x10, 0x36, - 0xEB, 0x72, 0xED, 0xDD, 0xF0, 0x5C, 0x74, 0x8E, - 0xE5, 0x2A, 0xAE, 0x6E, 0xC4, 0xF1, 0xFC, 0xD8, - 0xEE, 0x56, 0x07, 0x88, 0x02, 0xDC, 0x9D, 0xB7, - 0xF9, 0x13, 0xE1, 0xE1, 0x9D, 0x89, 0x26, 0x0B, - 0x23, 0x74, 0x4A, 0x43, 0xAA, 0xA0, 0xA8, 0x97, - 0x85, 0x15, 0x58, 0xAB, 0x2B, 0xB5, 0xDA, 0x1A, - 0xBA, 0x29, 0x62, 0xCF, 0xDD, 0xA3, 0xBA, 0x9D, - 0x7D, 0x83, 0xA5, 0x18, 0xD4, 0x03, 0x0F, 0x61, - 0x9F, 0xB1, 0x7E, 0xEC, 0xD2, 0x6E, 0xAF, 0xCF, - 0x1E, 0xC1, 0x88, 0x97, 0x99, 0xD6, 0xBF, 0x47, - 0xB9, 0x0A, 0x69, 0x11, 0x3A, 0x55, 0x8B, 0x1D, - 0x2D, 0xFF, 0x78, 0xC8, 0xDE, 0x82, 0x29, 0xD6, - 0x08, 0x3C, 0xC4, 0xCB, 0x2F, 0x01, 0xD0, 0xE8, - 0xB1, 0x75, 0x5E, 0x23, 0xE0, 0x37, 0x7C, 0x1C, - 0xB6, 0xD9, 0x47, 0xDE, 0x23, 0x87, 0xD3, 0x68, - 0x47, 0x46, 0x78, 0xF3, 0xBF, 0x54, 0xA3, 0xB9, - 0x54, 0xD5, 0xC5, 0x0A, 0x7C, 0x92, 0x2A, 0xC2, - 0x14, 0x76, 0xA6, 0x5C, 0x6D, 0x0B, 0x94, 0x56, - 0x00, 0x6B, 0x5C, 0x27, 0xDE, 0x77, 0x9B, 0xF1, - 0xB1, 0x8C, 0xA7, 0x49, 0x77, 0xFC, 0x4E, 0x29, - 0x23, 0x8F, 0x2F, 0xF7, 0x83, 0x8D, 0x36, 0xD9, - 0xAB, 0x0E, 0x78, 0xF5, 0x90, 0x05, 0xB9, 0x79, - 0x70, 0x88, 0x59, 0x6F, 0xE2, 0xC5, 0xD7, 0x80, - 0x95, 0x04, 0x29, 0xE0, 0xFA, 0x37, 0xE8, 0x8B, - 0xC5, 0x21, 0x51, 0x1A, 0x62, 0xCE, 0x93, 0xAF, - 0x1A, 0xFE, 0xC3, 0x6F, 0x86, 0x94, 0x5E, 0x13, - 0xA6, 0x9A, 0x26, 0xF0, 0xB5, 0x7C, 0x41, 0x9A, - 0x80, 0xB8, 0x84, 0x5A, 0x55, 0xA9, 0xB0, 0x6A, - 0xFA, 0xEB, 0x46, 0x32, 0x0B, 0xE2, 0x9C, 0x65, - 0x86, 0x11, 0x39, 0x7E, 0xAF, 0x93, 0x19, 0x09, - 0x70, 0x40, 0x80, 0x14, 0xBA, 0x1D, 0xB3, 0x62, - 0x5B, 0xF3, 0x9A, 0x21, 0x98, 0x7E, 0x63, 0xB6, - 0x1A, 0xBD, 0x65, 0x98, 0x35, 0x2A, 0xA9, 0x76, - 0x29, 0x59, 0x84, 0x25, 0x81, 0xB8, 0xDE, 0x25, - 0x32, 0x10, 0x50, 0xB7, 0xD3, 0xB3, 0x69, 0xC8, - 0xE1, 0x33, 0xCB, 0x9E, 0x9C, 0x7A, 0x7C, 0xD2, - 0x6C, 0x92, 0x97, 0xA9, 0xFA, 0xAF, 0x30, 0xBA, - 0x9A, 0xB3, 0x3D, 0x9A, 0xE5, 0x0A, 0x9B, 0x8D, - 0x89, 0xE2, 0x2B, 0xB8, 0xBC, 0xF0, 0x23, 0xFF, - 0x7B, 0x0D, 0x00, 0x36, 0xEE, 0x79, 0xCB, 0xA5, - 0x70, 0x4C, 0x66, 0x02, 0x79, 0x2E, 0x5B, 0x83, - 0xCE, 0x55, 0x8B, 0x89, 0xD6, 0xE3, 0x71, 0x63, - 0xBC, 0xB1, 0x5F, 0x67, 0xB4, 0x7E, 0x05, 0x0D, - 0xAC, 0x6D, 0x4E, 0x2C, 0xA5, 0xF4, 0x47, 0x89, - 0xAC, 0x5E, 0xBE, 0x2F, 0xFC, 0x9B, 0x2F, 0x0B, - 0xBE, 0x63, 0x54, 0x97, 0xBB, 0x23, 0x27, 0xCD, - 0xB9, 0xB2, 0x28, 0x0D, 0xA4, 0x78, 0x2C, 0xAB, - 0xD1, 0xC9, 0x94, 0x40, 0x54, 0xF2, 0x35, 0x61, - 0x49, 0x01, 0x87, 0x55, 0xA5, 0xB5, 0x1E, 0x84, - 0x92, 0x9E, 0xC1, 0xA4, 0x0B, 0x66, 0x2B, 0xF8, - 0xAF, 0xC3, 0x1E, 0xAF, 0x66, 0x3F, 0x6F, 0x5F, - 0x70, 0xEC, 0x25, 0x29, 0xE4, 0x65, 0xB2, 0x04, - 0x47, 0xF6, 0x3C, 0xB5, 0x5F, 0x66, 0x9F, 0xA4, - 0x1B, 0xFC, 0xA2, 0xD5, 0x3E, 0x84, 0xBA, 0x88, - 0x0D, 0xF1, 0x6A, 0xF2, 0xF6, 0x1D, 0xF1, 0xA3, - 0x45, 0xB2, 0x51, 0xD8, 0xA2, 0x8F, 0x55, 0xA6, - 0x89, 0xC4, 0x15, 0xD5, 0x73, 0xA8, 0xB1, 0x31, - 0x66, 0x9E, 0xC1, 0x43, 0xE1, 0x5D, 0x4E, 0x04, - 0x84, 0x8F, 0xF2, 0xBC, 0xE1, 0x4E, 0x4D, 0x60, - 0x81, 0xCA, 0x53, 0x34, 0x95, 0x17, 0x3B, 0xAE, - 0x8F, 0x95, 0xA7, 0xC6, 0x47, 0xC6, 0xAC, 0x32, - 0x12, 0x39, 0xCA, 0xEF, 0xE0, 0x07, 0xBF, 0x17, - 0x4F, 0xDC, 0x1B, 0x4E, 0x3C, 0x84, 0xF1, 0x9F, - 0x43, 0x70, 0x19, 0xE6, 0xF3, 0x8B, 0x8B, 0x5D, - 0xDB, 0xD2, 0x9D, 0xD4, 0xB2, 0x30, 0x45, 0x55, - 0xA2, 0x67, 0xA2, 0x76, 0x4A, 0x74, 0xAD, 0x88, - 0x71, 0xE6, 0x3E, 0x13, 0x06, 0x30, 0x17, 0xE1, - 0xEF, 0xAC, 0x71, 0xFB, 0x43, 0xCD, 0xF6, 0xFA, - 0x0E, 0x4C, 0x4E, 0x16, 0xF6, 0x6A, 0x09, 0x86, - 0x6B, 0xEA, 0x47, 0x6C, 0x70, 0xE7, 0xAD, 0xA2, - 0xE0, 0xFD, 0x7F, 0xF0, 0x5C, 0x21, 0x53, 0x0F, - 0x28, 0xA1, 0x43, 0xE1, 0x06, 0xCA, 0x0B, 0x31, - 0x88, 0x22, 0xA6, 0xE6, 0x34, 0x5B, 0xE6, 0xCF, - 0x25, 0x81, 0x63, 0xFF, 0x78, 0x66, 0x85, 0x19, - 0xE2, 0x0A, 0x7E, 0x81, 0x8A, 0x17, 0x1A, 0x18, - 0x8A, 0x5F, 0x5D, 0x9E, 0x82, 0x13, 0x10, 0xB9, - 0xD3, 0xE6, 0x93, 0x1C, 0xE4, 0x2C, 0xCB, 0x49, - 0x1E, 0xB6, 0x36, 0x13, 0xBF, 0x28, 0xEE, 0xCC, - 0x49, 0xF5, 0x79, 0xFC, 0x20, 0x65, 0xBD, 0xE8, - 0xF0, 0x1B, 0x4E, 0xC0, 0x0D, 0x3E, 0x89, 0x91, - 0xCC, 0x64, 0x10, 0xC0, 0x2A, 0x2B, 0xA3, 0xFA, - 0x60, 0x3D, 0xC3, 0x52, 0x2F, 0x93, 0xDE, 0xB7, - 0x6E, 0x8A, 0xDF, 0x6C, 0x08, 0xCC, 0x8B, 0x3B, - 0xC8, 0x50, 0xEF, 0x58, 0x64, 0x9A, 0x3D, 0x16, - 0x70, 0x94, 0x11, 0xD8, 0x94, 0x2B, 0x70, 0x91, - 0x10, 0x70, 0x88, 0xF0, 0x40, 0x75, 0x9A, 0x2B, - 0x39, 0xA1, 0x27, 0x3F, 0x2E, 0x91, 0xEA, 0xA1, - 0xCC, 0x12, 0xC1, 0x7F, 0x73, 0x8C, 0x5C, 0x6B, - 0xFC, 0xC5, 0x6A, 0x1C, 0x05, 0xF1, 0x3D, 0x30, - 0x82, 0x4A, 0x65, 0x35, 0xCE, 0x80, 0x10, 0xBB, - 0x41, 0x94, 0xFB, 0x84, 0x80, 0x7B, 0x91, 0xC4, - 0x4D, 0xA3, 0x5F, 0xB9, 0xFB, 0xF9, 0xC9, 0x1D, - 0x4F, 0x99, 0x1C, 0x1F, 0x47, 0x44, 0x89, 0x0E, - 0xED, 0x6D, 0xB5, 0x85, 0x41, 0x94, 0xEF, 0xF9, - 0x2E, 0xA0, 0xC8, 0xCA, 0xFB, 0x44, 0x02, 0xC6, - 0xBF, 0x96, 0x87, 0x80, 0x1D, 0xEF, 0x2A, 0x81, - 0xAB, 0xB2, 0x56, 0xDF, 0x54, 0x8B, 0xAB, 0xAF, - 0xFE, 0x18, 0x8C, 0xAA, 0xD4, 0x00, 0x17, 0xBE, - 0xCF, 0x06, 0xE5, 0xA6, 0xBF, 0x5A, 0x52, 0x3B, - 0x4E, 0xF5, 0x65, 0x60, 0x95, 0xDE, 0x8A, 0x25, - 0x88, 0xA5, 0x24, 0x96, 0x29, 0x13, 0x0D, 0x19, - 0x45, 0x95, 0x91, 0x08, 0xD2, 0x9C, 0x4C, 0x34, - 0x42, 0xF0, 0xA5, 0x72, 0xEB, 0xFB, 0x5E, 0xAA, - 0x68, 0x80, 0x82, 0xAC, 0x34, 0xAD, 0x89, 0xF6, - 0xAF, 0x54, 0x82, 0xCF, 0x98, 0x8C, 0x75, 0x63, - 0x8D, 0xBD, 0x1C, 0x2A, 0xD7, 0x00, 0xA7, 0x8E, - 0xB9, 0x33, 0xB6, 0x3B, 0x95, 0x9A, 0x59, 0x1D, - 0x3F, 0x23, 0x6B, 0x18, 0xF8, 0x4F, 0x1A, 0x8D, - 0xC0, 0x26, 0x9F, 0x87, 0x61, 0xB6, 0xC6, 0x60, - 0x38, 0x22, 0x73, 0x1C, 0x99, 0x23, 0xEF, 0xD9, - 0xFD, 0xCB, 0x54, 0x74, 0xBB, 0x77, 0x14, 0xA3, - 0xA9, 0xE6, 0x7C, 0x7E, 0x03, 0x3A, 0x13, 0x6E, - 0x1D, 0x6F, 0x64, 0xB3, 0xFA, 0xFB, 0x52, 0xDE, - 0xDF, 0x08, 0xFB, 0x6F, 0xC5, 0xFA, 0x51, 0x6A, - 0x69, 0x29, 0x9B, 0x96, 0xE8, 0x16, 0xC8, 0xD1, - 0xE4, 0x19, 0xBD, 0x14, 0x74, 0x27, 0xE7, 0x10, - 0xF0, 0xC3, 0xE2, 0xA7, 0x60, 0x48, 0xBF, 0xDD, - 0xC4, 0x0D, 0xD0, 0xF2, 0xEF, 0xA6, 0xC9, 0xA2, - 0x73, 0xD1, 0xCF, 0x41, 0xE1, 0x3B, 0xE5, 0x49, - 0x91, 0x5D, 0x09, 0xFD, 0x1D, 0x95, 0x29, 0xDB, - 0x52, 0x48, 0xEB, 0xF5, 0x1D, 0xF8, 0x06, 0x67, - 0x75, 0xF2, 0x57, 0xA4, 0x20, 0x60, 0xEA, 0xB0, - 0x85, 0x93, 0x7C, 0xDD, 0x52, 0x01, 0xD4, 0x57, - 0xA8, 0x31, 0x2D, 0xF9, 0x0A, 0xD2, 0x2A, 0xD1, - 0x34, 0x18, 0x35, 0x16, 0xB6, 0x8B, 0x0F, 0x0B, - 0xCF, 0x50, 0x80, 0xFE, 0x76, 0xCC, 0x4F, 0x30, - 0x98, 0x19, 0x16, 0x3D, 0x01, 0xEA, 0x8D, 0x8A, - 0x3D, 0xDC, 0xFB, 0x1F, 0x77, 0x8D, 0x72, 0x76, - 0x02, 0x3C, 0x5D, 0xEE, 0x55, 0x13, 0x5B, 0x6E, - 0x5A, 0x2D, 0xD5, 0x77, 0xD7, 0x01, 0x84, 0x7D, - 0x21, 0x8C, 0xDD, 0x94, 0x7D, 0x31, 0x3D, 0xF0, - 0xE7, 0x28, 0xF5, 0x72, 0x36, 0x60, 0xE0, 0x59, - 0x5F, 0xFE, 0x38, 0xF8, 0x2F, 0xDB, 0x9E, 0x55, - 0x5A, 0xD6, 0xBA, 0x6C, 0x87, 0xF3, 0xC0, 0x76, - 0x5F, 0xA3, 0x0A, 0xC3, 0xA3, 0x8D, 0x0E, 0x52, - 0xA8, 0xDA, 0x26, 0x3A, 0xF9, 0x3E, 0x36, 0xB1, - 0x06, 0xF8, 0x20, 0x2D, 0x1C, 0x0B, 0x93, 0xBB, - 0xD3, 0x64, 0x77, 0xCE, 0x11, 0xFC, 0xA2, 0x0E, - 0x1B, 0x5B, 0x9E, 0x13, 0x9F, 0x20, 0x8B, 0xAA, - 0xCD, 0x72, 0xD7, 0xA6, 0xF3, 0x1E, 0x4F, 0x72, - 0xC6, 0x49, 0x0F, 0x7B, 0xF0, 0x4C, 0x61, 0x1F, - 0x43, 0x0D, 0x4F, 0x0D, 0x33, 0x13, 0xED, 0x63, - 0xE5, 0xDB, 0x71, 0xAB, 0xA4, 0x83, 0xEF, 0xDC, - 0x86, 0x9D, 0x4B, 0xBD, 0x1B, 0x8A, 0xFE, 0x39, - 0xA8, 0x8B, 0xBA, 0x4C, 0x85, 0x28, 0xFC, 0xB3, - 0x62, 0x85, 0xD2, 0xF0, 0x38, 0xD0, 0x4B, 0xA4, - 0xD1, 0x3B, 0xD4, 0xD0, 0x2C, 0x78, 0x6C, 0x6A, - 0xC2, 0x64, 0x2C, 0x31, 0x4A, 0xD8, 0x69, 0x24, - 0xED, 0x77, 0x7D, 0x68, 0x9A, 0xA1, 0x78, 0x81, - 0xD9, 0x7E, 0x6C, 0xFE, 0x0A, 0x0D, 0x76, 0xF7, - 0x4B, 0x58, 0xE7, 0xC9, 0xB5, 0x11, 0x07, 0x87, - 0x88, 0x6A, 0x9F, 0x3D, 0xE0, 0xEE, 0xCC, 0x60, - 0x6B, 0x6B, 0xE6, 0xB5, 0x54, 0x8B, 0x32, 0x1F, - 0x04, 0x1D, 0x0E, 0x9E, 0xFA, 0x6D, 0xB0, 0xE0, - 0x6D, 0xF9, 0x79, 0xB4, 0xAB, 0x5E, 0xDF, 0x23, - 0x7F, 0x95, 0xAD, 0x80, 0x17, 0x23, 0x90, 0x1F, - 0xF0, 0xC3, 0xD9, 0x2D, 0xAC, 0x3F, 0x63, 0xF5, - 0x77, 0xC5, 0x05, 0xAC, 0x06, 0xB6, 0xA1, 0xB4, - 0xA2, 0x40, 0xB3, 0x99, 0x34, 0x7D, 0x31, 0xD4, - 0xB1, 0xD4, 0xC1, 0xBB, 0x71, 0x1E, 0xDA, 0x3F, - 0xA9, 0x12, 0x68, 0xFA, 0x5B, 0x20, 0x24, 0x6D, - 0x4D, 0x72, 0x43, 0x18, 0xBF, 0x66, 0x71, 0x69, - 0x26, 0x7D, 0x77, 0x78, 0xF8, 0xE5, 0x20, 0xAE, - 0x56, 0x6C, 0x0F, 0x72, 0x94, 0x42, 0x85, 0x4F, - 0xE4, 0xFB, 0x32, 0x26, 0x1B, 0x1C, 0x6E, 0x0B, - 0xF0, 0xB8, 0x58, 0x00, 0xD2, 0x36, 0x64, 0xAD, - 0xA9, 0x00, 0xCE, 0x35, 0x3C, 0x88, 0x79, 0x94, - 0x0C, 0x0C, 0x9B, 0xF2, 0xDA, 0xBD, 0xCA, 0x93, - 0x37, 0x26, 0xD3, 0x08, 0x54, 0xD2, 0x0D, 0xBC, - 0x5D, 0x43, 0x5F, 0xCF, 0x28, 0xB5, 0xAA, 0x15, - 0x28, 0x46, 0x45, 0x6B, 0xE8, 0xDF, 0xE8, 0xCE, - 0x8F, 0xC0, 0x1A, 0x53, 0x63, 0x3B, 0x53, 0x75, - 0xDD, 0x43, 0x1F, 0x07, 0x0A, 0xD5, 0xA1, 0x2A, - 0x6E, 0x28, 0xE1, 0xD7, 0xD0, 0x09, 0xCF, 0x62, - 0xC1, 0x5F, 0x21, 0xDB, 0xC5, 0x40, 0x99, 0x48, - 0x87, 0x6E, 0x11, 0xF5, 0x5A, 0x4E, 0xBC, 0xF9, - 0xA8, 0x02, 0x7C, 0x47, 0x39, 0xA5, 0xD8, 0x52, - 0xB1, 0x80, 0xDC, 0xFE, 0x08, 0x4B, 0x5D, 0x09, - 0xDE, 0x06, 0xF3, 0x2A, 0xAD, 0x14, 0x76, 0x40, - 0x2F, 0x82, 0x28, 0x6A, 0xB6, 0x43, 0xEF, 0x71, - 0x63, 0xC2, 0x56, 0xEB, 0x3B, 0x4B, 0x52, 0x2F, - 0x93, 0xD3, 0x18, 0x3E, 0x18, 0xA8, 0xF7, 0x58, - 0xFC, 0x8B, 0x3D, 0x4D, 0x4B, 0x72, 0xBD, 0xF7, - 0x04, 0xC9, 0xB8, 0xD7, 0x6C, 0x8C, 0x67, 0xBB, - 0x4C, 0x9B, 0x57, 0xF7, 0x22, 0x4E, 0x41, 0xB6, - 0xFD, 0xD9, 0xF8, 0x41, 0x62, 0x0F, 0xFF, 0xAA, - 0xC6, 0x87, 0x95, 0xFF, 0xFD, 0x58, 0xD9, 0xB2, - 0xBA, 0x47, 0x61, 0x24, 0xEA, 0x92, 0x6E, 0x74, - 0xB3, 0xDA, 0xE5, 0x83, 0x99, 0x24, 0xB1, 0x71, - 0x2A, 0x33, 0xB2, 0xD5, 0x8F, 0xF0, 0x32, 0xCE, - 0x37, 0xCF, 0xC7, 0x1C, 0xE8, 0xDE, 0x46, 0x78, - 0x96, 0x97, 0xF6, 0x73, 0x90, 0xE5, 0x71, 0x05, - 0xEA, 0x0D, 0xC2, 0x1D, 0x9E, 0x43, 0x34, 0xBC, - 0x8F, 0x45, 0xE5, 0x08, 0xCA, 0x20, 0x0C, 0x84 - }, - .len = 2048 - }, - .auth_tag = { - .data = { - 0xD0, 0x62, 0x1F, 0x20, 0x1C, 0xE8, 0xDD, 0x36, - 0x00, 0x74, 0xF6, 0xD7, 0xFD, 0x2C, 0xA0, 0xAF - }, - .len = 16 - } -}; - -/** AES-256 Test Vectors */ -static const struct gcm_test_data gcm_test_case_256_1 = { - .key = { - .data = { - 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 }, - .len = 32 - }, - .iv = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { 0x00 }, - .len = 0 - }, - .ciphertext = { - .data = { 0x00 }, - .len = 0 - }, - .auth_tag = { - .data = { - 0x53, 0x0F, 0x8A, 0xFB, 0xC7, 0x45, 0x36, 0xB9, - 0xA9, 0x63, 0xB4, 0xF1, 0xC4, 0xCB, 0x73, 0x8B }, - .len = 16 - } -}; - -/** AES-256 Test Vectors */ -static const struct gcm_test_data gcm_test_case_256_2 = { - .key = { - .data = { - 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 }, - .len = 32 - }, - .iv = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .len = 16 - }, - .ciphertext = { - .data = { - 0xCE, 0xA7, 0x40, 0x3D, 0x4D, 0x60, 0x6B, 0x6E, - 0x07, 0x4E, 0xC5, 0xD3, 0xBA, 0xF3, 0x9D, 0x18 }, - .len = 16 - }, - .auth_tag = { - .data = { - 0xD0, 0xD1, 0xC8, 0xA7, 0x99, 0x99, 0x6B, 0xF0, - 0x26, 0x5B, 0x98, 0xB5, 0xD4, 0x8A, 0xB9, 0x19 }, - .len = 16 - } -}; - -/** AES-256 Test Vectors */ -static const struct gcm_test_data gcm_test_case_256_3 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, - .len = 32 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, - 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, - 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, - 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, - 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, - 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, - 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, - 0xFA, 0x47, 0xC8, 0x2E, 0xF0, 0x68, 0xE1, 0x3E }, - .len = 64 - }, - .auth_tag = { - .data = { - 0x64, 0xAF, 0x1D, 0xFB, 0xE8, 0x0D, 0x37, 0xD8, - 0x92, 0xC3, 0xB9, 0x1D, 0xD3, 0x08, 0xAB, 0xFC }, - .len = 16 - } -}; - -/** AES-256 Test Vectors */ -static const struct gcm_test_data gcm_test_case_256_4 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, - .len = 32 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 8 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 }, - .len = 60 - }, - .ciphertext = { - .data = { - 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, - 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, - 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, - 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, - 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, - 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, - 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, - 0xFA, 0x47, 0xC8, 0x2E }, - .len = 60 - }, - .auth_tag = { - .data = { - 0x63, 0x16, 0x91, 0xAE, 0x17, 0x05, 0x5E, 0xA6, - 0x6D, 0x0A, 0x51, 0xE2, 0x50, 0x21, 0x85, 0x4A }, - .len = 16 - } - -}; - -/** AES-256 Test Vectors */ -static const struct gcm_test_data gcm_test_case_256_5 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, - .len = 32 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_text, - .len = 8 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 }, - .len = 60 - }, - .ciphertext = { - .data = { - 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, - 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, - 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, - 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, - 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, - 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, - 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, - 0xFA, 0x47, 0xC8, 0x2E }, - .len = 60 - }, - .auth_tag = { - .data = { - 0xA7, 0x99, 0xAC, 0xB8, 0x27, 0xDA, 0xB1, 0x82, - 0x79, 0xFD, 0x83, 0x73, 0x52, 0x4D, 0xDB, 0xF1 }, - .len = 16 - } - -}; - -/** AES-256 Test Vectors */ -static const struct gcm_test_data gcm_test_case_256_6 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, - .len = 32 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 12 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 }, - .len = 60 - }, - .ciphertext = { - .data = { - 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, - 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, - 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, - 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, - 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, - 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, - 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, - 0xFA, 0x47, 0xC8, 0x2E }, - .len = 60 - }, - .auth_tag = { - .data = { - 0x5D, 0xA5, 0x0E, 0x53, 0x64, 0x7F, 0x3F, 0xAE, - 0x1A, 0x1F, 0xC0, 0xB0, 0xD8, 0xBE, 0xF2, 0x64 }, - .len = 16 - } -}; - -/** AES-256 Test Vectors */ -static const struct gcm_test_data gcm_test_case_256_7 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, - .len = 32 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_text, - .len = 12 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 }, - .len = 60 - }, - .ciphertext = { - .data = { - 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, - 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, - 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, - 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, - 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, - 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, - 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, - 0xFA, 0x47, 0xC8, 0x2E }, - .len = 60 - }, - .auth_tag = { - .data = { - 0x4E, 0xD0, 0x91, 0x95, 0x83, 0xA9, 0x38, 0x72, - 0x09, 0xA9, 0xCE, 0x5F, 0x89, 0x06, 0x4E, 0xC8 }, - .len = 16 - } -}; - -/** variable AAD AES-128 Test Vectors */ -static const struct gcm_test_data gcm_test_case_aad_1 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_text, - .len = GCM_LARGE_AAD_LENGTH - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x42, 0x83, 0x1E, 0xC2, 0x21, 0x77, 0x74, 0x24, - 0x4B, 0x72, 0x21, 0xB7, 0x84, 0xD0, 0xD4, 0x9C, - 0xE3, 0xAA, 0x21, 0x2F, 0x2C, 0x02, 0xA4, 0xE0, - 0x35, 0xC1, 0x7E, 0x23, 0x29, 0xAC, 0xA1, 0x2E, - 0x21, 0xD5, 0x14, 0xB2, 0x54, 0x66, 0x93, 0x1C, - 0x7D, 0x8F, 0x6A, 0x5A, 0xAC, 0x84, 0xAA, 0x05, - 0x1B, 0xA3, 0x0B, 0x39, 0x6A, 0x0A, 0xAC, 0x97, - 0x3D, 0x58, 0xE0, 0x91, 0x47, 0x3F, 0x59, 0x85 - }, - .len = 64 - }, - .auth_tag = { - .data = { - 0xCA, 0x70, 0xAF, 0x96, 0xA8, 0x5D, 0x40, 0x47, - 0x0C, 0x3C, 0x48, 0xF5, 0xF0, 0xF5, 0xA5, 0x7D - }, - .len = 16 - } -}; - -/** variable AAD AES-256 Test Vectors */ -static const struct gcm_test_data gcm_test_case_aad_2 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, - .len = 32 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_text, - .len = GCM_LARGE_AAD_LENGTH - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, - 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, - 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, - 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, - 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, - 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, - 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, - 0xFA, 0x47, 0xC8, 0x2E, 0xF0, 0x68, 0xE1, 0x3E - }, - .len = 64 - }, - .auth_tag = { - .data = { - 0xBA, 0x06, 0xDA, 0xA1, 0x91, 0xE1, 0xFE, 0x22, - 0x59, 0xDA, 0x67, 0xAF, 0x9D, 0xA5, 0x43, 0x94 - }, - .len = 16 - } -}; - -/** GMAC Test Vectors */ -static uint8_t gmac_plaintext[GMAC_LARGE_PLAINTEXT_LENGTH] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 -}; - -static const struct gmac_test_data gmac_test_case_1 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 - }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gmac_plaintext, - .len = 160 - }, - .plaintext = { - .data = NULL, - .len = 0 - }, - .gmac_tag = { - .data = { - 0x4C, 0x0C, 0x4F, 0x47, 0x2D, 0x78, 0xF6, 0xD8, - 0x03, 0x53, 0x20, 0x2F, 0x1A, 0xDF, 0x90, 0xD0 - }, - .len = 16 - }, -}; - -static const struct gmac_test_data gmac_test_case_2 = { - .key = { - .data = { - 0xaa, 0x74, 0x0a, 0xbf, 0xad, 0xcd, 0xa7, 0x79, - 0x22, 0x0d, 0x3b, 0x40, 0x6c, 0x5d, 0x7e, 0xc0, - 0x9a, 0x77, 0xfe, 0x9d, 0x94, 0x10, 0x45, 0x39, - }, - .len = 24 - }, - .iv = { - .data = { - 0xab, 0x22, 0x65, 0xb4, 0xc1, 0x68, 0x95, - 0x55, 0x61, 0xf0, 0x43, 0x15, }, - .len = 12 - }, - .aad = { - .data = gmac_plaintext, - .len = 80 - }, - .plaintext = { - .data = NULL, - .len = 0 - }, - .gmac_tag = { - .data = { - 0xCF, 0x82, 0x80, 0x64, 0x02, 0x46, 0xF4, 0xFB, - 0x33, 0xAE, 0x1D, 0x90, 0xEA, 0x48, 0x83, 0xDB - }, - .len = 16 - }, -}; - -static const struct gmac_test_data gmac_test_case_3 = { - .key = { - .data = { - 0xb5, 0x48, 0xe4, 0x93, 0x4f, 0x5c, 0x64, 0xd3, - 0xc0, 0xf0, 0xb7, 0x8f, 0x7b, 0x4d, 0x88, 0x24, - 0xaa, 0xc4, 0x6b, 0x3c, 0x8d, 0x2c, 0xc3, 0x5e, - 0xe4, 0xbf, 0xb2, 0x54, 0xe4, 0xfc, 0xba, 0xf7, - }, - .len = 32 - }, - .iv = { - .data = { - 0x2e, 0xed, 0xe1, 0xdc, 0x64, 0x47, 0xc7, - 0xaf, 0xc4, 0x41, 0x53, 0x58, - }, - .len = 12 - }, - .aad = { - .data = gmac_plaintext, - .len = 65 - }, - .plaintext = { - .data = NULL, - .len = 0 - }, - .gmac_tag = { - .data = { - 0x77, 0x46, 0x0D, 0x6F, 0xB1, 0x87, 0xDB, 0xA9, - 0x46, 0xAD, 0xCD, 0xFB, 0xB7, 0xF9, 0x13, 0xA1 - }, - .len = 16 - }, -}; - -/******* GCM PERF VECTORS ***********/ - -struct cryptodev_perf_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[64]; - unsigned len; - } aad; - - struct { - uint8_t data[2048]; - unsigned len; - } plaintext; - - struct { - uint8_t data[2048]; - unsigned len; - } ciphertext; - - struct { - uint8_t data[16]; - unsigned len; - } auth_tag; - - struct { - uint32_t size; - uint8_t data[16]; - unsigned len; - } auth_tags[7]; - -}; - -/* 2048B */ -static const struct cryptodev_perf_test_data AES_GCM_128_12IV_0AAD = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = { 0 }, - .len = 0 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 - }, - .len = 2048 - }, - .ciphertext = { - .data = { - 0x42, 0x83, 0x1E, 0xC2, 0x21, 0x77, 0x74, 0x24, - 0x4B, 0x72, 0x21, 0xB7, 0x84, 0xD0, 0xD4, 0x9C, - 0xE3, 0xAA, 0x21, 0x2F, 0x2C, 0x02, 0xA4, 0xE0, - 0x35, 0xC1, 0x7E, 0x23, 0x29, 0xAC, 0xA1, 0x2E, - 0x21, 0xD5, 0x14, 0xB2, 0x54, 0x66, 0x93, 0x1C, - 0x7D, 0x8F, 0x6A, 0x5A, 0xAC, 0x84, 0xAA, 0x05, - 0x1B, 0xA3, 0x0B, 0x39, 0x6A, 0x0A, 0xAC, 0x97, - 0x3D, 0x58, 0xE0, 0x91, 0x47, 0x3F, 0x59, 0x85, - 0x04, 0x99, 0x55, 0xE1, 0x36, 0x76, 0xB7, 0x14, - 0x1D, 0xF0, 0xF6, 0x8C, 0x65, 0xD5, 0xAD, 0xFB, - 0x90, 0x7F, 0x5D, 0xA2, 0xD6, 0xFD, 0xD0, 0xE5, - 0x0D, 0x9B, 0x68, 0x21, 0x49, 0x42, 0x6E, 0x13, - 0xEC, 0x22, 0x50, 0x2A, 0x30, 0x47, 0x49, 0xA1, - 0x7F, 0xC3, 0x09, 0xE0, 0x56, 0x91, 0xC4, 0x54, - 0x70, 0xD7, 0x19, 0x40, 0xCA, 0x6B, 0x65, 0x27, - 0x3E, 0xE9, 0xD1, 0x0F, 0x1C, 0xB5, 0x45, 0x0D, - 0x27, 0xE7, 0xCF, 0x94, 0x10, 0xBF, 0xA2, 0xFA, - 0x86, 0x20, 0x3F, 0x6E, 0xE9, 0x95, 0x03, 0x5A, - 0x46, 0x11, 0x75, 0xD5, 0x37, 0x71, 0x7F, 0xE0, - 0xBC, 0x9F, 0xC8, 0xE9, 0xB1, 0x08, 0x2C, 0x59, - 0x6E, 0x51, 0x4A, 0x83, 0x38, 0xC1, 0xED, 0xE2, - 0x2E, 0x88, 0x90, 0xA5, 0x7D, 0xA4, 0x93, 0x9A, - 0x30, 0xD6, 0x96, 0x34, 0x0F, 0xC4, 0xD1, 0x7E, - 0xC9, 0x8F, 0xC5, 0xBB, 0x80, 0x50, 0x85, 0x75, - 0x7D, 0x82, 0x36, 0xDB, 0x62, 0x15, 0xAF, 0x4B, - 0x0A, 0x9D, 0xCD, 0x64, 0x00, 0xAB, 0x88, 0x28, - 0xA8, 0x35, 0x17, 0x70, 0x6F, 0x47, 0x44, 0xCD, - 0x65, 0xAE, 0xD5, 0x05, 0x0A, 0xA8, 0x2F, 0x48, - 0xAC, 0xA1, 0x72, 0x64, 0x1C, 0x7E, 0xD3, 0xF5, - 0xD8, 0x4E, 0x73, 0x17, 0x0C, 0xE5, 0x9F, 0xB6, - 0x00, 0xFA, 0xD7, 0x2C, 0x3D, 0x6A, 0x10, 0x47, - 0x7C, 0xF2, 0x6B, 0x13, 0x10, 0x8A, 0x76, 0x39, - 0xF8, 0x50, 0x33, 0xAC, 0x08, 0x1D, 0xA3, 0x48, - 0xE1, 0xD0, 0x05, 0x49, 0xB7, 0x76, 0x03, 0x72, - 0x07, 0xC5, 0xD3, 0x08, 0x79, 0x38, 0x66, 0xC1, - 0x52, 0xAF, 0x83, 0xCD, 0xF3, 0x86, 0x62, 0xBF, - 0x92, 0x24, 0x97, 0xBD, 0x5D, 0x7D, 0x81, 0x56, - 0x4C, 0xF3, 0xD2, 0x60, 0xC2, 0xDE, 0x61, 0xC1, - 0x39, 0x61, 0xDA, 0x07, 0x50, 0xC7, 0x98, 0x63, - 0x7E, 0xDD, 0x54, 0xCA, 0xDE, 0x12, 0xD2, 0xA8, - 0x19, 0x08, 0x6E, 0xF9, 0xFA, 0x6F, 0x58, 0x97, - 0xD4, 0x0B, 0x5C, 0x5B, 0xE5, 0x30, 0xE5, 0x4C, - 0x0E, 0x16, 0x87, 0xF0, 0x2C, 0xCB, 0x53, 0xB8, - 0x0C, 0xE5, 0xDF, 0x16, 0x7B, 0xE8, 0xC2, 0xCF, - 0xCC, 0xFF, 0x51, 0x24, 0xC1, 0xDD, 0x59, 0x9C, - 0xA7, 0x56, 0x03, 0xB9, 0x0A, 0x37, 0xA2, 0xAC, - 0x28, 0x8B, 0xEB, 0x51, 0x4E, 0xF1, 0xAE, 0xB5, - 0xC8, 0xB5, 0xCB, 0x8D, 0x23, 0xF6, 0x24, 0x2D, - 0xF6, 0x59, 0x62, 0xC0, 0xCB, 0xD3, 0x18, 0xE4, - 0xB7, 0x73, 0xEF, 0xDB, 0x13, 0x9A, 0xF5, 0xD3, - 0xD5, 0x61, 0x01, 0x14, 0xA5, 0xE5, 0x0D, 0x27, - 0xC9, 0xA5, 0x08, 0x1C, 0x60, 0xBA, 0x73, 0xFF, - 0xA9, 0xE0, 0x27, 0x86, 0x3F, 0xF7, 0x15, 0x03, - 0x69, 0xA7, 0x2B, 0x57, 0xAC, 0xA6, 0x70, 0x55, - 0xE9, 0xB5, 0x3F, 0xEB, 0x6F, 0xCE, 0x8A, 0xA1, - 0x9D, 0x8B, 0x84, 0xF1, 0x7C, 0xD0, 0x35, 0x21, - 0x91, 0x3D, 0x3D, 0x6E, 0x83, 0xFC, 0x45, 0x36, - 0x93, 0xDA, 0x66, 0xDF, 0x1A, 0x59, 0x22, 0xA5, - 0xC4, 0x99, 0x9B, 0xF8, 0x48, 0x9A, 0x50, 0x09, - 0xAB, 0xAE, 0x56, 0xB6, 0x49, 0x02, 0x3E, 0x90, - 0xB6, 0x07, 0x7E, 0xA7, 0x6A, 0x0A, 0xB5, 0x85, - 0x31, 0x0D, 0x84, 0xD4, 0x01, 0xE4, 0x48, 0x63, - 0xF3, 0xC1, 0x54, 0x65, 0xA6, 0x4C, 0x8B, 0x33, - 0xF9, 0x70, 0x59, 0x3B, 0xA6, 0xF6, 0x2B, 0x66, - 0xC5, 0xD2, 0xEB, 0xAB, 0x67, 0xD2, 0xE3, 0x78, - 0xA9, 0x1A, 0x4C, 0x99, 0xA9, 0xA6, 0xCA, 0xF7, - 0x65, 0xF0, 0x48, 0xF8, 0x2A, 0xEA, 0x96, 0x9F, - 0xC4, 0x50, 0x9A, 0x0C, 0xB6, 0x0D, 0x8A, 0x2F, - 0xC3, 0x99, 0x4E, 0xA0, 0x06, 0x4D, 0xAB, 0x25, - 0x2E, 0x44, 0x47, 0xB6, 0x98, 0xF1, 0x2C, 0x96, - 0x54, 0x51, 0x12, 0x41, 0x0D, 0xEF, 0x32, 0x9A, - 0x4A, 0xBD, 0xA2, 0x26, 0x53, 0xA8, 0xFD, 0x8B, - 0x6C, 0x95, 0x0A, 0x1A, 0x96, 0xEF, 0x3C, 0x85, - 0x34, 0x4E, 0x25, 0x9E, 0x1C, 0x67, 0x33, 0x8A, - 0xFF, 0x6D, 0x98, 0x93, 0x3D, 0x3F, 0x49, 0x6B, - 0xBF, 0x7C, 0x4F, 0x63, 0x5D, 0x62, 0x64, 0x67, - 0x0D, 0x07, 0x7F, 0x24, 0x4A, 0x23, 0xBC, 0x35, - 0xE0, 0x92, 0x6F, 0x51, 0xE7, 0x25, 0x97, 0xB9, - 0x14, 0x35, 0x2B, 0x48, 0xAC, 0x6F, 0x54, 0xDF, - 0xF2, 0xB4, 0xB0, 0xE0, 0xD3, 0x28, 0x0D, 0x66, - 0x46, 0x28, 0x0A, 0x16, 0x9C, 0x87, 0x73, 0xB7, - 0x9C, 0x2B, 0xB5, 0x43, 0xC9, 0x46, 0xB9, 0x1F, - 0x5F, 0x3C, 0x45, 0x03, 0x4B, 0xBF, 0x44, 0x4D, - 0xE1, 0x44, 0xDA, 0x54, 0xC5, 0x32, 0x3A, 0xFA, - 0x21, 0x5C, 0xAD, 0xD5, 0x1E, 0x1B, 0x54, 0x7C, - 0x9F, 0xEA, 0x92, 0x8C, 0xEA, 0x69, 0xC0, 0xCE, - 0xDA, 0x09, 0xAD, 0x95, 0xA0, 0x8E, 0x0B, 0x8E, - 0x10, 0x4F, 0x5B, 0x8F, 0xB8, 0x2D, 0xAC, 0x4C, - 0x94, 0x4B, 0x7C, 0x1E, 0xF1, 0x53, 0x20, 0x9B, - 0xD6, 0xC4, 0x92, 0x4C, 0x7F, 0xFB, 0x8B, 0x8E, - 0x40, 0x2F, 0x24, 0xA3, 0x4E, 0x46, 0x64, 0xF4, - 0xC6, 0x35, 0x0F, 0xC7, 0x40, 0x55, 0x43, 0xAF, - 0x7E, 0x91, 0x76, 0x48, 0x6F, 0x97, 0x7A, 0xF8, - 0x32, 0x1E, 0xD3, 0x5B, 0xBC, 0x19, 0xB5, 0x48, - 0xFA, 0x4F, 0x52, 0x77, 0x5B, 0x9E, 0xA2, 0xC8, - 0x9A, 0x83, 0x30, 0x8D, 0x9F, 0x0B, 0x6F, 0xA8, - 0x2E, 0x84, 0xCC, 0xC1, 0x50, 0x96, 0x46, 0xAE, - 0x73, 0x91, 0x7D, 0xCD, 0x88, 0xAB, 0x67, 0x3F, - 0x66, 0x3A, 0x8D, 0xB1, 0x89, 0x07, 0x93, 0xDB, - 0x42, 0x22, 0xDC, 0x13, 0xBD, 0xCD, 0xBB, 0x12, - 0x8D, 0x88, 0x44, 0x13, 0x22, 0x52, 0x81, 0xDC, - 0xEF, 0xA1, 0xE4, 0xA3, 0xA7, 0xBA, 0xEE, 0x98, - 0x79, 0x45, 0x29, 0x05, 0x65, 0x3D, 0xDC, 0xAF, - 0xA1, 0x37, 0x29, 0xFD, 0x05, 0xD1, 0x3A, 0xF7, - 0x32, 0x1D, 0x02, 0xEC, 0x28, 0x1E, 0x0F, 0x96, - 0xF3, 0x21, 0x19, 0x5F, 0x49, 0xB9, 0xEA, 0x9A, - 0xAD, 0x34, 0x58, 0xD1, 0xD9, 0xB1, 0x7D, 0xD2, - 0xEA, 0xED, 0x74, 0xE8, 0x25, 0x9A, 0x7B, 0xC5, - 0xC8, 0xD8, 0x76, 0xB6, 0xBC, 0x0B, 0x78, 0xCE, - 0xD9, 0xA6, 0xBB, 0x2F, 0x79, 0xA4, 0x45, 0x05, - 0x55, 0x6E, 0x20, 0x84, 0xEB, 0xC8, 0x70, 0xB0, - 0x3A, 0x2D, 0x06, 0x98, 0x29, 0x10, 0xB8, 0xC5, - 0xE9, 0xE4, 0xB6, 0xDE, 0x97, 0x9A, 0x0D, 0x8C, - 0xB6, 0x22, 0x16, 0x59, 0xAB, 0xB5, 0xD7, 0x14, - 0xAB, 0x08, 0x02, 0x27, 0x7B, 0xF7, 0x0E, 0xAC, - 0xC5, 0xAC, 0x4D, 0x7F, 0xE5, 0x65, 0x51, 0x40, - 0x44, 0x92, 0xB1, 0x6A, 0xB7, 0x00, 0x76, 0x89, - 0x6E, 0x08, 0x5F, 0x45, 0x2B, 0x53, 0x86, 0x86, - 0xA7, 0x85, 0xBC, 0x62, 0xAC, 0xAA, 0x82, 0x73, - 0x0A, 0xEB, 0x35, 0x16, 0x95, 0x26, 0xAB, 0x9E, - 0xE9, 0x64, 0x53, 0x99, 0x08, 0x31, 0xF5, 0x6B, - 0x1F, 0xFE, 0x47, 0x4B, 0x09, 0x33, 0x4F, 0xBF, - 0x1F, 0x0B, 0x4C, 0xB2, 0xB4, 0xA4, 0x17, 0xA9, - 0xAD, 0xC5, 0x62, 0x7C, 0xF1, 0x1B, 0xAE, 0x46, - 0xD3, 0xAC, 0xFD, 0x43, 0xFE, 0x79, 0xD0, 0x58, - 0x2F, 0x6C, 0x9F, 0xD0, 0x65, 0xA4, 0x64, 0x03, - 0xAF, 0x73, 0x46, 0x75, 0x7D, 0x49, 0x1B, 0x4C, - 0xFA, 0x49, 0xD8, 0x9A, 0xCC, 0x59, 0xC6, 0xC7, - 0xA1, 0x05, 0xC2, 0x32, 0xC8, 0x6C, 0x50, 0xA8, - 0x06, 0x58, 0xBE, 0x6C, 0x7D, 0x22, 0xD6, 0x0D, - 0x74, 0x40, 0xCE, 0xD6, 0x64, 0xD6, 0x47, 0xD0, - 0xBF, 0xF1, 0x5C, 0x54, 0xF9, 0x06, 0x3F, 0x3D, - 0x86, 0xBA, 0xF2, 0x0F, 0x5E, 0x2C, 0x01, 0xCC, - 0xD9, 0xC7, 0xB1, 0x4A, 0xB3, 0xD7, 0x26, 0xCC, - 0xC3, 0x7A, 0x74, 0x2C, 0xE1, 0x22, 0x65, 0xA0, - 0x5B, 0xCA, 0xF4, 0xE1, 0x7D, 0xE1, 0x56, 0xFD, - 0x94, 0x10, 0xC6, 0xA1, 0x4A, 0xE8, 0x6B, 0x34, - 0x4E, 0x71, 0x60, 0x77, 0x0F, 0x03, 0xDD, 0xFF, - 0xC8, 0x59, 0x54, 0x6C, 0xD4, 0x4A, 0x55, 0x24, - 0x35, 0x21, 0x60, 0x73, 0xDF, 0x6F, 0xE7, 0x3C, - 0xC2, 0xF0, 0xDA, 0xA9, 0xE5, 0x8C, 0xAC, 0xB6, - 0xFD, 0x2E, 0xF7, 0xA0, 0x18, 0xA7, 0x55, 0x47, - 0xD1, 0xCB, 0x9E, 0xAA, 0x58, 0x54, 0x3B, 0x37, - 0x18, 0xB5, 0xC1, 0xBB, 0x41, 0x59, 0xE4, 0x28, - 0x4A, 0x13, 0x90, 0x6A, 0xF7, 0xD1, 0xB3, 0x71, - 0xB6, 0x6E, 0xF6, 0x5D, 0x2E, 0x0E, 0x6C, 0x4A, - 0x7B, 0xF7, 0xB6, 0x21, 0xD4, 0xFC, 0x47, 0x8C, - 0x9B, 0x0A, 0x90, 0xAC, 0x11, 0x52, 0x86, 0x07, - 0x24, 0xDA, 0xA9, 0x49, 0x50, 0xD9, 0xDC, 0xE2, - 0x19, 0x87, 0x73, 0x88, 0xC3, 0xE4, 0xED, 0xC9, - 0x1C, 0xA8, 0x7E, 0x39, 0x48, 0x91, 0x10, 0xAB, - 0xFC, 0x3C, 0x1E, 0xEE, 0x08, 0xA1, 0xB9, 0xB2, - 0x02, 0x57, 0xB1, 0xD1, 0x35, 0x5E, 0x3D, 0x94, - 0xFB, 0x36, 0x27, 0x1A, 0x0E, 0x75, 0xFC, 0xBC, - 0xDB, 0xF3, 0xF5, 0x7C, 0x08, 0x39, 0xAA, 0xF4, - 0x2E, 0xEE, 0xCF, 0xCD, 0x2D, 0x70, 0xB8, 0x84, - 0xE6, 0x22, 0x5C, 0xC0, 0xB9, 0x33, 0xCB, 0x97, - 0xA1, 0xA3, 0xEE, 0x93, 0x71, 0xCF, 0xC9, 0x21, - 0x31, 0x7A, 0xEC, 0xE7, 0x70, 0xF2, 0xAA, 0x91, - 0xAA, 0x48, 0xAD, 0xAC, 0x03, 0xB1, 0x26, 0x52, - 0xBC, 0x65, 0x22, 0xA1, 0x09, 0x3D, 0xAB, 0x16, - 0x08, 0xBF, 0xCF, 0x3F, 0x59, 0x08, 0x6F, 0x68, - 0xEB, 0x8A, 0xB3, 0xCF, 0x77, 0x82, 0xFB, 0x25, - 0x78, 0x16, 0x4C, 0xDB, 0x72, 0xF5, 0xCF, 0x79, - 0x71, 0xE4, 0x4E, 0x23, 0x15, 0x7F, 0x1E, 0xA8, - 0x3E, 0xC0, 0x59, 0x91, 0x20, 0xAE, 0x2C, 0x1D, - 0x90, 0xC8, 0x49, 0x42, 0x48, 0x29, 0x82, 0x66, - 0x68, 0x49, 0x73, 0xDA, 0xE4, 0x28, 0xCD, 0x7B, - 0x4D, 0xE4, 0x23, 0x34, 0xB9, 0xE1, 0xB4, 0x42, - 0x67, 0x22, 0x5B, 0xEE, 0xE6, 0x74, 0x32, 0x6F, - 0x21, 0x9F, 0x97, 0x46, 0x03, 0xE1, 0xC9, 0x7A, - 0x14, 0x27, 0x30, 0xE1, 0xB2, 0x34, 0xE6, 0xAF, - 0x7B, 0xAA, 0xDD, 0x89, 0x04, 0x30, 0xD6, 0x78, - 0x0B, 0x3D, 0xC3, 0x69, 0xB0, 0x67, 0x4F, 0x4E, - 0x12, 0x21, 0x93, 0x2D, 0x79, 0xDD, 0x8B, 0xDB, - 0xEA, 0x90, 0x66, 0x54, 0xA8, 0x05, 0xF2, 0xE4, - 0x59, 0x8A, 0x96, 0x52, 0x30, 0xF0, 0x4E, 0x9A, - 0xE5, 0xD8, 0x72, 0x1C, 0x3B, 0x63, 0x02, 0xB9, - 0xC7, 0xA1, 0xDA, 0xC8, 0x6C, 0x48, 0xE0, 0xDE, - 0x59, 0x64, 0x89, 0x2C, 0xF9, 0xC8, 0x3B, 0x00, - 0xEC, 0xF2, 0x68, 0x51, 0x67, 0x05, 0x85, 0xAF, - 0xB8, 0xD5, 0x65, 0xEE, 0x73, 0x26, 0x88, 0xFB, - 0xA9, 0xD6, 0x6C, 0x68, 0x9D, 0x9F, 0x23, 0x6A, - 0x10, 0x24, 0x82, 0xB2, 0xB7, 0x40, 0x19, 0x3E, - 0x6F, 0xA2, 0xD5, 0x2C, 0x6E, 0x8D, 0xE9, 0x33, - 0x6E, 0x24, 0x94, 0x05, 0xE9, 0x2D, 0xD9, 0x3A, - 0x8C, 0xE5, 0xCC, 0x1D, 0x3F, 0xB8, 0x71, 0xA8, - 0x98, 0x33, 0xBB, 0x1A, 0xAC, 0x41, 0x0A, 0x04, - 0xFE, 0x4D, 0x46, 0x17, 0x8A, 0xCB, 0xF3, 0x4B, - 0x97, 0x02, 0xCC, 0x9D, 0x11, 0xF1, 0xBC, 0xA9, - 0xC1, 0xD1, 0xB6, 0xD6, 0x7B, 0x5F, 0x9D, 0x22, - 0x86, 0x71, 0xEC, 0x42, 0x53, 0xB7, 0x85, 0x30, - 0xAF, 0x1D, 0x01, 0xA7, 0xBF, 0x72, 0xC2, 0xC6, - 0xC9, 0xB8, 0xD8, 0xC7, 0xE9, 0xC4, 0xBA, 0xC5, - 0xB1, 0x8A, 0xB8, 0x62, 0xBF, 0x75, 0x75, 0x69, - 0xF8, 0x8D, 0x7E, 0xD9, 0xD2, 0x28, 0xB5, 0x40, - 0xCE, 0xCB, 0xB8, 0x74, 0x31, 0x40, 0x7B, 0x0D, - 0x73, 0x98, 0x99, 0x12, 0xB7, 0x75, 0x3E, 0xBC, - 0xAE, 0x48, 0xCA, 0xA9, 0x1E, 0xA7, 0x95, 0x31, - 0x87, 0x0F, 0x14, 0x52, 0xB6, 0x8E, 0x42, 0x50, - 0xB2, 0x76, 0x75, 0xD8, 0x7E, 0x66, 0x23, 0x13, - 0x8B, 0x29, 0xAA, 0x13, 0xCA, 0x8A, 0xD8, 0x9B, - 0x7B, 0x38, 0xD2, 0xE8, 0x67, 0xD1, 0x89, 0x25, - 0x9C, 0x63, 0x2F, 0xC3, 0x26, 0xC7, 0x74, 0x83, - 0x05, 0xED, 0x67, 0x02, 0x85, 0xAD, 0x1D, 0x0E, - 0xA9, 0xD6, 0xE1, 0xC7, 0x39, 0xA0, 0x6E, 0x72, - 0xCE, 0x56, 0x6C, 0xB8, 0x4A, 0xDE, 0x11, 0xA2, - 0xBF, 0xC1, 0x84, 0x98, 0x8F, 0xCA, 0x79, 0x74, - 0xCA, 0x9F, 0x45, 0x16, 0xBC, 0xB1, 0xF4, 0x03, - 0x76, 0x6E, 0xD5, 0x46, 0x60, 0xD7, 0x1D, 0xF0, - 0x87, 0x29, 0x63, 0x07, 0x06, 0xB9, 0xC2, 0x69, - 0x6D, 0xF9, 0x4B, 0x30, 0x96, 0x83, 0xB8, 0xC5, - 0xBE, 0x3A, 0xBA, 0xD0, 0x3E, 0x2B, 0x04, 0x16, - 0x6A, 0x00, 0x3B, 0x1A, 0x8E, 0xF8, 0xF6, 0x21, - 0x01, 0xD6, 0x08, 0x41, 0x74, 0xA2, 0xFC, 0x36, - 0xED, 0x11, 0x51, 0x5A, 0x4A, 0x21, 0x1A, 0x03, - 0x11, 0x95, 0x11, 0xF6, 0x73, 0x38, 0x67, 0xFC, - 0xF1, 0x2B, 0x22, 0x54, 0x65, 0x40, 0x7D, 0x8C, - 0x13, 0xC4, 0x46, 0x87, 0x09, 0x2B, 0xB5, 0xA1, - 0x82, 0x49, 0x46, 0x56, 0xF5, 0x5F, 0xF1, 0x04, - 0xD8, 0x6F, 0xDB, 0x38, 0xAD, 0xF4, 0x1A, 0xA3, - 0xFF, 0x7C, 0xC7, 0xA6, 0xAF, 0x87, 0x5C, 0x8C, - 0xEA, 0x3C, 0x9D, 0x7A, 0x4A, 0xD8, 0xA8, 0x66, - 0xDB, 0xBF, 0x12, 0x58, 0x98, 0x8E, 0xBA, 0x6F, - 0xAF, 0x20, 0xDA, 0xEE, 0x82, 0x34, 0x2F, 0x33, - 0x88, 0x98, 0xBA, 0xB2, 0x54, 0x7F, 0x9E, 0x63, - 0x19, 0x6C, 0x7D, 0xCE, 0x85, 0xF8, 0xB6, 0x77, - 0xCB, 0x38, 0x1F, 0xB1, 0x79, 0xBD, 0xED, 0x32, - 0xE3, 0xB9, 0x40, 0xEF, 0x3E, 0x6C, 0x29, 0x88, - 0x70, 0x99, 0x47, 0xA6, 0x4A, 0x1C, 0xCC, 0x0B, - 0x9B, 0x72, 0xA9, 0x29, 0x83, 0x4C, 0xDE, 0x4F, - 0x65, 0x4E, 0xCE, 0xBD, 0xFA, 0x76, 0x8D, 0xA6, - 0x1A, 0xD8, 0x66, 0xFE, 0xA4, 0x2A, 0x61, 0x50, - 0xEE, 0x15, 0xF1, 0xF0, 0x9D, 0xFF, 0xEC, 0xEE, - 0x00, 0x03, 0xFE, 0xAC, 0x53, 0x02, 0xCC, 0x87, - 0xB1, 0xA2, 0xD8, 0x34, 0x2C, 0xEC, 0xA6, 0x4C, - 0x02, 0xC0, 0xC1, 0x72, 0xD6, 0x54, 0x35, 0x24, - 0x25, 0x8B, 0xEC, 0xDA, 0x47, 0x5F, 0x5D, 0x7E, - 0xD8, 0x01, 0x51, 0xDD, 0x8F, 0xB4, 0x48, 0xDD, - 0x94, 0x99, 0x95, 0x77, 0xB3, 0x42, 0x14, 0xEB, - 0x26, 0x61, 0xE9, 0x22, 0xE3, 0x07, 0x73, 0xFB, - 0xEF, 0x38, 0x55, 0x35, 0x8F, 0xCC, 0x30, 0x1E, - 0x38, 0xE0, 0x35, 0xF4, 0x9A, 0x7C, 0xCF, 0x38, - 0x0B, 0x9E, 0xF4, 0x88, 0x4A, 0xEA, 0xF2, 0x67, - 0x9F, 0x61, 0x40, 0x34, 0x09, 0xDC, 0xBF, 0xFB, - 0x22, 0x27, 0x04, 0x8B, 0x8D, 0x85, 0x7F, 0xB2, - 0x29, 0x62, 0x25, 0x73, 0x7F, 0x46, 0x2E, 0xA3, - 0x8E, 0xAF, 0xEC, 0x55, 0x98, 0x1A, 0xEE, 0x29, - 0xA0, 0x1A, 0x5F, 0xFE, 0x5D, 0xA5, 0x76, 0x93, - 0xAB, 0x57, 0x56, 0xEA, 0xDB, 0x39, 0xAC, 0x48, - 0xBE, 0x95, 0x92, 0x2B, 0xC6, 0xE1, 0x2F, 0x36, - 0x4B, 0x08, 0x01, 0x90, 0x50, 0xD8, 0xFA, 0xF9, - 0x94, 0x4E, 0x76, 0x9B, 0x72, 0x59, 0xC2, 0x2F, - 0x61, 0x04, 0x0A, 0x9E, 0x28, 0xE5, 0x24, 0x1E, - 0x79, 0xCF, 0x8D, 0xB6, 0x52, 0xA7, 0x79, 0x5F, - 0x44, 0x98, 0xD5, 0x0E, 0x6E, 0x4B, 0x64, 0x9B, - }, - .len = 2048 - }, - .auth_tags[0] = { - .size = 64, - .data = { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, - 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, - .len = 16 - }, - .auth_tags[1] = { - .size = 128, - .data = { 0xE9, 0xA9, 0x75, 0xB6, 0xEF, 0x6F, 0x8C, 0xF1, - 0xB3, 0xA9, 0x19, 0xA4, 0xAE, 0x66, 0xBD, 0x9E }, - .len = 16 - }, - .auth_tags[2] = { - .size = 256, - .data = { 0x29, 0xC3, 0x18, 0x96, 0x54, 0xCB, 0xF5, 0xAA, - 0x4E, 0x62, 0xB6, 0xFF, 0x45, 0xA6, 0x18, 0x0C }, - .len = 16 - }, - .auth_tags[3] = { - .size = 512, - .data = { 0x3B, 0xD7, 0xC3, 0x5F, 0xE4, 0x1B, 0xC2, 0xBC, - 0xE9, 0xAC, 0xF2, 0xCE, 0xA7, 0x7B, 0x1D, 0x70 }, - .len = 16 - }, - .auth_tags[4] = { - .size = 1024, - .data = { 0xCC, 0xBB, 0xBC, 0xCF, 0x86, 0x01, 0x4D, 0x93, - 0x4B, 0x68, 0x55, 0x19, 0xA1, 0x40, 0xCD, 0xEA }, - .len = 16 - }, - .auth_tags[5] = { - .size = 1536, - .data = { 0x67, 0x31, 0x11, 0xA2, 0x58, 0xB5, 0x1C, 0x23, - 0xC0, 0x41, 0x05, 0x30, 0xC6, 0xBA, 0xFA, 0x88 }, - .len = 16 - }, - .auth_tags[6] = { - .size = 2048, - .data = { 0x03, 0x9C, 0x6B, 0xB9, 0x57, 0xBF, 0x6E, 0x86, - 0x3A, 0x09, 0x5F, 0x08, 0xA9, 0xE4, 0xF2, 0x1F }, - .len = 16 - }, - .auth_tag = { - .data = { - 0x03, 0x9C, 0x6B, 0xB9, 0x57, 0xBF, 0x6E, 0x86, - 0x3A, 0x09, 0x5F, 0x08, 0xA9, 0xE4, 0xF2, 0x1F - }, - .len = 16 - }, -}; - -static const struct gmac_test_data gmac_test_case_4 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 - }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 - }, - .len = 12 - }, - .aad = { - .data = gmac_plaintext, - .len = GMAC_LARGE_PLAINTEXT_LENGTH - }, - .plaintext = { - .data = NULL, - .len = 0 - }, - .gmac_tag = { - .data = { - 0x3f, 0x07, 0xcb, 0xb9, 0x86, 0x3a, 0xea, 0xc2, - 0x2f, 0x3a, 0x2a, 0x93, 0xd8, 0x09, 0x6b, 0xda - }, - .len = 16 - } -}; - -static const struct gcm_test_data gcm_test_case_SGL_1 = { - .key = { - .data = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, - .len = 16 - }, - .iv = { - .data = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - .len = 12 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, - 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, - 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - - }, - .len = 3120 - }, - .ciphertext = { - .data = { - 0x42, 0x83, 0x1E, 0xC2, 0x21, 0x77, 0x74, 0x24, - 0x4B, 0x72, 0x21, 0xB7, 0x84, 0xD0, 0xD4, 0x9C, - 0xE3, 0xAA, 0x21, 0x2F, 0x2C, 0x02, 0xA4, 0xE0, - 0x35, 0xC1, 0x7E, 0x23, 0x29, 0xAC, 0xA1, 0x2E, - 0x21, 0xD5, 0x14, 0xB2, 0x54, 0x66, 0x93, 0x1C, - 0x7D, 0x8F, 0x6A, 0x5A, 0xAC, 0x84, 0xAA, 0x05, - 0x1B, 0xA3, 0x0B, 0x39, 0x6A, 0x0A, 0xAC, 0x97, - 0x3D, 0x58, 0xE0, 0x91, 0x47, 0x3F, 0x59, 0x85, - 0x05, 0x99, 0x55, 0xE1, 0x36, 0x76, 0xB7, 0x14, - 0x1D, 0xF0, 0xF6, 0x8C, 0x65, 0xD5, 0xAD, 0xFA, - 0x90, 0x7F, 0x5D, 0xA2, 0xD6, 0xFD, 0xD0, 0xE5, - 0x0D, 0x9B, 0x68, 0x21, 0x49, 0x42, 0x6E, 0x13, - 0xEC, 0x22, 0x50, 0x2A, 0x30, 0x47, 0x49, 0xA1, - 0x7F, 0xC3, 0x09, 0xE0, 0x56, 0x91, 0xC4, 0x54, - 0x70, 0xD7, 0x19, 0x40, 0xCA, 0x6B, 0x65, 0x27, - 0x3E, 0xE9, 0xD1, 0x0F, 0x1C, 0xB5, 0x45, 0x0C, - 0x29, 0xE7, 0xCF, 0x94, 0x10, 0xBF, 0xA2, 0xFA, - 0x86, 0x20, 0x3F, 0x6E, 0xE9, 0x95, 0x03, 0x5C, - 0x46, 0x11, 0x75, 0xD5, 0x37, 0x71, 0x7F, 0xE0, - 0xBC, 0x9F, 0xC8, 0xE9, 0xB1, 0x08, 0x2C, 0x59, - 0x6E, 0x51, 0x4A, 0x83, 0x38, 0xC1, 0xED, 0xE2, - 0x2E, 0x88, 0x90, 0xA5, 0x7D, 0xA4, 0x93, 0x9A, - 0x30, 0xD6, 0x96, 0x34, 0x0F, 0xC4, 0xD1, 0x7E, - 0xC9, 0x8F, 0xC5, 0xBB, 0x80, 0x50, 0x85, 0x73, - 0x8B, 0x7C, 0x0A, 0xDA, 0xD3, 0x37, 0x1C, 0x8B, - 0x1E, 0xAE, 0x29, 0x54, 0x05, 0x53, 0x48, 0xE5, - 0x94, 0xF1, 0xC5, 0x1A, 0x60, 0xDC, 0x61, 0x43, - 0xCD, 0x45, 0x4C, 0x6B, 0x95, 0xAD, 0x52, 0xE0, - 0x9E, 0xD1, 0x4E, 0xCC, 0x03, 0x27, 0x50, 0xD4, - 0xEB, 0xBD, 0x71, 0xA6, 0xD0, 0x2B, 0x23, 0xC0, - 0x9E, 0x5F, 0x34, 0xFD, 0xDE, 0xC1, 0x43, 0x35, - 0x77, 0xFB, 0xFD, 0xDF, 0xA0, 0x28, 0x42, 0x3B, - 0x0F, 0x2D, 0x31, 0xB4, 0x7A, 0xA8, 0x2F, 0xDF, - 0x58, 0xB5, 0x00, 0x19, 0x8D, 0xEB, 0x2C, 0xBB, - 0xAE, 0xAD, 0x74, 0x7F, 0x25, 0xAA, 0x24, 0x3E, - 0xCD, 0x89, 0x5E, 0x05, 0xD3, 0xBA, 0x0E, 0x9A, - 0x34, 0x7B, 0xE0, 0x11, 0xD2, 0xBA, 0x5A, 0x51, - 0xB4, 0x0D, 0xEE, 0x61, 0x73, 0xFC, 0xD2, 0x01, - 0x2D, 0x52, 0x3E, 0x37, 0x55, 0x3F, 0x58, 0xA8, - 0x1C, 0x8F, 0x1D, 0xD6, 0x3C, 0x39, 0x06, 0x18, - 0x65, 0x60, 0x55, 0x19, 0xAD, 0x1E, 0x78, 0xE9, - 0xF7, 0xF5, 0xFC, 0xCD, 0x5F, 0xF1, 0x34, 0x0C, - 0xA6, 0xFD, 0x1E, 0x9E, 0xB3, 0xCE, 0x2E, 0x10, - 0xFB, 0x98, 0xDD, 0x0E, 0x09, 0x5D, 0x4E, 0x58, - 0x75, 0x9A, 0x54, 0x74, 0xFB, 0x40, 0x76, 0x55, - 0x0E, 0x3E, 0xA4, 0xCE, 0x56, 0xA5, 0xE0, 0x53, - 0xB7, 0xAD, 0x36, 0x99, 0x6E, 0xCD, 0xC2, 0x90, - 0x6E, 0xEA, 0xBC, 0x21, 0xAC, 0x31, 0xFF, 0x2B, - 0x00, 0xA7, 0x5E, 0xC1, 0x7A, 0xF1, 0xAB, 0x24, - 0xA3, 0x40, 0x0B, 0xEB, 0x16, 0x62, 0x35, 0x1E, - 0xE9, 0xA5, 0xD3, 0x7E, 0xAA, 0x7E, 0x28, 0xA8, - 0x3F, 0xD8, 0x0A, 0x04, 0x12, 0x0F, 0xFF, 0x68, - 0x10, 0x85, 0x22, 0xD6, 0x05, 0x6A, 0x3A, 0xCB, - 0xC0, 0xCF, 0x8C, 0x20, 0xF0, 0x34, 0x32, 0xAA, - 0x76, 0x93, 0xE2, 0x23, 0x4F, 0xF2, 0xE6, 0x84, - 0x3B, 0xD4, 0xF3, 0x5D, 0xF3, 0x17, 0xEE, 0x27, - 0x67, 0xC3, 0x01, 0x6F, 0x32, 0xDE, 0xF6, 0xF6, - 0x87, 0xE9, 0x82, 0xEF, 0x1F, 0xA1, 0xE2, 0x68, - 0xF8, 0x5D, 0x49, 0x92, 0x47, 0x01, 0x75, 0x87, - 0x52, 0xD3, 0x54, 0xAE, 0x3B, 0xB7, 0xB2, 0x07, - 0x0F, 0x62, 0x7B, 0xF7, 0x50, 0x97, 0x9A, 0x4A, - 0x98, 0x65, 0x23, 0xA3, 0x5D, 0x76, 0x0A, 0x9C, - 0x6C, 0xE7, 0x89, 0xAD, 0x86, 0x70, 0xE7, 0x16, - 0x5F, 0x2F, 0x2E, 0x97, 0x29, 0x31, 0xF0, 0x60, - 0x33, 0x2C, 0xD7, 0xAA, 0xD6, 0xF0, 0x50, 0xB8, - 0xBD, 0x29, 0xA8, 0xA9, 0xAC, 0x5E, 0x0A, 0x3A, - 0x59, 0x34, 0x9A, 0x92, 0x25, 0x71, 0xB3, 0x16, - 0xC5, 0xD3, 0xA4, 0x15, 0x75, 0x9A, 0xB5, 0x78, - 0x6E, 0xCF, 0xAF, 0xC0, 0x39, 0x28, 0x44, 0x21, - 0xBB, 0xE8, 0x32, 0xAB, 0xCB, 0xF8, 0x4B, 0xE7, - 0x63, 0x9C, 0x56, 0xE7, 0xB2, 0xD6, 0x23, 0x17, - 0xDE, 0x92, 0xE9, 0x22, 0xC3, 0x36, 0xA5, 0xAC, - 0xA9, 0x98, 0x34, 0xAA, 0xFB, 0x03, 0x33, 0x33, - 0xBE, 0xD8, 0x22, 0x7F, 0xFA, 0x34, 0xA0, 0x35, - 0xC8, 0xA0, 0xDC, 0x35, 0x82, 0x06, 0x58, 0xE6, - 0xBF, 0x7C, 0x4F, 0x63, 0x5D, 0x62, 0x64, 0x67, - 0x0D, 0x07, 0x7F, 0x24, 0x4A, 0x23, 0xBC, 0x35, - 0xE0, 0x92, 0x6F, 0x51, 0xE7, 0x25, 0x97, 0xB9, - 0x14, 0x35, 0x2B, 0x48, 0xAC, 0x6F, 0x54, 0xDF, - 0xF2, 0xB4, 0xB0, 0xE0, 0xD3, 0x28, 0x0D, 0x67, - 0x48, 0x28, 0x0A, 0x16, 0x9C, 0x87, 0x73, 0xB7, - 0x9C, 0x2B, 0xB5, 0x43, 0xC9, 0x46, 0xB9, 0x19, - 0x01, 0xAA, 0xDE, 0x75, 0xA6, 0x0F, 0xB5, 0x72, - 0x6A, 0x51, 0xE3, 0xAC, 0xE0, 0xF6, 0x96, 0x13, - 0xBB, 0xC7, 0x08, 0x13, 0x9E, 0x47, 0xAA, 0xF5, - 0x9E, 0x69, 0xAC, 0x95, 0x29, 0xFE, 0xFF, 0x99, - 0xB2, 0x52, 0x72, 0x45, 0xF2, 0x07, 0xEB, 0x3C, - 0x0F, 0x75, 0x29, 0x73, 0x0D, 0x77, 0x58, 0x83, - 0xCB, 0xDD, 0xE7, 0x68, 0x1C, 0xE3, 0xD1, 0xA4, - 0x5D, 0xD1, 0xAB, 0xB4, 0x5A, 0x3F, 0x27, 0x66, - 0xDA, 0xB4, 0x81, 0x65, 0xCE, 0x1A, 0x9A, 0x7D, - 0xC7, 0xB6, 0x31, 0xDE, 0x83, 0xC2, 0x7C, 0xF8, - 0xD3, 0xC7, 0x97, 0x28, 0x50, 0xF2, 0x95, 0xFC, - 0xA7, 0xB2, 0xA6, 0x46, 0xEF, 0x10, 0xD2, 0x38, - 0x93, 0x14, 0x8D, 0xA7, 0x09, 0x17, 0x42, 0x7A, - 0x85, 0xB9, 0x42, 0x71, 0x2A, 0x51, 0x9B, 0x66, - 0x71, 0x12, 0x57, 0xB7, 0xBD, 0x26, 0xB7, 0x91, - 0xF8, 0x84, 0x44, 0x35, 0xAD, 0x6F, 0xCB, 0xD7, - 0xFC, 0xA1, 0x28, 0x77, 0x09, 0x5B, 0x6D, 0x52, - 0x43, 0xA1, 0xE2, 0x0A, 0x7E, 0x5A, 0x84, 0x45, - 0x20, 0xDE, 0xA5, 0x73, 0x1D, 0x37, 0x6E, 0xD8, - 0x7A, 0x0D, 0x91, 0xBE, 0xF4, 0xB3, 0x89, 0xE9, - 0x1F, 0x1E, 0xF6, 0xD5, 0x37, 0xB4, 0x3C, 0x1D, - 0xBE, 0x0D, 0x5B, 0x01, 0xB0, 0x8B, 0xCE, 0x3E, - 0x6D, 0x8B, 0x99, 0x9A, 0xC5, 0xAE, 0xFE, 0xA9, - 0x78, 0x34, 0x20, 0xA7, 0x6C, 0x7D, 0x46, 0x72, - 0x37, 0xAF, 0xFD, 0x17, 0x59, 0xED, 0x83, 0x5B, - 0xEB, 0x6E, 0x4A, 0xF1, 0xE6, 0x0D, 0x44, 0x92, - 0x65, 0x8E, 0x97, 0xD6, 0x83, 0x6E, 0x97, 0xCA, - 0x4C, 0x0A, 0xCE, 0x32, 0x2A, 0xAD, 0x22, 0x73, - 0xCB, 0xCB, 0xC3, 0x55, 0x08, 0x63, 0x23, 0xC2, - 0x31, 0x24, 0x90, 0x54, 0x99, 0xB2, 0x8C, 0xC7, - 0x8A, 0xB6, 0xFF, 0xC2, 0x75, 0xB1, 0xD9, 0x3D, - 0x95, 0xDC, 0xB6, 0xCF, 0x11, 0x74, 0x06, 0x54, - 0x03, 0xE3, 0x9B, 0x49, 0xE4, 0xF2, 0x73, 0x04, - 0xF7, 0xDC, 0x71, 0xD7, 0xFA, 0x3C, 0xD2, 0x61, - 0x77, 0x61, 0xB3, 0xDB, 0x6B, 0xCE, 0xCA, 0xFF, - 0xF0, 0xAD, 0xBC, 0x94, 0xC8, 0xF8, 0xD5, 0xF4, - 0x38, 0xA3, 0x61, 0xAA, 0x8C, 0x96, 0xEE, 0x56, - 0xAC, 0xB4, 0x42, 0xBA, 0x1A, 0xE1, 0x70, 0x98, - 0x1F, 0x9A, 0x6F, 0x98, 0xB9, 0x13, 0x46, 0xAB, - 0x0B, 0xCD, 0xA3, 0x7B, 0x0C, 0xCB, 0x8F, 0x72, - 0x23, 0xCF, 0x9E, 0xD8, 0xBB, 0x3F, 0x32, 0x27, - 0x54, 0xB8, 0x60, 0x64, 0x83, 0xAE, 0x22, 0xD1, - 0x6A, 0xC9, 0xF8, 0x13, 0xC4, 0xE4, 0xFF, 0x97, - 0xD8, 0x92, 0xA3, 0xD1, 0xD4, 0x86, 0xD7, 0xC3, - 0xBB, 0x40, 0xA2, 0x45, 0x78, 0xB1, 0xDB, 0x80, - 0xC6, 0x8D, 0x0A, 0xF0, 0xC3, 0xC2, 0xE3, 0x48, - 0xA1, 0x05, 0xC2, 0x32, 0xC8, 0x6C, 0x50, 0xA8, - 0x06, 0x58, 0xBE, 0x6C, 0x7D, 0x22, 0xD6, 0x0D, - 0x74, 0x40, 0xCE, 0xD6, 0x64, 0xD6, 0x47, 0xD0, - 0xBF, 0xF1, 0x5C, 0x54, 0xF9, 0x06, 0x3F, 0x3D, - 0x86, 0xBA, 0xF2, 0x0F, 0x5E, 0x2C, 0x01, 0xCC, - 0xD9, 0xC7, 0xB1, 0x4A, 0xB3, 0xD7, 0x26, 0xCC, - 0xC3, 0x7A, 0x74, 0x2C, 0xE1, 0x22, 0x65, 0xA0, - 0x5B, 0xCA, 0xF4, 0xE1, 0x7D, 0xE1, 0x56, 0xFD, - 0x95, 0x10, 0xC6, 0xA1, 0x4A, 0xE8, 0x6B, 0x34, - 0x4E, 0x71, 0x60, 0x77, 0x0F, 0x03, 0xDD, 0xFE, - 0xC8, 0x59, 0x54, 0x6C, 0xD4, 0x4A, 0x55, 0x24, - 0x35, 0x21, 0x60, 0x73, 0xDF, 0x6F, 0xE7, 0x3C, - 0xC2, 0xF0, 0xDA, 0xA9, 0xE5, 0x8C, 0xAC, 0xB6, - 0xFD, 0x2E, 0xF7, 0xA0, 0x18, 0xA7, 0x55, 0x47, - 0xD1, 0xCB, 0x9E, 0xAA, 0x58, 0x54, 0x3B, 0x37, - 0x18, 0xB5, 0xC1, 0xBB, 0x41, 0x59, 0xE4, 0x29, - 0x44, 0x13, 0x90, 0x6A, 0xF7, 0xD1, 0xB3, 0x71, - 0xB6, 0x6E, 0xF6, 0x5D, 0x2E, 0x0E, 0x6C, 0x4C, - 0x7B, 0xF7, 0xB6, 0x21, 0xD4, 0xFC, 0x47, 0x8C, - 0x9B, 0x0A, 0x90, 0xAC, 0x11, 0x52, 0x86, 0x07, - 0x24, 0xDA, 0xA9, 0x49, 0x50, 0xD9, 0xDC, 0xE2, - 0x19, 0x87, 0x73, 0x88, 0xC3, 0xE4, 0xED, 0xC9, - 0x1C, 0xA8, 0x7E, 0x39, 0x48, 0x91, 0x10, 0xAB, - 0xFC, 0x3C, 0x1E, 0xEE, 0x08, 0xA1, 0xB9, 0xB4, - 0xF4, 0xA9, 0x8D, 0xD0, 0x84, 0x7C, 0x8E, 0x54, - 0xEF, 0x05, 0xC3, 0x2A, 0x0B, 0x8D, 0x3C, 0x71, - 0xE7, 0x37, 0x27, 0x16, 0x07, 0xA2, 0x8F, 0x7A, - 0x86, 0x05, 0x56, 0xA3, 0xB2, 0x75, 0xC5, 0x2C, - 0xD4, 0x52, 0x60, 0x68, 0xA6, 0x6A, 0x48, 0xB6, - 0x92, 0x50, 0xEC, 0x22, 0xAD, 0x01, 0x75, 0x57, - 0xAF, 0xDF, 0x0F, 0x36, 0x93, 0x59, 0xF9, 0xE3, - 0xA1, 0x41, 0x3B, 0x60, 0xB3, 0x13, 0x12, 0x50, - 0x4B, 0x18, 0x20, 0xB9, 0x7B, 0x88, 0x27, 0x81, - 0xB1, 0xDA, 0xCA, 0x6F, 0x63, 0x95, 0x40, 0xA1, - 0x42, 0xE2, 0x14, 0xB8, 0x2B, 0x10, 0xB9, 0xDA, - 0xE7, 0x30, 0x91, 0x13, 0x52, 0xC9, 0xA3, 0x5C, - 0xD7, 0xBB, 0x39, 0x8F, 0x9A, 0xB8, 0xC5, 0xAF, - 0xC6, 0x3E, 0x65, 0x90, 0x91, 0x8C, 0x9F, 0xDD, - 0x84, 0xFB, 0xAD, 0x72, 0x4D, 0xD1, 0x42, 0xAD, - 0x0A, 0x1B, 0x3A, 0xC6, 0x06, 0x03, 0x19, 0xCB, - 0x31, 0x8C, 0x18, 0xD4, 0xEE, 0x90, 0x94, 0x3C, - 0x44, 0xDC, 0xFB, 0x78, 0x5C, 0xB5, 0xE3, 0x2F, - 0x89, 0x74, 0x0E, 0x28, 0x9C, 0xE4, 0xB4, 0xD2, - 0xE3, 0x5A, 0x32, 0xF9, 0xC0, 0x81, 0x6A, 0x38, - 0xC2, 0xCF, 0xD8, 0xD9, 0x3E, 0xAD, 0xF9, 0xB1, - 0xA2, 0x55, 0x64, 0x1E, 0xEC, 0xF5, 0x0D, 0xB1, - 0x8D, 0x07, 0x4E, 0xE5, 0x59, 0xE1, 0xE7, 0xFE, - 0x4C, 0xCF, 0x11, 0xF8, 0x27, 0xC2, 0x29, 0xE2, - 0xAF, 0x74, 0xAA, 0x53, 0x81, 0xD2, 0xFD, 0x5A, - 0xF1, 0xEB, 0x96, 0x2C, 0x3E, 0x9B, 0xC2, 0x74, - 0xFB, 0x65, 0x08, 0xA2, 0x63, 0xD3, 0xC5, 0x51, - 0xAF, 0x19, 0x8B, 0x34, 0x8B, 0x7D, 0xB7, 0x97, - 0x55, 0x97, 0x6D, 0x01, 0x5D, 0x98, 0xAA, 0x67, - 0x11, 0xBD, 0xC2, 0x99, 0x2F, 0xB4, 0xCA, 0x04, - 0x36, 0xF0, 0xB1, 0xA0, 0xBD, 0xA3, 0x4F, 0x4F, - 0xB6, 0x7B, 0xF5, 0x1E, 0x38, 0x87, 0xC2, 0x38, - 0x99, 0x5C, 0xE9, 0x2D, 0xDF, 0xAF, 0x5A, 0xF3, - 0x7A, 0x17, 0x70, 0x35, 0xEC, 0xD5, 0x19, 0xF7, - 0xB0, 0x21, 0x1E, 0x77, 0x30, 0x23, 0x54, 0x26, - 0x61, 0x4E, 0xB9, 0x02, 0xDE, 0xF4, 0x86, 0x93, - 0x47, 0x28, 0x43, 0x47, 0xB0, 0x56, 0xDC, 0x84, - 0x3E, 0x6A, 0x6B, 0xEA, 0x4D, 0x63, 0xFE, 0x56, - 0x5E, 0xF7, 0x6B, 0x1E, 0x5B, 0x63, 0xF1, 0x07, - 0x20, 0x2E, 0x9B, 0xEE, 0xDC, 0x70, 0x5E, 0x36, - 0x59, 0xE3, 0x3D, 0xA6, 0x0E, 0x50, 0x71, 0x06, - 0xDD, 0x8B, 0x3C, 0xF7, 0xEC, 0x3C, 0x7A, 0x08, - 0x8D, 0x4E, 0x6A, 0x08, 0xB0, 0xEE, 0x50, 0xE0, - 0xF9, 0x0E, 0x40, 0xC0, 0x11, 0xBF, 0x8A, 0x17, - 0x63, 0x9D, 0x59, 0x14, 0x0E, 0x25, 0x94, 0x09, - 0xE6, 0x34, 0xEC, 0x0F, 0xE4, 0x7C, 0x59, 0xCD, - 0x99, 0x85, 0x8E, 0x0F, 0xA1, 0x9E, 0x84, 0xBC, - 0x13, 0x20, 0x5F, 0x56, 0x26, 0x10, 0x1A, 0x77, - 0x77, 0x7B, 0x4B, 0x68, 0x13, 0x8A, 0x2C, 0xA5, - 0x01, 0xBF, 0xAD, 0xF2, 0x2C, 0xD9, 0x4B, 0x24, - 0x4C, 0xF5, 0x96, 0x4E, 0xD8, 0xE8, 0x98, 0xA8, - 0x9C, 0x63, 0x2F, 0xC3, 0x26, 0xC7, 0x74, 0x83, - 0x05, 0xED, 0x67, 0x02, 0x85, 0xAD, 0x1D, 0x0E, - 0xA9, 0xD6, 0xE1, 0xC7, 0x39, 0xA0, 0x6E, 0x72, - 0xCE, 0x56, 0x6C, 0xB8, 0x4A, 0xDE, 0x11, 0xA2, - 0xBF, 0xC1, 0x84, 0x98, 0x8F, 0xCA, 0x79, 0x75, - 0xC4, 0x9F, 0x45, 0x16, 0xBC, 0xB1, 0xF4, 0x03, - 0x76, 0x6E, 0xD5, 0x46, 0x60, 0xD7, 0x1D, 0xF6, - 0xD9, 0xBF, 0xF8, 0x71, 0xEB, 0x09, 0x33, 0x56, - 0xE6, 0xEC, 0x72, 0xC8, 0xB3, 0x47, 0x14, 0x2C, - 0x24, 0xA1, 0x1F, 0x16, 0xBE, 0x77, 0xFA, 0x9F, - 0x6B, 0x83, 0x05, 0x03, 0x4D, 0x6F, 0xC9, 0x76, - 0x69, 0x8D, 0xD7, 0x91, 0x26, 0x2B, 0x1C, 0x84, - 0xF2, 0x2B, 0x23, 0xA6, 0xFF, 0x7B, 0xEE, 0xCC, - 0x4E, 0x03, 0x8A, 0x80, 0x9E, 0x88, 0x96, 0xC3, - 0x7A, 0x3E, 0x1B, 0xAC, 0x40, 0x84, 0xD1, 0x64, - 0x89, 0x5F, 0xE3, 0x41, 0x89, 0x77, 0x4B, 0x28, - 0x83, 0xCA, 0x78, 0x4F, 0x36, 0xC8, 0xCE, 0x53, - 0x75, 0x39, 0x3A, 0x58, 0x92, 0x91, 0xF5, 0xA7, - 0x6A, 0xD0, 0xB2, 0xBB, 0xFC, 0x8E, 0x3B, 0xFC, - 0x83, 0x67, 0x42, 0xAA, 0x18, 0x51, 0x48, 0xD4, - 0xC4, 0x85, 0x60, 0xA4, 0x2D, 0xD4, 0x4E, 0xA1, - 0xF0, 0xB6, 0x41, 0x98, 0x6F, 0x84, 0xDE, 0x0C, - 0x03, 0x8D, 0x83, 0x4A, 0x71, 0xBB, 0x32, 0x8B, - 0x83, 0xF7, 0xD8, 0x08, 0x05, 0xA4, 0x48, 0xFE, - 0xCA, 0xBB, 0x21, 0xA8, 0xBA, 0x2A, 0xD2, 0x65, - 0x4E, 0xEF, 0xA1, 0x8F, 0x01, 0x09, 0xC6, 0x8C, - 0xE5, 0x35, 0x32, 0xBB, 0x19, 0x15, 0xAB, 0x7A, - 0xFD, 0x29, 0x76, 0xF9, 0xD1, 0xC5, 0x3E, 0xFD, - 0x7A, 0x74, 0xBC, 0x41, 0x4F, 0x2C, 0x79, 0x6F, - 0x45, 0x4E, 0xFD, 0x88, 0x49, 0x9A, 0x90, 0x6F, - 0x65, 0x00, 0xC8, 0x08, 0xB8, 0x3B, 0x40, 0x06, - 0x9A, 0x98, 0x5B, 0x6A, 0xD3, 0x5E, 0x32, 0x0E, - 0xB0, 0x21, 0xE6, 0x2D, 0xEF, 0x7B, 0x99, 0x1B, - 0xAF, 0x96, 0x20, 0x12, 0xE9, 0x31, 0xDA, 0x20, - 0xB0, 0x27, 0x99, 0xC7, 0x14, 0x56, 0x3A, 0x08, - 0x46, 0xA4, 0xB2, 0x0C, 0x6C, 0x1F, 0x1B, 0xAF, - 0x9F, 0x90, 0x03, 0xBB, 0x03, 0xE0, 0x20, 0xE9, - 0x45, 0x33, 0xA0, 0x3E, 0x01, 0x2C, 0xA7, 0x4A, - 0xCC, 0xC6, 0xF5, 0xA3, 0x35, 0x0D, 0xE1, 0x5E, - 0x90, 0x0B, 0xAC, 0x9A, 0x05, 0x79, 0xB2, 0x90, - 0x39, 0xEE, 0xC8, 0x20, 0x55, 0xB3, 0x71, 0x46, - 0xAC, 0x92, 0x42, 0x85, 0xD5, 0x12, 0x03, 0x8D, - 0xBC, 0x82, 0xE7, 0x5A, 0x6E, 0x2E, 0x2C, 0xC0, - 0xB6, 0x44, 0xF8, 0xBB, 0x5F, 0x7A, 0x42, 0x86, - 0x28, 0xF0, 0x9B, 0xF9, 0x17, 0xDD, 0x35, 0x2F, - 0x56, 0xE4, 0x63, 0xFF, 0xEC, 0x87, 0xC5, 0x53, - 0xBF, 0x64, 0xB2, 0xDA, 0xDE, 0xC1, 0x6C, 0x85, - 0x82, 0x51, 0x40, 0x41, 0xC9, 0x7A, 0x0A, 0xB8, - 0xB2, 0x75, 0x03, 0x88, 0x22, 0x6D, 0x76, 0x6E, - 0x2D, 0x2B, 0x73, 0xCB, 0x48, 0xC4, 0xED, 0xE0, - 0x96, 0xFA, 0x36, 0x9F, 0x99, 0xC7, 0x97, 0xDE, - 0x6D, 0xFC, 0x69, 0x86, 0x57, 0x5F, 0xB9, 0x93, - 0x78, 0x5C, 0x07, 0x64, 0x61, 0xD0, 0x41, 0x14, - 0x32, 0xED, 0xC0, 0xE4, 0xAC, 0xFC, 0x10, 0x0D, - 0xAF, 0xEE, 0xDA, 0xB3, 0x6D, 0xB8, 0x7C, 0x10, - 0xD5, 0x3B, 0x88, 0xE1, 0x15, 0xE1, 0xA4, 0x27, - 0xFE, 0xEE, 0x0A, 0xC8, 0x95, 0xCF, 0xCA, 0x99, - 0x98, 0x1D, 0xF3, 0x0E, 0xB8, 0x03, 0xD5, 0x51, - 0x4B, 0x56, 0xB9, 0x07, 0x85, 0x58, 0x17, 0x51, - 0x16, 0xC4, 0x86, 0xBB, 0xD3, 0x50, 0x01, 0x0E, - 0x7B, 0x9C, 0xEF, 0xF0, 0x28, 0x4A, 0xD7, 0x3D, - 0x1E, 0x3A, 0xBB, 0xCF, 0x2C, 0x90, 0x12, 0x2A, - 0xB3, 0x90, 0x72, 0xE3, 0x93, 0x81, 0xE8, 0xA4, - 0xEF, 0x8F, 0xD9, 0x45, 0x4F, 0xB1, 0xD0, 0x21, - 0xDA, 0x20, 0x5C, 0xE9, 0x41, 0x41, 0x4E, 0x48, - 0x95, 0x4D, 0x5A, 0xB3, 0xE5, 0x8B, 0xFC, 0xDE, - 0xB9, 0x7B, 0x93, 0xBE, 0xA2, 0x74, 0x1B, 0xFA, - 0xED, 0xCC, 0x0E, 0xDD, 0x96, 0x13, 0x2C, 0xAC, - 0xDE, 0x2B, 0x2D, 0x8A, 0x30, 0x5A, 0xB8, 0x4B, - 0x08, 0x2C, 0x74, 0xF7, 0xB4, 0x45, 0xD3, 0xA5, - 0x62, 0x87, 0xCA, 0x16, 0xEB, 0x49, 0x46, 0x0C, - 0x87, 0x7F, 0x11, 0x1D, 0x22, 0x66, 0x0A, 0x38, - 0x90, 0x3A, 0x31, 0x38, 0x73, 0xB2, 0xD5, 0x5E, - 0x06, 0xC4, 0x1E, 0x3D, 0xB7, 0x52, 0xB8, 0xE5, - 0xC0, 0xF9, 0x72, 0xBC, 0x7A, 0x8A, 0xD3, 0xB4, - 0x1D, 0xA9, 0x93, 0x3B, 0x7E, 0xFF, 0x8E, 0xA0, - 0x96, 0x52, 0xE9, 0x9E, 0x60, 0x4C, 0x02, 0x90, - 0xE5, 0x46, 0x92, 0xB3, 0xB8, 0x24, 0xE9, 0xD0, - 0xCE, 0xD3, 0x0B, 0xCD, 0x8B, 0xE8, 0x72, 0xEA, - 0x6E, 0xBF, 0x2B, 0x99, 0x6F, 0xC0, 0x65, 0xE8, - 0x92, 0x30, 0x03, 0x28, 0xA9, 0xB0, 0xA7, 0x03, - 0x92, 0x2C, 0xC8, 0x38, 0x8C, 0x38, 0x56, 0xEE, - 0xDB, 0x39, 0xBD, 0x7E, 0xE9, 0x8D, 0xDB, 0xC1, - 0xD5, 0x71, 0xC7, 0x84, 0xF3, 0xB2, 0x23, 0x22, - 0xB5, 0x98, 0xB3, 0x36, 0xF1, 0xC4, 0xB1, 0xA4, - 0xF2, 0x84, 0x24, 0xE5, 0x97, 0x48, 0x34, 0x43, - 0xEF, 0xD9, 0xF4, 0x10, 0xE4, 0x13, 0xEE, 0x6C, - 0xE7, 0x5D, 0x9B, 0xBA, 0x35, 0xF5, 0x7D, 0xE5, - 0xBF, 0x8A, 0xCC, 0x3D, 0x28, 0xCF, 0xE8, 0x90, - 0xE3, 0xCF, 0x01, 0x69, 0xD7, 0xC0, 0xD2, 0x2C, - 0xC2, 0x9B, 0x89, 0xF2, 0xA9, 0x83, 0xA2, 0xA9, - 0x12, 0xAA, 0x56, 0xD8, 0xCB, 0xA5, 0x8B, 0x0A, - 0x03, 0xC1, 0xE1, 0x8E, 0x02, 0x36, 0x3D, 0x8F, - 0x58, 0x4D, 0xEB, 0x93, 0x91, 0xC6, 0xE7, 0x22, - 0xCE, 0xA8, 0x02, 0xD2, 0x82, 0x0D, 0x43, 0x4D, - 0x4E, 0x11, 0xF8, 0x7B, 0x45, 0xD0, 0x23, 0xF7, - 0x14, 0x35, 0x16, 0xA4, 0x0B, 0xAD, 0xFE, 0xE2, - 0x2B, 0xFD, 0xF7, 0x17, 0xA9, 0x93, 0x77, 0x82, - 0x45, 0x6E, 0x51, 0x1F, 0x5C, 0x2C, 0x5F, 0xFF, - 0x1A, 0xA3, 0x0E, 0x29, 0xA5, 0x1D, 0xFD, 0x0E, - 0xDD, 0x14, 0xF6, 0x69, 0x20, 0x15, 0xFD, 0xBB, - 0xF8, 0xAF, 0x3D, 0xF3, 0xCC, 0xB8, 0x7E, 0x64, - 0xED, 0x99, 0xF3, 0x1D, 0xFC, 0x96, 0xA2, 0x0A, - 0x9C, 0xC2, 0x9B, 0xD7, 0x03, 0xA6, 0x79, 0x3B, - 0x16, 0x0C, 0x6C, 0x5C, 0x2B, 0x61, 0x0E, 0x48, - 0x96, 0x5C, 0x46, 0x7F, 0xC3, 0xCD, 0x3C, 0x10, - 0x30, 0x8F, 0xC4, 0xB5, 0x92, 0x46, 0x1C, 0xDF, - 0x10, 0xEE, 0x43, 0x27, 0x42, 0x70, 0xD2, 0xC4, - 0x5E, 0x77, 0x78, 0x0E, 0x0E, 0xC3, 0x8B, 0x72, - 0xA0, 0xFC, 0x4C, 0x0F, 0x5D, 0xBE, 0xBE, 0x07, - 0x5B, 0x53, 0x38, 0xC8, 0x96, 0x82, 0x2D, 0x2D, - 0x8E, 0xA8, 0x6C, 0x68, 0x34, 0x42, 0x31, 0x90, - 0xD6, 0x4D, 0x29, 0xA9, 0x90, 0x95, 0x19, 0xD6, - 0x8F, 0x2F, 0xF4, 0xD3, 0x71, 0x21, 0xB7, 0x7D, - 0x51, 0xA6, 0x15, 0xE5, 0xDA, 0x08, 0x6A, 0x23, - 0xDE, 0x6C, 0xBA, 0xCF, 0x84, 0xF1, 0x47, 0x25, - 0x4A, 0xF1, 0x2F, 0x24, 0xED, 0x3B, 0xED, 0xF0, - 0xA7, 0x48, 0xAE, 0x58, 0x7F, 0x0B, 0x3B, 0x78, - 0xCE, 0x94, 0x32, 0x82, 0x63, 0x22, 0x67, 0xAA, - 0x45, 0x37, 0xCC, 0x43, 0xD5, 0x10, 0x59, 0x5B, - 0x09, 0xC6, 0x1C, 0x32, 0xCD, 0x19, 0xA2, 0x3C, - 0x2B, 0x84, 0x03, 0xD5, 0x97, 0x20, 0xE7, 0xFB, - 0x2D, 0x0A, 0x3C, 0x5C, 0xFD, 0x39, 0x9C, 0xDE, - 0x02, 0x3D, 0xC7, 0xDD, 0x51, 0xDE, 0x99, 0xB3, - 0x65, 0x00, 0x60, 0xCF, 0xAE, 0xCD, 0xE2, 0x83, - 0xD5, 0x36, 0x2C, 0x89, 0x28, 0x6D, 0xC3, 0x6A, - 0x80, 0xCD, 0x1A, 0xC3, 0x75, 0x11, 0x7E, 0x65, - 0x2A, 0x44, 0x9D, 0xB5, 0x12, 0x2A, 0x78, 0xD0, - 0x4D, 0xF8, 0x5E, 0xBF, 0xEC, 0x6B, 0x60, 0xD2, - 0x89, 0x92, 0x5E, 0x17, 0xDA, 0x33, 0x83, 0xDB, - 0xED, 0xF4, 0x5E, 0x82, 0xE9, 0x04, 0xD7, 0xE0, - 0xA4, 0x1B, 0xFE, 0x32, 0x93, 0x05, 0x2C, 0xCF, - 0xA2, 0xAE, 0x83, 0xCA, 0x2F, 0x5E, 0x47, 0x1C, - 0x85, 0x0D, 0x01, 0xE5, 0x44, 0x3D, 0xE4, 0x58, - 0x8E, 0xC0, 0x46, 0x05, 0x95, 0xBE, 0x59, 0xED, - 0x0F, 0x7B, 0xA1, 0xF7, 0xDB, 0x2C, 0x79, 0x86, - 0xE9, 0x54, 0x98, 0xA6, 0x2A, 0xD0, 0xFE, 0xC9, - 0x59, 0x1D, 0x31, 0xC6, 0x27, 0x83, 0x2C, 0x12, - 0x9C, 0xE1, 0x43, 0x3C, 0xEC, 0x65, 0x3B, 0xEF, - 0xFD, 0x92, 0xBC, 0x0E, 0x38, 0xBA, 0x56, 0x1C, - 0xC0, 0x81, 0x9E, 0xBE, 0x76, 0x59, 0x88, 0xA4, - 0x0C, 0x6B, 0xD9, 0x7C, 0xD6, 0x8C, 0x32, 0xCD, - 0x3F, 0xB6, 0xEF, 0xBF, 0xA6, 0xC7, 0xC9, 0xD3, - 0x02, 0xB0, 0x3B, 0xFF, 0xFC, 0x4A, 0x97, 0x14, - 0xFF, 0xF2, 0x48, 0xFE, 0x1B, 0xCE, 0x7D, 0x24, - 0xA1, 0xD6, 0x03, 0xB0, 0x2F, 0xAA, 0xF7, 0x71, - 0xC9, 0x0E, 0xCB, 0x57, 0xBA, 0xEF, 0xB5, 0x65, - 0xE1, 0x44, 0xE4, 0x6A, 0xEB, 0xE8, 0x2B, 0x8F, - 0x06, 0x23, 0x7A, 0xA9, 0x70, 0xAE, 0x48, 0x65, - 0x94, 0xEE, 0xA5, 0x94, 0x78, 0x7D, 0x09, 0xF8, - 0xB5, 0x4D, 0x64, 0x67, 0x10, 0x16, 0xA2, 0xFC, - 0x49, 0x93, 0x76, 0x71, 0xED, 0x56, 0x25, 0xB5, - 0x87, 0xE8, 0x84, 0x16, 0x55, 0xE1, 0x1E, 0x34, - 0xE3, 0xB2, 0x49, 0x8F, 0xDC, 0xDA, 0xC3, 0x17, - 0x82, 0x0E, 0x19, 0xD7, 0xE0, 0x09, 0xD7, 0xD9, - 0x59, 0x6B, 0x55, 0x60, 0x1C, 0x1B, 0x02, 0xE8, - 0xD1, 0x90, 0xF6, 0x3E, 0x94, 0x4A, 0x12, 0x0C, - 0xBB, 0x69, 0xFD, 0x7C, 0xA0, 0xDD, 0x5F, 0x93, - 0x9F, 0xFE, 0x2E, 0x79, 0xDB, 0xBE, 0x6F, 0x85, - 0xAD, 0x9B, 0xDE, 0xAA, 0x10, 0xCA, 0xDB, 0xF2, - 0xF9, 0xD0, 0x54, 0x15, 0x00, 0xF0, 0x6F, 0x86, - 0x16, 0xF6, 0xA8, 0xA4, 0x08, 0x7B, 0x50, 0xF1, - 0x35, 0xAC, 0xB6, 0xBB, 0x8B, 0xA0, 0x86, 0x3B, - 0x3B, 0xDA, 0x9F, 0x89, 0xB5, 0x9C, 0x44, 0x41, - 0x6A, 0xFD, 0x8A, 0x79, 0xA0, 0xFB, 0x7D, 0x1B, - 0xE8, 0xC4, 0xA7, 0x3F, 0x66, 0x97, 0xA9, 0xF8, - 0xEA, 0x0C, 0x30, 0x81, 0x63, 0xE4, 0xE3, 0x84, - 0x62, 0xC5, 0x19, 0xFB, 0x00, 0xD6, 0x72, 0xE6, - 0xC9, 0x6C, 0xDB, 0xEB, 0xF3, 0x6F, 0xDB, 0xE7, - 0x00, 0x53, 0xCE, 0x1D, 0xE5, 0xF5, 0x53, 0x18, - 0xE5, 0xAA, 0xDA, 0x90, 0x7B, 0xCB, 0x2B, 0x74, - 0xED, 0x70, 0xFE, 0x90, 0xA8, 0xC8, 0x80, 0x2B, - 0x93, 0x08, 0xDB, 0x6A, 0x0F, 0x3D, 0xA1, 0xFA, - 0xB6, 0x63, 0x18, 0xF8, 0x43, 0x68, 0x00, 0xD0, - 0x7A, 0x97, 0xCD, 0x5B, 0xB2, 0x84, 0x90, 0x06, - 0xB9, 0x81, 0xC5, 0x81, 0x05, 0x55, 0x8C, 0xC4, - 0x03, 0x89, 0xF5, 0x63, 0x87, 0x39, 0xEC, 0xD6, - 0x89, 0x01, 0xE7, 0x1C, 0x4C, 0xDF, 0x5D, 0x65, - 0xFE, 0x4B, 0x91, 0x04, 0x5B, 0x0E, 0x03, 0x38, - 0x2F, 0x21, 0xA8, 0x36, 0x58, 0x93, 0xAD, 0x1F, - 0xEB, 0xC3, 0x91, 0x90, 0x9B, 0x95, 0xCD, 0x53, - 0x81, 0xAA, 0xA9, 0x48, 0x4D, 0x2B, 0x22, 0xC7, - 0xBE, 0x1B, 0x38, 0x21, 0xA1, 0xFE, 0x23, 0xB4, - 0xAC, 0x66, 0x92, 0x9E, 0xF2, 0x27, 0xDC, 0x23, - 0x70, 0x6E, 0xBA, 0xF9, 0xED, 0x3B, 0xCE, 0x63, - 0xAD, 0x68, 0xF2, 0x80, 0xFA, 0x1B, 0x14, 0xB5, - 0xB4, 0x07, 0xE3, 0x5A, 0x81, 0x74, 0xE1, 0xF2, - }, - .len = 3120 - }, - .auth_tag = { - .data = { - 0xEA, 0xE9, 0x10, 0xB6, 0xB7, 0xAB, 0xEA, 0x90, - 0x8A, 0xD5, 0x63, 0x88, 0xDB, 0x2B, 0x8F, 0x23, - }, - .len = 16 - } -}; - -#endif /* TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h deleted file mode 100644 index 3214f9a6e7..0000000000 --- a/app/test/test_cryptodev_hash_test_vectors.h +++ /dev/null @@ -1,521 +0,0 @@ -/* - * BSD LICENSE - * - * Copyright(c) 2016-2017 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_HASH_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ - -static const uint8_t plaintext_hash[] = { - "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." -}; - -static const struct blockcipher_test_data -md5_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_MD5, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .digest = { - .data = { - 0xB3, 0xE6, 0xBB, 0x50, 0x41, 0x35, 0x3C, 0x6B, - 0x7A, 0xFF, 0xD2, 0x64, 0xAF, 0xD5, 0x1C, 0xB2 - }, - .len = 16 - } -}; - -static const struct blockcipher_test_data -hmac_md5_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_MD5_HMAC, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD - }, - .len = 16 - }, - .digest = { - .data = { - 0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE, - 0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B - }, - .len = 16, - .truncated_len = 12 - } -}; - -static const struct blockcipher_test_data -sha1_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA1, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .digest = { - .data = { - 0xA2, 0x8D, 0x40, 0x78, 0xDD, 0x9F, 0xBB, 0xD5, - 0x35, 0x62, 0xFB, 0xFA, 0x93, 0xFD, 0x7D, 0x70, - 0xA6, 0x7D, 0x45, 0xCA - }, - .len = 20 - } -}; - -static const struct blockcipher_test_data -hmac_sha1_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .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 = { - 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, - 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, - 0x3F, 0x91, 0x64, 0x59 - }, - .len = 20, - .truncated_len = 12 - } -}; - -static const struct blockcipher_test_data -sha224_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA224, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .digest = { - .data = { - 0x91, 0xE7, 0xCD, 0x75, 0x14, 0x9C, 0xA9, 0xE9, - 0x2E, 0x46, 0x12, 0x20, 0x22, 0xF9, 0x68, 0x28, - 0x39, 0x26, 0xDF, 0xB5, 0x78, 0x62, 0xB2, 0x6E, - 0x5E, 0x8F, 0x25, 0x84 - }, - .len = 28 - } -}; - -static const struct blockcipher_test_data -hmac_sha224_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, - 0xFB, 0xBF, 0xB0, 0x8C - }, - .len = 28 - }, - .digest = { - .data = { - 0x70, 0x0F, 0x04, 0x4D, 0x22, 0x02, 0x7D, 0x31, - 0x36, 0xDA, 0x77, 0x19, 0xB9, 0x66, 0x37, 0x7B, - 0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F, - 0x92, 0xF6, 0xAA, 0x19 - }, - .len = 28, - .truncated_len = 14 - } -}; - -static const struct blockcipher_test_data -sha256_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA256, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .digest = { - .data = { - 0x7F, 0xF1, 0x0C, 0xF5, 0x90, 0x97, 0x19, 0x0F, - 0x00, 0xE4, 0x83, 0x01, 0xCA, 0x59, 0x00, 0x2E, - 0x1F, 0xC7, 0x84, 0xEE, 0x76, 0xA6, 0x39, 0x15, - 0x76, 0x2F, 0x87, 0xF9, 0x01, 0x06, 0xF3, 0xB7 - }, - .len = 32 - } -}; - -static const struct blockcipher_test_data -hmac_sha256_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, - 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC - }, - .len = 32 - }, - .digest = { - .data = { - 0xAF, 0x8F, 0x70, 0x1B, 0x4B, 0xAF, 0x34, 0xCB, - 0x02, 0x24, 0x48, 0x45, 0x83, 0x52, 0x8F, 0x22, - 0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77, - 0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17 - }, - .len = 32, - .truncated_len = 16 - } -}; - -static const struct blockcipher_test_data -sha384_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA384, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .digest = { - .data = { - 0x1D, 0xE7, 0x3F, 0x55, 0x86, 0xFE, 0x48, 0x9F, - 0xAC, 0xC6, 0x85, 0x32, 0xFA, 0x8E, 0xA6, 0x77, - 0x25, 0x84, 0xA5, 0x98, 0x8D, 0x0B, 0x80, 0xF4, - 0xEB, 0x2C, 0xFB, 0x6C, 0xEA, 0x7B, 0xFD, 0xD5, - 0xAD, 0x41, 0xAB, 0x15, 0xB0, 0x03, 0x15, 0xEC, - 0x9E, 0x3D, 0xED, 0xCB, 0x80, 0x7B, 0xF4, 0xB6 - }, - .len = 48 - } -}; - -static const struct blockcipher_test_data -hmac_sha384_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, - 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, - 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, - 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89 - }, - .len = 48 - }, - .digest = { - .data = { - 0xE2, 0x83, 0x18, 0x55, 0xB5, 0x8D, 0x94, 0x9B, - 0x01, 0xB6, 0xE2, 0x57, 0x7A, 0x62, 0xF5, 0xF4, - 0xAB, 0x39, 0xF3, 0x3C, 0x28, 0xA0, 0x0F, 0xCC, - 0xEE, 0x1C, 0xF1, 0xF8, 0x69, 0xF1, 0x24, 0x3B, - 0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0, - 0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E - }, - .len = 48, - .truncated_len = 24 - } -}; - -static const struct blockcipher_test_data -sha512_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA512, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .digest = { - .data = { - 0xB9, 0xBA, 0x28, 0x48, 0x3C, 0xC2, 0xD3, 0x65, - 0x4A, 0xD6, 0x00, 0x1D, 0xCE, 0x61, 0x64, 0x54, - 0x45, 0x8C, 0x64, 0x0E, 0xED, 0x0E, 0xD8, 0x1C, - 0x72, 0xCE, 0xD2, 0x44, 0x91, 0xC8, 0xEB, 0xC7, - 0x99, 0xC5, 0xCA, 0x89, 0x72, 0x64, 0x96, 0x41, - 0xC8, 0xEA, 0xB2, 0x4E, 0xD1, 0x21, 0x13, 0x49, - 0x64, 0x4E, 0x15, 0x68, 0x12, 0x67, 0x26, 0x0F, - 0x2C, 0x3C, 0x83, 0x25, 0x27, 0x86, 0xF0, 0xDB - }, - .len = 64 - } -}; - -static const struct blockcipher_test_data -hmac_sha512_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, - 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, - 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, - 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89, - 0xDE, 0xAA, 0x36, 0x44, 0x98, 0x93, 0x97, 0x1E, - 0x6D, 0x53, 0x83, 0x87, 0xB3, 0xB7, 0x56, 0x41 - }, - .len = 64 - }, - .digest = { - .data = { - 0xB8, 0x0B, 0x35, 0x97, 0x3F, 0x24, 0x3F, 0x05, - 0x2A, 0x7F, 0x2F, 0xD8, 0xD7, 0x56, 0x58, 0xAD, - 0x6F, 0x8D, 0x1F, 0x4C, 0x30, 0xF9, 0xA8, 0x29, - 0x7A, 0xE0, 0x8D, 0x88, 0xF5, 0x2E, 0x94, 0xF5, - 0x06, 0xF7, 0x5D, 0x57, 0x32, 0xA8, 0x49, 0x29, - 0xEA, 0x6B, 0x6D, 0x95, 0xBD, 0x76, 0xF5, 0x79, - 0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87, - 0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20 - }, - .len = 64, - .truncated_len = 32 - } -}; - -static const struct blockcipher_test_case hash_test_cases[] = { - { - .test_descr = "MD5 Digest", - .test_data = &md5_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "MD5 Digest Verify", - .test_data = &md5_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "HMAC-MD5 Digest", - .test_data = &hmac_md5_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "HMAC-MD5 Digest Verify", - .test_data = &hmac_md5_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "SHA1 Digest", - .test_data = &sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "SHA1 Digest Verify", - .test_data = &sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "HMAC-SHA1 Digest", - .test_data = &hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "HMAC-SHA1 Digest Verify", - .test_data = &hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "SHA224 Digest", - .test_data = &sha224_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "SHA224 Digest Verify", - .test_data = &sha224_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "HMAC-SHA224 Digest", - .test_data = &hmac_sha224_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "HMAC-SHA224 Digest Verify", - .test_data = &hmac_sha224_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "SHA256 Digest", - .test_data = &sha256_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "SHA256 Digest Verify", - .test_data = &sha256_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "HMAC-SHA256 Digest", - .test_data = &hmac_sha256_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "HMAC-SHA256 Digest Verify", - .test_data = &hmac_sha256_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "SHA384 Digest", - .test_data = &sha384_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "SHA384 Digest Verify", - .test_data = &sha384_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "HMAC-SHA384 Digest", - .test_data = &hmac_sha384_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "HMAC-SHA384 Digest Verify", - .test_data = &hmac_sha384_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "SHA512 Digest", - .test_data = &sha512_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "SHA512 Digest Verify", - .test_data = &sha512_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL - }, - { - .test_descr = "HMAC-SHA512 Digest", - .test_data = &hmac_sha512_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, - { - .test_descr = "HMAC-SHA512 Digest Verify", - .test_data = &hmac_sha512_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER - }, -}; - -#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_hmac_test_vectors.h b/app/test/test_cryptodev_hmac_test_vectors.h deleted file mode 100644 index d30215fda8..0000000000 --- a/app/test/test_cryptodev_hmac_test_vectors.h +++ /dev/null @@ -1,121 +0,0 @@ -/*- - * 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 APP_TEST_TEST_CRYPTODEV_HMAC_TEST_VECTORS_H_ -#define APP_TEST_TEST_CRYPTODEV_HMAC_TEST_VECTORS_H_ - -/* *** MD5 test vectors *** */ - -#define MD5_DIGEST_LEN 16 - -struct HMAC_MD5_vector { - struct { - uint8_t data[64]; - uint16_t len; - } key; - - struct { - uint8_t data[1024]; - uint16_t len; - } plaintext; - - struct { - uint8_t data[16]; - uint16_t len; - } auth_tag; -}; - -static const struct -HMAC_MD5_vector HMAC_MD5_test_case_1 = { - .key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD - }, - .len = 16 - }, - .plaintext = { - .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_tag = { - .data = { - 0x67, 0x83, 0xE1, 0x0F, 0xB0, 0xBF, 0x33, 0x49, - 0x22, 0x04, 0x89, 0xDF, 0x86, 0xD0, 0x5F, 0x0C - }, - .len = MD5_DIGEST_LEN - } -}; - -static const struct -HMAC_MD5_vector HMAC_MD5_test_case_2 = { - .key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD - }, - .len = 32 - }, - .plaintext = { - .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_tag = { - .data = { - 0x39, 0x24, 0x70, 0x7A, 0x30, 0x38, 0x1E, 0x2B, - 0x9F, 0x6B, 0xD9, 0x3C, 0xAD, 0xC2, 0x73, 0x52 - }, - .len = MD5_DIGEST_LEN - } -}; - -#endif /* APP_TEST_TEST_CRYPTODEV_HMAC_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_kasumi_hash_test_vectors.h b/app/test/test_cryptodev_kasumi_hash_test_vectors.h deleted file mode 100644 index 69742faaa0..0000000000 --- a/app/test/test_cryptodev_kasumi_hash_test_vectors.h +++ /dev/null @@ -1,337 +0,0 @@ -/*- - * 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 - } -}; - -struct kasumi_hash_test_data kasumi_hash_test_case_6 = { - .key = { - .data = { - 0x83, 0xFD, 0x23, 0xA2, 0x44, 0xA7, 0x4C, 0xF3, - 0x58, 0xDA, 0x30, 0x19, 0xF1, 0x72, 0x26, 0x35 - }, - .len = 16 - }, - .aad = { - .data = { - 0x36, 0xAF, 0x61, 0x44, 0x4F, 0x30, 0x2A, 0xD2 - }, - .len = 8 - }, - .plaintext = { - .data = { - 0x35, 0xC6, 0x87, 0x16, 0x63, 0x3C, 0x66, 0xFB, - 0x75, 0x0C, 0x26, 0x68, 0x65, 0xD5, 0x3C, 0x11, - 0xEA, 0x05, 0xB1, 0xE9, 0xFA, 0x49, 0xC8, 0x39, - 0x8D, 0x48, 0xE1, 0xEF, 0xA5, 0x90, 0x9D, 0x39, - 0x47, 0x90, 0x28, 0x37, 0xF5, 0xAE, 0x96, 0xD5, - 0xA0, 0x5B, 0xC8, 0xD6, 0x1C, 0xA8, 0xDB, 0xEF, - 0x1B, 0x13, 0xA4, 0xB4, 0xAB, 0xFE, 0x4F, 0xB1, - 0x00, 0x60, 0x45, 0xB6, 0x74, 0xBB, 0x54, 0x72, - 0x93, 0x04, 0xC3, 0x82, 0xBE, 0x53, 0xA5, 0xAF, - 0x05, 0x55, 0x61, 0x76, 0xF6, 0xEA, 0xA2, 0xEF, - 0x1D, 0x05, 0xE4, 0xB0, 0x83, 0x18, 0x1E, 0xE6, - 0x74, 0xCD, 0xA5, 0xA4, 0x85, 0xF7, 0x4D, 0x7A, - 0xC0 - }, - .len = 776 - }, - .validAuthLenInBits = { - .len = 768 - }, - .validAuthOffsetLenInBits = { - .len = 64 - }, - .digest = { - .data = {0x95, 0xAE, 0x41, 0xBA}, - .len = 4 - } -}; - -struct kasumi_hash_test_data kasumi_hash_test_case_7 = { - .key = { - .data = { - 0x5A, 0xCB, 0x1D, 0x64, 0x4C, 0x0D, 0x51, 0x20, - 0x4E, 0xA5, 0xF1, 0x45, 0x10, 0x10, 0xD8, 0x52 - }, - .len = 16 - }, - .aad = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, - }, - .len = 8 - }, - .plaintext = { - .data = { - 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, - 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 - }, - .len = 128 - }, - .validAuthLenInBits = { - .len = 120 - }, - .validAuthOffsetLenInBits = { - .len = 64 - }, - .digest = { - .data = {0x87, 0x5F, 0xE4, 0x89}, - .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 deleted file mode 100644 index ef1dc6f32e..0000000000 --- a/app/test/test_cryptodev_kasumi_test_vectors.h +++ /dev/null @@ -1,407 +0,0 @@ -/*- - * 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; - - /* Includes: COUNT (4 bytes) and FRESH (4 bytes) */ - struct { - uint8_t data[8]; - unsigned len; - } aad; - - struct { - uint8_t data[1024]; /* Data may include direction bit */ - unsigned len; /* length must be in Bits */ - } plaintext; - - struct { - unsigned len; - } validDataLenInBits; - - struct { - uint8_t data[1024]; - unsigned len; /* length must be in Bits */ - } ciphertext; - - struct { - unsigned len; - } validCipherLenInBits; - - struct { - unsigned len; - } validCipherOffsetLenInBits; - - /* 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_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 - }, - .aad = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49 - }, - .len = 8 - }, - .plaintext = { - .data = { - 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, - 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 - }, - .len = 128 - }, - .ciphertext = { - .data = { - 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, - 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25 - }, - .len = 120 - }, - .validDataLenInBits = { - .len = 128 - }, - .validCipherLenInBits = { - .len = 120 - }, - .validCipherOffsetLenInBits = { - .len = 64 - }, - .validAuthLenInBits = { - .len = 120 - }, - .validAuthOffsetLenInBits = { - .len = 64 - }, - .digest = { - .data = {0x87, 0x5F, 0xE4, 0x89}, - .len = 4 - } -}; - -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 - }, -}; - -struct kasumi_test_data kasumi_test_case_6 = { - .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 - }, - .aad = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49 - }, - .len = 8 - }, - .plaintext = { - .data = { - 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, - 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 - }, - .len = 128 - }, - .ciphertext = { - .data = { - 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, - 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25 - }, - .len = 120 - }, - .validDataLenInBits = { - .len = 128 - }, - .validCipherLenInBits = { - .len = 120 - }, - .validCipherOffsetLenInBits = { - .len = 64 - }, - .validAuthLenInBits = { - .len = 120 - }, - .validAuthOffsetLenInBits = { - .len = 64 - }, - .digest = { - .data = {0x0F, 0xD2, 0xAA, 0xB5}, - .len = 4 - } -}; - -#endif /* TEST_CRYPTODEV_KASUMI_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c deleted file mode 100644 index 7f1adf874d..0000000000 --- a/app/test/test_cryptodev_perf.c +++ /dev/null @@ -1,4797 +0,0 @@ -/*- - * 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 -#include -#include -#include - -#include -#include -#include - -#include "test.h" -#include "test_cryptodev.h" -#include "test_cryptodev_gcm_test_vectors.h" - - -#define PERF_NUM_OPS_INFLIGHT (128) -#define DEFAULT_NUM_REQS_TO_SUBMIT (10000000) - -struct crypto_testsuite_params { - struct rte_mempool *mbuf_mp; - struct rte_mempool *op_mpool; - - uint16_t nb_queue_pairs; - - struct rte_cryptodev_config conf; - struct rte_cryptodev_qp_conf qp_conf; - uint8_t dev_id; -}; - -enum chain_mode { - CIPHER_HASH, - HASH_CIPHER, - CIPHER_ONLY, - HASH_ONLY -}; - - -struct symmetric_op { - const uint8_t *iv_data; - uint32_t iv_len; - - const uint8_t *aad_data; - uint32_t aad_len; - - const uint8_t *p_data; - uint32_t p_len; - - const uint8_t *c_data; - uint32_t c_len; - - const uint8_t *t_data; - uint32_t t_len; - -}; - -struct symmetric_session_attrs { - enum rte_crypto_cipher_operation cipher; - enum rte_crypto_auth_operation auth; - - enum rte_crypto_cipher_algorithm cipher_algorithm; - const uint8_t *key_cipher_data; - uint32_t key_cipher_len; - - enum rte_crypto_auth_algorithm auth_algorithm; - const uint8_t *key_auth_data; - uint32_t key_auth_len; - - uint32_t digest_len; -}; - -#define ALIGN_POW2_ROUNDUP(num, align) \ - (((num) + (align) - 1) & ~((align) - 1)) - -/* - * This struct is needed to avoid unnecessary allocation or checking - * of allocation of crypto params with current alloc on the fly - * implementation. - */ - -struct crypto_params { - uint8_t *aad; - uint8_t *iv; - uint8_t *digest; -}; - -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; - - struct symmetric_session_attrs *session_attrs; - - struct symmetric_op *symmetric_op; -}; - -#define MAX_NUM_OF_OPS_PER_UT (128) - -struct crypto_unittest_params { - struct rte_crypto_sym_xform cipher_xform; - struct rte_crypto_sym_xform auth_xform; - - struct rte_cryptodev_sym_session *sess; - - struct rte_crypto_op *op; - - struct rte_mbuf *obuf[MAX_NUM_OF_OPS_PER_UT]; - struct rte_mbuf *ibuf[MAX_NUM_OF_OPS_PER_UT]; - - 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 int cipher_key_len, - enum rte_crypto_auth_algorithm auth_algo); -static struct rte_cryptodev_sym_session * -test_perf_create_openssl_session(uint8_t dev_id, enum chain_mode chain, - enum rte_crypto_cipher_algorithm cipher_algo, - unsigned int cipher_key_len, - enum rte_crypto_auth_algorithm auth_algo); -static struct rte_cryptodev_sym_session * -test_perf_create_armv8_session(uint8_t dev_id, enum chain_mode chain, - enum rte_crypto_cipher_algorithm cipher_algo, - unsigned int 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 inline struct rte_crypto_op * -test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, - struct rte_cryptodev_sym_session *sess, unsigned int data_len, - unsigned int digest_len, enum chain_mode chain); -static inline struct rte_crypto_op * -test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, - struct rte_cryptodev_sym_session *sess, unsigned int data_len, - unsigned int digest_len, enum chain_mode chain __rte_unused); -static inline struct rte_crypto_op * -test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, - struct rte_cryptodev_sym_session *sess, unsigned int data_len, - unsigned int digest_len, enum chain_mode chain __rte_unused); -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 RTE_STR(CRYPTODEV_NAME_NULL_PMD); break; - case RTE_CRYPTODEV_AESNI_GCM_PMD: - return RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD); - case RTE_CRYPTODEV_AESNI_MB_PMD: - return RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD); - case RTE_CRYPTODEV_QAT_SYM_PMD: - return RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD); - case RTE_CRYPTODEV_SNOW3G_PMD: - return RTE_STR(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) -{ - struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); - size_t t_len = len - (blocksize ? (len % blocksize) : 0); - - if (m) { - char *dst = rte_pktmbuf_append(m, t_len); - - if (!dst) { - rte_pktmbuf_free(m); - return NULL; - } - - rte_memcpy(dst, (const void *)data, t_len); - } - return m; -} - -static struct crypto_testsuite_params testsuite_params = { NULL }; -static struct crypto_unittest_params unittest_params; -static enum rte_cryptodev_type gbl_cryptodev_perftest_devtype; - -static int -testsuite_setup(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_cryptodev_info info; - unsigned i, nb_devs, valid_dev_id = 0; - int ret; - uint16_t qp_id; - - ts_params->mbuf_mp = rte_mempool_lookup("CRYPTO_PERF_MBUFPOOL"); - if (ts_params->mbuf_mp == NULL) { - /* Not already created so create */ - ts_params->mbuf_mp = rte_pktmbuf_pool_create( - "CRYPTO_PERF_MBUFPOOL", - NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, - rte_socket_id()); - if (ts_params->mbuf_mp == NULL) { - RTE_LOG(ERR, USER1, "Can't create CRYPTO_PERF_MBUFPOOL\n"); - return TEST_FAILED; - } - } - - - ts_params->op_mpool = rte_crypto_op_pool_create("CRYPTO_OP_POOL", - RTE_CRYPTO_OP_TYPE_SYMMETRIC, - NUM_MBUFS, MBUF_CACHE_SIZE, - DEFAULT_NUM_XFORMS * - sizeof(struct rte_crypto_sym_xform), - rte_socket_id()); - if (ts_params->op_mpool == NULL) { - RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); - return TEST_FAILED; - } - - /* Create 2 AESNI MB devices if required */ - if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_AESNI_MB_PMD) { -#ifndef RTE_LIBRTE_PMD_AESNI_MB - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_MB must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_AESNI_MB_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), NULL); - - TEST_ASSERT(ret == 0, - "Failed to create instance %u of pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - } - } - } - - /* Create 2 AESNI GCM devices if required */ - if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_AESNI_GCM_PMD) { -#ifndef RTE_LIBRTE_PMD_AESNI_GCM - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_GCM must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_AESNI_GCM_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD), NULL); - - TEST_ASSERT(ret == 0, - "Failed to create instance %u of pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD)); - } - } - } - - /* Create 2 SNOW3G devices if required */ - if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_SNOW3G_PMD) { -#ifndef RTE_LIBRTE_PMD_SNOW3G - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_SNOW3G must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - 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( - RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD), NULL); - - TEST_ASSERT(ret == 0, - "Failed to create instance %u of pmd : %s", - i, RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD)); - } - } - } - - /* Create 2 OPENSSL devices if required */ - if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_OPENSSL_PMD) { -#ifndef RTE_LIBRTE_PMD_OPENSSL - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_OPENSSL must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_OPENSSL_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance %u of pmd : %s", i, - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); - } - } - } - - /* Create 2 ARMv8 devices if required */ - if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_ARMV8_PMD) { -#ifndef RTE_LIBRTE_PMD_ARMV8_CRYPTO - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO must be" - " enabled in config file to run this testsuite.\n"); - return TEST_FAILED; -#endif - nb_devs = rte_cryptodev_count_devtype( - RTE_CRYPTODEV_ARMV8_PMD); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - ret = rte_eal_vdev_init( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance %u of pmd : %s", i, - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); - } - } - } - -#ifndef RTE_LIBRTE_PMD_QAT - if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_QAT_SYM_PMD) { - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " - "in config file to run this testsuite.\n"); - return TEST_FAILED; - } -#endif - - nb_devs = rte_cryptodev_count(); - if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?\n"); - return TEST_FAILED; - } - - /* Search for the first valid */ - for (i = 0; i < nb_devs; i++) { - rte_cryptodev_info_get(i, &info); - if (info.dev_type == gbl_cryptodev_perftest_devtype) { - ts_params->dev_id = i; - valid_dev_id = 1; - break; - } - } - - if (!valid_dev_id) - return TEST_FAILED; - - /* - * Using Crypto Device Id 0 by default. - * Set up all the qps on this device - */ - - rte_cryptodev_info_get(ts_params->dev_id, &info); - - ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs; - ts_params->conf.socket_id = SOCKET_ID_ANY; - ts_params->conf.session_mp.nb_objs = info.sym.max_nb_sessions; - - TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->dev_id, - &ts_params->conf), - "Failed to configure cryptodev %u", - ts_params->dev_id); - - ts_params->qp_conf.nb_descriptors = PERF_NUM_OPS_INFLIGHT; - for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs ; qp_id++) { - - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - ts_params->dev_id, qp_id, - &ts_params->qp_conf, - rte_cryptodev_socket_id(ts_params->dev_id)), - "Failed to setup queue pair %u on cryptodev %u", - qp_id, ts_params->dev_id); - } - - return TEST_SUCCESS; -} -static void -testsuite_teardown(void) -{ - struct crypto_testsuite_params *ts_params = - &testsuite_params; - - if (ts_params->mbuf_mp != NULL) - RTE_LOG(DEBUG, USER1, "CRYPTO_PERF_MBUFPOOL count %u\n", - 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 -ut_setup(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Clear unit test parameters before running test */ - memset(ut_params, 0, sizeof(*ut_params)); - - rte_cryptodev_stats_reset(ts_params->dev_id); - - /* Start the device */ - TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->dev_id), - "Failed to start cryptodev %u", - ts_params->dev_id); - - return TEST_SUCCESS; -} - -static void -ut_teardown(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - struct rte_cryptodev_stats stats; - - unsigned i; - - /* free crypto session structure */ - if (ut_params->sess) - rte_cryptodev_sym_session_free(ts_params->dev_id, - ut_params->sess); - - /* free crypto operation structure */ - if (ut_params->op) - rte_crypto_op_free(ut_params->op); - - for (i = 0; i < MAX_NUM_OF_OPS_PER_UT; i++) { - if (ut_params->obuf[i]) - rte_pktmbuf_free(ut_params->obuf[i]); - else if (ut_params->ibuf[i]) - rte_pktmbuf_free(ut_params->ibuf[i]); - } - - if (ts_params->mbuf_mp != NULL) - RTE_LOG(DEBUG, USER1, "CRYPTO_PERF_MBUFPOOL count %u\n", - rte_mempool_avail_count(ts_params->mbuf_mp)); - - rte_cryptodev_stats_get(ts_params->dev_id, &stats); - - /* Stop the device */ - rte_cryptodev_stop(ts_params->dev_id); -} - -const char plaintext_quote[] = - "THE COUNT OF MONTE CRISTO by Alexandre Dumas, Pere Chapter 1. " - "Marseilles--The Arrival. On the 24th of February, 1815, the " - "look-out at Notre-Dame de la Garde signalled the three-master," - " the Pharaon from Smyrna, Trieste, and Naples. As usual, a " - "pilot put off immediately, and rounding the Chateau d'If, got " - "on board the vessel between Cape Morgion and Rion island. " - "Immediately, and according to custom, the ramparts of Fort " - "Saint-Jean were covered with spectators; it is always an event " - "at Marseilles for a ship to come into port, especially when " - "this ship, like the Pharaon, has been built, rigged, and laden" - " at the old Phocee docks, and belongs to an owner of the city." - " The ship drew on and had safely passed the strait, which some" - " volcanic shock has made between the Calasareigne and Jaros " - "islands; had doubled Pomegue, and approached the harbor under" - " topsails, jib, and spanker, but so slowly and sedately that" - " the idlers, with that instinct which is the forerunner of " - "evil, asked one another what misfortune could have happened " - "on board. However, those experienced in navigation saw plainly" - " that if any accident had occurred, it was not to the vessel " - "herself, for she bore down with all the evidence of being " - "skilfully handled, the anchor a-cockbill, the jib-boom guys " - "already eased off, and standing by the side of the pilot, who" - " was steering the Pharaon towards the narrow entrance of the" - " inner port, was a young man, who, with activity and vigilant" - " eye, watched every motion of the ship, and repeated each " - "direction of the pilot. The vague disquietude which prevailed " - "among the spectators had so much affected one of the crowd " - "that he did not await the arrival of the vessel in harbor, but" - " jumping into a small skiff, desired to be pulled alongside " - "the Pharaon, which he reached as she rounded into La Reserve " - "basin. When the young man on board saw this person approach, " - "he left his station by the pilot, and, hat in hand, leaned " - "over the ship's bulwarks. He was a fine, tall, slim young " - "fellow of eighteen or twenty, with black eyes, and hair as " - "dark as a raven's wing; and his whole appearance bespoke that " - "calmness and resolution peculiar to men accustomed from their " - "cradle to contend with danger. \"Ah, is it you, Dantes?\" " - "cried the man in the skiff. \"What's the matter? and why have " - "you such an air of sadness aboard?\" \"A great misfortune, M. " - "Morrel,\" replied the young man,--\"a great misfortune, for me" - " especially! Off Civita Vecchia we lost our brave Captain " - "Leclere.\" \"And the cargo?\" inquired the owner, eagerly. " - "\"Is all safe, M. Morrel; and I think you will be satisfied on" - " that head. But poor Captain Leclere--\" \"What happened to " - "him?\" asked the owner, with an air of considerable " - "resignation. \"What happened to the worthy captain?\" \"He " - "died.\" \"Fell into the sea?\" \"No, sir, he died of " - "brain-fever in dreadful agony.\" Then turning to the crew, " - "he said, \"Bear a hand there, to take in sail!\" All hands " - "obeyed, and at once the eight or ten seamen who composed the " - "crew, sprang to their respective stations at the spanker " - "brails and outhaul, topsail sheets and halyards, the jib " - "downhaul, and the topsail clewlines and buntlines. The young " - "sailor gave a look to see that his orders were promptly and " - "accurately obeyed, and then turned again to the owner. \"And " - "how did this misfortune occur?\" inquired the latter, resuming" - " the interrupted conversation. \"Alas, sir, in the most " - "unexpected manner. After a long talk with the harbor-master, " - "Captain Leclere left Naples greatly disturbed in mind. In " - "twenty-four hours he was attacked by a fever, and died three " - "days afterwards. We performed the usual burial service, and he" - " is at his rest, sewn up in his hammock with a thirty-six " - "pound shot at his head and his heels, off El Giglio island. " - "We bring to his widow his sword and cross of honor. It was " - "worth while, truly,\" added the young man with a melancholy " - "smile, \"to make war against the English for ten years, and " - "to die in his bed at last, like everybody else."; - -#define QUOTE_LEN_64B (64) -#define QUOTE_LEN_128B (128) -#define QUOTE_LEN_256B (256) -#define QUOTE_LEN_512B (512) -#define QUOTE_LEN_768B (768) -#define QUOTE_LEN_1024B (1024) -#define QUOTE_LEN_1280B (1280) -#define QUOTE_LEN_1536B (1536) -#define QUOTE_LEN_1792B (1792) -#define QUOTE_LEN_2048B (2048) - - -/* ***** AES-CBC / HMAC-SHA256 Performance Tests ***** */ - -#define HMAC_KEY_LENGTH_SHA256 (DIGEST_BYTE_LENGTH_SHA256) - -#define CIPHER_KEY_LENGTH_AES_CBC (16) -#define CIPHER_IV_LENGTH_AES_CBC (CIPHER_KEY_LENGTH_AES_CBC) - -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_128_iv[] = { - 0xf5, 0xd3, 0x89, 0x0f, 0x47, 0x00, 0xcb, 0x52, - 0x42, 0x1a, 0x7d, 0x3d, 0xf5, 0x82, 0x80, 0xf1 }; - -static uint8_t hmac_sha256_key[] = { - 0xff, 0xcb, 0x37, 0x30, 0x1d, 0x4a, 0xc2, 0x41, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x9a, 0x4f, 0x88, 0x1b, 0xb6, 0x8f, 0xd8, 0x60 }; - - -/* Cipher text output */ - -static const uint8_t AES_CBC_ciphertext_64B[] = { - 0x05, 0x15, 0x77, 0x32, 0xc9, 0x66, 0x91, 0x50, - 0x93, 0x9f, 0xbb, 0x4e, 0x2e, 0x5a, 0x02, 0xd0, - 0x2d, 0x9d, 0x31, 0x5d, 0xc8, 0x9e, 0x86, 0x36, - 0x54, 0x5c, 0x50, 0xe8, 0x75, 0x54, 0x74, 0x5e, - 0xd5, 0xa2, 0x84, 0x21, 0x2d, 0xc5, 0xf8, 0x1c, - 0x55, 0x1a, 0xba, 0x91, 0xce, 0xb5, 0xa3, 0x1e, - 0x31, 0xbf, 0xe9, 0xa1, 0x97, 0x5c, 0x2b, 0xd6, - 0x57, 0xa5, 0x9f, 0xab, 0xbd, 0xb0, 0x9b, 0x9c -}; - -static const uint8_t AES_CBC_ciphertext_128B[] = { - 0x79, 0x92, 0x65, 0xc8, 0xfb, 0x0a, 0xc7, 0xc4, - 0x9b, 0x3b, 0xbe, 0x69, 0x7f, 0x7c, 0xf4, 0x4e, - 0xa5, 0x0d, 0xf6, 0x33, 0xc4, 0xdf, 0xf3, 0x0d, - 0xdb, 0xb9, 0x68, 0x34, 0xb0, 0x0d, 0xbd, 0xb9, - 0xa7, 0xf3, 0x86, 0x50, 0x2a, 0xbe, 0x50, 0x5d, - 0xb3, 0xbe, 0x72, 0xf9, 0x02, 0xb1, 0x69, 0x0b, - 0x8c, 0x96, 0x4c, 0x3c, 0x0c, 0x1e, 0x76, 0xe5, - 0x7e, 0x75, 0xdd, 0xd0, 0xa9, 0x75, 0x00, 0x13, - 0x6b, 0x1e, 0xc0, 0xad, 0xfc, 0x03, 0xb5, 0x99, - 0xdc, 0x37, 0x35, 0xfc, 0x16, 0x34, 0xfd, 0xb4, - 0xea, 0x1e, 0xb6, 0x51, 0xdf, 0xab, 0x87, 0xd6, - 0x87, 0x41, 0xfa, 0x1c, 0xc6, 0x78, 0xa6, 0x3c, - 0x1d, 0x76, 0xfe, 0xff, 0x65, 0xfc, 0x63, 0x1e, - 0x1f, 0xe2, 0x7c, 0x9b, 0xa2, 0x72, 0xc3, 0x34, - 0x23, 0xdf, 0x01, 0xf0, 0xfd, 0x02, 0x8b, 0x97, - 0x00, 0x2b, 0x97, 0x4e, 0xab, 0x98, 0x21, 0x3c -}; - -static const uint8_t AES_CBC_ciphertext_256B[] = { - 0xc7, 0x71, 0x2b, 0xed, 0x2c, 0x97, 0x59, 0xfa, - 0xcf, 0x5a, 0xb9, 0x31, 0x92, 0xe0, 0xc9, 0x92, - 0xc0, 0x2d, 0xd5, 0x9c, 0x84, 0xbf, 0x70, 0x36, - 0x13, 0x48, 0xe0, 0xb1, 0xbf, 0x6c, 0xcd, 0x91, - 0xa0, 0xc3, 0x57, 0x6c, 0x3f, 0x0e, 0x34, 0x41, - 0xe7, 0x9c, 0xc0, 0xec, 0x18, 0x0c, 0x05, 0x52, - 0x78, 0xe2, 0x3c, 0x6e, 0xdf, 0xa5, 0x49, 0xc7, - 0xf2, 0x55, 0x00, 0x8f, 0x65, 0x6d, 0x4b, 0xd0, - 0xcb, 0xd4, 0xd2, 0x0b, 0xea, 0xf4, 0xb0, 0x85, - 0x61, 0x9e, 0x36, 0xc0, 0x71, 0xb7, 0x80, 0xad, - 0x40, 0x78, 0xb4, 0x70, 0x2b, 0xe8, 0x80, 0xc5, - 0x19, 0x35, 0x96, 0x55, 0x3b, 0x40, 0x03, 0xbb, - 0x9f, 0xa6, 0xc2, 0x82, 0x92, 0x04, 0xc3, 0xa6, - 0x96, 0xc4, 0x7f, 0x4c, 0x3e, 0x3c, 0x79, 0x82, - 0x88, 0x8b, 0x3f, 0x8b, 0xc5, 0x9f, 0x44, 0xbe, - 0x71, 0xe7, 0x09, 0xa2, 0x40, 0xa2, 0x23, 0x4e, - 0x9f, 0x31, 0xab, 0x6f, 0xdf, 0x59, 0x40, 0xe1, - 0x12, 0x15, 0x55, 0x4b, 0xea, 0x3f, 0xa1, 0x41, - 0x4f, 0xaf, 0xcd, 0x27, 0x2a, 0x61, 0xa1, 0x9e, - 0x82, 0x30, 0x05, 0x05, 0x55, 0xce, 0x99, 0xd3, - 0x8f, 0x3f, 0x86, 0x79, 0xdc, 0x9f, 0x33, 0x07, - 0x75, 0x26, 0xc8, 0x72, 0x81, 0x0f, 0x9b, 0xf7, - 0xb1, 0xfb, 0xd3, 0x91, 0x36, 0x08, 0xab, 0x26, - 0x70, 0x53, 0x0c, 0x99, 0xfd, 0xa9, 0x07, 0xb4, - 0xe9, 0xce, 0xc1, 0xd6, 0xd2, 0x2c, 0x71, 0x80, - 0xec, 0x59, 0x61, 0x0b, 0x24, 0xf0, 0x6d, 0x33, - 0x73, 0x45, 0x6e, 0x80, 0x03, 0x45, 0xf2, 0x76, - 0xa5, 0x8a, 0xc9, 0xcf, 0xaf, 0x4a, 0xed, 0x35, - 0xc0, 0x97, 0x52, 0xc5, 0x00, 0xdf, 0xef, 0xc7, - 0x9f, 0xf2, 0xe8, 0x15, 0x3e, 0xb3, 0x30, 0xe7, - 0x00, 0xd0, 0x4e, 0xeb, 0x79, 0xf6, 0xf6, 0xcf, - 0xf0, 0xe7, 0x61, 0xd5, 0x3d, 0x6a, 0x73, 0x9d -}; - -static const uint8_t AES_CBC_ciphertext_512B[] = { - 0xb4, 0xc6, 0xc6, 0x5f, 0x7e, 0xca, 0x05, 0x70, - 0x21, 0x7b, 0x92, 0x9e, 0x23, 0xe7, 0x92, 0xb8, - 0x27, 0x3d, 0x20, 0x29, 0x57, 0xfa, 0x1f, 0x26, - 0x0a, 0x04, 0x34, 0xa6, 0xf2, 0xdc, 0x44, 0xb6, - 0x43, 0x40, 0x62, 0xde, 0x0c, 0xde, 0x1c, 0x30, - 0x43, 0x85, 0x0b, 0xe8, 0x93, 0x1f, 0xa1, 0x2a, - 0x8a, 0x27, 0x35, 0x39, 0x14, 0x9f, 0x37, 0x64, - 0x59, 0xb5, 0x0e, 0x96, 0x82, 0x5d, 0x63, 0x45, - 0xd6, 0x93, 0x89, 0x46, 0xe4, 0x71, 0x31, 0xeb, - 0x0e, 0xd1, 0x7b, 0xda, 0x90, 0xb5, 0x81, 0xac, - 0x76, 0x54, 0x54, 0x85, 0x0b, 0xa9, 0x46, 0x9c, - 0xf0, 0xfd, 0xde, 0x5d, 0xa8, 0xe3, 0xee, 0xe9, - 0xf4, 0x9d, 0x34, 0x76, 0x39, 0xe7, 0xc3, 0x4a, - 0x84, 0x38, 0x92, 0x61, 0xf1, 0x12, 0x9f, 0x05, - 0xda, 0xdb, 0xc1, 0xd4, 0xb0, 0xa0, 0x27, 0x19, - 0xa0, 0x56, 0x5d, 0x9b, 0xcc, 0x47, 0x7c, 0x15, - 0x1d, 0x52, 0x66, 0xd5, 0xff, 0xef, 0x12, 0x23, - 0x86, 0xe2, 0xee, 0x81, 0x2c, 0x3d, 0x7d, 0x28, - 0xd5, 0x42, 0xdf, 0xdb, 0x75, 0x1c, 0xeb, 0xdf, - 0x13, 0x23, 0xd5, 0x17, 0x89, 0xea, 0xd7, 0x01, - 0xff, 0x57, 0x6a, 0x44, 0x61, 0xf4, 0xea, 0xbe, - 0x97, 0x9b, 0xc2, 0xb1, 0x9c, 0x5d, 0xff, 0x4f, - 0x73, 0x2d, 0x3f, 0x57, 0x28, 0x38, 0xbf, 0x3d, - 0x9f, 0xda, 0x49, 0x55, 0x8f, 0xb2, 0x77, 0xec, - 0x0f, 0xbc, 0xce, 0xb8, 0xc6, 0xe1, 0x03, 0xed, - 0x35, 0x9c, 0xf2, 0x4d, 0xa4, 0x29, 0x6c, 0xd6, - 0x6e, 0x05, 0x53, 0x46, 0xc1, 0x41, 0x09, 0x36, - 0x0b, 0x7d, 0xf4, 0x9e, 0x0f, 0xba, 0x86, 0x33, - 0xdd, 0xf1, 0xa7, 0xf7, 0xd5, 0x29, 0xa8, 0xa7, - 0x4d, 0xce, 0x0c, 0xf5, 0xb4, 0x6c, 0xd8, 0x27, - 0xb0, 0x87, 0x2a, 0x6f, 0x7f, 0x3f, 0x8f, 0xc3, - 0xe2, 0x3e, 0x94, 0xcf, 0x61, 0x4a, 0x09, 0x3d, - 0xf9, 0x55, 0x19, 0x31, 0xf2, 0xd2, 0x4a, 0x3e, - 0xc1, 0xf5, 0xed, 0x7c, 0x45, 0xb0, 0x0c, 0x7b, - 0xdd, 0xa6, 0x0a, 0x26, 0x66, 0xec, 0x85, 0x49, - 0x00, 0x38, 0x05, 0x7c, 0x9c, 0x1c, 0x92, 0xf5, - 0xf7, 0xdb, 0x5d, 0xbd, 0x61, 0x0c, 0xc9, 0xaf, - 0xfd, 0x57, 0x3f, 0xee, 0x2b, 0xad, 0x73, 0xef, - 0xa3, 0xc1, 0x66, 0x26, 0x44, 0x5e, 0xf9, 0x12, - 0x86, 0x66, 0xa9, 0x61, 0x75, 0xa1, 0xbc, 0x40, - 0x7f, 0xa8, 0x08, 0x02, 0xc0, 0x76, 0x0e, 0x76, - 0xb3, 0x26, 0x3d, 0x1c, 0x40, 0x65, 0xe4, 0x18, - 0x0f, 0x62, 0x17, 0x8f, 0x1e, 0x61, 0xb8, 0x08, - 0x83, 0x54, 0x42, 0x11, 0x03, 0x30, 0x8e, 0xb7, - 0xc1, 0x9c, 0xec, 0x69, 0x52, 0x95, 0xfb, 0x7b, - 0x1a, 0x0c, 0x20, 0x24, 0xf7, 0xb8, 0x38, 0x0c, - 0xb8, 0x7b, 0xb6, 0x69, 0x70, 0xd0, 0x61, 0xb9, - 0x70, 0x06, 0xc2, 0x5b, 0x20, 0x47, 0xf7, 0xd9, - 0x32, 0xc2, 0xf2, 0x90, 0xb6, 0x4d, 0xcd, 0x3c, - 0x6d, 0x74, 0xea, 0x82, 0x35, 0x1b, 0x08, 0x44, - 0xba, 0xb7, 0x33, 0x82, 0x33, 0x27, 0x54, 0x77, - 0x6e, 0x58, 0xfe, 0x46, 0x5a, 0xb4, 0x88, 0x53, - 0x8d, 0x9b, 0xb1, 0xab, 0xdf, 0x04, 0xe1, 0xfb, - 0xd7, 0x1e, 0xd7, 0x38, 0x64, 0x54, 0xba, 0xb0, - 0x6c, 0x84, 0x7a, 0x0f, 0xa7, 0x80, 0x6b, 0x86, - 0xd9, 0xc9, 0xc6, 0x31, 0x95, 0xfa, 0x8a, 0x2c, - 0x14, 0xe1, 0x85, 0x66, 0x27, 0xfd, 0x63, 0x3e, - 0xf0, 0xfa, 0x81, 0xc9, 0x89, 0x4f, 0xe2, 0x6a, - 0x8c, 0x17, 0xb5, 0xc7, 0x9f, 0x5d, 0x3f, 0x6b, - 0x3f, 0xcd, 0x13, 0x7a, 0x3c, 0xe6, 0x4e, 0xfa, - 0x7a, 0x10, 0xb8, 0x7c, 0x40, 0xec, 0x93, 0x11, - 0x1f, 0xd0, 0x9e, 0xc3, 0x56, 0xb9, 0xf5, 0x21, - 0x18, 0x41, 0x31, 0xea, 0x01, 0x8d, 0xea, 0x1c, - 0x95, 0x5e, 0x56, 0x33, 0xbc, 0x7a, 0x3f, 0x6f -}; - -static const uint8_t AES_CBC_ciphertext_768B[] = { - 0x3e, 0x7f, 0x9e, 0x4c, 0x88, 0x15, 0x68, 0x69, - 0x10, 0x09, 0xe1, 0xa7, 0x0f, 0x27, 0x88, 0x2d, - 0x90, 0x73, 0x4f, 0x67, 0xd3, 0x8b, 0xaf, 0xa1, - 0x2c, 0x37, 0xa5, 0x6c, 0x7c, 0xbd, 0x95, 0x4c, - 0x82, 0xcf, 0x05, 0x49, 0x16, 0x5c, 0xe7, 0x06, - 0xd4, 0xcb, 0x55, 0x65, 0x9a, 0xd0, 0xe1, 0x46, - 0x3a, 0x37, 0x71, 0xad, 0xb0, 0xb4, 0x99, 0x1e, - 0x23, 0x57, 0x48, 0x96, 0x9c, 0xc5, 0xc4, 0xdb, - 0x64, 0x3e, 0xc9, 0x7f, 0x90, 0x5a, 0xa0, 0x08, - 0x75, 0x4c, 0x09, 0x06, 0x31, 0x6e, 0x59, 0x29, - 0xfc, 0x2f, 0x72, 0xde, 0xf2, 0x40, 0x5a, 0xfe, - 0xd3, 0x66, 0x64, 0xb8, 0x9c, 0xc9, 0xa6, 0x1f, - 0xc3, 0x52, 0xcd, 0xb5, 0xd1, 0x4f, 0x43, 0x3f, - 0xf4, 0x59, 0x25, 0xc4, 0xdd, 0x3e, 0x58, 0x7c, - 0x21, 0xd6, 0x21, 0xce, 0xa4, 0xbe, 0x08, 0x23, - 0x46, 0x68, 0xc0, 0x00, 0x91, 0x47, 0xca, 0x9b, - 0xe0, 0xb4, 0xe3, 0xab, 0xbf, 0xcf, 0x68, 0x26, - 0x97, 0x23, 0x09, 0x93, 0x64, 0x8f, 0x57, 0x59, - 0xe2, 0x41, 0x7c, 0xa2, 0x48, 0x7e, 0xd5, 0x2c, - 0x54, 0x09, 0x1b, 0x07, 0x94, 0xca, 0x39, 0x83, - 0xdd, 0xf4, 0x7a, 0x1d, 0x2d, 0xdd, 0x67, 0xf7, - 0x3c, 0x30, 0x89, 0x3e, 0xc1, 0xdc, 0x1d, 0x8f, - 0xfc, 0xb1, 0xe9, 0x13, 0x31, 0xb0, 0x16, 0xdb, - 0x88, 0xf2, 0x32, 0x7e, 0x73, 0xa3, 0xdf, 0x08, - 0x6b, 0x53, 0x92, 0x08, 0xc9, 0x9d, 0x98, 0xb2, - 0xf4, 0x8c, 0xb1, 0x95, 0xdc, 0xb6, 0xfc, 0xec, - 0xf1, 0xc9, 0x0d, 0x6d, 0x42, 0x2c, 0xf5, 0x38, - 0x29, 0xf4, 0xd8, 0x98, 0x0f, 0xb0, 0x81, 0xa5, - 0xaa, 0xe6, 0x1f, 0x6e, 0x87, 0x32, 0x1b, 0x02, - 0x07, 0x57, 0x38, 0x83, 0xf3, 0xe4, 0x54, 0x7c, - 0xa8, 0x43, 0xdf, 0x3f, 0x42, 0xfd, 0x67, 0x28, - 0x06, 0x4d, 0xea, 0xce, 0x1f, 0x84, 0x4a, 0xcd, - 0x8c, 0x61, 0x5e, 0x8f, 0x61, 0xed, 0x84, 0x03, - 0x53, 0x6a, 0x9e, 0xbf, 0x68, 0x83, 0xa7, 0x42, - 0x56, 0x57, 0xcd, 0x45, 0x29, 0xfc, 0x7b, 0x07, - 0xfc, 0xe9, 0xb9, 0x42, 0xfd, 0x29, 0xd5, 0xfd, - 0x98, 0x11, 0xd1, 0x8d, 0x67, 0x29, 0x47, 0x61, - 0xd8, 0x27, 0x37, 0x79, 0x29, 0xd1, 0x94, 0x6f, - 0x8d, 0xf3, 0x1b, 0x3d, 0x6a, 0xb1, 0x59, 0xef, - 0x1b, 0xd4, 0x70, 0x0e, 0xac, 0xab, 0xa0, 0x2b, - 0x1f, 0x5e, 0x04, 0xf0, 0x0e, 0x35, 0x72, 0x90, - 0xfc, 0xcf, 0x86, 0x43, 0xea, 0x45, 0x6d, 0x22, - 0x63, 0x06, 0x1a, 0x58, 0xd7, 0x2d, 0xc5, 0xb0, - 0x60, 0x69, 0xe8, 0x53, 0xc2, 0xa2, 0x57, 0x83, - 0xc4, 0x31, 0xb4, 0xc6, 0xb3, 0xa1, 0x77, 0xb3, - 0x1c, 0xca, 0x89, 0x3f, 0xf5, 0x10, 0x3b, 0x36, - 0x31, 0x7d, 0x00, 0x46, 0x00, 0x92, 0xa0, 0xa0, - 0x34, 0xd8, 0x5e, 0x62, 0xa9, 0xe0, 0x23, 0x37, - 0x50, 0x85, 0xc7, 0x3a, 0x20, 0xa3, 0x98, 0xc0, - 0xac, 0x20, 0x06, 0x0f, 0x17, 0x3c, 0xfc, 0x43, - 0x8c, 0x9d, 0xec, 0xf5, 0x9a, 0x35, 0x96, 0xf7, - 0xb7, 0x4c, 0xf9, 0x69, 0xf8, 0xd4, 0x1e, 0x9e, - 0xf9, 0x7c, 0xc4, 0xd2, 0x11, 0x14, 0x41, 0xb9, - 0x89, 0xd6, 0x07, 0xd2, 0x37, 0x07, 0x5e, 0x5e, - 0xae, 0x60, 0xdc, 0xe4, 0xeb, 0x38, 0x48, 0x6d, - 0x95, 0x8d, 0x71, 0xf2, 0xba, 0xda, 0x5f, 0x08, - 0x9d, 0x4a, 0x0f, 0x56, 0x90, 0x64, 0xab, 0xb6, - 0x88, 0x22, 0xa8, 0x90, 0x1f, 0x76, 0x2c, 0x83, - 0x43, 0xce, 0x32, 0x55, 0x45, 0x84, 0x57, 0x43, - 0xf9, 0xa8, 0xd1, 0x4f, 0xe3, 0xc1, 0x72, 0x9c, - 0xeb, 0x64, 0xf7, 0xe4, 0x61, 0x2b, 0x93, 0xd1, - 0x1f, 0xbb, 0x5c, 0xff, 0xa1, 0x59, 0x69, 0xcf, - 0xf7, 0xaf, 0x58, 0x45, 0xd5, 0x3e, 0x98, 0x7d, - 0x26, 0x39, 0x5c, 0x75, 0x3c, 0x4a, 0xbf, 0x5e, - 0x12, 0x10, 0xb0, 0x93, 0x0f, 0x86, 0x82, 0xcf, - 0xb2, 0xec, 0x70, 0x5c, 0x0b, 0xad, 0x5d, 0x63, - 0x65, 0x32, 0xa6, 0x04, 0x58, 0x03, 0x91, 0x2b, - 0xdb, 0x8f, 0xd3, 0xa3, 0x2b, 0x3a, 0xf5, 0xa1, - 0x62, 0x6c, 0xb6, 0xf0, 0x13, 0x3b, 0x8c, 0x07, - 0x10, 0x82, 0xc9, 0x56, 0x24, 0x87, 0xfc, 0x56, - 0xe8, 0xef, 0x90, 0x8b, 0xd6, 0x48, 0xda, 0x53, - 0x04, 0x49, 0x41, 0xa4, 0x67, 0xe0, 0x33, 0x24, - 0x6b, 0x9c, 0x07, 0x55, 0x4c, 0x5d, 0xe9, 0x35, - 0xfa, 0xbd, 0xea, 0xa8, 0x3f, 0xe9, 0xf5, 0x20, - 0x5c, 0x60, 0x0f, 0x0d, 0x24, 0xcb, 0x1a, 0xd6, - 0xe8, 0x5c, 0xa8, 0x42, 0xae, 0xd0, 0xd2, 0xf2, - 0xa8, 0xbe, 0xea, 0x0f, 0x8d, 0xfb, 0x81, 0xa3, - 0xa4, 0xef, 0xb7, 0x3e, 0x91, 0xbd, 0x26, 0x0f, - 0x8e, 0xf1, 0xb2, 0xa5, 0x47, 0x06, 0xfa, 0x40, - 0x8b, 0x31, 0x7a, 0x5a, 0x74, 0x2a, 0x0a, 0x7c, - 0x62, 0x5d, 0x39, 0xa4, 0xae, 0x14, 0x85, 0x08, - 0x5b, 0x20, 0x85, 0xf1, 0x57, 0x6e, 0x71, 0x13, - 0x4e, 0x2b, 0x49, 0x87, 0x01, 0xdf, 0x37, 0xed, - 0x28, 0xee, 0x4d, 0xa1, 0xf4, 0xb3, 0x3b, 0xba, - 0x2d, 0xb3, 0x46, 0x17, 0x84, 0x80, 0x9d, 0xd7, - 0x93, 0x1f, 0x28, 0x7c, 0xf5, 0xf9, 0xd6, 0x85, - 0x8c, 0xa5, 0x44, 0xe9, 0x2c, 0x65, 0x51, 0x5f, - 0x53, 0x7a, 0x09, 0xd9, 0x30, 0x16, 0x95, 0x89, - 0x9c, 0x0b, 0xef, 0x90, 0x6d, 0x23, 0xd3, 0x48, - 0x57, 0x3b, 0x55, 0x69, 0x96, 0xfc, 0xf7, 0x52, - 0x92, 0x38, 0x36, 0xbf, 0xa9, 0x0a, 0xbb, 0x68, - 0x45, 0x08, 0x25, 0xee, 0x59, 0xfe, 0xee, 0xf2, - 0x2c, 0xd4, 0x5f, 0x78, 0x59, 0x0d, 0x90, 0xf1, - 0xd7, 0xe4, 0x39, 0x0e, 0x46, 0x36, 0xf5, 0x75, - 0x03, 0x3c, 0x28, 0xfb, 0xfa, 0x8f, 0xef, 0xc9, - 0x61, 0x00, 0x94, 0xc3, 0xd2, 0x0f, 0xd9, 0xda -}; - -static const uint8_t AES_CBC_ciphertext_1024B[] = { - 0x7d, 0x01, 0x7e, 0x2f, 0x92, 0xb3, 0xea, 0x72, - 0x4a, 0x3f, 0x10, 0xf9, 0x2b, 0xb0, 0xd5, 0xb9, - 0x19, 0x68, 0x94, 0xe9, 0x93, 0xe9, 0xd5, 0x26, - 0x20, 0x44, 0xe2, 0x47, 0x15, 0x8d, 0x75, 0x48, - 0x8e, 0xe4, 0x40, 0x81, 0xb5, 0x06, 0xa8, 0xb8, - 0x0e, 0x0f, 0x3b, 0xbc, 0x5b, 0xbe, 0x3b, 0xa2, - 0x2a, 0x0c, 0x48, 0x98, 0x19, 0xdf, 0xe9, 0x25, - 0x75, 0xab, 0x93, 0x44, 0xb1, 0x72, 0x70, 0xbb, - 0x20, 0xcf, 0x78, 0xe9, 0x4d, 0xc6, 0xa9, 0xa9, - 0x84, 0x78, 0xc5, 0xc0, 0xc4, 0xc9, 0x79, 0x1a, - 0xbc, 0x61, 0x25, 0x5f, 0xac, 0x01, 0x03, 0xb7, - 0xef, 0x07, 0xf2, 0x62, 0x98, 0xee, 0xe3, 0xad, - 0x94, 0x75, 0x30, 0x67, 0xb9, 0x15, 0x00, 0xe7, - 0x11, 0x32, 0x2e, 0x6b, 0x55, 0x9f, 0xac, 0x68, - 0xde, 0x61, 0x05, 0x80, 0x01, 0xf3, 0xad, 0xab, - 0xaf, 0x45, 0xe0, 0xf4, 0x68, 0x5c, 0xc0, 0x52, - 0x92, 0xc8, 0x21, 0xb6, 0xf5, 0x8a, 0x1d, 0xbb, - 0xfc, 0x4a, 0x11, 0x62, 0xa2, 0xc4, 0xf1, 0x2d, - 0x0e, 0xb2, 0xc7, 0x17, 0x34, 0xb4, 0x2a, 0x54, - 0x81, 0xc2, 0x1e, 0xcf, 0x51, 0x0a, 0x76, 0x54, - 0xf1, 0x48, 0x0d, 0x5c, 0xcd, 0x38, 0x3e, 0x38, - 0x3e, 0xf8, 0x46, 0x1d, 0x00, 0xf5, 0x62, 0xe1, - 0x5c, 0xb7, 0x8d, 0xce, 0xd0, 0x3f, 0xbb, 0x22, - 0xf1, 0xe5, 0xb1, 0xa0, 0x58, 0x5e, 0x3c, 0x0f, - 0x15, 0xd1, 0xac, 0x3e, 0xc7, 0x72, 0xc4, 0xde, - 0x8b, 0x95, 0x3e, 0x91, 0xf7, 0x1d, 0x04, 0x9a, - 0xc8, 0xe4, 0xbf, 0xd3, 0x22, 0xca, 0x4a, 0xdc, - 0xb6, 0x16, 0x79, 0x81, 0x75, 0x2f, 0x6b, 0xa7, - 0x04, 0x98, 0xa7, 0x4e, 0xc1, 0x19, 0x90, 0x33, - 0x33, 0x3c, 0x7f, 0xdd, 0xac, 0x09, 0x0c, 0xc3, - 0x91, 0x34, 0x74, 0xab, 0xa5, 0x35, 0x0a, 0x13, - 0xc3, 0x56, 0x67, 0x6d, 0x1a, 0x3e, 0xbf, 0x56, - 0x06, 0x67, 0x15, 0x5f, 0xfc, 0x8b, 0xa2, 0x3c, - 0x5e, 0xaf, 0x56, 0x1f, 0xe3, 0x2e, 0x9d, 0x0a, - 0xf9, 0x9b, 0xc7, 0xb5, 0x03, 0x1c, 0x68, 0x99, - 0xfa, 0x3c, 0x37, 0x59, 0xc1, 0xf7, 0x6a, 0x83, - 0x22, 0xee, 0xca, 0x7f, 0x7d, 0x49, 0xe6, 0x48, - 0x84, 0x54, 0x7a, 0xff, 0xb3, 0x72, 0x21, 0xd8, - 0x7a, 0x5d, 0xb1, 0x4b, 0xcc, 0x01, 0x6f, 0x90, - 0xc6, 0x68, 0x1c, 0x2c, 0xa1, 0xe2, 0x74, 0x40, - 0x26, 0x9b, 0x57, 0x53, 0xa3, 0x7c, 0x0b, 0x0d, - 0xcf, 0x05, 0x5d, 0x62, 0x4f, 0x75, 0x06, 0x62, - 0x1f, 0x26, 0x32, 0xaa, 0x25, 0xcc, 0x26, 0x8d, - 0xae, 0x01, 0x47, 0xa3, 0x00, 0x42, 0xe2, 0x4c, - 0xee, 0x29, 0xa2, 0x81, 0xa0, 0xfd, 0xeb, 0xff, - 0x9a, 0x66, 0x6e, 0x47, 0x5b, 0xab, 0x93, 0x5a, - 0x02, 0x6d, 0x6f, 0xf2, 0x6e, 0x02, 0x9d, 0xb1, - 0xab, 0x56, 0xdc, 0x8b, 0x9b, 0x17, 0xa8, 0xfb, - 0x87, 0x42, 0x7c, 0x91, 0x1e, 0x14, 0xc6, 0x6f, - 0xdc, 0xf0, 0x27, 0x30, 0xfa, 0x3f, 0xc4, 0xad, - 0x57, 0x85, 0xd2, 0xc9, 0x32, 0x2c, 0x13, 0xa6, - 0x04, 0x04, 0x50, 0x05, 0x2f, 0x72, 0xd9, 0x44, - 0x55, 0x6e, 0x93, 0x40, 0xed, 0x7e, 0xd4, 0x40, - 0x3e, 0x88, 0x3b, 0x8b, 0xb6, 0xeb, 0xc6, 0x5d, - 0x9c, 0x99, 0xa1, 0xcf, 0x30, 0xb2, 0xdc, 0x48, - 0x8a, 0x01, 0xa7, 0x61, 0x77, 0x50, 0x14, 0xf3, - 0x0c, 0x49, 0x53, 0xb3, 0xb4, 0xb4, 0x28, 0x41, - 0x4a, 0x2d, 0xd2, 0x4d, 0x2a, 0x30, 0x31, 0x83, - 0x03, 0x5e, 0xaa, 0xd3, 0xa3, 0xd1, 0xa1, 0xca, - 0x62, 0xf0, 0xe1, 0xf2, 0xff, 0xf0, 0x19, 0xa6, - 0xde, 0x22, 0x47, 0xb5, 0x28, 0x7d, 0xf7, 0x07, - 0x16, 0x0d, 0xb1, 0x55, 0x81, 0x95, 0xe5, 0x1d, - 0x4d, 0x78, 0xa9, 0x3e, 0xce, 0xe3, 0x1c, 0xf9, - 0x47, 0xc8, 0xec, 0xc5, 0xc5, 0x93, 0x4c, 0x34, - 0x20, 0x6b, 0xee, 0x9a, 0xe6, 0x86, 0x57, 0x58, - 0xd5, 0x58, 0xf1, 0x33, 0x10, 0x29, 0x9e, 0x93, - 0x2f, 0xf5, 0x90, 0x00, 0x17, 0x67, 0x4f, 0x39, - 0x18, 0xe1, 0xcf, 0x55, 0x78, 0xbb, 0xe6, 0x29, - 0x3e, 0x77, 0xd5, 0x48, 0xb7, 0x42, 0x72, 0x53, - 0x27, 0xfa, 0x5b, 0xe0, 0x36, 0x14, 0x97, 0xb8, - 0x9b, 0x3c, 0x09, 0x77, 0xc1, 0x0a, 0xe4, 0xa2, - 0x63, 0xfc, 0xbe, 0x5c, 0x17, 0xcf, 0x01, 0xf5, - 0x03, 0x0f, 0x17, 0xbc, 0x93, 0xdd, 0x5f, 0xe2, - 0xf3, 0x08, 0xa8, 0xb1, 0x85, 0xb6, 0x34, 0x3f, - 0x87, 0x42, 0xa5, 0x42, 0x3b, 0x0e, 0xd6, 0x83, - 0x6a, 0xfd, 0x5d, 0xc9, 0x67, 0xd5, 0x51, 0xc9, - 0x2a, 0x4e, 0x91, 0xb0, 0x59, 0xb2, 0x0f, 0xa2, - 0xe6, 0x47, 0x73, 0xc2, 0xa2, 0xae, 0xbb, 0xc8, - 0x42, 0xa3, 0x2a, 0x27, 0x29, 0x48, 0x8c, 0x54, - 0x6c, 0xec, 0x00, 0x2a, 0x42, 0xa3, 0x7a, 0x0f, - 0x12, 0x66, 0x6b, 0x96, 0xf6, 0xd0, 0x56, 0x4f, - 0x49, 0x5c, 0x47, 0xec, 0x05, 0x62, 0x54, 0xb2, - 0x64, 0x5a, 0x69, 0x1f, 0x19, 0xb4, 0x84, 0x5c, - 0xbe, 0x48, 0x8e, 0xfc, 0x58, 0x21, 0xce, 0xfa, - 0xaa, 0x84, 0xd2, 0xc1, 0x08, 0xb3, 0x87, 0x0f, - 0x4f, 0xa3, 0x3a, 0xb6, 0x44, 0xbe, 0x2e, 0x9a, - 0xdd, 0xb5, 0x44, 0x80, 0xca, 0xf4, 0xc3, 0x6e, - 0xba, 0x93, 0x77, 0xe0, 0x53, 0xfb, 0x37, 0xfb, - 0x88, 0xc3, 0x1f, 0x25, 0xde, 0x3e, 0x11, 0xf4, - 0x89, 0xe7, 0xd1, 0x3b, 0xb4, 0x23, 0xcb, 0x70, - 0xba, 0x35, 0x97, 0x7c, 0xbe, 0x84, 0x13, 0xcf, - 0xe0, 0x4d, 0x33, 0x91, 0x71, 0x85, 0xbb, 0x4b, - 0x97, 0x32, 0x5d, 0xa0, 0xb9, 0x8f, 0xdc, 0x27, - 0x5a, 0xeb, 0x71, 0xf1, 0xd5, 0x0d, 0x65, 0xb4, - 0x22, 0x81, 0xde, 0xa7, 0x58, 0x20, 0x0b, 0x18, - 0x11, 0x76, 0x5c, 0xe6, 0x6a, 0x2c, 0x99, 0x69, - 0xdc, 0xed, 0x67, 0x08, 0x5d, 0x5e, 0xe9, 0x1e, - 0x55, 0x70, 0xc1, 0x5a, 0x76, 0x1b, 0x8d, 0x2e, - 0x0d, 0xf9, 0xcc, 0x30, 0x8c, 0x44, 0x0f, 0x63, - 0x8c, 0x42, 0x8a, 0x9f, 0x4c, 0xd1, 0x48, 0x28, - 0x8a, 0xf5, 0x56, 0x2e, 0x23, 0x12, 0xfe, 0x67, - 0x9a, 0x13, 0x65, 0x75, 0x83, 0xf1, 0x3c, 0x98, - 0x07, 0x6b, 0xb7, 0x27, 0x5b, 0xf0, 0x70, 0xda, - 0x30, 0xf8, 0x74, 0x4e, 0x7a, 0x32, 0x84, 0xcc, - 0x0e, 0xcd, 0x80, 0x8b, 0x82, 0x31, 0x9a, 0x48, - 0xcf, 0x75, 0x00, 0x1f, 0x4f, 0xe0, 0x8e, 0xa3, - 0x6a, 0x2c, 0xd4, 0x73, 0x4c, 0x63, 0x7c, 0xa6, - 0x4d, 0x5e, 0xfd, 0x43, 0x3b, 0x27, 0xe1, 0x5e, - 0xa3, 0xa9, 0x5c, 0x3b, 0x60, 0xdd, 0xc6, 0x8d, - 0x5a, 0xf1, 0x3e, 0x89, 0x4b, 0x24, 0xcf, 0x01, - 0x3a, 0x2d, 0x44, 0xe7, 0xda, 0xe7, 0xa1, 0xac, - 0x11, 0x05, 0x0c, 0xa9, 0x7a, 0x82, 0x8c, 0x5c, - 0x29, 0x68, 0x9c, 0x73, 0x13, 0xcc, 0x67, 0x32, - 0x11, 0x5e, 0xe5, 0xcc, 0x8c, 0xf5, 0xa7, 0x52, - 0x83, 0x9a, 0x70, 0xef, 0xde, 0x55, 0x9c, 0xc7, - 0x8a, 0xed, 0xad, 0x28, 0x4a, 0xc5, 0x92, 0x6d, - 0x8e, 0x47, 0xca, 0xe3, 0xf8, 0x77, 0xb5, 0x26, - 0x64, 0x84, 0xc2, 0xf1, 0xd7, 0xae, 0x0c, 0xb9, - 0x39, 0x0f, 0x43, 0x6b, 0xe9, 0xe0, 0x09, 0x4b, - 0xe5, 0xe3, 0x17, 0xa6, 0x68, 0x69, 0x46, 0xf4, - 0xf0, 0x68, 0x7f, 0x2f, 0x1c, 0x7e, 0x4c, 0xd2, - 0xb5, 0xc6, 0x16, 0x85, 0xcf, 0x02, 0x4c, 0x89, - 0x0b, 0x25, 0xb0, 0xeb, 0xf3, 0x77, 0x08, 0x6a, - 0x46, 0x5c, 0xf6, 0x2f, 0xf1, 0x24, 0xc3, 0x4d, - 0x80, 0x60, 0x4d, 0x69, 0x98, 0xde, 0xc7, 0xa1, - 0xf6, 0x4e, 0x18, 0x0c, 0x2a, 0xb0, 0xb2, 0xe0, - 0x46, 0xe7, 0x49, 0x37, 0xc8, 0x5a, 0x23, 0x24, - 0xe3, 0x0f, 0xcc, 0x92, 0xb4, 0x8d, 0xdc, 0x9e -}; - -static const uint8_t AES_CBC_ciphertext_1280B[] = { - 0x91, 0x99, 0x5e, 0x9e, 0x84, 0xff, 0x59, 0x45, - 0xc1, 0xf4, 0xbc, 0x9c, 0xb9, 0x30, 0x6c, 0x51, - 0x73, 0x52, 0xb4, 0x44, 0x09, 0x79, 0xe2, 0x89, - 0x75, 0xeb, 0x54, 0x26, 0xce, 0xd8, 0x24, 0x98, - 0xaa, 0xf8, 0x13, 0x16, 0x68, 0x58, 0xc4, 0x82, - 0x0e, 0x31, 0xd3, 0x6a, 0x13, 0x58, 0x31, 0xe9, - 0x3a, 0xc1, 0x8b, 0xc5, 0x3f, 0x50, 0x42, 0xd1, - 0x93, 0xe4, 0x9b, 0x65, 0x2b, 0xf4, 0x1d, 0x9e, - 0x2d, 0xdb, 0x48, 0xef, 0x9a, 0x01, 0x68, 0xb6, - 0xea, 0x7a, 0x2b, 0xad, 0xfe, 0x77, 0x44, 0x7e, - 0x5a, 0xc5, 0x64, 0xb4, 0xfe, 0x5c, 0x80, 0xf3, - 0x20, 0x7e, 0xaf, 0x5b, 0xf8, 0xd1, 0x38, 0xa0, - 0x8d, 0x09, 0x77, 0x06, 0xfe, 0xf5, 0xf4, 0xe4, - 0xee, 0xb8, 0x95, 0x27, 0xed, 0x07, 0xb8, 0xaa, - 0x25, 0xb4, 0xe1, 0x4c, 0xeb, 0x3f, 0xdb, 0x39, - 0x66, 0x28, 0x1b, 0x60, 0x42, 0x8b, 0x99, 0xd9, - 0x49, 0xd6, 0x8c, 0xa4, 0x9d, 0xd8, 0x93, 0x58, - 0x8f, 0xfa, 0xd3, 0xf7, 0x37, 0x9c, 0x88, 0xab, - 0x16, 0x50, 0xfe, 0x01, 0x1f, 0x88, 0x48, 0xbe, - 0x21, 0xa9, 0x90, 0x9e, 0x73, 0xe9, 0x82, 0xf7, - 0xbf, 0x4b, 0x43, 0xf4, 0xbf, 0x22, 0x3c, 0x45, - 0x47, 0x95, 0x5b, 0x49, 0x71, 0x07, 0x1c, 0x8b, - 0x49, 0xa4, 0xa3, 0x49, 0xc4, 0x5f, 0xb1, 0xf5, - 0xe3, 0x6b, 0xf1, 0xdc, 0xea, 0x92, 0x7b, 0x29, - 0x40, 0xc9, 0x39, 0x5f, 0xdb, 0xbd, 0xf3, 0x6a, - 0x09, 0x9b, 0x2a, 0x5e, 0xc7, 0x0b, 0x25, 0x94, - 0x55, 0x71, 0x9c, 0x7e, 0x0e, 0xb4, 0x08, 0x12, - 0x8c, 0x6e, 0x77, 0xb8, 0x29, 0xf1, 0xc6, 0x71, - 0x04, 0x40, 0x77, 0x18, 0x3f, 0x01, 0x09, 0x9c, - 0x23, 0x2b, 0x5d, 0x2a, 0x88, 0x20, 0x23, 0x59, - 0x74, 0x2a, 0x67, 0x8f, 0xb7, 0xba, 0x38, 0x9f, - 0x0f, 0xcf, 0x94, 0xdf, 0xe1, 0x8f, 0x35, 0x5e, - 0x34, 0x0c, 0x32, 0x92, 0x2b, 0x23, 0x81, 0xf4, - 0x73, 0xa0, 0x5a, 0x2a, 0xbd, 0xa6, 0x6b, 0xae, - 0x43, 0xe2, 0xdc, 0x01, 0xc1, 0xc6, 0xc3, 0x04, - 0x06, 0xbb, 0xb0, 0x89, 0xb3, 0x4e, 0xbd, 0x81, - 0x1b, 0x03, 0x63, 0x93, 0xed, 0x4e, 0xf6, 0xe5, - 0x94, 0x6f, 0xd6, 0xf3, 0x20, 0xf3, 0xbc, 0x30, - 0xc5, 0xd6, 0xbe, 0x1c, 0x05, 0x34, 0x26, 0x4d, - 0x46, 0x5e, 0x56, 0x63, 0xfb, 0xdb, 0xcd, 0xed, - 0xb0, 0x7f, 0x83, 0x94, 0x55, 0x54, 0x2f, 0xab, - 0xc9, 0xb7, 0x16, 0x4f, 0x9e, 0x93, 0x25, 0xd7, - 0x9f, 0x39, 0x2b, 0x63, 0xcf, 0x1e, 0xa3, 0x0e, - 0x28, 0x47, 0x8a, 0x5f, 0x40, 0x02, 0x89, 0x1f, - 0x83, 0xe7, 0x87, 0xd1, 0x90, 0x17, 0xb8, 0x27, - 0x64, 0xe1, 0xe1, 0x48, 0x5a, 0x55, 0x74, 0x99, - 0x27, 0x9d, 0x05, 0x67, 0xda, 0x70, 0x12, 0x8f, - 0x94, 0x96, 0xfd, 0x36, 0xa4, 0x1d, 0x22, 0xe5, - 0x0b, 0xe5, 0x2f, 0x38, 0x55, 0xa3, 0x5d, 0x0b, - 0xcf, 0xd4, 0xa9, 0xb8, 0xd6, 0x9a, 0x16, 0x2e, - 0x6c, 0x4a, 0x25, 0x51, 0x7a, 0x09, 0x48, 0xdd, - 0xf0, 0xa3, 0x5b, 0x08, 0x1e, 0x2f, 0x03, 0x91, - 0x80, 0xe8, 0x0f, 0xe9, 0x5a, 0x2f, 0x90, 0xd3, - 0x64, 0xed, 0xd7, 0x51, 0x17, 0x66, 0x53, 0x40, - 0x43, 0x74, 0xef, 0x0a, 0x0d, 0x49, 0x41, 0xf2, - 0x67, 0x6e, 0xea, 0x14, 0xc8, 0x74, 0xd6, 0xa9, - 0xb9, 0x6a, 0xe3, 0xec, 0x7d, 0xe8, 0x6a, 0x21, - 0x3a, 0x52, 0x42, 0xfe, 0x9a, 0x15, 0x6d, 0x60, - 0x64, 0x88, 0xc5, 0xb2, 0x8b, 0x15, 0x2c, 0xff, - 0xe2, 0x35, 0xc3, 0xee, 0x9f, 0xcd, 0x82, 0xd9, - 0x14, 0x35, 0x2a, 0xb7, 0xf5, 0x2f, 0x7b, 0xbc, - 0x01, 0xfd, 0xa8, 0xe0, 0x21, 0x4e, 0x73, 0xf9, - 0xf2, 0xb0, 0x79, 0xc9, 0x10, 0x52, 0x8f, 0xa8, - 0x3e, 0x3b, 0xbe, 0xc5, 0xde, 0xf6, 0x53, 0xe3, - 0x1c, 0x25, 0x3a, 0x1f, 0x13, 0xbf, 0x13, 0xbb, - 0x94, 0xc2, 0x97, 0x43, 0x64, 0x47, 0x8f, 0x76, - 0xd7, 0xaa, 0xeb, 0xa4, 0x03, 0x50, 0x0c, 0x10, - 0x50, 0xd8, 0xf7, 0x75, 0x52, 0x42, 0xe2, 0x94, - 0x67, 0xf4, 0x60, 0xfb, 0x21, 0x9b, 0x7a, 0x05, - 0x50, 0x7c, 0x1b, 0x4a, 0x8b, 0x29, 0xe1, 0xac, - 0xd7, 0x99, 0xfd, 0x0d, 0x65, 0x92, 0xcd, 0x23, - 0xa7, 0x35, 0x8e, 0x13, 0xf2, 0xe4, 0x10, 0x74, - 0xc6, 0x4f, 0x19, 0xf7, 0x01, 0x0b, 0x46, 0xab, - 0xef, 0x8d, 0x4a, 0x4a, 0xfa, 0xda, 0xf3, 0xfb, - 0x40, 0x28, 0x88, 0xa2, 0x65, 0x98, 0x4d, 0x88, - 0xc7, 0xbf, 0x00, 0xc8, 0xd0, 0x91, 0xcb, 0x89, - 0x2f, 0xb0, 0x85, 0xfc, 0xa1, 0xc1, 0x9e, 0x83, - 0x88, 0xad, 0x95, 0xc0, 0x31, 0xa0, 0xad, 0xa2, - 0x42, 0xb5, 0xe7, 0x55, 0xd4, 0x93, 0x5a, 0x74, - 0x4e, 0x41, 0xc3, 0xcf, 0x96, 0x83, 0x46, 0xa1, - 0xb7, 0x5b, 0xb1, 0x34, 0x67, 0x4e, 0xb1, 0xd7, - 0x40, 0x20, 0x72, 0xe9, 0xc8, 0x74, 0xb7, 0xde, - 0x72, 0x29, 0x77, 0x4c, 0x74, 0x7e, 0xcc, 0x18, - 0xa5, 0x8d, 0x79, 0x8c, 0xd6, 0x6e, 0xcb, 0xd9, - 0xe1, 0x61, 0xe7, 0x36, 0xbc, 0x37, 0xea, 0xee, - 0xd8, 0x3c, 0x5e, 0x7c, 0x47, 0x50, 0xd5, 0xec, - 0x37, 0xc5, 0x63, 0xc3, 0xc9, 0x99, 0x23, 0x9f, - 0x64, 0x39, 0xdf, 0x13, 0x96, 0x6d, 0xea, 0x08, - 0x0c, 0x27, 0x2d, 0xfe, 0x0f, 0xc2, 0xa3, 0x97, - 0x04, 0x12, 0x66, 0x0d, 0x94, 0xbf, 0xbe, 0x3e, - 0xb9, 0xcf, 0x8e, 0xc1, 0x9d, 0xb1, 0x64, 0x17, - 0x54, 0x92, 0x3f, 0x0a, 0x51, 0xc8, 0xf5, 0x82, - 0x98, 0x73, 0x03, 0xc0, 0x5a, 0x51, 0x01, 0x67, - 0xb4, 0x01, 0x04, 0x06, 0xbc, 0x37, 0xde, 0x96, - 0x23, 0x3c, 0xce, 0x98, 0x3f, 0xd6, 0x51, 0x1b, - 0x01, 0x83, 0x0a, 0x1c, 0xf9, 0xeb, 0x7e, 0x72, - 0xa9, 0x51, 0x23, 0xc8, 0xd7, 0x2f, 0x12, 0xbc, - 0x08, 0xac, 0x07, 0xe7, 0xa7, 0xe6, 0x46, 0xae, - 0x54, 0xa3, 0xc2, 0xf2, 0x05, 0x2d, 0x06, 0x5e, - 0xfc, 0xe2, 0xa2, 0x23, 0xac, 0x86, 0xf2, 0x54, - 0x83, 0x4a, 0xb6, 0x48, 0x93, 0xa1, 0x78, 0xc2, - 0x07, 0xec, 0x82, 0xf0, 0x74, 0xa9, 0x18, 0xe9, - 0x53, 0x44, 0x49, 0xc2, 0x94, 0xf8, 0x94, 0x92, - 0x08, 0x3f, 0xbf, 0xa6, 0xe5, 0xc6, 0x03, 0x8a, - 0xc6, 0x90, 0x48, 0x6c, 0xee, 0xbd, 0x44, 0x92, - 0x1f, 0x2a, 0xce, 0x1d, 0xb8, 0x31, 0xa2, 0x9d, - 0x24, 0x93, 0xa8, 0x9f, 0x36, 0x00, 0x04, 0x7b, - 0xcb, 0x93, 0x59, 0xa1, 0x53, 0xdb, 0x13, 0x7a, - 0x54, 0xb1, 0x04, 0xdb, 0xce, 0x48, 0x4f, 0xe5, - 0x2f, 0xcb, 0xdf, 0x8f, 0x50, 0x7c, 0xfc, 0x76, - 0x80, 0xb4, 0xdc, 0x3b, 0xc8, 0x98, 0x95, 0xf5, - 0x50, 0xba, 0x70, 0x5a, 0x97, 0xd5, 0xfc, 0x98, - 0x4d, 0xf3, 0x61, 0x0f, 0xcf, 0xac, 0x49, 0x0a, - 0xdb, 0xc1, 0x42, 0x8f, 0xb6, 0x29, 0xd5, 0x65, - 0xef, 0x83, 0xf1, 0x30, 0x4b, 0x84, 0xd0, 0x69, - 0xde, 0xd2, 0x99, 0xe5, 0xec, 0xd3, 0x90, 0x86, - 0x39, 0x2a, 0x6e, 0xd5, 0x32, 0xe3, 0x0d, 0x2d, - 0x01, 0x8b, 0x17, 0x55, 0x1d, 0x65, 0x57, 0xbf, - 0xd8, 0x75, 0xa4, 0x85, 0xb6, 0x4e, 0x35, 0x14, - 0x58, 0xe4, 0x89, 0xb8, 0x7a, 0x58, 0x86, 0x0c, - 0xbd, 0x8b, 0x05, 0x7b, 0x63, 0xc0, 0x86, 0x80, - 0x33, 0x46, 0xd4, 0x9b, 0xb6, 0x0a, 0xeb, 0x6c, - 0xae, 0xd6, 0x57, 0x7a, 0xc7, 0x59, 0x33, 0xa0, - 0xda, 0xa4, 0x12, 0xbf, 0x52, 0x22, 0x05, 0x8d, - 0xeb, 0xee, 0xd5, 0xec, 0xea, 0x29, 0x9b, 0x76, - 0x95, 0x50, 0x6d, 0x99, 0xe1, 0x45, 0x63, 0x09, - 0x16, 0x5f, 0xb0, 0xf2, 0x5b, 0x08, 0x33, 0xdd, - 0x8f, 0xb7, 0x60, 0x7a, 0x8e, 0xc6, 0xfc, 0xac, - 0xa9, 0x56, 0x2c, 0xa9, 0x8b, 0x74, 0x33, 0xad, - 0x2a, 0x7e, 0x96, 0xb6, 0xba, 0x22, 0x28, 0xcf, - 0x4d, 0x96, 0xb7, 0xd1, 0xfa, 0x99, 0x4a, 0x61, - 0xe6, 0x84, 0xd1, 0x94, 0xca, 0xf5, 0x86, 0xb0, - 0xba, 0x34, 0x7a, 0x04, 0xcc, 0xd4, 0x81, 0xcd, - 0xd9, 0x86, 0xb6, 0xe0, 0x5a, 0x6f, 0x9b, 0x99, - 0xf0, 0xdf, 0x49, 0xae, 0x6d, 0xc2, 0x54, 0x67, - 0xe0, 0xb4, 0x34, 0x2d, 0x1c, 0x46, 0xdf, 0x73, - 0x3b, 0x45, 0x43, 0xe7, 0x1f, 0xa3, 0x36, 0x35, - 0x25, 0x33, 0xd9, 0xc0, 0x54, 0x38, 0x6e, 0x6b, - 0x80, 0xcf, 0x50, 0xa4, 0xb6, 0x21, 0x17, 0xfd, - 0x9b, 0x5c, 0x36, 0xca, 0xcc, 0x73, 0x73, 0xad, - 0xe0, 0x57, 0x77, 0x90, 0x0e, 0x7f, 0x0f, 0x87, - 0x7f, 0xdb, 0x73, 0xbf, 0xda, 0xc2, 0xb3, 0x05, - 0x22, 0x06, 0xf5, 0xa3, 0xfc, 0x1e, 0x8f, 0xda, - 0xcf, 0x49, 0xd6, 0xb3, 0x66, 0x2c, 0xb5, 0x00, - 0xaf, 0x85, 0x6e, 0xb8, 0x5b, 0x8c, 0xa1, 0xa4, - 0x21, 0xce, 0x40, 0xf3, 0x98, 0xac, 0xec, 0x88, - 0x62, 0x43, 0x2a, 0xac, 0xca, 0xcf, 0xb9, 0x30, - 0xeb, 0xfc, 0xef, 0xf0, 0x6e, 0x64, 0x6d, 0xe7, - 0x54, 0x88, 0x6b, 0x22, 0x29, 0xbe, 0xa5, 0x8c, - 0x31, 0x23, 0x3b, 0x4a, 0x80, 0x37, 0xe6, 0xd0, - 0x05, 0xfc, 0x10, 0x0e, 0xdd, 0xbb, 0x00, 0xc5, - 0x07, 0x20, 0x59, 0xd3, 0x41, 0x17, 0x86, 0x46, - 0xab, 0x68, 0xf6, 0x48, 0x3c, 0xea, 0x5a, 0x06, - 0x30, 0x21, 0x19, 0xed, 0x74, 0xbe, 0x0b, 0x97, - 0xee, 0x91, 0x35, 0x94, 0x1f, 0xcb, 0x68, 0x7f, - 0xe4, 0x48, 0xb0, 0x16, 0xfb, 0xf0, 0x74, 0xdb, - 0x06, 0x59, 0x2e, 0x5a, 0x9c, 0xce, 0x8f, 0x7d, - 0xba, 0x48, 0xd5, 0x3f, 0x5c, 0xb0, 0xc2, 0x33, - 0x48, 0x60, 0x17, 0x08, 0x85, 0xba, 0xff, 0xb9, - 0x34, 0x0a, 0x3d, 0x8f, 0x21, 0x13, 0x12, 0x1b -}; - -static const uint8_t AES_CBC_ciphertext_1536B[] = { - 0x89, 0x93, 0x05, 0x99, 0xa9, 0xed, 0xea, 0x62, - 0xc9, 0xda, 0x51, 0x15, 0xce, 0x42, 0x91, 0xc3, - 0x80, 0xc8, 0x03, 0x88, 0xc2, 0x63, 0xda, 0x53, - 0x1a, 0xf3, 0xeb, 0xd5, 0xba, 0x6f, 0x23, 0xb2, - 0xed, 0x8f, 0x89, 0xb1, 0xb3, 0xca, 0x90, 0x7a, - 0xdd, 0x3f, 0xf6, 0xca, 0x86, 0x58, 0x54, 0xbc, - 0xab, 0x0f, 0xf4, 0xab, 0x6d, 0x5d, 0x42, 0xd0, - 0x17, 0x49, 0x17, 0xd1, 0x93, 0xea, 0xe8, 0x22, - 0xc1, 0x34, 0x9f, 0x3a, 0x3b, 0xaa, 0xe9, 0x1b, - 0x93, 0xff, 0x6b, 0x68, 0xba, 0xe6, 0xd2, 0x39, - 0x3d, 0x55, 0x34, 0x8f, 0x98, 0x86, 0xb4, 0xd8, - 0x7c, 0x0d, 0x3e, 0x01, 0x63, 0x04, 0x01, 0xff, - 0x16, 0x0f, 0x51, 0x5f, 0x73, 0x53, 0xf0, 0x3a, - 0x38, 0xb4, 0x4d, 0x8d, 0xaf, 0xa3, 0xca, 0x2f, - 0x6f, 0xdf, 0xc0, 0x41, 0x6c, 0x48, 0x60, 0x1a, - 0xe4, 0xe7, 0x8a, 0x65, 0x6f, 0x8d, 0xd7, 0xe1, - 0x10, 0xab, 0x78, 0x5b, 0xb9, 0x69, 0x1f, 0xe0, - 0x5c, 0xf1, 0x19, 0x12, 0x21, 0xc7, 0x51, 0xbc, - 0x61, 0x5f, 0xc0, 0x36, 0x17, 0xc0, 0x28, 0xd9, - 0x51, 0xcb, 0x43, 0xd9, 0xfa, 0xd1, 0xad, 0x79, - 0x69, 0x86, 0x49, 0xc5, 0xe5, 0x69, 0x27, 0xce, - 0x22, 0xd0, 0xe1, 0x6a, 0xf9, 0x02, 0xca, 0x6c, - 0x34, 0xc7, 0xb8, 0x02, 0xc1, 0x38, 0x7f, 0xd5, - 0x15, 0xf5, 0xd6, 0xeb, 0xf9, 0x30, 0x40, 0x43, - 0xea, 0x87, 0xde, 0x35, 0xf6, 0x83, 0x59, 0x09, - 0x68, 0x62, 0x00, 0x87, 0xb8, 0xe7, 0xca, 0x05, - 0x0f, 0xac, 0x42, 0x58, 0x45, 0xaa, 0xc9, 0x9b, - 0xfd, 0x2a, 0xda, 0x65, 0x33, 0x93, 0x9d, 0xc6, - 0x93, 0x8d, 0xe2, 0xc5, 0x71, 0xc1, 0x5c, 0x13, - 0xde, 0x7b, 0xd4, 0xb9, 0x4c, 0x35, 0x61, 0x85, - 0x90, 0x78, 0xf7, 0x81, 0x98, 0x45, 0x99, 0x24, - 0x58, 0x73, 0x28, 0xf8, 0x31, 0xab, 0x54, 0x2e, - 0xc0, 0x38, 0x77, 0x25, 0x5c, 0x06, 0x9c, 0xc3, - 0x69, 0x21, 0x92, 0x76, 0xe1, 0x16, 0xdc, 0xa9, - 0xee, 0xb6, 0x80, 0x66, 0x43, 0x11, 0x24, 0xb3, - 0x07, 0x17, 0x89, 0x0f, 0xcb, 0xe0, 0x60, 0xa8, - 0x9d, 0x06, 0x4b, 0x6e, 0x72, 0xb7, 0xbc, 0x4f, - 0xb8, 0xc0, 0x80, 0xa2, 0xfb, 0x46, 0x5b, 0x8f, - 0x11, 0x01, 0x92, 0x9d, 0x37, 0x09, 0x98, 0xc8, - 0x0a, 0x46, 0xae, 0x12, 0xac, 0x61, 0x3f, 0xe7, - 0x41, 0x1a, 0xaa, 0x2e, 0xdc, 0xd7, 0x2a, 0x47, - 0xee, 0xdf, 0x08, 0xd1, 0xff, 0xea, 0x13, 0xc6, - 0x05, 0xdb, 0x29, 0xcc, 0x03, 0xba, 0x7b, 0x6d, - 0x40, 0xc1, 0xc9, 0x76, 0x75, 0x03, 0x7a, 0x71, - 0xc9, 0x5f, 0xd9, 0xe0, 0x61, 0x69, 0x36, 0x8f, - 0xb2, 0xbc, 0x28, 0xf3, 0x90, 0x71, 0xda, 0x5f, - 0x08, 0xd5, 0x0d, 0xc1, 0xe6, 0xbd, 0x2b, 0xc6, - 0x6c, 0x42, 0xfd, 0xbf, 0x10, 0xe8, 0x5f, 0x87, - 0x3d, 0x21, 0x42, 0x85, 0x01, 0x0a, 0xbf, 0x8e, - 0x49, 0xd3, 0x9c, 0x89, 0x3b, 0xea, 0xe1, 0xbf, - 0xe9, 0x9b, 0x5e, 0x0e, 0xb8, 0xeb, 0xcd, 0x3a, - 0xf6, 0x29, 0x41, 0x35, 0xdd, 0x9b, 0x13, 0x24, - 0xe0, 0x1d, 0x8a, 0xcb, 0x20, 0xf8, 0x41, 0x51, - 0x3e, 0x23, 0x8c, 0x67, 0x98, 0x39, 0x53, 0x77, - 0x2a, 0x68, 0xf4, 0x3c, 0x7e, 0xd6, 0xc4, 0x6e, - 0xf1, 0x53, 0xe9, 0xd8, 0x5c, 0xc1, 0xa9, 0x38, - 0x6f, 0x5e, 0xe4, 0xd4, 0x29, 0x1c, 0x6c, 0xee, - 0x2f, 0xea, 0xde, 0x61, 0x71, 0x5a, 0xea, 0xce, - 0x23, 0x6e, 0x1b, 0x16, 0x43, 0xb7, 0xc0, 0xe3, - 0x87, 0xa1, 0x95, 0x1e, 0x97, 0x4d, 0xea, 0xa6, - 0xf7, 0x25, 0xac, 0x82, 0x2a, 0xd3, 0xa6, 0x99, - 0x75, 0xdd, 0xc1, 0x55, 0x32, 0x6b, 0xea, 0x33, - 0x88, 0xce, 0x06, 0xac, 0x15, 0x39, 0x19, 0xa3, - 0x59, 0xaf, 0x7a, 0x1f, 0xd9, 0x72, 0x5e, 0xf7, - 0x4c, 0xf3, 0x5d, 0x6b, 0xf2, 0x16, 0x92, 0xa8, - 0x9e, 0x3d, 0xd4, 0x4c, 0x72, 0x55, 0x4e, 0x4a, - 0xf7, 0x8b, 0x2f, 0x67, 0x5a, 0x90, 0xb7, 0xcf, - 0x16, 0xd3, 0x7b, 0x5a, 0x9a, 0xc8, 0x9f, 0xbf, - 0x01, 0x76, 0x3b, 0x86, 0x2c, 0x2a, 0x78, 0x10, - 0x70, 0x05, 0x38, 0xf9, 0xdd, 0x2a, 0x1d, 0x00, - 0x25, 0xb7, 0x10, 0xac, 0x3b, 0x3c, 0x4d, 0x3c, - 0x01, 0x68, 0x3c, 0x5a, 0x29, 0xc2, 0xa0, 0x1b, - 0x95, 0x67, 0xf9, 0x0a, 0x60, 0xb7, 0x11, 0x9c, - 0x40, 0x45, 0xd7, 0xb0, 0xda, 0x49, 0x87, 0xcd, - 0xb0, 0x9b, 0x61, 0x8c, 0xf4, 0x0d, 0x94, 0x1d, - 0x79, 0x66, 0x13, 0x0b, 0xc6, 0x6b, 0x19, 0xee, - 0xa0, 0x6b, 0x64, 0x7d, 0xc4, 0xff, 0x98, 0x72, - 0x60, 0xab, 0x7f, 0x0f, 0x4d, 0x5d, 0x6b, 0xc3, - 0xba, 0x5e, 0x0d, 0x04, 0xd9, 0x59, 0x17, 0xd0, - 0x64, 0xbe, 0xfb, 0x58, 0xfc, 0xed, 0x18, 0xf6, - 0xac, 0x19, 0xa4, 0xfd, 0x16, 0x59, 0x80, 0x58, - 0xb8, 0x0f, 0x79, 0x24, 0x60, 0x18, 0x62, 0xa9, - 0xa3, 0xa0, 0xe8, 0x81, 0xd6, 0xec, 0x5b, 0xfe, - 0x5b, 0xb8, 0xa4, 0x00, 0xa9, 0xd0, 0x90, 0x17, - 0xe5, 0x50, 0x3d, 0x2b, 0x12, 0x6e, 0x2a, 0x13, - 0x65, 0x7c, 0xdf, 0xdf, 0xa7, 0xdd, 0x9f, 0x78, - 0x5f, 0x8f, 0x4e, 0x90, 0xa6, 0x10, 0xe4, 0x7b, - 0x68, 0x6b, 0xfd, 0xa9, 0x6d, 0x47, 0xfa, 0xec, - 0x42, 0x35, 0x07, 0x12, 0x3e, 0x78, 0x23, 0x15, - 0xff, 0xe2, 0x65, 0xc7, 0x47, 0x89, 0x2f, 0x97, - 0x7c, 0xd7, 0x6b, 0x69, 0x35, 0x79, 0x6f, 0x85, - 0xb4, 0xa9, 0x75, 0x04, 0x32, 0x9a, 0xfe, 0xf0, - 0xce, 0xe3, 0xf1, 0xab, 0x15, 0x47, 0xe4, 0x9c, - 0xc1, 0x48, 0x32, 0x3c, 0xbe, 0x44, 0x72, 0xc9, - 0xaa, 0x50, 0x37, 0xa6, 0xbe, 0x41, 0xcf, 0xe8, - 0x17, 0x4e, 0x37, 0xbe, 0xf1, 0x34, 0x2c, 0xd9, - 0x60, 0x48, 0x09, 0xa5, 0x26, 0x00, 0x31, 0x77, - 0x4e, 0xac, 0x7c, 0x89, 0x75, 0xe3, 0xde, 0x26, - 0x4c, 0x32, 0x54, 0x27, 0x8e, 0x92, 0x26, 0x42, - 0x85, 0x76, 0x01, 0x76, 0x62, 0x4c, 0x29, 0xe9, - 0x38, 0x05, 0x51, 0x54, 0x97, 0xa3, 0x03, 0x59, - 0x5e, 0xec, 0x0c, 0xe4, 0x96, 0xb7, 0x15, 0xa8, - 0x41, 0x06, 0x2b, 0x78, 0x95, 0x24, 0xf6, 0x32, - 0xc5, 0xec, 0xd7, 0x89, 0x28, 0x1e, 0xec, 0xb1, - 0xc7, 0x21, 0x0c, 0xd3, 0x80, 0x7c, 0x5a, 0xe6, - 0xb1, 0x3a, 0x52, 0x33, 0x84, 0x4e, 0x32, 0x6e, - 0x7a, 0xf6, 0x43, 0x15, 0x5b, 0xa6, 0xba, 0xeb, - 0xa8, 0xe4, 0xff, 0x4f, 0xbd, 0xbd, 0xa8, 0x5e, - 0xbe, 0x27, 0xaf, 0xc5, 0xf7, 0x9e, 0xdf, 0x48, - 0x22, 0xca, 0x6a, 0x0b, 0x3c, 0xd7, 0xe0, 0xdc, - 0xf3, 0x71, 0x08, 0xdc, 0x28, 0x13, 0x08, 0xf2, - 0x08, 0x1d, 0x9d, 0x7b, 0xd9, 0xde, 0x6f, 0xe6, - 0xe8, 0x88, 0x18, 0xc2, 0xcd, 0x93, 0xc5, 0x38, - 0x21, 0x68, 0x4c, 0x9a, 0xfb, 0xb6, 0x18, 0x16, - 0x73, 0x2c, 0x1d, 0x6f, 0x95, 0xfb, 0x65, 0x4f, - 0x7c, 0xec, 0x8d, 0x6c, 0xa8, 0xc0, 0x55, 0x28, - 0xc6, 0xc3, 0xea, 0xeb, 0x05, 0xf5, 0x65, 0xeb, - 0x53, 0xe1, 0x54, 0xef, 0xb8, 0x64, 0x98, 0x2d, - 0x98, 0x9e, 0xc8, 0xfe, 0xa2, 0x07, 0x30, 0xf7, - 0xf7, 0xae, 0xdb, 0x32, 0xf8, 0x71, 0x9d, 0x06, - 0xdf, 0x9b, 0xda, 0x61, 0x7d, 0xdb, 0xae, 0x06, - 0x24, 0x63, 0x74, 0xb6, 0xf3, 0x1b, 0x66, 0x09, - 0x60, 0xff, 0x2b, 0x29, 0xf5, 0xa9, 0x9d, 0x61, - 0x5d, 0x55, 0x10, 0x82, 0x21, 0xbb, 0x64, 0x0d, - 0xef, 0x5c, 0xe3, 0x30, 0x1b, 0x60, 0x1e, 0x5b, - 0xfe, 0x6c, 0xf5, 0x15, 0xa3, 0x86, 0x27, 0x58, - 0x46, 0x00, 0x20, 0xcb, 0x86, 0x9a, 0x52, 0x29, - 0x20, 0x68, 0x4d, 0x67, 0x88, 0x70, 0xc2, 0x31, - 0xd8, 0xbb, 0xa5, 0xa7, 0x88, 0x7f, 0x66, 0xbc, - 0xaa, 0x0f, 0xe1, 0x78, 0x7b, 0x97, 0x3c, 0xb7, - 0xd7, 0xd8, 0x04, 0xe0, 0x09, 0x60, 0xc8, 0xd0, - 0x9e, 0xe5, 0x6b, 0x31, 0x7f, 0x88, 0xfe, 0xc3, - 0xfd, 0x89, 0xec, 0x76, 0x4b, 0xb3, 0xa7, 0x37, - 0x03, 0xb7, 0xc6, 0x10, 0x7c, 0x9d, 0x0c, 0x75, - 0xd3, 0x08, 0x14, 0x94, 0x03, 0x42, 0x25, 0x26, - 0x85, 0xf7, 0xf0, 0x90, 0x06, 0x3e, 0x6f, 0x60, - 0x52, 0x55, 0xd5, 0x0f, 0x79, 0x64, 0x69, 0x69, - 0x46, 0xf9, 0x7f, 0x7f, 0x03, 0xf1, 0x1f, 0xdb, - 0x39, 0x05, 0xba, 0x4a, 0x8f, 0x17, 0xe7, 0xba, - 0xe2, 0x07, 0x7c, 0x1d, 0x9e, 0xbc, 0x94, 0xc0, - 0x61, 0x59, 0x8e, 0x72, 0xaf, 0xfc, 0x99, 0xe4, - 0xd5, 0xa8, 0xee, 0x0a, 0x48, 0x2d, 0x82, 0x8b, - 0x34, 0x54, 0x8a, 0xce, 0xc7, 0xfa, 0xdd, 0xba, - 0x54, 0xdf, 0xb3, 0x30, 0x33, 0x73, 0x2e, 0xd5, - 0x52, 0xab, 0x49, 0x91, 0x4e, 0x0a, 0xd6, 0x2f, - 0x67, 0xe4, 0xdd, 0x64, 0x48, 0x16, 0xd9, 0x85, - 0xaa, 0x52, 0xa5, 0x0b, 0xd3, 0xb4, 0x2d, 0x77, - 0x5e, 0x52, 0x77, 0x17, 0xcf, 0xbe, 0x88, 0x04, - 0x01, 0x52, 0xe2, 0xf1, 0x46, 0xe2, 0x91, 0x30, - 0x65, 0xcf, 0xc0, 0x65, 0x45, 0xc3, 0x7e, 0xf4, - 0x2e, 0xb5, 0xaf, 0x6f, 0xab, 0x1a, 0xfa, 0x70, - 0x35, 0xb8, 0x4f, 0x2d, 0x78, 0x90, 0x33, 0xb5, - 0x9a, 0x67, 0xdb, 0x2f, 0x28, 0x32, 0xb6, 0x54, - 0xab, 0x4c, 0x6b, 0x85, 0xed, 0x6c, 0x3e, 0x05, - 0x2a, 0xc7, 0x32, 0xe8, 0xf5, 0xa3, 0x7b, 0x4e, - 0x7b, 0x58, 0x24, 0x73, 0xf7, 0xfd, 0xc7, 0xc8, - 0x6c, 0x71, 0x68, 0xb1, 0xf6, 0xc5, 0x9e, 0x1e, - 0xe3, 0x5c, 0x25, 0xc0, 0x5b, 0x3e, 0x59, 0xa1, - 0x18, 0x5a, 0xe8, 0xb5, 0xd1, 0x44, 0x13, 0xa3, - 0xe6, 0x05, 0x76, 0xd2, 0x8d, 0x6e, 0x54, 0x68, - 0x0c, 0xa4, 0x7b, 0x8b, 0xd3, 0x8c, 0x42, 0x13, - 0x87, 0xda, 0xdf, 0x8f, 0xa5, 0x83, 0x7a, 0x42, - 0x99, 0xb7, 0xeb, 0xe2, 0x79, 0xe0, 0xdb, 0xda, - 0x33, 0xa8, 0x50, 0x3a, 0xd7, 0xe7, 0xd3, 0x61, - 0x18, 0xb8, 0xaa, 0x2d, 0xc8, 0xd8, 0x2c, 0x28, - 0xe5, 0x97, 0x0a, 0x7c, 0x6c, 0x7f, 0x09, 0xd7, - 0x88, 0x80, 0xac, 0x12, 0xed, 0xf8, 0xc6, 0xb5, - 0x2d, 0xd6, 0x63, 0x9b, 0x98, 0x35, 0x26, 0xde, - 0xf6, 0x31, 0xee, 0x7e, 0xa0, 0xfb, 0x16, 0x98, - 0xb1, 0x96, 0x1d, 0xee, 0xe3, 0x2f, 0xfb, 0x41, - 0xdd, 0xea, 0x10, 0x1e, 0x03, 0x89, 0x18, 0xd2, - 0x47, 0x0c, 0xa0, 0x57, 0xda, 0x76, 0x3a, 0x37, - 0x2c, 0xe4, 0xf9, 0x77, 0xc8, 0x43, 0x5f, 0xcb, - 0xd6, 0x85, 0xf7, 0x22, 0xe4, 0x32, 0x25, 0xa8, - 0xdc, 0x21, 0xc0, 0xf5, 0x95, 0xb2, 0xf8, 0x83, - 0xf0, 0x65, 0x61, 0x15, 0x48, 0x94, 0xb7, 0x03, - 0x7f, 0x66, 0xa1, 0x39, 0x1f, 0xdd, 0xce, 0x96, - 0xfe, 0x58, 0x81, 0x3d, 0x41, 0x11, 0x87, 0x13, - 0x26, 0x1b, 0x6d, 0xf3, 0xca, 0x2e, 0x2c, 0x76, - 0xd3, 0x2f, 0x6d, 0x49, 0x70, 0x53, 0x05, 0x96, - 0xcc, 0x30, 0x2b, 0x83, 0xf2, 0xc6, 0xb2, 0x4b, - 0x22, 0x13, 0x95, 0x42, 0xeb, 0x56, 0x4d, 0x22, - 0xe6, 0x43, 0x6f, 0xba, 0xe7, 0x3b, 0xe5, 0x59, - 0xce, 0x57, 0x88, 0x85, 0xb6, 0xbf, 0x15, 0x37, - 0xb3, 0x7a, 0x7e, 0xc4, 0xbc, 0x99, 0xfc, 0xe4, - 0x89, 0x00, 0x68, 0x39, 0xbc, 0x5a, 0xba, 0xab, - 0x52, 0xab, 0xe6, 0x81, 0xfd, 0x93, 0x62, 0xe9, - 0xb7, 0x12, 0xd1, 0x18, 0x1a, 0xb9, 0x55, 0x4a, - 0x0f, 0xae, 0x35, 0x11, 0x04, 0x27, 0xf3, 0x42, - 0x4e, 0xca, 0xdf, 0x9f, 0x12, 0x62, 0xea, 0x03, - 0xc0, 0xa9, 0x22, 0x7b, 0x6c, 0x6c, 0xe3, 0xdf, - 0x16, 0xad, 0x03, 0xc9, 0xfe, 0xa4, 0xdd, 0x4f -}; - -static const uint8_t AES_CBC_ciphertext_1792B[] = { - 0x59, 0xcc, 0xfe, 0x8f, 0xb4, 0x9d, 0x0e, 0xd1, - 0x85, 0xfc, 0x9b, 0x43, 0xc1, 0xb7, 0x54, 0x67, - 0x01, 0xef, 0xb8, 0x71, 0x36, 0xdb, 0x50, 0x48, - 0x7a, 0xea, 0xcf, 0xce, 0xba, 0x30, 0x10, 0x2e, - 0x96, 0x2b, 0xfd, 0xcf, 0x00, 0xe3, 0x1f, 0xac, - 0x66, 0x14, 0x30, 0x86, 0x49, 0xdb, 0x01, 0x8b, - 0x07, 0xdd, 0x00, 0x9d, 0x0d, 0x5c, 0x19, 0x11, - 0xe8, 0x44, 0x2b, 0x25, 0x70, 0xed, 0x7c, 0x33, - 0x0d, 0xe3, 0x34, 0x93, 0x63, 0xad, 0x26, 0xb1, - 0x11, 0x91, 0x34, 0x2e, 0x1d, 0x50, 0xaa, 0xd4, - 0xef, 0x3a, 0x6d, 0xd7, 0x33, 0x20, 0x0d, 0x3f, - 0x9b, 0xdd, 0xc3, 0xa5, 0xc5, 0xf1, 0x99, 0xdc, - 0xea, 0x52, 0xda, 0x55, 0xea, 0xa2, 0x7a, 0xc5, - 0x78, 0x44, 0x4a, 0x02, 0x33, 0x19, 0x62, 0x37, - 0xf8, 0x8b, 0xd1, 0x0c, 0x21, 0xdf, 0x40, 0x19, - 0x81, 0xea, 0xfb, 0x1c, 0xa7, 0xcc, 0x60, 0xfe, - 0x63, 0x25, 0x8f, 0xf3, 0x73, 0x0f, 0x45, 0xe6, - 0x6a, 0x18, 0xbf, 0xbe, 0xad, 0x92, 0x2a, 0x1e, - 0x15, 0x65, 0x6f, 0xef, 0x92, 0xcd, 0x0e, 0x19, - 0x3d, 0x42, 0xa8, 0xfc, 0x0d, 0x32, 0x58, 0xe0, - 0x56, 0x9f, 0xd6, 0x9b, 0x8b, 0xec, 0xe0, 0x45, - 0x4d, 0x7e, 0x73, 0x87, 0xff, 0x74, 0x92, 0x59, - 0x60, 0x13, 0x93, 0xda, 0xec, 0xbf, 0xfa, 0x20, - 0xb6, 0xe7, 0xdf, 0xc7, 0x10, 0xf5, 0x79, 0xb4, - 0xd7, 0xac, 0xaf, 0x2b, 0x37, 0x52, 0x30, 0x1d, - 0xbe, 0x0f, 0x60, 0x77, 0x3d, 0x03, 0x63, 0xa9, - 0xae, 0xb1, 0xf3, 0xca, 0xca, 0xb4, 0x21, 0xd7, - 0x6f, 0x2e, 0x5e, 0x9b, 0x68, 0x53, 0x80, 0xab, - 0x30, 0x23, 0x0a, 0x72, 0x6b, 0xb1, 0xd8, 0x25, - 0x5d, 0x3a, 0x62, 0x9b, 0x4f, 0x59, 0x3b, 0x79, - 0xa8, 0x9e, 0x08, 0x6d, 0x37, 0xb0, 0xfc, 0x42, - 0x51, 0x25, 0x86, 0xbd, 0x54, 0x5a, 0x95, 0x20, - 0x6c, 0xac, 0xb9, 0x30, 0x1c, 0x03, 0xc9, 0x49, - 0x38, 0x55, 0x31, 0x49, 0xed, 0xa9, 0x0e, 0xc3, - 0x65, 0xb4, 0x68, 0x6b, 0x07, 0x4c, 0x0a, 0xf9, - 0x21, 0x69, 0x7c, 0x9f, 0x28, 0x80, 0xe9, 0x49, - 0x22, 0x7c, 0xec, 0x97, 0xf7, 0x70, 0xb4, 0xb8, - 0x25, 0xe7, 0x80, 0x2c, 0x43, 0x24, 0x8a, 0x2e, - 0xac, 0xa2, 0x84, 0x20, 0xe7, 0xf4, 0x6b, 0x86, - 0x37, 0x05, 0xc7, 0x59, 0x04, 0x49, 0x2a, 0x99, - 0x80, 0x46, 0x32, 0x19, 0xe6, 0x30, 0xce, 0xc0, - 0xef, 0x6e, 0xec, 0xe5, 0x2f, 0x24, 0xc1, 0x78, - 0x45, 0x02, 0xd3, 0x64, 0x99, 0xf5, 0xc7, 0xbc, - 0x8f, 0x8c, 0x75, 0xb1, 0x0a, 0xc8, 0xc3, 0xbd, - 0x5e, 0x7e, 0xbd, 0x0e, 0xdf, 0x4b, 0x96, 0x6a, - 0xfd, 0x03, 0xdb, 0xd1, 0x31, 0x1e, 0x27, 0xf9, - 0xe5, 0x83, 0x9a, 0xfc, 0x13, 0x4c, 0xd3, 0x04, - 0xdb, 0xdb, 0x3f, 0x35, 0x93, 0x4e, 0x14, 0x6b, - 0x00, 0x5c, 0xb6, 0x11, 0x50, 0xee, 0x61, 0x5c, - 0x10, 0x5c, 0xd0, 0x90, 0x02, 0x2e, 0x12, 0xe0, - 0x50, 0x44, 0xad, 0x75, 0xcd, 0x94, 0xcf, 0x92, - 0xcb, 0xe3, 0xe8, 0x77, 0x4b, 0xd7, 0x1a, 0x7c, - 0xdd, 0x6b, 0x49, 0x21, 0x7c, 0xe8, 0x2c, 0x25, - 0x49, 0x86, 0x1e, 0x54, 0xae, 0xfc, 0x0e, 0x80, - 0xb1, 0xd5, 0xa5, 0x23, 0xcf, 0xcc, 0x0e, 0x11, - 0xe2, 0x7c, 0x3c, 0x25, 0x78, 0x64, 0x03, 0xa1, - 0xdd, 0x9f, 0x74, 0x12, 0x7b, 0x21, 0xb5, 0x73, - 0x15, 0x3c, 0xed, 0xad, 0x07, 0x62, 0x21, 0x79, - 0xd4, 0x2f, 0x0d, 0x72, 0xe9, 0x7c, 0x6b, 0x96, - 0x6e, 0xe5, 0x36, 0x4a, 0xd2, 0x38, 0xe1, 0xff, - 0x6e, 0x26, 0xa4, 0xac, 0x83, 0x07, 0xe6, 0x67, - 0x74, 0x6c, 0xec, 0x8b, 0x4b, 0x79, 0x33, 0x50, - 0x2f, 0x8f, 0xa0, 0x8f, 0xfa, 0x38, 0x6a, 0xa2, - 0x3a, 0x42, 0x85, 0x15, 0x90, 0xd0, 0xb3, 0x0d, - 0x8a, 0xe4, 0x60, 0x03, 0xef, 0xf9, 0x65, 0x8a, - 0x4e, 0x50, 0x8c, 0x65, 0xba, 0x61, 0x16, 0xc3, - 0x93, 0xb7, 0x75, 0x21, 0x98, 0x25, 0x60, 0x6e, - 0x3d, 0x68, 0xba, 0x7c, 0xe4, 0xf3, 0xd9, 0x9b, - 0xfb, 0x7a, 0xed, 0x1f, 0xb3, 0x4b, 0x88, 0x74, - 0x2c, 0xb8, 0x8c, 0x22, 0x95, 0xce, 0x90, 0xf1, - 0xdb, 0x80, 0xa6, 0x39, 0xae, 0x82, 0xa1, 0xef, - 0x75, 0xec, 0xfe, 0xf1, 0xe8, 0x04, 0xfd, 0x99, - 0x1b, 0x5f, 0x45, 0x87, 0x4f, 0xfa, 0xa2, 0x3e, - 0x3e, 0xb5, 0x01, 0x4b, 0x46, 0xeb, 0x13, 0x9a, - 0xe4, 0x7d, 0x03, 0x87, 0xb1, 0x59, 0x91, 0x8e, - 0x37, 0xd3, 0x16, 0xce, 0xef, 0x4b, 0xe9, 0x46, - 0x8d, 0x2a, 0x50, 0x2f, 0x41, 0xd3, 0x7b, 0xcf, - 0xf0, 0xb7, 0x8b, 0x65, 0x0f, 0xa3, 0x27, 0x10, - 0xe9, 0xa9, 0xe9, 0x2c, 0xbe, 0xbb, 0x82, 0xe3, - 0x7b, 0x0b, 0x81, 0x3e, 0xa4, 0x6a, 0x4f, 0x3b, - 0xd5, 0x61, 0xf8, 0x47, 0x04, 0x99, 0x5b, 0xff, - 0xf3, 0x14, 0x6e, 0x57, 0x5b, 0xbf, 0x1b, 0xb4, - 0x3f, 0xf9, 0x31, 0xf6, 0x95, 0xd5, 0x10, 0xa9, - 0x72, 0x28, 0x23, 0xa9, 0x6a, 0xa2, 0xcf, 0x7d, - 0xe3, 0x18, 0x95, 0xda, 0xbc, 0x6f, 0xe9, 0xd8, - 0xef, 0x49, 0x3f, 0xd3, 0xef, 0x1f, 0xe1, 0x50, - 0xe8, 0x8a, 0xc0, 0xce, 0xcc, 0xb7, 0x5e, 0x0e, - 0x8b, 0x95, 0x80, 0xfd, 0x58, 0x2a, 0x9b, 0xc8, - 0xb4, 0x17, 0x04, 0x46, 0x74, 0xd4, 0x68, 0x91, - 0x33, 0xc8, 0x31, 0x15, 0x84, 0x16, 0x35, 0x03, - 0x64, 0x6d, 0xa9, 0x4e, 0x20, 0xeb, 0xa9, 0x3f, - 0x21, 0x5e, 0x9b, 0x09, 0xc3, 0x45, 0xf8, 0x7c, - 0x59, 0x62, 0x29, 0x9a, 0x5c, 0xcf, 0xb4, 0x27, - 0x5e, 0x13, 0xea, 0xb3, 0xef, 0xd9, 0x01, 0x2a, - 0x65, 0x5f, 0x14, 0xf4, 0xbf, 0x28, 0x89, 0x3d, - 0xdd, 0x9d, 0x52, 0xbd, 0x9e, 0x5b, 0x3b, 0xd2, - 0xc2, 0x81, 0x35, 0xb6, 0xac, 0xdd, 0x27, 0xc3, - 0x7b, 0x01, 0x5a, 0x6d, 0x4c, 0x5e, 0x2c, 0x30, - 0xcb, 0x3a, 0xfa, 0xc1, 0xd7, 0x31, 0x67, 0x3e, - 0x08, 0x6a, 0xe8, 0x8c, 0x75, 0xac, 0x1a, 0x6a, - 0x52, 0xf7, 0x51, 0xcd, 0x85, 0x3f, 0x3c, 0xa7, - 0xea, 0xbc, 0xd7, 0x18, 0x9e, 0x27, 0x73, 0xe6, - 0x2b, 0x58, 0xb6, 0xd2, 0x29, 0x68, 0xd5, 0x8f, - 0x00, 0x4d, 0x55, 0xf6, 0x61, 0x5a, 0xcc, 0x51, - 0xa6, 0x5e, 0x85, 0xcb, 0x0b, 0xfd, 0x06, 0xca, - 0xf5, 0xbf, 0x0d, 0x13, 0x74, 0x78, 0x6d, 0x9e, - 0x20, 0x11, 0x84, 0x3e, 0x78, 0x17, 0x04, 0x4f, - 0x64, 0x2c, 0x3b, 0x3e, 0x93, 0x7b, 0x58, 0x33, - 0x07, 0x52, 0xf7, 0x60, 0x6a, 0xa8, 0x3b, 0x19, - 0x27, 0x7a, 0x93, 0xc5, 0x53, 0xad, 0xec, 0xf6, - 0xc8, 0x94, 0xee, 0x92, 0xea, 0xee, 0x7e, 0xea, - 0xb9, 0x5f, 0xac, 0x59, 0x5d, 0x2e, 0x78, 0x53, - 0x72, 0x81, 0x92, 0xdd, 0x1c, 0x63, 0xbe, 0x02, - 0xeb, 0xa8, 0x1b, 0x2a, 0x6e, 0x72, 0xe3, 0x2d, - 0x84, 0x0d, 0x8a, 0x22, 0xf6, 0xba, 0xab, 0x04, - 0x8e, 0x04, 0x24, 0xdb, 0xcc, 0xe2, 0x69, 0xeb, - 0x4e, 0xfa, 0x6b, 0x5b, 0xc8, 0xc0, 0xd9, 0x25, - 0xcb, 0x40, 0x8d, 0x4b, 0x8e, 0xa0, 0xd4, 0x72, - 0x98, 0x36, 0x46, 0x3b, 0x4f, 0x5f, 0x96, 0x84, - 0x03, 0x28, 0x86, 0x4d, 0xa1, 0x8a, 0xd7, 0xb2, - 0x5b, 0x27, 0x01, 0x80, 0x62, 0x49, 0x56, 0xb9, - 0xa0, 0xa1, 0xe3, 0x6e, 0x22, 0x2a, 0x5d, 0x03, - 0x86, 0x40, 0x36, 0x22, 0x5e, 0xd2, 0xe5, 0xc0, - 0x6b, 0xfa, 0xac, 0x80, 0x4e, 0x09, 0x99, 0xbc, - 0x2f, 0x9b, 0xcc, 0xf3, 0x4e, 0xf7, 0x99, 0x98, - 0x11, 0x6e, 0x6f, 0x62, 0x22, 0x6b, 0x92, 0x95, - 0x3b, 0xc3, 0xd2, 0x8e, 0x0f, 0x07, 0xc2, 0x51, - 0x5c, 0x4d, 0xb2, 0x6e, 0xc0, 0x27, 0x73, 0xcd, - 0x57, 0xb7, 0xf0, 0xe9, 0x2e, 0xc8, 0xe2, 0x0c, - 0xd1, 0xb5, 0x0f, 0xff, 0xf9, 0xec, 0x38, 0xba, - 0x97, 0xd6, 0x94, 0x9b, 0xd1, 0x79, 0xb6, 0x6a, - 0x01, 0x17, 0xe4, 0x7e, 0xa6, 0xd5, 0x86, 0x19, - 0xae, 0xf3, 0xf0, 0x62, 0x73, 0xc0, 0xf0, 0x0a, - 0x7a, 0x96, 0x93, 0x72, 0x89, 0x7e, 0x25, 0x57, - 0xf8, 0xf7, 0xd5, 0x1e, 0xe5, 0xac, 0xd6, 0x38, - 0x4f, 0xe8, 0x81, 0xd1, 0x53, 0x41, 0x07, 0x2d, - 0x58, 0x34, 0x1c, 0xef, 0x74, 0x2e, 0x61, 0xca, - 0xd3, 0xeb, 0xd6, 0x93, 0x0a, 0xf2, 0xf2, 0x86, - 0x9c, 0xe3, 0x7a, 0x52, 0xf5, 0x42, 0xf1, 0x8b, - 0x10, 0xf2, 0x25, 0x68, 0x7e, 0x61, 0xb1, 0x19, - 0xcf, 0x8f, 0x5a, 0x53, 0xb7, 0x68, 0x4f, 0x1a, - 0x71, 0xe9, 0x83, 0x91, 0x3a, 0x78, 0x0f, 0xf7, - 0xd4, 0x74, 0xf5, 0x06, 0xd2, 0x88, 0xb0, 0x06, - 0xe5, 0xc0, 0xfb, 0xb3, 0x91, 0xad, 0xc0, 0x84, - 0x31, 0xf2, 0x3a, 0xcf, 0x63, 0xe6, 0x4a, 0xd3, - 0x78, 0xbe, 0xde, 0x73, 0x3e, 0x02, 0x8e, 0xb8, - 0x3a, 0xf6, 0x55, 0xa7, 0xf8, 0x5a, 0xb5, 0x0e, - 0x0c, 0xc5, 0xe5, 0x66, 0xd5, 0xd2, 0x18, 0xf3, - 0xef, 0xa5, 0xc9, 0x68, 0x69, 0xe0, 0xcd, 0x00, - 0x33, 0x99, 0x6e, 0xea, 0xcb, 0x06, 0x7a, 0xe1, - 0xe1, 0x19, 0x0b, 0xe7, 0x08, 0xcd, 0x09, 0x1b, - 0x85, 0xec, 0xc4, 0xd4, 0x75, 0xf0, 0xd6, 0xfb, - 0x84, 0x95, 0x07, 0x44, 0xca, 0xa5, 0x2a, 0x6c, - 0xc2, 0x00, 0x58, 0x08, 0x87, 0x9e, 0x0a, 0xd4, - 0x06, 0xe2, 0x91, 0x5f, 0xb7, 0x1b, 0x11, 0xfa, - 0x85, 0xfc, 0x7c, 0xf2, 0x0f, 0x6e, 0x3c, 0x8a, - 0xe1, 0x0f, 0xa0, 0x33, 0x84, 0xce, 0x81, 0x4d, - 0x32, 0x4d, 0xeb, 0x41, 0xcf, 0x5a, 0x05, 0x60, - 0x47, 0x6c, 0x2a, 0xc4, 0x17, 0xd5, 0x16, 0x3a, - 0xe4, 0xe7, 0xab, 0x84, 0x94, 0x22, 0xff, 0x56, - 0xb0, 0x0c, 0x92, 0x6c, 0x19, 0x11, 0x4c, 0xb3, - 0xed, 0x58, 0x48, 0x84, 0x2a, 0xe2, 0x19, 0x2a, - 0xe1, 0xc0, 0x56, 0x82, 0x3c, 0x83, 0xb4, 0x58, - 0x2d, 0xf0, 0xb5, 0x1e, 0x76, 0x85, 0x51, 0xc2, - 0xe4, 0x95, 0x27, 0x96, 0xd1, 0x90, 0xc3, 0x17, - 0x75, 0xa1, 0xbb, 0x46, 0x5f, 0xa6, 0xf2, 0xef, - 0x71, 0x56, 0x92, 0xc5, 0x8a, 0x85, 0x52, 0xe4, - 0x63, 0x21, 0x6f, 0x55, 0x85, 0x2b, 0x6b, 0x0d, - 0xc9, 0x92, 0x77, 0x67, 0xe3, 0xff, 0x2a, 0x2b, - 0x90, 0x01, 0x3d, 0x74, 0x63, 0x04, 0x61, 0x3c, - 0x8e, 0xf8, 0xfc, 0x04, 0xdd, 0x21, 0x85, 0x92, - 0x1e, 0x4d, 0x51, 0x8d, 0xb5, 0x6b, 0xf1, 0xda, - 0x96, 0xf5, 0x8e, 0x3c, 0x38, 0x5a, 0xac, 0x9b, - 0xba, 0x0c, 0x84, 0x5d, 0x50, 0x12, 0xc7, 0xc5, - 0x7a, 0xcb, 0xb1, 0xfa, 0x16, 0x93, 0xdf, 0x98, - 0xda, 0x3f, 0x49, 0xa3, 0x94, 0x78, 0x70, 0xc7, - 0x0b, 0xb6, 0x91, 0xa6, 0x16, 0x2e, 0xcf, 0xfd, - 0x51, 0x6a, 0x5b, 0xad, 0x7a, 0xdd, 0xa9, 0x48, - 0x48, 0xac, 0xd6, 0x45, 0xbc, 0x23, 0x31, 0x1d, - 0x86, 0x54, 0x8a, 0x7f, 0x04, 0x97, 0x71, 0x9e, - 0xbc, 0x2e, 0x6b, 0xd9, 0x33, 0xc8, 0x20, 0xc9, - 0xe0, 0x25, 0x86, 0x59, 0x15, 0xcf, 0x63, 0xe5, - 0x99, 0xf1, 0x24, 0xf1, 0xba, 0xc4, 0x15, 0x02, - 0xe2, 0xdb, 0xfe, 0x4a, 0xf8, 0x3b, 0x91, 0x13, - 0x8d, 0x03, 0x81, 0x9f, 0xb3, 0x3f, 0x04, 0x03, - 0x58, 0xc0, 0xef, 0x27, 0x82, 0x14, 0xd2, 0x7f, - 0x93, 0x70, 0xb7, 0xb2, 0x02, 0x21, 0xb3, 0x07, - 0x7f, 0x1c, 0xef, 0x88, 0xee, 0x29, 0x7a, 0x0b, - 0x3d, 0x75, 0x5a, 0x93, 0xfe, 0x7f, 0x14, 0xf7, - 0x4e, 0x4b, 0x7f, 0x21, 0x02, 0xad, 0xf9, 0x43, - 0x29, 0x1a, 0xe8, 0x1b, 0xf5, 0x32, 0xb2, 0x96, - 0xe6, 0xe8, 0x96, 0x20, 0x9b, 0x96, 0x8e, 0x7b, - 0xfe, 0xd8, 0xc9, 0x9c, 0x65, 0x16, 0xd6, 0x68, - 0x95, 0xf8, 0x22, 0xe2, 0xae, 0x84, 0x03, 0xfd, - 0x87, 0xa2, 0x72, 0x79, 0x74, 0x95, 0xfa, 0xe1, - 0xfe, 0xd0, 0x4e, 0x3d, 0x39, 0x2e, 0x67, 0x55, - 0x71, 0x6c, 0x89, 0x33, 0x49, 0x0c, 0x1b, 0x46, - 0x92, 0x31, 0x6f, 0xa6, 0xf0, 0x09, 0xbd, 0x2d, - 0xe2, 0xca, 0xda, 0x18, 0x33, 0xce, 0x67, 0x37, - 0xfd, 0x6f, 0xcb, 0x9d, 0xbd, 0x42, 0xbc, 0xb2, - 0x9c, 0x28, 0xcd, 0x65, 0x3c, 0x61, 0xbc, 0xde, - 0x9d, 0xe1, 0x2a, 0x3e, 0xbf, 0xee, 0x3c, 0xcb, - 0xb1, 0x50, 0xa9, 0x2c, 0xbe, 0xb5, 0x43, 0xd0, - 0xec, 0x29, 0xf9, 0x16, 0x6f, 0x31, 0xd9, 0x9b, - 0x92, 0xb1, 0x32, 0xae, 0x0f, 0xb6, 0x9d, 0x0e, - 0x25, 0x7f, 0x89, 0x1f, 0x1d, 0x01, 0x68, 0xab, - 0x3d, 0xd1, 0x74, 0x5b, 0x4c, 0x38, 0x7f, 0x3d, - 0x33, 0xa5, 0xa2, 0x9f, 0xda, 0x84, 0xa5, 0x82, - 0x2d, 0x16, 0x66, 0x46, 0x08, 0x30, 0x14, 0x48, - 0x5e, 0xca, 0xe3, 0xf4, 0x8c, 0xcb, 0x32, 0xc6, - 0xf1, 0x43, 0x62, 0xc6, 0xef, 0x16, 0xfa, 0x43, - 0xae, 0x9c, 0x53, 0xe3, 0x49, 0x45, 0x80, 0xfd, - 0x1d, 0x8c, 0xa9, 0x6d, 0x77, 0x76, 0xaa, 0x40, - 0xc4, 0x4e, 0x7b, 0x78, 0x6b, 0xe0, 0x1d, 0xce, - 0x56, 0x3d, 0xf0, 0x11, 0xfe, 0x4f, 0x6a, 0x6d, - 0x0f, 0x4f, 0x90, 0x38, 0x92, 0x17, 0xfa, 0x56, - 0x12, 0xa6, 0xa1, 0x0a, 0xea, 0x2f, 0x50, 0xf9, - 0x60, 0x66, 0x6c, 0x7d, 0x5a, 0x08, 0x8e, 0x3c, - 0xf3, 0xf0, 0x33, 0x02, 0x11, 0x02, 0xfe, 0x4c, - 0x56, 0x2b, 0x9f, 0x0c, 0xbd, 0x65, 0x8a, 0x83, - 0xde, 0x7c, 0x05, 0x26, 0x93, 0x19, 0xcc, 0xf3, - 0x71, 0x0e, 0xad, 0x2f, 0xb3, 0xc9, 0x38, 0x50, - 0x64, 0xd5, 0x4c, 0x60, 0x5f, 0x02, 0x13, 0x34, - 0xc9, 0x75, 0xc4, 0x60, 0xab, 0x2e, 0x17, 0x7d -}; - -static const uint8_t AES_CBC_ciphertext_2048B[] = { - 0x8b, 0x55, 0xbd, 0xfd, 0x2b, 0x35, 0x76, 0x5c, - 0xd1, 0x90, 0xd7, 0x6a, 0x63, 0x1e, 0x39, 0x71, - 0x0d, 0x5c, 0xd8, 0x03, 0x00, 0x75, 0xf1, 0x07, - 0x03, 0x8d, 0x76, 0xeb, 0x3b, 0x00, 0x1e, 0x33, - 0x88, 0xfc, 0x8f, 0x08, 0x4d, 0x33, 0xf1, 0x3c, - 0xee, 0xd0, 0x5d, 0x19, 0x8b, 0x3c, 0x50, 0x86, - 0xfd, 0x8d, 0x58, 0x21, 0xb4, 0xae, 0x0f, 0x81, - 0xe9, 0x9f, 0xc9, 0xc0, 0x90, 0xf7, 0x04, 0x6f, - 0x39, 0x1d, 0x8a, 0x3f, 0x8d, 0x32, 0x23, 0xb5, - 0x1f, 0xcc, 0x8a, 0x12, 0x2d, 0x46, 0x82, 0x5e, - 0x6a, 0x34, 0x8c, 0xb1, 0x93, 0x70, 0x3b, 0xde, - 0x55, 0xaf, 0x16, 0x35, 0x99, 0x84, 0xd5, 0x88, - 0xc9, 0x54, 0xb1, 0xb2, 0xd3, 0xeb, 0x9e, 0x55, - 0x9a, 0xa9, 0xa7, 0xf5, 0xda, 0x29, 0xcf, 0xe1, - 0x98, 0x64, 0x45, 0x77, 0xf2, 0x12, 0x69, 0x8f, - 0x78, 0xd8, 0x82, 0x41, 0xb2, 0x9f, 0xe2, 0x1c, - 0x63, 0x9b, 0x24, 0x81, 0x67, 0x95, 0xa2, 0xff, - 0x26, 0x9d, 0x65, 0x48, 0x61, 0x30, 0x66, 0x41, - 0x68, 0x84, 0xbb, 0x59, 0x14, 0x8e, 0x9a, 0x62, - 0xb6, 0xca, 0xda, 0xbe, 0x7c, 0x41, 0x52, 0x6e, - 0x1b, 0x86, 0xbf, 0x08, 0xeb, 0x37, 0x84, 0x60, - 0xe4, 0xc4, 0x1e, 0xa8, 0x4c, 0x84, 0x60, 0x2f, - 0x70, 0x90, 0xf2, 0x26, 0xe7, 0x65, 0x0c, 0xc4, - 0x58, 0x36, 0x8e, 0x4d, 0xdf, 0xff, 0x9a, 0x39, - 0x93, 0x01, 0xcf, 0x6f, 0x6d, 0xde, 0xef, 0x79, - 0xb0, 0xce, 0xe2, 0x98, 0xdb, 0x85, 0x8d, 0x62, - 0x9d, 0xb9, 0x63, 0xfd, 0xf0, 0x35, 0xb5, 0xa9, - 0x1b, 0xf9, 0xe5, 0xd4, 0x2e, 0x22, 0x2d, 0xcc, - 0x42, 0xbf, 0x0e, 0x51, 0xf7, 0x15, 0x07, 0x32, - 0x75, 0x5b, 0x74, 0xbb, 0x00, 0xef, 0xd4, 0x66, - 0x8b, 0xad, 0x71, 0x53, 0x94, 0xd7, 0x7d, 0x2c, - 0x40, 0x3e, 0x69, 0xa0, 0x4c, 0x86, 0x5e, 0x06, - 0xed, 0xdf, 0x22, 0xe2, 0x24, 0x25, 0x4e, 0x9b, - 0x5f, 0x49, 0x74, 0xba, 0xed, 0xb1, 0xa6, 0xeb, - 0xae, 0x3f, 0xc6, 0x9e, 0x0b, 0x29, 0x28, 0x9a, - 0xb6, 0xb2, 0x74, 0x58, 0xec, 0xa6, 0x4a, 0xed, - 0xe5, 0x10, 0x00, 0x85, 0xe1, 0x63, 0x41, 0x61, - 0x30, 0x7c, 0x97, 0xcf, 0x75, 0xcf, 0xb6, 0xf3, - 0xf7, 0xda, 0x35, 0x3f, 0x85, 0x8c, 0x64, 0xca, - 0xb7, 0xea, 0x7f, 0xe4, 0xa3, 0x4d, 0x30, 0x84, - 0x8c, 0x9c, 0x80, 0x5a, 0x50, 0xa5, 0x64, 0xae, - 0x26, 0xd3, 0xb5, 0x01, 0x73, 0x36, 0x8a, 0x92, - 0x49, 0xc4, 0x1a, 0x94, 0x81, 0x9d, 0xf5, 0x6c, - 0x50, 0xe1, 0x58, 0x0b, 0x75, 0xdd, 0x6b, 0x6a, - 0xca, 0x69, 0xea, 0xc3, 0x33, 0x90, 0x9f, 0x3b, - 0x65, 0x5d, 0x5e, 0xee, 0x31, 0xb7, 0x32, 0xfd, - 0x56, 0x83, 0xb6, 0xfb, 0xa8, 0x04, 0xfc, 0x1e, - 0x11, 0xfb, 0x02, 0x23, 0x53, 0x49, 0x45, 0xb1, - 0x07, 0xfc, 0xba, 0xe7, 0x5f, 0x5d, 0x2d, 0x7f, - 0x9e, 0x46, 0xba, 0xe9, 0xb0, 0xdb, 0x32, 0x04, - 0xa4, 0xa7, 0x98, 0xab, 0x91, 0xcd, 0x02, 0x05, - 0xf5, 0x74, 0x31, 0x98, 0x83, 0x3d, 0x33, 0x11, - 0x0e, 0xe3, 0x8d, 0xa8, 0xc9, 0x0e, 0xf3, 0xb9, - 0x47, 0x67, 0xe9, 0x79, 0x2b, 0x34, 0xcd, 0x9b, - 0x45, 0x75, 0x29, 0xf0, 0xbf, 0xcc, 0xda, 0x3a, - 0x91, 0xb2, 0x15, 0x27, 0x7a, 0xe5, 0xf5, 0x6a, - 0x5e, 0xbe, 0x2c, 0x98, 0xe8, 0x40, 0x96, 0x4f, - 0x8a, 0x09, 0xfd, 0xf6, 0xb2, 0xe7, 0x45, 0xb6, - 0x08, 0xc1, 0x69, 0xe1, 0xb3, 0xc4, 0x24, 0x34, - 0x07, 0x85, 0xd5, 0xa9, 0x78, 0xca, 0xfa, 0x4b, - 0x01, 0x19, 0x4d, 0x95, 0xdc, 0xa5, 0xc1, 0x9c, - 0xec, 0x27, 0x5b, 0xa6, 0x54, 0x25, 0xbd, 0xc8, - 0x0a, 0xb7, 0x11, 0xfb, 0x4e, 0xeb, 0x65, 0x2e, - 0xe1, 0x08, 0x9c, 0x3a, 0x45, 0x44, 0x33, 0xef, - 0x0d, 0xb9, 0xff, 0x3e, 0x68, 0x9c, 0x61, 0x2b, - 0x11, 0xb8, 0x5c, 0x47, 0x0f, 0x94, 0xf2, 0xf8, - 0x0b, 0xbb, 0x99, 0x18, 0x85, 0xa3, 0xba, 0x44, - 0xf3, 0x79, 0xb3, 0x63, 0x2c, 0x1f, 0x2a, 0x35, - 0x3b, 0x23, 0x98, 0xab, 0xf4, 0x16, 0x36, 0xf8, - 0xde, 0x86, 0xa4, 0xd4, 0x75, 0xff, 0x51, 0xf9, - 0xeb, 0x42, 0x5f, 0x55, 0xe2, 0xbe, 0xd1, 0x5b, - 0xb5, 0x38, 0xeb, 0xb4, 0x4d, 0xec, 0xec, 0x99, - 0xe1, 0x39, 0x43, 0xaa, 0x64, 0xf7, 0xc9, 0xd8, - 0xf2, 0x9a, 0x71, 0x43, 0x39, 0x17, 0xe8, 0xa8, - 0xa2, 0xe2, 0xa4, 0x2c, 0x18, 0x11, 0x49, 0xdf, - 0x18, 0xdd, 0x85, 0x6e, 0x65, 0x96, 0xe2, 0xba, - 0xa1, 0x0a, 0x2c, 0xca, 0xdc, 0x5f, 0xe4, 0xf4, - 0x35, 0x03, 0xb2, 0xa9, 0xda, 0xcf, 0xb7, 0x6d, - 0x65, 0x82, 0x82, 0x67, 0x9d, 0x0e, 0xf3, 0xe8, - 0x85, 0x6c, 0x69, 0xb8, 0x4c, 0xa6, 0xc6, 0x2e, - 0x40, 0xb5, 0x54, 0x28, 0x95, 0xe4, 0x57, 0xe0, - 0x5b, 0xf8, 0xde, 0x59, 0xe0, 0xfd, 0x89, 0x48, - 0xac, 0x56, 0x13, 0x54, 0xb9, 0x1b, 0xf5, 0x59, - 0x97, 0xb6, 0xb3, 0xe8, 0xac, 0x2d, 0xfc, 0xd2, - 0xea, 0x57, 0x96, 0x57, 0xa8, 0x26, 0x97, 0x2c, - 0x01, 0x89, 0x56, 0xea, 0xec, 0x8c, 0x53, 0xd5, - 0xd7, 0x9e, 0xc9, 0x98, 0x0b, 0xad, 0x03, 0x75, - 0xa0, 0x6e, 0x98, 0x8b, 0x97, 0x8d, 0x8d, 0x85, - 0x7d, 0x74, 0xa7, 0x2d, 0xde, 0x67, 0x0c, 0xcd, - 0x54, 0xb8, 0x15, 0x7b, 0xeb, 0xf5, 0x84, 0xb9, - 0x78, 0xab, 0xd8, 0x68, 0x91, 0x1f, 0x6a, 0xa6, - 0x28, 0x22, 0xf7, 0x00, 0x49, 0x00, 0xbe, 0x41, - 0x71, 0x0a, 0xf5, 0xe7, 0x9f, 0xb4, 0x11, 0x41, - 0x3f, 0xcd, 0xa9, 0xa9, 0x01, 0x8b, 0x6a, 0xeb, - 0x54, 0x4c, 0x58, 0x92, 0x68, 0x02, 0x0e, 0xe9, - 0xed, 0x65, 0x4c, 0xfb, 0x95, 0x48, 0x58, 0xa2, - 0xaa, 0x57, 0x69, 0x13, 0x82, 0x0c, 0x2c, 0x4b, - 0x5d, 0x4e, 0x18, 0x30, 0xef, 0x1c, 0xb1, 0x9d, - 0x05, 0x05, 0x02, 0x1c, 0x97, 0xc9, 0x48, 0xfe, - 0x5e, 0x7b, 0x77, 0xa3, 0x1f, 0x2a, 0x81, 0x42, - 0xf0, 0x4b, 0x85, 0x12, 0x9c, 0x1f, 0x44, 0xb1, - 0x14, 0x91, 0x92, 0x65, 0x77, 0xb1, 0x87, 0xa2, - 0xfc, 0xa4, 0xe7, 0xd2, 0x9b, 0xf2, 0x17, 0xf0, - 0x30, 0x1c, 0x8d, 0x33, 0xbc, 0x25, 0x28, 0x48, - 0xfd, 0x30, 0x79, 0x0a, 0x99, 0x3e, 0xb4, 0x0f, - 0x1e, 0xa6, 0x68, 0x76, 0x19, 0x76, 0x29, 0xac, - 0x5d, 0xb8, 0x1e, 0x42, 0xd6, 0x85, 0x04, 0xbf, - 0x64, 0x1c, 0x2d, 0x53, 0xe9, 0x92, 0x78, 0xf8, - 0xc3, 0xda, 0x96, 0x92, 0x10, 0x6f, 0x45, 0x85, - 0xaf, 0x5e, 0xcc, 0xa8, 0xc0, 0xc6, 0x2e, 0x73, - 0x51, 0x3f, 0x5e, 0xd7, 0x52, 0x33, 0x71, 0x12, - 0x6d, 0x85, 0xee, 0xea, 0x85, 0xa8, 0x48, 0x2b, - 0x40, 0x64, 0x6d, 0x28, 0x73, 0x16, 0xd7, 0x82, - 0xd9, 0x90, 0xed, 0x1f, 0xa7, 0x5c, 0xb1, 0x5c, - 0x27, 0xb9, 0x67, 0x8b, 0xb4, 0x17, 0x13, 0x83, - 0x5f, 0x09, 0x72, 0x0a, 0xd7, 0xa0, 0xec, 0x81, - 0x59, 0x19, 0xb9, 0xa6, 0x5a, 0x37, 0x34, 0x14, - 0x47, 0xf6, 0xe7, 0x6c, 0xd2, 0x09, 0x10, 0xe7, - 0xdd, 0xbb, 0x02, 0xd1, 0x28, 0xfa, 0x01, 0x2c, - 0x93, 0x64, 0x2e, 0x1b, 0x4c, 0x02, 0x52, 0xcb, - 0x07, 0xa1, 0xb6, 0x46, 0x02, 0x80, 0xd9, 0x8f, - 0x5c, 0x62, 0xbe, 0x78, 0x9e, 0x75, 0xc4, 0x97, - 0x91, 0x39, 0x12, 0x65, 0xb9, 0x3b, 0xc2, 0xd1, - 0xaf, 0xf2, 0x1f, 0x4e, 0x4d, 0xd1, 0xf0, 0x9f, - 0xb7, 0x12, 0xfd, 0xe8, 0x75, 0x18, 0xc0, 0x9d, - 0x8c, 0x70, 0xff, 0x77, 0x05, 0xb6, 0x1a, 0x1f, - 0x96, 0x48, 0xf6, 0xfe, 0xd5, 0x5d, 0x98, 0xa5, - 0x72, 0x1c, 0x84, 0x76, 0x3e, 0xb8, 0x87, 0x37, - 0xdd, 0xd4, 0x3a, 0x45, 0xdd, 0x09, 0xd8, 0xe7, - 0x09, 0x2f, 0x3e, 0x33, 0x9e, 0x7b, 0x8c, 0xe4, - 0x85, 0x12, 0x4e, 0xf8, 0x06, 0xb7, 0xb1, 0x85, - 0x24, 0x96, 0xd8, 0xfe, 0x87, 0x92, 0x81, 0xb1, - 0xa3, 0x38, 0xb9, 0x56, 0xe1, 0xf6, 0x36, 0x41, - 0xbb, 0xd6, 0x56, 0x69, 0x94, 0x57, 0xb3, 0xa4, - 0xca, 0xa4, 0xe1, 0x02, 0x3b, 0x96, 0x71, 0xe0, - 0xb2, 0x2f, 0x85, 0x48, 0x1b, 0x4a, 0x41, 0x80, - 0x4b, 0x9c, 0xe0, 0xc9, 0x39, 0xb8, 0xb1, 0xca, - 0x64, 0x77, 0x46, 0x58, 0xe6, 0x84, 0xd5, 0x2b, - 0x65, 0xce, 0xe9, 0x09, 0xa3, 0xaa, 0xfb, 0x83, - 0xa9, 0x28, 0x68, 0xfd, 0xcd, 0xfd, 0x76, 0x83, - 0xe1, 0x20, 0x22, 0x77, 0x3a, 0xa3, 0xb2, 0x93, - 0x14, 0x91, 0xfc, 0xe2, 0x17, 0x63, 0x2b, 0xa6, - 0x29, 0x38, 0x7b, 0x9b, 0x8b, 0x15, 0x77, 0xd6, - 0xaa, 0x92, 0x51, 0x53, 0x50, 0xff, 0xa0, 0x35, - 0xa0, 0x59, 0x7d, 0xf0, 0x11, 0x23, 0x49, 0xdf, - 0x5a, 0x21, 0xc2, 0xfe, 0x35, 0xa0, 0x1d, 0xe2, - 0xae, 0xa2, 0x8a, 0x61, 0x5b, 0xf7, 0xf1, 0x1c, - 0x1c, 0xec, 0xc4, 0xf6, 0xdc, 0xaa, 0xc8, 0xc2, - 0xe5, 0xa1, 0x2e, 0x14, 0xe5, 0xc6, 0xc9, 0x73, - 0x03, 0x78, 0xeb, 0xed, 0xe0, 0x3e, 0xc5, 0xf4, - 0xf1, 0x50, 0xb2, 0x01, 0x91, 0x96, 0xf5, 0xbb, - 0xe1, 0x32, 0xcd, 0xa8, 0x66, 0xbf, 0x73, 0x85, - 0x94, 0xd6, 0x7e, 0x68, 0xc5, 0xe4, 0xed, 0xd5, - 0xe3, 0x67, 0x4c, 0xa5, 0xb3, 0x1f, 0xdf, 0xf8, - 0xb3, 0x73, 0x5a, 0xac, 0xeb, 0x46, 0x16, 0x24, - 0xab, 0xca, 0xa4, 0xdd, 0x87, 0x0e, 0x24, 0x83, - 0x32, 0x04, 0x4c, 0xd8, 0xda, 0x7d, 0xdc, 0xe3, - 0x01, 0x93, 0xf3, 0xc1, 0x5b, 0xbd, 0xc3, 0x1d, - 0x40, 0x62, 0xde, 0x94, 0x03, 0x85, 0x91, 0x2a, - 0xa0, 0x25, 0x10, 0xd3, 0x32, 0x9f, 0x93, 0x00, - 0xa7, 0x8a, 0xfa, 0x77, 0x7c, 0xaf, 0x4d, 0xc8, - 0x7a, 0xf3, 0x16, 0x2b, 0xba, 0xeb, 0x74, 0x51, - 0xb8, 0xdd, 0x32, 0xad, 0x68, 0x7d, 0xdd, 0xca, - 0x60, 0x98, 0xc9, 0x9b, 0xb6, 0x5d, 0x4d, 0x3a, - 0x66, 0x8a, 0xbe, 0x05, 0xf9, 0x0c, 0xc5, 0xba, - 0x52, 0x82, 0x09, 0x1f, 0x5a, 0x66, 0x89, 0x69, - 0xa3, 0x5d, 0x93, 0x50, 0x7d, 0x44, 0xc3, 0x2a, - 0xb8, 0xab, 0xec, 0xa6, 0x5a, 0xae, 0x4a, 0x6a, - 0xcd, 0xfd, 0xb6, 0xff, 0x3d, 0x98, 0x05, 0xd9, - 0x5b, 0x29, 0xc4, 0x6f, 0xe0, 0x76, 0xe2, 0x3f, - 0xec, 0xd7, 0xa4, 0x91, 0x63, 0xf5, 0x4e, 0x4b, - 0xab, 0x20, 0x8c, 0x3a, 0x41, 0xed, 0x8b, 0x4b, - 0xb9, 0x01, 0x21, 0xc0, 0x6d, 0xfd, 0x70, 0x5b, - 0x20, 0x92, 0x41, 0x89, 0x74, 0xb7, 0xe9, 0x8b, - 0xfc, 0x6d, 0x17, 0x3f, 0x7f, 0x89, 0x3d, 0x6b, - 0x8f, 0xbc, 0xd2, 0x57, 0xe9, 0xc9, 0x6e, 0xa7, - 0x19, 0x26, 0x18, 0xad, 0xef, 0xb5, 0x87, 0xbf, - 0xb8, 0xa8, 0xd6, 0x7d, 0xdd, 0x5f, 0x94, 0x54, - 0x09, 0x92, 0x2b, 0xf5, 0x04, 0xf7, 0x36, 0x69, - 0x8e, 0xf4, 0xdc, 0x1d, 0x6e, 0x55, 0xbb, 0xe9, - 0x13, 0x05, 0x83, 0x35, 0x9c, 0xed, 0xcf, 0x8c, - 0x26, 0x8c, 0x7b, 0xc7, 0x0b, 0xba, 0xfd, 0xe2, - 0x84, 0x5c, 0x2a, 0x79, 0x43, 0x99, 0xb2, 0xc3, - 0x82, 0x87, 0xc8, 0xcd, 0x37, 0x6d, 0xa1, 0x2b, - 0x39, 0xb2, 0x38, 0x99, 0xd9, 0xfc, 0x02, 0x15, - 0x55, 0x21, 0x62, 0x59, 0xeb, 0x00, 0x86, 0x08, - 0x20, 0xbe, 0x1a, 0x62, 0x4d, 0x7e, 0xdf, 0x68, - 0x73, 0x5b, 0x5f, 0xaf, 0x84, 0x96, 0x2e, 0x1f, - 0x6b, 0x03, 0xc9, 0xa6, 0x75, 0x18, 0xe9, 0xd4, - 0xbd, 0xc8, 0xec, 0x9a, 0x5a, 0xb3, 0x99, 0xab, - 0x5f, 0x7c, 0x08, 0x7f, 0x69, 0x4d, 0x52, 0xa2, - 0x30, 0x17, 0x3b, 0x16, 0x15, 0x1b, 0x11, 0x62, - 0x3e, 0x80, 0x4b, 0x85, 0x7c, 0x9c, 0xd1, 0x3a, - 0x13, 0x01, 0x5e, 0x45, 0xf1, 0xc8, 0x5f, 0xcd, - 0x0e, 0x21, 0xf5, 0x82, 0xd4, 0x7b, 0x5c, 0x45, - 0x27, 0x6b, 0xef, 0xfe, 0xb8, 0xc0, 0x6f, 0xdc, - 0x60, 0x7b, 0xe4, 0xd5, 0x75, 0x71, 0xe6, 0xe8, - 0x7d, 0x6b, 0x6d, 0x80, 0xaf, 0x76, 0x41, 0x58, - 0xb7, 0xac, 0xb7, 0x13, 0x2f, 0x81, 0xcc, 0xf9, - 0x19, 0x97, 0xe8, 0xee, 0x40, 0x91, 0xfc, 0x89, - 0x13, 0x1e, 0x67, 0x9a, 0xdb, 0x8f, 0x8f, 0xc7, - 0x4a, 0xc9, 0xaf, 0x2f, 0x67, 0x01, 0x3c, 0xb8, - 0xa8, 0x3e, 0x78, 0x93, 0x1b, 0xdf, 0xbb, 0x34, - 0x0b, 0x1a, 0xfa, 0xc2, 0x2d, 0xc5, 0x1c, 0xec, - 0x97, 0x4f, 0x48, 0x41, 0x15, 0x0e, 0x75, 0xed, - 0x66, 0x8c, 0x17, 0x7f, 0xb1, 0x48, 0x13, 0xc1, - 0xfb, 0x60, 0x06, 0xf9, 0x72, 0x41, 0x3e, 0xcf, - 0x6e, 0xb6, 0xc8, 0xeb, 0x4b, 0x5a, 0xd2, 0x0c, - 0x28, 0xda, 0x02, 0x7a, 0x46, 0x21, 0x42, 0xb5, - 0x34, 0xda, 0xcb, 0x5e, 0xbd, 0x66, 0x5c, 0xca, - 0xff, 0x52, 0x43, 0x89, 0xf9, 0x10, 0x9a, 0x9e, - 0x9b, 0xe3, 0xb0, 0x51, 0xe9, 0xf3, 0x0a, 0x35, - 0x77, 0x54, 0xcc, 0xac, 0xa6, 0xf1, 0x2e, 0x36, - 0x89, 0xac, 0xc5, 0xc6, 0x62, 0x5a, 0xc0, 0x6d, - 0xc4, 0xe1, 0xf7, 0x64, 0x30, 0xff, 0x11, 0x40, - 0x13, 0x89, 0xd8, 0xd7, 0x73, 0x3f, 0x93, 0x08, - 0x68, 0xab, 0x66, 0x09, 0x1a, 0xea, 0x78, 0xc9, - 0x52, 0xf2, 0xfd, 0x93, 0x1b, 0x94, 0xbe, 0x5c, - 0xe5, 0x00, 0x6e, 0x00, 0xb9, 0xea, 0x27, 0xaa, - 0xb3, 0xee, 0xe3, 0xc8, 0x6a, 0xb0, 0xc1, 0x8e, - 0x9b, 0x54, 0x40, 0x10, 0x96, 0x06, 0xe8, 0xb3, - 0xf5, 0x55, 0x77, 0xd7, 0x5c, 0x94, 0xc1, 0x74, - 0xf3, 0x07, 0x64, 0xac, 0x1c, 0xde, 0xc7, 0x22, - 0xb0, 0xbf, 0x2a, 0x5a, 0xc0, 0x8f, 0x8a, 0x83, - 0x50, 0xc2, 0x5e, 0x97, 0xa0, 0xbe, 0x49, 0x7e, - 0x47, 0xaf, 0xa7, 0x20, 0x02, 0x35, 0xa4, 0x57, - 0xd9, 0x26, 0x63, 0xdb, 0xf1, 0x34, 0x42, 0x89, - 0x36, 0xd1, 0x77, 0x6f, 0xb1, 0xea, 0x79, 0x7e, - 0x95, 0x10, 0x5a, 0xee, 0xa3, 0xae, 0x6f, 0xba, - 0xa9, 0xef, 0x5a, 0x7e, 0x34, 0x03, 0x04, 0x07, - 0x92, 0xd6, 0x07, 0x79, 0xaa, 0x14, 0x90, 0x97, - 0x05, 0x4d, 0xa6, 0x27, 0x10, 0x5c, 0x25, 0x24, - 0xcb, 0xcc, 0xf6, 0x77, 0x9e, 0x43, 0x23, 0xd4, - 0x98, 0xef, 0x22, 0xa8, 0xad, 0xf2, 0x26, 0x08, - 0x59, 0x69, 0xa4, 0xc3, 0x97, 0xe0, 0x5c, 0x6f, - 0xeb, 0x3d, 0xd4, 0x62, 0x6e, 0x80, 0x61, 0x02, - 0xf4, 0xfc, 0x94, 0x79, 0xbb, 0x4e, 0x6d, 0xd7, - 0x30, 0x5b, 0x10, 0x11, 0x5a, 0x3d, 0xa7, 0x50, - 0x1d, 0x9a, 0x13, 0x5f, 0x4f, 0xa8, 0xa7, 0xb6, - 0x39, 0xc7, 0xea, 0xe6, 0x19, 0x61, 0x69, 0xc7, - 0x9a, 0x3a, 0xeb, 0x9d, 0xdc, 0xf7, 0x06, 0x37, - 0xbd, 0xac, 0xe3, 0x18, 0xff, 0xfe, 0x11, 0xdb, - 0x67, 0x42, 0xb4, 0xea, 0xa8, 0xbd, 0xb0, 0x76, - 0xd2, 0x74, 0x32, 0xc2, 0xa4, 0x9c, 0xe7, 0x60, - 0xc5, 0x30, 0x9a, 0x57, 0x66, 0xcd, 0x0f, 0x02, - 0x4c, 0xea, 0xe9, 0xd3, 0x2a, 0x5c, 0x09, 0xc2, - 0xff, 0x6a, 0xde, 0x5d, 0xb7, 0xe9, 0x75, 0x6b, - 0x29, 0x94, 0xd6, 0xf7, 0xc3, 0xdf, 0xfb, 0x70, - 0xec, 0xb5, 0x8c, 0xb0, 0x78, 0x7a, 0xee, 0x52, - 0x5f, 0x8c, 0xae, 0x85, 0xe5, 0x98, 0xa2, 0xb7, - 0x7c, 0x02, 0x2a, 0xcc, 0x9e, 0xde, 0x99, 0x5f, - 0x84, 0x20, 0xbb, 0xdc, 0xf2, 0xd2, 0x13, 0x46, - 0x3c, 0xd6, 0x4d, 0xe7, 0x50, 0xef, 0x55, 0xc3, - 0x96, 0x9f, 0xec, 0x6c, 0xd8, 0xe2, 0xea, 0xed, - 0xc7, 0x33, 0xc9, 0xb3, 0x1c, 0x4f, 0x1d, 0x83, - 0x1d, 0xe4, 0xdd, 0xb2, 0x24, 0x8f, 0xf9, 0xf5 -}; - - -static const uint8_t HMAC_SHA256_ciphertext_64B_digest[] = { - 0xc5, 0x6d, 0x4f, 0x29, 0xf4, 0xd2, 0xcc, 0x87, - 0x3c, 0x81, 0x02, 0x6d, 0x38, 0x7a, 0x67, 0x3e, - 0x95, 0x9c, 0x5c, 0x8f, 0xda, 0x5c, 0x06, 0xe0, - 0x65, 0xf1, 0x6c, 0x51, 0x52, 0x49, 0x3e, 0x5f -}; - -static const uint8_t HMAC_SHA256_ciphertext_128B_digest[] = { - 0x76, 0x64, 0x2d, 0x69, 0x71, 0x5d, 0x6a, 0xd8, - 0x9f, 0x74, 0x11, 0x2f, 0x58, 0xe0, 0x4a, 0x2f, - 0x6c, 0x88, 0x5e, 0x4d, 0x9c, 0x79, 0x83, 0x1c, - 0x8a, 0x14, 0xd0, 0x07, 0xfb, 0xbf, 0x6c, 0x8f -}; - -static const uint8_t HMAC_SHA256_ciphertext_256B_digest[] = { - 0x05, 0xa7, 0x44, 0xcd, 0x91, 0x8c, 0x95, 0xcf, - 0x7b, 0x8f, 0xd3, 0x90, 0x86, 0x7e, 0x7b, 0xb9, - 0x05, 0xd6, 0x6e, 0x7a, 0xc1, 0x7b, 0x26, 0xff, - 0xd3, 0x4b, 0xe0, 0x22, 0x8b, 0xa8, 0x47, 0x52 -}; - -static const uint8_t HMAC_SHA256_ciphertext_512B_digest[] = { - 0x08, 0xb7, 0x29, 0x54, 0x18, 0x7e, 0x97, 0x49, - 0xc6, 0x7c, 0x9f, 0x94, 0xa5, 0x4f, 0xa2, 0x25, - 0xd0, 0xe2, 0x30, 0x7b, 0xad, 0x93, 0xc9, 0x12, - 0x0f, 0xf0, 0xf0, 0x71, 0xc2, 0xf6, 0x53, 0x8f -}; - -static const uint8_t HMAC_SHA256_ciphertext_768B_digest[] = { - 0xe4, 0x3e, 0x73, 0x93, 0x03, 0xaf, 0x6f, 0x9c, - 0xca, 0x57, 0x3b, 0x4a, 0x6e, 0x83, 0x58, 0xf5, - 0x66, 0xc2, 0xb4, 0xa7, 0xe0, 0xee, 0x63, 0x6b, - 0x48, 0xb7, 0x50, 0x45, 0x69, 0xdf, 0x5c, 0x5b -}; - -static const uint8_t HMAC_SHA256_ciphertext_1024B_digest[] = { - 0x03, 0xb9, 0x96, 0x26, 0xdc, 0x1c, 0xab, 0xe2, - 0xf5, 0x70, 0x55, 0x15, 0x67, 0x6e, 0x48, 0x11, - 0xe7, 0x67, 0xea, 0xfa, 0x5c, 0x6b, 0x28, 0x22, - 0xc9, 0x0e, 0x67, 0x04, 0xb3, 0x71, 0x7f, 0x88 -}; - -static const uint8_t HMAC_SHA256_ciphertext_1280B_digest[] = { - 0x01, 0x91, 0xb8, 0x78, 0xd3, 0x21, 0x74, 0xa5, - 0x1c, 0x8b, 0xd4, 0xd2, 0xc0, 0x49, 0xd7, 0xd2, - 0x16, 0x46, 0x66, 0x85, 0x50, 0x6d, 0x08, 0xcc, - 0xc7, 0x0a, 0xa3, 0x71, 0xcc, 0xde, 0xee, 0xdc -}; - -static const uint8_t HMAC_SHA256_ciphertext_1536B_digest[] = { - 0xf2, 0xe5, 0xe9, 0x57, 0x53, 0xd7, 0x69, 0x28, - 0x7b, 0x69, 0xb5, 0x49, 0xa3, 0x31, 0x56, 0x5f, - 0xa4, 0xe9, 0x87, 0x26, 0x2f, 0xe0, 0x2d, 0xd6, - 0x08, 0x44, 0x01, 0x71, 0x0c, 0x93, 0x85, 0x84 -}; - -static const uint8_t HMAC_SHA256_ciphertext_1792B_digest[] = { - 0xf6, 0x57, 0x62, 0x01, 0xbf, 0x2d, 0xea, 0x4a, - 0xef, 0x43, 0x85, 0x60, 0x18, 0xdf, 0x8b, 0xb4, - 0x60, 0xc0, 0xfd, 0x2f, 0x90, 0x15, 0xe6, 0x91, - 0x56, 0x61, 0x68, 0x7f, 0x5e, 0x92, 0xa8, 0xdd -}; - -static const uint8_t HMAC_SHA256_ciphertext_2048B_digest[] = { - 0x81, 0x1a, 0x29, 0xbc, 0x6b, 0x9f, 0xbb, 0xb8, - 0xef, 0x71, 0x7b, 0x1f, 0x6f, 0xd4, 0x7e, 0x68, - 0x3a, 0x9c, 0xb9, 0x98, 0x22, 0x81, 0xfa, 0x95, - 0xee, 0xbc, 0x7f, 0x23, 0x29, 0x88, 0x76, 0xb8 -}; - -struct crypto_data_params { - const char *name; - uint16_t length; - const char *plaintext; - struct crypto_expected_output { - const uint8_t *ciphertext; - const uint8_t *digest; - } expected; -}; - -#define MAX_PACKET_SIZE_INDEX 10 - -struct crypto_data_params aes_cbc_hmac_sha256_output[MAX_PACKET_SIZE_INDEX] = { - { "64B", 64, &plaintext_quote[sizeof(plaintext_quote) - 1 - 64], - { AES_CBC_ciphertext_64B, HMAC_SHA256_ciphertext_64B_digest } }, - { "128B", 128, &plaintext_quote[sizeof(plaintext_quote) - 1 - 128], - { AES_CBC_ciphertext_128B, HMAC_SHA256_ciphertext_128B_digest } }, - { "256B", 256, &plaintext_quote[sizeof(plaintext_quote) - 1 - 256], - { AES_CBC_ciphertext_256B, HMAC_SHA256_ciphertext_256B_digest } }, - { "512B", 512, &plaintext_quote[sizeof(plaintext_quote) - 1 - 512], - { AES_CBC_ciphertext_512B, HMAC_SHA256_ciphertext_512B_digest } }, - { "768B", 768, &plaintext_quote[sizeof(plaintext_quote) - 1 - 768], - { AES_CBC_ciphertext_768B, HMAC_SHA256_ciphertext_768B_digest } }, - { "1024B", 1024, &plaintext_quote[sizeof(plaintext_quote) - 1 - 1024], - { AES_CBC_ciphertext_1024B, HMAC_SHA256_ciphertext_1024B_digest } }, - { "1280B", 1280, &plaintext_quote[sizeof(plaintext_quote) - 1 - 1280], - { AES_CBC_ciphertext_1280B, HMAC_SHA256_ciphertext_1280B_digest } }, - { "1536B", 1536, &plaintext_quote[sizeof(plaintext_quote) - 1 - 1536], - { AES_CBC_ciphertext_1536B, HMAC_SHA256_ciphertext_1536B_digest } }, - { "1792B", 1792, &plaintext_quote[sizeof(plaintext_quote) - 1 - 1792], - { AES_CBC_ciphertext_1792B, HMAC_SHA256_ciphertext_1792B_digest } }, - { "2048B", 2048, &plaintext_quote[sizeof(plaintext_quote) - 1 - 2048], - { AES_CBC_ciphertext_2048B, HMAC_SHA256_ciphertext_2048B_digest } } -}; - -static int -test_perf_crypto_qp_vary_burst_size(uint16_t dev_num) -{ - uint32_t num_to_submit = 4096; - 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, burst_received; - uint32_t i, burst_size, num_sent, num_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; - - if (rte_cryptodev_count() == 0) { - printf("\nNo crypto devices available. Is kernel driver loaded?\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; - - 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_128_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_IV_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_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->dev_id, - &ut_params->cipher_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - /* Generate Crypto op data structure(s) */ - for (i = 0; i < num_to_submit ; i++) { - struct rte_mbuf *m = setup_test_string(ts_params->mbuf_mp, - data_params[0].expected.ciphertext, - data_params[0].length, 0); - TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); - - 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"); - - rte_memcpy(ut_params->digest, data_params[0].expected.digest, - DIGEST_BYTE_LENGTH_SHA256); - - - struct rte_crypto_op *op = - rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - - rte_crypto_op_attach_sym_session(op, ut_params->sess); - - op->sym->auth.digest.data = ut_params->digest; - op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, - data_params[0].length); - op->sym->auth.digest.length = DIGEST_BYTE_LENGTH_SHA256; - - op->sym->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - op->sym->auth.data.length = data_params[0].length; - - - 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; - - 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; - op->sym->cipher.data.length = data_params[0].length; - - op->sym->m_src = m; - - c_ops[i] = op; - } - - printf("\nTest to measure the IA cycle cost using AES128_CBC_SHA256_HMAC " - "algorithm with a constant request size of %u.", - data_params[0].length); - printf("\nThis test will keep retries at 0 and only measure IA cycle " - "cost for each request."); - printf("\nDev No\tQP No\tNum Sent\tNum Received\tTx/Rx burst"); - printf("\tRetries (Device Busy)\tAverage IA cycle cost " - "(assuming 0 retries)"); - for (i = 2; i <= 128 ; i *= 2) { - num_sent = 0; - num_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(dev_num, - 0, &c_ops[num_sent], - ((num_to_submit-num_sent) < burst_size) ? - num_to_submit-num_sent : burst_size); - if (burst_sent == 0) - retries++; - else - num_sent += burst_sent; - end_cycles = rte_rdtsc_precise(); - 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( - dev_num, 0, proc_ops, burst_size); - if (burst_received == 0) - failed_polls++; - else - num_received += burst_received; - end_cycles = rte_rdtsc_precise(); - total_cycles += end_cycles - start_cycles; - } - - while (num_received != num_to_submit) { - if (gbl_cryptodev_perftest_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, burst_size); - if (burst_received == 0) - failed_polls++; - else - num_received += burst_received; - } - - printf("\n%u\t%u\t%u\t\t%u\t\t%u", dev_num, 0, - num_sent, num_received, burst_size); - printf("\t\t%"PRIu64, retries); - printf("\t\t\t%"PRIu64, total_cycles/num_received); - } - 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_optimise_cyclecount(struct perf_test_params *pparams) -{ - 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; - 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 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"); - - 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"); - - 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"); - - c_ops[i] = op; - } - - 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"); - - for (i = 2; i <= 128 ; i *= 2) { - num_sent = 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]); - } - rte_cryptodev_sym_session_free(ts_params->dev_id, sess); - - 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 int -test_perf_openssl_optimise_cyclecount(struct perf_test_params *pparams) -{ - 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; - - static struct rte_cryptodev_sym_session *sess; - - static struct rte_crypto_op *(*test_perf_set_crypto_op) - (struct rte_crypto_op *, struct rte_mbuf *, - struct rte_cryptodev_sym_session *, - unsigned int, unsigned int, - enum chain_mode); - - unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); - - if (rte_cryptodev_count() == 0) { - printf("\nNo crypto devices found. Is PMD build configured?\n"); - return TEST_FAILED; - } - - /* Create Crypto session*/ - sess = test_perf_create_openssl_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 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"); - - 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"); - - switch (pparams->cipher_algo) { - case RTE_CRYPTO_CIPHER_3DES_CBC: - case RTE_CRYPTO_CIPHER_3DES_CTR: - test_perf_set_crypto_op = test_perf_set_crypto_op_3des; - break; - case RTE_CRYPTO_CIPHER_AES_CBC: - case RTE_CRYPTO_CIPHER_AES_CTR: - test_perf_set_crypto_op = test_perf_set_crypto_op_aes; - break; - case RTE_CRYPTO_CIPHER_AES_GCM: - test_perf_set_crypto_op = - test_perf_set_crypto_op_aes_gcm; - break; - default: - return TEST_FAILED; - } - - op = test_perf_set_crypto_op(op, m, sess, pparams->buf_size, - digest_length, pparams->chain); - TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); - - c_ops[i] = op; - } - - printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " - "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), - pparams->cipher_key_length, - auth_algo_name(pparams->auth_algo), - pparams->buf_size); - printf("\nOps Tx\tOps Rx\tOps/burst "); - printf("Retries EmptyPolls\tIACycles/CyOp\tIACycles/Burst\t" - "IACycles/Byte"); - - for (i = 2; i <= 128 ; i *= 2) { - num_sent = 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) { - /* Sending 0 length burst to flush sw crypto device */ - 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]); - } - rte_cryptodev_sym_session_free(ts_params->dev_id, sess); - - return TEST_SUCCESS; -} - -static int -test_perf_armv8_optimise_cyclecount(struct perf_test_params *pparams) -{ - 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; - uint32_t nb_ops; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - - static struct rte_cryptodev_sym_session *sess; - - unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); - - if (rte_cryptodev_count() == 0) { - printf("\nNo crypto devices found. Is PMD build configured?\n"); - return TEST_FAILED; - } - - /* Create Crypto session*/ - sess = test_perf_create_armv8_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 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"); - - 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"); - - op = test_perf_set_crypto_op_aes(op, m, sess, pparams->buf_size, - digest_length, pparams->chain); - TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); - - c_ops[i] = op; - } - - printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " - "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), - pparams->cipher_key_length, - 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"); - - for (i = 2; i <= 128 ; i *= 2) { - num_sent = 0; - num_ops_received = 0; - retries = 0; - failed_polls = 0; - burst_size = i; - total_cycles = 0; - while (num_sent < num_to_submit) { - if ((num_to_submit - num_sent) < burst_size) - nb_ops = num_to_submit - num_sent; - else - nb_ops = burst_size; - - start_cycles = rte_rdtsc(); - burst_sent = rte_cryptodev_enqueue_burst( - ts_params->dev_id, - 0, &c_ops[num_sent], - nb_ops); - end_cycles = rte_rdtsc(); - - if (burst_sent == 0) - retries++; - num_sent += burst_sent; - total_cycles += (end_cycles - start_cycles); - - start_cycles = rte_rdtsc(); - burst_received = rte_cryptodev_dequeue_burst( - ts_params->dev_id, 0, proc_ops, - burst_size); - end_cycles = rte_rdtsc(); - 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) { - /* Sending 0 length burst to flush sw crypto device */ - rte_cryptodev_enqueue_burst( - ts_params->dev_id, 0, NULL, 0); - - start_cycles = rte_rdtsc(); - burst_received = rte_cryptodev_dequeue_burst( - ts_params->dev_id, 0, proc_ops, burst_size); - end_cycles = rte_rdtsc(); - - 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 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; - case RTE_CRYPTO_AUTH_AES_GCM: - return 0; - 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; - case RTE_CRYPTO_AUTH_AES_GCM: - return DIGEST_BYTE_LENGTH_AES_GCM; - default: - return 0; - } -} - -static uint8_t aes_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_iv[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static uint8_t triple_des_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, -}; - -static uint8_t triple_des_iv[] = { - 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_key; - cipher_xform.cipher.key.length = cipher_key_len; - if (chain != CIPHER_ONLY) { - /* 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); - case CIPHER_ONLY: - cipher_xform.next = NULL; - /* Create Crypto session*/ - return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); - default: - return NULL; - } -} - -#define SNOW3G_CIPHER_IV_LENGTH 16 - -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.add_auth_data_length = SNOW3G_CIPHER_IV_LENGTH; - 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; - } -} - -static struct rte_cryptodev_sym_session * -test_perf_create_openssl_session(uint8_t dev_id, enum chain_mode chain, - enum rte_crypto_cipher_algorithm cipher_algo, - unsigned int 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; - - switch (cipher_algo) { - case RTE_CRYPTO_CIPHER_3DES_CBC: - case RTE_CRYPTO_CIPHER_3DES_CTR: - cipher_xform.cipher.key.data = triple_des_key; - break; - case RTE_CRYPTO_CIPHER_AES_CBC: - case RTE_CRYPTO_CIPHER_AES_CTR: - case RTE_CRYPTO_CIPHER_AES_GCM: - cipher_xform.cipher.key.data = aes_key; - break; - default: - return NULL; - } - - cipher_xform.cipher.key.length = cipher_key_len; - - /* Setup Auth Parameters */ - auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - auth_xform.auth.algo = auth_algo; - - switch (auth_algo) { - case RTE_CRYPTO_AUTH_SHA1_HMAC: - auth_xform.auth.key.data = hmac_sha_key; - break; - case RTE_CRYPTO_AUTH_AES_GCM: - auth_xform.auth.key.data = NULL; - break; - default: - return NULL; - } - - 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_armv8_session(uint8_t dev_id, enum chain_mode chain, - enum rte_crypto_cipher_algorithm cipher_algo, - unsigned int 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; - - switch (cipher_algo) { - case RTE_CRYPTO_CIPHER_AES_CBC: - cipher_xform.cipher.key.data = aes_cbc_128_key; - break; - default: - return NULL; - } - - cipher_xform.cipher.key.length = cipher_key_len; - - /* Setup Auth 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.digest_length = get_auth_digest_length(auth_algo); - - switch (chain) { - case CIPHER_HASH: - cipher_xform.next = &auth_xform; - auth_xform.next = NULL; - /* Encrypt and hash the result */ - cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - /* 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; - /* Hash encrypted message and decrypt */ - cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - /* Create Crypto session*/ - return rte_cryptodev_sym_session_create(dev_id, &auth_xform); - default: - return NULL; - } -} - -#define AES_BLOCK_SIZE 16 -#define AES_CIPHER_IV_LENGTH 16 - -#define TRIPLE_DES_BLOCK_SIZE 8 -#define TRIPLE_DES_CIPHER_IV_LENGTH 8 - -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_aes(struct rte_crypto_op *op, struct rte_mbuf *m, - struct rte_cryptodev_sym_session *sess, unsigned int data_len, - unsigned int digest_len, enum chain_mode chain) -{ - if (rte_crypto_op_attach_sym_session(op, sess) != 0) { - rte_crypto_op_free(op); - return NULL; - } - - /* Authentication Parameters */ - if (chain == CIPHER_ONLY) { - op->sym->auth.digest.data = NULL; - op->sym->auth.digest.phys_addr = 0; - op->sym->auth.digest.length = 0; - op->sym->auth.aad.data = NULL; - op->sym->auth.aad.length = 0; - op->sym->auth.data.offset = 0; - op->sym->auth.data.length = 0; - } else { - op->sym->auth.digest.data = rte_pktmbuf_mtod_offset(m, - uint8_t *, AES_CIPHER_IV_LENGTH + data_len); - op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, - AES_CIPHER_IV_LENGTH + data_len); - op->sym->auth.digest.length = digest_len; - op->sym->auth.aad.data = aes_iv; - op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; - op->sym->auth.data.offset = AES_CIPHER_IV_LENGTH; - op->sym->auth.data.length = data_len; - } - - - /* Cipher Parameters */ - op->sym->cipher.iv.data = rte_pktmbuf_mtod(m, uint8_t *); - op->sym->cipher.iv.phys_addr = rte_pktmbuf_mtophys(m); - op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; - - rte_memcpy(op->sym->cipher.iv.data, aes_iv, AES_CIPHER_IV_LENGTH); - - op->sym->cipher.data.offset = AES_CIPHER_IV_LENGTH; - op->sym->cipher.data.length = data_len; - - op->sym->m_src = m; - - return op; -} - -static inline struct rte_crypto_op * -test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, - struct rte_cryptodev_sym_session *sess, unsigned int data_len, - unsigned int digest_len, enum chain_mode chain __rte_unused) -{ - 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 = aes_iv; - op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; - - /* Cipher Parameters */ - op->sym->cipher.iv.data = aes_iv; - op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; - - /* Data lengths/offsets Parameters */ - op->sym->auth.data.offset = AES_BLOCK_SIZE; - op->sym->auth.data.length = data_len - AES_BLOCK_SIZE; - - op->sym->cipher.data.offset = AES_BLOCK_SIZE; - op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; - - op->sym->m_src = m; - - 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; -} - -static inline struct rte_crypto_op * -test_perf_set_crypto_op_snow3g_cipher(struct rte_crypto_op *op, - struct rte_mbuf *m, - struct rte_cryptodev_sym_session *sess, - unsigned data_len) -{ - if (rte_crypto_op_attach_sym_session(op, sess) != 0) { - rte_crypto_op_free(op); - return NULL; - } - - /* Cipher Parameters */ - op->sym->cipher.iv.data = rte_pktmbuf_mtod(m, uint8_t *); - op->sym->cipher.iv.length = SNOW3G_CIPHER_IV_LENGTH; - rte_memcpy(op->sym->cipher.iv.data, snow3g_iv, SNOW3G_CIPHER_IV_LENGTH); - op->sym->cipher.iv.phys_addr = rte_pktmbuf_mtophys(m); - - op->sym->cipher.data.offset = SNOW3G_CIPHER_IV_LENGTH; - op->sym->cipher.data.length = data_len << 3; - - op->sym->m_src = m; - - return op; -} - - -static inline struct rte_crypto_op * -test_perf_set_crypto_op_snow3g_hash(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 *)rte_pktmbuf_mtod_offset(m, uint8_t *, - data_len); - op->sym->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(m, data_len + - SNOW3G_CIPHER_IV_LENGTH); - op->sym->auth.digest.length = digest_len; - op->sym->auth.aad.data = rte_pktmbuf_mtod(m, uint8_t *); - op->sym->auth.aad.length = SNOW3G_CIPHER_IV_LENGTH; - rte_memcpy(op->sym->auth.aad.data, snow3g_iv, - SNOW3G_CIPHER_IV_LENGTH); - op->sym->auth.aad.phys_addr = rte_pktmbuf_mtophys(m); - - /* Data lengths/offsets Parameters */ - op->sym->auth.data.offset = SNOW3G_CIPHER_IV_LENGTH; - op->sym->auth.data.length = data_len << 3; - - op->sym->m_src = m; - - return op; -} - - -static inline struct rte_crypto_op * -test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, - struct rte_cryptodev_sym_session *sess, unsigned int data_len, - unsigned int digest_len, enum chain_mode chain __rte_unused) -{ - 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 = triple_des_iv; - op->sym->auth.aad.length = TRIPLE_DES_CIPHER_IV_LENGTH; - - /* Cipher Parameters */ - op->sym->cipher.iv.data = triple_des_iv; - op->sym->cipher.iv.length = TRIPLE_DES_CIPHER_IV_LENGTH; - - /* Data lengths/offsets Parameters */ - op->sym->auth.data.offset = 0; - op->sym->auth.data.length = data_len; - - op->sym->cipher.data.offset = TRIPLE_DES_BLOCK_SIZE; - op->sym->cipher.data.length = data_len - TRIPLE_DES_BLOCK_SIZE; - - 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; - - 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 * 8]; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - - 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; - } - - /* 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; - } - - /* Make room for Digest and IV in mbuf */ - if (pparams->chain != CIPHER_ONLY) - rte_pktmbuf_append(mbufs[i], digest_length); - rte_pktmbuf_prepend(mbufs[i], AES_CIPHER_IV_LENGTH); - } - - - 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_aes(ops[i], - mbufs[i + (pparams->burst_size * - (j % NUM_MBUF_SETS))], - sess, pparams->buf_size, digest_length, - pparams->chain); - - /* enqueue burst */ - burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, - queue_id, ops, 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 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]); - rte_cryptodev_sym_session_free(dev_id, sess); - - 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++) { - /* - * Buffer size + iv/aad len is allocated, for perf tests they - * are equal + digest len. - */ - mbufs[i] = test_perf_create_pktmbuf( - ts_params->mbuf_mp, - pparams->buf_size + SNOW3G_CIPHER_IV_LENGTH + - digest_length); - - 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++) { - if (pparams->chain == HASH_ONLY) - ops[i+op_offset] = - test_perf_set_crypto_op_snow3g_hash(ops[i+op_offset], - mbufs[i + - (pparams->burst_size * (j % NUM_MBUF_SETS))], - sess, - pparams->buf_size, digest_length); - else if (pparams->chain == CIPHER_ONLY) - ops[i+op_offset] = - test_perf_set_crypto_op_snow3g_cipher(ops[i+op_offset], - mbufs[i + - (pparams->burst_size * (j % NUM_MBUF_SETS))], - sess, - pparams->buf_size); - else - return 1; - } - - /* 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]); - rte_cryptodev_sym_session_free(dev_id, sess); - - printf("\n"); - return TEST_SUCCESS; -} - -static int -test_perf_openssl(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; - - unsigned int 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; - - static struct rte_crypto_op *(*test_perf_set_crypto_op) - (struct rte_crypto_op *, struct rte_mbuf *, - struct rte_cryptodev_sym_session *, - unsigned int, unsigned int, - enum chain_mode); - - switch (pparams->cipher_algo) { - case RTE_CRYPTO_CIPHER_3DES_CBC: - case RTE_CRYPTO_CIPHER_3DES_CTR: - test_perf_set_crypto_op = test_perf_set_crypto_op_3des; - break; - case RTE_CRYPTO_CIPHER_AES_CBC: - case RTE_CRYPTO_CIPHER_AES_CTR: - test_perf_set_crypto_op = test_perf_set_crypto_op_aes; - break; - case RTE_CRYPTO_CIPHER_AES_GCM: - test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; - break; - default: - return TEST_FAILED; - } - - if (rte_cryptodev_count() == 0) { - printf("\nNo crypto devices found. Is PMD build configured?\n"); - return TEST_FAILED; - } - - /* Create Crypto session*/ - sess = test_perf_create_openssl_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; - - 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, - pparams->chain); - - /* enqueue burst */ - burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, - queue_id, ops, 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 throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) - / 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]); - rte_cryptodev_sym_session_free(dev_id, sess); - - printf("\n"); - return TEST_SUCCESS; -} - -static int -test_perf_armv8(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; - uint16_t burst_size; - uint16_t ops_needed; - - 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; - - unsigned int 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"); - return TEST_FAILED; - } - - /* Create Crypto session*/ - sess = test_perf_create_armv8_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(); - - while (total_enqueued < pparams->total_operations) { - if ((total_enqueued + pparams->burst_size) <= - pparams->total_operations) - burst_size = pparams->burst_size; - else - burst_size = pparams->total_operations - total_enqueued; - - 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_aes(ops[i], - mbufs[i + (pparams->burst_size * - (j % NUM_MBUF_SETS))], sess, - pparams->buf_size, digest_length, - pparams->chain); - - /* enqueue burst */ - burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, - queue_id, ops, 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(); - - double ops_s = ((double)processed / (tsc_end - tsc_start)) - * rte_get_tsc_hz(); - double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) - / 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; -} - -/* - - 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_ONLY, - .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_NULL - }, - { - .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_snow3G_vary_pkt_size(void) -{ - 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_openssl_vary_pkt_size(void) -{ - unsigned int total_operations = 10000; - unsigned int burst_size = { 64 }; - unsigned int 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_3DES_CBC, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, - .cipher_key_length = 24, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key_length = 32, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .cipher_key_length = 24, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_AES_GCM - }, - }; - - 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)\tRetries\t" - "EmptyPolls\n"); - for (j = 0; j < RTE_DIM(buf_lengths); j++) { - params_set[i].buf_size = buf_lengths[j]; - test_perf_openssl(testsuite_params.dev_id, 0, - ¶ms_set[i]); - } - } - - return 0; -} - -static int -test_perf_openssl_vary_burst_size(void) -{ - unsigned int total_operations = 4096; - uint16_t buf_lengths[] = { 40 }; - uint8_t i, j; - - struct perf_test_params params_set[] = { - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, - .cipher_key_length = 24, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key_length = 32, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, - .cipher_key_length = 24, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }, - { - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_AES_GCM - }, - }; - - 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_openssl_optimise_cyclecount(¶ms_set[i]); - } - } - - return 0; -} - -static int -test_perf_armv8_vary_pkt_size(void) -{ - unsigned int total_operations = 100000; - unsigned int burst_size = { 64 }; - unsigned int 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 = HASH_CIPHER, - - .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 = HASH_CIPHER, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA256_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)\tRetries\t" - "EmptyPolls\n"); - for (j = 0; j < RTE_DIM(buf_lengths); j++) { - params_set[i].buf_size = buf_lengths[j]; - test_perf_armv8(testsuite_params.dev_id, 0, - ¶ms_set[i]); - } - } - - return 0; -} - -static int -test_perf_armv8_vary_burst_size(void) -{ - unsigned int total_operations = 4096; - uint16_t buf_lengths[] = { 64 }; - 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 = HASH_CIPHER, - - .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 = HASH_CIPHER, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC - }, - }; - - 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_armv8_optimise_cyclecount(¶ms_set[i]); - } - } - - return 0; -} - -static int -test_perf_aes_cbc_vary_burst_size(void) -{ - return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id); -} - - -static struct rte_cryptodev_sym_session * -test_perf_create_session(uint8_t dev_id, struct perf_test_params *pparams) -{ - static struct rte_cryptodev_sym_session *sess; - struct rte_crypto_sym_xform cipher_xform = { 0 }; - struct rte_crypto_sym_xform auth_xform = { 0 }; - - uint8_t cipher_key[pparams->session_attrs->key_cipher_len]; - uint8_t auth_key[pparams->session_attrs->key_auth_len]; - - memcpy(cipher_key, pparams->session_attrs->key_cipher_data, - pparams->session_attrs->key_cipher_len); - memcpy(auth_key, pparams->session_attrs->key_auth_data, - pparams->session_attrs->key_auth_len); - - cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform.next = NULL; - - cipher_xform.cipher.algo = pparams->session_attrs->cipher_algorithm; - cipher_xform.cipher.op = pparams->session_attrs->cipher; - cipher_xform.cipher.key.data = cipher_key; - cipher_xform.cipher.key.length = pparams->session_attrs->key_cipher_len; - - auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - auth_xform.next = NULL; - - auth_xform.auth.op = pparams->session_attrs->auth; - auth_xform.auth.algo = pparams->session_attrs->auth_algorithm; - - auth_xform.auth.digest_length = pparams->session_attrs->digest_len; - auth_xform.auth.key.length = pparams->session_attrs->key_auth_len; - - - cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - if (cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { - cipher_xform.next = &auth_xform; - sess = rte_cryptodev_sym_session_create(dev_id, - &cipher_xform); - } else { - auth_xform.next = &cipher_xform; - sess = rte_cryptodev_sym_session_create(dev_id, - &auth_xform); - } - - return sess; -} - -static inline struct rte_crypto_op * -perf_gcm_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, - struct rte_cryptodev_sym_session *sess, - struct crypto_params *m_hlp, - struct perf_test_params *params) -{ - if (rte_crypto_op_attach_sym_session(op, sess) != 0) { - rte_crypto_op_free(op); - return NULL; - } - - uint16_t iv_pad_len = ALIGN_POW2_ROUNDUP(params->symmetric_op->iv_len, - 16); - - op->sym->auth.digest.data = m_hlp->digest; - op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - m, - params->symmetric_op->aad_len + - iv_pad_len + - params->symmetric_op->p_len); - - op->sym->auth.digest.length = params->symmetric_op->t_len; - - op->sym->auth.aad.data = m_hlp->aad; - op->sym->auth.aad.length = params->symmetric_op->aad_len; - op->sym->auth.aad.phys_addr = rte_pktmbuf_mtophys_offset( - m, - iv_pad_len); - - rte_memcpy(op->sym->auth.aad.data, params->symmetric_op->aad_data, - params->symmetric_op->aad_len); - - op->sym->cipher.iv.data = m_hlp->iv; - rte_memcpy(op->sym->cipher.iv.data, params->symmetric_op->iv_data, - params->symmetric_op->iv_len); - if (params->symmetric_op->iv_len == 12) - op->sym->cipher.iv.data[15] = 1; - - op->sym->cipher.iv.length = params->symmetric_op->iv_len; - - op->sym->auth.data.offset = - iv_pad_len + params->symmetric_op->aad_len; - op->sym->auth.data.length = params->symmetric_op->p_len; - - op->sym->cipher.data.offset = - iv_pad_len + params->symmetric_op->aad_len; - op->sym->cipher.data.length = params->symmetric_op->p_len; - - op->sym->m_src = m; - - return op; -} - -static struct rte_mbuf * -test_perf_create_pktmbuf_fill(struct rte_mempool *mpool, - struct perf_test_params *params, - unsigned buf_sz, struct crypto_params *m_hlp) -{ - struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); - uint16_t iv_pad_len = - ALIGN_POW2_ROUNDUP(params->symmetric_op->iv_len, 16); - uint16_t aad_len = params->symmetric_op->aad_len; - uint16_t digest_size = params->symmetric_op->t_len; - char *p; - - p = rte_pktmbuf_append(m, aad_len); - if (p == NULL) { - rte_pktmbuf_free(m); - return NULL; - } - m_hlp->aad = (uint8_t *)p; - - p = rte_pktmbuf_append(m, iv_pad_len); - if (p == NULL) { - rte_pktmbuf_free(m); - return NULL; - } - m_hlp->iv = (uint8_t *)p; - - p = rte_pktmbuf_append(m, buf_sz); - if (p == NULL) { - rte_pktmbuf_free(m); - return NULL; - } - rte_memcpy(p, params->symmetric_op->p_data, buf_sz); - - p = rte_pktmbuf_append(m, digest_size); - if (p == NULL) { - rte_pktmbuf_free(m); - return NULL; - } - m_hlp->digest = (uint8_t *)p; - - return m; -} - -static int -perf_AES_GCM(uint8_t dev_id, uint16_t queue_id, - struct perf_test_params *pparams, uint32_t test_ops) -{ - int j = 0; - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_cryptodev_sym_session *sess; - struct rte_crypto_op *ops[pparams->burst_size]; - struct rte_crypto_op *proc_ops[pparams->burst_size]; - uint32_t total_operations = pparams->total_operations; - - 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 i = 0, l = 0, m = 0; - uint16_t burst = pparams->burst_size * NUM_MBUF_SETS; - uint16_t ops_unused = 0; - - struct rte_mbuf *mbufs[burst]; - struct crypto_params m_hlp[burst]; - - if (rte_cryptodev_count() == 0) { - printf("\nNo crypto devices available. " - "Is kernel driver loaded?\n"); - return TEST_FAILED; - } - - sess = test_perf_create_session(dev_id, pparams); - TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); - - for (i = 0; i < burst; i++) { - mbufs[i] = test_perf_create_pktmbuf_fill( - ts_params->mbuf_mp, - pparams, pparams->symmetric_op->p_len, - &m_hlp[i]); - } - - if (test_ops) - total_operations = test_ops; - - tsc_start = rte_rdtsc_precise(); - while (total_enqueued < total_operations) { - uint16_t burst_size = - total_enqueued+pparams->burst_size <= total_operations ? - pparams->burst_size : 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"); - } else { - for (i = 0; i < ops_needed; i++) - ops[i] = perf_gcm_set_crypto_op(ops[i], - mbufs[i + (pparams->burst_size * - (j % NUM_MBUF_SETS))], - sess, &m_hlp[i + (pparams->burst_size * - (j % NUM_MBUF_SETS))], pparams); - - /* enqueue burst */ - burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, - queue_id, ops, 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 < 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++) { - if (test_ops) { - uint16_t iv_pad_len = ALIGN_POW2_ROUNDUP - (pparams->symmetric_op->iv_len, 16); - uint8_t *pkt = rte_pktmbuf_mtod( - proc_ops[m]->sym->m_src, - uint8_t *); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - pparams->symmetric_op->c_data, - pkt + iv_pad_len + - pparams->symmetric_op->aad_len, - pparams->symmetric_op->c_len, - "GCM Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - pparams->symmetric_op->t_data, - pkt + iv_pad_len + - pparams->symmetric_op->aad_len + - pparams->symmetric_op->c_len, - pparams->symmetric_op->t_len, - "GCM MAC data not as expected"); - - } - 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->symmetric_op->p_len * 8) - / 1000000000; - - if (!test_ops) { - printf("\n%u\t\t%6.2f\t%16.2f\t%8"PRIu64"\t%10"PRIu64, - pparams->symmetric_op->p_len, - ops_s/1000000, throughput, retries, failed_polls); - } - - for (i = 0; i < burst; i++) - rte_pktmbuf_free(mbufs[i]); - rte_cryptodev_sym_session_free(dev_id, sess); - - return 0; -} - -static int -test_perf_AES_GCM(int continual_buf_len, int continual_size) -{ - uint16_t i, j, k, loops = 1; - - uint16_t buf_lengths[] = { 64, 128, 256, 512, 1024, 1536, 2048 }; - - static const struct cryptodev_perf_test_data *gcm_tests[] = { - &AES_GCM_128_12IV_0AAD - }; - - if (continual_buf_len) - loops = continual_size; - - int TEST_CASES_GCM = RTE_DIM(gcm_tests); - - const unsigned burst_size = 32; - - struct symmetric_op ops_set[TEST_CASES_GCM]; - struct perf_test_params params_set[TEST_CASES_GCM]; - struct symmetric_session_attrs session_attrs[TEST_CASES_GCM]; - static const struct cryptodev_perf_test_data *gcm_test; - - for (i = 0; i < TEST_CASES_GCM; ++i) { - - gcm_test = gcm_tests[i]; - - session_attrs[i].cipher = - RTE_CRYPTO_CIPHER_OP_ENCRYPT; - session_attrs[i].cipher_algorithm = - RTE_CRYPTO_CIPHER_AES_GCM; - session_attrs[i].key_cipher_data = - gcm_test->key.data; - session_attrs[i].key_cipher_len = - gcm_test->key.len; - session_attrs[i].auth_algorithm = - RTE_CRYPTO_AUTH_AES_GCM; - session_attrs[i].auth = - RTE_CRYPTO_AUTH_OP_GENERATE; - session_attrs[i].key_auth_data = NULL; - session_attrs[i].key_auth_len = 0; - session_attrs[i].digest_len = - gcm_test->auth_tag.len; - - ops_set[i].aad_data = gcm_test->aad.data; - ops_set[i].aad_len = gcm_test->aad.len; - ops_set[i].iv_data = gcm_test->iv.data; - ops_set[i].iv_len = gcm_test->iv.len; - ops_set[i].p_data = gcm_test->plaintext.data; - ops_set[i].p_len = buf_lengths[i]; - ops_set[i].c_data = gcm_test->ciphertext.data; - ops_set[i].c_len = buf_lengths[i]; - ops_set[i].t_data = gcm_test->auth_tags[i].data; - ops_set[i].t_len = gcm_test->auth_tags[i].len; - - params_set[i].chain = CIPHER_HASH; - params_set[i].session_attrs = &session_attrs[i]; - params_set[i].symmetric_op = &ops_set[i]; - if (continual_buf_len) - params_set[i].total_operations = 0xFFFFFF; - else - params_set[i].total_operations = 1000000; - - params_set[i].burst_size = burst_size; - - } - - if (continual_buf_len) - printf("\nCipher algo: %s Cipher hash: %s cipher key size: %ub" - " burst size: %u", "AES_GCM", "AES_GCM", - gcm_test->key.len << 3, burst_size); - - for (i = 0; i < RTE_DIM(gcm_tests); i++) { - - if (!continual_buf_len) { - printf("\nCipher algo: %s Cipher hash: %s cipher key size: %ub" - " burst size: %u", "AES_GCM", "AES_GCM", - gcm_test->key.len << 3, burst_size); - printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\t" - " Retries\tEmptyPolls"); - } - - uint16_t len = RTE_DIM(buf_lengths); - uint16_t p = 0; - - if (continual_buf_len) { - for (k = 0; k < RTE_DIM(buf_lengths); k++) - if (buf_lengths[k] == continual_buf_len) { - len = k + 1; - p = k; - break; - } - } - for (j = p; j < len; ++j) { - - params_set[i].symmetric_op->c_len = buf_lengths[j]; - params_set[i].symmetric_op->p_len = buf_lengths[j]; - - ops_set[i].t_data = gcm_tests[i]->auth_tags[j].data; - ops_set[i].t_len = gcm_tests[i]->auth_tags[j].len; - - /* Run is twice, one for encryption/hash checks, - * one for perf - */ - if (perf_AES_GCM(testsuite_params.dev_id, 0, - ¶ms_set[i], 1)) - return TEST_FAILED; - - for (k = 0; k < loops; k++) { - if (continual_buf_len) - printf("\n\nBuffer Size(B)\tOPS(M)\t" - "Throughput(Gbps)\t" - "Retries\tEmptyPolls"); - if (perf_AES_GCM(testsuite_params.dev_id, 0, - ¶ms_set[i], 0)) - return TEST_FAILED; - if (continual_buf_len) - printf("\n\nCompleted loop %i of %i ...", - k+1, loops); - } - } - - } - printf("\n"); - return 0; -} - -static int test_cryptodev_perf_AES_GCM(void) -{ - return test_perf_AES_GCM(0, 0); -} -/* - * This function calls AES GCM performance tests providing - * size of packet as an argument. If size of packet is not - * in the buf_lengths array, all sizes will be used - */ -static int test_continual_perf_AES_GCM(void) -{ - return test_perf_AES_GCM(1024, 10); -} - -static int -test_perf_continual_performance_test(void) -{ - unsigned int total_operations = 0xFFFFFF; - unsigned int total_loops = 10; - unsigned int burst_size = 32; - uint8_t i; - - struct perf_test_params params_set = { - .total_operations = total_operations, - .burst_size = burst_size, - .buf_size = 1024, - - .chain = CIPHER_HASH, - - .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key_length = 16, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC - }; - - for (i = 1; i <= total_loops; ++i) { - printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." - " burst_size: %d ops\n", - chain_mode_name(params_set.chain), - cipher_algo_name(params_set.cipher_algo), - auth_algo_name(params_set.auth_algo), - params_set.cipher_key_length, - burst_size); - printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\t" - "Retries\tEmptyPolls\n"); - test_perf_aes_sha(testsuite_params.dev_id, 0, - ¶ms_set); - printf("\nCompleted loop %i of %i ...", i, total_loops); - } - return 0; -} - -static struct unit_test_suite cryptodev_qat_continual_testsuite = { - .suite_name = "Crypto Device Continual Performance Test", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_perf_continual_performance_test), - TEST_CASE_ST(ut_setup, ut_teardown, - test_continual_perf_AES_GCM), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -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_aes_cbc_encrypt_digest_vary_pkt_size), - TEST_CASE_ST(ut_setup, ut_teardown, - test_cryptodev_perf_AES_GCM), - TEST_CASE_ST(ut_setup, ut_teardown, - test_perf_aes_cbc_vary_burst_size), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_gcm_testsuite = { - .suite_name = "Crypto Device AESNI GCM Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_cryptodev_perf_AES_GCM), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -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_snow3G_vary_burst_size), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_openssl_testsuite = { - .suite_name = "Crypto Device OPENSSL Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_perf_openssl_vary_pkt_size), - TEST_CASE_ST(ut_setup, ut_teardown, - test_perf_openssl_vary_burst_size), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_armv8_testsuite = { - .suite_name = "Crypto Device ARMv8 Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_perf_armv8_vary_pkt_size), - TEST_CASE_ST(ut_setup, ut_teardown, - test_perf_armv8_vary_burst_size), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -perftest_aesni_gcm_cryptodev(void) -{ - gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_AESNI_GCM_PMD; - - return unit_test_suite_runner(&cryptodev_gcm_testsuite); -} - -static int -perftest_aesni_mb_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_AESNI_MB_PMD; - - return unit_test_suite_runner(&cryptodev_aes_testsuite); -} - -static int -perftest_qat_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) -{ - 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 int -perftest_openssl_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_OPENSSL_PMD; - - return unit_test_suite_runner(&cryptodev_openssl_testsuite); -} - -static int -perftest_qat_continual_cryptodev(void) -{ - gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_QAT_SYM_PMD; - - return unit_test_suite_runner(&cryptodev_qat_continual_testsuite); -} - -static int -perftest_sw_armv8_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_ARMV8_PMD; - - return unit_test_suite_runner(&cryptodev_armv8_testsuite); -} - -REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev); -REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev); -REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev); -REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perftest, perftest_qat_snow3g_cryptodev); -REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_perftest, perftest_aesni_gcm_cryptodev); -REGISTER_TEST_COMMAND(cryptodev_openssl_perftest, - perftest_openssl_cryptodev); -REGISTER_TEST_COMMAND(cryptodev_qat_continual_perftest, - perftest_qat_continual_cryptodev); -REGISTER_TEST_COMMAND(cryptodev_sw_armv8_perftest, - perftest_sw_armv8_cryptodev); diff --git a/app/test/test_cryptodev_snow3g_hash_test_vectors.h b/app/test/test_cryptodev_snow3g_hash_test_vectors.h deleted file mode 100644 index a8a47db577..0000000000 --- a/app/test/test_cryptodev_snow3g_hash_test_vectors.h +++ /dev/null @@ -1,548 +0,0 @@ -/*- - * 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_SNOW3G_HASH_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_SNOW3G_HASH_TEST_VECTORS_H_ - -struct snow3g_hash_test_data { - struct { - uint8_t data[64]; - unsigned len; - } key; - - struct { - uint8_t data[64]; - unsigned len; - } aad; - - struct { - uint8_t data[2056]; - unsigned len; /* length must be in Bits */ - } plaintext; - - struct { - unsigned len; - } validAuthLenInBits; - - struct { - unsigned len; - } validAuthOffsetLenInBits; - - struct { - uint8_t data[64]; - unsigned len; - } digest; -}; - -struct snow3g_hash_test_data snow3g_hash_test_case_1 = { - .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, - 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD - }, - .len = 16 - }, - .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 - }, - .len = 384 - }, - .validAuthLenInBits = { - .len = 384 - }, - .validAuthOffsetLenInBits = { - .len = 128 - }, - .digest = { - .data = {0x38, 0xB5, 0x54, 0xC0 }, - .len = 4 - } -}; - -struct snow3g_hash_test_data snow3g_hash_test_case_2 = { - .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, - 0xA9, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0xF7, 0x37 - }, - .len = 16 - }, - .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 - }, - .len = 1000 - }, - .validAuthLenInBits = { - .len = 1000 - }, - .validAuthOffsetLenInBits = { - .len = 128 - }, - .digest = { - .data = {0x06, 0x17, 0x45, 0xAE}, - .len = 4 - } -}; - -struct snow3g_hash_test_data snow3g_hash_test_case_3 = { - .key = { - .data = { - 0xB3, 0x12, 0x0F, 0xFD, 0xB2, 0xCF, 0x6A, 0xF4, - 0xE7, 0x3E, 0xAF, 0x2E, 0xF4, 0xEB, 0xEC, 0x69 - }, - .len = 16 - }, - .aad = { - .data = { - 0x29, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0x77, 0x37, - 0xA9, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0xF7, 0x37 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0xE0, 0x95, 0x80, 0x45, 0xF3, 0xA0, 0xBB, 0xA4, - 0xE3, 0x96, 0x83, 0x46, 0xF0, 0xA3, 0xB8, 0xA7, - 0xC0, 0x2A, 0x01, 0x8A, 0xE6, 0x40, 0x76, 0x52, - 0x26, 0xB9, 0x87, 0xC9, 0x13, 0xE6, 0xCB, 0xF0, - 0x83, 0x57, 0x00, 0x16, 0xCF, 0x83, 0xEF, 0xBC, - 0x61, 0xC0, 0x82, 0x51, 0x3E, 0x21, 0x56, 0x1A, - 0x42, 0x7C, 0x00, 0x9D, 0x28, 0xC2, 0x98, 0xEF, - 0xAC, 0xE7, 0x8E, 0xD6, 0xD5, 0x6C, 0x2D, 0x45, - 0x05, 0xAD, 0x03, 0x2E, 0x9C, 0x04, 0xDC, 0x60, - 0xE7, 0x3A, 0x81, 0x69, 0x6D, 0xA6, 0x65, 0xC6, - 0xC4, 0x86, 0x03, 0xA5, 0x7B, 0x45, 0xAB, 0x33, - 0x22, 0x15, 0x85, 0xE6, 0x8E, 0xE3, 0x16, 0x91, - 0x87, 0xFB, 0x02, 0x39, 0x52, 0x86, 0x32, 0xDD, - 0x65, 0x6C, 0x80, 0x7E, 0xA3, 0x24, 0x8B, 0x7B, - 0x46, 0xD0, 0x02, 0xB2, 0xB5, 0xC7, 0x45, 0x8E, - 0xB8, 0x5B, 0x9C, 0xE9, 0x58, 0x79, 0xE0, 0x34, - 0x08, 0x59, 0x05, 0x5E, 0x3B, 0x0A, 0xBB, 0xC3, - 0xEA, 0xCE, 0x87, 0x19, 0xCA, 0xA8, 0x02, 0x65, - 0xC9, 0x72, 0x05, 0xD5, 0xDC, 0x4B, 0xCC, 0x90, - 0x2F, 0xE1, 0x83, 0x96, 0x29, 0xED, 0x71, 0x32, - 0x8A, 0x0F, 0x04, 0x49, 0xF5, 0x88, 0x55, 0x7E, - 0x68, 0x98, 0x86, 0x0E, 0x04, 0x2A, 0xEC, 0xD8, - 0x4B, 0x24, 0x04, 0xC2, 0x12, 0xC9, 0x22, 0x2D, - 0xA5, 0xBF, 0x8A, 0x89, 0xEF, 0x67, 0x97, 0x87, - 0x0C, 0xF5, 0x07, 0x71, 0xA6, 0x0F, 0x66, 0xA2, - 0xEE, 0x62, 0x85, 0x36, 0x57, 0xAD, 0xDF, 0x04, - 0xCD, 0xDE, 0x07, 0xFA, 0x41, 0x4E, 0x11, 0xF1, - 0x2B, 0x4D, 0x81, 0xB9, 0xB4, 0xE8, 0xAC, 0x53, - 0x8E, 0xA3, 0x06, 0x66, 0x68, 0x8D, 0x88, 0x1F, - 0x6C, 0x34, 0x84, 0x21, 0x99, 0x2F, 0x31, 0xB9, - 0x4F, 0x88, 0x06, 0xED, 0x8F, 0xCC, 0xFF, 0x4C, - 0x91, 0x23, 0xB8, 0x96, 0x42, 0x52, 0x7A, 0xD6, - 0x13, 0xB1, 0x09, 0xBF, 0x75, 0x16, 0x74, 0x85, - 0xF1, 0x26, 0x8B, 0xF8, 0x84, 0xB4, 0xCD, 0x23, - 0xD2, 0x9A, 0x09, 0x34, 0x92, 0x57, 0x03, 0xD6, - 0x34, 0x09, 0x8F, 0x77, 0x67, 0xF1, 0xBE, 0x74, - 0x91, 0xE7, 0x08, 0xA8, 0xBB, 0x94, 0x9A, 0x38, - 0x73, 0x70, 0x8A, 0xEF, 0x4A, 0x36, 0x23, 0x9E, - 0x50, 0xCC, 0x08, 0x23, 0x5C, 0xD5, 0xED, 0x6B, - 0xBE, 0x57, 0x86, 0x68, 0xA1, 0x7B, 0x58, 0xC1, - 0x17, 0x1D, 0x0B, 0x90, 0xE8, 0x13, 0xA9, 0xE4, - 0xF5, 0x8A, 0x89, 0xD7, 0x19, 0xB1, 0x10, 0x42, - 0xD6, 0x36, 0x0B, 0x1B, 0x0F, 0x52, 0xDE, 0xB7, - 0x30, 0xA5, 0x8D, 0x58, 0xFA, 0xF4, 0x63, 0x15, - 0x95, 0x4B, 0x0A, 0x87, 0x26, 0x91, 0x47, 0x59, - 0x77, 0xDC, 0x88, 0xC0, 0xD7, 0x33, 0xFE, 0xFF, - 0x54, 0x60, 0x0A, 0x0C, 0xC1, 0xD0, 0x30, 0x0A, - 0xAA, 0xEB, 0x94, 0x57, 0x2C, 0x6E, 0x95, 0xB0, - 0x1A, 0xE9, 0x0D, 0xE0, 0x4F, 0x1D, 0xCE, 0x47, - 0xF8, 0x7E, 0x8F, 0xA7, 0xBE, 0xBF, 0x77, 0xE1, - 0xDB, 0xC2, 0x0D, 0x6B, 0xA8, 0x5C, 0xB9, 0x14, - 0x3D, 0x51, 0x8B, 0x28, 0x5D, 0xFA, 0x04, 0xB6, - 0x98, 0xBF, 0x0C, 0xF7, 0x81, 0x9F, 0x20, 0xFA, - 0x7A, 0x28, 0x8E, 0xB0, 0x70, 0x3D, 0x99, 0x5C, - 0x59, 0x94, 0x0C, 0x7C, 0x66, 0xDE, 0x57, 0xA9, - 0xB7, 0x0F, 0x82, 0x37, 0x9B, 0x70, 0xE2, 0x03, - 0x1E, 0x45, 0x0F, 0xCF, 0xD2, 0x18, 0x13, 0x26, - 0xFC, 0xD2, 0x8D, 0x88, 0x23, 0xBA, 0xAA, 0x80, - 0xDF, 0x6E, 0x0F, 0x44, 0x35, 0x59, 0x64, 0x75, - 0x39, 0xFD, 0x89, 0x07, 0xC0, 0xFF, 0xD9, 0xD7, - 0x9C, 0x13, 0x0E, 0xD8, 0x1C, 0x9A, 0xFD, 0x9B, - 0x7E, 0x84, 0x8C, 0x9F, 0xED, 0x38, 0x44, 0x3D, - 0x5D, 0x38, 0x0E, 0x53, 0xFB, 0xDB, 0x8A, 0xC8, - 0xC3, 0xD3, 0xF0, 0x68, 0x76, 0x05, 0x4F, 0x12, - 0x24, 0x61, 0x10, 0x7D, 0xE9, 0x2F, 0xEA, 0x09, - 0xC6, 0xF6, 0x92, 0x3A, 0x18, 0x8D, 0x53, 0xAF, - 0xE5, 0x4A, 0x10, 0xF6, 0x0E, 0x6E, 0x9D, 0x5A, - 0x03, 0xD9, 0x96, 0xB5, 0xFB, 0xC8, 0x20, 0xF8, - 0xA6, 0x37, 0x11, 0x6A, 0x27, 0xAD, 0x04, 0xB4, - 0x44, 0xA0, 0x93, 0x2D, 0xD6, 0x0F, 0xBD, 0x12, - 0x67, 0x1C, 0x11, 0xE1, 0xC0, 0xEC, 0x73, 0xE7, - 0x89, 0x87, 0x9F, 0xAA, 0x3D, 0x42, 0xC6, 0x4D, - 0x20, 0xCD, 0x12, 0x52, 0x74, 0x2A, 0x37, 0x68, - 0xC2, 0x5A, 0x90, 0x15, 0x85, 0x88, 0x8E, 0xCE, - 0xE1, 0xE6, 0x12, 0xD9, 0x93, 0x6B, 0x40, 0x3B, - 0x07, 0x75, 0x94, 0x9A, 0x66, 0xCD, 0xFD, 0x99, - 0xA2, 0x9B, 0x13, 0x45, 0xBA, 0xA8, 0xD9, 0xD5, - 0x40, 0x0C, 0x91, 0x02, 0x4B, 0x0A, 0x60, 0x73, - 0x63, 0xB0, 0x13, 0xCE, 0x5D, 0xE9, 0xAE, 0x86, - 0x9D, 0x3B, 0x8D, 0x95, 0xB0, 0x57, 0x0B, 0x3C, - 0x2D, 0x39, 0x14, 0x22, 0xD3, 0x24, 0x50, 0xCB, - 0xCF, 0xAE, 0x96, 0x65, 0x22, 0x86, 0xE9, 0x6D, - 0xEC, 0x12, 0x14, 0xA9, 0x34, 0x65, 0x27, 0x98, - 0x0A, 0x81, 0x92, 0xEA, 0xC1, 0xC3, 0x9A, 0x3A, - 0xAF, 0x6F, 0x15, 0x35, 0x1D, 0xA6, 0xBE, 0x76, - 0x4D, 0xF8, 0x97, 0x72, 0xEC, 0x04, 0x07, 0xD0, - 0x6E, 0x44, 0x15, 0xBE, 0xFA, 0xE7, 0xC9, 0x25, - 0x80, 0xDF, 0x9B, 0xF5, 0x07, 0x49, 0x7C, 0x8F, - 0x29, 0x95, 0x16, 0x0D, 0x4E, 0x21, 0x8D, 0xAA, - 0xCB, 0x02, 0x94, 0x4A, 0xBF, 0x83, 0x34, 0x0C, - 0xE8, 0xBE, 0x16, 0x86, 0xA9, 0x60, 0xFA, 0xF9, - 0x0E, 0x2D, 0x90, 0xC5, 0x5C, 0xC6, 0x47, 0x5B, - 0xAB, 0xC3, 0x17, 0x1A, 0x80, 0xA3, 0x63, 0x17, - 0x49, 0x54, 0x95, 0x5D, 0x71, 0x01, 0xDA, 0xB1, - 0x6A, 0xE8, 0x17, 0x91, 0x67, 0xE2, 0x14, 0x44, - 0xB4, 0x43, 0xA9, 0xEA, 0xAA, 0x7C, 0x91, 0xDE, - 0x36, 0xD1, 0x18, 0xC3, 0x9D, 0x38, 0x9F, 0x8D, - 0xD4, 0x46, 0x9A, 0x84, 0x6C, 0x9A, 0x26, 0x2B, - 0xF7, 0xFA, 0x18, 0x48, 0x7A, 0x79, 0xE8, 0xDE, - 0x11, 0x69, 0x9E, 0x0B, 0x8F, 0xDF, 0x55, 0x7C, - 0xB4, 0x87, 0x19, 0xD4, 0x53, 0xBA, 0x71, 0x30, - 0x56, 0x10, 0x9B, 0x93, 0xA2, 0x18, 0xC8, 0x96, - 0x75, 0xAC, 0x19, 0x5F, 0xB4, 0xFB, 0x06, 0x63, - 0x9B, 0x37, 0x97, 0x14, 0x49, 0x55, 0xB3, 0xC9, - 0x32, 0x7D, 0x1A, 0xEC, 0x00, 0x3D, 0x42, 0xEC, - 0xD0, 0xEA, 0x98, 0xAB, 0xF1, 0x9F, 0xFB, 0x4A, - 0xF3, 0x56, 0x1A, 0x67, 0xE7, 0x7C, 0x35, 0xBF, - 0x15, 0xC5, 0x9C, 0x24, 0x12, 0xDA, 0x88, 0x1D, - 0xB0, 0x2B, 0x1B, 0xFB, 0xCE, 0xBF, 0xAC, 0x51, - 0x52, 0xBC, 0x99, 0xBC, 0x3F, 0x1D, 0x15, 0xF7, - 0x71, 0x00, 0x1B, 0x70, 0x29, 0xFE, 0xDB, 0x02, - 0x8F, 0x8B, 0x85, 0x2B, 0xC4, 0x40, 0x7E, 0xB8, - 0x3F, 0x89, 0x1C, 0x9C, 0xA7, 0x33, 0x25, 0x4F, - 0xDD, 0x1E, 0x9E, 0xDB, 0x56, 0x91, 0x9C, 0xE9, - 0xFE, 0xA2, 0x1C, 0x17, 0x40, 0x72, 0x52, 0x1C, - 0x18, 0x31, 0x9A, 0x54, 0xB5, 0xD4, 0xEF, 0xBE, - 0xBD, 0xDF, 0x1D, 0x8B, 0x69, 0xB1, 0xCB, 0xF2, - 0x5F, 0x48, 0x9F, 0xCC, 0x98, 0x13, 0x72, 0x54, - 0x7C, 0xF4, 0x1D, 0x00, 0x8E, 0xF0, 0xBC, 0xA1, - 0x92, 0x6F, 0x93, 0x4B, 0x73, 0x5E, 0x09, 0x0B, - 0x3B, 0x25, 0x1E, 0xB3, 0x3A, 0x36, 0xF8, 0x2E, - 0xD9, 0xB2, 0x9C, 0xF4, 0xCB, 0x94, 0x41, 0x88, - 0xFA, 0x0E, 0x1E, 0x38, 0xDD, 0x77, 0x8F, 0x7D, - 0x1C, 0x9D, 0x98, 0x7B, 0x28, 0xD1, 0x32, 0xDF, - 0xB9, 0x73, 0x1F, 0xA4, 0xF4, 0xB4, 0x16, 0x93, - 0x5B, 0xE4, 0x9D, 0xE3, 0x05, 0x16, 0xAF, 0x35, - 0x78, 0x58, 0x1F, 0x2F, 0x13, 0xF5, 0x61, 0xC0, - 0x66, 0x33, 0x61, 0x94, 0x1E, 0xAB, 0x24, 0x9A, - 0x4B, 0xC1, 0x23, 0xF8, 0xD1, 0x5C, 0xD7, 0x11, - 0xA9, 0x56, 0xA1, 0xBF, 0x20, 0xFE, 0x6E, 0xB7, - 0x8A, 0xEA, 0x23, 0x73, 0x36, 0x1D, 0xA0, 0x42, - 0x6C, 0x79, 0xA5, 0x30, 0xC3, 0xBB, 0x1D, 0xE0, - 0xC9, 0x97, 0x22, 0xEF, 0x1F, 0xDE, 0x39, 0xAC, - 0x2B, 0x00, 0xA0, 0xA8, 0xEE, 0x7C, 0x80, 0x0A, - 0x08, 0xBC, 0x22, 0x64, 0xF8, 0x9F, 0x4E, 0xFF, - 0xE6, 0x27, 0xAC, 0x2F, 0x05, 0x31, 0xFB, 0x55, - 0x4F, 0x6D, 0x21, 0xD7, 0x4C, 0x59, 0x0A, 0x70, - 0xAD, 0xFA, 0xA3, 0x90, 0xBD, 0xFB, 0xB3, 0xD6, - 0x8E, 0x46, 0x21, 0x5C, 0xAB, 0x18, 0x7D, 0x23, - 0x68, 0xD5, 0xA7, 0x1F, 0x5E, 0xBE, 0xC0, 0x81, - 0xCD, 0x3B, 0x20, 0xC0, 0x82, 0xDB, 0xE4, 0xCD, - 0x2F, 0xAC, 0xA2, 0x87, 0x73, 0x79, 0x5D, 0x6B, - 0x0C, 0x10, 0x20, 0x4B, 0x65, 0x9A, 0x93, 0x9E, - 0xF2, 0x9B, 0xBE, 0x10, 0x88, 0x24, 0x36, 0x24, - 0x42, 0x99, 0x27, 0xA7, 0xEB, 0x57, 0x6D, 0xD3, - 0xA0, 0x0E, 0xA5, 0xE0, 0x1A, 0xF5, 0xD4, 0x75, - 0x83, 0xB2, 0x27, 0x2C, 0x0C, 0x16, 0x1A, 0x80, - 0x65, 0x21, 0xA1, 0x6F, 0xF9, 0xB0, 0xA7, 0x22, - 0xC0, 0xCF, 0x26, 0xB0, 0x25, 0xD5, 0x83, 0x6E, - 0x22, 0x58, 0xA4, 0xF7, 0xD4, 0x77, 0x3A, 0xC8, - 0x01, 0xE4, 0x26, 0x3B, 0xC2, 0x94, 0xF4, 0x3D, - 0xEF, 0x7F, 0xA8, 0x70, 0x3F, 0x3A, 0x41, 0x97, - 0x46, 0x35, 0x25, 0x88, 0x76, 0x52, 0xB0, 0xB2, - 0xA4, 0xA2, 0xA7, 0xCF, 0x87, 0xF0, 0x09, 0x14, - 0x87, 0x1E, 0x25, 0x03, 0x91, 0x13, 0xC7, 0xE1, - 0x61, 0x8D, 0xA3, 0x40, 0x64, 0xB5, 0x7A, 0x43, - 0xC4, 0x63, 0x24, 0x9F, 0xB8, 0xD0, 0x5E, 0x0F, - 0x26, 0xF4, 0xA6, 0xD8, 0x49, 0x72, 0xE7, 0xA9, - 0x05, 0x48, 0x24, 0x14, 0x5F, 0x91, 0x29, 0x5C, - 0xDB, 0xE3, 0x9A, 0x6F, 0x92, 0x0F, 0xAC, 0xC6, - 0x59, 0x71, 0x2B, 0x46, 0xA5, 0x4B, 0xA2, 0x95, - 0xBB, 0xE6, 0xA9, 0x01, 0x54, 0xE9, 0x1B, 0x33, - 0x98, 0x5A, 0x2B, 0xCD, 0x42, 0x0A, 0xD5, 0xC6, - 0x7E, 0xC9, 0xAD, 0x8E, 0xB7, 0xAC, 0x68, 0x64, - 0xDB, 0x27, 0x2A, 0x51, 0x6B, 0xC9, 0x4C, 0x28, - 0x39, 0xB0, 0xA8, 0x16, 0x9A, 0x6B, 0xF5, 0x8E, - 0x1A, 0x0C, 0x2A, 0xDA, 0x8C, 0x88, 0x3B, 0x7B, - 0xF4, 0x97, 0xA4, 0x91, 0x71, 0x26, 0x8E, 0xD1, - 0x5D, 0xDD, 0x29, 0x69, 0x38, 0x4E, 0x7F, 0xF4, - 0xBF, 0x4A, 0xAB, 0x2E, 0xC9, 0xEC, 0xC6, 0x52, - 0x9C, 0xF6, 0x29, 0xE2, 0xDF, 0x0F, 0x08, 0xA7, - 0x7A, 0x65, 0xAF, 0xA1, 0x2A, 0xA9, 0xB5, 0x05, - 0xDF, 0x8B, 0x28, 0x7E, 0xF6, 0xCC, 0x91, 0x49, - 0x3D, 0x1C, 0xAA, 0x39, 0x07, 0x6E, 0x28, 0xEF, - 0x1E, 0xA0, 0x28, 0xF5, 0x11, 0x8D, 0xE6, 0x1A, - 0xE0, 0x2B, 0xB6, 0xAE, 0xFC, 0x33, 0x43, 0xA0, - 0x50, 0x29, 0x2F, 0x19, 0x9F, 0x40, 0x18, 0x57, - 0xB2, 0xBE, 0xAD, 0x5E, 0x6E, 0xE2, 0xA1, 0xF1, - 0x91, 0x02, 0x2F, 0x92, 0x78, 0x01, 0x6F, 0x04, - 0x77, 0x91, 0xA9, 0xD1, 0x8D, 0xA7, 0xD2, 0xA6, - 0xD2, 0x7F, 0x2E, 0x0E, 0x51, 0xC2, 0xF6, 0xEA, - 0x30, 0xE8, 0xAC, 0x49, 0xA0, 0x60, 0x4F, 0x4C, - 0x13, 0x54, 0x2E, 0x85, 0xB6, 0x83, 0x81, 0xB9, - 0xFD, 0xCF, 0xA0, 0xCE, 0x4B, 0x2D, 0x34, 0x13, - 0x54, 0x85, 0x2D, 0x36, 0x02, 0x45, 0xC5, 0x36, - 0xB6, 0x12, 0xAF, 0x71, 0xF3, 0xE7, 0x7C, 0x90, - 0x95, 0xAE, 0x2D, 0xBD, 0xE5, 0x04, 0xB2, 0x65, - 0x73, 0x3D, 0xAB, 0xFE, 0x10, 0xA2, 0x0F, 0xC7, - 0xD6, 0xD3, 0x2C, 0x21, 0xCC, 0xC7, 0x2B, 0x8B, - 0x34, 0x44, 0xAE, 0x66, 0x3D, 0x65, 0x92, 0x2D, - 0x17, 0xF8, 0x2C, 0xAA, 0x2B, 0x86, 0x5C, 0xD8, - 0x89, 0x13, 0xD2, 0x91, 0xA6, 0x58, 0x99, 0x02, - 0x6E, 0xA1, 0x32, 0x84, 0x39, 0x72, 0x3C, 0x19, - 0x8C, 0x36, 0xB0, 0xC3, 0xC8, 0xD0, 0x85, 0xBF, - 0xAF, 0x8A, 0x32, 0x0F, 0xDE, 0x33, 0x4B, 0x4A, - 0x49, 0x19, 0xB4, 0x4C, 0x2B, 0x95, 0xF6, 0xE8, - 0xEC, 0xF7, 0x33, 0x93, 0xF7, 0xF0, 0xD2, 0xA4, - 0x0E, 0x60, 0xB1, 0xD4, 0x06, 0x52, 0x6B, 0x02, - 0x2D, 0xDC, 0x33, 0x18, 0x10, 0xB1, 0xA5, 0xF7, - 0xC3, 0x47, 0xBD, 0x53, 0xED, 0x1F, 0x10, 0x5D, - 0x6A, 0x0D, 0x30, 0xAB, 0xA4, 0x77, 0xE1, 0x78, - 0x88, 0x9A, 0xB2, 0xEC, 0x55, 0xD5, 0x58, 0xDE, - 0xAB, 0x26, 0x30, 0x20, 0x43, 0x36, 0x96, 0x2B, - 0x4D, 0xB5, 0xB6, 0x63, 0xB6, 0x90, 0x2B, 0x89, - 0xE8, 0x5B, 0x31, 0xBC, 0x6A, 0xF5, 0x0F, 0xC5, - 0x0A, 0xCC, 0xB3, 0xFB, 0x9B, 0x57, 0xB6, 0x63, - 0x29, 0x70, 0x31, 0x37, 0x8D, 0xB4, 0x78, 0x96, - 0xD7, 0xFB, 0xAF, 0x6C, 0x60, 0x0A, 0xDD, 0x2C, - 0x67, 0xF9, 0x36, 0xDB, 0x03, 0x79, 0x86, 0xDB, - 0x85, 0x6E, 0xB4, 0x9C, 0xF2, 0xDB, 0x3F, 0x7D, - 0xA6, 0xD2, 0x36, 0x50, 0xE4, 0x38, 0xF1, 0x88, - 0x40, 0x41, 0xB0, 0x13, 0x11, 0x9E, 0x4C, 0x2A, - 0xE5, 0xAF, 0x37, 0xCC, 0xCD, 0xFB, 0x68, 0x66, - 0x07, 0x38, 0xB5, 0x8B, 0x3C, 0x59, 0xD1, 0xC0, - 0x24, 0x84, 0x37, 0x47, 0x2A, 0xBA, 0x1F, 0x35, - 0xCA, 0x1F, 0xB9, 0x0C, 0xD7, 0x14, 0xAA, 0x9F, - 0x63, 0x55, 0x34, 0xF4, 0x9E, 0x7C, 0x5B, 0xBA, - 0x81, 0xC2, 0xB6, 0xB3, 0x6F, 0xDE, 0xE2, 0x1C, - 0xA2, 0x7E, 0x34, 0x7F, 0x79, 0x3D, 0x2C, 0xE9, - 0x44, 0xED, 0xB2, 0x3C, 0x8C, 0x9B, 0x91, 0x4B, - 0xE1, 0x03, 0x35, 0xE3, 0x50, 0xFE, 0xB5, 0x07, - 0x03, 0x94, 0xB7, 0xA4, 0xA1, 0x5C, 0x0C, 0xA1, - 0x20, 0x28, 0x35, 0x68, 0xB7, 0xBF, 0xC2, 0x54, - 0xFE, 0x83, 0x8B, 0x13, 0x7A, 0x21, 0x47, 0xCE, - 0x7C, 0x11, 0x3A, 0x3A, 0x4D, 0x65, 0x49, 0x9D, - 0x9E, 0x86, 0xB8, 0x7D, 0xBC, 0xC7, 0xF0, 0x3B, - 0xBD, 0x3A, 0x3A, 0xB1, 0xAA, 0x24, 0x3E, 0xCE, - 0x5B, 0xA9, 0xBC, 0xF2, 0x5F, 0x82, 0x83, 0x6C, - 0xFE, 0x47, 0x3B, 0x2D, 0x83, 0xE7, 0xA7, 0x20, - 0x1C, 0xD0, 0xB9, 0x6A, 0x72, 0x45, 0x1E, 0x86, - 0x3F, 0x6C, 0x3B, 0xA6, 0x64, 0xA6, 0xD0, 0x73, - 0xD1, 0xF7, 0xB5, 0xED, 0x99, 0x08, 0x65, 0xD9, - 0x78, 0xBD, 0x38, 0x15, 0xD0, 0x60, 0x94, 0xFC, - 0x9A, 0x2A, 0xBA, 0x52, 0x21, 0xC2, 0x2D, 0x5A, - 0xB9, 0x96, 0x38, 0x9E, 0x37, 0x21, 0xE3, 0xAF, - 0x5F, 0x05, 0xBE, 0xDD, 0xC2, 0x87, 0x5E, 0x0D, - 0xFA, 0xEB, 0x39, 0x02, 0x1E, 0xE2, 0x7A, 0x41, - 0x18, 0x7C, 0xBB, 0x45, 0xEF, 0x40, 0xC3, 0xE7, - 0x3B, 0xC0, 0x39, 0x89, 0xF9, 0xA3, 0x0D, 0x12, - 0xC5, 0x4B, 0xA7, 0xD2, 0x14, 0x1D, 0xA8, 0xA8, - 0x75, 0x49, 0x3E, 0x65, 0x77, 0x6E, 0xF3, 0x5F, - 0x97, 0xDE, 0xBC, 0x22, 0x86, 0xCC, 0x4A, 0xF9, - 0xB4, 0x62, 0x3E, 0xEE, 0x90, 0x2F, 0x84, 0x0C, - 0x52, 0xF1, 0xB8, 0xAD, 0x65, 0x89, 0x39, 0xAE, - 0xF7, 0x1F, 0x3F, 0x72, 0xB9, 0xEC, 0x1D, 0xE2, - 0x15, 0x88, 0xBD, 0x35, 0x48, 0x4E, 0xA4, 0x44, - 0x36, 0x34, 0x3F, 0xF9, 0x5E, 0xAD, 0x6A, 0xB1, - 0xD8, 0xAF, 0xB1, 0xB2, 0xA3, 0x03, 0xDF, 0x1B, - 0x71, 0xE5, 0x3C, 0x4A, 0xEA, 0x6B, 0x2E, 0x3E, - 0x93, 0x72, 0xBE, 0x0D, 0x1B, 0xC9, 0x97, 0x98, - 0xB0, 0xCE, 0x3C, 0xC1, 0x0D, 0x2A, 0x59, 0x6D, - 0x56, 0x5D, 0xBA, 0x82, 0xF8, 0x8C, 0xE4, 0xCF, - 0xF3, 0xB3, 0x3D, 0x5D, 0x24, 0xE9, 0xC0, 0x83, - 0x11, 0x24, 0xBF, 0x1A, 0xD5, 0x4B, 0x79, 0x25, - 0x32, 0x98, 0x3D, 0xD6, 0xC3, 0xA8, 0xB7, 0xD0 - }, - .len = 16448 - }, - .validAuthLenInBits = { - .len = 16448 - }, - .validAuthOffsetLenInBits = { - .len = 128 - }, - .digest = { - .data = {0x17, 0x9F, 0x2F, 0xA6}, - .len = 4 - } -}; - -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_cryptodev_snow3g_test_vectors.h b/app/test/test_cryptodev_snow3g_test_vectors.h deleted file mode 100644 index 51917c14cb..0000000000 --- a/app/test/test_cryptodev_snow3g_test_vectors.h +++ /dev/null @@ -1,443 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015 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_SNOW3G_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_SNOW3G_TEST_VECTORS_H_ - -struct snow3g_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; - } validDataLenInBits; - - struct { - unsigned len; - } validCipherLenInBits; - - struct { - unsigned len; - } validCipherOffsetLenInBits; - - struct { - unsigned len; - } validAuthLenInBits; - - struct { - unsigned len; - } validAuthOffsetLenInBits; - - struct { - uint8_t data[64]; - unsigned len; - } aad; - - struct { - uint8_t data[64]; - unsigned len; - } digest; -}; -struct snow3g_test_data snow3g_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, - 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .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 = { - 0x8C, 0xEB, 0xA6, 0x29, 0x43, 0xDC, 0xED, 0x3A, - 0x09, 0x90, 0xB0, 0x6E, 0xA1, 0xB0, 0xA2, 0xC4, - 0xFB, 0x3C, 0xED, 0xC7, 0x1B, 0x36, 0x9F, 0x42, - 0xBA, 0x64, 0xC1, 0xEB, 0x66, 0x65, 0xE7, 0x2A, - 0xA1, 0xC9, 0xBB, 0x0D, 0xEA, 0xA2, 0x0F, 0xE8, - 0x60, 0x58, 0xB8, 0xBA, 0xEE, 0x2C, 0x2E, 0x7F, - 0x0B, 0xEC, 0xCE, 0x48, 0xB5, 0x29, 0x32, 0xA5, - 0x3C, 0x9D, 0x5F, 0x93, 0x1A, 0x3A, 0x7C, 0x53, - 0x22, 0x59, 0xAF, 0x43, 0x25, 0xE2, 0xA6, 0x5E, - 0x30, 0x84, 0xAD, 0x5F, 0x6A, 0x51, 0x3B, 0x7B, - 0xDD, 0xC1, 0xB6, 0x5F, 0x0A, 0xA0, 0xD9, 0x7A, - 0x05, 0x3D, 0xB5, 0x5A, 0x88, 0xC4, 0xC4, 0xF9, - 0x60, 0x5E, 0x41, 0x40 - }, - .len = 800 - }, - .validDataLenInBits = { - .len = 798 - }, - .validCipherLenInBits = { - .len = 800 - }, - .validCipherOffsetLenInBits = { - .len = 128 - }, - .aad = { - .data = { - 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00, - 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00 - }, - .len = 16 - } -}; - -struct snow3g_test_data snow3g_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, - 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .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 = { - 0xE0, 0xDA, 0x15, 0xCA, 0x8E, 0x25, 0x54, 0xF5, - 0xE5, 0x6C, 0x94, 0x68, 0xDC, 0x6C, 0x7C, 0x12, - 0x9C, 0x56, 0x8A, 0xA5, 0x03, 0x23, 0x17, 0xE0, - 0x4E, 0x07, 0x29, 0x64, 0x6C, 0xAB, 0xEF, 0xA6, - 0x89, 0x86, 0x4C, 0x41, 0x0F, 0x24, 0xF9, 0x19, - 0xE6, 0x1E, 0x3D, 0xFD, 0xFA, 0xD7, 0x7E, 0x56, - 0x0D, 0xB0, 0xA9, 0xCD, 0x36, 0xC3, 0x4A, 0xE4, - 0x18, 0x14, 0x90, 0xB2, 0x9F, 0x5F, 0xA2, 0xFC - }, - .len = 512 - }, - .validDataLenInBits = { - .len = 510 - }, - .validCipherLenInBits = { - .len = 512 - }, - .validCipherOffsetLenInBits = { - .len = 128 - }, - .aad = { - .data = { - 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00, - 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00 - }, - .len = 16 - } -}; - -struct snow3g_test_data snow3g_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, - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, - 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8 - }, - .len = 120 - }, - .ciphertext = { - .data = { - 0xBA, 0x0F, 0x31, 0x30, 0x03, 0x34, 0xC5, 0x6B, - 0x52, 0xA7, 0x49, 0x7C, 0xBA, 0xC0, 0x46 - }, - .len = 120 - }, - .validDataLenInBits = { - .len = 120 - }, - .validCipherLenInBits = { - .len = 120 - }, - .validCipherOffsetLenInBits = { - .len = 128 - }, - .aad = { - .data = { - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .digest = { - .data = {0xE8, 0x60, 0x5A, 0x3E}, - .len = 4 - }, - .validAuthLenInBits = { - .len = 120 - }, - .validAuthOffsetLenInBits = { - .len = 128 - } -}; - -struct snow3g_test_data snow3g_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, - 0x39, 0x8A, 0x59, 0xB4, 0x2C, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .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 = { - 0x98, 0x9B, 0x71, 0x9C, 0xDC, 0x33, 0xCE, 0xB7, - 0xCF, 0x27, 0x6A, 0x52, 0x82, 0x7C, 0xEF, 0x94, - 0xA5, 0x6C, 0x40, 0xC0, 0xAB, 0x9D, 0x81, 0xF7, - 0xA2, 0xA9, 0xBA, 0xC6, 0x0E, 0x11, 0xC4, 0xB0 - }, - .len = 256 - }, - .validDataLenInBits = { - .len = 253 - }, - .validCipherLenInBits = { - .len = 256 - }, - .validCipherOffsetLenInBits = { - .len = 128 - } -}; - -struct snow3g_test_data snow3g_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, - 0x72, 0xA4, 0xF2, 0x0F, 0x48, 0x00, 0x00, 0x00 - }, - .len = 16}, - .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 = { - 0x58, 0x92, 0xBB, 0xA8, 0x8B, 0xBB, 0xCA, 0xAE, - 0xAE, 0x76, 0x9A, 0xA0, 0x6B, 0x68, 0x3D, 0x3A, - 0x17, 0xCC, 0x04, 0xA3, 0x69, 0x88, 0x16, 0x97, - 0x43, 0x5E, 0x44, 0xFE, 0xD5, 0xFF, 0x9A, 0xF5, - 0x7B, 0x9E, 0x89, 0x0D, 0x4D, 0x5C, 0x64, 0x70, - 0x98, 0x85, 0xD4, 0x8A, 0xE4, 0x06, 0x90, 0xEC, - 0x04, 0x3B, 0xAA, 0xE9, 0x70, 0x57, 0x96, 0xE4, - 0xA9, 0xFF, 0x5A, 0x4B, 0x8D, 0x8B, 0x36, 0xD7, - 0xF3, 0xFE, 0x57, 0xCC, 0x6C, 0xFD, 0x6C, 0xD0, - 0x05, 0xCD, 0x38, 0x52, 0xA8, 0x5E, 0x94, 0xCE, - 0x6B, 0xCD, 0x90, 0xD0, 0xD0, 0x78, 0x39, 0xCE, - 0x09, 0x73, 0x35, 0x44, 0xCA, 0x8E, 0x35, 0x08, - 0x43, 0x24, 0x85, 0x50, 0x92, 0x2A, 0xC1, 0x28, - 0x18 - }, - .len = 840 - }, - .validDataLenInBits = { - .len = 837 - }, - .validCipherLenInBits = { - .len = 840 - }, - .validCipherOffsetLenInBits = { - .len = 128 - } -}; -struct snow3g_test_data snow3g_test_case_6 = { - .key = { - .data = { - 0xC7, 0x36, 0xC6, 0xAA, 0xB2, 0x2B, 0xFF, 0xF9, - 0x1E, 0x26, 0x98, 0xD2, 0xE2, 0x2A, 0xD5, 0x7E - }, - .len = 16 - }, - .iv = { - .data = { - 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, - 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD - }, - .len = 16 - }, - .aad = { - .data = { - 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, - 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD - }, - .len = 16 - }, - .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 - }, - .len = 384 - }, - .ciphertext = { - .data = { - 0x95, 0x2E, 0x5A, 0xE1, 0x50, 0xB8, 0x59, 0x2A, - 0x9B, 0xA0, 0x38, 0xA9, 0x8E, 0x2F, 0xED, 0xAB, - 0xFD, 0xC8, 0x3B, 0x47, 0x46, 0x0B, 0x50, 0x16, - 0xEC, 0x88, 0x45, 0xB6, 0x05, 0xC7, 0x54, 0xF8, - 0xBD, 0x91, 0xAA, 0xB6, 0xA4, 0xDC, 0x64, 0xB4, - 0xCB, 0xEB, 0x97, 0x06, 0x4C, 0xF7, 0x02, 0x3D - }, - .len = 384 - }, - .digest = { - .data = {0x38, 0xB5, 0x54, 0xC0 }, - .len = 4 - }, - .validDataLenInBits = { - .len = 384 - }, - .validCipherLenInBits = { - .len = 384 - }, - .validCipherOffsetLenInBits = { - .len = 128 - }, - .validAuthLenInBits = { - .len = 384 - }, - .validAuthOffsetLenInBits = { - .len = 128 - } -}; - -#endif /* TEST_CRYPTODEV_SNOW3G_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_zuc_hash_test_vectors.h b/app/test/test_cryptodev_zuc_hash_test_vectors.h deleted file mode 100644 index 988452cbbd..0000000000 --- a/app/test/test_cryptodev_zuc_hash_test_vectors.h +++ /dev/null @@ -1,359 +0,0 @@ -/*- - * 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_ZUC_HASH_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_ZUC_HASH_TEST_VECTORS_H_ - -struct zuc_hash_test_data { - struct { - uint8_t data[64]; - unsigned len; - } key; - - struct { - uint8_t data[64]; - unsigned len; - } aad; - - struct { - uint8_t data[2056]; - unsigned len; /* length must be in Bits */ - } plaintext; - - struct { - unsigned len; - } validAuthLenInBits; - - struct { - unsigned len; - } validAuthOffsetLenInBits; - - struct { - uint8_t data[64]; - unsigned len; - } digest; -}; - -struct zuc_hash_test_data zuc_hash_test_case_1 = { - .key = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .aad = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = {0x00}, - .len = 8 - }, - .validAuthLenInBits = { - .len = 1 - }, - .validAuthOffsetLenInBits = { - .len = 128 - }, - .digest = { - .data = {0xC8, 0xA9, 0x59, 0x5E}, - .len = 4 - } -}; - -struct zuc_hash_test_data zuc_hash_test_case_2 = { - .key = { - .data = { - 0x47, 0x05, 0x41, 0x25, 0x56, 0x1E, 0xB2, 0xDD, - 0xA9, 0x40, 0x59, 0xDA, 0x05, 0x09, 0x78, 0x50 - }, - .len = 16 - }, - .aad = { - .data = { - 0x56, 0x1E, 0xB2, 0xDD, 0xA0, 0x00, 0x00, 0x00, - 0x56, 0x1E, 0xB2, 0xDD, 0xA0, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }, - .len = 96 - }, - .validAuthLenInBits = { - .len = 90 - }, - .validAuthOffsetLenInBits = { - .len = 128 - }, - .digest = { - .data = {0x67, 0x19, 0xA0, 0x88}, - .len = 4 - } -}; - -struct zuc_hash_test_data zuc_hash_test_case_3 = { - .key = { - .data = { - 0xC9, 0xE6, 0xCE, 0xC4, 0x60, 0x7C, 0x72, 0xDB, - 0x00, 0x0A, 0xEF, 0xA8, 0x83, 0x85, 0xAB, 0x0A - }, - .len = 16 - }, - .aad = { - .data = { - 0xA9, 0x40, 0x59, 0xDA, 0x50, 0x00, 0x00, 0x00, - 0x29, 0x40, 0x59, 0xDA, 0x50, 0x00, 0x80, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x98, 0x3B, 0x41, 0xD4, 0x7D, 0x78, 0x0C, 0x9E, - 0x1A, 0xD1, 0x1D, 0x7E, 0xB7, 0x03, 0x91, 0xB1, - 0xDE, 0x0B, 0x35, 0xDA, 0x2D, 0xC6, 0x2F, 0x83, - 0xE7, 0xB7, 0x8D, 0x63, 0x06, 0xCA, 0x0E, 0xA0, - 0x7E, 0x94, 0x1B, 0x7B, 0xE9, 0x13, 0x48, 0xF9, - 0xFC, 0xB1, 0x70, 0xE2, 0x21, 0x7F, 0xEC, 0xD9, - 0x7F, 0x9F, 0x68, 0xAD, 0xB1, 0x6E, 0x5D, 0x7D, - 0x21, 0xE5, 0x69, 0xD2, 0x80, 0xED, 0x77, 0x5C, - 0xEB, 0xDE, 0x3F, 0x40, 0x93, 0xC5, 0x38, 0x81, - 0x00 - }, - .len = 584 - }, - .validAuthLenInBits = { - .len = 577 - }, - .validAuthOffsetLenInBits = { - .len = 128 - }, - .digest = { - .data = {0xFA, 0xE8, 0xFF, 0x0B}, - .len = 4 - } -}; - -struct zuc_hash_test_data zuc_hash_test_case_4 = { - .key = { - .data = { - 0xC8, 0xA4, 0x82, 0x62, 0xD0, 0xC2, 0xE2, 0xBA, - 0xC4, 0xB9, 0x6E, 0xF7, 0x7E, 0x80, 0xCA, 0x59 - }, - .len = 16 - }, - .aad = { - .data = { - 0x05, 0x09, 0x78, 0x50, 0x80, 0x00, 0x00, 0x00, - 0x85, 0x09, 0x78, 0x50, 0x80, 0x00, 0x80, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0xB5, 0x46, 0x43, 0x0B, 0xF8, 0x7B, 0x4F, 0x1E, - 0xE8, 0x34, 0x70, 0x4C, 0xD6, 0x95, 0x1C, 0x36, - 0xE2, 0x6F, 0x10, 0x8C, 0xF7, 0x31, 0x78, 0x8F, - 0x48, 0xDC, 0x34, 0xF1, 0x67, 0x8C, 0x05, 0x22, - 0x1C, 0x8F, 0xA7, 0xFF, 0x2F, 0x39, 0xF4, 0x77, - 0xE7, 0xE4, 0x9E, 0xF6, 0x0A, 0x4E, 0xC2, 0xC3, - 0xDE, 0x24, 0x31, 0x2A, 0x96, 0xAA, 0x26, 0xE1, - 0xCF, 0xBA, 0x57, 0x56, 0x38, 0x38, 0xB2, 0x97, - 0xF4, 0x7E, 0x85, 0x10, 0xC7, 0x79, 0xFD, 0x66, - 0x54, 0xB1, 0x43, 0x38, 0x6F, 0xA6, 0x39, 0xD3, - 0x1E, 0xDB, 0xD6, 0xC0, 0x6E, 0x47, 0xD1, 0x59, - 0xD9, 0x43, 0x62, 0xF2, 0x6A, 0xEE, 0xED, 0xEE, - 0x0E, 0x4F, 0x49, 0xD9, 0xBF, 0x84, 0x12, 0x99, - 0x54, 0x15, 0xBF, 0xAD, 0x56, 0xEE, 0x82, 0xD1, - 0xCA, 0x74, 0x63, 0xAB, 0xF0, 0x85, 0xB0, 0x82, - 0xB0, 0x99, 0x04, 0xD6, 0xD9, 0x90, 0xD4, 0x3C, - 0xF2, 0xE0, 0x62, 0xF4, 0x08, 0x39, 0xD9, 0x32, - 0x48, 0xB1, 0xEB, 0x92, 0xCD, 0xFE, 0xD5, 0x30, - 0x0B, 0xC1, 0x48, 0x28, 0x04, 0x30, 0xB6, 0xD0, - 0xCA, 0xA0, 0x94, 0xB6, 0xEC, 0x89, 0x11, 0xAB, - 0x7D, 0xC3, 0x68, 0x24, 0xB8, 0x24, 0xDC, 0x0A, - 0xF6, 0x68, 0x2B, 0x09, 0x35, 0xFD, 0xE7, 0xB4, - 0x92, 0xA1, 0x4D, 0xC2, 0xF4, 0x36, 0x48, 0x03, - 0x8D, 0xA2, 0xCF, 0x79, 0x17, 0x0D, 0x2D, 0x50, - 0x13, 0x3F, 0xD4, 0x94, 0x16, 0xCB, 0x6E, 0x33, - 0xBE, 0xA9, 0x0B, 0x8B, 0xF4, 0x55, 0x9B, 0x03, - 0x73, 0x2A, 0x01, 0xEA, 0x29, 0x0E, 0x6D, 0x07, - 0x4F, 0x79, 0xBB, 0x83, 0xC1, 0x0E, 0x58, 0x00, - 0x15, 0xCC, 0x1A, 0x85, 0xB3, 0x6B, 0x55, 0x01, - 0x04, 0x6E, 0x9C, 0x4B, 0xDC, 0xAE, 0x51, 0x35, - 0x69, 0x0B, 0x86, 0x66, 0xBD, 0x54, 0xB7, 0xA7, - 0x03, 0xEA, 0x7B, 0x6F, 0x22, 0x0A, 0x54, 0x69, - 0xA5, 0x68, 0x02, 0x7E - }, - .len = 2080 - }, - .validAuthLenInBits = { - .len = 2079 - }, - .validAuthOffsetLenInBits = { - .len = 128 - }, - .digest = { - .data = {0x00, 0x4A, 0xC4, 0xD6}, - .len = 4 - } -}; - -struct zuc_hash_test_data zuc_hash_test_case_5 = { - .key = { - .data = { - 0x6B, 0x8B, 0x08, 0xEE, 0x79, 0xE0, 0xB5, 0x98, - 0x2D, 0x6D, 0x12, 0x8E, 0xA9, 0xF2, 0x20, 0xCB - }, - .len = 16 - }, - .aad = { - .data = { - 0x56, 0x1E, 0xB2, 0xDD, 0xE0, 0x00, 0x00, 0x00, - 0x56, 0x1E, 0xB2, 0xDD, 0xE0, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x5B, 0xAD, 0x72, 0x47, 0x10, 0xBA, 0x1C, 0x56, - 0xD5, 0xA3, 0x15, 0xF8, 0xD4, 0x0F, 0x6E, 0x09, - 0x37, 0x80, 0xBE, 0x8E, 0x8D, 0xE0, 0x7B, 0x69, - 0x92, 0x43, 0x20, 0x18, 0xE0, 0x8E, 0xD9, 0x6A, - 0x57, 0x34, 0xAF, 0x8B, 0xAD, 0x8A, 0x57, 0x5D, - 0x3A, 0x1F, 0x16, 0x2F, 0x85, 0x04, 0x5C, 0xC7, - 0x70, 0x92, 0x55, 0x71, 0xD9, 0xF5, 0xB9, 0x4E, - 0x45, 0x4A, 0x77, 0xC1, 0x6E, 0x72, 0x93, 0x6B, - 0xF0, 0x16, 0xAE, 0x15, 0x74, 0x99, 0xF0, 0x54, - 0x3B, 0x5D, 0x52, 0xCA, 0xA6, 0xDB, 0xEA, 0xB6, - 0x97, 0xD2, 0xBB, 0x73, 0xE4, 0x1B, 0x80, 0x75, - 0xDC, 0xE7, 0x9B, 0x4B, 0x86, 0x04, 0x4F, 0x66, - 0x1D, 0x44, 0x85, 0xA5, 0x43, 0xDD, 0x78, 0x60, - 0x6E, 0x04, 0x19, 0xE8, 0x05, 0x98, 0x59, 0xD3, - 0xCB, 0x2B, 0x67, 0xCE, 0x09, 0x77, 0x60, 0x3F, - 0x81, 0xFF, 0x83, 0x9E, 0x33, 0x18, 0x59, 0x54, - 0x4C, 0xFB, 0xC8, 0xD0, 0x0F, 0xEF, 0x1A, 0x4C, - 0x85, 0x10, 0xFB, 0x54, 0x7D, 0x6B, 0x06, 0xC6, - 0x11, 0xEF, 0x44, 0xF1, 0xBC, 0xE1, 0x07, 0xCF, - 0xA4, 0x5A, 0x06, 0xAA, 0xB3, 0x60, 0x15, 0x2B, - 0x28, 0xDC, 0x1E, 0xBE, 0x6F, 0x7F, 0xE0, 0x9B, - 0x05, 0x16, 0xF9, 0xA5, 0xB0, 0x2A, 0x1B, 0xD8, - 0x4B, 0xB0, 0x18, 0x1E, 0x2E, 0x89, 0xE1, 0x9B, - 0xD8, 0x12, 0x59, 0x30, 0xD1, 0x78, 0x68, 0x2F, - 0x38, 0x62, 0xDC, 0x51, 0xB6, 0x36, 0xF0, 0x4E, - 0x72, 0x0C, 0x47, 0xC3, 0xCE, 0x51, 0xAD, 0x70, - 0xD9, 0x4B, 0x9B, 0x22, 0x55, 0xFB, 0xAE, 0x90, - 0x65, 0x49, 0xF4, 0x99, 0xF8, 0xC6, 0xD3, 0x99, - 0x47, 0xED, 0x5E, 0x5D, 0xF8, 0xE2, 0xDE, 0xF1, - 0x13, 0x25, 0x3E, 0x7B, 0x08, 0xD0, 0xA7, 0x6B, - 0x6B, 0xFC, 0x68, 0xC8, 0x12, 0xF3, 0x75, 0xC7, - 0x9B, 0x8F, 0xE5, 0xFD, 0x85, 0x97, 0x6A, 0xA6, - 0xD4, 0x6B, 0x4A, 0x23, 0x39, 0xD8, 0xAE, 0x51, - 0x47, 0xF6, 0x80, 0xFB, 0xE7, 0x0F, 0x97, 0x8B, - 0x38, 0xEF, 0xFD, 0x7B, 0x2F, 0x78, 0x66, 0xA2, - 0x25, 0x54, 0xE1, 0x93, 0xA9, 0x4E, 0x98, 0xA6, - 0x8B, 0x74, 0xBD, 0x25, 0xBB, 0x2B, 0x3F, 0x5F, - 0xB0, 0xA5, 0xFD, 0x59, 0x88, 0x7F, 0x9A, 0xB6, - 0x81, 0x59, 0xB7, 0x17, 0x8D, 0x5B, 0x7B, 0x67, - 0x7C, 0xB5, 0x46, 0xBF, 0x41, 0xEA, 0xDC, 0xA2, - 0x16, 0xFC, 0x10, 0x85, 0x01, 0x28, 0xF8, 0xBD, - 0xEF, 0x5C, 0x8D, 0x89, 0xF9, 0x6A, 0xFA, 0x4F, - 0xA8, 0xB5, 0x48, 0x85, 0x56, 0x5E, 0xD8, 0x38, - 0xA9, 0x50, 0xFE, 0xE5, 0xF1, 0xC3, 0xB0, 0xA4, - 0xF6, 0xFB, 0x71, 0xE5, 0x4D, 0xFD, 0x16, 0x9E, - 0x82, 0xCE, 0xCC, 0x72, 0x66, 0xC8, 0x50, 0xE6, - 0x7C, 0x5E, 0xF0, 0xBA, 0x96, 0x0F, 0x52, 0x14, - 0x06, 0x0E, 0x71, 0xEB, 0x17, 0x2A, 0x75, 0xFC, - 0x14, 0x86, 0x83, 0x5C, 0xBE, 0xA6, 0x53, 0x44, - 0x65, 0xB0, 0x55, 0xC9, 0x6A, 0x72, 0xE4, 0x10, - 0x52, 0x24, 0x18, 0x23, 0x25, 0xD8, 0x30, 0x41, - 0x4B, 0x40, 0x21, 0x4D, 0xAA, 0x80, 0x91, 0xD2, - 0xE0, 0xFB, 0x01, 0x0A, 0xE1, 0x5C, 0x6D, 0xE9, - 0x08, 0x50, 0x97, 0x3B, 0xDF, 0x1E, 0x42, 0x3B, - 0xE1, 0x48, 0xA2, 0x37, 0xB8, 0x7A, 0x0C, 0x9F, - 0x34, 0xD4, 0xB4, 0x76, 0x05, 0xB8, 0x03, 0xD7, - 0x43, 0xA8, 0x6A, 0x90, 0x39, 0x9A, 0x4A, 0xF3, - 0x96, 0xD3, 0xA1, 0x20, 0x0A, 0x62, 0xF3, 0xD9, - 0x50, 0x79, 0x62, 0xE8, 0xE5, 0xBE, 0xE6, 0xD3, - 0xDA, 0x2B, 0xB3, 0xF7, 0x23, 0x76, 0x64, 0xAC, - 0x7A, 0x29, 0x28, 0x23, 0x90, 0x0B, 0xC6, 0x35, - 0x03, 0xB2, 0x9E, 0x80, 0xD6, 0x3F, 0x60, 0x67, - 0xBF, 0x8E, 0x17, 0x16, 0xAC, 0x25, 0xBE, 0xBA, - 0x35, 0x0D, 0xEB, 0x62, 0xA9, 0x9F, 0xE0, 0x31, - 0x85, 0xEB, 0x4F, 0x69, 0x93, 0x7E, 0xCD, 0x38, - 0x79, 0x41, 0xFD, 0xA5, 0x44, 0xBA, 0x67, 0xDB, - 0x09, 0x11, 0x77, 0x49, 0x38, 0xB0, 0x18, 0x27, - 0xBC, 0xC6, 0x9C, 0x92, 0xB3, 0xF7, 0x72, 0xA9, - 0xD2, 0x85, 0x9E, 0xF0, 0x03, 0x39, 0x8B, 0x1F, - 0x6B, 0xBA, 0xD7, 0xB5, 0x74, 0xF7, 0x98, 0x9A, - 0x1D, 0x10, 0xB2, 0xDF, 0x79, 0x8E, 0x0D, 0xBF, - 0x30, 0xD6, 0x58, 0x74, 0x64, 0xD2, 0x48, 0x78, - 0xCD, 0x00, 0xC0, 0xEA, 0xEE, 0x8A, 0x1A, 0x0C, - 0xC7, 0x53, 0xA2, 0x79, 0x79, 0xE1, 0x1B, 0x41, - 0xDB, 0x1D, 0xE3, 0xD5, 0x03, 0x8A, 0xFA, 0xF4, - 0x9F, 0x5C, 0x68, 0x2C, 0x37, 0x48, 0xD8, 0xA3, - 0xA9, 0xEC, 0x54, 0xE6, 0xA3, 0x71, 0x27, 0x5F, - 0x16, 0x83, 0x51, 0x0F, 0x8E, 0x4F, 0x90, 0x93, - 0x8F, 0x9A, 0xB6, 0xE1, 0x34, 0xC2, 0xCF, 0xDF, - 0x48, 0x41, 0xCB, 0xA8, 0x8E, 0x0C, 0xFF, 0x2B, - 0x0B, 0xCC, 0x8E, 0x6A, 0xDC, 0xB7, 0x11, 0x09, - 0xB5, 0x19, 0x8F, 0xEC, 0xF1, 0xBB, 0x7E, 0x5C, - 0x53, 0x1A, 0xCA, 0x50, 0xA5, 0x6A, 0x8A, 0x3B, - 0x6D, 0xE5, 0x98, 0x62, 0xD4, 0x1F, 0xA1, 0x13, - 0xD9, 0xCD, 0x95, 0x78, 0x08, 0xF0, 0x85, 0x71, - 0xD9, 0xA4, 0xBB, 0x79, 0x2A, 0xF2, 0x71, 0xF6, - 0xCC, 0x6D, 0xBB, 0x8D, 0xC7, 0xEC, 0x36, 0xE3, - 0x6B, 0xE1, 0xED, 0x30, 0x81, 0x64, 0xC3, 0x1C, - 0x7C, 0x0A, 0xFC, 0x54, 0x1C - }, - .len = 5672 - }, - .validAuthLenInBits = { - .len = 5670 - }, - .validAuthOffsetLenInBits = { - .len = 128 - }, - .digest = { - .data = {0x0C, 0xA1, 0x27, 0x92}, - .len = 4 - } -}; - -#endif /* TEST_CRYPTODEV_ZUC_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_zuc_test_vectors.h b/app/test/test_cryptodev_zuc_test_vectors.h deleted file mode 100644 index 03a3d1f459..0000000000 --- a/app/test/test_cryptodev_zuc_test_vectors.h +++ /dev/null @@ -1,582 +0,0 @@ -/*- - * 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_ZUC_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ - -struct zuc_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; - } validDataLenInBits; - - struct { - unsigned len; - } validCipherLenInBits; - - struct { - unsigned len; - } validCipherOffsetLenInBits; - - struct { - unsigned len; - } validAuthLenInBits; - - struct { - unsigned len; - } validAuthOffsetLenInBits; - - struct { - uint8_t data[64]; - unsigned len; - } aad; - - struct { - uint8_t data[64]; - unsigned len; - } digest; -}; -struct zuc_test_data zuc_test_case_1 = { - .key = { - .data = { - 0x17, 0x3D, 0x14, 0xBA, 0x50, 0x03, 0x73, 0x1D, - 0x7A, 0x60, 0x04, 0x94, 0x70, 0xF0, 0x0A, 0x29 - }, - .len = 16 - }, - .iv = { - .data = { - 0x66, 0x03, 0x54, 0x92, 0x78, 0x00, 0x00, 0x00, - 0x66, 0x03, 0x54, 0x92, 0x78, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6C, 0xF6, 0x53, 0x40, 0x73, 0x55, 0x52, 0xAB, - 0x0C, 0x97, 0x52, 0xFA, 0x6F, 0x90, 0x25, 0xFE, - 0x0B, 0xD6, 0x75, 0xD9, 0x00, 0x58, 0x75, 0xB2, - 0x00 - }, - .len = 200 - }, - .ciphertext = { - .data = { - 0xA6, 0xC8, 0x5F, 0xC6, 0x6A, 0xFB, 0x85, 0x33, - 0xAA, 0xFC, 0x25, 0x18, 0xDF, 0xE7, 0x84, 0x94, - 0x0E, 0xE1, 0xE4, 0xB0, 0x30, 0x23, 0x8C, 0xC8, - 0x00 - }, - .len = 200 - }, - .validDataLenInBits = { - .len = 193 - }, - .validCipherLenInBits = { - .len = 193 - }, - .validCipherOffsetLenInBits = { - .len = 128 - } -}; - -struct zuc_test_data zuc_test_case_2 = { - .key = { - .data = { - 0xE5, 0xBD, 0x3E, 0xA0, 0xEB, 0x55, 0xAD, 0xE8, - 0x66, 0xC6, 0xAC, 0x58, 0xBD, 0x54, 0x30, 0x2A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x05, 0x68, 0x23, 0xC4, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x68, 0x23, 0xC4, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x14, 0xA8, 0xEF, 0x69, 0x3D, 0x67, 0x85, 0x07, - 0xBB, 0xE7, 0x27, 0x0A, 0x7F, 0x67, 0xFF, 0x50, - 0x06, 0xC3, 0x52, 0x5B, 0x98, 0x07, 0xE4, 0x67, - 0xC4, 0xE5, 0x60, 0x00, 0xBA, 0x33, 0x8F, 0x5D, - 0x42, 0x95, 0x59, 0x03, 0x67, 0x51, 0x82, 0x22, - 0x46, 0xC8, 0x0D, 0x3B, 0x38, 0xF0, 0x7F, 0x4B, - 0xE2, 0xD8, 0xFF, 0x58, 0x05, 0xF5, 0x13, 0x22, - 0x29, 0xBD, 0xE9, 0x3B, 0xBB, 0xDC, 0xAF, 0x38, - 0x2B, 0xF1, 0xEE, 0x97, 0x2F, 0xBF, 0x99, 0x77, - 0xBA, 0xDA, 0x89, 0x45, 0x84, 0x7A, 0x2A, 0x6C, - 0x9A, 0xD3, 0x4A, 0x66, 0x75, 0x54, 0xE0, 0x4D, - 0x1F, 0x7F, 0xA2, 0xC3, 0x32, 0x41, 0xBD, 0x8F, - 0x01, 0xBA, 0x22, 0x0D - }, - .len = 800 - }, - .ciphertext = { - .data = { - 0x13, 0x1D, 0x43, 0xE0, 0xDE, 0xA1, 0xBE, 0x5C, - 0x5A, 0x1B, 0xFD, 0x97, 0x1D, 0x85, 0x2C, 0xBF, - 0x71, 0x2D, 0x7B, 0x4F, 0x57, 0x96, 0x1F, 0xEA, - 0x32, 0x08, 0xAF, 0xA8, 0xBC, 0xA4, 0x33, 0xF4, - 0x56, 0xAD, 0x09, 0xC7, 0x41, 0x7E, 0x58, 0xBC, - 0x69, 0xCF, 0x88, 0x66, 0xD1, 0x35, 0x3F, 0x74, - 0x86, 0x5E, 0x80, 0x78, 0x1D, 0x20, 0x2D, 0xFB, - 0x3E, 0xCF, 0xF7, 0xFC, 0xBC, 0x3B, 0x19, 0x0F, - 0xE8, 0x2A, 0x20, 0x4E, 0xD0, 0xE3, 0x50, 0xFC, - 0x0F, 0x6F, 0x26, 0x13, 0xB2, 0xF2, 0xBC, 0xA6, - 0xDF, 0x5A, 0x47, 0x3A, 0x57, 0xA4, 0xA0, 0x0D, - 0x98, 0x5E, 0xBA, 0xD8, 0x80, 0xD6, 0xF2, 0x38, - 0x64, 0xA0, 0x7B, 0x01 - }, - .len = 800 - }, - .validDataLenInBits = { - .len = 800 - }, - .validCipherLenInBits = { - .len = 800 - }, - .validCipherOffsetLenInBits = { - .len = 128 - } -}; - -struct zuc_test_data zuc_test_case_3 = { - .key = { - .data = { - 0xD4, 0x55, 0x2A, 0x8F, 0xD6, 0xE6, 0x1C, 0xC8, - 0x1A, 0x20, 0x09, 0x14, 0x1A, 0x29, 0xC1, 0x0B - }, - .len = 16 - }, - .iv = { - .data = { - 0x76, 0x45, 0x2E, 0xC1, 0x14, 0x00, 0x00, 0x00, - 0x76, 0x45, 0x2E, 0xC1, 0x14, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x38, 0xF0, 0x7F, 0x4B, 0xE2, 0xD8, 0xFF, 0x58, - 0x05, 0xF5, 0x13, 0x22, 0x29, 0xBD, 0xE9, 0x3B, - 0xBB, 0xDC, 0xAF, 0x38, 0x2B, 0xF1, 0xEE, 0x97, - 0x2F, 0xBF, 0x99, 0x77, 0xBA, 0xDA, 0x89, 0x45, - 0x84, 0x7A, 0x2A, 0x6C, 0x9A, 0xD3, 0x4A, 0x66, - 0x75, 0x54, 0xE0, 0x4D, 0x1F, 0x7F, 0xA2, 0xC3, - 0x32, 0x41, 0xBD, 0x8F, 0x01, 0xBA, 0x22, 0x0D, - 0x3C, 0xA4, 0xEC, 0x41, 0xE0, 0x74, 0x59, 0x5F, - 0x54, 0xAE, 0x2B, 0x45, 0x4F, 0xD9, 0x71, 0x43, - 0x20, 0x43, 0x60, 0x19, 0x65, 0xCC, 0xA8, 0x5C, - 0x24, 0x17, 0xED, 0x6C, 0xBE, 0xC3, 0xBA, 0xDA, - 0x84, 0xFC, 0x8A, 0x57, 0x9A, 0xEA, 0x78, 0x37, - 0xB0, 0x27, 0x11, 0x77, 0x24, 0x2A, 0x64, 0xDC, - 0x0A, 0x9D, 0xE7, 0x1A, 0x8E, 0xDE, 0xE8, 0x6C, - 0xA3, 0xD4, 0x7D, 0x03, 0x3D, 0x6B, 0xF5, 0x39, - 0x80, 0x4E, 0xCA, 0x86, 0xC5, 0x84, 0xA9, 0x05, - 0x2D, 0xE4, 0x6A, 0xD3, 0xFC, 0xED, 0x65, 0x54, - 0x3B, 0xD9, 0x02, 0x07, 0x37, 0x2B, 0x27, 0xAF, - 0xB7, 0x92, 0x34, 0xF5, 0xFF, 0x43, 0xEA, 0x87, - 0x08, 0x20, 0xE2, 0xC2, 0xB7, 0x8A, 0x8A, 0xAE, - 0x61, 0xCC, 0xE5, 0x2A, 0x05, 0x15, 0xE3, 0x48, - 0xD1, 0x96, 0x66, 0x4A, 0x34, 0x56, 0xB1, 0x82, - 0xA0, 0x7C, 0x40, 0x6E, 0x4A, 0x20, 0x79, 0x12, - 0x71, 0xCF, 0xED, 0xA1, 0x65, 0xD5, 0x35, 0xEC, - 0x5E, 0xA2, 0xD4, 0xDF, 0x40 - }, - .len = 1576 - }, - .ciphertext = { - .data = { - 0x83, 0x83, 0xB0, 0x22, 0x9F, 0xCC, 0x0B, 0x9D, - 0x22, 0x95, 0xEC, 0x41, 0xC9, 0x77, 0xE9, 0xC2, - 0xBB, 0x72, 0xE2, 0x20, 0x37, 0x81, 0x41, 0xF9, - 0xC8, 0x31, 0x8F, 0x3A, 0x27, 0x0D, 0xFB, 0xCD, - 0xEE, 0x64, 0x11, 0xC2, 0xB3, 0x04, 0x4F, 0x17, - 0x6D, 0xC6, 0xE0, 0x0F, 0x89, 0x60, 0xF9, 0x7A, - 0xFA, 0xCD, 0x13, 0x1A, 0xD6, 0xA3, 0xB4, 0x9B, - 0x16, 0xB7, 0xBA, 0xBC, 0xF2, 0xA5, 0x09, 0xEB, - 0xB1, 0x6A, 0x75, 0xDC, 0xAB, 0x14, 0xFF, 0x27, - 0x5D, 0xBE, 0xEE, 0xA1, 0xA2, 0xB1, 0x55, 0xF9, - 0xD5, 0x2C, 0x26, 0x45, 0x2D, 0x01, 0x87, 0xC3, - 0x10, 0xA4, 0xEE, 0x55, 0xBE, 0xAA, 0x78, 0xAB, - 0x40, 0x24, 0x61, 0x5B, 0xA9, 0xF5, 0xD5, 0xAD, - 0xC7, 0x72, 0x8F, 0x73, 0x56, 0x06, 0x71, 0xF0, - 0x13, 0xE5, 0xE5, 0x50, 0x08, 0x5D, 0x32, 0x91, - 0xDF, 0x7D, 0x5F, 0xEC, 0xED, 0xDE, 0xD5, 0x59, - 0x64, 0x1B, 0x6C, 0x2F, 0x58, 0x52, 0x33, 0xBC, - 0x71, 0xE9, 0x60, 0x2B, 0xD2, 0x30, 0x58, 0x55, - 0xBB, 0xD2, 0x5F, 0xFA, 0x7F, 0x17, 0xEC, 0xBC, - 0x04, 0x2D, 0xAA, 0xE3, 0x8C, 0x1F, 0x57, 0xAD, - 0x8E, 0x8E, 0xBD, 0x37, 0x34, 0x6F, 0x71, 0xBE, - 0xFD, 0xBB, 0x74, 0x32, 0xE0, 0xE0, 0xBB, 0x2C, - 0xFC, 0x09, 0xBC, 0xD9, 0x65, 0x70, 0xCB, 0x0C, - 0x0C, 0x39, 0xDF, 0x5E, 0x29, 0x29, 0x4E, 0x82, - 0x70, 0x3A, 0x63, 0x7F, 0x80 - }, - .len = 1576 - }, - .validDataLenInBits = { - .len = 1570 - }, - .validCipherLenInBits = { - .len = 1570 - }, - .validCipherOffsetLenInBits = { - .len = 128 - }, - .aad = { - .data = { - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .digest = { - .data = {0xE8, 0x60, 0x5A, 0x3E}, - .len = 4 - }, - .validAuthLenInBits = { - .len = 120 - }, - .validAuthOffsetLenInBits = { - .len = 128 - } -}; - -struct zuc_test_data zuc_test_case_4 = { - .key = { - .data = { - 0xDB, 0x84, 0xB4, 0xFB, 0xCC, 0xDA, 0x56, 0x3B, - 0x66, 0x22, 0x7B, 0xFE, 0x45, 0x6F, 0x0F, 0x77 - }, - .len = 16 - }, - .iv = { - .data = { - 0xE4, 0x85, 0x0F, 0xE1, 0x84, 0x00, 0x00, 0x00, - 0xE4, 0x85, 0x0F, 0xE1, 0x84, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0xE5, 0x39, 0xF3, 0xB8, 0x97, 0x32, 0x40, 0xDA, - 0x03, 0xF2, 0xB8, 0xAA, 0x05, 0xEE, 0x0A, 0x00, - 0xDB, 0xAF, 0xC0, 0xE1, 0x82, 0x05, 0x5D, 0xFE, - 0x3D, 0x73, 0x83, 0xD9, 0x2C, 0xEF, 0x40, 0xE9, - 0x29, 0x28, 0x60, 0x5D, 0x52, 0xD0, 0x5F, 0x4F, - 0x90, 0x18, 0xA1, 0xF1, 0x89, 0xAE, 0x39, 0x97, - 0xCE, 0x19, 0x15, 0x5F, 0xB1, 0x22, 0x1D, 0xB8, - 0xBB, 0x09, 0x51, 0xA8, 0x53, 0xAD, 0x85, 0x2C, - 0xE1, 0x6C, 0xFF, 0x07, 0x38, 0x2C, 0x93, 0xA1, - 0x57, 0xDE, 0x00, 0xDD, 0xB1, 0x25, 0xC7, 0x53, - 0x9F, 0xD8, 0x50, 0x45, 0xE4, 0xEE, 0x07, 0xE0, - 0xC4, 0x3F, 0x9E, 0x9D, 0x6F, 0x41, 0x4F, 0xC4, - 0xD1, 0xC6, 0x29, 0x17, 0x81, 0x3F, 0x74, 0xC0, - 0x0F, 0xC8, 0x3F, 0x3E, 0x2E, 0xD7, 0xC4, 0x5B, - 0xA5, 0x83, 0x52, 0x64, 0xB4, 0x3E, 0x0B, 0x20, - 0xAF, 0xDA, 0x6B, 0x30, 0x53, 0xBF, 0xB6, 0x42, - 0x3B, 0x7F, 0xCE, 0x25, 0x47, 0x9F, 0xF5, 0xF1, - 0x39, 0xDD, 0x9B, 0x5B, 0x99, 0x55, 0x58, 0xE2, - 0xA5, 0x6B, 0xE1, 0x8D, 0xD5, 0x81, 0xCD, 0x01, - 0x7C, 0x73, 0x5E, 0x6F, 0x0D, 0x0D, 0x97, 0xC4, - 0xDD, 0xC1, 0xD1, 0xDA, 0x70, 0xC6, 0xDB, 0x4A, - 0x12, 0xCC, 0x92, 0x77, 0x8E, 0x2F, 0xBB, 0xD6, - 0xF3, 0xBA, 0x52, 0xAF, 0x91, 0xC9, 0xC6, 0xB6, - 0x4E, 0x8D, 0xA4, 0xF7, 0xA2, 0xC2, 0x66, 0xD0, - 0x2D, 0x00, 0x17, 0x53, 0xDF, 0x08, 0x96, 0x03, - 0x93, 0xC5, 0xD5, 0x68, 0x88, 0xBF, 0x49, 0xEB, - 0x5C, 0x16, 0xD9, 0xA8, 0x04, 0x27, 0xA4, 0x16, - 0xBC, 0xB5, 0x97, 0xDF, 0x5B, 0xFE, 0x6F, 0x13, - 0x89, 0x0A, 0x07, 0xEE, 0x13, 0x40, 0xE6, 0x47, - 0x6B, 0x0D, 0x9A, 0xA8, 0xF8, 0x22, 0xAB, 0x0F, - 0xD1, 0xAB, 0x0D, 0x20, 0x4F, 0x40, 0xB7, 0xCE, - 0x6F, 0x2E, 0x13, 0x6E, 0xB6, 0x74, 0x85, 0xE5, - 0x07, 0x80, 0x4D, 0x50, 0x45, 0x88, 0xAD, 0x37, - 0xFF, 0xD8, 0x16, 0x56, 0x8B, 0x2D, 0xC4, 0x03, - 0x11, 0xDF, 0xB6, 0x54, 0xCD, 0xEA, 0xD4, 0x7E, - 0x23, 0x85, 0xC3, 0x43, 0x62, 0x03, 0xDD, 0x83, - 0x6F, 0x9C, 0x64, 0xD9, 0x74, 0x62, 0xAD, 0x5D, - 0xFA, 0x63, 0xB5, 0xCF, 0xE0, 0x8A, 0xCB, 0x95, - 0x32, 0x86, 0x6F, 0x5C, 0xA7, 0x87, 0x56, 0x6F, - 0xCA, 0x93, 0xE6, 0xB1, 0x69, 0x3E, 0xE1, 0x5C, - 0xF6, 0xF7, 0xA2, 0xD6, 0x89, 0xD9, 0x74, 0x17, - 0x98, 0xDC, 0x1C, 0x23, 0x8E, 0x1B, 0xE6, 0x50, - 0x73, 0x3B, 0x18, 0xFB, 0x34, 0xFF, 0x88, 0x0E, - 0x16, 0xBB, 0xD2, 0x1B, 0x47, 0xAC - }, - .len = 2800 - }, - .ciphertext = { - .data = { - 0x4B, 0xBF, 0xA9, 0x1B, 0xA2, 0x5D, 0x47, 0xDB, - 0x9A, 0x9F, 0x19, 0x0D, 0x96, 0x2A, 0x19, 0xAB, - 0x32, 0x39, 0x26, 0xB3, 0x51, 0xFB, 0xD3, 0x9E, - 0x35, 0x1E, 0x05, 0xDA, 0x8B, 0x89, 0x25, 0xE3, - 0x0B, 0x1C, 0xCE, 0x0D, 0x12, 0x21, 0x10, 0x10, - 0x95, 0x81, 0x5C, 0xC7, 0xCB, 0x63, 0x19, 0x50, - 0x9E, 0xC0, 0xD6, 0x79, 0x40, 0x49, 0x19, 0x87, - 0xE1, 0x3F, 0x0A, 0xFF, 0xAC, 0x33, 0x2A, 0xA6, - 0xAA, 0x64, 0x62, 0x6D, 0x3E, 0x9A, 0x19, 0x17, - 0x51, 0x9E, 0x0B, 0x97, 0xB6, 0x55, 0xC6, 0xA1, - 0x65, 0xE4, 0x4C, 0xA9, 0xFE, 0xAC, 0x07, 0x90, - 0xD2, 0xA3, 0x21, 0xAD, 0x3D, 0x86, 0xB7, 0x9C, - 0x51, 0x38, 0x73, 0x9F, 0xA3, 0x8D, 0x88, 0x7E, - 0xC7, 0xDE, 0xF4, 0x49, 0xCE, 0x8A, 0xBD, 0xD3, - 0xE7, 0xF8, 0xDC, 0x4C, 0xA9, 0xE7, 0xB7, 0x33, - 0x14, 0xAD, 0x31, 0x0F, 0x90, 0x25, 0xE6, 0x19, - 0x46, 0xB3, 0xA5, 0x6D, 0xC6, 0x49, 0xEC, 0x0D, - 0xA0, 0xD6, 0x39, 0x43, 0xDF, 0xF5, 0x92, 0xCF, - 0x96, 0x2A, 0x7E, 0xFB, 0x2C, 0x85, 0x24, 0xE3, - 0x5A, 0x2A, 0x6E, 0x78, 0x79, 0xD6, 0x26, 0x04, - 0xEF, 0x26, 0x86, 0x95, 0xFA, 0x40, 0x03, 0x02, - 0x7E, 0x22, 0xE6, 0x08, 0x30, 0x77, 0x52, 0x20, - 0x64, 0xBD, 0x4A, 0x5B, 0x90, 0x6B, 0x5F, 0x53, - 0x12, 0x74, 0xF2, 0x35, 0xED, 0x50, 0x6C, 0xFF, - 0x01, 0x54, 0xC7, 0x54, 0x92, 0x8A, 0x0C, 0xE5, - 0x47, 0x6F, 0x2C, 0xB1, 0x02, 0x0A, 0x12, 0x22, - 0xD3, 0x2C, 0x14, 0x55, 0xEC, 0xAE, 0xF1, 0xE3, - 0x68, 0xFB, 0x34, 0x4D, 0x17, 0x35, 0xBF, 0xBE, - 0xDE, 0xB7, 0x1D, 0x0A, 0x33, 0xA2, 0xA5, 0x4B, - 0x1D, 0xA5, 0xA2, 0x94, 0xE6, 0x79, 0x14, 0x4D, - 0xDF, 0x11, 0xEB, 0x1A, 0x3D, 0xE8, 0xCF, 0x0C, - 0xC0, 0x61, 0x91, 0x79, 0x74, 0xF3, 0x5C, 0x1D, - 0x9C, 0xA0, 0xAC, 0x81, 0x80, 0x7F, 0x8F, 0xCC, - 0xE6, 0x19, 0x9A, 0x6C, 0x77, 0x12, 0xDA, 0x86, - 0x50, 0x21, 0xB0, 0x4C, 0xE0, 0x43, 0x95, 0x16, - 0xF1, 0xA5, 0x26, 0xCC, 0xDA, 0x9F, 0xD9, 0xAB, - 0xBD, 0x53, 0xC3, 0xA6, 0x84, 0xF9, 0xAE, 0x1E, - 0x7E, 0xE6, 0xB1, 0x1D, 0xA1, 0x38, 0xEA, 0x82, - 0x6C, 0x55, 0x16, 0xB5, 0xAA, 0xDF, 0x1A, 0xBB, - 0xE3, 0x6F, 0xA7, 0xFF, 0xF9, 0x2E, 0x3A, 0x11, - 0x76, 0x06, 0x4E, 0x8D, 0x95, 0xF2, 0xE4, 0x88, - 0x2B, 0x55, 0x00, 0xB9, 0x32, 0x28, 0xB2, 0x19, - 0x4A, 0x47, 0x5C, 0x1A, 0x27, 0xF6, 0x3F, 0x9F, - 0xFD, 0x26, 0x49, 0x89, 0xA1, 0xBC - }, - .len = 2800 - }, - .validDataLenInBits = { - .len = 2798 - }, - .validCipherLenInBits = { - .len = 2798 - }, - .validCipherOffsetLenInBits = { - .len = 128 - } -}; - -struct zuc_test_data zuc_test_case_5 = { - .key = { - .data = { - 0xE1, 0x3F, 0xED, 0x21, 0xB4, 0x6E, 0x4E, 0x7E, - 0xC3, 0x12, 0x53, 0xB2, 0xBB, 0x17, 0xB3, 0xE0 - }, - .len = 16 - }, - .iv = { - .data = { - 0x27, 0x38, 0xCD, 0xAA, 0xD0, 0x00, 0x00, 0x00, - 0x27, 0x38, 0xCD, 0xAA, 0xD0, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x8D, 0x74, 0xE2, 0x0D, 0x54, 0x89, 0x4E, 0x06, - 0xD3, 0xCB, 0x13, 0xCB, 0x39, 0x33, 0x06, 0x5E, - 0x86, 0x74, 0xBE, 0x62, 0xAD, 0xB1, 0xC7, 0x2B, - 0x3A, 0x64, 0x69, 0x65, 0xAB, 0x63, 0xCB, 0x7B, - 0x78, 0x54, 0xDF, 0xDC, 0x27, 0xE8, 0x49, 0x29, - 0xF4, 0x9C, 0x64, 0xB8, 0x72, 0xA4, 0x90, 0xB1, - 0x3F, 0x95, 0x7B, 0x64, 0x82, 0x7E, 0x71, 0xF4, - 0x1F, 0xBD, 0x42, 0x69, 0xA4, 0x2C, 0x97, 0xF8, - 0x24, 0x53, 0x70, 0x27, 0xF8, 0x6E, 0x9F, 0x4A, - 0xD8, 0x2D, 0x1D, 0xF4, 0x51, 0x69, 0x0F, 0xDD, - 0x98, 0xB6, 0xD0, 0x3F, 0x3A, 0x0E, 0xBE, 0x3A, - 0x31, 0x2D, 0x6B, 0x84, 0x0B, 0xA5, 0xA1, 0x82, - 0x0B, 0x2A, 0x2C, 0x97, 0x09, 0xC0, 0x90, 0xD2, - 0x45, 0xED, 0x26, 0x7C, 0xF8, 0x45, 0xAE, 0x41, - 0xFA, 0x97, 0x5D, 0x33, 0x33, 0xAC, 0x30, 0x09, - 0xFD, 0x40, 0xEB, 0xA9, 0xEB, 0x5B, 0x88, 0x57, - 0x14, 0xB7, 0x68, 0xB6, 0x97, 0x13, 0x8B, 0xAF, - 0x21, 0x38, 0x0E, 0xCA, 0x49, 0xF6, 0x44, 0xD4, - 0x86, 0x89, 0xE4, 0x21, 0x57, 0x60, 0xB9, 0x06, - 0x73, 0x9F, 0x0D, 0x2B, 0x3F, 0x09, 0x11, 0x33, - 0xCA, 0x15, 0xD9, 0x81, 0xCB, 0xE4, 0x01, 0xBA, - 0xF7, 0x2D, 0x05, 0xAC, 0xE0, 0x5C, 0xCC, 0xB2, - 0xD2, 0x97, 0xF4, 0xEF, 0x6A, 0x5F, 0x58, 0xD9, - 0x12, 0x46, 0xCF, 0xA7, 0x72, 0x15, 0xB8, 0x92, - 0xAB, 0x44, 0x1D, 0x52, 0x78, 0x45, 0x27, 0x95, - 0xCC, 0xB7, 0xF5, 0xD7, 0x90, 0x57, 0xA1, 0xC4, - 0xF7, 0x7F, 0x80, 0xD4, 0x6D, 0xB2, 0x03, 0x3C, - 0xB7, 0x9B, 0xED, 0xF8, 0xE6, 0x05, 0x51, 0xCE, - 0x10, 0xC6, 0x67, 0xF6, 0x2A, 0x97, 0xAB, 0xAF, - 0xAB, 0xBC, 0xD6, 0x77, 0x20, 0x18, 0xDF, 0x96, - 0xA2, 0x82, 0xEA, 0x73, 0x7C, 0xE2, 0xCB, 0x33, - 0x12, 0x11, 0xF6, 0x0D, 0x53, 0x54, 0xCE, 0x78, - 0xF9, 0x91, 0x8D, 0x9C, 0x20, 0x6C, 0xA0, 0x42, - 0xC9, 0xB6, 0x23, 0x87, 0xDD, 0x70, 0x96, 0x04, - 0xA5, 0x0A, 0xF1, 0x6D, 0x8D, 0x35, 0xA8, 0x90, - 0x6B, 0xE4, 0x84, 0xCF, 0x2E, 0x74, 0xA9, 0x28, - 0x99, 0x40, 0x36, 0x43, 0x53, 0x24, 0x9B, 0x27, - 0xB4, 0xC9, 0xAE, 0x29, 0xED, 0xDF, 0xC7, 0xDA, - 0x64, 0x18, 0x79, 0x1A, 0x4E, 0x7B, 0xAA, 0x06, - 0x60, 0xFA, 0x64, 0x51, 0x1F, 0x2D, 0x68, 0x5C, - 0xC3, 0xA5, 0xFF, 0x70, 0xE0, 0xD2, 0xB7, 0x42, - 0x92, 0xE3, 0xB8, 0xA0, 0xCD, 0x6B, 0x04, 0xB1, - 0xC7, 0x90, 0xB8, 0xEA, 0xD2, 0x70, 0x37, 0x08, - 0x54, 0x0D, 0xEA, 0x2F, 0xC0, 0x9C, 0x3D, 0xA7, - 0x70, 0xF6, 0x54, 0x49, 0xE8, 0x4D, 0x81, 0x7A, - 0x4F, 0x55, 0x10, 0x55, 0xE1, 0x9A, 0xB8, 0x50, - 0x18, 0xA0, 0x02, 0x8B, 0x71, 0xA1, 0x44, 0xD9, - 0x67, 0x91, 0xE9, 0xA3, 0x57, 0x79, 0x33, 0x50, - 0x4E, 0xEE, 0x00, 0x60, 0x34, 0x0C, 0x69, 0xD2, - 0x74, 0xE1, 0xBF, 0x9D, 0x80, 0x5D, 0xCB, 0xCC, - 0x1A, 0x6F, 0xAA, 0x97, 0x68, 0x00, 0xB6, 0xFF, - 0x2B, 0x67, 0x1D, 0xC4, 0x63, 0x65, 0x2F, 0xA8, - 0xA3, 0x3E, 0xE5, 0x09, 0x74, 0xC1, 0xC2, 0x1B, - 0xE0, 0x1E, 0xAB, 0xB2, 0x16, 0x74, 0x30, 0x26, - 0x9D, 0x72, 0xEE, 0x51, 0x1C, 0x9D, 0xDE, 0x30, - 0x79, 0x7C, 0x9A, 0x25, 0xD8, 0x6C, 0xE7, 0x4F, - 0x5B, 0x96, 0x1B, 0xE5, 0xFD, 0xFB, 0x68, 0x07, - 0x81, 0x40, 0x39, 0xE7, 0x13, 0x76, 0x36, 0xBD, - 0x1D, 0x7F, 0xA9, 0xE0, 0x9E, 0xFD, 0x20, 0x07, - 0x50, 0x59, 0x06, 0xA5, 0xAC, 0x45, 0xDF, 0xDE, - 0xED, 0x77, 0x57, 0xBB, 0xEE, 0x74, 0x57, 0x49, - 0xC2, 0x96, 0x33, 0x35, 0x0B, 0xEE, 0x0E, 0xA6, - 0xF4, 0x09, 0xDF, 0x45, 0x80, 0x16, 0x00 - }, - .len = 4024 - }, - .ciphertext = { - .data = { - 0x94, 0xEA, 0xA4, 0xAA, 0x30, 0xA5, 0x71, 0x37, - 0xDD, 0xF0, 0x9B, 0x97, 0xB2, 0x56, 0x18, 0xA2, - 0x0A, 0x13, 0xE2, 0xF1, 0x0F, 0xA5, 0xBF, 0x81, - 0x61, 0xA8, 0x79, 0xCC, 0x2A, 0xE7, 0x97, 0xA6, - 0xB4, 0xCF, 0x2D, 0x9D, 0xF3, 0x1D, 0xEB, 0xB9, - 0x90, 0x5C, 0xCF, 0xEC, 0x97, 0xDE, 0x60, 0x5D, - 0x21, 0xC6, 0x1A, 0xB8, 0x53, 0x1B, 0x7F, 0x3C, - 0x9D, 0xA5, 0xF0, 0x39, 0x31, 0xF8, 0xA0, 0x64, - 0x2D, 0xE4, 0x82, 0x11, 0xF5, 0xF5, 0x2F, 0xFE, - 0xA1, 0x0F, 0x39, 0x2A, 0x04, 0x76, 0x69, 0x98, - 0x5D, 0xA4, 0x54, 0xA2, 0x8F, 0x08, 0x09, 0x61, - 0xA6, 0xC2, 0xB6, 0x2D, 0xAA, 0x17, 0xF3, 0x3C, - 0xD6, 0x0A, 0x49, 0x71, 0xF4, 0x8D, 0x2D, 0x90, - 0x93, 0x94, 0xA5, 0x5F, 0x48, 0x11, 0x7A, 0xCE, - 0x43, 0xD7, 0x08, 0xE6, 0xB7, 0x7D, 0x3D, 0xC4, - 0x6D, 0x8B, 0xC0, 0x17, 0xD4, 0xD1, 0xAB, 0xB7, - 0x7B, 0x74, 0x28, 0xC0, 0x42, 0xB0, 0x6F, 0x2F, - 0x99, 0xD8, 0xD0, 0x7C, 0x98, 0x79, 0xD9, 0x96, - 0x00, 0x12, 0x7A, 0x31, 0x98, 0x5F, 0x10, 0x99, - 0xBB, 0xD7, 0xD6, 0xC1, 0x51, 0x9E, 0xDE, 0x8F, - 0x5E, 0xEB, 0x4A, 0x61, 0x0B, 0x34, 0x9A, 0xC0, - 0x1E, 0xA2, 0x35, 0x06, 0x91, 0x75, 0x6B, 0xD1, - 0x05, 0xC9, 0x74, 0xA5, 0x3E, 0xDD, 0xB3, 0x5D, - 0x1D, 0x41, 0x00, 0xB0, 0x12, 0xE5, 0x22, 0xAB, - 0x41, 0xF4, 0xC5, 0xF2, 0xFD, 0xE7, 0x6B, 0x59, - 0xCB, 0x8B, 0x96, 0xD8, 0x85, 0xCF, 0xE4, 0x08, - 0x0D, 0x13, 0x28, 0xA0, 0xD6, 0x36, 0xCC, 0x0E, - 0xDC, 0x05, 0x80, 0x0B, 0x76, 0xAC, 0xCA, 0x8F, - 0xEF, 0x67, 0x20, 0x84, 0xD1, 0xF5, 0x2A, 0x8B, - 0xBD, 0x8E, 0x09, 0x93, 0x32, 0x09, 0x92, 0xC7, - 0xFF, 0xBA, 0xE1, 0x7C, 0x40, 0x84, 0x41, 0xE0, - 0xEE, 0x88, 0x3F, 0xC8, 0xA8, 0xB0, 0x5E, 0x22, - 0xF5, 0xFF, 0x7F, 0x8D, 0x1B, 0x48, 0xC7, 0x4C, - 0x46, 0x8C, 0x46, 0x7A, 0x02, 0x8F, 0x09, 0xFD, - 0x7C, 0xE9, 0x11, 0x09, 0xA5, 0x70, 0xA2, 0xD5, - 0xC4, 0xD5, 0xF4, 0xFA, 0x18, 0xC5, 0xDD, 0x3E, - 0x45, 0x62, 0xAF, 0xE2, 0x4E, 0xF7, 0x71, 0x90, - 0x1F, 0x59, 0xAF, 0x64, 0x58, 0x98, 0xAC, 0xEF, - 0x08, 0x8A, 0xBA, 0xE0, 0x7E, 0x92, 0xD5, 0x2E, - 0xB2, 0xDE, 0x55, 0x04, 0x5B, 0xB1, 0xB7, 0xC4, - 0x16, 0x4E, 0xF2, 0xD7, 0xA6, 0xCA, 0xC1, 0x5E, - 0xEB, 0x92, 0x6D, 0x7E, 0xA2, 0xF0, 0x8B, 0x66, - 0xE1, 0xF7, 0x59, 0xF3, 0xAE, 0xE4, 0x46, 0x14, - 0x72, 0x5A, 0xA3, 0xC7, 0x48, 0x2B, 0x30, 0x84, - 0x4C, 0x14, 0x3F, 0xF8, 0x5B, 0x53, 0xF1, 0xE5, - 0x83, 0xC5, 0x01, 0x25, 0x7D, 0xDD, 0xD0, 0x96, - 0xB8, 0x12, 0x68, 0xDA, 0xA3, 0x03, 0xF1, 0x72, - 0x34, 0xC2, 0x33, 0x35, 0x41, 0xF0, 0xBB, 0x8E, - 0x19, 0x06, 0x48, 0xC5, 0x80, 0x7C, 0x86, 0x6D, - 0x71, 0x93, 0x22, 0x86, 0x09, 0xAD, 0xB9, 0x48, - 0x68, 0x6F, 0x7D, 0xE2, 0x94, 0xA8, 0x02, 0xCC, - 0x38, 0xF7, 0xFE, 0x52, 0x08, 0xF5, 0xEA, 0x31, - 0x96, 0xD0, 0x16, 0x7B, 0x9B, 0xDD, 0x02, 0xF0, - 0xD2, 0xA5, 0x22, 0x1C, 0xA5, 0x08, 0xF8, 0x93, - 0xAF, 0x5C, 0x4B, 0x4B, 0xB9, 0xF4, 0xF5, 0x20, - 0xFD, 0x84, 0x28, 0x9B, 0x3D, 0xBE, 0x7E, 0x61, - 0x49, 0x7A, 0x7E, 0x2A, 0x58, 0x40, 0x37, 0xEA, - 0x63, 0x7B, 0x69, 0x81, 0x12, 0x71, 0x74, 0xAF, - 0x57, 0xB4, 0x71, 0xDF, 0x4B, 0x27, 0x68, 0xFD, - 0x79, 0xC1, 0x54, 0x0F, 0xB3, 0xED, 0xF2, 0xEA, - 0x22, 0xCB, 0x69, 0xBE, 0xC0, 0xCF, 0x8D, 0x93, - 0x3D, 0x9C, 0x6F, 0xDD, 0x64, 0x5E, 0x85, 0x05, - 0x91, 0xCC, 0xA3, 0xD6, 0x2C, 0x0C, 0xC0 - }, - .len = 4024 - }, - .validDataLenInBits = { - .len = 4019 - }, - .validCipherLenInBits = { - .len = 4019 - }, - .validCipherOffsetLenInBits = { - .len = 128 - } -}; - -#endif /* TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ */ diff --git a/app/test/test_cycles.c b/app/test/test_cycles.c deleted file mode 100644 index f1897979d2..0000000000 --- a/app/test/test_cycles.c +++ /dev/null @@ -1,137 +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 -#include - -#include -#include - -#include "test.h" - -#define N 10000 - -/* - * Cycles test - * =========== - * - * - Loop N times and check that the timer always increments and - * never decrements during this loop. - * - * - Wait one second using rte_usleep() and check that the increment - * of cycles is correct with regard to the frequency of the timer. - */ - -static int -test_cycles(void) -{ - unsigned i; - uint64_t start_cycles, cycles, prev_cycles; - uint64_t hz = rte_get_timer_hz(); - uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */ - - /* check that the timer is always incrementing */ - start_cycles = rte_get_timer_cycles(); - prev_cycles = start_cycles; - for (i=0; i max_inc) { - printf("increment too high or going backwards\n"); - return -1; - } - prev_cycles = cycles; - } - - /* check that waiting 1 second is precise */ - prev_cycles = rte_get_timer_cycles(); - rte_delay_us(1000000); - cycles = rte_get_timer_cycles(); - - if ((uint64_t)(cycles - prev_cycles) > (hz + max_inc)) { - printf("delay_us is not accurate: too long\n"); - return -1; - } - if ((uint64_t)(cycles - prev_cycles) < (hz - max_inc)) { - printf("delay_us is not accurate: too short\n"); - return -1; - } - - return 0; -} - -REGISTER_TEST_COMMAND(cycles_autotest, test_cycles); - -/* - * rte_delay_us_callback test - * - * - check if callback is correctly registered/unregistered - * - */ - -static unsigned int pattern; -static void my_rte_delay_us(unsigned int us) -{ - pattern += us; -} - -static int -test_user_delay_us(void) -{ - pattern = 0; - - rte_delay_us(2); - if (pattern != 0) - return -1; - - /* register custom delay function */ - rte_delay_us_callback_register(my_rte_delay_us); - - rte_delay_us(2); - if (pattern != 2) - return -1; - - rte_delay_us(3); - if (pattern != 5) - return -1; - - /* restore original delay function */ - rte_delay_us_callback_register(rte_delay_us_block); - - rte_delay_us(3); - if (pattern != 5) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(user_delay_us, test_user_delay_us); diff --git a/app/test/test_debug.c b/app/test/test_debug.c deleted file mode 100644 index 0a3b2c468a..0000000000 --- a/app/test/test_debug.c +++ /dev/null @@ -1,149 +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 -#include -#include -#include - -#include -#include -#include - -#include "test.h" - -/* - * Debug test - * ========== - */ - -/* use fork() to test rte_panic() */ -static int -test_panic(void) -{ - int pid; - int status; - - pid = fork(); - - if (pid == 0) - rte_panic("Test Debug\n"); - else if (pid < 0){ - printf("Fork Failed\n"); - return -1; - } - wait(&status); - if(status == 0){ - printf("Child process terminated normally!\n"); - return -1; - } else - printf("Child process terminated as expected - Test passed!\n"); - - return 0; -} - -/* use fork() to test rte_exit() */ -static int -test_exit_val(int exit_val) -{ - int pid; - int status; - - pid = fork(); - - if (pid == 0) - rte_exit(exit_val, __func__); - else if (pid < 0){ - printf("Fork Failed\n"); - return -1; - } - wait(&status); - printf("Child process status: %d\n", status); -#ifndef RTE_EAL_ALWAYS_PANIC_ON_ERROR - if(!WIFEXITED(status) || WEXITSTATUS(status) != (uint8_t)exit_val){ - printf("Child process terminated with incorrect status (expected = %d)!\n", - exit_val); - return -1; - } -#endif - return 0; -} - -static int -test_exit(void) -{ - int test_vals[] = { 0, 1, 2, 255, -1 }; - unsigned i; - for (i = 0; i < sizeof(test_vals) / sizeof(test_vals[0]); i++){ - if (test_exit_val(test_vals[i]) < 0) - return -1; - } - printf("%s Passed\n", __func__); - return 0; -} - -static void -dummy_app_usage(const char *progname) -{ - RTE_SET_USED(progname); -} - -static int -test_usage(void) -{ - if (rte_set_application_usage_hook(dummy_app_usage) != NULL) { - printf("Non-NULL value returned for initial usage hook\n"); - return -1; - } - if (rte_set_application_usage_hook(NULL) != dummy_app_usage) { - printf("Incorrect value returned for application usage hook\n"); - return -1; - } - return 0; -} - -static int -test_debug(void) -{ - rte_dump_stack(); - rte_dump_registers(); - if (test_panic() < 0) - return -1; - if (test_exit() < 0) - return -1; - if (test_usage() < 0) - return -1; - return 0; -} - -REGISTER_TEST_COMMAND(debug_autotest, test_debug); diff --git a/app/test/test_devargs.c b/app/test/test_devargs.c deleted file mode 100644 index 63242f1caf..0000000000 --- a/app/test/test_devargs.c +++ /dev/null @@ -1,134 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright 2014 6WIND S.A. - * - * 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 6WIND S.A 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 -#include -#include -#include - -#include -#include - -#include "test.h" - -/* clear devargs list that was modified by the test */ -static void free_devargs_list(void) -{ - struct rte_devargs *devargs; - - while (!TAILQ_EMPTY(&devargs_list)) { - devargs = TAILQ_FIRST(&devargs_list); - TAILQ_REMOVE(&devargs_list, devargs, next); - free(devargs->args); - free(devargs); - } -} - -static int -test_devargs(void) -{ - struct rte_devargs_list save_devargs_list; - struct rte_devargs *devargs; - - /* save the real devargs_list, it is restored at the end of the test */ - save_devargs_list = devargs_list; - TAILQ_INIT(&devargs_list); - - /* test valid cases */ - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:00.1") < 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "0000:5:00.0") < 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "04:00.0,arg=val") < 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "0000:01:00.1") < 0) - goto fail; - if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 2) - goto fail; - if (rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 2) - goto fail; - if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "net_ring0") < 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "net_ring1,key=val,k2=val2") < 0) - goto fail; - if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 2) - goto fail; - free_devargs_list(); - - /* check virtual device with argument parsing */ - if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "net_ring1,k1=val,k2=val2") < 0) - goto fail; - devargs = TAILQ_FIRST(&devargs_list); - if (strncmp(devargs->virt.drv_name, "net_ring1", - sizeof(devargs->virt.drv_name)) != 0) - goto fail; - if (!devargs->args || strcmp(devargs->args, "k1=val,k2=val2") != 0) - goto fail; - free_devargs_list(); - - /* check PCI device with empty argument parsing */ - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "04:00.1") < 0) - goto fail; - devargs = TAILQ_FIRST(&devargs_list); - if (devargs->pci.addr.domain != 0 || - devargs->pci.addr.bus != 4 || - devargs->pci.addr.devid != 0 || - devargs->pci.addr.function != 1) - goto fail; - if (!devargs->args || strcmp(devargs->args, "") != 0) - goto fail; - free_devargs_list(); - - /* test error case: bad PCI address */ - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:1") == 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "00.1") == 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "foo") == 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, ",") == 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "000f:0:0") == 0) - goto fail; - - devargs_list = save_devargs_list; - return 0; - - fail: - free_devargs_list(); - devargs_list = save_devargs_list; - return -1; -} - -REGISTER_TEST_COMMAND(devargs_autotest, test_devargs); diff --git a/app/test/test_distributor.c b/app/test/test_distributor.c deleted file mode 100644 index 85cb8f3919..0000000000 --- a/app/test/test_distributor.c +++ /dev/null @@ -1,579 +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 "test.h" - -#include -#include -#include -#include -#include -#include -#include - -#define ITER_POWER 20 /* log 2 of how many iterations we do when timing. */ -#define BURST 32 -#define BIG_BATCH 1024 - -/* statics - all zero-initialized by default */ -static volatile int quit; /**< general quit variable for all threads */ -static volatile int zero_quit; /**< var for when we just want thr0 to quit*/ -static volatile unsigned worker_idx; - -struct worker_stats { - volatile unsigned handled_packets; -} __rte_cache_aligned; -struct worker_stats worker_stats[RTE_MAX_LCORE]; - -/* returns the total count of the number of packets handled by the worker - * functions given below. - */ -static inline unsigned -total_packet_count(void) -{ - unsigned i, count = 0; - for (i = 0; i < worker_idx; i++) - count += worker_stats[i].handled_packets; - return count; -} - -/* resets the packet counts for a new test */ -static inline void -clear_packet_count(void) -{ - memset(&worker_stats, 0, sizeof(worker_stats)); -} - -/* this is the basic worker function for sanity test - * it does nothing but return packets and count them. - */ -static int -handle_work(void *arg) -{ - struct rte_mbuf *pkt = NULL; - struct rte_distributor *d = arg; - unsigned count = 0; - unsigned id = __sync_fetch_and_add(&worker_idx, 1); - - pkt = rte_distributor_get_pkt(d, id, NULL); - while (!quit) { - worker_stats[id].handled_packets++, count++; - pkt = rte_distributor_get_pkt(d, id, pkt); - } - worker_stats[id].handled_packets++, count++; - rte_distributor_return_pkt(d, id, pkt); - return 0; -} - -/* do basic sanity testing of the distributor. This test tests the following: - * - send 32 packets through distributor with the same tag and ensure they - * all go to the one worker - * - send 32 packets throught the distributor with two different tags and - * verify that they go equally to two different workers. - * - send 32 packets with different tags through the distributors and - * just verify we get all packets back. - * - send 1024 packets through the distributor, gathering the returned packets - * as we go. Then verify that we correctly got all 1024 pointers back again, - * not necessarily in the same order (as different flows). - */ -static int -sanity_test(struct rte_distributor *d, struct rte_mempool *p) -{ - struct rte_mbuf *bufs[BURST]; - unsigned i; - - printf("=== Basic distributor sanity tests ===\n"); - clear_packet_count(); - if (rte_mempool_get_bulk(p, (void *)bufs, BURST) != 0) { - printf("line %d: Error getting mbufs from pool\n", __LINE__); - return -1; - } - - /* now set all hash values in all buffers to zero, so all pkts go to the - * one worker thread */ - for (i = 0; i < BURST; i++) - bufs[i]->hash.usr = 0; - - rte_distributor_process(d, bufs, BURST); - rte_distributor_flush(d); - if (total_packet_count() != BURST) { - printf("Line %d: Error, not all packets flushed. " - "Expected %u, got %u\n", - __LINE__, BURST, total_packet_count()); - return -1; - } - - for (i = 0; i < rte_lcore_count() - 1; i++) - printf("Worker %u handled %u packets\n", i, - worker_stats[i].handled_packets); - printf("Sanity test with all zero hashes done.\n"); - if (worker_stats[0].handled_packets != BURST) - return -1; - - /* pick two flows and check they go correctly */ - if (rte_lcore_count() >= 3) { - clear_packet_count(); - for (i = 0; i < BURST; i++) - bufs[i]->hash.usr = (i & 1) << 8; - - rte_distributor_process(d, bufs, BURST); - rte_distributor_flush(d); - if (total_packet_count() != BURST) { - printf("Line %d: Error, not all packets flushed. " - "Expected %u, got %u\n", - __LINE__, BURST, total_packet_count()); - return -1; - } - - for (i = 0; i < rte_lcore_count() - 1; i++) - printf("Worker %u handled %u packets\n", i, - worker_stats[i].handled_packets); - printf("Sanity test with two hash values done\n"); - - if (worker_stats[0].handled_packets != 16 || - worker_stats[1].handled_packets != 16) - return -1; - } - - /* give a different hash value to each packet, - * so load gets distributed */ - clear_packet_count(); - for (i = 0; i < BURST; i++) - bufs[i]->hash.usr = i; - - rte_distributor_process(d, bufs, BURST); - rte_distributor_flush(d); - if (total_packet_count() != BURST) { - printf("Line %d: Error, not all packets flushed. " - "Expected %u, got %u\n", - __LINE__, BURST, total_packet_count()); - return -1; - } - - for (i = 0; i < rte_lcore_count() - 1; i++) - printf("Worker %u handled %u packets\n", i, - worker_stats[i].handled_packets); - printf("Sanity test with non-zero hashes done\n"); - - rte_mempool_put_bulk(p, (void *)bufs, BURST); - - /* sanity test with BIG_BATCH packets to ensure they all arrived back - * from the returned packets function */ - clear_packet_count(); - struct rte_mbuf *many_bufs[BIG_BATCH], *return_bufs[BIG_BATCH]; - unsigned num_returned = 0; - - /* flush out any remaining packets */ - rte_distributor_flush(d); - rte_distributor_clear_returns(d); - if (rte_mempool_get_bulk(p, (void *)many_bufs, BIG_BATCH) != 0) { - printf("line %d: Error getting mbufs from pool\n", __LINE__); - return -1; - } - for (i = 0; i < BIG_BATCH; i++) - many_bufs[i]->hash.usr = i << 2; - - for (i = 0; i < BIG_BATCH/BURST; i++) { - rte_distributor_process(d, &many_bufs[i*BURST], BURST); - num_returned += rte_distributor_returned_pkts(d, - &return_bufs[num_returned], - BIG_BATCH - num_returned); - } - rte_distributor_flush(d); - num_returned += rte_distributor_returned_pkts(d, - &return_bufs[num_returned], BIG_BATCH - num_returned); - - if (num_returned != BIG_BATCH) { - printf("line %d: Number returned is not the same as " - "number sent\n", __LINE__); - return -1; - } - /* big check - make sure all packets made it back!! */ - for (i = 0; i < BIG_BATCH; i++) { - unsigned j; - struct rte_mbuf *src = many_bufs[i]; - for (j = 0; j < BIG_BATCH; j++) - if (return_bufs[j] == src) - break; - - if (j == BIG_BATCH) { - printf("Error: could not find source packet #%u\n", i); - return -1; - } - } - printf("Sanity test of returned packets done\n"); - - rte_mempool_put_bulk(p, (void *)many_bufs, BIG_BATCH); - - printf("\n"); - return 0; -} - - -/* to test that the distributor does not lose packets, we use this worker - * function which frees mbufs when it gets them. The distributor thread does - * the mbuf allocation. If distributor drops packets we'll eventually run out - * of mbufs. - */ -static int -handle_work_with_free_mbufs(void *arg) -{ - struct rte_mbuf *pkt = NULL; - struct rte_distributor *d = arg; - unsigned count = 0; - unsigned id = __sync_fetch_and_add(&worker_idx, 1); - - pkt = rte_distributor_get_pkt(d, id, NULL); - while (!quit) { - worker_stats[id].handled_packets++, count++; - rte_pktmbuf_free(pkt); - pkt = rte_distributor_get_pkt(d, id, pkt); - } - worker_stats[id].handled_packets++, count++; - rte_distributor_return_pkt(d, id, pkt); - return 0; -} - -/* Perform a sanity test of the distributor with a large number of packets, - * where we allocate a new set of mbufs for each burst. The workers then - * free the mbufs. This ensures that we don't have any packet leaks in the - * library. - */ -static int -sanity_test_with_mbuf_alloc(struct rte_distributor *d, struct rte_mempool *p) -{ - unsigned i; - struct rte_mbuf *bufs[BURST]; - - printf("=== Sanity test with mbuf alloc/free ===\n"); - clear_packet_count(); - for (i = 0; i < ((1<hash.usr = (i+j) << 1; - rte_mbuf_refcnt_set(bufs[j], 1); - } - - rte_distributor_process(d, bufs, BURST); - } - - rte_distributor_flush(d); - if (total_packet_count() < (1<hash.usr = 0; - - rte_distributor_process(d, bufs, BURST); - /* at this point, we will have processed some packets and have a full - * backlog for the other ones at worker 0. - */ - - /* get more buffers to queue up, again setting them to the same flow */ - if (rte_mempool_get_bulk(p, (void *)bufs, BURST) != 0) { - printf("line %d: Error getting mbufs from pool\n", __LINE__); - return -1; - } - for (i = 0; i < BURST; i++) - bufs[i]->hash.usr = 0; - - /* get worker zero to quit */ - zero_quit = 1; - rte_distributor_process(d, bufs, BURST); - - /* flush the distributor */ - rte_distributor_flush(d); - if (total_packet_count() != BURST * 2) { - printf("Line %d: Error, not all packets flushed. " - "Expected %u, got %u\n", - __LINE__, BURST * 2, total_packet_count()); - return -1; - } - - for (i = 0; i < rte_lcore_count() - 1; i++) - printf("Worker %u handled %u packets\n", i, - worker_stats[i].handled_packets); - - printf("Sanity test with worker shutdown passed\n\n"); - return 0; -} - -/* Test that the flush function is able to move packets between workers when - * one worker shuts down.. - */ -static int -test_flush_with_worker_shutdown(struct rte_distributor *d, - struct rte_mempool *p) -{ - struct rte_mbuf *bufs[BURST]; - unsigned i; - - printf("=== Test flush fn with worker shutdown ===\n"); - - clear_packet_count(); - if (rte_mempool_get_bulk(p, (void *)bufs, BURST) != 0) { - printf("line %d: Error getting mbufs from pool\n", __LINE__); - return -1; - } - - /* now set all hash values in all buffers to zero, so all pkts go to the - * one worker thread */ - for (i = 0; i < BURST; i++) - bufs[i]->hash.usr = 0; - - rte_distributor_process(d, bufs, BURST); - /* at this point, we will have processed some packets and have a full - * backlog for the other ones at worker 0. - */ - - /* get worker zero to quit */ - zero_quit = 1; - - /* flush the distributor */ - rte_distributor_flush(d); - - zero_quit = 0; - if (total_packet_count() != BURST) { - printf("Line %d: Error, not all packets flushed. " - "Expected %u, got %u\n", - __LINE__, BURST, total_packet_count()); - return -1; - } - - for (i = 0; i < rte_lcore_count() - 1; i++) - printf("Worker %u handled %u packets\n", i, - worker_stats[i].handled_packets); - - printf("Flush test with worker shutdown passed\n\n"); - return 0; -} - -static -int test_error_distributor_create_name(void) -{ - struct rte_distributor *d = NULL; - char *name = NULL; - - d = rte_distributor_create(name, rte_socket_id(), - rte_lcore_count() - 1); - if (d != NULL || rte_errno != EINVAL) { - printf("ERROR: No error on create() with NULL name param\n"); - return -1; - } - - return 0; -} - - -static -int test_error_distributor_create_numworkers(void) -{ - struct rte_distributor *d = NULL; - d = rte_distributor_create("test_numworkers", rte_socket_id(), - RTE_MAX_LCORE + 10); - if (d != NULL || rte_errno != EINVAL) { - printf("ERROR: No error on create() with num_workers > MAX\n"); - return -1; - } - return 0; -} - - -/* Useful function which ensures that all worker functions terminate */ -static void -quit_workers(struct rte_distributor *d, struct rte_mempool *p) -{ - const unsigned num_workers = rte_lcore_count() - 1; - unsigned i; - struct rte_mbuf *bufs[RTE_MAX_LCORE]; - rte_mempool_get_bulk(p, (void *)bufs, num_workers); - - zero_quit = 0; - quit = 1; - for (i = 0; i < num_workers; i++) - bufs[i]->hash.usr = i << 1; - rte_distributor_process(d, bufs, num_workers); - - rte_mempool_put_bulk(p, (void *)bufs, num_workers); - - rte_distributor_process(d, NULL, 0); - rte_distributor_flush(d); - rte_eal_mp_wait_lcore(); - quit = 0; - worker_idx = 0; -} - -static int -test_distributor(void) -{ - static struct rte_distributor *d; - static struct rte_mempool *p; - - if (rte_lcore_count() < 2) { - printf("ERROR: not enough cores to test distributor\n"); - return -1; - } - - if (d == NULL) { - d = rte_distributor_create("Test_distributor", rte_socket_id(), - rte_lcore_count() - 1); - if (d == NULL) { - printf("Error creating distributor\n"); - return -1; - } - } else { - rte_distributor_flush(d); - rte_distributor_clear_returns(d); - } - - const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ? - (BIG_BATCH * 2) - 1 : (511 * rte_lcore_count()); - if (p == NULL) { - p = rte_pktmbuf_pool_create("DT_MBUF_POOL", nb_bufs, BURST, - 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - if (p == NULL) { - printf("Error creating mempool\n"); - return -1; - } - } - - rte_eal_mp_remote_launch(handle_work, d, SKIP_MASTER); - if (sanity_test(d, p) < 0) - goto err; - quit_workers(d, p); - - rte_eal_mp_remote_launch(handle_work_with_free_mbufs, d, SKIP_MASTER); - if (sanity_test_with_mbuf_alloc(d, p) < 0) - goto err; - quit_workers(d, p); - - if (rte_lcore_count() > 2) { - rte_eal_mp_remote_launch(handle_work_for_shutdown_test, d, - SKIP_MASTER); - if (sanity_test_with_worker_shutdown(d, p) < 0) - goto err; - quit_workers(d, p); - - rte_eal_mp_remote_launch(handle_work_for_shutdown_test, d, - SKIP_MASTER); - if (test_flush_with_worker_shutdown(d, p) < 0) - goto err; - quit_workers(d, p); - - } else { - printf("Not enough cores to run tests for worker shutdown\n"); - } - - if (test_error_distributor_create_numworkers() == -1 || - test_error_distributor_create_name() == -1) { - printf("rte_distributor_create parameter check tests failed"); - return -1; - } - - return 0; - -err: - quit_workers(d, p); - return -1; -} - -REGISTER_TEST_COMMAND(distributor_autotest, test_distributor); diff --git a/app/test/test_distributor_perf.c b/app/test/test_distributor_perf.c deleted file mode 100644 index 7947fe9b16..0000000000 --- a/app/test/test_distributor_perf.c +++ /dev/null @@ -1,260 +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 "test.h" - -#include -#include -#include -#include -#include -#include -#include - -#define ITER_POWER 20 /* log 2 of how many iterations we do when timing. */ -#define BURST 32 -#define BIG_BATCH 1024 - -/* static vars - zero initialized by default */ -static volatile int quit; -static volatile unsigned worker_idx; - -struct worker_stats { - volatile unsigned handled_packets; -} __rte_cache_aligned; -struct worker_stats worker_stats[RTE_MAX_LCORE]; - -/* worker thread used for testing the time to do a round-trip of a cache - * line between two cores and back again - */ -static void -flip_bit(volatile uint64_t *arg) -{ - uint64_t old_val = 0; - while (old_val != 2) { - while (!*arg) - rte_pause(); - old_val = *arg; - *arg = 0; - } -} - -/* test case to time the number of cycles to round-trip a cache line between - * two cores and back again. - */ -static void -time_cache_line_switch(void) -{ - /* allocate a full cache line for data, we use only first byte of it */ - uint64_t data[RTE_CACHE_LINE_SIZE*3 / sizeof(uint64_t)]; - - unsigned i, slaveid = rte_get_next_lcore(rte_lcore_id(), 0, 0); - volatile uint64_t *pdata = &data[0]; - *pdata = 1; - rte_eal_remote_launch((lcore_function_t *)flip_bit, &data[0], slaveid); - while (*pdata) - rte_pause(); - - const uint64_t start_time = rte_rdtsc(); - for (i = 0; i < (1 << ITER_POWER); i++) { - while (*pdata) - rte_pause(); - *pdata = 1; - } - const uint64_t end_time = rte_rdtsc(); - - while (*pdata) - rte_pause(); - *pdata = 2; - rte_eal_wait_lcore(slaveid); - printf("==== Cache line switch test ===\n"); - printf("Time for %u iterations = %"PRIu64" ticks\n", (1<> ITER_POWER); -} - -/* returns the total count of the number of packets handled by the worker - * functions given below. - */ -static unsigned -total_packet_count(void) -{ - unsigned i, count = 0; - for (i = 0; i < worker_idx; i++) - count += worker_stats[i].handled_packets; - return count; -} - -/* resets the packet counts for a new test */ -static void -clear_packet_count(void) -{ - memset(&worker_stats, 0, sizeof(worker_stats)); -} - -/* this is the basic worker function for performance tests. - * it does nothing but return packets and count them. - */ -static int -handle_work(void *arg) -{ - struct rte_mbuf *pkt = NULL; - struct rte_distributor *d = arg; - unsigned count = 0; - unsigned id = __sync_fetch_and_add(&worker_idx, 1); - - pkt = rte_distributor_get_pkt(d, id, NULL); - while (!quit) { - worker_stats[id].handled_packets++, count++; - pkt = rte_distributor_get_pkt(d, id, pkt); - } - worker_stats[id].handled_packets++, count++; - rte_distributor_return_pkt(d, id, pkt); - return 0; -} - -/* this basic performance test just repeatedly sends in 32 packets at a time - * to the distributor and verifies at the end that we got them all in the worker - * threads and finally how long per packet the processing took. - */ -static inline int -perf_test(struct rte_distributor *d, struct rte_mempool *p) -{ - unsigned i; - uint64_t start, end; - struct rte_mbuf *bufs[BURST]; - - clear_packet_count(); - if (rte_mempool_get_bulk(p, (void *)bufs, BURST) != 0) { - printf("Error getting mbufs from pool\n"); - return -1; - } - /* ensure we have different hash value for each pkt */ - for (i = 0; i < BURST; i++) - bufs[i]->hash.usr = i; - - start = rte_rdtsc(); - for (i = 0; i < (1<> ITER_POWER); - printf("Time per packet: %"PRIu64"\n\n", - ((end - start) >> ITER_POWER)/BURST); - rte_mempool_put_bulk(p, (void *)bufs, BURST); - - for (i = 0; i < rte_lcore_count() - 1; i++) - printf("Worker %u handled %u packets\n", i, - worker_stats[i].handled_packets); - printf("Total packets: %u (%x)\n", total_packet_count(), - total_packet_count()); - printf("=== Perf test done ===\n\n"); - - return 0; -} - -/* Useful function which ensures that all worker functions terminate */ -static void -quit_workers(struct rte_distributor *d, struct rte_mempool *p) -{ - const unsigned num_workers = rte_lcore_count() - 1; - unsigned i; - struct rte_mbuf *bufs[RTE_MAX_LCORE]; - rte_mempool_get_bulk(p, (void *)bufs, num_workers); - - quit = 1; - for (i = 0; i < num_workers; i++) - bufs[i]->hash.usr = i << 1; - rte_distributor_process(d, bufs, num_workers); - - rte_mempool_put_bulk(p, (void *)bufs, num_workers); - - rte_distributor_process(d, NULL, 0); - rte_eal_mp_wait_lcore(); - quit = 0; - worker_idx = 0; -} - -static int -test_distributor_perf(void) -{ - static struct rte_distributor *d; - static struct rte_mempool *p; - - if (rte_lcore_count() < 2) { - printf("ERROR: not enough cores to test distributor\n"); - return -1; - } - - /* first time how long it takes to round-trip a cache line */ - time_cache_line_switch(); - - if (d == NULL) { - d = rte_distributor_create("Test_perf", rte_socket_id(), - rte_lcore_count() - 1); - if (d == NULL) { - printf("Error creating distributor\n"); - return -1; - } - } else { - rte_distributor_flush(d); - rte_distributor_clear_returns(d); - } - - const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ? - (BIG_BATCH * 2) - 1 : (511 * rte_lcore_count()); - if (p == NULL) { - p = rte_pktmbuf_pool_create("DPT_MBUF_POOL", nb_bufs, BURST, - 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - if (p == NULL) { - printf("Error creating mempool\n"); - return -1; - } - } - - rte_eal_mp_remote_launch(handle_work, d, SKIP_MASTER); - if (perf_test(d, p) < 0) - return -1; - quit_workers(d, p); - - return 0; -} - -REGISTER_TEST_COMMAND(distributor_perf_autotest, test_distributor_perf); diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c deleted file mode 100644 index 91b40664ba..0000000000 --- a/app/test/test_eal_flags.c +++ /dev/null @@ -1,1444 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * Copyright(c) 2014 6WIND S.A. - * 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 - -#include "test.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "process.h" - -#ifdef RTE_LIBRTE_XEN_DOM0 -#define DEFAULT_MEM_SIZE "30" -#else -#define DEFAULT_MEM_SIZE "18" -#endif -#define mp_flag "--proc-type=secondary" -#define no_hpet "--no-hpet" -#define no_huge "--no-huge" -#define no_shconf "--no-shconf" -#define pci_whitelist "--pci-whitelist" -#define vdev "--vdev" -#define memtest "memtest" -#define memtest1 "memtest1" -#define memtest2 "memtest2" -#define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 10) -#define launch_proc(ARGV) process_dup(ARGV, \ - sizeof(ARGV)/(sizeof(ARGV[0])), __func__) - -enum hugepage_action { - HUGEPAGE_CHECK_EXISTS = 0, - HUGEPAGE_CHECK_LOCKED, - HUGEPAGE_DELETE, - HUGEPAGE_INVALID -}; - -/* if string contains a hugepage path */ -static int -get_hugepage_path(char * src, int src_len, char * dst, int dst_len) -{ -#define NUM_TOKENS 4 - char *tokens[NUM_TOKENS]; - - /* if we couldn't properly split the string */ - if (rte_strsplit(src, src_len, tokens, NUM_TOKENS, ' ') < NUM_TOKENS) - return 0; - - if (strncmp(tokens[2], "hugetlbfs", sizeof("hugetlbfs")) == 0) { - snprintf(dst, dst_len, "%s", tokens[1]); - return 1; - } - return 0; -} - -/* - * Cycles through hugepage directories and looks for hugepage - * files associated with a given prefix. Depending on value of - * action, the hugepages are checked if they exist, checked if - * they can be locked, or are simply deleted. - * - * Returns 1 if it finds at least one hugepage matching the action - * Returns 0 if no matching hugepages were found - * Returns -1 if it encounters an error - */ -static int -process_hugefiles(const char * prefix, enum hugepage_action action) -{ - FILE * hugedir_handle = NULL; - DIR * hugepage_dir = NULL; - struct dirent *dirent = NULL; - - char hugefile_prefix[PATH_MAX] = {0}; - char hugedir[PATH_MAX] = {0}; - char line[PATH_MAX] = {0}; - - int fd, lck_result, result = 0; - - const int prefix_len = snprintf(hugefile_prefix, - sizeof(hugefile_prefix), "%smap_", prefix); - if (prefix_len <= 0 || prefix_len >= (int)sizeof(hugefile_prefix) - || prefix_len >= (int)sizeof(dirent->d_name)) { - printf("Error creating hugefile filename prefix\n"); - return -1; - } - - /* get hugetlbfs mountpoints from /proc/mounts */ - hugedir_handle = fopen("/proc/mounts", "r"); - - if (hugedir_handle == NULL) { - printf("Error parsing /proc/mounts!\n"); - return -1; - } - - /* read and parse script output */ - while (fgets(line, sizeof(line), hugedir_handle) != NULL) { - - /* check if we have a hugepage filesystem path */ - if (!get_hugepage_path(line, sizeof(line), hugedir, sizeof(hugedir))) - continue; - - /* check if directory exists */ - if ((hugepage_dir = opendir(hugedir)) == NULL) { - fclose(hugedir_handle); - printf("Error reading %s: %s\n", hugedir, strerror(errno)); - return -1; - } - - while ((dirent = readdir(hugepage_dir)) != NULL) { - if (memcmp(dirent->d_name, hugefile_prefix, prefix_len) != 0) - continue; - - switch (action) { - case HUGEPAGE_CHECK_EXISTS: - { - /* file exists, return */ - result = 1; - goto end; - } - break; - case HUGEPAGE_DELETE: - { - char file_path[PATH_MAX] = {0}; - - snprintf(file_path, sizeof(file_path), - "%s/%s", hugedir, dirent->d_name); - - /* remove file */ - if (remove(file_path) < 0) { - printf("Error deleting %s - %s!\n", - dirent->d_name, strerror(errno)); - closedir(hugepage_dir); - result = -1; - goto end; - } - result = 1; - } - break; - case HUGEPAGE_CHECK_LOCKED: - { - /* try and lock the file */ - fd = openat(dirfd(hugepage_dir), dirent->d_name, O_RDONLY); - - /* this shouldn't happen */ - if (fd == -1) { - printf("Error opening %s - %s!\n", - dirent->d_name, strerror(errno)); - closedir(hugepage_dir); - result = -1; - goto end; - } - - /* non-blocking lock */ - lck_result = flock(fd, LOCK_EX | LOCK_NB); - - /* if lock succeeds, there's something wrong */ - if (lck_result != -1) { - result = 0; - - /* unlock the resulting lock */ - flock(fd, LOCK_UN); - close(fd); - closedir(hugepage_dir); - goto end; - } - result = 1; - close(fd); - } - break; - /* shouldn't happen */ - default: - goto end; - } /* switch */ - - } /* read hugepage directory */ - closedir(hugepage_dir); - } /* read /proc/mounts */ -end: - fclose(hugedir_handle); - return result; -} - -#ifdef RTE_EXEC_ENV_LINUXAPP -/* - * count the number of "node*" files in /sys/devices/system/node/ - */ -static int -get_number_of_sockets(void) -{ - struct dirent *dirent = NULL; - const char * nodedir = "/sys/devices/system/node/"; - DIR * dir = NULL; - int result = 0; - - /* check if directory exists */ - if ((dir = opendir(nodedir)) == NULL) { - /* if errno==ENOENT this means we don't have NUMA support */ - if (errno == ENOENT) { - printf("No NUMA nodes detected: assuming 1 available socket\n"); - return 1; - } - printf("Error opening %s: %s\n", nodedir, strerror(errno)); - return -1; - } - - while ((dirent = readdir(dir)) != NULL) - if (strncmp(dirent->d_name, "node", sizeof("node") - 1) == 0) - result++; - - closedir(dir); - return result; -} -#endif - -static char* -get_current_prefix(char * prefix, int size) -{ - char path[PATH_MAX] = {0}; - char buf[PATH_MAX] = {0}; - - /* get file for config (fd is always 3) */ - snprintf(path, sizeof(path), "/proc/self/fd/%d", 3); - - /* return NULL on error */ - if (readlink(path, buf, sizeof(buf)) == -1) - return NULL; - - /* get the basename */ - snprintf(buf, sizeof(buf), "%s", basename(buf)); - - /* copy string all the way from second char up to start of _config */ - snprintf(prefix, size, "%.*s", - (int)(strnlen(buf, sizeof(buf)) - sizeof("_config")), - &buf[1]); - - return prefix; -} - -/* - * Test that the app doesn't run with invalid whitelist option. - * Final tests ensures it does run with valid options as sanity check (one - * test for with Domain+BDF, second for just with BDF) - */ -static int -test_whitelist_flag(void) -{ - unsigned i; -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point */ - const char * prefix = ""; -#else - char prefix[PATH_MAX], tmp[PATH_MAX]; - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); -#endif - - const char *wlinval[][11] = { - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "error", "", ""}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "0:0:0", "", ""}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "0:error:0.1", "", ""}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "0:0:0.1error", "", ""}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "error0:0:0.1", "", ""}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "0:0:0.1.2", "", ""}, - }; - /* Test with valid whitelist option */ - const char *wlval1[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "00FF:09:0B.3"}; - const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "09:0B.3", pci_whitelist, "0a:0b.1"}; - const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", - pci_whitelist, "09:0B.3,type=test", - pci_whitelist, "08:00.1,type=normal", - }; - - for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) { - if (launch_proc(wlinval[i]) == 0) { - printf("Error - process did run ok with invalid " - "whitelist parameter\n"); - return -1; - } - } - if (launch_proc(wlval1) != 0 ) { - printf("Error - process did not run ok with valid whitelist\n"); - return -1; - } - if (launch_proc(wlval2) != 0 ) { - printf("Error - process did not run ok with valid whitelist value set\n"); - return -1; - } - if (launch_proc(wlval3) != 0 ) { - printf("Error - process did not run ok with valid whitelist + args\n"); - return -1; - } - - return 0; -} - -/* - * Test that the app doesn't run with invalid blacklist option. - * Final test ensures it does run with valid options as sanity check - */ -static int -test_invalid_b_flag(void) -{ -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point */ - const char * prefix = ""; -#else - char prefix[PATH_MAX], tmp[PATH_MAX]; - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); -#endif - - const char *blinval[][9] = { - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error"}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0"}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:error:0.1"}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1error"}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error0:0:0.1"}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1.2"}, - }; - /* Test with valid blacklist option */ - const char *blval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "FF:09:0B.3"}; - - int i; - - for (i = 0; i != sizeof (blinval) / sizeof (blinval[0]); i++) { - if (launch_proc(blinval[i]) == 0) { - printf("Error - process did run ok with invalid " - "blacklist parameter\n"); - return -1; - } - } - if (launch_proc(blval) != 0) { - printf("Error - process did not run ok with valid blacklist value\n"); - return -1; - } - return 0; -} - -/* - * Test that the app doesn't run with invalid vdev option. - * Final test ensures it does run with valid options as sanity check - */ -#ifdef RTE_LIBRTE_PMD_RING -static int -test_invalid_vdev_flag(void) -{ -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point, and we also need to - * run another primary process here */ - const char * prefix = no_shconf; -#else - const char * prefix = "--file-prefix=vdev"; -#endif - - /* Test with invalid vdev option */ - const char *vdevinval[] = {prgname, prefix, "-n", "1", - "-c", "1", vdev, "eth_dummy"}; - - /* Test with valid vdev option */ - const char *vdevval1[] = {prgname, prefix, "-n", "1", - "-c", "1", vdev, "net_ring0"}; - - const char *vdevval2[] = {prgname, prefix, "-n", "1", - "-c", "1", vdev, "net_ring0,args=test"}; - - const char *vdevval3[] = {prgname, prefix, "-n", "1", - "-c", "1", vdev, "net_ring0,nodeaction=r1:0:CREATE"}; - - if (launch_proc(vdevinval) == 0) { - printf("Error - process did run ok with invalid " - "vdev parameter\n"); - return -1; - } - - if (launch_proc(vdevval1) != 0) { - printf("Error - process did not run ok with valid vdev value\n"); - return -1; - } - - if (launch_proc(vdevval2) != 0) { - printf("Error - process did not run ok with valid vdev value," - "with dummy args\n"); - return -1; - } - - if (launch_proc(vdevval3) != 0) { - printf("Error - process did not run ok with valid vdev value," - "with valid args\n"); - return -1; - } - return 0; -} -#endif - -/* - * Test that the app doesn't run with invalid -r option. - */ -static int -test_invalid_r_flag(void) -{ -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point */ - const char * prefix = ""; -#else - char prefix[PATH_MAX], tmp[PATH_MAX]; - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); -#endif - - const char *rinval[][9] = { - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "error"}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "0"}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "-1"}, - {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "17"}, - }; - /* Test with valid blacklist option */ - const char *rval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "16"}; - - int i; - - for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); i++) { - if (launch_proc(rinval[i]) == 0) { - printf("Error - process did run ok with invalid " - "-r (rank) parameter\n"); - return -1; - } - } - if (launch_proc(rval) != 0) { - printf("Error - process did not run ok with valid -r (rank) value\n"); - return -1; - } - return 0; -} - -/* - * Test that the app doesn't run without the coremask/corelist flags. In all cases - * should give an error and fail to run - */ -static int -test_missing_c_flag(void) -{ -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point */ - const char * prefix = ""; -#else - char prefix[PATH_MAX], tmp[PATH_MAX]; - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); -#endif - - /* -c flag but no coremask value */ - const char *argv1[] = { prgname, prefix, mp_flag, "-n", "3", "-c"}; - /* No -c, -l or --lcores flag at all */ - const char *argv2[] = { prgname, prefix, mp_flag, "-n", "3"}; - /* bad coremask value */ - const char *argv3[] = { prgname, prefix, mp_flag, - "-n", "3", "-c", "error" }; - /* sanity check of tests - valid coremask value */ - const char *argv4[] = { prgname, prefix, mp_flag, - "-n", "3", "-c", "1" }; - /* -l flag but no corelist value */ - const char *argv5[] = { prgname, prefix, mp_flag, - "-n", "3", "-l"}; - const char *argv6[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", " " }; - /* bad corelist values */ - const char *argv7[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "error" }; - const char *argv8[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "1-" }; - const char *argv9[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "1," }; - const char *argv10[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "1#2" }; - /* sanity check test - valid corelist value */ - const char *argv11[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "1-2,3" }; - - /* --lcores flag but no lcores value */ - const char *argv12[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores" }; - const char *argv13[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", " " }; - /* bad lcores value */ - const char *argv14[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "1-3-5" }; - const char *argv15[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "0-1,,2" }; - const char *argv16[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "0-,1" }; - const char *argv17[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(0-,2-4)" }; - const char *argv18[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(-1,2)" }; - const char *argv19[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(2-4)@(2-4-6)" }; - const char *argv20[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(a,2)" }; - const char *argv21[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "1-3@(1,3)" }; - const char *argv22[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "3@((1,3)" }; - const char *argv23[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(4-7)=(1,3)" }; - const char *argv24[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "[4-7]@(1,3)" }; - /* sanity check of tests - valid lcores value */ - const char *argv25[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", - "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"}; - - if (launch_proc(argv2) != 0) { - printf("Error - " - "process did not run ok when missing -c flag\n"); - return -1; - } - - if (launch_proc(argv1) == 0 - || launch_proc(argv3) == 0) { - printf("Error - " - "process ran without error with invalid -c flag\n"); - return -1; - } - if (launch_proc(argv4) != 0) { - printf("Error - " - "process did not run ok with valid coremask value\n"); - return -1; - } - - /* start -l test */ - if (launch_proc(argv5) == 0 - || launch_proc(argv6) == 0 - || launch_proc(argv7) == 0 - || launch_proc(argv8) == 0 - || launch_proc(argv9) == 0 - || launch_proc(argv10) == 0) { - printf("Error - " - "process ran without error with invalid -l flag\n"); - return -1; - } - if (launch_proc(argv11) != 0) { - printf("Error - " - "process did not run ok with valid corelist value\n"); - return -1; - } - - /* start --lcores tests */ - if (launch_proc(argv12) == 0 || launch_proc(argv13) == 0 || - launch_proc(argv14) == 0 || launch_proc(argv15) == 0 || - launch_proc(argv16) == 0 || launch_proc(argv17) == 0 || - launch_proc(argv18) == 0 || launch_proc(argv19) == 0 || - launch_proc(argv20) == 0 || launch_proc(argv21) == 0 || - launch_proc(argv21) == 0 || launch_proc(argv22) == 0 || - launch_proc(argv23) == 0 || launch_proc(argv24) == 0) { - printf("Error - " - "process ran without error with invalid --lcore flag\n"); - return -1; - } - - if (launch_proc(argv25) != 0) { - printf("Error - " - "process did not run ok with valid corelist value\n"); - return -1; - } - - return 0; -} - -/* - * Test --master-lcore option with matching coremask - */ -static int -test_master_lcore_flag(void) -{ -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point */ - const char *prefix = ""; -#else - char prefix[PATH_MAX], tmp[PATH_MAX]; - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); -#endif - - /* --master-lcore flag but no value */ - const char *argv1[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore"}; - /* --master-lcore flag with invalid value */ - const char *argv2[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "-1"}; - const char *argv3[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "X"}; - /* master lcore not in coremask */ - const char *argv4[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "2"}; - /* valid value */ - const char *argv5[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "1"}; - /* valid value set before coremask */ - const char *argv6[] = { prgname, prefix, mp_flag, "-n", "1", "--master-lcore", "1", "-c", "3"}; - - if (launch_proc(argv1) == 0 - || launch_proc(argv2) == 0 - || launch_proc(argv3) == 0 - || launch_proc(argv4) == 0) { - printf("Error - process ran without error with wrong --master-lcore\n"); - return -1; - } - if (launch_proc(argv5) != 0 - || launch_proc(argv6) != 0) { - printf("Error - process did not run ok with valid --master-lcore\n"); - return -1; - } - return 0; -} - -/* - * Test that the app doesn't run with invalid -n flag option. - * Final test ensures it does run with valid options as sanity check - * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf - * flags. - */ -static int -test_invalid_n_flag(void) -{ -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point */ - const char * prefix = ""; -#else - char prefix[PATH_MAX], tmp[PATH_MAX]; - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); -#endif - - /* -n flag but no value */ - const char *argv1[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n"}; - /* bad numeric value */ - const char *argv2[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "e" }; - /* zero is invalid */ - const char *argv3[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "0" }; - /* sanity test - check with good value */ - const char *argv4[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "2" }; - /* sanity test - check with no -n flag */ - const char *argv5[] = { prgname, prefix, no_huge, no_shconf, "-c", "1"}; - - if (launch_proc(argv1) == 0 - || launch_proc(argv2) == 0 - || launch_proc(argv3) == 0) { - printf("Error - process ran without error when" - "invalid -n flag\n"); - return -1; - } - if (launch_proc(argv4) != 0) { - printf("Error - process did not run ok with valid num-channel value\n"); - return -1; - } - if (launch_proc(argv5) != 0) { - printf("Error - process did not run ok without -n flag\n"); - return -1; - } - - return 0; -} - -/* - * Test that the app runs with HPET, and without HPET - */ -static int -test_no_hpet_flag(void) -{ - char prefix[PATH_MAX], tmp[PATH_MAX]; - -#ifdef RTE_EXEC_ENV_BSDAPP - return 0; -#endif - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); - - /* With --no-hpet */ - const char *argv1[] = {prgname, prefix, mp_flag, no_hpet, "-c", "1", "-n", "2"}; - /* Without --no-hpet */ - const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-n", "2"}; - - if (launch_proc(argv1) != 0) { - printf("Error - process did not run ok with --no-hpet flag\n"); - return -1; - } - if (launch_proc(argv2) != 0) { - printf("Error - process did not run ok without --no-hpet flag\n"); - return -1; - } - return 0; -} - -/* - * Test that the app runs with --no-huge and doesn't run when --socket-mem are - * specified with --no-huge. - */ -static int -test_no_huge_flag(void) -{ -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point, and we also need to - * run another primary process here */ - const char * prefix = no_shconf; -#else - const char * prefix = "--file-prefix=nohuge"; -#endif - - /* With --no-huge */ - const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2"}; - /* With --no-huge and -m */ - const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", - "-m", DEFAULT_MEM_SIZE}; - - /* With --no-huge and --socket-mem */ - const char *argv3[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", - "--socket-mem=" DEFAULT_MEM_SIZE}; - /* With --no-huge, -m and --socket-mem */ - const char *argv4[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", - "-m", DEFAULT_MEM_SIZE, "--socket-mem=" DEFAULT_MEM_SIZE}; - if (launch_proc(argv1) != 0) { - printf("Error - process did not run ok with --no-huge flag\n"); - return -1; - } - if (launch_proc(argv2) != 0) { - printf("Error - process did not run ok with --no-huge and -m flags\n"); - return -1; - } -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target does not support NUMA, hence no --socket-mem tests */ - return 0; -#endif - - if (launch_proc(argv3) == 0) { - printf("Error - process run ok with --no-huge and --socket-mem " - "flags\n"); - return -1; - } - if (launch_proc(argv4) == 0) { - printf("Error - process run ok with --no-huge, -m and " - "--socket-mem flags\n"); - return -1; - } - return 0; -} - -#ifdef RTE_LIBRTE_XEN_DOM0 -static int -test_dom0_misc_flags(void) -{ - char prefix[PATH_MAX], tmp[PATH_MAX]; - - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); - - /* check that some general flags don't prevent things from working. - * All cases, apart from the first, app should run. - * No futher testing of output done. - */ - /* sanity check - failure with invalid option */ - const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"}; - - /* With --no-pci */ - const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"}; - /* With -v */ - const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"}; - /* With valid --syslog */ - const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1", - "--syslog", "syslog"}; - /* With empty --syslog (should fail) */ - const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"}; - /* With invalid --syslog */ - const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"}; - /* With no-sh-conf */ - const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "20", - "--no-shconf", "--file-prefix=noshconf" }; - - if (launch_proc(argv0) == 0) { - printf("Error - process ran ok with invalid flag\n"); - return -1; - } - if (launch_proc(argv1) != 0) { - printf("Error - process did not run ok with --no-pci flag\n"); - return -1; - } - if (launch_proc(argv2) != 0) { - printf("Error - process did not run ok with -v flag\n"); - return -1; - } - if (launch_proc(argv3) != 0) { - printf("Error - process did not run ok with --syslog flag\n"); - return -1; - } - if (launch_proc(argv4) == 0) { - printf("Error - process run ok with empty --syslog flag\n"); - return -1; - } - if (launch_proc(argv5) == 0) { - printf("Error - process run ok with invalid --syslog flag\n"); - return -1; - } - if (launch_proc(argv6) != 0) { - printf("Error - process did not run ok with --no-shconf flag\n"); - return -1; - } - - return 0; -} -#else -static int -test_misc_flags(void) -{ - char hugepath[PATH_MAX] = {0}; -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point */ - const char * prefix = ""; - const char * nosh_prefix = ""; -#else - char prefix[PATH_MAX], tmp[PATH_MAX]; - const char * nosh_prefix = "--file-prefix=noshconf"; - FILE * hugedir_handle = NULL; - char line[PATH_MAX] = {0}; - unsigned i, isempty = 1; - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); - - /* - * get first valid hugepage path - */ - - /* get hugetlbfs mountpoints from /proc/mounts */ - hugedir_handle = fopen("/proc/mounts", "r"); - - if (hugedir_handle == NULL) { - printf("Error opening /proc/mounts!\n"); - return -1; - } - - /* read /proc/mounts */ - while (fgets(line, sizeof(line), hugedir_handle) != NULL) { - - /* find first valid hugepath */ - if (get_hugepage_path(line, sizeof(line), hugepath, sizeof(hugepath))) - break; - } - - fclose(hugedir_handle); - - /* check if path is not empty */ - for (i = 0; i < sizeof(hugepath); i++) - if (hugepath[i] != '\0') - isempty = 0; - - if (isempty) { - printf("No mounted hugepage dir found!\n"); - return -1; - } -#endif - - - /* check that some general flags don't prevent things from working. - * All cases, apart from the first, app should run. - * No futher testing of output done. - */ - /* sanity check - failure with invalid option */ - const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"}; - - /* With --no-pci */ - const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"}; - /* With -v */ - const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"}; - /* With valid --syslog */ - const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1", - "--syslog", "syslog"}; - /* With empty --syslog (should fail) */ - const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"}; - /* With invalid --syslog */ - const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"}; - /* With no-sh-conf */ - const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, - no_shconf, nosh_prefix }; - -#ifdef RTE_EXEC_ENV_BSDAPP - return 0; -#endif - /* With --huge-dir */ - const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, - "--file-prefix=hugedir", "--huge-dir", hugepath}; - /* With empty --huge-dir (should fail) */ - const char *argv8[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, - "--file-prefix=hugedir", "--huge-dir"}; - /* With invalid --huge-dir */ - const char *argv9[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, - "--file-prefix=hugedir", "--huge-dir", "invalid"}; - /* Secondary process with invalid --huge-dir (should run as flag has no - * effect on secondary processes) */ - const char *argv10[] = {prgname, prefix, mp_flag, "-c", "1", "--huge-dir", "invalid"}; - - /* try running with base-virtaddr param */ - const char *argv11[] = {prgname, "--file-prefix=virtaddr", - "-c", "1", "-n", "2", "--base-virtaddr=0x12345678"}; - - /* try running with --vfio-intr INTx flag */ - const char *argv12[] = {prgname, "--file-prefix=intr", - "-c", "1", "-n", "2", "--vfio-intr=legacy"}; - - /* try running with --vfio-intr MSI flag */ - const char *argv13[] = {prgname, "--file-prefix=intr", - "-c", "1", "-n", "2", "--vfio-intr=msi"}; - - /* try running with --vfio-intr MSI-X flag */ - const char *argv14[] = {prgname, "--file-prefix=intr", - "-c", "1", "-n", "2", "--vfio-intr=msix"}; - - /* try running with --vfio-intr invalid flag */ - const char *argv15[] = {prgname, "--file-prefix=intr", - "-c", "1", "-n", "2", "--vfio-intr=invalid"}; - - - if (launch_proc(argv0) == 0) { - printf("Error - process ran ok with invalid flag\n"); - return -1; - } - if (launch_proc(argv1) != 0) { - printf("Error - process did not run ok with --no-pci flag\n"); - return -1; - } - if (launch_proc(argv2) != 0) { - printf("Error - process did not run ok with -v flag\n"); - return -1; - } - if (launch_proc(argv3) != 0) { - printf("Error - process did not run ok with --syslog flag\n"); - return -1; - } - if (launch_proc(argv4) == 0) { - printf("Error - process run ok with empty --syslog flag\n"); - return -1; - } - if (launch_proc(argv5) == 0) { - printf("Error - process run ok with invalid --syslog flag\n"); - return -1; - } - if (launch_proc(argv6) != 0) { - printf("Error - process did not run ok with --no-shconf flag\n"); - return -1; - } -#ifdef RTE_EXEC_ENV_BSDAPP - return 0; -#endif - if (launch_proc(argv7) != 0) { - printf("Error - process did not run ok with --huge-dir flag\n"); - return -1; - } - if (launch_proc(argv8) == 0) { - printf("Error - process run ok with empty --huge-dir flag\n"); - return -1; - } - if (launch_proc(argv9) == 0) { - printf("Error - process run ok with invalid --huge-dir flag\n"); - return -1; - } - if (launch_proc(argv10) != 0) { - printf("Error - secondary process did not run ok with invalid --huge-dir flag\n"); - return -1; - } - if (launch_proc(argv11) != 0) { - printf("Error - process did not run ok with --base-virtaddr parameter\n"); - return -1; - } - if (launch_proc(argv12) != 0) { - printf("Error - process did not run ok with " - "--vfio-intr INTx parameter\n"); - return -1; - } - if (launch_proc(argv13) != 0) { - printf("Error - process did not run ok with " - "--vfio-intr MSI parameter\n"); - return -1; - } - if (launch_proc(argv14) != 0) { - printf("Error - process did not run ok with " - "--vfio-intr MSI-X parameter\n"); - return -1; - } - if (launch_proc(argv15) == 0) { - printf("Error - process run ok with " - "--vfio-intr invalid parameter\n"); - return -1; - } - return 0; -} -#endif - -static int -test_file_prefix(void) -{ - /* - * 1. check if current process hugefiles are locked - * 2. try to run secondary process without a corresponding primary process - * (while failing to run, it will also remove any unused hugepage files) - * 3. check if current process hugefiles are still in place and are locked - * 4. run a primary process with memtest1 prefix - * 5. check if memtest1 hugefiles are created - * 6. run a primary process with memtest2 prefix - * 7. check that only memtest2 hugefiles are present in the hugedir - */ - -#ifdef RTE_EXEC_ENV_BSDAPP - return 0; -#endif - - /* this should fail unless the test itself is run with "memtest" prefix */ - const char *argv0[] = {prgname, mp_flag, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, - "--file-prefix=" memtest }; - - /* primary process with memtest1 */ - const char *argv1[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, - "--file-prefix=" memtest1 }; - - /* primary process with memtest2 */ - const char *argv2[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, - "--file-prefix=" memtest2 }; - - char prefix[32]; - if (get_current_prefix(prefix, sizeof(prefix)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } -#ifdef RTE_LIBRTE_XEN_DOM0 - return 0; -#endif - - /* check if files for current prefix are present */ - if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) { - printf("Error - hugepage files for %s were not created!\n", prefix); - return -1; - } - - /* checks if files for current prefix are locked */ - if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) { - printf("Error - hugepages for current process aren't locked!\n"); - return -1; - } - - /* check if files for secondary process are present */ - if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) { - /* check if they are not locked */ - if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) { - printf("Error - hugepages for current process are locked!\n"); - return -1; - } - /* they aren't locked, delete them */ - else { - if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) { - printf("Error - deleting hugepages failed!\n"); - return -1; - } - } - } - - if (launch_proc(argv0) == 0) { - printf("Error - secondary process ran ok without primary process\n"); - return -1; - } - - /* check if files for current prefix are present */ - if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) { - printf("Error - hugepage files for %s were not created!\n", prefix); - return -1; - } - - /* checks if files for current prefix are locked */ - if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) { - printf("Error - hugepages for current process aren't locked!\n"); - return -1; - } - - if (launch_proc(argv1) != 0) { - printf("Error - failed to run with --file-prefix=%s\n", memtest); - return -1; - } - - /* check if memtest1_map0 is present */ - if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) { - printf("Error - hugepage files for %s were not created!\n", memtest1); - return -1; - } - - if (launch_proc(argv2) != 0) { - printf("Error - failed to run with --file-prefix=%s\n", memtest2); - return -1; - } - - /* check if hugefiles for memtest2 are present */ - if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) { - printf("Error - hugepage files for %s were not created!\n", memtest2); - return -1; - } - - /* check if hugefiles for memtest1 are present */ - if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { - printf("Error - hugepage files for %s were not deleted!\n", memtest1); - return -1; - } - - return 0; -} - -/* - * Tests for correct handling of -m and --socket-mem flags - */ -static int -test_memory_flags(void) -{ -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD target doesn't support prefixes at this point */ - const char * prefix = ""; -#else - char prefix[PATH_MAX], tmp[PATH_MAX]; - if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); -#endif - - /* valid -m flag and mp flag */ - const char *argv0[] = {prgname, prefix, mp_flag, "-c", "10", - "-n", "2", "-m", DEFAULT_MEM_SIZE}; - - /* valid -m flag */ - const char *argv1[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE}; - - /* invalid (zero) --socket-mem flag */ - const char *argv2[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, "--socket-mem=0,0,0,0"}; - - /* invalid (incomplete) --socket-mem flag */ - const char *argv3[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, "--socket-mem=2,2,"}; - - /* invalid (mixed with invalid data) --socket-mem flag */ - const char *argv4[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, "--socket-mem=2,2,Fred"}; - - /* invalid (with numeric value as last character) --socket-mem flag */ - const char *argv5[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, "--socket-mem=2,2,Fred0"}; - - /* invalid (with empty socket) --socket-mem flag */ - const char *argv6[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, "--socket-mem=2,,2"}; - - /* invalid (null) --socket-mem flag */ - const char *argv7[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, "--socket-mem="}; - - /* valid --socket-mem specified together with -m flag */ - const char *argv8[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE, "--socket-mem=2,2"}; - - /* construct an invalid socket mask with 2 megs on each socket plus - * extra 2 megs on socket that doesn't exist on current system */ - char invalid_socket_mem[SOCKET_MEM_STRLEN]; - char buf[SOCKET_MEM_STRLEN]; /* to avoid copying string onto itself */ - -#ifdef RTE_EXEC_ENV_BSDAPP - int i, num_sockets = 1; -#else - int i, num_sockets = get_number_of_sockets(); -#endif - - if (num_sockets <= 0 || num_sockets > RTE_MAX_NUMA_NODES) { - printf("Error - cannot get number of sockets!\n"); - return -1; - } - - snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "--socket-mem="); - - /* add one extra socket */ - for (i = 0; i < num_sockets + 1; i++) { - snprintf(buf, sizeof(buf), "%s%s", invalid_socket_mem, DEFAULT_MEM_SIZE); - snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf); - - if (num_sockets + 1 - i > 1) { - snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem); - snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf); - } - } - - /* construct a valid socket mask with 2 megs on each existing socket */ - char valid_socket_mem[SOCKET_MEM_STRLEN]; - - snprintf(valid_socket_mem, sizeof(valid_socket_mem), "--socket-mem="); - - /* add one extra socket */ - for (i = 0; i < num_sockets; i++) { - snprintf(buf, sizeof(buf), "%s%s", valid_socket_mem, DEFAULT_MEM_SIZE); - snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf); - - if (num_sockets - i > 1) { - snprintf(buf, sizeof(buf), "%s,", valid_socket_mem); - snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf); - } - } - - /* invalid --socket-mem flag (with extra socket) */ - const char *argv9[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, invalid_socket_mem}; - - /* valid --socket-mem flag */ - const char *argv10[] = {prgname, "-c", "10", "-n", "2", - "--file-prefix=" memtest, valid_socket_mem}; - - if (launch_proc(argv0) != 0) { - printf("Error - secondary process failed with valid -m flag !\n"); - return -1; - } - -#ifdef RTE_EXEC_ENV_BSDAPP - /* no other tests are applicable to BSD */ - return 0; -#endif - - if (launch_proc(argv1) != 0) { - printf("Error - process failed with valid -m flag!\n"); - return -1; - } -#ifdef RTE_LIBRTE_XEN_DOM0 - return 0; -#endif - if (launch_proc(argv2) == 0) { - printf("Error - process run ok with invalid (zero) --socket-mem!\n"); - return -1; - } - - if (launch_proc(argv3) == 0) { - printf("Error - process run ok with invalid " - "(incomplete) --socket-mem!\n"); - return -1; - } - - if (launch_proc(argv4) == 0) { - printf("Error - process run ok with invalid " - "(mixed with invalid input) --socket-mem!\n"); - return -1; - } - - if (launch_proc(argv5) == 0) { - printf("Error - process run ok with invalid " - "(mixed with invalid input with a numeric value as " - "last character) --socket-mem!\n"); - return -1; - } - - if (launch_proc(argv6) == 0) { - printf("Error - process run ok with invalid " - "(with empty socket) --socket-mem!\n"); - return -1; - } - - if (launch_proc(argv7) == 0) { - printf("Error - process run ok with invalid (null) --socket-mem!\n"); - return -1; - } - - if (launch_proc(argv8) == 0) { - printf("Error - process run ok with --socket-mem and -m specified!\n"); - return -1; - } - - if (launch_proc(argv9) == 0) { - printf("Error - process run ok with extra socket in --socket-mem!\n"); - return -1; - } - - if (launch_proc(argv10) != 0) { - printf("Error - process failed with valid --socket-mem!\n"); - return -1; - } - - return 0; -} - -static int -test_eal_flags(void) -{ - int ret = 0; - - ret = test_missing_c_flag(); - if (ret < 0) { - printf("Error in test_missing_c_flag()\n"); - return ret; - } - - ret = test_master_lcore_flag(); - if (ret < 0) { - printf("Error in test_master_lcore_flag()\n"); - return ret; - } - - ret = test_invalid_n_flag(); - if (ret < 0) { - printf("Error in test_invalid_n_flag()\n"); - return ret; - } - - ret = test_no_hpet_flag(); - if (ret < 0) { - printf("Error in test_no_hpet_flag()\n"); - return ret; - } - - ret = test_no_huge_flag(); - if (ret < 0) { - printf("Error in test_no_huge_flag()\n"); - return ret; - } - - ret = test_whitelist_flag(); - if (ret < 0) { - printf("Error in test_invalid_whitelist_flag()\n"); - return ret; - } - - ret = test_invalid_b_flag(); - if (ret < 0) { - printf("Error in test_invalid_b_flag()\n"); - return ret; - } - -#ifdef RTE_LIBRTE_PMD_RING - ret = test_invalid_vdev_flag(); - if (ret < 0) { - printf("Error in test_invalid_vdev_flag()\n"); - return ret; - } -#endif - ret = test_invalid_r_flag(); - if (ret < 0) { - printf("Error in test_invalid_r_flag()\n"); - return ret; - } - - ret = test_memory_flags(); - if (ret < 0) { - printf("Error in test_memory_flags()\n"); - return ret; - } - - ret = test_file_prefix(); - if (ret < 0) { - printf("Error in test_file_prefix()\n"); - return ret; - } - -#ifdef RTE_LIBRTE_XEN_DOM0 - ret = test_dom0_misc_flags(); -#else - ret = test_misc_flags(); -#endif - if (ret < 0) { - printf("Error in test_misc_flags()"); - return ret; - } - - return ret; -} - -REGISTER_TEST_COMMAND(eal_flags_autotest, test_eal_flags); diff --git a/app/test/test_eal_fs.c b/app/test/test_eal_fs.c deleted file mode 100644 index 78978120cd..0000000000 --- a/app/test/test_eal_fs.c +++ /dev/null @@ -1,206 +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 "test.h" -#include -#include -#include -#include - -/* eal_filesystem.h is not a public header file, so use relative path */ -#include "../../lib/librte_eal/common/eal_filesystem.h" - -static int -test_parse_sysfs_value(void) -{ - char filename[PATH_MAX] = ""; - char proc_path[PATH_MAX]; - char file_template[] = "/tmp/eal_test_XXXXXX"; - int tmp_file_handle = -1; - FILE *fd = NULL; - unsigned valid_number; - unsigned long retval = 0; - -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD doesn't have /proc/pid/fd */ - return 0; -#endif - - printf("Testing function eal_parse_sysfs_value()\n"); - - /* get a temporary filename to use for all tests - create temp file handle and then - * use /proc to get the actual file that we can open */ - tmp_file_handle = mkstemp(file_template); - if (tmp_file_handle == -1) { - perror("mkstemp() failure"); - goto error; - } - snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", tmp_file_handle); - if (readlink(proc_path, filename, sizeof(filename)) < 0) { - perror("readlink() failure"); - goto error; - } - printf("Temporary file is: %s\n", filename); - - /* test we get an error value if we use file before it's created */ - printf("Test reading a missing file ...\n"); - if (eal_parse_sysfs_value("/dev/not-quite-null", &retval) == 0) { - printf("Error with eal_parse_sysfs_value() - returned success on reading empty file\n"); - goto error; - } - printf("Confirmed return error when reading empty file\n"); - - /* test reading a valid number value with "\n" on the end */ - printf("Test reading valid values ...\n"); - valid_number = 15; - fd = fopen(filename,"w"); - if (fd == NULL) { - printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); - goto error; - } - fprintf(fd,"%u\n", valid_number); - fclose(fd); - fd = NULL; - if (eal_parse_sysfs_value(filename, &retval) < 0) { - printf("eal_parse_sysfs_value() returned error - test failed\n"); - goto error; - } - if (retval != valid_number) { - printf("Invalid value read by eal_parse_sysfs_value() - test failed\n"); - goto error; - } - printf("Read '%u\\n' ok\n", valid_number); - - /* test reading a valid hex number value with "\n" on the end */ - valid_number = 25; - fd = fopen(filename,"w"); - if (fd == NULL) { - printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); - goto error; - } - fprintf(fd,"0x%x\n", valid_number); - fclose(fd); - fd = NULL; - if (eal_parse_sysfs_value(filename, &retval) < 0) { - printf("eal_parse_sysfs_value() returned error - test failed\n"); - goto error; - } - if (retval != valid_number) { - printf("Invalid value read by eal_parse_sysfs_value() - test failed\n"); - goto error; - } - printf("Read '0x%x\\n' ok\n", valid_number); - - printf("Test reading invalid values ...\n"); - - /* test reading an empty file - expect failure!*/ - fd = fopen(filename,"w"); - if (fd == NULL) { - printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); - goto error; - } - fclose(fd); - fd = NULL; - if (eal_parse_sysfs_value(filename, &retval) == 0) { - printf("eal_parse_sysfs_value() read invalid value - test failed\n"); - goto error; - } - - /* test reading a valid number value *without* "\n" on the end - expect failure!*/ - valid_number = 3; - fd = fopen(filename,"w"); - if (fd == NULL) { - printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); - goto error; - } - fprintf(fd,"%u", valid_number); - fclose(fd); - fd = NULL; - if (eal_parse_sysfs_value(filename, &retval) == 0) { - printf("eal_parse_sysfs_value() read invalid value - test failed\n"); - goto error; - } - - /* test reading a valid number value followed by string - expect failure!*/ - valid_number = 3; - fd = fopen(filename,"w"); - if (fd == NULL) { - printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); - goto error; - } - fprintf(fd,"%uJ\n", valid_number); - fclose(fd); - fd = NULL; - if (eal_parse_sysfs_value(filename, &retval) == 0) { - printf("eal_parse_sysfs_value() read invalid value - test failed\n"); - goto error; - } - - /* test reading a non-numeric value - expect failure!*/ - fd = fopen(filename,"w"); - if (fd == NULL) { - printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); - goto error; - } - fprintf(fd,"error\n"); - fclose(fd); - fd = NULL; - if (eal_parse_sysfs_value(filename, &retval) == 0) { - printf("eal_parse_sysfs_value() read invalid value - test failed\n"); - goto error; - } - - close(tmp_file_handle); - unlink(filename); - printf("eal_parse_sysfs_value() - OK\n"); - return 0; - -error: - if (fd) - fclose(fd); - if (tmp_file_handle > 0) - close(tmp_file_handle); - if (filename[0] != '\0') - unlink(filename); - return -1; -} - -static int -test_eal_fs(void) -{ - if (test_parse_sysfs_value() < 0) - return -1; - return 0; -} - -REGISTER_TEST_COMMAND(eal_fs_autotest, test_eal_fs); diff --git a/app/test/test_efd.c b/app/test/test_efd.c deleted file mode 100644 index de49e1d7e1..0000000000 --- a/app/test/test_efd.c +++ /dev/null @@ -1,500 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2016-2017 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 -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define EFD_TEST_KEY_LEN 8 -#define TABLE_SIZE (1 << 21) -#define ITERATIONS 3 - -#if RTE_EFD_VALUE_NUM_BITS == 32 -#define VALUE_BITMASK 0xffffffff -#else -#define VALUE_BITMASK ((1 << RTE_EFD_VALUE_NUM_BITS) - 1) -#endif -static unsigned int test_socket_id; - -/* 5-tuple key type */ -struct flow_key { - uint32_t ip_src; - uint32_t ip_dst; - uint16_t port_src; - uint16_t port_dst; - uint8_t proto; -} __attribute__((packed)); -/* - * Print out result of unit test efd operation. - */ -#if defined(UNIT_TEST_EFD_VERBOSE) - -static void print_key_info(const char *msg, const struct flow_key *key, - efd_value_t val) -{ - const uint8_t *p = (const uint8_t *) key; - unsigned int i; - - printf("%s key:0x", msg); - for (i = 0; i < sizeof(struct flow_key); i++) - printf("%02X", p[i]); - - printf(" @ val %d\n", val); -} -#else - -static void print_key_info(__attribute__((unused)) const char *msg, - __attribute__((unused)) const struct flow_key *key, - __attribute__((unused)) efd_value_t val) -{ -} -#endif - -/* Keys used by unit test functions */ -static struct flow_key keys[5] = { - { - .ip_src = IPv4(0x03, 0x02, 0x01, 0x00), - .ip_dst = IPv4(0x07, 0x06, 0x05, 0x04), - .port_src = 0x0908, - .port_dst = 0x0b0a, - .proto = 0x0c, - }, - { - .ip_src = IPv4(0x13, 0x12, 0x11, 0x10), - .ip_dst = IPv4(0x17, 0x16, 0x15, 0x14), - .port_src = 0x1918, - .port_dst = 0x1b1a, - .proto = 0x1c, - }, - { - .ip_src = IPv4(0x23, 0x22, 0x21, 0x20), - .ip_dst = IPv4(0x27, 0x26, 0x25, 0x24), - .port_src = 0x2928, - .port_dst = 0x2b2a, - .proto = 0x2c, - }, - { - .ip_src = IPv4(0x33, 0x32, 0x31, 0x30), - .ip_dst = IPv4(0x37, 0x36, 0x35, 0x34), - .port_src = 0x3938, - .port_dst = 0x3b3a, - .proto = 0x3c, - }, - { - .ip_src = IPv4(0x43, 0x42, 0x41, 0x40), - .ip_dst = IPv4(0x47, 0x46, 0x45, 0x44), - .port_src = 0x4948, - .port_dst = 0x4b4a, - .proto = 0x4c, - } -}; -/* Array to store the data */ -efd_value_t data[5]; - -static inline uint8_t efd_get_all_sockets_bitmask(void) -{ - uint8_t all_cpu_sockets_bitmask = 0; - unsigned int i; - unsigned int next_lcore = rte_get_master_lcore(); - const int val_true = 1, val_false = 0; - for (i = 0; i < rte_lcore_count(); i++) { - all_cpu_sockets_bitmask |= 1 << rte_lcore_to_socket_id(next_lcore); - next_lcore = rte_get_next_lcore(next_lcore, val_false, val_true); - } - - return all_cpu_sockets_bitmask; -} - -/* - * Basic sequence of operations for a single key: - * - add - * - lookup (hit) - * - delete - * Note: lookup (miss) is not applicable since this is a filter - */ -static int test_add_delete(void) -{ - struct rte_efd_table *handle; - /* test with standard add/lookup/delete functions */ - efd_value_t prev_value; - printf("Entering %s\n", __func__); - - handle = rte_efd_create("test_add_delete", - TABLE_SIZE, sizeof(struct flow_key), - efd_get_all_sockets_bitmask(), test_socket_id); - TEST_ASSERT_NOT_NULL(handle, "Error creating the EFD table\n"); - - data[0] = mrand48() & VALUE_BITMASK; - TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[0], - data[0]), - "Error inserting the key"); - print_key_info("Add", &keys[0], data[0]); - - TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[0]), - data[0], - "failed to find key"); - - TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id, &keys[0], - &prev_value), - "failed to delete key"); - TEST_ASSERT_EQUAL(prev_value, data[0], - "failed to delete the expected value, got %d, " - "expected %d", prev_value, data[0]); - print_key_info("Del", &keys[0], data[0]); - - rte_efd_free(handle); - - return 0; -} - -/* - * Sequence of operations for a single key: - * - add - * - lookup: hit - * - add: update - * - lookup: hit (updated data) - * - delete: hit - */ -static int test_add_update_delete(void) -{ - struct rte_efd_table *handle; - printf("Entering %s\n", __func__); - /* test with standard add/lookup/delete functions */ - efd_value_t prev_value; - data[1] = mrand48() & VALUE_BITMASK; - - handle = rte_efd_create("test_add_update_delete", TABLE_SIZE, - sizeof(struct flow_key), - efd_get_all_sockets_bitmask(), test_socket_id); - TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n"); - - TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[1], - data[1]), "Error inserting the key"); - print_key_info("Add", &keys[1], data[1]); - - TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[1]), - data[1], "failed to find key"); - print_key_info("Lkp", &keys[1], data[1]); - - data[1] = data[1] + 1; - TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[1], - data[1]), "Error re-inserting the key"); - print_key_info("Add", &keys[1], data[1]); - - TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[1]), - data[1], "failed to find key"); - print_key_info("Lkp", &keys[1], data[1]); - - TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id, &keys[1], - &prev_value), "failed to delete key"); - TEST_ASSERT_EQUAL(prev_value, data[1], - "failed to delete the expected value, got %d, " - "expected %d", prev_value, data[1]); - print_key_info("Del", &keys[1], data[1]); - - - rte_efd_free(handle); - return 0; -} - -/* - * Sequence of operations for find existing EFD table - * - * - create table - * - find existing table: hit - * - find non-existing table: miss - * - */ -static int test_efd_find_existing(void) -{ - struct rte_efd_table *handle = NULL, *result = NULL; - - printf("Entering %s\n", __func__); - - /* Create EFD table. */ - handle = rte_efd_create("efd_find_existing", TABLE_SIZE, - sizeof(struct flow_key), - efd_get_all_sockets_bitmask(), test_socket_id); - TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n"); - - /* Try to find existing EFD table */ - result = rte_efd_find_existing("efd_find_existing"); - TEST_ASSERT_EQUAL(result, handle, "could not find existing efd table"); - - /* Try to find non-existing EFD table */ - result = rte_efd_find_existing("efd_find_non_existing"); - TEST_ASSERT_NULL(result, "found table that shouldn't exist"); - - /* Cleanup. */ - rte_efd_free(handle); - - return 0; -} - -/* - * Sequence of operations for 5 keys - * - add keys - * - lookup keys: hit (bulk) - * - add keys (update) - * - lookup keys: hit (updated data) - * - delete keys : hit - */ -static int test_five_keys(void) -{ - struct rte_efd_table *handle; - const void *key_array[5] = {0}; - efd_value_t result[5] = {0}; - efd_value_t prev_value; - unsigned int i; - printf("Entering %s\n", __func__); - - handle = rte_efd_create("test_five_keys", TABLE_SIZE, - sizeof(struct flow_key), - efd_get_all_sockets_bitmask(), test_socket_id); - TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n"); - - /* Setup data */ - for (i = 0; i < 5; i++) - data[i] = mrand48() & VALUE_BITMASK; - - /* Add */ - for (i = 0; i < 5; i++) { - TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, - &keys[i], data[i]), - "Error inserting the key"); - print_key_info("Add", &keys[i], data[i]); - } - - /* Lookup */ - for (i = 0; i < 5; i++) - key_array[i] = &keys[i]; - - rte_efd_lookup_bulk(handle, test_socket_id, 5, - (const void **) (void *) &key_array, result); - - for (i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(result[i], data[i], - "bulk: failed to find key. Expected %d, got %d", - data[i], result[i]); - print_key_info("Lkp", &keys[i], data[i]); - } - - /* Modify data (bulk) */ - for (i = 0; i < 5; i++) - data[i] = data[i] + 1; - - /* Add - update */ - for (i = 0; i < 5; i++) { - TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, - &keys[i], data[i]), - "Error inserting the key"); - print_key_info("Add", &keys[i], data[i]); - } - - /* Lookup */ - for (i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, - &keys[i]), data[i], - "failed to find key"); - print_key_info("Lkp", &keys[i], data[i]); - } - - /* Delete */ - for (i = 0; i < 5; i++) { - TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id, - &keys[i], &prev_value), - "failed to delete key"); - TEST_ASSERT_EQUAL(prev_value, data[i], - "failed to delete the expected value, got %d, " - "expected %d", prev_value, data[i]); - print_key_info("Del", &keys[i], data[i]); - } - - - rte_efd_free(handle); - - return 0; -} - -/* - * Test to see the average table utilization (entries added/max entries) - * before hitting a random entry that cannot be added - */ -static int test_average_table_utilization(void) -{ - struct rte_efd_table *handle = NULL; - uint32_t num_rules_in = TABLE_SIZE; - uint8_t simple_key[EFD_TEST_KEY_LEN]; - unsigned int i, j; - unsigned int added_keys, average_keys_added = 0; - - printf("Evaluating table utilization and correctness, please wait\n"); - fflush(stdout); - - for (j = 0; j < ITERATIONS; j++) { - handle = rte_efd_create("test_efd", num_rules_in, - EFD_TEST_KEY_LEN, efd_get_all_sockets_bitmask(), - test_socket_id); - if (handle == NULL) { - printf("efd table creation failed\n"); - return -1; - } - - unsigned int succeeded = 0; - unsigned int lost_keys = 0; - - /* Add random entries until key cannot be added */ - for (added_keys = 0; added_keys < num_rules_in; added_keys++) { - - for (i = 0; i < EFD_TEST_KEY_LEN; i++) - simple_key[i] = rte_rand() & 0xFF; - - efd_value_t val = simple_key[0]; - - if (rte_efd_update(handle, test_socket_id, simple_key, - val)) - break; /* continue;*/ - if (rte_efd_lookup(handle, test_socket_id, simple_key) - != val) - lost_keys++; - else - succeeded++; - } - - average_keys_added += succeeded; - - /* Reset the table */ - rte_efd_free(handle); - - /* Print progress on operations */ - printf("Added %10u Succeeded %10u Lost %10u\n", - added_keys, succeeded, lost_keys); - fflush(stdout); - } - - average_keys_added /= ITERATIONS; - - printf("\nAverage table utilization = %.2f%% (%u/%u)\n", - ((double) average_keys_added / num_rules_in * 100), - average_keys_added, num_rules_in); - - return 0; -} - -/* - * Do tests for EFD creation with bad parameters. - */ -static int test_efd_creation_with_bad_parameters(void) -{ - struct rte_efd_table *handle, *tmp; - printf("Entering %s, **Errors are expected **\n", __func__); - - handle = rte_efd_create("creation_with_bad_parameters_0", TABLE_SIZE, 0, - efd_get_all_sockets_bitmask(), test_socket_id); - if (handle != NULL) { - rte_efd_free(handle); - printf("Impossible creating EFD table successfully " - "if key_len in parameter is zero\n"); - return -1; - } - - handle = rte_efd_create("creation_with_bad_parameters_1", TABLE_SIZE, - sizeof(struct flow_key), 0, test_socket_id); - if (handle != NULL) { - rte_efd_free(handle); - printf("Impossible creating EFD table successfully " - "with invalid socket bitmask\n"); - return -1; - } - - handle = rte_efd_create("creation_with_bad_parameters_2", TABLE_SIZE, - sizeof(struct flow_key), efd_get_all_sockets_bitmask(), - 255); - if (handle != NULL) { - rte_efd_free(handle); - printf("Impossible creating EFD table successfully " - "with invalid socket\n"); - return -1; - } - - /* test with same name should fail */ - handle = rte_efd_create("same_name", TABLE_SIZE, - sizeof(struct flow_key), - efd_get_all_sockets_bitmask(), 0); - if (handle == NULL) { - printf("Cannot create first EFD table with 'same_name'\n"); - return -1; - } - tmp = rte_efd_create("same_name", TABLE_SIZE, sizeof(struct flow_key), - efd_get_all_sockets_bitmask(), 0); - if (tmp != NULL) { - printf("Creation of EFD table with same name should fail\n"); - rte_efd_free(handle); - rte_efd_free(tmp); - return -1; - } - rte_efd_free(handle); - - printf("# Test successful. No more errors expected\n"); - - return 0; -} - -static int -test_efd(void) -{ - - /* Unit tests */ - if (test_add_delete() < 0) - return -1; - if (test_efd_find_existing() < 0) - return -1; - if (test_add_update_delete() < 0) - return -1; - if (test_five_keys() < 0) - return -1; - if (test_efd_creation_with_bad_parameters() < 0) - return -1; - if (test_average_table_utilization() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(efd_autotest, test_efd); diff --git a/app/test/test_efd_perf.c b/app/test/test_efd_perf.c deleted file mode 100644 index 2b8a8eac5b..0000000000 --- a/app/test/test_efd_perf.c +++ /dev/null @@ -1,414 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2016-2017 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 -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define NUM_KEYSIZES 10 -#define NUM_SHUFFLES 10 -#define MAX_KEYSIZE 64 -#define MAX_ENTRIES (1 << 19) -#define KEYS_TO_ADD (MAX_ENTRIES * 3 / 4) /* 75% table utilization */ -#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ - -#if RTE_EFD_VALUE_NUM_BITS == 32 -#define VALUE_BITMASK 0xffffffff -#else -#define VALUE_BITMASK ((1 << RTE_EFD_VALUE_NUM_BITS) - 1) -#endif -static unsigned int test_socket_id; - -static inline uint8_t efd_get_all_sockets_bitmask(void) -{ - uint8_t all_cpu_sockets_bitmask = 0; - unsigned int i; - unsigned int next_lcore = rte_get_master_lcore(); - const int val_true = 1, val_false = 0; - for (i = 0; i < rte_lcore_count(); i++) { - all_cpu_sockets_bitmask |= 1 << rte_lcore_to_socket_id(next_lcore); - next_lcore = rte_get_next_lcore(next_lcore, val_false, val_true); - } - - return all_cpu_sockets_bitmask; -} - -enum operations { - ADD = 0, - LOOKUP, - LOOKUP_MULTI, - DELETE, - NUM_OPERATIONS -}; - -struct efd_perf_params { - struct rte_efd_table *efd_table; - uint32_t key_size; - unsigned int cycle; -}; - -static uint32_t hashtest_key_lens[] = { - /* standard key sizes */ - 4, 8, 16, 32, 48, 64, - /* IPv4 SRC + DST + protocol, unpadded */ - 9, - /* IPv4 5-tuple, unpadded */ - 13, - /* IPv6 5-tuple, unpadded */ - 37, - /* IPv6 5-tuple, padded to 8-byte boundary */ - 40 -}; - -/* Array to store number of cycles per operation */ -uint64_t cycles[NUM_KEYSIZES][NUM_OPERATIONS]; - -/* Array to store the data */ -efd_value_t data[KEYS_TO_ADD]; - -/* Array to store all input keys */ -uint8_t keys[KEYS_TO_ADD][MAX_KEYSIZE]; - -/* Shuffle the keys that have been added, so lookups will be totally random */ -static void -shuffle_input_keys(struct efd_perf_params *params) -{ - efd_value_t temp_data; - unsigned int i; - uint32_t swap_idx; - uint8_t temp_key[MAX_KEYSIZE]; - - for (i = KEYS_TO_ADD - 1; i > 0; i--) { - swap_idx = rte_rand() % i; - - memcpy(temp_key, keys[i], hashtest_key_lens[params->cycle]); - temp_data = data[i]; - - memcpy(keys[i], keys[swap_idx], hashtest_key_lens[params->cycle]); - data[i] = data[swap_idx]; - - memcpy(keys[swap_idx], temp_key, hashtest_key_lens[params->cycle]); - data[swap_idx] = temp_data; - } -} - -static int key_compare(const void *key1, const void *key2) -{ - return memcmp(key1, key2, MAX_KEYSIZE); -} - -/* - * TODO: we could "error proof" these as done in test_hash_perf.c ln 165: - * - * The current setup may give errors if too full in some cases which we check - * for. However, since EFD allows for ~99% capacity, these errors are rare for - * #"KEYS_TO_ADD" which is 75% capacity. - */ -static int -setup_keys_and_data(struct efd_perf_params *params, unsigned int cycle) -{ - unsigned int i, j; - int num_duplicates; - - params->key_size = hashtest_key_lens[cycle]; - params->cycle = cycle; - - /* Reset all arrays */ - for (i = 0; i < params->key_size; i++) - keys[0][i] = 0; - - /* Generate a list of keys, some of which may be duplicates */ - for (i = 0; i < KEYS_TO_ADD; i++) { - for (j = 0; j < params->key_size; j++) - keys[i][j] = rte_rand() & 0xFF; - - data[i] = rte_rand() & VALUE_BITMASK; - } - - /* Remove duplicates from the keys array */ - do { - num_duplicates = 0; - - /* Sort the list of keys to make it easier to find duplicates */ - qsort(keys, KEYS_TO_ADD, MAX_KEYSIZE, key_compare); - - /* Sift through the list of keys and look for duplicates */ - int num_duplicates = 0; - for (i = 0; i < KEYS_TO_ADD - 1; i++) { - if (memcmp(keys[i], keys[i + 1], params->key_size) == 0) { - /* This key already exists, try again */ - num_duplicates++; - for (j = 0; j < params->key_size; j++) - keys[i][j] = rte_rand() & 0xFF; - } - } - } while (num_duplicates != 0); - - /* Shuffle the random values again */ - shuffle_input_keys(params); - - params->efd_table = rte_efd_create("test_efd_perf", - MAX_ENTRIES, params->key_size, - efd_get_all_sockets_bitmask(), test_socket_id); - TEST_ASSERT_NOT_NULL(params->efd_table, "Error creating the efd table\n"); - - return 0; -} - -static int -timed_adds(struct efd_perf_params *params) -{ - const uint64_t start_tsc = rte_rdtsc(); - unsigned int i, a; - int32_t ret; - - for (i = 0; i < KEYS_TO_ADD; i++) { - ret = rte_efd_update(params->efd_table, test_socket_id, keys[i], - data[i]); - if (ret != 0) { - printf("Error %d in rte_efd_update - key=0x", ret); - for (a = 0; a < params->key_size; a++) - printf("%02x", keys[i][a]); - printf(" value=%d\n", data[i]); - - return -1; - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[params->cycle][ADD] = time_taken / KEYS_TO_ADD; - return 0; -} - -static int -timed_lookups(struct efd_perf_params *params) -{ - unsigned int i, j, a; - const uint64_t start_tsc = rte_rdtsc(); - efd_value_t ret_data; - - for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) { - for (j = 0; j < KEYS_TO_ADD; j++) { - ret_data = rte_efd_lookup(params->efd_table, - test_socket_id, keys[j]); - if (ret_data != data[j]) { - printf("Value mismatch using rte_efd_lookup: " - "key #%d (0x", i); - for (a = 0; a < params->key_size; a++) - printf("%02x", keys[i][a]); - printf(")\n"); - printf(" Expected %d, got %d\n", data[i], - ret_data); - - return -1; - } - - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[params->cycle][LOOKUP] = time_taken / NUM_LOOKUPS; - - return 0; -} - -static int -timed_lookups_multi(struct efd_perf_params *params) -{ - unsigned int i, j, k, a; - efd_value_t result[RTE_EFD_BURST_MAX] = {0}; - const void *keys_burst[RTE_EFD_BURST_MAX]; - const uint64_t start_tsc = rte_rdtsc(); - - for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) { - for (j = 0; j < KEYS_TO_ADD / RTE_EFD_BURST_MAX; j++) { - for (k = 0; k < RTE_EFD_BURST_MAX; k++) - keys_burst[k] = keys[j * RTE_EFD_BURST_MAX + k]; - - rte_efd_lookup_bulk(params->efd_table, test_socket_id, - RTE_EFD_BURST_MAX, - keys_burst, result); - - for (k = 0; k < RTE_EFD_BURST_MAX; k++) { - uint32_t data_idx = j * RTE_EFD_BURST_MAX + k; - if (result[k] != data[data_idx]) { - printf("Value mismatch using " - "rte_efd_lookup_bulk: key #%d " - "(0x", i); - for (a = 0; a < params->key_size; a++) - printf("%02x", - keys[data_idx][a]); - printf(")\n"); - printf(" Expected %d, got %d\n", - data[data_idx], result[k]); - - return -1; - } - } - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[params->cycle][LOOKUP_MULTI] = time_taken / NUM_LOOKUPS; - - return 0; -} - -static int -timed_deletes(struct efd_perf_params *params) -{ - unsigned int i, a; - const uint64_t start_tsc = rte_rdtsc(); - int32_t ret; - - for (i = 0; i < KEYS_TO_ADD; i++) { - ret = rte_efd_delete(params->efd_table, test_socket_id, keys[i], - NULL); - - if (ret != 0) { - printf("Error %d in rte_efd_delete - key=0x", ret); - for (a = 0; a < params->key_size; a++) - printf("%02x", keys[i][a]); - printf("\n"); - - return -1; - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[params->cycle][DELETE] = time_taken / KEYS_TO_ADD; - - return 0; -} - -static void -perform_frees(struct efd_perf_params *params) -{ - if (params->efd_table != NULL) { - rte_efd_free(params->efd_table); - params->efd_table = NULL; - } -} - -static int -exit_with_fail(const char *testname, struct efd_perf_params *params, - unsigned int i) -{ - - printf("<<<<>>>>\n", - testname, hashtest_key_lens[params->cycle], i); - perform_frees(params); - return -1; -} - -static int -run_all_tbl_perf_tests(void) -{ - unsigned int i, j; - struct efd_perf_params params; - - printf("Measuring performance, please wait\n"); - fflush(stdout); - - test_socket_id = rte_socket_id(); - - for (i = 0; i < NUM_KEYSIZES; i++) { - - if (setup_keys_and_data(¶ms, i) < 0) { - printf("Could not create keys/data/table\n"); - return -1; - } - - if (timed_adds(¶ms) < 0) - return exit_with_fail("timed_adds", ¶ms, i); - - for (j = 0; j < NUM_SHUFFLES; j++) - shuffle_input_keys(¶ms); - - if (timed_lookups(¶ms) < 0) - return exit_with_fail("timed_lookups", ¶ms, i); - - if (timed_lookups_multi(¶ms) < 0) - return exit_with_fail("timed_lookups_multi", ¶ms, i); - - if (timed_deletes(¶ms) < 0) - return exit_with_fail("timed_deletes", ¶ms, i); - - /* Print a dot to show progress on operations */ - printf("."); - fflush(stdout); - - perform_frees(¶ms); - } - - printf("\nResults (in CPU cycles/operation)\n"); - printf("-----------------------------------\n"); - printf("\n%-18s%-18s%-18s%-18s%-18s\n", - "Keysize", "Add", "Lookup", "Lookup_bulk", "Delete"); - for (i = 0; i < NUM_KEYSIZES; i++) { - printf("%-18d", hashtest_key_lens[i]); - for (j = 0; j < NUM_OPERATIONS; j++) - printf("%-18"PRIu64, cycles[i][j]); - printf("\n"); - } - return 0; -} - -static int -test_efd_perf(void) -{ - - if (run_all_tbl_perf_tests() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(efd_perf_autotest, test_efd_perf); diff --git a/app/test/test_errno.c b/app/test/test_errno.c deleted file mode 100644 index 388decbb2a..0000000000 --- a/app/test/test_errno.c +++ /dev/null @@ -1,116 +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 -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -static int -test_errno(void) -{ - const char *rte_retval; - const char *libc_retval; -#ifdef RTE_EXEC_ENV_BSDAPP - /* BSD has a colon in the string, unlike linux */ - const char unknown_code_result[] = "Unknown error: %d"; -#else - const char unknown_code_result[] = "Unknown error %d"; -#endif - char expected_libc_retval[sizeof(unknown_code_result)+3]; - - /* use a small selection of standard errors for testing */ - int std_errs[] = {EAGAIN, EBADF, EACCES, EINTR, EINVAL}; - /* test ALL registered RTE error codes for overlap */ - int rte_errs[] = {E_RTE_SECONDARY, E_RTE_NO_CONFIG}; - unsigned i; - - rte_errno = 0; - if (rte_errno != 0) - return -1; - /* check for standard errors we return the same as libc */ - for (i = 0; i < sizeof(std_errs)/sizeof(std_errs[0]); i++){ - rte_retval = rte_strerror(std_errs[i]); - libc_retval = strerror(std_errs[i]); - printf("rte_strerror: '%s', strerror: '%s'\n", - rte_retval, libc_retval); - if (strcmp(rte_retval, libc_retval) != 0) - return -1; - } - /* for rte-specific errors ensure we return a different string - * and that the string for libc is for an unknown error - */ - for (i = 0; i < sizeof(rte_errs)/sizeof(rte_errs[0]); i++){ - rte_retval = rte_strerror(rte_errs[i]); - libc_retval = strerror(rte_errs[i]); - printf("rte_strerror: '%s', strerror: '%s'\n", - rte_retval, libc_retval); - if (strcmp(rte_retval, libc_retval) == 0) - return -1; - /* generate appropriate error string for unknown error number - * and then check that this is what we got back. If not, we have - * a duplicate error number that conflicts with errno.h */ - snprintf(expected_libc_retval, sizeof(expected_libc_retval), - unknown_code_result, rte_errs[i]); - if ((strcmp(expected_libc_retval, libc_retval) != 0) && - (strcmp("", libc_retval) != 0)){ - printf("Error, duplicate error code %d\n", rte_errs[i]); - return -1; - } - } - - /* ensure that beyond RTE_MAX_ERRNO, we always get an unknown code */ - rte_retval = rte_strerror(RTE_MAX_ERRNO + 1); - libc_retval = strerror(RTE_MAX_ERRNO + 1); - snprintf(expected_libc_retval, sizeof(expected_libc_retval), - unknown_code_result, RTE_MAX_ERRNO + 1); - printf("rte_strerror: '%s', strerror: '%s'\n", - rte_retval, libc_retval); - if ((strcmp(rte_retval, libc_retval) != 0) || - (strcmp(expected_libc_retval, libc_retval) != 0)){ - if (strcmp("", libc_retval) != 0){ - printf("Failed test for RTE_MAX_ERRNO + 1 value\n"); - return -1; - } - } - - return 0; -} - -REGISTER_TEST_COMMAND(errno_autotest, test_errno); diff --git a/app/test/test_func_reentrancy.c b/app/test/test_func_reentrancy.c deleted file mode 100644 index baa01ffc2c..0000000000 --- a/app/test/test_func_reentrancy.c +++ /dev/null @@ -1,510 +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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef RTE_LIBRTE_HASH -#include -#include -#include -#endif /* RTE_LIBRTE_HASH */ - -#ifdef RTE_LIBRTE_LPM -#include -#endif /* RTE_LIBRTE_LPM */ - -#include - -#include "test.h" - -typedef int (*case_func_t)(void* arg); -typedef void (*case_clean_t)(unsigned lcore_id); - -#define MAX_STRING_SIZE (256) -#define MAX_ITER_TIMES (16) -#define MAX_LPM_ITER_TIMES (8) - -#define MEMPOOL_ELT_SIZE (sizeof(uint32_t)) -#define MEMPOOL_SIZE (4) - -#define MAX_LCORES RTE_MAX_MEMZONE / (MAX_ITER_TIMES * 4U) - -static rte_atomic32_t obj_count = RTE_ATOMIC32_INIT(0); -static rte_atomic32_t synchro = RTE_ATOMIC32_INIT(0); - -#define WAIT_SYNCHRO_FOR_SLAVES() do{ \ - if (lcore_self != rte_get_master_lcore()) \ - while (rte_atomic32_read(&synchro) == 0); \ -} while(0) - -/* - * rte_eal_init only init once - */ -static int -test_eal_init_once(__attribute__((unused)) void *arg) -{ - unsigned lcore_self = rte_lcore_id(); - - WAIT_SYNCHRO_FOR_SLAVES(); - - rte_atomic32_set(&obj_count, 1); /* silent the check in the caller */ - if (rte_eal_init(0, NULL) != -1) - return -1; - - return 0; -} - -/* - * ring create/lookup reentrancy test - */ -static int -ring_create_lookup(__attribute__((unused)) void *arg) -{ - unsigned lcore_self = rte_lcore_id(); - struct rte_ring * rp; - char ring_name[MAX_STRING_SIZE]; - int i; - - WAIT_SYNCHRO_FOR_SLAVES(); - - /* create the same ring simultaneously on all threads */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - rp = rte_ring_create("fr_test_once", 4096, SOCKET_ID_ANY, 0); - if (rp != NULL) - rte_atomic32_inc(&obj_count); - } - - /* create/lookup new ring several times */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(ring_name, sizeof(ring_name), "fr_test_%d_%d", lcore_self, i); - rp = rte_ring_create(ring_name, 4096, SOCKET_ID_ANY, 0); - if (NULL == rp) - return -1; - if (rte_ring_lookup(ring_name) != rp) - return -1; - } - - /* verify all ring created sucessful */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(ring_name, sizeof(ring_name), "fr_test_%d_%d", lcore_self, i); - if (rte_ring_lookup(ring_name) == NULL) - return -1; - } - - return 0; -} - -static void -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; -} - -static int -mempool_create_lookup(__attribute__((unused)) void *arg) -{ - unsigned lcore_self = rte_lcore_id(); - struct rte_mempool * mp; - char mempool_name[MAX_STRING_SIZE]; - int i; - - WAIT_SYNCHRO_FOR_SLAVES(); - - /* create the same mempool simultaneously on all threads */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - mp = rte_mempool_create("fr_test_once", MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, 0, 0, - NULL, NULL, - my_obj_init, NULL, - SOCKET_ID_ANY, 0); - if (mp != NULL) - rte_atomic32_inc(&obj_count); - } - - /* create/lookup new ring several times */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(mempool_name, sizeof(mempool_name), "fr_test_%d_%d", lcore_self, i); - mp = rte_mempool_create(mempool_name, MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, 0, 0, - NULL, NULL, - my_obj_init, NULL, - SOCKET_ID_ANY, 0); - if (NULL == mp) - return -1; - if (rte_mempool_lookup(mempool_name) != mp) - return -1; - } - - /* verify all ring created sucessful */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(mempool_name, sizeof(mempool_name), "fr_test_%d_%d", lcore_self, i); - if (rte_mempool_lookup(mempool_name) == NULL) - return -1; - } - - return 0; -} - -#ifdef RTE_LIBRTE_HASH -static void -hash_clean(unsigned lcore_id) -{ - char hash_name[MAX_STRING_SIZE]; - struct rte_hash *handle; - int i; - - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(hash_name, sizeof(hash_name), "fr_test_%d_%d", lcore_id, i); - - if ((handle = rte_hash_find_existing(hash_name)) != NULL) - rte_hash_free(handle); - } -} - -static int -hash_create_free(__attribute__((unused)) void *arg) -{ - unsigned lcore_self = rte_lcore_id(); - struct rte_hash *handle; - char hash_name[MAX_STRING_SIZE]; - int i; - struct rte_hash_parameters hash_params = { - .name = NULL, - .entries = 16, - .key_len = 4, - .hash_func = (rte_hash_function)rte_jhash_32b, - .hash_func_init_val = 0, - .socket_id = 0, - }; - - WAIT_SYNCHRO_FOR_SLAVES(); - - /* create the same hash simultaneously on all threads */ - hash_params.name = "fr_test_once"; - for (i = 0; i < MAX_ITER_TIMES; i++) { - handle = rte_hash_create(&hash_params); - if (handle != NULL) - rte_atomic32_inc(&obj_count); - } - - /* create mutiple times simultaneously */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(hash_name, sizeof(hash_name), "fr_test_%d_%d", lcore_self, i); - hash_params.name = hash_name; - - handle = rte_hash_create(&hash_params); - if (NULL == handle) - return -1; - - /* verify correct existing and then free all */ - if (handle != rte_hash_find_existing(hash_name)) - return -1; - - rte_hash_free(handle); - } - - /* verify free correct */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(hash_name, sizeof(hash_name), "fr_test_%d_%d", lcore_self, i); - - if (NULL != rte_hash_find_existing(hash_name)) - return -1; - } - - return 0; -} - -static void -fbk_clean(unsigned lcore_id) -{ - char fbk_name[MAX_STRING_SIZE]; - struct rte_fbk_hash_table *handle; - int i; - - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(fbk_name, sizeof(fbk_name), "fr_test_%d_%d", lcore_id, i); - - if ((handle = rte_fbk_hash_find_existing(fbk_name)) != NULL) - rte_fbk_hash_free(handle); - } -} - -static int -fbk_create_free(__attribute__((unused)) void *arg) -{ - unsigned lcore_self = rte_lcore_id(); - struct rte_fbk_hash_table *handle; - char fbk_name[MAX_STRING_SIZE]; - int i; - struct rte_fbk_hash_params fbk_params = { - .name = NULL, - .entries = 4, - .entries_per_bucket = 4, - .socket_id = 0, - .hash_func = rte_jhash_1word, - .init_val = RTE_FBK_HASH_INIT_VAL_DEFAULT, - }; - - WAIT_SYNCHRO_FOR_SLAVES(); - - /* create the same fbk hash table simultaneously on all threads */ - fbk_params.name = "fr_test_once"; - for (i = 0; i < MAX_ITER_TIMES; i++) { - handle = rte_fbk_hash_create(&fbk_params); - if (handle != NULL) - rte_atomic32_inc(&obj_count); - } - - /* create mutiple fbk tables simultaneously */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(fbk_name, sizeof(fbk_name), "fr_test_%d_%d", lcore_self, i); - fbk_params.name = fbk_name; - - handle = rte_fbk_hash_create(&fbk_params); - if (NULL == handle) - return -1; - - /* verify correct existing and then free all */ - if (handle != rte_fbk_hash_find_existing(fbk_name)) - return -1; - - rte_fbk_hash_free(handle); - } - - /* verify free correct */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - snprintf(fbk_name, sizeof(fbk_name), "fr_test_%d_%d", lcore_self, i); - - if (NULL != rte_fbk_hash_find_existing(fbk_name)) - return -1; - } - - return 0; -} -#endif /* RTE_LIBRTE_HASH */ - -#ifdef RTE_LIBRTE_LPM -static void -lpm_clean(unsigned lcore_id) -{ - char lpm_name[MAX_STRING_SIZE]; - struct rte_lpm *lpm; - int i; - - for (i = 0; i < MAX_LPM_ITER_TIMES; i++) { - snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_id, i); - - if ((lpm = rte_lpm_find_existing(lpm_name)) != NULL) - rte_lpm_free(lpm); - } -} - -static int -lpm_create_free(__attribute__((unused)) void *arg) -{ - unsigned lcore_self = rte_lcore_id(); - struct rte_lpm *lpm; - struct rte_lpm_config config; - - config.max_rules = 4; - config.number_tbl8s = 256; - config.flags = 0; - char lpm_name[MAX_STRING_SIZE]; - int i; - - WAIT_SYNCHRO_FOR_SLAVES(); - - /* create the same lpm simultaneously on all threads */ - for (i = 0; i < MAX_ITER_TIMES; i++) { - lpm = rte_lpm_create("fr_test_once", SOCKET_ID_ANY, &config); - if (lpm != NULL) - rte_atomic32_inc(&obj_count); - } - - /* create mutiple fbk tables simultaneously */ - for (i = 0; i < MAX_LPM_ITER_TIMES; i++) { - snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_self, i); - lpm = rte_lpm_create(lpm_name, SOCKET_ID_ANY, &config); - if (NULL == lpm) - return -1; - - /* verify correct existing and then free all */ - if (lpm != rte_lpm_find_existing(lpm_name)) - return -1; - - rte_lpm_free(lpm); - } - - /* verify free correct */ - for (i = 0; i < MAX_LPM_ITER_TIMES; i++) { - snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_self, i); - if (NULL != rte_lpm_find_existing(lpm_name)) - return -1; - } - - return 0; -} -#endif /* RTE_LIBRTE_LPM */ - -struct test_case{ - case_func_t func; - void* arg; - case_clean_t clean; - char name[MAX_STRING_SIZE]; -}; - -/* All test cases in the test suite */ -struct test_case test_cases[] = { - { test_eal_init_once, NULL, NULL, "eal init once" }, - { ring_create_lookup, NULL, NULL, "ring create/lookup" }, - { mempool_create_lookup, NULL, NULL, "mempool create/lookup" }, -#ifdef RTE_LIBRTE_HASH - { hash_create_free, NULL, hash_clean, "hash create/free" }, - { fbk_create_free, NULL, fbk_clean, "fbk create/free" }, -#endif /* RTE_LIBRTE_HASH */ -#ifdef RTE_LIBRTE_LPM - { lpm_create_free, NULL, lpm_clean, "lpm create/free" }, -#endif /* RTE_LIBRTE_LPM */ -}; - -/** - * launch test case in two separate thread - */ -static int -launch_test(struct test_case *pt_case) -{ - int ret = 0; - unsigned lcore_id; - unsigned cores_save = rte_lcore_count(); - unsigned cores = RTE_MIN(cores_save, MAX_LCORES); - unsigned count; - - if (pt_case->func == NULL) - return -1; - - rte_atomic32_set(&obj_count, 0); - rte_atomic32_set(&synchro, 0); - - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (cores == 1) - break; - cores--; - rte_eal_remote_launch(pt_case->func, pt_case->arg, lcore_id); - } - - rte_atomic32_set(&synchro, 1); - - if (pt_case->func(pt_case->arg) < 0) - ret = -1; - - cores = cores_save; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (cores == 1) - break; - cores--; - if (rte_eal_wait_lcore(lcore_id) < 0) - ret = -1; - - if (pt_case->clean != NULL) - pt_case->clean(lcore_id); - } - - count = rte_atomic32_read(&obj_count); - if (count != 1) { - printf("%s: common object allocated %d times (should be 1)\n", - pt_case->name, count); - ret = -1; - } - - return ret; -} - -/** - * Main entry of func_reentrancy test - */ -static int -test_func_reentrancy(void) -{ - uint32_t case_id; - struct test_case *pt_case = NULL; - - if (rte_lcore_count() <= 1) { - printf("Not enough lcore for testing\n"); - return -1; - } - else if (rte_lcore_count() > MAX_LCORES) - printf("Too many lcores, some cores will be disabled\n"); - - for (case_id = 0; case_id < sizeof(test_cases)/sizeof(struct test_case); case_id ++) { - pt_case = &test_cases[case_id]; - if (pt_case->func == NULL) - continue; - - if (launch_test(pt_case) < 0) { - printf("Func-ReEnt CASE %"PRIu32": %s FAIL\n", case_id, pt_case->name); - return -1; - } - printf("Func-ReEnt CASE %"PRIu32": %s PASS\n", case_id, pt_case->name); - } - - return 0; -} - -REGISTER_TEST_COMMAND(func_reentrancy_autotest, test_func_reentrancy); diff --git a/app/test/test_hash.c b/app/test/test_hash.c deleted file mode 100644 index 2c87efe692..0000000000 --- a/app/test/test_hash.c +++ /dev/null @@ -1,1517 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2015 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#include -#include -#include -#include - -/******************************************************************************* - * Hash function performance test configuration section. Each performance test - * will be performed HASHTEST_ITERATIONS times. - * - * The five arrays below control what tests are performed. Every combination - * from the array entries is tested. - */ -static rte_hash_function hashtest_funcs[] = {rte_jhash, rte_hash_crc}; -static uint32_t hashtest_initvals[] = {0}; -static uint32_t hashtest_key_lens[] = {0, 2, 4, 5, 6, 7, 8, 10, 11, 15, 16, 21, 31, 32, 33, 63, 64}; -#define MAX_KEYSIZE 64 -/******************************************************************************/ -#define LOCAL_FBK_HASH_ENTRIES_MAX (1 << 15) - -/* - * 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 RETURN_IF_ERROR_FBK(cond, str, ...) do { \ - if (cond) { \ - printf("ERROR line %d: " str "\n", __LINE__, ##__VA_ARGS__); \ - if (handle) rte_fbk_hash_free(handle); \ - return -1; \ - } \ -} while(0) - -/* 5-tuple key type */ -struct flow_key { - uint32_t ip_src; - uint32_t ip_dst; - uint16_t port_src; - uint16_t port_dst; - uint8_t proto; -} __attribute__((packed)); - -/* - * Hash function that always returns the same value, to easily test what - * happens when a bucket is full. - */ -static uint32_t pseudo_hash(__attribute__((unused)) const void *keys, - __attribute__((unused)) uint32_t key_len, - __attribute__((unused)) uint32_t init_val) -{ - return 3; -} - -/* - * Print out result of unit test hash operation. - */ -#if defined(UNIT_TEST_HASH_VERBOSE) -static void print_key_info(const char *msg, const struct flow_key *key, - int32_t pos) -{ - uint8_t *p = (uint8_t *)key; - unsigned i; - - printf("%s key:0x", msg); - for (i = 0; i < sizeof(struct flow_key); i++) { - printf("%02X", p[i]); - } - printf(" @ pos %d\n", pos); -} -#else -static void print_key_info(__attribute__((unused)) const char *msg, - __attribute__((unused)) const struct flow_key *key, - __attribute__((unused)) int32_t pos) -{ -} -#endif - -/* Keys used by unit test functions */ -static struct flow_key keys[5] = { { - .ip_src = IPv4(0x03, 0x02, 0x01, 0x00), - .ip_dst = IPv4(0x07, 0x06, 0x05, 0x04), - .port_src = 0x0908, - .port_dst = 0x0b0a, - .proto = 0x0c, -}, { - .ip_src = IPv4(0x13, 0x12, 0x11, 0x10), - .ip_dst = IPv4(0x17, 0x16, 0x15, 0x14), - .port_src = 0x1918, - .port_dst = 0x1b1a, - .proto = 0x1c, -}, { - .ip_src = IPv4(0x23, 0x22, 0x21, 0x20), - .ip_dst = IPv4(0x27, 0x26, 0x25, 0x24), - .port_src = 0x2928, - .port_dst = 0x2b2a, - .proto = 0x2c, -}, { - .ip_src = IPv4(0x33, 0x32, 0x31, 0x30), - .ip_dst = IPv4(0x37, 0x36, 0x35, 0x34), - .port_src = 0x3938, - .port_dst = 0x3b3a, - .proto = 0x3c, -}, { - .ip_src = IPv4(0x43, 0x42, 0x41, 0x40), - .ip_dst = IPv4(0x47, 0x46, 0x45, 0x44), - .port_src = 0x4948, - .port_dst = 0x4b4a, - .proto = 0x4c, -} }; - -/* Parameters used for hash table in unit test functions. Name set later. */ -static struct rte_hash_parameters ut_params = { - .entries = 64, - .key_len = sizeof(struct flow_key), /* 13 */ - .hash_func = rte_jhash, - .hash_func_init_val = 0, - .socket_id = 0, -}; - -#define CRC32_ITERATIONS (1U << 10) -#define CRC32_DWORDS (1U << 6) -/* - * Test if all CRC32 implementations yield the same hash value - */ -static int -test_crc32_hash_alg_equiv(void) -{ - uint32_t hash_val; - uint32_t init_val; - uint64_t data64[CRC32_DWORDS]; - unsigned i, j; - size_t data_len; - - printf("\n# CRC32 implementations equivalence test\n"); - for (i = 0; i < CRC32_ITERATIONS; i++) { - /* Randomizing data_len of data set */ - data_len = (size_t) ((rte_rand() % sizeof(data64)) + 1); - init_val = (uint32_t) rte_rand(); - - /* Fill the data set */ - for (j = 0; j < CRC32_DWORDS; j++) - data64[j] = rte_rand(); - - /* Calculate software CRC32 */ - rte_hash_crc_set_alg(CRC32_SW); - hash_val = rte_hash_crc(data64, data_len, init_val); - - /* Check against 4-byte-operand sse4.2 CRC32 if available */ - rte_hash_crc_set_alg(CRC32_SSE42); - if (hash_val != rte_hash_crc(data64, data_len, init_val)) { - printf("Failed checking CRC32_SW against CRC32_SSE42\n"); - break; - } - - /* Check against 8-byte-operand sse4.2 CRC32 if available */ - rte_hash_crc_set_alg(CRC32_SSE42_x64); - if (hash_val != rte_hash_crc(data64, data_len, init_val)) { - printf("Failed checking CRC32_SW against CRC32_SSE42_x64\n"); - break; - } - - /* Check against 8-byte-operand ARM64 CRC32 if available */ - rte_hash_crc_set_alg(CRC32_ARM64); - if (hash_val != rte_hash_crc(data64, data_len, init_val)) { - printf("Failed checking CRC32_SW against CRC32_ARM64\n"); - break; - } - } - - /* Resetting to best available algorithm */ - rte_hash_crc_set_alg(CRC32_SSE42_x64); - - if (i == CRC32_ITERATIONS) - return 0; - - printf("Failed test data (hex, %zu bytes total):\n", data_len); - for (j = 0; j < data_len; j++) - printf("%02X%c", ((uint8_t *)data64)[j], - ((j+1) % 16 == 0 || j == data_len - 1) ? '\n' : ' '); - - return -1; -} - -/* - * Test a hash function. - */ -static void run_hash_func_test(rte_hash_function f, uint32_t init_val, - uint32_t key_len) -{ - static uint8_t key[MAX_KEYSIZE]; - unsigned i; - - - for (i = 0; i < key_len; i++) - key[i] = (uint8_t) rte_rand(); - - /* just to be on the safe side */ - if (!f) - return; - - f(key, key_len, init_val); -} - -/* - * Test all hash functions. - */ -static void run_hash_func_tests(void) -{ - unsigned i, j, k; - - for (i = 0; - i < sizeof(hashtest_funcs) / sizeof(rte_hash_function); - i++) { - for (j = 0; - j < sizeof(hashtest_initvals) / sizeof(uint32_t); - j++) { - for (k = 0; - k < sizeof(hashtest_key_lens) / sizeof(uint32_t); - k++) { - run_hash_func_test(hashtest_funcs[i], - hashtest_initvals[j], - hashtest_key_lens[k]); - } - } - } -} - -/* - * Basic sequence of operations for a single key: - * - add - * - lookup (hit) - * - delete - * - lookup (miss) - */ -static int test_add_delete(void) -{ - struct rte_hash *handle; - /* test with standard add/lookup/delete functions */ - int pos0, expectedPos0; - - ut_params.name = "test1"; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - pos0 = rte_hash_add_key(handle, &keys[0]); - print_key_info("Add", &keys[0], pos0); - RETURN_IF_ERROR(pos0 < 0, "failed to add key (pos0=%d)", pos0); - expectedPos0 = pos0; - - pos0 = rte_hash_lookup(handle, &keys[0]); - print_key_info("Lkp", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != expectedPos0, - "failed to find key (pos0=%d)", pos0); - - pos0 = rte_hash_del_key(handle, &keys[0]); - print_key_info("Del", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != expectedPos0, - "failed to delete key (pos0=%d)", pos0); - - pos0 = rte_hash_lookup(handle, &keys[0]); - print_key_info("Lkp", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != -ENOENT, - "fail: found key after deleting! (pos0=%d)", pos0); - - rte_hash_free(handle); - - /* repeat test with precomputed hash functions */ - hash_sig_t hash_value; - int pos1, expectedPos1; - - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - hash_value = rte_hash_hash(handle, &keys[0]); - pos1 = rte_hash_add_key_with_hash(handle, &keys[0], hash_value); - print_key_info("Add", &keys[0], pos1); - RETURN_IF_ERROR(pos1 < 0, "failed to add key (pos1=%d)", pos1); - expectedPos1 = pos1; - - pos1 = rte_hash_lookup_with_hash(handle, &keys[0], hash_value); - print_key_info("Lkp", &keys[0], pos1); - RETURN_IF_ERROR(pos1 != expectedPos1, - "failed to find key (pos1=%d)", pos1); - - pos1 = rte_hash_del_key_with_hash(handle, &keys[0], hash_value); - print_key_info("Del", &keys[0], pos1); - RETURN_IF_ERROR(pos1 != expectedPos1, - "failed to delete key (pos1=%d)", pos1); - - pos1 = rte_hash_lookup_with_hash(handle, &keys[0], hash_value); - print_key_info("Lkp", &keys[0], pos1); - RETURN_IF_ERROR(pos1 != -ENOENT, - "fail: found key after deleting! (pos1=%d)", pos1); - - rte_hash_free(handle); - - return 0; -} - -/* - * Sequence of operations for a single key: - * - delete: miss - * - add - * - lookup: hit - * - add: update - * - lookup: hit (updated data) - * - delete: hit - * - delete: miss - * - lookup: miss - */ -static int test_add_update_delete(void) -{ - struct rte_hash *handle; - int pos0, expectedPos0; - - ut_params.name = "test2"; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - pos0 = rte_hash_del_key(handle, &keys[0]); - print_key_info("Del", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != -ENOENT, - "fail: found non-existent key (pos0=%d)", pos0); - - pos0 = rte_hash_add_key(handle, &keys[0]); - print_key_info("Add", &keys[0], pos0); - RETURN_IF_ERROR(pos0 < 0, "failed to add key (pos0=%d)", pos0); - expectedPos0 = pos0; - - pos0 = rte_hash_lookup(handle, &keys[0]); - print_key_info("Lkp", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != expectedPos0, - "failed to find key (pos0=%d)", pos0); - - pos0 = rte_hash_add_key(handle, &keys[0]); - print_key_info("Add", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != expectedPos0, - "failed to re-add key (pos0=%d)", pos0); - - pos0 = rte_hash_lookup(handle, &keys[0]); - print_key_info("Lkp", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != expectedPos0, - "failed to find key (pos0=%d)", pos0); - - pos0 = rte_hash_del_key(handle, &keys[0]); - print_key_info("Del", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != expectedPos0, - "failed to delete key (pos0=%d)", pos0); - - pos0 = rte_hash_del_key(handle, &keys[0]); - print_key_info("Del", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != -ENOENT, - "fail: deleted already deleted key (pos0=%d)", pos0); - - pos0 = rte_hash_lookup(handle, &keys[0]); - print_key_info("Lkp", &keys[0], pos0); - RETURN_IF_ERROR(pos0 != -ENOENT, - "fail: found key after deleting! (pos0=%d)", pos0); - - rte_hash_free(handle); - return 0; -} - -/* - * Sequence of operations for retrieving a key with its position - * - * - create table - * - add key - * - get the key with its position: hit - * - delete key - * - try to get the deleted key: miss - * - */ -static int test_hash_get_key_with_position(void) -{ - struct rte_hash *handle = NULL; - int pos, expectedPos, result; - void *key; - - ut_params.name = "hash_get_key_w_pos"; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - pos = rte_hash_add_key(handle, &keys[0]); - print_key_info("Add", &keys[0], pos); - RETURN_IF_ERROR(pos < 0, "failed to add key (pos0=%d)", pos); - expectedPos = pos; - - result = rte_hash_get_key_with_position(handle, pos, &key); - RETURN_IF_ERROR(result != 0, "error retrieving a key"); - - pos = rte_hash_del_key(handle, &keys[0]); - print_key_info("Del", &keys[0], pos); - RETURN_IF_ERROR(pos != expectedPos, - "failed to delete key (pos0=%d)", pos); - - result = rte_hash_get_key_with_position(handle, pos, &key); - RETURN_IF_ERROR(result != -ENOENT, "non valid key retrieved"); - - rte_hash_free(handle); - return 0; -} - -/* - * Sequence of operations for find existing hash table - * - * - create table - * - find existing table: hit - * - find non-existing table: miss - * - */ -static int test_hash_find_existing(void) -{ - struct rte_hash *handle = NULL, *result = NULL; - - /* Create hash table. */ - ut_params.name = "hash_find_existing"; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - /* Try to find existing hash table */ - result = rte_hash_find_existing("hash_find_existing"); - RETURN_IF_ERROR(result != handle, "could not find existing hash table"); - - /* Try to find non-existing hash table */ - result = rte_hash_find_existing("hash_find_non_existing"); - RETURN_IF_ERROR(!(result == NULL), "found table that shouldn't exist"); - - /* Cleanup. */ - rte_hash_free(handle); - - return 0; -} - -/* - * Sequence of operations for 5 keys - * - add keys - * - lookup keys: hit - * - add keys (update) - * - lookup keys: hit (updated data) - * - delete keys : hit - * - lookup keys: miss - */ -static int test_five_keys(void) -{ - struct rte_hash *handle; - const void *key_array[5] = {0}; - int pos[5]; - int expected_pos[5]; - unsigned i; - int ret; - - ut_params.name = "test3"; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - /* Add */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_add_key(handle, &keys[i]); - print_key_info("Add", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] < 0, - "failed to add key (pos[%u]=%d)", i, pos[i]); - expected_pos[i] = pos[i]; - } - - /* Lookup */ - for(i = 0; i < 5; i++) - key_array[i] = &keys[i]; - - 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]); - RETURN_IF_ERROR(pos[i] != expected_pos[i], - "failed to find key (pos[%u]=%d)", i, pos[i]); - } - - /* Add - update */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_add_key(handle, &keys[i]); - print_key_info("Add", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != expected_pos[i], - "failed to add key (pos[%u]=%d)", i, pos[i]); - } - - /* Lookup */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_lookup(handle, &keys[i]); - print_key_info("Lkp", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != expected_pos[i], - "failed to find key (pos[%u]=%d)", i, pos[i]); - } - - /* Delete */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_del_key(handle, &keys[i]); - print_key_info("Del", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != expected_pos[i], - "failed to delete key (pos[%u]=%d)", i, pos[i]); - } - - /* Lookup */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_lookup(handle, &keys[i]); - print_key_info("Lkp", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != -ENOENT, - "found non-existent key (pos[%u]=%d)", i, pos[i]); - } - - /* Lookup multi */ - 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]); - RETURN_IF_ERROR(pos[i] != -ENOENT, - "found not-existent key (pos[%u]=%d)", i, pos[i]); - } - - rte_hash_free(handle); - - return 0; -} - -/* - * Add keys to the same bucket until bucket full. - * - add 5 keys to the same bucket (hash created with 4 keys per bucket): - * first 4 successful, 5th successful, pushing existing item in bucket - * - lookup the 5 keys: 5 hits - * - add the 5 keys again: 5 OK - * - lookup the 5 keys: 5 hits (updated data) - * - delete the 5 keys: 5 OK - * - lookup the 5 keys: 5 misses - */ -static int test_full_bucket(void) -{ - struct rte_hash_parameters params_pseudo_hash = { - .name = "test4", - .entries = 64, - .key_len = sizeof(struct flow_key), /* 13 */ - .hash_func = pseudo_hash, - .hash_func_init_val = 0, - .socket_id = 0, - }; - struct rte_hash *handle; - int pos[5]; - int expected_pos[5]; - unsigned i; - - handle = rte_hash_create(¶ms_pseudo_hash); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - /* Fill bucket */ - for (i = 0; i < 4; i++) { - pos[i] = rte_hash_add_key(handle, &keys[i]); - print_key_info("Add", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] < 0, - "failed to add key (pos[%u]=%d)", i, pos[i]); - expected_pos[i] = pos[i]; - } - /* - * This should work and will push one of the items - * in the bucket because it is full - */ - pos[4] = rte_hash_add_key(handle, &keys[4]); - print_key_info("Add", &keys[4], pos[4]); - RETURN_IF_ERROR(pos[4] < 0, - "failed to add key (pos[4]=%d)", pos[4]); - expected_pos[4] = pos[4]; - - /* Lookup */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_lookup(handle, &keys[i]); - print_key_info("Lkp", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != expected_pos[i], - "failed to find key (pos[%u]=%d)", i, pos[i]); - } - - /* Add - update */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_add_key(handle, &keys[i]); - print_key_info("Add", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != expected_pos[i], - "failed to add key (pos[%u]=%d)", i, pos[i]); - } - - /* Lookup */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_lookup(handle, &keys[i]); - print_key_info("Lkp", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != expected_pos[i], - "failed to find key (pos[%u]=%d)", i, pos[i]); - } - - /* Delete 1 key, check other keys are still found */ - pos[1] = rte_hash_del_key(handle, &keys[1]); - print_key_info("Del", &keys[1], pos[1]); - RETURN_IF_ERROR(pos[1] != expected_pos[1], - "failed to delete key (pos[1]=%d)", pos[1]); - pos[3] = rte_hash_lookup(handle, &keys[3]); - print_key_info("Lkp", &keys[3], pos[3]); - RETURN_IF_ERROR(pos[3] != expected_pos[3], - "failed lookup after deleting key from same bucket " - "(pos[3]=%d)", pos[3]); - - /* Go back to previous state */ - pos[1] = rte_hash_add_key(handle, &keys[1]); - print_key_info("Add", &keys[1], pos[1]); - expected_pos[1] = pos[1]; - RETURN_IF_ERROR(pos[1] < 0, "failed to add key (pos[1]=%d)", pos[1]); - - /* Delete */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_del_key(handle, &keys[i]); - print_key_info("Del", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != expected_pos[i], - "failed to delete key (pos[%u]=%d)", i, pos[i]); - } - - /* Lookup */ - for (i = 0; i < 5; i++) { - pos[i] = rte_hash_lookup(handle, &keys[i]); - print_key_info("Lkp", &keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != -ENOENT, - "fail: found non-existent key (pos[%u]=%d)", i, pos[i]); - } - - rte_hash_free(handle); - - /* Cover the NULL case. */ - rte_hash_free(0); - return 0; -} - -/******************************************************************************/ -static int -fbk_hash_unit_test(void) -{ - struct rte_fbk_hash_params params = { - .name = "fbk_hash_test", - .entries = LOCAL_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = 4, - .socket_id = 0, - }; - - struct rte_fbk_hash_params invalid_params_1 = { - .name = "invalid_1", - .entries = LOCAL_FBK_HASH_ENTRIES_MAX + 1, /* Not power of 2 */ - .entries_per_bucket = 4, - .socket_id = 0, - }; - - struct rte_fbk_hash_params invalid_params_2 = { - .name = "invalid_2", - .entries = 4, - .entries_per_bucket = 3, /* Not power of 2 */ - .socket_id = 0, - }; - - struct rte_fbk_hash_params invalid_params_3 = { - .name = "invalid_3", - .entries = 0, /* Entries is 0 */ - .entries_per_bucket = 4, - .socket_id = 0, - }; - - struct rte_fbk_hash_params invalid_params_4 = { - .name = "invalid_4", - .entries = LOCAL_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = 0, /* Entries per bucket is 0 */ - .socket_id = 0, - }; - - struct rte_fbk_hash_params invalid_params_5 = { - .name = "invalid_5", - .entries = 4, - .entries_per_bucket = 8, /* Entries per bucket > entries */ - .socket_id = 0, - }; - - struct rte_fbk_hash_params invalid_params_6 = { - .name = "invalid_6", - .entries = RTE_FBK_HASH_ENTRIES_MAX * 2, /* Entries > max allowed */ - .entries_per_bucket = 4, - .socket_id = 0, - }; - - struct rte_fbk_hash_params invalid_params_7 = { - .name = "invalid_7", - .entries = RTE_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = RTE_FBK_HASH_ENTRIES_PER_BUCKET_MAX * 2, /* Entries > max allowed */ - .socket_id = 0, - }; - - struct rte_fbk_hash_params invalid_params_8 = { - .name = "invalid_7", - .entries = RTE_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = 4, - .socket_id = RTE_MAX_NUMA_NODES + 1, /* invalid socket */ - }; - - /* try to create two hashes with identical names - * in this case, trying to create a second one will not - * fail but will simply return pointer to the existing - * hash with that name. sort of like a "find hash by name" :-) - */ - struct rte_fbk_hash_params invalid_params_same_name_1 = { - .name = "same_name", /* hash with identical name */ - .entries = 4, - .entries_per_bucket = 2, - .socket_id = 0, - }; - - /* trying to create this hash should return a pointer to an existing hash */ - struct rte_fbk_hash_params invalid_params_same_name_2 = { - .name = "same_name", /* hash with identical name */ - .entries = RTE_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = 4, - .socket_id = 0, - }; - - /* this is a sanity check for "same name" test - * creating this hash will check if we are actually able to create - * multiple hashes with different names (instead of having just one). - */ - struct rte_fbk_hash_params different_name = { - .name = "different_name", /* different name */ - .entries = LOCAL_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = 4, - .socket_id = 0, - }; - - struct rte_fbk_hash_params params_jhash = { - .name = "valid", - .entries = LOCAL_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = 4, - .socket_id = 0, - .hash_func = rte_jhash_1word, /* Tests for different hash_func */ - .init_val = RTE_FBK_HASH_INIT_VAL_DEFAULT, - }; - - struct rte_fbk_hash_params params_nohash = { - .name = "valid nohash", - .entries = LOCAL_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = 4, - .socket_id = 0, - .hash_func = NULL, /* Tests for null hash_func */ - .init_val = RTE_FBK_HASH_INIT_VAL_DEFAULT, - }; - - struct rte_fbk_hash_table *handle, *tmp; - uint32_t keys[5] = - {0xc6e18639, 0xe67c201c, 0xd4c8cffd, 0x44728691, 0xd5430fa9}; - uint16_t vals[5] = {28108, 5699, 38490, 2166, 61571}; - int status; - unsigned i; - double used_entries; - - /* Try creating hashes with invalid parameters */ - printf("# Testing hash creation with invalid parameters " - "- expect error msgs\n"); - handle = rte_fbk_hash_create(&invalid_params_1); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - - handle = rte_fbk_hash_create(&invalid_params_2); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - - handle = rte_fbk_hash_create(&invalid_params_3); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - - handle = rte_fbk_hash_create(&invalid_params_4); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - - handle = rte_fbk_hash_create(&invalid_params_5); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - - handle = rte_fbk_hash_create(&invalid_params_6); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - - handle = rte_fbk_hash_create(&invalid_params_7); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - - handle = rte_fbk_hash_create(&invalid_params_8); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - - handle = rte_fbk_hash_create(&invalid_params_same_name_1); - RETURN_IF_ERROR_FBK(handle == NULL, "fbk hash creation should have succeeded"); - - tmp = rte_fbk_hash_create(&invalid_params_same_name_2); - if (tmp != NULL) - rte_fbk_hash_free(tmp); - RETURN_IF_ERROR_FBK(tmp != NULL, "fbk hash creation should have failed"); - - /* we are not freeing handle here because we need a hash list - * to be not empty for the next test */ - - /* create a hash in non-empty list - good for coverage */ - tmp = rte_fbk_hash_create(&different_name); - RETURN_IF_ERROR_FBK(tmp == NULL, "fbk hash creation should have succeeded"); - - /* free both hashes */ - rte_fbk_hash_free(handle); - rte_fbk_hash_free(tmp); - - /* Create empty jhash hash. */ - handle = rte_fbk_hash_create(¶ms_jhash); - RETURN_IF_ERROR_FBK(handle == NULL, "fbk jhash hash creation failed"); - - /* Cleanup. */ - rte_fbk_hash_free(handle); - - /* Create empty jhash hash. */ - handle = rte_fbk_hash_create(¶ms_nohash); - RETURN_IF_ERROR_FBK(handle == NULL, "fbk nohash hash creation failed"); - - /* Cleanup. */ - rte_fbk_hash_free(handle); - - /* Create empty hash. */ - handle = rte_fbk_hash_create(¶ms); - RETURN_IF_ERROR_FBK(handle == NULL, "fbk hash creation failed"); - - used_entries = rte_fbk_hash_get_load_factor(handle) * LOCAL_FBK_HASH_ENTRIES_MAX; - RETURN_IF_ERROR_FBK((unsigned)used_entries != 0, \ - "load factor right after creation is not zero but it should be"); - /* Add keys. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_add_key(handle, keys[i], vals[i]); - RETURN_IF_ERROR_FBK(status != 0, "fbk hash add failed"); - } - - used_entries = rte_fbk_hash_get_load_factor(handle) * LOCAL_FBK_HASH_ENTRIES_MAX; - RETURN_IF_ERROR_FBK((unsigned)used_entries != (unsigned)((((double)5)/LOCAL_FBK_HASH_ENTRIES_MAX)*LOCAL_FBK_HASH_ENTRIES_MAX), \ - "load factor now is not as expected"); - /* Find value of added keys. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_lookup(handle, keys[i]); - RETURN_IF_ERROR_FBK(status != vals[i], - "fbk hash lookup failed"); - } - - /* Change value of added keys. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_add_key(handle, keys[i], vals[4 - i]); - RETURN_IF_ERROR_FBK(status != 0, "fbk hash update failed"); - } - - /* Find new values. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_lookup(handle, keys[i]); - RETURN_IF_ERROR_FBK(status != vals[4-i], - "fbk hash lookup failed"); - } - - /* Delete keys individually. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_delete_key(handle, keys[i]); - RETURN_IF_ERROR_FBK(status != 0, "fbk hash delete failed"); - } - - used_entries = rte_fbk_hash_get_load_factor(handle) * LOCAL_FBK_HASH_ENTRIES_MAX; - RETURN_IF_ERROR_FBK((unsigned)used_entries != 0, \ - "load factor right after deletion is not zero but it should be"); - /* Lookup should now fail. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_lookup(handle, keys[i]); - RETURN_IF_ERROR_FBK(status == 0, - "fbk hash lookup should have failed"); - } - - /* Add keys again. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_add_key(handle, keys[i], vals[i]); - RETURN_IF_ERROR_FBK(status != 0, "fbk hash add failed"); - } - - /* Make sure they were added. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_lookup(handle, keys[i]); - RETURN_IF_ERROR_FBK(status != vals[i], - "fbk hash lookup failed"); - } - - /* Clear all entries. */ - rte_fbk_hash_clear_all(handle); - - /* Lookup should fail. */ - for (i = 0; i < 5; i++) { - status = rte_fbk_hash_lookup(handle, keys[i]); - RETURN_IF_ERROR_FBK(status == 0, - "fbk hash lookup should have failed"); - } - - /* coverage */ - - /* fill up the hash_table */ - for (i = 0; i < RTE_FBK_HASH_ENTRIES_MAX + 1; i++) - rte_fbk_hash_add_key(handle, i, (uint16_t) i); - - /* Find non-existent key in a full hashtable */ - status = rte_fbk_hash_lookup(handle, RTE_FBK_HASH_ENTRIES_MAX + 1); - RETURN_IF_ERROR_FBK(status != -ENOENT, - "fbk hash lookup succeeded"); - - /* Delete non-existent key in a full hashtable */ - status = rte_fbk_hash_delete_key(handle, RTE_FBK_HASH_ENTRIES_MAX + 1); - RETURN_IF_ERROR_FBK(status != -ENOENT, - "fbk hash delete succeeded"); - - /* Delete one key from a full hashtable */ - status = rte_fbk_hash_delete_key(handle, 1); - RETURN_IF_ERROR_FBK(status != 0, - "fbk hash delete failed"); - - /* Clear all entries. */ - rte_fbk_hash_clear_all(handle); - - /* Cleanup. */ - rte_fbk_hash_free(handle); - - /* Cover the NULL case. */ - rte_fbk_hash_free(0); - - return 0; -} - -/* - * Sequence of operations for find existing fbk hash table - * - * - create table - * - find existing table: hit - * - find non-existing table: miss - * - */ -static int test_fbk_hash_find_existing(void) -{ - struct rte_fbk_hash_params params = { - .name = "fbk_hash_find_existing", - .entries = LOCAL_FBK_HASH_ENTRIES_MAX, - .entries_per_bucket = 4, - .socket_id = 0, - }; - struct rte_fbk_hash_table *handle = NULL, *result = NULL; - - /* Create hash table. */ - handle = rte_fbk_hash_create(¶ms); - RETURN_IF_ERROR_FBK(handle == NULL, "fbk hash creation failed"); - - /* Try to find existing fbk hash table */ - result = rte_fbk_hash_find_existing("fbk_hash_find_existing"); - RETURN_IF_ERROR_FBK(result != handle, "could not find existing fbk hash table"); - - /* Try to find non-existing fbk hash table */ - result = rte_fbk_hash_find_existing("fbk_hash_find_non_existing"); - RETURN_IF_ERROR_FBK(!(result == NULL), "found fbk table that shouldn't exist"); - - /* Cleanup. */ - rte_fbk_hash_free(handle); - - return 0; -} - -#define BUCKET_ENTRIES 4 -/* - * Do tests for hash creation with bad parameters. - */ -static int test_hash_creation_with_bad_parameters(void) -{ - struct rte_hash *handle, *tmp; - struct rte_hash_parameters params; - - handle = rte_hash_create(NULL); - if (handle != NULL) { - rte_hash_free(handle); - printf("Impossible creating hash sucessfully without any parameter\n"); - return -1; - } - - memcpy(¶ms, &ut_params, sizeof(params)); - params.name = "creation_with_bad_parameters_0"; - params.entries = RTE_HASH_ENTRIES_MAX + 1; - handle = rte_hash_create(¶ms); - if (handle != NULL) { - rte_hash_free(handle); - printf("Impossible creating hash sucessfully with entries in parameter exceeded\n"); - return -1; - } - - memcpy(¶ms, &ut_params, sizeof(params)); - params.name = "creation_with_bad_parameters_2"; - params.entries = BUCKET_ENTRIES - 1; - handle = rte_hash_create(¶ms); - if (handle != NULL) { - rte_hash_free(handle); - printf("Impossible creating hash sucessfully if entries less than bucket_entries in parameter\n"); - return -1; - } - - memcpy(¶ms, &ut_params, sizeof(params)); - params.name = "creation_with_bad_parameters_3"; - params.key_len = 0; - handle = rte_hash_create(¶ms); - if (handle != NULL) { - rte_hash_free(handle); - printf("Impossible creating hash sucessfully if key_len in parameter is zero\n"); - return -1; - } - - memcpy(¶ms, &ut_params, sizeof(params)); - params.name = "creation_with_bad_parameters_4"; - params.socket_id = RTE_MAX_NUMA_NODES + 1; - handle = rte_hash_create(¶ms); - if (handle != NULL) { - rte_hash_free(handle); - printf("Impossible creating hash sucessfully with invalid socket\n"); - return -1; - } - - /* test with same name should fail */ - memcpy(¶ms, &ut_params, sizeof(params)); - params.name = "same_name"; - handle = rte_hash_create(¶ms); - if (handle == NULL) { - printf("Cannot create first hash table with 'same_name'\n"); - return -1; - } - tmp = rte_hash_create(¶ms); - if (tmp != NULL) { - printf("Creation of hash table with same name should fail\n"); - rte_hash_free(handle); - rte_hash_free(tmp); - return -1; - } - rte_hash_free(handle); - - printf("# Test successful. No more errors expected\n"); - - return 0; -} - -/* - * Do tests for hash creation with parameters that look incorrect - * but are actually valid. - */ -static int -test_hash_creation_with_good_parameters(void) -{ - struct rte_hash *handle; - struct rte_hash_parameters params; - - /* create with null hash function - should choose DEFAULT_HASH_FUNC */ - memcpy(¶ms, &ut_params, sizeof(params)); - params.name = "name"; - params.hash_func = NULL; - handle = rte_hash_create(¶ms); - if (handle == NULL) { - printf("Creating hash with null hash_func failed\n"); - return -1; - } - - rte_hash_free(handle); - - return 0; -} - -#define ITERATIONS 3 -/* - * Test to see the average table utilization (entries added/max entries) - * before hitting a random entry that cannot be added - */ -static int test_average_table_utilization(void) -{ - struct rte_hash *handle; - uint8_t simple_key[MAX_KEYSIZE]; - unsigned i, j; - unsigned added_keys, average_keys_added = 0; - int ret; - - printf("\n# Running test to determine average utilization" - "\n before adding elements begins to fail\n"); - printf("Measuring performance, please wait"); - fflush(stdout); - ut_params.entries = 1 << 16; - ut_params.name = "test_average_utilization"; - ut_params.hash_func = rte_jhash; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - for (j = 0; j < ITERATIONS; j++) { - ret = 0; - /* Add random entries until key cannot be added */ - for (added_keys = 0; ret >= 0; added_keys++) { - for (i = 0; i < ut_params.key_len; i++) - simple_key[i] = rte_rand() % 255; - ret = rte_hash_add_key(handle, simple_key); - } - if (ret != -ENOSPC) { - printf("Unexpected error when adding keys\n"); - rte_hash_free(handle); - return -1; - } - - average_keys_added += added_keys; - - /* Reset the table */ - rte_hash_reset(handle); - - /* Print a dot to show progress on operations */ - printf("."); - fflush(stdout); - } - - average_keys_added /= ITERATIONS; - - printf("\nAverage table utilization = %.2f%% (%u/%u)\n", - ((double) average_keys_added / ut_params.entries * 100), - average_keys_added, ut_params.entries); - rte_hash_free(handle); - - return 0; -} - -#define NUM_ENTRIES 256 -static int test_hash_iteration(void) -{ - struct rte_hash *handle; - unsigned i; - uint8_t keys[NUM_ENTRIES][MAX_KEYSIZE]; - const void *next_key; - void *next_data; - void *data[NUM_ENTRIES]; - unsigned added_keys; - uint32_t iter = 0; - int ret = 0; - - ut_params.entries = NUM_ENTRIES; - ut_params.name = "test_hash_iteration"; - ut_params.hash_func = rte_jhash; - ut_params.key_len = 16; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - /* Add random entries until key cannot be added */ - for (added_keys = 0; added_keys < NUM_ENTRIES; added_keys++) { - data[added_keys] = (void *) ((uintptr_t) rte_rand()); - for (i = 0; i < ut_params.key_len; i++) - keys[added_keys][i] = rte_rand() % 255; - ret = rte_hash_add_key_data(handle, keys[added_keys], data[added_keys]); - if (ret < 0) - break; - } - - /* Iterate through the hash table */ - while (rte_hash_iterate(handle, &next_key, &next_data, &iter) >= 0) { - /* Search for the key in the list of keys added */ - for (i = 0; i < NUM_ENTRIES; i++) { - if (memcmp(next_key, keys[i], ut_params.key_len) == 0) { - if (next_data != data[i]) { - printf("Data found in the hash table is" - "not the data added with the key\n"); - goto err; - } - added_keys--; - break; - } - } - if (i == NUM_ENTRIES) { - printf("Key found in the hash table was not added\n"); - goto err; - } - } - - /* Check if all keys have been iterated */ - if (added_keys != 0) { - printf("There were still %u keys to iterate\n", added_keys); - goto err; - } - - rte_hash_free(handle); - return 0; - -err: - rte_hash_free(handle); - return -1; -} - -static uint8_t key[16] = {0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f}; -static struct rte_hash_parameters hash_params_ex = { - .name = NULL, - .entries = 64, - .key_len = 0, - .hash_func = NULL, - .hash_func_init_val = 0, - .socket_id = 0, -}; - -/* - * add/delete key with jhash2 - */ -static int -test_hash_add_delete_jhash2(void) -{ - int ret = -1; - struct rte_hash *handle; - int32_t pos1, pos2; - - hash_params_ex.name = "hash_test_jhash2"; - hash_params_ex.key_len = 4; - hash_params_ex.hash_func = (rte_hash_function)rte_jhash_32b; - - handle = rte_hash_create(&hash_params_ex); - if (handle == NULL) { - printf("test_hash_add_delete_jhash2 fail to create hash\n"); - goto fail_jhash2; - } - pos1 = rte_hash_add_key(handle, (void *)&key[0]); - if (pos1 < 0) { - printf("test_hash_add_delete_jhash2 fail to add hash key\n"); - goto fail_jhash2; - } - - pos2 = rte_hash_del_key(handle, (void *)&key[0]); - if (pos2 < 0 || pos1 != pos2) { - printf("test_hash_add_delete_jhash2 delete different key from being added\n"); - goto fail_jhash2; - } - ret = 0; - -fail_jhash2: - if (handle != NULL) - rte_hash_free(handle); - - return ret; -} - -/* - * add/delete (2) key with jhash2 - */ -static int -test_hash_add_delete_2_jhash2(void) -{ - int ret = -1; - struct rte_hash *handle; - int32_t pos1, pos2; - - hash_params_ex.name = "hash_test_2_jhash2"; - hash_params_ex.key_len = 8; - hash_params_ex.hash_func = (rte_hash_function)rte_jhash_32b; - - handle = rte_hash_create(&hash_params_ex); - if (handle == NULL) - goto fail_2_jhash2; - - pos1 = rte_hash_add_key(handle, (void *)&key[0]); - if (pos1 < 0) - goto fail_2_jhash2; - - pos2 = rte_hash_del_key(handle, (void *)&key[0]); - if (pos2 < 0 || pos1 != pos2) - goto fail_2_jhash2; - - ret = 0; - -fail_2_jhash2: - if (handle != NULL) - rte_hash_free(handle); - - return ret; -} - -static uint32_t -test_hash_jhash_1word(const void *key, uint32_t length, uint32_t initval) -{ - const uint32_t *k = key; - - RTE_SET_USED(length); - - return rte_jhash_1word(k[0], initval); -} - -static uint32_t -test_hash_jhash_2word(const void *key, uint32_t length, uint32_t initval) -{ - const uint32_t *k = key; - - RTE_SET_USED(length); - - return rte_jhash_2words(k[0], k[1], initval); -} - -static uint32_t -test_hash_jhash_3word(const void *key, uint32_t length, uint32_t initval) -{ - const uint32_t *k = key; - - RTE_SET_USED(length); - - return rte_jhash_3words(k[0], k[1], k[2], initval); -} - -/* - * add/delete key with jhash 1word - */ -static int -test_hash_add_delete_jhash_1word(void) -{ - int ret = -1; - struct rte_hash *handle; - int32_t pos1, pos2; - - hash_params_ex.name = "hash_test_jhash_1word"; - hash_params_ex.key_len = 4; - hash_params_ex.hash_func = test_hash_jhash_1word; - - handle = rte_hash_create(&hash_params_ex); - if (handle == NULL) - goto fail_jhash_1word; - - pos1 = rte_hash_add_key(handle, (void *)&key[0]); - if (pos1 < 0) - goto fail_jhash_1word; - - pos2 = rte_hash_del_key(handle, (void *)&key[0]); - if (pos2 < 0 || pos1 != pos2) - goto fail_jhash_1word; - - ret = 0; - -fail_jhash_1word: - if (handle != NULL) - rte_hash_free(handle); - - return ret; -} - -/* - * add/delete key with jhash 2word - */ -static int -test_hash_add_delete_jhash_2word(void) -{ - int ret = -1; - struct rte_hash *handle; - int32_t pos1, pos2; - - hash_params_ex.name = "hash_test_jhash_2word"; - hash_params_ex.key_len = 8; - hash_params_ex.hash_func = test_hash_jhash_2word; - - handle = rte_hash_create(&hash_params_ex); - if (handle == NULL) - goto fail_jhash_2word; - - pos1 = rte_hash_add_key(handle, (void *)&key[0]); - if (pos1 < 0) - goto fail_jhash_2word; - - pos2 = rte_hash_del_key(handle, (void *)&key[0]); - if (pos2 < 0 || pos1 != pos2) - goto fail_jhash_2word; - - ret = 0; - -fail_jhash_2word: - if (handle != NULL) - rte_hash_free(handle); - - return ret; -} - -/* - * add/delete key with jhash 3word - */ -static int -test_hash_add_delete_jhash_3word(void) -{ - int ret = -1; - struct rte_hash *handle; - int32_t pos1, pos2; - - hash_params_ex.name = "hash_test_jhash_3word"; - hash_params_ex.key_len = 12; - hash_params_ex.hash_func = test_hash_jhash_3word; - - handle = rte_hash_create(&hash_params_ex); - if (handle == NULL) - goto fail_jhash_3word; - - pos1 = rte_hash_add_key(handle, (void *)&key[0]); - if (pos1 < 0) - goto fail_jhash_3word; - - pos2 = rte_hash_del_key(handle, (void *)&key[0]); - if (pos2 < 0 || pos1 != pos2) - goto fail_jhash_3word; - - ret = 0; - -fail_jhash_3word: - if (handle != NULL) - rte_hash_free(handle); - - return ret; -} - -/* - * Do all unit and performance tests. - */ -static int -test_hash(void) -{ - if (test_add_delete() < 0) - return -1; - if (test_hash_add_delete_jhash2() < 0) - return -1; - if (test_hash_add_delete_2_jhash2() < 0) - return -1; - if (test_hash_add_delete_jhash_1word() < 0) - return -1; - if (test_hash_add_delete_jhash_2word() < 0) - return -1; - if (test_hash_add_delete_jhash_3word() < 0) - return -1; - if (test_hash_get_key_with_position() < 0) - return -1; - if (test_hash_find_existing() < 0) - return -1; - if (test_add_update_delete() < 0) - return -1; - if (test_five_keys() < 0) - return -1; - if (test_full_bucket() < 0) - return -1; - - if (test_fbk_hash_find_existing() < 0) - return -1; - if (fbk_hash_unit_test() < 0) - return -1; - if (test_hash_creation_with_bad_parameters() < 0) - return -1; - if (test_hash_creation_with_good_parameters() < 0) - return -1; - if (test_average_table_utilization() < 0) - return -1; - if (test_hash_iteration() < 0) - return -1; - - run_hash_func_tests(); - - if (test_crc32_hash_alg_equiv() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(hash_autotest, test_hash); diff --git a/app/test/test_hash_functions.c b/app/test/test_hash_functions.c deleted file mode 100644 index 9652b04d45..0000000000 --- a/app/test/test_hash_functions.c +++ /dev/null @@ -1,322 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2015 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * Hash values calculated for key sizes from array "hashtest_key_lens" - * and for initial values from array "hashtest_initvals. - * Each key will be formed by increasing each byte by 1: - * e.g.: key size = 4, key = 0x03020100 - * key size = 8, key = 0x0706050403020100 - */ -static uint32_t hash_values_jhash[2][12] = {{ - 0x8ba9414b, 0xdf0d39c9, - 0xe4cf1d42, 0xd4ccb93c, 0x5e84eafc, 0x21362cfe, - 0x2f4775ab, 0x9ff036cc, 0xeca51474, 0xbc9d6816, - 0x12926a31, 0x1c9fa888 -}, -{ - 0x5c62c303, 0x1b8cf784, - 0x8270ac65, 0x05fa6668, 0x762df861, 0xda088f2f, - 0x59614cd4, 0x7a94f690, 0xdc1e4993, 0x30825494, - 0x91d0e462, 0x768087fc -} -}; -static uint32_t hash_values_crc[2][12] = {{ - 0x00000000, 0xf26b8303, - 0x91545164, 0x06040eb1, 0x9bb99201, 0xcc4c4fe4, - 0x14a90993, 0xf8a5dd8c, 0xcaa1ad0b, 0x7ac1e03e, - 0x43f44466, 0x4a11475e -}, -{ - 0xbdfd3980, 0x70204542, - 0x98cd4c70, 0xd52c702f, 0x41fc0e1c, 0x3905f65c, - 0x94bff47f, 0x1bab102d, 0xf4a2c645, 0xbf441539, - 0x789c104f, 0x53028d3e -} -}; - -/******************************************************************************* - * Hash function performance test configuration section. Each performance test - * will be performed HASHTEST_ITERATIONS times. - * - * The three arrays below control what tests are performed. Every combination - * from the array entries is tested. - */ -#define HASHTEST_ITERATIONS 1000000 -#define MAX_KEYSIZE 64 -static rte_hash_function hashtest_funcs[] = {rte_jhash, rte_hash_crc}; -static uint32_t hashtest_initvals[] = {0, 0xdeadbeef}; -static uint32_t hashtest_key_lens[] = { - 1, 2, /* Unusual key sizes */ - 4, 8, 16, 32, 48, 64, /* standard key sizes */ - 9, /* IPv4 SRC + DST + protocol, unpadded */ - 13, /* IPv4 5-tuple, unpadded */ - 37, /* IPv6 5-tuple, unpadded */ - 40 /* IPv6 5-tuple, padded to 8-byte boundary */ -}; -/******************************************************************************/ - -/* - * To help print out name of hash functions. - */ -static const char * -get_hash_name(rte_hash_function f) -{ - if (f == rte_jhash) - return "jhash"; - - if (f == rte_hash_crc) - return "rte_hash_crc"; - - return "UnknownHash"; -} - -/* - * Test a hash function. - */ -static void -run_hash_func_perf_test(uint32_t key_len, uint32_t init_val, - rte_hash_function f) -{ - static uint8_t key[HASHTEST_ITERATIONS][MAX_KEYSIZE]; - uint64_t ticks, start, end; - unsigned i, j; - - for (i = 0; i < HASHTEST_ITERATIONS; i++) { - for (j = 0; j < key_len; j++) - key[i][j] = (uint8_t) rte_rand(); - } - - start = rte_rdtsc(); - for (i = 0; i < HASHTEST_ITERATIONS; i++) - f(key[i], key_len, init_val); - end = rte_rdtsc(); - ticks = end - start; - - printf("%-12s, %-18u, %-13u, %.02f\n", get_hash_name(f), (unsigned) key_len, - (unsigned) init_val, (double)ticks / HASHTEST_ITERATIONS); -} - -/* - * Test all hash functions. - */ -static void -run_hash_func_perf_tests(void) -{ - unsigned i, j, k; - - printf(" *** Hash function performance test results ***\n"); - printf(" Number of iterations for each test = %d\n", - HASHTEST_ITERATIONS); - printf("Hash Func. , Key Length (bytes), Initial value, Ticks/Op.\n"); - - for (i = 0; i < RTE_DIM(hashtest_initvals); i++) { - for (j = 0; j < RTE_DIM(hashtest_key_lens); j++) { - for (k = 0; k < RTE_DIM(hashtest_funcs); k++) { - run_hash_func_perf_test(hashtest_key_lens[j], - hashtest_initvals[i], - hashtest_funcs[k]); - } - } - } -} - -/* - * Verify that hash functions return what they are expected to return - * (using precalculated values stored above) - */ -static int -verify_precalculated_hash_func_tests(void) -{ - unsigned i, j; - uint8_t key[64]; - uint32_t hash; - - for (i = 0; i < 64; i++) - key[i] = (uint8_t) i; - - for (i = 0; i < sizeof(hashtest_key_lens) / sizeof(uint32_t); i++) { - for (j = 0; j < sizeof(hashtest_initvals) / sizeof(uint32_t); j++) { - hash = rte_jhash(key, hashtest_key_lens[i], - hashtest_initvals[j]); - if (hash != hash_values_jhash[j][i]) { - printf("jhash for %u bytes with initial value 0x%x." - "Expected 0x%x, but got 0x%x\n", - hashtest_key_lens[i], hashtest_initvals[j], - hash_values_jhash[j][i], hash); - return -1; - } - - hash = rte_hash_crc(key, hashtest_key_lens[i], - hashtest_initvals[j]); - if (hash != hash_values_crc[j][i]) { - printf("CRC for %u bytes with initial value 0x%x." - "Expected 0x%x, but got 0x%x\n", - hashtest_key_lens[i], hashtest_initvals[j], - hash_values_crc[j][i], hash); - return -1; - } - } - } - - return 0; -} - -/* - * Verify that rte_jhash and rte_jhash_32b return the same - */ -static int -verify_jhash_32bits(void) -{ - unsigned i, j; - uint8_t key[64]; - uint32_t hash, hash32; - - for (i = 0; i < 64; i++) - key[i] = rand() & 0xff; - - for (i = 0; i < sizeof(hashtest_key_lens) / sizeof(uint32_t); i++) { - for (j = 0; j < sizeof(hashtest_initvals) / sizeof(uint32_t); j++) { - /* Key size must be multiple of 4 (32 bits) */ - if ((hashtest_key_lens[i] & 0x3) == 0) { - hash = rte_jhash(key, hashtest_key_lens[i], - hashtest_initvals[j]); - /* Divide key length by 4 in rte_jhash for 32 bits */ - hash32 = rte_jhash_32b((const unaligned_uint32_t *)key, - hashtest_key_lens[i] >> 2, - hashtest_initvals[j]); - if (hash != hash32) { - printf("rte_jhash returns different value (0x%x)" - "than rte_jhash_32b (0x%x)\n", - hash, hash32); - return -1; - } - } - } - } - - return 0; -} - -/* - * Verify that rte_jhash and rte_jhash_1word, rte_jhash_2words - * and rte_jhash_3words return the same - */ -static int -verify_jhash_words(void) -{ - unsigned i; - uint32_t key[3]; - uint32_t hash, hash_words; - - for (i = 0; i < 3; i++) - key[i] = rand(); - - /* Test rte_jhash_1word */ - hash = rte_jhash(key, 4, 0); - hash_words = rte_jhash_1word(key[0], 0); - if (hash != hash_words) { - printf("rte_jhash returns different value (0x%x)" - "than rte_jhash_1word (0x%x)\n", - hash, hash_words); - return -1; - } - /* Test rte_jhash_2words */ - hash = rte_jhash(key, 8, 0); - hash_words = rte_jhash_2words(key[0], key[1], 0); - if (hash != hash_words) { - printf("rte_jhash returns different value (0x%x)" - "than rte_jhash_2words (0x%x)\n", - hash, hash_words); - return -1; - } - /* Test rte_jhash_3words */ - hash = rte_jhash(key, 12, 0); - hash_words = rte_jhash_3words(key[0], key[1], key[2], 0); - if (hash != hash_words) { - printf("rte_jhash returns different value (0x%x)" - "than rte_jhash_3words (0x%x)\n", - hash, hash_words); - return -1; - } - - return 0; -} - -/* - * Run all functional tests for hash functions - */ -static int -run_hash_func_tests(void) -{ - if (verify_precalculated_hash_func_tests() != 0) - return -1; - - if (verify_jhash_32bits() != 0) - return -1; - - if (verify_jhash_words() != 0) - return -1; - - return 0; - -} - -static int -test_hash_functions(void) -{ - if (run_hash_func_tests() != 0) - return -1; - - run_hash_func_perf_tests(); - - return 0; -} - -REGISTER_TEST_COMMAND(hash_functions_autotest, test_hash_functions); diff --git a/app/test/test_hash_multiwriter.c b/app/test/test_hash_multiwriter.c deleted file mode 100644 index 4dcbd9d56d..0000000000 --- a/app/test/test_hash_multiwriter.c +++ /dev/null @@ -1,281 +0,0 @@ -/*- - * 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 -#include - -#include -#include -#include -#include -#include -#include -#include - -#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) -{ - 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; - if (test_hash_multiwriter() < 0) - return -1; - } - - printf("Test multi-writer without Hardware transactional memory\n"); - use_htm = 0; - if (test_hash_multiwriter() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(hash_multiwriter_autotest, test_hash_multiwriter_main); diff --git a/app/test/test_hash_perf.c b/app/test/test_hash_perf.c deleted file mode 100644 index c0051b20fb..0000000000 --- a/app/test/test_hash_perf.c +++ /dev/null @@ -1,659 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2015 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 -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define MAX_ENTRIES (1 << 19) -#define KEYS_TO_ADD (MAX_ENTRIES * 3 / 4) /* 75% table utilization */ -#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ -#define BUCKET_SIZE 4 -#define NUM_BUCKETS (MAX_ENTRIES / BUCKET_SIZE) -#define MAX_KEYSIZE 64 -#define NUM_KEYSIZES 10 -#define NUM_SHUFFLES 10 -#define BURST_SIZE 16 - -enum operations { - ADD = 0, - LOOKUP, - LOOKUP_MULTI, - DELETE, - NUM_OPERATIONS -}; - -static uint32_t hashtest_key_lens[] = { - /* standard key sizes */ - 4, 8, 16, 32, 48, 64, - /* IPv4 SRC + DST + protocol, unpadded */ - 9, - /* IPv4 5-tuple, unpadded */ - 13, - /* IPv6 5-tuple, unpadded */ - 37, - /* IPv6 5-tuple, padded to 8-byte boundary */ - 40 -}; - -struct rte_hash *h[NUM_KEYSIZES]; - -/* Array that stores if a slot is full */ -uint8_t slot_taken[MAX_ENTRIES]; - -/* Array to store number of cycles per operation */ -uint64_t cycles[NUM_KEYSIZES][NUM_OPERATIONS][2][2]; - -/* Array to store all input keys */ -uint8_t keys[KEYS_TO_ADD][MAX_KEYSIZE]; - -/* Array to store the precomputed hash for 'keys' */ -hash_sig_t signatures[KEYS_TO_ADD]; - -/* Array to store how many busy entries have each bucket */ -uint8_t buckets[NUM_BUCKETS]; - -/* Array to store the positions where keys are added */ -int32_t positions[KEYS_TO_ADD]; - -/* Parameters used for hash table in unit test functions. */ -static struct rte_hash_parameters ut_params = { - .entries = MAX_ENTRIES, - .hash_func = rte_jhash, - .hash_func_init_val = 0, -}; - -static int -create_table(unsigned with_data, unsigned table_index) -{ - char name[RTE_HASH_NAMESIZE]; - - if (with_data) - /* Table will store 8-byte data */ - sprintf(name, "test_hash%d_data", hashtest_key_lens[table_index]); - else - sprintf(name, "test_hash%d", hashtest_key_lens[table_index]); - - ut_params.name = name; - ut_params.key_len = hashtest_key_lens[table_index]; - ut_params.socket_id = rte_socket_id(); - h[table_index] = rte_hash_find_existing(name); - if (h[table_index] != NULL) - /* - * If table was already created, free it to create it again, - * so we force it is empty - */ - rte_hash_free(h[table_index]); - h[table_index] = rte_hash_create(&ut_params); - if (h[table_index] == NULL) { - printf("Error creating table\n"); - return -1; - } - return 0; - -} - -/* Shuffle the keys that have been added, so lookups will be totally random */ -static void -shuffle_input_keys(unsigned table_index) -{ - unsigned i; - uint32_t swap_idx; - uint8_t temp_key[MAX_KEYSIZE]; - hash_sig_t temp_signature; - int32_t temp_position; - - for (i = KEYS_TO_ADD - 1; i > 0; i--) { - swap_idx = rte_rand() % i; - - memcpy(temp_key, keys[i], hashtest_key_lens[table_index]); - temp_signature = signatures[i]; - temp_position = positions[i]; - - memcpy(keys[i], keys[swap_idx], hashtest_key_lens[table_index]); - signatures[i] = signatures[swap_idx]; - positions[i] = positions[swap_idx]; - - memcpy(keys[swap_idx], temp_key, hashtest_key_lens[table_index]); - signatures[swap_idx] = temp_signature; - positions[swap_idx] = temp_position; - } -} - -/* - * Looks for random keys which - * ALL can fit in hash table (no errors) - */ -static int -get_input_keys(unsigned with_pushes, unsigned table_index) -{ - unsigned i, j; - unsigned bucket_idx, incr, success = 1; - uint8_t k = 0; - int32_t ret; - const uint32_t bucket_bitmask = NUM_BUCKETS - 1; - - /* Reset all arrays */ - for (i = 0; i < MAX_ENTRIES; i++) - slot_taken[i] = 0; - - for (i = 0; i < NUM_BUCKETS; i++) - buckets[i] = 0; - - for (j = 0; j < hashtest_key_lens[table_index]; j++) - keys[0][j] = 0; - - /* - * Add only entries that are not duplicated and that fits in the table - * (cannot store more than BUCKET_SIZE entries in a bucket). - * Regardless a key has been added correctly or not (success), - * the next one to try will be increased by 1. - */ - for (i = 0; i < KEYS_TO_ADD;) { - incr = 0; - if (i != 0) { - keys[i][0] = ++k; - /* Overflow, need to increment the next byte */ - if (keys[i][0] == 0) - incr = 1; - for (j = 1; j < hashtest_key_lens[table_index]; j++) { - /* Do not increase next byte */ - if (incr == 0) - if (success == 1) - keys[i][j] = keys[i - 1][j]; - else - keys[i][j] = keys[i][j]; - /* Increase next byte by one */ - else { - if (success == 1) - keys[i][j] = keys[i-1][j] + 1; - else - keys[i][j] = keys[i][j] + 1; - if (keys[i][j] == 0) - incr = 1; - else - incr = 0; - } - } - } - success = 0; - signatures[i] = rte_hash_hash(h[table_index], keys[i]); - bucket_idx = signatures[i] & bucket_bitmask; - /* - * If we are not inserting keys in secondary location, - * when bucket is full, do not try to insert the key - */ - if (with_pushes == 0) - if (buckets[bucket_idx] == BUCKET_SIZE) - continue; - - /* If key can be added, leave in successful key arrays "keys" */ - ret = rte_hash_add_key_with_hash(h[table_index], keys[i], - signatures[i]); - if (ret >= 0) { - /* If key is already added, ignore the entry and do not store */ - if (slot_taken[ret]) - continue; - else { - /* Store the returned position and mark slot as taken */ - slot_taken[ret] = 1; - positions[i] = ret; - buckets[bucket_idx]++; - success = 1; - i++; - } - } - } - - /* Reset the table, so we can measure the time to add all the entries */ - rte_hash_free(h[table_index]); - h[table_index] = rte_hash_create(&ut_params); - - return 0; -} - -static int -timed_adds(unsigned with_hash, unsigned with_data, unsigned table_index) -{ - unsigned i; - const uint64_t start_tsc = rte_rdtsc(); - void *data; - int32_t ret; - - for (i = 0; i < KEYS_TO_ADD; i++) { - data = (void *) ((uintptr_t) signatures[i]); - if (with_hash && with_data) { - ret = rte_hash_add_key_with_hash_data(h[table_index], - (const void *) keys[i], - signatures[i], data); - if (ret < 0) { - printf("Failed to add key number %u\n", ret); - return -1; - } - } else if (with_hash && !with_data) { - ret = rte_hash_add_key_with_hash(h[table_index], - (const void *) keys[i], - signatures[i]); - if (ret >= 0) - positions[i] = ret; - else { - printf("Failed to add key number %u\n", ret); - return -1; - } - } else if (!with_hash && with_data) { - ret = rte_hash_add_key_data(h[table_index], - (const void *) keys[i], - data); - if (ret < 0) { - printf("Failed to add key number %u\n", ret); - return -1; - } - } else { - ret = rte_hash_add_key(h[table_index], keys[i]); - if (ret >= 0) - positions[i] = ret; - else { - printf("Failed to add key number %u\n", ret); - return -1; - } - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[table_index][ADD][with_hash][with_data] = time_taken/KEYS_TO_ADD; - - return 0; -} - -static int -timed_lookups(unsigned with_hash, unsigned with_data, unsigned table_index) -{ - unsigned i, j; - const uint64_t start_tsc = rte_rdtsc(); - void *ret_data; - void *expected_data; - int32_t ret; - - for (i = 0; i < NUM_LOOKUPS/KEYS_TO_ADD; i++) { - for (j = 0; j < KEYS_TO_ADD; j++) { - if (with_hash && with_data) { - ret = rte_hash_lookup_with_hash_data(h[table_index], - (const void *) keys[j], - signatures[j], &ret_data); - if (ret < 0) { - printf("Key number %u was not found\n", j); - return -1; - } - expected_data = (void *) ((uintptr_t) signatures[j]); - if (ret_data != expected_data) { - printf("Data returned for key number %u is %p," - " but should be %p\n", j, ret_data, - expected_data); - return -1; - } - } else if (with_hash && !with_data) { - ret = rte_hash_lookup_with_hash(h[table_index], - (const void *) keys[j], - signatures[j]); - if (ret < 0 || ret != positions[j]) { - printf("Key looked up in %d, should be in %d\n", - ret, positions[j]); - return -1; - } - } else if (!with_hash && with_data) { - ret = rte_hash_lookup_data(h[table_index], - (const void *) keys[j], &ret_data); - if (ret < 0) { - printf("Key number %u was not found\n", j); - return -1; - } - expected_data = (void *) ((uintptr_t) signatures[j]); - if (ret_data != expected_data) { - printf("Data returned for key number %u is %p," - " but should be %p\n", j, ret_data, - expected_data); - return -1; - } - } else { - ret = rte_hash_lookup(h[table_index], keys[j]); - if (ret < 0 || ret != positions[j]) { - printf("Key looked up in %d, should be in %d\n", - ret, positions[j]); - return -1; - } - } - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[table_index][LOOKUP][with_hash][with_data] = time_taken/NUM_LOOKUPS; - - return 0; -} - -static int -timed_lookups_multi(unsigned with_data, unsigned table_index) -{ - unsigned i, j, k; - int32_t positions_burst[BURST_SIZE]; - const void *keys_burst[BURST_SIZE]; - void *expected_data[BURST_SIZE]; - void *ret_data[BURST_SIZE]; - uint64_t hit_mask; - int ret; - - const uint64_t start_tsc = rte_rdtsc(); - - for (i = 0; i < NUM_LOOKUPS/KEYS_TO_ADD; i++) { - for (j = 0; j < KEYS_TO_ADD/BURST_SIZE; j++) { - for (k = 0; k < BURST_SIZE; k++) - keys_burst[k] = keys[j * BURST_SIZE + k]; - if (with_data) { - ret = rte_hash_lookup_bulk_data(h[table_index], - (const void **) keys_burst, - BURST_SIZE, - &hit_mask, - ret_data); - if (ret != BURST_SIZE) { - printf("Expect to find %u keys," - " but found %d\n", BURST_SIZE, ret); - return -1; - } - for (k = 0; k < BURST_SIZE; k++) { - if ((hit_mask & (1ULL << k)) == 0) { - printf("Key number %u not found\n", - j * BURST_SIZE + k); - return -1; - } - expected_data[k] = (void *) ((uintptr_t) signatures[j * BURST_SIZE + k]); - if (ret_data[k] != expected_data[k]) { - printf("Data returned for key number %u is %p," - " but should be %p\n", j * BURST_SIZE + k, - ret_data[k], expected_data[k]); - return -1; - } - } - } else { - rte_hash_lookup_bulk(h[table_index], - (const void **) keys_burst, - BURST_SIZE, - positions_burst); - for (k = 0; k < BURST_SIZE; k++) { - if (positions_burst[k] != positions[j * BURST_SIZE + k]) { - printf("Key looked up in %d, should be in %d\n", - positions_burst[k], - positions[j * BURST_SIZE + k]); - return -1; - } - } - } - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[table_index][LOOKUP_MULTI][0][with_data] = time_taken/NUM_LOOKUPS; - - return 0; -} - -static int -timed_deletes(unsigned with_hash, unsigned with_data, unsigned table_index) -{ - unsigned i; - const uint64_t start_tsc = rte_rdtsc(); - int32_t ret; - - for (i = 0; i < KEYS_TO_ADD; i++) { - /* There are no delete functions with data, so just call two functions */ - if (with_hash) - ret = rte_hash_del_key_with_hash(h[table_index], - (const void *) keys[i], - signatures[i]); - else - ret = rte_hash_del_key(h[table_index], - (const void *) keys[i]); - if (ret >= 0) - positions[i] = ret; - else { - printf("Failed to add key number %u\n", ret); - return -1; - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[table_index][DELETE][with_hash][with_data] = time_taken/KEYS_TO_ADD; - - return 0; -} - -static void -free_table(unsigned table_index) -{ - rte_hash_free(h[table_index]); -} - -static void -reset_table(unsigned table_index) -{ - rte_hash_reset(h[table_index]); -} - -static int -run_all_tbl_perf_tests(unsigned with_pushes) -{ - unsigned i, j, with_data, with_hash; - - printf("Measuring performance, please wait"); - fflush(stdout); - - for (with_data = 0; with_data <= 1; with_data++) { - for (i = 0; i < NUM_KEYSIZES; i++) { - if (create_table(with_data, i) < 0) - return -1; - - if (get_input_keys(with_pushes, i) < 0) - return -1; - for (with_hash = 0; with_hash <= 1; with_hash++) { - if (timed_adds(with_hash, with_data, i) < 0) - return -1; - - for (j = 0; j < NUM_SHUFFLES; j++) - shuffle_input_keys(i); - - if (timed_lookups(with_hash, with_data, i) < 0) - return -1; - - if (timed_lookups_multi(with_data, i) < 0) - return -1; - - if (timed_deletes(with_hash, with_data, i) < 0) - return -1; - - /* Print a dot to show progress on operations */ - printf("."); - fflush(stdout); - - reset_table(i); - } - free_table(i); - } - } - - printf("\nResults (in CPU cycles/operation)\n"); - printf("-----------------------------------\n"); - for (with_data = 0; with_data <= 1; with_data++) { - if (with_data) - printf("\n Operations with 8-byte data\n"); - else - printf("\n Operations without data\n"); - for (with_hash = 0; with_hash <= 1; with_hash++) { - if (with_hash) - printf("\nWith pre-computed hash values\n"); - else - printf("\nWithout pre-computed hash values\n"); - - printf("\n%-18s%-18s%-18s%-18s%-18s\n", - "Keysize", "Add", "Lookup", "Lookup_bulk", "Delete"); - for (i = 0; i < NUM_KEYSIZES; i++) { - printf("%-18d", hashtest_key_lens[i]); - for (j = 0; j < NUM_OPERATIONS; j++) - printf("%-18"PRIu64, cycles[i][j][with_hash][with_data]); - printf("\n"); - } - } - } - return 0; -} - -/* Control operation of performance testing of fbk hash. */ -#define LOAD_FACTOR 0.667 /* How full to make the hash table. */ -#define TEST_SIZE 1000000 /* How many operations to time. */ -#define TEST_ITERATIONS 30 /* How many measurements to take. */ -#define ENTRIES (1 << 15) /* How many entries. */ - -static int -fbk_hash_perf_test(void) -{ - struct rte_fbk_hash_params params = { - .name = "fbk_hash_test", - .entries = ENTRIES, - .entries_per_bucket = 4, - .socket_id = rte_socket_id(), - }; - struct rte_fbk_hash_table *handle = NULL; - uint32_t *keys = NULL; - unsigned indexes[TEST_SIZE]; - uint64_t lookup_time = 0; - unsigned added = 0; - unsigned value = 0; - uint32_t key; - uint16_t val; - unsigned i, j; - - handle = rte_fbk_hash_create(¶ms); - if (handle == NULL) { - printf("Error creating table\n"); - return -1; - } - - keys = rte_zmalloc(NULL, ENTRIES * sizeof(*keys), 0); - if (keys == NULL) { - printf("fbk hash: memory allocation for key store failed\n"); - return -1; - } - - /* Generate random keys and values. */ - for (i = 0; i < ENTRIES; i++) { - key = (uint32_t)rte_rand(); - key = ((uint64_t)key << 32) | (uint64_t)rte_rand(); - val = (uint16_t)rte_rand(); - - if (rte_fbk_hash_add_key(handle, key, val) == 0) { - keys[added] = key; - added++; - } - if (added > (LOAD_FACTOR * ENTRIES)) - break; - } - - for (i = 0; i < TEST_ITERATIONS; i++) { - uint64_t begin; - uint64_t end; - - /* Generate random indexes into keys[] array. */ - for (j = 0; j < TEST_SIZE; j++) - indexes[j] = rte_rand() % added; - - begin = rte_rdtsc(); - /* Do lookups */ - for (j = 0; j < TEST_SIZE; j++) - value += rte_fbk_hash_lookup(handle, keys[indexes[j]]); - - end = rte_rdtsc(); - lookup_time += (double)(end - begin); - } - - printf("\n\n *** FBK Hash function performance test results ***\n"); - /* - * The use of the 'value' variable ensures that the hash lookup is not - * being optimised out by the compiler. - */ - if (value != 0) - printf("Number of ticks per lookup = %g\n", - (double)lookup_time / - ((double)TEST_ITERATIONS * (double)TEST_SIZE)); - - rte_fbk_hash_free(handle); - - return 0; -} - -static int -test_hash_perf(void) -{ - unsigned with_pushes; - - for (with_pushes = 0; with_pushes <= 1; with_pushes++) { - if (with_pushes == 0) - printf("\nALL ELEMENTS IN PRIMARY LOCATION\n"); - else - printf("\nELEMENTS IN PRIMARY OR SECONDARY LOCATION\n"); - if (run_all_tbl_perf_tests(with_pushes) < 0) - return -1; - } - if (fbk_hash_perf_test() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(hash_perf_autotest, test_hash_perf); diff --git a/app/test/test_hash_scaling.c b/app/test/test_hash_scaling.c deleted file mode 100644 index 46c48e549b..0000000000 --- a/app/test/test_hash_scaling.c +++ /dev/null @@ -1,220 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015 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 - -#include -#include -#include -#include -#include - -#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) - -enum locking_mode_t { - NORMAL_LOCK, - LOCK_ELISION, - NULL_LOCK -}; - -struct { - uint32_t num_iterations; - struct rte_hash *h; - rte_spinlock_t *lock; - int locking_mode; -} tbl_scaling_test_params; - -static rte_atomic64_t gcycles; - -static int test_hash_scaling_worker(__attribute__((unused)) void *arg) -{ - uint64_t i, key; - uint32_t thr_id = rte_sys_gettid(); - uint64_t begin, cycles = 0; - - switch (tbl_scaling_test_params.locking_mode) { - - case NORMAL_LOCK: - - for (i = 0; i < tbl_scaling_test_params.num_iterations; i++) { - /* different threads get different keys because - we use the thread-id in the key computation - */ - key = rte_hash_crc(&i, sizeof(i), thr_id); - begin = rte_rdtsc_precise(); - rte_spinlock_lock(tbl_scaling_test_params.lock); - rte_hash_add_key(tbl_scaling_test_params.h, &key); - rte_spinlock_unlock(tbl_scaling_test_params.lock); - cycles += rte_rdtsc_precise() - begin; - } - break; - - case LOCK_ELISION: - - for (i = 0; i < tbl_scaling_test_params.num_iterations; i++) { - key = rte_hash_crc(&i, sizeof(i), thr_id); - begin = rte_rdtsc_precise(); - rte_spinlock_lock_tm(tbl_scaling_test_params.lock); - rte_hash_add_key(tbl_scaling_test_params.h, &key); - rte_spinlock_unlock_tm(tbl_scaling_test_params.lock); - cycles += rte_rdtsc_precise() - begin; - } - break; - - default: - - for (i = 0; i < tbl_scaling_test_params.num_iterations; i++) { - key = rte_hash_crc(&i, sizeof(i), thr_id); - begin = rte_rdtsc_precise(); - rte_hash_add_key(tbl_scaling_test_params.h, &key); - cycles += rte_rdtsc_precise() - begin; - } - } - - rte_atomic64_add(&gcycles, cycles); - - return 0; -} - -/* - * Do scalability perf tests. - */ -static int -test_hash_scaling(int locking_mode) -{ - static unsigned calledCount = 1; - uint32_t num_iterations = 1024*1024; - uint64_t i, key; - struct rte_hash_parameters hash_params = { - .entries = num_iterations*2, - .key_len = sizeof(key), - .hash_func = rte_hash_crc, - .hash_func_init_val = 0, - .socket_id = rte_socket_id(), - .extra_flag = RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT - }; - struct rte_hash *handle; - char name[RTE_HASH_NAMESIZE]; - rte_spinlock_t lock; - - rte_spinlock_init(&lock); - - 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_scaling_test_params.num_iterations = - num_iterations/rte_lcore_count(); - tbl_scaling_test_params.h = handle; - tbl_scaling_test_params.lock = &lock; - tbl_scaling_test_params.locking_mode = locking_mode; - - rte_atomic64_init(&gcycles); - rte_atomic64_clear(&gcycles); - - /* fill up to initial size */ - for (i = 0; i < num_iterations; i++) { - key = rte_hash_crc(&i, sizeof(i), 0xabcdabcd); - rte_hash_add_key(tbl_scaling_test_params.h, &key); - } - - rte_eal_mp_remote_launch(test_hash_scaling_worker, NULL, CALL_MASTER); - rte_eal_mp_wait_lcore(); - - unsigned long long int cycles_per_operation = - rte_atomic64_read(&gcycles)/ - (tbl_scaling_test_params.num_iterations*rte_lcore_count()); - const char *lock_name; - - switch (locking_mode) { - case NORMAL_LOCK: - lock_name = "normal spinlock"; - break; - case LOCK_ELISION: - lock_name = "lock elision"; - break; - default: - lock_name = "null lock"; - } - printf("--------------------------------------------------------\n"); - printf("Cores: %d; %s mode -> cycles per operation: %llu\n", - rte_lcore_count(), lock_name, cycles_per_operation); - printf("--------------------------------------------------------\n"); - /* CSV output */ - printf(">>>%d,%s,%llu\n", rte_lcore_count(), lock_name, - cycles_per_operation); - - rte_hash_free(handle); - return 0; -} - -static int -test_hash_scaling_main(void) -{ - int r = 0; - - if (rte_lcore_count() == 1) - r = test_hash_scaling(NULL_LOCK); - - if (r == 0) - r = test_hash_scaling(NORMAL_LOCK); - - if (!rte_tm_supported()) { - printf("Hardware transactional memory (lock elision) is NOT supported\n"); - return r; - } - printf("Hardware transactional memory (lock elision) is supported\n"); - - if (r == 0) - r = test_hash_scaling(LOCK_ELISION); - - return r; -} - -REGISTER_TEST_COMMAND(hash_scaling_autotest, test_hash_scaling_main); diff --git a/app/test/test_interrupts.c b/app/test/test_interrupts.c deleted file mode 100644 index 371101f088..0000000000 --- a/app/test/test_interrupts.c +++ /dev/null @@ -1,551 +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 -#include -#include - -#include -#include -#include - -#include "test.h" - -#define TEST_INTERRUPT_CHECK_INTERVAL 100 /* ms */ - -/* predefined interrupt handle types */ -enum test_interrupt_handle_type { - TEST_INTERRUPT_HANDLE_INVALID, - TEST_INTERRUPT_HANDLE_VALID, - TEST_INTERRUPT_HANDLE_VALID_UIO, - TEST_INTERRUPT_HANDLE_VALID_ALARM, - TEST_INTERRUPT_HANDLE_CASE1, - TEST_INTERRUPT_HANDLE_MAX -}; - -/* flag of if callback is called */ -static volatile int flag; -static struct rte_intr_handle intr_handles[TEST_INTERRUPT_HANDLE_MAX]; -static enum test_interrupt_handle_type test_intr_type = - TEST_INTERRUPT_HANDLE_MAX; - -#ifdef RTE_EXEC_ENV_LINUXAPP -union intr_pipefds{ - struct { - int pipefd[2]; - }; - struct { - int readfd; - int writefd; - }; -}; - -static union intr_pipefds pfds; - -/** - * Check if the interrupt handle is valid. - */ -static inline int -test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle) -{ - if (!intr_handle || intr_handle->fd < 0) - return -1; - - return 0; -} - -/** - * Initialization for interrupt test. - */ -static int -test_interrupt_init(void) -{ - if (pipe(pfds.pipefd) < 0) - return -1; - - intr_handles[TEST_INTERRUPT_HANDLE_INVALID].fd = -1; - intr_handles[TEST_INTERRUPT_HANDLE_INVALID].type = - RTE_INTR_HANDLE_UNKNOWN; - - intr_handles[TEST_INTERRUPT_HANDLE_VALID].fd = pfds.readfd; - intr_handles[TEST_INTERRUPT_HANDLE_VALID].type = - RTE_INTR_HANDLE_UNKNOWN; - - intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO].fd = pfds.readfd; - intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO].type = - RTE_INTR_HANDLE_UIO; - - intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM].fd = pfds.readfd; - intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM].type = - RTE_INTR_HANDLE_ALARM; - - intr_handles[TEST_INTERRUPT_HANDLE_CASE1].fd = pfds.writefd; - intr_handles[TEST_INTERRUPT_HANDLE_CASE1].type = RTE_INTR_HANDLE_UIO; - - return 0; -} - -/** - * Deinitialization for interrupt test. - */ -static int -test_interrupt_deinit(void) -{ - close(pfds.pipefd[0]); - close(pfds.pipefd[1]); - - return 0; -} - -/** - * Write the pipe to simulate an interrupt. - */ -static int -test_interrupt_trigger_interrupt(void) -{ - if (write(pfds.writefd, "1", 1) < 0) - return -1; - - return 0; -} - -/** - * Check if two interrupt handles are the same. - */ -static int -test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l, - struct rte_intr_handle *intr_handle_r) -{ - if (!intr_handle_l || !intr_handle_r) - return -1; - - if (intr_handle_l->fd != intr_handle_r->fd || - intr_handle_l->type != intr_handle_r->type) - return -1; - - return 0; -} - -#else -/* to be implemented for bsd later */ -static inline int -test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle) -{ - RTE_SET_USED(intr_handle); - - return 0; -} - -static int -test_interrupt_init(void) -{ - return 0; -} - -static int -test_interrupt_deinit(void) -{ - return 0; -} - -static int -test_interrupt_trigger_interrupt(void) -{ - return 0; -} - -static int -test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l, - struct rte_intr_handle *intr_handle_r) -{ - (void)intr_handle_l; - (void)intr_handle_r; - - return 0; -} -#endif /* RTE_EXEC_ENV_LINUXAPP */ - -/** - * Callback for the test interrupt. - */ -static void -test_interrupt_callback(struct rte_intr_handle *intr_handle, void *arg) -{ - if (test_intr_type >= TEST_INTERRUPT_HANDLE_MAX) { - printf("invalid interrupt type\n"); - flag = -1; - return; - } - - if (test_interrupt_handle_sanity_check(intr_handle) < 0) { - printf("null or invalid intr_handle for %s\n", __func__); - flag = -1; - return; - } - - if (rte_intr_callback_unregister(intr_handle, - test_interrupt_callback, arg) >= 0) { - printf("%s: unexpectedly able to unregister itself\n", - __func__); - flag = -1; - return; - } - - if (test_interrupt_handle_compare(intr_handle, - &(intr_handles[test_intr_type])) == 0) - flag = 1; -} - -/** - * Callback for the test interrupt. - */ -static void -test_interrupt_callback_1(struct rte_intr_handle *intr_handle, - __attribute__((unused)) void *arg) -{ - if (test_interrupt_handle_sanity_check(intr_handle) < 0) { - printf("null or invalid intr_handle for %s\n", __func__); - flag = -1; - return; - } -} - -/** - * Tests for rte_intr_enable(). - */ -static int -test_interrupt_enable(void) -{ - struct rte_intr_handle test_intr_handle; - - /* check with null intr_handle */ - if (rte_intr_enable(NULL) == 0) { - printf("unexpectedly enable null intr_handle successfully\n"); - return -1; - } - - /* check with invalid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID]; - if (rte_intr_enable(&test_intr_handle) == 0) { - printf("unexpectedly enable invalid intr_handle " - "successfully\n"); - return -1; - } - - /* check with valid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; - if (rte_intr_enable(&test_intr_handle) == 0) { - printf("unexpectedly enable a specific intr_handle " - "successfully\n"); - return -1; - } - - /* check with specific valid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM]; - if (rte_intr_enable(&test_intr_handle) == 0) { - printf("unexpectedly enable a specific intr_handle " - "successfully\n"); - return -1; - } - - /* check with valid handler and its type */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1]; - if (rte_intr_enable(&test_intr_handle) < 0) { - printf("fail to enable interrupt on a simulated handler\n"); - return -1; - } - - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO]; - if (rte_intr_enable(&test_intr_handle) == 0) { - printf("unexpectedly enable a specific intr_handle " - "successfully\n"); - return -1; - } - - return 0; -} - -/** - * Tests for rte_intr_disable(). - */ -static int -test_interrupt_disable(void) -{ - struct rte_intr_handle test_intr_handle; - - /* check with null intr_handle */ - if (rte_intr_disable(NULL) == 0) { - printf("unexpectedly disable null intr_handle " - "successfully\n"); - return -1; - } - - /* check with invalid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID]; - if (rte_intr_disable(&test_intr_handle) == 0) { - printf("unexpectedly disable invalid intr_handle " - "successfully\n"); - return -1; - } - - /* check with valid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; - if (rte_intr_disable(&test_intr_handle) == 0) { - printf("unexpectedly disable a specific intr_handle " - "successfully\n"); - return -1; - } - - /* check with specific valid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM]; - if (rte_intr_disable(&test_intr_handle) == 0) { - printf("unexpectedly disable a specific intr_handle " - "successfully\n"); - return -1; - } - - /* check with valid handler and its type */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1]; - if (rte_intr_disable(&test_intr_handle) < 0) { - printf("fail to disable interrupt on a simulated handler\n"); - return -1; - } - - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO]; - if (rte_intr_disable(&test_intr_handle) == 0) { - printf("unexpectedly disable a specific intr_handle " - "successfully\n"); - return -1; - } - - return 0; -} - -/** - * Check the full path of a specified type of interrupt simulated. - */ -static int -test_interrupt_full_path_check(enum test_interrupt_handle_type intr_type) -{ - int count; - struct rte_intr_handle test_intr_handle; - - flag = 0; - test_intr_handle = intr_handles[intr_type]; - test_intr_type = intr_type; - if (rte_intr_callback_register(&test_intr_handle, - test_interrupt_callback, NULL) < 0) { - printf("fail to register callback\n"); - return -1; - } - - if (test_interrupt_trigger_interrupt() < 0) - return -1; - - /* check flag */ - for (count = 0; flag == 0 && count < 3; count++) - rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); - - rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); - if (rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback, NULL) < 0) - return -1; - - if (flag == 0) { - printf("callback has not been called\n"); - return -1; - } else if (flag < 0) { - printf("it has internal error in callback\n"); - return -1; - } - - return 0; -} - -/** - * Main function of testing interrupt. - */ -static int -test_interrupt(void) -{ - int ret = -1; - struct rte_intr_handle test_intr_handle; - - if (test_interrupt_init() < 0) { - printf("fail to initialize for testing interrupt\n"); - return -1; - } - - printf("Check unknown valid interrupt full path\n"); - if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID) < 0) { - printf("failure occured during checking unknown valid " - "interrupt full path\n"); - goto out; - } - - printf("Check valid UIO interrupt full path\n"); - if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID_UIO) - < 0) { - printf("failure occured during checking valid UIO interrupt " - "full path\n"); - goto out; - } - - printf("Check valid alarm interrupt full path\n"); - if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID_ALARM) - < 0) { - printf("failure occured during checking valid alarm " - "interrupt full path\n"); - goto out; - } - - printf("start register/unregister test\n"); - /* check if it will fail to register cb with intr_handle = NULL */ - if (rte_intr_callback_register(NULL, test_interrupt_callback, - NULL) == 0) { - printf("unexpectedly register successfully with null " - "intr_handle\n"); - goto out; - } - - /* check if it will fail to register cb with invalid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID]; - if (rte_intr_callback_register(&test_intr_handle, - test_interrupt_callback, NULL) == 0) { - printf("unexpectedly register successfully with invalid " - "intr_handle\n"); - goto out; - } - - /* check if it will fail to register without callback */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; - if (rte_intr_callback_register(&test_intr_handle, NULL, NULL) == 0) { - printf("unexpectedly register successfully with " - "null callback\n"); - goto out; - } - - /* check if it will fail to unregister cb with intr_handle = NULL */ - if (rte_intr_callback_unregister(NULL, - test_interrupt_callback, NULL) > 0) { - printf("unexpectedly unregister successfully with " - "null intr_handle\n"); - goto out; - } - - /* check if it will fail to unregister cb with invalid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID]; - if (rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback, NULL) > 0) { - printf("unexpectedly unregister successfully with " - "invalid intr_handle\n"); - goto out; - } - - /* check if it is ok to register the same intr_handle twice */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; - if (rte_intr_callback_register(&test_intr_handle, - test_interrupt_callback, NULL) < 0) { - printf("it fails to register test_interrupt_callback\n"); - goto out; - } - if (rte_intr_callback_register(&test_intr_handle, - test_interrupt_callback_1, NULL) < 0) { - printf("it fails to register test_interrupt_callback_1\n"); - goto out; - } - /* check if it will fail to unregister with invalid parameter */ - if (rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback, (void *)0xff) != 0) { - printf("unexpectedly unregisters successfully with " - "invalid arg\n"); - goto out; - } - if (rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback, NULL) <= 0) { - printf("it fails to unregister test_interrupt_callback\n"); - goto out; - } - if (rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback_1, (void *)-1) <= 0) { - printf("it fails to unregister test_interrupt_callback_1 " - "for all\n"); - goto out; - } - rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); - - printf("start interrupt enable/disable test\n"); - /* check interrupt enable/disable functions */ - if (test_interrupt_enable() < 0) { - printf("fail to check interrupt enabling\n"); - goto out; - } - rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); - - if (test_interrupt_disable() < 0) { - printf("fail to check interrupt disabling\n"); - goto out; - } - rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); - - ret = 0; - -out: - printf("Clearing for interrupt tests\n"); - /* clear registered callbacks */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; - rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback, (void *)-1); - rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback_1, (void *)-1); - - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO]; - rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback, (void *)-1); - rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback_1, (void *)-1); - - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM]; - rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback, (void *)-1); - rte_intr_callback_unregister(&test_intr_handle, - test_interrupt_callback_1, (void *)-1); - - rte_delay_ms(2 * TEST_INTERRUPT_CHECK_INTERVAL); - /* deinit */ - test_interrupt_deinit(); - - return ret; -} - -REGISTER_TEST_COMMAND(interrupt_autotest, test_interrupt); diff --git a/app/test/test_kni.c b/app/test/test_kni.c deleted file mode 100644 index 309741cb35..0000000000 --- a/app/test/test_kni.c +++ /dev/null @@ -1,636 +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 -#include -#include -#include -#include - -#include "test.h" - -#include -#include -#include -#include -#include - -#define NB_MBUF 8192 -#define MAX_PACKET_SZ 2048 -#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM) -#define PKT_BURST_SZ 32 -#define MEMPOOL_CACHE_SZ PKT_BURST_SZ -#define SOCKET 0 -#define NB_RXD 128 -#define NB_TXD 512 -#define KNI_TIMEOUT_MS 5000 /* ms */ - -#define IFCONFIG "/sbin/ifconfig " -#define TEST_KNI_PORT "test_kni_port" -#define KNI_TEST_MAX_PORTS 4 -/* The threshold number of mbufs to be transmitted or received. */ -#define KNI_NUM_MBUF_THRESHOLD 100 -static int kni_pkt_mtu = 0; - -struct test_kni_stats { - volatile uint64_t ingress; - volatile uint64_t egress; -}; - -static const struct rte_eth_rxconf rx_conf = { - .rx_thresh = { - .pthresh = 8, - .hthresh = 8, - .wthresh = 4, - }, - .rx_free_thresh = 0, -}; - -static const struct rte_eth_txconf tx_conf = { - .tx_thresh = { - .pthresh = 36, - .hthresh = 0, - .wthresh = 0, - }, - .tx_free_thresh = 0, - .tx_rs_thresh = 0, -}; - -static const struct rte_eth_conf port_conf = { - .rxmode = { - .header_split = 0, - .hw_ip_checksum = 0, - .hw_vlan_filter = 0, - .jumbo_frame = 0, - .hw_strip_crc = 0, - }, - .txmode = { - .mq_mode = ETH_DCB_NONE, - }, -}; - -static struct rte_kni_ops kni_ops = { - .change_mtu = NULL, - .config_network_if = NULL, -}; - -static unsigned lcore_master, lcore_ingress, lcore_egress; -static struct rte_kni *test_kni_ctx; -static struct test_kni_stats stats; - -static volatile uint32_t test_kni_processing_flag; - -static struct rte_mempool * -test_kni_create_mempool(void) -{ - struct rte_mempool * mp; - - mp = rte_mempool_lookup("kni_mempool"); - if (!mp) - mp = rte_pktmbuf_pool_create("kni_mempool", - NB_MBUF, - MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, - SOCKET); - - return mp; -} - -static struct rte_mempool * -test_kni_lookup_mempool(void) -{ - return rte_mempool_lookup("kni_mempool"); -} -/* Callback for request of changing MTU */ -static int -kni_change_mtu(uint8_t port_id, unsigned new_mtu) -{ - printf("Change MTU of port %d to %u\n", port_id, new_mtu); - kni_pkt_mtu = new_mtu; - printf("Change MTU of port %d to %i successfully.\n", - port_id, kni_pkt_mtu); - return 0; -} -/** - * This loop fully tests the basic functions of KNI. e.g. transmitting, - * receiving to, from kernel space, and kernel requests. - * - * This is the loop to transmit/receive mbufs to/from kernel interface with - * supported by KNI kernel module. The ingress lcore will allocate mbufs and - * transmit them to kernel space; while the egress lcore will receive the mbufs - * from kernel space and free them. - * On the master lcore, several commands will be run to check handling the - * kernel requests. And it will finally set the flag to exit the KNI - * transmitting/receiving to/from the kernel space. - * - * Note: To support this testing, the KNI kernel module needs to be insmodded - * in one of its loopback modes. - */ -static int -test_kni_loop(__rte_unused void *arg) -{ - int ret = 0; - unsigned nb_rx, nb_tx, num, i; - const unsigned lcore_id = rte_lcore_id(); - struct rte_mbuf *pkts_burst[PKT_BURST_SZ]; - - if (lcore_id == lcore_master) { - rte_delay_ms(KNI_TIMEOUT_MS); - /* tests of handling kernel request */ - if (system(IFCONFIG TEST_KNI_PORT" up") == -1) - ret = -1; - if (system(IFCONFIG TEST_KNI_PORT" mtu 1400") == -1) - ret = -1; - if (system(IFCONFIG TEST_KNI_PORT" down") == -1) - ret = -1; - rte_delay_ms(KNI_TIMEOUT_MS); - test_kni_processing_flag = 1; - } else if (lcore_id == lcore_ingress) { - struct rte_mempool *mp = test_kni_lookup_mempool(); - - if (mp == NULL) - return -1; - - while (1) { - if (test_kni_processing_flag) - break; - - for (nb_rx = 0; nb_rx < PKT_BURST_SZ; nb_rx++) { - pkts_burst[nb_rx] = rte_pktmbuf_alloc(mp); - if (!pkts_burst[nb_rx]) - break; - } - - num = rte_kni_tx_burst(test_kni_ctx, pkts_burst, - nb_rx); - stats.ingress += num; - rte_kni_handle_request(test_kni_ctx); - if (num < nb_rx) { - for (i = num; i < nb_rx; i++) { - rte_pktmbuf_free(pkts_burst[i]); - } - } - rte_delay_ms(10); - } - } else if (lcore_id == lcore_egress) { - while (1) { - if (test_kni_processing_flag) - break; - num = rte_kni_rx_burst(test_kni_ctx, pkts_burst, - PKT_BURST_SZ); - stats.egress += num; - for (nb_tx = 0; nb_tx < num; nb_tx++) - rte_pktmbuf_free(pkts_burst[nb_tx]); - rte_delay_ms(10); - } - } - - return ret; -} - -static int -test_kni_allocate_lcores(void) -{ - unsigned i, count = 0; - - lcore_master = rte_get_master_lcore(); - printf("master lcore: %u\n", lcore_master); - for (i = 0; i < RTE_MAX_LCORE; i++) { - if (count >=2 ) - break; - if (rte_lcore_is_enabled(i) && i != lcore_master) { - count ++; - if (count == 1) - lcore_ingress = i; - else if (count == 2) - lcore_egress = i; - } - } - printf("count: %u\n", count); - - return count == 2 ? 0 : -1; -} - -static int -test_kni_register_handler_mp(void) -{ -#define TEST_KNI_HANDLE_REQ_COUNT 10 /* 5s */ -#define TEST_KNI_HANDLE_REQ_INTERVAL 500 /* ms */ -#define TEST_KNI_MTU 1450 -#define TEST_KNI_MTU_STR " 1450" - int pid; - - pid = fork(); - if (pid < 0) { - printf("Failed to fork a process\n"); - return -1; - } else if (pid == 0) { - int i; - struct rte_kni *kni = rte_kni_get(TEST_KNI_PORT); - struct rte_kni_ops ops = { - .change_mtu = kni_change_mtu, - .config_network_if = NULL, - }; - - if (!kni) { - printf("Failed to get KNI named %s\n", TEST_KNI_PORT); - exit(-1); - } - - kni_pkt_mtu = 0; - - /* Check with the invalid parameters */ - if (rte_kni_register_handlers(kni, NULL) == 0) { - printf("Unexpectedly register successuflly " - "with NULL ops pointer\n"); - exit(-1); - } - if (rte_kni_register_handlers(NULL, &ops) == 0) { - printf("Unexpectedly register successfully " - "to NULL KNI device pointer\n"); - exit(-1); - } - - if (rte_kni_register_handlers(kni, &ops)) { - printf("Fail to register ops\n"); - exit(-1); - } - - /* Check registering again after it has been registered */ - if (rte_kni_register_handlers(kni, &ops) == 0) { - printf("Unexpectedly register successfully after " - "it has already been registered\n"); - exit(-1); - } - - /** - * Handle the request of setting MTU, - * with registered handlers. - */ - for (i = 0; i < TEST_KNI_HANDLE_REQ_COUNT; i++) { - rte_kni_handle_request(kni); - if (kni_pkt_mtu == TEST_KNI_MTU) - break; - rte_delay_ms(TEST_KNI_HANDLE_REQ_INTERVAL); - } - if (i >= TEST_KNI_HANDLE_REQ_COUNT) { - printf("MTU has not been set\n"); - exit(-1); - } - - kni_pkt_mtu = 0; - if (rte_kni_unregister_handlers(kni) < 0) { - printf("Fail to unregister ops\n"); - exit(-1); - } - - /* Check with invalid parameter */ - if (rte_kni_unregister_handlers(NULL) == 0) { - exit(-1); - } - - /** - * Handle the request of setting MTU, - * without registered handlers. - */ - for (i = 0; i < TEST_KNI_HANDLE_REQ_COUNT; i++) { - rte_kni_handle_request(kni); - if (kni_pkt_mtu != 0) - break; - rte_delay_ms(TEST_KNI_HANDLE_REQ_INTERVAL); - } - if (kni_pkt_mtu != 0) { - printf("MTU shouldn't be set\n"); - exit(-1); - } - - exit(0); - } else { - int p_ret, status; - - rte_delay_ms(1000); - if (system(IFCONFIG TEST_KNI_PORT " mtu" TEST_KNI_MTU_STR) - == -1) - return -1; - - rte_delay_ms(1000); - if (system(IFCONFIG TEST_KNI_PORT " mtu" TEST_KNI_MTU_STR) - == -1) - return -1; - - p_ret = wait(&status); - if (!WIFEXITED(status)) { - printf("Child process (%d) exit abnormally\n", p_ret); - return -1; - } - if (WEXITSTATUS(status) != 0) { - printf("Child process exit with failure\n"); - return -1; - } - } - - return 0; -} - -static int -test_kni_processing(uint8_t port_id, struct rte_mempool *mp) -{ - int ret = 0; - unsigned i; - struct rte_kni *kni; - struct rte_kni_conf conf; - struct rte_eth_dev_info info; - struct rte_kni_ops ops; - - if (!mp) - return -1; - - memset(&conf, 0, sizeof(conf)); - memset(&info, 0, sizeof(info)); - memset(&ops, 0, sizeof(ops)); - - rte_eth_dev_info_get(port_id, &info); - conf.addr = info.pci_dev->addr; - conf.id = info.pci_dev->id; - snprintf(conf.name, sizeof(conf.name), TEST_KNI_PORT); - - /* core id 1 configured for kernel thread */ - conf.core_id = 1; - conf.force_bind = 1; - conf.mbuf_size = MAX_PACKET_SZ; - conf.group_id = (uint16_t)port_id; - - ops = kni_ops; - ops.port_id = port_id; - - /* basic test of kni processing */ - kni = rte_kni_alloc(mp, &conf, &ops); - if (!kni) { - printf("fail to create kni\n"); - return -1; - } - - test_kni_ctx = kni; - test_kni_processing_flag = 0; - stats.ingress = 0; - stats.egress = 0; - - /** - * Check multiple processes support on - * registerring/unregisterring handlers. - */ - if (test_kni_register_handler_mp() < 0) { - printf("fail to check multiple process support\n"); - ret = -1; - goto fail_kni; - } - - rte_eal_mp_remote_launch(test_kni_loop, NULL, CALL_MASTER); - RTE_LCORE_FOREACH_SLAVE(i) { - if (rte_eal_wait_lcore(i) < 0) { - ret = -1; - goto fail_kni; - } - } - /** - * Check if the number of mbufs received from kernel space is equal - * to that of transmitted to kernel space - */ - if (stats.ingress < KNI_NUM_MBUF_THRESHOLD || - stats.egress < KNI_NUM_MBUF_THRESHOLD) { - printf("The ingress/egress number should not be " - "less than %u\n", (unsigned)KNI_NUM_MBUF_THRESHOLD); - ret = -1; - goto fail_kni; - } - - if (rte_kni_release(kni) < 0) { - printf("fail to release kni\n"); - return -1; - } - test_kni_ctx = NULL; - - /* test of releasing a released kni device */ - if (rte_kni_release(kni) == 0) { - printf("should not release a released kni device\n"); - return -1; - } - - /* test of reusing memzone */ - kni = rte_kni_alloc(mp, &conf, &ops); - if (!kni) { - printf("fail to create kni\n"); - return -1; - } - - /* Release the kni for following testing */ - if (rte_kni_release(kni) < 0) { - printf("fail to release kni\n"); - return -1; - } - - return ret; -fail_kni: - if (rte_kni_release(kni) < 0) { - printf("fail to release kni\n"); - ret = -1; - } - - return ret; -} - -static int -test_kni(void) -{ - int ret = -1; - uint8_t nb_ports, port_id; - struct rte_kni *kni; - struct rte_mempool *mp; - struct rte_kni_conf conf; - struct rte_eth_dev_info info; - struct rte_kni_ops ops; - - /* Initialize KNI subsytem */ - rte_kni_init(KNI_TEST_MAX_PORTS); - - if (test_kni_allocate_lcores() < 0) { - printf("No enough lcores for kni processing\n"); - return -1; - } - - mp = test_kni_create_mempool(); - if (!mp) { - printf("fail to create mempool for kni\n"); - return -1; - } - - nb_ports = rte_eth_dev_count(); - if (nb_ports == 0) { - printf("no supported nic port found\n"); - return -1; - } - - /* configuring port 0 for the test is enough */ - port_id = 0; - ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf); - if (ret < 0) { - printf("fail to configure port %d\n", port_id); - return -1; - } - - ret = rte_eth_rx_queue_setup(port_id, 0, NB_RXD, SOCKET, &rx_conf, mp); - if (ret < 0) { - printf("fail to setup rx queue for port %d\n", port_id); - return -1; - } - - ret = rte_eth_tx_queue_setup(port_id, 0, NB_TXD, SOCKET, &tx_conf); - if (ret < 0) { - printf("fail to setup tx queue for port %d\n", port_id); - return -1; - } - - ret = rte_eth_dev_start(port_id); - if (ret < 0) { - printf("fail to start port %d\n", port_id); - return -1; - } - rte_eth_promiscuous_enable(port_id); - - /* basic test of kni processing */ - ret = test_kni_processing(port_id, mp); - if (ret < 0) - goto fail; - - /* test of allocating KNI with NULL mempool pointer */ - memset(&info, 0, sizeof(info)); - memset(&conf, 0, sizeof(conf)); - memset(&ops, 0, sizeof(ops)); - rte_eth_dev_info_get(port_id, &info); - conf.addr = info.pci_dev->addr; - conf.id = info.pci_dev->id; - conf.group_id = (uint16_t)port_id; - conf.mbuf_size = MAX_PACKET_SZ; - - ops = kni_ops; - ops.port_id = port_id; - kni = rte_kni_alloc(NULL, &conf, &ops); - if (kni) { - ret = -1; - printf("unexpectedly creates kni successfully with NULL " - "mempool pointer\n"); - goto fail; - } - - /* test of allocating KNI without configurations */ - kni = rte_kni_alloc(mp, NULL, NULL); - if (kni) { - ret = -1; - printf("Unexpectedly allocate KNI device successfully " - "without configurations\n"); - goto fail; - } - - /* test of allocating KNI without a name */ - memset(&conf, 0, sizeof(conf)); - memset(&info, 0, sizeof(info)); - memset(&ops, 0, sizeof(ops)); - rte_eth_dev_info_get(port_id, &info); - conf.addr = info.pci_dev->addr; - conf.id = info.pci_dev->id; - conf.group_id = (uint16_t)port_id; - conf.mbuf_size = MAX_PACKET_SZ; - - ops = kni_ops; - ops.port_id = port_id; - kni = rte_kni_alloc(mp, &conf, &ops); - if (kni) { - ret = -1; - printf("Unexpectedly allocate a KNI device successfully " - "without a name\n"); - goto fail; - } - - /* test of releasing NULL kni context */ - ret = rte_kni_release(NULL); - if (ret == 0) { - ret = -1; - printf("unexpectedly release kni successfully\n"); - goto fail; - } - - /* test of handling request on NULL device pointer */ - ret = rte_kni_handle_request(NULL); - if (ret == 0) { - ret = -1; - printf("Unexpectedly handle request on NULL device pointer\n"); - goto fail; - } - - /* test of getting KNI device with pointer to NULL */ - kni = rte_kni_get(NULL); - if (kni) { - ret = -1; - printf("Unexpectedly get a KNI device with " - "NULL name pointer\n"); - goto fail; - } - - /* test of getting KNI device with an zero length name string */ - memset(&conf, 0, sizeof(conf)); - kni = rte_kni_get(conf.name); - if (kni) { - ret = -1; - printf("Unexpectedly get a KNI device with " - "zero length name string\n"); - goto fail; - } - - /* test of getting KNI device with an invalid string name */ - memset(&conf, 0, sizeof(conf)); - snprintf(conf.name, sizeof(conf.name), "testing"); - kni = rte_kni_get(conf.name); - if (kni) { - ret = -1; - printf("Unexpectedly get a KNI device with " - "a never used name string\n"); - goto fail; - } - ret = 0; - -fail: - rte_eth_dev_stop(port_id); - - return ret; -} - -REGISTER_TEST_COMMAND(kni_autotest, test_kni); diff --git a/app/test/test_kvargs.c b/app/test/test_kvargs.c deleted file mode 100644 index 4d9e805b3a..0000000000 --- a/app/test/test_kvargs.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2014 6WIND S.A. - * - * 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 6WIND S.A. 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 -#include -#include - -#include -#include - -#include "test.h" - -/* incrementd in handler, to check it is properly called once per - * key/value association */ -static unsigned count; - -/* this handler increment the "count" variable at each call and check - * that the key is "check" and the value is "value%d" */ -static int check_handler(const char *key, const char *value, - __rte_unused void *opaque) -{ - char buf[16]; - - /* we check that the value is "check" */ - if (strcmp(key, "check")) - return -1; - - /* we check that the value is "value$(count)" */ - snprintf(buf, sizeof(buf), "value%d", count); - if (strncmp(buf, value, sizeof(buf))) - return -1; - - count ++; - return 0; -} - -/* test a valid case */ -static int test_valid_kvargs(void) -{ - struct rte_kvargs *kvlist; - const char *args; - const char *valid_keys_list[] = { "foo", "check", NULL }; - const char **valid_keys; - - /* empty args is valid */ - args = ""; - valid_keys = NULL; - kvlist = rte_kvargs_parse(args, valid_keys); - if (kvlist == NULL) { - printf("rte_kvargs_parse() error"); - goto fail; - } - rte_kvargs_free(kvlist); - - /* first test without valid_keys */ - args = "foo=1234,check=value0,check=value1"; - valid_keys = NULL; - kvlist = rte_kvargs_parse(args, valid_keys); - if (kvlist == NULL) { - printf("rte_kvargs_parse() error"); - goto fail; - } - /* call check_handler() for all entries with key="check" */ - count = 0; - if (rte_kvargs_process(kvlist, "check", check_handler, NULL) < 0) { - printf("rte_kvargs_process() error\n"); - rte_kvargs_free(kvlist); - goto fail; - } - if (count != 2) { - printf("invalid count value %d after rte_kvargs_process(check)\n", - count); - rte_kvargs_free(kvlist); - goto fail; - } - count = 0; - /* call check_handler() for all entries with key="unexistant_key" */ - if (rte_kvargs_process(kvlist, "unexistant_key", check_handler, NULL) < 0) { - printf("rte_kvargs_process() error\n"); - rte_kvargs_free(kvlist); - goto fail; - } - if (count != 0) { - printf("invalid count value %d after rte_kvargs_process(unexistant_key)\n", - count); - rte_kvargs_free(kvlist); - goto fail; - } - /* count all entries with key="foo" */ - count = rte_kvargs_count(kvlist, "foo"); - if (count != 1) { - printf("invalid count value %d after rte_kvargs_count(foo)\n", - count); - rte_kvargs_free(kvlist); - goto fail; - } - /* count all entries */ - count = rte_kvargs_count(kvlist, NULL); - if (count != 3) { - printf("invalid count value %d after rte_kvargs_count(NULL)\n", - count); - rte_kvargs_free(kvlist); - goto fail; - } - /* count all entries with key="unexistant_key" */ - count = rte_kvargs_count(kvlist, "unexistant_key"); - if (count != 0) { - printf("invalid count value %d after rte_kvargs_count(unexistant_key)\n", - count); - rte_kvargs_free(kvlist); - goto fail; - } - rte_kvargs_free(kvlist); - - /* second test using valid_keys */ - args = "foo=droids,check=value0,check=value1,check=wrong_value"; - valid_keys = valid_keys_list; - kvlist = rte_kvargs_parse(args, valid_keys); - if (kvlist == NULL) { - printf("rte_kvargs_parse() error"); - goto fail; - } - /* call check_handler() on all entries with key="check", it - * should fail as the value is not recognized by the handler */ - if (rte_kvargs_process(kvlist, "check", check_handler, NULL) == 0) { - printf("rte_kvargs_process() is success bu should not\n"); - rte_kvargs_free(kvlist); - goto fail; - } - count = rte_kvargs_count(kvlist, "check"); - if (count != 3) { - printf("invalid count value %d after rte_kvargs_count(check)\n", - count); - rte_kvargs_free(kvlist); - goto fail; - } - rte_kvargs_free(kvlist); - - return 0; - - fail: - printf("while processing <%s>", args); - if (valid_keys != NULL && *valid_keys != NULL) { - printf(" using valid_keys=<%s", *valid_keys); - while (*(++valid_keys) != NULL) - printf(",%s", *valid_keys); - printf(">"); - } - printf("\n"); - return -1; -} - -/* test several error cases */ -static int test_invalid_kvargs(void) -{ - struct rte_kvargs *kvlist; - /* list of argument that should fail */ - const char *args_list[] = { - "wrong-key=x", /* key not in valid_keys_list */ - "foo=1,foo=", /* empty value */ - "foo=1,,foo=2", /* empty key/value */ - "foo=1,foo", /* no value */ - "foo=1,=2", /* no key */ - ",=", /* also test with a smiley */ - NULL }; - const char **args; - const char *valid_keys_list[] = { "foo", "check", NULL }; - const char **valid_keys = valid_keys_list; - - for (args = args_list; *args != NULL; args++) { - - kvlist = rte_kvargs_parse(*args, valid_keys); - if (kvlist != NULL) { - printf("rte_kvargs_parse() returned 0 (but should not)\n"); - rte_kvargs_free(kvlist); - goto fail; - } - return 0; - } - - fail: - printf("while processing <%s>", *args); - if (valid_keys != NULL && *valid_keys != NULL) { - printf(" using valid_keys=<%s", *valid_keys); - while (*(++valid_keys) != NULL) - printf(",%s", *valid_keys); - printf(">"); - } - printf("\n"); - return -1; -} - -static int -test_kvargs(void) -{ - printf("== test valid case ==\n"); - if (test_valid_kvargs() < 0) - return -1; - printf("== test invalid case ==\n"); - if (test_invalid_kvargs() < 0) - return -1; - return 0; -} - -REGISTER_TEST_COMMAND(kvargs_autotest, test_kvargs); diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c deleted file mode 100644 index 32296604d2..0000000000 --- a/app/test/test_link_bonding.c +++ /dev/null @@ -1,5005 +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 "unistd.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "virtual_pmd.h" -#include "packet_burst_generator.h" - -#include "test.h" - -#define TEST_MAX_NUMBER_OF_PORTS (6) - -#define RX_RING_SIZE 128 -#define RX_FREE_THRESH 32 -#define RX_PTHRESH 8 -#define RX_HTHRESH 8 -#define RX_WTHRESH 0 - -#define TX_RING_SIZE 512 -#define TX_FREE_THRESH 32 -#define TX_PTHRESH 32 -#define TX_HTHRESH 0 -#define TX_WTHRESH 0 -#define TX_RSBIT_THRESH 32 -#define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\ - ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \ - ETH_TXQ_FLAGS_NOXSUMTCP) - -#define MBUF_CACHE_SIZE (250) -#define BURST_SIZE (32) - -#define RTE_TEST_RX_DESC_MAX (2048) -#define RTE_TEST_TX_DESC_MAX (2048) -#define MAX_PKT_BURST (512) -#define DEF_PKT_BURST (16) - -#define BONDED_DEV_NAME ("unit_test_bond_dev") - -#define INVALID_SOCKET_ID (-1) -#define INVALID_PORT_ID (-1) -#define INVALID_BONDING_MODE (-1) - - -uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 }; -uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; - -struct link_bonding_unittest_params { - int8_t bonded_port_id; - int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS]; - uint8_t bonded_slave_count; - uint8_t bonding_mode; - - uint16_t nb_rx_q; - uint16_t nb_tx_q; - - struct rte_mempool *mbuf_pool; - - struct ether_addr *default_slave_mac; - struct ether_addr *default_bonded_mac; - - /* Packet Headers */ - struct ether_hdr *pkt_eth_hdr; - struct ipv4_hdr *pkt_ipv4_hdr; - struct ipv6_hdr *pkt_ipv6_hdr; - struct udp_hdr *pkt_udp_hdr; - -}; - -static struct ipv4_hdr pkt_ipv4_hdr; -static struct ipv6_hdr pkt_ipv6_hdr; -static struct udp_hdr pkt_udp_hdr; - -static struct link_bonding_unittest_params default_params = { - .bonded_port_id = -1, - .slave_port_ids = { -1 }, - .bonded_slave_count = 0, - .bonding_mode = BONDING_MODE_ROUND_ROBIN, - - .nb_rx_q = 1, - .nb_tx_q = 1, - - .mbuf_pool = NULL, - - .default_slave_mac = (struct ether_addr *)slave_mac, - .default_bonded_mac = (struct ether_addr *)bonded_mac, - - .pkt_eth_hdr = NULL, - .pkt_ipv4_hdr = &pkt_ipv4_hdr, - .pkt_ipv6_hdr = &pkt_ipv6_hdr, - .pkt_udp_hdr = &pkt_udp_hdr - -}; - -static struct link_bonding_unittest_params *test_params = &default_params; - -static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; -static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; -static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB }; - -static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98); -static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98); -static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97); - -static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, - 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA }; -static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, - 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA }; -static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, - 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB }; - -static uint16_t src_port = 1024; -static uint16_t dst_port_0 = 1024; -static uint16_t dst_port_1 = 2024; - -static uint16_t vlan_id = 0x100; - -struct rte_eth_rxmode rx_mode = { - .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */ - .split_hdr_size = 0, - .header_split = 0, /**< Header Split disabled. */ - .hw_ip_checksum = 0, /**< IP checksum offload disabled. */ - .hw_vlan_filter = 1, /**< VLAN filtering enabled. */ - .hw_vlan_strip = 1, /**< VLAN strip enabled. */ - .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ - .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */ - .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */ -}; - -struct rte_fdir_conf fdir_conf = { - .mode = RTE_FDIR_MODE_NONE, - .pballoc = RTE_FDIR_PBALLOC_64K, - .status = RTE_FDIR_REPORT_STATUS, - .drop_queue = 127, -}; - -static struct rte_eth_conf default_pmd_conf = { - .rxmode = { - .mq_mode = ETH_MQ_RX_NONE, - .max_rx_pkt_len = ETHER_MAX_LEN, - .split_hdr_size = 0, - .header_split = 0, /**< Header Split disabled */ - .hw_ip_checksum = 0, /**< IP checksum offload enabled */ - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, - .lpbk_mode = 0, -}; - -static const struct rte_eth_rxconf rx_conf_default = { - .rx_thresh = { - .pthresh = RX_PTHRESH, - .hthresh = RX_HTHRESH, - .wthresh = RX_WTHRESH, - }, - .rx_free_thresh = RX_FREE_THRESH, - .rx_drop_en = 0, -}; - -static struct rte_eth_txconf tx_conf_default = { - .tx_thresh = { - .pthresh = TX_PTHRESH, - .hthresh = TX_HTHRESH, - .wthresh = TX_WTHRESH, - }, - .tx_free_thresh = TX_FREE_THRESH, - .tx_rs_thresh = TX_RSBIT_THRESH, - .txq_flags = TX_Q_FLAGS - -}; - -static int -configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr) -{ - int q_id; - - if (en_isr) - default_pmd_conf.intr_conf.lsc = 1; - else - default_pmd_conf.intr_conf.lsc = 0; - - TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q, - test_params->nb_tx_q, &default_pmd_conf), - "rte_eth_dev_configure for port %d failed", port_id); - - for (q_id = 0; q_id < test_params->nb_rx_q; q_id++) - TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE, - rte_eth_dev_socket_id(port_id), &rx_conf_default, - test_params->mbuf_pool) , - "rte_eth_rx_queue_setup for port %d failed", port_id); - - for (q_id = 0; q_id < test_params->nb_tx_q; q_id++) - TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE, - rte_eth_dev_socket_id(port_id), &tx_conf_default), - "rte_eth_tx_queue_setup for port %d failed", port_id); - - if (start) - TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id), - "rte_eth_dev_start for port %d failed", port_id); - - return 0; -} - -static int slaves_initialized; - -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER; - - -static int -test_setup(void) -{ - int i, nb_mbuf_per_pool; - struct ether_addr *mac_addr = (struct ether_addr *)slave_mac; - - /* Allocate ethernet packet header with space for VLAN header */ - if (test_params->pkt_eth_hdr == NULL) { - test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) + - sizeof(struct vlan_hdr)); - - TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr, - "Ethernet header struct allocation failed!"); - } - - nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST + - RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; - if (test_params->mbuf_pool == NULL) { - test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", - nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, - RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - TEST_ASSERT_NOT_NULL(test_params->mbuf_pool, - "rte_mempool_create failed"); - } - - /* Create / Initialize virtual eth devs */ - if (!slaves_initialized) { - for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) { - char pmd_name[RTE_ETH_NAME_MAX_LEN]; - - mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i; - - snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i); - - test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name, - mac_addr, rte_socket_id(), 1); - TEST_ASSERT(test_params->slave_port_ids[i] >= 0, - "Failed to create virtual virtual ethdev %s", pmd_name); - - TEST_ASSERT_SUCCESS(configure_ethdev( - test_params->slave_port_ids[i], 1, 0), - "Failed to configure virtual ethdev %s", pmd_name); - } - slaves_initialized = 1; - } - - return 0; -} - -static int -test_create_bonded_device(void) -{ - int current_slave_count; - - uint8_t slaves[RTE_MAX_ETHPORTS]; - - /* Don't try to recreate bonded device if re-running test suite*/ - if (test_params->bonded_port_id == -1) { - test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME, - test_params->bonding_mode, rte_socket_id()); - - TEST_ASSERT(test_params->bonded_port_id >= 0, - "Failed to create bonded ethdev %s", BONDED_DEV_NAME); - - TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0), - "Failed to configure bonded ethdev %s", BONDED_DEV_NAME); - } - - TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id, - test_params->bonding_mode), "Failed to set ethdev %d to mode %d", - test_params->bonded_port_id, test_params->bonding_mode); - - current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - - TEST_ASSERT_EQUAL(current_slave_count, 0, - "Number of slaves %d is great than expected %d.", - current_slave_count, 0); - - current_slave_count = rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS); - - TEST_ASSERT_EQUAL(current_slave_count, 0, - "Number of active slaves %d is great than expected %d.", - current_slave_count, 0); - - return 0; -} - - -static int -test_create_bonded_device_with_invalid_params(void) -{ - int port_id; - - test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN; - - /* Invalid name */ - port_id = rte_eth_bond_create(NULL, test_params->bonding_mode, - rte_socket_id()); - TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly"); - - test_params->bonding_mode = INVALID_BONDING_MODE; - - /* Invalid bonding mode */ - port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode, - rte_socket_id()); - TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly."); - - test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN; - - /* Invalid socket id */ - port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode, - INVALID_SOCKET_ID); - TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly."); - - return 0; -} - -static int -test_add_slave_to_bonded_device(void) -{ - int current_slave_count; - - uint8_t slaves[RTE_MAX_ETHPORTS]; - - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id, - test_params->slave_port_ids[test_params->bonded_slave_count]), - "Failed to add slave (%d) to bonded port (%d).", - test_params->slave_port_ids[test_params->bonded_slave_count], - test_params->bonded_port_id); - - current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1, - "Number of slaves (%d) is greater than expected (%d).", - current_slave_count, test_params->bonded_slave_count + 1); - - current_slave_count = rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(current_slave_count, 0, - "Number of active slaves (%d) is not as expected (%d).\n", - current_slave_count, 0); - - test_params->bonded_slave_count++; - - return 0; -} - -static int -test_add_slave_to_invalid_bonded_device(void) -{ - /* Invalid port ID */ - TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5, - test_params->slave_port_ids[test_params->bonded_slave_count]), - "Expected call to failed as invalid port specified."); - - /* Non bonded device */ - TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0], - test_params->slave_port_ids[test_params->bonded_slave_count]), - "Expected call to failed as invalid port specified."); - - return 0; -} - - -static int -test_remove_slave_from_bonded_device(void) -{ - int current_slave_count; - struct ether_addr read_mac_addr, *mac_addr; - uint8_t slaves[RTE_MAX_ETHPORTS]; - - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id, - test_params->slave_port_ids[test_params->bonded_slave_count-1]), - "Failed to remove slave %d from bonded port (%d).", - test_params->slave_port_ids[test_params->bonded_slave_count-1], - test_params->bonded_port_id); - - - current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - - TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1, - "Number of slaves (%d) is great than expected (%d).\n", - current_slave_count, test_params->bonded_slave_count - 1); - - - mac_addr = (struct ether_addr *)slave_mac; - mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = - test_params->bonded_slave_count-1; - - rte_eth_macaddr_get( - test_params->slave_port_ids[test_params->bonded_slave_count-1], - &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)), - "bonded port mac address not set to that of primary port\n"); - - rte_eth_stats_reset( - test_params->slave_port_ids[test_params->bonded_slave_count-1]); - - virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id, - 0); - - test_params->bonded_slave_count--; - - return 0; -} - -static int -test_remove_slave_from_invalid_bonded_device(void) -{ - /* Invalid port ID */ - TEST_ASSERT_FAIL(rte_eth_bond_slave_remove( - test_params->bonded_port_id + 5, - test_params->slave_port_ids[test_params->bonded_slave_count - 1]), - "Expected call to failed as invalid port specified."); - - /* Non bonded device */ - TEST_ASSERT_FAIL(rte_eth_bond_slave_remove( - test_params->slave_port_ids[0], - test_params->slave_port_ids[test_params->bonded_slave_count - 1]), - "Expected call to failed as invalid port specified."); - - return 0; -} - -static int bonded_id = 2; - -static int -test_add_already_bonded_slave_to_bonded_device(void) -{ - int port_id, current_slave_count; - uint8_t slaves[RTE_MAX_ETHPORTS]; - char pmd_name[RTE_ETH_NAME_MAX_LEN]; - - test_add_slave_to_bonded_device(); - - current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(current_slave_count, 1, - "Number of slaves (%d) is not that expected (%d).", - current_slave_count, 1); - - snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id); - - port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode, - rte_socket_id()); - TEST_ASSERT(port_id >= 0, "Failed to create bonded device."); - - TEST_ASSERT(rte_eth_bond_slave_add(port_id, - test_params->slave_port_ids[test_params->bonded_slave_count - 1]) - < 0, - "Added slave (%d) to bonded port (%d) unexpectedly.", - test_params->slave_port_ids[test_params->bonded_slave_count-1], - port_id); - - return test_remove_slave_from_bonded_device(); -} - - -static int -test_get_slaves_from_bonded_device(void) -{ - int current_slave_count; - uint8_t slaves[RTE_MAX_ETHPORTS]; - - TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), - "Failed to add slave to bonded device"); - - /* Invalid port id */ - current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves, - RTE_MAX_ETHPORTS); - TEST_ASSERT(current_slave_count < 0, - "Invalid port id unexpectedly succeeded"); - - current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT(current_slave_count < 0, - "Invalid port id unexpectedly succeeded"); - - /* Invalid slaves pointer */ - current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, - NULL, RTE_MAX_ETHPORTS); - TEST_ASSERT(current_slave_count < 0, - "Invalid slave array unexpectedly succeeded"); - - current_slave_count = rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS); - TEST_ASSERT(current_slave_count < 0, - "Invalid slave array unexpectedly succeeded"); - - /* non bonded device*/ - current_slave_count = rte_eth_bond_slaves_get( - test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS); - TEST_ASSERT(current_slave_count < 0, - "Invalid port id unexpectedly succeeded"); - - current_slave_count = rte_eth_bond_active_slaves_get( - test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS); - TEST_ASSERT(current_slave_count < 0, - "Invalid port id unexpectedly succeeded"); - - TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(), - "Failed to remove slaves from bonded device"); - - return 0; -} - - -static int -test_add_remove_multiple_slaves_to_from_bonded_device(void) -{ - int i; - - for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) - TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), - "Failed to add slave to bonded device"); - - for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) - TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(), - "Failed to remove slaves from bonded device"); - - return 0; -} - -static void -enable_bonded_slaves(void) -{ - int i; - - for (i = 0; i < test_params->bonded_slave_count; i++) { - virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i], - 1); - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 1); - } -} - -static int -test_start_bonded_device(void) -{ - struct rte_eth_link link_status; - - int current_slave_count, current_bonding_mode, primary_port; - uint8_t slaves[RTE_MAX_ETHPORTS]; - - /* Add slave to bonded device*/ - TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), - "Failed to add slave to bonded device"); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), - "Failed to start bonded pmd eth device %d.", - test_params->bonded_port_id); - - /* Change link status of virtual pmd so it will be added to the active - * slave list of the bonded device*/ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[test_params->bonded_slave_count-1], 1); - - current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count, - "Number of slaves (%d) is not expected value (%d).", - current_slave_count, test_params->bonded_slave_count); - - current_slave_count = rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count, - "Number of active slaves (%d) is not expected value (%d).", - current_slave_count, test_params->bonded_slave_count); - - current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode, - "Bonded device mode (%d) is not expected value (%d).\n", - current_bonding_mode, test_params->bonding_mode); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0], - "Primary port (%d) is not expected value (%d).", - primary_port, test_params->slave_port_ids[0]); - - rte_eth_link_get(test_params->bonded_port_id, &link_status); - TEST_ASSERT_EQUAL(link_status.link_status, 1, - "Bonded port (%d) status (%d) is not expected value (%d).\n", - test_params->bonded_port_id, link_status.link_status, 1); - - return 0; -} - -static int -test_stop_bonded_device(void) -{ - int current_slave_count; - uint8_t slaves[RTE_MAX_ETHPORTS]; - - struct rte_eth_link link_status; - - rte_eth_dev_stop(test_params->bonded_port_id); - - rte_eth_link_get(test_params->bonded_port_id, &link_status); - TEST_ASSERT_EQUAL(link_status.link_status, 0, - "Bonded port (%d) status (%d) is not expected value (%d).", - test_params->bonded_port_id, link_status.link_status, 0); - - current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count, - "Number of slaves (%d) is not expected value (%d).", - current_slave_count, test_params->bonded_slave_count); - - current_slave_count = rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(current_slave_count, 0, - "Number of active slaves (%d) is not expected value (%d).", - current_slave_count, 0); - - return 0; -} - -static int -remove_slaves_and_stop_bonded_device(void) -{ - /* Clean up and remove slaves from bonded device */ - while (test_params->bonded_slave_count > 0) - TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(), - "test_remove_slave_from_bonded_device failed"); - - rte_eth_dev_stop(test_params->bonded_port_id); - rte_eth_stats_reset(test_params->bonded_port_id); - rte_eth_bond_mac_address_reset(test_params->bonded_port_id); - - return 0; -} - -static int -test_set_bonding_mode(void) -{ - int i, bonding_mode; - - int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN, - BONDING_MODE_ACTIVE_BACKUP, - BONDING_MODE_BALANCE, - BONDING_MODE_BROADCAST - }; - - /* Test supported link bonding modes */ - for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) { - /* Invalid port ID */ - TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID, - bonding_modes[i]), - "Expected call to failed as invalid port (%d) specified.", - INVALID_PORT_ID); - - /* Non bonded device */ - TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0], - bonding_modes[i]), - "Expected call to failed as invalid port (%d) specified.", - test_params->slave_port_ids[0]); - - TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id, - bonding_modes[i]), - "Failed to set link bonding mode on port (%d) to (%d).", - test_params->bonded_port_id, bonding_modes[i]); - - bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i], - "Link bonding mode (%d) of port (%d) is not expected value (%d).", - bonding_mode, test_params->bonded_port_id, - bonding_modes[i]); - - /* Invalid port ID */ - bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID); - TEST_ASSERT(bonding_mode < 0, - "Expected call to failed as invalid port (%d) specified.", - INVALID_PORT_ID); - - /* Non bonded device */ - bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]); - TEST_ASSERT(bonding_mode < 0, - "Expected call to failed as invalid port (%d) specified.", - test_params->slave_port_ids[0]); - } - - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_set_primary_slave(void) -{ - int i, j, retval; - struct ether_addr read_mac_addr; - struct ether_addr *expected_mac_addr; - - /* Add 4 slaves to bonded device */ - for (i = test_params->bonded_slave_count; i < 4; i++) - TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), - "Failed to add slave to bonded device."); - - TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id, - BONDING_MODE_ROUND_ROBIN), - "Failed to set link bonding mode on port (%d) to (%d).", - test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN); - - /* Invalid port ID */ - TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID, - test_params->slave_port_ids[i]), - "Expected call to failed as invalid port specified."); - - /* Non bonded device */ - TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i], - test_params->slave_port_ids[i]), - "Expected call to failed as invalid port specified."); - - /* Set slave as primary - * Verify slave it is now primary slave - * Verify that MAC address of bonded device is that of primary slave - * Verify that MAC address of all bonded slaves are that of primary slave - */ - for (i = 0; i < 4; i++) { - TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, - test_params->slave_port_ids[i]), - "Failed to set bonded port (%d) primary port to (%d)", - test_params->bonded_port_id, test_params->slave_port_ids[i]); - - retval = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT(retval >= 0, - "Failed to read primary port from bonded port (%d)\n", - test_params->bonded_port_id); - - TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i], - "Bonded port (%d) primary port (%d) not expected value (%d)\n", - test_params->bonded_port_id, retval, - test_params->slave_port_ids[i]); - - /* stop/start bonded eth dev to apply new MAC */ - rte_eth_dev_stop(test_params->bonded_port_id); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), - "Failed to start bonded port %d", - test_params->bonded_port_id); - - expected_mac_addr = (struct ether_addr *)&slave_mac; - expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i; - - /* Check primary slave MAC */ - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port mac address not set to that of primary port\n"); - - /* Check bonded MAC */ - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port mac address not set to that of primary port\n"); - - /* Check other slaves MACs */ - for (j = 0; j < 4; j++) { - if (j != i) { - rte_eth_macaddr_get(test_params->slave_port_ids[j], - &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port mac address not set to that of primary " - "port"); - } - } - } - - - /* Test with none existent port */ - TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10), - "read primary port from expectedly"); - - /* Test with slave port */ - TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]), - "read primary port from expectedly\n"); - - TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(), - "Failed to stop and remove slaves from bonded device"); - - /* No slaves */ - TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0, - "read primary port from expectedly\n"); - - return 0; -} - -static int -test_set_explicit_bonded_mac(void) -{ - int i; - struct ether_addr read_mac_addr; - struct ether_addr *mac_addr; - - uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 }; - - mac_addr = (struct ether_addr *)explicit_bonded_mac; - - /* Invalid port ID */ - TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr), - "Expected call to failed as invalid port specified."); - - /* Non bonded device */ - TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set( - test_params->slave_port_ids[0], mac_addr), - "Expected call to failed as invalid port specified."); - - /* NULL MAC address */ - TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set( - test_params->bonded_port_id, NULL), - "Expected call to failed as NULL MAC specified"); - - TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( - test_params->bonded_port_id, mac_addr), - "Failed to set MAC address on bonded port (%d)", - test_params->bonded_port_id); - - /* Add 4 slaves to bonded device */ - for (i = test_params->bonded_slave_count; i < 4; i++) { - TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), - "Failed to add slave to bonded device.\n"); - } - - /* Check bonded MAC */ - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)), - "bonded port mac address not set to that of primary port"); - - /* Check other slaves MACs */ - for (i = 0; i < 4; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port mac address not set to that of primary port"); - } - - /* test resetting mac address on bonded device */ - TEST_ASSERT_SUCCESS( - rte_eth_bond_mac_address_reset(test_params->bonded_port_id), - "Failed to reset MAC address on bonded port (%d)", - test_params->bonded_port_id); - - TEST_ASSERT_FAIL( - rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]), - "Reset MAC address on bonded port (%d) unexpectedly", - test_params->slave_port_ids[1]); - - /* test resetting mac address on bonded device with no slaves */ - TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(), - "Failed to remove slaves and stop bonded device"); - - TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id), - "Failed to reset MAC address on bonded port (%d)", - test_params->bonded_port_id); - - return 0; -} - -#define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3) - -static int -test_set_bonded_port_initialization_mac_assignment(void) -{ - int i, slave_count, bonded_port_id; - - uint8_t slaves[RTE_MAX_ETHPORTS]; - int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT]; - - struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr; - - /* Initialize default values for MAC addresses */ - memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr)); - memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr)); - - /* - * 1. a - Create / configure bonded / slave ethdevs - */ - bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test", - BONDING_MODE_ACTIVE_BACKUP, rte_socket_id()); - TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device"); - - TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0), - "Failed to configure bonded ethdev"); - - for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) { - char pmd_name[RTE_ETH_NAME_MAX_LEN]; - - slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100; - - snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i); - - slave_port_ids[i] = virtual_ethdev_create(pmd_name, - &slave_mac_addr, rte_socket_id(), 1); - - TEST_ASSERT(slave_port_ids[i] >= 0, - "Failed to create slave ethdev %s", pmd_name); - - TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0), - "Failed to configure virtual ethdev %s", - pmd_name); - } - - - /* - * 2. Add slave ethdevs to bonded device - */ - for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) { - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id, - slave_port_ids[i]), - "Failed to add slave (%d) to bonded port (%d).", - slave_port_ids[i], bonded_port_id); - } - - slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves, - RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count, - "Number of slaves (%d) is not as expected (%d)", - slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT); - - - /* - * 3. Set explicit MAC address on bonded ethdev - */ - bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF; - bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA; - - TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( - bonded_port_id, &bonded_mac_addr), - "Failed to set MAC address on bonded port (%d)", - bonded_port_id); - - - /* 4. a - Start bonded ethdev - * b - Enable slave devices - * c - Verify bonded/slaves ethdev MAC addresses - */ - TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id), - "Failed to start bonded pmd eth device %d.", - bonded_port_id); - - for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) { - virtual_ethdev_simulate_link_status_interrupt( - slave_port_ids[i], 1); - } - - rte_eth_macaddr_get(bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port mac address not as expected"); - - rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 0 mac address not as expected"); - - slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100; - rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 1 mac address not as expected"); - - slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100; - rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 2 mac address not as expected"); - - - /* 7. a - Change primary port - * b - Stop / Start bonded port - * d - Verify slave ethdev MAC addresses - */ - TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id, - slave_port_ids[2]), - "failed to set primary port on bonded device."); - - rte_eth_dev_stop(bonded_port_id); - TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id), - "Failed to start bonded pmd eth device %d.", - bonded_port_id); - - rte_eth_macaddr_get(bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port mac address not as expected"); - - slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100; - rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 0 mac address not as expected"); - - slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100; - rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 1 mac address not as expected"); - - rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 2 mac address not as expected"); - - /* 6. a - Stop bonded ethdev - * b - remove slave ethdevs - * c - Verify slave ethdevs MACs are restored - */ - rte_eth_dev_stop(bonded_port_id); - - for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) { - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id, - slave_port_ids[i]), - "Failed to remove slave %d from bonded port (%d).", - slave_port_ids[i], bonded_port_id); - } - - slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves, - RTE_MAX_ETHPORTS); - - TEST_ASSERT_EQUAL(slave_count, 0, - "Number of slaves (%d) is great than expected (%d).", - slave_count, 0); - - slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100; - rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 0 mac address not as expected"); - - slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100; - rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 1 mac address not as expected"); - - slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100; - rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port 2 mac address not as expected"); - - return 0; -} - - -static int -initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr, - uint8_t number_of_slaves, uint8_t enable_slave) -{ - /* Configure bonded device */ - TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, - bond_en_isr), "Failed to configure bonding port (%d) in mode %d " - "with (%d) slaves.", test_params->bonded_port_id, bonding_mode, - number_of_slaves); - - /* Add slaves to bonded device */ - while (number_of_slaves > test_params->bonded_slave_count) - TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), - "Failed to add slave (%d to bonding port (%d).", - test_params->bonded_slave_count - 1, - test_params->bonded_port_id); - - /* Set link bonding mode */ - TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id, - bonding_mode), - "Failed to set link bonding mode on port (%d) to (%d).", - test_params->bonded_port_id, bonding_mode); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), - "Failed to start bonded pmd eth device %d.", - test_params->bonded_port_id); - - if (enable_slave) - enable_bonded_slaves(); - - return 0; -} - -static int -test_adding_slave_after_bonded_device_started(void) -{ - int i; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 0, 4, 0), - "Failed to add slaves to bonded device"); - - /* Enabled slave devices */ - for (i = 0; i < test_params->bonded_slave_count + 1; i++) { - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 1); - } - - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id, - test_params->slave_port_ids[test_params->bonded_slave_count]), - "Failed to add slave to bonded port.\n"); - - rte_eth_stats_reset( - test_params->slave_port_ids[test_params->bonded_slave_count]); - - test_params->bonded_slave_count++; - - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4 -#define TEST_LSC_WAIT_TIMEOUT_MS 500 - -int test_lsc_interrupt_count; - - -static void -test_bonding_lsc_event_callback(uint8_t port_id __rte_unused, - enum rte_eth_event_type type __rte_unused, void *param __rte_unused) -{ - pthread_mutex_lock(&mutex); - test_lsc_interrupt_count++; - - pthread_cond_signal(&cvar); - pthread_mutex_unlock(&mutex); -} - -static inline int -lsc_timeout(int wait_us) -{ - int retval = 0; - - struct timespec ts; - struct timeval tp; - - gettimeofday(&tp, NULL); - - /* Convert from timeval to timespec */ - ts.tv_sec = tp.tv_sec; - ts.tv_nsec = tp.tv_usec * 1000; - ts.tv_nsec += wait_us * 1000; - - pthread_mutex_lock(&mutex); - if (test_lsc_interrupt_count < 1) - retval = pthread_cond_timedwait(&cvar, &mutex, &ts); - - pthread_mutex_unlock(&mutex); - - if (retval == 0 && test_lsc_interrupt_count < 1) - return -1; - - return retval; -} - -static int -test_status_interrupt(void) -{ - int slave_count; - uint8_t slaves[RTE_MAX_ETHPORTS]; - - /* initialized bonding device with T slaves */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 1, - TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1), - "Failed to initialise bonded device"); - - test_lsc_interrupt_count = 0; - - /* register link status change interrupt callback */ - rte_eth_dev_callback_register(test_params->bonded_port_id, - RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, - &test_params->bonded_port_id); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - - TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT, - "Number of active slaves (%d) is not as expected (%d)", - slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT); - - /* Bring all 4 slaves link status to down and test that we have received a - * lsc interrupts */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[0], 0); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 0); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[2], 0); - - TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0, - "Received a link status change interrupt unexpectedly"); - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 0); - - TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0, - "timed out waiting for interrupt"); - - TEST_ASSERT(test_lsc_interrupt_count > 0, - "Did not receive link status change interrupt"); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - - TEST_ASSERT_EQUAL(slave_count, 0, - "Number of active slaves (%d) is not as expected (%d)", - slave_count, 0); - - /* bring one slave port up so link status will change */ - test_lsc_interrupt_count = 0; - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[0], 1); - - TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0, - "timed out waiting for interrupt"); - - /* test that we have received another lsc interrupt */ - TEST_ASSERT(test_lsc_interrupt_count > 0, - "Did not receive link status change interrupt"); - - /* Verify that calling the same slave lsc interrupt doesn't cause another - * lsc interrupt from bonded device */ - test_lsc_interrupt_count = 0; - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[0], 1); - - TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0, - "received unexpected interrupt"); - - TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0, - "Did not receive link status change interrupt"); - - - /* unregister lsc callback before exiting */ - rte_eth_dev_callback_unregister(test_params->bonded_port_id, - RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, - &test_params->bonded_port_id); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size, - uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac, - uint8_t toggle_ip_addr, uint8_t toggle_udp_port) -{ - uint16_t pktlen, generated_burst_size, ether_type; - void *ip_hdr; - - if (ipv4) - ether_type = ETHER_TYPE_IPv4; - else - ether_type = ETHER_TYPE_IPv6; - - if (toggle_dst_mac) - initialize_eth_header(test_params->pkt_eth_hdr, - (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, - ether_type, vlan, vlan_id); - else - initialize_eth_header(test_params->pkt_eth_hdr, - (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, - ether_type, vlan, vlan_id); - - - if (toggle_udp_port) - pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, - dst_port_1, 64); - else - pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, - dst_port_0, 64); - - if (ipv4) { - if (toggle_ip_addr) - pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, - dst_addr_1, pktlen); - else - pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, - dst_addr_0, pktlen); - - ip_hdr = test_params->pkt_ipv4_hdr; - } else { - if (toggle_ip_addr) - pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr, - (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1, - pktlen); - else - pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr, - (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0, - pktlen); - - ip_hdr = test_params->pkt_ipv6_hdr; - } - - /* Generate burst of packets to transmit */ - generated_burst_size = generate_packet_burst(test_params->mbuf_pool, - pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4, - test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128, - 1); - TEST_ASSERT_EQUAL(generated_burst_size, burst_size, - "Failed to generate packet burst"); - - return generated_burst_size; -} - -/** Round Robin Mode Tests */ - -static int -test_roundrobin_tx_burst(void) -{ - int i, burst_size; - struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; - struct rte_eth_stats port_stats; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 0, 2, 1), - "Failed to intialise bonded device"); - - burst_size = 20 * test_params->bonded_slave_count; - - TEST_ASSERT(burst_size <= MAX_PKT_BURST, - "Burst size specified is greater than supported."); - - /* Generate test bursts of packets to transmit */ - TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0), - burst_size, "failed to generate test burst"); - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size, - "tx burst failed"); - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "Bonded Port (%d) opackets value (%u) not as expected (%d)\n", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - burst_size); - - /* Verify slave ports tx stats */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)burst_size / test_params->bonded_slave_count, - "Slave Port (%d) opackets value (%u) not as expected (%d)\n", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - burst_size / test_params->bonded_slave_count); - } - - /* Put all slaves down and try and transmit */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 0); - } - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, - pkt_burst, burst_size), 0, - "tx burst return unexpected value"); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val) -{ - int i, refcnt; - - for (i = 0; i < nb_mbufs; i++) { - refcnt = rte_mbuf_refcnt_read(mbufs[i]); - TEST_ASSERT_EQUAL(refcnt, val, - "mbuf ref count (%d)is not the expected value (%d)", - refcnt, val); - } - return 0; -} - -static void -free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs) -{ - int i; - - for (i = 0; i < nb_mbufs; i++) - rte_pktmbuf_free(mbufs[i]); -} - -#define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2) -#define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64) -#define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22) -#define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1) - -static int -test_roundrobin_tx_burst_slave_tx_fail(void) -{ - struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; - struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST]; - - struct rte_eth_stats port_stats; - - int i, first_fail_idx, tx_count; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 0, - TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1), - "Failed to intialise bonded device"); - - /* Generate test bursts of packets to transmit */ - TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, - TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0), - TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, - "Failed to generate test packet burst"); - - /* Copy references to packets which we expect not to be transmitted */ - first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - - (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT * - TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) + - TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX; - - for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) { - expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx + - (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)]; - } - - /* Set virtual slave to only fail transmission of - * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */ - virtual_ethdev_tx_burst_fn_set_success( - test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], - 0); - - virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( - test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], - TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT); - - tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst, - TEST_RR_SLAVE_TX_FAIL_BURST_SIZE); - - TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - - TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, - "Transmitted (%d) an unexpected (%d) number of packets", tx_count, - TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - - TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT); - - /* Verify that failed packet are expected failed packets */ - for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) { - TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count], - "expected mbuf (%d) pointer %p not expected pointer %p", - i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]); - } - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - - TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, - "Bonded Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - - TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT); - - /* Verify slave ports tx stats */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - int slave_expected_tx_count; - - rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); - - slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE / - test_params->bonded_slave_count; - - if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX) - slave_expected_tx_count = slave_expected_tx_count - - TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; - - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)slave_expected_tx_count, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->slave_port_ids[i], - (unsigned int)port_stats.opackets, slave_expected_tx_count); - } - - /* Verify that all mbufs have a ref value of zero */ - TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count], - TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1), - "mbufs refcnts not as expected"); - free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_roundrobin_rx_burst_on_single_slave(void) -{ - struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - - struct rte_eth_stats port_stats; - - int i, j, burst_size = 25; - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 0, 4, 1), - "Failed to initialize bonded device with slaves"); - - /* Generate test bursts of packets to transmit */ - TEST_ASSERT_EQUAL(generate_test_burst( - gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size, - "burst generation failed"); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - /* Add rx data to slave */ - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &gen_pkt_burst[0], burst_size); - - /* Call rx burst on bonded device */ - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_rx_burst( - test_params->bonded_port_id, 0, rx_pkt_burst, - MAX_PKT_BURST), burst_size, - "round-robin rx burst failed"); - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, - "Bonded Port (%d) ipackets value (%u) not as expected (%d)", - test_params->bonded_port_id, - (unsigned int)port_stats.ipackets, burst_size); - - - - /* Verify bonded slave devices rx count */ - /* Verify slave ports tx stats */ - for (j = 0; j < test_params->bonded_slave_count; j++) { - rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); - - if (i == j) { - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, - "Slave Port (%d) ipackets value (%u) not as expected" - " (%d)", test_params->slave_port_ids[i], - (unsigned int)port_stats.ipackets, burst_size); - } else { - TEST_ASSERT_EQUAL(port_stats.ipackets, 0, - "Slave Port (%d) ipackets value (%u) not as expected" - " (%d)", test_params->slave_port_ids[i], - (unsigned int)port_stats.ipackets, 0); - } - - /* Reset bonded slaves stats */ - rte_eth_stats_reset(test_params->slave_port_ids[j]); - } - /* reset bonded device stats */ - rte_eth_stats_reset(test_params->bonded_port_id); - } - - /* free mbufs */ - for (i = 0; i < MAX_PKT_BURST; i++) { - if (gen_pkt_burst[i] != NULL) - rte_pktmbuf_free(gen_pkt_burst[i]); - - if (rx_pkt_burst[i] != NULL) - rte_pktmbuf_free(rx_pkt_burst[i]); - } - - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3) - -static int -test_roundrobin_rx_burst_on_multiple_slaves(void) -{ - struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; - - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_eth_stats port_stats; - - int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 }; - int i, nb_rx; - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 0, 4, 1), - "Failed to initialize bonded device with slaves"); - - /* Generate test bursts of packets to transmit */ - for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) { - TEST_ASSERT_EQUAL(generate_test_burst( - &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0), - burst_size[i], "burst generation failed"); - } - - /* Add rx data to slaves */ - for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) { - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &gen_pkt_burst[i][0], burst_size[i]); - } - - /* Call rx burst on bonded device */ - /* Send burst on bonded port */ - nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, - MAX_PKT_BURST); - TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2], - "round-robin rx burst failed (%d != %d)\n", nb_rx, - burst_size[0] + burst_size[1] + burst_size[2]); - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, - (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), - "Bonded Port (%d) ipackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.ipackets, - burst_size[0] + burst_size[1] + burst_size[2]); - - /* Verify bonded slave devices rx counts */ - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[0], - (unsigned int)port_stats.ipackets, burst_size[0]); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets, - burst_size[1]); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[2], - (unsigned int)port_stats.ipackets, burst_size[2]); - - rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, 0, - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[3], - (unsigned int)port_stats.ipackets, 0); - - /* free mbufs */ - for (i = 0; i < MAX_PKT_BURST; i++) { - if (rx_pkt_burst[i] != NULL) - rte_pktmbuf_free(rx_pkt_burst[i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_roundrobin_verify_mac_assignment(void) -{ - struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2; - - int i; - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); - rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2); - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 0, 4, 1), - "Failed to initialize bonded device with slaves"); - - /* Verify that all MACs are the same as first slave added to bonded dev */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[i]); - } - - /* change primary and verify that MAC addresses haven't changed */ - TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, - test_params->slave_port_ids[2]), - "Failed to set bonded port (%d) primary port to (%d)", - test_params->bonded_port_id, test_params->slave_port_ids[i]); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address has changed to that of primary" - " port without stop/start toggle of bonded device", - test_params->slave_port_ids[i]); - } - - /* stop / start bonded device and verify that primary MAC address is - * propagate to bonded device and slaves */ - rte_eth_dev_stop(test_params->bonded_port_id); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), - "Failed to start bonded device"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS( - memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of new primary port", - test_params->slave_port_ids[i]); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of new primary" - " port", test_params->slave_port_ids[i]); - } - - /* Set explicit MAC address */ - TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( - test_params->bonded_port_id, (struct ether_addr *)bonded_mac), - "Failed to set MAC"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of new primary port", - test_params->slave_port_ids[i]); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), "slave port (%d) mac address not set to" - " that of new primary port\n", test_params->slave_port_ids[i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_roundrobin_verify_promiscuous_enable_disable(void) -{ - int i, promiscuous_en; - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 0, 4, 1), - "Failed to initialize bonded device with slaves"); - - rte_eth_promiscuous_enable(test_params->bonded_port_id); - - promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(promiscuous_en, 1, - "Port (%d) promiscuous mode not enabled", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - promiscuous_en = rte_eth_promiscuous_get( - test_params->slave_port_ids[i]); - TEST_ASSERT_EQUAL(promiscuous_en, 1, - "slave port (%d) promiscuous mode not enabled", - test_params->slave_port_ids[i]); - } - - rte_eth_promiscuous_disable(test_params->bonded_port_id); - - promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(promiscuous_en, 0, - "Port (%d) promiscuous mode not disabled\n", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - promiscuous_en = rte_eth_promiscuous_get( - test_params->slave_port_ids[i]); - TEST_ASSERT_EQUAL(promiscuous_en, 0, - "Port (%d) promiscuous mode not disabled\n", - test_params->slave_port_ids[i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_RR_LINK_STATUS_SLAVE_COUNT (4) -#define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2) - -static int -test_roundrobin_verify_slave_link_status_change_behaviour(void) -{ - struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST]; - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - - struct rte_eth_stats port_stats; - uint8_t slaves[RTE_MAX_ETHPORTS]; - - int i, burst_size, slave_count; - - /* NULL all pointers in array to simplify cleanup */ - memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); - - /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves - * in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1), - "Failed to initialize bonded device with slaves"); - - /* Verify Current Slaves Count /Active Slave Count is */ - slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, - RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT, - "Number of slaves (%d) is not as expected (%d).", - slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT); - - /* Set 2 slaves eth_devs link status to down */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 0); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 0); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, - TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT, - "Number of active slaves (%d) is not as expected (%d).\n", - slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT); - - burst_size = 20; - - /* Verify that pkts are not sent on slaves with link status down: - * - * 1. Generate test burst of traffic - * 2. Transmit burst on bonded eth_dev - * 3. Verify stats for bonded eth_dev (opackets = burst_size) - * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0) - */ - TEST_ASSERT_EQUAL( - generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0), - burst_size, "generate_test_burst failed"); - - rte_eth_stats_reset(test_params->bonded_port_id); - - - TEST_ASSERT_EQUAL( - rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst, - burst_size), burst_size, "rte_eth_tx_burst failed"); - - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "Port (%d) opackets stats (%d) not expected (%d) value", - test_params->bonded_port_id, (int)port_stats.opackets, - burst_size); - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10, - "Port (%d) opackets stats (%d) not expected (%d) value", - test_params->slave_port_ids[0], (int)port_stats.opackets, 10); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0, - "Port (%d) opackets stats (%d) not expected (%d) value", - test_params->slave_port_ids[1], (int)port_stats.opackets, 0); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10, - "Port (%d) opackets stats (%d) not expected (%d) value", - test_params->slave_port_ids[2], (int)port_stats.opackets, 10); - - rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0, - "Port (%d) opackets stats (%d) not expected (%d) value", - test_params->slave_port_ids[3], (int)port_stats.opackets, 0); - - /* Verify that pkts are not sent on slaves with link status down: - * - * 1. Generate test bursts of traffic - * 2. Add bursts on to virtual eth_devs - * 3. Rx burst on bonded eth_dev, expected (burst_ size * - * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received - * 4. Verify stats for bonded eth_dev - * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0) - */ - for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) { - TEST_ASSERT_EQUAL(generate_test_burst( - &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), - burst_size, "failed to generate packet burst"); - - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &gen_pkt_burst[i][0], burst_size); - } - - TEST_ASSERT_EQUAL(rte_eth_rx_burst( - test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), - burst_size + burst_size, - "rte_eth_rx_burst failed"); - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size), - "(%d) port_stats.ipackets not as expected\n", - test_params->bonded_port_id); - - /* free mbufs */ - for (i = 0; i < MAX_PKT_BURST; i++) { - if (rx_pkt_burst[i] != NULL) - rte_pktmbuf_free(rx_pkt_burst[i]); - - if (gen_pkt_burst[1][i] != NULL) - rte_pktmbuf_free(gen_pkt_burst[1][i]); - - if (gen_pkt_burst[3][i] != NULL) - rte_pktmbuf_free(gen_pkt_burst[1][i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2) - -uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 }; - - -int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 }; - -static int -test_roundrobin_verfiy_polling_slave_link_status_change(void) -{ - struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac; - char slave_name[RTE_ETH_NAME_MAX_LEN]; - - int i; - - for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) { - /* Generate slave name / MAC address */ - snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i); - mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i; - - /* Create slave devices with no ISR Support */ - if (polling_test_slaves[i] == -1) { - polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr, - rte_socket_id(), 0); - TEST_ASSERT(polling_test_slaves[i] >= 0, - "Failed to create virtual virtual ethdev %s\n", slave_name); - - /* Configure slave */ - TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0), - "Failed to configure virtual ethdev %s(%d)", slave_name, - polling_test_slaves[i]); - } - - /* Add slave to bonded device */ - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id, - polling_test_slaves[i]), - "Failed to add slave %s(%d) to bonded device %d", - slave_name, polling_test_slaves[i], - test_params->bonded_port_id); - } - - /* Initialize bonded device */ - TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1), - "Failed to configure bonded device %d", - test_params->bonded_port_id); - - - /* Register link status change interrupt callback */ - rte_eth_dev_callback_register(test_params->bonded_port_id, - RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, - &test_params->bonded_port_id); - - /* link status change callback for first slave link up */ - test_lsc_interrupt_count = 0; - - virtual_ethdev_set_link_status(polling_test_slaves[0], 1); - - TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt"); - - - /* no link status change callback for second slave link up */ - test_lsc_interrupt_count = 0; - - virtual_ethdev_set_link_status(polling_test_slaves[1], 1); - - TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded"); - - /* link status change callback for both slave links down */ - test_lsc_interrupt_count = 0; - - virtual_ethdev_set_link_status(polling_test_slaves[0], 0); - virtual_ethdev_set_link_status(polling_test_slaves[1], 0); - - TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt"); - - /* Un-Register link status change interrupt callback */ - rte_eth_dev_callback_unregister(test_params->bonded_port_id, - RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, - &test_params->bonded_port_id); - - - /* Clean up and remove slaves from bonded device */ - for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) { - - TEST_ASSERT_SUCCESS( - rte_eth_bond_slave_remove(test_params->bonded_port_id, - polling_test_slaves[i]), - "Failed to remove slave %d from bonded port (%d)", - polling_test_slaves[i], test_params->bonded_port_id); - } - - return remove_slaves_and_stop_bonded_device(); -} - - -/** Active Backup Mode Tests */ - -static int -test_activebackup_tx_burst(void) -{ - int i, pktlen, primary_port, burst_size; - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - struct rte_eth_stats port_stats; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1), - "Failed to initialize bonded device with slaves"); - - initialize_eth_header(test_params->pkt_eth_hdr, - (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, - ETHER_TYPE_IPv4, 0, 0); - pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, - dst_port_0, 16); - pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, - dst_addr_0, pktlen); - - burst_size = 20 * test_params->bonded_slave_count; - - TEST_ASSERT(burst_size < MAX_PKT_BURST, - "Burst size specified is greater than supported."); - - /* Generate a burst of packets to transmit */ - TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst, - test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, - test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1), - burst_size, "failed to generate burst correctly"); - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst, - burst_size), burst_size, "tx burst failed"); - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "Bonded Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - burst_size); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - - /* Verify slave ports tx stats */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); - if (test_params->slave_port_ids[i] == primary_port) { - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, - (unsigned int)port_stats.opackets, - burst_size / test_params->bonded_slave_count); - } else { - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, - (unsigned int)port_stats.opackets, 0); - } - } - - /* Put all slaves down and try and transmit */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 0); - } - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, - pkts_burst, burst_size), 0, "Sending empty burst failed"); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4) - -static int -test_activebackup_rx_burst(void) -{ - struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - - struct rte_eth_stats port_stats; - - int primary_port; - - int i, j, burst_size = 17; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ACTIVE_BACKUP, 0, - TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1), - "Failed to initialize bonded device with slaves"); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT(primary_port >= 0, - "failed to get primary slave for bonded port (%d)", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - /* Generate test bursts of packets to transmit */ - TEST_ASSERT_EQUAL(generate_test_burst( - &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), - burst_size, "burst generation failed"); - - /* Add rx data to slave */ - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &gen_pkt_burst[0], burst_size); - - /* Call rx burst on bonded device */ - TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0, - &rx_pkt_burst[0], MAX_PKT_BURST), burst_size, - "rte_eth_rx_burst failed"); - - if (test_params->slave_port_ids[i] == primary_port) { - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, - "Bonded Port (%d) ipackets value (%u) not as expected (%d)", - test_params->bonded_port_id, - (unsigned int)port_stats.ipackets, burst_size); - - /* Verify bonded slave devices rx count */ - for (j = 0; j < test_params->bonded_slave_count; j++) { - rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); - if (i == j) { - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, - "Slave Port (%d) ipackets value (%u) not as " - "expected (%d)", test_params->slave_port_ids[i], - (unsigned int)port_stats.ipackets, burst_size); - } else { - TEST_ASSERT_EQUAL(port_stats.ipackets, 0, - "Slave Port (%d) ipackets value (%u) not as " - "expected (%d)\n", test_params->slave_port_ids[i], - (unsigned int)port_stats.ipackets, 0); - } - } - } else { - for (j = 0; j < test_params->bonded_slave_count; j++) { - rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, 0, - "Slave Port (%d) ipackets value (%u) not as expected " - "(%d)", test_params->slave_port_ids[i], - (unsigned int)port_stats.ipackets, 0); - } - } - - /* free mbufs */ - for (i = 0; i < MAX_PKT_BURST; i++) { - if (rx_pkt_burst[i] != NULL) { - rte_pktmbuf_free(rx_pkt_burst[i]); - rx_pkt_burst[i] = NULL; - } - } - - /* reset bonded device stats */ - rte_eth_stats_reset(test_params->bonded_port_id); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_activebackup_verify_promiscuous_enable_disable(void) -{ - int i, primary_port, promiscuous_en; - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1), - "Failed to initialize bonded device with slaves"); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT(primary_port >= 0, - "failed to get primary slave for bonded port (%d)", - test_params->bonded_port_id); - - rte_eth_promiscuous_enable(test_params->bonded_port_id); - - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, - "Port (%d) promiscuous mode not enabled", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - promiscuous_en = rte_eth_promiscuous_get( - test_params->slave_port_ids[i]); - if (primary_port == test_params->slave_port_ids[i]) { - TEST_ASSERT_EQUAL(promiscuous_en, 1, - "slave port (%d) promiscuous mode not enabled", - test_params->slave_port_ids[i]); - } else { - TEST_ASSERT_EQUAL(promiscuous_en, 0, - "slave port (%d) promiscuous mode enabled", - test_params->slave_port_ids[i]); - } - - } - - rte_eth_promiscuous_disable(test_params->bonded_port_id); - - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, - "Port (%d) promiscuous mode not disabled\n", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - promiscuous_en = rte_eth_promiscuous_get( - test_params->slave_port_ids[i]); - TEST_ASSERT_EQUAL(promiscuous_en, 0, - "slave port (%d) promiscuous mode not disabled\n", - test_params->slave_port_ids[i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_activebackup_verify_mac_assignment(void) -{ - struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1; - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); - rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1); - - /* Initialize bonded device with 2 slaves in active backup mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1), - "Failed to initialize bonded device with slaves"); - - /* Verify that bonded MACs is that of first slave and that the other slave - * MAC hasn't been changed */ - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected", - test_params->slave_port_ids[1]); - - /* change primary and verify that MAC addresses haven't changed */ - TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id, - test_params->slave_port_ids[1]), 0, - "Failed to set bonded port (%d) primary port to (%d)", - test_params->bonded_port_id, test_params->slave_port_ids[1]); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected", - test_params->slave_port_ids[1]); - - /* stop / start bonded device and verify that primary MAC address is - * propagated to bonded device and slaves */ - - rte_eth_dev_stop(test_params->bonded_port_id); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), - "Failed to start device"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[1]); - - /* Set explicit MAC address */ - TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( - test_params->bonded_port_id, (struct ether_addr *)bonded_mac), - "failed to set MAC address"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of bonded port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of bonded port", - test_params->slave_port_ids[1]); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_activebackup_verify_slave_link_status_change_failover(void) -{ - struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_eth_stats port_stats; - - uint8_t slaves[RTE_MAX_ETHPORTS]; - - int i, j, burst_size, slave_count, primary_port; - - burst_size = 21; - - memset(pkt_burst, 0, sizeof(pkt_burst)); - - /* Generate packet burst for testing */ - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, - "generate_test_burst failed"); - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ACTIVE_BACKUP, 0, - TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1), - "Failed to initialize bonded device with slaves"); - - /* Verify Current Slaves Count /Active Slave Count is */ - slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, - RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, 4, - "Number of slaves (%d) is not as expected (%d).", - slave_count, 4); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, 4, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 4); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0], - "Primary port not as expected"); - - /* Bring 2 slaves down and verify active slave count */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 0); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 0); - - TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 2); - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 1); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 1); - - - /* Bring primary port down, verify that active slave count is 3 and primary - * has changed */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[0], 0); - - TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), - 3, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 3); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2], - "Primary port not as expected"); - - /* Verify that pkts are sent on new primary slave */ - - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, &pkt_burst[0][0], - burst_size), burst_size, "rte_eth_tx_burst failed"); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[2]); - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "(%d) port_stats.opackets not as expected\n", - test_params->slave_port_ids[0]); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "(%d) port_stats.opackets not as expected\n", - test_params->slave_port_ids[1]); - - rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "(%d) port_stats.opackets not as expected\n", - test_params->slave_port_ids[3]); - - /* Generate packet burst for testing */ - - for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) { - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size, - "generate_test_burst failed"); - - virtual_ethdev_add_mbufs_to_rx_queue( - test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size); - } - - TEST_ASSERT_EQUAL(rte_eth_rx_burst( - test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), - burst_size, "rte_eth_rx_burst\n"); - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, - "(%d) port_stats.ipackets not as expected", - test_params->bonded_port_id); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[2]); - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[0]); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[1]); - - rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[3]); - - /* free mbufs */ - for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) { - for (j = 0; j < MAX_PKT_BURST; j++) { - if (pkt_burst[i][j] != NULL) { - rte_pktmbuf_free(pkt_burst[i][j]); - pkt_burst[i][j] = NULL; - } - } - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -/** Balance Mode Tests */ - -static int -test_balance_xmit_policy_configuration(void) -{ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1), - "Failed to initialize_bonded_device_with_slaves."); - - /* Invalid port id */ - TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set( - INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2), - "Expected call to failed as invalid port specified."); - - /* Set xmit policy on non bonded device */ - TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set( - test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2), - "Expected call to failed as invalid port specified."); - - - TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( - test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), - "Failed to set balance xmit policy."); - - TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), - BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected."); - - - TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( - test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23), - "Failed to set balance xmit policy."); - - TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), - BALANCE_XMIT_POLICY_LAYER23, - "balance xmit policy not as expected."); - - - TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( - test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34), - "Failed to set balance xmit policy."); - - TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), - BALANCE_XMIT_POLICY_LAYER34, - "balance xmit policy not as expected."); - - /* Invalid port id */ - TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID), - "Expected call to failed as invalid port specified."); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2) - -static int -test_balance_l2_tx_burst(void) -{ - struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; - int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 }; - - uint16_t pktlen; - int i; - struct rte_eth_stats port_stats; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1), - "Failed to initialize_bonded_device_with_slaves."); - - TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( - test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), - "Failed to set balance xmit policy."); - - initialize_eth_header(test_params->pkt_eth_hdr, - (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, - ETHER_TYPE_IPv4, 0, 0); - pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, - dst_port_0, 16); - pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, - dst_addr_0, pktlen); - - /* Generate a burst 1 of packets to transmit */ - TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0], - test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, - test_params->pkt_udp_hdr, burst_size[0], - PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0], - "failed to generate packet burst"); - - initialize_eth_header(test_params->pkt_eth_hdr, - (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, - ETHER_TYPE_IPv4, 0, 0); - - /* Generate a burst 2 of packets to transmit */ - TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0], - test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, - test_params->pkt_udp_hdr, burst_size[1], - PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1], - "failed to generate packet burst"); - - /* Send burst 1 on bonded port */ - for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) { - TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, - &pkts_burst[i][0], burst_size[i]), - burst_size[i], "Failed to transmit packet burst"); - } - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)(burst_size[0] + burst_size[1]), - "Bonded Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - burst_size[0] + burst_size[1]); - - - /* Verify slave ports tx stats */ - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0], - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, - burst_size[0]); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1], - "Slave Port (%d) opackets value (%u) not as expected (%d)\n", - test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, - burst_size[1]); - - /* Put all slaves down and try and transmit */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 0); - } - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]), - 0, "Expected zero packet"); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4, - uint8_t toggle_mac_addr, uint8_t toggle_ip_addr) -{ - int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2; - - struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST]; - struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST]; - - struct rte_eth_stats port_stats; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BALANCE, 0, 2, 1), - "Failed to initialize_bonded_device_with_slaves."); - - TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( - test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23), - "Failed to set balance xmit policy."); - - burst_size_1 = 20; - burst_size_2 = 10; - - TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST, - "Burst size specified is greater than supported."); - - /* Generate test bursts of packets to transmit */ - TEST_ASSERT_EQUAL(generate_test_burst( - pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0), - burst_size_1, "failed to generate packet burst"); - - TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4, - toggle_mac_addr, toggle_ip_addr, 0), burst_size_2, - "failed to generate packet burst"); - - /* Send burst 1 on bonded port */ - nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, - burst_size_1); - TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed"); - - /* Send burst 2 on bonded port */ - nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, - burst_size_2); - TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed"); - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2), - "Bonded Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - nb_tx_1 + nb_tx_2); - - /* Verify slave ports tx stats */ - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, - nb_tx_1); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, - nb_tx_2); - - /* Put all slaves down and try and transmit */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 0); - } - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, pkts_burst_1, - burst_size_1), 0, "Expected zero packet"); - - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void) -{ - return balance_l23_tx_burst(0, 1, 1, 0); -} - -static int -test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void) -{ - return balance_l23_tx_burst(1, 1, 0, 1); -} - -static int -test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void) -{ - return balance_l23_tx_burst(0, 0, 0, 1); -} - -static int -test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void) -{ - return balance_l23_tx_burst(1, 0, 0, 1); -} - -static int -test_balance_l23_tx_burst_toggle_mac_addr(void) -{ - return balance_l23_tx_burst(0, 0, 1, 0); -} - -static int -balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4, - uint8_t toggle_mac_addr, uint8_t toggle_ip_addr, - uint8_t toggle_udp_port) -{ - int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2; - - struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST]; - struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST]; - - struct rte_eth_stats port_stats; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BALANCE, 0, 2, 1), - "Failed to initialize_bonded_device_with_slaves."); - - TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( - test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34), - "Failed to set balance xmit policy."); - - burst_size_1 = 20; - burst_size_2 = 10; - - TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST, - "Burst size specified is greater than supported."); - - /* Generate test bursts of packets to transmit */ - TEST_ASSERT_EQUAL(generate_test_burst( - pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0), - burst_size_1, "failed to generate burst"); - - TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, - vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr, - toggle_udp_port), burst_size_2, "failed to generate burst"); - - /* Send burst 1 on bonded port */ - nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, - burst_size_1); - TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed"); - - /* Send burst 2 on bonded port */ - nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, - burst_size_2); - TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed"); - - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2), - "Bonded Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - nb_tx_1 + nb_tx_2); - - /* Verify slave ports tx stats */ - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, - nb_tx_1); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, - nb_tx_2); - - /* Put all slaves down and try and transmit */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 0); - } - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, pkts_burst_1, - burst_size_1), 0, "Expected zero packet"); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void) -{ - return balance_l34_tx_burst(0, 1, 0, 1, 0); -} - -static int -test_balance_l34_tx_burst_ipv4_toggle_udp_port(void) -{ - return balance_l34_tx_burst(0, 1, 0, 0, 1); -} - -static int -test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void) -{ - return balance_l34_tx_burst(1, 1, 0, 1, 0); -} - -static int -test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void) -{ - return balance_l34_tx_burst(0, 0, 0, 1, 0); -} - -static int -test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void) -{ - return balance_l34_tx_burst(1, 0, 0, 1, 0); -} - -static int -test_balance_l34_tx_burst_ipv6_toggle_udp_port(void) -{ - return balance_l34_tx_burst(0, 0, 0, 0, 1); -} - -#define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2) -#define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40) -#define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20) -#define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25) -#define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0) - -static int -test_balance_tx_burst_slave_tx_fail(void) -{ - struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1]; - struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2]; - - struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT]; - - struct rte_eth_stats port_stats; - - int i, first_tx_fail_idx, tx_count_1, tx_count_2; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BALANCE, 0, - TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1), - "Failed to intialise bonded device"); - - TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( - test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), - "Failed to set balance xmit policy."); - - - /* Generate test bursts for transmission */ - TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1, - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0), - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, - "Failed to generate test packet burst 1"); - - first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; - - /* copy mbuf referneces for expected transmission failures */ - for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++) - expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx]; - - TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0), - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, - "Failed to generate test packet burst 2"); - - - /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail - * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */ - virtual_ethdev_tx_burst_fn_set_success( - test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], - 0); - - virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( - test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); - - - /* Transmit burst 1 */ - tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1); - - TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, - "Transmitted (%d) packets, expected to transmit (%d) packets", - tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); - - /* Verify that failed packet are expected failed packets */ - for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) { - TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1], - "expected mbuf (%d) pointer %p not expected pointer %p", - i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]); - } - - /* Transmit burst 2 */ - tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); - - TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, - "Transmitted (%d) packets, expected to transmit (%d) packets", - tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); - - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) + - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2), - "Bonded Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) + - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); - - /* Verify slave ports tx stats */ - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t) - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->slave_port_ids[0], - (unsigned int)port_stats.opackets, - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); - - - - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, - "Slave Port (%d) opackets value (%u) not as expected (%d)", - test_params->slave_port_ids[1], - (unsigned int)port_stats.opackets, - TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); - - /* Verify that all mbufs have a ref value of zero */ - TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1], - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1), - "mbufs refcnts not as expected"); - - free_mbufs(&pkts_burst_1[tx_count_1], - TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3) - -static int -test_balance_rx_burst(void) -{ - struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; - - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_eth_stats port_stats; - - int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 }; - int i, j; - - memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BALANCE, 0, 3, 1), - "Failed to intialise bonded device"); - - /* Generate test bursts of packets to transmit */ - for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { - TEST_ASSERT_EQUAL(generate_test_burst( - &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, - 0, 0), burst_size[i], - "failed to generate packet burst"); - } - - /* Add rx data to slaves */ - for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &gen_pkt_burst[i][0], burst_size[i]); - } - - /* Call rx burst on bonded device */ - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0, - rx_pkt_burst, MAX_PKT_BURST), - burst_size[0] + burst_size[1] + burst_size[2], - "balance rx burst failed\n"); - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, - (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), - "Bonded Port (%d) ipackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.ipackets, - burst_size[0] + burst_size[1] + burst_size[2]); - - - /* Verify bonded slave devices rx counts */ - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[0], - (unsigned int)port_stats.ipackets, burst_size[0]); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets, - burst_size[1]); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets, - burst_size[2]); - - rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, 0, - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets, - 0); - - /* free mbufs */ - for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { - for (j = 0; j < MAX_PKT_BURST; j++) { - if (gen_pkt_burst[i][j] != NULL) { - rte_pktmbuf_free(gen_pkt_burst[i][j]); - gen_pkt_burst[i][j] = NULL; - } - } - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_balance_verify_promiscuous_enable_disable(void) -{ - int i; - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BALANCE, 0, 4, 1), - "Failed to intialise bonded device"); - - rte_eth_promiscuous_enable(test_params->bonded_port_id); - - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, - "Port (%d) promiscuous mode not enabled", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( - test_params->slave_port_ids[i]), 1, - "Port (%d) promiscuous mode not enabled", - test_params->slave_port_ids[i]); - } - - rte_eth_promiscuous_disable(test_params->bonded_port_id); - - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, - "Port (%d) promiscuous mode not disabled", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( - test_params->slave_port_ids[i]), 0, - "Port (%d) promiscuous mode not disabled", - test_params->slave_port_ids[i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_balance_verify_mac_assignment(void) -{ - struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1; - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); - rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1); - - /* Initialize bonded device with 2 slaves in active backup mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BALANCE, 0, 2, 1), - "Failed to intialise bonded device"); - - /* Verify that bonded MACs is that of first slave and that the other slave - * MAC hasn't been changed */ - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[1]); - - /* change primary and verify that MAC addresses haven't changed */ - TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, - test_params->slave_port_ids[1]), - "Failed to set bonded port (%d) primary port to (%d)\n", - test_params->bonded_port_id, test_params->slave_port_ids[1]); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[1]); - - /* stop / start bonded device and verify that primary MAC address is - * propagated to bonded device and slaves */ - - rte_eth_dev_stop(test_params->bonded_port_id); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), - "Failed to start bonded device"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[1]); - - /* Set explicit MAC address */ - TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( - test_params->bonded_port_id, (struct ether_addr *)bonded_mac), - "failed to set MAC"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of bonded port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected\n", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of bonded port", - test_params->slave_port_ids[1]); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4) - -static int -test_balance_verify_slave_link_status_change_behaviour(void) -{ - struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST]; - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_eth_stats port_stats; - - uint8_t slaves[RTE_MAX_ETHPORTS]; - - int i, j, burst_size, slave_count; - - memset(pkt_burst, 0, sizeof(pkt_burst)); - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1), - "Failed to intialise bonded device"); - - TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( - test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), - "Failed to set balance xmit policy."); - - - /* Verify Current Slaves Count /Active Slave Count is */ - slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, - RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, - "Number of slaves (%d) is not as expected (%d).", - slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT); - - /* Set 2 slaves link status to down */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 0); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 0); - - TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 2); - - /* Send to sets of packet burst and verify that they are balanced across - * slaves */ - burst_size = 21; - - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, - "generate_test_burst failed"); - - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size, - "generate_test_burst failed"); - - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), - burst_size, "rte_eth_tx_burst failed"); - - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size), - burst_size, "rte_eth_tx_burst failed"); - - - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size), - "(%d) port_stats.opackets (%d) not as expected (%d).", - test_params->bonded_port_id, (int)port_stats.opackets, - burst_size + burst_size); - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "(%d) port_stats.opackets (%d) not as expected (%d).", - test_params->slave_port_ids[0], (int)port_stats.opackets, - burst_size); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "(%d) port_stats.opackets (%d) not as expected (%d).", - test_params->slave_port_ids[2], (int)port_stats.opackets, - burst_size); - - /* verify that all packets get send on primary slave when no other slaves - * are available */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[2], 0); - - TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 1); - - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size, - "generate_test_burst failed"); - - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size), - burst_size, "rte_eth_tx_burst failed"); - - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)(burst_size + burst_size + burst_size), - "(%d) port_stats.opackets (%d) not as expected (%d).\n", - test_params->bonded_port_id, (int)port_stats.opackets, - burst_size + burst_size + burst_size); - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size), - "(%d) port_stats.opackets (%d) not as expected (%d).", - test_params->slave_port_ids[0], (int)port_stats.opackets, - burst_size + burst_size); - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[0], 0); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 1); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[2], 1); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 1); - - for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) { - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size, - "Failed to generate packet burst"); - - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &pkt_burst[i][0], burst_size); - } - - /* Verify that pkts are not received on slaves with link status down */ - - rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, - MAX_PKT_BURST); - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3), - "(%d) port_stats.ipackets (%d) not as expected (%d)\n", - test_params->bonded_port_id, (int)port_stats.ipackets, - burst_size * 3); - - /* free mbufs allocate for rx testing */ - for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { - for (j = 0; j < MAX_PKT_BURST; j++) { - if (pkt_burst[i][j] != NULL) { - rte_pktmbuf_free(pkt_burst[i][j]); - pkt_burst[i][j] = NULL; - } - } - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_broadcast_tx_burst(void) -{ - int i, pktlen, burst_size; - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - - struct rte_eth_stats port_stats; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BROADCAST, 0, 2, 1), - "Failed to intialise bonded device"); - - initialize_eth_header(test_params->pkt_eth_hdr, - (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, - ETHER_TYPE_IPv4, 0, 0); - - pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, - dst_port_0, 16); - pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, - dst_addr_0, pktlen); - - burst_size = 20 * test_params->bonded_slave_count; - - TEST_ASSERT(burst_size < MAX_PKT_BURST, - "Burst size specified is greater than supported."); - - /* Generate a burst of packets to transmit */ - TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, - pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, - 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, - 1), burst_size, "Failed to generate packet burst"); - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, - pkts_burst, burst_size), burst_size, - "Bonded Port (%d) rx burst failed, packets transmitted value " - "not as expected (%d)", - test_params->bonded_port_id, burst_size); - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)burst_size * test_params->bonded_slave_count, - "Bonded Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - burst_size); - - /* Verify slave ports tx stats */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "Slave Port (%d) opackets value (%u) not as expected (%d)\n", - test_params->bonded_port_id, - (unsigned int)port_stats.opackets, burst_size); - } - - /* Put all slaves down and try and transmit */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 0); - } - - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, pkts_burst, burst_size), 0, - "transmitted an unexpected number of packets"); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - - -#define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3) -#define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40) -#define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15) -#define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10) - -static int -test_broadcast_tx_burst_slave_tx_fail(void) -{ - struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE]; - struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT]; - - struct rte_eth_stats port_stats; - - int i, tx_count; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BROADCAST, 0, - TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1), - "Failed to intialise bonded device"); - - /* Generate test bursts for transmission */ - TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst, - TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0), - TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, - "Failed to generate test packet burst"); - - for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) { - expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i]; - } - - /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail - * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */ - virtual_ethdev_tx_burst_fn_set_success( - test_params->slave_port_ids[0], - 0); - virtual_ethdev_tx_burst_fn_set_success( - test_params->slave_port_ids[1], - 0); - virtual_ethdev_tx_burst_fn_set_success( - test_params->slave_port_ids[2], - 0); - - virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( - test_params->slave_port_ids[0], - TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); - - virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( - test_params->slave_port_ids[1], - TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); - - virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( - test_params->slave_port_ids[2], - TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); - - /* Transmit burst */ - tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst, - TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE); - - TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, - "Transmitted (%d) packets, expected to transmit (%d) packets", - tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); - - /* Verify that failed packet are expected failed packets */ - for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) { - TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count], - "expected mbuf (%d) pointer %p not expected pointer %p", - i, expected_fail_pkts[i], pkts_burst[i + tx_count]); - } - - /* Verify slave ports tx stats */ - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT, - "Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); - - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, - "Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - - TEST_ASSERT_EQUAL(port_stats.opackets, - (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT, - "Port (%d) opackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.opackets, - TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - - TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); - - - /* Verify that all mbufs who transmission failed have a ref value of one */ - TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count], - TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1), - "mbufs refcnts not as expected"); - - free_mbufs(&pkts_burst[tx_count], - TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define BROADCAST_RX_BURST_NUM_OF_SLAVES (3) - -static int -test_broadcast_rx_burst(void) -{ - struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST]; - - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_eth_stats port_stats; - - int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 }; - int i, j; - - memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BROADCAST, 0, 3, 1), - "Failed to intialise bonded device"); - - /* Generate test bursts of packets to transmit */ - for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { - TEST_ASSERT_EQUAL(generate_test_burst( - &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0), - burst_size[i], "failed to generate packet burst"); - } - - /* Add rx data to slave 0 */ - for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &gen_pkt_burst[i][0], burst_size[i]); - } - - - /* Call rx burst on bonded device */ - /* Send burst on bonded port */ - TEST_ASSERT_EQUAL(rte_eth_rx_burst( - test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), - burst_size[0] + burst_size[1] + burst_size[2], - "rx burst failed"); - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, - (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), - "Bonded Port (%d) ipackets value (%u) not as expected (%d)", - test_params->bonded_port_id, (unsigned int)port_stats.ipackets, - burst_size[0] + burst_size[1] + burst_size[2]); - - - /* Verify bonded slave devices rx counts */ - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets, - burst_size[0]); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets, - burst_size[1]); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets, - burst_size[2]); - - rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, 0, - "Slave Port (%d) ipackets value (%u) not as expected (%d)", - test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets, - 0); - - /* free mbufs allocate for rx testing */ - for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { - for (j = 0; j < MAX_PKT_BURST; j++) { - if (gen_pkt_burst[i][j] != NULL) { - rte_pktmbuf_free(gen_pkt_burst[i][j]); - gen_pkt_burst[i][j] = NULL; - } - } - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_broadcast_verify_promiscuous_enable_disable(void) -{ - int i; - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BROADCAST, 0, 4, 1), - "Failed to intialise bonded device"); - - rte_eth_promiscuous_enable(test_params->bonded_port_id); - - - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, - "Port (%d) promiscuous mode not enabled", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( - test_params->slave_port_ids[i]), 1, - "Port (%d) promiscuous mode not enabled", - test_params->slave_port_ids[i]); - } - - rte_eth_promiscuous_disable(test_params->bonded_port_id); - - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, - "Port (%d) promiscuous mode not disabled", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( - test_params->slave_port_ids[i]), 0, - "Port (%d) promiscuous mode not disabled", - test_params->slave_port_ids[i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_broadcast_verify_mac_assignment(void) -{ - struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1; - - int i; - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); - rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1); - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BROADCAST, 0, 4, 1), - "Failed to intialise bonded device"); - - /* Verify that all MACs are the same as first slave added to bonded - * device */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[i]); - } - - /* change primary and verify that MAC addresses haven't changed */ - TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, - test_params->slave_port_ids[2]), - "Failed to set bonded port (%d) primary port to (%d)", - test_params->bonded_port_id, test_params->slave_port_ids[i]); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address has changed to that of primary " - "port without stop/start toggle of bonded device", - test_params->slave_port_ids[i]); - } - - /* stop / start bonded device and verify that primary MAC address is - * propagated to bonded device and slaves */ - - rte_eth_dev_stop(test_params->bonded_port_id); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), - "Failed to start bonded device"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of new primary port", - test_params->slave_port_ids[i]); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of new primary " - "port", test_params->slave_port_ids[i]); - } - - /* Set explicit MAC address */ - TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( - test_params->bonded_port_id, (struct ether_addr *)bonded_mac), - "Failed to set MAC address"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of new primary port", - test_params->slave_port_ids[i]); - - - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of new primary " - "port", test_params->slave_port_ids[i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4) -static int -test_broadcast_verify_slave_link_status_change_behaviour(void) -{ - struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST]; - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_eth_stats port_stats; - - uint8_t slaves[RTE_MAX_ETHPORTS]; - - int i, j, burst_size, slave_count; - - memset(pkt_burst, 0, sizeof(pkt_burst)); - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES, - 1), "Failed to intialise bonded device"); - - /* Verify Current Slaves Count /Active Slave Count is */ - slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, - RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, 4, - "Number of slaves (%d) is not as expected (%d).", - slave_count, 4); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, 4, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 4); - - /* Set 2 slaves link status to down */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 0); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 0); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, 2, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 2); - - for (i = 0; i < test_params->bonded_slave_count; i++) - rte_eth_stats_reset(test_params->slave_port_ids[i]); - - /* Verify that pkts are not sent on slaves with link status down */ - burst_size = 21; - - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size, - "generate_test_burst failed"); - - TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, - &pkt_burst[0][0], burst_size), burst_size, - "rte_eth_tx_burst failed\n"); - - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count), - "(%d) port_stats.opackets (%d) not as expected (%d)\n", - test_params->bonded_port_id, (int)port_stats.opackets, - burst_size * slave_count); - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[0]); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[1]); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[2]); - - - rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, 0, - "(%d) port_stats.opackets not as expected", - test_params->slave_port_ids[3]); - - - for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) { - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0), - burst_size, "failed to generate packet burst"); - - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &pkt_burst[i][0], burst_size); - } - - /* Verify that pkts are not received on slaves with link status down */ - TEST_ASSERT_EQUAL(rte_eth_rx_burst( - test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), - burst_size + burst_size, "rte_eth_rx_burst failed"); - - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size), - "(%d) port_stats.ipackets not as expected\n", - test_params->bonded_port_id); - - /* free mbufs allocate for rx testing */ - for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) { - for (j = 0; j < MAX_PKT_BURST; j++) { - if (pkt_burst[i][j] != NULL) { - rte_pktmbuf_free(pkt_burst[i][j]); - pkt_burst[i][j] = NULL; - } - } - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_reconfigure_bonded_device(void) -{ - test_params->nb_rx_q = 4; - test_params->nb_tx_q = 4; - - TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0), - "failed to reconfigure bonded device"); - - test_params->nb_rx_q = 2; - test_params->nb_tx_q = 2; - - TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0), - "failed to reconfigure bonded device with less rx/tx queues"); - - return 0; -} - - -static int -test_close_bonded_device(void) -{ - rte_eth_dev_close(test_params->bonded_port_id); - return 0; -} - -static void -testsuite_teardown(void) -{ - free(test_params->pkt_eth_hdr); - test_params->pkt_eth_hdr = NULL; - - /* Clean up and remove slaves from bonded device */ - remove_slaves_and_stop_bonded_device(); -} - -static void -free_virtualpmd_tx_queue(void) -{ - int i, slave_port, to_free_cnt; - struct rte_mbuf *pkts_to_free[MAX_PKT_BURST]; - - /* Free tx queue of virtual pmd */ - for (slave_port = 0; slave_port < test_params->bonded_slave_count; - slave_port++) { - to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue( - test_params->slave_port_ids[slave_port], - pkts_to_free, MAX_PKT_BURST); - for (i = 0; i < to_free_cnt; i++) - rte_pktmbuf_free(pkts_to_free[i]); - } -} - -static int -test_tlb_tx_burst(void) -{ - int i, burst_size, nb_tx; - uint64_t nb_tx2 = 0; - struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; - struct rte_eth_stats port_stats[32]; - uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0; - uint16_t pktlen; - - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves - (BONDING_MODE_TLB, 1, 3, 1), - "Failed to initialise bonded device"); - - burst_size = 20 * test_params->bonded_slave_count; - - TEST_ASSERT(burst_size < MAX_PKT_BURST, - "Burst size specified is greater than supported.\n"); - - - /* Generate bursts of packets */ - for (i = 0; i < 400000; i++) { - /*test two types of mac src own(bonding) and others */ - if (i % 2 == 0) { - initialize_eth_header(test_params->pkt_eth_hdr, - (struct ether_addr *)src_mac, - (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0); - } else { - initialize_eth_header(test_params->pkt_eth_hdr, - (struct ether_addr *)test_params->default_slave_mac, - (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0); - } - pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, - dst_port_0, 16); - pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, - dst_addr_0, pktlen); - generate_packet_burst(test_params->mbuf_pool, pkt_burst, - test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, - 1, test_params->pkt_udp_hdr, burst_size, 60, 1); - /* Send burst on bonded port */ - nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst, - burst_size); - nb_tx2 += nb_tx; - - free_virtualpmd_tx_queue(); - - TEST_ASSERT_EQUAL(nb_tx, burst_size, - "number of packet not equal burst size"); - - rte_delay_us(5); - } - - - /* Verify bonded port tx stats */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]); - - all_bond_opackets = port_stats[0].opackets; - all_bond_obytes = port_stats[0].obytes; - - TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2, - "Bonded Port (%d) opackets value (%u) not as expected (%d)\n", - test_params->bonded_port_id, (unsigned int)port_stats[0].opackets, - burst_size); - - - /* Verify slave ports tx stats */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]); - sum_ports_opackets += port_stats[i].opackets; - } - - TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets, - "Total packets sent by slaves is not equal to packets sent by bond interface"); - - /* checking if distribution of packets is balanced over slaves */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - TEST_ASSERT(port_stats[i].obytes > 0 && - port_stats[i].obytes < all_bond_obytes, - "Packets are not balanced over slaves"); - } - - /* Put all slaves down and try and transmit */ - for (i = 0; i < test_params->bonded_slave_count; i++) { - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[i], 0); - } - - /* Send burst on bonded port */ - nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst, - burst_size); - TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst"); - - /* Clean ugit checkout masterp and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4) - -static int -test_tlb_rx_burst(void) -{ - struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - - struct rte_eth_stats port_stats; - - int primary_port; - - uint16_t i, j, nb_rx, burst_size = 17; - - /* Initialize bonded device with 4 slaves in transmit load balancing mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_TLB, - TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1), - "Failed to initialize bonded device"); - - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT(primary_port >= 0, - "failed to get primary slave for bonded port (%d)", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - /* Generate test bursts of packets to transmit */ - TEST_ASSERT_EQUAL(generate_test_burst( - &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size, - "burst generation failed"); - - /* Add rx data to slave */ - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], - &gen_pkt_burst[0], burst_size); - - /* Call rx burst on bonded device */ - nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, - &rx_pkt_burst[0], MAX_PKT_BURST); - - TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n"); - - if (test_params->slave_port_ids[i] == primary_port) { - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, - "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n", - test_params->bonded_port_id, - (unsigned int)port_stats.ipackets, burst_size); - - /* Verify bonded slave devices rx count */ - for (j = 0; j < test_params->bonded_slave_count; j++) { - rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); - if (i == j) { - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, - "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", - test_params->slave_port_ids[i], - (unsigned int)port_stats.ipackets, burst_size); - } else { - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0, - "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", - test_params->slave_port_ids[i], - (unsigned int)port_stats.ipackets, 0); - } - } - } else { - for (j = 0; j < test_params->bonded_slave_count; j++) { - rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0, - "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", - test_params->slave_port_ids[i], - (unsigned int)port_stats.ipackets, 0); - } - } - - /* free mbufs */ - for (i = 0; i < burst_size; i++) - rte_pktmbuf_free(rx_pkt_burst[i]); - - /* reset bonded device stats */ - rte_eth_stats_reset(test_params->bonded_port_id); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_tlb_verify_promiscuous_enable_disable(void) -{ - int i, primary_port, promiscuous_en; - - /* Initialize bonded device with 4 slaves in transmit load balancing mode */ - TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves( - BONDING_MODE_TLB, 0, 4, 1), - "Failed to initialize bonded device"); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT(primary_port >= 0, - "failed to get primary slave for bonded port (%d)", - test_params->bonded_port_id); - - rte_eth_promiscuous_enable(test_params->bonded_port_id); - - promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(promiscuous_en, (int)1, - "Port (%d) promiscuous mode not enabled\n", - test_params->bonded_port_id); - for (i = 0; i < test_params->bonded_slave_count; i++) { - promiscuous_en = rte_eth_promiscuous_get( - test_params->slave_port_ids[i]); - if (primary_port == test_params->slave_port_ids[i]) { - TEST_ASSERT_EQUAL(promiscuous_en, (int)1, - "Port (%d) promiscuous mode not enabled\n", - test_params->bonded_port_id); - } else { - TEST_ASSERT_EQUAL(promiscuous_en, (int)0, - "Port (%d) promiscuous mode enabled\n", - test_params->bonded_port_id); - } - - } - - rte_eth_promiscuous_disable(test_params->bonded_port_id); - - promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(promiscuous_en, (int)0, - "Port (%d) promiscuous mode not disabled\n", - test_params->bonded_port_id); - - for (i = 0; i < test_params->bonded_slave_count; i++) { - promiscuous_en = rte_eth_promiscuous_get( - test_params->slave_port_ids[i]); - TEST_ASSERT_EQUAL(promiscuous_en, (int)0, - "slave port (%d) promiscuous mode not disabled\n", - test_params->slave_port_ids[i]); - } - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_tlb_verify_mac_assignment(void) -{ - struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1; - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); - rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1); - - /* Initialize bonded device with 2 slaves in active backup mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_TLB, 0, 2, 1), - "Failed to initialize bonded device"); - - /* Verify that bonded MACs is that of first slave and that the other slave - * MAC hasn't been changed */ - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected", - test_params->slave_port_ids[1]); - - /* change primary and verify that MAC addresses haven't changed */ - TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id, - test_params->slave_port_ids[1]), 0, - "Failed to set bonded port (%d) primary port to (%d)", - test_params->bonded_port_id, test_params->slave_port_ids[1]); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected", - test_params->slave_port_ids[1]); - - /* stop / start bonded device and verify that primary MAC address is - * propagated to bonded device and slaves */ - - rte_eth_dev_stop(test_params->bonded_port_id); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), - "Failed to start device"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of primary port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of primary port", - test_params->slave_port_ids[1]); - - - /* Set explicit MAC address */ - TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( - test_params->bonded_port_id, (struct ether_addr *)bonded_mac), - "failed to set MAC addres"); - - rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "bonded port (%d) mac address not set to that of bonded port", - test_params->bonded_port_id); - - rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not as expected", - test_params->slave_port_ids[0]); - - rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); - TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, - sizeof(read_mac_addr)), - "slave port (%d) mac address not set to that of bonded port", - test_params->slave_port_ids[1]); - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -static int -test_tlb_verify_slave_link_status_change_failover(void) -{ - struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; - struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; - struct rte_eth_stats port_stats; - - uint8_t slaves[RTE_MAX_ETHPORTS]; - - int i, j, burst_size, slave_count, primary_port; - - burst_size = 21; - - memset(pkt_burst, 0, sizeof(pkt_burst)); - - - - /* Initialize bonded device with 4 slaves in round robin mode */ - TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( - BONDING_MODE_TLB, 0, - TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1), - "Failed to initialize bonded device with slaves"); - - /* Verify Current Slaves Count /Active Slave Count is */ - slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, - RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, 4, - "Number of slaves (%d) is not as expected (%d).\n", - slave_count, 4); - - slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, - slaves, RTE_MAX_ETHPORTS); - TEST_ASSERT_EQUAL(slave_count, (int)4, - "Number of slaves (%d) is not as expected (%d).\n", - slave_count, 4); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0], - "Primary port not as expected"); - - /* Bring 2 slaves down and verify active slave count */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 0); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 0); - - TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 2); - - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[1], 1); - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[3], 1); - - - /* Bring primary port down, verify that active slave count is 3 and primary - * has changed */ - virtual_ethdev_simulate_link_status_interrupt( - test_params->slave_port_ids[0], 0); - - TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( - test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3, - "Number of active slaves (%d) is not as expected (%d).", - slave_count, 3); - - primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); - TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2], - "Primary port not as expected"); - rte_delay_us(500000); - /* Verify that pkts are sent on new primary slave */ - for (i = 0; i < 4; i++) { - TEST_ASSERT_EQUAL(generate_test_burst( - &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, - "generate_test_burst failed\n"); - TEST_ASSERT_EQUAL(rte_eth_tx_burst( - test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size, - "rte_eth_tx_burst failed\n"); - rte_delay_us(11000); - } - - rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); - TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0, - "(%d) port_stats.opackets not as expected\n", - test_params->slave_port_ids[0]); - - rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); - TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, - "(%d) port_stats.opackets not as expected\n", - test_params->slave_port_ids[1]); - - rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); - TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, - "(%d) port_stats.opackets not as expected\n", - test_params->slave_port_ids[2]); - - rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); - TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, - "(%d) port_stats.opackets not as expected\n", - test_params->slave_port_ids[3]); - - - /* Generate packet burst for testing */ - - for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) { - if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) != - burst_size) - return -1; - - virtual_ethdev_add_mbufs_to_rx_queue( - test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size); - } - - if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, - MAX_PKT_BURST) != burst_size) { - printf("rte_eth_rx_burst\n"); - return -1; - - } - - /* Verify bonded device rx count */ - rte_eth_stats_get(test_params->bonded_port_id, &port_stats); - TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, - "(%d) port_stats.ipackets not as expected\n", - test_params->bonded_port_id); - - /* free mbufs */ - - for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) { - for (j = 0; j < MAX_PKT_BURST; j++) { - if (pkt_burst[i][j] != NULL) { - rte_pktmbuf_free(pkt_burst[i][j]); - pkt_burst[i][j] = NULL; - } - } - } - - - /* Clean up and remove slaves from bonded device */ - return remove_slaves_and_stop_bonded_device(); -} - -#define TEST_ALB_SLAVE_COUNT 2 - -static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1}; -static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2}; -static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3}; -static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4}; - -static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0); -static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1); -static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2); -static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3); -static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4); - -static int -test_alb_change_mac_in_reply_sent(void) -{ - struct rte_mbuf *pkt; - struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; - - struct ether_hdr *eth_pkt; - struct arp_hdr *arp_pkt; - - int slave_idx, nb_pkts, pkt_idx; - int retval = 0; - - struct ether_addr bond_mac, client_mac; - struct ether_addr *slave_mac1, *slave_mac2; - - TEST_ASSERT_SUCCESS( - initialize_bonded_device_with_slaves(BONDING_MODE_ALB, - 0, TEST_ALB_SLAVE_COUNT, 1), - "Failed to initialize_bonded_device_with_slaves."); - - /* Flush tx queue */ - rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); - for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; - slave_idx++) { - nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( - test_params->slave_port_ids[slave_idx], pkts_sent, - MAX_PKT_BURST); - } - - ether_addr_copy( - rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, - &bond_mac); - - /* - * Generating four packets with different mac and ip addresses and sending - * them through the bonding port. - */ - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, - 0); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1, - ARP_OP_REPLY); - rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); - - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, - 0); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2, - ARP_OP_REPLY); - rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); - - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, - 0); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3, - ARP_OP_REPLY); - rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); - - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, - 0); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4, - ARP_OP_REPLY); - rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); - - slave_mac1 = - rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs; - slave_mac2 = - rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs; - - /* - * Checking if packets are properly distributed on bonding ports. Packets - * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1. - */ - for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { - nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( - test_params->slave_port_ids[slave_idx], pkts_sent, - MAX_PKT_BURST); - - for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { - eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - - if (slave_idx%2 == 0) { - if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) { - retval = -1; - goto test_end; - } - } else { - if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) { - retval = -1; - goto test_end; - } - } - } - } - -test_end: - retval += remove_slaves_and_stop_bonded_device(); - return retval; -} - -static int -test_alb_reply_from_client(void) -{ - struct ether_hdr *eth_pkt; - struct arp_hdr *arp_pkt; - - struct rte_mbuf *pkt; - struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; - - int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0; - int retval = 0; - - struct ether_addr bond_mac, client_mac; - struct ether_addr *slave_mac1, *slave_mac2; - - TEST_ASSERT_SUCCESS( - initialize_bonded_device_with_slaves(BONDING_MODE_ALB, - 0, TEST_ALB_SLAVE_COUNT, 1), - "Failed to initialize_bonded_device_with_slaves."); - - /* Flush tx queue */ - rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); - for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { - nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( - test_params->slave_port_ids[slave_idx], pkts_sent, - MAX_PKT_BURST); - } - - ether_addr_copy( - rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, - &bond_mac); - - /* - * Generating four packets with different mac and ip addresses and placing - * them in the rx queue to be received by the bonding driver on rx_burst. - */ - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, - 0); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host, - ARP_OP_REPLY); - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, - 1); - - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, - 0); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host, - ARP_OP_REPLY); - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, - 1); - - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, - 0); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host, - ARP_OP_REPLY); - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, - 1); - - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, - 0); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host, - ARP_OP_REPLY); - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, - 1); - - /* - * Issue rx_burst and tx_burst to force bonding driver to send update ARP - * packets to every client in alb table. - */ - rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST); - rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); - - slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs; - slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs; - - /* - * Checking if update ARP packets were properly send on slave ports. - */ - for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { - nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( - test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST); - nb_pkts_sum += nb_pkts; - - for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { - eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *); - arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); - - if (slave_idx%2 == 0) { - if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) { - retval = -1; - goto test_end; - } - } else { - if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) { - retval = -1; - goto test_end; - } - } - } - } - - /* Check if proper number of packets was send */ - if (nb_pkts_sum < 4) { - retval = -1; - goto test_end; - } - -test_end: - retval += remove_slaves_and_stop_bonded_device(); - return retval; -} - -static int -test_alb_receive_vlan_reply(void) -{ - struct ether_hdr *eth_pkt; - struct vlan_hdr *vlan_pkt; - struct arp_hdr *arp_pkt; - - struct rte_mbuf *pkt; - struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; - - int slave_idx, nb_pkts, pkt_idx; - int retval = 0; - - struct ether_addr bond_mac, client_mac; - - TEST_ASSERT_SUCCESS( - initialize_bonded_device_with_slaves(BONDING_MODE_ALB, - 0, TEST_ALB_SLAVE_COUNT, 1), - "Failed to initialize_bonded_device_with_slaves."); - - /* Flush tx queue */ - rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); - for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { - nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( - test_params->slave_port_ids[slave_idx], pkts_sent, - MAX_PKT_BURST); - } - - ether_addr_copy( - rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, - &bond_mac); - - /* - * Generating packet with double VLAN header and placing it in the rx queue. - */ - pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); - memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN); - eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0, - 0); - vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1)); - vlan_pkt->vlan_tci = rte_cpu_to_be_16(1); - vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN); - vlan_pkt = vlan_pkt+1; - vlan_pkt->vlan_tci = rte_cpu_to_be_16(2); - vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP); - arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1)); - initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host, - ARP_OP_REPLY); - virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, - 1); - - rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST); - rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); - - /* - * Checking if VLAN headers in generated ARP Update packet are correct. - */ - for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { - nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( - test_params->slave_port_ids[slave_idx], pkts_sent, - MAX_PKT_BURST); - - for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { - eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *); - vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1)); - if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) { - retval = -1; - goto test_end; - } - if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) { - retval = -1; - goto test_end; - } - vlan_pkt = vlan_pkt+1; - if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) { - retval = -1; - goto test_end; - } - if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) { - retval = -1; - goto test_end; - } - } - } - -test_end: - retval += remove_slaves_and_stop_bonded_device(); - return retval; -} - -static int -test_alb_ipv4_tx(void) -{ - int burst_size, retval, pkts_send; - struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; - - retval = 0; - - TEST_ASSERT_SUCCESS( - initialize_bonded_device_with_slaves(BONDING_MODE_ALB, - 0, TEST_ALB_SLAVE_COUNT, 1), - "Failed to initialize_bonded_device_with_slaves."); - - burst_size = 32; - - /* Generate test bursts of packets to transmit */ - if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) { - retval = -1; - goto test_end; - } - - /* - * Checking if ipv4 traffic is transmitted via TLB policy. - */ - pkts_send = rte_eth_tx_burst( - test_params->bonded_port_id, 0, pkt_burst, burst_size); - if (pkts_send != burst_size) { - retval = -1; - goto test_end; - } - -test_end: - retval += remove_slaves_and_stop_bonded_device(); - return retval; -} - -static struct unit_test_suite link_bonding_test_suite = { - .suite_name = "Link Bonding Unit Test Suite", - .setup = test_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE(test_create_bonded_device), - TEST_CASE(test_create_bonded_device_with_invalid_params), - TEST_CASE(test_add_slave_to_bonded_device), - TEST_CASE(test_add_slave_to_invalid_bonded_device), - TEST_CASE(test_remove_slave_from_bonded_device), - TEST_CASE(test_remove_slave_from_invalid_bonded_device), - TEST_CASE(test_get_slaves_from_bonded_device), - TEST_CASE(test_add_already_bonded_slave_to_bonded_device), - TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device), - TEST_CASE(test_start_bonded_device), - TEST_CASE(test_stop_bonded_device), - TEST_CASE(test_set_bonding_mode), - TEST_CASE(test_set_primary_slave), - TEST_CASE(test_set_explicit_bonded_mac), - TEST_CASE(test_set_bonded_port_initialization_mac_assignment), - TEST_CASE(test_status_interrupt), - TEST_CASE(test_adding_slave_after_bonded_device_started), - TEST_CASE(test_roundrobin_tx_burst), - TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail), - TEST_CASE(test_roundrobin_rx_burst_on_single_slave), - TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves), - TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable), - TEST_CASE(test_roundrobin_verify_mac_assignment), - TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour), - TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change), - TEST_CASE(test_activebackup_tx_burst), - TEST_CASE(test_activebackup_rx_burst), - TEST_CASE(test_activebackup_verify_promiscuous_enable_disable), - TEST_CASE(test_activebackup_verify_mac_assignment), - TEST_CASE(test_activebackup_verify_slave_link_status_change_failover), - TEST_CASE(test_balance_xmit_policy_configuration), - TEST_CASE(test_balance_l2_tx_burst), - TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr), - TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr), - TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr), - TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr), - TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr), - TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr), - TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port), - TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr), - TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr), - TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr), - TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port), - TEST_CASE(test_balance_tx_burst_slave_tx_fail), - TEST_CASE(test_balance_rx_burst), - TEST_CASE(test_balance_verify_promiscuous_enable_disable), - TEST_CASE(test_balance_verify_mac_assignment), - TEST_CASE(test_balance_verify_slave_link_status_change_behaviour), - TEST_CASE(test_tlb_tx_burst), - TEST_CASE(test_tlb_rx_burst), - TEST_CASE(test_tlb_verify_mac_assignment), - TEST_CASE(test_tlb_verify_promiscuous_enable_disable), - TEST_CASE(test_tlb_verify_slave_link_status_change_failover), - TEST_CASE(test_alb_change_mac_in_reply_sent), - TEST_CASE(test_alb_reply_from_client), - TEST_CASE(test_alb_receive_vlan_reply), - TEST_CASE(test_alb_ipv4_tx), - TEST_CASE(test_broadcast_tx_burst), - TEST_CASE(test_broadcast_tx_burst_slave_tx_fail), - TEST_CASE(test_broadcast_rx_burst), - TEST_CASE(test_broadcast_verify_promiscuous_enable_disable), - TEST_CASE(test_broadcast_verify_mac_assignment), - TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour), - TEST_CASE(test_reconfigure_bonded_device), - TEST_CASE(test_close_bonded_device), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - - -static int -test_link_bonding(void) -{ - return unit_test_suite_runner(&link_bonding_test_suite); -} - -REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding); diff --git a/app/test/test_link_bonding_mode4.c b/app/test/test_link_bonding_mode4.c deleted file mode 100644 index 53caa3e980..0000000000 --- a/app/test/test_link_bonding_mode4.c +++ /dev/null @@ -1,1602 +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "packet_burst_generator.h" - -#include "test.h" - -#define SLAVE_COUNT (4) - -#define RX_RING_SIZE 128 -#define TX_RING_SIZE 512 - -#define MBUF_CACHE_SIZE (250) -#define BURST_SIZE (32) - -#define TEST_RX_DESC_MAX (2048) -#define TEST_TX_DESC_MAX (2048) -#define MAX_PKT_BURST (32) -#define DEF_PKT_BURST (16) - -#define BONDED_DEV_NAME ("unit_test_mode4_bond_dev") - -#define SLAVE_DEV_NAME_FMT ("unit_test_mode4_slave_%d") -#define SLAVE_RX_QUEUE_FMT ("unit_test_mode4_slave_%d_rx") -#define SLAVE_TX_QUEUE_FMT ("unit_test_mode4_slave_%d_tx") - -#define INVALID_SOCKET_ID (-1) -#define INVALID_PORT_ID (0xFF) -#define INVALID_BONDING_MODE (-1) - -static const struct ether_addr slave_mac_default = { - { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } -}; - -static const struct ether_addr parnter_mac_default = { - { 0x22, 0xBB, 0xFF, 0xBB, 0x00, 0x00 } -}; - -static const struct ether_addr parnter_system = { - { 0x33, 0xFF, 0xBB, 0xFF, 0x00, 0x00 } -}; - -static const struct ether_addr slow_protocol_mac_addr = { - { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 } -}; - -struct slave_conf { - struct rte_ring *rx_queue; - struct rte_ring *tx_queue; - uint8_t port_id; - uint8_t bonded : 1; - - uint8_t lacp_parnter_state; -}; - -struct ether_vlan_hdr { - struct ether_hdr pkt_eth_hdr; - struct vlan_hdr vlan_hdr; -}; - -struct link_bonding_unittest_params { - uint8_t bonded_port_id; - struct slave_conf slave_ports[SLAVE_COUNT]; - - struct rte_mempool *mbuf_pool; -}; - -#define TEST_DEFAULT_SLAVE_COUNT RTE_DIM(test_params.slave_ports) -#define TEST_RX_SLAVE_COUT TEST_DEFAULT_SLAVE_COUNT -#define TEST_TX_SLAVE_COUNT TEST_DEFAULT_SLAVE_COUNT -#define TEST_MARKER_SLAVE_COUT TEST_DEFAULT_SLAVE_COUNT -#define TEST_EXPIRED_SLAVE_COUNT TEST_DEFAULT_SLAVE_COUNT -#define TEST_PROMISC_SLAVE_COUNT TEST_DEFAULT_SLAVE_COUNT - -static struct link_bonding_unittest_params test_params = { - .bonded_port_id = INVALID_PORT_ID, - .slave_ports = { [0 ... SLAVE_COUNT - 1] = { .port_id = INVALID_PORT_ID} }, - - .mbuf_pool = NULL, -}; - -static struct rte_eth_conf default_pmd_conf = { - .rxmode = { - .mq_mode = ETH_MQ_RX_NONE, - .max_rx_pkt_len = ETHER_MAX_LEN, - .split_hdr_size = 0, - .header_split = 0, /**< Header Split disabled */ - .hw_ip_checksum = 0, /**< IP checksum offload enabled */ - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, - .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++) - -/* Macro for iterating over every port that can be used as a slave - * in this test. - * _i variable used as an index in test_params->slave_ports - * _slave pointer to &test_params->slave_ports[_idx] - */ -#define FOR_EACH_PORT(_i, _port) \ - FOR_EACH(_i, _port, test_params.slave_ports, \ - RTE_DIM(test_params.slave_ports)) - -/* Macro for iterating over every port that can be used as a slave - * in this test and satisfy given condition. - * - * _i variable used as an index in test_params->slave_ports - * _slave pointer to &test_params->slave_ports[_idx] - * _condition condition that need to be checked - */ -#define FOR_EACH_PORT_IF(_i, _port, _condition) FOR_EACH_PORT((_i), (_port)) \ - if (!!(_condition)) - -/* Macro for iterating over every port that is currently a slave of a bonded - * device. - * _i variable used as an index in test_params->slave_ports - * _slave pointer to &test_params->slave_ports[_idx] - * */ -#define FOR_EACH_SLAVE(_i, _slave) \ - FOR_EACH_PORT_IF(_i, _slave, (_slave)->bonded != 0) - -/* - * Returns packets from slaves TX queue. - * slave slave port - * buffer for packets - * size size of buffer - * return number of packets or negative error number - */ -static int -slave_get_pkts(struct slave_conf *slave, struct rte_mbuf **buf, uint16_t size) -{ - return rte_ring_dequeue_burst(slave->tx_queue, (void **)buf, size); -} - -/* - * Injects given packets into slaves RX queue. - * slave slave port - * buffer for packets - * size number of packets to be injected - * return number of queued packets or negative error number - */ -static int -slave_put_pkts(struct slave_conf *slave, struct rte_mbuf **buf, uint16_t size) -{ - return rte_ring_enqueue_burst(slave->rx_queue, (void **)buf, size); -} - -static uint16_t -bond_rx(struct rte_mbuf **buf, uint16_t size) -{ - return rte_eth_rx_burst(test_params.bonded_port_id, 0, buf, size); -} - -static uint16_t -bond_tx(struct rte_mbuf **buf, uint16_t size) -{ - return rte_eth_tx_burst(test_params.bonded_port_id, 0, buf, size); -} - -static void -free_pkts(struct rte_mbuf **pkts, uint16_t count) -{ - uint16_t i; - - for (i = 0; i < count; i++) { - if (pkts[i] != NULL) - rte_pktmbuf_free(pkts[i]); - } -} - -static int -configure_ethdev(uint8_t port_id, uint8_t start) -{ - TEST_ASSERT(rte_eth_dev_configure(port_id, 1, 1, &default_pmd_conf) == 0, - "Failed to configure device %u", port_id); - - TEST_ASSERT(rte_eth_rx_queue_setup(port_id, 0, RX_RING_SIZE, - rte_eth_dev_socket_id(port_id), NULL, test_params.mbuf_pool) == 0, - "Failed to setup rx queue."); - - TEST_ASSERT(rte_eth_tx_queue_setup(port_id, 0, TX_RING_SIZE, - rte_eth_dev_socket_id(port_id), NULL) == 0, - "Failed to setup tx queue."); - - if (start) { - TEST_ASSERT(rte_eth_dev_start(port_id) == 0, - "Failed to start device (%d).", port_id); - } - return 0; -} - -static int -add_slave(struct slave_conf *slave, uint8_t start) -{ - struct ether_addr addr, addr_check; - - /* Some sanity check */ - RTE_VERIFY(test_params.slave_ports <= slave && - slave - test_params.slave_ports < (int)RTE_DIM(test_params.slave_ports)); - RTE_VERIFY(slave->bonded == 0); - RTE_VERIFY(slave->port_id != INVALID_PORT_ID); - - ether_addr_copy(&slave_mac_default, &addr); - addr.addr_bytes[ETHER_ADDR_LEN - 1] = slave->port_id; - - rte_eth_dev_mac_addr_remove(slave->port_id, &addr); - - TEST_ASSERT_SUCCESS(rte_eth_dev_mac_addr_add(slave->port_id, &addr, 0), - "Failed to set slave MAC address"); - - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params.bonded_port_id, - slave->port_id), - "Failed to add slave (idx=%u, id=%u) to bonding (id=%u)", - (uint8_t)(slave - test_params.slave_ports), slave->port_id, - test_params.bonded_port_id); - - slave->bonded = 1; - if (start) { - TEST_ASSERT_SUCCESS(rte_eth_dev_start(slave->port_id), - "Failed to start slave %u", slave->port_id); - } - - rte_eth_macaddr_get(slave->port_id, &addr_check); - TEST_ASSERT_EQUAL(is_same_ether_addr(&addr, &addr_check), 1, - "Slave MAC address is not as expected"); - - RTE_VERIFY(slave->lacp_parnter_state == 0); - return 0; -} - -static int -remove_slave(struct slave_conf *slave) -{ - ptrdiff_t slave_idx = slave - test_params.slave_ports; - - RTE_VERIFY(test_params.slave_ports <= slave && - slave_idx < (ptrdiff_t)RTE_DIM(test_params.slave_ports)); - - RTE_VERIFY(slave->bonded == 1); - RTE_VERIFY(slave->port_id != INVALID_PORT_ID); - - TEST_ASSERT_EQUAL(rte_ring_count(slave->rx_queue), 0, - "Slave %u tx queue not empty while removing from bonding.", - slave->port_id); - - TEST_ASSERT_EQUAL(rte_ring_count(slave->rx_queue), 0, - "Slave %u tx queue not empty while removing from bonding.", - slave->port_id); - - TEST_ASSERT_EQUAL(rte_eth_bond_slave_remove(test_params.bonded_port_id, - slave->port_id), 0, - "Failed to remove slave (idx=%u, id=%u) from bonding (id=%u)", - (uint8_t)slave_idx, slave->port_id, - test_params.bonded_port_id); - - slave->bonded = 0; - slave->lacp_parnter_state = 0; - 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 external_sm) -{ - uint8_t i; - - RTE_VERIFY(test_params.bonded_port_id != INVALID_PORT_ID); - - for (i = 0; i < slave_count; i++) { - TEST_ASSERT_SUCCESS(add_slave(&test_params.slave_ports[i], 1), - "Failed to add port %u to bonded device.\n", - test_params.slave_ports[i].port_id); - } - - /* Reset mode 4 configuration */ - rte_eth_bond_8023ad_setup(test_params.bonded_port_id, NULL); - rte_eth_promiscuous_disable(test_params.bonded_port_id); - - 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; -} - -static int -remove_slaves_and_stop_bonded_device(void) -{ - struct slave_conf *slave; - int retval; - uint8_t slaves[RTE_MAX_ETHPORTS]; - uint8_t i; - - rte_eth_dev_stop(test_params.bonded_port_id); - - FOR_EACH_SLAVE(i, slave) - remove_slave(slave); - - retval = rte_eth_bond_slaves_get(test_params.bonded_port_id, slaves, - RTE_DIM(slaves)); - - TEST_ASSERT_EQUAL(retval, 0, - "Expected bonded device %u have 0 slaves but returned %d.", - test_params.bonded_port_id, retval); - - FOR_EACH_PORT(i, slave) { - rte_eth_dev_stop(slave->port_id); - - TEST_ASSERT(slave->bonded == 0, - "Port id=%u is still marked as enslaved.", slave->port_id); - } - - return TEST_SUCCESS; -} - -static int -test_setup(void) -{ - int retval, nb_mbuf_per_pool; - char name[RTE_ETH_NAME_MAX_LEN]; - struct slave_conf *port; - const uint8_t socket_id = rte_socket_id(); - uint8_t i; - - if (test_params.mbuf_pool == NULL) { - nb_mbuf_per_pool = TEST_RX_DESC_MAX + DEF_PKT_BURST + - TEST_TX_DESC_MAX + MAX_PKT_BURST; - test_params.mbuf_pool = rte_pktmbuf_pool_create("TEST_MODE4", - nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, - RTE_MBUF_DEFAULT_BUF_SIZE, socket_id); - - TEST_ASSERT(test_params.mbuf_pool != NULL, - "rte_mempool_create failed\n"); - } - - /* Create / initialize ring eth devs. */ - FOR_EACH_PORT(i, port) { - port = &test_params.slave_ports[i]; - - if (port->rx_queue == NULL) { - retval = snprintf(name, RTE_DIM(name), SLAVE_RX_QUEUE_FMT, i); - TEST_ASSERT(retval <= (int)RTE_DIM(name) - 1, "Name too long"); - port->rx_queue = rte_ring_create(name, RX_RING_SIZE, socket_id, 0); - TEST_ASSERT(port->rx_queue != NULL, - "Failed to allocate rx ring '%s': %s", name, - rte_strerror(rte_errno)); - } - - if (port->tx_queue == NULL) { - retval = snprintf(name, RTE_DIM(name), SLAVE_TX_QUEUE_FMT, i); - TEST_ASSERT(retval <= (int)RTE_DIM(name) - 1, "Name too long"); - port->tx_queue = rte_ring_create(name, TX_RING_SIZE, socket_id, 0); - TEST_ASSERT_NOT_NULL(port->tx_queue, - "Failed to allocate tx ring '%s': %s", name, - rte_strerror(rte_errno)); - } - - if (port->port_id == INVALID_PORT_ID) { - retval = snprintf(name, RTE_DIM(name), SLAVE_DEV_NAME_FMT, i); - TEST_ASSERT(retval < (int)RTE_DIM(name) - 1, "Name too long"); - retval = rte_eth_from_rings(name, &port->rx_queue, 1, - &port->tx_queue, 1, socket_id); - TEST_ASSERT(retval >= 0, - "Failed to create ring ethdev '%s'\n", name); - - port->port_id = rte_eth_dev_count() - 1; - } - - retval = configure_ethdev(port->port_id, 1); - TEST_ASSERT_SUCCESS(retval, "Failed to configure virtual ethdev %s\n", - name); - } - - if (test_params.bonded_port_id == INVALID_PORT_ID) { - retval = rte_eth_bond_create(BONDED_DEV_NAME, BONDING_MODE_8023AD, - socket_id); - - TEST_ASSERT(retval >= 0, "Failed to create bonded ethdev %s", - BONDED_DEV_NAME); - - test_params.bonded_port_id = retval; - TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bonded_port_id, 0), - "Failed to configure bonded ethdev %s", BONDED_DEV_NAME); - } else if (rte_eth_bond_mode_get(test_params.bonded_port_id) != - BONDING_MODE_8023AD) { - TEST_ASSERT(rte_eth_bond_mode_set(test_params.bonded_port_id, - BONDING_MODE_8023AD) == 0, - "Failed to set ethdev %d to mode %d", - test_params.bonded_port_id, BONDING_MODE_8023AD); - } - - return 0; -} - -static void -testsuite_teardown(void) -{ - struct slave_conf *port; - uint8_t i; - - /* Only stop ports. - * Any cleanup/reset state is done when particular test is - * started. */ - - rte_eth_dev_stop(test_params.bonded_port_id); - - FOR_EACH_PORT(i, port) - rte_eth_dev_stop(port->port_id); -} - -/* - * Check if given LACP packet. If it is, make make replay packet to force - * COLLECTING state. - * return 0 when pkt is LACP frame, 1 if it is not slow frame, 2 if it is slow - * frame but not LACP - */ -static int -make_lacp_reply(struct slave_conf *slave, struct rte_mbuf *pkt) -{ - struct ether_hdr *hdr; - struct slow_protocol_frame *slow_hdr; - struct lacpdu *lacp; - - /* look for LACP */ - hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *); - if (hdr->ether_type != rte_cpu_to_be_16(ETHER_TYPE_SLOW)) - return 1; - - slow_hdr = rte_pktmbuf_mtod(pkt, struct slow_protocol_frame *); - /* ignore packets of other types */ - if (slow_hdr->slow_protocol.subtype != SLOW_SUBTYPE_LACP) - return 2; - - slow_hdr = rte_pktmbuf_mtod(pkt, struct slow_protocol_frame *); - - /* Change source address to partner address */ - ether_addr_copy(&parnter_mac_default, &slow_hdr->eth_hdr.s_addr); - slow_hdr->eth_hdr.s_addr.addr_bytes[ETHER_ADDR_LEN - 1] = slave->port_id; - - lacp = (struct lacpdu *) &slow_hdr->slow_protocol; - /* Save last received state */ - slave->lacp_parnter_state = lacp->actor.state; - /* Change it into LACP replay by matching parameters. */ - memcpy(&lacp->partner.port_params, &lacp->actor.port_params, - sizeof(struct port_params)); - - lacp->partner.state = lacp->actor.state; - - ether_addr_copy(&parnter_system, &lacp->actor.port_params.system); - lacp->actor.state = STATE_LACP_ACTIVE | - STATE_SYNCHRONIZATION | - STATE_AGGREGATION | - STATE_COLLECTING | - STATE_DISTRIBUTING; - - return 0; -} - -/* - * Reads packets from given slave, search for LACP packet and reply them. - * - * Receives burst of packets from slave. Looks for LACP packet. Drops - * all other packets. Prepares response LACP and sends it back. - * - * return number of LACP received and replied, -1 on error. - */ -static int -bond_handshake_reply(struct slave_conf *slave) -{ - int retval; - struct rte_mbuf *rx_buf[MAX_PKT_BURST]; - struct rte_mbuf *lacp_tx_buf[MAX_PKT_BURST]; - uint16_t lacp_tx_buf_cnt = 0, i; - - retval = slave_get_pkts(slave, rx_buf, RTE_DIM(rx_buf)); - TEST_ASSERT(retval >= 0, "Getting slave %u packets failed.", - slave->port_id); - - for (i = 0; i < (uint16_t)retval; i++) { - if (make_lacp_reply(slave, rx_buf[i]) == 0) { - /* reply with actor's LACP */ - lacp_tx_buf[lacp_tx_buf_cnt++] = rx_buf[i]; - } else - rte_pktmbuf_free(rx_buf[i]); - } - - if (lacp_tx_buf_cnt == 0) - return 0; - - retval = slave_put_pkts(slave, lacp_tx_buf, lacp_tx_buf_cnt); - if (retval <= lacp_tx_buf_cnt) { - /* retval might be negative */ - for (i = RTE_MAX(0, retval); retval < lacp_tx_buf_cnt; retval++) - rte_pktmbuf_free(lacp_tx_buf[i]); - } - - TEST_ASSERT_EQUAL(retval, lacp_tx_buf_cnt, - "Failed to equeue lacp packets into slave %u tx queue.", - slave->port_id); - - return lacp_tx_buf_cnt; -} - -/* - * Function check if given slave tx queue contains packets that make mode 4 - * handshake complete. It will drain slave queue. - * return 0 if handshake not completed, 1 if handshake was complete, - */ -static int -bond_handshake_done(struct slave_conf *slave) -{ - const uint8_t expected_state = STATE_LACP_ACTIVE | STATE_SYNCHRONIZATION | - STATE_AGGREGATION | STATE_COLLECTING | STATE_DISTRIBUTING; - - return slave->lacp_parnter_state == expected_state; -} - -static unsigned -bond_get_update_timeout_ms(void) -{ - struct rte_eth_bond_8023ad_conf conf; - - rte_eth_bond_8023ad_conf_get(test_params.bonded_port_id, &conf); - return conf.update_timeout_ms; -} - -/* - * Exchanges LACP packets with partner to achieve dynamic port configuration. - * return TEST_SUCCESS if initial handshake succeed, TEST_FAILED otherwise. - */ -static int -bond_handshake(void) -{ - struct slave_conf *slave; - struct rte_mbuf *buf[MAX_PKT_BURST]; - uint16_t nb_pkts; - uint8_t all_slaves_done, i, j; - uint8_t status[RTE_DIM(test_params.slave_ports)] = { 0 }; - const unsigned delay = bond_get_update_timeout_ms(); - - /* Exchange LACP frames */ - all_slaves_done = 0; - for (i = 0; i < 30 && all_slaves_done == 0; ++i) { - rte_delay_ms(delay); - - all_slaves_done = 1; - FOR_EACH_SLAVE(j, slave) { - /* If response already send, skip slave */ - if (status[j] != 0) - continue; - - if (bond_handshake_reply(slave) < 0) { - all_slaves_done = 0; - break; - } - - status[j] = bond_handshake_done(slave); - if (status[j] == 0) - all_slaves_done = 0; - } - - nb_pkts = bond_tx(NULL, 0); - TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets transmitted unexpectedly"); - - nb_pkts = bond_rx(buf, RTE_DIM(buf)); - free_pkts(buf, nb_pkts); - TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets received unexpectedly"); - } - /* If response didn't send - report failure */ - TEST_ASSERT_EQUAL(all_slaves_done, 1, "Bond handshake failed\n"); - - /* If flags doesn't match - report failure */ - return all_slaves_done = 1 ? TEST_SUCCESS : TEST_FAILED; -} - -#define TEST_LACP_SLAVE_COUT RTE_DIM(test_params.slave_ports) -static int -test_mode4_lacp(void) -{ - int retval; - - retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); - TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); - - /* Test LACP handshake function */ - retval = bond_handshake(); - TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); - - retval = remove_slaves_and_stop_bonded_device(); - TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); - - return TEST_SUCCESS; -} - -static int -generate_packets(struct ether_addr *src_mac, - struct ether_addr *dst_mac, uint16_t count, struct rte_mbuf **buf) -{ - uint16_t pktlen = PACKET_BURST_GEN_PKT_LEN; - uint8_t vlan_enable = 0; - uint16_t vlan_id = 0; - uint8_t ip4_type = 1; /* 0 - ipv6 */ - - uint16_t src_port = 10, dst_port = 20; - - uint32_t ip_src[4] = { [0 ... 2] = 0xDEADBEEF, [3] = IPv4(192, 168, 0, 1) }; - uint32_t ip_dst[4] = { [0 ... 2] = 0xFEEDFACE, [3] = IPv4(192, 168, 0, 2) }; - - struct ether_hdr pkt_eth_hdr; - struct udp_hdr pkt_udp_hdr; - union { - struct ipv4_hdr v4; - struct ipv6_hdr v6; - } pkt_ip_hdr; - - int retval; - - initialize_eth_header(&pkt_eth_hdr, src_mac, dst_mac, ip4_type, - vlan_enable, vlan_id); - - if (ip4_type) - initialize_ipv4_header(&pkt_ip_hdr.v4, ip_src[3], ip_dst[3], pktlen); - else - initialize_ipv6_header(&pkt_ip_hdr.v6, (uint8_t *)ip_src, - (uint8_t *)&ip_dst, pktlen); - - initialize_udp_header(&pkt_udp_hdr, src_port, dst_port, 16); - - retval = generate_packet_burst(test_params.mbuf_pool, buf, - &pkt_eth_hdr, vlan_enable, &pkt_ip_hdr, 1, &pkt_udp_hdr, - count, pktlen, 1); - - if (retval > 0 && retval != count) - free_pkts(&buf[count - retval], retval); - - TEST_ASSERT_EQUAL(retval, count, "Failed to generate %u packets", - count); - - return count; -} - -static int -generate_and_put_packets(struct slave_conf *slave, struct ether_addr *src_mac, - struct ether_addr *dst_mac, uint16_t count) -{ - struct rte_mbuf *pkts[MAX_PKT_BURST]; - int retval; - - retval = generate_packets(src_mac, dst_mac, count, pkts); - if (retval != (int)count) - return retval; - - retval = slave_put_pkts(slave, pkts, count); - if (retval > 0 && retval != count) - free_pkts(&pkts[retval], count - retval); - - TEST_ASSERT_EQUAL(retval, count, - "Failed to enqueue packets into slave %u RX queue", slave->port_id); - - return TEST_SUCCESS; -} - -static int -test_mode4_rx(void) -{ - struct slave_conf *slave; - uint16_t i, j; - - uint16_t expected_pkts_cnt; - struct rte_mbuf *pkts[MAX_PKT_BURST]; - int retval; - unsigned delay; - - struct ether_hdr *hdr; - - struct ether_addr src_mac = { { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } }; - struct ether_addr dst_mac; - struct ether_addr bonded_mac; - - retval = initialize_bonded_device_with_slaves(TEST_PROMISC_SLAVE_COUNT, - 0); - TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); - - retval = bond_handshake(); - TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); - - rte_eth_macaddr_get(test_params.bonded_port_id, &bonded_mac); - ether_addr_copy(&bonded_mac, &dst_mac); - - /* Assert that dst address is not bonding address. Do not set the - * least significant bit of the zero byte as this would create a - * multicast address. - */ - dst_mac.addr_bytes[0] += 2; - - /* First try with promiscuous mode enabled. - * Add 2 packets to each slave. First with bonding MAC address, second with - * different. Check if we received all of them. */ - rte_eth_promiscuous_enable(test_params.bonded_port_id); - - expected_pkts_cnt = 0; - FOR_EACH_SLAVE(i, slave) { - retval = generate_and_put_packets(slave, &src_mac, &bonded_mac, 1); - TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to slave %u", - slave->port_id); - - retval = generate_and_put_packets(slave, &src_mac, &dst_mac, 1); - TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to slave %u", - slave->port_id); - - /* Expect 2 packets per slave */ - expected_pkts_cnt += 2; - } - - retval = rte_eth_rx_burst(test_params.bonded_port_id, 0, pkts, - RTE_DIM(pkts)); - - if (retval == expected_pkts_cnt) { - int cnt[2] = { 0, 0 }; - - for (i = 0; i < expected_pkts_cnt; i++) { - hdr = rte_pktmbuf_mtod(pkts[i], struct ether_hdr *); - cnt[is_same_ether_addr(&hdr->d_addr, &bonded_mac)]++; - } - - free_pkts(pkts, expected_pkts_cnt); - - /* For division by 2 expected_pkts_cnt must be even */ - RTE_VERIFY((expected_pkts_cnt & 1) == 0); - TEST_ASSERT(cnt[0] == expected_pkts_cnt / 2 && - cnt[1] == expected_pkts_cnt / 2, - "Expected %u packets with the same MAC and %u with different but " - "got %u with the same and %u with diffrent MAC", - expected_pkts_cnt / 2, expected_pkts_cnt / 2, cnt[1], cnt[0]); - } else if (retval > 0) - free_pkts(pkts, retval); - - TEST_ASSERT_EQUAL(retval, expected_pkts_cnt, - "Expected %u packets but received only %d", expected_pkts_cnt, retval); - - /* Now, disable promiscuous mode. When promiscuous mode is disabled we - * expect to receive only packets that are directed to bonding port. */ - rte_eth_promiscuous_disable(test_params.bonded_port_id); - - expected_pkts_cnt = 0; - FOR_EACH_SLAVE(i, slave) { - retval = generate_and_put_packets(slave, &src_mac, &bonded_mac, 1); - TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to slave %u", - slave->port_id); - - retval = generate_and_put_packets(slave, &src_mac, &dst_mac, 1); - TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to slave %u", - slave->port_id); - - /* Expect only one packet per slave */ - expected_pkts_cnt += 1; - } - - retval = rte_eth_rx_burst(test_params.bonded_port_id, 0, pkts, - RTE_DIM(pkts)); - - if (retval == expected_pkts_cnt) { - int eq_cnt = 0; - - for (i = 0; i < expected_pkts_cnt; i++) { - hdr = rte_pktmbuf_mtod(pkts[i], struct ether_hdr *); - eq_cnt += is_same_ether_addr(&hdr->d_addr, &bonded_mac); - } - - free_pkts(pkts, expected_pkts_cnt); - TEST_ASSERT_EQUAL(eq_cnt, expected_pkts_cnt, "Packet address mismatch"); - } else if (retval > 0) - free_pkts(pkts, retval); - - TEST_ASSERT_EQUAL(retval, expected_pkts_cnt, - "Expected %u packets but received only %d", expected_pkts_cnt, retval); - - /* Link down test: simulate link down for first slave. */ - delay = bond_get_update_timeout_ms(); - - uint8_t slave_down_id = INVALID_PORT_ID; - - /* Find first slave and make link down on it*/ - FOR_EACH_SLAVE(i, slave) { - rte_eth_dev_set_link_down(slave->port_id); - slave_down_id = slave->port_id; - break; - } - - RTE_VERIFY(slave_down_id != INVALID_PORT_ID); - - /* Give some time to rearrange bonding */ - for (i = 0; i < 3; i++) { - rte_delay_ms(delay); - bond_handshake(); - } - - TEST_ASSERT_SUCCESS(bond_handshake(), "Handshake after link down failed"); - - /* Put packet to each slave */ - FOR_EACH_SLAVE(i, slave) { - void *pkt = NULL; - - dst_mac.addr_bytes[ETHER_ADDR_LEN - 1] = slave->port_id; - retval = generate_and_put_packets(slave, &src_mac, &dst_mac, 1); - TEST_ASSERT_SUCCESS(retval, "Failed to generate test packet burst."); - - src_mac.addr_bytes[ETHER_ADDR_LEN - 1] = slave->port_id; - retval = generate_and_put_packets(slave, &src_mac, &bonded_mac, 1); - TEST_ASSERT_SUCCESS(retval, "Failed to generate test packet burst."); - - retval = bond_rx(pkts, RTE_DIM(pkts)); - - /* Clean anything */ - if (retval > 0) - free_pkts(pkts, retval); - - while (rte_ring_dequeue(slave->rx_queue, (void **)&pkt) == 0) - rte_pktmbuf_free(pkt); - - if (slave_down_id == slave->port_id) - TEST_ASSERT_EQUAL(retval, 0, "Packets received unexpectedly."); - else - TEST_ASSERT_NOT_EQUAL(retval, 0, - "Expected to receive some packets on slave %u.", - slave->port_id); - rte_eth_dev_start(slave->port_id); - - for (j = 0; j < 5; j++) { - TEST_ASSERT(bond_handshake_reply(slave) >= 0, - "Handshake after link up"); - - if (bond_handshake_done(slave) == 1) - break; - } - - TEST_ASSERT(j < 5, "Failed to agregate slave after link up"); - } - - remove_slaves_and_stop_bonded_device(); - return TEST_SUCCESS; -} - -static int -test_mode4_tx_burst(void) -{ - struct slave_conf *slave; - uint16_t i, j; - - uint16_t exp_pkts_cnt, pkts_cnt = 0; - struct rte_mbuf *pkts[MAX_PKT_BURST]; - int retval; - unsigned delay; - - 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, 0); - TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); - - retval = bond_handshake(); - TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); - - rte_eth_macaddr_get(test_params.bonded_port_id, &bonded_mac); - - /* Prepare burst */ - for (pkts_cnt = 0; pkts_cnt < RTE_DIM(pkts); pkts_cnt++) { - dst_mac.addr_bytes[ETHER_ADDR_LEN - 1] = pkts_cnt; - retval = generate_packets(&bonded_mac, &dst_mac, 1, &pkts[pkts_cnt]); - - if (retval != 1) - free_pkts(pkts, pkts_cnt); - - TEST_ASSERT_EQUAL(retval, 1, "Failed to generate packet %u", pkts_cnt); - } - exp_pkts_cnt = pkts_cnt; - - /* Transmit packets on bonded device */ - retval = bond_tx(pkts, pkts_cnt); - if (retval > 0 && retval < pkts_cnt) - free_pkts(&pkts[retval], pkts_cnt - retval); - - TEST_ASSERT_EQUAL(retval, pkts_cnt, "TX on bonded device failed"); - - /* Check if packets were transmitted properly. Every slave should have - * at least one packet, and sum must match. Under normal operation - * there should be no LACP nor MARKER frames. */ - pkts_cnt = 0; - FOR_EACH_SLAVE(i, slave) { - uint16_t normal_cnt, slow_cnt; - - retval = slave_get_pkts(slave, pkts, RTE_DIM(pkts)); - normal_cnt = 0; - slow_cnt = 0; - - for (j = 0; j < retval; j++) { - if (make_lacp_reply(slave, pkts[j]) == 1) - normal_cnt++; - else - slow_cnt++; - } - - free_pkts(pkts, normal_cnt + slow_cnt); - TEST_ASSERT_EQUAL(slow_cnt, 0, - "slave %u unexpectedly transmitted %d SLOW packets", slave->port_id, - slow_cnt); - - TEST_ASSERT_NOT_EQUAL(normal_cnt, 0, - "slave %u did not transmitted any packets", slave->port_id); - - pkts_cnt += normal_cnt; - } - - TEST_ASSERT_EQUAL(exp_pkts_cnt, pkts_cnt, - "Expected %u packets but transmitted only %d", exp_pkts_cnt, pkts_cnt); - - /* Link down test: - * simulate link down for first slave. */ - delay = bond_get_update_timeout_ms(); - - uint8_t slave_down_id = INVALID_PORT_ID; - - FOR_EACH_SLAVE(i, slave) { - rte_eth_dev_set_link_down(slave->port_id); - slave_down_id = slave->port_id; - break; - } - - RTE_VERIFY(slave_down_id != INVALID_PORT_ID); - - /* Give some time to rearrange bonding. */ - for (i = 0; i < 3; i++) { - bond_handshake(); - rte_delay_ms(delay); - } - - TEST_ASSERT_SUCCESS(bond_handshake(), "Handshake after link down failed"); - - /* Prepare burst. */ - for (pkts_cnt = 0; pkts_cnt < RTE_DIM(pkts); pkts_cnt++) { - dst_mac.addr_bytes[ETHER_ADDR_LEN - 1] = pkts_cnt; - retval = generate_packets(&bonded_mac, &dst_mac, 1, &pkts[pkts_cnt]); - - if (retval != 1) - free_pkts(pkts, pkts_cnt); - - TEST_ASSERT_EQUAL(retval, 1, "Failed to generate test packet %u", - pkts_cnt); - } - exp_pkts_cnt = pkts_cnt; - - /* Transmit packets on bonded device. */ - retval = bond_tx(pkts, pkts_cnt); - if (retval > 0 && retval < pkts_cnt) - free_pkts(&pkts[retval], pkts_cnt - retval); - - TEST_ASSERT_EQUAL(retval, pkts_cnt, "TX on bonded device failed"); - - /* Check if packets was transmitted properly. Every slave should have - * at least one packet, and sum must match. Under normal operation - * there should be no LACP nor MARKER frames. */ - pkts_cnt = 0; - FOR_EACH_SLAVE(i, slave) { - uint16_t normal_cnt, slow_cnt; - - retval = slave_get_pkts(slave, pkts, RTE_DIM(pkts)); - normal_cnt = 0; - slow_cnt = 0; - - for (j = 0; j < retval; j++) { - if (make_lacp_reply(slave, pkts[j]) == 1) - normal_cnt++; - else - slow_cnt++; - } - - free_pkts(pkts, normal_cnt + slow_cnt); - - if (slave_down_id == slave->port_id) { - TEST_ASSERT_EQUAL(normal_cnt + slow_cnt, 0, - "slave %u enexpectedly transmitted %u packets", - normal_cnt + slow_cnt, slave->port_id); - } else { - TEST_ASSERT_EQUAL(slow_cnt, 0, - "slave %u unexpectedly transmitted %d SLOW packets", - slave->port_id, slow_cnt); - - TEST_ASSERT_NOT_EQUAL(normal_cnt, 0, - "slave %u did not transmitted any packets", slave->port_id); - } - - pkts_cnt += normal_cnt; - } - - TEST_ASSERT_EQUAL(exp_pkts_cnt, pkts_cnt, - "Expected %u packets but transmitted only %d", exp_pkts_cnt, pkts_cnt); - - return remove_slaves_and_stop_bonded_device(); -} - -static void -init_marker(struct rte_mbuf *pkt, struct slave_conf *slave) -{ - struct marker_header *marker_hdr = rte_pktmbuf_mtod(pkt, - struct marker_header *); - - /* Copy multicast destination address */ - ether_addr_copy(&slow_protocol_mac_addr, &marker_hdr->eth_hdr.d_addr); - - /* Init source address */ - ether_addr_copy(&parnter_mac_default, &marker_hdr->eth_hdr.s_addr); - marker_hdr->eth_hdr.s_addr.addr_bytes[ETHER_ADDR_LEN-1] = slave->port_id; - - marker_hdr->eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_SLOW); - - marker_hdr->marker.subtype = SLOW_SUBTYPE_MARKER; - marker_hdr->marker.version_number = 1; - marker_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_INFO; - marker_hdr->marker.info_length = - offsetof(struct marker, reserved_90) - - offsetof(struct marker, requester_port); - RTE_VERIFY(marker_hdr->marker.info_length == 16); - marker_hdr->marker.requester_port = slave->port_id + 1; - marker_hdr->marker.tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION; - marker_hdr->marker.terminator_length = 0; -} - -static int -test_mode4_marker(void) -{ - struct slave_conf *slave; - struct rte_mbuf *pkts[MAX_PKT_BURST]; - struct rte_mbuf *marker_pkt; - struct marker_header *marker_hdr; - - unsigned delay; - int retval; - uint16_t nb_pkts; - 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, - 0); - TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); - - /* Test LACP handshake function */ - retval = bond_handshake(); - TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); - - delay = bond_get_update_timeout_ms(); - FOR_EACH_SLAVE(i, slave) { - marker_pkt = rte_pktmbuf_alloc(test_params.mbuf_pool); - TEST_ASSERT_NOT_NULL(marker_pkt, "Failed to allocate marker packet"); - init_marker(marker_pkt, slave); - - retval = slave_put_pkts(slave, &marker_pkt, 1); - if (retval != 1) - rte_pktmbuf_free(marker_pkt); - - TEST_ASSERT_EQUAL(retval, 1, - "Failed to send marker packet to slave %u", slave->port_id); - - for (j = 0; j < 20; ++j) { - rte_delay_ms(delay); - retval = rte_eth_rx_burst(test_params.bonded_port_id, 0, pkts, - RTE_DIM(pkts)); - - if (retval > 0) - free_pkts(pkts, retval); - - TEST_ASSERT_EQUAL(retval, 0, "Received packets unexpectedly"); - - retval = rte_eth_tx_burst(test_params.bonded_port_id, 0, NULL, 0); - TEST_ASSERT_EQUAL(retval, 0, - "Requested TX of 0 packets but %d transmitted", retval); - - /* Check if LACP packet was send by state machines - First and only packet must be a maker response */ - retval = slave_get_pkts(slave, pkts, MAX_PKT_BURST); - if (retval == 0) - continue; - if (retval > 1) - free_pkts(pkts, retval); - - TEST_ASSERT_EQUAL(retval, 1, "failed to get slave packets"); - nb_pkts = retval; - - marker_hdr = rte_pktmbuf_mtod(pkts[0], struct marker_header *); - /* Check if it's slow packet*/ - if (marker_hdr->eth_hdr.ether_type != ethtype_slow_be) - retval = -1; - /* Check if it's marker packet */ - else if (marker_hdr->marker.subtype != SLOW_SUBTYPE_MARKER) - retval = -2; - else if (marker_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_RESP) - retval = -3; - - free_pkts(pkts, nb_pkts); - - TEST_ASSERT_NOT_EQUAL(retval, -1, "Unexpected protocol type"); - TEST_ASSERT_NOT_EQUAL(retval, -2, "Unexpected sub protocol type"); - TEST_ASSERT_NOT_EQUAL(retval, -3, "Unexpected marker type"); - break; - } - - TEST_ASSERT(j < 20, "Marker response not found"); - } - - retval = remove_slaves_and_stop_bonded_device(); - TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); - - return TEST_SUCCESS; -} - -static int -test_mode4_expired(void) -{ - struct slave_conf *slave, *exp_slave = NULL; - struct rte_mbuf *pkts[MAX_PKT_BURST]; - int retval; - uint32_t old_delay; - - uint8_t i; - uint16_t j; - - struct rte_eth_bond_8023ad_conf conf; - - 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; - conf.slow_periodic_ms = 600; - conf.short_timeout_ms = 300; - conf.long_timeout_ms = 900; - conf.aggregate_wait_timeout_ms = 200; - conf.tx_period_ms = 100; - old_delay = conf.update_timeout_ms; - conf.update_timeout_ms = 10; - rte_eth_bond_8023ad_setup(test_params.bonded_port_id, &conf); - - /* Wait for new settings to be applied. */ - for (i = 0; i < old_delay/conf.update_timeout_ms * 2; i++) { - FOR_EACH_SLAVE(j, slave) - bond_handshake_reply(slave); - - rte_delay_ms(conf.update_timeout_ms); - } - - retval = bond_handshake(); - TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); - - /* Find first slave */ - FOR_EACH_SLAVE(i, slave) { - exp_slave = slave; - break; - } - - RTE_VERIFY(exp_slave != NULL); - - /* When one of partners do not send or respond to LACP frame in - * conf.long_timeout_ms time, internal state machines should detect this - * and transit to expired state. */ - for (j = 0; j < conf.long_timeout_ms/conf.update_timeout_ms + 2; j++) { - rte_delay_ms(conf.update_timeout_ms); - - retval = bond_tx(NULL, 0); - TEST_ASSERT_EQUAL(retval, 0, "Unexpectedly received %d packets", - retval); - - FOR_EACH_SLAVE(i, slave) { - retval = bond_handshake_reply(slave); - TEST_ASSERT(retval >= 0, "Handshake failed"); - - /* Remove replay for slave that supose to be expired. */ - if (slave == exp_slave) { - while (rte_ring_count(slave->rx_queue) > 0) { - void *pkt = NULL; - - rte_ring_dequeue(slave->rx_queue, &pkt); - rte_pktmbuf_free(pkt); - } - } - } - - retval = bond_rx(pkts, RTE_DIM(pkts)); - if (retval > 0) - free_pkts(pkts, retval); - - TEST_ASSERT_EQUAL(retval, 0, "Unexpectedly received %d packets", - retval); - } - - /* After test only expected slave should be in EXPIRED state */ - FOR_EACH_SLAVE(i, slave) { - if (slave == exp_slave) - TEST_ASSERT(slave->lacp_parnter_state & STATE_EXPIRED, - "Slave %u should be in expired.", slave->port_id); - else - TEST_ASSERT_EQUAL(bond_handshake_done(slave), 1, - "Slave %u should be operational.", slave->port_id); - } - - retval = remove_slaves_and_stop_bonded_device(); - TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); - - return TEST_SUCCESS; -} - -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; - uint8_t i, env_state; - uint8_t slaves[RTE_DIM(test_params.slave_ports)]; - int slaves_count; - - env_state = 0; - FOR_EACH_PORT(i, port) { - if (rte_ring_count(port->rx_queue) != 0) - env_state |= 0x01; - - if (rte_ring_count(port->tx_queue) != 0) - env_state |= 0x02; - - if (port->bonded != 0) - env_state |= 0x04; - - if (port->lacp_parnter_state != 0) - env_state |= 0x08; - - if (env_state != 0) - break; - } - - slaves_count = rte_eth_bond_slaves_get(test_params.bonded_port_id, - slaves, RTE_DIM(slaves)); - - if (slaves_count != 0) - env_state |= 0x10; - - TEST_ASSERT_EQUAL(env_state, 0, - "Environment not clean (port %u):%s%s%s%s%s", - port->port_id, - env_state & 0x01 ? " slave rx queue not clean" : "", - env_state & 0x02 ? " slave tx queue not clean" : "", - env_state & 0x04 ? " port marked as enslaved" : "", - env_state & 0x80 ? " slave state is not reset" : "", - env_state & 0x10 ? " slave count not equal 0" : "."); - - - return TEST_SUCCESS; -} - -static int -test_mode4_executor(int (*test_func)(void)) -{ - struct slave_conf *port; - int test_result; - uint8_t i; - void *pkt; - - /* Check if environment is clean. Fail to launch a test if there was - * a critical error before that prevented to reset environment. */ - TEST_ASSERT_SUCCESS(check_environment(), - "Refusing to launch test in dirty environment."); - - RTE_VERIFY(test_func != NULL); - test_result = (*test_func)(); - - /* If test succeed check if environment wast left in good condition. */ - if (test_result == TEST_SUCCESS) - test_result = check_environment(); - - /* Reset environment in case test failed to do that. */ - if (test_result != TEST_SUCCESS) { - TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(), - "Failed to stop bonded device"); - - FOR_EACH_PORT(i, port) { - while (rte_ring_count(port->rx_queue) != 0) { - if (rte_ring_dequeue(port->rx_queue, &pkt) == 0) - rte_pktmbuf_free(pkt); - } - - while (rte_ring_count(port->tx_queue) != 0) { - if (rte_ring_dequeue(port->tx_queue, &pkt) == 0) - rte_pktmbuf_free(pkt); - } - } - } - - return test_result; -} - -static int -test_mode4_lacp_wrapper(void) -{ - return test_mode4_executor(&test_mode4_lacp); -} - -static int -test_mode4_marker_wrapper(void) -{ - return test_mode4_executor(&test_mode4_marker); -} - -static int -test_mode4_rx_wrapper(void) -{ - return test_mode4_executor(&test_mode4_rx); -} - -static int -test_mode4_tx_burst_wrapper(void) -{ - return test_mode4_executor(&test_mode4_tx_burst); -} - -static int -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, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_NAMED("test_mode4_lacp", test_mode4_lacp_wrapper), - TEST_CASE_NAMED("test_mode4_rx", test_mode4_rx_wrapper), - 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 */ - } -}; - -static int -test_link_bonding_mode4(void) -{ - return unit_test_suite_runner(&link_bonding_mode4_test_suite); -} - -REGISTER_TEST_COMMAND(link_bonding_mode4_autotest, test_link_bonding_mode4); diff --git a/app/test/test_link_bonding_rssconf.c b/app/test/test_link_bonding_rssconf.c deleted file mode 100644 index 34f1c166ba..0000000000 --- a/app/test/test_link_bonding_rssconf.c +++ /dev/null @@ -1,673 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "test.h" - -#define SLAVE_COUNT (4) - -#define RXTX_RING_SIZE 1024 -#define RXTX_QUEUE_COUNT 4 - -#define BONDED_DEV_NAME ("rssconf_bond_dev") - -#define SLAVE_DEV_NAME_FMT ("rssconf_slave%d") -#define SLAVE_RXTX_QUEUE_FMT ("rssconf_slave%d_q%d") - -#define NUM_MBUFS 8191 -#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) -#define MBUF_CACHE_SIZE 250 -#define BURST_SIZE 32 - -#define INVALID_SOCKET_ID (-1) -#define INVALID_PORT_ID (0xFF) -#define INVALID_BONDING_MODE (-1) - -struct slave_conf { - uint8_t port_id; - struct rte_eth_dev_info dev_info; - - struct rte_eth_rss_conf rss_conf; - uint8_t rss_key[40]; - struct rte_eth_rss_reta_entry64 reta_conf[512 / RTE_RETA_GROUP_SIZE]; - - uint8_t is_slave; - struct rte_ring *rxtx_queue[RXTX_QUEUE_COUNT]; -}; - -struct link_bonding_rssconf_unittest_params { - uint8_t bond_port_id; - struct rte_eth_dev_info bond_dev_info; - struct rte_eth_rss_reta_entry64 bond_reta_conf[512 / RTE_RETA_GROUP_SIZE]; - struct slave_conf slave_ports[SLAVE_COUNT]; - - struct rte_mempool *mbuf_pool; -}; - -static struct link_bonding_rssconf_unittest_params test_params = { - .bond_port_id = INVALID_PORT_ID, - .slave_ports = { - [0 ... SLAVE_COUNT - 1] = { .port_id = INVALID_PORT_ID, .is_slave = 0} - }, - .mbuf_pool = NULL, -}; - -/** - * Default port configuration with RSS turned off - */ -static struct rte_eth_conf default_pmd_conf = { - .rxmode = { - .mq_mode = ETH_MQ_RX_NONE, - .max_rx_pkt_len = ETHER_MAX_LEN, - .split_hdr_size = 0, - .header_split = 0, /**< Header Split disabled */ - .hw_ip_checksum = 0, /**< IP checksum offload enabled */ - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, - .lpbk_mode = 0, -}; - -static struct rte_eth_conf rss_pmd_conf = { - .rxmode = { - .mq_mode = ETH_MQ_RX_RSS, - .max_rx_pkt_len = ETHER_MAX_LEN, - .split_hdr_size = 0, - .header_split = 0, /**< Header Split disabled */ - .hw_ip_checksum = 0, /**< IP checksum offload enabled */ - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, - .rx_adv_conf = { - .rss_conf = { - .rss_key = NULL, - .rss_hf = ETH_RSS_IPV6, - }, - }, - .lpbk_mode = 0, -}; - -#define FOR_EACH(_i, _item, _array, _size) \ - for (_i = 0, _item = &_array[0]; _i < _size && (_item = &_array[_i]); _i++) - -/* Macro for iterating over every port that can be used as a slave - * in this test. - * _i variable used as an index in test_params->slave_ports - * _slave pointer to &test_params->slave_ports[_idx] - */ -#define FOR_EACH_PORT(_i, _port) \ - FOR_EACH(_i, _port, test_params.slave_ports, \ - RTE_DIM(test_params.slave_ports)) - -static int -configure_ethdev(uint8_t port_id, struct rte_eth_conf *eth_conf, uint8_t start) -{ - int rxq, txq; - - TEST_ASSERT(rte_eth_dev_configure(port_id, RXTX_QUEUE_COUNT, - RXTX_QUEUE_COUNT, eth_conf) == 0, "Failed to configure device %u", - port_id); - - for (rxq = 0; rxq < RXTX_QUEUE_COUNT; rxq++) { - TEST_ASSERT(rte_eth_rx_queue_setup(port_id, rxq, RXTX_RING_SIZE, - rte_eth_dev_socket_id(port_id), NULL, - test_params.mbuf_pool) == 0, "Failed to setup rx queue."); - } - - for (txq = 0; txq < RXTX_QUEUE_COUNT; txq++) { - TEST_ASSERT(rte_eth_tx_queue_setup(port_id, txq, RXTX_RING_SIZE, - rte_eth_dev_socket_id(port_id), NULL) == 0, - "Failed to setup tx queue."); - } - - if (start) { - TEST_ASSERT(rte_eth_dev_start(port_id) == 0, - "Failed to start device (%d).", port_id); - } - - return 0; -} - -/** - * Remove all slaves from bonding - */ -static int -remove_slaves(void) -{ - unsigned n; - struct slave_conf *port; - - FOR_EACH_PORT(n, port) { - port = &test_params.slave_ports[n]; - if (port->is_slave) { - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove( - test_params.bond_port_id, port->port_id), - "Cannot remove slave %d from bonding", port->port_id); - port->is_slave = 0; - } - } - - return 0; -} - -static int -remove_slaves_and_stop_bonded_device(void) -{ - TEST_ASSERT_SUCCESS(remove_slaves(), "Removing slaves"); - rte_eth_dev_stop(test_params.bond_port_id); - return TEST_SUCCESS; -} - -/** - * Add all slaves to bonding - */ -static int -bond_slaves(void) -{ - unsigned n; - struct slave_conf *port; - - FOR_EACH_PORT(n, port) { - port = &test_params.slave_ports[n]; - if (!port->is_slave) { - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params.bond_port_id, - port->port_id), "Cannot attach slave %d to the bonding", - port->port_id); - port->is_slave = 1; - } - } - - return 0; -} - -/** - * Set all RETA values in port_id to value - */ -static int -reta_set(uint8_t port_id, uint8_t value, int reta_size) -{ - struct rte_eth_rss_reta_entry64 reta_conf[512/RTE_RETA_GROUP_SIZE]; - int i, j; - - for (i = 0; i < reta_size / RTE_RETA_GROUP_SIZE; i++) { - /* select all fields to set */ - reta_conf[i].mask = ~0LL; - for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) - reta_conf[i].reta[j] = value; - } - - return rte_eth_dev_rss_reta_update(port_id, reta_conf, reta_size); -} - -/** - * Check if slaves RETA is synchronized with bonding port. Returns 1 if slave - * port is synced with bonding port. - */ -static int -reta_check_synced(struct slave_conf *port) -{ - unsigned i; - - for (i = 0; i < test_params.bond_dev_info.reta_size; - i++) { - - int index = i / RTE_RETA_GROUP_SIZE; - int shift = i % RTE_RETA_GROUP_SIZE; - - if (port->reta_conf[index].reta[shift] != - test_params.bond_reta_conf[index].reta[shift]) - return 0; - - } - - return 1; -} - -/** - * Fetch bonding ports RETA - */ -static int -bond_reta_fetch(void) { - unsigned j; - - for (j = 0; j < test_params.bond_dev_info.reta_size / RTE_RETA_GROUP_SIZE; - j++) - test_params.bond_reta_conf[j].mask = ~0LL; - - TEST_ASSERT_SUCCESS(rte_eth_dev_rss_reta_query(test_params.bond_port_id, - test_params.bond_reta_conf, test_params.bond_dev_info.reta_size), - "Cannot take bonding ports RSS configuration"); - return 0; -} - -/** - * Fetch slaves RETA - */ -static int -slave_reta_fetch(struct slave_conf *port) { - unsigned j; - - for (j = 0; j < port->dev_info.reta_size / RTE_RETA_GROUP_SIZE; j++) - port->reta_conf[j].mask = ~0LL; - - TEST_ASSERT_SUCCESS(rte_eth_dev_rss_reta_query(port->port_id, - port->reta_conf, port->dev_info.reta_size), - "Cannot take bonding ports RSS configuration"); - return 0; -} - -/** - * Remove and add slave to check if slaves configuration is synced with - * the bonding ports values after adding new slave. - */ -static int -slave_remove_and_add(void) -{ - struct slave_conf *port = &(test_params.slave_ports[0]); - - /* 1. Remove first slave from bonding */ - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params.bond_port_id, - port->port_id), "Cannot remove slave #d from bonding"); - - /* 2. Change removed (ex-)slave and bonding configuration to different - * values - */ - reta_set(test_params.bond_port_id, 1, test_params.bond_dev_info.reta_size); - bond_reta_fetch(); - - reta_set(port->port_id, 2, port->dev_info.reta_size); - slave_reta_fetch(port); - - TEST_ASSERT(reta_check_synced(port) == 0, - "Removed slave didn't should be synchronized with bonding port"); - - /* 3. Add (ex-)slave and check if configuration changed*/ - TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params.bond_port_id, - port->port_id), "Cannot add slave"); - - bond_reta_fetch(); - slave_reta_fetch(port); - - return reta_check_synced(port); -} - -/** - * Test configuration propagation over slaves. - */ -static int -test_propagate(void) -{ - unsigned i; - uint8_t n; - struct slave_conf *port; - uint8_t bond_rss_key[40]; - struct rte_eth_rss_conf bond_rss_conf; - - int retval = 0; - uint64_t rss_hf = 0; - uint64_t default_rss_hf = 0; - - rte_eth_dev_info_get(test_params.bond_port_id, &test_params.bond_dev_info); - - /* - * Test hash function propagation - */ - for (i = 0; i < sizeof(test_params.bond_dev_info.flow_type_rss_offloads)*8; - i++) { - - rss_hf = test_params.bond_dev_info.flow_type_rss_offloads & (1<port_id, - &port->rss_conf); - TEST_ASSERT_SUCCESS(retval, - "Cannot take slaves RSS configuration"); - - TEST_ASSERT(port->rss_conf.rss_hf == rss_hf, - "Hash function not propagated for slave %d", - port->port_id); - } - - default_rss_hf = rss_hf; - } - - } - - /* - * Test key propagation - */ - for (i = 1; i < 10; i++) { - - /* Set all keys to zero */ - FOR_EACH_PORT(n, port) { - port = &test_params.slave_ports[n]; - memset(port->rss_conf.rss_key, 0, 40); - retval = rte_eth_dev_rss_hash_update(port->port_id, - &port->rss_conf); - TEST_ASSERT_SUCCESS(retval, "Cannot set slaves RSS keys"); - } - - memset(bond_rss_key, i, sizeof(bond_rss_key)); - bond_rss_conf.rss_hf = default_rss_hf, - bond_rss_conf.rss_key = bond_rss_key; - bond_rss_conf.rss_key_len = 40; - - retval = rte_eth_dev_rss_hash_update(test_params.bond_port_id, - &bond_rss_conf); - TEST_ASSERT_SUCCESS(retval, "Cannot set bonded port RSS keys"); - - FOR_EACH_PORT(n, port) { - port = &test_params.slave_ports[n]; - - retval = rte_eth_dev_rss_hash_conf_get(port->port_id, - &(port->rss_conf)); - - TEST_ASSERT_SUCCESS(retval, - "Cannot take slaves RSS configuration"); - - /* compare keys */ - retval = memcmp(port->rss_conf.rss_key, bond_rss_key, - sizeof(bond_rss_key)); - TEST_ASSERT(retval == 0, "Key value not propagated for slave %d", - port->port_id); - } - } - - /* - * Test RETA propagation - */ - for (i = 0; i < RXTX_QUEUE_COUNT; i++) { - - /* Set all keys to zero */ - FOR_EACH_PORT(n, port) { - port = &test_params.slave_ports[n]; - retval = reta_set(port->port_id, (i + 1) % RXTX_QUEUE_COUNT, - port->dev_info.reta_size); - TEST_ASSERT_SUCCESS(retval, "Cannot set slaves RETA"); - } - - TEST_ASSERT_SUCCESS(reta_set(test_params.bond_port_id, - i % RXTX_QUEUE_COUNT, test_params.bond_dev_info.reta_size), - "Cannot set bonded port RETA"); - - bond_reta_fetch(); - - FOR_EACH_PORT(n, port) { - port = &test_params.slave_ports[n]; - - slave_reta_fetch(port); - TEST_ASSERT(reta_check_synced(port) == 1, "RETAs inconsistent"); - } - } - - return TEST_SUCCESS; -} - -/** - * Test propagation logic, when RX_RSS mq_mode is turned on for bonding port - */ -static int -test_rss(void) -{ - /** - * Configure bonding port in RSS mq mode - */ - TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id, - &rss_pmd_conf, 0), "Failed to configure bonding device\n"); - - rte_eth_dev_info_get(test_params.bond_port_id, &test_params.bond_dev_info); - - TEST_ASSERT_SUCCESS(bond_slaves(), "Bonding slaves failed"); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bond_port_id), - "Failed to start bonding port (%d).", test_params.bond_port_id); - - TEST_ASSERT_SUCCESS(test_propagate(), "Propagation test failed"); - - TEST_ASSERT(slave_remove_and_add() == 1, "New slave should be synced"); - - remove_slaves_and_stop_bonded_device(); - - return TEST_SUCCESS; -} - -/** - * Test propagation logic, when RX_RSS mq_mode is turned off for bonding port - */ -static int -test_rss_lazy(void) -{ - TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id, - &default_pmd_conf, 0), "Failed to configure bonding device\n"); - - rte_eth_dev_info_get(test_params.bond_port_id, &test_params.bond_dev_info); - - TEST_ASSERT_SUCCESS(bond_slaves(), "Bonding slaves failed"); - - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bond_port_id), - "Failed to start bonding port (%d).", test_params.bond_port_id); - - TEST_ASSERT_SUCCESS(test_propagate(), "Propagation test failed"); - - TEST_ASSERT(slave_remove_and_add() == 0, "New slave shouldn't be synced"); - - remove_slaves_and_stop_bonded_device(); - - return TEST_SUCCESS; -} - -static int -test_setup(void) -{ - unsigned n; - int retval; - int port_id; - char name[256]; - struct slave_conf *port; - - if (test_params.mbuf_pool == NULL) { - - test_params.mbuf_pool = rte_mempool_create("RSS_MBUF_POOL", NUM_MBUFS * - SLAVE_COUNT, MBUF_SIZE, MBUF_CACHE_SIZE, - sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, - NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0); - - TEST_ASSERT(test_params.mbuf_pool != NULL, - "rte_mempool_create failed\n"); - } - - /* Create / initialize ring eth devs. */ - FOR_EACH_PORT(n, port) { - port = &test_params.slave_ports[n]; - - port_id = rte_eth_dev_count(); - snprintf(name, sizeof(name), SLAVE_DEV_NAME_FMT, port_id); - - retval = eth_dev_null_create(name, 0, 64, 0); - TEST_ASSERT_SUCCESS(retval, "Failed to create null device '%s'\n", - name); - - port->port_id = port_id; - - port->rss_conf.rss_key = port->rss_key; - port->rss_conf.rss_key_len = 40; - - retval = configure_ethdev(port->port_id, &default_pmd_conf, 0); - TEST_ASSERT_SUCCESS(retval, "Failed to configure virtual ethdev %s\n", - name); - - rte_eth_dev_info_get(port->port_id, &port->dev_info); - } - - if (test_params.bond_port_id == INVALID_PORT_ID) { - retval = rte_eth_bond_create(BONDED_DEV_NAME, 0, rte_socket_id()); - - TEST_ASSERT(retval >= 0, "Failed to create bonded ethdev %s", - BONDED_DEV_NAME); - - test_params.bond_port_id = retval; - - TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id, - &default_pmd_conf, 0), "Failed to configure bonding device\n"); - - rte_eth_dev_info_get(test_params.bond_port_id, - &test_params.bond_dev_info); - } - - return TEST_SUCCESS; -} - -static void -testsuite_teardown(void) -{ - struct slave_conf *port; - uint8_t i; - - /* Only stop ports. - * Any cleanup/reset state is done when particular test is - * started. */ - - rte_eth_dev_stop(test_params.bond_port_id); - - FOR_EACH_PORT(i, port) - rte_eth_dev_stop(port->port_id); -} - -static int -check_environment(void) -{ - return TEST_SUCCESS; -} - -static int -test_rssconf_executor(int (*test_func)(void)) -{ - int test_result; - - /* Check if environment is clean. Fail to launch a test if there was - * a critical error before that prevented to reset environment. */ - TEST_ASSERT_SUCCESS(check_environment(), - "Refusing to launch test in dirty environment."); - - RTE_VERIFY(test_func != NULL); - test_result = (*test_func)(); - - /* If test succeed check if environment wast left in good condition. */ - if (test_result == TEST_SUCCESS) - test_result = check_environment(); - - /* Reset environment in case test failed to do that. */ - if (test_result != TEST_SUCCESS) { - TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(), - "Failed to stop bonded device"); - } - - return test_result; -} - -static int -test_setup_wrapper(void) -{ - return test_rssconf_executor(&test_setup); -} - -static int -test_rss_wrapper(void) -{ - return test_rssconf_executor(&test_rss); -} - -static int -test_rss_lazy_wrapper(void) -{ - return test_rssconf_executor(&test_rss_lazy); -} - -static struct unit_test_suite link_bonding_rssconf_test_suite = { - .suite_name = "RSS Dynamic Configuration for Bonding Unit Test Suite", - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_NAMED("test_setup", test_setup_wrapper), - TEST_CASE_NAMED("test_rss", test_rss_wrapper), - TEST_CASE_NAMED("test_rss_lazy", test_rss_lazy_wrapper), - - TEST_CASES_END() - } -}; - -static int -test_link_bonding_rssconf(void) -{ - return unit_test_suite_runner(&link_bonding_rssconf_test_suite); -} - -REGISTER_TEST_COMMAND(link_bonding_rssconf_autotest, test_link_bonding_rssconf); diff --git a/app/test/test_logs.c b/app/test/test_logs.c deleted file mode 100644 index 6985ddde3b..0000000000 --- a/app/test/test_logs.c +++ /dev/null @@ -1,89 +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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define RTE_LOGTYPE_TESTAPP1 RTE_LOGTYPE_USER1 -#define RTE_LOGTYPE_TESTAPP2 RTE_LOGTYPE_USER2 - -/* - * Logs - * ==== - * - * - Enable log types. - * - Set log level. - * - Send logs with different types and levels, some should not be displayed. - */ - -static int -test_logs(void) -{ - /* enable these logs type */ - rte_set_log_type(RTE_LOGTYPE_TESTAPP1, 1); - rte_set_log_type(RTE_LOGTYPE_TESTAPP2, 1); - - /* 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 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 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; -} - -REGISTER_TEST_COMMAND(logs_autotest, test_logs); diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c deleted file mode 100644 index 41ae80fe16..0000000000 --- a/app/test/test_lpm.c +++ /dev/null @@ -1,1319 +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 -#include -#include - -#include -#include - -#include "test.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) - -typedef int32_t (*rte_lpm_test)(void); - -static int32_t test0(void); -static int32_t test1(void); -static int32_t test2(void); -static int32_t test3(void); -static int32_t test4(void); -static int32_t test5(void); -static int32_t test6(void); -static int32_t test7(void); -static int32_t test8(void); -static int32_t test9(void); -static int32_t test10(void); -static int32_t test11(void); -static int32_t test12(void); -static int32_t test13(void); -static int32_t test14(void); -static int32_t test15(void); -static int32_t test16(void); -static int32_t test17(void); -static int32_t test18(void); - -rte_lpm_test tests[] = { -/* Test Cases */ - test0, - test1, - test2, - test3, - test4, - test5, - test6, - test7, - test8, - test9, - test10, - test11, - test12, - test13, - test14, - test15, - test16, - test17, - test18 -}; - -#define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0])) -#define MAX_DEPTH 32 -#define MAX_RULES 256 -#define NUMBER_TBL8S 256 -#define PASS 0 - -/* - * Check that rte_lpm_create fails gracefully for incorrect user input - * arguments - */ -int32_t -test0(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm_create: lpm name == NULL */ - lpm = rte_lpm_create(NULL, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm == NULL); - - /* rte_lpm_create: max_rules = 0 */ - /* Note: __func__ inserts the function name, in this case "test0". */ - config.max_rules = 0; - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm == NULL); - - /* socket_id < -1 is invalid */ - config.max_rules = MAX_RULES; - lpm = rte_lpm_create(__func__, -2, &config); - TEST_LPM_ASSERT(lpm == NULL); - - return PASS; -} - -/* - * Create lpm table then delete lpm table 100 times - * Use a slightly different rules size each time - * */ -int32_t -test1(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - int32_t i; - - /* rte_lpm_free: Free NULL */ - for (i = 0; i < 100; i++) { - config.max_rules = MAX_RULES - i; - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - rte_lpm_free(lpm); - } - - /* Can not test free so return success */ - return PASS; -} - -/* - * Call rte_lpm_free for NULL pointer user input. Note: free has no return and - * therefore it is impossible to check for failure but this test is added to - * increase function coverage metrics and to validate that freeing null does - * not crash. - */ -int32_t -test2(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - rte_lpm_free(lpm); - rte_lpm_free(NULL); - return PASS; -} - -/* - * Check that rte_lpm_add fails gracefully for incorrect user input arguments - */ -int32_t -test3(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip = IPv4(0, 0, 0, 0), next_hop = 100; - uint8_t depth = 24; - int32_t status = 0; - - /* rte_lpm_add: lpm == NULL */ - status = rte_lpm_add(NULL, ip, depth, next_hop); - TEST_LPM_ASSERT(status < 0); - - /*Create vaild lpm to use in rest of test. */ - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* rte_lpm_add: depth < 1 */ - status = rte_lpm_add(lpm, ip, 0, next_hop); - TEST_LPM_ASSERT(status < 0); - - /* rte_lpm_add: depth > MAX_DEPTH */ - status = rte_lpm_add(lpm, ip, (MAX_DEPTH + 1), next_hop); - TEST_LPM_ASSERT(status < 0); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Check that rte_lpm_delete fails gracefully for incorrect user input - * arguments - */ -int32_t -test4(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip = IPv4(0, 0, 0, 0); - uint8_t depth = 24; - int32_t status = 0; - - /* rte_lpm_delete: lpm == NULL */ - status = rte_lpm_delete(NULL, ip, depth); - TEST_LPM_ASSERT(status < 0); - - /*Create vaild lpm to use in rest of test. */ - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* rte_lpm_delete: depth < 1 */ - status = rte_lpm_delete(lpm, ip, 0); - TEST_LPM_ASSERT(status < 0); - - /* rte_lpm_delete: depth > MAX_DEPTH */ - status = rte_lpm_delete(lpm, ip, (MAX_DEPTH + 1)); - TEST_LPM_ASSERT(status < 0); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Check that rte_lpm_lookup fails gracefully for incorrect user input - * arguments - */ -int32_t -test5(void) -{ -#if defined(RTE_LIBRTE_LPM_DEBUG) - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip = IPv4(0, 0, 0, 0), next_hop_return = 0; - int32_t status = 0; - - /* rte_lpm_lookup: lpm == NULL */ - status = rte_lpm_lookup(NULL, ip, &next_hop_return); - TEST_LPM_ASSERT(status < 0); - - /*Create vaild lpm to use in rest of test. */ - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* rte_lpm_lookup: depth < 1 */ - status = rte_lpm_lookup(lpm, ip, NULL); - TEST_LPM_ASSERT(status < 0); - - rte_lpm_free(lpm); -#endif - return PASS; -} - - - -/* - * Call add, lookup and delete for a single rule with depth <= 24 - */ -int32_t -test6(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip = IPv4(0, 0, 0, 0), next_hop_add = 100, next_hop_return = 0; - uint8_t depth = 24; - int32_t status = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Call add, lookup and delete for a single rule with depth > 24 - */ - -int32_t -test7(void) -{ - xmm_t ipx4; - uint32_t hop[4]; - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip = IPv4(0, 0, 0, 0), next_hop_add = 100, next_hop_return = 0; - uint8_t depth = 32; - int32_t status = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - ipx4 = vect_set_epi32(ip, ip + 0x100, ip - 0x100, ip); - rte_lpm_lookupx4(lpm, ipx4, hop, UINT32_MAX); - TEST_LPM_ASSERT(hop[0] == next_hop_add); - TEST_LPM_ASSERT(hop[1] == UINT32_MAX); - TEST_LPM_ASSERT(hop[2] == UINT32_MAX); - TEST_LPM_ASSERT(hop[3] == next_hop_add); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Use rte_lpm_add to add rules which effect only the second half of the lpm - * table. Use all possible depths ranging from 1..32. Set the next hop = to the - * depth. Check lookup hit for on every add and check for lookup miss on the - * first half of the lpm table after each add. Finally delete all rules going - * backwards (i.e. from depth = 32 ..1) and carry out a lookup after each - * delete. The lookup should return the next_hop_add value related to the - * previous depth value (i.e. depth -1). - */ -int32_t -test8(void) -{ - xmm_t ipx4; - uint32_t hop[4]; - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip1 = IPv4(127, 255, 255, 255), ip2 = IPv4(128, 0, 0, 0); - uint32_t next_hop_add, next_hop_return; - uint8_t depth; - int32_t status = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Loop with rte_lpm_add. */ - for (depth = 1; depth <= 32; depth++) { - /* Let the next_hop_add value = depth. Just for change. */ - next_hop_add = depth; - - status = rte_lpm_add(lpm, ip2, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - /* Check IP in first half of tbl24 which should be empty. */ - status = rte_lpm_lookup(lpm, ip1, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - status = rte_lpm_lookup(lpm, ip2, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add)); - - ipx4 = vect_set_epi32(ip2, ip1, ip2, ip1); - rte_lpm_lookupx4(lpm, ipx4, hop, UINT32_MAX); - TEST_LPM_ASSERT(hop[0] == UINT32_MAX); - TEST_LPM_ASSERT(hop[1] == next_hop_add); - TEST_LPM_ASSERT(hop[2] == UINT32_MAX); - TEST_LPM_ASSERT(hop[3] == next_hop_add); - } - - /* Loop with rte_lpm_delete. */ - for (depth = 32; depth >= 1; depth--) { - next_hop_add = (uint8_t) (depth - 1); - - status = rte_lpm_delete(lpm, ip2, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip2, &next_hop_return); - - if (depth != 1) { - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add)); - } else { - TEST_LPM_ASSERT(status == -ENOENT); - } - - status = rte_lpm_lookup(lpm, ip1, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - ipx4 = vect_set_epi32(ip1, ip1, ip2, ip2); - rte_lpm_lookupx4(lpm, ipx4, hop, UINT32_MAX); - if (depth != 1) { - TEST_LPM_ASSERT(hop[0] == next_hop_add); - TEST_LPM_ASSERT(hop[1] == next_hop_add); - } else { - TEST_LPM_ASSERT(hop[0] == UINT32_MAX); - TEST_LPM_ASSERT(hop[1] == UINT32_MAX); - } - TEST_LPM_ASSERT(hop[2] == UINT32_MAX); - TEST_LPM_ASSERT(hop[3] == UINT32_MAX); - } - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * - Add & lookup to hit invalid TBL24 entry - * - Add & lookup to hit valid TBL24 entry not extended - * - Add & lookup to hit valid extended TBL24 entry with invalid TBL8 entry - * - Add & lookup to hit valid extended TBL24 entry with valid TBL8 entry - * - */ -int32_t -test9(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip, ip_1, ip_2; - uint8_t depth, depth_1, depth_2; - uint32_t next_hop_add, next_hop_add_1, next_hop_add_2, next_hop_return; - int32_t status = 0; - - /* Add & lookup to hit invalid TBL24 entry */ - ip = IPv4(128, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_delete_all(lpm); - - /* Add & lookup to hit valid TBL24 entry not extended */ - ip = IPv4(128, 0, 0, 0); - depth = 23; - next_hop_add = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - depth = 24; - next_hop_add = 101; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - depth = 24; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - depth = 23; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_delete_all(lpm); - - /* Add & lookup to hit valid extended TBL24 entry with invalid TBL8 - * entry */ - ip = IPv4(128, 0, 0, 0); - depth = 32; - next_hop_add = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - ip = IPv4(128, 0, 0, 5); - depth = 32; - next_hop_add = 101; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - ip = IPv4(128, 0, 0, 0); - depth = 32; - next_hop_add = 100; - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_delete_all(lpm); - - /* Add & lookup to hit valid extended TBL24 entry with valid TBL8 - * entry */ - ip_1 = IPv4(128, 0, 0, 0); - depth_1 = 25; - next_hop_add_1 = 101; - - ip_2 = IPv4(128, 0, 0, 5); - depth_2 = 32; - next_hop_add_2 = 102; - - next_hop_return = 0; - - status = rte_lpm_add(lpm, ip_1, depth_1, next_hop_add_1); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip_1, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); - - status = rte_lpm_add(lpm, ip_2, depth_2, next_hop_add_2); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip_2, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_2)); - - status = rte_lpm_delete(lpm, ip_2, depth_2); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip_2, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); - - status = rte_lpm_delete(lpm, ip_1, depth_1); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip_1, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_free(lpm); - - return PASS; -} - - -/* - * - Add rule that covers a TBL24 range previously invalid & lookup (& delete & - * lookup) - * - Add rule that extends a TBL24 invalid entry & lookup (& delete & lookup) - * - Add rule that extends a TBL24 valid entry & lookup for both rules (& - * delete & lookup) - * - Add rule that updates the next hop in TBL24 & lookup (& delete & lookup) - * - Add rule that updates the next hop in TBL8 & lookup (& delete & lookup) - * - Delete a rule that is not present in the TBL24 & lookup - * - Delete a rule that is not present in the TBL8 & lookup - * - */ -int32_t -test10(void) -{ - - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip, next_hop_add, next_hop_return; - uint8_t depth; - int32_t status = 0; - - /* Add rule that covers a TBL24 range previously invalid & lookup - * (& delete & lookup) */ - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - ip = IPv4(128, 0, 0, 0); - depth = 16; - next_hop_add = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_delete_all(lpm); - - ip = IPv4(128, 0, 0, 0); - depth = 25; - next_hop_add = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - rte_lpm_delete_all(lpm); - - /* Add rule that extends a TBL24 valid entry & lookup for both rules - * (& delete & lookup) */ - - ip = IPv4(128, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - ip = IPv4(128, 0, 0, 10); - depth = 32; - next_hop_add = 101; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - ip = IPv4(128, 0, 0, 0); - next_hop_add = 100; - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - ip = IPv4(128, 0, 0, 0); - depth = 24; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - ip = IPv4(128, 0, 0, 10); - depth = 32; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_delete_all(lpm); - - /* Add rule that updates the next hop in TBL24 & lookup - * (& delete & lookup) */ - - ip = IPv4(128, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - next_hop_add = 101; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_delete_all(lpm); - - /* Add rule that updates the next hop in TBL8 & lookup - * (& delete & lookup) */ - - ip = IPv4(128, 0, 0, 0); - depth = 32; - next_hop_add = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - next_hop_add = 101; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_delete_all(lpm); - - /* Delete a rule that is not present in the TBL24 & lookup */ - - ip = IPv4(128, 0, 0, 0); - depth = 24; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status < 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_delete_all(lpm); - - /* Delete a rule that is not present in the TBL8 & lookup */ - - ip = IPv4(128, 0, 0, 0); - depth = 32; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status < 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Add two rules, lookup to hit the more specific one, lookup to hit the less - * specific one delete the less specific rule and lookup previous values again; - * add a more specific rule than the existing rule, lookup again - * - * */ -int32_t -test11(void) -{ - - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip, next_hop_add, next_hop_return; - uint8_t depth; - int32_t status = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - ip = IPv4(128, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - ip = IPv4(128, 0, 0, 10); - depth = 32; - next_hop_add = 101; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - ip = IPv4(128, 0, 0, 0); - next_hop_add = 100; - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - ip = IPv4(128, 0, 0, 0); - depth = 24; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - ip = IPv4(128, 0, 0, 10); - depth = 32; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * 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 - * and contraction. - * - * */ - -int32_t -test12(void) -{ - xmm_t ipx4; - uint32_t hop[4]; - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip, i, next_hop_add, next_hop_return; - uint8_t depth; - int32_t status = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - ip = IPv4(128, 0, 0, 0); - depth = 32; - next_hop_add = 100; - - for (i = 0; i < 1000; i++) { - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add)); - - ipx4 = vect_set_epi32(ip, ip + 1, ip, ip - 1); - rte_lpm_lookupx4(lpm, ipx4, hop, UINT32_MAX); - TEST_LPM_ASSERT(hop[0] == UINT32_MAX); - TEST_LPM_ASSERT(hop[1] == next_hop_add); - TEST_LPM_ASSERT(hop[2] == UINT32_MAX); - TEST_LPM_ASSERT(hop[3] == next_hop_add); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - } - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Add a rule to tbl24, lookup (hit), then add a rule that will extend this - * tbl24 entry, lookup (hit). delete the rule that caused the tbl24 extension, - * lookup (miss) and repeat for loop of 1000 times. This will check tbl8 - * extension and contraction. - * - * */ - -int32_t -test13(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip, i, next_hop_add_1, next_hop_add_2, next_hop_return; - uint8_t depth; - int32_t status = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - ip = IPv4(128, 0, 0, 0); - depth = 24; - next_hop_add_1 = 100; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add_1); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); - - depth = 32; - next_hop_add_2 = 101; - - for (i = 0; i < 1000; i++) { - status = rte_lpm_add(lpm, ip, depth, next_hop_add_2); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add_2)); - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add_1)); - } - - depth = 24; - - status = rte_lpm_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Fore TBL8 extension exhaustion. Add 256 rules that require a tbl8 extension. - * No more tbl8 extensions will be allowed. Now add one more rule that required - * a tbl8 extension and get fail. - * */ -int32_t -test14(void) -{ - - /* We only use depth = 32 in the loop below so we must make sure - * that we have enough storage for all rules at that depth*/ - - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = 256 * 32; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint32_t ip, next_hop_add, next_hop_return; - uint8_t depth; - int32_t status = 0; - - /* Add enough space for 256 rules for every depth */ - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - depth = 32; - next_hop_add = 100; - ip = IPv4(0, 0, 0, 0); - - /* Add 256 rules that require a tbl8 extension */ - for (; ip <= IPv4(0, 0, 255, 0); ip += 256) { - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add)); - } - - /* All tbl8 extensions have been used above. Try to add one more and - * we get a fail */ - ip = IPv4(1, 0, 0, 0); - depth = 32; - - status = rte_lpm_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status < 0); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Sequence of operations for find existing lpm table - * - * - create table - * - find existing table: hit - * - find non-existing table: miss - * - */ -int32_t -test15(void) -{ - struct rte_lpm *lpm = NULL, *result = NULL; - struct rte_lpm_config config; - - config.max_rules = 256 * 32; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* Create lpm */ - lpm = rte_lpm_create("lpm_find_existing", SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Try to find existing lpm */ - result = rte_lpm_find_existing("lpm_find_existing"); - TEST_LPM_ASSERT(result == lpm); - - /* Try to find non-existing lpm */ - result = rte_lpm_find_existing("lpm_find_non_existing"); - TEST_LPM_ASSERT(result == NULL); - - /* Cleanup. */ - rte_lpm_delete_all(lpm); - rte_lpm_free(lpm); - - return PASS; -} - -/* - * test failure condition of overloading the tbl8 so no more will fit - * Check we get an error return value in that case - */ -int32_t -test16(void) -{ - uint32_t ip; - struct rte_lpm_config config; - - config.max_rules = 256 * 32; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - struct rte_lpm *lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - - /* ip loops through all possibilities for top 24 bits of address */ - for (ip = 0; ip < 0xFFFFFF; ip++) { - /* add an entry within a different tbl8 each time, since - * depth >24 and the top 24 bits are different */ - if (rte_lpm_add(lpm, (ip << 8) + 0xF0, 30, 0) < 0) - break; - } - - if (ip != NUMBER_TBL8S) { - printf("Error, unexpected failure with filling tbl8 groups\n"); - printf("Failed after %u additions, expected after %u\n", - (unsigned)ip, (unsigned)NUMBER_TBL8S); - } - - rte_lpm_free(lpm); - return 0; -} - -/* - * Test for overwriting of tbl8: - * - add rule /32 and lookup - * - add new rule /24 and lookup - * - add third rule /25 and lookup - * - lookup /32 and /24 rule to ensure the table has not been overwritten. - */ -int32_t -test17(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - const uint32_t ip_10_32 = IPv4(10, 10, 10, 2); - const uint32_t ip_10_24 = IPv4(10, 10, 10, 0); - const uint32_t ip_20_25 = IPv4(10, 10, 20, 2); - const uint8_t d_ip_10_32 = 32, - d_ip_10_24 = 24, - d_ip_20_25 = 25; - const uint32_t next_hop_ip_10_32 = 100, - next_hop_ip_10_24 = 105, - next_hop_ip_20_25 = 111; - uint32_t next_hop_return = 0; - int32_t status = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - if ((status = rte_lpm_add(lpm, ip_10_32, d_ip_10_32, - next_hop_ip_10_32)) < 0) - return -1; - - status = rte_lpm_lookup(lpm, ip_10_32, &next_hop_return); - uint32_t test_hop_10_32 = next_hop_return; - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); - - if ((status = rte_lpm_add(lpm, ip_10_24, d_ip_10_24, - next_hop_ip_10_24)) < 0) - return -1; - - status = rte_lpm_lookup(lpm, ip_10_24, &next_hop_return); - uint32_t test_hop_10_24 = next_hop_return; - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); - - if ((status = rte_lpm_add(lpm, ip_20_25, d_ip_20_25, - next_hop_ip_20_25)) < 0) - return -1; - - status = rte_lpm_lookup(lpm, ip_20_25, &next_hop_return); - uint32_t test_hop_20_25 = next_hop_return; - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_20_25); - - if (test_hop_10_32 == test_hop_10_24) { - printf("Next hop return equal\n"); - return -1; - } - - if (test_hop_10_24 == test_hop_20_25) { - printf("Next hop return equal\n"); - return -1; - } - - status = rte_lpm_lookup(lpm, ip_10_32, &next_hop_return); - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); - - status = rte_lpm_lookup(lpm, ip_10_24, &next_hop_return); - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); - - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Test for recycle of tbl8 - * - step 1: add a rule with depth=28 (> 24) - * - step 2: add a rule with same 24-bit prefix and depth=23 (< 24) - * - step 3: delete the first rule - * - step 4: check tbl8 is freed - * - step 5: add a rule same as the first one (depth=28) - * - step 6: check same tbl8 is allocated - * - step 7: add a rule with same 24-bit prefix and depth=24 - * - step 8: delete the rule (depth=28) added in step 5 - * - step 9: check tbl8 is freed - * - step 10: add a rule with same 24-bit prefix and depth = 28 - * - setp 11: check same tbl8 is allocated again - */ -int32_t -test18(void) -{ -#define group_idx next_hop - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - uint32_t ip, next_hop; - uint8_t depth; - uint32_t tbl8_group_index; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - ip = IPv4(192, 168, 100, 100); - depth = 28; - next_hop = 1; - rte_lpm_add(lpm, ip, depth, next_hop); - - TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); - tbl8_group_index = lpm->tbl24[ip>>8].group_idx; - - depth = 23; - next_hop = 2; - rte_lpm_add(lpm, ip, depth, next_hop); - TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); - - depth = 28; - rte_lpm_delete(lpm, ip, depth); - - TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group); - - next_hop = 3; - rte_lpm_add(lpm, ip, depth, next_hop); - - TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); - TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl24[ip>>8].group_idx); - - depth = 24; - next_hop = 4; - rte_lpm_add(lpm, ip, depth, next_hop); - TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); - - depth = 28; - rte_lpm_delete(lpm, ip, depth); - - TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group); - - next_hop = 5; - rte_lpm_add(lpm, ip, depth, next_hop); - - TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); - TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl24[ip>>8].group_idx); - - rte_lpm_free(lpm); -#undef group_idx - return PASS; -} - -/* - * Do all unit tests. - */ - -static int -test_lpm(void) -{ - unsigned i; - int status, global_status = 0; - - for (i = 0; i < NUM_LPM_TESTS; i++) { - status = tests[i](); - if (status < 0) { - printf("ERROR: LPM Test %u: FAIL\n", i); - global_status = status; - } - } - - return global_status; -} - -REGISTER_TEST_COMMAND(lpm_autotest, test_lpm); diff --git a/app/test/test_lpm6.c b/app/test/test_lpm6.c deleted file mode 100644 index 61134f7003..0000000000 --- a/app/test/test_lpm6.c +++ /dev/null @@ -1,1770 +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 -#include -#include -#include - -#include -#include - -#include "test.h" -#include "test_lpm6_data.h" - -#define TEST_LPM_ASSERT(cond) do { \ - if (!(cond)) { \ - printf("Error at line %d: \n", __LINE__); \ - return -1; \ - } \ -} while(0) - -typedef int32_t (* rte_lpm6_test)(void); - -static int32_t test0(void); -static int32_t test1(void); -static int32_t test2(void); -static int32_t test3(void); -static int32_t test4(void); -static int32_t test5(void); -static int32_t test6(void); -static int32_t test7(void); -static int32_t test8(void); -static int32_t test9(void); -static int32_t test10(void); -static int32_t test11(void); -static int32_t test12(void); -static int32_t test13(void); -static int32_t test14(void); -static int32_t test15(void); -static int32_t test16(void); -static int32_t test17(void); -static int32_t test18(void); -static int32_t test19(void); -static int32_t test20(void); -static int32_t test21(void); -static int32_t test22(void); -static int32_t test23(void); -static int32_t test24(void); -static int32_t test25(void); -static int32_t test26(void); -static int32_t test27(void); - -rte_lpm6_test tests6[] = { -/* Test Cases */ - test0, - test1, - test2, - test3, - test4, - test5, - test6, - test7, - test8, - test9, - test10, - test11, - test12, - test13, - test14, - test15, - test16, - test17, - test18, - test19, - test20, - test21, - test22, - test23, - test24, - test25, - test26, - test27, -}; - -#define NUM_LPM6_TESTS (sizeof(tests6)/sizeof(tests6[0])) -#define MAX_DEPTH 128 -#define MAX_RULES 1000000 -#define NUMBER_TBL8S (1 << 16) -#define MAX_NUM_TBL8S (1 << 21) -#define PASS 0 - -static void -IPv6(uint8_t *ip, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, - uint8_t b6, uint8_t b7, uint8_t b8, uint8_t b9, uint8_t b10, - uint8_t b11, uint8_t b12, uint8_t b13, uint8_t b14, uint8_t b15, - uint8_t b16) -{ - ip[0] = b1; - ip[1] = b2; - ip[2] = b3; - ip[3] = b4; - ip[4] = b5; - ip[5] = b6; - ip[6] = b7; - ip[7] = b8; - ip[8] = b9; - ip[9] = b10; - ip[10] = b11; - ip[11] = b12; - ip[12] = b13; - ip[13] = b14; - ip[14] = b15; - ip[15] = b16; -} - -/* - * Check that rte_lpm6_create fails gracefully for incorrect user input - * arguments - */ -int32_t -test0(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm6_create: lpm name == NULL */ - lpm = rte_lpm6_create(NULL, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm == NULL); - - /* rte_lpm6_create: max_rules = 0 */ - /* Note: __func__ inserts the function name, in this case "test0". */ - config.max_rules = 0; - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm == NULL); - - /* socket_id < -1 is invalid */ - config.max_rules = MAX_RULES; - lpm = rte_lpm6_create(__func__, -2, &config); - TEST_LPM_ASSERT(lpm == NULL); - - /* rte_lpm6_create: number_tbl8s is bigger than the maximum */ - config.number_tbl8s = MAX_NUM_TBL8S + 1; - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm == NULL); - - /* rte_lpm6_create: config = NULL */ - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, NULL); - TEST_LPM_ASSERT(lpm == NULL); - - return PASS; -} - -/* - * Creates two different LPM tables. Tries to create a third one with the same - * name as the first one and expects the create function to return the same - * pointer. - */ -int32_t -test1(void) -{ - struct rte_lpm6 *lpm1 = NULL, *lpm2 = NULL, *lpm3 = NULL; - struct rte_lpm6_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm6_create: lpm name == LPM1 */ - lpm1 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm1 != NULL); - - /* rte_lpm6_create: lpm name == LPM2 */ - lpm2 = rte_lpm6_create("LPM2", SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm2 != NULL); - - /* rte_lpm6_create: lpm name == LPM2 */ - lpm3 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm3 == NULL); - - rte_lpm6_free(lpm1); - rte_lpm6_free(lpm2); - - return PASS; -} - -/* - * Create lpm table then delete lpm table 20 times - * Use a slightly different rules size each time - */ -int32_t -test2(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - int32_t i; - - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm6_free: Free NULL */ - 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); - - rte_lpm6_free(lpm); - } - - /* Can not test free so return success */ - return PASS; -} - -/* - * Call rte_lpm6_free for NULL pointer user input. Note: free has no return and - * therefore it is impossible to check for failure but this test is added to - * increase function coverage metrics and to validate that freeing null does - * not crash. - */ -int32_t -test3(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - rte_lpm6_free(lpm); - rte_lpm6_free(NULL); - return PASS; -} - -/* - * Check that rte_lpm6_add fails gracefully for incorrect user input arguments - */ -int32_t -test4(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 24, next_hop = 100; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm6_add: lpm == NULL */ - status = rte_lpm6_add(NULL, ip, depth, next_hop); - TEST_LPM_ASSERT(status < 0); - - /*Create vaild lpm to use in rest of test. */ - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* rte_lpm6_add: depth < 1 */ - status = rte_lpm6_add(lpm, ip, 0, next_hop); - TEST_LPM_ASSERT(status < 0); - - /* rte_lpm6_add: depth > MAX_DEPTH */ - status = rte_lpm6_add(lpm, ip, (MAX_DEPTH + 1), next_hop); - TEST_LPM_ASSERT(status < 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Check that rte_lpm6_delete fails gracefully for incorrect user input - * arguments - */ -int32_t -test5(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 24; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm_delete: lpm == NULL */ - status = rte_lpm6_delete(NULL, ip, depth); - TEST_LPM_ASSERT(status < 0); - - /*Create vaild lpm to use in rest of test. */ - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* rte_lpm_delete: depth < 1 */ - status = rte_lpm6_delete(lpm, ip, 0); - TEST_LPM_ASSERT(status < 0); - - /* rte_lpm_delete: depth > MAX_DEPTH */ - status = rte_lpm6_delete(lpm, ip, (MAX_DEPTH + 1)); - TEST_LPM_ASSERT(status < 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Check that rte_lpm6_lookup fails gracefully for incorrect user input - * arguments - */ -int32_t -test6(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t next_hop_return = 0; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm6_lookup: lpm == NULL */ - status = rte_lpm6_lookup(NULL, ip, &next_hop_return); - TEST_LPM_ASSERT(status < 0); - - /*Create vaild lpm to use in rest of test. */ - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* rte_lpm6_lookup: ip = NULL */ - status = rte_lpm6_lookup(lpm, NULL, &next_hop_return); - TEST_LPM_ASSERT(status < 0); - - /* rte_lpm6_lookup: next_hop = NULL */ - status = rte_lpm6_lookup(lpm, ip, NULL); - TEST_LPM_ASSERT(status < 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Checks that rte_lpm6_lookup_bulk_func fails gracefully for incorrect user - * input arguments - */ -int32_t -test7(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[10][16]; - int16_t next_hop_return[10]; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm6_lookup: lpm == NULL */ - status = rte_lpm6_lookup_bulk_func(NULL, ip, next_hop_return, 10); - TEST_LPM_ASSERT(status < 0); - - /*Create vaild lpm to use in rest of test. */ - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* rte_lpm6_lookup: ip = NULL */ - status = rte_lpm6_lookup_bulk_func(lpm, NULL, next_hop_return, 10); - TEST_LPM_ASSERT(status < 0); - - /* rte_lpm6_lookup: next_hop = NULL */ - status = rte_lpm6_lookup_bulk_func(lpm, ip, NULL, 10); - TEST_LPM_ASSERT(status < 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Checks that rte_lpm6_delete_bulk_func fails gracefully for incorrect user - * input arguments - */ -int32_t -test8(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[10][16]; - uint8_t depth[10]; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* rte_lpm6_delete: lpm == NULL */ - status = rte_lpm6_delete_bulk_func(NULL, ip, depth, 10); - TEST_LPM_ASSERT(status < 0); - - /*Create vaild lpm to use in rest of test. */ - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* rte_lpm6_delete: ip = NULL */ - status = rte_lpm6_delete_bulk_func(lpm, NULL, depth, 10); - TEST_LPM_ASSERT(status < 0); - - /* rte_lpm6_delete: next_hop = NULL */ - status = rte_lpm6_delete_bulk_func(lpm, ip, NULL, 10); - TEST_LPM_ASSERT(status < 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Call add, lookup and delete for a single rule with depth < 24. - * Check all the combinations for the first three bytes that result in a hit. - * Delete the rule and check that the same test returs a miss. - */ -int32_t -test9(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 16, next_hop_add = 100, next_hop_return = 0; - int32_t status = 0; - uint8_t i; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - for (i = 0; i < UINT8_MAX; i++) { - ip[2] = i; - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - } - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - for (i = 0; i < UINT8_MAX; i++) { - ip[2] = i; - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - } - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Adds max_rules + 1 and expects a failure. Deletes a rule, then adds - * another one and expects success. - */ -int32_t -test10(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add = 100; - int32_t status = 0; - int i; - - config.max_rules = 127; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - for (i = 1; i < 128; i++) { - depth = (uint8_t)i; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - } - - depth = 128; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == -ENOSPC); - - depth = 127; - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - depth = 128; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Creates an LPM table with a small number of tbl8s and exhaust them in the - * middle of the process of creating a rule. - */ -int32_t -test11(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add = 100; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = 16; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - depth = 128; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - ip[0] = 1; - depth = 25; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - depth = 33; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - depth = 41; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - depth = 49; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == -ENOSPC); - - depth = 41; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Creates an LPM table with a small number of tbl8s and exhaust them in the - * middle of the process of adding a rule when there is already an existing rule - * in that position and needs to be extended. - */ -int32_t -test12(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add = 100; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = 16; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - depth = 128; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - ip[0] = 1; - depth = 41; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - depth = 49; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == -ENOSPC); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Creates an LPM table with max_rules = 2 and tries to add 3 rules. - * Delete one of the rules and tries to add the third one again. - */ -int32_t -test13(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add = 100; - int32_t status = 0; - - config.max_rules = 2; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - depth = 1; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - depth = 2; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - depth = 3; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == -ENOSPC); - - depth = 2; - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - depth = 3; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * 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. - */ -int32_t -test14(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - 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; - - config.max_rules = MAX_RULES; - config.number_tbl8s = 256; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - for (i = 0; i < 256; i++) { - ip[0] = (uint8_t)i; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - } - - ip[0] = 255; - ip[1] = 1; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == -ENOSPC); - - ip[0] = 255; - ip[1] = 0; - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - ip[0] = 255; - ip[1] = 1; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Call add, lookup and delete for a single rule with depth = 24 - */ -int32_t -test15(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 24, next_hop_add = 100, next_hop_return = 0; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Call add, lookup and delete for a single rule with depth > 24 - */ -int32_t -test16(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 128, next_hop_add = 100, next_hop_return = 0; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Use rte_lpm6_add to add rules which effect only the second half of the lpm - * table. Use all possible depths ranging from 1..32. Set the next hop = to the - * depth. Check lookup hit for on every add and check for lookup miss on the - * first half of the lpm table after each add. Finally delete all rules going - * backwards (i.e. from depth = 32 ..1) and carry out a lookup after each - * delete. The lookup should return the next_hop_add value related to the - * previous depth value (i.e. depth -1). - */ -int32_t -test17(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip1[] = {127,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255}; - uint8_t ip2[] = {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add, next_hop_return; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Loop with rte_lpm6_add. */ - for (depth = 1; depth <= 16; depth++) { - /* Let the next_hop_add value = depth. Just for change. */ - next_hop_add = depth; - - status = rte_lpm6_add(lpm, ip2, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - /* Check IP in first half of tbl24 which should be empty. */ - status = rte_lpm6_lookup(lpm, ip1, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - status = rte_lpm6_lookup(lpm, ip2, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add)); - } - - /* Loop with rte_lpm6_delete. */ - for (depth = 16; depth >= 1; depth--) { - next_hop_add = (uint8_t) (depth - 1); - - status = rte_lpm6_delete(lpm, ip2, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip2, &next_hop_return); - - if (depth != 1) { - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add)); - } - else { - TEST_LPM_ASSERT(status == -ENOENT); - } - - status = rte_lpm6_lookup(lpm, ip1, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - } - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * - Add & lookup to hit invalid TBL24 entry - * - Add & lookup to hit valid TBL24 entry not extended - * - Add & lookup to hit valid extended TBL24 entry with invalid TBL8 entry - * - Add & lookup to hit valid extended TBL24 entry with valid TBL8 entry - */ -int32_t -test18(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[16], ip_1[16], ip_2[16]; - uint8_t depth, depth_1, depth_2, next_hop_add, next_hop_add_1, - next_hop_add_2, next_hop_return; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* Add & lookup to hit invalid TBL24 entry */ - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_delete_all(lpm); - - /* Add & lookup to hit valid TBL24 entry not extended */ - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 23; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - depth = 24; - next_hop_add = 101; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - depth = 24; - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - depth = 23; - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_delete_all(lpm); - - /* Add & lookup to hit valid extended TBL24 entry with invalid TBL8 - * entry. - */ - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 32; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - IPv6(ip, 128, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 32; - next_hop_add = 101; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 32; - next_hop_add = 100; - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_delete_all(lpm); - - /* Add & lookup to hit valid extended TBL24 entry with valid TBL8 - * entry - */ - IPv6(ip_1, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth_1 = 25; - next_hop_add_1 = 101; - - IPv6(ip_2, 128, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth_2 = 32; - next_hop_add_2 = 102; - - next_hop_return = 0; - - status = rte_lpm6_add(lpm, ip_1, depth_1, next_hop_add_1); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip_1, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); - - status = rte_lpm6_add(lpm, ip_2, depth_2, next_hop_add_2); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip_2, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_2)); - - status = rte_lpm6_delete(lpm, ip_2, depth_2); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip_2, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); - - status = rte_lpm6_delete(lpm, ip_1, depth_1); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip_1, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * - Add rule that covers a TBL24 range previously invalid & lookup (& delete & - * lookup) - * - Add rule that extends a TBL24 invalid entry & lookup (& delete & lookup) - * - Add rule that extends a TBL24 valid entry & lookup for both rules (& - * delete & lookup) - * - Add rule that updates the next hop in TBL24 & lookup (& delete & lookup) - * - Add rule that updates the next hop in TBL8 & lookup (& delete & lookup) - * - Delete a rule that is not present in the TBL24 & lookup - * - Delete a rule that is not present in the TBL8 & lookup - */ -int32_t -test19(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[16]; - uint8_t depth, next_hop_add, next_hop_return; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* Add rule that covers a TBL24 range previously invalid & lookup - * (& delete & lookup) - */ - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 16; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_delete_all(lpm); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 25; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - rte_lpm6_delete_all(lpm); - - /* - * Add rule that extends a TBL24 valid entry & lookup for both rules - * (& delete & lookup) - */ - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip, 128, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 32; - next_hop_add = 101; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - next_hop_add = 100; - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 24; - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - IPv6(ip, 128, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 32; - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_delete_all(lpm); - - /* - * Add rule that updates the next hop in TBL24 & lookup - * (& delete & lookup) - */ - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - next_hop_add = 101; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_delete_all(lpm); - - /* - * Add rule that updates the next hop in TBL8 & lookup - * (& delete & lookup) - */ - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 32; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - next_hop_add = 101; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_delete_all(lpm); - - /* Delete a rule that is not present in the TBL24 & lookup */ - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status < 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_delete_all(lpm); - - /* Delete a rule that is not present in the TBL8 & lookup */ - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 32; - next_hop_add = 100; - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status < 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Add two rules, lookup to hit the more specific one, lookup to hit the less - * specific one delete the less specific rule and lookup previous values again; - * add a more specific rule than the existing rule, lookup again - */ -int32_t -test20(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[16]; - uint8_t depth, next_hop_add, next_hop_return; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 24; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10); - depth = 128; - next_hop_add = 101; - - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - next_hop_add = 100; - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 24; - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10); - depth = 128; - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Adds 3 rules and look them up through the lookup_bulk function. - * Includes in the lookup a fourth IP address that won't match - * and checks that the result is as expected. - */ -int32_t -test21(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip_batch[4][16]; - uint8_t depth, next_hop_add; - int16_t next_hop_return[4]; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - IPv6(ip_batch[0], 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 48; - next_hop_add = 100; - - status = rte_lpm6_add(lpm, ip_batch[0], depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip_batch[1], 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 48; - next_hop_add = 101; - - status = rte_lpm6_add(lpm, ip_batch[1], depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip_batch[2], 128, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 48; - next_hop_add = 102; - - status = rte_lpm6_add(lpm, ip_batch[2], depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip_batch[3], 128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, - next_hop_return, 4); - TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == 100 - && next_hop_return[1] == 101 && next_hop_return[2] == 102 - && next_hop_return[3] == -1); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Adds 5 rules and look them up. - * Use the delete_bulk function to delete two of them. Lookup again. - * Use the delete_bulk function to delete one more. Lookup again. - * Use the delete_bulk function to delete two more, one invalid. Lookup again. - * Use the delete_bulk function to delete the remaining one. Lookup again. - */ -int32_t -test22(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip_batch[5][16]; - uint8_t depth[5], next_hop_add; - int16_t next_hop_return[5]; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Adds 5 rules and look them up */ - - IPv6(ip_batch[0], 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth[0] = 48; - next_hop_add = 101; - - status = rte_lpm6_add(lpm, ip_batch[0], depth[0], next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip_batch[1], 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth[1] = 48; - next_hop_add = 102; - - status = rte_lpm6_add(lpm, ip_batch[1], depth[1], next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip_batch[2], 128, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth[2] = 48; - next_hop_add = 103; - - status = rte_lpm6_add(lpm, ip_batch[2], depth[2], next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip_batch[3], 128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth[3] = 48; - next_hop_add = 104; - - status = rte_lpm6_add(lpm, ip_batch[3], depth[3], next_hop_add); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip_batch[4], 128, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth[4] = 48; - next_hop_add = 105; - - status = rte_lpm6_add(lpm, ip_batch[4], depth[4], next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, - next_hop_return, 5); - TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == 101 - && next_hop_return[1] == 102 && next_hop_return[2] == 103 - && next_hop_return[3] == 104 && next_hop_return[4] == 105); - - /* Use the delete_bulk function to delete two of them. Lookup again */ - - status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[0], depth, 2); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, - next_hop_return, 5); - TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1 - && next_hop_return[1] == -1 && next_hop_return[2] == 103 - && next_hop_return[3] == 104 && next_hop_return[4] == 105); - - /* Use the delete_bulk function to delete one more. Lookup again */ - - status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[2], depth, 1); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, - next_hop_return, 5); - TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1 - && next_hop_return[1] == -1 && next_hop_return[2] == -1 - && next_hop_return[3] == 104 && next_hop_return[4] == 105); - - /* Use the delete_bulk function to delete two, one invalid. Lookup again */ - - IPv6(ip_batch[4], 128, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[3], depth, 2); - TEST_LPM_ASSERT(status == 0); - - IPv6(ip_batch[4], 128, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, - next_hop_return, 5); - TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1 - && next_hop_return[1] == -1 && next_hop_return[2] == -1 - && next_hop_return[3] == -1 && next_hop_return[4] == 105); - - /* Use the delete_bulk function to delete the remaining one. Lookup again */ - - status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[4], depth, 1); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, - next_hop_return, 5); - TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1 - && next_hop_return[1] == -1 && next_hop_return[2] == -1 - && next_hop_return[3] == -1 && next_hop_return[4] == -1); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Add an extended rule (i.e. depth greater than 24, lookup (hit), delete, - * lookup (miss) in a for loop of 30 times. This will check tbl8 extension - * and contraction. - */ -int32_t -test23(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint32_t i; - uint8_t ip[16]; - uint8_t depth, next_hop_add, next_hop_return; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - depth = 128; - next_hop_add = 100; - - for (i = 0; i < 30; i++) { - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_add)); - - status = rte_lpm6_delete(lpm, ip, depth); - TEST_LPM_ASSERT(status == 0); - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT(status == -ENOENT); - } - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Sequence of operations for find existing lpm table - * - * - create table - * - find existing table: hit - * - find non-existing table: miss - */ -int32_t -test24(void) -{ - struct rte_lpm6 *lpm = NULL, *result = NULL; - struct rte_lpm6_config config; - - config.max_rules = 256 * 32; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - /* Create lpm */ - lpm = rte_lpm6_create("lpm_find_existing", SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Try to find existing lpm */ - result = rte_lpm6_find_existing("lpm_find_existing"); - TEST_LPM_ASSERT(result == lpm); - - /* Try to find non-existing lpm */ - result = rte_lpm6_find_existing("lpm_find_non_existing"); - TEST_LPM_ASSERT(result == NULL); - - /* Cleanup. */ - rte_lpm6_delete_all(lpm); - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Add a set of random routes with random depths. - * Lookup different IP addresses that match the routes previously added. - * Checks that the next hop is the expected one. - * The routes, IP addresses and expected result for every case have been - * precalculated by using a python script and stored in a .h file. - */ -int32_t -test25(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[16]; - uint32_t i; - uint8_t depth, next_hop_add, next_hop_return, next_hop_expected; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - for (i = 0; i < 1000; i++) { - memcpy(ip, large_route_table[i].ip, 16); - depth = large_route_table[i].depth; - next_hop_add = large_route_table[i].next_hop; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - } - - /* generate large IPS table and expected next_hops */ - generate_large_ips_table(1); - - for (i = 0; i < 100000; i++) { - memcpy(ip, large_ips_table[i].ip, 16); - next_hop_expected = large_ips_table[i].next_hop; - - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - TEST_LPM_ASSERT((status == 0) && - (next_hop_return == next_hop_expected)); - } - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Test for overwriting of tbl8: - * - add rule /32 and lookup - * - add new rule /24 and lookup - * - add third rule /25 and lookup - * - lookup /32 and /24 rule to ensure the table has not been overwritten. - */ -int32_t -test26(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip_10_32[] = {10, 10, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t ip_10_24[] = {10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t ip_20_25[] = {10, 10, 20, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t d_ip_10_32 = 32; - uint8_t d_ip_10_24 = 24; - uint8_t d_ip_20_25 = 25; - uint8_t next_hop_ip_10_32 = 100; - uint8_t next_hop_ip_10_24 = 105; - uint8_t next_hop_ip_20_25 = 111; - uint8_t next_hop_return = 0; - int32_t status = 0; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - if ((status = rte_lpm6_add(lpm, ip_10_32, d_ip_10_32, - next_hop_ip_10_32)) < 0) - return -1; - - status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return); - uint8_t test_hop_10_32 = next_hop_return; - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); - - if ((status = rte_lpm6_add(lpm, ip_10_24, d_ip_10_24, - next_hop_ip_10_24)) < 0) - return -1; - - status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return); - uint8_t test_hop_10_24 = next_hop_return; - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); - - if ((status = rte_lpm6_add(lpm, ip_20_25, d_ip_20_25, - next_hop_ip_20_25)) < 0) - return -1; - - status = rte_lpm6_lookup(lpm, ip_20_25, &next_hop_return); - uint8_t test_hop_20_25 = next_hop_return; - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_20_25); - - if (test_hop_10_32 == test_hop_10_24) { - printf("Next hop return equal\n"); - return -1; - } - - if (test_hop_10_24 == test_hop_20_25){ - printf("Next hop return equal\n"); - return -1; - } - - status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return); - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); - - status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return); - TEST_LPM_ASSERT(status == 0); - TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Add a rule that reaches the end of the tree. - * Add a rule that is more generic than the first one. - * Check every possible combination that produces a match for the second rule. - * This tests tbl expansion. - */ -int32_t -test27(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint8_t ip[] = {128,128,128,128,128,128,128,128,128,128,128,128,128,128,0,0}; - uint8_t depth = 128, next_hop_add = 100, next_hop_return; - int32_t status = 0; - int i, j; - - config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - depth = 128; - next_hop_add = 128; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - depth = 112; - next_hop_add = 112; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - - for (i = 0; i < 256; i++) { - ip[14] = (uint8_t)i; - for (j = 0; j < 256; j++) { - ip[15] = (uint8_t)j; - status = rte_lpm6_lookup(lpm, ip, &next_hop_return); - if (i == 0 && j == 0) - TEST_LPM_ASSERT(status == 0 && next_hop_return == 128); - else - TEST_LPM_ASSERT(status == 0 && next_hop_return == 112); - } - } - - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Do all unit tests. - */ -static int -test_lpm6(void) -{ - unsigned i; - 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) { - printf("ERROR: LPM Test %s: FAIL\n", RTE_STR(tests6[i])); - global_status = status; - } - } - - return global_status; -} - -REGISTER_TEST_COMMAND(lpm6_autotest, test_lpm6); diff --git a/app/test/test_lpm6_data.h b/app/test/test_lpm6_data.h deleted file mode 100644 index c3573b2bfb..0000000000 --- a/app/test/test_lpm6_data.h +++ /dev/null @@ -1,1188 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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. - */ -#ifndef _TEST_LPM_ROUTES_H_ -#define _TEST_LPM_ROUTES_H_ - -#include -#include - -struct rules_tbl_entry { - uint8_t ip[16]; - uint8_t depth; - uint8_t next_hop; -}; - -struct ips_tbl_entry { - uint8_t ip[16]; - uint8_t next_hop; -}; - -/* this large_route_table[ ] is the same as the one with same name - * in previous test_lpm6_routes.h . Because this table has only 1000 - * lines, keeping it doesn't make LPM6 test case so large and also - * make the algorithm to generate rule table unnecessary and the - * algorithm to genertate test input IPv6 and associated expected - * next_hop much simple. - */ - -static struct rules_tbl_entry large_route_table[] = { - {{66, 70, 154, 143, 197, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 146}, - {{107, 79, 18, 235, 142, 84, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 141}, - {{247, 132, 113, 1, 215, 247, 183, 239, 128, 0, 0, 0, 0, 0, 0, 0}, 67, 23}, - {{48, 19, 41, 12, 76, 101, 114, 160, 45, 103, 134, 146, 128, 0, 0, 0}, 97, 252}, - {{5, 70, 208, 170, 19, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 6}, - {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 137}, - {{12, 188, 26, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 9}, - {{1, 235, 101, 202, 26, 92, 23, 22, 179, 223, 128, 0, 0, 0, 0, 0}, 82, 9}, - {{215, 19, 224, 102, 45, 133, 102, 249, 56, 20, 214, 219, 93, 125, 52, 0}, 120, 163}, - {{178, 183, 109, 64, 136, 84, 11, 53, 217, 102, 0, 0, 0, 0, 0, 0}, 79, 197}, - {{212, 39, 158, 71, 253, 98, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 249}, - {{92, 58, 159, 130, 105, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 88}, - {{118, 140, 65, 198, 212, 93, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 104}, - {{86, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 36}, - {{79, 135, 242, 193, 197, 11, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 239}, - {{163, 228, 239, 80, 41, 66, 176, 176, 0, 0, 0, 0, 0, 0, 0, 0}, 67, 201}, - {{31, 9, 231, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 94}, - {{108, 144, 205, 39, 215, 26, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 241}, - {{247, 217, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 239}, - {{24, 186, 73, 182, 240, 251, 125, 165, 0, 0, 0, 0, 0, 0, 0, 0}, 66, 151}, - {{245, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 12, 137}, - {{44, 94, 138, 224, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 231}, - {{184, 221, 109, 135, 225, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 11}, - {{51, 179, 136, 184, 30, 118, 24, 16, 26, 161, 206, 101, 0, 0, 0, 0}, 96, 20}, - {{48, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15, 68}, - {{143, 235, 237, 220, 89, 119, 187, 143, 209, 94, 46, 58, 120, 0, 0, 0}, 101, 64}, - {{121, 190, 90, 177, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 152}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 217}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 101}, - {{111, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15, 58}, - {{162, 23, 52, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 254}, - {{76, 103, 44, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 148}, - {{80, 85, 219, 214, 12, 4, 65, 129, 162, 148, 208, 78, 39, 69, 94, 184}, 126, 126}, - {{80, 54, 251, 28, 152, 23, 244, 192, 151, 83, 6, 144, 223, 213, 224, 128}, 123, 76}, - {{39, 232, 237, 103, 191, 188, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 240}, - {{20, 231, 89, 210, 167, 173, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 33}, - {{125, 67, 198, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 47}, - {{26, 239, 153, 5, 213, 121, 31, 114, 161, 46, 84, 15, 148, 160, 0, 0}, 109, 41}, - {{102, 212, 159, 118, 223, 115, 134, 172, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 72}, - {{85, 181, 241, 127, 3, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 43}, - {{61, 199, 131, 226, 3, 230, 94, 119, 240, 0, 0, 0, 0, 0, 0, 0}, 68, 26}, - {{0, 143, 160, 184, 162, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 139}, - {{170, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 219}, - {{61, 122, 24, 251, 124, 122, 202, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 105}, - {{33, 219, 226, 3, 180, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 210}, - {{51, 251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 151}, - {{106, 185, 11, 122, 197, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 28}, - {{192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 64}, - {{239, 195, 77, 239, 131, 156, 2, 246, 191, 178, 204, 160, 21, 213, 30, 128}, 121, 9}, - {{141, 207, 181, 99, 55, 245, 151, 228, 65, 50, 85, 16, 0, 0, 0, 0}, 92, 250}, - {{110, 159, 230, 251, 224, 210, 58, 49, 0, 0, 0, 0, 0, 0, 0, 0}, 66, 200}, - {{134, 26, 104, 32, 129, 41, 201, 50, 164, 69, 178, 156, 156, 133, 8, 218}, 127, 132}, - {{253, 207, 116, 105, 210, 166, 186, 99, 182, 0, 0, 0, 0, 0, 0, 0}, 71, 182}, - {{211, 73, 38, 80, 183, 168, 52, 138, 25, 214, 112, 8, 252, 0, 0, 0}, 102, 7}, - {{200, 244, 108, 238, 164, 141, 215, 39, 233, 249, 120, 80, 112, 0, 0, 0}, 100, 146}, - {{107, 44, 250, 202, 64, 37, 107, 105, 140, 0, 0, 0, 0, 0, 0, 0}, 70, 98}, - {{93, 86, 56, 27, 159, 195, 126, 39, 240, 201, 48, 0, 0, 0, 0, 0}, 86, 179}, - {{32, 202, 214, 242, 39, 141, 61, 146, 138, 96, 0, 0, 0, 0, 0, 0}, 77, 245}, - {{167, 77, 249, 28, 210, 196, 227, 241, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 2}, - {{241, 59, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 5}, - {{143, 68, 146, 210, 173, 155, 251, 173, 0, 0, 0, 0, 0, 0, 0, 0}, 66, 169}, - {{167, 180, 226, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 52}, - {{241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 177}, - {{238, 9, 168, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 74}, - {{203, 148, 16, 96, 125, 18, 86, 1, 91, 244, 251, 20, 31, 14, 75, 128}, 122, 212}, - {{111, 227, 137, 94, 65, 21, 77, 137, 119, 130, 159, 19, 159, 45, 18, 192}, 122, 238}, - {{59, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 18}, - {{110, 192, 255, 120, 84, 215, 3, 130, 38, 224, 0, 0, 0, 0, 0, 0}, 75, 155}, - {{152, 79, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 97}, - {{118, 186, 157, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 8}, - {{70, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 123}, - {{253, 119, 114, 227, 18, 243, 81, 61, 238, 107, 190, 144, 0, 0, 0, 0}, 92, 11}, - {{166, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 211}, - {{43, 95, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 116}, - {{94, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 57}, - {{182, 251, 195, 132, 66, 7, 208, 146, 223, 231, 211, 181, 25, 176, 0, 0}, 108, 178}, - {{152, 166, 111, 233, 194, 17, 230, 41, 221, 253, 69, 123, 108, 0, 0, 0}, 102, 93}, - {{106, 141, 235, 190, 82, 241, 152, 186, 195, 81, 86, 144, 0, 0, 0, 0}, 92, 3}, - {{32, 81, 210, 153, 151, 29, 11, 62, 127, 177, 194, 254, 103, 83, 58, 128}, 121, 162}, - {{79, 112, 224, 26, 174, 39, 98, 181, 115, 57, 209, 189, 136, 48, 0, 0}, 109, 125}, - {{106, 197, 83, 151, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 33}, - {{190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 254}, - {{156, 73, 249, 148, 55, 192, 20, 42, 142, 128, 0, 0, 0, 0, 0, 0}, 74, 66}, - {{64, 107, 36, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 4}, - {{115, 148, 71, 250, 158, 174, 168, 249, 106, 110, 196, 0, 0, 0, 0, 0}, 86, 122}, - {{18, 139, 152, 44, 38, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 59}, - {{55, 229, 117, 106, 146, 95, 74, 220, 122, 0, 84, 202, 183, 138, 120, 0}, 117, 99}, - {{153, 211, 3, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 41}, - {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 112}, - {{49, 192, 102, 142, 216, 3, 114, 64, 165, 128, 168, 0, 0, 0, 0, 0}, 85, 255}, - {{201, 143, 240, 240, 209, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 106}, - {{158, 19, 164, 196, 87, 162, 33, 120, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 170}, - {{5, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 86}, - {{34, 170, 246, 62, 198, 85, 193, 227, 252, 68, 0, 0, 0, 0, 0, 0}, 79, 155}, - {{21, 52, 9, 86, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 35, 65}, - {{203, 81, 49, 171, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 39}, - {{211, 218, 87, 244, 93, 181, 118, 41, 156, 143, 254, 0, 0, 0, 0, 0}, 90, 162}, - {{77, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 69}, - {{158, 219, 219, 39, 4, 219, 100, 63, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 163}, - {{61, 50, 232, 1, 185, 252, 243, 54, 189, 240, 170, 192, 0, 0, 0, 0}, 90, 116}, - {{241, 143, 33, 19, 247, 55, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 19}, - {{61, 28, 61, 252, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 48}, - {{102, 112, 194, 108, 90, 253, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 230}, - {{74, 88, 58, 66, 172, 41, 144, 204, 195, 240, 0, 0, 0, 0, 0, 0}, 78, 155}, - {{44, 148, 187, 58, 190, 59, 190, 187, 124, 138, 222, 131, 0, 0, 0, 0}, 96, 158}, - {{67, 7, 216, 139, 93, 224, 20, 135, 186, 86, 209, 111, 60, 80, 0, 0}, 113, 252}, - {{209, 26, 12, 174, 5, 101, 164, 181, 237, 63, 192, 57, 54, 120, 0, 0}, 110, 176}, - {{4, 66, 232, 52, 239, 56, 48, 58, 192, 0, 0, 0, 0, 0, 0, 0}, 66, 211}, - {{158, 165, 2, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 15}, - {{85, 204, 245, 198, 68, 44, 39, 71, 32, 0, 0, 0, 0, 0, 0, 0}, 68, 95}, - {{181, 134, 25, 87, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 169}, - {{26, 230, 61, 36, 79, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 249}, - {{5, 170, 198, 139, 65, 186, 188, 45, 42, 253, 165, 89, 206, 0, 0, 0}, 105, 61}, - {{211, 245, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 63}, - {{117, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 43}, - {{103, 17, 123, 102, 70, 206, 90, 92, 124, 198, 0, 0, 0, 0, 0, 0}, 81, 228}, - {{192, 237, 88, 244, 53, 30, 61, 160, 143, 64, 0, 0, 0, 0, 0, 0}, 78, 165}, - {{199, 82, 217, 183, 2, 179, 195, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 3}, - {{157, 230, 79, 162, 57, 125, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 211}, - {{27, 67, 64, 235, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 210}, - {{72, 158, 163, 106, 193, 137, 190, 7, 250, 165, 249, 73, 64, 0, 0, 0}, 99, 61}, - {{34, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 120}, - {{215, 141, 95, 192, 189, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 94}, - {{31, 181, 56, 141, 120, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 153}, - {{153, 73, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 221}, - {{162, 107, 41, 189, 165, 155, 22, 139, 165, 72, 96, 0, 0, 0, 0, 0}, 87, 163}, - {{218, 17, 204, 165, 217, 251, 107, 45, 29, 15, 192, 167, 75, 0, 0, 0}, 106, 188}, - {{200, 124, 238, 213, 35, 228, 94, 141, 86, 187, 101, 60, 115, 52, 131, 16}, 124, 15}, - {{74, 237, 160, 56, 141, 217, 191, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 28}, - {{163, 47, 242, 103, 173, 217, 88, 154, 38, 200, 32, 0, 0, 0, 0, 0}, 84, 240}, - {{20, 227, 128, 28, 144, 147, 22, 13, 94, 129, 107, 88, 0, 0, 0, 0}, 93, 59}, - {{95, 144, 229, 107, 218, 125, 204, 233, 161, 42, 180, 64, 0, 0, 0, 0}, 90, 195}, - {{155, 220, 83, 208, 108, 16, 134, 156, 128, 0, 0, 0, 0, 0, 0, 0}, 66, 10}, - {{179, 138, 55, 80, 190, 153, 12, 237, 22, 120, 69, 0, 0, 0, 0, 0}, 88, 206}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 137}, - {{3, 119, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 225}, - {{13, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 223}, - {{117, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15, 29}, - {{164, 19, 195, 47, 136, 190, 156, 255, 30, 74, 143, 134, 162, 0, 0, 0}, 103, 166}, - {{40, 235, 94, 135, 135, 230, 71, 33, 64, 233, 0, 0, 0, 0, 0, 0}, 80, 178}, - {{222, 151, 166, 97, 129, 250, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 38}, - {{174, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 141}, - {{6, 189, 100, 150, 250, 13, 46, 98, 228, 139, 50, 52, 52, 196, 128, 0}, 116, 230}, - {{75, 252, 89, 205, 37, 52, 106, 79, 188, 120, 54, 119, 160, 0, 0, 0}, 99, 124}, - {{38, 18, 146, 6, 63, 64, 231, 10, 152, 199, 5, 143, 147, 4, 252, 0}, 118, 54}, - {{111, 119, 169, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 162}, - {{105, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 32}, - {{143, 57, 57, 101, 98, 182, 74, 227, 205, 143, 253, 237, 8, 0, 0, 0}, 102, 237}, - {{30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 215}, - {{14, 232, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 138}, - {{14, 53, 67, 216, 229, 155, 149, 139, 31, 253, 184, 126, 133, 108, 40, 0}, 118, 73}, - {{22, 58, 40, 143, 188, 132, 239, 14, 181, 252, 81, 192, 0, 0, 0, 0}, 90, 43}, - {{11, 222, 185, 243, 248, 150, 79, 230, 214, 213, 3, 23, 193, 196, 0, 0}, 112, 88}, - {{14, 226, 198, 117, 84, 93, 22, 96, 77, 241, 173, 68, 68, 204, 72, 0}, 119, 91}, - {{15, 103, 247, 219, 150, 142, 92, 50, 144, 0, 0, 0, 0, 0, 0, 0}, 69, 140}, - {{0, 213, 77, 244, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 65}, - {{178, 174, 174, 239, 72, 181, 36, 217, 40, 169, 12, 104, 149, 157, 125, 128}, 122, 201}, - {{118, 53, 55, 17, 97, 227, 243, 176, 2, 0, 0, 0, 0, 0, 0, 0}, 72, 69}, - {{21, 253, 4, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 35, 170}, - {{5, 249, 186, 133, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 192}, - {{47, 79, 35, 66, 11, 178, 161, 28, 87, 180, 45, 128, 0, 0, 0, 0}, 89, 21}, - {{242, 227, 20, 73, 150, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 35}, - {{121, 169, 102, 118, 157, 192, 154, 186, 126, 0, 0, 0, 0, 0, 0, 0}, 71, 235}, - {{9, 138, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 240}, - {{45, 173, 14, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 136}, - {{127, 47, 51, 201, 236, 45, 142, 80, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 186}, - {{247, 233, 34, 38, 181, 207, 127, 20, 224, 118, 59, 148, 0, 0, 0, 0}, 95, 174}, - {{126, 187, 198, 104, 245, 223, 219, 18, 31, 124, 0, 0, 0, 0, 0, 0}, 79, 153}, - {{3, 163, 107, 228, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 35, 118}, - {{167, 109, 2, 95, 11, 62, 45, 128, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 113}, - {{76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 58}, - {{58, 190, 204, 151, 222, 147, 47, 78, 38, 203, 9, 17, 64, 0, 0, 0}, 101, 206}, - {{254, 220, 254, 220, 204, 79, 35, 127, 242, 63, 106, 232, 127, 180, 0, 0}, 111, 42}, - {{77, 156, 8, 209, 181, 37, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 230}, - {{65, 89, 137, 76, 208, 199, 166, 90, 128, 0, 0, 0, 0, 0, 0, 0}, 67, 6}, - {{47, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 254}, - {{172, 154, 12, 108, 77, 37, 106, 8, 234, 7, 248, 212, 112, 160, 0, 0}, 108, 214}, - {{254, 117, 239, 244, 154, 89, 166, 241, 12, 108, 127, 153, 206, 160, 0, 0}, 107, 43}, - {{113, 160, 206, 52, 143, 12, 9, 148, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 178}, - {{178, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 179}, - {{229, 177, 28, 106, 59, 75, 182, 241, 36, 79, 224, 0, 0, 0, 0, 0}, 87, 236}, - {{156, 72, 93, 193, 50, 235, 75, 228, 88, 115, 89, 119, 128, 0, 0, 0}, 98, 184}, - {{28, 232, 28, 249, 83, 105, 211, 7, 136, 147, 231, 64, 0, 0, 0, 0}, 91, 95}, - {{217, 33, 23, 107, 74, 42, 135, 197, 144, 34, 40, 243, 13, 126, 36, 136}, 127, 152}, - {{64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 113}, - {{85, 172, 121, 126, 213, 57, 225, 54, 197, 73, 85, 251, 9, 64, 0, 0}, 108, 137}, - {{104, 46, 25, 71, 86, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 224}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 61}, - {{241, 113, 254, 106, 53, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 205}, - {{29, 36, 12, 244, 197, 127, 240, 8, 167, 134, 154, 248, 199, 123, 143, 240}, 124, 170}, - {{58, 29, 129, 94, 43, 139, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 117}, - {{213, 124, 147, 196, 7, 82, 67, 70, 228, 0, 0, 0, 0, 0, 0, 0}, 70, 225}, - {{164, 168, 161, 140, 87, 85, 250, 41, 34, 0, 0, 0, 0, 0, 0, 0}, 72, 34}, - {{186, 142, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 5}, - {{237, 249, 9, 70, 247, 97, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 92}, - {{155, 92, 145, 218, 125, 226, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 230}, - {{35, 169, 62, 156, 86, 4, 125, 219, 119, 113, 191, 75, 198, 113, 0, 0}, 112, 61}, - {{207, 63, 96, 186, 26, 68, 115, 161, 163, 59, 190, 166, 18, 78, 232, 0}, 117, 221}, - {{86, 40, 200, 199, 247, 86, 159, 179, 191, 184, 117, 173, 211, 158, 0, 128}, 121, 105}, - {{104, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 181}, - {{205, 35, 123, 178, 36, 64, 62, 153, 195, 250, 0, 0, 0, 0, 0, 0}, 79, 110}, - {{117, 40, 57, 157, 138, 160, 223, 59, 155, 145, 64, 0, 0, 0, 0, 0}, 86, 103}, - {{74, 166, 140, 146, 74, 72, 229, 99, 167, 124, 107, 117, 217, 14, 246, 64}, 123, 218}, - {{12, 222, 244, 183, 83, 146, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 146}, - {{11, 98, 146, 110, 95, 96, 80, 142, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 90}, - {{235, 5, 187, 199, 30, 170, 82, 187, 228, 159, 22, 25, 204, 112, 0, 0}, 108, 197}, - {{35, 96, 146, 145, 155, 116, 252, 181, 29, 205, 230, 246, 30, 0, 0, 0}, 103, 158}, - {{174, 38, 56, 244, 227, 102, 252, 237, 128, 86, 0, 0, 0, 0, 0, 0}, 81, 118}, - {{65, 134, 37, 58, 90, 125, 60, 84, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 95}, - {{253, 117, 135, 98, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 152}, - {{111, 115, 188, 184, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 239}, - {{202, 24, 89, 9, 149, 45, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 48}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 228}, - {{244, 98, 52, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 247}, - {{151, 167, 43, 178, 116, 194, 173, 126, 236, 98, 40, 0, 0, 0, 0, 0}, 85, 12}, - {{60, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 129}, - {{208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 50}, - {{126, 11, 216, 242, 7, 45, 121, 208, 110, 135, 210, 75, 59, 182, 228, 42}, 128, 250}, - {{217, 26, 184, 146, 3, 18, 240, 15, 135, 8, 0, 0, 0, 0, 0, 0}, 77, 249}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 230}, - {{145, 28, 29, 184, 2, 85, 234, 135, 98, 111, 136, 32, 0, 0, 0, 0}, 92, 228}, - {{108, 104, 255, 254, 34, 95, 72, 157, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 181}, - {{153, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 206}, - {{22, 250, 130, 201, 132, 248, 189, 108, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 122}, - {{158, 165, 234, 18, 44, 61, 82, 61, 235, 0, 0, 0, 0, 0, 0, 0}, 72, 81}, - {{236, 57, 124, 110, 124, 218, 82, 70, 142, 78, 18, 128, 0, 0, 0, 0}, 95, 175}, - {{94, 209, 200, 201, 149, 162, 248, 134, 239, 226, 1, 237, 16, 134, 56, 0}, 118, 170}, - {{187, 42, 31, 144, 236, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 174}, - {{90, 214, 185, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 104}, - {{194, 220, 211, 212, 211, 32, 196, 98, 71, 62, 153, 103, 80, 35, 128, 0}, 114, 113}, - {{24, 255, 158, 64, 180, 148, 10, 81, 243, 247, 0, 0, 0, 0, 0, 0}, 80, 89}, - {{231, 155, 100, 242, 112, 160, 160, 95, 98, 253, 219, 21, 239, 90, 0, 0}, 113, 151}, - {{225, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 108}, - {{136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 224}, - {{250, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 95}, - {{72, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 173}, - {{185, 51, 51, 167, 18, 44, 36, 59, 35, 135, 20, 104, 0, 0, 0, 0}, 93, 176}, - {{57, 146, 252, 60, 197, 68, 39, 162, 80, 198, 137, 50, 97, 92, 124, 0}, 119, 84}, - {{254, 46, 242, 105, 86, 94, 96, 14, 130, 176, 0, 0, 0, 0, 0, 0}, 78, 104}, - {{247, 202, 176, 76, 69, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 236}, - {{50, 233, 203, 77, 42, 21, 115, 163, 166, 138, 192, 52, 178, 37, 112, 0}, 116, 153}, - {{62, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 190}, - {{53, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 202}, - {{198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 54}, - {{189, 234, 106, 247, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 156}, - {{110, 24, 228, 65, 216, 147, 9, 48, 60, 179, 172, 91, 115, 185, 227, 96}, 126, 245}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 218}, - {{74, 177, 89, 218, 248, 18, 176, 39, 118, 173, 201, 152, 0, 0, 0, 0}, 93, 72}, - {{31, 13, 153, 92, 27, 122, 150, 232, 88, 95, 202, 171, 208, 158, 0, 0}, 112, 183}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 183}, - {{63, 37, 46, 158, 139, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 241}, - {{53, 209, 59, 13, 202, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 106}, - {{184, 44, 149, 221, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 180}, - {{222, 134, 37, 62, 223, 193, 39, 246, 15, 151, 200, 146, 0, 0, 0, 0}, 96, 142}, - {{199, 176, 189, 37, 233, 177, 252, 216, 94, 175, 253, 119, 96, 0, 0, 0}, 100, 6}, - {{44, 195, 201, 106, 209, 120, 122, 38, 43, 30, 142, 22, 196, 175, 100, 0}, 118, 33}, - {{33, 166, 10, 174, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 224}, - {{54, 1, 189, 195, 133, 49, 36, 80, 138, 200, 0, 0, 0, 0, 0, 0}, 78, 14}, - {{241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 149}, - {{221, 131, 4, 247, 112, 89, 187, 119, 219, 80, 122, 156, 216, 160, 0, 0}, 108, 131}, - {{102, 20, 46, 129, 202, 247, 129, 1, 237, 71, 103, 58, 217, 44, 4, 0}, 121, 133}, - {{107, 156, 151, 44, 215, 98, 171, 126, 85, 32, 42, 128, 0, 0, 0, 0}, 89, 33}, - {{54, 25, 70, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 204}, - {{149, 211, 242, 14, 112, 219, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 43}, - {{95, 26, 143, 193, 8, 76, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 168}, - {{63, 102, 244, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 180}, - {{64, 85, 124, 226, 59, 239, 64, 130, 68, 122, 93, 74, 32, 37, 0, 0}, 112, 208}, - {{113, 90, 253, 149, 3, 218, 34, 215, 3, 143, 192, 64, 0, 0, 0, 0}, 90, 25}, - {{75, 231, 33, 5, 11, 94, 117, 104, 150, 60, 72, 161, 96, 38, 0, 0}, 111, 50}, - {{52, 13, 248, 1, 251, 14, 50, 29, 212, 123, 130, 177, 101, 96, 0, 0}, 109, 110}, - {{248, 221, 150, 132, 252, 82, 96, 2, 80, 232, 97, 239, 253, 64, 0, 0}, 109, 21}, - {{136, 77, 164, 161, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 147}, - {{1, 33, 66, 254, 144, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 43, 56}, - {{181, 25, 186, 225, 109, 190, 76, 158, 118, 122, 20, 64, 125, 55, 8, 0}, 117, 144}, - {{191, 187, 160, 140, 17, 6, 80, 120, 236, 212, 104, 144, 128, 0, 0, 0}, 100, 198}, - {{201, 61, 150, 254, 70, 77, 214, 211, 171, 163, 245, 64, 0, 0, 0, 0}, 90, 235}, - {{143, 226, 190, 50, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 105}, - {{65, 168, 226, 36, 201, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 138}, - {{136, 40, 65, 90, 47, 16, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 122}, - {{94, 189, 224, 200, 170, 11, 79, 172, 0, 0, 0, 0, 0, 0, 0, 0}, 65, 193}, - {{236, 41, 169, 234, 14, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 43, 231}, - {{1, 40, 140, 95, 81, 173, 250, 248, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 250}, - {{83, 176, 146, 112, 89, 156, 57, 220, 125, 48, 44, 0, 0, 0, 0, 0}, 86, 24}, - {{76, 125, 228, 249, 243, 160, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 191}, - {{10, 203, 204, 49, 212, 115, 125, 4, 239, 122, 81, 34, 1, 198, 216, 0}, 117, 111}, - {{74, 214, 23, 44, 211, 40, 161, 61, 237, 190, 155, 59, 173, 42, 0, 0}, 111, 205}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 133}, - {{127, 0, 130, 61, 209, 5, 232, 35, 35, 42, 114, 52, 169, 234, 191, 0}, 122, 122}, - {{201, 107, 210, 13, 187, 62, 145, 28, 31, 189, 56, 0, 0, 0, 0, 0}, 87, 227}, - {{147, 171, 63, 145, 47, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 53}, - {{93, 232, 10, 97, 21, 243, 213, 135, 200, 0, 0, 0, 0, 0, 0, 0}, 72, 224}, - {{144, 121, 41, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 199}, - {{116, 105, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 79}, - {{142, 149, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 19}, - {{97, 0, 228, 158, 50, 233, 251, 249, 0, 66, 197, 226, 0, 0, 0, 0}, 96, 211}, - {{114, 228, 199, 155, 175, 104, 26, 213, 66, 249, 120, 218, 164, 252, 212, 0}, 120, 6}, - {{224, 166, 76, 200, 121, 60, 110, 65, 60, 95, 137, 190, 92, 218, 218, 0}, 121, 143}, - {{139, 219, 92, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 135}, - {{203, 237, 64, 189, 28, 13, 75, 197, 219, 243, 172, 3, 142, 32, 0, 0}, 109, 21}, - {{237, 186, 88, 254, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 220}, - {{182, 230, 93, 162, 129, 25, 56, 196, 112, 0, 0, 0, 0, 0, 0, 0}, 68, 151}, - {{245, 45, 69, 226, 90, 212, 254, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 111}, - {{107, 229, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 63}, - {{119, 208, 177, 235, 222, 252, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 112}, - {{178, 151, 220, 162, 120, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 48}, - {{109, 26, 95, 170, 166, 151, 137, 83, 226, 82, 5, 114, 253, 210, 18, 12}, 126, 100}, - {{126, 27, 252, 19, 219, 129, 121, 48, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 156}, - {{211, 195, 152, 145, 154, 93, 228, 215, 135, 101, 28, 82, 0, 0, 0, 0}, 95, 120}, - {{252, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 5}, - {{192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 103}, - {{64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 84}, - {{225, 179, 43, 43, 222, 145, 205, 238, 164, 158, 147, 229, 56, 0, 0, 0}, 101, 24}, - {{208, 127, 151, 24, 64, 113, 47, 85, 209, 79, 144, 0, 0, 0, 0, 0}, 86, 81}, - {{178, 144, 203, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 96}, - {{56, 227, 139, 4, 86, 87, 180, 1, 215, 167, 237, 156, 111, 64, 47, 0}, 121, 6}, - {{80, 76, 204, 119, 172, 169, 254, 81, 104, 166, 219, 44, 173, 161, 212, 0}, 119, 40}, - {{129, 141, 139, 34, 241, 101, 223, 144, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 143}, - {{85, 102, 137, 98, 65, 103, 54, 142, 144, 0, 0, 0, 0, 0, 0, 0}, 68, 69}, - {{56, 31, 159, 13, 201, 139, 161, 31, 89, 137, 4, 0, 0, 0, 0, 0}, 92, 48}, - {{229, 221, 54, 216, 223, 27, 196, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 115}, - {{5, 144, 176, 43, 180, 187, 20, 49, 59, 73, 108, 34, 83, 32, 192, 0}, 115, 130}, - {{24, 217, 205, 193, 74, 123, 160, 106, 103, 74, 200, 0, 0, 0, 0, 0}, 86, 57}, - {{247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 97}, - {{12, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 146}, - {{160, 28, 201, 119, 148, 93, 251, 118, 28, 179, 123, 52, 71, 232, 48, 0}, 117, 194}, - {{152, 126, 17, 54, 101, 56, 130, 1, 205, 41, 207, 90, 151, 123, 128, 0}, 114, 129}, - {{77, 165, 29, 239, 95, 242, 34, 1, 11, 204, 135, 239, 128, 0, 0, 0}, 97, 159}, - {{183, 108, 146, 118, 74, 190, 7, 141, 9, 92, 2, 2, 8, 218, 120, 0}, 117, 242}, - {{37, 152, 29, 239, 242, 53, 56, 143, 219, 22, 14, 158, 49, 0, 0, 0}, 104, 162}, - {{198, 53, 241, 102, 240, 244, 97, 203, 62, 128, 213, 214, 220, 0, 0, 0}, 102, 140}, - {{144, 89, 48, 42, 249, 231, 189, 178, 232, 199, 30, 58, 63, 57, 0, 0}, 113, 77}, - {{68, 212, 177, 123, 44, 224, 19, 172, 89, 87, 192, 0, 0, 0, 0, 0}, 82, 121}, - {{252, 29, 179, 224, 4, 121, 205, 67, 152, 0, 0, 0, 0, 0, 0, 0}, 69, 102}, - {{28, 110, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 28}, - {{24, 88, 231, 1, 4, 71, 71, 241, 252, 14, 197, 0, 0, 0, 0, 0}, 89, 154}, - {{63, 131, 43, 76, 58, 140, 163, 74, 158, 80, 0, 0, 0, 0, 0, 0}, 76, 39}, - {{56, 28, 147, 149, 98, 93, 216, 216, 203, 156, 0, 0, 0, 0, 0, 0}, 78, 163}, - {{134, 169, 6, 103, 161, 244, 134, 117, 16, 0, 0, 0, 0, 0, 0, 0}, 68, 42}, - {{143, 247, 125, 190, 106, 50, 204, 98, 250, 151, 161, 96, 0, 0, 0, 0}, 92, 207}, - {{235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 25}, - {{46, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 150}, - {{171, 35, 128, 117, 74, 29, 199, 67, 109, 176, 0, 0, 0, 0, 0, 0}, 76, 103}, - {{220, 233, 236, 112, 135, 136, 215, 43, 42, 0, 0, 0, 0, 0, 0, 0}, 71, 155}, - {{228, 11, 144, 117, 206, 192, 118, 25, 141, 78, 4, 105, 0, 0, 0, 0}, 96, 142}, - {{195, 67, 194, 229, 14, 53, 129, 7, 30, 208, 38, 100, 182, 59, 0, 0}, 112, 2}, - {{25, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 59}, - {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 112}, - {{26, 203, 217, 152, 16, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 166}, - {{250, 213, 14, 235, 110, 171, 174, 23, 102, 128, 0, 0, 0, 0, 0, 0}, 73, 62}, - {{175, 230, 160, 13, 187, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 176}, - {{92, 155, 156, 93, 191, 73, 28, 82, 187, 129, 57, 5, 16, 0, 0, 0}, 100, 6}, - {{45, 203, 3, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 26}, - {{120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 6}, - {{216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 13}, - {{135, 215, 0, 71, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 41}, - {{221, 149, 1, 40, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 135}, - {{95, 143, 255, 194, 2, 157, 191, 113, 10, 229, 204, 56, 0, 0, 0, 0}, 93, 171}, - {{202, 212, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 20}, - {{147, 203, 238, 120, 194, 23, 25, 58, 208, 177, 169, 0, 0, 0, 0, 0}, 89, 119}, - {{137, 170, 113, 252, 215, 194, 224, 146, 233, 87, 86, 192, 26, 46, 0, 0}, 112, 49}, - {{224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 141}, - {{250, 90, 241, 174, 163, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 132}, - {{66, 190, 202, 144, 122, 86, 22, 103, 107, 164, 57, 54, 228, 128, 0, 0}, 105, 176}, - {{76, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 12, 186}, - {{120, 246, 1, 52, 187, 163, 78, 105, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 93}, - {{137, 242, 136, 71, 98, 10, 53, 97, 160, 85, 132, 127, 185, 222, 0, 0}, 111, 242}, - {{255, 133, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 163}, - {{128, 177, 92, 155, 91, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 184}, - {{45, 120, 186, 192, 240, 199, 178, 95, 32, 0, 0, 0, 0, 0, 0, 0}, 68, 188}, - {{151, 98, 103, 254, 90, 6, 10, 109, 14, 158, 69, 29, 140, 237, 40, 232}, 126, 193}, - {{148, 164, 81, 85, 76, 14, 84, 64, 89, 176, 0, 0, 0, 0, 0, 0}, 78, 63}, - {{145, 187, 165, 136, 88, 30, 107, 191, 205, 120, 119, 216, 158, 123, 64, 0}, 115, 160}, - {{78, 120, 28, 243, 216, 180, 87, 19, 253, 16, 110, 33, 228, 24, 232, 0}, 117, 251}, - {{74, 6, 166, 166, 183, 157, 96, 84, 151, 0, 0, 0, 0, 0, 0, 0}, 72, 228}, - {{89, 96, 4, 221, 214, 253, 58, 49, 9, 0, 0, 0, 0, 0, 0, 0}, 72, 168}, - {{97, 9, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 194}, - {{213, 215, 45, 200, 170, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 166}, - {{5, 14, 92, 0, 28, 245, 130, 202, 32, 40, 207, 77, 166, 170, 246, 64}, 122, 210}, - {{77, 45, 43, 71, 202, 0, 157, 146, 59, 91, 225, 0, 0, 0, 0, 0}, 89, 254}, - {{101, 174, 94, 168, 162, 171, 71, 12, 16, 224, 0, 0, 0, 0, 0, 0}, 75, 49}, - {{58, 17, 187, 194, 87, 73, 215, 103, 180, 12, 40, 66, 0, 0, 0, 0}, 96, 95}, - {{160, 91, 68, 81, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 193}, - {{94, 112, 249, 13, 167, 245, 101, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 155}, - {{236, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15, 133}, - {{168, 243, 103, 221, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 10}, - {{86, 194, 218, 188, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 31}, - {{232, 3, 134, 67, 63, 196, 86, 14, 170, 243, 77, 134, 187, 140, 72, 18}, 127, 98}, - {{55, 253, 19, 201, 199, 71, 229, 218, 54, 64, 12, 162, 0, 0, 0, 0}, 96, 22}, - {{142, 34, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 214}, - {{213, 16, 208, 50, 100, 33, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 217}, - {{117, 237, 132, 185, 184, 246, 79, 42, 103, 98, 162, 243, 128, 0, 0, 0}, 98, 102}, - {{120, 25, 214, 222, 61, 157, 203, 102, 3, 146, 192, 0, 0, 0, 0, 0}, 83, 169}, - {{222, 46, 254, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 152}, - {{254, 70, 158, 171, 11, 245, 223, 97, 70, 17, 27, 192, 186, 0, 0, 0}, 103, 214}, - {{192, 128, 228, 17, 68, 20, 44, 31, 52, 34, 212, 1, 224, 0, 0, 0}, 99, 178}, - {{237, 229, 203, 8, 121, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 164}, - {{6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 15}, - {{71, 197, 251, 122, 138, 232, 12, 241, 116, 240, 0, 0, 0, 0, 0, 0}, 76, 94}, - {{18, 241, 135, 210, 233, 54, 121, 185, 4, 0, 0, 0, 0, 0, 0, 0}, 70, 239}, - {{32, 50, 213, 63, 73, 217, 180, 21, 187, 128, 0, 0, 0, 0, 0, 0}, 73, 82}, - {{203, 166, 233, 73, 92, 182, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 54}, - {{56, 162, 126, 4, 18, 195, 192, 64, 164, 156, 119, 196, 64, 0, 0, 0}, 98, 47}, - {{120, 87, 81, 136, 180, 179, 68, 148, 243, 38, 80, 0, 0, 0, 0, 0}, 84, 214}, - {{64, 244, 193, 50, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 215}, - {{91, 168, 253, 158, 131, 83, 159, 163, 113, 169, 112, 0, 0, 0, 0, 0}, 84, 153}, - {{159, 103, 102, 132, 111, 46, 18, 77, 36, 15, 137, 33, 177, 31, 243, 192}, 122, 245}, - {{123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 118}, - {{67, 81, 226, 190, 7, 79, 71, 250, 155, 245, 44, 81, 215, 213, 171, 224}, 123, 128}, - {{103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 7}, - {{246, 44, 168, 200, 198, 238, 52, 196, 125, 115, 0, 0, 0, 0, 0, 0}, 80, 152}, - {{205, 14, 186, 252, 239, 213, 59, 119, 105, 37, 140, 209, 4, 231, 0, 0}, 114, 248}, - {{70, 91, 254, 106, 94, 71, 170, 19, 158, 242, 192, 0, 0, 0, 0, 0}, 85, 143}, - {{250, 86, 233, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 159}, - {{122, 222, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 11}, - {{27, 224, 235, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 110}, - {{239, 100, 224, 3, 46, 127, 150, 251, 204, 120, 228, 64, 0, 0, 0, 0}, 97, 181}, - {{144, 115, 182, 206, 146, 13, 21, 111, 37, 70, 179, 129, 173, 82, 93, 128}, 121, 4}, - {{73, 190, 57, 243, 49, 51, 15, 209, 0, 0, 0, 0, 0, 0, 0, 0}, 67, 101}, - {{18, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 38}, - {{23, 37, 236, 177, 186, 7, 209, 135, 114, 44, 0, 0, 0, 0, 0, 0}, 78, 57}, - {{200, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 142}, - {{181, 255, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 184}, - {{135, 168, 6, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 91}, - {{200, 224, 33, 245, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 224}, - {{70, 111, 10, 62, 200, 224, 38, 204, 14, 164, 0, 0, 0, 0, 0, 0}, 78, 114}, - {{158, 133, 252, 18, 242, 12, 16, 60, 5, 52, 251, 179, 38, 235, 12, 0}, 118, 184}, - {{2, 23, 116, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 215}, - {{33, 25, 170, 74, 215, 134, 151, 181, 175, 232, 20, 155, 189, 242, 13, 0}, 120, 167}, - {{160, 186, 218, 183, 167, 84, 59, 152, 13, 137, 80, 128, 0, 0, 0, 0}, 89, 233}, - {{32, 141, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 101}, - {{207, 24, 202, 226, 191, 136, 78, 124, 160, 0, 0, 0, 0, 0, 0, 0}, 67, 139}, - {{210, 173, 172, 27, 197, 57, 114, 146, 169, 32, 0, 0, 0, 0, 0, 0}, 79, 32}, - {{95, 113, 12, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 57}, - {{129, 108, 186, 28, 19, 229, 96, 134, 199, 254, 199, 64, 0, 0, 0, 0}, 91, 151}, - {{103, 226, 38, 123, 35, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 0}, - {{41, 117, 43, 35, 208, 115, 73, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 227}, - {{42, 220, 61, 34, 199, 183, 42, 16, 223, 135, 0, 135, 213, 150, 100, 0}, 118, 124}, - {{165, 227, 96, 243, 112, 171, 117, 106, 50, 37, 82, 60, 80, 0, 0, 0}, 104, 228}, - {{158, 60, 111, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 64}, - {{124, 108, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 179}, - {{232, 68, 132, 159, 156, 103, 95, 190, 76, 0, 0, 0, 0, 0, 0, 0}, 70, 107}, - {{70, 77, 240, 209, 72, 63, 63, 45, 125, 79, 77, 41, 13, 0, 0, 0}, 104, 206}, - {{146, 254, 7, 5, 68, 240, 67, 237, 112, 0, 0, 0, 0, 0, 0, 0}, 68, 95}, - {{162, 223, 117, 27, 2, 156, 94, 170, 157, 114, 162, 50, 0, 0, 0, 0}, 96, 219}, - {{161, 62, 191, 68, 239, 73, 100, 37, 168, 254, 139, 202, 252, 65, 74, 0}, 119, 138}, - {{248, 122, 115, 81, 15, 158, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 84}, - {{8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 161}, - {{142, 96, 105, 133, 251, 57, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 25}, - {{138, 196, 139, 131, 233, 93, 65, 242, 86, 169, 7, 72, 82, 128, 0, 0}, 107, 113}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 46}, - {{175, 151, 75, 238, 26, 12, 100, 186, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 72}, - {{82, 205, 211, 176, 170, 79, 57, 153, 161, 218, 32, 48, 0, 0, 0, 0}, 93, 230}, - {{227, 123, 232, 74, 236, 202, 211, 121, 200, 8, 59, 189, 81, 219, 144, 0}, 117, 142}, - {{205, 196, 89, 90, 103, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 134}, - {{63, 145, 23, 127, 102, 216, 49, 36, 168, 164, 59, 133, 18, 146, 0, 0}, 112, 100}, - {{213, 72, 154, 16, 230, 236, 218, 203, 223, 51, 31, 251, 103, 64, 0, 0}, 109, 45}, - {{126, 148, 232, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 219}, - {{160, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 52}, - {{137, 38, 146, 20, 99, 188, 83, 123, 159, 159, 64, 0, 0, 0, 0, 0}, 83, 240}, - {{123, 228, 36, 44, 242, 29, 51, 228, 140, 60, 237, 0, 0, 0, 0, 0}, 90, 13}, - {{163, 169, 25, 89, 190, 114, 165, 158, 140, 210, 192, 0, 0, 0, 0, 0}, 84, 191}, - {{225, 38, 70, 89, 218, 236, 60, 5, 69, 163, 248, 50, 163, 64, 0, 0}, 106, 95}, - {{91, 94, 36, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 65}, - {{209, 238, 110, 0, 2, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 195}, - {{57, 17, 224, 164, 69, 95, 138, 172, 111, 55, 239, 167, 160, 0, 0, 0}, 103, 21}, - {{112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 114}, - {{102, 96, 223, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 92}, - {{137, 204, 150, 75, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 237}, - {{136, 56, 252, 240, 85, 48, 248, 231, 17, 49, 47, 238, 15, 233, 159, 184}, 125, 172}, - {{57, 31, 132, 123, 234, 255, 37, 82, 167, 204, 37, 158, 128, 0, 0, 0}, 98, 116}, - {{55, 198, 139, 219, 161, 156, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 54}, - {{44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 203}, - {{53, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 74}, - {{227, 62, 107, 236, 118, 156, 60, 34, 31, 179, 76, 221, 0, 0, 0, 0}, 96, 220}, - {{105, 40, 240, 216, 91, 61, 19, 128, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 219}, - {{96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 179}, - {{118, 142, 251, 249, 128, 105, 113, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 61, 194}, - {{101, 70, 196, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 187}, - {{245, 173, 165, 177, 200, 161, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 79}, - {{0, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 87}, - {{92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 126}, - {{125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 106}, - {{56, 59, 35, 82, 101, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 96}, - {{184, 72, 77, 251, 8, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 45}, - {{143, 74, 132, 205, 218, 247, 30, 160, 145, 199, 138, 12, 89, 220, 0, 0}, 110, 8}, - {{30, 178, 111, 225, 73, 79, 173, 52, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 226}, - {{224, 48, 154, 231, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 222}, - {{123, 144, 170, 143, 85, 169, 130, 245, 214, 0, 0, 0, 0, 0, 0, 0}, 71, 218}, - {{166, 224, 212, 100, 149, 55, 35, 210, 246, 108, 41, 245, 127, 174, 128, 0}, 116, 59}, - {{75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 80}, - {{197, 128, 190, 87, 47, 53, 92, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 177}, - {{249, 10, 76, 217, 225, 20, 124, 205, 44, 159, 190, 8, 0, 0, 0, 0}, 98, 44}, - {{180, 226, 0, 167, 137, 232, 174, 120, 113, 95, 22, 184, 0, 0, 0, 0}, 93, 206}, - {{123, 153, 102, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 64}, - {{5, 144, 206, 158, 239, 189, 171, 120, 69, 46, 128, 237, 0, 0, 0, 0}, 96, 236}, - {{159, 235, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 101}, - {{42, 194, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 49}, - {{205, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 179}, - {{19, 65, 141, 20, 127, 77, 70, 205, 151, 115, 157, 23, 118, 128, 0, 0}, 109, 112}, - {{96, 11, 214, 40, 245, 251, 61, 64, 128, 241, 183, 183, 0, 0, 0, 0}, 96, 31}, - {{120, 4, 235, 112, 34, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 111}, - {{110, 127, 207, 76, 100, 148, 130, 206, 249, 2, 104, 0, 0, 0, 0, 0}, 86, 65}, - {{226, 190, 191, 249, 173, 96, 127, 200, 62, 20, 0, 0, 0, 0, 0, 0}, 78, 222}, - {{89, 88, 182, 14, 78, 122, 213, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 4}, - {{167, 94, 163, 227, 28, 111, 117, 103, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 67}, - {{57, 220, 53, 116, 243, 184, 242, 134, 16, 70, 83, 61, 161, 128, 0, 0}, 109, 197}, - {{63, 235, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 121}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 167}, - {{15, 159, 42, 167, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 140}, - {{216, 252, 113, 40, 239, 46, 172, 48, 103, 250, 82, 179, 136, 64, 0, 0}, 106, 193}, - {{158, 147, 16, 44, 124, 56, 44, 48, 138, 64, 169, 0, 0, 0, 0, 0}, 90, 47}, - {{238, 238, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 187}, - {{63, 159, 177, 162, 106, 212, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 102}, - {{59, 40, 252, 185, 187, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 237}, - {{2, 218, 11, 68, 173, 196, 16, 223, 2, 18, 122, 215, 154, 0, 0, 0}, 103, 237}, - {{3, 9, 206, 73, 108, 196, 183, 119, 141, 162, 10, 180, 115, 32, 0, 0}, 107, 115}, - {{17, 227, 208, 146, 63, 201, 73, 239, 29, 79, 80, 0, 0, 0, 0, 0}, 84, 217}, - {{115, 180, 176, 241, 52, 209, 6, 64, 189, 76, 0, 0, 0, 0, 0, 0}, 79, 21}, - {{191, 88, 98, 245, 91, 46, 137, 254, 170, 80, 11, 55, 212, 28, 128, 0}, 113, 3}, - {{97, 141, 171, 175, 22, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 62}, - {{32, 204, 102, 191, 164, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 80}, - {{29, 133, 210, 252, 124, 66, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 184}, - {{207, 179, 54, 144, 116, 67, 29, 64, 13, 199, 0, 0, 0, 0, 0, 0}, 80, 197}, - {{129, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 63}, - {{50, 152, 249, 143, 174, 234, 240, 48, 158, 255, 80, 105, 0, 0, 0, 0}, 99, 62}, - {{105, 208, 95, 218, 44, 11, 87, 134, 109, 18, 138, 66, 17, 69, 128, 0}, 114, 231}, - {{151, 79, 158, 220, 122, 101, 210, 164, 64, 0, 0, 0, 0, 0, 0, 0}, 67, 158}, - {{236, 97, 87, 155, 254, 137, 122, 208, 168, 201, 194, 118, 224, 0, 0, 0}, 101, 118}, - {{14, 229, 193, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 237}, - {{46, 154, 50, 80, 92, 147, 158, 86, 1, 112, 0, 0, 0, 0, 0, 0}, 79, 15}, - {{88, 131, 21, 84, 62, 86, 7, 110, 142, 251, 242, 110, 194, 175, 247, 0}, 122, 84}, - {{229, 216, 111, 92, 173, 32, 63, 70, 36, 84, 6, 74, 136, 166, 38, 0}, 119, 205}, - {{121, 147, 216, 245, 37, 189, 146, 63, 145, 74, 128, 0, 0, 0, 0, 0}, 82, 220}, - {{44, 26, 254, 11, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 42}, - {{209, 114, 97, 249, 227, 159, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 144}, - {{184, 244, 43, 117, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 74}, - {{60, 81, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 89}, - {{18, 40, 21, 113, 226, 91, 195, 88, 161, 19, 142, 0, 0, 0, 0, 0}, 88, 77}, - {{57, 0, 212, 158, 56, 51, 108, 198, 59, 5, 137, 196, 0, 0, 0, 0}, 94, 2}, - {{168, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 75}, - {{64, 181, 254, 103, 1, 230, 117, 199, 128, 0, 0, 0, 0, 0, 0, 0}, 65, 18}, - {{212, 48, 214, 127, 78, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 246}, - {{155, 185, 236, 163, 204, 49, 129, 120, 183, 47, 10, 243, 65, 92, 192, 0}, 114, 10}, - {{94, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 207}, - {{19, 210, 136, 113, 73, 79, 132, 196, 224, 0, 0, 0, 0, 0, 0, 0}, 68, 41}, - {{24, 203, 246, 242, 241, 223, 150, 237, 213, 202, 11, 128, 0, 0, 0, 0}, 89, 102}, - {{115, 59, 171, 221, 172, 181, 170, 67, 115, 205, 44, 107, 162, 67, 56, 0}, 118, 118}, - {{250, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 146}, - {{203, 240, 28, 158, 182, 12, 86, 182, 142, 47, 143, 57, 239, 0, 0, 0}, 104, 122}, - {{196, 218, 109, 52, 2, 0, 64, 153, 34, 250, 240, 185, 117, 0, 0, 0}, 107, 6}, - {{137, 131, 191, 40, 72, 209, 74, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 18}, - {{236, 126, 167, 37, 185, 20, 34, 207, 76, 0, 0, 0, 0, 0, 0, 0}, 70, 83}, - {{129, 192, 245, 137, 251, 52, 75, 68, 81, 112, 146, 133, 64, 0, 0, 0}, 99, 90}, - {{7, 31, 148, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 140}, - {{112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 242}, - {{167, 50, 202, 179, 74, 146, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 31}, - {{44, 188, 186, 250, 229, 71, 28, 118, 35, 253, 245, 191, 199, 18, 0, 0}, 111, 9}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 230}, - {{156, 163, 215, 175, 71, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 50}, - {{67, 24, 151, 198, 242, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 34}, - {{134, 107, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 11}, - {{35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 71}, - {{46, 196, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 146}, - {{82, 172, 8, 26, 154, 34, 125, 188, 5, 149, 159, 44, 78, 222, 236, 176}, 124, 249}, - {{78, 157, 79, 70, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 143}, - {{231, 5, 210, 247, 198, 5, 157, 191, 206, 225, 149, 142, 207, 40, 0, 0}, 110, 17}, - {{38, 254, 235, 199, 191, 60, 43, 159, 190, 243, 203, 185, 184, 218, 132, 0}, 119, 60}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 162}, - {{95, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 12, 5}, - {{17, 128, 244, 178, 160, 78, 83, 92, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 139}, - {{18, 102, 62, 251, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 8}, - {{30, 75, 108, 40, 231, 166, 233, 220, 163, 176, 252, 210, 60, 30, 128, 0}, 114, 246}, - {{18, 3, 207, 64, 25, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 171}, - {{52, 83, 235, 61, 164, 236, 83, 173, 143, 105, 14, 0, 0, 0, 0, 0}, 88, 206}, - {{166, 175, 186, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 163}, - {{221, 154, 82, 98, 41, 126, 85, 52, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 166}, - {{94, 84, 182, 120, 204, 232, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 128}, - {{27, 174, 227, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 59}, - {{218, 12, 4, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 179}, - {{9, 5, 190, 195, 60, 216, 80, 150, 128, 117, 86, 128, 128, 112, 98, 208}, 124, 87}, - {{7, 226, 104, 112, 212, 9, 172, 124, 209, 121, 170, 229, 44, 178, 128, 0}, 114, 29}, - {{47, 71, 174, 76, 52, 83, 23, 18, 106, 48, 56, 32, 0, 0, 0, 0}, 91, 184}, - {{51, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 45}, - {{28, 182, 167, 124, 28, 22, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 144}, - {{34, 61, 14, 51, 253, 17, 19, 170, 49, 206, 188, 207, 247, 167, 192, 0}, 114, 119}, - {{2, 235, 18, 14, 195, 66, 237, 30, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 113}, - {{51, 182, 142, 133, 127, 96, 159, 132, 99, 161, 64, 0, 0, 0, 0, 0}, 82, 50}, - {{170, 145, 230, 123, 215, 189, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 207}, - {{151, 166, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 3}, - {{16, 141, 196, 129, 132, 207, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 13}, - {{205, 25, 184, 191, 201, 206, 109, 224, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 42}, - {{48, 114, 33, 103, 247, 255, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 31}, - {{179, 156, 119, 146, 125, 21, 42, 146, 237, 213, 191, 132, 0, 0, 0, 0}, 94, 30}, - {{179, 129, 186, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 94}, - {{17, 179, 217, 188, 128, 212, 4, 4, 152, 0, 0, 0, 0, 0, 0, 0}, 71, 190}, - {{132, 63, 74, 89, 209, 64, 63, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 238}, - {{16, 50, 248, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 20}, - {{189, 96, 58, 53, 191, 235, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 84}, - {{111, 98, 6, 65, 35, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 108}, - {{118, 223, 83, 220, 110, 122, 23, 112, 185, 155, 73, 0, 0, 0, 0, 0}, 89, 136}, - {{173, 191, 150, 197, 204, 35, 169, 79, 31, 214, 251, 240, 0, 0, 0, 0}, 93, 196}, - {{26, 76, 129, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 67}, - {{231, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 12, 104}, - {{93, 172, 223, 252, 203, 0, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 15}, - {{53, 142, 203, 124, 104, 51, 241, 12, 161, 17, 101, 245, 120, 110, 192, 199}, 128, 237}, - {{9, 77, 120, 197, 193, 10, 237, 174, 233, 2, 165, 11, 229, 47, 144, 0}, 116, 224}, - {{99, 161, 189, 88, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 179}, - {{18, 8, 76, 66, 2, 185, 206, 132, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 84}, - {{169, 53, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 65}, - {{136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 178}, - {{131, 162, 144, 124, 12, 98, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 154}, - {{75, 50, 129, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 106}, - {{212, 183, 40, 225, 152, 136, 174, 91, 0, 0, 0, 0, 0, 0, 0, 0}, 67, 125}, - {{158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 118}, - {{7, 48, 132, 149, 169, 212, 198, 137, 202, 0, 0, 0, 0, 0, 0, 0}, 73, 52}, - {{173, 195, 129, 163, 141, 249, 40, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 173}, - {{109, 79, 75, 219, 205, 182, 22, 245, 223, 17, 146, 78, 109, 119, 128, 0}, 113, 8}, - {{174, 195, 24, 182, 215, 198, 214, 86, 34, 128, 0, 0, 0, 0, 0, 0}, 74, 211}, - {{22, 40, 51, 109, 70, 91, 152, 56, 0, 0, 0, 0, 0, 0, 0, 0}, 61, 253}, - {{169, 115, 246, 126, 65, 118, 219, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 47}, - {{154, 37, 70, 124, 107, 123, 232, 241, 164, 142, 71, 226, 182, 126, 0, 0}, 112, 73}, - {{6, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 192}, - {{216, 167, 158, 158, 222, 19, 96, 28, 40, 6, 70, 12, 147, 27, 85, 240}, 128, 55}, - {{72, 222, 52, 69, 69, 206, 163, 106, 235, 206, 80, 128, 0, 0, 0, 0}, 94, 147}, - {{150, 112, 106, 56, 15, 243, 154, 97, 134, 110, 160, 20, 183, 144, 234, 8}, 125, 86}, - {{58, 186, 106, 58, 124, 171, 53, 85, 33, 100, 64, 0, 0, 0, 0, 0}, 82, 16}, - {{7, 195, 22, 31, 62, 217, 209, 46, 90, 49, 189, 50, 168, 126, 0, 0}, 111, 167}, - {{92, 44, 159, 198, 185, 94, 231, 177, 64, 0, 0, 0, 0, 0, 0, 0}, 67, 148}, - {{169, 108, 190, 162, 23, 39, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 66}, - {{161, 5, 3, 11, 158, 157, 166, 212, 246, 22, 140, 101, 92, 0, 0, 0}, 104, 70}, - {{71, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 166}, - {{48, 136, 194, 145, 57, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 109}, - {{144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 226}, - {{223, 209, 10, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 8}, - {{154, 79, 170, 9, 43, 139, 249, 176, 186, 72, 216, 0, 0, 0, 0, 0}, 85, 218}, - {{1, 8, 123, 205, 167, 134, 128, 102, 10, 72, 0, 0, 0, 0, 0, 0}, 78, 54}, - {{31, 105, 48, 77, 103, 187, 99, 67, 96, 0, 0, 0, 0, 0, 0, 0}, 67, 48}, - {{14, 73, 54, 76, 232, 35, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 244}, - {{14, 109, 251, 190, 36, 253, 99, 120, 94, 64, 0, 0, 0, 0, 0, 0}, 74, 50}, - {{122, 170, 9, 134, 124, 91, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 173}, - {{246, 10, 85, 88, 82, 217, 95, 56, 216, 203, 160, 0, 0, 0, 0, 0}, 84, 245}, - {{77, 100, 114, 207, 150, 177, 69, 134, 74, 131, 147, 117, 177, 64, 210, 128}, 121, 54}, - {{171, 123, 22, 138, 132, 229, 250, 81, 186, 227, 146, 27, 170, 205, 128, 0}, 113, 86}, - {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 115}, - {{12, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 144}, - {{255, 124, 179, 165, 169, 250, 66, 171, 223, 125, 247, 0, 0, 0, 0, 0}, 89, 171}, - {{244, 235, 211, 10, 251, 255, 206, 6, 198, 12, 50, 136, 0, 0, 0, 0}, 93, 231}, - {{221, 77, 237, 41, 50, 33, 103, 24, 25, 127, 208, 0, 0, 0, 0, 0}, 88, 34}, - {{216, 69, 47, 53, 117, 24, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 225}, - {{180, 87, 25, 236, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 174}, - {{110, 32, 24, 34, 116, 133, 245, 128, 123, 95, 125, 122, 100, 129, 128, 0}, 113, 37}, - {{27, 117, 179, 112, 133, 137, 110, 193, 246, 201, 219, 65, 56, 234, 106, 128}, 121, 39}, - {{186, 117, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 59}, - {{243, 119, 54, 16, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 96}, - {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 147}, - {{78, 48, 117, 200, 245, 118, 115, 240, 170, 125, 84, 103, 33, 168, 0, 0}, 110, 56}, - {{201, 253, 184, 254, 143, 81, 95, 42, 243, 147, 96, 145, 23, 26, 0, 0}, 111, 234}, - {{41, 215, 84, 136, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 199}, - {{91, 244, 137, 184, 231, 95, 135, 10, 184, 0, 0, 0, 0, 0, 0, 0}, 69, 191}, - {{113, 31, 181, 245, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 235}, - {{181, 216, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 45}, - {{87, 26, 119, 229, 97, 255, 9, 43, 32, 0, 0, 0, 0, 0, 0, 0}, 67, 164}, - {{205, 112, 67, 163, 196, 148, 5, 105, 8, 138, 144, 3, 171, 213, 159, 128}, 121, 130}, - {{136, 27, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 166}, - {{2, 175, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 140}, - {{222, 131, 85, 218, 16, 229, 44, 230, 243, 76, 250, 139, 1, 203, 108, 0}, 118, 47}, - {{101, 180, 77, 142, 194, 73, 196, 246, 107, 100, 194, 72, 204, 124, 0, 0}, 111, 148}, - {{96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 103}, - {{46, 62, 191, 130, 110, 128, 235, 62, 68, 39, 58, 152, 207, 204, 96, 0}, 116, 94}, - {{111, 11, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 85}, - {{58, 43, 14, 93, 102, 210, 117, 208, 222, 171, 130, 41, 16, 16, 0, 0}, 109, 250}, - {{141, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 153}, - {{170, 153, 160, 170, 144, 235, 122, 8, 106, 34, 24, 32, 102, 57, 12, 168}, 125, 182}, - {{34, 113, 163, 107, 61, 177, 39, 172, 242, 2, 130, 0, 0, 0, 0, 0}, 94, 23}, - {{222, 191, 239, 110, 162, 191, 195, 181, 80, 50, 85, 240, 88, 32, 0, 0}, 108, 38}, - {{179, 82, 253, 151, 212, 0, 72, 253, 175, 22, 34, 78, 53, 32, 0, 0}, 110, 121}, - {{10, 162, 20, 46, 164, 64, 88, 1, 202, 204, 124, 0, 0, 0, 0, 0}, 87, 146}, - {{210, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 138}, - {{183, 200, 1, 2, 51, 6, 66, 142, 20, 77, 48, 244, 0, 0, 0, 0}, 94, 149}, - {{29, 20, 224, 57, 204, 161, 131, 254, 53, 133, 163, 0, 0, 0, 0, 0}, 88, 232}, - {{75, 58, 170, 52, 146, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 255}, - {{92, 21, 1, 113, 185, 88, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 148}, - {{103, 180, 222, 187, 129, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 117}, - {{32, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 237}, - {{7, 60, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 113}, - {{167, 122, 205, 185, 21, 199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 162}, - {{21, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 225}, - {{92, 159, 167, 169, 136, 176, 95, 255, 87, 137, 112, 16, 0, 0, 0, 0}, 92, 210}, - {{84, 120, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 34}, - {{126, 5, 126, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 224}, - {{4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 143}, - {{239, 154, 181, 182, 189, 211, 244, 53, 144, 0, 0, 0, 0, 0, 0, 0}, 68, 216}, - {{254, 188, 139, 167, 135, 47, 147, 239, 187, 106, 228, 156, 234, 234, 102, 0}, 120, 239}, - {{225, 168, 138, 92, 193, 255, 47, 233, 11, 154, 205, 86, 209, 88, 0, 0}, 111, 54}, - {{223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 35}, - {{235, 252, 115, 10, 151, 104, 193, 207, 38, 228, 229, 245, 42, 13, 108, 0}, 119, 230}, - {{1, 137, 53, 36, 210, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 234}, - {{149, 182, 72, 197, 92, 229, 9, 10, 220, 128, 72, 19, 4, 58, 192, 0}, 115, 70}, - {{105, 73, 57, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 246}, - {{189, 61, 230, 24, 235, 82, 58, 102, 97, 111, 121, 252, 156, 94, 191, 166}, 127, 217}, - {{193, 108, 231, 86, 140, 14, 192, 4, 135, 80, 129, 166, 158, 61, 230, 20}, 128, 201}, - {{110, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 49}, - {{3, 102, 36, 231, 15, 242, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 2}, - {{81, 189, 220, 168, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 64}, - {{168, 75, 133, 180, 91, 165, 77, 232, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 239}, - {{106, 179, 186, 109, 81, 234, 233, 167, 101, 160, 90, 102, 174, 234, 208, 0}, 116, 47}, - {{46, 105, 234, 21, 23, 247, 169, 33, 47, 5, 0, 0, 0, 0, 0, 0}, 80, 43}, - {{152, 144, 100, 142, 129, 23, 227, 50, 67, 81, 249, 116, 0, 0, 0, 0}, 94, 17}, - {{109, 74, 145, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 5}, - {{100, 243, 22, 230, 38, 44, 128, 86, 132, 57, 0, 0, 0, 0, 0, 0}, 81, 240}, - {{153, 251, 115, 65, 104, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 197}, - {{43, 113, 60, 224, 36, 20, 42, 161, 24, 223, 192, 0, 0, 0, 0, 0}, 84, 192}, - {{61, 77, 121, 176, 138, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 160}, - {{119, 194, 146, 49, 59, 242, 25, 220, 122, 104, 80, 0, 0, 0, 0, 0}, 84, 199}, - {{254, 162, 155, 47, 187, 3, 1, 114, 142, 191, 152, 44, 144, 26, 202, 0}, 127, 217}, - {{176, 1, 114, 42, 191, 145, 43, 1, 141, 18, 64, 0, 0, 0, 0, 0}, 83, 75}, - {{170, 244, 67, 132, 145, 163, 76, 213, 85, 237, 248, 22, 207, 64, 0, 0}, 106, 222}, - {{102, 190, 58, 32, 75, 15, 89, 163, 64, 7, 168, 0, 0, 0, 0, 0}, 85, 39}, - {{124, 170, 35, 47, 152, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 9}, - {{192, 221, 20, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 217}, - {{208, 178, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 142}, - {{188, 68, 77, 30, 68, 153, 102, 180, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 18}, - {{114, 178, 121, 188, 205, 233, 35, 77, 34, 197, 158, 174, 101, 0, 0, 0}, 104, 180}, - {{195, 98, 67, 12, 13, 43, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 205}, - {{146, 190, 42, 222, 14, 54, 28, 128, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 251}, - {{185, 202, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 178}, - {{138, 30, 129, 95, 224, 161, 120, 128, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 198}, - {{69, 181, 5, 227, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 84}, - {{90, 180, 0, 164, 227, 75, 174, 119, 128, 0, 0, 0, 0, 0, 0, 0}, 66, 128}, - {{20, 60, 58, 119, 245, 177, 162, 186, 13, 112, 211, 239, 128, 0, 0, 0}, 97, 75}, - {{158, 124, 157, 25, 230, 139, 51, 212, 76, 109, 236, 210, 48, 0, 0, 0}, 101, 192}, - {{125, 108, 242, 36, 94, 13, 36, 106, 90, 51, 83, 217, 131, 151, 0, 0}, 114, 60}, - {{222, 218, 162, 158, 15, 53, 191, 178, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 169}, - {{104, 202, 127, 109, 73, 16, 17, 12, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 10}, - {{172, 171, 246, 26, 176, 34, 22, 152, 246, 56, 173, 120, 105, 60, 92, 0}, 118, 64}, - {{190, 22, 171, 206, 109, 186, 179, 128, 253, 182, 108, 212, 220, 167, 171, 180}, 127, 182}, - {{119, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 29}, - {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 39}, - {{170, 144, 64, 2, 107, 166, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 93}, - {{234, 9, 96, 20, 156, 157, 1, 34, 88, 0, 0, 0, 0, 0, 0, 0}, 75, 228}, - {{147, 237, 16, 120, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 236}, - {{182, 189, 162, 158, 223, 90, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 190}, - {{116, 148, 142, 240, 10, 253, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 217}, - {{211, 73, 140, 69, 252, 27, 75, 46, 37, 6, 147, 32, 0, 0, 0, 0}, 93, 74}, - {{148, 61, 120, 49, 220, 65, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 61, 180}, - {{172, 35, 202, 180, 129, 75, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 91}, - {{215, 109, 147, 157, 32, 28, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 230}, - {{151, 26, 182, 112, 205, 220, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 175}, - {{73, 91, 93, 61, 196, 3, 66, 26, 149, 96, 0, 0, 0, 0, 0, 0}, 75, 171}, - {{203, 163, 52, 247, 28, 119, 56, 223, 138, 70, 174, 97, 77, 59, 46, 0}, 120, 202}, - {{251, 50, 228, 178, 202, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 113}, - {{217, 159, 164, 199, 14, 237, 170, 184, 100, 231, 92, 222, 0, 0, 0, 0}, 96, 187}, - {{16, 161, 85, 193, 202, 21, 3, 155, 63, 116, 124, 203, 34, 13, 215, 0}, 120, 38}, - {{111, 52, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 35}, - {{69, 12, 116, 151, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 115}, - {{187, 60, 97, 40, 112, 101, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 18}, - {{230, 194, 136, 255, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 34}, - {{179, 239, 170, 107, 3, 13, 212, 67, 177, 69, 8, 0, 0, 0, 0, 0}, 87, 75}, - {{11, 58, 130, 89, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 232}, - {{217, 178, 43, 203, 234, 20, 234, 186, 157, 88, 146, 192, 0, 0, 0, 0}, 91, 154}, - {{6, 180, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 195}, - {{157, 154, 218, 158, 39, 224, 103, 230, 164, 0, 0, 0, 0, 0, 0, 0}, 70, 122}, - {{225, 10, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 97}, - {{16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 220}, - {{166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 80}, - {{29, 190, 131, 215, 232, 246, 41, 226, 52, 192, 0, 0, 0, 0, 0, 0}, 77, 133}, - {{138, 74, 163, 93, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 93}, - {{229, 64, 97, 41, 28, 243, 249, 185, 97, 35, 49, 27, 175, 24, 0, 0}, 110, 176}, - {{6, 73, 94, 160, 186, 216, 84, 117, 233, 169, 146, 234, 0, 0, 0, 0}, 95, 68}, - {{163, 40, 242, 81, 224, 35, 72, 194, 176, 78, 224, 174, 12, 0, 0, 0}, 103, 247}, - {{2, 205, 40, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 240}, - {{174, 225, 240, 160, 212, 8, 246, 67, 36, 0, 0, 0, 0, 0, 0, 0}, 74, 83}, - {{5, 117, 182, 141, 166, 249, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 132}, - {{46, 152, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 217}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 214}, - {{233, 202, 159, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 193}, - {{172, 54, 159, 5, 14, 245, 106, 182, 2, 0, 0, 0, 0, 0, 0, 0}, 71, 61}, - {{241, 222, 251, 114, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 65}, - {{31, 243, 190, 4, 207, 198, 249, 59, 167, 127, 93, 64, 0, 0, 0, 0}, 91, 108}, - {{201, 35, 222, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 244}, - {{187, 105, 13, 114, 238, 197, 145, 23, 169, 116, 91, 28, 0, 0, 0, 0}, 95, 194}, - {{251, 251, 121, 168, 152, 178, 147, 188, 229, 123, 154, 242, 190, 165, 173, 48}, 124, 82}, - {{66, 187, 191, 164, 31, 196, 40, 186, 148, 115, 134, 57, 222, 254, 48, 0}, 116, 45}, - {{209, 17, 111, 41, 154, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 224}, - {{40, 245, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 17}, - {{72, 121, 151, 83, 170, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 133}, - {{171, 172, 101, 238, 201, 148, 23, 81, 4, 11, 64, 0, 0, 0, 0, 0}, 85, 125}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 42}, - {{20, 46, 27, 93, 195, 184, 6, 162, 109, 225, 22, 152, 0, 0, 0, 0}, 96, 140}, - {{243, 122, 30, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 91}, - {{89, 250, 80, 72, 148, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 92}, - {{187, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 125}, - {{172, 160, 143, 114, 128, 239, 174, 133, 176, 154, 159, 134, 10, 0, 0, 0}, 106, 249}, - {{254, 202, 113, 112, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 202}, - {{80, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 107}, - {{222, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 124}, - {{219, 138, 253, 12, 188, 197, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 57}, - {{124, 41, 173, 8, 202, 192, 61, 254, 174, 48, 239, 112, 0, 0, 0, 0}, 92, 181}, - {{195, 236, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 107}, - {{83, 82, 42, 244, 136, 191, 197, 81, 91, 154, 216, 85, 29, 150, 198, 22}, 128, 101}, - {{112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 102}, - {{44, 30, 219, 248, 214, 88, 225, 132, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 136}, - {{41, 171, 206, 178, 195, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 114}, - {{159, 15, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 215}, - {{42, 188, 37, 174, 86, 40, 4, 84, 174, 216, 0, 0, 0, 0, 0, 0}, 79, 249}, - {{185, 227, 85, 177, 219, 95, 250, 227, 69, 154, 118, 0, 0, 0, 0, 0}, 88, 29}, - {{22, 185, 238, 100, 25, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 71}, - {{122, 149, 117, 77, 88, 250, 187, 203, 136, 22, 85, 42, 105, 234, 79, 8}, 127, 112}, - {{93, 152, 229, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 72}, - {{129, 37, 165, 167, 241, 24, 37, 40, 2, 128, 0, 0, 0, 0, 0, 0}, 73, 155}, - {{30, 202, 177, 3, 253, 202, 164, 248, 0, 0, 0, 0, 0, 0, 0, 0}, 61, 66}, - {{176, 25, 220, 120, 194, 228, 10, 45, 225, 142, 192, 96, 0, 0, 0, 0}, 91, 77}, - {{96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 109}, - {{82, 56, 12, 204, 61, 45, 147, 240, 221, 0, 0, 0, 0, 0, 0, 0}, 72, 37}, - {{242, 38, 240, 41, 140, 75, 250, 37, 175, 115, 97, 224, 0, 0, 0, 0}, 91, 56}, - {{251, 192, 23, 90, 135, 56, 252, 56, 79, 219, 80, 167, 22, 0, 0, 0}, 103, 5}, - {{62, 128, 139, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 15}, - {{214, 1, 84, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 183}, - {{207, 90, 237, 137, 171, 140, 227, 88, 250, 26, 197, 162, 163, 0, 0, 0}, 105, 171}, - {{196, 151, 235, 232, 114, 248, 1, 207, 193, 184, 186, 71, 157, 0, 0, 0}, 112, 202}, - {{152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 136}, - {{9, 174, 211, 200, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 107}, - {{89, 150, 95, 28, 209, 13, 125, 159, 254, 244, 110, 0, 0, 0, 0, 0}, 87, 193}, - {{23, 28, 202, 10, 90, 158, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 4}, - {{48, 25, 180, 9, 84, 236, 6, 144, 30, 198, 41, 56, 0, 0, 0, 0}, 96, 68}, - {{252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 40}, - {{20, 165, 57, 130, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 255}, - {{167, 56, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 108}, - {{91, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 219}, - {{24, 46, 9, 4, 170, 150, 56, 130, 127, 120, 118, 104, 168, 48, 0, 0}, 108, 12}, - {{156, 60, 245, 247, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 84}, - {{148, 104, 187, 174, 129, 28, 127, 162, 92, 222, 52, 18, 0, 0, 0, 0}, 96, 33}, - {{38, 253, 182, 153, 233, 194, 159, 41, 94, 193, 254, 160, 0, 0, 0, 0}, 91, 199}, - {{156, 77, 105, 235, 145, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 52}, - {{100, 211, 238, 147, 65, 222, 99, 73, 252, 113, 46, 113, 52, 136, 0, 0}, 113, 184}, - {{13, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 124}, - {{29, 240, 141, 230, 78, 237, 25, 135, 131, 6, 65, 77, 77, 248, 0, 0}, 109, 128}, - {{15, 192, 109, 31, 149, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 255}, - {{80, 185, 170, 71, 41, 58, 158, 106, 253, 7, 2, 184, 173, 0, 0, 0}, 105, 146}, - {{16, 229, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 172}, - {{169, 2, 153, 9, 169, 203, 245, 154, 184, 0, 0, 0, 0, 0, 0, 0}, 70, 116}, - {{144, 135, 239, 164, 142, 187, 64, 109, 0, 0, 0, 0, 0, 0, 0, 0}, 66, 189}, - {{170, 78, 252, 227, 242, 199, 130, 251, 200, 0, 0, 0, 0, 0, 0, 0}, 70, 10}, - {{232, 18, 15, 126, 166, 126, 58, 25, 209, 62, 76, 79, 0, 0, 0, 0}, 98, 184}, - {{170, 82, 72, 53, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 98}, - {{152, 100, 37, 122, 242, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 37}, - {{174, 231, 230, 33, 71, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 174}, - {{74, 225, 252, 153, 202, 8, 162, 39, 64, 0, 0, 0, 0, 0, 0, 0}, 67, 251}, - {{167, 186, 101, 187, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 115}, - {{83, 7, 21, 122, 243, 67, 171, 146, 145, 160, 168, 103, 223, 64, 0, 0}, 107, 252}, - {{83, 132, 219, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 176}, - {{22, 113, 72, 102, 73, 16, 236, 57, 197, 122, 31, 0, 0, 0, 0, 0}, 91, 155}, - {{250, 59, 64, 35, 72, 112, 159, 85, 200, 5, 193, 39, 152, 185, 148, 16}, 124, 36}, - {{220, 21, 48, 164, 224, 121, 17, 69, 10, 118, 106, 0, 0, 0, 0, 0}, 88, 202}, - {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 208}, - {{247, 64, 83, 125, 195, 225, 50, 76, 18, 104, 0, 0, 0, 0, 0, 0}, 77, 158}, - {{78, 91, 31, 202, 189, 25, 13, 133, 220, 0, 0, 0, 0, 0, 0, 0}, 72, 136}, - {{105, 197, 26, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 191}, - {{14, 31, 154, 242, 241, 231, 55, 151, 223, 56, 134, 255, 113, 206, 69, 0}, 120, 126}, - {{247, 193, 58, 176, 16, 71, 31, 120, 213, 104, 231, 83, 26, 118, 91, 135}, 128, 139}, - {{136, 32, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 216}, - {{100, 238, 112, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 93}, - {{80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 196}, - {{233, 224, 254, 57, 33, 205, 140, 217, 181, 72, 0, 0, 0, 0, 0, 0}, 81, 119}, - {{107, 75, 65, 158, 128, 142, 191, 188, 188, 240, 148, 243, 116, 0, 0, 0}, 104, 93}, - {{39, 70, 120, 114, 69, 237, 95, 48, 233, 176, 91, 154, 0, 0, 0, 0}, 96, 183}, - {{10, 61, 43, 101, 64, 102, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 207}, - {{151, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 102}, - {{210, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 36}, - {{52, 222, 249, 31, 108, 137, 199, 1, 242, 173, 184, 144, 0, 0, 0, 0}, 93, 41}, - {{123, 111, 88, 192, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 70}, - {{180, 82, 188, 125, 140, 8, 196, 74, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 218}, - {{77, 158, 34, 101, 196, 102, 56, 220, 42, 143, 181, 187, 240, 64, 161, 0}, 120, 226}, - {{88, 220, 222, 38, 23, 108, 5, 148, 185, 110, 20, 14, 67, 61, 0, 0}, 114, 25}, - {{90, 65, 220, 165, 197, 133, 110, 92, 228, 19, 2, 17, 0, 0, 0, 0}, 98, 6}, - {{35, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 26}, - {{103, 123, 49, 209, 228, 229, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 149}, - {{50, 244, 58, 191, 95, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 127}, - {{140, 169, 75, 77, 78, 86, 40, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 144}, - {{99, 176, 175, 83, 114, 50, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 213}, - {{19, 208, 211, 76, 85, 176, 247, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 115}, - {{153, 28, 188, 113, 211, 116, 7, 178, 136, 205, 96, 0, 0, 0, 0, 0}, 83, 146}, - {{160, 180, 220, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 58}, - {{234, 6, 112, 19, 61, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 222}, - {{97, 110, 34, 117, 149, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 16}, - {{99, 173, 119, 73, 250, 30, 144, 30, 128, 0, 0, 0, 0, 0, 0, 0}, 65, 169}, - {{169, 134, 111, 89, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 175}, - {{134, 80, 227, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 3}, - {{231, 243, 35, 80, 75, 207, 128, 137, 54, 170, 71, 238, 0, 0, 0, 0}, 96, 2}, - {{189, 190, 121, 135, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 193}, - {{143, 155, 216, 193, 239, 205, 204, 153, 143, 236, 69, 23, 200, 211, 0, 0}, 118, 151}, - {{32, 1, 115, 244, 33, 219, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 182}, - {{220, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 148}, - {{206, 87, 135, 235, 116, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 53}, - {{152, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 87}, - {{58, 146, 188, 233, 230, 236, 192, 214, 168, 128, 0, 0, 0, 0, 0, 0}, 73, 235}, - {{84, 220, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 51}, - {{106, 145, 142, 42, 186, 186, 58, 1, 48, 98, 165, 131, 48, 156, 192, 0}, 116, 11}, - {{53, 219, 120, 242, 166, 214, 81, 130, 64, 0, 0, 0, 0, 0, 0, 0}, 68, 28}, - {{240, 120, 76, 163, 32, 197, 181, 251, 98, 220, 29, 226, 0, 0, 0, 0}, 96, 73}, - {{234, 197, 12, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 216}, - {{191, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 99}, - {{200, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 35}, - {{29, 129, 47, 83, 19, 75, 158, 1, 28, 24, 26, 147, 82, 119, 140, 100}, 127, 195}, - {{241, 174, 26, 53, 152, 112, 200, 134, 84, 187, 177, 176, 42, 64, 0, 0}, 108, 176}, - {{77, 171, 145, 48, 195, 84, 190, 36, 122, 199, 18, 0, 0, 0, 0, 0}, 87, 217}, - {{105, 104, 135, 53, 226, 118, 238, 169, 9, 253, 132, 162, 217, 123, 191, 96}, 126, 244}, - {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 125}, - {{41, 85, 143, 128, 91, 137, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 219}, - {{116, 110, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 165}, - {{75, 213, 44, 16, 43, 157, 34, 171, 98, 117, 109, 151, 5, 60, 224, 0}, 117, 6}, - {{229, 23, 116, 61, 80, 139, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 47}, - {{83, 123, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 73}, - {{151, 243, 45, 217, 216, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 98}, - {{171, 184, 110, 211, 237, 114, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 21}, - {{7, 246, 199, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 142}, - {{103, 47, 70, 17, 31, 232, 44, 75, 145, 155, 100, 216, 0, 0, 0, 0}, 93, 34}, - {{65, 170, 169, 100, 167, 147, 142, 251, 20, 64, 0, 0, 0, 0, 0, 0}, 74, 41}, - {{235, 6, 229, 248, 151, 137, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 80}, - {{156, 39, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 11}, - {{92, 188, 82, 192, 142, 249, 190, 128, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 254}, - {{253, 218, 181, 46, 134, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 95}, - {{189, 19, 31, 244, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 8}, - {{30, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 212}, - {{81, 226, 13, 173, 79, 123, 223, 124, 108, 80, 83, 238, 0, 0, 0, 0}, 95, 217}, - {{126, 211, 206, 82, 147, 215, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 15}, - {{42, 229, 135, 197, 196, 243, 94, 181, 133, 34, 16, 0, 0, 0, 0, 0}, 84, 66}, - {{68, 210, 158, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 122}, - {{183, 63, 223, 94, 81, 41, 203, 20, 236, 212, 220, 199, 0, 0, 0, 0}, 97, 12}, - {{131, 146, 2, 125, 174, 43, 231, 20, 194, 0, 0, 0, 0, 0, 0, 0}, 71, 171}, - {{31, 180, 246, 158, 28, 192, 236, 39, 237, 55, 74, 195, 171, 192, 0, 0}, 106, 42}, - {{179, 10, 70, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 194}, - {{147, 51, 85, 185, 234, 209, 236, 87, 147, 17, 7, 68, 148, 32, 0, 0}, 107, 237}, - {{177, 178, 6, 40, 46, 166, 87, 198, 214, 234, 23, 224, 0, 0, 0, 0}, 93, 151}, - {{201, 53, 40, 20, 49, 4, 38, 139, 133, 217, 214, 134, 89, 200, 0, 0}, 109, 238}, - {{4, 26, 181, 37, 206, 129, 233, 32, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 128}, - {{81, 58, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 227}, - {{18, 238, 250, 161, 57, 246, 208, 118, 14, 76, 73, 25, 65, 22, 152, 120}, 127, 138}, - {{31, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 60}, - {{115, 195, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 148}, - {{116, 22, 75, 33, 16, 129, 35, 124, 10, 112, 31, 213, 181, 108, 177, 46}, 128, 129}, - {{117, 214, 20, 80, 83, 51, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 202}, - {{120, 75, 124, 149, 120, 123, 242, 151, 181, 164, 128, 0, 0, 0, 0, 0}, 81, 88}, - {{87, 238, 168, 62, 88, 166, 52, 104, 219, 169, 93, 128, 0, 0, 0, 0}, 90, 3}, - {{237, 44, 224, 146, 52, 85, 245, 192, 65, 137, 37, 95, 156, 176, 0, 0}, 108, 243}, - {{214, 241, 51, 63, 73, 61, 193, 165, 23, 108, 0, 0, 0, 0, 0, 0}, 80, 95}, - {{87, 242, 21, 157, 45, 188, 36, 62, 66, 243, 64, 0, 0, 0, 0, 0}, 87, 255}, - {{0, 97, 220, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 48}, - {{227, 206, 189, 31, 222, 8, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 38}, - {{174, 27, 0, 16, 13, 150, 33, 122, 154, 59, 236, 35, 248, 178, 64, 0}, 115, 20}, - {{39, 20, 125, 69, 252, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 43, 41}, - {{141, 232, 1, 12, 125, 229, 168, 14, 125, 116, 180, 0, 0, 0, 0, 0}, 92, 133}, - {{93, 238, 40, 228, 254, 203, 251, 6, 60, 82, 243, 242, 0, 0, 0, 0}, 95, 189}, - {{44, 115, 200, 17, 146, 223, 115, 253, 126, 206, 152, 90, 0, 0, 0, 0}, 95, 151}, - {{213, 58, 235, 255, 6, 163, 61, 10, 224, 0, 0, 0, 0, 0, 0, 0}, 68, 100}, - {{25, 86, 139, 116, 190, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 118}, - {{113, 40, 65, 141, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 164}, - {{149, 205, 200, 186, 19, 126, 215, 199, 94, 37, 100, 32, 128, 0, 0, 0}, 98, 71}, - {{39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 251}, - {{81, 87, 80, 173, 163, 166, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 51}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 185}, - {{140, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 144}, - {{6, 42, 1, 178, 250, 53, 186, 178, 114, 121, 192, 0, 0, 0, 0, 0}, 84, 51}, - {{2, 17, 234, 51, 169, 5, 219, 149, 245, 237, 4, 0, 0, 0, 0, 0}, 87, 32}, - {{112, 187, 173, 17, 229, 171, 225, 170, 8, 0, 0, 0, 0, 0, 0, 0}, 70, 137}, - {{203, 71, 140, 237, 113, 96, 123, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 2}, - {{99, 138, 207, 2, 244, 25, 211, 98, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 163}, - {{114, 42, 98, 246, 252, 48, 233, 118, 63, 226, 157, 226, 192, 0, 0, 0}, 100, 162}, - {{161, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 192}, - {{233, 70, 240, 45, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 185}, - {{28, 123, 31, 176, 235, 229, 169, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 51}, - {{146, 197, 243, 235, 243, 56, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 93}, - {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 159}, - {{141, 92, 13, 27, 87, 241, 171, 143, 220, 0, 0, 0, 0, 0, 0, 0}, 72, 189}, - {{164, 151, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 248}, - {{35, 188, 248, 79, 39, 151, 232, 215, 248, 245, 185, 144, 78, 102, 173, 128}, 123, 38}, - {{193, 232, 166, 60, 62, 80, 230, 225, 165, 240, 0, 0, 0, 0, 0, 0}, 76, 167}, - {{109, 229, 118, 155, 43, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 28}, - {{160, 62, 63, 212, 218, 138, 154, 108, 163, 127, 197, 237, 183, 44, 140, 192}, 125, 37}, - {{196, 37, 51, 146, 26, 85, 53, 31, 216, 141, 52, 218, 153, 32, 0, 0}, 107, 234}, - {{228, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 70}, - {{154, 248, 20, 242, 154, 244, 63, 17, 121, 52, 70, 84, 118, 208, 0, 0}, 108, 50}, - {{41, 100, 27, 84, 106, 112, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 171}, - {{81, 99, 197, 139, 30, 150, 230, 216, 81, 190, 84, 165, 29, 64, 128, 0}, 113, 236}, - {{112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 3}, - {{164, 119, 253, 126, 160, 249, 183, 191, 119, 111, 224, 0, 0, 0, 0, 0}, 86, 64}, - {{138, 58, 198, 254, 0, 197, 60, 91, 132, 199, 181, 251, 78, 160, 0, 0}, 108, 213}, - {{209, 89, 168, 236, 146, 169, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 15}, - {{131, 210, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 145}, - {{165, 190, 157, 7, 131, 5, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 27}, - {{179, 226, 57, 204, 187, 70, 52, 81, 119, 162, 229, 42, 47, 185, 9, 162}, 127, 75}, - {{98, 235, 155, 51, 107, 167, 127, 137, 254, 246, 162, 171, 180, 13, 233, 0}, 123, 76}, - {{107, 79, 76, 90, 94, 151, 155, 31, 33, 115, 19, 204, 98, 115, 0, 0}, 113, 247}, - {{143, 46, 30, 175, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 43, 121}, - {{155, 85, 217, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 214}, - {{58, 62, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 221}, - {{92, 155, 53, 3, 39, 108, 155, 200, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 102}, - {{64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 191}, - {{63, 134, 251, 59, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 197}, - {{234, 149, 220, 106, 0, 144, 214, 128, 35, 102, 0, 0, 0, 0, 0, 0}, 79, 106}, -}; - -#define NUM_ROUTE_ENTRIES \ - (sizeof(large_route_table) / sizeof(large_route_table[0])) - -#define NUM_IPS_ENTRIES (NUM_ROUTE_ENTRIES * 100) - -/* clear the previous large_ips_table and reduce LPM6 test case much smaller, - * keep same size as previous one to make test case run similar input data. - */ -static struct ips_tbl_entry large_ips_table[NUM_IPS_ENTRIES]; - -/* let the most significant depth bits of ip_out[] same as ip_in[] - * in the same bit position. ip_out[] and ip_in[] are IPv6 address. - */ -static inline void mask_ip6_prefix(uint8_t *ip_out, - const uint8_t *ip_in, uint8_t depth) -{ - int k; - uint8_t mask_in, mask_out; - - for (k = 0; k < 16; k++) { - if (depth >= 8) - ip_out[k] = ip_in[k]; - else if (depth > 0) { - mask_in = (uint8_t)((unsigned int)(-1) << (8 - depth)); - mask_out = ~mask_in; - ip_out[k] = (ip_in[k] & mask_in) - | (ip_out[k] & mask_out); - } else - return; - - depth -= 8; - } -} - -/* check if IPv6 address ip[] match the rule with IPv6 address ip_rule[] - * and depth. if matched, return 0, else return -1. - */ -static inline int check_lpm6_rule(uint8_t *ip, - const uint8_t *ip_rule, uint8_t depth) -{ - int k; - uint8_t mask; - - for (k = 0; k < 16; k++) { - if (depth >= 8) { - if (ip[k] != ip_rule[k]) - return -1; - } else if (depth > 0) { - mask = (uint8_t)((unsigned int)(-1) << (8 - depth)); - if ((ip[k] & mask) == (ip_rule[k] & mask)) - return 0; - else - return -1; - } else - return 0; - - depth -= 8; - } - - return 0; -} - -/* check input IPv6 address ip[] with each one in rule[] and - * output the *next_hop from the matched item in rule[] with - * longest depth. The count of items in rule[ ] is rule_num. - * if found that some item in rule[] is matched return 0, - * else return -1; - */ -static int get_next_hop(uint8_t *ip, uint8_t *next_hop, - const struct rules_tbl_entry *rule, int rule_num) -{ - int i; - int result; - uint8_t max_depth = 0; - - for (i = 0; i < rule_num; i++) { - if (rule[i].depth >= max_depth) { - result = check_lpm6_rule(ip, rule[i].ip, rule[i].depth); - if (result == 0) { - *next_hop = rule[i].next_hop; - max_depth = rule[i].depth; - } - } - } - - if (max_depth > 0) - return 0; - else - return -1; -} - -/* the implementation of algorithm to generate large IPS table - * at run time. if gen_expected_nex_hop is non-zero, the expected - * next_hop of the IPv6 address of each item in IPS table is computed. - */ -static void generate_large_ips_table(int gen_expected_next_hop) -{ - uint32_t i, j, k; - - for (i = 0; i < NUM_IPS_ENTRIES; i++) { - for (j = 0; j < 16; j++) - large_ips_table[i].ip[j] = lrand48(); - } - - for (k = j = 0, i = 0; i < NUM_IPS_ENTRIES; i++) { - mask_ip6_prefix(large_ips_table[i].ip, - large_route_table[j].ip, large_route_table[j].depth); - k++; - if (k == (NUM_IPS_ENTRIES / NUM_ROUTE_ENTRIES)) { - j++; - k = 0; - } - if (j == NUM_ROUTE_ENTRIES) - j = 0; - } - - if (gen_expected_next_hop == 0) - return; - - for (k = 0; k < NUM_IPS_ENTRIES; k++) - get_next_hop(large_ips_table[k].ip, - &(large_ips_table[k].next_hop), - large_route_table, - NUM_ROUTE_ENTRIES); - -} - -#endif /* _TEST_LPM_ROUTES_H_ */ diff --git a/app/test/test_lpm6_perf.c b/app/test/test_lpm6_perf.c deleted file mode 100644 index 0723081bb5..0000000000 --- a/app/test/test_lpm6_perf.c +++ /dev/null @@ -1,192 +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 -#include -#include -#include - -#include -#include -#include -#include - -#include "test.h" -#include "test_lpm6_data.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); - - /* Only generate IPv6 address of each item in large IPS table, - * here next_hop is not needed. - */ - generate_large_ips_table(0); - - 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; -} - -REGISTER_TEST_COMMAND(lpm6_perf_autotest, test_lpm6_perf); diff --git a/app/test/test_lpm_perf.c b/app/test/test_lpm_perf.c deleted file mode 100644 index e7e1281bda..0000000000 --- a/app/test/test_lpm_perf.c +++ /dev/null @@ -1,513 +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 -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "test.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 - -#define MAX_RULE_NUM (1200000) - -struct route_rule { - uint32_t ip; - uint8_t depth; -}; - -struct route_rule large_route_table[MAX_RULE_NUM]; - -static uint32_t num_route_entries; -#define NUM_ROUTE_ENTRIES num_route_entries - -enum { - IP_CLASS_A, - IP_CLASS_B, - IP_CLASS_C -}; - -/* struct route_rule_count defines the total number of rules in following a/b/c - * each item in a[]/b[]/c[] is the number of common IP address class A/B/C, not - * including the ones for private local network. - */ -struct route_rule_count { - uint32_t a[RTE_LPM_MAX_DEPTH]; - uint32_t b[RTE_LPM_MAX_DEPTH]; - uint32_t c[RTE_LPM_MAX_DEPTH]; -}; - -/* All following numbers of each depth of each common IP class are just - * got from previous large constant table in app/test/test_lpm_routes.h . - * In order to match similar performance, they keep same depth and IP - * address coverage as previous constant table. These numbers don't - * include any private local IP address. As previous large const rule - * table was just dumped from a real router, there are no any IP address - * in class C or D. - */ -static struct route_rule_count rule_count = { - .a = { /* IP class A in which the most significant bit is 0 */ - 0, /* depth = 1 */ - 0, /* depth = 2 */ - 1, /* depth = 3 */ - 0, /* depth = 4 */ - 2, /* depth = 5 */ - 1, /* depth = 6 */ - 3, /* depth = 7 */ - 185, /* depth = 8 */ - 26, /* depth = 9 */ - 16, /* depth = 10 */ - 39, /* depth = 11 */ - 144, /* depth = 12 */ - 233, /* depth = 13 */ - 528, /* depth = 14 */ - 866, /* depth = 15 */ - 3856, /* depth = 16 */ - 3268, /* depth = 17 */ - 5662, /* depth = 18 */ - 17301, /* depth = 19 */ - 22226, /* depth = 20 */ - 11147, /* depth = 21 */ - 16746, /* depth = 22 */ - 17120, /* depth = 23 */ - 77578, /* depth = 24 */ - 401, /* depth = 25 */ - 656, /* depth = 26 */ - 1107, /* depth = 27 */ - 1121, /* depth = 28 */ - 2316, /* depth = 29 */ - 717, /* depth = 30 */ - 10, /* depth = 31 */ - 66 /* depth = 32 */ - }, - .b = { /* IP class A in which the most 2 significant bits are 10 */ - 0, /* depth = 1 */ - 0, /* depth = 2 */ - 0, /* depth = 3 */ - 0, /* depth = 4 */ - 1, /* depth = 5 */ - 1, /* depth = 6 */ - 1, /* depth = 7 */ - 3, /* depth = 8 */ - 3, /* depth = 9 */ - 30, /* depth = 10 */ - 25, /* depth = 11 */ - 168, /* depth = 12 */ - 305, /* depth = 13 */ - 569, /* depth = 14 */ - 1129, /* depth = 15 */ - 50800, /* depth = 16 */ - 1645, /* depth = 17 */ - 1820, /* depth = 18 */ - 3506, /* depth = 19 */ - 3258, /* depth = 20 */ - 3424, /* depth = 21 */ - 4971, /* depth = 22 */ - 6885, /* depth = 23 */ - 39771, /* depth = 24 */ - 424, /* depth = 25 */ - 170, /* depth = 26 */ - 433, /* depth = 27 */ - 92, /* depth = 28 */ - 366, /* depth = 29 */ - 377, /* depth = 30 */ - 2, /* depth = 31 */ - 200 /* depth = 32 */ - }, - .c = { /* IP class A in which the most 3 significant bits are 110 */ - 0, /* depth = 1 */ - 0, /* depth = 2 */ - 0, /* depth = 3 */ - 0, /* depth = 4 */ - 0, /* depth = 5 */ - 0, /* depth = 6 */ - 0, /* depth = 7 */ - 12, /* depth = 8 */ - 8, /* depth = 9 */ - 9, /* depth = 10 */ - 33, /* depth = 11 */ - 69, /* depth = 12 */ - 237, /* depth = 13 */ - 1007, /* depth = 14 */ - 1717, /* depth = 15 */ - 14663, /* depth = 16 */ - 8070, /* depth = 17 */ - 16185, /* depth = 18 */ - 48261, /* depth = 19 */ - 36870, /* depth = 20 */ - 33960, /* depth = 21 */ - 50638, /* depth = 22 */ - 61422, /* depth = 23 */ - 466549, /* depth = 24 */ - 1829, /* depth = 25 */ - 4824, /* depth = 26 */ - 4927, /* depth = 27 */ - 5914, /* depth = 28 */ - 10254, /* depth = 29 */ - 4905, /* depth = 30 */ - 1, /* depth = 31 */ - 716 /* depth = 32 */ - } -}; - -static void generate_random_rule_prefix(uint32_t ip_class, uint8_t depth) -{ -/* IP address class A, the most significant bit is 0 */ -#define IP_HEAD_MASK_A 0x00000000 -#define IP_HEAD_BIT_NUM_A 1 - -/* IP address class B, the most significant 2 bits are 10 */ -#define IP_HEAD_MASK_B 0x80000000 -#define IP_HEAD_BIT_NUM_B 2 - -/* IP address class C, the most significant 3 bits are 110 */ -#define IP_HEAD_MASK_C 0xC0000000 -#define IP_HEAD_BIT_NUM_C 3 - - uint32_t class_depth; - uint32_t range; - uint32_t mask; - uint32_t step; - uint32_t start; - uint32_t fixed_bit_num; - uint32_t ip_head_mask; - uint32_t rule_num; - uint32_t k; - struct route_rule *ptr_rule; - - if (ip_class == IP_CLASS_A) { /* IP Address class A */ - fixed_bit_num = IP_HEAD_BIT_NUM_A; - ip_head_mask = IP_HEAD_MASK_A; - rule_num = rule_count.a[depth - 1]; - } else if (ip_class == IP_CLASS_B) { /* IP Address class B */ - fixed_bit_num = IP_HEAD_BIT_NUM_B; - ip_head_mask = IP_HEAD_MASK_B; - rule_num = rule_count.b[depth - 1]; - } else { /* IP Address class C */ - fixed_bit_num = IP_HEAD_BIT_NUM_C; - ip_head_mask = IP_HEAD_MASK_C; - rule_num = rule_count.c[depth - 1]; - } - - if (rule_num == 0) - return; - - /* the number of rest bits which don't include the most significant - * fixed bits for this IP address class - */ - class_depth = depth - fixed_bit_num; - - /* range is the maximum number of rules for this depth and - * this IP address class - */ - range = 1 << class_depth; - - /* only mask the most depth significant generated bits - * except fixed bits for IP address class - */ - mask = range - 1; - - /* Widen coverage of IP address in generated rules */ - if (range <= rule_num) - step = 1; - else - step = round((double)range / rule_num); - - /* Only generate rest bits except the most significant - * fixed bits for IP address class - */ - start = lrand48() & mask; - ptr_rule = &large_route_table[num_route_entries]; - for (k = 0; k < rule_num; k++) { - ptr_rule->ip = (start << (RTE_LPM_MAX_DEPTH - depth)) - | ip_head_mask; - ptr_rule->depth = depth; - ptr_rule++; - start = (start + step) & mask; - } - num_route_entries += rule_num; -} - -static void insert_rule_in_random_pos(uint32_t ip, uint8_t depth) -{ - uint32_t pos; - int try_count = 0; - struct route_rule tmp; - - do { - pos = lrand48(); - try_count++; - } while ((try_count < 10) && (pos > num_route_entries)); - - if ((pos > num_route_entries) || (pos >= MAX_RULE_NUM)) - pos = num_route_entries >> 1; - - tmp = large_route_table[pos]; - large_route_table[pos].ip = ip; - large_route_table[pos].depth = depth; - if (num_route_entries < MAX_RULE_NUM) - large_route_table[num_route_entries++] = tmp; -} - -static void generate_large_route_rule_table(void) -{ - uint32_t ip_class; - uint8_t depth; - - num_route_entries = 0; - memset(large_route_table, 0, sizeof(large_route_table)); - - for (ip_class = IP_CLASS_A; ip_class <= IP_CLASS_C; ip_class++) { - for (depth = 1; depth <= RTE_LPM_MAX_DEPTH; depth++) { - generate_random_rule_prefix(ip_class, depth); - } - } - - /* Add following rules to keep same as previous large constant table, - * they are 4 rules with private local IP address and 1 all-zeros prefix - * with depth = 8. - */ - insert_rule_in_random_pos(IPv4(0, 0, 0, 0), 8); - insert_rule_in_random_pos(IPv4(10, 2, 23, 147), 32); - insert_rule_in_random_pos(IPv4(192, 168, 100, 10), 24); - insert_rule_in_random_pos(IPv4(192, 168, 25, 100), 24); - insert_rule_in_random_pos(IPv4(192, 168, 129, 124), 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 = 2000000; - config.number_tbl8s = 2048; - 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()); - - generate_large_route_rule_table(); - - 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; -} - -REGISTER_TEST_COMMAND(lpm_perf_autotest, test_lpm_perf); diff --git a/app/test/test_malloc.c b/app/test/test_malloc.c deleted file mode 100644 index 0673d85b7e..0000000000 --- a/app/test/test_malloc.c +++ /dev/null @@ -1,962 +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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define N 10000 - -/* - * Malloc - * ====== - * - * Allocate some dynamic memory from heap (3 areas). Check that areas - * don't overlap and that alignment constraints match. This test is - * done many times on different lcores simultaneously. - */ - -/* Test if memory overlaps: return 1 if true, or 0 if false. */ -static int -is_memory_overlap(void *p1, size_t len1, void *p2, size_t len2) -{ - unsigned long ptr1 = (unsigned long)p1; - unsigned long ptr2 = (unsigned long)p2; - - if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1) - return 1; - else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2) - return 1; - return 0; -} - -static int -is_aligned(void *p, int align) -{ - unsigned long addr = (unsigned long)p; - unsigned mask = align - 1; - - if (addr & mask) - return 0; - return 1; -} - -static int -test_align_overlap_per_lcore(__attribute__((unused)) void *arg) -{ - const unsigned align1 = 8, - align2 = 64, - align3 = 2048; - unsigned i,j; - void *p1 = NULL, *p2 = NULL, *p3 = NULL; - int ret = 0; - - for (i = 0; i < N; i++) { - p1 = rte_zmalloc("dummy", 1000, align1); - if (!p1){ - printf("rte_zmalloc returned NULL (i=%u)\n", i); - ret = -1; - break; - } - for(j = 0; j < 1000 ; j++) { - if( *(char *)p1 != 0) { - printf("rte_zmalloc didn't zero" - "the allocated memory\n"); - ret = -1; - } - } - p2 = rte_malloc("dummy", 1000, align2); - if (!p2){ - printf("rte_malloc returned NULL (i=%u)\n", i); - ret = -1; - rte_free(p1); - break; - } - p3 = rte_malloc("dummy", 1000, align3); - if (!p3){ - printf("rte_malloc returned NULL (i=%u)\n", i); - ret = -1; - rte_free(p1); - rte_free(p2); - break; - } - if (is_memory_overlap(p1, 1000, p2, 1000)) { - printf("p1 and p2 overlaps\n"); - ret = -1; - } - if (is_memory_overlap(p2, 1000, p3, 1000)) { - printf("p2 and p3 overlaps\n"); - ret = -1; - } - if (is_memory_overlap(p1, 1000, p3, 1000)) { - printf("p1 and p3 overlaps\n"); - ret = -1; - } - if (!is_aligned(p1, align1)) { - printf("p1 is not aligned\n"); - ret = -1; - } - if (!is_aligned(p2, align2)) { - printf("p2 is not aligned\n"); - ret = -1; - } - if (!is_aligned(p3, align3)) { - printf("p3 is not aligned\n"); - ret = -1; - } - rte_free(p1); - rte_free(p2); - rte_free(p3); - } - rte_malloc_dump_stats(stdout, "dummy"); - - return ret; -} - -static int -test_reordered_free_per_lcore(__attribute__((unused)) void *arg) -{ - const unsigned align1 = 8, - align2 = 64, - align3 = 2048; - unsigned i,j; - void *p1, *p2, *p3; - int ret = 0; - - for (i = 0; i < 30; i++) { - p1 = rte_zmalloc("dummy", 1000, align1); - if (!p1){ - printf("rte_zmalloc returned NULL (i=%u)\n", i); - ret = -1; - break; - } - for(j = 0; j < 1000 ; j++) { - if( *(char *)p1 != 0) { - printf("rte_zmalloc didn't zero" - "the allocated memory\n"); - ret = -1; - } - } - /* use calloc to allocate 1000 16-byte items this time */ - p2 = rte_calloc("dummy", 1000, 16, align2); - /* for third request use regular malloc again */ - p3 = rte_malloc("dummy", 1000, align3); - if (!p2 || !p3){ - printf("rte_malloc returned NULL (i=%u)\n", i); - ret = -1; - break; - } - if (is_memory_overlap(p1, 1000, p2, 1000)) { - printf("p1 and p2 overlaps\n"); - ret = -1; - } - if (is_memory_overlap(p2, 1000, p3, 1000)) { - printf("p2 and p3 overlaps\n"); - ret = -1; - } - if (is_memory_overlap(p1, 1000, p3, 1000)) { - printf("p1 and p3 overlaps\n"); - ret = -1; - } - if (!is_aligned(p1, align1)) { - printf("p1 is not aligned\n"); - ret = -1; - } - if (!is_aligned(p2, align2)) { - printf("p2 is not aligned\n"); - ret = -1; - } - if (!is_aligned(p3, align3)) { - printf("p3 is not aligned\n"); - ret = -1; - } - /* try freeing in every possible order */ - switch (i%6){ - case 0: - rte_free(p1); - rte_free(p2); - rte_free(p3); - break; - case 1: - rte_free(p1); - rte_free(p3); - rte_free(p2); - break; - case 2: - rte_free(p2); - rte_free(p1); - rte_free(p3); - break; - case 3: - rte_free(p2); - rte_free(p3); - rte_free(p1); - break; - case 4: - rte_free(p3); - rte_free(p1); - rte_free(p2); - break; - case 5: - rte_free(p3); - rte_free(p2); - rte_free(p1); - break; - } - } - rte_malloc_dump_stats(stdout, "dummy"); - - return ret; -} - -/* test function inside the malloc lib*/ -static int -test_str_to_size(void) -{ - struct { - const char *str; - uint64_t value; - } test_values[] = - {{ "5G", (uint64_t)5 * 1024 * 1024 *1024 }, - {"0x20g", (uint64_t)0x20 * 1024 * 1024 *1024}, - {"10M", 10 * 1024 * 1024}, - {"050m", 050 * 1024 * 1024}, - {"8K", 8 * 1024}, - {"15k", 15 * 1024}, - {"0200", 0200}, - {"0x103", 0x103}, - {"432", 432}, - {"-1", 0}, /* negative values return 0 */ - {" -2", 0}, - {" -3MB", 0}, - {"18446744073709551616", 0} /* ULLONG_MAX + 1 == out of range*/ - }; - unsigned i; - for (i = 0; i < sizeof(test_values)/sizeof(test_values[0]); i++) - if (rte_str_to_size(test_values[i].str) != test_values[i].value) - return -1; - return 0; -} - -static int -test_multi_alloc_statistics(void) -{ - int socket = 0; - struct rte_malloc_socket_stats pre_stats, post_stats ,first_stats, second_stats; - size_t size = 2048; - int align = 1024; -#ifndef RTE_LIBRTE_MALLOC_DEBUG - int trailer_size = 0; -#else - int trailer_size = RTE_CACHE_LINE_SIZE; -#endif - int overhead = RTE_CACHE_LINE_SIZE + trailer_size; - - rte_malloc_get_socket_stats(socket, &pre_stats); - - void *p1 = rte_malloc_socket("stats", size , align, socket); - if (!p1) - return -1; - rte_free(p1); - rte_malloc_dump_stats(stdout, "stats"); - - rte_malloc_get_socket_stats(socket,&post_stats); - /* Check statistics reported are correct */ - /* All post stats should be equal to pre stats after alloc freed */ - if ((post_stats.heap_totalsz_bytes != pre_stats.heap_totalsz_bytes) && - (post_stats.heap_freesz_bytes!=pre_stats.heap_freesz_bytes) && - (post_stats.heap_allocsz_bytes!=pre_stats.heap_allocsz_bytes)&& - (post_stats.alloc_count!=pre_stats.alloc_count)&& - (post_stats.free_count!=pre_stats.free_count)) { - printf("Malloc statistics are incorrect - freed alloc\n"); - return -1; - } - /* Check two consecutive allocations */ - size = 1024; - align = 0; - rte_malloc_get_socket_stats(socket,&pre_stats); - void *p2 = rte_malloc_socket("add", size ,align, socket); - if (!p2) - return -1; - rte_malloc_get_socket_stats(socket,&first_stats); - - void *p3 = rte_malloc_socket("add2", size,align, socket); - if (!p3) - return -1; - - rte_malloc_get_socket_stats(socket,&second_stats); - - rte_free(p2); - rte_free(p3); - - /* After freeing both allocations check stats return to original */ - rte_malloc_get_socket_stats(socket, &post_stats); - - if(second_stats.heap_totalsz_bytes != first_stats.heap_totalsz_bytes) { - printf("Incorrect heap statistics: Total size \n"); - return -1; - } - /* Check allocated size is equal to two additions plus overhead */ - if(second_stats.heap_allocsz_bytes != - size + overhead + first_stats.heap_allocsz_bytes) { - printf("Incorrect heap statistics: Allocated size \n"); - return -1; - } - /* Check that allocation count increments correctly i.e. +1 */ - if (second_stats.alloc_count != first_stats.alloc_count + 1) { - printf("Incorrect heap statistics: Allocated count \n"); - return -1; - } - - if (second_stats.free_count != first_stats.free_count){ - printf("Incorrect heap statistics: Free count \n"); - return -1; - } - - /* Make sure that we didn't touch our greatest chunk: 2 * 11M) */ - if (post_stats.greatest_free_size != pre_stats.greatest_free_size) { - printf("Incorrect heap statistics: Greatest free size \n"); - return -1; - } - /* Free size must equal the original free size minus the new allocation*/ - if (first_stats.heap_freesz_bytes <= second_stats.heap_freesz_bytes) { - printf("Incorrect heap statistics: Free size \n"); - return -1; - } - - if ((post_stats.heap_totalsz_bytes != pre_stats.heap_totalsz_bytes) && - (post_stats.heap_freesz_bytes!=pre_stats.heap_freesz_bytes) && - (post_stats.heap_allocsz_bytes!=pre_stats.heap_allocsz_bytes)&& - (post_stats.alloc_count!=pre_stats.alloc_count)&& - (post_stats.free_count!=pre_stats.free_count)) { - printf("Malloc statistics are incorrect - freed alloc\n"); - return -1; - } - return 0; -} - -static int -test_rte_malloc_type_limits(void) -{ - /* The type-limits functionality is not yet implemented, - * so always return 0 no matter what the retval. - */ - const char *typename = "limit_test"; - rte_malloc_set_limit(typename, 64 * 1024); - rte_malloc_dump_stats(stdout, typename); - return 0; -} - -static int -test_realloc(void) -{ - const char hello_str[] = "Hello, world!"; - const unsigned size1 = 1024; - const unsigned size2 = size1 + 1024; - const unsigned size3 = size2; - const unsigned size4 = size3 + 1024; - - /* test data is the same even if element is moved*/ - char *ptr1 = rte_zmalloc(NULL, size1, RTE_CACHE_LINE_SIZE); - if (!ptr1){ - printf("NULL pointer returned from rte_zmalloc\n"); - return -1; - } - snprintf(ptr1, size1, "%s" ,hello_str); - char *ptr2 = rte_realloc(ptr1, size2, RTE_CACHE_LINE_SIZE); - if (!ptr2){ - rte_free(ptr1); - printf("NULL pointer returned from rte_realloc\n"); - return -1; - } - if (ptr1 == ptr2){ - printf("unexpected - ptr1 == ptr2\n"); - } - if (strcmp(ptr2, hello_str) != 0){ - printf("Error - lost data from pointed area\n"); - rte_free(ptr2); - return -1; - } - unsigned i; - for (i = strnlen(hello_str, sizeof(hello_str)); i < size1; i++) - if (ptr2[i] != 0){ - printf("Bad data in realloc\n"); - rte_free(ptr2); - return -1; - } - /* now allocate third element, free the second - * and resize third. It should not move. (ptr1 is now invalid) - */ - char *ptr3 = rte_zmalloc(NULL, size3, RTE_CACHE_LINE_SIZE); - if (!ptr3){ - printf("NULL pointer returned from rte_zmalloc\n"); - rte_free(ptr2); - return -1; - } - for (i = 0; i < size3; i++) - if (ptr3[i] != 0){ - printf("Bad data in zmalloc\n"); - rte_free(ptr3); - rte_free(ptr2); - return -1; - } - rte_free(ptr2); - /* first resize to half the size of the freed block */ - char *ptr4 = rte_realloc(ptr3, size4, RTE_CACHE_LINE_SIZE); - if (!ptr4){ - printf("NULL pointer returned from rte_realloc\n"); - rte_free(ptr3); - return -1; - } - if (ptr3 != ptr4){ - printf("Unexpected - ptr4 != ptr3\n"); - rte_free(ptr4); - return -1; - } - /* now resize again to the full size of the freed block */ - ptr4 = rte_realloc(ptr3, size3 + size2 + size1, RTE_CACHE_LINE_SIZE); - if (ptr3 != ptr4){ - printf("Unexpected - ptr4 != ptr3 on second resize\n"); - rte_free(ptr4); - return -1; - } - rte_free(ptr4); - - /* now try a resize to a smaller size, see if it works */ - const unsigned size5 = 1024; - const unsigned size6 = size5 / 2; - char *ptr5 = rte_malloc(NULL, size5, RTE_CACHE_LINE_SIZE); - if (!ptr5){ - printf("NULL pointer returned from rte_malloc\n"); - return -1; - } - char *ptr6 = rte_realloc(ptr5, size6, RTE_CACHE_LINE_SIZE); - if (!ptr6){ - printf("NULL pointer returned from rte_realloc\n"); - rte_free(ptr5); - return -1; - } - if (ptr5 != ptr6){ - printf("Error, resizing to a smaller size moved data\n"); - rte_free(ptr6); - return -1; - } - rte_free(ptr6); - - /* check for behaviour changing alignment */ - const unsigned size7 = 1024; - const unsigned orig_align = RTE_CACHE_LINE_SIZE; - unsigned new_align = RTE_CACHE_LINE_SIZE * 2; - char *ptr7 = rte_malloc(NULL, size7, orig_align); - if (!ptr7){ - printf("NULL pointer returned from rte_malloc\n"); - return -1; - } - /* calc an alignment we don't already have */ - while(RTE_PTR_ALIGN(ptr7, new_align) == ptr7) - new_align *= 2; - char *ptr8 = rte_realloc(ptr7, size7, new_align); - if (!ptr8){ - printf("NULL pointer returned from rte_realloc\n"); - rte_free(ptr7); - return -1; - } - if (RTE_PTR_ALIGN(ptr8, new_align) != ptr8){ - printf("Failure to re-align data\n"); - rte_free(ptr8); - return -1; - } - rte_free(ptr8); - - /* test behaviour when there is a free block after current one, - * but its not big enough - */ - unsigned size9 = 1024, size10 = 1024; - unsigned size11 = size9 + size10 + 256; - char *ptr9 = rte_malloc(NULL, size9, RTE_CACHE_LINE_SIZE); - if (!ptr9){ - printf("NULL pointer returned from rte_malloc\n"); - return -1; - } - char *ptr10 = rte_malloc(NULL, size10, RTE_CACHE_LINE_SIZE); - if (!ptr10){ - printf("NULL pointer returned from rte_malloc\n"); - return -1; - } - rte_free(ptr9); - char *ptr11 = rte_realloc(ptr10, size11, RTE_CACHE_LINE_SIZE); - if (!ptr11){ - printf("NULL pointer returned from rte_realloc\n"); - rte_free(ptr10); - return -1; - } - if (ptr11 == ptr10){ - printf("Error, unexpected that realloc has not created new buffer\n"); - rte_free(ptr11); - return -1; - } - rte_free(ptr11); - - /* check we don't crash if we pass null to realloc - * We should get a malloc of the size requested*/ - const size_t size12 = 1024; - size_t size12_check; - char *ptr12 = rte_realloc(NULL, size12, RTE_CACHE_LINE_SIZE); - if (!ptr12){ - printf("NULL pointer returned from rte_realloc\n"); - return -1; - } - if (rte_malloc_validate(ptr12, &size12_check) < 0 || - size12_check != size12){ - rte_free(ptr12); - return -1; - } - rte_free(ptr12); - return 0; -} - -static int -test_random_alloc_free(void *_ __attribute__((unused))) -{ - struct mem_list { - struct mem_list *next; - char data[0]; - } *list_head = NULL; - unsigned i; - unsigned count = 0; - - rte_srand((unsigned)rte_rdtsc()); - - for (i = 0; i < N; i++){ - unsigned free_mem = 0; - size_t allocated_size; - while (!free_mem){ - const unsigned mem_size = sizeof(struct mem_list) + \ - rte_rand() % (64 * 1024); - const unsigned align = 1 << (rte_rand() % 12); /* up to 4k alignment */ - struct mem_list *entry = rte_malloc(NULL, - mem_size, align); - if (entry == NULL) - return -1; - if (RTE_PTR_ALIGN(entry, align)!= entry) - return -1; - if (rte_malloc_validate(entry, &allocated_size) == -1 - || allocated_size < mem_size) - return -1; - memset(entry->data, rte_lcore_id(), - mem_size - sizeof(*entry)); - entry->next = list_head; - if (rte_malloc_validate(entry, NULL) == -1) - return -1; - list_head = entry; - - count++; - /* switch to freeing the memory with a 20% probability */ - free_mem = ((rte_rand() % 10) >= 8); - } - while (list_head){ - struct mem_list *entry = list_head; - list_head = list_head->next; - rte_free(entry); - } - } - printf("Lcore %u allocated/freed %u blocks\n", rte_lcore_id(), count); - return 0; -} - -#define err_return() do { \ - printf("%s: %d - Error\n", __func__, __LINE__); \ - goto err_return; \ -} while (0) - -static int -test_rte_malloc_validate(void) -{ - const size_t request_size = 1024; - size_t allocated_size; - char *data_ptr = rte_malloc(NULL, request_size, RTE_CACHE_LINE_SIZE); -#ifdef RTE_LIBRTE_MALLOC_DEBUG - int retval; - char *over_write_vals = NULL; -#endif - - if (data_ptr == NULL) { - printf("%s: %d - Allocation error\n", __func__, __LINE__); - return -1; - } - - /* check that a null input returns -1 */ - if (rte_malloc_validate(NULL, NULL) != -1) - err_return(); - - /* check that we get ok on a valid pointer */ - if (rte_malloc_validate(data_ptr, &allocated_size) < 0) - err_return(); - - /* check that the returned size is ok */ - if (allocated_size < request_size) - err_return(); - -#ifdef RTE_LIBRTE_MALLOC_DEBUG - - /****** change the header to be bad */ - char save_buf[64]; - over_write_vals = (char *)((uintptr_t)data_ptr - sizeof(save_buf)); - /* first save the data as a backup before overwriting it */ - memcpy(save_buf, over_write_vals, sizeof(save_buf)); - memset(over_write_vals, 1, sizeof(save_buf)); - /* then run validate */ - retval = rte_malloc_validate(data_ptr, NULL); - /* finally restore the data again */ - memcpy(over_write_vals, save_buf, sizeof(save_buf)); - /* check we previously had an error */ - if (retval != -1) - err_return(); - - /* check all ok again */ - if (rte_malloc_validate(data_ptr, &allocated_size) < 0) - err_return(); - - /**** change the trailer to be bad */ - over_write_vals = (char *)((uintptr_t)data_ptr + allocated_size); - /* first save the data as a backup before overwriting it */ - memcpy(save_buf, over_write_vals, sizeof(save_buf)); - memset(over_write_vals, 1, sizeof(save_buf)); - /* then run validate */ - retval = rte_malloc_validate(data_ptr, NULL); - /* finally restore the data again */ - memcpy(over_write_vals, save_buf, sizeof(save_buf)); - if (retval != -1) - err_return(); - - /* check all ok again */ - if (rte_malloc_validate(data_ptr, &allocated_size) < 0) - err_return(); -#endif - - rte_free(data_ptr); - return 0; - -err_return: - /*clean up */ - rte_free(data_ptr); - return -1; -} - -static int -test_zero_aligned_alloc(void) -{ - char *p1 = rte_malloc(NULL,1024, 0); - if (!p1) - goto err_return; - if (!rte_is_aligned(p1, RTE_CACHE_LINE_SIZE)) - goto err_return; - rte_free(p1); - return 0; - -err_return: - /*clean up */ - if (p1) rte_free(p1); - return -1; -} - -static int -test_malloc_bad_params(void) -{ - const char *type = NULL; - size_t size = 0; - unsigned align = RTE_CACHE_LINE_SIZE; - - /* rte_malloc expected to return null with inappropriate size */ - char *bad_ptr = rte_malloc(type, size, align); - if (bad_ptr != NULL) - goto err_return; - - /* rte_malloc expected to return null with inappropriate alignment */ - align = 17; - size = 1024; - - bad_ptr = rte_malloc(type, size, align); - if (bad_ptr != NULL) - goto err_return; - - return 0; - -err_return: - /* clean up pointer */ - if (bad_ptr) - rte_free(bad_ptr); - return -1; -} - -/* Check if memory is avilable on a specific socket */ -static int -is_mem_on_socket(int32_t socket) -{ - const struct rte_memseg *ms = rte_eal_get_physmem_layout(); - unsigned i; - - for (i = 0; i < RTE_MAX_MEMSEG; i++) { - if (socket == ms[i].socket_id) - return 1; - } - return 0; -} - -/* - * Find what socket a memory address is on. Only works for addresses within - * memsegs, not heap or stack... - */ -static int32_t -addr_to_socket(void * addr) -{ - const struct rte_memseg *ms = rte_eal_get_physmem_layout(); - unsigned i; - - for (i = 0; i < RTE_MAX_MEMSEG; i++) { - if ((ms[i].addr <= addr) && - ((uintptr_t)addr < - ((uintptr_t)ms[i].addr + (uintptr_t)ms[i].len))) - return ms[i].socket_id; - } - return -1; -} - -/* Test using rte_[c|m|zm]alloc_socket() on a specific socket */ -static int -test_alloc_single_socket(int32_t socket) -{ - const char *type = NULL; - const size_t size = 10; - const unsigned align = 0; - char *mem = NULL; - int32_t desired_socket = (socket == SOCKET_ID_ANY) ? - (int32_t)rte_socket_id() : socket; - - /* Test rte_calloc_socket() */ - mem = rte_calloc_socket(type, size, sizeof(char), align, socket); - if (mem == NULL) - return -1; - if (addr_to_socket(mem) != desired_socket) { - rte_free(mem); - return -1; - } - rte_free(mem); - - /* Test rte_malloc_socket() */ - mem = rte_malloc_socket(type, size, align, socket); - if (mem == NULL) - return -1; - if (addr_to_socket(mem) != desired_socket) { - return -1; - } - rte_free(mem); - - /* Test rte_zmalloc_socket() */ - mem = rte_zmalloc_socket(type, size, align, socket); - if (mem == NULL) - return -1; - if (addr_to_socket(mem) != desired_socket) { - rte_free(mem); - return -1; - } - rte_free(mem); - - return 0; -} - -static int -test_alloc_socket(void) -{ - unsigned socket_count = 0; - unsigned i; - - if (test_alloc_single_socket(SOCKET_ID_ANY) < 0) - return -1; - - for (i = 0; i < RTE_MAX_NUMA_NODES; i++) { - if (is_mem_on_socket(i)) { - socket_count++; - if (test_alloc_single_socket(i) < 0) { - printf("Fail: rte_malloc_socket(..., %u) did not succeed\n", - i); - return -1; - } - } - else { - if (test_alloc_single_socket(i) == 0) { - printf("Fail: rte_malloc_socket(..., %u) succeeded\n", - i); - return -1; - } - } - } - - /* Print warnign if only a single socket, but don't fail the test */ - if (socket_count < 2) { - printf("WARNING: alloc_socket test needs memory on multiple sockets!\n"); - } - - return 0; -} - -static int -test_malloc(void) -{ - unsigned lcore_id; - int ret = 0; - - if (test_str_to_size() < 0){ - printf("test_str_to_size() failed\n"); - return -1; - } - else printf("test_str_to_size() passed\n"); - - if (test_zero_aligned_alloc() < 0){ - printf("test_zero_aligned_alloc() failed\n"); - return -1; - } - else printf("test_zero_aligned_alloc() passed\n"); - - if (test_malloc_bad_params() < 0){ - printf("test_malloc_bad_params() failed\n"); - return -1; - } - else printf("test_malloc_bad_params() passed\n"); - - if (test_realloc() < 0){ - printf("test_realloc() failed\n"); - return -1; - } - else printf("test_realloc() passed\n"); - - /*----------------------------*/ - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - rte_eal_remote_launch(test_align_overlap_per_lcore, NULL, lcore_id); - } - - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) - ret = -1; - } - if (ret < 0){ - printf("test_align_overlap_per_lcore() failed\n"); - return ret; - } - else printf("test_align_overlap_per_lcore() passed\n"); - - /*----------------------------*/ - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - rte_eal_remote_launch(test_reordered_free_per_lcore, NULL, lcore_id); - } - - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) - ret = -1; - } - if (ret < 0){ - printf("test_reordered_free_per_lcore() failed\n"); - return ret; - } - else printf("test_reordered_free_per_lcore() passed\n"); - - /*----------------------------*/ - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - rte_eal_remote_launch(test_random_alloc_free, NULL, lcore_id); - } - - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) - ret = -1; - } - if (ret < 0){ - printf("test_random_alloc_free() failed\n"); - return ret; - } - else printf("test_random_alloc_free() passed\n"); - - /*----------------------------*/ - ret = test_rte_malloc_type_limits(); - if (ret < 0){ - printf("test_rte_malloc_type_limits() failed\n"); - return ret; - } - /* TODO: uncomment following line once type limits are valid */ - /*else printf("test_rte_malloc_type_limits() passed\n");*/ - - /*----------------------------*/ - ret = test_rte_malloc_validate(); - if (ret < 0){ - printf("test_rte_malloc_validate() failed\n"); - return ret; - } - else printf("test_rte_malloc_validate() passed\n"); - - ret = test_alloc_socket(); - if (ret < 0){ - printf("test_alloc_socket() failed\n"); - return ret; - } - else printf("test_alloc_socket() passed\n"); - - ret = test_multi_alloc_statistics(); - if (ret < 0) { - printf("test_multi_alloc_statistics() failed\n"); - return ret; - } - else - printf("test_multi_alloc_statistics() passed\n"); - - return 0; -} - -REGISTER_TEST_COMMAND(malloc_autotest, test_malloc); diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c deleted file mode 100644 index a2e9bc6cfb..0000000000 --- a/app/test/test_mbuf.c +++ /dev/null @@ -1,1152 +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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define MBUF_DATA_SIZE 2048 -#define NB_MBUF 128 -#define MBUF_TEST_DATA_LEN 1464 -#define MBUF_TEST_DATA_LEN2 50 -#define MBUF_TEST_HDR1_LEN 20 -#define MBUF_TEST_HDR2_LEN 30 -#define MBUF_TEST_ALL_HDRS_LEN (MBUF_TEST_HDR1_LEN+MBUF_TEST_HDR2_LEN) - -/* size of private data for mbuf in pktmbuf_pool2 */ -#define MBUF2_PRIV_SIZE 128 - -#define REFCNT_MAX_ITER 64 -#define REFCNT_MAX_TIMEOUT 10 -#define REFCNT_MAX_REF (RTE_MAX_LCORE) -#define REFCNT_MBUF_NUM 64 -#define REFCNT_RING_SIZE (REFCNT_MBUF_NUM * REFCNT_MAX_REF) - -#define MAGIC_DATA 0x42424242 - -#define MAKE_STRING(x) # x - -static struct rte_mempool *pktmbuf_pool = NULL; -static struct rte_mempool *pktmbuf_pool2 = NULL; - -#ifdef RTE_MBUF_REFCNT_ATOMIC - -static struct rte_mempool *refcnt_pool = NULL; -static struct rte_ring *refcnt_mbuf_ring = NULL; -static volatile uint32_t refcnt_stop_slaves; -static unsigned refcnt_lcore[RTE_MAX_LCORE]; - -#endif - -/* - * MBUF - * ==== - * - * #. Allocate a mbuf pool. - * - * - The pool contains NB_MBUF elements, where each mbuf is MBUF_SIZE - * bytes long. - * - * #. Test multiple allocations of mbufs from this pool. - * - * - Allocate NB_MBUF and store pointers in a table. - * - If an allocation fails, return an error. - * - Free all these mbufs. - * - Repeat the same test to check that mbufs were freed correctly. - * - * #. Test data manipulation in pktmbuf. - * - * - Alloc an mbuf. - * - Append data using rte_pktmbuf_append(). - * - Test for error in rte_pktmbuf_append() when len is too large. - * - Trim data at the end of mbuf using rte_pktmbuf_trim(). - * - Test for error in rte_pktmbuf_trim() when len is too large. - * - Prepend a header using rte_pktmbuf_prepend(). - * - Test for error in rte_pktmbuf_prepend() when len is too large. - * - Remove data at the beginning of mbuf using rte_pktmbuf_adj(). - * - Test for error in rte_pktmbuf_adj() when len is too large. - * - Check that appended data is not corrupt. - * - Free the mbuf. - * - Between all these tests, check data_len and pkt_len, and - * that the mbuf is contiguous. - * - Repeat the test to check that allocation operations - * reinitialize the mbuf correctly. - * - * #. Test packet cloning - * - Clone a mbuf and verify the data - * - Clone the cloned mbuf and verify the data - * - Attach a mbuf to another that does not have the same priv_size. - */ - -#define GOTO_FAIL(str, ...) do { \ - printf("mbuf test FAILED (l.%d): <" str ">\n", \ - __LINE__, ##__VA_ARGS__); \ - goto fail; \ -} while(0) - -/* - * test data manipulation in mbuf with non-ascii data - */ -static int -test_pktmbuf_with_non_ascii_data(void) -{ - struct rte_mbuf *m = NULL; - char *data; - - m = rte_pktmbuf_alloc(pktmbuf_pool); - if (m == NULL) - GOTO_FAIL("Cannot allocate mbuf"); - if (rte_pktmbuf_pkt_len(m) != 0) - GOTO_FAIL("Bad length"); - - data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN); - if (data == NULL) - GOTO_FAIL("Cannot append data"); - if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) - GOTO_FAIL("Bad pkt length"); - if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) - GOTO_FAIL("Bad data length"); - memset(data, 0xff, rte_pktmbuf_pkt_len(m)); - if (!rte_pktmbuf_is_contiguous(m)) - GOTO_FAIL("Buffer should be continuous"); - rte_pktmbuf_dump(stdout, m, MBUF_TEST_DATA_LEN); - - rte_pktmbuf_free(m); - - return 0; - -fail: - if(m) { - rte_pktmbuf_free(m); - } - return -1; -} - -/* - * test data manipulation in mbuf - */ -static int -test_one_pktmbuf(void) -{ - struct rte_mbuf *m = NULL; - char *data, *data2, *hdr; - unsigned i; - - printf("Test pktmbuf API\n"); - - /* alloc a mbuf */ - - m = rte_pktmbuf_alloc(pktmbuf_pool); - if (m == NULL) - GOTO_FAIL("Cannot allocate mbuf"); - if (rte_pktmbuf_pkt_len(m) != 0) - GOTO_FAIL("Bad length"); - - rte_pktmbuf_dump(stdout, m, 0); - - /* append data */ - - data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN); - if (data == NULL) - GOTO_FAIL("Cannot append data"); - if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) - GOTO_FAIL("Bad pkt length"); - if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) - GOTO_FAIL("Bad data length"); - memset(data, 0x66, rte_pktmbuf_pkt_len(m)); - if (!rte_pktmbuf_is_contiguous(m)) - GOTO_FAIL("Buffer should be continuous"); - rte_pktmbuf_dump(stdout, m, MBUF_TEST_DATA_LEN); - rte_pktmbuf_dump(stdout, m, 2*MBUF_TEST_DATA_LEN); - - /* this append should fail */ - - data2 = rte_pktmbuf_append(m, (uint16_t)(rte_pktmbuf_tailroom(m) + 1)); - if (data2 != NULL) - GOTO_FAIL("Append should not succeed"); - - /* append some more data */ - - data2 = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2); - if (data2 == NULL) - GOTO_FAIL("Cannot append data"); - if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2) - GOTO_FAIL("Bad pkt length"); - if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2) - GOTO_FAIL("Bad data length"); - if (!rte_pktmbuf_is_contiguous(m)) - GOTO_FAIL("Buffer should be continuous"); - - /* trim data at the end of mbuf */ - - if (rte_pktmbuf_trim(m, MBUF_TEST_DATA_LEN2) < 0) - GOTO_FAIL("Cannot trim data"); - if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) - GOTO_FAIL("Bad pkt length"); - if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) - GOTO_FAIL("Bad data length"); - if (!rte_pktmbuf_is_contiguous(m)) - GOTO_FAIL("Buffer should be continuous"); - - /* this trim should fail */ - - if (rte_pktmbuf_trim(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) == 0) - GOTO_FAIL("trim should not succeed"); - - /* prepend one header */ - - hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR1_LEN); - if (hdr == NULL) - GOTO_FAIL("Cannot prepend"); - if (data - hdr != MBUF_TEST_HDR1_LEN) - GOTO_FAIL("Prepend failed"); - if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN) - GOTO_FAIL("Bad pkt length"); - if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN) - GOTO_FAIL("Bad data length"); - if (!rte_pktmbuf_is_contiguous(m)) - GOTO_FAIL("Buffer should be continuous"); - memset(hdr, 0x55, MBUF_TEST_HDR1_LEN); - - /* prepend another header */ - - hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR2_LEN); - if (hdr == NULL) - GOTO_FAIL("Cannot prepend"); - if (data - hdr != MBUF_TEST_ALL_HDRS_LEN) - GOTO_FAIL("Prepend failed"); - if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN) - GOTO_FAIL("Bad pkt length"); - if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN) - GOTO_FAIL("Bad data length"); - if (!rte_pktmbuf_is_contiguous(m)) - GOTO_FAIL("Buffer should be continuous"); - memset(hdr, 0x55, MBUF_TEST_HDR2_LEN); - - rte_mbuf_sanity_check(m, 1); - rte_mbuf_sanity_check(m, 0); - rte_pktmbuf_dump(stdout, m, 0); - - /* this prepend should fail */ - - hdr = rte_pktmbuf_prepend(m, (uint16_t)(rte_pktmbuf_headroom(m) + 1)); - if (hdr != NULL) - GOTO_FAIL("prepend should not succeed"); - - /* remove data at beginning of mbuf (adj) */ - - if (data != rte_pktmbuf_adj(m, MBUF_TEST_ALL_HDRS_LEN)) - GOTO_FAIL("rte_pktmbuf_adj failed"); - if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) - GOTO_FAIL("Bad pkt length"); - if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) - GOTO_FAIL("Bad data length"); - if (!rte_pktmbuf_is_contiguous(m)) - GOTO_FAIL("Buffer should be continuous"); - - /* this adj should fail */ - - if (rte_pktmbuf_adj(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) != NULL) - GOTO_FAIL("rte_pktmbuf_adj should not succeed"); - - /* check data */ - - if (!rte_pktmbuf_is_contiguous(m)) - GOTO_FAIL("Buffer should be continuous"); - - for (i=0; inext = rte_pktmbuf_alloc(pktmbuf_pool); - if (m->next == NULL) - GOTO_FAIL("Next Pkt Null\n"); - - rte_pktmbuf_append(m->next, sizeof(uint32_t)); - data = rte_pktmbuf_mtod(m->next, unaligned_uint32_t *); - *data = MAGIC_DATA; - - clone = rte_pktmbuf_clone(m, pktmbuf_pool); - if (clone == NULL) - GOTO_FAIL("cannot clone data\n"); - - data = rte_pktmbuf_mtod(clone, unaligned_uint32_t *); - if (*data != MAGIC_DATA) - GOTO_FAIL("invalid data in clone\n"); - - data = rte_pktmbuf_mtod(clone->next, unaligned_uint32_t *); - if (*data != MAGIC_DATA) - GOTO_FAIL("invalid data in clone->next\n"); - - if (rte_mbuf_refcnt_read(m) != 2) - GOTO_FAIL("invalid refcnt in m\n"); - - if (rte_mbuf_refcnt_read(m->next) != 2) - GOTO_FAIL("invalid refcnt in m->next\n"); - - /* try to clone the clone */ - - clone2 = rte_pktmbuf_clone(clone, pktmbuf_pool); - if (clone2 == NULL) - GOTO_FAIL("cannot clone the clone\n"); - - data = rte_pktmbuf_mtod(clone2, unaligned_uint32_t *); - if (*data != MAGIC_DATA) - GOTO_FAIL("invalid data in clone2\n"); - - data = rte_pktmbuf_mtod(clone2->next, unaligned_uint32_t *); - if (*data != MAGIC_DATA) - GOTO_FAIL("invalid data in clone2->next\n"); - - if (rte_mbuf_refcnt_read(m) != 3) - GOTO_FAIL("invalid refcnt in m\n"); - - if (rte_mbuf_refcnt_read(m->next) != 3) - GOTO_FAIL("invalid refcnt in m->next\n"); - - /* free mbuf */ - rte_pktmbuf_free(m); - rte_pktmbuf_free(clone); - rte_pktmbuf_free(clone2); - - m = NULL; - clone = NULL; - clone2 = NULL; - printf("%s ok\n", __func__); - return 0; - -fail: - if (m) - rte_pktmbuf_free(m); - if (clone) - rte_pktmbuf_free(clone); - if (clone2) - rte_pktmbuf_free(clone2); - return -1; -} - -static int -test_attach_from_different_pool(void) -{ - struct rte_mbuf *m = NULL; - struct rte_mbuf *clone = NULL; - struct rte_mbuf *clone2 = NULL; - char *data, *c_data, *c_data2; - - /* alloc a mbuf */ - m = rte_pktmbuf_alloc(pktmbuf_pool); - if (m == NULL) - GOTO_FAIL("cannot allocate mbuf"); - - if (rte_pktmbuf_pkt_len(m) != 0) - GOTO_FAIL("Bad length"); - - data = rte_pktmbuf_mtod(m, char *); - - /* allocate a new mbuf from the second pool, and attach it to the first - * mbuf */ - clone = rte_pktmbuf_alloc(pktmbuf_pool2); - if (clone == NULL) - GOTO_FAIL("cannot allocate mbuf from second pool\n"); - - /* check data room size and priv size, and erase priv */ - if (rte_pktmbuf_data_room_size(clone->pool) != 0) - GOTO_FAIL("data room size should be 0\n"); - if (rte_pktmbuf_priv_size(clone->pool) != MBUF2_PRIV_SIZE) - GOTO_FAIL("data room size should be %d\n", MBUF2_PRIV_SIZE); - memset(clone + 1, 0, MBUF2_PRIV_SIZE); - - /* save data pointer to compare it after detach() */ - c_data = rte_pktmbuf_mtod(clone, char *); - if (c_data != (char *)clone + sizeof(*clone) + MBUF2_PRIV_SIZE) - GOTO_FAIL("bad data pointer in clone"); - if (rte_pktmbuf_headroom(clone) != 0) - GOTO_FAIL("bad headroom in clone"); - - rte_pktmbuf_attach(clone, m); - - if (rte_pktmbuf_mtod(clone, char *) != data) - GOTO_FAIL("clone was not attached properly\n"); - if (rte_pktmbuf_headroom(clone) != RTE_PKTMBUF_HEADROOM) - GOTO_FAIL("bad headroom in clone after attach"); - if (rte_mbuf_refcnt_read(m) != 2) - GOTO_FAIL("invalid refcnt in m\n"); - - /* allocate a new mbuf from the second pool, and attach it to the first - * cloned mbuf */ - clone2 = rte_pktmbuf_alloc(pktmbuf_pool2); - if (clone2 == NULL) - GOTO_FAIL("cannot allocate clone2 from second pool\n"); - - /* check data room size and priv size, and erase priv */ - if (rte_pktmbuf_data_room_size(clone2->pool) != 0) - GOTO_FAIL("data room size should be 0\n"); - if (rte_pktmbuf_priv_size(clone2->pool) != MBUF2_PRIV_SIZE) - GOTO_FAIL("data room size should be %d\n", MBUF2_PRIV_SIZE); - memset(clone2 + 1, 0, MBUF2_PRIV_SIZE); - - /* save data pointer to compare it after detach() */ - c_data2 = rte_pktmbuf_mtod(clone2, char *); - if (c_data2 != (char *)clone2 + sizeof(*clone2) + MBUF2_PRIV_SIZE) - GOTO_FAIL("bad data pointer in clone2"); - if (rte_pktmbuf_headroom(clone2) != 0) - GOTO_FAIL("bad headroom in clone2"); - - rte_pktmbuf_attach(clone2, clone); - - if (rte_pktmbuf_mtod(clone2, char *) != data) - GOTO_FAIL("clone2 was not attached properly\n"); - if (rte_pktmbuf_headroom(clone2) != RTE_PKTMBUF_HEADROOM) - GOTO_FAIL("bad headroom in clone2 after attach"); - if (rte_mbuf_refcnt_read(m) != 3) - GOTO_FAIL("invalid refcnt in m\n"); - - /* detach the clones */ - 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); - rte_pktmbuf_free(clone); - rte_pktmbuf_free(m); - printf("%s ok\n", __func__); - return 0; - -fail: - if (m) - rte_pktmbuf_free(m); - if (clone) - rte_pktmbuf_free(clone); - if (clone2) - rte_pktmbuf_free(clone2); - return -1; -} -#undef GOTO_FAIL - -/* - * test allocation and free of mbufs - */ -static int -test_pktmbuf_pool(void) -{ - unsigned i; - struct rte_mbuf *m[NB_MBUF]; - int ret = 0; - - for (i=0; idata_off += 64; - } - - /* free them */ - for (i=0; idata_off != RTE_PKTMBUF_HEADROOM) { - printf("invalid data_off\n"); - ret = -1; - } - } - - /* free them */ - for (i=0; inext; - rte_pktmbuf_free_seg(mt); - } - } - } - - return ret; -} - -/* - * Stress test for rte_mbuf atomic refcnt. - * Implies that RTE_MBUF_REFCNT_ATOMIC is defined. - * For more efficency, recomended to run with RTE_LIBRTE_MBUF_DEBUG defined. - */ - -#ifdef RTE_MBUF_REFCNT_ATOMIC - -static int -test_refcnt_slave(__attribute__((unused)) void *arg) -{ - unsigned lcore, free; - void *mp = 0; - - lcore = rte_lcore_id(); - printf("%s started at lcore %u\n", __func__, lcore); - - free = 0; - while (refcnt_stop_slaves == 0) { - if (rte_ring_dequeue(refcnt_mbuf_ring, &mp) == 0) { - free++; - rte_pktmbuf_free((struct rte_mbuf *)mp); - } - } - - refcnt_lcore[lcore] += free; - printf("%s finished at lcore %u, " - "number of freed mbufs: %u\n", - __func__, lcore, free); - return 0; -} - -static void -test_refcnt_iter(unsigned lcore, unsigned iter) -{ - uint16_t ref; - unsigned i, n, tref, wn; - struct rte_mbuf *m; - - tref = 0; - - /* For each mbuf in the pool: - * - allocate mbuf, - * - 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_avail_count(refcnt_pool); - i != n && (m = rte_pktmbuf_alloc(refcnt_pool)) != NULL; - i++) { - ref = RTE_MAX(rte_rand() % REFCNT_MAX_REF, 1UL); - tref += ref; - if ((ref & 1) != 0) { - rte_pktmbuf_refcnt_update(m, ref); - while (ref-- != 0) - rte_ring_enqueue(refcnt_mbuf_ring, m); - } else { - while (ref-- != 0) { - rte_pktmbuf_refcnt_update(m, 1); - rte_ring_enqueue(refcnt_mbuf_ring, m); - } - } - rte_pktmbuf_free(m); - } - - if (i != n) - rte_panic("(lcore=%u, iter=%u): was able to allocate only " - "%u from %u mbufs\n", lcore, iter, i, n); - - /* wait till slave lcores will consume all mbufs */ - while (!rte_ring_empty(refcnt_mbuf_ring)) - ; - - /* check that all mbufs are back into mempool by now */ - for (wn = 0; wn != REFCNT_MAX_TIMEOUT; wn++) { - 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(100); - } - - rte_panic("(lcore=%u, iter=%u): after %us only " - "%u of %u mbufs left free\n", lcore, iter, wn, i, n); -} - -static int -test_refcnt_master(void) -{ - unsigned i, lcore; - - lcore = rte_lcore_id(); - printf("%s started at lcore %u\n", __func__, lcore); - - for (i = 0; i != REFCNT_MAX_ITER; i++) - test_refcnt_iter(lcore, i); - - refcnt_stop_slaves = 1; - rte_wmb(); - - printf("%s finished at lcore %u\n", __func__, lcore); - return 0; -} - -#endif - -static int -test_refcnt_mbuf(void) -{ -#ifdef RTE_MBUF_REFCNT_ATOMIC - - unsigned lnum, master, slave, tref; - - - if ((lnum = rte_lcore_count()) == 1) { - printf("skipping %s, number of lcores: %u is not enough\n", - __func__, lnum); - return 0; - } - - printf("starting %s, at %u lcores\n", __func__, lnum); - - /* create refcnt pool & ring if they don't exist */ - - if (refcnt_pool == NULL && - (refcnt_pool = rte_pktmbuf_pool_create( - MAKE_STRING(refcnt_pool), - REFCNT_MBUF_NUM, 0, 0, 0, - SOCKET_ID_ANY)) == NULL) { - printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n", - __func__); - return -1; - } - - if (refcnt_mbuf_ring == NULL && - (refcnt_mbuf_ring = rte_ring_create("refcnt_mbuf_ring", - rte_align32pow2(REFCNT_RING_SIZE), SOCKET_ID_ANY, - RING_F_SP_ENQ)) == NULL) { - printf("%s: cannot allocate " MAKE_STRING(refcnt_mbuf_ring) - "\n", __func__); - return -1; - } - - refcnt_stop_slaves = 0; - memset(refcnt_lcore, 0, sizeof (refcnt_lcore)); - - rte_eal_mp_remote_launch(test_refcnt_slave, NULL, SKIP_MASTER); - - test_refcnt_master(); - - rte_eal_mp_wait_lcore(); - - /* check that we porcessed all references */ - tref = 0; - master = rte_get_master_lcore(); - - RTE_LCORE_FOREACH_SLAVE(slave) - tref += refcnt_lcore[slave]; - - if (tref != refcnt_lcore[master]) - rte_panic("refernced mbufs: %u, freed mbufs: %u\n", - tref, refcnt_lcore[master]); - - rte_mempool_dump(stdout, refcnt_pool); - rte_ring_dump(stdout, refcnt_mbuf_ring); - -#endif - return 0; -} - -#include -#include - -/* use fork() to test mbuf errors panic */ -static int -verify_mbuf_check_panics(struct rte_mbuf *buf) -{ - int pid; - int status; - - pid = fork(); - - if (pid == 0) { - rte_mbuf_sanity_check(buf, 1); /* should panic */ - exit(0); /* return normally if it doesn't panic */ - } else if (pid < 0){ - printf("Fork Failed\n"); - return -1; - } - wait(&status); - if(status == 0) - return -1; - - return 0; -} - -static int -test_failing_mbuf_sanity_check(void) -{ - struct rte_mbuf *buf; - struct rte_mbuf badbuf; - - printf("Checking rte_mbuf_sanity_check for failure conditions\n"); - - /* get a good mbuf to use to make copies */ - buf = rte_pktmbuf_alloc(pktmbuf_pool); - if (buf == NULL) - return -1; - printf("Checking good mbuf initially\n"); - if (verify_mbuf_check_panics(buf) != -1) - return -1; - - printf("Now checking for error conditions\n"); - - if (verify_mbuf_check_panics(NULL)) { - printf("Error with NULL mbuf test\n"); - return -1; - } - - badbuf = *buf; - badbuf.pool = NULL; - if (verify_mbuf_check_panics(&badbuf)) { - printf("Error with bad-pool mbuf test\n"); - return -1; - } - - badbuf = *buf; - badbuf.buf_physaddr = 0; - if (verify_mbuf_check_panics(&badbuf)) { - printf("Error with bad-physaddr mbuf test\n"); - return -1; - } - - badbuf = *buf; - badbuf.buf_addr = NULL; - if (verify_mbuf_check_panics(&badbuf)) { - printf("Error with bad-addr mbuf test\n"); - return -1; - } - - badbuf = *buf; - badbuf.refcnt = 0; - if (verify_mbuf_check_panics(&badbuf)) { - printf("Error with bad-refcnt(0) mbuf test\n"); - return -1; - } - - badbuf = *buf; - badbuf.refcnt = UINT16_MAX; - if (verify_mbuf_check_panics(&badbuf)) { - printf("Error with bad-refcnt(MAX) mbuf test\n"); - return -1; - } - - return 0; -} - -static int -test_mbuf_linearize(int pkt_len, int nb_segs) { - - struct rte_mbuf *m = NULL, *mbuf = NULL; - uint8_t *data; - int data_len = 0; - int remain; - int seg, seg_len; - int i; - - if (pkt_len < 1) { - printf("Packet size must be 1 or more (is %d)\n", pkt_len); - return -1; - } - - if (nb_segs < 1) { - printf("Number of segments must be 1 or more (is %d)\n", - nb_segs); - return -1; - } - - seg_len = pkt_len / nb_segs; - if (seg_len == 0) - seg_len = 1; - - remain = pkt_len; - - /* Create chained mbuf_src and fill it generated data */ - for (seg = 0; remain > 0; seg++) { - - m = rte_pktmbuf_alloc(pktmbuf_pool); - if (m == NULL) { - printf("Cannot create segment for source mbuf"); - goto fail; - } - - /* Make sure if tailroom is zeroed */ - memset(rte_pktmbuf_mtod(m, uint8_t *), 0, - rte_pktmbuf_tailroom(m)); - - data_len = remain; - if (data_len > seg_len) - data_len = seg_len; - - data = (uint8_t *)rte_pktmbuf_append(m, data_len); - if (data == NULL) { - printf("Cannot append %d bytes to the mbuf\n", - data_len); - goto fail; - } - - for (i = 0; i < data_len; i++) - data[i] = (seg * seg_len + i) % 0x0ff; - - if (seg == 0) - mbuf = m; - else - rte_pktmbuf_chain(mbuf, m); - - remain -= data_len; - } - - /* Create destination buffer to store coalesced data */ - if (rte_pktmbuf_linearize(mbuf)) { - printf("Mbuf linearization failed\n"); - goto fail; - } - - if (!rte_pktmbuf_is_contiguous(mbuf)) { - printf("Source buffer should be contiguous after " - "linearization\n"); - goto fail; - } - - data = rte_pktmbuf_mtod(mbuf, uint8_t *); - - for (i = 0; i < pkt_len; i++) - if (data[i] != (i % 0x0ff)) { - printf("Incorrect data in linearized mbuf\n"); - goto fail; - } - - rte_pktmbuf_free(mbuf); - return 0; - -fail: - if (mbuf) - rte_pktmbuf_free(mbuf); - return -1; -} - -static int -test_mbuf_linearize_check(void) -{ - struct test_mbuf_array { - int size; - int nb_segs; - } mbuf_array[] = { - { 128, 1 }, - { 64, 64 }, - { 512, 10 }, - { 250, 11 }, - { 123, 8 }, - }; - unsigned int i; - - printf("Test mbuf linearize API\n"); - - for (i = 0; i < RTE_DIM(mbuf_array); i++) - if (test_mbuf_linearize(mbuf_array[i].size, - mbuf_array[i].nb_segs)) { - printf("Test failed for %d, %d\n", mbuf_array[i].size, - mbuf_array[i].nb_segs); - return -1; - } - - return 0; -} - -static int -test_mbuf(void) -{ - RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != RTE_CACHE_LINE_MIN_SIZE * 2); - - /* create pktmbuf pool if it does not exist */ - if (pktmbuf_pool == NULL) { - pktmbuf_pool = rte_pktmbuf_pool_create("test_pktmbuf_pool", - NB_MBUF, 32, 0, MBUF_DATA_SIZE, SOCKET_ID_ANY); - } - - if (pktmbuf_pool == NULL) { - printf("cannot allocate mbuf pool\n"); - return -1; - } - - /* create a specific pktmbuf pool with a priv_size != 0 and no data - * room size */ - if (pktmbuf_pool2 == NULL) { - pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2", - NB_MBUF, 32, MBUF2_PRIV_SIZE, 0, SOCKET_ID_ANY); - } - - if (pktmbuf_pool2 == NULL) { - printf("cannot allocate mbuf pool\n"); - return -1; - } - - /* test multiple mbuf alloc */ - if (test_pktmbuf_pool() < 0) { - printf("test_mbuf_pool() failed\n"); - return -1; - } - - /* do it another time to check that all mbufs were freed */ - if (test_pktmbuf_pool() < 0) { - printf("test_mbuf_pool() failed (2)\n"); - return -1; - } - - /* test that the pointer to the data on a packet mbuf is set properly */ - if (test_pktmbuf_pool_ptr() < 0) { - printf("test_pktmbuf_pool_ptr() failed\n"); - return -1; - } - - /* test data manipulation in mbuf */ - if (test_one_pktmbuf() < 0) { - printf("test_one_mbuf() failed\n"); - return -1; - } - - - /* - * do it another time, to check that allocation reinitialize - * the mbuf correctly - */ - if (test_one_pktmbuf() < 0) { - printf("test_one_mbuf() failed (2)\n"); - return -1; - } - - if (test_pktmbuf_with_non_ascii_data() < 0) { - printf("test_pktmbuf_with_non_ascii_data() failed\n"); - return -1; - } - - /* test free pktmbuf segment one by one */ - if (test_pktmbuf_free_segment() < 0) { - printf("test_pktmbuf_free_segment() failed.\n"); - return -1; - } - - if (testclone_testupdate_testdetach()<0){ - printf("testclone_and_testupdate() failed \n"); - return -1; - } - - if (test_attach_from_different_pool() < 0) { - printf("test_attach_from_different_pool() failed\n"); - return -1; - } - - if (test_refcnt_mbuf()<0){ - printf("test_refcnt_mbuf() failed \n"); - return -1; - } - - if (test_failing_mbuf_sanity_check() < 0) { - printf("test_failing_mbuf_sanity_check() failed\n"); - return -1; - } - - if (test_mbuf_linearize_check() < 0) { - printf("test_mbuf_linearize_check() failed\n"); - return -1; - } - return 0; -} - -REGISTER_TEST_COMMAND(mbuf_autotest, test_mbuf); diff --git a/app/test/test_memcpy.c b/app/test/test_memcpy.c deleted file mode 100644 index 1d93dd53b1..0000000000 --- a/app/test/test_memcpy.c +++ /dev/null @@ -1,162 +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 -#include -#include -#include - -#include -#include -#include - -#include "test.h" - -/* - * Set this to the maximum buffer size you want to test. If it is 0, then the - * values in the buf_sizes[] array below will be used. - */ -#define TEST_VALUE_RANGE 0 - -/* List of buffer sizes to test */ -#if TEST_VALUE_RANGE == 0 -static size_t buf_sizes[] = { - 0, 1, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, - 256, 257, 320, 384, 511, 512, 513, 1023, 1024, 1025, 1518, 1522, 1600, - 2048, 3072, 4096, 5120, 6144, 7168, 8192 -}; -/* MUST be as large as largest packet size above */ -#define SMALL_BUFFER_SIZE 8192 -#else /* TEST_VALUE_RANGE != 0 */ -static size_t buf_sizes[TEST_VALUE_RANGE]; -#define SMALL_BUFFER_SIZE TEST_VALUE_RANGE -#endif /* TEST_VALUE_RANGE == 0 */ - -/* Data is aligned on this many bytes (power of 2) */ -#define ALIGNMENT_UNIT 32 - - -/* - * Create two buffers, and initialise one with random values. These are copied - * to the second buffer and then compared to see if the copy was successful. - * The bytes outside the copied area are also checked to make sure they were not - * changed. - */ -static int -test_single_memcpy(unsigned int off_src, unsigned int off_dst, size_t size) -{ - unsigned int i; - uint8_t dest[SMALL_BUFFER_SIZE + ALIGNMENT_UNIT]; - uint8_t src[SMALL_BUFFER_SIZE + ALIGNMENT_UNIT]; - void * ret; - - /* Setup buffers */ - for (i = 0; i < SMALL_BUFFER_SIZE + ALIGNMENT_UNIT; i++) { - dest[i] = 0; - src[i] = (uint8_t) rte_rand(); - } - - /* Do the copy */ - ret = rte_memcpy(dest + off_dst, src + off_src, size); - if (ret != (dest + off_dst)) { - printf("rte_memcpy() returned %p, not %p\n", - ret, dest + off_dst); - } - - /* Check nothing before offset is affected */ - for (i = 0; i < off_dst; i++) { - if (dest[i] != 0) { - printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): " - "[modified before start of dst].\n", - (unsigned)size, off_src, off_dst); - return -1; - } - } - - /* Check everything was copied */ - for (i = 0; i < size; i++) { - if (dest[i + off_dst] != src[i + off_src]) { - printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): " - "[didn't copy byte %u].\n", - (unsigned)size, off_src, off_dst, i); - return -1; - } - } - - /* Check nothing after copy was affected */ - for (i = size; i < SMALL_BUFFER_SIZE; i++) { - if (dest[i + off_dst] != 0) { - printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): " - "[copied too many].\n", - (unsigned)size, off_src, off_dst); - return -1; - } - } - return 0; -} - -/* - * Check functionality for various buffer sizes and data offsets/alignments. - */ -static int -func_test(void) -{ - unsigned int off_src, off_dst, i; - unsigned int num_buf_sizes = sizeof(buf_sizes) / sizeof(buf_sizes[0]); - int ret; - - for (off_src = 0; off_src < ALIGNMENT_UNIT; off_src++) { - for (off_dst = 0; off_dst < ALIGNMENT_UNIT; off_dst++) { - for (i = 0; i < num_buf_sizes; i++) { - ret = test_single_memcpy(off_src, off_dst, - buf_sizes[i]); - if (ret != 0) - return -1; - } - } - } - return 0; -} - -static int -test_memcpy(void) -{ - int ret; - - ret = func_test(); - if (ret != 0) - return -1; - return 0; -} - -REGISTER_TEST_COMMAND(memcpy_autotest, test_memcpy); diff --git a/app/test/test_memcpy_perf.c b/app/test/test_memcpy_perf.c deleted file mode 100644 index ff3aaaacad..0000000000 --- a/app/test/test_memcpy_perf.c +++ /dev/null @@ -1,354 +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 -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "test.h" - -/* - * Set this to the maximum buffer size you want to test. If it is 0, then the - * values in the buf_sizes[] array below will be used. - */ -#define TEST_VALUE_RANGE 0 - -/* List of buffer sizes to test */ -#if TEST_VALUE_RANGE == 0 -static size_t buf_sizes[] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, - 129, 191, 192, 193, 255, 256, 257, 319, 320, 321, 383, 384, 385, 447, 448, - 449, 511, 512, 513, 767, 768, 769, 1023, 1024, 1025, 1518, 1522, 1536, 1600, - 2048, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680, 8192 -}; -/* MUST be as large as largest packet size above */ -#define SMALL_BUFFER_SIZE 8192 -#else /* TEST_VALUE_RANGE != 0 */ -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) */ -#ifdef RTE_MACHINE_CPUFLAG_AVX512F -#define ALIGNMENT_UNIT 64 -#elif defined RTE_MACHINE_CPUFLAG_AVX2 -#define ALIGNMENT_UNIT 32 -#else /* RTE_MACHINE_CPUFLAG */ -#define ALIGNMENT_UNIT 16 -#endif /* RTE_MACHINE_CPUFLAG */ - -/* - * Pointers used in performance tests. The two large buffers are for uncached - * access where random addresses within the buffer are used for each - * memcpy. The two small buffers are for cached access. - */ -static uint8_t *large_buf_read, *large_buf_write; -static uint8_t *small_buf_read, *small_buf_write; - -/* Initialise data buffers. */ -static int -init_buffers(void) -{ - unsigned i; - - large_buf_read = rte_malloc("memcpy", LARGE_BUFFER_SIZE + ALIGNMENT_UNIT, ALIGNMENT_UNIT); - if (large_buf_read == NULL) - goto error_large_buf_read; - - large_buf_write = rte_malloc("memcpy", LARGE_BUFFER_SIZE + ALIGNMENT_UNIT, ALIGNMENT_UNIT); - if (large_buf_write == NULL) - goto error_large_buf_write; - - small_buf_read = rte_malloc("memcpy", SMALL_BUFFER_SIZE + ALIGNMENT_UNIT, ALIGNMENT_UNIT); - if (small_buf_read == NULL) - goto error_small_buf_read; - - small_buf_write = rte_malloc("memcpy", SMALL_BUFFER_SIZE + ALIGNMENT_UNIT, ALIGNMENT_UNIT); - if (small_buf_write == NULL) - goto error_small_buf_write; - - for (i = 0; i < LARGE_BUFFER_SIZE; i++) - large_buf_read[i] = rte_rand(); - for (i = 0; i < SMALL_BUFFER_SIZE; i++) - small_buf_read[i] = rte_rand(); - - return 0; - -error_small_buf_write: - rte_free(small_buf_read); -error_small_buf_read: - rte_free(large_buf_write); -error_large_buf_write: - rte_free(large_buf_read); -error_large_buf_read: - printf("ERROR: not enough memory\n"); - return -1; -} - -/* Cleanup data buffers */ -static void -free_buffers(void) -{ - rte_free(large_buf_read); - rte_free(large_buf_write); - rte_free(small_buf_read); - rte_free(small_buf_write); -} - -/* - * Get a random offset into large array, with enough space needed to perform - * max copy size. Offset is aligned, uoffset is used for unalignment setting. - */ -static inline size_t -get_rand_offset(size_t uoffset) -{ - return ((rte_rand() % (LARGE_BUFFER_SIZE - SMALL_BUFFER_SIZE)) & - ~(ALIGNMENT_UNIT - 1)) + uoffset; -} - -/* Fill in source and destination addresses. */ -static inline void -fill_addr_arrays(size_t *dst_addr, int is_dst_cached, size_t dst_uoffset, - size_t *src_addr, int is_src_cached, size_t src_uoffset) -{ - unsigned int i; - - for (i = 0; i < TEST_BATCH_SIZE; i++) { - dst_addr[i] = (is_dst_cached) ? dst_uoffset : get_rand_offset(dst_uoffset); - src_addr[i] = (is_src_cached) ? src_uoffset : get_rand_offset(src_uoffset); - } -} - -/* - * WORKAROUND: For some reason the first test doing an uncached write - * takes a very long time (~25 times longer than is expected). So we do - * it once without timing. - */ -static void -do_uncached_write(uint8_t *dst, int is_dst_cached, - const uint8_t *src, int is_src_cached, size_t size) -{ - unsigned i, j; - size_t dst_addrs[TEST_BATCH_SIZE], src_addrs[TEST_BATCH_SIZE]; - - for (i = 0; i < (TEST_ITERATIONS / TEST_BATCH_SIZE); i++) { - fill_addr_arrays(dst_addrs, is_dst_cached, 0, - src_addrs, is_src_cached, 0); - for (j = 0; j < TEST_BATCH_SIZE; j++) { - rte_memcpy(dst+dst_addrs[j], src+src_addrs[j], size); - } - } -} - -/* - * Run a single memcpy performance test. This is a macro to ensure that if - * the "size" parameter is a constant it won't be converted to a variable. - */ -#define SINGLE_PERF_TEST(dst, is_dst_cached, dst_uoffset, \ - src, is_src_cached, src_uoffset, size) \ -do { \ - unsigned int iter, t; \ - size_t dst_addrs[TEST_BATCH_SIZE], src_addrs[TEST_BATCH_SIZE]; \ - uint64_t start_time, total_time = 0; \ - uint64_t total_time2 = 0; \ - for (iter = 0; iter < (TEST_ITERATIONS / TEST_BATCH_SIZE); iter++) { \ - fill_addr_arrays(dst_addrs, is_dst_cached, dst_uoffset, \ - src_addrs, is_src_cached, src_uoffset); \ - start_time = rte_rdtsc(); \ - for (t = 0; t < TEST_BATCH_SIZE; t++) \ - rte_memcpy(dst+dst_addrs[t], src+src_addrs[t], size); \ - total_time += rte_rdtsc() - start_time; \ - } \ - for (iter = 0; iter < (TEST_ITERATIONS / TEST_BATCH_SIZE); iter++) { \ - fill_addr_arrays(dst_addrs, is_dst_cached, dst_uoffset, \ - src_addrs, is_src_cached, src_uoffset); \ - start_time = rte_rdtsc(); \ - for (t = 0; t < TEST_BATCH_SIZE; t++) \ - memcpy(dst+dst_addrs[t], src+src_addrs[t], size); \ - total_time2 += rte_rdtsc() - start_time; \ - } \ - printf("%8.0f -", (double)total_time /TEST_ITERATIONS); \ - printf("%5.0f", (double)total_time2 / TEST_ITERATIONS); \ -} while (0) - -/* Run aligned memcpy tests for each cached/uncached permutation */ -#define ALL_PERF_TESTS_FOR_SIZE(n) \ -do { \ - if (__builtin_constant_p(n)) \ - printf("\nC%6u", (unsigned)n); \ - else \ - printf("\n%7u", (unsigned)n); \ - SINGLE_PERF_TEST(small_buf_write, 1, 0, small_buf_read, 1, 0, n); \ - SINGLE_PERF_TEST(large_buf_write, 0, 0, small_buf_read, 1, 0, n); \ - SINGLE_PERF_TEST(small_buf_write, 1, 0, large_buf_read, 0, 0, n); \ - SINGLE_PERF_TEST(large_buf_write, 0, 0, large_buf_read, 0, 0, n); \ -} while (0) - -/* Run unaligned memcpy tests for each cached/uncached permutation */ -#define ALL_PERF_TESTS_FOR_SIZE_UNALIGNED(n) \ -do { \ - if (__builtin_constant_p(n)) \ - printf("\nC%6u", (unsigned)n); \ - else \ - printf("\n%7u", (unsigned)n); \ - SINGLE_PERF_TEST(small_buf_write, 1, 1, small_buf_read, 1, 5, n); \ - SINGLE_PERF_TEST(large_buf_write, 0, 1, small_buf_read, 1, 5, n); \ - SINGLE_PERF_TEST(small_buf_write, 1, 1, large_buf_read, 0, 5, n); \ - SINGLE_PERF_TEST(large_buf_write, 0, 1, large_buf_read, 0, 5, n); \ -} while (0) - -/* Run memcpy tests for constant length */ -#define ALL_PERF_TEST_FOR_CONSTANT \ -do { \ - TEST_CONSTANT(6U); TEST_CONSTANT(64U); TEST_CONSTANT(128U); \ - TEST_CONSTANT(192U); TEST_CONSTANT(256U); TEST_CONSTANT(512U); \ - TEST_CONSTANT(768U); TEST_CONSTANT(1024U); TEST_CONSTANT(1536U); \ -} while (0) - -/* Run all memcpy tests for aligned constant cases */ -static inline void -perf_test_constant_aligned(void) -{ -#define TEST_CONSTANT ALL_PERF_TESTS_FOR_SIZE - ALL_PERF_TEST_FOR_CONSTANT; -#undef TEST_CONSTANT -} - -/* Run all memcpy tests for unaligned constant cases */ -static inline void -perf_test_constant_unaligned(void) -{ -#define TEST_CONSTANT ALL_PERF_TESTS_FOR_SIZE_UNALIGNED - ALL_PERF_TEST_FOR_CONSTANT; -#undef TEST_CONSTANT -} - -/* Run all memcpy tests for aligned variable cases */ -static inline void -perf_test_variable_aligned(void) -{ - unsigned n = sizeof(buf_sizes) / sizeof(buf_sizes[0]); - unsigned i; - for (i = 0; i < n; i++) { - ALL_PERF_TESTS_FOR_SIZE((size_t)buf_sizes[i]); - } -} - -/* Run all memcpy tests for unaligned variable cases */ -static inline void -perf_test_variable_unaligned(void) -{ - unsigned n = sizeof(buf_sizes) / sizeof(buf_sizes[0]); - unsigned i; - for (i = 0; i < n; i++) { - ALL_PERF_TESTS_FOR_SIZE_UNALIGNED((size_t)buf_sizes[i]); - } -} - -/* Run all memcpy tests */ -static int -perf_test(void) -{ - int ret; - - ret = init_buffers(); - if (ret != 0) - return ret; - -#if TEST_VALUE_RANGE != 0 - /* Set up buf_sizes array, if required */ - unsigned i; - for (i = 0; i < TEST_VALUE_RANGE; i++) - buf_sizes[i] = i; -#endif - - /* See function comment */ - do_uncached_write(large_buf_write, 0, small_buf_read, 1, SMALL_BUFFER_SIZE); - - printf("\n** rte_memcpy() - memcpy perf. tests (C = compile-time constant) **\n" - "======= ============== ============== ============== ==============\n" - " Size Cache to cache Cache to mem Mem to cache Mem to mem\n" - "(bytes) (ticks) (ticks) (ticks) (ticks)\n" - "------- -------------- -------------- -------------- --------------"); - - printf("\n========================== %2dB aligned ============================", ALIGNMENT_UNIT); - /* Do aligned tests where size is a variable */ - perf_test_variable_aligned(); - printf("\n------- -------------- -------------- -------------- --------------"); - /* Do aligned tests where size is a compile-time constant */ - perf_test_constant_aligned(); - printf("\n=========================== Unaligned ============================="); - /* Do unaligned tests where size is a variable */ - perf_test_variable_unaligned(); - printf("\n------- -------------- -------------- -------------- --------------"); - /* Do unaligned tests where size is a compile-time constant */ - perf_test_constant_unaligned(); - printf("\n======= ============== ============== ============== ==============\n\n"); - - free_buffers(); - - return 0; -} - -static int -test_memcpy_perf(void) -{ - int ret; - - ret = perf_test(); - if (ret != 0) - return -1; - return 0; -} - -REGISTER_TEST_COMMAND(memcpy_perf_autotest, test_memcpy_perf); diff --git a/app/test/test_memory.c b/app/test/test_memory.c deleted file mode 100644 index 921bdc8833..0000000000 --- a/app/test/test_memory.c +++ /dev/null @@ -1,89 +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 -#include - -#include -#include - -#include "test.h" - -/* - * Memory - * ====== - * - * - Dump the mapped memory. The python-expect script checks that at - * least one line is dumped. - * - * - Check that memory size is different than 0. - * - * - Try to read all memory; it should not segfault. - */ - -static int -test_memory(void) -{ - uint64_t s; - unsigned i; - size_t j; - const struct rte_memseg *mem; - - /* - * dump the mapped memory: the python-expect script checks - * that at least one line is dumped - */ - printf("Dump memory layout\n"); - rte_dump_physmem_layout(stdout); - - /* check that memory size is != 0 */ - s = rte_eal_get_physmem_size(); - if (s == 0) { - printf("No memory detected\n"); - return -1; - } - - /* try to read memory (should not segfault) */ - mem = rte_eal_get_physmem_layout(); - for (i = 0; i < RTE_MAX_MEMSEG && mem[i].addr != NULL ; i++) { - - /* check memory */ - for (j = 0; j -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * Mempool - * ======= - * - * Basic tests: done on one core with and without cache: - * - * - Get one object, put one object - * - Get two objects, put two objects - * - Get all objects, test that their content is not modified and - * put them back in the pool. - */ - -#define MEMPOOL_ELT_SIZE 2048 -#define MAX_KEEP 16 -#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 rte_atomic32_t synchro; - -/* - * save the object number in the first 4 bytes of object data. All - * other bytes are set to 0. - */ -static void -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(struct rte_mempool *mp, int use_external_cache) -{ - uint32_t *objnum; - void **objtable; - void *obj, *obj2; - 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_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"); - /* 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->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 (rte_mempool_virt2phy(mp, obj) != rte_mem_virt2phy(obj)) - GOTO_ERR(ret, out); -#endif - - printf("put the object back\n"); - rte_mempool_generic_put(mp, &obj, 1, cache, 0); - rte_mempool_dump(stdout, mp); - - printf("get 2 objects\n"); - 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_generic_put(mp, &obj, 1, cache, 0); - rte_mempool_generic_put(mp, &obj2, 1, cache, 0); - rte_mempool_dump(stdout, mp); - - /* - * get many objects: we cannot get them all because the cache - * on other cores may not be empty. - */ - objtable = malloc(MEMPOOL_SIZE * sizeof(void *)); - if (objtable == NULL) - GOTO_ERR(ret, out); - - for (i = 0; i < MEMPOOL_SIZE; i++) { - if (rte_mempool_generic_get(mp, &objtable[i], 1, cache, 0) < 0) - break; - } - - /* - * for each object, check that its content was not modified, - * and put objects back in pool - */ - while (i--) { - obj = objtable[i]; - obj_data = obj; - objnum = obj; - if (*objnum > MEMPOOL_SIZE) { - printf("bad object number(%d)\n", *objnum); - ret = -1; - break; - } - for (j = sizeof(*objnum); j < mp->elt_size; j++) { - if (obj_data[j] != 0) - ret = -1; - } - - 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; -} - -static int test_mempool_creation_with_exceeded_cache_size(void) -{ - struct rte_mempool *mp_cov; - - 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; -} - -static struct rte_mempool *mp_spsc; -static rte_spinlock_t scsp_spinlock; -static void *scsp_obj_table[MAX_KEEP]; - -/* - * single producer function - */ -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() / 4; - - start_cycles = rte_get_timer_cycles(); - while (1) { - end_cycles = rte_get_timer_cycles(); - /* duration uses up, stop producing */ - if (start_cycles + duration < end_cycles) - break; - rte_spinlock_lock(&scsp_spinlock); - for (i = 0; i < MAX_KEEP; i ++) { - if (NULL != scsp_obj_table[i]) { - obj = scsp_obj_table[i]; - break; - } - } - rte_spinlock_unlock(&scsp_spinlock); - if (i >= MAX_KEEP) { - continue; - } - if (rte_mempool_from_obj(obj) != mp_spsc) { - printf("obj not owned by this mempool\n"); - RET_ERR(); - } - rte_mempool_put(mp_spsc, obj); - rte_spinlock_lock(&scsp_spinlock); - scsp_obj_table[i] = NULL; - rte_spinlock_unlock(&scsp_spinlock); - } - - return 0; -} - -/* - * single consumer function - */ -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() / 8; - - start_cycles = rte_get_timer_cycles(); - while (1) { - end_cycles = rte_get_timer_cycles(); - /* duration uses up, stop consuming */ - if (start_cycles + duration < end_cycles) - break; - rte_spinlock_lock(&scsp_spinlock); - for (i = 0; i < MAX_KEEP; i ++) { - if (NULL == scsp_obj_table[i]) - break; - } - rte_spinlock_unlock(&scsp_spinlock); - if (i >= MAX_KEEP) - continue; - if (rte_mempool_get(mp_spsc, &obj) < 0) - break; - rte_spinlock_lock(&scsp_spinlock); - scsp_obj_table[i] = obj; - rte_spinlock_unlock(&scsp_spinlock); - } - - return 0; -} - -/* - * 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) -{ - return test_mempool_single_consumer(); -} - -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*/ - return ; -} - -/* - * it tests the mempool operations based on singple producer and single consumer - */ -static int -test_mempool_sp_sc(void) -{ - int ret = 0; - unsigned lcore_id = rte_lcore_id(); - unsigned lcore_next; - - /* create a mempool with single producer/consumer ring */ - 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 (mp_spsc == NULL) - RET_ERR(); - } - if (rte_mempool_lookup("test_mempool_sp_sc") != mp_spsc) { - printf("Cannot lookup mempool from its name\n"); - rte_mempool_free(mp_spsc); - RET_ERR(); - } - lcore_next = rte_get_next_lcore(lcore_id, 0, 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) - ret = -1; - - if (rte_eal_wait_lcore(lcore_next) < 0) - ret = -1; - rte_mempool_free(mp_spsc); - - return ret; -} - -/* - * it tests some more basic of mempool - */ -static int -test_mempool_basic_ex(struct rte_mempool *mp) -{ - unsigned i; - void **obj; - void *err_obj; - int ret = -1; - - if (mp == NULL) - return ret; - - 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_in_use_count(mp)); - if (rte_mempool_full(mp) != 1) { - 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_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_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 should be empty\n"); - goto fail_mp_basic_ex; - } - - 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 should be full\n"); - goto fail_mp_basic_ex; - } - - ret = 0; - -fail_mp_basic_ex: - if (obj != NULL) - rte_free((void *)obj); - - return ret; -} - -static int -test_mempool_same_name_twice_creation(void) -{ - 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; -} - -/* - * BAsic test for mempool_xmem functions. - */ -static int -test_mempool_xmem_misc(void) -{ - uint32_t elt_num, total_size; - size_t sz; - ssize_t usz; - - elt_num = MAX_KEEP; - total_size = rte_mempool_calc_obj_size(MEMPOOL_ELT_SIZE, 0, NULL); - sz = rte_mempool_xmem_size(elt_num, total_size, MEMPOOL_PG_SHIFT_MAX); - - usz = rte_mempool_xmem_usage(NULL, elt_num, total_size, 0, 1, - MEMPOOL_PG_SHIFT_MAX); - - 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); - return -1; - } - - return 0; -} - -static void -walk_cb(struct rte_mempool *mp, void *userdata __rte_unused) -{ - printf("\t%s\n", mp->name); -} - -static int -test_mempool(void) -{ - struct rte_mempool *mp_cache = NULL; - struct rte_mempool *mp_nocache = NULL; - struct rte_mempool *mp_stack = NULL; - - rte_atomic32_init(&synchro); - - /* create a mempool (without cache) */ - 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) */ - 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"); - goto err; - } - - printf("Walk into mempools:\n"); - rte_mempool_walk(walk_cb, NULL); - - rte_mempool_list_dump(stdout); - - /* basic tests without cache */ - if (test_mempool_basic(mp_nocache, 0) < 0) - goto err; - - /* basic tests with cache */ - 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) - goto err; - - /* mempool operation test based on single producer and single comsumer */ - if (test_mempool_sp_sc() < 0) - goto err; - - if (test_mempool_creation_with_exceeded_cache_size() < 0) - goto err; - - if (test_mempool_same_name_twice_creation() < 0) - goto err; - - if (test_mempool_xmem_misc() < 0) - 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_stack); - return -1; -} - -REGISTER_TEST_COMMAND(mempool_autotest, test_mempool); diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c deleted file mode 100644 index ebf1721ac3..0000000000 --- a/app/test/test_mempool_perf.c +++ /dev/null @@ -1,383 +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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * Mempool performance - * ======= - * - * Each core get *n_keep* objects per bulk of *n_get_bulk*. Then, - * objects are put back in the pool per bulk of *n_put_bulk*. - * - * This sequence is done during TIME_S seconds. - * - * This test is done on the following configurations: - * - * - Cores configuration (*cores*) - * - * - One core with cache - * - Two cores with cache - * - Max. cores with cache - * - 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*) - * - * - Bulk get from 1 to 32 - * - Bulk put from 1 to 32 - * - * - Number of kept objects (*n_keep*) - * - * - 32 - * - 128 - */ - -#define N 65536 -#define TIME_S 5 -#define MEMPOOL_ELT_SIZE 2048 -#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; - -/* number of objects in one bulk operation (get or put) */ -static unsigned n_get_bulk; -static unsigned n_put_bulk; - -/* number of objects retrived from mempool before putting them back */ -static unsigned n_keep; - -/* number of enqueues / dequeues */ -struct mempool_test_stats { - uint64_t enq_count; -} __rte_cache_aligned; - -static struct mempool_test_stats stats[RTE_MAX_LCORE]; - -/* - * save the object number in the first 4 bytes of object data. All - * other bytes are set to 0. - */ -static void -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; -} - -static int -per_lcore_mempool_test(__attribute__((unused)) void *arg) -{ - void *obj_table[MAX_KEEP]; - unsigned i, idx; - unsigned lcore_id = rte_lcore_id(); - 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) - GOTO_ERR(ret, out); - if (((n_keep / n_put_bulk) * n_put_bulk) != n_keep) - GOTO_ERR(ret, out); - - stats[lcore_id].enq_count = 0; - - /* wait synchro for slaves */ - if (lcore_id != rte_get_master_lcore()) - while (rte_atomic32_read(&synchro) == 0); - - start_cycles = rte_get_timer_cycles(); - - while (time_diff/hz < TIME_S) { - for (i = 0; likely(i < (N/n_keep)); i++) { - /* get n_keep objects by bulk of n_bulk */ - idx = 0; - while (idx < n_keep) { - ret = rte_mempool_generic_get(mp, - &obj_table[idx], - n_get_bulk, - cache, 0); - if (unlikely(ret < 0)) { - rte_mempool_dump(stdout, mp); - /* in this case, objects are lost... */ - GOTO_ERR(ret, out); - } - idx += n_get_bulk; - } - - /* put the objects back */ - idx = 0; - while (idx < n_keep) { - rte_mempool_generic_put(mp, &obj_table[idx], - n_put_bulk, - cache, 0); - idx += n_put_bulk; - } - } - end_cycles = rte_get_timer_cycles(); - time_diff = end_cycles - start_cycles; - stats[lcore_id].enq_count += N; - } - -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 */ -static int -launch_cores(unsigned cores) -{ - unsigned lcore_id; - uint64_t rate; - int ret; - unsigned cores_save = cores; - - rte_atomic32_set(&synchro, 0); - - /* reset stats */ - memset(stats, 0, sizeof(stats)); - - printf("mempool_autotest cache=%u cores=%u n_get_bulk=%u " - "n_put_bulk=%u n_keep=%u ", - use_external_cache ? - external_cache_size : (unsigned) mp->cache_size, - cores, n_get_bulk, n_put_bulk, n_keep); - - if (rte_mempool_avail_count(mp) != MEMPOOL_SIZE) { - printf("mempool is not full\n"); - return -1; - } - - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (cores == 1) - break; - cores--; - rte_eal_remote_launch(per_lcore_mempool_test, - NULL, lcore_id); - } - - /* start synchro and launch test on master */ - rte_atomic32_set(&synchro, 1); - - ret = per_lcore_mempool_test(NULL); - - cores = cores_save; - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (cores == 1) - break; - cores--; - if (rte_eal_wait_lcore(lcore_id) < 0) - ret = -1; - } - - if (ret < 0) { - printf("per-lcore test returned -1\n"); - return -1; - } - - rate = 0; - for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) - rate += (stats[lcore_id].enq_count / TIME_S); - - printf("rate_persec=%" PRIu64 "\n", rate); - - return 0; -} - -/* for a given number of core, launch all test cases */ -static int -do_one_mempool_test(unsigned cores) -{ - unsigned bulk_tab_get[] = { 1, 4, 32, 0 }; - unsigned bulk_tab_put[] = { 1, 4, 32, 0 }; - unsigned keep_tab[] = { 32, 128, 0 }; - unsigned *get_bulk_ptr; - unsigned *put_bulk_ptr; - unsigned *keep_ptr; - int ret; - - for (get_bulk_ptr = bulk_tab_get; *get_bulk_ptr; get_bulk_ptr++) { - for (put_bulk_ptr = bulk_tab_put; *put_bulk_ptr; put_bulk_ptr++) { - for (keep_ptr = keep_tab; *keep_ptr; keep_ptr++) { - - n_get_bulk = *get_bulk_ptr; - n_put_bulk = *put_bulk_ptr; - n_keep = *keep_ptr; - ret = launch_cores(cores); - - if (ret < 0) - return -1; - } - } - } - return 0; -} - -static int -test_mempool_perf(void) -{ - rte_atomic32_init(&synchro); - - /* create a mempool (without cache) */ - if (mp_nocache == NULL) - mp_nocache = rte_mempool_create("perf_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; - - /* create a mempool (with cache) */ - if (mp_cache == NULL) - mp_cache = rte_mempool_create("perf_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; - - /* performance test with 1, 2 and max cores */ - printf("start performance test (without cache)\n"); - mp = mp_nocache; - - 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; - - /* performance test with 1, 2 and max cores */ - printf("start performance test (with cache)\n"); - mp = mp_cache; - - 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; - - /* 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; -} - -REGISTER_TEST_COMMAND(mempool_perf_autotest, test_mempool_perf); diff --git a/app/test/test_memzone.c b/app/test/test_memzone.c deleted file mode 100644 index 7ae31cf746..0000000000 --- a/app/test/test_memzone.c +++ /dev/null @@ -1,875 +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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../../lib/librte_eal/common/malloc_elem.h" - -#include "test.h" - -/* - * Memzone - * ======= - * - * - Search for three reserved zones or reserve them if they do not exist: - * - * - One is on any socket id. - * - The second is on socket 0. - * - The last one is on socket 1 (if socket 1 exists). - * - * - Check that the zones exist. - * - * - Check that the zones are cache-aligned. - * - * - Check that zones do not overlap. - * - * - Check that the zones are on the correct socket id. - * - * - Check that a lookup of the first zone returns the same pointer. - * - * - Check that it is not possible to create another zone with the - * same name as an existing zone. - * - * - Check flags for specific huge page size reservation - */ - -/* Test if memory overlaps: return 1 if true, or 0 if false. */ -static int -is_memory_overlap(phys_addr_t ptr1, size_t len1, phys_addr_t ptr2, size_t len2) -{ - if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1) - return 1; - else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2) - return 1; - return 0; -} - -static int -test_memzone_invalid_alignment(void) -{ - const struct rte_memzone * mz; - - mz = rte_memzone_lookup("invalid_alignment"); - if (mz != NULL) { - printf("Zone with invalid alignment has been reserved\n"); - return -1; - } - - mz = rte_memzone_reserve_aligned("invalid_alignment", 100, - SOCKET_ID_ANY, 0, 100); - if (mz != NULL) { - printf("Zone with invalid alignment has been reserved\n"); - return -1; - } - return 0; -} - -static int -test_memzone_reserving_zone_size_bigger_than_the_maximum(void) -{ - const struct rte_memzone * mz; - - mz = rte_memzone_lookup("zone_size_bigger_than_the_maximum"); - if (mz != NULL) { - printf("zone_size_bigger_than_the_maximum has been reserved\n"); - return -1; - } - - mz = rte_memzone_reserve("zone_size_bigger_than_the_maximum", (size_t)-1, - SOCKET_ID_ANY, 0); - if (mz != NULL) { - printf("It is impossible to reserve such big a memzone\n"); - return -1; - } - - return 0; -} - -static int -test_memzone_reserve_flags(void) -{ - const struct rte_memzone *mz; - const struct rte_memseg *ms; - int hugepage_2MB_avail = 0; - int hugepage_1GB_avail = 0; - int hugepage_16MB_avail = 0; - int hugepage_16GB_avail = 0; - const size_t size = 100; - int i = 0; - ms = rte_eal_get_physmem_layout(); - for (i = 0; i < RTE_MAX_MEMSEG; i++) { - if (ms[i].hugepage_sz == RTE_PGSIZE_2M) - hugepage_2MB_avail = 1; - if (ms[i].hugepage_sz == RTE_PGSIZE_1G) - hugepage_1GB_avail = 1; - if (ms[i].hugepage_sz == RTE_PGSIZE_16M) - hugepage_16MB_avail = 1; - if (ms[i].hugepage_sz == RTE_PGSIZE_16G) - hugepage_16GB_avail = 1; - } - /* Display the availability of 2MB ,1GB, 16MB, 16GB pages */ - if (hugepage_2MB_avail) - printf("2MB Huge pages available\n"); - if (hugepage_1GB_avail) - printf("1GB Huge pages available\n"); - if (hugepage_16MB_avail) - printf("16MB Huge pages available\n"); - if (hugepage_16GB_avail) - printf("16GB Huge pages available\n"); - /* - * If 2MB pages available, check that a small memzone is correctly - * reserved from 2MB huge pages when requested by the RTE_MEMZONE_2MB flag. - * Also check that RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an - * available page size (i.e 1GB ) when 2MB pages are unavailable. - */ - if (hugepage_2MB_avail) { - mz = rte_memzone_reserve("flag_zone_2M", size, SOCKET_ID_ANY, - RTE_MEMZONE_2MB); - if (mz == NULL) { - printf("MEMZONE FLAG 2MB\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_2M) { - printf("hugepage_sz not equal 2M\n"); - return -1; - } - - mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY, - RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY); - if (mz == NULL) { - printf("MEMZONE FLAG 2MB\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_2M) { - printf("hugepage_sz not equal 2M\n"); - return -1; - } - - /* Check if 1GB huge pages are unavailable, that function fails unless - * HINT flag is indicated - */ - if (!hugepage_1GB_avail) { - mz = rte_memzone_reserve("flag_zone_1G_HINT", size, SOCKET_ID_ANY, - RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY); - if (mz == NULL) { - printf("MEMZONE FLAG 1GB & HINT\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_2M) { - printf("hugepage_sz not equal 2M\n"); - return -1; - } - - mz = rte_memzone_reserve("flag_zone_1G", size, SOCKET_ID_ANY, - RTE_MEMZONE_1GB); - if (mz != NULL) { - printf("MEMZONE FLAG 1GB\n"); - return -1; - } - } - } - - /*As with 2MB tests above for 1GB huge page requests*/ - if (hugepage_1GB_avail) { - mz = rte_memzone_reserve("flag_zone_1G", size, SOCKET_ID_ANY, - RTE_MEMZONE_1GB); - if (mz == NULL) { - printf("MEMZONE FLAG 1GB\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_1G) { - printf("hugepage_sz not equal 1G\n"); - return -1; - } - - mz = rte_memzone_reserve("flag_zone_1G_HINT", size, SOCKET_ID_ANY, - RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY); - if (mz == NULL) { - printf("MEMZONE FLAG 1GB\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_1G) { - printf("hugepage_sz not equal 1G\n"); - return -1; - } - - /* Check if 1GB huge pages are unavailable, that function fails unless - * HINT flag is indicated - */ - if (!hugepage_2MB_avail) { - mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY, - RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY); - if (mz == NULL){ - printf("MEMZONE FLAG 2MB & HINT\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_1G) { - printf("hugepage_sz not equal 1G\n"); - return -1; - } - mz = rte_memzone_reserve("flag_zone_2M", size, SOCKET_ID_ANY, - RTE_MEMZONE_2MB); - if (mz != NULL) { - printf("MEMZONE FLAG 2MB\n"); - return -1; - } - } - - if (hugepage_2MB_avail && hugepage_1GB_avail) { - mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY, - RTE_MEMZONE_2MB|RTE_MEMZONE_1GB); - if (mz != NULL) { - printf("BOTH SIZES SET\n"); - return -1; - } - } - } - /* - * This option is for IBM Power. If 16MB pages available, check - * that a small memzone is correctly reserved from 16MB huge pages - * when requested by the RTE_MEMZONE_16MB flag. Also check that - * RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an available - * page size (i.e 16GB ) when 16MB pages are unavailable. - */ - if (hugepage_16MB_avail) { - mz = rte_memzone_reserve("flag_zone_16M", size, SOCKET_ID_ANY, - RTE_MEMZONE_16MB); - if (mz == NULL) { - printf("MEMZONE FLAG 16MB\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_16M) { - printf("hugepage_sz not equal 16M\n"); - return -1; - } - - mz = rte_memzone_reserve("flag_zone_16M_HINT", size, - SOCKET_ID_ANY, RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY); - if (mz == NULL) { - printf("MEMZONE FLAG 2MB\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_16M) { - printf("hugepage_sz not equal 16M\n"); - return -1; - } - - /* Check if 1GB huge pages are unavailable, that function fails - * unless HINT flag is indicated - */ - if (!hugepage_16GB_avail) { - mz = rte_memzone_reserve("flag_zone_16G_HINT", size, - SOCKET_ID_ANY, - RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY); - if (mz == NULL) { - printf("MEMZONE FLAG 16GB & HINT\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_16M) { - printf("hugepage_sz not equal 16M\n"); - return -1; - } - - mz = rte_memzone_reserve("flag_zone_16G", size, - SOCKET_ID_ANY, RTE_MEMZONE_16GB); - if (mz != NULL) { - printf("MEMZONE FLAG 16GB\n"); - return -1; - } - } - } - /*As with 16MB tests above for 16GB huge page requests*/ - if (hugepage_16GB_avail) { - mz = rte_memzone_reserve("flag_zone_16G", size, SOCKET_ID_ANY, - RTE_MEMZONE_16GB); - if (mz == NULL) { - printf("MEMZONE FLAG 16GB\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_16G) { - printf("hugepage_sz not equal 16G\n"); - return -1; - } - - mz = rte_memzone_reserve("flag_zone_16G_HINT", size, - SOCKET_ID_ANY, RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY); - if (mz == NULL) { - printf("MEMZONE FLAG 16GB\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_16G) { - printf("hugepage_sz not equal 16G\n"); - return -1; - } - - /* Check if 1GB huge pages are unavailable, that function fails - * unless HINT flag is indicated - */ - if (!hugepage_16MB_avail) { - mz = rte_memzone_reserve("flag_zone_16M_HINT", size, - SOCKET_ID_ANY, - RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY); - if (mz == NULL) { - printf("MEMZONE FLAG 16MB & HINT\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_16G) { - printf("hugepage_sz not equal 16G\n"); - return -1; - } - mz = rte_memzone_reserve("flag_zone_16M", size, - SOCKET_ID_ANY, RTE_MEMZONE_16MB); - if (mz != NULL) { - printf("MEMZONE FLAG 16MB\n"); - return -1; - } - } - - if (hugepage_16MB_avail && hugepage_16GB_avail) { - mz = rte_memzone_reserve("flag_zone_16M_HINT", size, - SOCKET_ID_ANY, - RTE_MEMZONE_16MB|RTE_MEMZONE_16GB); - if (mz != NULL) { - printf("BOTH SIZES SET\n"); - return -1; - } - } - } - return 0; -} - - -/* Find the heap with the greatest free block size */ -static size_t -find_max_block_free_size(const unsigned _align) -{ - struct rte_malloc_socket_stats stats; - unsigned i, align = _align; - size_t len = 0; - - for (i = 0; i < RTE_MAX_NUMA_NODES; i++) { - rte_malloc_get_socket_stats(i, &stats); - if (stats.greatest_free_size > len) - len = stats.greatest_free_size; - } - - if (align < RTE_CACHE_LINE_SIZE) - align = RTE_CACHE_LINE_ROUNDUP(align+1); - - if (len <= MALLOC_ELEM_OVERHEAD + align) - return 0; - - return len - MALLOC_ELEM_OVERHEAD - align; -} - -static int -test_memzone_reserve_max(void) -{ - const struct rte_memzone *mz; - size_t maxlen; - - maxlen = find_max_block_free_size(0); - - if (maxlen == 0) { - printf("There is no space left!\n"); - return 0; - } - - mz = rte_memzone_reserve("max_zone", 0, SOCKET_ID_ANY, 0); - if (mz == NULL){ - printf("Failed to reserve a big chunk of memory - %s\n", - rte_strerror(rte_errno)); - rte_dump_physmem_layout(stdout); - rte_memzone_dump(stdout); - return -1; - } - - if (mz->len != maxlen) { - printf("Memzone reserve with 0 size did not return bigest block\n"); - printf("Expected size = %zu, actual size = %zu\n", maxlen, mz->len); - rte_dump_physmem_layout(stdout); - rte_memzone_dump(stdout); - return -1; - } - return 0; -} - -static int -test_memzone_reserve_max_aligned(void) -{ - const struct rte_memzone *mz; - size_t maxlen = 0; - - /* random alignment */ - rte_srand((unsigned)rte_rdtsc()); - const unsigned align = 1 << ((rte_rand() % 8) + 5); /* from 128 up to 4k alignment */ - - maxlen = find_max_block_free_size(align); - - if (maxlen == 0) { - printf("There is no space left for biggest %u-aligned memzone!\n", align); - return 0; - } - - mz = rte_memzone_reserve_aligned("max_zone_aligned", 0, - SOCKET_ID_ANY, 0, align); - if (mz == NULL){ - printf("Failed to reserve a big chunk of memory - %s\n", - rte_strerror(rte_errno)); - rte_dump_physmem_layout(stdout); - rte_memzone_dump(stdout); - return -1; - } - - if (mz->len != maxlen) { - printf("Memzone reserve with 0 size and alignment %u did not return" - " bigest block\n", align); - printf("Expected size = %zu, actual size = %zu\n", - maxlen, mz->len); - rte_dump_physmem_layout(stdout); - rte_memzone_dump(stdout); - return -1; - } - return 0; -} - -static int -test_memzone_aligned(void) -{ - const struct rte_memzone *memzone_aligned_32; - const struct rte_memzone *memzone_aligned_128; - const struct rte_memzone *memzone_aligned_256; - const struct rte_memzone *memzone_aligned_512; - const struct rte_memzone *memzone_aligned_1024; - - /* memzone that should automatically be adjusted to align on 64 bytes */ - memzone_aligned_32 = rte_memzone_reserve_aligned("aligned_32", 100, - SOCKET_ID_ANY, 0, 32); - - /* memzone that is supposed to be aligned on a 128 byte boundary */ - memzone_aligned_128 = rte_memzone_reserve_aligned("aligned_128", 100, - SOCKET_ID_ANY, 0, 128); - - /* memzone that is supposed to be aligned on a 256 byte boundary */ - memzone_aligned_256 = rte_memzone_reserve_aligned("aligned_256", 100, - SOCKET_ID_ANY, 0, 256); - - /* memzone that is supposed to be aligned on a 512 byte boundary */ - memzone_aligned_512 = rte_memzone_reserve_aligned("aligned_512", 100, - SOCKET_ID_ANY, 0, 512); - - /* memzone that is supposed to be aligned on a 1024 byte boundary */ - memzone_aligned_1024 = rte_memzone_reserve_aligned("aligned_1024", 100, - SOCKET_ID_ANY, 0, 1024); - - printf("check alignments and lengths\n"); - if (memzone_aligned_32 == NULL) { - printf("Unable to reserve 64-byte aligned memzone!\n"); - return -1; - } - if ((memzone_aligned_32->phys_addr & RTE_CACHE_LINE_MASK) != 0) - return -1; - if (((uintptr_t) memzone_aligned_32->addr & RTE_CACHE_LINE_MASK) != 0) - return -1; - if ((memzone_aligned_32->len & RTE_CACHE_LINE_MASK) != 0) - return -1; - - if (memzone_aligned_128 == NULL) { - printf("Unable to reserve 128-byte aligned memzone!\n"); - return -1; - } - if ((memzone_aligned_128->phys_addr & 127) != 0) - return -1; - if (((uintptr_t) memzone_aligned_128->addr & 127) != 0) - return -1; - if ((memzone_aligned_128->len & RTE_CACHE_LINE_MASK) != 0) - return -1; - - if (memzone_aligned_256 == NULL) { - printf("Unable to reserve 256-byte aligned memzone!\n"); - return -1; - } - if ((memzone_aligned_256->phys_addr & 255) != 0) - return -1; - if (((uintptr_t) memzone_aligned_256->addr & 255) != 0) - return -1; - if ((memzone_aligned_256->len & RTE_CACHE_LINE_MASK) != 0) - return -1; - - if (memzone_aligned_512 == NULL) { - printf("Unable to reserve 512-byte aligned memzone!\n"); - return -1; - } - if ((memzone_aligned_512->phys_addr & 511) != 0) - return -1; - if (((uintptr_t) memzone_aligned_512->addr & 511) != 0) - return -1; - if ((memzone_aligned_512->len & RTE_CACHE_LINE_MASK) != 0) - return -1; - - if (memzone_aligned_1024 == NULL) { - printf("Unable to reserve 1024-byte aligned memzone!\n"); - return -1; - } - if ((memzone_aligned_1024->phys_addr & 1023) != 0) - return -1; - if (((uintptr_t) memzone_aligned_1024->addr & 1023) != 0) - return -1; - if ((memzone_aligned_1024->len & RTE_CACHE_LINE_MASK) != 0) - return -1; - - /* check that zones don't overlap */ - printf("check overlapping\n"); - if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len, - memzone_aligned_128->phys_addr, memzone_aligned_128->len)) - return -1; - if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len, - memzone_aligned_256->phys_addr, memzone_aligned_256->len)) - return -1; - if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len, - memzone_aligned_512->phys_addr, memzone_aligned_512->len)) - return -1; - if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len, - memzone_aligned_1024->phys_addr, memzone_aligned_1024->len)) - return -1; - if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len, - memzone_aligned_256->phys_addr, memzone_aligned_256->len)) - return -1; - if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len, - memzone_aligned_512->phys_addr, memzone_aligned_512->len)) - return -1; - if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len, - memzone_aligned_1024->phys_addr, memzone_aligned_1024->len)) - return -1; - if (is_memory_overlap(memzone_aligned_256->phys_addr, memzone_aligned_256->len, - memzone_aligned_512->phys_addr, memzone_aligned_512->len)) - return -1; - if (is_memory_overlap(memzone_aligned_256->phys_addr, memzone_aligned_256->len, - memzone_aligned_1024->phys_addr, memzone_aligned_1024->len)) - return -1; - if (is_memory_overlap(memzone_aligned_512->phys_addr, memzone_aligned_512->len, - memzone_aligned_1024->phys_addr, memzone_aligned_1024->len)) - return -1; - return 0; -} - -static int -check_memzone_bounded(const char *name, uint32_t len, uint32_t align, - uint32_t bound) -{ - const struct rte_memzone *mz; - phys_addr_t bmask; - - bmask = ~((phys_addr_t)bound - 1); - - if ((mz = rte_memzone_reserve_bounded(name, len, SOCKET_ID_ANY, 0, - align, bound)) == NULL) { - printf("%s(%s): memzone creation failed\n", - __func__, name); - return -1; - } - - if ((mz->phys_addr & ((phys_addr_t)align - 1)) != 0) { - printf("%s(%s): invalid phys addr alignment\n", - __func__, mz->name); - return -1; - } - - if (((uintptr_t) mz->addr & ((uintptr_t)align - 1)) != 0) { - printf("%s(%s): invalid virtual addr alignment\n", - __func__, mz->name); - return -1; - } - - if ((mz->len & RTE_CACHE_LINE_MASK) != 0 || mz->len < len || - mz->len < RTE_CACHE_LINE_SIZE) { - printf("%s(%s): invalid length\n", - __func__, mz->name); - return -1; - } - - if ((mz->phys_addr & bmask) != - ((mz->phys_addr + mz->len - 1) & bmask)) { - printf("%s(%s): invalid memzone boundary %u crossed\n", - __func__, mz->name, bound); - return -1; - } - - return 0; -} - -static int -test_memzone_bounded(void) -{ - const struct rte_memzone *memzone_err; - const char *name; - int rc; - - /* should fail as boundary is not power of two */ - name = "bounded_error_31"; - if ((memzone_err = rte_memzone_reserve_bounded(name, - 100, SOCKET_ID_ANY, 0, 32, UINT32_MAX)) != NULL) { - printf("%s(%s)created a memzone with invalid boundary " - "conditions\n", __func__, memzone_err->name); - return -1; - } - - /* should fail as len is greater then boundary */ - name = "bounded_error_32"; - if ((memzone_err = rte_memzone_reserve_bounded(name, - 100, SOCKET_ID_ANY, 0, 32, 32)) != NULL) { - printf("%s(%s)created a memzone with invalid boundary " - "conditions\n", __func__, memzone_err->name); - return -1; - } - - if ((rc = check_memzone_bounded("bounded_128", 100, 128, 128)) != 0) - return rc; - - if ((rc = check_memzone_bounded("bounded_256", 100, 256, 128)) != 0) - return rc; - - if ((rc = check_memzone_bounded("bounded_1K", 100, 64, 1024)) != 0) - return rc; - - if ((rc = check_memzone_bounded("bounded_1K_MAX", 0, 64, 1024)) != 0) - return rc; - - return 0; -} - -static int -test_memzone_free(void) -{ - const struct rte_memzone *mz[RTE_MAX_MEMZONE]; - int i; - char name[20]; - - mz[0] = rte_memzone_reserve("tempzone0", 2000, SOCKET_ID_ANY, 0); - mz[1] = rte_memzone_reserve("tempzone1", 4000, SOCKET_ID_ANY, 0); - - if (mz[0] > mz[1]) - return -1; - if (!rte_memzone_lookup("tempzone0")) - return -1; - if (!rte_memzone_lookup("tempzone1")) - return -1; - - if (rte_memzone_free(mz[0])) { - printf("Fail memzone free - tempzone0\n"); - return -1; - } - if (rte_memzone_lookup("tempzone0")) { - printf("Found previously free memzone - tempzone0\n"); - return -1; - } - mz[2] = rte_memzone_reserve("tempzone2", 2000, SOCKET_ID_ANY, 0); - - if (mz[2] > mz[1]) { - printf("tempzone2 should have gotten the free entry from tempzone0\n"); - return -1; - } - if (rte_memzone_free(mz[2])) { - printf("Fail memzone free - tempzone2\n"); - return -1; - } - if (rte_memzone_lookup("tempzone2")) { - printf("Found previously free memzone - tempzone2\n"); - return -1; - } - if (rte_memzone_free(mz[1])) { - printf("Fail memzone free - tempzone1\n"); - return -1; - } - if (rte_memzone_lookup("tempzone1")) { - printf("Found previously free memzone - tempzone1\n"); - return -1; - } - - i = 0; - do { - snprintf(name, sizeof(name), "tempzone%u", i); - mz[i] = rte_memzone_reserve(name, 1, SOCKET_ID_ANY, 0); - } while (mz[i++] != NULL); - - if (rte_memzone_free(mz[0])) { - printf("Fail memzone free - tempzone0\n"); - return -1; - } - mz[0] = rte_memzone_reserve("tempzone0new", 0, SOCKET_ID_ANY, 0); - - if (mz[0] == NULL) { - printf("Fail to create memzone - tempzone0new - when MAX memzones were " - "created and one was free\n"); - return -1; - } - - for (i = i - 2; i >= 0; i--) { - if (rte_memzone_free(mz[i])) { - printf("Fail memzone free - tempzone%d\n", i); - return -1; - } - } - - return 0; -} - -static int -test_memzone(void) -{ - const struct rte_memzone *memzone1; - const struct rte_memzone *memzone2; - const struct rte_memzone *memzone3; - const struct rte_memzone *memzone4; - const struct rte_memzone *mz; - - memzone1 = rte_memzone_reserve("testzone1", 100, - SOCKET_ID_ANY, 0); - - memzone2 = rte_memzone_reserve("testzone2", 1000, - 0, 0); - - memzone3 = rte_memzone_reserve("testzone3", 1000, - 1, 0); - - memzone4 = rte_memzone_reserve("testzone4", 1024, - SOCKET_ID_ANY, 0); - - /* memzone3 may be NULL if we don't have NUMA */ - if (memzone1 == NULL || memzone2 == NULL || memzone4 == NULL) - return -1; - - rte_memzone_dump(stdout); - - /* check cache-line alignments */ - printf("check alignments and lengths\n"); - - if ((memzone1->phys_addr & RTE_CACHE_LINE_MASK) != 0) - return -1; - if ((memzone2->phys_addr & RTE_CACHE_LINE_MASK) != 0) - return -1; - if (memzone3 != NULL && (memzone3->phys_addr & RTE_CACHE_LINE_MASK) != 0) - return -1; - if ((memzone1->len & RTE_CACHE_LINE_MASK) != 0 || memzone1->len == 0) - return -1; - if ((memzone2->len & RTE_CACHE_LINE_MASK) != 0 || memzone2->len == 0) - return -1; - if (memzone3 != NULL && ((memzone3->len & RTE_CACHE_LINE_MASK) != 0 || - memzone3->len == 0)) - return -1; - if (memzone4->len != 1024) - return -1; - - /* check that zones don't overlap */ - printf("check overlapping\n"); - - if (is_memory_overlap(memzone1->phys_addr, memzone1->len, - memzone2->phys_addr, memzone2->len)) - return -1; - if (memzone3 != NULL && - is_memory_overlap(memzone1->phys_addr, memzone1->len, - memzone3->phys_addr, memzone3->len)) - return -1; - if (memzone3 != NULL && - is_memory_overlap(memzone2->phys_addr, memzone2->len, - memzone3->phys_addr, memzone3->len)) - return -1; - - printf("check socket ID\n"); - - /* memzone2 must be on socket id 0 and memzone3 on socket 1 */ - if (memzone2->socket_id != 0) - return -1; - if (memzone3 != NULL && memzone3->socket_id != 1) - return -1; - - printf("test zone lookup\n"); - mz = rte_memzone_lookup("testzone1"); - if (mz != memzone1) - return -1; - - printf("test duplcate zone name\n"); - mz = rte_memzone_reserve("testzone1", 100, - SOCKET_ID_ANY, 0); - if (mz != NULL) - return -1; - - printf("test free memzone\n"); - if (test_memzone_free() < 0) - return -1; - - printf("test reserving memzone with bigger size than the maximum\n"); - if (test_memzone_reserving_zone_size_bigger_than_the_maximum() < 0) - return -1; - - printf("test memzone_reserve flags\n"); - if (test_memzone_reserve_flags() < 0) - return -1; - - printf("test alignment for memzone_reserve\n"); - if (test_memzone_aligned() < 0) - return -1; - - printf("test boundary alignment for memzone_reserve\n"); - if (test_memzone_bounded() < 0) - return -1; - - printf("test invalid alignment for memzone_reserve\n"); - if (test_memzone_invalid_alignment() < 0) - return -1; - - printf("test reserving the largest size memzone possible\n"); - if (test_memzone_reserve_max() < 0) - return -1; - - printf("test reserving the largest size aligned memzone possible\n"); - if (test_memzone_reserve_max_aligned() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(memzone_autotest, test_memzone); diff --git a/app/test/test_meter.c b/app/test/test_meter.c deleted file mode 100644 index 26b0565788..0000000000 --- a/app/test/test_meter.c +++ /dev/null @@ -1,497 +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 -#include -#include -#include -#include - -#include "test.h" - -#include -#include - -#define mlog(format, ...) do{\ - printf("Line %d:",__LINE__);\ - printf(format, ##__VA_ARGS__);\ - printf("\n");\ - }while(0); - -#define melog(format, ...) do{\ - printf("Line %d:",__LINE__);\ - printf(format, ##__VA_ARGS__);\ - printf(" failed!\n");\ - return -1;\ - }while(0); - -#define TM_TEST_SRTCM_CIR_DF 46000000 -#define TM_TEST_SRTCM_CBS_DF 2048 -#define TM_TEST_SRTCM_EBS_DF 4096 - -#define TM_TEST_TRTCM_CIR_DF 46000000 -#define TM_TEST_TRTCM_PIR_DF 69000000 -#define TM_TEST_TRTCM_CBS_DF 2048 -#define TM_TEST_TRTCM_PBS_DF 4096 - -static struct rte_meter_srtcm_params sparams = - {.cir = TM_TEST_SRTCM_CIR_DF, - .cbs = TM_TEST_SRTCM_CBS_DF, - .ebs = TM_TEST_SRTCM_EBS_DF,}; - -static struct rte_meter_trtcm_params tparams= - {.cir = TM_TEST_TRTCM_CIR_DF, - .pir = TM_TEST_TRTCM_PIR_DF, - .cbs = TM_TEST_TRTCM_CBS_DF, - .pbs = TM_TEST_TRTCM_PBS_DF,}; - -/** - * functional test for rte_meter_srtcm_config - */ -static inline int -tm_test_srtcm_config(void) -{ -#define SRTCM_CFG_MSG "srtcm_config" - struct rte_meter_srtcm sm; - struct rte_meter_srtcm_params sparams1; - - /* invalid parameter test */ - if(rte_meter_srtcm_config(NULL, NULL) == 0) - melog(SRTCM_CFG_MSG); - if(rte_meter_srtcm_config(&sm, NULL) == 0) - melog(SRTCM_CFG_MSG); - if(rte_meter_srtcm_config(NULL, &sparams) == 0) - melog(SRTCM_CFG_MSG); - - /* cbs and ebs can't both be zero */ - sparams1 = sparams; - sparams1.cbs = 0; - sparams1.ebs = 0; - if(rte_meter_srtcm_config(&sm, &sparams1) == 0) - melog(SRTCM_CFG_MSG); - - /* cir should never be 0 */ - sparams1 = sparams; - sparams1.cir = 0; - if(rte_meter_srtcm_config(&sm, &sparams1) == 0) - melog(SRTCM_CFG_MSG); - - /* one of ebs and cbs can be zero, should be successful */ - sparams1 = sparams; - sparams1.ebs = 0; - if(rte_meter_srtcm_config(&sm, &sparams1) != 0) - melog(SRTCM_CFG_MSG); - - sparams1 = sparams; - sparams1.cbs = 0; - if(rte_meter_srtcm_config(&sm, &sparams1) != 0) - melog(SRTCM_CFG_MSG); - - /* usual parameter, should be successful */ - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_CFG_MSG); - - return 0; - -} - -/** - * functional test for rte_meter_trtcm_config - */ -static inline int -tm_test_trtcm_config(void) -{ - struct rte_meter_trtcm tm; - struct rte_meter_trtcm_params tparams1; -#define TRTCM_CFG_MSG "trtcm_config" - - /* invalid parameter test */ - if(rte_meter_trtcm_config(NULL, NULL) == 0) - melog(TRTCM_CFG_MSG); - if(rte_meter_trtcm_config(&tm, NULL) == 0) - melog(TRTCM_CFG_MSG); - if(rte_meter_trtcm_config(NULL, &tparams) == 0) - melog(TRTCM_CFG_MSG); - - /* cir, cbs, pir and pbs never be zero */ - tparams1 = tparams; - tparams1.cir = 0; - if(rte_meter_trtcm_config(&tm, &tparams1) == 0) - melog(TRTCM_CFG_MSG); - - tparams1 = tparams; - tparams1.cbs = 0; - if(rte_meter_trtcm_config(&tm, &tparams1) == 0) - melog(TRTCM_CFG_MSG); - - tparams1 = tparams; - tparams1.pbs = 0; - if(rte_meter_trtcm_config(&tm, &tparams1) == 0) - melog(TRTCM_CFG_MSG); - - tparams1 = tparams; - tparams1.pir = 0; - if(rte_meter_trtcm_config(&tm, &tparams1) == 0) - melog(TRTCM_CFG_MSG); - - /* pir should be greater or equal to cir */ - tparams1 = tparams; - tparams1.pir = tparams1.cir - 1; - if(rte_meter_trtcm_config(&tm, &tparams1) == 0) - melog(TRTCM_CFG_MSG" pir < cir test"); - - /* usual parameter, should be successful */ - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_CFG_MSG); - - return 0; -} - -/** - * functional test for rte_meter_srtcm_color_blind_check - */ -static inline int -tm_test_srtcm_color_blind_check(void) -{ -#define SRTCM_BLIND_CHECK_MSG "srtcm_blind_check" - struct rte_meter_srtcm sm; - uint64_t time; - uint64_t hz = rte_get_tsc_hz(); - - /* Test green */ - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_srtcm_color_blind_check( - &sm, time, TM_TEST_SRTCM_CBS_DF - 1) - != e_RTE_METER_GREEN) - melog(SRTCM_BLIND_CHECK_MSG" GREEN"); - - /* Test yellow */ - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_srtcm_color_blind_check( - &sm, time, TM_TEST_SRTCM_CBS_DF + 1) - != e_RTE_METER_YELLOW) - melog(SRTCM_BLIND_CHECK_MSG" YELLOW"); - - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_srtcm_color_blind_check( - &sm, time, (uint32_t)sm.ebs - 1) != e_RTE_METER_YELLOW) - melog(SRTCM_BLIND_CHECK_MSG" YELLOW"); - - /* Test red */ - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_srtcm_color_blind_check( - &sm, time, TM_TEST_SRTCM_EBS_DF + 1) - != e_RTE_METER_RED) - melog(SRTCM_BLIND_CHECK_MSG" RED"); - - return 0; - -} - -/** - * functional test for rte_meter_trtcm_color_blind_check - */ -static inline int -tm_test_trtcm_color_blind_check(void) -{ -#define TRTCM_BLIND_CHECK_MSG "trtcm_blind_check" - - uint64_t time; - struct rte_meter_trtcm tm; - uint64_t hz = rte_get_tsc_hz(); - - /* Test green */ - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_trtcm_color_blind_check( - &tm, time, TM_TEST_TRTCM_CBS_DF - 1) - != e_RTE_METER_GREEN) - melog(TRTCM_BLIND_CHECK_MSG" GREEN"); - - /* Test yellow */ - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_trtcm_color_blind_check( - &tm, time, TM_TEST_TRTCM_CBS_DF + 1) - != e_RTE_METER_YELLOW) - melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); - - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_trtcm_color_blind_check( - &tm, time, TM_TEST_TRTCM_PBS_DF - 1) - != e_RTE_METER_YELLOW) - melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); - - /* Test red */ - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_trtcm_color_blind_check( - &tm, time, TM_TEST_TRTCM_PBS_DF + 1) - != e_RTE_METER_RED) - melog(TRTCM_BLIND_CHECK_MSG" RED"); - - return 0; -} - - -/** - * @in[4] : the flags packets carries. - * @in[4] : the flags function expect to return. - * It will do blind check at the time of 1 second from beginning. - * At the time, it will use packets length of cbs -1, cbs + 1, - * ebs -1 and ebs +1 with flag in[0], in[1], in[2] and in[3] to do - * aware check, expect flag out[0], out[1], out[2] and out[3] - */ - -static inline int -tm_test_srtcm_aware_check -(enum rte_meter_color in[4], enum rte_meter_color out[4]) -{ -#define SRTCM_AWARE_CHECK_MSG "srtcm_aware_check" - struct rte_meter_srtcm sm; - uint64_t time; - uint64_t hz = rte_get_tsc_hz(); - - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_srtcm_color_aware_check( - &sm, time, TM_TEST_SRTCM_CBS_DF - 1, in[0]) != out[0]) - melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]); - - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_srtcm_color_aware_check( - &sm, time, TM_TEST_SRTCM_CBS_DF + 1, in[1]) != out[1]) - melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]); - - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_srtcm_color_aware_check( - &sm, time, TM_TEST_SRTCM_EBS_DF - 1, in[2]) != out[2]) - melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]); - - if(rte_meter_srtcm_config(&sm, &sparams) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_srtcm_color_aware_check( - &sm, time, TM_TEST_SRTCM_EBS_DF + 1, in[3]) != out[3]) - melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]); - - return 0; -} - - -/** - * functional test for rte_meter_srtcm_color_aware_check - */ -static inline int -tm_test_srtcm_color_aware_check(void) -{ - enum rte_meter_color in[4], out[4]; - - /** - * test 4 points that will produce green, yellow, yellow, red flag - * if using blind check - */ - - /* previouly have a green, test points should keep unchanged */ - in[0] = in[1] = in[2] = in[3] = e_RTE_METER_GREEN; - out[0] = e_RTE_METER_GREEN; - out[1] = e_RTE_METER_YELLOW; - out[2] = e_RTE_METER_YELLOW; - out[3] = e_RTE_METER_RED; - if(tm_test_srtcm_aware_check(in, out) != 0) - return -1; - - /** - * previously have a yellow, green & yellow = yellow - * yellow & red = red - */ - in[0] = in[1] = in[2] = in[3] = e_RTE_METER_YELLOW; - out[0] = e_RTE_METER_YELLOW; - out[1] = e_RTE_METER_YELLOW; - out[2] = e_RTE_METER_YELLOW; - out[3] = e_RTE_METER_RED; - if(tm_test_srtcm_aware_check(in, out) != 0) - return -1; - - /** - * previously have a red, red & green = red - * red & yellow = red - */ - in[0] = in[1] = in[2] = in[3] = e_RTE_METER_RED; - out[0] = e_RTE_METER_RED; - out[1] = e_RTE_METER_RED; - out[2] = e_RTE_METER_RED; - out[3] = e_RTE_METER_RED; - if(tm_test_srtcm_aware_check(in, out) != 0) - return -1; - - return 0; -} - -/** - * @in[4] : the flags packets carries. - * @in[4] : the flags function expect to return. - * It will do blind check at the time of 1 second from beginning. - * At the time, it will use packets length of cbs -1, cbs + 1, - * ebs -1 and ebs +1 with flag in[0], in[1], in[2] and in[3] to do - * aware check, expect flag out[0], out[1], out[2] and out[3] - */ -static inline int -tm_test_trtcm_aware_check -(enum rte_meter_color in[4], enum rte_meter_color out[4]) -{ -#define TRTCM_AWARE_CHECK_MSG "trtcm_aware_check" - struct rte_meter_trtcm tm; - uint64_t time; - uint64_t hz = rte_get_tsc_hz(); - - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_trtcm_color_aware_check( - &tm, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0]) - melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]); - - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_trtcm_color_aware_check( - &tm, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1]) - melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]); - - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_trtcm_color_aware_check( - &tm, time, TM_TEST_TRTCM_PBS_DF - 1, in[2]) != out[2]) - melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]); - - if(rte_meter_trtcm_config(&tm, &tparams) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if(rte_meter_trtcm_color_aware_check( - &tm, time, TM_TEST_TRTCM_PBS_DF + 1, in[3]) != out[3]) - melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]); - - return 0; -} - - -/** - * functional test for rte_meter_trtcm_color_aware_check - */ - -static inline int -tm_test_trtcm_color_aware_check(void) -{ - enum rte_meter_color in[4], out[4]; - /** - * test 4 points that will produce green, yellow, yellow, red flag - * if using blind check - */ - - /* previouly have a green, test points should keep unchanged */ - in[0] = in[1] = in[2] = in[3] = e_RTE_METER_GREEN; - out[0] = e_RTE_METER_GREEN; - out[1] = e_RTE_METER_YELLOW; - out[2] = e_RTE_METER_YELLOW; - out[3] = e_RTE_METER_RED; - if(tm_test_trtcm_aware_check(in, out) != 0) - return -1; - - in[0] = in[1] = in[2] = in[3] = e_RTE_METER_YELLOW; - out[0] = e_RTE_METER_YELLOW; - out[1] = e_RTE_METER_YELLOW; - out[2] = e_RTE_METER_YELLOW; - out[3] = e_RTE_METER_RED; - if(tm_test_trtcm_aware_check(in, out) != 0) - return -1; - - in[0] = in[1] = in[2] = in[3] = e_RTE_METER_RED; - out[0] = e_RTE_METER_RED; - out[1] = e_RTE_METER_RED; - out[2] = e_RTE_METER_RED; - out[3] = e_RTE_METER_RED; - if(tm_test_trtcm_aware_check(in, out) != 0) - return -1; - - return 0; -} - -/** - * test main entrance for library meter - */ -static int -test_meter(void) -{ - if(tm_test_srtcm_config() != 0 ) - return -1; - - if(tm_test_trtcm_config() != 0 ) - return -1; - - if(tm_test_srtcm_color_blind_check() != 0) - return -1; - - if(tm_test_trtcm_color_blind_check()!= 0) - return -1; - - if(tm_test_srtcm_color_aware_check()!= 0) - return -1; - - if(tm_test_trtcm_color_aware_check()!= 0) - return -1; - - return 0; - -} - -REGISTER_TEST_COMMAND(meter_autotest, test_meter); diff --git a/app/test/test_mp_secondary.c b/app/test/test_mp_secondary.c deleted file mode 100644 index 26c4afd67f..0000000000 --- a/app/test/test_mp_secondary.c +++ /dev/null @@ -1,285 +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 - -#include "test.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef RTE_LIBRTE_HASH -#include -#include -#endif /* RTE_LIBRTE_HASH */ - -#ifdef RTE_LIBRTE_LPM -#include -#endif /* RTE_LIBRTE_LPM */ - -#include - -#include "process.h" - -#define launch_proc(ARGV) process_dup(ARGV, \ - sizeof(ARGV)/(sizeof(ARGV[0])), __func__) - -#ifdef RTE_EXEC_ENV_LINUXAPP -static char* -get_current_prefix(char * prefix, int size) -{ - char path[PATH_MAX] = {0}; - char buf[PATH_MAX] = {0}; - - /* get file for config (fd is always 3) */ - snprintf(path, sizeof(path), "/proc/self/fd/%d", 3); - - /* return NULL on error */ - if (readlink(path, buf, sizeof(buf)) == -1) - return NULL; - - /* get the basename */ - snprintf(buf, sizeof(buf), "%s", basename(buf)); - - /* copy string all the way from second char up to start of _config */ - snprintf(prefix, size, "%.*s", - (int)(strnlen(buf, sizeof(buf)) - sizeof("_config")), - &buf[1]); - - return prefix; -} -#endif - -/* - * This function is called in the primary i.e. main test, to spawn off secondary - * processes to run actual mp tests. Uses fork() and exec pair - */ -static int -run_secondary_instances(void) -{ - int ret = 0; - char coremask[10]; - -#ifdef RTE_EXEC_ENV_LINUXAPP - char tmp[PATH_MAX] = {0}; - char prefix[PATH_MAX] = {0}; - - get_current_prefix(tmp, sizeof(tmp)); - - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); -#else - const char *prefix = ""; -#endif - - /* good case, using secondary */ - const char *argv1[] = { - prgname, "-c", coremask, "--proc-type=secondary", - prefix - }; - /* good case, using auto */ - const char *argv2[] = { - prgname, "-c", coremask, "--proc-type=auto", - prefix - }; - /* bad case, using invalid type */ - const char *argv3[] = { - prgname, "-c", coremask, "--proc-type=ERROR", - prefix - }; -#ifdef RTE_EXEC_ENV_LINUXAPP - /* bad case, using invalid file prefix */ - const char *argv4[] = { - prgname, "-c", coremask, "--proc-type=secondary", - "--file-prefix=ERROR" - }; -#endif - - snprintf(coremask, sizeof(coremask), "%x", \ - (1 << rte_get_master_lcore())); - - ret |= launch_proc(argv1); - ret |= launch_proc(argv2); - - ret |= !(launch_proc(argv3)); -#ifdef RTE_EXEC_ENV_LINUXAPP - ret |= !(launch_proc(argv4)); -#endif - - return ret; -} - -/* - * This function is run in the secondary instance to test that creation of - * objects fails in a secondary - */ -static int -run_object_creation_tests(void) -{ - const unsigned flags = 0; - const unsigned size = 1024; - const unsigned elt_size = 64; - const unsigned cache_size = 64; - const unsigned priv_data_size = 32; - - printf("### Testing object creation - expect lots of mz reserve errors!\n"); - - rte_errno = 0; - if ((rte_memzone_reserve("test_mz", size, rte_socket_id(), - flags) == NULL) && - (rte_memzone_lookup("test_mz") == NULL)) { - printf("Error: unexpected return value from rte_memzone_reserve\n"); - return -1; - } - printf("# Checked rte_memzone_reserve() OK\n"); - - rte_errno = 0; - if ((rte_ring_create( - "test_ring", size, rte_socket_id(), flags) == NULL) && - (rte_ring_lookup("test_ring") == NULL)){ - printf("Error: unexpected return value from rte_ring_create()\n"); - return -1; - } - printf("# Checked rte_ring_create() OK\n"); - - rte_errno = 0; - if ((rte_mempool_create("test_mp", size, elt_size, cache_size, - priv_data_size, NULL, NULL, NULL, NULL, - rte_socket_id(), flags) == NULL) && - (rte_mempool_lookup("test_mp") == NULL)){ - printf("Error: unexpected return value from rte_mempool_create()\n"); - return -1; - } - printf("# Checked rte_mempool_create() OK\n"); - -#ifdef RTE_LIBRTE_HASH - const struct rte_hash_parameters hash_params = { .name = "test_mp_hash" }; - rte_errno=0; - if ((rte_hash_create(&hash_params) != NULL) && - (rte_hash_find_existing(hash_params.name) == NULL)){ - printf("Error: unexpected return value from rte_hash_create()\n"); - return -1; - } - printf("# Checked rte_hash_create() OK\n"); - - const struct rte_fbk_hash_params fbk_params = { .name = "test_fbk_mp_hash" }; - rte_errno=0; - if ((rte_fbk_hash_create(&fbk_params) != NULL) && - (rte_fbk_hash_find_existing(fbk_params.name) == NULL)){ - printf("Error: unexpected return value from rte_fbk_hash_create()\n"); - return -1; - } - printf("# Checked rte_fbk_hash_create() OK\n"); -#endif - -#ifdef RTE_LIBRTE_LPM - rte_errno=0; - struct rte_lpm_config config; - - config.max_rules = rte_socket_id(); - config.number_tbl8s = 256; - config.flags = 0; - if ((rte_lpm_create("test_lpm", size, &config) != NULL) && - (rte_lpm_find_existing("test_lpm") == NULL)){ - printf("Error: unexpected return value from rte_lpm_create()\n"); - return -1; - } - 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"); - if (getuid() == 0) /* pci scans can fail as non-root */ - return -1; - } else - printf("PCI scan succeeded in secondary\n"); -#endif - - return 0; -} - -/* if called in a primary process, just spawns off a secondary process to - * run validation tests - which brings us right back here again... - * if called in a secondary process, this runs a series of API tests to check - * how things run in a secondary instance. - */ -int -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(); - } - - printf("IN SECONDARY PROCESS\n"); - - return run_object_creation_tests(); -} - -REGISTER_TEST_COMMAND(multiprocess_autotest, test_mp_secondary); diff --git a/app/test/test_pci.c b/app/test/test_pci.c deleted file mode 100644 index 7985376066..0000000000 --- a/app/test/test_pci.c +++ /dev/null @@ -1,322 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * Copyright(c) 2014 6WIND S.A. - * 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 -#include -#include -#include - -#include -#include -#include -#include - -#include "test.h" -#include "resource.h" - -/* Generic maximum number of drivers to have room to allocate all drivers */ -#define NUM_MAX_DRIVERS 256 - -/* - * PCI test - * ======== - * - * - Register a driver with a ``probe()`` function. - * - * - Dump all PCI devices. - * - * - Check that the ``probe()`` function is called at least once. - */ - -int test_pci_run = 0; /* value checked by the multiprocess test */ -static unsigned pci_dev_count; - -static int my_driver_init(struct rte_pci_driver *dr, - struct rte_pci_device *dev); - -/* IXGBE NICS */ -const struct rte_pci_id my_driver_id[] = { - {RTE_PCI_DEVICE(0x0001, 0x1234)}, - { .vendor_id = 0, /* sentinel */ }, -}; - -const struct rte_pci_id my_driver_id2[] = { - {RTE_PCI_DEVICE(0x0001, 0x4444)}, - {RTE_PCI_DEVICE(0x0002, 0xabcd)}, - { .vendor_id = 0, /* sentinel */ }, -}; - -struct rte_pci_driver my_driver = { - .driver = { - .name = "test_driver" - }, - .probe = my_driver_init, - .id_table = my_driver_id, - .drv_flags = 0, -}; - -struct rte_pci_driver my_driver2 = { - .driver = { - .name = "test_driver2" - }, - .probe = my_driver_init, - .id_table = my_driver_id2, - .drv_flags = 0, -}; - -static int -my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr, - struct rte_pci_device *dev) -{ - printf("My driver init called in %s\n", dr->driver.name); - printf("%x:%x:%x.%d", dev->addr.domain, dev->addr.bus, - dev->addr.devid, dev->addr.function); - printf(" - vendor:%x device:%x\n", dev->id.vendor_id, dev->id.device_id); - - pci_dev_count ++; - return 0; -} - -static void -blacklist_all_devices(void) -{ - struct rte_pci_device *dev = NULL; - unsigned i = 0; - char pci_addr_str[16]; - - TAILQ_FOREACH(dev, &pci_device_list, next) { - snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT, - dev->addr.domain, dev->addr.bus, dev->addr.devid, - dev->addr.function); - if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, - pci_addr_str) < 0) { - printf("Error: cannot blacklist <%s>", pci_addr_str); - break; - } - i++; - } - printf("%u devices blacklisted\n", i); -} - -/* clear devargs list that was modified by the test */ -static void free_devargs_list(void) -{ - struct rte_devargs *devargs; - - while (!TAILQ_EMPTY(&devargs_list)) { - devargs = TAILQ_FIRST(&devargs_list); - TAILQ_REMOVE(&devargs_list, devargs, next); - free(devargs->args); - free(devargs); - } -} - -/* 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_pci_device *dev; - struct rte_pci_driver *dr; - const struct resource *r; - int ret; - - 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 original devices & drivers lists */ - while (!TAILQ_EMPTY(&pci_driver_list)) { - dr = TAILQ_FIRST(&pci_driver_list); - rte_eal_pci_unregister(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); - - pci_dev_count = 0; - printf("Scan bus\n"); - rte_eal_pci_probe(); - - if (pci_dev_count == 0) { - printf("no device detected\n"); - return -1; - } - - /* save the real devargs_list */ - save_devargs_list = devargs_list; - TAILQ_INIT(&devargs_list); - - blacklist_all_devices(); - - pci_dev_count = 0; - printf("Scan bus with all devices blacklisted\n"); - rte_eal_pci_probe(); - - free_devargs_list(); - devargs_list = save_devargs_list; - - if (pci_dev_count != 0) { - printf("not all devices are blacklisted\n"); - return -1; - } - - test_pci_run = 1; - - rte_eal_pci_unregister(&my_driver); - rte_eal_pci_unregister(&my_driver2); - - 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; -} - -REGISTER_TEST_COMMAND(pci_autotest, test_pci); 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 deleted file mode 100644 index 2f9c1dada8..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/class +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 7752421cf1..0000000000 Binary files a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/config and /dev/null differ 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 deleted file mode 100644 index 900731ffd5..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/consistent_dma_mask_bits +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 48a629093b..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/device +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 900731ffd5..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/dma_mask_bits +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index d00491fd7e..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/enable +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 573541ac97..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/irq +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index f4c76ed932..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/modalias +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index d00491fd7e..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/msi_bus +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 3a2e3f4984..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/numa_node +++ /dev/null @@ -1 +0,0 @@ --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 deleted file mode 100644 index f3889296bf..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/resource +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index 573541ac97..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_numvfs +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 4b9026d8e2..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_totalvfs +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 89a932cc4d..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_device +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 446afb4b76..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_vendor +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 1dbe34de5d..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/uevent +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index 446afb4b76..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/vendor +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 22dd9361aa..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/class +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index f61bbe633c..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/device +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index f3889296bf..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/resource +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index f61bbe633c..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_device +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 4321b81fb2..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_vendor +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 4321b81fb2..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/vendor +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 22dd9361aa..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/class +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index ccaa498206..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/device +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index f3889296bf..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/resource +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index ccaa498206..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_device +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 446afb4b76..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_vendor +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 446afb4b76..0000000000 --- a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/vendor +++ /dev/null @@ -1 +0,0 @@ -0x0001 diff --git a/app/test/test_per_lcore.c b/app/test/test_per_lcore.c deleted file mode 100644 index 747513d47b..0000000000 --- a/app/test/test_per_lcore.c +++ /dev/null @@ -1,139 +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 -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * Per-lcore variables and lcore launch - * ==================================== - * - * - Use ``rte_eal_mp_remote_launch()`` to call ``assign_vars()`` on - * every available lcore. In this function, a per-lcore variable is - * assigned to the lcore_id. - * - * - Use ``rte_eal_mp_remote_launch()`` to call ``display_vars()`` on - * every available lcore. The function checks that the variable is - * correctly set, or returns -1. - * - * - If at least one per-core variable was not correct, the test function - * returns -1. - */ - -static RTE_DEFINE_PER_LCORE(unsigned, test) = 0x12345678; - -static int -assign_vars(__attribute__((unused)) void *arg) -{ - if (RTE_PER_LCORE(test) != 0x12345678) - return -1; - RTE_PER_LCORE(test) = rte_lcore_id(); - return 0; -} - -static int -display_vars(__attribute__((unused)) void *arg) -{ - unsigned lcore_id = rte_lcore_id(); - unsigned var = RTE_PER_LCORE(test); - unsigned socket_id = rte_lcore_to_socket_id(lcore_id); - - printf("on socket %u, on core %u, variable is %u\n", socket_id, lcore_id, var); - if (lcore_id != var) - return -1; - - RTE_PER_LCORE(test) = 0x12345678; - return 0; -} - -static int -test_per_lcore_delay(__attribute__((unused)) void *arg) -{ - rte_delay_ms(100); - printf("wait 100ms on lcore %u\n", rte_lcore_id()); - - return 0; -} - -static int -test_per_lcore(void) -{ - unsigned lcore_id; - int ret; - - rte_eal_mp_remote_launch(assign_vars, NULL, SKIP_MASTER); - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) - return -1; - } - - rte_eal_mp_remote_launch(display_vars, NULL, SKIP_MASTER); - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) - return -1; - } - - /* test if it could do remote launch twice at the same time or not */ - ret = rte_eal_mp_remote_launch(test_per_lcore_delay, NULL, SKIP_MASTER); - if (ret < 0) { - printf("It fails to do remote launch but it should able to do\n"); - return -1; - } - /* it should not be able to launch a lcore which is running */ - ret = rte_eal_mp_remote_launch(test_per_lcore_delay, NULL, SKIP_MASTER); - if (ret == 0) { - printf("It does remote launch successfully but it should not at this time\n"); - return -1; - } - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) - return -1; - } - - return 0; -} - -REGISTER_TEST_COMMAND(per_lcore_autotest, test_per_lcore); diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c deleted file mode 100644 index e055aa0726..0000000000 --- a/app/test/test_pmd_perf.c +++ /dev/null @@ -1,913 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include "packet_burst_generator.h" -#include "test.h" - -#define NB_ETHPORTS_USED (1) -#define NB_SOCKETS (2) -#define MEMPOOL_CACHE_SIZE 250 -#define MAX_PKT_BURST (32) -#define RTE_TEST_RX_DESC_DEFAULT (128) -#define RTE_TEST_TX_DESC_DEFAULT (512) -#define RTE_PORT_ALL (~(uint8_t)0x0) - -/* how long test would take at full line rate */ -#define RTE_TEST_DURATION (2) - -/* - * RX and TX Prefetch, Host, and Write-back threshold values should be - * carefully set for optimal performance. Consult the network - * controller's datasheet and supporting DPDK documentation for guidance - * on how these parameters should be set. - */ -#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ -#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ -#define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */ - -/* - * These default values are optimized for use with the Intel(R) 82599 10 GbE - * Controller and the DPDK ixgbe PMD. Consider using other values for other - * network controllers and/or network drivers. - */ -#define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */ -#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ -#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ - -#define MAX_TRAFFIC_BURST 2048 - -#define NB_MBUF RTE_MAX( \ - (unsigned)(nb_ports*nb_rx_queue*nb_rxd + \ - nb_ports*nb_lcores*MAX_PKT_BURST + \ - nb_ports*nb_tx_queue*nb_txd + \ - nb_lcores*MEMPOOL_CACHE_SIZE + \ - nb_ports*MAX_TRAFFIC_BURST), \ - (unsigned)8192) - - -static struct rte_mempool *mbufpool[NB_SOCKETS]; -/* ethernet addresses of ports */ -static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; - -static struct rte_eth_conf port_conf = { - .rxmode = { - .mq_mode = ETH_MQ_RX_NONE, - .max_rx_pkt_len = ETHER_MAX_LEN, - .split_hdr_size = 0, - .header_split = 0, /**< Header Split disabled */ - .hw_ip_checksum = 0, /**< IP checksum offload enabled */ - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ - .hw_vlan_strip = 0, /**< VLAN strip enabled. */ - .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ - .enable_scatter = 0, /**< scatter rx disabled */ - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, - .lpbk_mode = 1, /* enable loopback */ -}; - -static struct rte_eth_rxconf rx_conf = { - .rx_thresh = { - .pthresh = RX_PTHRESH, - .hthresh = RX_HTHRESH, - .wthresh = RX_WTHRESH, - }, - .rx_free_thresh = 32, -}; - -static struct rte_eth_txconf tx_conf = { - .tx_thresh = { - .pthresh = TX_PTHRESH, - .hthresh = TX_HTHRESH, - .wthresh = TX_WTHRESH, - }, - .tx_free_thresh = 32, /* Use PMD default values */ - .tx_rs_thresh = 32, /* Use PMD default values */ - .txq_flags = (ETH_TXQ_FLAGS_NOMULTSEGS | - ETH_TXQ_FLAGS_NOVLANOFFL | - ETH_TXQ_FLAGS_NOXSUMSCTP | - ETH_TXQ_FLAGS_NOXSUMUDP | - ETH_TXQ_FLAGS_NOXSUMTCP) -}; - -enum { - LCORE_INVALID = 0, - LCORE_AVAIL, - LCORE_USED, -}; - -struct lcore_conf { - uint8_t status; - uint8_t socketid; - uint16_t nb_ports; - uint8_t portlist[RTE_MAX_ETHPORTS]; -} __rte_cache_aligned; - -struct lcore_conf lcore_conf[RTE_MAX_LCORE]; - -static uint64_t link_mbps; - -enum { - SC_CONTINUOUS = 0, - SC_BURST_POLL_FIRST, - SC_BURST_XMIT_FIRST, -}; - -static uint32_t sc_flag; - -/* Check the link status of all ports in up to 3s, and print them finally */ -static void -check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) -{ -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */ - uint8_t portid, count, all_ports_up, print_flag = 0; - struct rte_eth_link link; - - printf("Checking link statuses...\n"); - fflush(stdout); - for (count = 0; count <= MAX_CHECK_TIME; count++) { - all_ports_up = 1; - for (portid = 0; portid < port_num; portid++) { - if ((port_mask & (1 << portid)) == 0) - continue; - memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(portid, &link); - /* print link status if flag set */ - if (print_flag == 1) { - if (link.link_status) { - printf("Port %d Link Up - speed %u " - "Mbps - %s\n", (uint8_t)portid, - (unsigned)link.link_speed, - (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? - ("full-duplex") : ("half-duplex\n")); - if (link_mbps == 0) - link_mbps = link.link_speed; - } else - printf("Port %d Link Down\n", - (uint8_t)portid); - continue; - } - /* clear all_ports_up flag if any link down */ - if (link.link_status == ETH_LINK_DOWN) { - all_ports_up = 0; - break; - } - } - /* after finally printing all link status, get out */ - if (print_flag == 1) - break; - - if (all_ports_up == 0) { - fflush(stdout); - rte_delay_ms(CHECK_INTERVAL); - } - - /* set the print_flag if all ports up or timeout */ - if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) - print_flag = 1; - } -} - -static void -print_ethaddr(const char *name, const struct ether_addr *eth_addr) -{ - char buf[ETHER_ADDR_FMT_SIZE]; - ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr); - printf("%s%s", name, buf); -} - -static int -init_traffic(struct rte_mempool *mp, - struct rte_mbuf **pkts_burst, uint32_t burst_size) -{ - struct ether_hdr pkt_eth_hdr; - struct ipv4_hdr pkt_ipv4_hdr; - struct udp_hdr pkt_udp_hdr; - uint32_t pktlen; - static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; - static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; - - - initialize_eth_header(&pkt_eth_hdr, - (struct ether_addr *)src_mac, - (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0); - - pktlen = initialize_ipv4_header(&pkt_ipv4_hdr, - IPV4_ADDR(10, 0, 0, 1), - IPV4_ADDR(10, 0, 0, 2), 26); - printf("IPv4 pktlen %u\n", pktlen); - - pktlen = initialize_udp_header(&pkt_udp_hdr, 0, 0, 18); - - printf("UDP pktlen %u\n", pktlen); - - return generate_packet_burst(mp, pkts_burst, &pkt_eth_hdr, - 0, &pkt_ipv4_hdr, 1, - &pkt_udp_hdr, burst_size, - PACKET_BURST_GEN_PKT_LEN, 1); -} - -static int -init_lcores(void) -{ - unsigned lcore_id; - - for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { - lcore_conf[lcore_id].socketid = - rte_lcore_to_socket_id(lcore_id); - if (rte_lcore_is_enabled(lcore_id) == 0) { - lcore_conf[lcore_id].status = LCORE_INVALID; - continue; - } else - lcore_conf[lcore_id].status = LCORE_AVAIL; - } - return 0; -} - -static int -init_mbufpool(unsigned nb_mbuf) -{ - int socketid; - unsigned lcore_id; - char s[64]; - - for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { - if (rte_lcore_is_enabled(lcore_id) == 0) - continue; - - socketid = rte_lcore_to_socket_id(lcore_id); - if (socketid >= NB_SOCKETS) { - rte_exit(EXIT_FAILURE, - "Socket %d of lcore %u is out of range %d\n", - socketid, lcore_id, NB_SOCKETS); - } - if (mbufpool[socketid] == NULL) { - snprintf(s, sizeof(s), "mbuf_pool_%d", socketid); - mbufpool[socketid] = - rte_pktmbuf_pool_create(s, nb_mbuf, - MEMPOOL_CACHE_SIZE, 0, - RTE_MBUF_DEFAULT_BUF_SIZE, socketid); - if (mbufpool[socketid] == NULL) - rte_exit(EXIT_FAILURE, - "Cannot init mbuf pool on socket %d\n", - socketid); - else - printf("Allocated mbuf pool on socket %d\n", - socketid); - } - } - return 0; -} - -static uint16_t -alloc_lcore(uint16_t socketid) -{ - unsigned lcore_id; - - for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { - if (LCORE_AVAIL != lcore_conf[lcore_id].status || - lcore_conf[lcore_id].socketid != socketid || - lcore_id == rte_get_master_lcore()) - continue; - lcore_conf[lcore_id].status = LCORE_USED; - lcore_conf[lcore_id].nb_ports = 0; - return lcore_id; - } - - return (uint16_t)-1; -} - -volatile uint64_t stop; -uint64_t count; -uint64_t drop; -uint64_t idle; - -static void -reset_count(void) -{ - count = 0; - drop = 0; - idle = 0; -} - -static void -stats_display(uint8_t port_id) -{ - struct rte_eth_stats stats; - rte_eth_stats_get(port_id, &stats); - - printf(" RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes: " - "%-"PRIu64"\n", - stats.ipackets, stats.imissed, stats.ibytes); - printf(" RX-errors: %-10"PRIu64" RX-nombuf: %-10"PRIu64"\n", - stats.ierrors, stats.rx_nombuf); - printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes: " - "%-"PRIu64"\n", - stats.opackets, stats.oerrors, stats.obytes); -} - -static void -signal_handler(int signum) -{ - /* USR1 signal, stop testing */ - if (signum == SIGUSR1) { - printf("Force Stop!\n"); - stop = 1; - } - - /* USR2 signal, print stats */ - if (signum == SIGUSR2) - stats_display(0); -} - -struct rte_mbuf **tx_burst; - -uint64_t (*do_measure)(struct lcore_conf *conf, - struct rte_mbuf *pkts_burst[], - uint64_t total_pkts); - -static uint64_t -measure_rxtx(struct lcore_conf *conf, - struct rte_mbuf *pkts_burst[], - uint64_t total_pkts) -{ - unsigned i, portid, nb_rx, nb_tx; - uint64_t prev_tsc, cur_tsc; - - prev_tsc = rte_rdtsc(); - - while (likely(!stop)) { - for (i = 0; i < conf->nb_ports; i++) { - portid = conf->portlist[i]; - nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, - pkts_burst, MAX_PKT_BURST); - if (unlikely(nb_rx == 0)) { - idle++; - continue; - } - - count += nb_rx; - nb_tx = rte_eth_tx_burst(portid, 0, pkts_burst, nb_rx); - if (unlikely(nb_tx < nb_rx)) { - drop += (nb_rx - nb_tx); - do { - rte_pktmbuf_free(pkts_burst[nb_tx]); - } while (++nb_tx < nb_rx); - } - } - if (unlikely(count >= total_pkts)) - break; - } - - cur_tsc = rte_rdtsc(); - - return cur_tsc - prev_tsc; -} - -static uint64_t -measure_rxonly(struct lcore_conf *conf, - struct rte_mbuf *pkts_burst[], - uint64_t total_pkts) -{ - unsigned i, portid, nb_rx, nb_tx; - uint64_t diff_tsc, cur_tsc; - - diff_tsc = 0; - while (likely(!stop)) { - for (i = 0; i < conf->nb_ports; i++) { - portid = conf->portlist[i]; - - cur_tsc = rte_rdtsc(); - nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, - pkts_burst, MAX_PKT_BURST); - if (unlikely(nb_rx == 0)) { - idle++; - continue; - } - diff_tsc += rte_rdtsc() - cur_tsc; - - count += nb_rx; - nb_tx = rte_eth_tx_burst(portid, 0, pkts_burst, nb_rx); - if (unlikely(nb_tx < nb_rx)) { - drop += (nb_rx - nb_tx); - do { - rte_pktmbuf_free(pkts_burst[nb_tx]); - } while (++nb_tx < nb_rx); - } - } - if (unlikely(count >= total_pkts)) - break; - } - - return diff_tsc; -} - -static uint64_t -measure_txonly(struct lcore_conf *conf, - struct rte_mbuf *pkts_burst[], - uint64_t total_pkts) -{ - unsigned i, portid, nb_rx, nb_tx; - uint64_t diff_tsc, cur_tsc; - - printf("do tx measure\n"); - diff_tsc = 0; - while (likely(!stop)) { - for (i = 0; i < conf->nb_ports; i++) { - portid = conf->portlist[i]; - nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, - pkts_burst, MAX_PKT_BURST); - if (unlikely(nb_rx == 0)) { - idle++; - continue; - } - - count += nb_rx; - - cur_tsc = rte_rdtsc(); - nb_tx = rte_eth_tx_burst(portid, 0, pkts_burst, nb_rx); - if (unlikely(nb_tx < nb_rx)) { - drop += (nb_rx - nb_tx); - do { - rte_pktmbuf_free(pkts_burst[nb_tx]); - } while (++nb_tx < nb_rx); - } - diff_tsc += rte_rdtsc() - cur_tsc; - } - if (unlikely(count >= total_pkts)) - break; - } - - return diff_tsc; -} - -/* main processing loop */ -static int -main_loop(__rte_unused void *args) -{ -#define PACKET_SIZE 64 -#define FRAME_GAP 12 -#define MAC_PREAMBLE 8 - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - unsigned lcore_id; - unsigned i, portid, nb_rx = 0, nb_tx = 0; - struct lcore_conf *conf; - int pkt_per_port; - uint64_t diff_tsc; - uint64_t packets_per_second, total_packets; - - lcore_id = rte_lcore_id(); - conf = &lcore_conf[lcore_id]; - if (conf->status != LCORE_USED) - return 0; - - pkt_per_port = MAX_TRAFFIC_BURST; - - int idx = 0; - for (i = 0; i < conf->nb_ports; i++) { - int num = pkt_per_port; - portid = conf->portlist[i]; - printf("inject %d packet to port %d\n", num, portid); - while (num) { - nb_tx = RTE_MIN(MAX_PKT_BURST, num); - nb_tx = rte_eth_tx_burst(portid, 0, - &tx_burst[idx], nb_tx); - num -= nb_tx; - idx += nb_tx; - } - } - printf("Total packets inject to prime ports = %u\n", idx); - - packets_per_second = (link_mbps * 1000 * 1000) / - ((PACKET_SIZE + FRAME_GAP + MAC_PREAMBLE) * CHAR_BIT); - printf("Each port will do %"PRIu64" packets per second\n", - packets_per_second); - - total_packets = RTE_TEST_DURATION * conf->nb_ports * packets_per_second; - printf("Test will stop after at least %"PRIu64" packets received\n", - + total_packets); - - diff_tsc = do_measure(conf, pkts_burst, total_packets); - - for (i = 0; i < conf->nb_ports; i++) { - portid = conf->portlist[i]; - int nb_free = pkt_per_port; - do { /* dry out */ - nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, - pkts_burst, MAX_PKT_BURST); - nb_tx = 0; - while (nb_tx < nb_rx) - rte_pktmbuf_free(pkts_burst[nb_tx++]); - nb_free -= nb_rx; - } while (nb_free != 0); - printf("free %d mbuf left in port %u\n", pkt_per_port, portid); - } - - if (count == 0) - return -1; - - printf("%"PRIu64" packet, %"PRIu64" drop, %"PRIu64" idle\n", - count, drop, idle); - printf("Result: %"PRIu64" cycles per packet\n", diff_tsc / count); - - return 0; -} - -rte_atomic64_t start; - -static inline int -poll_burst(void *args) -{ -#define MAX_IDLE (10000) - unsigned lcore_id; - struct rte_mbuf **pkts_burst; - uint64_t diff_tsc, cur_tsc; - uint16_t next[RTE_MAX_ETHPORTS]; - struct lcore_conf *conf; - uint32_t pkt_per_port = *((uint32_t *)args); - unsigned i, portid, nb_rx = 0; - uint64_t total; - uint64_t timeout = MAX_IDLE; - - lcore_id = rte_lcore_id(); - conf = &lcore_conf[lcore_id]; - if (conf->status != LCORE_USED) - return 0; - - total = pkt_per_port * conf->nb_ports; - printf("start to receive total expect %"PRIu64"\n", total); - - pkts_burst = (struct rte_mbuf **) - rte_calloc_socket("poll_burst", - total, sizeof(void *), - RTE_CACHE_LINE_SIZE, conf->socketid); - if (!pkts_burst) - return -1; - - for (i = 0; i < conf->nb_ports; i++) { - portid = conf->portlist[i]; - next[portid] = i * pkt_per_port; - } - - while (!rte_atomic64_read(&start)) - ; - - cur_tsc = rte_rdtsc(); - while (total) { - for (i = 0; i < conf->nb_ports; i++) { - portid = conf->portlist[i]; - nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, - &pkts_burst[next[portid]], - MAX_PKT_BURST); - if (unlikely(nb_rx == 0)) { - timeout--; - if (unlikely(timeout == 0)) - goto timeout; - continue; - } - next[portid] += nb_rx; - total -= nb_rx; - } - } -timeout: - diff_tsc = rte_rdtsc() - cur_tsc; - - printf("%"PRIu64" packets lost, IDLE %"PRIu64" times\n", - total, MAX_IDLE - timeout); - - /* clean up */ - total = pkt_per_port * conf->nb_ports - total; - for (i = 0; i < total; i++) - rte_pktmbuf_free(pkts_burst[i]); - - rte_free(pkts_burst); - - if (total > 0) - return diff_tsc / total; - else - return -1; -} - -static int -exec_burst(uint32_t flags, int lcore) -{ - unsigned i, portid, nb_tx = 0; - struct lcore_conf *conf; - uint32_t pkt_per_port; - int num, idx = 0; - int diff_tsc; - - conf = &lcore_conf[lcore]; - - pkt_per_port = MAX_TRAFFIC_BURST; - num = pkt_per_port; - - rte_atomic64_init(&start); - - /* start polling thread, but not actually poll yet */ - rte_eal_remote_launch(poll_burst, - (void *)&pkt_per_port, lcore); - - /* Only when polling first */ - if (flags == SC_BURST_POLL_FIRST) - rte_atomic64_set(&start, 1); - - /* start xmit */ - while (num) { - nb_tx = RTE_MIN(MAX_PKT_BURST, num); - for (i = 0; i < conf->nb_ports; i++) { - portid = conf->portlist[i]; - rte_eth_tx_burst(portid, 0, - &tx_burst[idx], nb_tx); - idx += nb_tx; - } - num -= nb_tx; - } - - sleep(5); - - /* only when polling second */ - if (flags == SC_BURST_XMIT_FIRST) - rte_atomic64_set(&start, 1); - - /* wait for polling finished */ - diff_tsc = rte_eal_wait_lcore(lcore); - if (diff_tsc < 0) { - printf("exec_burst: Failed to measure cycles per packet\n"); - return -1; - } - - printf("Result: %d cycles per packet\n", diff_tsc); - - return 0; -} - -static int -test_pmd_perf(void) -{ - uint16_t nb_ports, num, nb_lcores, slave_id = (uint16_t)-1; - uint16_t nb_rxd = MAX_TRAFFIC_BURST; - uint16_t nb_txd = MAX_TRAFFIC_BURST; - uint16_t portid; - uint16_t nb_rx_queue = 1, nb_tx_queue = 1; - int socketid = -1; - int ret; - - printf("Start PMD RXTX cycles cost test.\n"); - - signal(SIGUSR1, signal_handler); - signal(SIGUSR2, signal_handler); - - nb_ports = rte_eth_dev_count(); - if (nb_ports < NB_ETHPORTS_USED) { - printf("At least %u port(s) used for perf. test\n", - NB_ETHPORTS_USED); - return -1; - } - - nb_lcores = rte_lcore_count(); - - memset(lcore_conf, 0, sizeof(lcore_conf)); - init_lcores(); - - init_mbufpool(NB_MBUF); - - if (sc_flag == SC_CONTINUOUS) { - nb_rxd = RTE_TEST_RX_DESC_DEFAULT; - nb_txd = RTE_TEST_TX_DESC_DEFAULT; - } - printf("CONFIG RXD=%d TXD=%d\n", nb_rxd, nb_txd); - - reset_count(); - num = 0; - for (portid = 0; portid < nb_ports; portid++) { - if (socketid == -1) { - socketid = rte_eth_dev_socket_id(portid); - slave_id = alloc_lcore(socketid); - if (slave_id == (uint16_t)-1) { - printf("No avail lcore to run test\n"); - return -1; - } - printf("Performance test runs on lcore %u socket %u\n", - slave_id, socketid); - } - - if (socketid != rte_eth_dev_socket_id(portid)) { - printf("Skip port %d\n", portid); - continue; - } - - /* port configure */ - ret = rte_eth_dev_configure(portid, nb_rx_queue, - nb_tx_queue, &port_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Cannot configure device: err=%d, port=%d\n", - ret, portid); - - rte_eth_macaddr_get(portid, &ports_eth_addr[portid]); - printf("Port %u ", portid); - print_ethaddr("Address:", &ports_eth_addr[portid]); - printf("\n"); - - /* tx queue setup */ - ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, - socketid, &tx_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "rte_eth_tx_queue_setup: err=%d, " - "port=%d\n", ret, portid); - - /* rx queue steup */ - ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, - socketid, &rx_conf, - mbufpool[socketid]); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d," - "port=%d\n", ret, portid); - - /* Start device */ - stop = 0; - ret = rte_eth_dev_start(portid); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "rte_eth_dev_start: err=%d, port=%d\n", - ret, portid); - - /* always eanble promiscuous */ - rte_eth_promiscuous_enable(portid); - - lcore_conf[slave_id].portlist[num++] = portid; - lcore_conf[slave_id].nb_ports++; - } - check_all_ports_link_status(nb_ports, RTE_PORT_ALL); - - if (tx_burst == NULL) { - tx_burst = (struct rte_mbuf **) - rte_calloc_socket("tx_buff", - MAX_TRAFFIC_BURST * nb_ports, - sizeof(void *), - RTE_CACHE_LINE_SIZE, socketid); - if (!tx_burst) - return -1; - } - - init_traffic(mbufpool[socketid], - tx_burst, MAX_TRAFFIC_BURST * nb_ports); - - printf("Generate %d packets @socket %d\n", - MAX_TRAFFIC_BURST * nb_ports, socketid); - - if (sc_flag == SC_CONTINUOUS) { - /* do both rxtx by default */ - if (NULL == do_measure) - do_measure = measure_rxtx; - - rte_eal_remote_launch(main_loop, NULL, slave_id); - - if (rte_eal_wait_lcore(slave_id) < 0) - return -1; - } else if (sc_flag == SC_BURST_POLL_FIRST || - sc_flag == SC_BURST_XMIT_FIRST) - if (exec_burst(sc_flag, slave_id) < 0) - return -1; - - /* port tear down */ - for (portid = 0; portid < nb_ports; portid++) { - if (socketid != rte_eth_dev_socket_id(portid)) - continue; - - rte_eth_dev_stop(portid); - } - - return 0; -} - -int -test_set_rxtx_conf(cmdline_fixed_string_t mode) -{ - printf("mode switch to %s\n", mode); - - if (!strcmp(mode, "vector")) { - /* vector rx, tx */ - tx_conf.txq_flags = 0xf01; - tx_conf.tx_rs_thresh = 32; - tx_conf.tx_free_thresh = 32; - port_conf.rxmode.hw_ip_checksum = 0; - port_conf.rxmode.enable_scatter = 0; - return 0; - } else if (!strcmp(mode, "scalar")) { - /* bulk alloc rx, full-featured tx */ - tx_conf.txq_flags = 0; - tx_conf.tx_rs_thresh = 32; - tx_conf.tx_free_thresh = 32; - port_conf.rxmode.hw_ip_checksum = 1; - port_conf.rxmode.enable_scatter = 0; - return 0; - } else if (!strcmp(mode, "hybrid")) { - /* bulk alloc rx, vector tx - * when vec macro not define, - * using the same rx/tx as scalar - */ - tx_conf.txq_flags = 0xf01; - tx_conf.tx_rs_thresh = 32; - tx_conf.tx_free_thresh = 32; - port_conf.rxmode.hw_ip_checksum = 1; - port_conf.rxmode.enable_scatter = 0; - return 0; - } else if (!strcmp(mode, "full")) { - /* full feature rx,tx pair */ - tx_conf.txq_flags = 0x0; /* must condition */ - tx_conf.tx_rs_thresh = 32; - tx_conf.tx_free_thresh = 32; - port_conf.rxmode.hw_ip_checksum = 0; - port_conf.rxmode.enable_scatter = 1; /* must condition */ - return 0; - } - - return -1; -} - -int -test_set_rxtx_anchor(cmdline_fixed_string_t type) -{ - printf("type switch to %s\n", type); - - if (!strcmp(type, "rxtx")) { - do_measure = measure_rxtx; - return 0; - } else if (!strcmp(type, "rxonly")) { - do_measure = measure_rxonly; - return 0; - } else if (!strcmp(type, "txonly")) { - do_measure = measure_txonly; - return 0; - } - - return -1; -} - -int -test_set_rxtx_sc(cmdline_fixed_string_t type) -{ - printf("stream control switch to %s\n", type); - - if (!strcmp(type, "continuous")) { - sc_flag = SC_CONTINUOUS; - return 0; - } else if (!strcmp(type, "poll_before_xmit")) { - sc_flag = SC_BURST_POLL_FIRST; - return 0; - } else if (!strcmp(type, "poll_after_xmit")) { - sc_flag = SC_BURST_XMIT_FIRST; - return 0; - } - - return -1; -} - -REGISTER_TEST_COMMAND(pmd_perf_autotest, test_pmd_perf); diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c deleted file mode 100644 index 2cdf60d103..0000000000 --- a/app/test/test_pmd_ring.c +++ /dev/null @@ -1,529 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2015 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 "test.h" - -#include - -#include -#include - -static struct rte_mempool *mp; -static int tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte; - -#define SOCKET0 0 -#define RING_SIZE 256 -#define NUM_RINGS 2 -#define NB_MBUF 512 - - -static int -test_ethdev_configure_port(int port) -{ - struct rte_eth_conf null_conf; - struct rte_eth_link link; - - memset(&null_conf, 0, sizeof(struct rte_eth_conf)); - - if (rte_eth_dev_configure(port, 1, 2, &null_conf) < 0) { - printf("Configure failed for port %d\n", port); - return -1; - } - - /* Test queue release */ - if (rte_eth_dev_configure(port, 1, 1, &null_conf) < 0) { - printf("Configure failed for port %d\n", port); - return -1; - } - - if (rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL) < 0) { - printf("TX queue setup failed port %d\n", port); - return -1; - } - - if (rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0, - NULL, mp) < 0) { - printf("RX queue setup failed port %d\n", port); - return -1; - } - - if (rte_eth_dev_start(port) < 0) { - printf("Error starting port %d\n", port); - return -1; - } - - rte_eth_link_get(port, &link); - - return 0; -} - -static int -test_send_basic_packets(void) -{ - struct rte_mbuf bufs[RING_SIZE]; - struct rte_mbuf *pbufs[RING_SIZE]; - int i; - - printf("Testing send and receive RING_SIZE/2 packets (tx_porta -> rx_portb)\n"); - - for (i = 0; i < RING_SIZE/2; i++) - pbufs[i] = &bufs[i]; - - if (rte_eth_tx_burst(tx_porta, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) { - printf("Failed to transmit packet burst port %d\n", tx_porta); - return -1; - } - - if (rte_eth_rx_burst(rx_portb, 0, pbufs, RING_SIZE) != RING_SIZE/2) { - printf("Failed to receive packet burst on port %d\n", rx_portb); - return -1; - } - - for (i = 0; i < RING_SIZE/2; i++) - if (pbufs[i] != &bufs[i]) { - printf("Error: received data does not match that transmitted\n"); - return -1; - } - - return 0; -} - -static int -test_send_basic_packets_port(int port) -{ - struct rte_mbuf bufs[RING_SIZE]; - struct rte_mbuf *pbufs[RING_SIZE]; - int i; - - printf("Testing send and receive RING_SIZE/2 packets (cmdl_port0 -> cmdl_port0)\n"); - - for (i = 0; i < RING_SIZE/2; i++) - pbufs[i] = &bufs[i]; - - if (rte_eth_tx_burst(port, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) { - printf("Failed to transmit packet burst port %d\n", port); - return -1; - } - - if (rte_eth_rx_burst(port, 0, pbufs, RING_SIZE) != RING_SIZE/2) { - printf("Failed to receive packet burst on port %d\n", port); - return -1; - } - - for (i = 0; i < RING_SIZE/2; i++) - if (pbufs[i] != &bufs[i]) { - printf("Error: received data does not match that transmitted\n"); - return -1; - } - - return 0; -} - - -static int -test_get_stats(int port) -{ - struct rte_eth_stats stats; - struct rte_mbuf buf, *pbuf = &buf; - - printf("Testing ring PMD stats_get port %d\n", port); - - /* check stats of RXTX port, should all be zero */ - - rte_eth_stats_get(port, &stats); - if (stats.ipackets != 0 || stats.opackets != 0 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not zero\n", port); - return -1; - } - - /* send and receive 1 packet and check for stats update */ - if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", port); - return -1; - } - - if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", port); - return -1; - } - - rte_eth_stats_get(port, &stats); - if (stats.ipackets != 1 || stats.opackets != 1 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", port); - return -1; - } - return 0; -} - -static int -test_stats_reset(int port) -{ - struct rte_eth_stats stats; - struct rte_mbuf buf, *pbuf = &buf; - - printf("Testing ring PMD stats_reset port %d\n", port); - - rte_eth_stats_reset(port); - - /* check stats of RXTX port, should all be zero */ - rte_eth_stats_get(port, &stats); - if (stats.ipackets != 0 || stats.opackets != 0 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not zero\n", port); - return -1; - } - - /* send and receive 1 packet and check for stats update */ - if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", port); - return -1; - } - - if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", port); - return -1; - } - - rte_eth_stats_get(port, &stats); - if (stats.ipackets != 1 || stats.opackets != 1 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", port); - return -1; - } - - rte_eth_stats_reset(port); - - /* check stats of RXTX port, should all be zero */ - rte_eth_stats_get(port, &stats); - if (stats.ipackets != 0 || stats.opackets != 0 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not zero\n", port); - return -1; - } - - return 0; -} - -static int -test_pmd_ring_pair_create_attach(int portd, int porte) -{ - struct rte_eth_stats stats, stats2; - struct rte_mbuf buf, *pbuf = &buf; - struct rte_eth_conf null_conf; - - if ((rte_eth_dev_configure(portd, 1, 1, &null_conf) < 0) - || (rte_eth_dev_configure(porte, 1, 1, &null_conf) < 0)) { - printf("Configure failed for port\n"); - return -1; - } - - if ((rte_eth_tx_queue_setup(portd, 0, RING_SIZE, SOCKET0, NULL) < 0) - || (rte_eth_tx_queue_setup(porte, 0, RING_SIZE, SOCKET0, NULL) < 0)) { - printf("TX queue setup failed\n"); - return -1; - } - - if ((rte_eth_rx_queue_setup(portd, 0, RING_SIZE, SOCKET0, NULL, mp) < 0) - || (rte_eth_rx_queue_setup(porte, 0, RING_SIZE, SOCKET0, NULL, mp) < 0)) { - printf("RX queue setup failed\n"); - return -1; - } - - if ((rte_eth_dev_start(portd) < 0) - || (rte_eth_dev_start(porte) < 0)) { - printf("Error starting port\n"); - return -1; - } - - rte_eth_stats_reset(portd); - /* check stats of port, should all be zero */ - rte_eth_stats_get(portd, &stats); - if (stats.ipackets != 0 || stats.opackets != 0 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not zero\n", portd); - return -1; - } - - rte_eth_stats_reset(porte); - /* check stats of port, should all be zero */ - rte_eth_stats_get(porte, &stats2); - if (stats2.ipackets != 0 || stats2.opackets != 0 || - stats2.ibytes != 0 || stats2.obytes != 0 || - stats2.ierrors != 0 || stats2.oerrors != 0) { - printf("Error: port %d stats are not zero\n", porte); - return -1; - } - - /* - * send and receive 1 packet (portd -> porte) - * and check for stats update - */ - printf("Testing send and receive 1 packet (portd -> porte)\n"); - if (rte_eth_tx_burst(portd, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", portd); - return -1; - } - - if (rte_eth_rx_burst(porte, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", porte); - return -1; - } - - rte_eth_stats_get(portd, &stats); - rte_eth_stats_get(porte, &stats2); - if (stats.ipackets != 0 || stats.opackets != 1 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", portd); - return -1; - } - - if (stats2.ipackets != 1 || stats2.opackets != 0 || - stats2.ibytes != 0 || stats2.obytes != 0 || - stats2.ierrors != 0 || stats2.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", porte); - return -1; - } - - /* - * send and receive 1 packet (porte -> portd) - * and check for stats update - */ - printf("Testing send and receive 1 packet (porte -> portd)\n"); - if (rte_eth_tx_burst(porte, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", porte); - return -1; - } - - if (rte_eth_rx_burst(portd, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", portd); - return -1; - } - - rte_eth_stats_get(portd, &stats); - rte_eth_stats_get(porte, &stats2); - if (stats.ipackets != 1 || stats.opackets != 1 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", portd); - return -1; - } - - if (stats2.ipackets != 1 || stats2.opackets != 1 || - stats2.ibytes != 0 || stats2.obytes != 0 || - stats2.ierrors != 0 || stats2.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", porte); - return -1; - } - - /* - * send and receive 1 packet (portd -> portd) - * and check for stats update - */ - printf("Testing send and receive 1 packet (portd -> portd)\n"); - if (rte_eth_tx_burst(portd, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", portd); - return -1; - } - - if (rte_eth_rx_burst(portd, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", porte); - return -1; - } - - rte_eth_stats_get(portd, &stats); - rte_eth_stats_get(porte, &stats2); - if (stats.ipackets != 2 || stats.opackets != 2 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", portd); - return -1; - } - - if (stats2.ipackets != 1 || stats2.opackets != 1 || - stats2.ibytes != 0 || stats2.obytes != 0 || - stats2.ierrors != 0 || stats2.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", porte); - return -1; - } - - /* - * send and receive 1 packet (porte -> porte) - * and check for stats update - */ - printf("Testing send and receive 1 packet (porte -> porte)\n"); - if (rte_eth_tx_burst(porte, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", porte); - return -1; - } - - if (rte_eth_rx_burst(porte, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", porte); - return -1; - } - - rte_eth_stats_get(portd, &stats); - rte_eth_stats_get(porte, &stats2); - if (stats.ipackets != 2 || stats.opackets != 2 || - stats.ibytes != 0 || stats.obytes != 0 || - stats.ierrors != 0 || stats.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", portd); - return -1; - } - - if (stats2.ipackets != 2 || stats2.opackets != 2 || - stats2.ibytes != 0 || stats2.obytes != 0 || - stats2.ierrors != 0 || stats2.oerrors != 0) { - printf("Error: port %d stats are not as expected\n", porte); - return -1; - } - - rte_eth_dev_stop(portd); - rte_eth_dev_stop(porte); - - return 0; -} - -static int -test_pmd_ring(void) -{ - struct rte_ring *rxtx[NUM_RINGS]; - int port, cmdl_port0 = -1; - uint8_t nb_ports; - - nb_ports = rte_eth_dev_count(); - printf("nb_ports=%d\n", (int)nb_ports); - - /* create the rings and eth_rings in the test code. - * This does not test the rte_pmd_ring_devinit function. - * - * Test with the command line option --vdev=net_ring0 to test rte_pmd_ring_devinit. - */ - rxtx[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); - if (rxtx[0] == NULL) { - printf("rte_ring_create R0 failed"); - return -1; - } - - rxtx[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); - if (rxtx[1] == NULL) { - printf("rte_ring_create R1 failed"); - return -1; - } - - tx_porta = rte_eth_from_rings("net_ringa", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); - rx_portb = rte_eth_from_rings("net_ringb", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); - rxtx_portc = rte_eth_from_rings("net_ringc", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); - rxtx_portd = rte_eth_from_rings("net_ringd", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); - rxtx_porte = rte_eth_from_rings("net_ringe", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); - - printf("tx_porta=%d rx_portb=%d rxtx_portc=%d rxtx_portd=%d rxtx_porte=%d\n", - tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte); - - if ((tx_porta == -1) || (rx_portb == -1) || (rxtx_portc == -1) - || (rxtx_portd == -1) || (rxtx_porte == -1)) { - printf("rte_eth_from rings failed\n"); - return -1; - } - - mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32, - 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - if (mp == NULL) - return -1; - - if ((tx_porta >= RTE_MAX_ETHPORTS) || (rx_portb >= RTE_MAX_ETHPORTS) - || (rxtx_portc >= RTE_MAX_ETHPORTS) - || (rxtx_portd >= RTE_MAX_ETHPORTS) - || (rxtx_porte >= RTE_MAX_ETHPORTS)) { - printf(" port exceed max eth ports\n"); - return -1; - } - - if (test_ethdev_configure_port(tx_porta) < 0) - return -1; - - if (test_ethdev_configure_port(rx_portb) < 0) - return -1; - - if (test_ethdev_configure_port(rxtx_portc) < 0) - return -1; - - if (test_send_basic_packets() < 0) - return -1; - - if (test_get_stats(rxtx_portc) < 0) - return -1; - - if (test_stats_reset(rxtx_portc) < 0) - return -1; - - rte_eth_dev_stop(tx_porta); - rte_eth_dev_stop(rx_portb); - rte_eth_dev_stop(rxtx_portc); - - if (test_pmd_ring_pair_create_attach(rxtx_portd, rxtx_porte) < 0) - return -1; - - /* find a port created with the --vdev=net_ring0 command line option */ - for (port = 0; port < nb_ports; port++) { - struct rte_eth_dev_info dev_info; - - rte_eth_dev_info_get(port, &dev_info); - if (!strcmp(dev_info.driver_name, "Rings PMD")) { - printf("found a command line ring port=%d\n", port); - cmdl_port0 = port; - break; - } - } - if (cmdl_port0 != -1) { - if (test_ethdev_configure_port(cmdl_port0) < 0) - return -1; - if (test_send_basic_packets_port(cmdl_port0) < 0) - return -1; - if (test_stats_reset(cmdl_port0) < 0) - return -1; - if (test_get_stats(cmdl_port0) < 0) - return -1; - rte_eth_dev_stop(cmdl_port0); - } - return 0; -} - -REGISTER_TEST_COMMAND(ring_pmd_autotest, test_pmd_ring); diff --git a/app/test/test_pmd_ring_perf.c b/app/test/test_pmd_ring_perf.c deleted file mode 100644 index af011f7db5..0000000000 --- a/app/test/test_pmd_ring_perf.c +++ /dev/null @@ -1,184 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015 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 -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define RING_NAME "RING_PERF" -#define RING_SIZE 4096 -#define MAX_BURST 32 - -/* - * the sizes to enqueue and dequeue in testing - * (marked volatile so they won't be seen as compile-time constants) - */ -static const volatile unsigned bulk_sizes[] = { 1, 8, 32 }; - -/* The ring structure used for tests */ -static struct rte_ring *r; -static uint8_t ring_ethdev_port; - -/* Get cycle counts for dequeuing from an empty ring. Should be 2 or 3 cycles */ -static void -test_empty_dequeue(void) -{ - const unsigned iter_shift = 26; - const unsigned iterations = 1 << iter_shift; - unsigned i = 0; - void *burst[MAX_BURST]; - - const uint64_t sc_start = rte_rdtsc(); - for (i = 0; i < iterations; i++) - rte_ring_sc_dequeue_bulk(r, burst, bulk_sizes[0]); - const uint64_t sc_end = rte_rdtsc(); - - const uint64_t eth_start = rte_rdtsc(); - for (i = 0; i < iterations; i++) - rte_eth_rx_burst(ring_ethdev_port, 0, (void *)burst, - bulk_sizes[0]); - const uint64_t eth_end = rte_rdtsc(); - - printf("Ring empty dequeue : %.1F\n", - (double)(sc_end - sc_start) / iterations); - printf("Ethdev empty dequeue: %.1F\n", - (double)(eth_end - eth_start) / iterations); -} - -/* - * Test function that determines how long an enqueue + dequeue of a single item - * takes on a single lcore. Result is for comparison with the bulk enq+deq. - */ -static void -test_single_enqueue_dequeue(void) -{ - const unsigned iter_shift = 24; - const unsigned iterations = 1 << iter_shift; - unsigned i = 0; - void *burst = NULL; - struct rte_mbuf *mburst[1] = { NULL }; - - const uint64_t sc_start = rte_rdtsc_precise(); - rte_compiler_barrier(); - for (i = 0; i < iterations; i++) { - rte_ring_enqueue_bulk(r, &burst, 1); - rte_ring_dequeue_bulk(r, &burst, 1); - } - const uint64_t sc_end = rte_rdtsc_precise(); - rte_compiler_barrier(); - - const uint64_t eth_start = rte_rdtsc_precise(); - rte_compiler_barrier(); - for (i = 0; i < iterations; i++) { - rte_eth_tx_burst(ring_ethdev_port, 0, mburst, 1); - rte_eth_rx_burst(ring_ethdev_port, 0, mburst, 1); - } - const uint64_t eth_end = rte_rdtsc_precise(); - rte_compiler_barrier(); - - printf("Ring single enq/dequeue : %"PRIu64"\n", - (sc_end-sc_start) >> iter_shift); - printf("Ethdev single enq/dequeue: %"PRIu64"\n", - (eth_end-eth_start) >> iter_shift); -} - -/* Times enqueue and dequeue on a single lcore */ -static void -test_bulk_enqueue_dequeue(void) -{ - const unsigned iter_shift = 23; - const unsigned iterations = 1 << iter_shift; - unsigned sz, i = 0; - struct rte_mbuf *burst[MAX_BURST] = {0}; - - for (sz = 0; sz < sizeof(bulk_sizes)/sizeof(bulk_sizes[0]); sz++) { - const uint64_t sc_start = rte_rdtsc(); - for (i = 0; i < iterations; i++) { - rte_ring_sp_enqueue_bulk(r, (void *)burst, bulk_sizes[sz]); - rte_ring_sc_dequeue_bulk(r, (void *)burst, bulk_sizes[sz]); - } - const uint64_t sc_end = rte_rdtsc(); - - const uint64_t eth_start = rte_rdtsc_precise(); - rte_compiler_barrier(); - for (i = 0; i < iterations; i++) { - rte_eth_tx_burst(ring_ethdev_port, 0, burst, bulk_sizes[sz]); - rte_eth_rx_burst(ring_ethdev_port, 0, burst, bulk_sizes[sz]); - } - const uint64_t eth_end = rte_rdtsc_precise(); - rte_compiler_barrier(); - - double sc_avg = ((double)(sc_end-sc_start) / - (iterations * bulk_sizes[sz])); - double eth_avg = ((double)(eth_end-eth_start) / - (iterations * bulk_sizes[sz])); - - printf("ring bulk enq/deq (size: %u) : %.1F\n", bulk_sizes[sz], - sc_avg); - printf("ethdev bulk enq/deq (size:%u): %.1F\n", bulk_sizes[sz], - eth_avg); - - printf("\n"); - } -} - -static int -test_ring_pmd_perf(void) -{ - r = rte_ring_create(RING_NAME, RING_SIZE, rte_socket_id(), - RING_F_SP_ENQ|RING_F_SC_DEQ); - if (r == NULL && (r = rte_ring_lookup(RING_NAME)) == NULL) - return -1; - - ring_ethdev_port = rte_eth_from_ring(r); - - printf("\n### Testing const single element enq/deq ###\n"); - test_single_enqueue_dequeue(); - - printf("\n### Testing empty dequeue ###\n"); - test_empty_dequeue(); - - printf("\n### Testing using a single lcore ###\n"); - test_bulk_enqueue_dequeue(); - - return 0; -} - -REGISTER_TEST_COMMAND(ring_pmd_perf_autotest, test_ring_pmd_perf); diff --git a/app/test/test_power.c b/app/test/test_power.c deleted file mode 100644 index b2e1344c3d..0000000000 --- a/app/test/test_power.c +++ /dev/null @@ -1,107 +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 -#include -#include -#include -#include - -#include "test.h" - -#include - -static int -test_power(void) -{ - int ret = -1; - enum power_management_env env; - - /* Test setting an invalid environment */ - ret = rte_power_set_env(PM_ENV_NOT_SET); - if (ret == 0) { - printf("Unexpectedly succeeded on setting an invalid environment\n"); - return -1; - } - - /* Test that the environment has not been set */ - env = rte_power_get_env(); - if (env != PM_ENV_NOT_SET) { - printf("Unexpectedly got a valid environment configuration\n"); - return -1; - } - - /* verify that function pointers are NULL */ - if (rte_power_freqs != NULL) { - printf("rte_power_freqs should be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - if (rte_power_get_freq != NULL) { - printf("rte_power_get_freq should be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - if (rte_power_set_freq != NULL) { - printf("rte_power_set_freq should be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - if (rte_power_freq_up != NULL) { - printf("rte_power_freq_up should be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - if (rte_power_freq_down != NULL) { - printf("rte_power_freq_down should be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - if (rte_power_freq_max != NULL) { - printf("rte_power_freq_max should be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - if (rte_power_freq_min != NULL) { - printf("rte_power_freq_min should be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - rte_power_unset_env(); - return 0; -fail_all: - rte_power_unset_env(); - return -1; -} - -REGISTER_TEST_COMMAND(power_autotest, test_power); diff --git a/app/test/test_power_acpi_cpufreq.c b/app/test/test_power_acpi_cpufreq.c deleted file mode 100644 index 64f5dd5679..0000000000 --- a/app/test/test_power_acpi_cpufreq.c +++ /dev/null @@ -1,540 +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 -#include -#include -#include -#include - -#include "test.h" - -#include - -#define TEST_POWER_LCORE_ID 2U -#define TEST_POWER_LCORE_INVALID ((unsigned)RTE_MAX_LCORE) -#define TEST_POWER_FREQS_NUM_MAX ((unsigned)RTE_MAX_LCORE_FREQS) - -#define TEST_POWER_SYSFILE_CUR_FREQ \ - "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq" - -static uint32_t total_freq_num; -static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX]; - -static int -check_cur_freq(unsigned lcore_id, uint32_t idx) -{ -#define TEST_POWER_CONVERT_TO_DECIMAL 10 - FILE *f; - char fullpath[PATH_MAX]; - char buf[BUFSIZ]; - uint32_t cur_freq; - int ret = -1; - - if (snprintf(fullpath, sizeof(fullpath), - TEST_POWER_SYSFILE_CUR_FREQ, lcore_id) < 0) { - return 0; - } - f = fopen(fullpath, "r"); - if (f == NULL) { - return 0; - } - if (fgets(buf, sizeof(buf), f) == NULL) { - goto fail_get_cur_freq; - } - cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL); - ret = (freqs[idx] == cur_freq ? 0 : -1); - -fail_get_cur_freq: - fclose(f); - - return ret; -} - -/* Check rte_power_freqs() */ -static int -check_power_freqs(void) -{ - uint32_t ret; - - total_freq_num = 0; - memset(freqs, 0, sizeof(freqs)); - - /* test with an invalid lcore id */ - ret = rte_power_freqs(TEST_POWER_LCORE_INVALID, freqs, - TEST_POWER_FREQS_NUM_MAX); - if (ret > 0) { - printf("Unexpectedly get available freqs successfully on " - "lcore %u\n", TEST_POWER_LCORE_INVALID); - return -1; - } - - /* test with NULL buffer to save available freqs */ - ret = rte_power_freqs(TEST_POWER_LCORE_ID, NULL, - TEST_POWER_FREQS_NUM_MAX); - if (ret > 0) { - printf("Unexpectedly get available freqs successfully with " - "NULL buffer on lcore %u\n", TEST_POWER_LCORE_ID); - return -1; - } - - /* test of getting zero number of freqs */ - ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, 0); - if (ret > 0) { - printf("Unexpectedly get available freqs successfully with " - "zero buffer size on lcore %u\n", TEST_POWER_LCORE_ID); - return -1; - } - - /* test with all valid input parameters */ - ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, - TEST_POWER_FREQS_NUM_MAX); - if (ret == 0 || ret > TEST_POWER_FREQS_NUM_MAX) { - printf("Fail to get available freqs on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Save the total number of available freqs */ - total_freq_num = ret; - - return 0; -} - -/* Check rte_power_get_freq() */ -static int -check_power_get_freq(void) -{ - int ret; - uint32_t count; - - /* test with an invalid lcore id */ - count = rte_power_get_freq(TEST_POWER_LCORE_INVALID); - if (count < TEST_POWER_FREQS_NUM_MAX) { - printf("Unexpectedly get freq index successfully on " - "lcore %u\n", TEST_POWER_LCORE_INVALID); - return -1; - } - - count = rte_power_get_freq(TEST_POWER_LCORE_ID); - if (count >= TEST_POWER_FREQS_NUM_MAX) { - printf("Fail to get the freq index on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Check the current frequency */ - ret = check_cur_freq(TEST_POWER_LCORE_ID, count); - if (ret < 0) - return -1; - - return 0; -} - -/* Check rte_power_set_freq() */ -static int -check_power_set_freq(void) -{ - int ret; - - /* test with an invalid lcore id */ - ret = rte_power_set_freq(TEST_POWER_LCORE_INVALID, 0); - if (ret >= 0) { - printf("Unexpectedly set freq index successfully on " - "lcore %u\n", TEST_POWER_LCORE_INVALID); - return -1; - } - - /* test with an invalid freq index */ - ret = rte_power_set_freq(TEST_POWER_LCORE_ID, - TEST_POWER_FREQS_NUM_MAX); - if (ret >= 0) { - printf("Unexpectedly set an invalid freq index (%u)" - "successfully on lcore %u\n", TEST_POWER_FREQS_NUM_MAX, - TEST_POWER_LCORE_ID); - return -1; - } - - /** - * test with an invalid freq index which is right one bigger than - * total number of freqs - */ - ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num); - if (ret >= 0) { - printf("Unexpectedly set an invalid freq index (%u)" - "successfully on lcore %u\n", total_freq_num, - TEST_POWER_LCORE_ID); - return -1; - } - ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); - if (ret < 0) { - printf("Fail to set freq index on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Check the current frequency */ - ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); - if (ret < 0) - return -1; - - return 0; -} - -/* Check rte_power_freq_down() */ -static int -check_power_freq_down(void) -{ - int ret; - - /* test with an invalid lcore id */ - ret = rte_power_freq_down(TEST_POWER_LCORE_INVALID); - if (ret >= 0) { - printf("Unexpectedly scale down successfully the freq on " - "lcore %u\n", TEST_POWER_LCORE_INVALID); - return -1; - } - - /* Scale down to min and then scale down one step */ - ret = rte_power_freq_min(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale down the freq to min on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - ret = rte_power_freq_down(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale down the freq on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Check the current frequency */ - ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); - if (ret < 0) - return -1; - - /* Scale up to max and then scale down one step */ - ret = rte_power_freq_max(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale up the freq to max on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - ret = rte_power_freq_down(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale down the freq on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Check the current frequency */ - ret = check_cur_freq(TEST_POWER_LCORE_ID, 1); - if (ret < 0) - return -1; - - return 0; -} - -/* Check rte_power_freq_up() */ -static int -check_power_freq_up(void) -{ - int ret; - - /* test with an invalid lcore id */ - ret = rte_power_freq_up(TEST_POWER_LCORE_INVALID); - if (ret >= 0) { - printf("Unexpectedly scale up successfully the freq on %u\n", - TEST_POWER_LCORE_INVALID); - return -1; - } - - /* Scale down to min and then scale up one step */ - ret = rte_power_freq_min(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale down the freq to min on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - ret = rte_power_freq_up(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale up the freq on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Check the current frequency */ - ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2); - if (ret < 0) - return -1; - - /* Scale up to max and then scale up one step */ - ret = rte_power_freq_max(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale up the freq to max on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - ret = rte_power_freq_up(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale up the freq on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Check the current frequency */ - ret = check_cur_freq(TEST_POWER_LCORE_ID, 0); - if (ret < 0) - return -1; - - return 0; -} - -/* Check rte_power_freq_max() */ -static int -check_power_freq_max(void) -{ - int ret; - - /* test with an invalid lcore id */ - ret = rte_power_freq_max(TEST_POWER_LCORE_INVALID); - if (ret >= 0) { - printf("Unexpectedly scale up successfully the freq to max on " - "lcore %u\n", TEST_POWER_LCORE_INVALID); - return -1; - } - ret = rte_power_freq_max(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale up the freq to max on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Check the current frequency */ - ret = check_cur_freq(TEST_POWER_LCORE_ID, 0); - if (ret < 0) - return -1; - - return 0; -} - -/* Check rte_power_freq_min() */ -static int -check_power_freq_min(void) -{ - int ret; - - /* test with an invalid lcore id */ - ret = rte_power_freq_min(TEST_POWER_LCORE_INVALID); - if (ret >= 0) { - printf("Unexpectedly scale down successfully the freq to min " - "on lcore %u\n", TEST_POWER_LCORE_INVALID); - return -1; - } - ret = rte_power_freq_min(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Fail to scale down the freq to min on lcore %u\n", - TEST_POWER_LCORE_ID); - return -1; - } - - /* Check the current frequency */ - ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); - if (ret < 0) - return -1; - - return 0; -} - -static int -test_power_acpi_cpufreq(void) -{ - int ret = -1; - enum power_management_env env; - - ret = rte_power_set_env(PM_ENV_ACPI_CPUFREQ); - if (ret != 0) { - printf("Failed on setting environment to PM_ENV_ACPI_CPUFREQ, this " - "may occur if environment is not configured correctly or " - " operating in another valid Power management environment\n"); - return -1; - } - - /* Test environment configuration */ - env = rte_power_get_env(); - if (env != PM_ENV_ACPI_CPUFREQ) { - printf("Unexpectedly got an environment other than ACPI cpufreq\n"); - goto fail_all; - } - - /* verify that function pointers are not NULL */ - if (rte_power_freqs == NULL) { - printf("rte_power_freqs should not be NULL, environment has not been " - "initialised\n"); - goto fail_all; - } - if (rte_power_get_freq == NULL) { - printf("rte_power_get_freq should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_set_freq == NULL) { - printf("rte_power_set_freq should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_up == NULL) { - printf("rte_power_freq_up should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_down == NULL) { - printf("rte_power_freq_down should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_max == NULL) { - printf("rte_power_freq_max should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - if (rte_power_freq_min == NULL) { - printf("rte_power_freq_min should not be NULL, environment has not " - "been initialised\n"); - goto fail_all; - } - - /* test of init power management for an invalid lcore */ - ret = rte_power_init(TEST_POWER_LCORE_INVALID); - if (ret == 0) { - printf("Unexpectedly initialise power management successfully " - "for lcore %u\n", TEST_POWER_LCORE_INVALID); - rte_power_unset_env(); - return -1; - } - - /* Test initialisation of a valid lcore */ - ret = rte_power_init(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Cannot initialise power management for lcore %u, this " - "may occur if environment is not configured " - "correctly(APCI cpufreq) or operating in another valid " - "Power management environment\n", TEST_POWER_LCORE_ID); - rte_power_unset_env(); - return -1; - } - - /** - * test of initialising power management for the lcore which has - * been initialised - */ - ret = rte_power_init(TEST_POWER_LCORE_ID); - if (ret == 0) { - printf("Unexpectedly init successfully power twice on " - "lcore %u\n", TEST_POWER_LCORE_ID); - goto fail_all; - } - - ret = check_power_freqs(); - if (ret < 0) - goto fail_all; - - if (total_freq_num < 2) { - rte_power_exit(TEST_POWER_LCORE_ID); - printf("Frequency can not be changed due to CPU itself\n"); - rte_power_unset_env(); - return 0; - } - - ret = check_power_get_freq(); - if (ret < 0) - goto fail_all; - - ret = check_power_set_freq(); - if (ret < 0) - goto fail_all; - - ret = check_power_freq_down(); - if (ret < 0) - goto fail_all; - - ret = check_power_freq_up(); - if (ret < 0) - goto fail_all; - - ret = check_power_freq_max(); - if (ret < 0) - goto fail_all; - - ret = check_power_freq_min(); - if (ret < 0) - goto fail_all; - - ret = rte_power_exit(TEST_POWER_LCORE_ID); - if (ret < 0) { - printf("Cannot exit power management for lcore %u\n", - TEST_POWER_LCORE_ID); - rte_power_unset_env(); - return -1; - } - - /** - * test of exiting power management for the lcore which has been exited - */ - ret = rte_power_exit(TEST_POWER_LCORE_ID); - if (ret == 0) { - printf("Unexpectedly exit successfully power management twice " - "on lcore %u\n", TEST_POWER_LCORE_ID); - rte_power_unset_env(); - return -1; - } - - /* test of exit power management for an invalid lcore */ - ret = rte_power_exit(TEST_POWER_LCORE_INVALID); - if (ret == 0) { - printf("Unpectedly exit power management successfully for " - "lcore %u\n", TEST_POWER_LCORE_INVALID); - rte_power_unset_env(); - return -1; - } - rte_power_unset_env(); - return 0; - -fail_all: - rte_power_exit(TEST_POWER_LCORE_ID); - rte_power_unset_env(); - return -1; -} - -REGISTER_TEST_COMMAND(power_acpi_cpufreq_autotest, test_power_acpi_cpufreq); diff --git a/app/test/test_power_kvm_vm.c b/app/test/test_power_kvm_vm.c deleted file mode 100644 index 253a5f8b6f..0000000000 --- a/app/test/test_power_kvm_vm.c +++ /dev/null @@ -1,303 +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 -#include -#include -#include -#include - -#include "test.h" - -#include - -#define TEST_POWER_VM_LCORE_ID 0U -#define TEST_POWER_VM_LCORE_OUT_OF_BOUNDS (RTE_MAX_LCORE+1) -#define TEST_POWER_VM_LCORE_INVALID 1U - -static int -test_power_kvm_vm(void) -{ - int ret; - enum power_management_env env; - - ret = rte_power_set_env(PM_ENV_KVM_VM); - if (ret != 0) { - printf("Failed on setting environment to PM_ENV_KVM_VM\n"); - return -1; - } - - /* Test environment configuration */ - env = rte_power_get_env(); - if (env != PM_ENV_KVM_VM) { - printf("Unexpectedly got a Power Management environment other than " - "KVM VM\n"); - rte_power_unset_env(); - return -1; - } - - /* verify that function pointers are not NULL */ - if (rte_power_freqs == NULL) { - printf("rte_power_freqs should not be NULL, environment has not been " - "initialised\n"); - return -1; - } - if (rte_power_get_freq == NULL) { - printf("rte_power_get_freq should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_set_freq == NULL) { - printf("rte_power_set_freq should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_freq_up == NULL) { - printf("rte_power_freq_up should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_freq_down == NULL) { - printf("rte_power_freq_down should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_freq_max == NULL) { - printf("rte_power_freq_max should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - if (rte_power_freq_min == NULL) { - printf("rte_power_freq_min should not be NULL, environment has not " - "been initialised\n"); - return -1; - } - /* Test initialisation of an out of bounds lcore */ - ret = rte_power_init(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - if (ret != -1) { - printf("rte_power_init unexpectedly succeeded on an invalid lcore %u\n", - TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - rte_power_unset_env(); - return -1; - } - - /* Test initialisation of a valid lcore */ - ret = rte_power_init(TEST_POWER_VM_LCORE_ID); - if (ret < 0) { - printf("Cannot initialise power management for lcore %u, this " - "may occur if environment is not configured " - "correctly(KVM VM) or operating in another valid " - "Power management environment\n", TEST_POWER_VM_LCORE_ID); - rte_power_unset_env(); - return -1; - } - - /* Test initialisation of previously initialised lcore */ - ret = rte_power_init(TEST_POWER_VM_LCORE_ID); - if (ret == 0) { - printf("rte_power_init unexpectedly succeeded on calling init twice on" - " lcore %u\n", TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test frequency up of invalid lcore */ - ret = rte_power_freq_up(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - if (ret == 1) { - printf("rte_power_freq_up unexpectedly succeeded on invalid lcore %u\n", - TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - goto fail_all; - } - - /* Test frequency down of invalid lcore */ - ret = rte_power_freq_down(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - if (ret == 1) { - printf("rte_power_freq_down unexpectedly succeeded on invalid lcore " - "%u\n", TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - goto fail_all; - } - - /* Test frequency min of invalid lcore */ - ret = rte_power_freq_min(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - if (ret == 1) { - printf("rte_power_freq_min unexpectedly succeeded on invalid lcore " - "%u\n", TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - goto fail_all; - } - - /* Test frequency max of invalid lcore */ - ret = rte_power_freq_max(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - if (ret == 1) { - printf("rte_power_freq_max unexpectedly succeeded on invalid lcore " - "%u\n", TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); - goto fail_all; - } - - /* Test frequency up of valid but uninitialised lcore */ - ret = rte_power_freq_up(TEST_POWER_VM_LCORE_INVALID); - if (ret == 1) { - printf("rte_power_freq_up unexpectedly succeeded on invalid lcore %u\n", - TEST_POWER_VM_LCORE_INVALID); - goto fail_all; - } - - /* Test frequency down of valid but uninitialised lcore */ - ret = rte_power_freq_down(TEST_POWER_VM_LCORE_INVALID); - if (ret == 1) { - printf("rte_power_freq_down unexpectedly succeeded on invalid lcore " - "%u\n", TEST_POWER_VM_LCORE_INVALID); - goto fail_all; - } - - /* Test frequency min of valid but uninitialised lcore */ - ret = rte_power_freq_min(TEST_POWER_VM_LCORE_INVALID); - if (ret == 1) { - printf("rte_power_freq_min unexpectedly succeeded on invalid lcore " - "%u\n", TEST_POWER_VM_LCORE_INVALID); - goto fail_all; - } - - /* Test frequency max of valid but uninitialised lcore */ - ret = rte_power_freq_max(TEST_POWER_VM_LCORE_INVALID); - if (ret == 1) { - printf("rte_power_freq_max unexpectedly succeeded on invalid lcore " - "%u\n", TEST_POWER_VM_LCORE_INVALID); - goto fail_all; - } - - /* Test frequency up of valid lcore */ - ret = rte_power_freq_up(TEST_POWER_VM_LCORE_ID); - if (ret != 1) { - printf("rte_power_freq_up unexpectedly failed on valid lcore %u\n", - TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test frequency down of valid lcore */ - ret = rte_power_freq_down(TEST_POWER_VM_LCORE_ID); - if (ret != 1) { - printf("rte_power_freq_down unexpectedly failed on valid lcore " - "%u\n", TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test frequency min of valid lcore */ - ret = rte_power_freq_min(TEST_POWER_VM_LCORE_ID); - if (ret != 1) { - printf("rte_power_freq_min unexpectedly failed on valid lcore " - "%u\n", TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test frequency max of valid lcore */ - ret = rte_power_freq_max(TEST_POWER_VM_LCORE_ID); - if (ret != 1) { - printf("rte_power_freq_max unexpectedly failed on valid lcore " - "%u\n", TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test unsupported rte_power_freqs */ - ret = rte_power_freqs(TEST_POWER_VM_LCORE_ID, NULL, 0); - if (ret != -ENOTSUP) { - printf("rte_power_freqs did not return the expected -ENOTSUP(%d) but " - "returned %d\n", -ENOTSUP, ret); - goto fail_all; - } - - /* Test unsupported rte_power_get_freq */ - ret = rte_power_get_freq(TEST_POWER_VM_LCORE_ID); - if (ret != -ENOTSUP) { - printf("rte_power_get_freq did not return the expected -ENOTSUP(%d) but" - " returned %d for lcore %u\n", - -ENOTSUP, ret, TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test unsupported rte_power_set_freq */ - ret = rte_power_set_freq(TEST_POWER_VM_LCORE_ID, 0); - if (ret != -ENOTSUP) { - printf("rte_power_set_freq did not return the expected -ENOTSUP(%d) but" - " returned %d for lcore %u\n", - -ENOTSUP, ret, TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test removing of an lcore */ - ret = rte_power_exit(TEST_POWER_VM_LCORE_ID); - if (ret != 0) { - printf("rte_power_exit unexpectedly failed on valid lcore %u," - "please ensure that the environment has been configured " - "correctly\n", TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test frequency up of previously removed lcore */ - ret = rte_power_freq_up(TEST_POWER_VM_LCORE_ID); - if (ret == 0) { - printf("rte_power_freq_up unexpectedly succeeded on a removed " - "lcore %u\n", TEST_POWER_VM_LCORE_ID); - return -1; - } - - /* Test frequency down of previously removed lcore */ - ret = rte_power_freq_down(TEST_POWER_VM_LCORE_ID); - if (ret == 0) { - printf("rte_power_freq_down unexpectedly succeeded on a removed " - "lcore %u\n", TEST_POWER_VM_LCORE_ID); - return -1; - } - - /* Test frequency min of previously removed lcore */ - ret = rte_power_freq_min(TEST_POWER_VM_LCORE_ID); - if (ret == 0) { - printf("rte_power_freq_min unexpectedly succeeded on a removed " - "lcore %u\n", TEST_POWER_VM_LCORE_ID); - return -1; - } - - /* Test frequency max of previously removed lcore */ - ret = rte_power_freq_max(TEST_POWER_VM_LCORE_ID); - if (ret == 0) { - printf("rte_power_freq_max unexpectedly succeeded on a removed " - "lcore %u\n", TEST_POWER_VM_LCORE_ID); - return -1; - } - rte_power_unset_env(); - return 0; -fail_all: - rte_power_exit(TEST_POWER_VM_LCORE_ID); - rte_power_unset_env(); - return -1; -} - -REGISTER_TEST_COMMAND(power_kvm_vm_autotest, test_power_kvm_vm); diff --git a/app/test/test_prefetch.c b/app/test/test_prefetch.c deleted file mode 100644 index 80afaaf345..0000000000 --- a/app/test/test_prefetch.c +++ /dev/null @@ -1,61 +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 -#include - -#include - -#include "test.h" - -/* - * Prefetch test - * ============= - * - * - Just test that the macro can be called and validate the compilation. - * The test always return success. - */ - -static int -test_prefetch(void) -{ - int a; - - rte_prefetch0(&a); - rte_prefetch1(&a); - rte_prefetch2(&a); - - return 0; -} - -REGISTER_TEST_COMMAND(prefetch_autotest, test_prefetch); diff --git a/app/test/test_red.c b/app/test/test_red.c deleted file mode 100644 index 348075dc39..0000000000 --- a/app/test/test_red.c +++ /dev/null @@ -1,1885 +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#include - -#ifdef __INTEL_COMPILER -#pragma warning(disable:2259) /* conversion may lose significant bits */ -#pragma warning(disable:181) /* Arg incompatible with format string */ -#endif - -#define TEST_HZ_PER_KHZ 1000 -#define TEST_NSEC_MARGIN 500 /**< nanosecond margin when calculating clk freq */ - -#define MAX_QEMPTY_TIME_MSEC 50000 -#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 */ - struct rte_red_config *rconfig; /**< RTE_RED configuration parameters */ - uint8_t num_cfg; /**< Number of RTE_RED configs to test */ - uint8_t *wq_log2; /**< Test wq_log2 value to use */ - uint32_t min_th; /**< Queue minimum threshold */ - uint32_t max_th; /**< Queue maximum threshold */ - uint8_t *maxp_inv; /**< Inverse mark probability */ -}; - -struct test_queue { /**< Test structure for RTE_RED Queues */ - struct rte_red *rdata; /**< RTE_RED runtime data */ - uint32_t num_queues; /**< Number of RTE_RED queues to test */ - uint32_t *qconfig; /**< Configuration of RTE_RED queues for test */ - uint32_t *q; /**< Queue size */ - uint32_t q_ramp_up; /**< Num of enqueues to ramp up the queue */ - uint32_t avg_ramp_up; /**< Average num of enqueues to ramp up the queue */ - uint32_t avg_tolerance; /**< Tolerance in queue average */ - double drop_tolerance; /**< Drop tolerance of packets not enqueued */ -}; - -struct test_var { /**< Test variables used for testing RTE_RED */ - uint32_t wait_usec; /**< Micro second wait interval */ - uint32_t num_iterations; /**< Number of test iterations */ - uint32_t num_ops; /**< Number of test operations */ - uint64_t clk_freq; /**< CPU clock frequency */ - uint32_t sleep_sec; /**< Seconds to sleep */ - uint32_t *dropped; /**< Test operations dropped */ - uint32_t *enqueued; /**< Test operations enqueued */ -}; - -struct test_config { /**< Master test structure for RTE_RED */ - const char *ifname; /**< Interface name */ - const char *msg; /**< Test message for display */ - const char *htxt; /**< Header txt display for result output */ - struct test_rte_red_config *tconfig; /**< Test structure for RTE_RED config */ - struct test_queue *tqueue; /**< Test structure for RTE_RED Queues */ - struct test_var *tvar; /**< Test variables used for testing RTE_RED */ - uint32_t *tlevel; /**< Queue levels */ -}; - -enum test_result { - FAIL = 0, - PASS -}; - -/**< Test structure to define tests to run */ -struct tests { - struct test_config *testcfg; - enum test_result (*testfn)(struct test_config *); -}; - -struct rdtsc_prof { - uint64_t clk_start; - uint64_t clk_min; /**< min clocks */ - uint64_t clk_max; /**< max clocks */ - uint64_t clk_avgc; /**< count to calc average */ - double clk_avg; /**< cumulative sum to calc average */ - const char *name; -}; - -static const uint64_t port_speed_bytes = (10ULL*1000ULL*1000ULL*1000ULL)/8ULL; -static double inv_cycles_per_byte = 0; -static double pkt_time_usec = 0; - -static void init_port_ts(uint64_t cpu_clock) -{ - double cycles_per_byte = (double)(cpu_clock) / (double)(port_speed_bytes); - inv_cycles_per_byte = 1.0 / cycles_per_byte; - pkt_time_usec = 1000000.0 / ((double)port_speed_bytes / (double)RTE_RED_S); -} - -static uint64_t get_port_ts(void) -{ - return (uint64_t)((double)rte_rdtsc() * inv_cycles_per_byte); -} - -static void rdtsc_prof_init(struct rdtsc_prof *p, const char *name) -{ - p->clk_min = (uint64_t)(-1LL); - p->clk_max = 0; - p->clk_avg = 0; - p->clk_avgc = 0; - p->name = name; -} - -static inline void rdtsc_prof_start(struct rdtsc_prof *p) -{ - p->clk_start = rte_rdtsc_precise(); -} - -static inline void rdtsc_prof_end(struct rdtsc_prof *p) -{ - uint64_t clk_start = rte_rdtsc() - p->clk_start; - - p->clk_avgc++; - p->clk_avg += (double) clk_start; - - if (clk_start > p->clk_max) - p->clk_max = clk_start; - if (clk_start < p->clk_min) - p->clk_min = clk_start; -} - -static void rdtsc_prof_print(struct rdtsc_prof *p) -{ - if (p->clk_avgc>0) { - printf("RDTSC stats for %s: n=%" PRIu64 ", min=%" PRIu64 ", max=%" PRIu64 ", avg=%.1f\n", - p->name, - p->clk_avgc, - p->clk_min, - p->clk_max, - (p->clk_avg / ((double) p->clk_avgc))); - } -} - -static uint32_t rte_red_get_avg_int(const struct rte_red_config *red_cfg, - struct rte_red *red) -{ - /** - * scale by 1/n and convert from fixed-point to integer - */ - return red->avg >> (RTE_RED_SCALING + red_cfg->wq_log2); -} - -static double rte_red_get_avg_float(const struct rte_red_config *red_cfg, - struct rte_red *red) -{ - /** - * scale by 1/n and convert from fixed-point to floating-point - */ - return ldexp((double)red->avg, -(RTE_RED_SCALING + red_cfg->wq_log2)); -} - -static void rte_red_set_avg_int(const struct rte_red_config *red_cfg, - struct rte_red *red, - uint32_t avg) -{ - /** - * scale by n and convert from integer to fixed-point - */ - red->avg = avg << (RTE_RED_SCALING + red_cfg->wq_log2); -} - -static double calc_exp_avg_on_empty(double avg, uint32_t n, uint32_t time_diff) -{ - return avg * pow((1.0 - 1.0 / (double)n), (double)time_diff / pkt_time_usec); -} - -static double calc_drop_rate(uint32_t enqueued, uint32_t dropped) -{ - return (double)dropped / ((double)enqueued + (double)dropped); -} - -/** - * calculate the drop probability - */ -static double calc_drop_prob(uint32_t min_th, uint32_t max_th, - uint32_t maxp_inv, uint32_t avg) -{ - double drop_prob = 0.0; - - if (avg < min_th) { - drop_prob = 0.0; - } else if (avg < max_th) { - drop_prob = (1.0 / (double)maxp_inv) - * ((double)(avg - min_th) - / (double)(max_th - min_th)); - } else { - drop_prob = 1.0; - } - return drop_prob; -} - -/** - * check if drop rate matches drop probability within tolerance - */ -static int check_drop_rate(double *diff, double drop_rate, double drop_prob, double tolerance) -{ - double abs_diff = 0.0; - int ret = 1; - - abs_diff = fabs(drop_rate - drop_prob); - if ((int)abs_diff == 0) { - *diff = 0.0; - } else { - *diff = (abs_diff / drop_prob) * 100.0; - if (*diff > tolerance) { - ret = 0; - } - } - return ret; -} - -/** - * check if average queue size is within tolerance - */ -static int check_avg(double *diff, double avg, double exp_avg, double tolerance) -{ - double abs_diff = 0.0; - int ret = 1; - - abs_diff = fabs(avg - exp_avg); - if ((int)abs_diff == 0) { - *diff = 0.0; - } else { - *diff = (abs_diff / exp_avg) * 100.0; - if (*diff > tolerance) { - ret = 0; - } - } - return ret; -} - -/** - * initialize the test rte_red config - */ -static enum test_result -test_rte_red_init(struct test_config *tcfg) -{ - unsigned i = 0; - - tcfg->tvar->clk_freq = rte_get_timer_hz(); - init_port_ts( tcfg->tvar->clk_freq ); - - for (i = 0; i < tcfg->tconfig->num_cfg; i++) { - if (rte_red_config_init(&tcfg->tconfig->rconfig[i], - (uint16_t)tcfg->tconfig->wq_log2[i], - (uint16_t)tcfg->tconfig->min_th, - (uint16_t)tcfg->tconfig->max_th, - (uint16_t)tcfg->tconfig->maxp_inv[i]) != 0) { - return FAIL; - } - } - - *tcfg->tqueue->q = 0; - *tcfg->tvar->dropped = 0; - *tcfg->tvar->enqueued = 0; - return PASS; -} - -/** - * enqueue until actual queue size reaches target level - */ -static int -increase_actual_qsize(struct rte_red_config *red_cfg, - struct rte_red *red, - uint32_t *q, - uint32_t level, - uint32_t attempts) -{ - uint32_t i = 0; - - for (i = 0; i < attempts; i++) { - int ret = 0; - - /** - * enqueue - */ - ret = rte_red_enqueue(red_cfg, red, *q, get_port_ts() ); - if (ret == 0) { - if (++(*q) >= level) - break; - } - } - /** - * check if target actual queue size has been reached - */ - if (*q != level) - return -1; - /** - * success - */ - return 0; -} - -/** - * enqueue until average queue size reaches target level - */ -static int -increase_average_qsize(struct rte_red_config *red_cfg, - struct rte_red *red, - uint32_t *q, - uint32_t level, - uint32_t num_ops) -{ - uint32_t avg = 0; - uint32_t i = 0; - - for (i = 0; i < num_ops; i++) { - /** - * enqueue - */ - rte_red_enqueue(red_cfg, red, *q, get_port_ts()); - } - /** - * check if target average queue size has been reached - */ - avg = rte_red_get_avg_int(red_cfg, red); - if (avg != level) - return -1; - /** - * success - */ - return 0; -} - -/** - * setup default values for the functional test structures - */ -static struct rte_red_config ft_wrconfig[1]; -static struct rte_red ft_rtdata[1]; -static uint8_t ft_wq_log2[] = {9}; -static uint8_t ft_maxp_inv[] = {10}; -static uint32_t ft_qconfig[] = {0, 0, 1, 1}; -static uint32_t ft_q[] ={0}; -static uint32_t ft_dropped[] ={0}; -static uint32_t ft_enqueued[] ={0}; - -static struct test_rte_red_config ft_tconfig = { - .rconfig = ft_wrconfig, - .num_cfg = RTE_DIM(ft_wrconfig), - .wq_log2 = ft_wq_log2, - .min_th = 32, - .max_th = 128, - .maxp_inv = ft_maxp_inv, -}; - -static struct test_queue ft_tqueue = { - .rdata = ft_rtdata, - .num_queues = RTE_DIM(ft_rtdata), - .qconfig = ft_qconfig, - .q = ft_q, - .q_ramp_up = 1000000, - .avg_ramp_up = 1000000, - .avg_tolerance = 5, /* 5 percent */ - .drop_tolerance = 50, /* 50 percent */ -}; - -static struct test_var ft_tvar = { - .wait_usec = 10000, - .num_iterations = 5, - .num_ops = 10000, - .clk_freq = 0, - .dropped = ft_dropped, - .enqueued = ft_enqueued, - .sleep_sec = (MAX_QEMPTY_TIME_MSEC / MSEC_PER_SEC) + 2, -}; - -/** - * functional test enqueue/dequeue packets - */ -static void enqueue_dequeue_func(struct rte_red_config *red_cfg, - struct rte_red *red, - uint32_t *q, - uint32_t num_ops, - uint32_t *enqueued, - uint32_t *dropped) -{ - uint32_t i = 0; - - for (i = 0; i < num_ops; i++) { - int ret = 0; - - /** - * enqueue - */ - ret = rte_red_enqueue(red_cfg, red, *q, get_port_ts()); - if (ret == 0) - (*enqueued)++; - else - (*dropped)++; - } -} - -/** - * Test F1: functional test 1 - */ -static uint32_t ft1_tlevels[] = {6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 126, 132, 138, 144}; - -static struct test_config func_test1_config = { - .ifname = "functional test 1 interface", - .msg = "functional test 1 : use one rte_red configuration,\n" - " increase average queue size to various levels,\n" - " compare drop rate to drop probability\n\n", - .htxt = " " - "avg queue size " - "enqueued " - "dropped " - "drop prob % " - "drop rate % " - "diff % " - "tolerance % " - "\n", - .tconfig = &ft_tconfig, - .tqueue = &ft_tqueue, - .tvar = &ft_tvar, - .tlevel = ft1_tlevels, -}; - -static enum test_result func_test1(struct test_config *tcfg) -{ - enum test_result result = PASS; - uint32_t i = 0; - - printf("%s", tcfg->msg); - - if (test_rte_red_init(tcfg) != PASS) { - result = FAIL; - goto out; - } - - printf("%s", tcfg->htxt); - - for (i = 0; i < RTE_DIM(ft1_tlevels); i++) { - const char *label = NULL; - uint32_t avg = 0; - double drop_rate = 0.0; - double drop_prob = 0.0; - double diff = 0.0; - - /** - * reset rte_red run-time data - */ - rte_red_rt_data_init(tcfg->tqueue->rdata); - *tcfg->tvar->enqueued = 0; - *tcfg->tvar->dropped = 0; - - if (increase_actual_qsize(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - tcfg->tlevel[i], - tcfg->tqueue->q_ramp_up) != 0) { - result = FAIL; - goto out; - } - - if (increase_average_qsize(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - tcfg->tlevel[i], - tcfg->tqueue->avg_ramp_up) != 0) { - result = FAIL; - goto out; - } - - enqueue_dequeue_func(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - tcfg->tvar->num_ops, - tcfg->tvar->enqueued, - tcfg->tvar->dropped); - - avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); - if (avg != tcfg->tlevel[i]) { - fprintf(stderr, "Fail: avg != level\n"); - result = FAIL; - } - - drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped); - drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th, - *tcfg->tconfig->maxp_inv, tcfg->tlevel[i]); - if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance)) - result = FAIL; - - if (tcfg->tlevel[i] == tcfg->tconfig->min_th) - label = "min thresh: "; - else if (tcfg->tlevel[i] == tcfg->tconfig->max_th) - label = "max thresh: "; - else - label = " "; - printf("%s%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n", - label, avg, *tcfg->tvar->enqueued, *tcfg->tvar->dropped, - drop_prob * 100.0, drop_rate * 100.0, diff, - (double)tcfg->tqueue->drop_tolerance); - } -out: - return result; -} - -/** - * Test F2: functional test 2 - */ -static uint32_t ft2_tlevel[] = {127}; -static uint8_t ft2_wq_log2[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9}; -static uint8_t ft2_maxp_inv[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; -static struct rte_red_config ft2_rconfig[10]; - -static struct test_rte_red_config ft2_tconfig = { - .rconfig = ft2_rconfig, - .num_cfg = RTE_DIM(ft2_rconfig), - .wq_log2 = ft2_wq_log2, - .min_th = 32, - .max_th = 128, - .maxp_inv = ft2_maxp_inv, -}; - -static struct test_config func_test2_config = { - .ifname = "functional test 2 interface", - .msg = "functional test 2 : use several RED configurations,\n" - " increase average queue size to just below maximum threshold,\n" - " compare drop rate to drop probability\n\n", - .htxt = "RED config " - "avg queue size " - "min threshold " - "max threshold " - "drop prob % " - "drop rate % " - "diff % " - "tolerance % " - "\n", - .tconfig = &ft2_tconfig, - .tqueue = &ft_tqueue, - .tvar = &ft_tvar, - .tlevel = ft2_tlevel, -}; - -static enum test_result func_test2(struct test_config *tcfg) -{ - enum test_result result = PASS; - double prev_drop_rate = 1.0; - uint32_t i = 0; - - printf("%s", tcfg->msg); - - if (test_rte_red_init(tcfg) != PASS) { - result = FAIL; - goto out; - } - rte_red_rt_data_init(tcfg->tqueue->rdata); - - if (increase_actual_qsize(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - *tcfg->tlevel, - tcfg->tqueue->q_ramp_up) != 0) { - result = FAIL; - goto out; - } - - if (increase_average_qsize(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - *tcfg->tlevel, - tcfg->tqueue->avg_ramp_up) != 0) { - result = FAIL; - goto out; - } - printf("%s", tcfg->htxt); - - for (i = 0; i < tcfg->tconfig->num_cfg; i++) { - uint32_t avg = 0; - double drop_rate = 0.0; - double drop_prob = 0.0; - double diff = 0.0; - - *tcfg->tvar->dropped = 0; - *tcfg->tvar->enqueued = 0; - - enqueue_dequeue_func(&tcfg->tconfig->rconfig[i], - tcfg->tqueue->rdata, - tcfg->tqueue->q, - tcfg->tvar->num_ops, - tcfg->tvar->enqueued, - tcfg->tvar->dropped); - - avg = rte_red_get_avg_int(&tcfg->tconfig->rconfig[i], tcfg->tqueue->rdata); - if (avg != *tcfg->tlevel) - result = FAIL; - - drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped); - drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th, - tcfg->tconfig->maxp_inv[i], *tcfg->tlevel); - if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance)) - result = FAIL; - /** - * drop rate should decrease as maxp_inv increases - */ - if (drop_rate > prev_drop_rate) - result = FAIL; - prev_drop_rate = drop_rate; - - printf("%-15u%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n", - i, avg, tcfg->tconfig->min_th, tcfg->tconfig->max_th, - drop_prob * 100.0, drop_rate * 100.0, diff, - (double)tcfg->tqueue->drop_tolerance); - } -out: - return result; -} - -/** - * Test F3: functional test 3 - */ -static uint32_t ft3_tlevel[] = {1022}; - -static struct test_rte_red_config ft3_tconfig = { - .rconfig = ft_wrconfig, - .num_cfg = RTE_DIM(ft_wrconfig), - .wq_log2 = ft_wq_log2, - .min_th = 32, - .max_th = 1023, - .maxp_inv = ft_maxp_inv, -}; - -static struct test_config func_test3_config = { - .ifname = "functional test 3 interface", - .msg = "functional test 3 : use one RED configuration,\n" - " increase average queue size to target level,\n" - " dequeue all packets until queue is empty,\n" - " confirm that average queue size is computed correctly while queue is empty\n\n", - .htxt = "q avg before " - "q avg after " - "expected " - "difference % " - "tolerance % " - "result " - "\n", - .tconfig = &ft3_tconfig, - .tqueue = &ft_tqueue, - .tvar = &ft_tvar, - .tlevel = ft3_tlevel, -}; - -static enum test_result func_test3(struct test_config *tcfg) -{ - enum test_result result = PASS; - uint32_t i = 0; - - printf("%s", tcfg->msg); - - if (test_rte_red_init(tcfg) != PASS) { - result = FAIL; - goto out; - } - - rte_red_rt_data_init(tcfg->tqueue->rdata); - - if (increase_actual_qsize(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - *tcfg->tlevel, - tcfg->tqueue->q_ramp_up) != 0) { - result = FAIL; - goto out; - } - - if (increase_average_qsize(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - *tcfg->tlevel, - tcfg->tqueue->avg_ramp_up) != 0) { - result = FAIL; - goto out; - } - - printf("%s", tcfg->htxt); - - for (i = 0; i < tcfg->tvar->num_iterations; i++) { - double avg_before = 0; - double avg_after = 0; - double exp_avg = 0; - double diff = 0.0; - - avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); - - /** - * empty the queue - */ - *tcfg->tqueue->q = 0; - rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts()); - - rte_delay_us(tcfg->tvar->wait_usec); - - /** - * enqueue one packet to recalculate average queue size - */ - if (rte_red_enqueue(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - *tcfg->tqueue->q, - get_port_ts()) == 0) { - (*tcfg->tqueue->q)++; - } else { - printf("%s:%d: packet enqueued on empty queue was dropped\n", __func__, __LINE__); - result = FAIL; - } - - exp_avg = calc_exp_avg_on_empty(avg_before, - (1 << *tcfg->tconfig->wq_log2), - tcfg->tvar->wait_usec); - avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata); - if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance)) - result = FAIL; - - printf("%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n", - avg_before, avg_after, exp_avg, diff, - (double)tcfg->tqueue->avg_tolerance, - diff <= (double)tcfg->tqueue->avg_tolerance ? "pass" : "fail"); - } -out: - return result; -} - -/** - * Test F4: functional test 4 - */ -static uint32_t ft4_tlevel[] = {1022}; -static uint8_t ft4_wq_log2[] = {11}; - -static struct test_rte_red_config ft4_tconfig = { - .rconfig = ft_wrconfig, - .num_cfg = RTE_DIM(ft_wrconfig), - .min_th = 32, - .max_th = 1023, - .wq_log2 = ft4_wq_log2, - .maxp_inv = ft_maxp_inv, -}; - -static struct test_queue ft4_tqueue = { - .rdata = ft_rtdata, - .num_queues = RTE_DIM(ft_rtdata), - .qconfig = ft_qconfig, - .q = ft_q, - .q_ramp_up = 1000000, - .avg_ramp_up = 1000000, - .avg_tolerance = 0, /* 0 percent */ - .drop_tolerance = 50, /* 50 percent */ -}; - -static struct test_config func_test4_config = { - .ifname = "functional test 4 interface", - .msg = "functional test 4 : use one RED configuration,\n" - " increase average queue size to target level,\n" - " dequeue all packets until queue is empty,\n" - " confirm that average queue size is computed correctly while\n" - " queue is empty for more than 50 sec,\n" - " (this test takes 52 sec to run)\n\n", - .htxt = "q avg before " - "q avg after " - "expected " - "difference % " - "tolerance % " - "result " - "\n", - .tconfig = &ft4_tconfig, - .tqueue = &ft4_tqueue, - .tvar = &ft_tvar, - .tlevel = ft4_tlevel, -}; - -static enum test_result func_test4(struct test_config *tcfg) -{ - enum test_result result = PASS; - uint64_t time_diff = 0; - uint64_t start = 0; - double avg_before = 0.0; - double avg_after = 0.0; - double exp_avg = 0.0; - double diff = 0.0; - - printf("%s", tcfg->msg); - - if (test_rte_red_init(tcfg) != PASS) { - result = FAIL; - goto out; - } - - rte_red_rt_data_init(tcfg->tqueue->rdata); - - if (increase_actual_qsize(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - *tcfg->tlevel, - tcfg->tqueue->q_ramp_up) != 0) { - result = FAIL; - goto out; - } - - if (increase_average_qsize(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - *tcfg->tlevel, - tcfg->tqueue->avg_ramp_up) != 0) { - result = FAIL; - goto out; - } - - printf("%s", tcfg->htxt); - - avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); - - /** - * empty the queue - */ - *tcfg->tqueue->q = 0; - rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts()); - - /** - * record empty time locally - */ - start = rte_rdtsc(); - - sleep(tcfg->tvar->sleep_sec); - - /** - * enqueue one packet to recalculate average queue size - */ - if (rte_red_enqueue(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - *tcfg->tqueue->q, - get_port_ts()) != 0) { - result = FAIL; - goto out; - } - (*tcfg->tqueue->q)++; - - /** - * calculate how long queue has been empty - */ - time_diff = ((rte_rdtsc() - start) / tcfg->tvar->clk_freq) - * MSEC_PER_SEC; - if (time_diff < MAX_QEMPTY_TIME_MSEC) { - /** - * this could happen if sleep was interrupted for some reason - */ - result = FAIL; - goto out; - } - - /** - * confirm that average queue size is now at expected level - */ - exp_avg = 0.0; - avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); - if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance)) - result = FAIL; - - printf("%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n", - avg_before, avg_after, exp_avg, - diff, (double)tcfg->tqueue->avg_tolerance, - diff <= (double)tcfg->tqueue->avg_tolerance ? "pass" : "fail"); -out: - return result; -} - -/** - * Test F5: functional test 5 - */ -static uint32_t ft5_tlevel[] = {127}; -static uint8_t ft5_wq_log2[] = {9, 8}; -static uint8_t ft5_maxp_inv[] = {10, 20}; -static struct rte_red_config ft5_config[2]; -static struct rte_red ft5_data[4]; -static uint32_t ft5_q[4]; -static uint32_t ft5_dropped[] = {0, 0, 0, 0}; -static uint32_t ft5_enqueued[] = {0, 0, 0, 0}; - -static struct test_rte_red_config ft5_tconfig = { - .rconfig = ft5_config, - .num_cfg = RTE_DIM(ft5_config), - .min_th = 32, - .max_th = 128, - .wq_log2 = ft5_wq_log2, - .maxp_inv = ft5_maxp_inv, -}; - -static struct test_queue ft5_tqueue = { - .rdata = ft5_data, - .num_queues = RTE_DIM(ft5_data), - .qconfig = ft_qconfig, - .q = ft5_q, - .q_ramp_up = 1000000, - .avg_ramp_up = 1000000, - .avg_tolerance = 5, /* 10 percent */ - .drop_tolerance = 50, /* 50 percent */ -}; - -struct test_var ft5_tvar = { - .wait_usec = 0, - .num_iterations = 15, - .num_ops = 10000, - .clk_freq = 0, - .dropped = ft5_dropped, - .enqueued = ft5_enqueued, - .sleep_sec = 0, -}; - -static struct test_config func_test5_config = { - .ifname = "functional test 5 interface", - .msg = "functional test 5 : use several queues (each with its own run-time data),\n" - " use several RED configurations (such that each configuration is shared by multiple queues),\n" - " increase average queue size to just below maximum threshold,\n" - " compare drop rate to drop probability,\n" - " (this is a larger scale version of functional test 2)\n\n", - .htxt = "queue " - "config " - "avg queue size " - "min threshold " - "max threshold " - "drop prob % " - "drop rate % " - "diff % " - "tolerance % " - "\n", - .tconfig = &ft5_tconfig, - .tqueue = &ft5_tqueue, - .tvar = &ft5_tvar, - .tlevel = ft5_tlevel, -}; - -static enum test_result func_test5(struct test_config *tcfg) -{ - enum test_result result = PASS; - uint32_t j = 0; - - printf("%s", tcfg->msg); - - if (test_rte_red_init(tcfg) != PASS) { - result = FAIL; - goto out; - } - - printf("%s", tcfg->htxt); - - for (j = 0; j < tcfg->tqueue->num_queues; j++) { - rte_red_rt_data_init(&tcfg->tqueue->rdata[j]); - tcfg->tqueue->q[j] = 0; - - if (increase_actual_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j], - &tcfg->tqueue->q[j], - *tcfg->tlevel, - tcfg->tqueue->q_ramp_up) != 0) { - result = FAIL; - goto out; - } - - if (increase_average_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j], - &tcfg->tqueue->q[j], - *tcfg->tlevel, - tcfg->tqueue->avg_ramp_up) != 0) { - result = FAIL; - goto out; - } - } - - for (j = 0; j < tcfg->tqueue->num_queues; j++) { - uint32_t avg = 0; - double drop_rate = 0.0; - double drop_prob = 0.0; - double diff = 0.0; - - tcfg->tvar->dropped[j] = 0; - tcfg->tvar->enqueued[j] = 0; - - enqueue_dequeue_func(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j], - &tcfg->tqueue->q[j], - tcfg->tvar->num_ops, - &tcfg->tvar->enqueued[j], - &tcfg->tvar->dropped[j]); - - avg = rte_red_get_avg_int(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j]); - if (avg != *tcfg->tlevel) - result = FAIL; - - drop_rate = calc_drop_rate(tcfg->tvar->enqueued[j],tcfg->tvar->dropped[j]); - drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th, - tcfg->tconfig->maxp_inv[tcfg->tqueue->qconfig[j]], - *tcfg->tlevel); - if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance)) - result = FAIL; - - printf("%-15u%-15u%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n", - j, tcfg->tqueue->qconfig[j], avg, - tcfg->tconfig->min_th, tcfg->tconfig->max_th, - drop_prob * 100.0, drop_rate * 100.0, - diff, (double)tcfg->tqueue->drop_tolerance); - } -out: - return result; -} - -/** - * Test F6: functional test 6 - */ -static uint32_t ft6_tlevel[] = {1022}; -static uint8_t ft6_wq_log2[] = {9, 8}; -static uint8_t ft6_maxp_inv[] = {10, 20}; -static struct rte_red_config ft6_config[2]; -static struct rte_red ft6_data[4]; -static uint32_t ft6_q[4]; - -static struct test_rte_red_config ft6_tconfig = { - .rconfig = ft6_config, - .num_cfg = RTE_DIM(ft6_config), - .min_th = 32, - .max_th = 1023, - .wq_log2 = ft6_wq_log2, - .maxp_inv = ft6_maxp_inv, -}; - -static struct test_queue ft6_tqueue = { - .rdata = ft6_data, - .num_queues = RTE_DIM(ft6_data), - .qconfig = ft_qconfig, - .q = ft6_q, - .q_ramp_up = 1000000, - .avg_ramp_up = 1000000, - .avg_tolerance = 5, /* 10 percent */ - .drop_tolerance = 50, /* 50 percent */ -}; - -static struct test_config func_test6_config = { - .ifname = "functional test 6 interface", - .msg = "functional test 6 : use several queues (each with its own run-time data),\n" - " use several RED configurations (such that each configuration is sharte_red by multiple queues),\n" - " increase average queue size to target level,\n" - " dequeue all packets until queue is empty,\n" - " confirm that average queue size is computed correctly while queue is empty\n" - " (this is a larger scale version of functional test 3)\n\n", - .htxt = "queue " - "config " - "q avg before " - "q avg after " - "expected " - "difference % " - "tolerance % " - "result ""\n", - .tconfig = &ft6_tconfig, - .tqueue = &ft6_tqueue, - .tvar = &ft_tvar, - .tlevel = ft6_tlevel, -}; - -static enum test_result func_test6(struct test_config *tcfg) -{ - enum test_result result = PASS; - uint32_t j = 0; - - printf("%s", tcfg->msg); - if (test_rte_red_init(tcfg) != PASS) { - result = FAIL; - goto out; - } - printf("%s", tcfg->htxt); - - for (j = 0; j < tcfg->tqueue->num_queues; j++) { - rte_red_rt_data_init(&tcfg->tqueue->rdata[j]); - tcfg->tqueue->q[j] = 0; - - if (increase_actual_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j], - &tcfg->tqueue->q[j], - *tcfg->tlevel, - tcfg->tqueue->q_ramp_up) != 0) { - result = FAIL; - goto out; - } - if (increase_average_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j], - &tcfg->tqueue->q[j], - *tcfg->tlevel, - tcfg->tqueue->avg_ramp_up) != 0) { - result = FAIL; - goto out; - } - } - for (j = 0; j < tcfg->tqueue->num_queues; j++) { - double avg_before = 0; - double avg_after = 0; - double exp_avg = 0; - double diff = 0.0; - - avg_before = rte_red_get_avg_float(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j]); - - /** - * empty the queue - */ - tcfg->tqueue->q[j] = 0; - rte_red_mark_queue_empty(&tcfg->tqueue->rdata[j], get_port_ts()); - rte_delay_us(tcfg->tvar->wait_usec); - - /** - * enqueue one packet to recalculate average queue size - */ - if (rte_red_enqueue(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j], - tcfg->tqueue->q[j], - get_port_ts()) == 0) { - tcfg->tqueue->q[j]++; - } else { - printf("%s:%d: packet enqueued on empty queue was dropped\n", __func__, __LINE__); - result = FAIL; - } - - exp_avg = calc_exp_avg_on_empty(avg_before, - (1 << tcfg->tconfig->wq_log2[tcfg->tqueue->qconfig[j]]), - tcfg->tvar->wait_usec); - avg_after = rte_red_get_avg_float(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], - &tcfg->tqueue->rdata[j]); - if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance)) - result = FAIL; - - printf("%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n", - j, tcfg->tqueue->qconfig[j], avg_before, avg_after, - exp_avg, diff, (double)tcfg->tqueue->avg_tolerance, - diff <= tcfg->tqueue->avg_tolerance ? "pass" : "fail"); - } -out: - return result; -} - -/** - * setup default values for the performance test structures - */ -static struct rte_red_config pt_wrconfig[1]; -static struct rte_red pt_rtdata[1]; -static uint8_t pt_wq_log2[] = {9}; -static uint8_t pt_maxp_inv[] = {10}; -static uint32_t pt_qconfig[] = {0}; -static uint32_t pt_q[] = {0}; -static uint32_t pt_dropped[] = {0}; -static uint32_t pt_enqueued[] = {0}; - -static struct test_rte_red_config pt_tconfig = { - .rconfig = pt_wrconfig, - .num_cfg = RTE_DIM(pt_wrconfig), - .wq_log2 = pt_wq_log2, - .min_th = 32, - .max_th = 128, - .maxp_inv = pt_maxp_inv, -}; - -static struct test_queue pt_tqueue = { - .rdata = pt_rtdata, - .num_queues = RTE_DIM(pt_rtdata), - .qconfig = pt_qconfig, - .q = pt_q, - .q_ramp_up = 1000000, - .avg_ramp_up = 1000000, - .avg_tolerance = 5, /* 10 percent */ - .drop_tolerance = 50, /* 50 percent */ -}; - -/** - * enqueue/dequeue packets - */ -static void enqueue_dequeue_perf(struct rte_red_config *red_cfg, - struct rte_red *red, - uint32_t *q, - uint32_t num_ops, - uint32_t *enqueued, - uint32_t *dropped, - struct rdtsc_prof *prof) -{ - uint32_t i = 0; - - for (i = 0; i < num_ops; i++) { - uint64_t ts = 0; - int ret = 0; - /** - * enqueue - */ - ts = get_port_ts(); - rdtsc_prof_start(prof); - ret = rte_red_enqueue(red_cfg, red, *q, ts ); - rdtsc_prof_end(prof); - if (ret == 0) - (*enqueued)++; - else - (*dropped)++; - } -} - -/** - * Setup test structures for tests P1, P2, P3 - * performance tests 1, 2 and 3 - */ -static uint32_t pt1_tlevel[] = {16}; -static uint32_t pt2_tlevel[] = {80}; -static uint32_t pt3_tlevel[] = {144}; - -static struct test_var perf1_tvar = { - .wait_usec = 0, - .num_iterations = 15, - .num_ops = 50000000, - .clk_freq = 0, - .dropped = pt_dropped, - .enqueued = pt_enqueued, - .sleep_sec = 0 -}; - -static struct test_config perf1_test1_config = { - .ifname = "performance test 1 interface", - .msg = "performance test 1 : use one RED configuration,\n" - " set actual and average queue sizes to level below min threshold,\n" - " measure enqueue performance\n\n", - .tconfig = &pt_tconfig, - .tqueue = &pt_tqueue, - .tvar = &perf1_tvar, - .tlevel = pt1_tlevel, -}; - -static struct test_config perf1_test2_config = { - .ifname = "performance test 2 interface", - .msg = "performance test 2 : use one RED configuration,\n" - " set actual and average queue sizes to level in between min and max thresholds,\n" - " measure enqueue performance\n\n", - .tconfig = &pt_tconfig, - .tqueue = &pt_tqueue, - .tvar = &perf1_tvar, - .tlevel = pt2_tlevel, -}; - -static struct test_config perf1_test3_config = { - .ifname = "performance test 3 interface", - .msg = "performance test 3 : use one RED configuration,\n" - " set actual and average queue sizes to level above max threshold,\n" - " measure enqueue performance\n\n", - .tconfig = &pt_tconfig, - .tqueue = &pt_tqueue, - .tvar = &perf1_tvar, - .tlevel = pt3_tlevel, -}; - -/** - * Performance test function to measure enqueue performance. - * This runs performance tests 1, 2 and 3 - */ -static enum test_result perf1_test(struct test_config *tcfg) -{ - enum test_result result = PASS; - struct rdtsc_prof prof = {0, 0, 0, 0, 0.0, NULL}; - uint32_t total = 0; - - printf("%s", tcfg->msg); - - rdtsc_prof_init(&prof, "enqueue"); - - if (test_rte_red_init(tcfg) != PASS) { - result = FAIL; - goto out; - } - - /** - * set average queue size to target level - */ - *tcfg->tqueue->q = *tcfg->tlevel; - - /** - * initialize the rte_red run time data structure - */ - rte_red_rt_data_init(tcfg->tqueue->rdata); - - /** - * set the queue average - */ - rte_red_set_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, *tcfg->tlevel); - if (rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata) - != *tcfg->tlevel) { - result = FAIL; - goto out; - } - - enqueue_dequeue_perf(tcfg->tconfig->rconfig, - tcfg->tqueue->rdata, - tcfg->tqueue->q, - tcfg->tvar->num_ops, - tcfg->tvar->enqueued, - tcfg->tvar->dropped, - &prof); - - total = *tcfg->tvar->enqueued + *tcfg->tvar->dropped; - - printf("\ntotal: %u, enqueued: %u (%.2lf%%), dropped: %u (%.2lf%%)\n", total, - *tcfg->tvar->enqueued, ((double)(*tcfg->tvar->enqueued) / (double)total) * 100.0, - *tcfg->tvar->dropped, ((double)(*tcfg->tvar->dropped) / (double)total) * 100.0); - - rdtsc_prof_print(&prof); -out: - return result; -} - -/** - * Setup test structures for tests P4, P5, P6 - * performance tests 4, 5 and 6 - */ -static uint32_t pt4_tlevel[] = {16}; -static uint32_t pt5_tlevel[] = {80}; -static uint32_t pt6_tlevel[] = {144}; - -static struct test_var perf2_tvar = { - .wait_usec = 500, - .num_iterations = 10000, - .num_ops = 10000, - .dropped = pt_dropped, - .enqueued = pt_enqueued, - .sleep_sec = 0 -}; - -static struct test_config perf2_test4_config = { - .ifname = "performance test 4 interface", - .msg = "performance test 4 : use one RED configuration,\n" - " set actual and average queue sizes to level below min threshold,\n" - " dequeue all packets until queue is empty,\n" - " measure enqueue performance when queue is empty\n\n", - .htxt = "iteration " - "q avg before " - "q avg after " - "expected " - "difference % " - "tolerance % " - "result ""\n", - .tconfig = &pt_tconfig, - .tqueue = &pt_tqueue, - .tvar = &perf2_tvar, - .tlevel = pt4_tlevel, -}; - -static struct test_config perf2_test5_config = { - .ifname = "performance test 5 interface", - .msg = "performance test 5 : use one RED configuration,\n" - " set actual and average queue sizes to level in between min and max thresholds,\n" - " dequeue all packets until queue is empty,\n" - " measure enqueue performance when queue is empty\n\n", - .htxt = "iteration " - "q avg before " - "q avg after " - "expected " - "difference " - "tolerance " - "result ""\n", - .tconfig = &pt_tconfig, - .tqueue = &pt_tqueue, - .tvar = &perf2_tvar, - .tlevel = pt5_tlevel, -}; - -static struct test_config perf2_test6_config = { - .ifname = "performance test 6 interface", - .msg = "performance test 6 : use one RED configuration,\n" - " set actual and average queue sizes to level above max threshold,\n" - " dequeue all packets until queue is empty,\n" - " measure enqueue performance when queue is empty\n\n", - .htxt = "iteration " - "q avg before " - "q avg after " - "expected " - "difference % " - "tolerance % " - "result ""\n", - .tconfig = &pt_tconfig, - .tqueue = &pt_tqueue, - .tvar = &perf2_tvar, - .tlevel = pt6_tlevel, -}; - -/** - * Performance test function to measure enqueue performance when the - * queue is empty. This runs performance tests 4, 5 and 6 - */ -static enum test_result perf2_test(struct test_config *tcfg) -{ - enum test_result result = PASS; - struct rdtsc_prof prof = {0, 0, 0, 0, 0.0, NULL}; - uint32_t total = 0; - uint32_t i = 0; - - printf("%s", tcfg->msg); - - rdtsc_prof_init(&prof, "enqueue"); - - if (test_rte_red_init(tcfg) != PASS) { - result = FAIL; - goto out; - } - - printf("%s", tcfg->htxt); - - for (i = 0; i < tcfg->tvar->num_iterations; i++) { - uint32_t count = 0; - uint64_t ts = 0; - double avg_before = 0; - int ret = 0; - - /** - * set average queue size to target level - */ - *tcfg->tqueue->q = *tcfg->tlevel; - count = (*tcfg->tqueue->rdata).count; - - /** - * initialize the rte_red run time data structure - */ - rte_red_rt_data_init(tcfg->tqueue->rdata); - (*tcfg->tqueue->rdata).count = count; - - /** - * set the queue average - */ - rte_red_set_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, *tcfg->tlevel); - avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); - if ((avg_before < *tcfg->tlevel) || (avg_before > *tcfg->tlevel)) { - result = FAIL; - goto out; - } - - /** - * empty the queue - */ - *tcfg->tqueue->q = 0; - rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts()); - - /** - * wait for specified period of time - */ - rte_delay_us(tcfg->tvar->wait_usec); - - /** - * measure performance of enqueue operation while queue is empty - */ - ts = get_port_ts(); - rdtsc_prof_start(&prof); - ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, - *tcfg->tqueue->q, ts ); - rdtsc_prof_end(&prof); - - /** - * gather enqueued/dropped statistics - */ - if (ret == 0) - (*tcfg->tvar->enqueued)++; - else - (*tcfg->tvar->dropped)++; - - /** - * on first and last iteration, confirm that - * average queue size was computed correctly - */ - if ((i == 0) || (i == tcfg->tvar->num_iterations - 1)) { - double avg_after = 0; - double exp_avg = 0; - double diff = 0.0; - int ok = 0; - - avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); - exp_avg = calc_exp_avg_on_empty(avg_before, - (1 << *tcfg->tconfig->wq_log2), - tcfg->tvar->wait_usec); - if (check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance)) - ok = 1; - printf("%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n", - i, avg_before, avg_after, exp_avg, diff, - (double)tcfg->tqueue->avg_tolerance, ok ? "pass" : "fail"); - if (!ok) { - result = FAIL; - goto out; - } - } - } - total = *tcfg->tvar->enqueued + *tcfg->tvar->dropped; - printf("\ntotal: %u, enqueued: %u (%.2lf%%), dropped: %u (%.2lf%%)\n", total, - *tcfg->tvar->enqueued, ((double)(*tcfg->tvar->enqueued) / (double)total) * 100.0, - *tcfg->tvar->dropped, ((double)(*tcfg->tvar->dropped) / (double)total) * 100.0); - - rdtsc_prof_print(&prof); -out: - return result; -} - -/** - * setup default values for overflow test structures - */ -static uint32_t avg_max = 0; -static uint32_t avg_max_bits = 0; - -static struct rte_red_config ovfl_wrconfig[1]; -static struct rte_red ovfl_rtdata[1]; -static uint8_t ovfl_maxp_inv[] = {10}; -static uint32_t ovfl_qconfig[] = {0, 0, 1, 1}; -static uint32_t ovfl_q[] ={0}; -static uint32_t ovfl_dropped[] ={0}; -static uint32_t ovfl_enqueued[] ={0}; -static uint32_t ovfl_tlevel[] = {1023}; -static uint8_t ovfl_wq_log2[] = {12}; - -static struct test_rte_red_config ovfl_tconfig = { - .rconfig = ovfl_wrconfig, - .num_cfg = RTE_DIM(ovfl_wrconfig), - .wq_log2 = ovfl_wq_log2, - .min_th = 32, - .max_th = 1023, - .maxp_inv = ovfl_maxp_inv, -}; - -static struct test_queue ovfl_tqueue = { - .rdata = ovfl_rtdata, - .num_queues = RTE_DIM(ovfl_rtdata), - .qconfig = ovfl_qconfig, - .q = ovfl_q, - .q_ramp_up = 1000000, - .avg_ramp_up = 1000000, - .avg_tolerance = 5, /* 10 percent */ - .drop_tolerance = 50, /* 50 percent */ -}; - -static struct test_var ovfl_tvar = { - .wait_usec = 10000, - .num_iterations = 1, - .num_ops = 10000, - .clk_freq = 0, - .dropped = ovfl_dropped, - .enqueued = ovfl_enqueued, - .sleep_sec = 0 -}; - -static void ovfl_check_avg(uint32_t avg) -{ - if (avg > avg_max) { - double avg_log = 0; - uint32_t bits = 0; - avg_max = avg; - avg_log = log(((double)avg_max)); - avg_log = avg_log / log(2.0); - bits = (uint32_t)ceil(avg_log); - if (bits > avg_max_bits) - avg_max_bits = bits; - } -} - -static struct test_config ovfl_test1_config = { - .ifname = "queue avergage overflow test interface", - .msg = "overflow test 1 : use one RED configuration,\n" - " increase average queue size to target level,\n" - " check maximum number of bits requirte_red to represent avg_s\n\n", - .htxt = "avg queue size " - "wq_log2 " - "fraction bits " - "max queue avg " - "num bits " - "enqueued " - "dropped " - "drop prob % " - "drop rate % " - "\n", - .tconfig = &ovfl_tconfig, - .tqueue = &ovfl_tqueue, - .tvar = &ovfl_tvar, - .tlevel = ovfl_tlevel, -}; - -static enum test_result ovfl_test1(struct test_config *tcfg) -{ - enum test_result result = PASS; - uint32_t avg = 0; - uint32_t i = 0; - double drop_rate = 0.0; - double drop_prob = 0.0; - double diff = 0.0; - int ret = 0; - - printf("%s", tcfg->msg); - - if (test_rte_red_init(tcfg) != PASS) { - - result = FAIL; - goto out; - } - - /** - * reset rte_red run-time data - */ - rte_red_rt_data_init(tcfg->tqueue->rdata); - - /** - * increase actual queue size - */ - for (i = 0; i < tcfg->tqueue->q_ramp_up; i++) { - ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, - *tcfg->tqueue->q, get_port_ts()); - - if (ret == 0) { - if (++(*tcfg->tqueue->q) >= *tcfg->tlevel) - break; - } - } - - /** - * enqueue - */ - for (i = 0; i < tcfg->tqueue->avg_ramp_up; i++) { - ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, - *tcfg->tqueue->q, get_port_ts()); - ovfl_check_avg((*tcfg->tqueue->rdata).avg); - avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); - if (avg == *tcfg->tlevel) { - if (ret == 0) - (*tcfg->tvar->enqueued)++; - else - (*tcfg->tvar->dropped)++; - } - } - - /** - * check if target average queue size has been reached - */ - avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); - if (avg != *tcfg->tlevel) { - result = FAIL; - goto out; - } - - /** - * check drop rate against drop probability - */ - drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped); - drop_prob = calc_drop_prob(tcfg->tconfig->min_th, - tcfg->tconfig->max_th, - *tcfg->tconfig->maxp_inv, - *tcfg->tlevel); - if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance)) - result = FAIL; - - printf("%s", tcfg->htxt); - - printf("%-16u%-9u%-15u0x%08x %-10u%-10u%-10u%-13.2lf%-13.2lf\n", - avg, *tcfg->tconfig->wq_log2, RTE_RED_SCALING, - avg_max, avg_max_bits, - *tcfg->tvar->enqueued, *tcfg->tvar->dropped, - drop_prob * 100.0, drop_rate * 100.0); -out: - return result; -} - -/** - * define the functional and performance tests to be executed - */ -struct tests func_tests[] = { - { &func_test1_config, func_test1 }, - { &func_test2_config, func_test2 }, - { &func_test3_config, func_test3 }, - { &func_test4_config, func_test4 }, - { &func_test5_config, func_test5 }, - { &func_test6_config, func_test6 }, - { &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 }, - { &perf1_test3_config, perf1_test }, - { &perf2_test4_config, perf2_test }, - { &perf2_test5_config, perf2_test }, - { &perf2_test6_config, perf2_test }, -}; - -/** - * function to execute the required_red tests - */ -static void run_tests(struct tests *test_type, uint32_t test_count, uint32_t *num_tests, uint32_t *num_pass) -{ - enum test_result result = PASS; - uint32_t i = 0; - - for (i = 0; i < test_count; i++) { - printf("\n--------------------------------------------------------------------------------\n"); - result = test_type[i].testfn(test_type[i].testcfg); - (*num_tests)++; - if (result == PASS) { - (*num_pass)++; - printf("--------------------------------------------------------------------------\n"); - } else { - printf("--------------------------------------------------------------------------\n"); - } - } - return; -} - -/** - * check if functions accept invalid parameters - * - * First, all functions will be called without initialized RED - * Then, all of them will be called with NULL/invalid parameters - * - * Some functions are not tested as they are performance-critical and thus - * don't do any parameter checking. - */ -static int -test_invalid_parameters(void) -{ - struct rte_red_config config; - - if (rte_red_rt_data_init(NULL) == 0) { - printf("rte_red_rt_data_init should have failed!\n"); - return -1; - } - - if (rte_red_config_init(NULL, 0, 0, 0, 0) == 0) { - printf("rte_red_config_init should have failed!\n"); - return -1; - } - - if (rte_red_rt_data_init(NULL) == 0) { - printf("rte_red_rt_data_init should have failed!\n"); - return -1; - } - - /* NULL config */ - if (rte_red_config_init(NULL, 0, 0, 0, 0) == 0) { - printf("%i: rte_red_config_init should have failed!\n", __LINE__); - return -1; - } - /* min_treshold == max_treshold */ - if (rte_red_config_init(&config, 0, 1, 1, 0) == 0) { - printf("%i: rte_red_config_init should have failed!\n", __LINE__); - return -1; - } - /* min_treshold > max_treshold */ - if (rte_red_config_init(&config, 0, 2, 1, 0) == 0) { - printf("%i: rte_red_config_init should have failed!\n", __LINE__); - return -1; - } - /* wq_log2 > RTE_RED_WQ_LOG2_MAX */ - if (rte_red_config_init(&config, - RTE_RED_WQ_LOG2_MAX + 1, 1, 2, 0) == 0) { - printf("%i: rte_red_config_init should have failed!\n", __LINE__); - return -1; - } - /* wq_log2 < RTE_RED_WQ_LOG2_MIN */ - if (rte_red_config_init(&config, - RTE_RED_WQ_LOG2_MIN - 1, 1, 2, 0) == 0) { - printf("%i: rte_red_config_init should have failed!\n", __LINE__); - return -1; - } - /* maxp_inv > RTE_RED_MAXP_INV_MAX */ - if (rte_red_config_init(&config, - RTE_RED_WQ_LOG2_MIN, 1, 2, RTE_RED_MAXP_INV_MAX + 1) == 0) { - printf("%i: rte_red_config_init should have failed!\n", __LINE__); - return -1; - } - /* maxp_inv < RTE_RED_MAXP_INV_MIN */ - if (rte_red_config_init(&config, - RTE_RED_WQ_LOG2_MIN, 1, 2, RTE_RED_MAXP_INV_MIN - 1) == 0) { - printf("%i: rte_red_config_init should have failed!\n", __LINE__); - return -1; - } - - 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; - - 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(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 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); -} - -REGISTER_TEST_COMMAND(red_autotest, test_red); -REGISTER_TEST_COMMAND(red_perf, test_red_perf); -REGISTER_TEST_COMMAND(red_all, test_red_all); diff --git a/app/test/test_reorder.c b/app/test/test_reorder.c deleted file mode 100644 index e8a0a2f234..0000000000 --- a/app/test/test_reorder.c +++ /dev/null @@ -1,386 +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 "test.h" -#include "stdio.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define BURST 32 -#define REORDER_BUFFER_SIZE 16384 -#define NUM_MBUFS (2*REORDER_BUFFER_SIZE) -#define REORDER_BUFFER_SIZE_INVALID 2049 - -struct reorder_unittest_params { - struct rte_mempool *p; - struct rte_reorder_buffer *b; -}; - -static struct reorder_unittest_params default_params = { - .p = NULL, - .b = NULL -}; - -static struct reorder_unittest_params *test_params = &default_params; - -static int -test_reorder_create(void) -{ - struct rte_reorder_buffer *b = NULL; - - b = rte_reorder_create(NULL, rte_socket_id(), REORDER_BUFFER_SIZE); - TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), - "No error on create() with NULL name"); - - b = rte_reorder_create("PKT", rte_socket_id(), REORDER_BUFFER_SIZE_INVALID); - TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), - "No error on create() with invalid buffer size param."); - - b = rte_reorder_create("PKT_RO1", rte_socket_id(), REORDER_BUFFER_SIZE); - TEST_ASSERT_EQUAL(b, test_params->b, - "New reorder instance created with already existing name"); - - return 0; -} - -static int -test_reorder_init(void) -{ - struct rte_reorder_buffer *b = NULL; - unsigned int size; - /* - * The minimum memory area size that should be passed to library is, - * sizeof(struct rte_reorder_buffer) + (2 * size * sizeof(struct rte_mbuf *)); - * Otherwise error will be thrown - */ - - size = 100; - b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE); - TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), - "No error on init with NULL buffer."); - - b = rte_malloc(NULL, size, 0); - b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE); - TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), - "No error on init with invalid mem zone size."); - rte_free(b); - - size = 262336; - b = rte_malloc(NULL, size, 0); - b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE_INVALID); - TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), - "No error on init with invalid buffer size param."); - - b = rte_reorder_init(b, size, NULL, REORDER_BUFFER_SIZE); - TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), - "No error on init with invalid name."); - rte_free(b); - - return 0; -} - -static int -test_reorder_find_existing(void) -{ - struct rte_reorder_buffer *b = NULL; - - /* Try to find existing reorder buffer instance */ - b = rte_reorder_find_existing("PKT_RO1"); - TEST_ASSERT_EQUAL(b, test_params->b, - "existing reorder buffer instance not found"); - - /* Try to find non existing reorder buffer instance */ - b = rte_reorder_find_existing("ro_find_non_existing"); - TEST_ASSERT((b == NULL) && (rte_errno == ENOENT), - "non existing reorder buffer instance found"); - - return 0; -} - -static int -test_reorder_free(void) -{ - struct rte_reorder_buffer *b1 = NULL, *b2 = NULL; - const char *name = "test_free"; - - b1 = rte_reorder_create(name, rte_socket_id(), 8); - TEST_ASSERT_NOT_NULL(b1, "Failed to create reorder buffer."); - - b2 = rte_reorder_find_existing(name); - TEST_ASSERT_EQUAL(b1, b2, "Failed to find existing reorder buffer"); - - rte_reorder_free(b1); - - b2 = rte_reorder_find_existing(name); - TEST_ASSERT((b2 == NULL) && (rte_errno == ENOENT), - "Found previously freed reorder buffer"); - - return 0; -} - -static int -test_reorder_insert(void) -{ - struct rte_reorder_buffer *b = NULL; - struct rte_mempool *p = test_params->p; - const unsigned int size = 4; - const unsigned int num_bufs = 7; - struct rte_mbuf *bufs[num_bufs]; - int ret = 0; - unsigned i; - - /* This would create a reorder buffer instance consisting of: - * reorder_seq = 0 - * ready_buf: RB[size] = {NULL, NULL, NULL, NULL} - * order_buf: OB[size] = {NULL, NULL, NULL, NULL} - */ - b = rte_reorder_create("test_insert", rte_socket_id(), size); - TEST_ASSERT_NOT_NULL(b, "Failed to create reorder buffer"); - - ret = rte_mempool_get_bulk(p, (void *)bufs, num_bufs); - TEST_ASSERT_SUCCESS(ret, "Error getting mbuf from pool"); - - for (i = 0; i < num_bufs; i++) - bufs[i]->seqn = i; - - /* This should fill up order buffer: - * reorder_seq = 0 - * RB[] = {NULL, NULL, NULL, NULL} - * OB[] = {0, 1, 2, 3} - */ - for (i = 0; i < size; i++) { - ret = rte_reorder_insert(b, bufs[i]); - if (ret != 0) { - printf("%s:%d: Error inserting packet with seqn less than size\n", - __func__, __LINE__); - ret = -1; - goto exit; - } - } - - /* early packet - should move mbufs to ready buf and move sequence window - * reorder_seq = 4 - * RB[] = {0, 1, 2, 3} - * OB[] = {4, NULL, NULL, NULL} - */ - ret = rte_reorder_insert(b, bufs[4]); - if (ret != 0) { - printf("%s:%d: Error inserting early packet with seqn: size\n", - __func__, __LINE__); - ret = -1; - goto exit; - } - - /* early packet from current sequence window - full ready buffer */ - bufs[5]->seqn = 2 * size; - ret = rte_reorder_insert(b, bufs[5]); - if (!((ret == -1) && (rte_errno == ENOSPC))) { - printf("%s:%d: No error inserting early packet with full ready buffer\n", - __func__, __LINE__); - ret = -1; - goto exit; - } - - /* late packet */ - bufs[6]->seqn = 3 * size; - ret = rte_reorder_insert(b, bufs[6]); - if (!((ret == -1) && (rte_errno == ERANGE))) { - printf("%s:%d: No error inserting late packet with seqn:" - " 3 * size\n", __func__, __LINE__); - ret = -1; - goto exit; - } - - ret = 0; -exit: - rte_mempool_put_bulk(p, (void *)bufs, num_bufs); - rte_reorder_free(b); - return ret; -} - -static int -test_reorder_drain(void) -{ - struct rte_reorder_buffer *b = NULL; - struct rte_mempool *p = test_params->p; - const unsigned int size = 4; - const unsigned int num_bufs = 8; - struct rte_mbuf *bufs[num_bufs]; - struct rte_mbuf *robufs[num_bufs]; - int ret = 0; - unsigned i, cnt; - - /* This would create a reorder buffer instance consisting of: - * reorder_seq = 0 - * ready_buf: RB[size] = {NULL, NULL, NULL, NULL} - * order_buf: OB[size] = {NULL, NULL, NULL, NULL} - */ - b = rte_reorder_create("test_drain", rte_socket_id(), size); - TEST_ASSERT_NOT_NULL(b, "Failed to create reorder buffer"); - - ret = rte_mempool_get_bulk(p, (void *)bufs, num_bufs); - TEST_ASSERT_SUCCESS(ret, "Error getting mbuf from pool"); - - /* Check no drained packets if reorder is empty */ - cnt = rte_reorder_drain(b, robufs, 1); - if (cnt != 0) { - printf("%s:%d: drained packets from empty reorder buffer\n", - __func__, __LINE__); - ret = -1; - goto exit; - } - - for (i = 0; i < num_bufs; i++) - bufs[i]->seqn = i; - - /* Insert packet with seqn 1: - * reorder_seq = 0 - * RB[] = {NULL, NULL, NULL, NULL} - * OB[] = {1, NULL, NULL, NULL} - */ - rte_reorder_insert(b, bufs[1]); - - cnt = rte_reorder_drain(b, robufs, 1); - if (cnt != 1) { - printf("%s:%d:%d: number of expected packets not drained\n", - __func__, __LINE__, cnt); - ret = -1; - goto exit; - } - - /* Insert more packets - * RB[] = {NULL, NULL, NULL, NULL} - * OB[] = {NULL, 2, 3, NULL} - */ - rte_reorder_insert(b, bufs[2]); - rte_reorder_insert(b, bufs[3]); - - /* Insert more packets - * RB[] = {NULL, NULL, NULL, NULL} - * OB[] = {NULL, 2, 3, 4} - */ - rte_reorder_insert(b, bufs[4]); - - /* Insert more packets - * RB[] = {2, 3, 4, NULL} - * OB[] = {NULL, NULL, 7, NULL} - */ - rte_reorder_insert(b, bufs[7]); - - /* drained expected packets */ - cnt = rte_reorder_drain(b, robufs, 4); - if (cnt != 3) { - printf("%s:%d:%d: number of expected packets not drained\n", - __func__, __LINE__, cnt); - ret = -1; - goto exit; - } - - /* - * RB[] = {NULL, NULL, NULL, NULL} - * OB[] = {NULL, NULL, 7, NULL} - */ - cnt = rte_reorder_drain(b, robufs, 1); - if (cnt != 0) { - printf("%s:%d:%d: number of expected packets not drained\n", - __func__, __LINE__, cnt); - ret = -1; - goto exit; - } - ret = 0; -exit: - rte_mempool_put_bulk(p, (void *)bufs, num_bufs); - rte_reorder_free(b); - return ret; -} - -static int -test_setup(void) -{ - /* reorder buffer instance creation */ - if (test_params->b == NULL) { - test_params->b = rte_reorder_create("PKT_RO1", rte_socket_id(), - REORDER_BUFFER_SIZE); - if (test_params->b == NULL) { - printf("%s: Error creating reorder buffer instance b\n", - __func__); - return -1; - } - } else - rte_reorder_reset(test_params->b); - - /* mempool creation */ - if (test_params->p == NULL) { - test_params->p = rte_pktmbuf_pool_create("RO_MBUF_POOL", - NUM_MBUFS, BURST, 0, RTE_MBUF_DEFAULT_BUF_SIZE, - rte_socket_id()); - if (test_params->p == NULL) { - printf("%s: Error creating mempool\n", __func__); - return -1; - } - } - return 0; -} - -static struct unit_test_suite reorder_test_suite = { - - .setup = test_setup, - .suite_name = "Reorder Unit Test Suite", - .unit_test_cases = { - TEST_CASE(test_reorder_create), - TEST_CASE(test_reorder_init), - TEST_CASE(test_reorder_find_existing), - TEST_CASE(test_reorder_free), - TEST_CASE(test_reorder_insert), - TEST_CASE(test_reorder_drain), - TEST_CASES_END() - } -}; - -static int -test_reorder(void) -{ - return unit_test_suite_runner(&reorder_test_suite); -} - -REGISTER_TEST_COMMAND(reorder_autotest, test_reorder); diff --git a/app/test/test_resource.c b/app/test/test_resource.c deleted file mode 100644 index a3a82f13a5..0000000000 --- a/app/test/test_resource.c +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * 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 -#include - -#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; -} - -REGISTER_TEST_COMMAND(resource_autotest, test_resource); diff --git a/app/test/test_ring.c b/app/test/test_ring.c deleted file mode 100644 index ebcb896415..0000000000 --- a/app/test/test_ring.c +++ /dev/null @@ -1,1381 +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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * Ring - * ==== - * - * #. Basic tests: done on one core: - * - * - Using single producer/single consumer functions: - * - * - Enqueue one object, two objects, MAX_BULK objects - * - Dequeue one object, two objects, MAX_BULK objects - * - Check that dequeued pointers are correct - * - * - Using multi producers/multi consumers functions: - * - * - Enqueue one object, two objects, MAX_BULK objects - * - Dequeue one object, two objects, MAX_BULK objects - * - Check that dequeued pointers are correct - * - * - Test watermark and default bulk enqueue/dequeue: - * - * - Set watermark - * - Set default bulk value - * - Enqueue objects, check that -EDQUOT is returned when - * watermark is exceeded - * - Check that dequeued pointers are correct - * - * #. Check live watermark change - * - * - Start a loop on another lcore that will enqueue and dequeue - * objects in a ring. It will monitor the value of watermark. - * - At the same time, change the watermark on the master lcore. - * - The slave lcore will check that watermark changes from 16 to 32. - * - * #. Performance tests. - * - * Tests done in test_ring_perf.c - */ - -#define RING_SIZE 4096 -#define MAX_BULK 32 - -static rte_atomic32_t synchro; - -static struct rte_ring *r; - -#define TEST_RING_VERIFY(exp) \ - if (!(exp)) { \ - printf("error at %s:%d\tcondition " #exp " failed\n", \ - __func__, __LINE__); \ - rte_ring_dump(stdout, r); \ - return -1; \ - } - -#define TEST_RING_FULL_EMTPY_ITER 8 - -static int -check_live_watermark_change(__attribute__((unused)) void *dummy) -{ - uint64_t hz = rte_get_timer_hz(); - void *obj_table[MAX_BULK]; - unsigned watermark, watermark_old = 16; - uint64_t cur_time, end_time; - int64_t diff = 0; - int i, ret; - unsigned count = 4; - - /* init the object table */ - memset(obj_table, 0, sizeof(obj_table)); - end_time = rte_get_timer_cycles() + (hz / 4); - - /* check that bulk and watermark are 4 and 32 (respectively) */ - while (diff >= 0) { - - /* add in ring until we reach watermark */ - ret = 0; - for (i = 0; i < 16; i ++) { - if (ret != 0) - break; - ret = rte_ring_enqueue_bulk(r, obj_table, count); - } - - if (ret != -EDQUOT) { - printf("Cannot enqueue objects, or watermark not " - "reached (ret=%d)\n", ret); - return -1; - } - - /* read watermark, the only change allowed is from 16 to 32 */ - watermark = r->prod.watermark; - if (watermark != watermark_old && - (watermark_old != 16 || watermark != 32)) { - printf("Bad watermark change %u -> %u\n", watermark_old, - watermark); - return -1; - } - watermark_old = watermark; - - /* dequeue objects from ring */ - while (i--) { - ret = rte_ring_dequeue_bulk(r, obj_table, count); - if (ret != 0) { - printf("Cannot dequeue (ret=%d)\n", ret); - return -1; - } - } - - cur_time = rte_get_timer_cycles(); - diff = end_time - cur_time; - } - - if (watermark_old != 32 ) { - printf(" watermark was not updated (wm=%u)\n", - watermark_old); - return -1; - } - - return 0; -} - -static int -test_live_watermark_change(void) -{ - unsigned lcore_id = rte_lcore_id(); - unsigned lcore_id2 = rte_get_next_lcore(lcore_id, 0, 1); - - printf("Test watermark live modification\n"); - rte_ring_set_water_mark(r, 16); - - /* launch a thread that will enqueue and dequeue, checking - * watermark and quota */ - rte_eal_remote_launch(check_live_watermark_change, NULL, lcore_id2); - - rte_delay_ms(100); - rte_ring_set_water_mark(r, 32); - rte_delay_ms(100); - - if (rte_eal_wait_lcore(lcore_id2) < 0) - return -1; - - return 0; -} - -/* Test for catch on invalid watermark values */ -static int -test_set_watermark( void ){ - unsigned count; - int setwm; - - struct rte_ring *r = rte_ring_lookup("test_ring_basic_ex"); - if(r == NULL){ - printf( " ring lookup failed\n" ); - goto error; - } - count = r->prod.size*2; - setwm = rte_ring_set_water_mark(r, count); - if (setwm != -EINVAL){ - printf("Test failed to detect invalid watermark count value\n"); - goto error; - } - - count = 0; - rte_ring_set_water_mark(r, count); - if (r->prod.watermark != r->prod.size) { - printf("Test failed to detect invalid watermark count value\n"); - goto error; - } - return 0; - -error: - return -1; -} - -/* - * helper routine for test_ring_basic - */ -static int -test_ring_basic_full_empty(void * const src[], void *dst[]) -{ - unsigned i, rand; - const unsigned rsz = RING_SIZE - 1; - - printf("Basic full/empty test\n"); - - for (i = 0; TEST_RING_FULL_EMTPY_ITER != i; i++) { - - /* random shift in the ring */ - rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL); - printf("%s: iteration %u, random shift: %u;\n", - __func__, i, rand); - TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src, - rand)); - TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rand)); - - /* fill the ring */ - TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src, - rsz)); - TEST_RING_VERIFY(0 == rte_ring_free_count(r)); - TEST_RING_VERIFY(rsz == rte_ring_count(r)); - TEST_RING_VERIFY(rte_ring_full(r)); - TEST_RING_VERIFY(0 == rte_ring_empty(r)); - - /* empty the ring */ - TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rsz)); - TEST_RING_VERIFY(rsz == rte_ring_free_count(r)); - TEST_RING_VERIFY(0 == rte_ring_count(r)); - TEST_RING_VERIFY(0 == rte_ring_full(r)); - TEST_RING_VERIFY(rte_ring_empty(r)); - - /* check data */ - TEST_RING_VERIFY(0 == memcmp(src, dst, rsz)); - rte_ring_dump(stdout, r); - } - return 0; -} - -static int -test_ring_basic(void) -{ - void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL; - int ret; - unsigned i, num_elems; - - /* alloc dummy object pointers */ - src = malloc(RING_SIZE*2*sizeof(void *)); - if (src == NULL) - goto fail; - - for (i = 0; i < RING_SIZE*2 ; i++) { - src[i] = (void *)(unsigned long)i; - } - cur_src = src; - - /* alloc some room for copied objects */ - dst = malloc(RING_SIZE*2*sizeof(void *)); - if (dst == NULL) - goto fail; - - memset(dst, 0, RING_SIZE*2*sizeof(void *)); - cur_dst = dst; - - printf("enqueue 1 obj\n"); - ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1); - cur_src += 1; - if (ret != 0) - goto fail; - - printf("enqueue 2 objs\n"); - ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2); - cur_src += 2; - if (ret != 0) - goto fail; - - printf("enqueue MAX_BULK objs\n"); - ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK); - cur_src += MAX_BULK; - if (ret != 0) - goto fail; - - printf("dequeue 1 obj\n"); - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1); - cur_dst += 1; - if (ret != 0) - goto fail; - - printf("dequeue 2 objs\n"); - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2); - cur_dst += 2; - if (ret != 0) - goto fail; - - printf("dequeue MAX_BULK objs\n"); - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK); - cur_dst += MAX_BULK; - if (ret != 0) - goto fail; - - /* check data */ - if (memcmp(src, dst, cur_dst - dst)) { - rte_hexdump(stdout, "src", src, cur_src - src); - rte_hexdump(stdout, "dst", dst, cur_dst - dst); - printf("data after dequeue is not the same\n"); - goto fail; - } - cur_src = src; - cur_dst = dst; - - printf("enqueue 1 obj\n"); - ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1); - cur_src += 1; - if (ret != 0) - goto fail; - - printf("enqueue 2 objs\n"); - ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2); - cur_src += 2; - if (ret != 0) - goto fail; - - printf("enqueue MAX_BULK objs\n"); - ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK); - cur_src += MAX_BULK; - if (ret != 0) - goto fail; - - printf("dequeue 1 obj\n"); - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1); - cur_dst += 1; - if (ret != 0) - goto fail; - - printf("dequeue 2 objs\n"); - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2); - cur_dst += 2; - if (ret != 0) - goto fail; - - printf("dequeue MAX_BULK objs\n"); - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK); - cur_dst += MAX_BULK; - if (ret != 0) - goto fail; - - /* check data */ - if (memcmp(src, dst, cur_dst - dst)) { - rte_hexdump(stdout, "src", src, cur_src - src); - rte_hexdump(stdout, "dst", dst, cur_dst - dst); - printf("data after dequeue is not the same\n"); - goto fail; - } - cur_src = src; - cur_dst = dst; - - printf("fill and empty the ring\n"); - for (i = 0; istats[lcore_id]; - - printf("Test the ring stats.\n"); - - /* Reset the watermark in case it was set in another test. */ - rte_ring_set_water_mark(r, 0); - - /* Reset the ring stats. */ - memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id])); - - /* Allocate some dummy object pointers. */ - src = malloc(RING_SIZE*2*sizeof(void *)); - if (src == NULL) - goto fail; - - for (i = 0; i < RING_SIZE*2 ; i++) { - src[i] = (void *)(unsigned long)i; - } - - /* Allocate some memory for copied objects. */ - dst = malloc(RING_SIZE*2*sizeof(void *)); - if (dst == NULL) - goto fail; - - memset(dst, 0, RING_SIZE*2*sizeof(void *)); - - /* Set the head and tail pointers. */ - cur_src = src; - cur_dst = dst; - - /* Do Enqueue tests. */ - printf("Test the dequeue stats.\n"); - - /* Fill the ring up to RING_SIZE -1. */ - printf("Fill the ring.\n"); - for (i = 0; i< (RING_SIZE/MAX_BULK); i++) { - rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK); - cur_src += MAX_BULK; - } - - /* Adjust for final enqueue = MAX_BULK -1. */ - cur_src--; - - printf("Verify that the ring is full.\n"); - if (rte_ring_full(r) != 1) - goto fail; - - - printf("Verify the enqueue success stats.\n"); - /* Stats should match above enqueue operations to fill the ring. */ - if (ring_stats->enq_success_bulk != (RING_SIZE/MAX_BULK)) - goto fail; - - /* Current max objects is RING_SIZE -1. */ - if (ring_stats->enq_success_objs != RING_SIZE -1) - goto fail; - - /* Shouldn't have any failures yet. */ - if (ring_stats->enq_fail_bulk != 0) - goto fail; - if (ring_stats->enq_fail_objs != 0) - goto fail; - - - printf("Test stats for SP burst enqueue to a full ring.\n"); - num_items = 2; - ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items); - if ((ret & RTE_RING_SZ_MASK) != 0) - goto fail; - - failed_enqueue_ops += 1; - failed_enqueue_items += num_items; - - /* The enqueue should have failed. */ - if (ring_stats->enq_fail_bulk != failed_enqueue_ops) - goto fail; - if (ring_stats->enq_fail_objs != failed_enqueue_items) - goto fail; - - - printf("Test stats for SP bulk enqueue to a full ring.\n"); - num_items = 4; - ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items); - if (ret != -ENOBUFS) - goto fail; - - failed_enqueue_ops += 1; - failed_enqueue_items += num_items; - - /* The enqueue should have failed. */ - if (ring_stats->enq_fail_bulk != failed_enqueue_ops) - goto fail; - if (ring_stats->enq_fail_objs != failed_enqueue_items) - goto fail; - - - printf("Test stats for MP burst enqueue to a full ring.\n"); - num_items = 8; - ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items); - if ((ret & RTE_RING_SZ_MASK) != 0) - goto fail; - - failed_enqueue_ops += 1; - failed_enqueue_items += num_items; - - /* The enqueue should have failed. */ - if (ring_stats->enq_fail_bulk != failed_enqueue_ops) - goto fail; - if (ring_stats->enq_fail_objs != failed_enqueue_items) - goto fail; - - - printf("Test stats for MP bulk enqueue to a full ring.\n"); - num_items = 16; - ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items); - if (ret != -ENOBUFS) - goto fail; - - failed_enqueue_ops += 1; - failed_enqueue_items += num_items; - - /* The enqueue should have failed. */ - if (ring_stats->enq_fail_bulk != failed_enqueue_ops) - goto fail; - if (ring_stats->enq_fail_objs != failed_enqueue_items) - goto fail; - - - /* Do Dequeue tests. */ - printf("Test the dequeue stats.\n"); - - printf("Empty the ring.\n"); - for (i = 0; ideq_success_bulk != (RING_SIZE/MAX_BULK)) - goto fail; - - /* Objects dequeued is RING_SIZE -1. */ - if (ring_stats->deq_success_objs != RING_SIZE -1) - goto fail; - - /* Shouldn't have any dequeue failure stats yet. */ - if (ring_stats->deq_fail_bulk != 0) - goto fail; - - printf("Test stats for SC burst dequeue with an empty ring.\n"); - num_items = 2; - ret = rte_ring_sc_dequeue_burst(r, cur_dst, num_items); - if ((ret & RTE_RING_SZ_MASK) != 0) - goto fail; - - failed_dequeue_ops += 1; - failed_dequeue_items += num_items; - - /* The dequeue should have failed. */ - if (ring_stats->deq_fail_bulk != failed_dequeue_ops) - goto fail; - if (ring_stats->deq_fail_objs != failed_dequeue_items) - goto fail; - - - printf("Test stats for SC bulk dequeue with an empty ring.\n"); - num_items = 4; - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, num_items); - if (ret != -ENOENT) - goto fail; - - failed_dequeue_ops += 1; - failed_dequeue_items += num_items; - - /* The dequeue should have failed. */ - if (ring_stats->deq_fail_bulk != failed_dequeue_ops) - goto fail; - if (ring_stats->deq_fail_objs != failed_dequeue_items) - goto fail; - - - printf("Test stats for MC burst dequeue with an empty ring.\n"); - num_items = 8; - ret = rte_ring_mc_dequeue_burst(r, cur_dst, num_items); - if ((ret & RTE_RING_SZ_MASK) != 0) - goto fail; - failed_dequeue_ops += 1; - failed_dequeue_items += num_items; - - /* The dequeue should have failed. */ - if (ring_stats->deq_fail_bulk != failed_dequeue_ops) - goto fail; - if (ring_stats->deq_fail_objs != failed_dequeue_items) - goto fail; - - - printf("Test stats for MC bulk dequeue with an empty ring.\n"); - num_items = 16; - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, num_items); - if (ret != -ENOENT) - goto fail; - - failed_dequeue_ops += 1; - failed_dequeue_items += num_items; - - /* The dequeue should have failed. */ - if (ring_stats->deq_fail_bulk != failed_dequeue_ops) - goto fail; - if (ring_stats->deq_fail_objs != failed_dequeue_items) - goto fail; - - - printf("Test total enqueue/dequeue stats.\n"); - /* At this point the enqueue and dequeue stats should be the same. */ - if (ring_stats->enq_success_bulk != ring_stats->deq_success_bulk) - goto fail; - if (ring_stats->enq_success_objs != ring_stats->deq_success_objs) - goto fail; - if (ring_stats->enq_fail_bulk != ring_stats->deq_fail_bulk) - goto fail; - if (ring_stats->enq_fail_objs != ring_stats->deq_fail_objs) - goto fail; - - - /* Watermark Tests. */ - printf("Test the watermark/quota stats.\n"); - - printf("Verify the initial watermark stats.\n"); - /* Watermark stats should be 0 since there is no watermark. */ - if (ring_stats->enq_quota_bulk != 0) - goto fail; - if (ring_stats->enq_quota_objs != 0) - goto fail; - - /* Set a watermark. */ - rte_ring_set_water_mark(r, 16); - - /* Reset pointers. */ - cur_src = src; - cur_dst = dst; - - last_enqueue_ops = ring_stats->enq_success_bulk; - last_enqueue_items = ring_stats->enq_success_objs; - - - printf("Test stats for SP burst enqueue below watermark.\n"); - num_items = 8; - ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items); - if ((ret & RTE_RING_SZ_MASK) != num_items) - goto fail; - - /* Watermark stats should still be 0. */ - if (ring_stats->enq_quota_bulk != 0) - goto fail; - if (ring_stats->enq_quota_objs != 0) - goto fail; - - /* Success stats should have increased. */ - if (ring_stats->enq_success_bulk != last_enqueue_ops + 1) - goto fail; - if (ring_stats->enq_success_objs != last_enqueue_items + num_items) - goto fail; - - last_enqueue_ops = ring_stats->enq_success_bulk; - last_enqueue_items = ring_stats->enq_success_objs; - - - printf("Test stats for SP burst enqueue at watermark.\n"); - num_items = 8; - ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items); - if ((ret & RTE_RING_SZ_MASK) != num_items) - goto fail; - - /* Watermark stats should have changed. */ - if (ring_stats->enq_quota_bulk != 1) - goto fail; - if (ring_stats->enq_quota_objs != num_items) - goto fail; - - last_quota_ops = ring_stats->enq_quota_bulk; - last_quota_items = ring_stats->enq_quota_objs; - - - printf("Test stats for SP burst enqueue above watermark.\n"); - num_items = 1; - ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items); - if ((ret & RTE_RING_SZ_MASK) != num_items) - goto fail; - - /* Watermark stats should have changed. */ - if (ring_stats->enq_quota_bulk != last_quota_ops +1) - goto fail; - if (ring_stats->enq_quota_objs != last_quota_items + num_items) - goto fail; - - last_quota_ops = ring_stats->enq_quota_bulk; - last_quota_items = ring_stats->enq_quota_objs; - - - printf("Test stats for MP burst enqueue above watermark.\n"); - num_items = 2; - ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items); - if ((ret & RTE_RING_SZ_MASK) != num_items) - goto fail; - - /* Watermark stats should have changed. */ - if (ring_stats->enq_quota_bulk != last_quota_ops +1) - goto fail; - if (ring_stats->enq_quota_objs != last_quota_items + num_items) - goto fail; - - last_quota_ops = ring_stats->enq_quota_bulk; - last_quota_items = ring_stats->enq_quota_objs; - - - printf("Test stats for SP bulk enqueue above watermark.\n"); - num_items = 4; - ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items); - if (ret != -EDQUOT) - goto fail; - - /* Watermark stats should have changed. */ - if (ring_stats->enq_quota_bulk != last_quota_ops +1) - goto fail; - if (ring_stats->enq_quota_objs != last_quota_items + num_items) - goto fail; - - last_quota_ops = ring_stats->enq_quota_bulk; - last_quota_items = ring_stats->enq_quota_objs; - - - printf("Test stats for MP bulk enqueue above watermark.\n"); - num_items = 8; - ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items); - if (ret != -EDQUOT) - goto fail; - - /* Watermark stats should have changed. */ - if (ring_stats->enq_quota_bulk != last_quota_ops +1) - goto fail; - if (ring_stats->enq_quota_objs != last_quota_items + num_items) - goto fail; - - printf("Test watermark success stats.\n"); - /* Success stats should be same as last non-watermarked enqueue. */ - if (ring_stats->enq_success_bulk != last_enqueue_ops) - goto fail; - if (ring_stats->enq_success_objs != last_enqueue_items) - goto fail; - - - /* Cleanup. */ - - /* Empty the ring. */ - for (i = 0; istats[lcore_id], 0, sizeof(r->stats[lcore_id])); - - /* Free memory before test completed */ - free(src); - free(dst); - return 0; - -fail: - free(src); - free(dst); - return -1; -#endif -} - -/* - * it will always fail to create ring with a wrong ring size number in this function - */ -static int -test_ring_creation_with_wrong_size(void) -{ - struct rte_ring * rp = NULL; - - /* Test if ring size is not power of 2 */ - rp = rte_ring_create("test_bad_ring_size", RING_SIZE + 1, SOCKET_ID_ANY, 0); - if (NULL != rp) { - return -1; - } - - /* Test if ring size is exceeding the limit */ - rp = rte_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), SOCKET_ID_ANY, 0); - if (NULL != rp) { - return -1; - } - return 0; -} - -/* - * it tests if it would always fail to create ring with an used ring name - */ -static int -test_ring_creation_with_an_used_name(void) -{ - struct rte_ring * rp; - - rp = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0); - if (NULL != rp) - return -1; - - return 0; -} - -/* - * Test to if a non-power of 2 count causes the create - * function to fail correctly - */ -static int -test_create_count_odd(void) -{ - struct rte_ring *r = rte_ring_create("test_ring_count", - 4097, SOCKET_ID_ANY, 0 ); - if(r != NULL){ - return -1; - } - return 0; -} - -static int -test_lookup_null(void) -{ - struct rte_ring *rlp = rte_ring_lookup("ring_not_found"); - if (rlp ==NULL) - if (rte_errno != ENOENT){ - printf( "test failed to returnn error on null pointer\n"); - return -1; - } - return 0; -} - -/* - * it tests some more basic ring operations - */ -static int -test_ring_basic_ex(void) -{ - int ret = -1; - unsigned i; - struct rte_ring * rp; - void **obj = NULL; - - obj = rte_calloc("test_ring_basic_ex_malloc", RING_SIZE, sizeof(void *), 0); - if (obj == NULL) { - printf("test_ring_basic_ex fail to rte_malloc\n"); - goto fail_test; - } - - rp = rte_ring_create("test_ring_basic_ex", RING_SIZE, SOCKET_ID_ANY, - RING_F_SP_ENQ | RING_F_SC_DEQ); - if (rp == NULL) { - printf("test_ring_basic_ex fail to create ring\n"); - goto fail_test; - } - - if (rte_ring_lookup("test_ring_basic_ex") != rp) { - goto fail_test; - } - - if (rte_ring_empty(rp) != 1) { - printf("test_ring_basic_ex ring is not empty but it should be\n"); - goto fail_test; - } - - printf("%u ring entries are now free\n", rte_ring_free_count(rp)); - - for (i = 0; i < RING_SIZE; i ++) { - rte_ring_enqueue(rp, obj[i]); - } - - if (rte_ring_full(rp) != 1) { - printf("test_ring_basic_ex ring is not full but it should be\n"); - goto fail_test; - } - - for (i = 0; i < RING_SIZE; i ++) { - rte_ring_dequeue(rp, &obj[i]); - } - - if (rte_ring_empty(rp) != 1) { - printf("test_ring_basic_ex ring is not empty but it should be\n"); - goto fail_test; - } - - /* Covering the ring burst operation */ - ret = rte_ring_enqueue_burst(rp, obj, 2); - if ((ret & RTE_RING_SZ_MASK) != 2) { - printf("test_ring_basic_ex: rte_ring_enqueue_burst fails \n"); - goto fail_test; - } - - ret = rte_ring_dequeue_burst(rp, obj, 2); - if (ret != 2) { - printf("test_ring_basic_ex: rte_ring_dequeue_burst fails \n"); - goto fail_test; - } - - ret = 0; -fail_test: - if (obj != NULL) - rte_free(obj); - - return ret; -} - -static int -test_ring(void) -{ - /* some more basic operations */ - if (test_ring_basic_ex() < 0) - return -1; - - rte_atomic32_init(&synchro); - - if (r == NULL) - r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0); - if (r == NULL) - return -1; - - /* retrieve the ring from its name */ - if (rte_ring_lookup("test") != r) { - printf("Cannot lookup ring from its name\n"); - return -1; - } - - /* burst operations */ - if (test_ring_burst_basic() < 0) - return -1; - - /* basic operations */ - if (test_ring_basic() < 0) - return -1; - - /* ring stats */ - if (test_ring_stats() < 0) - return -1; - - /* basic operations */ - if (test_live_watermark_change() < 0) - return -1; - - if ( test_set_watermark() < 0){ - printf ("Test failed to detect invalid parameter\n"); - return -1; - } - else - printf ( "Test detected forced bad watermark values\n"); - - if ( test_create_count_odd() < 0){ - printf ("Test failed to detect odd count\n"); - return -1; - } - else - printf ( "Test detected odd count\n"); - - if ( test_lookup_null() < 0){ - printf ("Test failed to detect NULL ring lookup\n"); - return -1; - } - else - printf ( "Test detected NULL ring lookup \n"); - - /* test of creating ring with wrong size */ - if (test_ring_creation_with_wrong_size() < 0) - return -1; - - /* test of creation ring with an used name */ - if (test_ring_creation_with_an_used_name() < 0) - return -1; - - /* dump the ring status */ - rte_ring_list_dump(stdout); - - return 0; -} - -REGISTER_TEST_COMMAND(ring_autotest, test_ring); diff --git a/app/test/test_ring_perf.c b/app/test/test_ring_perf.c deleted file mode 100644 index 320c20cd2c..0000000000 --- a/app/test/test_ring_perf.c +++ /dev/null @@ -1,417 +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 -#include -#include -#include -#include - -#include "test.h" - -/* - * Ring - * ==== - * - * Measures performance of various operations using rdtsc - * * Empty ring dequeue - * * Enqueue/dequeue of bursts in 1 threads - * * Enqueue/dequeue of bursts in 2 threads - */ - -#define RING_NAME "RING_PERF" -#define RING_SIZE 4096 -#define MAX_BURST 32 - -/* - * the sizes to enqueue and dequeue in testing - * (marked volatile so they won't be seen as compile-time constants) - */ -static const volatile unsigned bulk_sizes[] = { 8, 32 }; - -/* The ring structure used for tests */ -static struct rte_ring *r; - -struct lcore_pair { - unsigned c1, c2; -}; - -static volatile unsigned lcore_count = 0; - -/**** Functions to analyse our core mask to get cores for different tests ***/ - -static int -get_two_hyperthreads(struct lcore_pair *lcp) -{ - unsigned id1, id2; - unsigned c1, c2, s1, s2; - RTE_LCORE_FOREACH(id1) { - /* inner loop just re-reads all id's. We could skip the first few - * elements, but since number of cores is small there is little point - */ - RTE_LCORE_FOREACH(id2) { - if (id1 == id2) - continue; - c1 = lcore_config[id1].core_id; - c2 = lcore_config[id2].core_id; - s1 = lcore_config[id1].socket_id; - s2 = lcore_config[id2].socket_id; - if ((c1 == c2) && (s1 == s2)){ - lcp->c1 = id1; - lcp->c2 = id2; - return 0; - } - } - } - return 1; -} - -static int -get_two_cores(struct lcore_pair *lcp) -{ - unsigned id1, id2; - unsigned c1, c2, s1, s2; - RTE_LCORE_FOREACH(id1) { - RTE_LCORE_FOREACH(id2) { - if (id1 == id2) - continue; - c1 = lcore_config[id1].core_id; - c2 = lcore_config[id2].core_id; - s1 = lcore_config[id1].socket_id; - s2 = lcore_config[id2].socket_id; - if ((c1 != c2) && (s1 == s2)){ - lcp->c1 = id1; - lcp->c2 = id2; - return 0; - } - } - } - return 1; -} - -static int -get_two_sockets(struct lcore_pair *lcp) -{ - unsigned id1, id2; - unsigned s1, s2; - RTE_LCORE_FOREACH(id1) { - RTE_LCORE_FOREACH(id2) { - if (id1 == id2) - continue; - s1 = lcore_config[id1].socket_id; - s2 = lcore_config[id2].socket_id; - if (s1 != s2){ - lcp->c1 = id1; - lcp->c2 = id2; - return 0; - } - } - } - return 1; -} - -/* Get cycle counts for dequeuing from an empty ring. Should be 2 or 3 cycles */ -static void -test_empty_dequeue(void) -{ - const unsigned iter_shift = 26; - const unsigned iterations = 1<size; - unsigned i; - void *burst[MAX_BURST] = {0}; - - if ( __sync_add_and_fetch(&lcore_count, 1) != 2 ) - while(lcore_count != 2) - rte_pause(); - - const uint64_t sp_start = rte_rdtsc(); - for (i = 0; i < iterations; i++) - while (rte_ring_sp_enqueue_bulk(r, burst, size) != 0) - rte_pause(); - const uint64_t sp_end = rte_rdtsc(); - - const uint64_t mp_start = rte_rdtsc(); - for (i = 0; i < iterations; i++) - while (rte_ring_mp_enqueue_bulk(r, burst, size) != 0) - rte_pause(); - const uint64_t mp_end = rte_rdtsc(); - - params->spsc = ((double)(sp_end - sp_start))/(iterations*size); - params->mpmc = ((double)(mp_end - mp_start))/(iterations*size); - return 0; -} - -/* - * Function that uses rdtsc to measure timing for ring dequeue. Needs pair - * thread running enqueue_bulk function - */ -static int -dequeue_bulk(void *p) -{ - const unsigned iter_shift = 23; - const unsigned iterations = 1<size; - unsigned i; - void *burst[MAX_BURST] = {0}; - - if ( __sync_add_and_fetch(&lcore_count, 1) != 2 ) - while(lcore_count != 2) - rte_pause(); - - const uint64_t sc_start = rte_rdtsc(); - for (i = 0; i < iterations; i++) - while (rte_ring_sc_dequeue_bulk(r, burst, size) != 0) - rte_pause(); - const uint64_t sc_end = rte_rdtsc(); - - const uint64_t mc_start = rte_rdtsc(); - for (i = 0; i < iterations; i++) - while (rte_ring_mc_dequeue_bulk(r, burst, size) != 0) - rte_pause(); - const uint64_t mc_end = rte_rdtsc(); - - params->spsc = ((double)(sc_end - sc_start))/(iterations*size); - params->mpmc = ((double)(mc_end - mc_start))/(iterations*size); - return 0; -} - -/* - * Function that calls the enqueue and dequeue bulk functions on pairs of cores. - * used to measure ring perf between hyperthreads, cores and sockets. - */ -static void -run_on_core_pair(struct lcore_pair *cores, - lcore_function_t f1, lcore_function_t f2) -{ - struct thread_params param1 = {0}, param2 = {0}; - unsigned i; - for (i = 0; i < sizeof(bulk_sizes)/sizeof(bulk_sizes[0]); i++) { - lcore_count = 0; - param1.size = param2.size = bulk_sizes[i]; - if (cores->c1 == rte_get_master_lcore()) { - rte_eal_remote_launch(f2, ¶m2, cores->c2); - f1(¶m1); - rte_eal_wait_lcore(cores->c2); - } else { - rte_eal_remote_launch(f1, ¶m1, cores->c1); - rte_eal_remote_launch(f2, ¶m2, cores->c2); - rte_eal_wait_lcore(cores->c1); - rte_eal_wait_lcore(cores->c2); - } - printf("SP/SC bulk enq/dequeue (size: %u): %.2F\n", bulk_sizes[i], - param1.spsc + param2.spsc); - printf("MP/MC bulk enq/dequeue (size: %u): %.2F\n", bulk_sizes[i], - param1.mpmc + param2.mpmc); - } -} - -/* - * Test function that determines how long an enqueue + dequeue of a single item - * takes on a single lcore. Result is for comparison with the bulk enq+deq. - */ -static void -test_single_enqueue_dequeue(void) -{ - const unsigned iter_shift = 24; - const unsigned iterations = 1<> iter_shift); - printf("MP/MC single enq/dequeue: %"PRIu64"\n", - (mc_end-mc_start) >> iter_shift); -} - -/* - * Test that does both enqueue and dequeue on a core using the burst() API calls - * instead of the bulk() calls used in other tests. Results should be the same - * as for the bulk function called on a single lcore. - */ -static void -test_burst_enqueue_dequeue(void) -{ - const unsigned iter_shift = 23; - const unsigned iterations = 1<> iter_shift) / bulk_sizes[sz]; - uint64_t sc_avg = ((sc_end-sc_start) >> iter_shift) / bulk_sizes[sz]; - - printf("SP/SC burst enq/dequeue (size: %u): %"PRIu64"\n", bulk_sizes[sz], - sc_avg); - printf("MP/MC burst enq/dequeue (size: %u): %"PRIu64"\n", bulk_sizes[sz], - mc_avg); - } -} - -/* Times enqueue and dequeue on a single lcore */ -static void -test_bulk_enqueue_dequeue(void) -{ - const unsigned iter_shift = 23; - const unsigned iterations = 1< -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * rwlock test - * =========== - * - * - There is a global rwlock and a table of rwlocks (one per lcore). - * - * - The test function takes all of these locks and launches the - * ``test_rwlock_per_core()`` function on each core (except the master). - * - * - The function takes the global write lock, display something, - * then releases the global lock. - * - Then, it takes the per-lcore write lock, display something, and - * releases the per-core lock. - * - Finally, a read lock is taken during 100 ms, then released. - * - * - The main function unlocks the per-lcore locks sequentially and - * waits between each lock. This triggers the display of a message - * for each core, in the correct order. - * - * Then, it tries to take the global write lock and display the last - * message. The autotest script checks that the message order is correct. - */ - -static rte_rwlock_t sl; -static rte_rwlock_t sl_tab[RTE_MAX_LCORE]; - -static int -test_rwlock_per_core(__attribute__((unused)) void *arg) -{ - rte_rwlock_write_lock(&sl); - printf("Global write lock taken on core %u\n", rte_lcore_id()); - rte_rwlock_write_unlock(&sl); - - rte_rwlock_write_lock(&sl_tab[rte_lcore_id()]); - printf("Hello from core %u !\n", rte_lcore_id()); - rte_rwlock_write_unlock(&sl_tab[rte_lcore_id()]); - - rte_rwlock_read_lock(&sl); - printf("Global read lock taken on core %u\n", rte_lcore_id()); - rte_delay_ms(100); - printf("Release global read lock on core %u\n", rte_lcore_id()); - rte_rwlock_read_unlock(&sl); - - return 0; -} - -static int -test_rwlock(void) -{ - int i; - - rte_rwlock_init(&sl); - for (i=0; i -#include -#include -#include -#include - -#include "test.h" - -#include -#include -#include -#include -#include - - -#define SUBPORT 0 -#define PIPE 1 -#define TC 2 -#define QUEUE 3 - -static struct rte_sched_subport_params subport_param[] = { - { - .tb_rate = 1250000000, - .tb_size = 1000000, - - .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000}, - .tc_period = 10, - }, -}; - -static struct rte_sched_pipe_params pipe_profile[] = { - { /* Profile #0 */ - .tb_rate = 305175, - .tb_size = 1000000, - - .tc_rate = {305175, 305175, 305175, 305175}, - .tc_period = 40, - - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - }, -}; - -static struct rte_sched_port_params port_param = { - .socket = 0, /* computed */ - .rate = 0, /* computed */ - .mtu = 1522, - .frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT, - .n_subports_per_port = 1, - .n_pipes_per_subport = 1024, - .qsize = {32, 32, 32, 32}, - .pipe_profiles = pipe_profile, - .n_pipe_profiles = 1, -}; - -#define NB_MBUF 32 -#define MBUF_DATA_SZ (2048 + RTE_PKTMBUF_HEADROOM) -#define MEMPOOL_CACHE_SZ 0 -#define SOCKET 0 - - -static struct rte_mempool * -create_mempool(void) -{ - struct rte_mempool * mp; - - mp = rte_mempool_lookup("test_sched"); - if (!mp) - mp = rte_pktmbuf_pool_create("test_sched", NB_MBUF, - MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, SOCKET); - - return mp; -} - -static void -prepare_pkt(struct rte_mbuf *mbuf) -{ - struct ether_hdr *eth_hdr; - struct vlan_hdr *vlan1, *vlan2; - struct ipv4_hdr *ip_hdr; - - /* Simulate a classifier */ - eth_hdr = rte_pktmbuf_mtod(mbuf, struct ether_hdr *); - vlan1 = (struct vlan_hdr *)(ð_hdr->ether_type ); - vlan2 = (struct vlan_hdr *)((uintptr_t)ð_hdr->ether_type + sizeof(struct vlan_hdr)); - eth_hdr = (struct ether_hdr *)((uintptr_t)ð_hdr->ether_type + 2 *sizeof(struct vlan_hdr)); - ip_hdr = (struct ipv4_hdr *)((uintptr_t)eth_hdr + sizeof(eth_hdr->ether_type)); - - vlan1->vlan_tci = rte_cpu_to_be_16(SUBPORT); - vlan2->vlan_tci = rte_cpu_to_be_16(PIPE); - eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4); - ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE); - - - rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW); - - /* 64 byte packet */ - mbuf->pkt_len = 60; - mbuf->data_len = 60; -} - - -/** - * test main entrance for library sched - */ -static int -test_sched(void) -{ - struct rte_mempool *mp = NULL; - struct rte_sched_port *port = NULL; - uint32_t pipe; - struct rte_mbuf *in_mbufs[10]; - struct rte_mbuf *out_mbufs[10]; - int i; - - int err; - - mp = create_mempool(); - TEST_ASSERT_NOT_NULL(mp, "Error creating mempool\n"); - - port_param.socket = 0; - port_param.rate = (uint64_t) 10000 * 1000 * 1000 / 8; - - port = rte_sched_port_config(&port_param); - TEST_ASSERT_NOT_NULL(port, "Error config sched port\n"); - - err = rte_sched_subport_config(port, SUBPORT, subport_param); - TEST_ASSERT_SUCCESS(err, "Error config sched, err=%d\n", err); - - for (pipe = 0; pipe < port_param.n_pipes_per_subport; pipe ++) { - err = rte_sched_pipe_config(port, SUBPORT, pipe, 0); - TEST_ASSERT_SUCCESS(err, "Error config sched pipe %u, err=%d\n", pipe, err); - } - - for (i = 0; i < 10; i++) { - in_mbufs[i] = rte_pktmbuf_alloc(mp); - TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n"); - prepare_pkt(in_mbufs[i]); - } - - - err = rte_sched_port_enqueue(port, in_mbufs, 10); - TEST_ASSERT_EQUAL(err, 10, "Wrong enqueue, err=%d\n", err); - - err = rte_sched_port_dequeue(port, out_mbufs, 10); - TEST_ASSERT_EQUAL(err, 10, "Wrong dequeue, err=%d\n", err); - - for (i = 0; i < 10; i++) { - enum rte_meter_color color; - uint32_t subport, traffic_class, queue; - - color = rte_sched_port_pkt_read_color(out_mbufs[i]); - TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n"); - - rte_sched_port_pkt_read_tree_path(out_mbufs[i], - &subport, &pipe, &traffic_class, &queue); - - TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n"); - TEST_ASSERT_EQUAL(pipe, PIPE, "Wrong pipe\n"); - TEST_ASSERT_EQUAL(traffic_class, TC, "Wrong traffic_class\n"); - TEST_ASSERT_EQUAL(queue, QUEUE, "Wrong queue\n"); - - } - - - struct rte_sched_subport_stats subport_stats; - uint32_t tc_ov; - rte_sched_subport_read_stats(port, SUBPORT, &subport_stats, &tc_ov); -#if 0 - TEST_ASSERT_EQUAL(subport_stats.n_pkts_tc[TC-1], 10, "Wrong subport stats\n"); -#endif - struct rte_sched_queue_stats queue_stats; - uint16_t qlen; - rte_sched_queue_read_stats(port, QUEUE, &queue_stats, &qlen); -#if 0 - TEST_ASSERT_EQUAL(queue_stats.n_pkts, 10, "Wrong queue stats\n"); -#endif - - rte_sched_port_free(port); - - return 0; -} - -REGISTER_TEST_COMMAND(sched_autotest, test_sched); diff --git a/app/test/test_spinlock.c b/app/test/test_spinlock.c deleted file mode 100644 index 2d94eecc21..0000000000 --- a/app/test/test_spinlock.c +++ /dev/null @@ -1,336 +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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * Spinlock test - * ============= - * - * - There is a global spinlock and a table of spinlocks (one per lcore). - * - * - The test function takes all of these locks and launches the - * ``test_spinlock_per_core()`` function on each core (except the master). - * - * - The function takes the global lock, display something, then releases - * the global lock. - * - The function takes the per-lcore lock, display something, then releases - * the per-core lock. - * - * - The main function unlocks the per-lcore locks sequentially and - * waits between each lock. This triggers the display of a message - * for each core, in the correct order. The autotest script checks that - * this order is correct. - * - * - A load test is carried out, with all cores attempting to lock a single lock - * multiple times - */ - -static rte_spinlock_t sl, sl_try; -static rte_spinlock_t sl_tab[RTE_MAX_LCORE]; -static rte_spinlock_recursive_t slr; -static unsigned count = 0; - -static rte_atomic32_t synchro; - -static int -test_spinlock_per_core(__attribute__((unused)) void *arg) -{ - rte_spinlock_lock(&sl); - printf("Global lock taken on core %u\n", rte_lcore_id()); - rte_spinlock_unlock(&sl); - - rte_spinlock_lock(&sl_tab[rte_lcore_id()]); - printf("Hello from core %u !\n", rte_lcore_id()); - rte_spinlock_unlock(&sl_tab[rte_lcore_id()]); - - return 0; -} - -static int -test_spinlock_recursive_per_core(__attribute__((unused)) void *arg) -{ - unsigned id = rte_lcore_id(); - - rte_spinlock_recursive_lock(&slr); - printf("Global recursive lock taken on core %u - count = %d\n", - id, slr.count); - rte_spinlock_recursive_lock(&slr); - printf("Global recursive lock taken on core %u - count = %d\n", - id, slr.count); - rte_spinlock_recursive_lock(&slr); - printf("Global recursive lock taken on core %u - count = %d\n", - id, slr.count); - - printf("Hello from within recursive locks from core %u !\n", id); - - rte_spinlock_recursive_unlock(&slr); - printf("Global recursive lock released on core %u - count = %d\n", - id, slr.count); - rte_spinlock_recursive_unlock(&slr); - printf("Global recursive lock released on core %u - count = %d\n", - id, slr.count); - rte_spinlock_recursive_unlock(&slr); - printf("Global recursive lock released on core %u - count = %d\n", - id, slr.count); - - return 0; -} - -static rte_spinlock_t lk = RTE_SPINLOCK_INITIALIZER; -static uint64_t lock_count[RTE_MAX_LCORE] = {0}; - -#define TIME_MS 100 - -static int -load_loop_fn(void *func_param) -{ - uint64_t time_diff = 0, begin; - uint64_t hz = rte_get_timer_hz(); - uint64_t lcount = 0; - const int use_lock = *(int*)func_param; - const unsigned lcore = rte_lcore_id(); - - /* wait synchro for slaves */ - if (lcore != rte_get_master_lcore()) - while (rte_atomic32_read(&synchro) == 0); - - begin = rte_get_timer_cycles(); - while (time_diff < hz * TIME_MS / 1000) { - if (use_lock) - rte_spinlock_lock(&lk); - lcount++; - if (use_lock) - rte_spinlock_unlock(&lk); - /* delay to make lock duty cycle slighlty realistic */ - rte_delay_us(1); - time_diff = rte_get_timer_cycles() - begin; - } - lock_count[lcore] = lcount; - return 0; -} - -static int -test_spinlock_perf(void) -{ - unsigned int i; - uint64_t total = 0; - int lock = 0; - const unsigned lcore = rte_lcore_id(); - - printf("\nTest with no lock on single core...\n"); - load_loop_fn(&lock); - printf("Core [%u] count = %"PRIu64"\n", lcore, lock_count[lcore]); - memset(lock_count, 0, sizeof(lock_count)); - - printf("\nTest with lock on single core...\n"); - lock = 1; - load_loop_fn(&lock); - printf("Core [%u] count = %"PRIu64"\n", lcore, lock_count[lcore]); - memset(lock_count, 0, sizeof(lock_count)); - - printf("\nTest with lock on %u cores...\n", rte_lcore_count()); - - /* Clear synchro and start slaves */ - rte_atomic32_set(&synchro, 0); - rte_eal_mp_remote_launch(load_loop_fn, &lock, SKIP_MASTER); - - /* start synchro and launch test on master */ - rte_atomic32_set(&synchro, 1); - load_loop_fn(&lock); - - rte_eal_mp_wait_lcore(); - - RTE_LCORE_FOREACH(i) { - printf("Core [%u] count = %"PRIu64"\n", i, lock_count[i]); - total += lock_count[i]; - } - - printf("Total count = %"PRIu64"\n", total); - - return 0; -} - -/* - * Use rte_spinlock_trylock() to trylock a spinlock object, - * If it could not lock the object sucessfully, it would - * return immediately and the variable of "count" would be - * increased by one per times. the value of "count" could be - * checked as the result later. - */ -static int -test_spinlock_try(__attribute__((unused)) void *arg) -{ - if (rte_spinlock_trylock(&sl_try) == 0) { - rte_spinlock_lock(&sl); - count ++; - rte_spinlock_unlock(&sl); - } - - return 0; -} - - -/* - * Test rte_eal_get_lcore_state() in addition to spinlocks - * as we have "waiting" then "running" lcores. - */ -static int -test_spinlock(void) -{ - int ret = 0; - int i; - - /* slave cores should be waiting: print it */ - RTE_LCORE_FOREACH_SLAVE(i) { - printf("lcore %d state: %d\n", i, - (int) rte_eal_get_lcore_state(i)); - } - - rte_spinlock_init(&sl); - rte_spinlock_init(&sl_try); - rte_spinlock_recursive_init(&slr); - for (i=0; i -#include -#include -#include -#include - -#include - -#include "test.h" - -#define LOG(...) do {\ - fprintf(stderr, "%s() ln %d: ", __func__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ -} while(0) - -#define DATA_BYTE 'a' - -static int -test_rte_strsplit(void) -{ - int i; - do { - /* ======================================================= - * split a mac address correct number of splits requested - * =======================================================*/ - char test_string[] = "54:65:76:87:98:90"; - char *splits[6]; - - LOG("Source string: '%s', to split on ':'\n", test_string); - if (rte_strsplit(test_string, sizeof(test_string), - splits, 6, ':') != 6) { - LOG("Error splitting mac address\n"); - return -1; - } - for (i = 0; i < 6; i++) - LOG("Token %d = %s\n", i + 1, splits[i]); - } while (0); - - - do { - /* ======================================================= - * split on spaces smaller number of splits requested - * =======================================================*/ - char test_string[] = "54 65 76 87 98 90"; - char *splits[6]; - - LOG("Source string: '%s', to split on ' '\n", test_string); - if (rte_strsplit(test_string, sizeof(test_string), - splits, 3, ' ') != 3) { - LOG("Error splitting mac address for max 2 splits\n"); - return -1; - } - for (i = 0; i < 3; i++) - LOG("Token %d = %s\n", i + 1, splits[i]); - } while (0); - - do { - /* ======================================================= - * split on commas - more splits than commas requested - * =======================================================*/ - char test_string[] = "a,b,c,d"; - char *splits[6]; - - LOG("Source string: '%s', to split on ','\n", test_string); - if (rte_strsplit(test_string, sizeof(test_string), - splits, 6, ',') != 4) { - LOG("Error splitting %s on ','\n", test_string); - return -1; - } - for (i = 0; i < 4; i++) - LOG("Token %d = %s\n", i + 1, splits[i]); - } while(0); - - do { - /* ======================================================= - * Try splitting on non-existent character. - * =======================================================*/ - char test_string[] = "a,b,c,d"; - char *splits[6]; - - LOG("Source string: '%s', to split on ' '\n", test_string); - if (rte_strsplit(test_string, sizeof(test_string), - splits, 6, ' ') != 1) { - LOG("Error splitting %s on ' '\n", test_string); - return -1; - } - LOG("String not split\n"); - } while(0); - - do { - /* ======================================================= - * Invalid / edge case parameter checks - * =======================================================*/ - char test_string[] = "a,b,c,d"; - char *splits[6]; - - if (rte_strsplit(NULL, 0, splits, 6, ',') >= 0 - || errno != EINVAL){ - LOG("Error: rte_strsplit accepted NULL string parameter\n"); - return -1; - } - - if (rte_strsplit(test_string, sizeof(test_string), NULL, 0, ',') >= 0 - || errno != EINVAL){ - LOG("Error: rte_strsplit accepted NULL array parameter\n"); - return -1; - } - - errno = 0; - if (rte_strsplit(test_string, 0, splits, 6, ',') != 0 || errno != 0) { - LOG("Error: rte_strsplit did not accept 0 length string\n"); - return -1; - } - - if (rte_strsplit(test_string, sizeof(test_string), splits, 0, ',') != 0 - || errno != 0) { - LOG("Error: rte_strsplit did not accept 0 length array\n"); - return -1; - } - - LOG("Parameter test cases passed\n"); - } while(0); - - LOG("%s - PASSED\n", __func__); - return 0; -} - -static int -test_string_fns(void) -{ - if (test_rte_strsplit() < 0) - return -1; - return 0; -} - -REGISTER_TEST_COMMAND(string_autotest, test_string_fns); diff --git a/app/test/test_table.c b/app/test/test_table.c deleted file mode 100644 index 1faa0a6d80..0000000000 --- a/app/test/test_table.c +++ /dev/null @@ -1,202 +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 -#include -#include -#include -#include "test.h" -#include "test_table.h" -#include "test_table_pipeline.h" -#include "test_table_ports.h" -#include "test_table_tables.h" -#include "test_table_combined.h" -#include "test_table_acl.h" - -/* Global variables */ -struct rte_pipeline *p; -struct rte_ring *rings_rx[N_PORTS]; -struct rte_ring *rings_tx[N_PORTS]; -struct rte_mempool *pool = NULL; - -uint32_t port_in_id[N_PORTS]; -uint32_t port_out_id[N_PORTS]; -uint32_t port_out_id_type[3]; -uint32_t table_id[N_PORTS*2]; -uint64_t override_hit_mask = 0xFFFFFFFF; -uint64_t override_miss_mask = 0xFFFFFFFF; -uint64_t non_reserved_actions_hit = 0; -uint64_t non_reserved_actions_miss = 0; -uint8_t connect_miss_action_to_port_out = 0; -uint8_t connect_miss_action_to_table = 0; -uint32_t table_entry_default_action = RTE_PIPELINE_ACTION_DROP; -uint32_t table_entry_hit_action = RTE_PIPELINE_ACTION_PORT; -uint32_t table_entry_miss_action = RTE_PIPELINE_ACTION_DROP; -rte_pipeline_port_in_action_handler port_in_action = NULL; -rte_pipeline_port_out_action_handler port_out_action = NULL; -rte_pipeline_table_action_handler_hit action_handler_hit = NULL; -rte_pipeline_table_action_handler_miss action_handler_miss = NULL; - -/* Function prototypes */ -static void app_init_rings(void); -static void app_init_mbuf_pools(void); - -uint64_t pipeline_test_hash(void *key, - __attribute__((unused)) uint32_t key_size, - __attribute__((unused)) uint64_t seed) -{ - uint32_t *k32 = (uint32_t *) key; - uint32_t ip_dst = rte_be_to_cpu_32(k32[0]); - uint64_t signature = ip_dst; - - return signature; -} - -static void -app_init_mbuf_pools(void) -{ - /* Init the buffer pool */ - printf("Getting/Creating the mempool ...\n"); - pool = rte_mempool_lookup("mempool"); - if (!pool) { - pool = rte_pktmbuf_pool_create( - "mempool", - POOL_SIZE, - POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE, - 0); - if (pool == NULL) - rte_panic("Cannot create mbuf pool\n"); - } -} - -static void -app_init_rings(void) -{ - uint32_t i; - - for (i = 0; i < N_PORTS; i++) { - char name[32]; - - snprintf(name, sizeof(name), "app_ring_rx_%u", i); - rings_rx[i] = rte_ring_lookup(name); - if (rings_rx[i] == NULL) { - rings_rx[i] = rte_ring_create( - name, - RING_RX_SIZE, - 0, - RING_F_SP_ENQ | RING_F_SC_DEQ); - } - if (rings_rx[i] == NULL) - rte_panic("Cannot create RX ring %u\n", i); - } - - for (i = 0; i < N_PORTS; i++) { - char name[32]; - - snprintf(name, sizeof(name), "app_ring_tx_%u", i); - rings_tx[i] = rte_ring_lookup(name); - if (rings_tx[i] == NULL) { - rings_tx[i] = rte_ring_create( - name, - RING_TX_SIZE, - 0, - RING_F_SP_ENQ | RING_F_SC_DEQ); - } - if (rings_tx[i] == NULL) - rte_panic("Cannot create TX ring %u\n", i); - } - -} - -static int -test_table(void) -{ - int status, failures; - unsigned i; - - failures = 0; - - app_init_rings(); - app_init_mbuf_pools(); - - printf("\n\n\n\n************Pipeline tests************\n"); - - if (test_table_pipeline() < 0) - return -1; - - printf("\n\n\n\n************Port tests************\n"); - for (i = 0; i < n_port_tests; i++) { - status = port_tests[i](); - if (status < 0) { - printf("\nPort test number %d failed (%d).\n", i, - status); - failures++; - return -1; - } - } - - printf("\n\n\n\n************Table tests************\n"); - for (i = 0; i < n_table_tests; i++) { - status = table_tests[i](); - if (status < 0) { - printf("\nTable test number %d failed (%d).\n", i, - status); - failures++; - return -1; - } - } - - printf("\n\n\n\n************Table tests************\n"); - for (i = 0; i < n_table_tests_combined; i++) { - status = table_tests_combined[i](); - if (status < 0) { - printf("\nCombined table test number %d failed with " - "reason number %d.\n", i, status); - failures++; - return -1; - } - } - - if (failures) - return -1; - -#ifdef RTE_LIBRTE_ACL - printf("\n\n\n\n************ACL tests************\n"); - if (test_table_acl() < 0) - return -1; -#endif - - return 0; -} - -REGISTER_TEST_COMMAND(table_autotest, test_table); diff --git a/app/test/test_table.h b/app/test/test_table.h deleted file mode 100644 index 84d1845a3d..0000000000 --- a/app/test/test_table.h +++ /dev/null @@ -1,206 +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 -#include -#include -#include -#include -#include - -#ifdef RTE_LIBRTE_ACL -#include -#endif - -#include -#include -#include - -#ifndef TEST_TABLE_H_ -#define TEST_TABLE_H_ - -#define RING_SIZE 4096 -#define MAX_BULK 32 -#define N 65536 -#define TIME_S 5 -#define TEST_RING_FULL_EMTPY_ITER 8 -#define N_PORTS 2 -#define N_PKTS 2 -#define N_PKTS_EXT 6 -#define RING_RX rings_rx[0] -#define RING_RX_2 rings_rx[1] -#define RING_TX rings_tx[0] -#define RING_TX_2 rings_tx[1] -#define PORT_RX_RING_SIZE 128 -#define PORT_TX_RING_SIZE 512 -#define RING_RX_SIZE 128 -#define RING_TX_SIZE 128 -#define POOL_BUFFER_SIZE RTE_MBUF_DEFAULT_BUF_SIZE -#define POOL_SIZE (32 * 1024) -#define POOL_CACHE_SIZE 256 -#define BURST_SIZE 8 -#define WORKER_TYPE 1 -#define MAX_DUMMY_PORTS 2 -#define MP_NAME "dummy_port_mempool" -#define MBUF_COUNT (8000 * MAX_DUMMY_PORTS) -#define MP_CACHE_SZ 256 -#define MP_SOCKET 0 -#define MP_FLAGS 0 - -/* Macros */ -#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset)) - -#define RING_ENQUEUE(ring, value) do { \ - struct rte_mbuf *m; \ - uint32_t *k32, *signature; \ - uint8_t *key; \ - \ - m = rte_pktmbuf_alloc(pool); \ - if (m == NULL) \ - return -1; \ - signature = RTE_MBUF_METADATA_UINT32_PTR(m, \ - APP_METADATA_OFFSET(0)); \ - key = RTE_MBUF_METADATA_UINT8_PTR(m, \ - APP_METADATA_OFFSET(32)); \ - k32 = (uint32_t *) key; \ - k32[0] = (value); \ - *signature = pipeline_test_hash(key, 0, 0); \ - rte_ring_enqueue((ring), m); \ -} while (0) - -#define RUN_PIPELINE(pipeline) do { \ - rte_pipeline_run((pipeline)); \ - rte_pipeline_flush((pipeline)); \ -} while (0) - -#define VERIFY(var, value) do { \ - if ((var) != -(value)) \ - return var; \ -} while (0) - -#define VERIFY_TRAFFIC(ring, sent, expected) do { \ - unsigned i, n = 0; \ - void *mbuf = NULL; \ - \ - for (i = 0; i < (sent); i++) { \ - if (!rte_ring_dequeue((ring), &mbuf)) { \ - if (mbuf == NULL) \ - continue; \ - n++; \ - rte_pktmbuf_free((struct rte_mbuf *)mbuf); \ - } \ - else \ - break; \ - } \ - printf("Expected %d, got %d\n", expected, n); \ - if (n != (expected)) { \ - return -21; \ - } \ -} while (0) - -/* Function definitions */ -uint64_t pipeline_test_hash( - void *key, - __attribute__((unused)) uint32_t key_size, - __attribute__((unused)) uint64_t seed); - -/* Extern variables */ -extern struct rte_pipeline *p; -extern struct rte_ring *rings_rx[N_PORTS]; -extern struct rte_ring *rings_tx[N_PORTS]; -extern struct rte_mempool *pool; -extern uint32_t port_in_id[N_PORTS]; -extern uint32_t port_out_id[N_PORTS]; -extern uint32_t port_out_id_type[3]; -extern uint32_t table_id[N_PORTS*2]; -extern uint64_t override_hit_mask; -extern uint64_t override_miss_mask; -extern uint64_t non_reserved_actions_hit; -extern uint64_t non_reserved_actions_miss; -extern uint8_t connect_miss_action_to_port_out; -extern uint8_t connect_miss_action_to_table; -extern uint32_t table_entry_default_action; -extern uint32_t table_entry_hit_action; -extern uint32_t table_entry_miss_action; -extern rte_pipeline_port_in_action_handler port_in_action; -extern rte_pipeline_port_out_action_handler port_out_action; -extern rte_pipeline_table_action_handler_hit action_handler_hit; -extern rte_pipeline_table_action_handler_miss action_handler_miss; - -/* Global data types */ -struct manage_ops { - uint32_t op_id; - void *op_data; - int expected_result; -}; - -/* Internal pipeline structures */ -struct rte_port_in { - struct rte_port_in_ops ops; - uint32_t burst_size; - uint32_t table_id; - void *h_port; -}; - -struct rte_port_out { - struct rte_port_out_ops ops; - void *h_port; -}; - -struct rte_table { - struct rte_table_ops ops; - rte_pipeline_table_action_handler_hit f_action; - uint32_t table_next_id; - uint32_t table_next_id_valid; - uint8_t actions_lookup_miss[RTE_CACHE_LINE_SIZE]; - uint32_t action_data_size; - void *h_table; -}; - -#define RTE_PIPELINE_MAX_NAME_SZ 124 - -struct rte_pipeline { - char name[RTE_PIPELINE_MAX_NAME_SZ]; - uint32_t socket_id; - struct rte_port_in ports_in[16]; - struct rte_port_out ports_out[16]; - struct rte_table tables[64]; - uint32_t num_ports_in; - uint32_t num_ports_out; - uint32_t num_tables; - struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX]; - struct rte_table_entry *actions[RTE_PORT_IN_BURST_SIZE_MAX]; - uint64_t mask_action[64]; - uint32_t mask_actions; -}; -#endif diff --git a/app/test/test_table_acl.c b/app/test/test_table_acl.c deleted file mode 100644 index b3bfda4ccc..0000000000 --- a/app/test/test_table_acl.c +++ /dev/null @@ -1,760 +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 -#include "test_table.h" -#include "test_table_acl.h" - -#define IPv4(a, b, c, d) ((uint32_t)(((a) & 0xff) << 24) | \ - (((b) & 0xff) << 16) | \ - (((c) & 0xff) << 8) | \ - ((d) & 0xff)) - -/* - * Rule and trace formats definitions. - **/ - -struct ipv4_5tuple { - uint8_t proto; - uint32_t ip_src; - uint32_t ip_dst; - uint16_t port_src; - uint16_t port_dst; -}; - -enum { - PROTO_FIELD_IPV4, - SRC_FIELD_IPV4, - DST_FIELD_IPV4, - SRCP_FIELD_IPV4, - DSTP_FIELD_IPV4, - NUM_FIELDS_IPV4 -}; - -struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = PROTO_FIELD_IPV4, - .input_index = PROTO_FIELD_IPV4, - .offset = offsetof(struct ipv4_5tuple, proto), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = SRC_FIELD_IPV4, - .input_index = SRC_FIELD_IPV4, - .offset = offsetof(struct ipv4_5tuple, ip_src), - }, - { - .type = RTE_ACL_FIELD_TYPE_MASK, - .size = sizeof(uint32_t), - .field_index = DST_FIELD_IPV4, - .input_index = DST_FIELD_IPV4, - .offset = offsetof(struct ipv4_5tuple, ip_dst), - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = SRCP_FIELD_IPV4, - .input_index = SRCP_FIELD_IPV4, - .offset = offsetof(struct ipv4_5tuple, port_src), - }, - { - .type = RTE_ACL_FIELD_TYPE_RANGE, - .size = sizeof(uint16_t), - .field_index = DSTP_FIELD_IPV4, - .input_index = SRCP_FIELD_IPV4, - .offset = offsetof(struct ipv4_5tuple, port_dst), - }, -}; - -struct rte_table_acl_rule_add_params table_acl_IPv4_rule; - -typedef int (*parse_5tuple)(char *text, - struct rte_table_acl_rule_add_params *rule); - -/* -* The order of the fields in the rule string after the initial '@' -*/ -enum { - CB_FLD_SRC_ADDR, - CB_FLD_DST_ADDR, - CB_FLD_SRC_PORT_RANGE, - CB_FLD_DST_PORT_RANGE, - CB_FLD_PROTO, - CB_FLD_NUM, -}; - - -#define GET_CB_FIELD(in, fd, base, lim, dlm) \ -do { \ - unsigned long val; \ - char *end; \ - \ - errno = 0; \ - val = strtoul((in), &end, (base)); \ - if (errno != 0 || end[0] != (dlm) || val > (lim)) \ - return -EINVAL; \ - (fd) = (typeof(fd)) val; \ - (in) = end + 1; \ -} while (0) - - - - -static int -parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len) -{ - uint8_t a, b, c, d, m; - - GET_CB_FIELD(in, a, 0, UINT8_MAX, '.'); - GET_CB_FIELD(in, b, 0, UINT8_MAX, '.'); - GET_CB_FIELD(in, c, 0, UINT8_MAX, '.'); - GET_CB_FIELD(in, d, 0, UINT8_MAX, '/'); - GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0); - - addr[0] = IPv4(a, b, c, d); - mask_len[0] = m; - - return 0; -} - -static int -parse_port_range(const char *in, uint16_t *port_low, uint16_t *port_high) -{ - uint16_t a, b; - - GET_CB_FIELD(in, a, 0, UINT16_MAX, ':'); - GET_CB_FIELD(in, b, 0, UINT16_MAX, 0); - - port_low[0] = a; - port_high[0] = b; - - return 0; -} - -static int -parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v) -{ - int i, rc; - char *s, *sp, *in[CB_FLD_NUM]; - static const char *dlm = " \t\n"; - - /* - ** Skip leading '@' - */ - if (strchr(str, '@') != str) - return -EINVAL; - - s = str + 1; - - /* - * Populate the 'in' array with the location of each - * field in the string we're parsing - */ - for (i = 0; i != DIM(in); i++) { - in[i] = strtok_r(s, dlm, &sp); - if (in[i] == NULL) - return -EINVAL; - s = NULL; - } - - /* Parse x.x.x.x/x */ - rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR], - &v->field_value[SRC_FIELD_IPV4].value.u32, - &v->field_value[SRC_FIELD_IPV4].mask_range.u32); - if (rc != 0) { - RTE_LOG(ERR, PIPELINE, "failed to read src address/mask: %s\n", - in[CB_FLD_SRC_ADDR]); - return rc; - } - - printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32, - v->field_value[SRC_FIELD_IPV4].mask_range.u32); - - /* Parse x.x.x.x/x */ - rc = parse_ipv4_net(in[CB_FLD_DST_ADDR], - &v->field_value[DST_FIELD_IPV4].value.u32, - &v->field_value[DST_FIELD_IPV4].mask_range.u32); - if (rc != 0) { - RTE_LOG(ERR, PIPELINE, "failed to read dest address/mask: %s\n", - in[CB_FLD_DST_ADDR]); - return rc; - } - - printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32, - v->field_value[DST_FIELD_IPV4].mask_range.u32); - /* Parse n:n */ - rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE], - &v->field_value[SRCP_FIELD_IPV4].value.u16, - &v->field_value[SRCP_FIELD_IPV4].mask_range.u16); - if (rc != 0) { - RTE_LOG(ERR, PIPELINE, "failed to read source port range: %s\n", - in[CB_FLD_SRC_PORT_RANGE]); - return rc; - } - - printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16, - v->field_value[SRCP_FIELD_IPV4].mask_range.u16); - /* Parse n:n */ - rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE], - &v->field_value[DSTP_FIELD_IPV4].value.u16, - &v->field_value[DSTP_FIELD_IPV4].mask_range.u16); - if (rc != 0) { - RTE_LOG(ERR, PIPELINE, "failed to read dest port range: %s\n", - in[CB_FLD_DST_PORT_RANGE]); - return rc; - } - - printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16, - v->field_value[DSTP_FIELD_IPV4].mask_range.u16); - /* parse 0/0xnn */ - GET_CB_FIELD(in[CB_FLD_PROTO], - v->field_value[PROTO_FIELD_IPV4].value.u8, - 0, UINT8_MAX, '/'); - GET_CB_FIELD(in[CB_FLD_PROTO], - v->field_value[PROTO_FIELD_IPV4].mask_range.u8, - 0, UINT8_MAX, 0); - - printf("V=%u, mask=%u\n", - (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8, - v->field_value[PROTO_FIELD_IPV4].mask_range.u8); - return 0; -} - -static int -parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v) -{ - int i, rc; - char *s, *sp, *in[CB_FLD_NUM]; - static const char *dlm = " \t\n"; - - /* - ** Skip leading '@' - */ - if (strchr(str, '@') != str) - return -EINVAL; - - s = str + 1; - - /* - * Populate the 'in' array with the location of each - * field in the string we're parsing - */ - for (i = 0; i != DIM(in); i++) { - in[i] = strtok_r(s, dlm, &sp); - if (in[i] == NULL) - return -EINVAL; - s = NULL; - } - - /* Parse x.x.x.x/x */ - rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR], - &v->field_value[SRC_FIELD_IPV4].value.u32, - &v->field_value[SRC_FIELD_IPV4].mask_range.u32); - if (rc != 0) { - RTE_LOG(ERR, PIPELINE, "failed to read src address/mask: %s\n", - in[CB_FLD_SRC_ADDR]); - return rc; - } - - printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32, - v->field_value[SRC_FIELD_IPV4].mask_range.u32); - - /* Parse x.x.x.x/x */ - rc = parse_ipv4_net(in[CB_FLD_DST_ADDR], - &v->field_value[DST_FIELD_IPV4].value.u32, - &v->field_value[DST_FIELD_IPV4].mask_range.u32); - if (rc != 0) { - RTE_LOG(ERR, PIPELINE, "failed to read dest address/mask: %s\n", - in[CB_FLD_DST_ADDR]); - return rc; - } - - printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32, - v->field_value[DST_FIELD_IPV4].mask_range.u32); - /* Parse n:n */ - rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE], - &v->field_value[SRCP_FIELD_IPV4].value.u16, - &v->field_value[SRCP_FIELD_IPV4].mask_range.u16); - if (rc != 0) { - RTE_LOG(ERR, PIPELINE, "failed to read source port range: %s\n", - in[CB_FLD_SRC_PORT_RANGE]); - return rc; - } - - printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16, - v->field_value[SRCP_FIELD_IPV4].mask_range.u16); - /* Parse n:n */ - rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE], - &v->field_value[DSTP_FIELD_IPV4].value.u16, - &v->field_value[DSTP_FIELD_IPV4].mask_range.u16); - if (rc != 0) { - RTE_LOG(ERR, PIPELINE, "failed to read dest port range: %s\n", - in[CB_FLD_DST_PORT_RANGE]); - return rc; - } - - printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16, - v->field_value[DSTP_FIELD_IPV4].mask_range.u16); - /* parse 0/0xnn */ - GET_CB_FIELD(in[CB_FLD_PROTO], - v->field_value[PROTO_FIELD_IPV4].value.u8, - 0, UINT8_MAX, '/'); - GET_CB_FIELD(in[CB_FLD_PROTO], - v->field_value[PROTO_FIELD_IPV4].mask_range.u8, - 0, UINT8_MAX, 0); - - printf("V=%u, mask=%u\n", - (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8, - v->field_value[PROTO_FIELD_IPV4].mask_range.u8); - return 0; -} - -/* - * The format for these rules DO NOT need the port ranges to be - * separated by ' : ', just ':'. It's a lot more readable and - * cleaner, IMO. - */ -char lines[][128] = { - "@0.0.0.0/0 0.0.0.0/0 0:65535 0:65535 2/0xff", /* Protocol check */ - "@192.168.3.1/32 0.0.0.0/0 0:65535 0:65535 0/0", /* Src IP checl */ - "@0.0.0.0/0 10.4.4.1/32 0:65535 0:65535 0/0", /* dst IP check */ - "@0.0.0.0/0 0.0.0.0/0 105:105 0:65535 0/0", /* src port check */ - "@0.0.0.0/0 0.0.0.0/0 0:65535 206:206 0/0", /* dst port check */ -}; - -char line[128]; - - -static int -setup_acl_pipeline(void) -{ - int ret; - int i; - struct rte_pipeline_params pipeline_params = { - .name = "PIPELINE", - .socket_id = 0, - }; - uint32_t n; - struct rte_table_acl_rule_add_params rule_params; - struct rte_pipeline_table_acl_rule_delete_params *delete_params; - parse_5tuple parser; - char acl_name[64]; - - /* Pipeline configuration */ - p = rte_pipeline_create(&pipeline_params); - if (p == NULL) { - RTE_LOG(INFO, PIPELINE, "%s: Failed to configure pipeline\n", - __func__); - goto fail; - } - - /* Input port configuration */ - for (i = 0; i < N_PORTS; i++) { - struct rte_port_ring_reader_params port_ring_params = { - .ring = rings_rx[i], - }; - - struct rte_pipeline_port_in_params port_params = { - .ops = &rte_port_ring_reader_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .burst_size = BURST_SIZE, - }; - - /* Put in action for some ports */ - if (i) - port_params.f_action = port_in_action; - - ret = rte_pipeline_port_in_create(p, &port_params, - &port_in_id[i]); - if (ret) { - rte_panic("Unable to configure input port %d, ret:%d\n", - i, ret); - goto fail; - } - } - - /* output Port configuration */ - for (i = 0; i < N_PORTS; i++) { - struct rte_port_ring_writer_params port_ring_params = { - .ring = rings_tx[i], - .tx_burst_sz = BURST_SIZE, - }; - - struct rte_pipeline_port_out_params port_params = { - .ops = &rte_port_ring_writer_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - }; - - - if (rte_pipeline_port_out_create(p, &port_params, - &port_out_id[i])) { - rte_panic("Unable to configure output port %d\n", i); - goto fail; - } - } - - /* Table configuration */ - for (i = 0; i < N_PORTS; i++) { - struct rte_pipeline_table_params table_params; - - /* Set up defaults for stub */ - table_params.ops = &rte_table_stub_ops; - table_params.arg_create = NULL; - table_params.f_action_hit = action_handler_hit; - table_params.f_action_miss = NULL; - table_params.action_data_size = 0; - - RTE_LOG(INFO, PIPELINE, "miss_action=%x\n", - table_entry_miss_action); - - printf("RTE_ACL_RULE_SZ(%zu) = %zu\n", DIM(ipv4_defs), - RTE_ACL_RULE_SZ(DIM(ipv4_defs))); - - struct rte_table_acl_params acl_params; - - acl_params.n_rules = 1 << 5; - acl_params.n_rule_fields = DIM(ipv4_defs); - snprintf(acl_name, sizeof(acl_name), "ACL%d", i); - acl_params.name = acl_name; - memcpy(acl_params.field_format, ipv4_defs, sizeof(ipv4_defs)); - - table_params.ops = &rte_table_acl_ops; - table_params.arg_create = &acl_params; - - if (rte_pipeline_table_create(p, &table_params, &table_id[i])) { - rte_panic("Unable to configure table %u\n", i); - goto fail; - } - - if (connect_miss_action_to_table) { - if (rte_pipeline_table_create(p, &table_params, - &table_id[i+2])) { - rte_panic("Unable to configure table %u\n", i); - goto fail; - } - } - } - - for (i = 0; i < N_PORTS; i++) { - if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], - table_id[i])) { - rte_panic("Unable to connect input port %u to " - "table %u\n", - port_in_id[i], table_id[i]); - goto fail; - } - } - - /* Add bulk entries to tables */ - for (i = 0; i < N_PORTS; i++) { - struct rte_table_acl_rule_add_params keys[5]; - struct rte_pipeline_table_entry entries[5]; - struct rte_table_acl_rule_add_params *key_array[5]; - struct rte_pipeline_table_entry *table_entries[5]; - int key_found[5]; - struct rte_pipeline_table_entry *table_entries_ptr[5]; - struct rte_pipeline_table_entry entries_ptr[5]; - - parser = parse_cb_ipv4_rule; - for (n = 0; n < 5; n++) { - memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params)); - key_array[n] = &keys[n]; - - snprintf(line, sizeof(line), "%s", lines[n]); - printf("PARSING [%s]\n", line); - - ret = parser(line, &keys[n]); - if (ret != 0) { - RTE_LOG(ERR, PIPELINE, - "line %u: parse_cb_ipv4vlan_rule" - " failed, error code: %d (%s)\n", - n, ret, strerror(-ret)); - return ret; - } - - keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1; - - entries[n].action = RTE_PIPELINE_ACTION_PORT; - entries[n].port_id = port_out_id[i^1]; - table_entries[n] = &entries[n]; - table_entries_ptr[n] = &entries_ptr[n]; - } - - ret = rte_pipeline_table_entry_add_bulk(p, table_id[i], - (void **)key_array, table_entries, 5, key_found, table_entries_ptr); - if (ret < 0) { - rte_panic("Add entry bulk to table %u failed (%d)\n", - table_id[i], ret); - goto fail; - } - } - - /* Delete bulk entries from tables */ - for (i = 0; i < N_PORTS; i++) { - struct rte_table_acl_rule_delete_params keys[5]; - struct rte_table_acl_rule_delete_params *key_array[5]; - struct rte_pipeline_table_entry *table_entries[5]; - int key_found[5]; - - for (n = 0; n < 5; n++) { - memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params)); - key_array[n] = &keys[n]; - - snprintf(line, sizeof(line), "%s", lines[n]); - printf("PARSING [%s]\n", line); - - ret = parse_cb_ipv4_rule_del(line, &keys[n]); - if (ret != 0) { - RTE_LOG(ERR, PIPELINE, - "line %u: parse_cb_ipv4vlan_rule" - " failed, error code: %d (%s)\n", - n, ret, strerror(-ret)); - return ret; - } - } - - ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i], - (void **)key_array, 5, key_found, table_entries); - if (ret < 0) { - rte_panic("Delete bulk entries from table %u failed (%d)\n", - table_id[i], ret); - goto fail; - } else - printf("Bulk deleted rules.\n"); - } - - /* Add entries to tables */ - for (i = 0; i < N_PORTS; i++) { - struct rte_pipeline_table_entry table_entry = { - .action = RTE_PIPELINE_ACTION_PORT, - {.port_id = port_out_id[i^1]}, - }; - int key_found; - struct rte_pipeline_table_entry *entry_ptr; - - memset(&rule_params, 0, sizeof(rule_params)); - parser = parse_cb_ipv4_rule; - - for (n = 1; n <= 5; n++) { - snprintf(line, sizeof(line), "%s", lines[n-1]); - printf("PARSING [%s]\n", line); - - ret = parser(line, &rule_params); - if (ret != 0) { - RTE_LOG(ERR, PIPELINE, - "line %u: parse_cb_ipv4vlan_rule" - " failed, error code: %d (%s)\n", - n, ret, strerror(-ret)); - return ret; - } - - rule_params.priority = RTE_ACL_MAX_PRIORITY - n; - - ret = rte_pipeline_table_entry_add(p, table_id[i], - &rule_params, - &table_entry, &key_found, &entry_ptr); - if (ret < 0) { - rte_panic("Add entry to table %u failed (%d)\n", - table_id[i], ret); - goto fail; - } - } - - /* delete a few rules */ - for (n = 2; n <= 3; n++) { - snprintf(line, sizeof(line), "%s", lines[n-1]); - printf("PARSING [%s]\n", line); - - ret = parser(line, &rule_params); - if (ret != 0) { - RTE_LOG(ERR, PIPELINE, "line %u: parse rule " - " failed, error code: %d (%s)\n", - n, ret, strerror(-ret)); - return ret; - } - - delete_params = (struct - rte_pipeline_table_acl_rule_delete_params *) - &(rule_params.field_value[0]); - ret = rte_pipeline_table_entry_delete(p, table_id[i], - delete_params, &key_found, NULL); - if (ret < 0) { - rte_panic("Add entry to table %u failed (%d)\n", - table_id[i], ret); - goto fail; - } else - printf("Deleted Rule.\n"); - } - - - /* Try to add duplicates */ - for (n = 1; n <= 5; n++) { - snprintf(line, sizeof(line), "%s", lines[n-1]); - printf("PARSING [%s]\n", line); - - ret = parser(line, &rule_params); - if (ret != 0) { - RTE_LOG(ERR, PIPELINE, "line %u: parse rule" - " failed, error code: %d (%s)\n", - n, ret, strerror(-ret)); - return ret; - } - - rule_params.priority = RTE_ACL_MAX_PRIORITY - n; - - ret = rte_pipeline_table_entry_add(p, table_id[i], - &rule_params, - &table_entry, &key_found, &entry_ptr); - if (ret < 0) { - rte_panic("Add entry to table %u failed (%d)\n", - table_id[i], ret); - goto fail; - } - } - } - - /* Enable input ports */ - for (i = 0; i < N_PORTS ; i++) - if (rte_pipeline_port_in_enable(p, port_in_id[i])) - rte_panic("Unable to enable input port %u\n", - port_in_id[i]); - - /* Check pipeline consistency */ - if (rte_pipeline_check(p) < 0) { - rte_panic("Pipeline consistency check failed\n"); - goto fail; - } - - return 0; -fail: - - return -1; -} - -static int -test_pipeline_single_filter(int expected_count) -{ - int i, j, ret, tx_count; - struct ipv4_5tuple five_tuple; - - /* Allocate a few mbufs and manually insert into the rings. */ - for (i = 0; i < N_PORTS; i++) { - for (j = 0; j < 8; j++) { - struct rte_mbuf *mbuf; - - mbuf = rte_pktmbuf_alloc(pool); - if (mbuf == NULL) - /* this will cause test failure after cleanup - * of already enqueued mbufs, as the mbuf - * counts won't match */ - break; - memset(rte_pktmbuf_mtod(mbuf, char *), 0x00, - sizeof(struct ipv4_5tuple)); - - five_tuple.proto = j; - five_tuple.ip_src = rte_bswap32(IPv4(192, 168, j, 1)); - five_tuple.ip_dst = rte_bswap32(IPv4(10, 4, j, 1)); - five_tuple.port_src = rte_bswap16(100 + j); - five_tuple.port_dst = rte_bswap16(200 + j); - - memcpy(rte_pktmbuf_mtod(mbuf, char *), &five_tuple, - sizeof(struct ipv4_5tuple)); - RTE_LOG(INFO, PIPELINE, "%s: Enqueue onto ring %d\n", - __func__, i); - rte_ring_enqueue(rings_rx[i], mbuf); - } - } - - /* Run pipeline once */ - for (i = 0; i< N_PORTS; i++) - rte_pipeline_run(p); - - rte_pipeline_flush(p); - - tx_count = 0; - - for (i = 0; i < N_PORTS; i++) { - void *objs[RING_TX_SIZE]; - struct rte_mbuf *mbuf; - - ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10); - if (ret <= 0) { - printf("Got no objects from ring %d - error code %d\n", - i, ret); - } else { - printf("Got %d object(s) from ring %d!\n", ret, i); - for (j = 0; j < ret; j++) { - mbuf = (struct rte_mbuf *)objs[j]; - rte_hexdump(stdout, "mbuf", - rte_pktmbuf_mtod(mbuf, char *), 64); - rte_pktmbuf_free(mbuf); - } - tx_count += ret; - } - } - - if (tx_count != expected_count) { - RTE_LOG(INFO, PIPELINE, - "%s: Unexpected packets for ACL test, " - "expected %d, got %d\n", - __func__, expected_count, tx_count); - goto fail; - } - - rte_pipeline_free(p); - - return 0; -fail: - return -1; - -} - -int -test_table_acl(void) -{ - - - override_hit_mask = 0xFF; /* All packets are a hit */ - - setup_acl_pipeline(); - if (test_pipeline_single_filter(10) < 0) - return -1; - - return 0; -} diff --git a/app/test/test_table_acl.h b/app/test/test_table_acl.h deleted file mode 100644 index a64c3e6cb0..0000000000 --- a/app/test/test_table_acl.h +++ /dev/null @@ -1,35 +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. - */ - -/* Test prototypes */ -int test_table_acl(void); diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c deleted file mode 100644 index a2d19a1a23..0000000000 --- a/app/test/test_table_combined.c +++ /dev/null @@ -1,881 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include "test_table_combined.h" -#include "test_table.h" -#include - -#define MAX_TEST_KEYS 128 -#define N_PACKETS 50 - -enum check_table_result { - CHECK_TABLE_OK, - CHECK_TABLE_PORT_CONFIG, - CHECK_TABLE_PORT_ENABLE, - CHECK_TABLE_TABLE_CONFIG, - CHECK_TABLE_ENTRY_ADD, - CHECK_TABLE_DEFAULT_ENTRY_ADD, - CHECK_TABLE_CONNECT, - CHECK_TABLE_MANAGE_ERROR, - CHECK_TABLE_CONSISTENCY, - CHECK_TABLE_NO_TRAFFIC, - CHECK_TABLE_INVALID_PARAMETER, -}; - -struct table_packets { - uint32_t hit_packet[MAX_TEST_KEYS]; - uint32_t miss_packet[MAX_TEST_KEYS]; - uint32_t n_hit_packets; - uint32_t n_miss_packets; -}; - -combined_table_test table_tests_combined[] = { - test_table_lpm_combined, - test_table_lpm_ipv6_combined, - test_table_hash8lru, - test_table_hash8ext, - test_table_hash16lru, - test_table_hash16ext, - test_table_hash32lru, - test_table_hash32ext, - test_table_hash_cuckoo_combined, -}; - -unsigned n_table_tests_combined = RTE_DIM(table_tests_combined); - -/* Generic port tester function */ -static int -test_table_type(struct rte_table_ops *table_ops, void *table_args, - void *key, struct table_packets *table_packets, - struct manage_ops *manage_ops, unsigned n_ops) -{ - uint32_t ring_in_id, table_id, ring_out_id, ring_out_2_id; - unsigned i; - - RTE_SET_USED(manage_ops); - RTE_SET_USED(n_ops); - /* Create pipeline */ - struct rte_pipeline_params pipeline_params = { - .name = "pipeline", - .socket_id = 0, - }; - - struct rte_pipeline *pipeline = rte_pipeline_create(&pipeline_params); - - /* Create input ring */ - struct rte_port_ring_reader_params ring_params_rx = { - .ring = RING_RX, - }; - - struct rte_port_ring_writer_params ring_params_tx = { - .ring = RING_RX, - .tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX, - }; - - struct rte_pipeline_port_in_params ring_in_params = { - .ops = &rte_port_ring_reader_ops, - .arg_create = (void *)&ring_params_rx, - .f_action = NULL, - .burst_size = RTE_PORT_IN_BURST_SIZE_MAX, - }; - - if (rte_pipeline_port_in_create(pipeline, &ring_in_params, - &ring_in_id) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_PORT_CONFIG; - } - - /* Create table */ - struct rte_pipeline_table_params table_params = { - .ops = table_ops, - .arg_create = table_args, - .f_action_hit = NULL, - .f_action_miss = NULL, - .arg_ah = NULL, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(pipeline, &table_params, - &table_id) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_TABLE_CONFIG; - } - - /* Create output ports */ - ring_params_tx.ring = RING_TX; - - struct rte_pipeline_port_out_params ring_out_params = { - .ops = &rte_port_ring_writer_ops, - .arg_create = (void *)&ring_params_tx, - .f_action = NULL, - }; - - if (rte_pipeline_port_out_create(pipeline, &ring_out_params, - &ring_out_id) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_PORT_CONFIG; - } - - ring_params_tx.ring = RING_TX_2; - - if (rte_pipeline_port_out_create(pipeline, &ring_out_params, - &ring_out_2_id) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_PORT_CONFIG; - } - - /* Add entry to the table */ - struct rte_pipeline_table_entry default_entry = { - .action = RTE_PIPELINE_ACTION_DROP, - {.table_id = ring_out_id}, - }; - - struct rte_pipeline_table_entry table_entry = { - .action = RTE_PIPELINE_ACTION_PORT, - {.table_id = ring_out_id}, - }; - - struct rte_pipeline_table_entry *default_entry_ptr, *entry_ptr; - - int key_found; - - if (rte_pipeline_table_default_entry_add(pipeline, table_id, - &default_entry, &default_entry_ptr) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_DEFAULT_ENTRY_ADD; - } - - if (rte_pipeline_table_entry_add(pipeline, table_id, - key ? key : &table_entry, &table_entry, &key_found, - &entry_ptr) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_ENTRY_ADD; - } - - /* Create connections and check consistency */ - if (rte_pipeline_port_in_connect_to_table(pipeline, ring_in_id, - table_id) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_CONNECT; - } - - if (rte_pipeline_port_in_enable(pipeline, ring_in_id) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_PORT_ENABLE; - } - - if (rte_pipeline_check(pipeline) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_CONSISTENCY; - } - - - - /* Flow test - All hits */ - if (table_packets->n_hit_packets) { - for (i = 0; i < table_packets->n_hit_packets; i++) - RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]); - - RUN_PIPELINE(pipeline); - - VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, - table_packets->n_hit_packets); - } - - /* Flow test - All misses */ - if (table_packets->n_miss_packets) { - for (i = 0; i < table_packets->n_miss_packets; i++) - RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]); - - RUN_PIPELINE(pipeline); - - VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0); - } - - /* Flow test - Half hits, half misses */ - if (table_packets->n_hit_packets && table_packets->n_miss_packets) { - for (i = 0; i < (table_packets->n_hit_packets) / 2; i++) - RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]); - - for (i = 0; i < (table_packets->n_miss_packets) / 2; i++) - RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]); - - RUN_PIPELINE(pipeline); - VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, - table_packets->n_hit_packets / 2); - } - - /* Flow test - Single packet */ - if (table_packets->n_hit_packets) { - RING_ENQUEUE(RING_RX, table_packets->hit_packet[0]); - RUN_PIPELINE(pipeline); - VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 1); - } - if (table_packets->n_miss_packets) { - RING_ENQUEUE(RING_RX, table_packets->miss_packet[0]); - RUN_PIPELINE(pipeline); - VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0); - } - - - /* Change table entry action */ - printf("Change entry action\n"); - table_entry.table_id = ring_out_2_id; - - if (rte_pipeline_table_default_entry_add(pipeline, table_id, - &default_entry, &default_entry_ptr) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_ENTRY_ADD; - } - - if (rte_pipeline_table_entry_add(pipeline, table_id, - key ? key : &table_entry, &table_entry, &key_found, - &entry_ptr) != 0) { - rte_pipeline_free(pipeline); - return -CHECK_TABLE_ENTRY_ADD; - } - - /* Check that traffic destination has changed */ - if (table_packets->n_hit_packets) { - for (i = 0; i < table_packets->n_hit_packets; i++) - RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]); - - RUN_PIPELINE(pipeline); - VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 0); - VERIFY_TRAFFIC(RING_TX_2, table_packets->n_hit_packets, - table_packets->n_hit_packets); - } - - printf("delete entry\n"); - /* Delete table entry */ - rte_pipeline_table_entry_delete(pipeline, table_id, - key ? key : &table_entry, &key_found, NULL); - - rte_pipeline_free(pipeline); - - return 0; -} - -/* Table tests */ -int -test_table_stub_combined(void) -{ - int status, i; - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < N_PACKETS; i++) - table_packets.hit_packet[i] = i; - - table_packets.n_hit_packets = N_PACKETS; - table_packets.n_miss_packets = 0; - - status = test_table_type(&rte_table_stub_ops, NULL, NULL, - &table_packets, NULL, 1); - VERIFY(status, CHECK_TABLE_OK); - - return 0; -} - -int -test_table_lpm_combined(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_lpm_params lpm_params = { - .name = "LPM", - .n_rules = 1 << 16, - .number_tbl8s = 1 << 8, - .flags = 0, - .entry_unique_size = 8, - .offset = APP_METADATA_OFFSET(0), - }; - - struct rte_table_lpm_key lpm_key = { - .ip = 0xadadadad, - .depth = 16, - }; - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - - for (i = 0; i < N_PACKETS; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < N_PACKETS; i++) - table_packets.miss_packet[i] = 0xfefefefe; - - table_packets.n_hit_packets = N_PACKETS; - table_packets.n_miss_packets = N_PACKETS; - - status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params, - (void *)&lpm_key, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - lpm_params.n_rules = 0; - - status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params, - (void *)&lpm_key, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - lpm_params.n_rules = 1 << 24; - lpm_key.depth = 0; - - status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params, - (void *)&lpm_key, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_ENTRY_ADD); - - lpm_key.depth = 33; - - status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params, - (void *)&lpm_key, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_ENTRY_ADD); - - return 0; -} - -int -test_table_lpm_ipv6_combined(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_lpm_ipv6_params lpm_ipv6_params = { - .name = "LPM", - .n_rules = 1 << 16, - .number_tbl8s = 1 << 13, - .entry_unique_size = 8, - .offset = APP_METADATA_OFFSET(32), - }; - - struct rte_table_lpm_ipv6_key lpm_ipv6_key = { - .depth = 16, - }; - memset(lpm_ipv6_key.ip, 0xad, 16); - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < N_PACKETS; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < N_PACKETS; i++) - table_packets.miss_packet[i] = 0xadadadab; - - table_packets.n_hit_packets = N_PACKETS; - table_packets.n_miss_packets = N_PACKETS; - - status = test_table_type(&rte_table_lpm_ipv6_ops, - (void *)&lpm_ipv6_params, - (void *)&lpm_ipv6_key, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - lpm_ipv6_params.n_rules = 0; - - status = test_table_type(&rte_table_lpm_ipv6_ops, - (void *)&lpm_ipv6_params, - (void *)&lpm_ipv6_key, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - lpm_ipv6_params.n_rules = 1 << 24; - lpm_ipv6_key.depth = 0; - - status = test_table_type(&rte_table_lpm_ipv6_ops, - (void *)&lpm_ipv6_params, - (void *)&lpm_ipv6_key, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_ENTRY_ADD); - - lpm_ipv6_key.depth = 129; - status = test_table_type(&rte_table_lpm_ipv6_ops, - (void *)&lpm_ipv6_params, - (void *)&lpm_ipv6_key, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_ENTRY_ADD); - - return 0; -} - -int -test_table_hash8lru(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_key8_lru_params key8lru_params = { - .n_entries = 1<<24, - .f_hash = pipeline_test_hash, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - }; - - uint8_t key8lru[8]; - uint32_t *k8lru = (uint32_t *) key8lru; - - memset(key8lru, 0, sizeof(key8lru)); - k8lru[0] = 0xadadadad; - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < 50; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < 50; i++) - table_packets.miss_packet[i] = 0xfefefefe; - - table_packets.n_hit_packets = 50; - table_packets.n_miss_packets = 50; - - status = test_table_type(&rte_table_hash_key8_lru_ops, - (void *)&key8lru_params, (void *)key8lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - key8lru_params.n_entries = 0; - - status = test_table_type(&rte_table_hash_key8_lru_ops, - (void *)&key8lru_params, (void *)key8lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key8lru_params.n_entries = 1<<16; - key8lru_params.f_hash = NULL; - - status = test_table_type(&rte_table_hash_key8_lru_ops, - (void *)&key8lru_params, (void *)key8lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - return 0; -} - -int -test_table_hash16lru(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_key16_lru_params key16lru_params = { - .n_entries = 1<<16, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - }; - - uint8_t key16lru[16]; - uint32_t *k16lru = (uint32_t *) key16lru; - - memset(key16lru, 0, sizeof(key16lru)); - k16lru[0] = 0xadadadad; - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < 50; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < 50; i++) - table_packets.miss_packet[i] = 0xfefefefe; - - table_packets.n_hit_packets = 50; - table_packets.n_miss_packets = 50; - - status = test_table_type(&rte_table_hash_key16_lru_ops, - (void *)&key16lru_params, (void *)key16lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - key16lru_params.n_entries = 0; - - status = test_table_type(&rte_table_hash_key16_lru_ops, - (void *)&key16lru_params, (void *)key16lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key16lru_params.n_entries = 1<<16; - key16lru_params.f_hash = NULL; - - status = test_table_type(&rte_table_hash_key16_lru_ops, - (void *)&key16lru_params, (void *)key16lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - return 0; -} - -int -test_table_hash32lru(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_key32_lru_params key32lru_params = { - .n_entries = 1<<16, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - }; - - uint8_t key32lru[32]; - uint32_t *k32lru = (uint32_t *) key32lru; - - memset(key32lru, 0, sizeof(key32lru)); - k32lru[0] = 0xadadadad; - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < 50; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < 50; i++) - table_packets.miss_packet[i] = 0xbdadadad; - - table_packets.n_hit_packets = 50; - table_packets.n_miss_packets = 50; - - status = test_table_type(&rte_table_hash_key32_lru_ops, - (void *)&key32lru_params, (void *)key32lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - key32lru_params.n_entries = 0; - - status = test_table_type(&rte_table_hash_key32_lru_ops, - (void *)&key32lru_params, (void *)key32lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key32lru_params.n_entries = 1<<16; - key32lru_params.f_hash = NULL; - - status = test_table_type(&rte_table_hash_key32_lru_ops, - (void *)&key32lru_params, (void *)key32lru, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - return 0; -} - -int -test_table_hash8ext(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_key8_ext_params key8ext_params = { - .n_entries = 1<<16, - .n_entries_ext = 1<<15, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - }; - - uint8_t key8ext[8]; - uint32_t *k8ext = (uint32_t *) key8ext; - - memset(key8ext, 0, sizeof(key8ext)); - k8ext[0] = 0xadadadad; - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < 50; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < 50; i++) - table_packets.miss_packet[i] = 0xbdadadad; - - table_packets.n_hit_packets = 50; - table_packets.n_miss_packets = 50; - - status = test_table_type(&rte_table_hash_key8_ext_ops, - (void *)&key8ext_params, (void *)key8ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - key8ext_params.n_entries = 0; - - status = test_table_type(&rte_table_hash_key8_ext_ops, - (void *)&key8ext_params, (void *)key8ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key8ext_params.n_entries = 1<<16; - key8ext_params.f_hash = NULL; - - status = test_table_type(&rte_table_hash_key8_ext_ops, - (void *)&key8ext_params, (void *)key8ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key8ext_params.f_hash = pipeline_test_hash; - key8ext_params.n_entries_ext = 0; - - status = test_table_type(&rte_table_hash_key8_ext_ops, - (void *)&key8ext_params, (void *)key8ext, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - return 0; -} - -int -test_table_hash16ext(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_key16_ext_params key16ext_params = { - .n_entries = 1<<16, - .n_entries_ext = 1<<15, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - }; - - uint8_t key16ext[16]; - uint32_t *k16ext = (uint32_t *) key16ext; - - memset(key16ext, 0, sizeof(key16ext)); - k16ext[0] = 0xadadadad; - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < 50; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < 50; i++) - table_packets.miss_packet[i] = 0xbdadadad; - - table_packets.n_hit_packets = 50; - table_packets.n_miss_packets = 50; - - status = test_table_type(&rte_table_hash_key16_ext_ops, - (void *)&key16ext_params, (void *)key16ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - key16ext_params.n_entries = 0; - - status = test_table_type(&rte_table_hash_key16_ext_ops, - (void *)&key16ext_params, (void *)key16ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key16ext_params.n_entries = 1<<16; - key16ext_params.f_hash = NULL; - - status = test_table_type(&rte_table_hash_key16_ext_ops, - (void *)&key16ext_params, (void *)key16ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key16ext_params.f_hash = pipeline_test_hash; - key16ext_params.n_entries_ext = 0; - - status = test_table_type(&rte_table_hash_key16_ext_ops, - (void *)&key16ext_params, (void *)key16ext, &table_packets, NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - return 0; -} - -int -test_table_hash32ext(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_key32_ext_params key32ext_params = { - .n_entries = 1<<16, - .n_entries_ext = 1<<15, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - }; - - uint8_t key32ext[32]; - uint32_t *k32ext = (uint32_t *) key32ext; - - memset(key32ext, 0, sizeof(key32ext)); - k32ext[0] = 0xadadadad; - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < 50; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < 50; i++) - table_packets.miss_packet[i] = 0xbdadadad; - - table_packets.n_hit_packets = 50; - table_packets.n_miss_packets = 50; - - status = test_table_type(&rte_table_hash_key32_ext_ops, - (void *)&key32ext_params, (void *)key32ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - key32ext_params.n_entries = 0; - - status = test_table_type(&rte_table_hash_key32_ext_ops, - (void *)&key32ext_params, (void *)key32ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key32ext_params.n_entries = 1<<16; - key32ext_params.f_hash = NULL; - - status = test_table_type(&rte_table_hash_key32_ext_ops, - (void *)&key32ext_params, (void *)key32ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - key32ext_params.f_hash = pipeline_test_hash; - key32ext_params.n_entries_ext = 0; - - status = test_table_type(&rte_table_hash_key32_ext_ops, - (void *)&key32ext_params, (void *)key32ext, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - return 0; -} - -int -test_table_hash_cuckoo_combined(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_cuckoo_params cuckoo_params = { - .key_size = 32, - .n_keys = 1<<16, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .name = "CUCKOO_HASH", - }; - - uint8_t key_cuckoo[32]; - uint32_t *kcuckoo = (uint32_t *) key_cuckoo; - - memset(key_cuckoo, 0, sizeof(key_cuckoo)); - kcuckoo[0] = 0xadadadad; - - struct table_packets table_packets; - - printf("--------------\n"); - printf("RUNNING TEST - %s\n", __func__); - printf("--------------\n"); - for (i = 0; i < 50; i++) - table_packets.hit_packet[i] = 0xadadadad; - - for (i = 0; i < 50; i++) - table_packets.miss_packet[i] = 0xbdadadad; - - table_packets.n_hit_packets = 50; - table_packets.n_miss_packets = 50; - - status = test_table_type(&rte_table_hash_cuckoo_dosig_ops, - (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_OK); - - /* Invalid parameters */ - cuckoo_params.key_size = 0; - - status = test_table_type(&rte_table_hash_cuckoo_dosig_ops, - (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - cuckoo_params.key_size = 32; - cuckoo_params.n_keys = 0; - - status = test_table_type(&rte_table_hash_cuckoo_dosig_ops, - (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - cuckoo_params.n_keys = 1<<16; - cuckoo_params.f_hash = NULL; - - status = test_table_type(&rte_table_hash_cuckoo_dosig_ops, - (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets, - NULL, 0); - VERIFY(status, CHECK_TABLE_TABLE_CONFIG); - - return 0; -} - diff --git a/app/test/test_table_combined.h b/app/test/test_table_combined.h deleted file mode 100644 index e1619f9258..0000000000 --- a/app/test/test_table_combined.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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. - */ - -/* Test prototypes */ -int test_table_stub_combined(void); -int test_table_lpm_combined(void); -int test_table_lpm_ipv6_combined(void); -#ifdef RTE_LIBRTE_ACL -int test_table_acl(void); -#endif -int test_table_hash8unoptimized(void); -int test_table_hash8lru(void); -int test_table_hash8ext(void); -int test_table_hash16unoptimized(void); -int test_table_hash16lru(void); -int test_table_hash16ext(void); -int test_table_hash32unoptimized(void); -int test_table_hash32lru(void); -int test_table_hash32ext(void); -int test_table_hash_cuckoo_combined(void); - -/* Extern variables */ -typedef int (*combined_table_test)(void); - -extern combined_table_test table_tests_combined[]; -extern unsigned n_table_tests_combined; diff --git a/app/test/test_table_pipeline.c b/app/test/test_table_pipeline.c deleted file mode 100644 index 36bfeda3d8..0000000000 --- a/app/test/test_table_pipeline.c +++ /dev/null @@ -1,600 +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 -#include -#include -#include -#include -#include "test_table.h" -#include "test_table_pipeline.h" - -#if 0 - -static rte_pipeline_port_out_action_handler port_action_0x00 - (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg); -static rte_pipeline_port_out_action_handler port_action_0xFF - (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg); -static rte_pipeline_port_out_action_handler port_action_stub - (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg); - - -rte_pipeline_port_out_action_handler port_action_0x00(struct rte_mbuf **pkts, - uint32_t n, - uint64_t *pkts_mask, - void *arg) -{ - RTE_SET_USED(pkts); - RTE_SET_USED(n); - RTE_SET_USED(arg); - printf("Port Action 0x00\n"); - *pkts_mask = 0x00; - return 0; -} - -rte_pipeline_port_out_action_handler port_action_0xFF(struct rte_mbuf **pkts, - uint32_t n, - uint64_t *pkts_mask, - void *arg) -{ - RTE_SET_USED(pkts); - RTE_SET_USED(n); - RTE_SET_USED(arg); - printf("Port Action 0xFF\n"); - *pkts_mask = 0xFF; - return 0; -} - -rte_pipeline_port_out_action_handler port_action_stub(struct rte_mbuf **pkts, - uint32_t n, - uint64_t *pkts_mask, - void *arg) -{ - RTE_SET_USED(pkts); - RTE_SET_USED(n); - RTE_SET_USED(pkts_mask); - RTE_SET_USED(arg); - printf("Port Action stub\n"); - return 0; -} - -#endif - -rte_pipeline_table_action_handler_hit -table_action_0x00(struct rte_pipeline *p, struct rte_mbuf **pkts, - uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg); - -rte_pipeline_table_action_handler_hit -table_action_stub_hit(struct rte_pipeline *p, struct rte_mbuf **pkts, - uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg); - -rte_pipeline_table_action_handler_miss -table_action_stub_miss(struct rte_pipeline *p, struct rte_mbuf **pkts, - uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg); - -rte_pipeline_table_action_handler_hit -table_action_0x00(__attribute__((unused)) struct rte_pipeline *p, - __attribute__((unused)) struct rte_mbuf **pkts, - uint64_t pkts_mask, - __attribute__((unused)) struct rte_pipeline_table_entry **entry, - __attribute__((unused)) void *arg) -{ - printf("Table Action, setting pkts_mask to 0x00\n"); - pkts_mask = ~0x00; - rte_pipeline_ah_packet_drop(p, pkts_mask); - return 0; -} - -rte_pipeline_table_action_handler_hit -table_action_stub_hit(__attribute__((unused)) struct rte_pipeline *p, - __attribute__((unused)) struct rte_mbuf **pkts, - uint64_t pkts_mask, - __attribute__((unused)) struct rte_pipeline_table_entry **entry, - __attribute__((unused)) void *arg) -{ - printf("STUB Table Action Hit - doing nothing\n"); - printf("STUB Table Action Hit - setting mask to 0x%"PRIx64"\n", - override_hit_mask); - pkts_mask = (~override_hit_mask) & 0x3; - rte_pipeline_ah_packet_drop(p, pkts_mask); - return 0; -} - -rte_pipeline_table_action_handler_miss -table_action_stub_miss(struct rte_pipeline *p, - __attribute__((unused)) struct rte_mbuf **pkts, - uint64_t pkts_mask, - __attribute__((unused)) struct rte_pipeline_table_entry **entry, - __attribute__((unused)) void *arg) -{ - printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n", - override_miss_mask); - pkts_mask = (~override_miss_mask) & 0x3; - rte_pipeline_ah_packet_drop(p, pkts_mask); - return 0; -} - -enum e_test_type { - e_TEST_STUB = 0, - e_TEST_LPM, - e_TEST_LPM6, - e_TEST_HASH_LRU_8, - e_TEST_HASH_LRU_16, - e_TEST_HASH_LRU_32, - e_TEST_HASH_EXT_8, - e_TEST_HASH_EXT_16, - e_TEST_HASH_EXT_32 -}; - -char pipeline_test_names[][64] = { - "Stub", - "LPM", - "LPMv6", - "8-bit LRU Hash", - "16-bit LRU Hash", - "32-bit LRU Hash", - "16-bit Ext Hash", - "8-bit Ext Hash", - "32-bit Ext Hash", - "" -}; - - -static int -cleanup_pipeline(void) -{ - - rte_pipeline_free(p); - - return 0; -} - - -static int check_pipeline_invalid_params(void); - -static int -check_pipeline_invalid_params(void) -{ - struct rte_pipeline_params pipeline_params_1 = { - .name = NULL, - .socket_id = 0, - }; - struct rte_pipeline_params pipeline_params_2 = { - .name = "PIPELINE", - .socket_id = -1, - }; - struct rte_pipeline_params pipeline_params_3 = { - .name = "PIPELINE", - .socket_id = 127, - }; - - p = rte_pipeline_create(NULL); - if (p != NULL) { - RTE_LOG(INFO, PIPELINE, - "%s: configured pipeline with null params\n", - __func__); - goto fail; - } - p = rte_pipeline_create(&pipeline_params_1); - if (p != NULL) { - RTE_LOG(INFO, PIPELINE, "%s: Configure pipeline with NULL " - "name\n", __func__); - goto fail; - } - - p = rte_pipeline_create(&pipeline_params_2); - if (p != NULL) { - RTE_LOG(INFO, PIPELINE, "%s: Configure pipeline with invalid " - "socket\n", __func__); - goto fail; - } - - p = rte_pipeline_create(&pipeline_params_3); - if (p != NULL) { - RTE_LOG(INFO, PIPELINE, "%s: Configure pipeline with invalid " - "socket\n", __func__); - goto fail; - } - - /* Check pipeline consistency */ - if (!rte_pipeline_check(p)) { - rte_panic("Pipeline consistency reported as OK\n"); - goto fail; - } - - - return 0; -fail: - return -1; -} - - -static int -setup_pipeline(int test_type) -{ - int ret; - int i; - struct rte_pipeline_params pipeline_params = { - .name = "PIPELINE", - .socket_id = 0, - }; - - RTE_LOG(INFO, PIPELINE, "%s: **** Setting up %s test\n", - __func__, pipeline_test_names[test_type]); - - /* Pipeline configuration */ - p = rte_pipeline_create(&pipeline_params); - if (p == NULL) { - RTE_LOG(INFO, PIPELINE, "%s: Failed to configure pipeline\n", - __func__); - goto fail; - } - - ret = rte_pipeline_free(p); - if (ret != 0) { - RTE_LOG(INFO, PIPELINE, "%s: Failed to free pipeline\n", - __func__); - goto fail; - } - - /* Pipeline configuration */ - p = rte_pipeline_create(&pipeline_params); - if (p == NULL) { - RTE_LOG(INFO, PIPELINE, "%s: Failed to configure pipeline\n", - __func__); - goto fail; - } - - - /* Input port configuration */ - for (i = 0; i < N_PORTS; i++) { - struct rte_port_ring_reader_params port_ring_params = { - .ring = rings_rx[i], - }; - - struct rte_pipeline_port_in_params port_params = { - .ops = &rte_port_ring_reader_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .burst_size = BURST_SIZE, - }; - - /* Put in action for some ports */ - if (i) - port_params.f_action = NULL; - - ret = rte_pipeline_port_in_create(p, &port_params, - &port_in_id[i]); - if (ret) { - rte_panic("Unable to configure input port %d, ret:%d\n", - i, ret); - goto fail; - } - } - - /* output Port configuration */ - for (i = 0; i < N_PORTS; i++) { - struct rte_port_ring_writer_params port_ring_params = { - .ring = rings_tx[i], - .tx_burst_sz = BURST_SIZE, - }; - - struct rte_pipeline_port_out_params port_params = { - .ops = &rte_port_ring_writer_ops, - .arg_create = (void *) &port_ring_params, - .f_action = NULL, - .arg_ah = NULL, - }; - - if (i) - port_params.f_action = port_out_action; - - if (rte_pipeline_port_out_create(p, &port_params, - &port_out_id[i])) { - rte_panic("Unable to configure output port %d\n", i); - goto fail; - } - } - - /* Table configuration */ - for (i = 0; i < N_PORTS; i++) { - struct rte_pipeline_table_params table_params = { - .ops = &rte_table_stub_ops, - .arg_create = NULL, - .f_action_hit = action_handler_hit, - .f_action_miss = action_handler_miss, - .action_data_size = 0, - }; - - if (rte_pipeline_table_create(p, &table_params, &table_id[i])) { - rte_panic("Unable to configure table %u\n", i); - goto fail; - } - - if (connect_miss_action_to_table) - if (rte_pipeline_table_create(p, &table_params, - &table_id[i+2])) { - rte_panic("Unable to configure table %u\n", i); - goto fail; - } - } - - for (i = 0; i < N_PORTS; i++) - if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], - table_id[i])) { - rte_panic("Unable to connect input port %u to " - "table %u\n", port_in_id[i], table_id[i]); - goto fail; - } - - /* Add entries to tables */ - for (i = 0; i < N_PORTS; i++) { - struct rte_pipeline_table_entry default_entry = { - .action = (enum rte_pipeline_action) - table_entry_default_action, - {.port_id = port_out_id[i^1]}, - }; - struct rte_pipeline_table_entry *default_entry_ptr; - - if (connect_miss_action_to_table) { - printf("Setting first table to output to next table\n"); - default_entry.action = RTE_PIPELINE_ACTION_TABLE; - default_entry.table_id = table_id[i+2]; - } - - /* Add the default action for the table. */ - ret = rte_pipeline_table_default_entry_add(p, table_id[i], - &default_entry, &default_entry_ptr); - if (ret < 0) { - rte_panic("Unable to add default entry to table %u " - "code %d\n", table_id[i], ret); - goto fail; - } else - printf("Added default entry to table id %d with " - "action %x\n", - table_id[i], default_entry.action); - - if (connect_miss_action_to_table) { - /* We create a second table so the first can pass - traffic into it */ - struct rte_pipeline_table_entry default_entry = { - .action = RTE_PIPELINE_ACTION_PORT, - {.port_id = port_out_id[i^1]}, - }; - printf("Setting secont table to output to port\n"); - - /* Add the default action for the table. */ - ret = rte_pipeline_table_default_entry_add(p, - table_id[i+2], - &default_entry, &default_entry_ptr); - if (ret < 0) { - rte_panic("Unable to add default entry to " - "table %u code %d\n", - table_id[i], ret); - goto fail; - } else - printf("Added default entry to table id %d " - "with action %x\n", - table_id[i], default_entry.action); - } - } - - /* Enable input ports */ - for (i = 0; i < N_PORTS ; i++) - if (rte_pipeline_port_in_enable(p, port_in_id[i])) - rte_panic("Unable to enable input port %u\n", - port_in_id[i]); - - /* Check pipeline consistency */ - if (rte_pipeline_check(p) < 0) { - rte_panic("Pipeline consistency check failed\n"); - goto fail; - } else - printf("Pipeline Consistency OK!\n"); - - return 0; -fail: - - return -1; -} - -static int -test_pipeline_single_filter(int test_type, int expected_count) -{ - int i; - int j; - int ret; - int tx_count; - - RTE_LOG(INFO, PIPELINE, "%s: **** Running %s test\n", - __func__, pipeline_test_names[test_type]); - /* Run pipeline once */ - for (i = 0; i < N_PORTS; i++) - rte_pipeline_run(p); - - - ret = rte_pipeline_flush(NULL); - if (ret != -EINVAL) { - RTE_LOG(INFO, PIPELINE, - "%s: No pipeline flush error NULL pipeline (%d)\n", - __func__, ret); - goto fail; - } - - /* - * Allocate a few mbufs and manually insert into the rings. */ - for (i = 0; i < N_PORTS; i++) - for (j = 0; j < N_PORTS; j++) { - struct rte_mbuf *m; - uint8_t *key; - uint32_t *k32; - - m = rte_pktmbuf_alloc(pool); - if (m == NULL) { - rte_panic("Failed to alloc mbuf from pool\n"); - return -1; - } - key = RTE_MBUF_METADATA_UINT8_PTR(m, - APP_METADATA_OFFSET(32)); - - k32 = (uint32_t *) key; - k32[0] = 0xadadadad >> (j % 2); - - RTE_LOG(INFO, PIPELINE, "%s: Enqueue onto ring %d\n", - __func__, i); - rte_ring_enqueue(rings_rx[i], m); - } - - /* Run pipeline once */ - for (i = 0; i < N_PORTS; i++) - rte_pipeline_run(p); - - /* - * need to flush the pipeline, as there may be less hits than the burst - size and they will not have been flushed to the tx rings. */ - rte_pipeline_flush(p); - - /* - * Now we'll see what we got back on the tx rings. We should see whatever - * packets we had hits on that were destined for the output ports. - */ - tx_count = 0; - - for (i = 0; i < N_PORTS; i++) { - void *objs[RING_TX_SIZE]; - struct rte_mbuf *mbuf; - - ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10); - if (ret <= 0) - printf("Got no objects from ring %d - error code %d\n", - i, ret); - else { - printf("Got %d object(s) from ring %d!\n", ret, i); - for (j = 0; j < ret; j++) { - mbuf = (struct rte_mbuf *)objs[j]; - rte_hexdump(stdout, "Object:", - rte_pktmbuf_mtod(mbuf, char *), - mbuf->data_len); - rte_pktmbuf_free(mbuf); - } - tx_count += ret; - } - } - - if (tx_count != expected_count) { - RTE_LOG(INFO, PIPELINE, - "%s: Unexpected packets out for %s test, expected %d, " - "got %d\n", __func__, pipeline_test_names[test_type], - expected_count, tx_count); - goto fail; - } - - cleanup_pipeline(); - - return 0; -fail: - return -1; - -} - -int -test_table_pipeline(void) -{ - /* TEST - All packets dropped */ - action_handler_hit = NULL; - action_handler_miss = NULL; - table_entry_default_action = RTE_PIPELINE_ACTION_DROP; - setup_pipeline(e_TEST_STUB); - if (test_pipeline_single_filter(e_TEST_STUB, 0) < 0) - return -1; - - /* TEST - All packets passed through */ - table_entry_default_action = RTE_PIPELINE_ACTION_PORT; - setup_pipeline(e_TEST_STUB); - if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0) - return -1; - - /* TEST - one packet per port */ - action_handler_hit = NULL; - action_handler_miss = - (rte_pipeline_table_action_handler_miss) table_action_stub_miss; - table_entry_default_action = RTE_PIPELINE_ACTION_PORT; - override_miss_mask = 0x01; /* one packet per port */ - setup_pipeline(e_TEST_STUB); - if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0) - return -1; - - /* TEST - one packet per port */ - override_miss_mask = 0x02; /*all per port */ - setup_pipeline(e_TEST_STUB); - if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0) - return -1; - - /* TEST - all packets per port */ - override_miss_mask = 0x03; /*all per port */ - setup_pipeline(e_TEST_STUB); - if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0) - return -1; - - /* - * This test will set up two tables in the pipeline. the first table - * will forward to another table on miss, and the second table will - * forward to port. - */ - connect_miss_action_to_table = 1; - table_entry_default_action = RTE_PIPELINE_ACTION_TABLE; - action_handler_hit = NULL; /* not for stub, hitmask always zero */ - action_handler_miss = NULL; - setup_pipeline(e_TEST_STUB); - if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0) - return -1; - connect_miss_action_to_table = 0; - - printf("TEST - two tables, hitmask override to 0x01\n"); - connect_miss_action_to_table = 1; - action_handler_miss = - (rte_pipeline_table_action_handler_miss)table_action_stub_miss; - override_miss_mask = 0x01; - setup_pipeline(e_TEST_STUB); - if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0) - return -1; - connect_miss_action_to_table = 0; - - if (check_pipeline_invalid_params()) { - RTE_LOG(INFO, PIPELINE, "%s: Check pipeline invalid params " - "failed.\n", __func__); - return -1; - } - - return 0; -} diff --git a/app/test/test_table_pipeline.h b/app/test/test_table_pipeline.h deleted file mode 100644 index b3f20ba38e..0000000000 --- a/app/test/test_table_pipeline.h +++ /dev/null @@ -1,35 +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. - */ - -/* Test prototypes */ -int test_table_pipeline(void); diff --git a/app/test/test_table_ports.c b/app/test/test_table_ports.c deleted file mode 100644 index 2532367789..0000000000 --- a/app/test/test_table_ports.c +++ /dev/null @@ -1,220 +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 "test_table_ports.h" -#include "test_table.h" - -port_test port_tests[] = { - test_port_ring_reader, - test_port_ring_writer, -}; - -unsigned n_port_tests = RTE_DIM(port_tests); - -/* Port tests */ -int -test_port_ring_reader(void) -{ - int status, i; - struct rte_port_ring_reader_params port_ring_reader_params; - void *port; - - /* Invalid params */ - port = rte_port_ring_reader_ops.f_create(NULL, 0); - if (port != NULL) - return -1; - - status = rte_port_ring_reader_ops.f_free(port); - if (status >= 0) - return -2; - - /* Create and free */ - port_ring_reader_params.ring = RING_RX; - port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0); - if (port == NULL) - return -3; - - status = rte_port_ring_reader_ops.f_free(port); - if (status != 0) - return -4; - - /* -- Traffic RX -- */ - int expected_pkts, received_pkts; - struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX]; - void *mbuf[RTE_PORT_IN_BURST_SIZE_MAX]; - - port_ring_reader_params.ring = RING_RX; - port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0); - - /* Single packet */ - mbuf[0] = (void *)rte_pktmbuf_alloc(pool); - - expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring, - mbuf, 1); - received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf, 1); - - if (received_pkts < expected_pkts) - return -5; - - rte_pktmbuf_free(res_mbuf[0]); - - /* Multiple packets */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - mbuf[i] = rte_pktmbuf_alloc(pool); - - expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring, - (void * const *) mbuf, RTE_PORT_IN_BURST_SIZE_MAX); - received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf, - RTE_PORT_IN_BURST_SIZE_MAX); - - if (received_pkts < expected_pkts) - return -6; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(res_mbuf[i]); - - return 0; -} - -int -test_port_ring_writer(void) -{ - int status, i; - struct rte_port_ring_writer_params port_ring_writer_params; - void *port; - - /* Invalid params */ - port = rte_port_ring_writer_ops.f_create(NULL, 0); - if (port != NULL) - return -1; - - status = rte_port_ring_writer_ops.f_free(port); - if (status >= 0) - return -2; - - port_ring_writer_params.ring = NULL; - - port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0); - if (port != NULL) - return -3; - - port_ring_writer_params.ring = RING_TX; - port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX + 1; - - port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0); - if (port != NULL) - return -4; - - /* Create and free */ - port_ring_writer_params.ring = RING_TX; - port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX; - - port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0); - if (port == NULL) - return -5; - - status = rte_port_ring_writer_ops.f_free(port); - if (status != 0) - return -6; - - /* -- Traffic TX -- */ - int expected_pkts, received_pkts; - struct rte_mbuf *mbuf[RTE_PORT_IN_BURST_SIZE_MAX]; - struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX]; - - port_ring_writer_params.ring = RING_TX; - port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX; - port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0); - - /* Single packet */ - mbuf[0] = rte_pktmbuf_alloc(pool); - - rte_port_ring_writer_ops.f_tx(port, mbuf[0]); - rte_port_ring_writer_ops.f_flush(port); - expected_pkts = 1; - received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring, - (void **)res_mbuf, port_ring_writer_params.tx_burst_sz); - - if (received_pkts < expected_pkts) - return -7; - - rte_pktmbuf_free(res_mbuf[0]); - - /* Multiple packets */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) { - mbuf[i] = rte_pktmbuf_alloc(pool); - rte_port_ring_writer_ops.f_tx(port, mbuf[i]); - } - - expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX; - received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring, - (void **)res_mbuf, port_ring_writer_params.tx_burst_sz); - - if (received_pkts < expected_pkts) - return -8; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(res_mbuf[i]); - - /* TX Bulk */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - mbuf[i] = rte_pktmbuf_alloc(pool); - rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-1); - - expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX; - received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring, - (void **)res_mbuf, port_ring_writer_params.tx_burst_sz); - - if (received_pkts < expected_pkts) - return -8; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(res_mbuf[i]); - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - mbuf[i] = rte_pktmbuf_alloc(pool); - rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-3); - rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)2); - - expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX; - received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring, - (void **)res_mbuf, port_ring_writer_params.tx_burst_sz); - - if (received_pkts < expected_pkts) - return -9; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(res_mbuf[i]); - - return 0; -} diff --git a/app/test/test_table_ports.h b/app/test/test_table_ports.h deleted file mode 100644 index 512b77fe4d..0000000000 --- a/app/test/test_table_ports.h +++ /dev/null @@ -1,42 +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. - */ - -/* Test prototypes */ -int test_port_ring_reader(void); -int test_port_ring_writer(void); - -/* Extern variables */ -typedef int (*port_test)(void); - -extern port_test port_tests[]; -extern unsigned n_port_tests; diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c deleted file mode 100644 index d835eb9f5d..0000000000 --- a/app/test/test_table_tables.c +++ /dev/null @@ -1,1109 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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 -#include -#include -#include -#include -#include "test_table_tables.h" -#include "test_table.h" - -table_test table_tests[] = { - test_table_stub, - test_table_array, - test_table_lpm, - test_table_lpm_ipv6, - test_table_hash_lru, - test_table_hash_ext, - test_table_hash_cuckoo, -}; - -#define PREPARE_PACKET(mbuf, value) do { \ - uint32_t *k32, *signature; \ - uint8_t *key; \ - mbuf = rte_pktmbuf_alloc(pool); \ - signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \ - APP_METADATA_OFFSET(0)); \ - key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \ - APP_METADATA_OFFSET(32)); \ - memset(key, 0, 32); \ - k32 = (uint32_t *) key; \ - k32[0] = (value); \ - *signature = pipeline_test_hash(key, 0, 0); \ -} while (0) - -unsigned n_table_tests = RTE_DIM(table_tests); - -/* Function prototypes */ -static int -test_table_hash_lru_generic(struct rte_table_ops *ops); -static int -test_table_hash_ext_generic(struct rte_table_ops *ops); - -struct rte_bucket_4_8 { - /* Cache line 0 */ - uint64_t signature; - uint64_t lru_list; - struct rte_bucket_4_8 *next; - uint64_t next_valid; - uint64_t key[4]; - /* Cache line 1 */ - uint8_t data[0]; -}; - -#if RTE_TABLE_HASH_LRU_STRATEGY == 3 -uint64_t shuffles = 0xfffffffdfffbfff9ULL; -#else -uint64_t shuffles = 0x0003000200010000ULL; -#endif - -static int test_lru_update(void) -{ - struct rte_bucket_4_8 b; - struct rte_bucket_4_8 *bucket; - uint32_t i; - uint64_t pos; - uint64_t iterations; - uint64_t j; - int poss; - - printf("---------------------------\n"); - printf("Testing lru_update macro...\n"); - printf("---------------------------\n"); - bucket = &b; - iterations = 10; -#if RTE_TABLE_HASH_LRU_STRATEGY == 3 - bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL; -#else - bucket->lru_list = 0x0000000100020003ULL; -#endif - poss = 0; - for (j = 0; j < iterations; j++) - for (i = 0; i < 9; i++) { - uint32_t idx = i >> 1; - lru_update(bucket, idx); - pos = lru_pos(bucket); - poss += pos; - printf("%s: %d lru_list=%016"PRIx64", upd=%d, " - "pos=%"PRIx64"\n", - __func__, i, bucket->lru_list, i>>1, pos); - } - - if (bucket->lru_list != shuffles) { - printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016" - PRIx64"\n", - __func__, i, bucket->lru_list, shuffles); - return -1; - } - printf("%s: output checksum of results =%d\n", - __func__, poss); -#if 0 - if (poss != 126) { - printf("%s: ERROR output checksum of results =%d expected %d\n", - __func__, poss, 126); - return -1; - } -#endif - - fflush(stdout); - - uint64_t sc_start = rte_rdtsc(); - iterations = 100000000; - poss = 0; - for (j = 0; j < iterations; j++) { - for (i = 0; i < 4; i++) { - lru_update(bucket, i); - pos |= bucket->lru_list; - } - } - uint64_t sc_end = rte_rdtsc(); - - printf("%s: output checksum of results =%llu\n", - __func__, (long long unsigned int)pos); - printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n", - __func__, sc_start, sc_end); - printf("\nlru_update: %lu cycles per loop iteration.\n\n", - (long unsigned int)((sc_end-sc_start)/(iterations*4))); - - return 0; -} - -/* Table tests */ -int -test_table_stub(void) -{ - int i; - uint64_t expected_mask = 0, result_mask; - struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; - void *table; - char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; - - /* Create */ - table = rte_table_stub_ops.f_create(NULL, 0, 1); - if (table == NULL) - return -1; - - /* Traffic flow */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - if (i % 2 == 0) - PREPARE_PACKET(mbufs[i], 0xadadadad); - else - PREPARE_PACKET(mbufs[i], 0xadadadab); - - expected_mask = 0; - rte_table_stub_ops.f_lookup(table, mbufs, -1, - &result_mask, (void **)entries); - if (result_mask != expected_mask) - return -2; - - /* Free resources */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(mbufs[i]); - - return 0; -} - -int -test_table_array(void) -{ - int status, i; - uint64_t result_mask; - struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; - void *table; - char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; - char entry1, entry2; - void *entry_ptr; - int key_found; - - /* Initialize params and create tables */ - struct rte_table_array_params array_params = { - .n_entries = 7, - .offset = APP_METADATA_OFFSET(1) - }; - - table = rte_table_array_ops.f_create(NULL, 0, 1); - if (table != NULL) - return -1; - - array_params.n_entries = 0; - - table = rte_table_array_ops.f_create(&array_params, 0, 1); - if (table != NULL) - return -2; - - array_params.n_entries = 7; - - table = rte_table_array_ops.f_create(&array_params, 0, 1); - if (table != NULL) - return -3; - - array_params.n_entries = 1 << 24; - array_params.offset = APP_METADATA_OFFSET(1); - - table = rte_table_array_ops.f_create(&array_params, 0, 1); - if (table == NULL) - return -4; - - array_params.offset = APP_METADATA_OFFSET(32); - - table = rte_table_array_ops.f_create(&array_params, 0, 1); - if (table == NULL) - return -5; - - /* Free */ - status = rte_table_array_ops.f_free(table); - if (status < 0) - return -6; - - status = rte_table_array_ops.f_free(NULL); - if (status == 0) - return -7; - - /* Add */ - struct rte_table_array_key array_key_1 = { - .pos = 10, - }; - struct rte_table_array_key array_key_2 = { - .pos = 20, - }; - entry1 = 'A'; - entry2 = 'B'; - - table = rte_table_array_ops.f_create(&array_params, 0, 1); - if (table == NULL) - return -8; - - status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1, - &key_found, &entry_ptr); - if (status == 0) - return -9; - - status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL, - &key_found, &entry_ptr); - if (status == 0) - return -10; - - status = rte_table_array_ops.f_add(table, (void *) &array_key_1, - &entry1, &key_found, &entry_ptr); - if (status != 0) - return -11; - - /* Traffic flow */ - status = rte_table_array_ops.f_add(table, (void *) &array_key_2, - &entry2, &key_found, &entry_ptr); - if (status != 0) - return -12; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - if (i % 2 == 0) - PREPARE_PACKET(mbufs[i], 10); - else - PREPARE_PACKET(mbufs[i], 20); - - rte_table_array_ops.f_lookup(table, mbufs, -1, - &result_mask, (void **)entries); - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - if (i % 2 == 0 && *entries[i] != 'A') - return -13; - else - if (i % 2 == 1 && *entries[i] != 'B') - return -13; - - /* Free resources */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(mbufs[i]); - - status = rte_table_array_ops.f_free(table); - - return 0; -} - -int -test_table_lpm(void) -{ - int status, i; - uint64_t expected_mask = 0, result_mask; - struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; - void *table; - char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; - char entry; - void *entry_ptr; - int key_found; - uint32_t entry_size = 1; - - /* Initialize params and create tables */ - struct rte_table_lpm_params lpm_params = { - .name = "LPM", - .n_rules = 1 << 24, - .number_tbl8s = 1 << 8, - .flags = 0, - .entry_unique_size = entry_size, - .offset = APP_METADATA_OFFSET(1) - }; - - table = rte_table_lpm_ops.f_create(NULL, 0, entry_size); - if (table != NULL) - return -1; - - lpm_params.name = NULL; - - table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -2; - - lpm_params.name = "LPM"; - lpm_params.n_rules = 0; - - table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -3; - - lpm_params.n_rules = 1 << 24; - lpm_params.offset = APP_METADATA_OFFSET(32); - lpm_params.entry_unique_size = 0; - - table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -4; - - lpm_params.entry_unique_size = entry_size + 1; - - table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -5; - - lpm_params.entry_unique_size = entry_size; - - table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); - if (table == NULL) - return -6; - - /* Free */ - status = rte_table_lpm_ops.f_free(table); - if (status < 0) - return -7; - - status = rte_table_lpm_ops.f_free(NULL); - if (status == 0) - return -8; - - /* Add */ - struct rte_table_lpm_key lpm_key; - lpm_key.ip = 0xadadadad; - - table = rte_table_lpm_ops.f_create(&lpm_params, 0, 1); - if (table == NULL) - return -9; - - status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found, - &entry_ptr); - if (status == 0) - return -10; - - status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found, - &entry_ptr); - if (status == 0) - return -11; - - status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found, - &entry_ptr); - if (status == 0) - return -12; - - lpm_key.depth = 0; - status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, - &entry_ptr); - if (status == 0) - return -13; - - lpm_key.depth = 33; - status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, - &entry_ptr); - if (status == 0) - return -14; - - lpm_key.depth = 16; - status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, - &entry_ptr); - if (status != 0) - return -15; - - /* Delete */ - status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL); - if (status == 0) - return -16; - - status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL); - if (status == 0) - return -17; - - lpm_key.depth = 0; - status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); - if (status == 0) - return -18; - - lpm_key.depth = 33; - status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); - if (status == 0) - return -19; - - lpm_key.depth = 16; - status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); - if (status != 0) - return -20; - - status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); - if (status != 0) - return -21; - - /* Traffic flow */ - entry = 'A'; - status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, - &entry_ptr); - if (status < 0) - return -22; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - if (i % 2 == 0) { - expected_mask |= (uint64_t)1 << i; - PREPARE_PACKET(mbufs[i], 0xadadadad); - } else - PREPARE_PACKET(mbufs[i], 0xadadadab); - - rte_table_lpm_ops.f_lookup(table, mbufs, -1, - &result_mask, (void **)entries); - if (result_mask != expected_mask) - return -23; - - /* Free resources */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(mbufs[i]); - - status = rte_table_lpm_ops.f_free(table); - - return 0; -} - -int -test_table_lpm_ipv6(void) -{ - int status, i; - uint64_t expected_mask = 0, result_mask; - struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; - void *table; - char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; - char entry; - void *entry_ptr; - int key_found; - uint32_t entry_size = 1; - - /* Initialize params and create tables */ - struct rte_table_lpm_ipv6_params lpm_params = { - .name = "LPM", - .n_rules = 1 << 24, - .number_tbl8s = 1 << 21, - .entry_unique_size = entry_size, - .offset = APP_METADATA_OFFSET(32) - }; - - table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size); - if (table != NULL) - return -1; - - lpm_params.name = NULL; - - table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -2; - - lpm_params.name = "LPM"; - lpm_params.n_rules = 0; - - table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -3; - - lpm_params.n_rules = 1 << 24; - lpm_params.number_tbl8s = 0; - table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -4; - - lpm_params.number_tbl8s = 1 << 21; - lpm_params.entry_unique_size = 0; - table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -5; - - lpm_params.entry_unique_size = entry_size + 1; - table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); - if (table != NULL) - return -6; - - lpm_params.entry_unique_size = entry_size; - lpm_params.offset = APP_METADATA_OFFSET(32); - - table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); - if (table == NULL) - return -7; - - /* Free */ - status = rte_table_lpm_ipv6_ops.f_free(table); - if (status < 0) - return -8; - - status = rte_table_lpm_ipv6_ops.f_free(NULL); - if (status == 0) - return -9; - - /* Add */ - struct rte_table_lpm_ipv6_key lpm_key; - - lpm_key.ip[0] = 0xad; - lpm_key.ip[1] = 0xad; - lpm_key.ip[2] = 0xad; - lpm_key.ip[3] = 0xad; - - table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); - if (table == NULL) - return -10; - - status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry, - &key_found, &entry_ptr); - if (status == 0) - return -11; - - status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found, - &entry_ptr); - if (status == 0) - return -12; - - status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found, - &entry_ptr); - if (status == 0) - return -13; - - lpm_key.depth = 0; - status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, - &key_found, &entry_ptr); - if (status == 0) - return -14; - - lpm_key.depth = 129; - status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, - &key_found, &entry_ptr); - if (status == 0) - return -15; - - lpm_key.depth = 16; - status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, - &key_found, &entry_ptr); - if (status != 0) - return -16; - - /* Delete */ - status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found, - NULL); - if (status == 0) - return -17; - - status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL); - if (status == 0) - return -18; - - lpm_key.depth = 0; - status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, - NULL); - if (status == 0) - return -19; - - lpm_key.depth = 129; - status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, - NULL); - if (status == 0) - return -20; - - lpm_key.depth = 16; - status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, - NULL); - if (status != 0) - return -21; - - status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, - NULL); - if (status != 0) - return -22; - - /* Traffic flow */ - entry = 'A'; - status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, - &key_found, &entry_ptr); - if (status < 0) - return -23; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - if (i % 2 == 0) { - expected_mask |= (uint64_t)1 << i; - PREPARE_PACKET(mbufs[i], 0xadadadad); - } else - PREPARE_PACKET(mbufs[i], 0xadadadab); - - rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1, - &result_mask, (void **)entries); - if (result_mask != expected_mask) - return -24; - - /* Free resources */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(mbufs[i]); - - status = rte_table_lpm_ipv6_ops.f_free(table); - - return 0; -} - -static int -test_table_hash_lru_generic(struct rte_table_ops *ops) -{ - int status, i; - uint64_t expected_mask = 0, result_mask; - struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; - void *table; - char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; - char entry; - void *entry_ptr; - int key_found; - - /* Initialize params and create tables */ - struct rte_table_hash_key8_lru_params hash_params = { - .n_entries = 1 << 10, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(1), - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - }; - - hash_params.n_entries = 0; - - table = ops->f_create(&hash_params, 0, 1); - if (table != NULL) - return -1; - - hash_params.n_entries = 1 << 10; - hash_params.signature_offset = APP_METADATA_OFFSET(1); - - table = ops->f_create(&hash_params, 0, 1); - if (table == NULL) - return -2; - - hash_params.signature_offset = APP_METADATA_OFFSET(0); - hash_params.key_offset = APP_METADATA_OFFSET(1); - - table = ops->f_create(&hash_params, 0, 1); - if (table == NULL) - return -3; - - hash_params.key_offset = APP_METADATA_OFFSET(32); - hash_params.f_hash = NULL; - - table = ops->f_create(&hash_params, 0, 1); - if (table != NULL) - return -4; - - hash_params.f_hash = pipeline_test_hash; - - table = ops->f_create(&hash_params, 0, 1); - if (table == NULL) - return -5; - - /* Free */ - status = ops->f_free(table); - if (status < 0) - return -6; - - status = ops->f_free(NULL); - if (status == 0) - return -7; - - /* Add */ - uint8_t key[32]; - uint32_t *k32 = (uint32_t *) &key; - - memset(key, 0, 32); - k32[0] = rte_be_to_cpu_32(0xadadadad); - - table = ops->f_create(&hash_params, 0, 1); - if (table == NULL) - return -8; - - entry = 'A'; - status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); - if (status != 0) - return -9; - - /* Delete */ - status = ops->f_delete(table, &key, &key_found, NULL); - if (status != 0) - return -10; - - status = ops->f_delete(table, &key, &key_found, NULL); - if (status != 0) - return -11; - - /* Traffic flow */ - entry = 'A'; - status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); - if (status < 0) - return -12; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - if (i % 2 == 0) { - expected_mask |= (uint64_t)1 << i; - PREPARE_PACKET(mbufs[i], 0xadadadad); - } else - PREPARE_PACKET(mbufs[i], 0xadadadab); - - ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries); - if (result_mask != expected_mask) - return -13; - - /* Free resources */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(mbufs[i]); - - status = ops->f_free(table); - - return 0; -} - -static int -test_table_hash_ext_generic(struct rte_table_ops *ops) -{ - int status, i; - uint64_t expected_mask = 0, result_mask; - struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; - void *table; - char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; - char entry; - int key_found; - void *entry_ptr; - - /* Initialize params and create tables */ - struct rte_table_hash_key8_ext_params hash_params = { - .n_entries = 1 << 10, - .n_entries_ext = 1 << 4, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(1), - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - }; - - hash_params.n_entries = 0; - - table = ops->f_create(&hash_params, 0, 1); - if (table != NULL) - return -1; - - hash_params.n_entries = 1 << 10; - hash_params.n_entries_ext = 0; - table = ops->f_create(&hash_params, 0, 1); - if (table != NULL) - return -2; - - hash_params.n_entries_ext = 1 << 4; - hash_params.signature_offset = APP_METADATA_OFFSET(1); - table = ops->f_create(&hash_params, 0, 1); - if (table == NULL) - return -2; - - hash_params.signature_offset = APP_METADATA_OFFSET(0); - hash_params.key_offset = APP_METADATA_OFFSET(1); - - table = ops->f_create(&hash_params, 0, 1); - if (table == NULL) - return -3; - - hash_params.key_offset = APP_METADATA_OFFSET(32); - hash_params.f_hash = NULL; - - table = ops->f_create(&hash_params, 0, 1); - if (table != NULL) - return -4; - - hash_params.f_hash = pipeline_test_hash; - - table = ops->f_create(&hash_params, 0, 1); - if (table == NULL) - return -5; - - /* Free */ - status = ops->f_free(table); - if (status < 0) - return -6; - - status = ops->f_free(NULL); - if (status == 0) - return -7; - - /* Add */ - uint8_t key[32]; - uint32_t *k32 = (uint32_t *) &key; - - memset(key, 0, 32); - k32[0] = rte_be_to_cpu_32(0xadadadad); - - table = ops->f_create(&hash_params, 0, 1); - if (table == NULL) - return -8; - - entry = 'A'; - status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); - if (status != 0) - return -9; - - /* Delete */ - status = ops->f_delete(table, &key, &key_found, NULL); - if (status != 0) - return -10; - - status = ops->f_delete(table, &key, &key_found, NULL); - if (status != 0) - return -11; - - /* Traffic flow */ - entry = 'A'; - status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); - if (status < 0) - return -12; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - if (i % 2 == 0) { - expected_mask |= (uint64_t)1 << i; - PREPARE_PACKET(mbufs[i], 0xadadadad); - } else - PREPARE_PACKET(mbufs[i], 0xadadadab); - - ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries); - if (result_mask != expected_mask) - return -13; - - /* Free resources */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(mbufs[i]); - - status = ops->f_free(table); - - return 0; -} - -int -test_table_hash_lru(void) -{ - int status; - - status = test_table_hash_lru_generic(&rte_table_hash_key8_lru_ops); - if (status < 0) - return status; - - status = test_table_hash_lru_generic( - &rte_table_hash_key8_lru_dosig_ops); - if (status < 0) - return status; - - status = test_table_hash_lru_generic(&rte_table_hash_key16_lru_ops); - if (status < 0) - return status; - - status = test_table_hash_lru_generic(&rte_table_hash_key32_lru_ops); - if (status < 0) - return status; - - status = test_lru_update(); - if (status < 0) - return status; - - return 0; -} - -int -test_table_hash_ext(void) -{ - int status; - - status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops); - if (status < 0) - return status; - - status = test_table_hash_ext_generic( - &rte_table_hash_key8_ext_dosig_ops); - if (status < 0) - return status; - - status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops); - if (status < 0) - return status; - - status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops); - if (status < 0) - return status; - - return 0; -} - - -int -test_table_hash_cuckoo(void) -{ - int status, i; - uint64_t expected_mask = 0, result_mask; - struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; - void *table; - char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; - char entry; - void *entry_ptr; - int key_found; - uint32_t entry_size = 1; - - /* Initialize params and create tables */ - struct rte_table_hash_cuckoo_params cuckoo_params = { - .key_size = 32, - .n_keys = 1 << 24, - .f_hash = pipeline_test_hash, - .seed = 0, - .signature_offset = APP_METADATA_OFFSET(0), - .key_offset = APP_METADATA_OFFSET(32), - .name = "CUCKOO", - }; - - table = rte_table_hash_cuckoo_dosig_ops.f_create(NULL, 0, entry_size); - if (table != NULL) - return -1; - - cuckoo_params.key_size = 0; - - table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, - 0, entry_size); - if (table != NULL) - return -2; - - cuckoo_params.key_size = 32; - cuckoo_params.n_keys = 0; - - table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, - 0, entry_size); - if (table != NULL) - return -3; - - cuckoo_params.n_keys = 1 << 24; - cuckoo_params.f_hash = NULL; - - table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, - 0, entry_size); - if (table != NULL) - return -4; - - cuckoo_params.f_hash = pipeline_test_hash; - cuckoo_params.name = NULL; - - table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, - 0, entry_size); - if (table != NULL) - return -5; - - cuckoo_params.name = "CUCKOO"; - - table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, - 0, entry_size); - if (table == NULL) - return -6; - - /* Free */ - status = rte_table_hash_cuckoo_dosig_ops.f_free(table); - if (status < 0) - return -7; - - status = rte_table_hash_cuckoo_dosig_ops.f_free(NULL); - if (status == 0) - return -8; - - /* Add */ - uint8_t key_cuckoo[32]; - uint32_t *kcuckoo = (uint32_t *) &key_cuckoo; - - memset(key_cuckoo, 0, 32); - kcuckoo[0] = rte_be_to_cpu_32(0xadadadad); - - table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, 0, 1); - if (table == NULL) - return -9; - - entry = 'A'; - status = rte_table_hash_cuckoo_dosig_ops.f_add(NULL, &key_cuckoo, - &entry, &key_found, &entry_ptr); - if (status == 0) - return -10; - - status = rte_table_hash_cuckoo_dosig_ops.f_add(table, NULL, &entry, - &key_found, &entry_ptr); - if (status == 0) - return -11; - - status = rte_table_hash_cuckoo_dosig_ops.f_add(table, &key_cuckoo, - NULL, &key_found, &entry_ptr); - if (status == 0) - return -12; - - status = rte_table_hash_cuckoo_dosig_ops.f_add(table, &key_cuckoo, - &entry, &key_found, &entry_ptr); - if (status != 0) - return -13; - - status = rte_table_hash_cuckoo_dosig_ops.f_add(table, &key_cuckoo, - &entry, &key_found, &entry_ptr); - if (status != 0) - return -14; - - /* Delete */ - status = rte_table_hash_cuckoo_dosig_ops.f_delete(NULL, &key_cuckoo, - &key_found, NULL); - if (status == 0) - return -15; - - status = rte_table_hash_cuckoo_dosig_ops.f_delete(table, NULL, - &key_found, NULL); - if (status == 0) - return -16; - - status = rte_table_hash_cuckoo_dosig_ops.f_delete(table, &key_cuckoo, - &key_found, NULL); - if (status != 0) - return -17; - - status = rte_table_hash_cuckoo_dosig_ops.f_delete(table, &key_cuckoo, - &key_found, NULL); - if (status != -ENOENT) - return -18; - - /* Traffic flow */ - entry = 'A'; - status = rte_table_hash_cuckoo_dosig_ops.f_add(table, &key_cuckoo, - &entry, &key_found, - &entry_ptr); - if (status < 0) - return -19; - - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - if (i % 2 == 0) { - expected_mask |= (uint64_t)1 << i; - PREPARE_PACKET(mbufs[i], 0xadadadad); - } else - PREPARE_PACKET(mbufs[i], 0xadadadab); - - rte_table_hash_cuckoo_dosig_ops.f_lookup(table, mbufs, -1, - &result_mask, (void **)entries); - if (result_mask != expected_mask) - return -20; - - /* Free resources */ - for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) - rte_pktmbuf_free(mbufs[i]); - - status = rte_table_hash_cuckoo_dosig_ops.f_free(table); - - return 0; -} - diff --git a/app/test/test_table_tables.h b/app/test/test_table_tables.h deleted file mode 100644 index 35311362bb..0000000000 --- a/app/test/test_table_tables.h +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-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. - */ - -/* Test prototypes */ -int test_table_hash_cuckoo(void); -int test_table_lpm(void); -int test_table_lpm_ipv6(void); -int test_table_array(void); -#ifdef RTE_LIBRTE_ACL -int test_table_acl(void); -#endif -int test_table_hash_unoptimized(void); -int test_table_hash_lru(void); -int test_table_hash_ext(void); -int test_table_stub(void); - -/* Extern variables */ -typedef int (*table_test)(void); - -extern table_test table_tests[]; -extern unsigned n_table_tests; diff --git a/app/test/test_tailq.c b/app/test/test_tailq.c deleted file mode 100644 index 33a3e8a9c8..0000000000 --- a/app/test/test_tailq.c +++ /dev/null @@ -1,157 +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 -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "test.h" - -#define do_return(...) do { \ - printf("Error at %s, line %d: ", __func__, __LINE__); \ - printf(__VA_ARGS__); \ - return 1; \ -} while (0) - -static struct rte_tailq_elem rte_dummy_tailq = { - .name = "dummy", -}; -EAL_REGISTER_TAILQ(rte_dummy_tailq) - -static struct rte_tailq_elem rte_dummy_dyn_tailq = { - .name = "dummy_dyn", -}; -static struct rte_tailq_elem rte_dummy_dyn2_tailq = { - .name = "dummy_dyn", -}; - -static struct rte_tailq_entry d_elem; -static struct rte_tailq_entry d_dyn_elem; - -static int -test_tailq_early(void) -{ - struct rte_tailq_entry_head *d_head; - - d_head = RTE_TAILQ_CAST(rte_dummy_tailq.head, rte_tailq_entry_head); - if (d_head == NULL) - do_return("Error %s has not been initialised\n", - rte_dummy_tailq.name); - - /* check we can add an item to it */ - TAILQ_INSERT_TAIL(d_head, &d_elem, next); - - return 0; -} - -static int -test_tailq_create(void) -{ - struct rte_tailq_entry_head *d_head; - - /* create a tailq and check its non-null (since we are post-eal init) */ - if ((rte_eal_tailq_register(&rte_dummy_dyn_tailq) < 0) || - (rte_dummy_dyn_tailq.head == NULL)) - do_return("Error allocating %s\n", rte_dummy_dyn_tailq.name); - - d_head = RTE_TAILQ_CAST(rte_dummy_dyn_tailq.head, rte_tailq_entry_head); - - /* check we can add an item to it */ - TAILQ_INSERT_TAIL(d_head, &d_dyn_elem, next); - - if (strcmp(rte_dummy_dyn2_tailq.name, rte_dummy_dyn_tailq.name)) - do_return("Error, something is wrong in the tailq test\n"); - - /* try allocating again, and check for failure */ - if (!rte_eal_tailq_register(&rte_dummy_dyn2_tailq)) - do_return("Error, registering the same tailq %s did not fail\n", - rte_dummy_dyn2_tailq.name); - - return 0; -} - -static int -test_tailq_lookup(void) -{ - /* run successful test - check result is found */ - struct rte_tailq_entry_head *d_head; - struct rte_tailq_entry *d_ptr; - - d_head = RTE_TAILQ_LOOKUP(rte_dummy_tailq.name, rte_tailq_entry_head); - /* rte_dummy_tailq has been registered by EAL_REGISTER_TAILQ */ - if (d_head == NULL || - d_head != RTE_TAILQ_CAST(rte_dummy_tailq.head, rte_tailq_entry_head)) - do_return("Error with tailq lookup\n"); - - TAILQ_FOREACH(d_ptr, d_head, next) - if (d_ptr != &d_elem) - do_return("Error with tailq returned from lookup - " - "expected element not found\n"); - - d_head = RTE_TAILQ_LOOKUP(rte_dummy_dyn_tailq.name, rte_tailq_entry_head); - /* rte_dummy_dyn_tailq has been registered by test_tailq_create */ - if (d_head == NULL || - d_head != RTE_TAILQ_CAST(rte_dummy_dyn_tailq.head, rte_tailq_entry_head)) - do_return("Error with tailq lookup\n"); - - TAILQ_FOREACH(d_ptr, d_head, next) - if (d_ptr != &d_dyn_elem) - do_return("Error with tailq returned from lookup - " - "expected element not found\n"); - - /* now try a bad/error lookup */ - d_head = RTE_TAILQ_LOOKUP("coucou", rte_tailq_entry_head); - if (d_head != NULL) - do_return("Error, lookup does not return NULL for bad tailq name\n"); - - return 0; -} - -static int -test_tailq(void) -{ - int ret = 0; - ret |= test_tailq_early(); - ret |= test_tailq_create(); - ret |= test_tailq_lookup(); - return ret; -} - -REGISTER_TEST_COMMAND(tailq_autotest, test_tailq); diff --git a/app/test/test_thash.c b/app/test/test_thash.c deleted file mode 100644 index 61754a9475..0000000000 --- a/app/test/test_thash.c +++ /dev/null @@ -1,172 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015 Vladimir Medvedkin - * 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 -#include -#include - -#include "test.h" - -#include - -struct test_thash_v4 { - uint32_t dst_ip; - uint32_t src_ip; - uint16_t dst_port; - uint16_t src_port; - uint32_t hash_l3; - uint32_t hash_l3l4; -}; - -struct test_thash_v6 { - uint8_t dst_ip[16]; - uint8_t src_ip[16]; - uint16_t dst_port; - uint16_t src_port; - uint32_t hash_l3; - uint32_t hash_l3l4; -}; - -/*From 82599 Datasheet 7.1.2.8.3 RSS Verification Suite*/ -struct test_thash_v4 v4_tbl[] = { -{IPv4(161, 142, 100, 80), IPv4(66, 9, 149, 187), - 1766, 2794, 0x323e8fc2, 0x51ccc178}, -{IPv4(65, 69, 140, 83), IPv4(199, 92, 111, 2), - 4739, 14230, 0xd718262a, 0xc626b0ea}, -{IPv4(12, 22, 207, 184), IPv4(24, 19, 198, 95), - 38024, 12898, 0xd2d0a5de, 0x5c2b394a}, -{IPv4(209, 142, 163, 6), IPv4(38, 27, 205, 30), - 2217, 48228, 0x82989176, 0xafc7327f}, -{IPv4(202, 188, 127, 2), IPv4(153, 39, 163, 191), - 1303, 44251, 0x5d1809c5, 0x10e828a2}, -}; - -struct test_thash_v6 v6_tbl[] = { -/*3ffe:2501:200:3::1*/ -{{0x3f, 0xfe, 0x25, 0x01, 0x02, 0x00, 0x00, 0x03, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,}, -/*3ffe:2501:200:1fff::7*/ -{0x3f, 0xfe, 0x25, 0x01, 0x02, 0x00, 0x1f, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,}, -1766, 2794, 0x2cc18cd5, 0x40207d3d}, -/*ff02::1*/ -{{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,}, -/*3ffe:501:8::260:97ff:fe40:efab*/ -{0x3f, 0xfe, 0x05, 0x01, 0x00, 0x08, 0x00, 0x00, -0x02, 0x60, 0x97, 0xff, 0xfe, 0x40, 0xef, 0xab,}, -4739, 14230, 0x0f0c461c, 0xdde51bbf}, -/*fe80::200:f8ff:fe21:67cf*/ -{{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0xf8, 0xff, 0xfe, 0x21, 0x67, 0xcf,}, -/*3ffe:1900:4545:3:200:f8ff:fe21:67cf*/ -{0x3f, 0xfe, 0x19, 0x00, 0x45, 0x45, 0x00, 0x03, -0x02, 0x00, 0xf8, 0xff, 0xfe, 0x21, 0x67, 0xcf,}, -38024, 44251, 0x4b61e985, 0x02d1feef}, -}; - -uint8_t default_rss_key[] = { -0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, -0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, -0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, -0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, -0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, -}; - -static int -test_thash(void) -{ - uint32_t i, j; - union rte_thash_tuple tuple; - uint32_t rss_l3, rss_l3l4; - uint8_t rss_key_be[RTE_DIM(default_rss_key)]; - struct ipv6_hdr ipv6_hdr; - - /* Convert RSS key*/ - rte_convert_rss_key((uint32_t *)&default_rss_key, - (uint32_t *)rss_key_be, RTE_DIM(default_rss_key)); - - - for (i = 0; i < RTE_DIM(v4_tbl); i++) { - tuple.v4.src_addr = v4_tbl[i].src_ip; - tuple.v4.dst_addr = v4_tbl[i].dst_ip; - tuple.v4.sport = v4_tbl[i].src_port; - tuple.v4.dport = v4_tbl[i].dst_port; - /*Calculate hash with original key*/ - rss_l3 = rte_softrss((uint32_t *)&tuple, - RTE_THASH_V4_L3_LEN, default_rss_key); - rss_l3l4 = rte_softrss((uint32_t *)&tuple, - RTE_THASH_V4_L4_LEN, default_rss_key); - if ((rss_l3 != v4_tbl[i].hash_l3) || - (rss_l3l4 != v4_tbl[i].hash_l3l4)) - return -1; - /*Calculate hash with converted key*/ - rss_l3 = rte_softrss_be((uint32_t *)&tuple, - RTE_THASH_V4_L3_LEN, rss_key_be); - rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, - RTE_THASH_V4_L4_LEN, rss_key_be); - if ((rss_l3 != v4_tbl[i].hash_l3) || - (rss_l3l4 != v4_tbl[i].hash_l3l4)) - return -1; - } - for (i = 0; i < RTE_DIM(v6_tbl); i++) { - /*Fill ipv6 hdr*/ - for (j = 0; j < RTE_DIM(ipv6_hdr.src_addr); j++) - ipv6_hdr.src_addr[j] = v6_tbl[i].src_ip[j]; - for (j = 0; j < RTE_DIM(ipv6_hdr.dst_addr); j++) - ipv6_hdr.dst_addr[j] = v6_tbl[i].dst_ip[j]; - /*Load and convert ipv6 address into tuple*/ - rte_thash_load_v6_addrs(&ipv6_hdr, &tuple); - tuple.v6.sport = v6_tbl[i].src_port; - tuple.v6.dport = v6_tbl[i].dst_port; - /*Calculate hash with original key*/ - rss_l3 = rte_softrss((uint32_t *)&tuple, - RTE_THASH_V6_L3_LEN, default_rss_key); - rss_l3l4 = rte_softrss((uint32_t *)&tuple, - RTE_THASH_V6_L4_LEN, default_rss_key); - if ((rss_l3 != v6_tbl[i].hash_l3) || - (rss_l3l4 != v6_tbl[i].hash_l3l4)) - return -1; - /*Calculate hash with converted key*/ - rss_l3 = rte_softrss_be((uint32_t *)&tuple, - RTE_THASH_V6_L3_LEN, rss_key_be); - rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, - RTE_THASH_V6_L4_LEN, rss_key_be); - if ((rss_l3 != v6_tbl[i].hash_l3) || - (rss_l3l4 != v6_tbl[i].hash_l3l4)) - return -1; - } - return 0; -} - -REGISTER_TEST_COMMAND(thash_autotest, test_thash); diff --git a/app/test/test_timer.c b/app/test/test_timer.c deleted file mode 100644 index 2f6525a506..0000000000 --- a/app/test/test_timer.c +++ /dev/null @@ -1,629 +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 "test.h" - -/* - * Timer - * ===== - * - * #. Stress test 1. - * - * The objective of the timer stress tests is to check that there are no - * race conditions in list and status management. This test launches, - * resets and stops the timer very often on many cores at the same - * time. - * - * - Only one timer is used for this test. - * - On each core, the rte_timer_manage() function is called from the main - * loop every 3 microseconds. - * - In the main loop, the timer may be reset (randomly, with a - * probability of 0.5 %) 100 microseconds later on a random core, or - * stopped (with a probability of 0.5 % also). - * - In callback, the timer is can be reset (randomly, with a - * probability of 0.5 %) 100 microseconds later on the same core or - * on another core (same probability), or stopped (same - * probability). - * - * # Stress test 2. - * - * The objective of this test is similar to the first in that it attempts - * to find if there are any race conditions in the timer library. However, - * it is less complex in terms of operations performed and duration, as it - * is designed to have a predictable outcome that can be tested. - * - * - A set of timers is initialized for use by the test - * - All cores then simultaneously are set to schedule all the timers at - * the same time, so conflicts should occur. - * - Then there is a delay while we wait for the timers to expire - * - Then the master lcore calls timer_manage() and we check that all - * timers have had their callbacks called exactly once - no more no less. - * - Then we repeat the process, except after setting up the timers, we have - * all cores randomly reschedule them. - * - Again we check that the expected number of callbacks has occurred when - * we call timer-manage. - * - * #. Basic test. - * - * This test performs basic functional checks of the timers. The test - * uses four different timers that are loaded and stopped under - * specific conditions in specific contexts. - * - * - Four timers are used for this test. - * - On each core, the rte_timer_manage() function is called from main loop - * every 3 microseconds. - * - * The autotest python script checks that the behavior is correct: - * - * - timer0 - * - * - At initialization, timer0 is loaded by the master core, on master core - * in "single" mode (time = 1 second). - * - In the first 19 callbacks, timer0 is reloaded on the same core, - * then, it is explicitly stopped at the 20th call. - * - At t=25s, timer0 is reloaded once by timer2. - * - * - timer1 - * - * - At initialization, timer1 is loaded by the master core, on the - * master core in "single" mode (time = 2 seconds). - * - In the first 9 callbacks, timer1 is reloaded on another - * core. After the 10th callback, timer1 is not reloaded anymore. - * - * - timer2 - * - * - At initialization, timer2 is loaded by the master core, on the - * master core in "periodical" mode (time = 1 second). - * - In the callback, when t=25s, it stops timer3 and reloads timer0 - * on the current core. - * - * - timer3 - * - * - At initialization, timer3 is loaded by the master core, on - * another core in "periodical" mode (time = 1 second). - * - It is stopped at t=25s by timer2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TEST_DURATION_S 1 /* in seconds */ -#define NB_TIMER 4 - -#define RTE_LOGTYPE_TESTTIMER RTE_LOGTYPE_USER3 - -static volatile uint64_t end_time; -static volatile int test_failed; - -struct mytimerinfo { - struct rte_timer tim; - unsigned id; - unsigned count; -}; - -static struct mytimerinfo mytiminfo[NB_TIMER]; - -static void timer_basic_cb(struct rte_timer *tim, void *arg); - -static void -mytimer_reset(struct mytimerinfo *timinfo, uint64_t ticks, - enum rte_timer_type type, unsigned tim_lcore, - rte_timer_cb_t fct) -{ - rte_timer_reset_sync(&timinfo->tim, ticks, type, tim_lcore, - fct, timinfo); -} - -/* timer callback for stress tests */ -static void -timer_stress_cb(__attribute__((unused)) struct rte_timer *tim, - __attribute__((unused)) void *arg) -{ - long r; - unsigned lcore_id = rte_lcore_id(); - uint64_t hz = rte_get_timer_hz(); - - if (rte_timer_pending(tim)) - return; - - r = rte_rand(); - if ((r & 0xff) == 0) { - mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id, - timer_stress_cb); - } - else if ((r & 0xff) == 1) { - mytimer_reset(&mytiminfo[0], hz, SINGLE, - rte_get_next_lcore(lcore_id, 0, 1), - timer_stress_cb); - } - else if ((r & 0xff) == 2) { - rte_timer_stop(&mytiminfo[0].tim); - } -} - -static int -timer_stress_main_loop(__attribute__((unused)) void *arg) -{ - uint64_t hz = rte_get_timer_hz(); - unsigned lcore_id = rte_lcore_id(); - uint64_t cur_time; - int64_t diff = 0; - long r; - - while (diff >= 0) { - - /* call the timer handler on each core */ - rte_timer_manage(); - - /* simulate the processing of a packet - * (1 us = 2000 cycles at 2 Ghz) */ - rte_delay_us(1); - - /* randomly stop or reset timer */ - r = rte_rand(); - lcore_id = rte_get_next_lcore(lcore_id, 0, 1); - if ((r & 0xff) == 0) { - /* 100 us */ - mytimer_reset(&mytiminfo[0], hz/10000, SINGLE, lcore_id, - timer_stress_cb); - } - else if ((r & 0xff) == 1) { - rte_timer_stop_sync(&mytiminfo[0].tim); - } - cur_time = rte_get_timer_cycles(); - diff = end_time - cur_time; - } - - lcore_id = rte_lcore_id(); - RTE_LOG(INFO, TESTTIMER, "core %u finished\n", lcore_id); - - return 0; -} - -/* Need to synchronize slave lcores through multiple steps. */ -enum { SLAVE_WAITING = 1, SLAVE_RUN_SIGNAL, SLAVE_RUNNING, SLAVE_FINISHED }; -static rte_atomic16_t slave_state[RTE_MAX_LCORE]; - -static void -master_init_slaves(void) -{ - unsigned i; - - RTE_LCORE_FOREACH_SLAVE(i) { - rte_atomic16_set(&slave_state[i], SLAVE_WAITING); - } -} - -static void -master_start_slaves(void) -{ - unsigned i; - - RTE_LCORE_FOREACH_SLAVE(i) { - rte_atomic16_set(&slave_state[i], SLAVE_RUN_SIGNAL); - } - RTE_LCORE_FOREACH_SLAVE(i) { - while (rte_atomic16_read(&slave_state[i]) != SLAVE_RUNNING) - rte_pause(); - } -} - -static void -master_wait_for_slaves(void) -{ - unsigned i; - - RTE_LCORE_FOREACH_SLAVE(i) { - while (rte_atomic16_read(&slave_state[i]) != SLAVE_FINISHED) - rte_pause(); - } -} - -static void -slave_wait_to_start(void) -{ - unsigned lcore_id = rte_lcore_id(); - - while (rte_atomic16_read(&slave_state[lcore_id]) != SLAVE_RUN_SIGNAL) - rte_pause(); - rte_atomic16_set(&slave_state[lcore_id], SLAVE_RUNNING); -} - -static void -slave_finish(void) -{ - unsigned lcore_id = rte_lcore_id(); - - rte_atomic16_set(&slave_state[lcore_id], SLAVE_FINISHED); -} - - -static volatile int cb_count = 0; - -/* callback for second stress test. will only be called - * on master lcore */ -static void -timer_stress2_cb(struct rte_timer *tim __rte_unused, void *arg __rte_unused) -{ - cb_count++; -} - -#define NB_STRESS2_TIMERS 8192 - -static int -timer_stress2_main_loop(__attribute__((unused)) void *arg) -{ - static struct rte_timer *timers; - int i, ret; - 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; - static rte_atomic32_t collisions; - - if (lcore_id == master) { - cb_count = 0; - test_failed = 0; - rte_atomic32_set(&collisions, 0); - master_init_slaves(); - timers = rte_malloc(NULL, sizeof(*timers) * NB_STRESS2_TIMERS, 0); - if (timers == NULL) { - printf("Test Failed\n"); - printf("- Cannot allocate memory for timers\n" ); - test_failed = 1; - master_start_slaves(); - goto cleanup; - } - for (i = 0; i < NB_STRESS2_TIMERS; i++) - rte_timer_init(&timers[i]); - master_start_slaves(); - } else { - slave_wait_to_start(); - if (test_failed) - goto cleanup; - } - - /* have all cores schedule all timers on master lcore */ - for (i = 0; i < NB_STRESS2_TIMERS; i++) { - ret = rte_timer_reset(&timers[i], delay, SINGLE, master, - timer_stress2_cb, NULL); - /* there will be collisions when multiple cores simultaneously - * configure the same timers */ - if (ret != 0) - my_collisions++; - } - if (my_collisions != 0) - rte_atomic32_add(&collisions, my_collisions); - - /* wait long enough for timers to expire */ - rte_delay_ms(100); - - /* all cores rendezvous */ - if (lcore_id == master) { - master_wait_for_slaves(); - } else { - slave_finish(); - } - - /* now check that we get the right number of callbacks */ - if (lcore_id == master) { - my_collisions = rte_atomic32_read(&collisions); - if (my_collisions != 0) - printf("- %d timer reset collisions (OK)\n", my_collisions); - rte_timer_manage(); - if (cb_count != NB_STRESS2_TIMERS) { - printf("Test Failed\n"); - printf("- Stress test 2, part 1 failed\n"); - printf("- Expected %d callbacks, got %d\n", NB_STRESS2_TIMERS, - cb_count); - test_failed = 1; - master_start_slaves(); - goto cleanup; - } - cb_count = 0; - - /* proceed */ - master_start_slaves(); - } else { - /* proceed */ - slave_wait_to_start(); - if (test_failed) - goto cleanup; - } - - /* now test again, just stop and restart timers at random after init*/ - for (i = 0; i < NB_STRESS2_TIMERS; i++) - rte_timer_reset(&timers[i], delay, SINGLE, master, - timer_stress2_cb, NULL); - - /* pick random timer to reset, stopping them first half the time */ - for (i = 0; i < 100000; i++) { - int r = rand() % NB_STRESS2_TIMERS; - if (i % 2) - rte_timer_stop(&timers[r]); - rte_timer_reset(&timers[r], delay, SINGLE, master, - timer_stress2_cb, NULL); - } - - /* wait long enough for timers to expire */ - rte_delay_ms(100); - - /* now check that we get the right number of callbacks */ - if (lcore_id == master) { - master_wait_for_slaves(); - - rte_timer_manage(); - if (cb_count != NB_STRESS2_TIMERS) { - printf("Test Failed\n"); - printf("- Stress test 2, part 2 failed\n"); - printf("- Expected %d callbacks, got %d\n", NB_STRESS2_TIMERS, - cb_count); - test_failed = 1; - } else { - printf("Test OK\n"); - } - } - -cleanup: - if (lcore_id == master) { - master_wait_for_slaves(); - if (timers != NULL) { - rte_free(timers); - timers = NULL; - } - } else { - slave_finish(); - } - - return 0; -} - -/* timer callback for basic tests */ -static void -timer_basic_cb(struct rte_timer *tim, void *arg) -{ - struct mytimerinfo *timinfo = arg; - uint64_t hz = rte_get_timer_hz(); - unsigned lcore_id = rte_lcore_id(); - uint64_t cur_time = rte_get_timer_cycles(); - - if (rte_timer_pending(tim)) - return; - - timinfo->count ++; - - RTE_LOG(INFO, TESTTIMER, - "%"PRIu64": callback id=%u count=%u on core %u\n", - cur_time, timinfo->id, timinfo->count, lcore_id); - - /* reload timer 0 on same core */ - if (timinfo->id == 0 && timinfo->count < 20) { - mytimer_reset(timinfo, hz, SINGLE, lcore_id, timer_basic_cb); - return; - } - - /* reload timer 1 on next core */ - if (timinfo->id == 1 && timinfo->count < 10) { - mytimer_reset(timinfo, hz*2, SINGLE, - rte_get_next_lcore(lcore_id, 0, 1), - timer_basic_cb); - return; - } - - /* Explicitelly stop timer 0. Once stop() called, we can even - * erase the content of the structure: it is not referenced - * anymore by any code (in case of dynamic structure, it can - * be freed) */ - if (timinfo->id == 0 && timinfo->count == 20) { - - /* stop_sync() is not needed, because we know that the - * status of timer is only modified by this core */ - rte_timer_stop(tim); - memset(tim, 0xAA, sizeof(struct rte_timer)); - return; - } - - /* stop timer3, and restart a new timer0 (it was removed 5 - * seconds ago) for a single shot */ - if (timinfo->id == 2 && timinfo->count == 25) { - rte_timer_stop_sync(&mytiminfo[3].tim); - - /* need to reinit because structure was erased with 0xAA */ - rte_timer_init(&mytiminfo[0].tim); - mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id, - timer_basic_cb); - } -} - -static int -timer_basic_main_loop(__attribute__((unused)) void *arg) -{ - uint64_t hz = rte_get_timer_hz(); - unsigned lcore_id = rte_lcore_id(); - uint64_t cur_time; - int64_t diff = 0; - - /* launch all timers on core 0 */ - if (lcore_id == rte_get_master_lcore()) { - mytimer_reset(&mytiminfo[0], hz/4, SINGLE, lcore_id, - timer_basic_cb); - mytimer_reset(&mytiminfo[1], hz/2, SINGLE, lcore_id, - timer_basic_cb); - mytimer_reset(&mytiminfo[2], hz/4, PERIODICAL, lcore_id, - timer_basic_cb); - mytimer_reset(&mytiminfo[3], hz/4, PERIODICAL, - rte_get_next_lcore(lcore_id, 0, 1), - timer_basic_cb); - } - - while (diff >= 0) { - - /* call the timer handler on each core */ - rte_timer_manage(); - - /* simulate the processing of a packet - * (3 us = 6000 cycles at 2 Ghz) */ - rte_delay_us(3); - - cur_time = rte_get_timer_cycles(); - diff = end_time - cur_time; - } - RTE_LOG(INFO, TESTTIMER, "core %u finished\n", lcore_id); - - return 0; -} - -static int -timer_sanity_check(void) -{ -#ifdef RTE_LIBEAL_USE_HPET - if (eal_timer_source != EAL_TIMER_HPET) { - printf("Not using HPET, can't sanity check timer sources\n"); - return 0; - } - - const uint64_t t_hz = rte_get_tsc_hz(); - const uint64_t h_hz = rte_get_hpet_hz(); - printf("Hertz values: TSC = %"PRIu64", HPET = %"PRIu64"\n", t_hz, h_hz); - - const uint64_t tsc_start = rte_get_tsc_cycles(); - const uint64_t hpet_start = rte_get_hpet_cycles(); - rte_delay_ms(100); /* delay 1/10 second */ - const uint64_t tsc_end = rte_get_tsc_cycles(); - const uint64_t hpet_end = rte_get_hpet_cycles(); - printf("Measured cycles: TSC = %"PRIu64", HPET = %"PRIu64"\n", - tsc_end-tsc_start, hpet_end-hpet_start); - - const double tsc_time = (double)(tsc_end - tsc_start)/t_hz; - const double hpet_time = (double)(hpet_end - hpet_start)/h_hz; - /* get the percentage that the times differ by */ - const double time_diff = fabs(tsc_time - hpet_time)*100/tsc_time; - printf("Measured time: TSC = %.4f, HPET = %.4f\n", tsc_time, hpet_time); - - printf("Elapsed time measured by TSC and HPET differ by %f%%\n", - time_diff); - if (time_diff > 0.1) { - printf("Error times differ by >0.1%%"); - return -1; - } -#endif - return 0; -} - -static int -test_timer(void) -{ - unsigned i; - uint64_t cur_time; - uint64_t hz; - - /* sanity check our timer sources and timer config values */ - if (timer_sanity_check() < 0) { - printf("Timer sanity checks failed\n"); - return TEST_FAILED; - } - - if (rte_lcore_count() < 2) { - printf("not enough lcores for this test\n"); - return TEST_FAILED; - } - - /* init timer */ - for (i=0; i -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_ITERATIONS 1000000 - -int outstanding_count = 0; - -static void -timer_cb(struct rte_timer *t __rte_unused, void *param __rte_unused) -{ - outstanding_count--; -} - -#define DELAY_SECONDS 1 - -#ifdef RTE_EXEC_ENV_LINUXAPP -#define do_delay() usleep(10) -#else -#define do_delay() rte_pause() -#endif - -static int -test_timer_perf(void) -{ - unsigned iterations = 100; - unsigned i; - struct rte_timer *tms; - uint64_t start_tsc, end_tsc, delay_start; - unsigned lcore_id = rte_lcore_id(); - - tms = rte_malloc(NULL, sizeof(*tms) * MAX_ITERATIONS, 0); - - for (i = 0; i < MAX_ITERATIONS; i++) - rte_timer_init(&tms[i]); - - const uint64_t ticks = rte_get_timer_hz() * DELAY_SECONDS; - const uint64_t ticks_per_ms = rte_get_tsc_hz()/1000; - const uint64_t ticks_per_us = ticks_per_ms/1000; - - while (iterations <= MAX_ITERATIONS) { - - printf("Appending %u timers\n", iterations); - start_tsc = rte_rdtsc(); - for (i = 0; i < iterations; i++) - rte_timer_reset(&tms[i], ticks, SINGLE, lcore_id, - timer_cb, NULL); - end_tsc = rte_rdtsc(); - printf("Time for %u timers: %"PRIu64" (%"PRIu64"ms), ", iterations, - end_tsc-start_tsc, (end_tsc-start_tsc+ticks_per_ms/2)/(ticks_per_ms)); - printf("Time per timer: %"PRIu64" (%"PRIu64"us)\n", - (end_tsc-start_tsc)/iterations, - ((end_tsc-start_tsc)/iterations+ticks_per_us/2)/(ticks_per_us)); - outstanding_count = iterations; - delay_start = rte_get_timer_cycles(); - while (rte_get_timer_cycles() < delay_start + ticks) - do_delay(); - - start_tsc = rte_rdtsc(); - while (outstanding_count) - rte_timer_manage(); - end_tsc = rte_rdtsc(); - printf("Time for %u callbacks: %"PRIu64" (%"PRIu64"ms), ", iterations, - end_tsc-start_tsc, (end_tsc-start_tsc+ticks_per_ms/2)/(ticks_per_ms)); - printf("Time per callback: %"PRIu64" (%"PRIu64"us)\n", - (end_tsc-start_tsc)/iterations, - ((end_tsc-start_tsc)/iterations+ticks_per_us/2)/(ticks_per_us)); - - printf("Resetting %u timers\n", iterations); - start_tsc = rte_rdtsc(); - for (i = 0; i < iterations; i++) - rte_timer_reset(&tms[i], rte_rand() % ticks, SINGLE, lcore_id, - timer_cb, NULL); - end_tsc = rte_rdtsc(); - printf("Time for %u timers: %"PRIu64" (%"PRIu64"ms), ", iterations, - end_tsc-start_tsc, (end_tsc-start_tsc+ticks_per_ms/2)/(ticks_per_ms)); - printf("Time per timer: %"PRIu64" (%"PRIu64"us)\n", - (end_tsc-start_tsc)/iterations, - ((end_tsc-start_tsc)/iterations+ticks_per_us/2)/(ticks_per_us)); - outstanding_count = iterations; - - delay_start = rte_get_timer_cycles(); - while (rte_get_timer_cycles() < delay_start + ticks) - do_delay(); - - rte_timer_manage(); - if (outstanding_count != 0) { - printf("Error: outstanding callback count = %d\n", outstanding_count); - return -1; - } - - iterations *= 10; - printf("\n"); - } - - printf("All timers processed ok\n"); - - /* measure time to poll an empty timer list */ - start_tsc = rte_rdtsc(); - for (i = 0; i < iterations; i++) - rte_timer_manage(); - end_tsc = rte_rdtsc(); - printf("\nTime per rte_timer_manage with zero timers: %"PRIu64" cycles\n", - (end_tsc - start_tsc + iterations/2) / iterations); - - /* measure time to poll a timer list with timers, but without - * calling any callbacks */ - rte_timer_reset(&tms[0], ticks * 100, SINGLE, lcore_id, - timer_cb, NULL); - start_tsc = rte_rdtsc(); - for (i = 0; i < iterations; i++) - rte_timer_manage(); - end_tsc = rte_rdtsc(); - printf("Time per rte_timer_manage with zero callbacks: %"PRIu64" cycles\n", - (end_tsc - start_tsc + iterations/2) / iterations); - - return 0; -} - -REGISTER_TEST_COMMAND(timer_perf_autotest, test_timer_perf); diff --git a/app/test/test_timer_racecond.c b/app/test/test_timer_racecond.c deleted file mode 100644 index 7824ec4bf6..0000000000 --- a/app/test/test_timer_racecond.c +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015 Akamai Technologies. - * 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 "test.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef TEST_TIMER_RACECOND_VERBOSE - -#ifdef RTE_EXEC_ENV_LINUXAPP -#define usec_delay(us) usleep(us) -#else -#define usec_delay(us) rte_delay_us(us) -#endif - -#define BILLION (1UL << 30) - -#define TEST_DURATION_S 20 /* in seconds */ -#define N_TIMERS 50 - -static struct rte_timer timer[N_TIMERS]; -static unsigned timer_lcore_id[N_TIMERS]; - -static unsigned master; -static volatile unsigned stop_slaves; - -static int reload_timer(struct rte_timer *tim); - -static void -timer_cb(struct rte_timer *tim, void *arg __rte_unused) -{ - /* Simulate slow callback function, 100 us. */ - rte_delay_us(100); - -#ifdef TEST_TIMER_RACECOND_VERBOSE - if (tim == &timer[0]) - printf("------------------------------------------------\n"); - printf("timer_cb: core %u timer %lu\n", - rte_lcore_id(), tim - timer); -#endif - (void)reload_timer(tim); -} - -RTE_DEFINE_PER_LCORE(unsigned, n_reset_collisions); - -static int -reload_timer(struct rte_timer *tim) -{ - /* Make timer expire roughly when the TSC hits the next BILLION - * multiple. Add in timer's index to make them expire in nearly - * sorted order. This makes all timers somewhat synchronized, - * firing ~2-3 times per second, assuming 2-3 GHz TSCs. - */ - uint64_t ticks = BILLION - (rte_get_timer_cycles() % BILLION) + - (tim - timer); - int ret; - - ret = rte_timer_reset(tim, ticks, PERIODICAL, master, timer_cb, NULL); - if (ret != 0) { -#ifdef TEST_TIMER_RACECOND_VERBOSE - printf("- core %u failed to reset timer %lu (OK)\n", - rte_lcore_id(), tim - timer); -#endif - RTE_PER_LCORE(n_reset_collisions) += 1; - } - return ret; -} - -static int -slave_main_loop(__attribute__((unused)) void *arg) -{ - unsigned lcore_id = rte_lcore_id(); - unsigned i; - - RTE_PER_LCORE(n_reset_collisions) = 0; - - printf("Starting main loop on core %u\n", lcore_id); - - while (!stop_slaves) { - /* Wait until the timer manager is running. - * We know it's running when we see timer[0] NOT pending. - */ - if (rte_timer_pending(&timer[0])) { - rte_pause(); - continue; - } - - /* Now, go cause some havoc! - * Reload our timers. - */ - for (i = 0; i < N_TIMERS; i++) { - if (timer_lcore_id[i] == lcore_id) - (void)reload_timer(&timer[i]); - } - usec_delay(100*1000); /* sleep 100 ms */ - } - - if (RTE_PER_LCORE(n_reset_collisions) != 0) { - printf("- core %u, %u reset collisions (OK)\n", - lcore_id, RTE_PER_LCORE(n_reset_collisions)); - } - return 0; -} - -static int -test_timer_racecond(void) -{ - int ret; - uint64_t hz; - uint64_t cur_time; - uint64_t end_time; - int64_t diff = 0; - unsigned lcore_id; - unsigned i; - - master = lcore_id = rte_lcore_id(); - hz = rte_get_timer_hz(); - - /* init and start timers */ - for (i = 0; i < N_TIMERS; i++) { - rte_timer_init(&timer[i]); - ret = reload_timer(&timer[i]); - TEST_ASSERT(ret == 0, "reload_timer failed"); - - /* Distribute timers to slaves. - * Note that we assign timer[0] to the master. - */ - timer_lcore_id[i] = lcore_id; - lcore_id = rte_get_next_lcore(lcore_id, 1, 1); - } - - /* calculate the "end of test" time */ - cur_time = rte_get_timer_cycles(); - end_time = cur_time + (hz * TEST_DURATION_S); - - /* start slave cores */ - stop_slaves = 0; - printf("Start timer manage race condition test (%u seconds)\n", - TEST_DURATION_S); - rte_eal_mp_remote_launch(slave_main_loop, NULL, SKIP_MASTER); - - while (diff >= 0) { - /* run the timers */ - rte_timer_manage(); - - /* wait 100 ms */ - usec_delay(100*1000); - - cur_time = rte_get_timer_cycles(); - diff = end_time - cur_time; - } - - /* stop slave cores */ - printf("Stopping timer manage race condition test\n"); - stop_slaves = 1; - rte_eal_mp_wait_lcore(); - - /* stop timers */ - for (i = 0; i < N_TIMERS; i++) { - ret = rte_timer_stop(&timer[i]); - TEST_ASSERT(ret == 0, "rte_timer_stop failed"); - } - - return TEST_SUCCESS; -} - -REGISTER_TEST_COMMAND(timer_racecond_autotest, test_timer_racecond); diff --git a/app/test/test_version.c b/app/test/test_version.c deleted file mode 100644 index afc0d0b888..0000000000 --- a/app/test/test_version.c +++ /dev/null @@ -1,57 +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 -#include -#include - -#include -#include - -#include "test.h" - - -static int -test_version(void) -{ - const char *version = rte_version(); - if (version == NULL) - return -1; - printf("Version string: '%s'\n", version); - if (*version == '\0' || - strncmp(version, RTE_VER_PREFIX, sizeof(RTE_VER_PREFIX)-1) != 0) - return -1; - return 0; -} - -REGISTER_TEST_COMMAND(version_autotest, test_version); diff --git a/app/test/test_xmmt_ops.h b/app/test/test_xmmt_ops.h deleted file mode 100644 index 42174d2c92..0000000000 --- a/app/test/test_xmmt_ops.h +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015 Cavium Networks. 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 Cavium Networks 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_XMMT_OPS_H_ -#define _TEST_XMMT_OPS_H_ - -#include - -#if defined(RTE_ARCH_ARM) || defined(RTE_ARCH_ARM64) - -/* vect_* abstraction implementation using NEON */ - -/* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/ -#define vect_loadu_sil128(p) vld1q_s32((const int32_t *)p) - -/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */ -static inline xmm_t __attribute__((always_inline)) -vect_set_epi32(int i3, int i2, int i1, int i0) -{ - int32_t data[4] = {i0, i1, i2, i3}; - - return vld1q_s32(data); -} - -#elif defined(RTE_ARCH_X86) - -/* vect_* abstraction implementation using SSE */ - -/* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/ -#define vect_loadu_sil128(p) _mm_loadu_si128(p) - -/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */ -#define vect_set_epi32(i3, i2, i1, i0) _mm_set_epi32(i3, i2, i1, i0) - -#elif defined(RTE_ARCH_PPC_64) - -/* vect_* abstraction implementation using ALTIVEC */ - -/* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/ -#define vect_loadu_sil128(p) vec_ld(0, p) - -/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */ -static inline xmm_t __attribute__((always_inline)) -vect_set_epi32(int i3, int i2, int i1, int i0) -{ - xmm_t data = (xmm_t){i0, i1, i2, i3}; - - return data; -} - -#endif - -#endif /* _TEST_XMMT_OPS_H_ */ diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c deleted file mode 100644 index 6e4dcd8f96..0000000000 --- a/app/test/virtual_pmd.c +++ /dev/null @@ -1,641 +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 -#include -#include -#include -#include -#include - -#include "virtual_pmd.h" - -#define MAX_PKT_BURST 512 - -static const char *virtual_ethdev_driver_name = "Virtual PMD"; - -struct virtual_ethdev_private { - struct eth_dev_ops dev_ops; - struct rte_eth_stats eth_stats; - - struct rte_ring *rx_queue; - struct rte_ring *tx_queue; - - int tx_burst_fail_count; -}; - -struct virtual_ethdev_queue { - int port_id; - int queue_id; -}; - -static int -virtual_ethdev_start_success(struct rte_eth_dev *eth_dev __rte_unused) -{ - eth_dev->data->dev_started = 1; - - return 0; -} - -static int -virtual_ethdev_start_fail(struct rte_eth_dev *eth_dev __rte_unused) -{ - eth_dev->data->dev_started = 0; - - return -1; -} -static void virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused) -{ - void *pkt = NULL; - struct virtual_ethdev_private *prv = eth_dev->data->dev_private; - - eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; - eth_dev->data->dev_started = 0; - while (rte_ring_dequeue(prv->rx_queue, &pkt) != -ENOENT) - rte_pktmbuf_free(pkt); - - while (rte_ring_dequeue(prv->tx_queue, &pkt) != -ENOENT) - rte_pktmbuf_free(pkt); -} - -static void -virtual_ethdev_close(struct rte_eth_dev *dev __rte_unused) -{} - -static int -virtual_ethdev_configure_success(struct rte_eth_dev *dev __rte_unused) -{ - return 0; -} - -static int -virtual_ethdev_configure_fail(struct rte_eth_dev *dev __rte_unused) -{ - return -1; -} - -static void -virtual_ethdev_info_get(struct rte_eth_dev *dev __rte_unused, - struct rte_eth_dev_info *dev_info) -{ - dev_info->driver_name = virtual_ethdev_driver_name; - dev_info->max_mac_addrs = 1; - - dev_info->max_rx_pktlen = (uint32_t)2048; - - dev_info->max_rx_queues = (uint16_t)128; - dev_info->max_tx_queues = (uint16_t)512; - - dev_info->min_rx_bufsize = 0; -} - -static int -virtual_ethdev_rx_queue_setup_success(struct rte_eth_dev *dev, - uint16_t rx_queue_id, uint16_t nb_rx_desc __rte_unused, - unsigned int socket_id, - const struct rte_eth_rxconf *rx_conf __rte_unused, - struct rte_mempool *mb_pool __rte_unused) -{ - struct virtual_ethdev_queue *rx_q; - - rx_q = (struct virtual_ethdev_queue *)rte_zmalloc_socket(NULL, - sizeof(struct virtual_ethdev_queue), 0, socket_id); - - if (rx_q == NULL) - return -1; - - rx_q->port_id = dev->data->port_id; - rx_q->queue_id = rx_queue_id; - - dev->data->rx_queues[rx_queue_id] = rx_q; - - return 0; -} - -static int -virtual_ethdev_rx_queue_setup_fail(struct rte_eth_dev *dev __rte_unused, - uint16_t rx_queue_id __rte_unused, uint16_t nb_rx_desc __rte_unused, - unsigned int socket_id __rte_unused, - const struct rte_eth_rxconf *rx_conf __rte_unused, - struct rte_mempool *mb_pool __rte_unused) -{ - return -1; -} - -static int -virtual_ethdev_tx_queue_setup_success(struct rte_eth_dev *dev, - uint16_t tx_queue_id, uint16_t nb_tx_desc __rte_unused, - unsigned int socket_id, - const struct rte_eth_txconf *tx_conf __rte_unused) -{ - struct virtual_ethdev_queue *tx_q; - - tx_q = (struct virtual_ethdev_queue *)rte_zmalloc_socket(NULL, - sizeof(struct virtual_ethdev_queue), 0, socket_id); - - if (tx_q == NULL) - return -1; - - tx_q->port_id = dev->data->port_id; - tx_q->queue_id = tx_queue_id; - - dev->data->tx_queues[tx_queue_id] = tx_q; - - return 0; -} - -static int -virtual_ethdev_tx_queue_setup_fail(struct rte_eth_dev *dev __rte_unused, - uint16_t tx_queue_id __rte_unused, uint16_t nb_tx_desc __rte_unused, - unsigned int socket_id __rte_unused, - const struct rte_eth_txconf *tx_conf __rte_unused) -{ - return -1; -} - -static void -virtual_ethdev_rx_queue_release(void *q __rte_unused) -{ -} - -static void -virtual_ethdev_tx_queue_release(void *q __rte_unused) -{ -} - -static int -virtual_ethdev_link_update_success(struct rte_eth_dev *bonded_eth_dev, - int wait_to_complete __rte_unused) -{ - if (!bonded_eth_dev->data->dev_started) - bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; - - return 0; -} - -static int -virtual_ethdev_link_update_fail(struct rte_eth_dev *bonded_eth_dev __rte_unused, - int wait_to_complete __rte_unused) -{ - return -1; -} - -static void -virtual_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) -{ - struct virtual_ethdev_private *dev_private = dev->data->dev_private; - - if (stats) - rte_memcpy(stats, &dev_private->eth_stats, sizeof(*stats)); -} - -static void -virtual_ethdev_stats_reset(struct rte_eth_dev *dev) -{ - struct virtual_ethdev_private *dev_private = dev->data->dev_private; - void *pkt = NULL; - - while (rte_ring_dequeue(dev_private->tx_queue, &pkt) == -ENOBUFS) - rte_pktmbuf_free(pkt); - - /* Reset internal statistics */ - memset(&dev_private->eth_stats, 0, sizeof(dev_private->eth_stats)); -} - -static void -virtual_ethdev_promiscuous_mode_enable(struct rte_eth_dev *dev __rte_unused) -{} - -static void -virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused) -{} - - -static const struct eth_dev_ops virtual_ethdev_default_dev_ops = { - .dev_configure = virtual_ethdev_configure_success, - .dev_start = virtual_ethdev_start_success, - .dev_stop = virtual_ethdev_stop, - .dev_close = virtual_ethdev_close, - .dev_infos_get = virtual_ethdev_info_get, - .rx_queue_setup = virtual_ethdev_rx_queue_setup_success, - .tx_queue_setup = virtual_ethdev_tx_queue_setup_success, - .rx_queue_release = virtual_ethdev_rx_queue_release, - .tx_queue_release = virtual_ethdev_tx_queue_release, - .link_update = virtual_ethdev_link_update_success, - .stats_get = virtual_ethdev_stats_get, - .stats_reset = virtual_ethdev_stats_reset, - .promiscuous_enable = virtual_ethdev_promiscuous_mode_enable, - .promiscuous_disable = virtual_ethdev_promiscuous_mode_disable -}; - - -void -virtual_ethdev_start_fn_set_success(uint8_t port_id, uint8_t success) -{ - struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - struct virtual_ethdev_private *dev_private = dev->data->dev_private; - struct eth_dev_ops *dev_ops = &dev_private->dev_ops; - - if (success) - dev_ops->dev_start = virtual_ethdev_start_success; - else - dev_ops->dev_start = virtual_ethdev_start_fail; - -} - -void -virtual_ethdev_configure_fn_set_success(uint8_t port_id, uint8_t success) -{ - struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - struct virtual_ethdev_private *dev_private = dev->data->dev_private; - struct eth_dev_ops *dev_ops = &dev_private->dev_ops; - - if (success) - dev_ops->dev_configure = virtual_ethdev_configure_success; - else - dev_ops->dev_configure = virtual_ethdev_configure_fail; -} - -void -virtual_ethdev_rx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success) -{ - struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - struct virtual_ethdev_private *dev_private = dev->data->dev_private; - struct eth_dev_ops *dev_ops = &dev_private->dev_ops; - - if (success) - dev_ops->rx_queue_setup = virtual_ethdev_rx_queue_setup_success; - else - dev_ops->rx_queue_setup = virtual_ethdev_rx_queue_setup_fail; -} - -void -virtual_ethdev_tx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success) -{ - struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - struct virtual_ethdev_private *dev_private = dev->data->dev_private; - struct eth_dev_ops *dev_ops = &dev_private->dev_ops; - - if (success) - dev_ops->tx_queue_setup = virtual_ethdev_tx_queue_setup_success; - else - dev_ops->tx_queue_setup = virtual_ethdev_tx_queue_setup_fail; -} - -void -virtual_ethdev_link_update_fn_set_success(uint8_t port_id, uint8_t success) -{ - struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - struct virtual_ethdev_private *dev_private = dev->data->dev_private; - struct eth_dev_ops *dev_ops = &dev_private->dev_ops; - - if (success) - dev_ops->link_update = virtual_ethdev_link_update_success; - else - dev_ops->link_update = virtual_ethdev_link_update_fail; -} - - -static uint16_t -virtual_ethdev_rx_burst_success(void *queue __rte_unused, - struct rte_mbuf **bufs, - uint16_t nb_pkts) -{ - struct rte_eth_dev *vrtl_eth_dev; - struct virtual_ethdev_queue *pq_map; - struct virtual_ethdev_private *dev_private; - - int rx_count, i; - - pq_map = (struct virtual_ethdev_queue *)queue; - vrtl_eth_dev = &rte_eth_devices[pq_map->port_id]; - dev_private = vrtl_eth_dev->data->dev_private; - - rx_count = rte_ring_dequeue_burst(dev_private->rx_queue, (void **) bufs, - nb_pkts); - - /* increments ipackets count */ - dev_private->eth_stats.ipackets += rx_count; - - /* increments ibytes count */ - for (i = 0; i < rx_count; i++) - dev_private->eth_stats.ibytes += rte_pktmbuf_pkt_len(bufs[i]); - - return rx_count; -} - -static uint16_t -virtual_ethdev_rx_burst_fail(void *queue __rte_unused, - struct rte_mbuf **bufs __rte_unused, - uint16_t nb_pkts __rte_unused) -{ - return 0; -} - -static uint16_t -virtual_ethdev_tx_burst_success(void *queue, struct rte_mbuf **bufs, - uint16_t nb_pkts) -{ - struct virtual_ethdev_queue *tx_q = (struct virtual_ethdev_queue *)queue; - - struct rte_eth_dev *vrtl_eth_dev; - struct virtual_ethdev_private *dev_private; - - int i; - - vrtl_eth_dev = &rte_eth_devices[tx_q->port_id]; - dev_private = vrtl_eth_dev->data->dev_private; - - if (!vrtl_eth_dev->data->dev_link.link_status) - nb_pkts = 0; - else - nb_pkts = rte_ring_enqueue_burst(dev_private->tx_queue, (void **)bufs, - nb_pkts); - - /* increment opacket count */ - dev_private->eth_stats.opackets += nb_pkts; - - /* increment obytes count */ - for (i = 0; i < nb_pkts; i++) - dev_private->eth_stats.obytes += rte_pktmbuf_pkt_len(bufs[i]); - - return nb_pkts; -} - -static uint16_t -virtual_ethdev_tx_burst_fail(void *queue, struct rte_mbuf **bufs, - uint16_t nb_pkts) -{ - struct rte_eth_dev *vrtl_eth_dev = NULL; - struct virtual_ethdev_queue *tx_q = NULL; - struct virtual_ethdev_private *dev_private = NULL; - - int i; - - tx_q = (struct virtual_ethdev_queue *)queue; - vrtl_eth_dev = &rte_eth_devices[tx_q->port_id]; - dev_private = vrtl_eth_dev->data->dev_private; - - if (dev_private->tx_burst_fail_count < nb_pkts) { - int successfully_txd = nb_pkts - dev_private->tx_burst_fail_count; - - /* increment opacket count */ - dev_private->eth_stats.opackets += successfully_txd; - - /* free packets in burst */ - for (i = 0; i < successfully_txd; i++) { - /* free packets in burst */ - if (bufs[i] != NULL) - rte_pktmbuf_free(bufs[i]); - - bufs[i] = NULL; - } - - return successfully_txd; - } - - return 0; -} - - -void -virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success) -{ - struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; - - if (success) - vrtl_eth_dev->rx_pkt_burst = virtual_ethdev_rx_burst_success; - else - vrtl_eth_dev->rx_pkt_burst = virtual_ethdev_rx_burst_fail; -} - - -void -virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success) -{ - struct virtual_ethdev_private *dev_private = NULL; - struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; - - dev_private = vrtl_eth_dev->data->dev_private; - - if (success) - vrtl_eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_success; - else - vrtl_eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_fail; - - dev_private->tx_burst_fail_count = 0; -} - -void -virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id, - uint8_t packet_fail_count) -{ - struct virtual_ethdev_private *dev_private = NULL; - struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; - - - dev_private = vrtl_eth_dev->data->dev_private; - dev_private->tx_burst_fail_count = packet_fail_count; -} - -void -virtual_ethdev_set_link_status(uint8_t port_id, uint8_t link_status) -{ - struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; - - vrtl_eth_dev->data->dev_link.link_status = link_status; -} - -void -virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id, - uint8_t link_status) -{ - struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; - - vrtl_eth_dev->data->dev_link.link_status = link_status; - - _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL); -} - -int -virtual_ethdev_add_mbufs_to_rx_queue(uint8_t port_id, - struct rte_mbuf **pkt_burst, int burst_length) -{ - struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; - struct virtual_ethdev_private *dev_private = - vrtl_eth_dev->data->dev_private; - - return rte_ring_enqueue_burst(dev_private->rx_queue, (void **)pkt_burst, - burst_length); -} - -int -virtual_ethdev_get_mbufs_from_tx_queue(uint8_t port_id, - struct rte_mbuf **pkt_burst, int burst_length) -{ - struct virtual_ethdev_private *dev_private; - struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; - - dev_private = vrtl_eth_dev->data->dev_private; - return rte_ring_dequeue_burst(dev_private->tx_queue, (void **)pkt_burst, - burst_length); -} - -static uint8_t -get_number_of_sockets(void) -{ - int sockets = 0; - int i; - const struct rte_memseg *ms = rte_eal_get_physmem_layout(); - - for (i = 0; i < RTE_MAX_MEMSEG && ms[i].addr != NULL; i++) { - if (sockets < ms[i].socket_id) - sockets = ms[i].socket_id; - } - /* Number of sockets = maximum socket_id + 1 */ - return ++sockets; -} - -int -virtual_ethdev_create(const char *name, struct ether_addr *mac_addr, - uint8_t socket_id, uint8_t isr_support) -{ - struct rte_pci_device *pci_dev = NULL; - struct rte_eth_dev *eth_dev = NULL; - struct eth_driver *eth_drv = NULL; - struct rte_pci_driver *pci_drv = NULL; - struct rte_pci_id *id_table = NULL; - struct virtual_ethdev_private *dev_private = NULL; - char name_buf[RTE_RING_NAMESIZE]; - - - /* now do all data allocation - for eth_dev structure, dummy pci driver - * and internal (dev_private) data - */ - - if (socket_id >= get_number_of_sockets()) - goto err; - - pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, socket_id); - if (pci_dev == NULL) - goto err; - - eth_drv = rte_zmalloc_socket(name, sizeof(*eth_drv), 0, socket_id); - if (eth_drv == NULL) - goto err; - - pci_drv = rte_zmalloc_socket(name, sizeof(*pci_drv), 0, socket_id); - if (pci_drv == NULL) - goto err; - - id_table = rte_zmalloc_socket(name, sizeof(*id_table), 0, socket_id); - if (id_table == NULL) - goto err; - id_table->device_id = 0xBEEF; - - dev_private = rte_zmalloc_socket(name, sizeof(*dev_private), 0, socket_id); - if (dev_private == NULL) - goto err; - - snprintf(name_buf, sizeof(name_buf), "%s_rxQ", name); - dev_private->rx_queue = rte_ring_create(name_buf, MAX_PKT_BURST, socket_id, - 0); - if (dev_private->rx_queue == NULL) - goto err; - - snprintf(name_buf, sizeof(name_buf), "%s_txQ", name); - dev_private->tx_queue = rte_ring_create(name_buf, MAX_PKT_BURST, socket_id, - 0); - if (dev_private->tx_queue == NULL) - goto err; - - /* reserve an ethdev entry */ - eth_dev = rte_eth_dev_allocate(name); - if (eth_dev == NULL) - goto err; - - pci_dev->device.numa_node = socket_id; - pci_drv->driver.name = virtual_ethdev_driver_name; - pci_drv->id_table = id_table; - - if (isr_support) - pci_drv->drv_flags |= RTE_PCI_DRV_INTR_LSC; - else - pci_drv->drv_flags &= ~RTE_PCI_DRV_INTR_LSC; - - - eth_drv->pci_drv = (struct rte_pci_driver)(*pci_drv); - eth_dev->driver = eth_drv; - - eth_dev->data->nb_rx_queues = (uint16_t)1; - eth_dev->data->nb_tx_queues = (uint16_t)1; - - eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; - eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G; - eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX; - - eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0); - if (eth_dev->data->mac_addrs == NULL) - goto err; - - memcpy(eth_dev->data->mac_addrs, mac_addr, - sizeof(*eth_dev->data->mac_addrs)); - - eth_dev->data->dev_started = 0; - eth_dev->data->promiscuous = 0; - eth_dev->data->scattered_rx = 0; - eth_dev->data->all_multicast = 0; - - eth_dev->data->dev_private = dev_private; - - /* Copy default device operation functions */ - dev_private->dev_ops = virtual_ethdev_default_dev_ops; - eth_dev->dev_ops = &dev_private->dev_ops; - - pci_dev->device.driver = ð_drv->pci_drv.driver; - eth_dev->device = &pci_dev->device; - - eth_dev->rx_pkt_burst = virtual_ethdev_rx_burst_success; - eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_success; - - return eth_dev->data->port_id; - -err: - rte_free(pci_dev); - rte_free(pci_drv); - rte_free(eth_drv); - rte_free(id_table); - rte_free(dev_private); - - return -1; -} diff --git a/app/test/virtual_pmd.h b/app/test/virtual_pmd.h deleted file mode 100644 index de001884de..0000000000 --- a/app/test/virtual_pmd.h +++ /dev/null @@ -1,104 +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 __VIRTUAL_ETHDEV_H_ -#define __VIRTUAL_ETHDEV_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -int -virtual_ethdev_init(void); - -int -virtual_ethdev_create(const char *name, struct ether_addr *mac_addr, - uint8_t socket_id, uint8_t isr_support); - -void -virtual_ethdev_set_link_status(uint8_t port_id, uint8_t link_status); - -void -virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id, - uint8_t link_status); - -int -virtual_ethdev_add_mbufs_to_rx_queue(uint8_t port_id, - struct rte_mbuf **pkts_burst, int burst_length); - -int -virtual_ethdev_get_mbufs_from_tx_queue(uint8_t port_id, - struct rte_mbuf **pkt_burst, int burst_length); - -/** Control methods for the dev_ops functions pointer to control the behavior - * of the Virtual PMD */ - -void -virtual_ethdev_start_fn_set_success(uint8_t port_id, uint8_t success); - -void -virtual_ethdev_stop_fn_set_success(uint8_t port_id, uint8_t success); - -void -virtual_ethdev_configure_fn_set_success(uint8_t port_id, uint8_t success); - -void -virtual_ethdev_rx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success); - -void -virtual_ethdev_tx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success); - -void -virtual_ethdev_link_update_fn_set_success(uint8_t port_id, uint8_t success); - -void -virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success); - -void -virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success); - -/* if a value greater than zero is set for packet_fail_count then virtual - * device tx burst function will fail that many packet from burst or all - * packets if packet_fail_count is greater than the number of packets in the - * burst */ -void -virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id, - uint8_t packet_fail_count); - -#ifdef __cplusplus -} -#endif - -#endif /* __VIRTUAL_ETHDEV_H_ */ diff --git a/mk/rte.sdktest.mk b/mk/rte.sdktest.mk index ddbbbf6b24..1cdb40ba52 100644 --- a/mk/rte.sdktest.mk +++ b/mk/rte.sdktest.mk @@ -57,7 +57,7 @@ test fast_test perf_test: @mkdir -p $(AUTOTEST_DIR) ; \ cd $(AUTOTEST_DIR) ; \ if [ -f $(RTE_OUTPUT)/app/test ]; then \ - python $(RTE_SDK)/app/test/autotest.py \ + python $(RTE_SDK)/test/test/autotest.py \ $(RTE_OUTPUT)/app/test \ $(RTE_TARGET) \ $(BLACKLIST) $(WHITELIST); \ @@ -71,10 +71,10 @@ coverage: @mkdir -p $(AUTOTEST_DIR) ; \ cd $(AUTOTEST_DIR) ; \ if [ -f $(RTE_OUTPUT)/app/test ]; then \ - python $(RTE_SDK)/app/cmdline_test/cmdline_test.py \ + python $(RTE_SDK)/test/cmdline_test/cmdline_test.py \ $(RTE_OUTPUT)/app/cmdline_test; \ ulimit -S -n 100 ; \ - python $(RTE_SDK)/app/test/autotest.py \ + python $(RTE_SDK)/test/test/autotest.py \ $(RTE_OUTPUT)/app/test \ $(RTE_TARGET) \ $(BLACKLIST) $(WHITELIST) ; \ diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000000..e996fd8cf1 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,39 @@ +# BSD LICENSE +# +# Copyright(c) 2017 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 + +DIRS-$(CONFIG_RTE_APP_TEST) += test +DIRS-$(CONFIG_RTE_LIBRTE_ACL) += test-acl +DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += test-pipeline +DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_test + +include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/test/cmdline_test/Makefile b/test/cmdline_test/Makefile new file mode 100644 index 0000000000..c6169f56dd --- /dev/null +++ b/test/cmdline_test/Makefile @@ -0,0 +1,55 @@ +# 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 $(RTE_SDK)/mk/rte.vars.mk + +ifeq ($(CONFIG_RTE_LIBRTE_CMDLINE),y) + +# +# library name +# +APP = cmdline_test + +# +# all sources are stored in SRCS-y +# +SRCS-y += cmdline_test.c +SRCS-y += commands.c + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +# this application needs libraries first +DEPDIRS-y += lib drivers + +include $(RTE_SDK)/mk/rte.app.mk + +endif diff --git a/test/cmdline_test/cmdline_test.c b/test/cmdline_test/cmdline_test.c new file mode 100644 index 0000000000..716b5f1685 --- /dev/null +++ b/test/cmdline_test/cmdline_test.c @@ -0,0 +1,64 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "cmdline_test.h" + +int +main(int __attribute__((unused)) argc, char __attribute__((unused)) ** argv) +{ + struct cmdline *cl; + + cl = cmdline_stdin_new(main_ctx, "CMDLINE_TEST>>"); + if (cl == NULL) { + return -1; + } + cmdline_interact(cl); + cmdline_stdin_exit(cl); + + return 0; +} diff --git a/test/cmdline_test/cmdline_test.h b/test/cmdline_test/cmdline_test.h new file mode 100644 index 0000000000..1c9af122fe --- /dev/null +++ b/test/cmdline_test/cmdline_test.h @@ -0,0 +1,39 @@ +/*- + * 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 _CMDLINE_TEST_H_ +#define _CMDLINE_TEST_H_ + +extern cmdline_parse_ctx_t main_ctx[]; + +#endif diff --git a/test/cmdline_test/cmdline_test.py b/test/cmdline_test/cmdline_test.py new file mode 100755 index 0000000000..229f71f3e3 --- /dev/null +++ b/test/cmdline_test/cmdline_test.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +# 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. + +# Script that runs cmdline_test app and feeds keystrokes into it. +from __future__ import print_function +import cmdline_test_data +import os +import pexpect +import sys + + +# +# function to run test +# +def runTest(child, test): + child.send(test["Sequence"]) + if test["Result"] is None: + return 0 + child.expect(test["Result"], 1) + + +# +# history test is a special case +# +# This test does the following: +# 1) fills the history with garbage up to its full capacity +# (just enough to remove last entry) +# 2) scrolls back history to the very beginning +# 3) checks if the output is as expected, that is, the first +# number in the sequence (not the last entry before it) +# +# This is a self-contained test, it needs only a pexpect child +# +def runHistoryTest(child): + # find out history size + child.sendline(cmdline_test_data.CMD_GET_BUFSIZE) + child.expect("History buffer size: \\d+", timeout=1) + history_size = int(child.after[len(cmdline_test_data.BUFSIZE_TEMPLATE):]) + i = 0 + + # fill the history with numbers + while i < history_size / 10: + # add 1 to prevent from parsing as octals + child.send("1" + str(i).zfill(8) + cmdline_test_data.ENTER) + # the app will simply print out the number + child.expect(str(i + 100000000), timeout=1) + i += 1 + # scroll back history + child.send(cmdline_test_data.UP * (i + 2) + cmdline_test_data.ENTER) + child.expect("100000000", timeout=1) + +# the path to cmdline_test executable is supplied via command-line. +if len(sys.argv) < 2: + print("Error: please supply cmdline_test app path") + sys.exit(1) + +test_app_path = sys.argv[1] + +if not os.path.exists(test_app_path): + print("Error: please supply cmdline_test app path") + sys.exit(1) + +child = pexpect.spawn(test_app_path) + +print("Running command-line tests...") +for test in cmdline_test_data.tests: + testname = (test["Name"] + ":").ljust(30) + try: + runTest(child, test) + print(testname, "PASS") + except: + print(testname, "FAIL") + print(child) + sys.exit(1) + +# since last test quits the app, run new instance +child = pexpect.spawn(test_app_path) + +testname = ("History fill test:").ljust(30) +try: + runHistoryTest(child) + print(testname, "PASS") +except: + print(testname, "FAIL") + print(child) + sys.exit(1) +child.close() +sys.exit(0) diff --git a/test/cmdline_test/cmdline_test_data.py b/test/cmdline_test/cmdline_test_data.py new file mode 100644 index 0000000000..28dfefe158 --- /dev/null +++ b/test/cmdline_test/cmdline_test_data.py @@ -0,0 +1,310 @@ +# 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. + +# collection of static data + +# keycode constants +CTRL_A = chr(1) +CTRL_B = chr(2) +CTRL_C = chr(3) +CTRL_D = chr(4) +CTRL_E = chr(5) +CTRL_F = chr(6) +CTRL_K = chr(11) +CTRL_L = chr(12) +CTRL_N = chr(14) +CTRL_P = chr(16) +CTRL_W = chr(23) +CTRL_Y = chr(25) +ALT_B = chr(27) + chr(98) +ALT_D = chr(27) + chr(100) +ALT_F = chr(27) + chr(102) +ALT_BKSPACE = chr(27) + chr(127) +DEL = chr(27) + chr(91) + chr(51) + chr(126) +TAB = chr(9) +HELP = chr(63) +BKSPACE = chr(127) +RIGHT = chr(27) + chr(91) + chr(67) +DOWN = chr(27) + chr(91) + chr(66) +LEFT = chr(27) + chr(91) + chr(68) +UP = chr(27) + chr(91) + chr(65) +ENTER2 = '\r' +ENTER = '\n' + +# expected result constants +NOT_FOUND = "Command not found" +BAD_ARG = "Bad arguments" +AMBIG = "Ambiguous command" +CMD1 = "Command 1 parsed!" +CMD2 = "Command 2 parsed!" +SINGLE = "Single word command parsed!" +SINGLE_LONG = "Single long word command parsed!" +AUTO1 = "Autocomplete command 1 parsed!" +AUTO2 = "Autocomplete command 2 parsed!" + +# misc defines +CMD_QUIT = "quit" +CMD_GET_BUFSIZE = "get_history_bufsize" +BUFSIZE_TEMPLATE = "History buffer size: " +PROMPT = "CMDLINE_TEST>>" + +# test defines +# each test tests progressively diverse set of keys. this way for example +# if we want to use some key sequence in the test, we first need to test +# that it itself does what it is expected to do. Most of the tests are +# designed that way. +# +# example: "arrows & delete test 1". we enter a partially valid command, +# then move 3 chars left and use delete three times. this way we get to +# know that "delete", "left" and "ctrl+B" all work (because if any of +# them fails, the whole test will fail and next tests won't be run). +# +# each test consists of name, character sequence to send to child, +# and expected output (if any). + +tests = [ + # test basic commands + {"Name": "command test 1", + "Sequence": "ambiguous first" + ENTER, + "Result": CMD1}, + {"Name": "command test 2", + "Sequence": "ambiguous second" + ENTER, + "Result": CMD2}, + {"Name": "command test 3", + "Sequence": "ambiguous ambiguous" + ENTER, + "Result": AMBIG}, + {"Name": "command test 4", + "Sequence": "ambiguous ambiguous2" + ENTER, + "Result": AMBIG}, + + {"Name": "invalid command test 1", + "Sequence": "ambiguous invalid" + ENTER, + "Result": BAD_ARG}, + # test invalid commands + {"Name": "invalid command test 2", + "Sequence": "invalid" + ENTER, + "Result": NOT_FOUND}, + {"Name": "invalid command test 3", + "Sequence": "ambiguousinvalid" + ENTER2, + "Result": NOT_FOUND}, + + # test arrows and deletes + {"Name": "arrows & delete test 1", + "Sequence": "singlebad" + LEFT*2 + CTRL_B + DEL*3 + ENTER, + "Result": SINGLE}, + {"Name": "arrows & delete test 2", + "Sequence": "singlebad" + LEFT*5 + RIGHT + CTRL_F + DEL*3 + ENTER, + "Result": SINGLE}, + + # test backspace + {"Name": "backspace test", + "Sequence": "singlebad" + BKSPACE*3 + ENTER, + "Result": SINGLE}, + + # test goto left and goto right + {"Name": "goto left test", + "Sequence": "biguous first" + CTRL_A + "am" + ENTER, + "Result": CMD1}, + {"Name": "goto right test", + "Sequence": "biguous fir" + CTRL_A + "am" + CTRL_E + "st" + ENTER, + "Result": CMD1}, + + # test goto words + {"Name": "goto left word test", + "Sequence": "ambiguous st" + ALT_B + "fir" + ENTER, + "Result": CMD1}, + {"Name": "goto right word test", + "Sequence": "ambig first" + CTRL_A + ALT_F + "uous" + ENTER, + "Result": CMD1}, + + # test removing words + {"Name": "remove left word 1", + "Sequence": "single invalid" + CTRL_W + ENTER, + "Result": SINGLE}, + {"Name": "remove left word 2", + "Sequence": "single invalid" + ALT_BKSPACE + ENTER, + "Result": SINGLE}, + {"Name": "remove right word", + "Sequence": "single invalid" + ALT_B + ALT_D + ENTER, + "Result": SINGLE}, + + # test kill buffer (copy and paste) + {"Name": "killbuffer test 1", + "Sequence": "ambiguous" + CTRL_A + CTRL_K + " first" + CTRL_A + + CTRL_Y + ENTER, + "Result": CMD1}, + {"Name": "killbuffer test 2", + "Sequence": "ambiguous" + CTRL_A + CTRL_K + CTRL_Y*26 + ENTER, + "Result": NOT_FOUND}, + + # test newline + {"Name": "newline test", + "Sequence": "invalid" + CTRL_C + "single" + ENTER, + "Result": SINGLE}, + + # test redisplay (nothing should really happen) + {"Name": "redisplay test", + "Sequence": "single" + CTRL_L + ENTER, + "Result": SINGLE}, + + # test autocomplete + {"Name": "autocomplete test 1", + "Sequence": "si" + TAB + ENTER, + "Result": SINGLE}, + {"Name": "autocomplete test 2", + "Sequence": "si" + TAB + "_" + TAB + ENTER, + "Result": SINGLE_LONG}, + {"Name": "autocomplete test 3", + "Sequence": "in" + TAB + ENTER, + "Result": NOT_FOUND}, + {"Name": "autocomplete test 4", + "Sequence": "am" + TAB + ENTER, + "Result": BAD_ARG}, + {"Name": "autocomplete test 5", + "Sequence": "am" + TAB + "fir" + TAB + ENTER, + "Result": CMD1}, + {"Name": "autocomplete test 6", + "Sequence": "am" + TAB + "fir" + TAB + TAB + ENTER, + "Result": CMD1}, + {"Name": "autocomplete test 7", + "Sequence": "am" + TAB + "fir" + TAB + " " + TAB + ENTER, + "Result": CMD1}, + {"Name": "autocomplete test 8", + "Sequence": "am" + TAB + " am" + TAB + " " + ENTER, + "Result": AMBIG}, + {"Name": "autocomplete test 9", + "Sequence": "am" + TAB + "inv" + TAB + ENTER, + "Result": BAD_ARG}, + {"Name": "autocomplete test 10", + "Sequence": "au" + TAB + ENTER, + "Result": NOT_FOUND}, + {"Name": "autocomplete test 11", + "Sequence": "au" + TAB + "1" + ENTER, + "Result": AUTO1}, + {"Name": "autocomplete test 12", + "Sequence": "au" + TAB + "2" + ENTER, + "Result": AUTO2}, + {"Name": "autocomplete test 13", + "Sequence": "au" + TAB + "2" + TAB + ENTER, + "Result": AUTO2}, + {"Name": "autocomplete test 14", + "Sequence": "au" + TAB + "2 " + TAB + ENTER, + "Result": AUTO2}, + {"Name": "autocomplete test 15", + "Sequence": "24" + TAB + ENTER, + "Result": "24"}, + + # test history + {"Name": "history test 1", + "Sequence": "invalid" + ENTER + "single" + ENTER + "invalid" + + ENTER + UP + CTRL_P + ENTER, + "Result": SINGLE}, + {"Name": "history test 2", + "Sequence": "invalid" + ENTER + "ambiguous first" + ENTER + "invalid" + + ENTER + "single" + ENTER + UP * 3 + CTRL_N + DOWN + ENTER, + "Result": SINGLE}, + + # + # tests that improve coverage + # + + # empty space tests + {"Name": "empty space test 1", + "Sequence": RIGHT + LEFT + CTRL_B + CTRL_F + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 2", + "Sequence": BKSPACE + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 3", + "Sequence": CTRL_E*2 + CTRL_A*2 + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 4", + "Sequence": ALT_F*2 + ALT_B*2 + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 5", + "Sequence": " " + CTRL_E*2 + CTRL_A*2 + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 6", + "Sequence": " " + CTRL_A + ALT_F*2 + ALT_B*2 + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 7", + "Sequence": " " + CTRL_A + CTRL_D + CTRL_E + CTRL_D + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 8", + "Sequence": " space" + CTRL_W*2 + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 9", + "Sequence": " space" + ALT_BKSPACE*2 + ENTER, + "Result": PROMPT}, + {"Name": "empty space test 10", + "Sequence": " space " + CTRL_A + ALT_D*3 + ENTER, + "Result": PROMPT}, + + # non-printable char tests + {"Name": "non-printable test 1", + "Sequence": chr(27) + chr(47) + ENTER, + "Result": PROMPT}, + {"Name": "non-printable test 2", + "Sequence": chr(27) + chr(128) + ENTER*7, + "Result": PROMPT}, + {"Name": "non-printable test 3", + "Sequence": chr(27) + chr(91) + chr(127) + ENTER*6, + "Result": PROMPT}, + + # miscellaneous tests + {"Name": "misc test 1", + "Sequence": ENTER, + "Result": PROMPT}, + {"Name": "misc test 2", + "Sequence": "single #comment" + ENTER, + "Result": SINGLE}, + {"Name": "misc test 3", + "Sequence": "#empty line" + ENTER, + "Result": PROMPT}, + {"Name": "misc test 4", + "Sequence": " single " + ENTER, + "Result": SINGLE}, + {"Name": "misc test 5", + "Sequence": "single#" + ENTER, + "Result": SINGLE}, + {"Name": "misc test 6", + "Sequence": 'a' * 257 + ENTER, + "Result": NOT_FOUND}, + {"Name": "misc test 7", + "Sequence": "clear_history" + UP*5 + DOWN*5 + ENTER, + "Result": PROMPT}, + {"Name": "misc test 8", + "Sequence": "a" + HELP + CTRL_C, + "Result": PROMPT}, + {"Name": "misc test 9", + "Sequence": CTRL_D*3, + "Result": None}, +] diff --git a/test/cmdline_test/commands.c b/test/cmdline_test/commands.c new file mode 100644 index 0000000000..404f51af6f --- /dev/null +++ b/test/cmdline_test/commands.c @@ -0,0 +1,389 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "cmdline_test.h" + +/*** quit ***/ +/* exit application */ + +struct cmd_quit_result { + cmdline_fixed_string_t quit; +}; + +static void +cmd_quit_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_quit(cl); +} + +cmdline_parse_token_string_t cmd_quit_tok = + TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, + "quit"); + +cmdline_parse_inst_t cmd_quit = { + .f = cmd_quit_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "exit application", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_quit_tok, + NULL, + }, +}; + + + +/*** single ***/ +/* a simple single-word command */ + +struct cmd_single_result { + cmdline_fixed_string_t single; +}; + +static void +cmd_single_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_printf(cl, "Single word command parsed!\n"); +} + +cmdline_parse_token_string_t cmd_single_tok = + TOKEN_STRING_INITIALIZER(struct cmd_single_result, single, + "single"); + +cmdline_parse_inst_t cmd_single = { + .f = cmd_single_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "a simple single-word command", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_single_tok, + NULL, + }, +}; + + + +/*** single_long ***/ +/* a variant of "single" command. useful to test autocomplete */ + +struct cmd_single_long_result { + cmdline_fixed_string_t single_long; +}; + +static void +cmd_single_long_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_printf(cl, "Single long word command parsed!\n"); +} + +cmdline_parse_token_string_t cmd_single_long_tok = + TOKEN_STRING_INITIALIZER(struct cmd_single_long_result, single_long, + "single_long"); + +cmdline_parse_inst_t cmd_single_long = { + .f = cmd_single_long_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "a variant of \"single\" command, useful to test autocomplete", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_single_long_tok, + NULL, + }, +}; + + + +/*** autocomplete_1 ***/ +/* first command to test autocomplete when multiple commands have chars + * in common but none should complete due to ambiguity + */ + +struct cmd_autocomplete_1_result { + cmdline_fixed_string_t token; +}; + +static void +cmd_autocomplete_1_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_printf(cl, "Autocomplete command 1 parsed!\n"); +} + +cmdline_parse_token_string_t cmd_autocomplete_1_tok = + TOKEN_STRING_INITIALIZER(struct cmd_autocomplete_1_result, token, + "autocomplete_1"); + +cmdline_parse_inst_t cmd_autocomplete_1 = { + .f = cmd_autocomplete_1_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "first ambiguous autocomplete command", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_autocomplete_1_tok, + NULL, + }, +}; + + + +/*** autocomplete_2 ***/ +/* second command to test autocomplete when multiple commands have chars + * in common but none should complete due to ambiguity + */ + +struct cmd_autocomplete_2_result { + cmdline_fixed_string_t token; +}; + +static void +cmd_autocomplete_2_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_printf(cl, "Autocomplete command 2 parsed!\n"); +} + +cmdline_parse_token_string_t cmd_autocomplete_2_tok = + TOKEN_STRING_INITIALIZER(struct cmd_autocomplete_2_result, token, + "autocomplete_2"); + +cmdline_parse_inst_t cmd_autocomplete_2 = { + .f = cmd_autocomplete_2_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "second ambiguous autocomplete command", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_autocomplete_2_tok, + NULL, + }, +}; + + + +/*** number command ***/ +/* a command that simply returns whatever (uint32) number is supplied to it */ + +struct cmd_num_result { + unsigned num; +}; + +static void +cmd_num_parsed(void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + unsigned result = ((struct cmd_num_result*)parsed_result)->num; + cmdline_printf(cl, "%u\n", result); +} + +cmdline_parse_token_num_t cmd_num_tok = + TOKEN_NUM_INITIALIZER(struct cmd_num_result, num, UINT32); + +cmdline_parse_inst_t cmd_num = { + .f = cmd_num_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "a command that simply returns whatever number is entered", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_num_tok, + NULL, + }, +}; + + + +/*** ambiguous first|ambiguous ***/ +/* first command used to test command ambiguity */ + +struct cmd_ambig_result_1 { + cmdline_fixed_string_t common_part; + cmdline_fixed_string_t ambig_part; +}; + +static void +cmd_ambig_1_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_printf(cl, "Command 1 parsed!\n"); +} + +cmdline_parse_token_string_t cmd_ambig_common_1 = + TOKEN_STRING_INITIALIZER(struct cmd_ambig_result_1, common_part, + "ambiguous"); +cmdline_parse_token_string_t cmd_ambig_ambig_1 = + TOKEN_STRING_INITIALIZER(struct cmd_ambig_result_1, ambig_part, + "first#ambiguous#ambiguous2"); + +cmdline_parse_inst_t cmd_ambig_1 = { + .f = cmd_ambig_1_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "first command used to test command ambiguity", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_ambig_common_1, + (void*)&cmd_ambig_ambig_1, + NULL, + }, +}; + + + +/*** ambiguous second|ambiguous ***/ +/* second command used to test command ambiguity */ + +struct cmd_ambig_result_2 { + cmdline_fixed_string_t common_part; + cmdline_fixed_string_t ambig_part; +}; + +static void +cmd_ambig_2_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_printf(cl, "Command 2 parsed!\n"); +} + +cmdline_parse_token_string_t cmd_ambig_common_2 = + TOKEN_STRING_INITIALIZER(struct cmd_ambig_result_2, common_part, + "ambiguous"); +cmdline_parse_token_string_t cmd_ambig_ambig_2 = + TOKEN_STRING_INITIALIZER(struct cmd_ambig_result_2, ambig_part, + "second#ambiguous#ambiguous2"); + +cmdline_parse_inst_t cmd_ambig_2 = { + .f = cmd_ambig_2_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "second command used to test command ambiguity", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_ambig_common_2, + (void*)&cmd_ambig_ambig_2, + NULL, + }, +}; + + + +/*** get_history_bufsize ***/ +/* command that displays total space in history buffer + * this will be useful for testing history (to fill it up just enough to + * remove the last entry, we need to know how big it is). + */ + +struct cmd_get_history_bufsize_result { + cmdline_fixed_string_t str; +}; + +static void +cmd_get_history_bufsize_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_printf(cl, "History buffer size: %zu\n", + sizeof(cl->rdl.history_buf)); +} + +cmdline_parse_token_string_t cmd_get_history_bufsize_tok = + TOKEN_STRING_INITIALIZER(struct cmd_get_history_bufsize_result, str, + "get_history_bufsize"); + +cmdline_parse_inst_t cmd_get_history_bufsize = { + .f = cmd_get_history_bufsize_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "command that displays total space in history buffer", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_get_history_bufsize_tok, + NULL, + }, +}; + + + +/*** clear_history ***/ +/* clears history buffer */ + +struct cmd_clear_history_result { + cmdline_fixed_string_t str; +}; + +static void +cmd_clear_history_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + rdline_clear_history(&cl->rdl); +} + +cmdline_parse_token_string_t cmd_clear_history_tok = + TOKEN_STRING_INITIALIZER(struct cmd_clear_history_result, str, + "clear_history"); + +cmdline_parse_inst_t cmd_clear_history = { + .f = cmd_clear_history_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "clear command history", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_clear_history_tok, + NULL, + }, +}; + + + +/****************/ + +cmdline_parse_ctx_t main_ctx[] = { + (cmdline_parse_inst_t *)&cmd_quit, + (cmdline_parse_inst_t *)&cmd_ambig_1, + (cmdline_parse_inst_t *)&cmd_ambig_2, + (cmdline_parse_inst_t *)&cmd_single, + (cmdline_parse_inst_t *)&cmd_single_long, + (cmdline_parse_inst_t *)&cmd_num, + (cmdline_parse_inst_t *)&cmd_get_history_bufsize, + (cmdline_parse_inst_t *)&cmd_clear_history, + (cmdline_parse_inst_t *)&cmd_autocomplete_1, + (cmdline_parse_inst_t *)&cmd_autocomplete_2, + NULL, +}; diff --git a/test/test-acl/Makefile b/test/test-acl/Makefile new file mode 100644 index 0000000000..43dfdcbd51 --- /dev/null +++ b/test/test-acl/Makefile @@ -0,0 +1,48 @@ +# 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 $(RTE_SDK)/mk/rte.vars.mk + +ifeq ($(CONFIG_RTE_LIBRTE_ACL),y) + +APP = testacl + +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/test/test-acl/main.c b/test/test-acl/main.c new file mode 100644 index 0000000000..1b2b1760e1 --- /dev/null +++ b/test/test-acl/main.c @@ -0,0 +1,1125 @@ +/*- + * 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 +#include +#include + +#include +#include +#include +#include + +#define PRINT_USAGE_START "%s [EAL options]\n" + +#define RTE_LOGTYPE_TESTACL RTE_LOGTYPE_USER1 + +#define APP_NAME "TESTACL" + +#define GET_CB_FIELD(in, fd, base, lim, dlm) do { \ + unsigned long val; \ + char *end_fld; \ + errno = 0; \ + val = strtoul((in), &end_fld, (base)); \ + if (errno != 0 || end_fld[0] != (dlm) || val > (lim)) \ + return -EINVAL; \ + (fd) = (typeof(fd))val; \ + (in) = end_fld + 1; \ +} while (0) + +#define OPT_RULE_FILE "rulesf" +#define OPT_TRACE_FILE "tracef" +#define OPT_RULE_NUM "rulenum" +#define OPT_TRACE_NUM "tracenum" +#define OPT_TRACE_STEP "tracestep" +#define OPT_SEARCH_ALG "alg" +#define OPT_BLD_CATEGORIES "bldcat" +#define OPT_RUN_CATEGORIES "runcat" +#define OPT_MAX_SIZE "maxsize" +#define OPT_ITER_NUM "iter" +#define OPT_VERBOSE "verbose" +#define OPT_IPV6 "ipv6" + +#define TRACE_DEFAULT_NUM 0x10000 +#define TRACE_STEP_MAX 0x1000 +#define TRACE_STEP_DEF 0x100 + +#define RULE_NUM 0x10000 + +enum { + DUMP_NONE, + DUMP_SEARCH, + DUMP_PKT, + DUMP_MAX +}; + +struct acl_alg { + const char *name; + enum rte_acl_classify_alg alg; +}; + +static const struct acl_alg acl_alg[] = { + { + .name = "scalar", + .alg = RTE_ACL_CLASSIFY_SCALAR, + }, + { + .name = "sse", + .alg = RTE_ACL_CLASSIFY_SSE, + }, + { + .name = "avx2", + .alg = RTE_ACL_CLASSIFY_AVX2, + }, + { + .name = "neon", + .alg = RTE_ACL_CLASSIFY_NEON, + }, + { + .name = "altivec", + .alg = RTE_ACL_CLASSIFY_ALTIVEC, + }, +}; + +static struct { + const char *prgname; + const char *rule_file; + const char *trace_file; + size_t max_size; + uint32_t bld_categories; + uint32_t run_categories; + uint32_t nb_rules; + uint32_t nb_traces; + uint32_t trace_step; + uint32_t trace_sz; + uint32_t iter_num; + uint32_t verbose; + uint32_t ipv6; + struct acl_alg alg; + uint32_t used_traces; + void *traces; + struct rte_acl_ctx *acx; +} config = { + .bld_categories = 3, + .run_categories = 1, + .nb_rules = RULE_NUM, + .nb_traces = TRACE_DEFAULT_NUM, + .trace_step = TRACE_STEP_DEF, + .iter_num = 1, + .verbose = DUMP_MAX, + .alg = { + .name = "default", + .alg = RTE_ACL_CLASSIFY_DEFAULT, + }, + .ipv6 = 0 +}; + +static struct rte_acl_param prm = { + .name = APP_NAME, + .socket_id = SOCKET_ID_ANY, +}; + +/* + * Rule and trace formats definitions. + */ + +struct ipv4_5tuple { + uint8_t proto; + uint32_t ip_src; + uint32_t ip_dst; + uint16_t port_src; + uint16_t port_dst; +}; + +enum { + PROTO_FIELD_IPV4, + SRC_FIELD_IPV4, + DST_FIELD_IPV4, + SRCP_FIELD_IPV4, + DSTP_FIELD_IPV4, + NUM_FIELDS_IPV4 +}; + +/* + * That effectively defines order of IPV4VLAN classifications: + * - PROTO + * - VLAN (TAG and DOMAIN) + * - SRC IP ADDRESS + * - DST IP ADDRESS + * - PORTS (SRC and DST) + */ +enum { + RTE_ACL_IPV4VLAN_PROTO, + RTE_ACL_IPV4VLAN_VLAN, + RTE_ACL_IPV4VLAN_SRC, + RTE_ACL_IPV4VLAN_DST, + RTE_ACL_IPV4VLAN_PORTS, + RTE_ACL_IPV4VLAN_NUM +}; + +struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint8_t), + .field_index = PROTO_FIELD_IPV4, + .input_index = RTE_ACL_IPV4VLAN_PROTO, + .offset = offsetof(struct ipv4_5tuple, proto), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = SRC_FIELD_IPV4, + .input_index = RTE_ACL_IPV4VLAN_SRC, + .offset = offsetof(struct ipv4_5tuple, ip_src), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = DST_FIELD_IPV4, + .input_index = RTE_ACL_IPV4VLAN_DST, + .offset = offsetof(struct ipv4_5tuple, ip_dst), + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = SRCP_FIELD_IPV4, + .input_index = RTE_ACL_IPV4VLAN_PORTS, + .offset = offsetof(struct ipv4_5tuple, port_src), + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = DSTP_FIELD_IPV4, + .input_index = RTE_ACL_IPV4VLAN_PORTS, + .offset = offsetof(struct ipv4_5tuple, port_dst), + }, +}; + +#define IPV6_ADDR_LEN 16 +#define IPV6_ADDR_U16 (IPV6_ADDR_LEN / sizeof(uint16_t)) +#define IPV6_ADDR_U32 (IPV6_ADDR_LEN / sizeof(uint32_t)) + +struct ipv6_5tuple { + uint8_t proto; + uint32_t ip_src[IPV6_ADDR_U32]; + uint32_t ip_dst[IPV6_ADDR_U32]; + uint16_t port_src; + uint16_t port_dst; +}; + +enum { + PROTO_FIELD_IPV6, + SRC1_FIELD_IPV6, + SRC2_FIELD_IPV6, + SRC3_FIELD_IPV6, + SRC4_FIELD_IPV6, + DST1_FIELD_IPV6, + DST2_FIELD_IPV6, + DST3_FIELD_IPV6, + DST4_FIELD_IPV6, + SRCP_FIELD_IPV6, + DSTP_FIELD_IPV6, + NUM_FIELDS_IPV6 +}; + +struct rte_acl_field_def ipv6_defs[NUM_FIELDS_IPV6] = { + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint8_t), + .field_index = PROTO_FIELD_IPV6, + .input_index = PROTO_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, proto), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = SRC1_FIELD_IPV6, + .input_index = SRC1_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, ip_src[0]), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = SRC2_FIELD_IPV6, + .input_index = SRC2_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, ip_src[1]), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = SRC3_FIELD_IPV6, + .input_index = SRC3_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, ip_src[2]), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = SRC4_FIELD_IPV6, + .input_index = SRC4_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, ip_src[3]), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = DST1_FIELD_IPV6, + .input_index = DST1_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, ip_dst[0]), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = DST2_FIELD_IPV6, + .input_index = DST2_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, ip_dst[1]), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = DST3_FIELD_IPV6, + .input_index = DST3_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, ip_dst[2]), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = DST4_FIELD_IPV6, + .input_index = DST4_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, ip_dst[3]), + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = SRCP_FIELD_IPV6, + .input_index = SRCP_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, port_src), + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = DSTP_FIELD_IPV6, + .input_index = SRCP_FIELD_IPV6, + .offset = offsetof(struct ipv6_5tuple, port_dst), + }, +}; + + +enum { + CB_FLD_SRC_ADDR, + CB_FLD_DST_ADDR, + CB_FLD_SRC_PORT_LOW, + CB_FLD_SRC_PORT_DLM, + CB_FLD_SRC_PORT_HIGH, + CB_FLD_DST_PORT_LOW, + CB_FLD_DST_PORT_DLM, + CB_FLD_DST_PORT_HIGH, + CB_FLD_PROTO, + CB_FLD_NUM, +}; + +enum { + CB_TRC_SRC_ADDR, + CB_TRC_DST_ADDR, + CB_TRC_SRC_PORT, + CB_TRC_DST_PORT, + CB_TRC_PROTO, + CB_TRC_NUM, +}; + +RTE_ACL_RULE_DEF(acl_rule, RTE_ACL_MAX_FIELDS); + +static const char cb_port_delim[] = ":"; + +static char line[LINE_MAX]; + +#define dump_verbose(lvl, fh, fmt, args...) do { \ + if ((lvl) <= (int32_t)config.verbose) \ + fprintf(fh, fmt, ##args); \ +} while (0) + + +/* + * Parse ClassBench input trace (test vectors and expected results) file. + * Expected format: + * \ + * + */ +static int +parse_cb_ipv4_trace(char *str, struct ipv4_5tuple *v) +{ + int i; + char *s, *sp, *in[CB_TRC_NUM]; + static const char *dlm = " \t\n"; + + s = str; + for (i = 0; i != RTE_DIM(in); i++) { + in[i] = strtok_r(s, dlm, &sp); + if (in[i] == NULL) + return -EINVAL; + s = NULL; + } + + GET_CB_FIELD(in[CB_TRC_SRC_ADDR], v->ip_src, 0, UINT32_MAX, 0); + GET_CB_FIELD(in[CB_TRC_DST_ADDR], v->ip_dst, 0, UINT32_MAX, 0); + GET_CB_FIELD(in[CB_TRC_SRC_PORT], v->port_src, 0, UINT16_MAX, 0); + GET_CB_FIELD(in[CB_TRC_DST_PORT], v->port_dst, 0, UINT16_MAX, 0); + GET_CB_FIELD(in[CB_TRC_PROTO], v->proto, 0, UINT8_MAX, 0); + + /* convert to network byte order. */ + v->ip_src = rte_cpu_to_be_32(v->ip_src); + v->ip_dst = rte_cpu_to_be_32(v->ip_dst); + v->port_src = rte_cpu_to_be_16(v->port_src); + v->port_dst = rte_cpu_to_be_16(v->port_dst); + + return 0; +} + +/* + * Parses IPV6 address, exepcts the following format: + * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX (where X - is a hexedecimal digit). + */ +static int +parse_ipv6_addr(const char *in, const char **end, uint32_t v[IPV6_ADDR_U32], + char dlm) +{ + uint32_t addr[IPV6_ADDR_U16]; + + GET_CB_FIELD(in, addr[0], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[1], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[2], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[3], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[4], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[5], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[6], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[7], 16, UINT16_MAX, dlm); + + *end = in; + + v[0] = (addr[0] << 16) + addr[1]; + v[1] = (addr[2] << 16) + addr[3]; + v[2] = (addr[4] << 16) + addr[5]; + v[3] = (addr[6] << 16) + addr[7]; + + return 0; +} + +static int +parse_cb_ipv6_addr_trace(const char *in, uint32_t v[IPV6_ADDR_U32]) +{ + int32_t rc; + const char *end; + + rc = parse_ipv6_addr(in, &end, v, 0); + if (rc != 0) + return rc; + + v[0] = rte_cpu_to_be_32(v[0]); + v[1] = rte_cpu_to_be_32(v[1]); + v[2] = rte_cpu_to_be_32(v[2]); + v[3] = rte_cpu_to_be_32(v[3]); + + return 0; +} + +/* + * Parse ClassBench input trace (test vectors and expected results) file. + * Expected format: + * \ + * + */ +static int +parse_cb_ipv6_trace(char *str, struct ipv6_5tuple *v) +{ + int32_t i, rc; + char *s, *sp, *in[CB_TRC_NUM]; + static const char *dlm = " \t\n"; + + s = str; + for (i = 0; i != RTE_DIM(in); i++) { + in[i] = strtok_r(s, dlm, &sp); + if (in[i] == NULL) + return -EINVAL; + s = NULL; + } + + /* get ip6 src address. */ + rc = parse_cb_ipv6_addr_trace(in[CB_TRC_SRC_ADDR], v->ip_src); + if (rc != 0) + return rc; + + /* get ip6 dst address. */ + rc = parse_cb_ipv6_addr_trace(in[CB_TRC_DST_ADDR], v->ip_dst); + if (rc != 0) + return rc; + + GET_CB_FIELD(in[CB_TRC_SRC_PORT], v->port_src, 0, UINT16_MAX, 0); + GET_CB_FIELD(in[CB_TRC_DST_PORT], v->port_dst, 0, UINT16_MAX, 0); + GET_CB_FIELD(in[CB_TRC_PROTO], v->proto, 0, UINT8_MAX, 0); + + /* convert to network byte order. */ + v->port_src = rte_cpu_to_be_16(v->port_src); + v->port_dst = rte_cpu_to_be_16(v->port_dst); + + return 0; +} + +static void +tracef_init(void) +{ + static const char name[] = APP_NAME; + FILE *f; + size_t sz; + uint32_t n; + struct ipv4_5tuple *v; + struct ipv6_5tuple *w; + + sz = config.nb_traces * (config.ipv6 ? sizeof(*w) : sizeof(*v)); + config.traces = rte_zmalloc_socket(name, sz, RTE_CACHE_LINE_SIZE, + SOCKET_ID_ANY); + if (config.traces == NULL) + rte_exit(EXIT_FAILURE, "Cannot allocate %zu bytes for " + "requested %u number of trace records\n", + sz, config.nb_traces); + + f = fopen(config.trace_file, "r"); + if (f == NULL) + rte_exit(-EINVAL, "failed to open file: %s\n", + config.trace_file); + + v = config.traces; + w = config.traces; + for (n = 0; n != config.nb_traces; n++) { + + if (fgets(line, sizeof(line), f) == NULL) + break; + + if (config.ipv6) { + if (parse_cb_ipv6_trace(line, w + n) != 0) + rte_exit(EXIT_FAILURE, + "%s: failed to parse ipv6 trace " + "record at line %u\n", + config.trace_file, n + 1); + } else { + if (parse_cb_ipv4_trace(line, v + n) != 0) + rte_exit(EXIT_FAILURE, + "%s: failed to parse ipv4 trace " + "record at line %u\n", + config.trace_file, n + 1); + } + } + + config.used_traces = n; + fclose(f); +} + +static int +parse_ipv6_net(const char *in, struct rte_acl_field field[4]) +{ + int32_t rc; + const char *mp; + uint32_t i, m, v[4]; + const uint32_t nbu32 = sizeof(uint32_t) * CHAR_BIT; + + /* get address. */ + rc = parse_ipv6_addr(in, &mp, v, '/'); + if (rc != 0) + return rc; + + /* get mask. */ + GET_CB_FIELD(mp, m, 0, CHAR_BIT * sizeof(v), 0); + + /* put all together. */ + for (i = 0; i != RTE_DIM(v); i++) { + if (m >= (i + 1) * nbu32) + field[i].mask_range.u32 = nbu32; + else + field[i].mask_range.u32 = m > (i * nbu32) ? + m - (i * 32) : 0; + + field[i].value.u32 = v[i]; + } + + return 0; +} + + +static int +parse_cb_ipv6_rule(char *str, struct acl_rule *v) +{ + int i, rc; + char *s, *sp, *in[CB_FLD_NUM]; + static const char *dlm = " \t\n"; + + /* + * Skip leading '@' + */ + if (strchr(str, '@') != str) + return -EINVAL; + + s = str + 1; + + for (i = 0; i != RTE_DIM(in); i++) { + in[i] = strtok_r(s, dlm, &sp); + if (in[i] == NULL) + return -EINVAL; + s = NULL; + } + + rc = parse_ipv6_net(in[CB_FLD_SRC_ADDR], v->field + SRC1_FIELD_IPV6); + if (rc != 0) { + RTE_LOG(ERR, TESTACL, + "failed to read source address/mask: %s\n", + in[CB_FLD_SRC_ADDR]); + return rc; + } + + rc = parse_ipv6_net(in[CB_FLD_DST_ADDR], v->field + DST1_FIELD_IPV6); + if (rc != 0) { + RTE_LOG(ERR, TESTACL, + "failed to read destination address/mask: %s\n", + in[CB_FLD_DST_ADDR]); + return rc; + } + + /* source port. */ + GET_CB_FIELD(in[CB_FLD_SRC_PORT_LOW], + v->field[SRCP_FIELD_IPV6].value.u16, + 0, UINT16_MAX, 0); + GET_CB_FIELD(in[CB_FLD_SRC_PORT_HIGH], + v->field[SRCP_FIELD_IPV6].mask_range.u16, + 0, UINT16_MAX, 0); + + if (strncmp(in[CB_FLD_SRC_PORT_DLM], cb_port_delim, + sizeof(cb_port_delim)) != 0) + return -EINVAL; + + /* destination port. */ + GET_CB_FIELD(in[CB_FLD_DST_PORT_LOW], + v->field[DSTP_FIELD_IPV6].value.u16, + 0, UINT16_MAX, 0); + GET_CB_FIELD(in[CB_FLD_DST_PORT_HIGH], + v->field[DSTP_FIELD_IPV6].mask_range.u16, + 0, UINT16_MAX, 0); + + if (strncmp(in[CB_FLD_DST_PORT_DLM], cb_port_delim, + sizeof(cb_port_delim)) != 0) + return -EINVAL; + + GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV6].value.u8, + 0, UINT8_MAX, '/'); + GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV6].mask_range.u8, + 0, UINT8_MAX, 0); + + return 0; +} + +static int +parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len) +{ + uint8_t a, b, c, d, m; + + GET_CB_FIELD(in, a, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, b, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, c, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, d, 0, UINT8_MAX, '/'); + GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0); + + addr[0] = IPv4(a, b, c, d); + mask_len[0] = m; + + return 0; +} +/* + * Parse ClassBench rules file. + * Expected format: + * '@''/' \ + * '/' \ + * ":" \ + * ":" \ + * '/' + */ +static int +parse_cb_ipv4_rule(char *str, struct acl_rule *v) +{ + int i, rc; + char *s, *sp, *in[CB_FLD_NUM]; + static const char *dlm = " \t\n"; + + /* + * Skip leading '@' + */ + if (strchr(str, '@') != str) + return -EINVAL; + + s = str + 1; + + for (i = 0; i != RTE_DIM(in); i++) { + in[i] = strtok_r(s, dlm, &sp); + if (in[i] == NULL) + return -EINVAL; + s = NULL; + } + + rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR], + &v->field[SRC_FIELD_IPV4].value.u32, + &v->field[SRC_FIELD_IPV4].mask_range.u32); + if (rc != 0) { + RTE_LOG(ERR, TESTACL, + "failed to read source address/mask: %s\n", + in[CB_FLD_SRC_ADDR]); + return rc; + } + + rc = parse_ipv4_net(in[CB_FLD_DST_ADDR], + &v->field[DST_FIELD_IPV4].value.u32, + &v->field[DST_FIELD_IPV4].mask_range.u32); + if (rc != 0) { + RTE_LOG(ERR, TESTACL, + "failed to read destination address/mask: %s\n", + in[CB_FLD_DST_ADDR]); + return rc; + } + + /* source port. */ + GET_CB_FIELD(in[CB_FLD_SRC_PORT_LOW], + v->field[SRCP_FIELD_IPV4].value.u16, + 0, UINT16_MAX, 0); + GET_CB_FIELD(in[CB_FLD_SRC_PORT_HIGH], + v->field[SRCP_FIELD_IPV4].mask_range.u16, + 0, UINT16_MAX, 0); + + if (strncmp(in[CB_FLD_SRC_PORT_DLM], cb_port_delim, + sizeof(cb_port_delim)) != 0) + return -EINVAL; + + /* destination port. */ + GET_CB_FIELD(in[CB_FLD_DST_PORT_LOW], + v->field[DSTP_FIELD_IPV4].value.u16, + 0, UINT16_MAX, 0); + GET_CB_FIELD(in[CB_FLD_DST_PORT_HIGH], + v->field[DSTP_FIELD_IPV4].mask_range.u16, + 0, UINT16_MAX, 0); + + if (strncmp(in[CB_FLD_DST_PORT_DLM], cb_port_delim, + sizeof(cb_port_delim)) != 0) + return -EINVAL; + + GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV4].value.u8, + 0, UINT8_MAX, '/'); + GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV4].mask_range.u8, + 0, UINT8_MAX, 0); + + return 0; +} + +typedef int (*parse_5tuple)(char *text, struct acl_rule *rule); + +static int +add_cb_rules(FILE *f, struct rte_acl_ctx *ctx) +{ + int rc; + uint32_t n; + struct acl_rule v; + parse_5tuple parser; + + memset(&v, 0, sizeof(v)); + parser = (config.ipv6 != 0) ? parse_cb_ipv6_rule : parse_cb_ipv4_rule; + + for (n = 1; fgets(line, sizeof(line), f) != NULL; n++) { + + rc = parser(line, &v); + if (rc != 0) { + RTE_LOG(ERR, TESTACL, "line %u: parse_cb_ipv4vlan_rule" + " failed, error code: %d (%s)\n", + n, rc, strerror(-rc)); + return rc; + } + + v.data.category_mask = RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, + typeof(v.data.category_mask)); + v.data.priority = RTE_ACL_MAX_PRIORITY - n; + v.data.userdata = n; + + rc = rte_acl_add_rules(ctx, (struct rte_acl_rule *)&v, 1); + if (rc != 0) { + RTE_LOG(ERR, TESTACL, "line %u: failed to add rules " + "into ACL context, error code: %d (%s)\n", + n, rc, strerror(-rc)); + return rc; + } + } + + return 0; +} + +static void +acx_init(void) +{ + int ret; + FILE *f; + struct rte_acl_config cfg; + + memset(&cfg, 0, sizeof(cfg)); + + /* setup ACL build config. */ + if (config.ipv6) { + cfg.num_fields = RTE_DIM(ipv6_defs); + memcpy(&cfg.defs, ipv6_defs, sizeof(ipv6_defs)); + } else { + cfg.num_fields = RTE_DIM(ipv4_defs); + memcpy(&cfg.defs, ipv4_defs, sizeof(ipv4_defs)); + } + cfg.num_categories = config.bld_categories; + cfg.max_size = config.max_size; + + /* setup ACL creation parameters. */ + prm.rule_size = RTE_ACL_RULE_SZ(cfg.num_fields); + prm.max_rule_num = config.nb_rules; + + config.acx = rte_acl_create(&prm); + if (config.acx == NULL) + rte_exit(rte_errno, "failed to create ACL context\n"); + + /* set default classify method for this context. */ + if (config.alg.alg != RTE_ACL_CLASSIFY_DEFAULT) { + ret = rte_acl_set_ctx_classify(config.acx, config.alg.alg); + if (ret != 0) + rte_exit(ret, "failed to setup %s method " + "for ACL context\n", config.alg.name); + } + + /* add ACL rules. */ + f = fopen(config.rule_file, "r"); + if (f == NULL) + rte_exit(-EINVAL, "failed to open file %s\n", + config.rule_file); + + ret = add_cb_rules(f, config.acx); + if (ret != 0) + rte_exit(ret, "failed to add rules into ACL context\n"); + + fclose(f); + + /* perform build. */ + ret = rte_acl_build(config.acx, &cfg); + + dump_verbose(DUMP_NONE, stdout, + "rte_acl_build(%u) finished with %d\n", + config.bld_categories, ret); + + rte_acl_dump(config.acx); + + if (ret != 0) + rte_exit(ret, "failed to build search context\n"); +} + +static uint32_t +search_ip5tuples_once(uint32_t categories, uint32_t step, const char *alg) +{ + int ret; + uint32_t i, j, k, n, r; + const uint8_t *data[step], *v; + uint32_t results[step * categories]; + + v = config.traces; + for (i = 0; i != config.used_traces; i += n) { + + n = RTE_MIN(step, config.used_traces - i); + + for (j = 0; j != n; j++) { + data[j] = v; + v += config.trace_sz; + } + + ret = rte_acl_classify(config.acx, data, results, + n, categories); + + if (ret != 0) + rte_exit(ret, "classify for ipv%c_5tuples returns %d\n", + config.ipv6 ? '6' : '4', ret); + + for (r = 0, j = 0; j != n; j++) { + for (k = 0; k != categories; k++, r++) { + dump_verbose(DUMP_PKT, stdout, + "ipv%c_5tuple: %u, category: %u, " + "result: %u\n", + config.ipv6 ? '6' : '4', + i + j + 1, k, results[r] - 1); + } + + } + } + + dump_verbose(DUMP_SEARCH, stdout, + "%s(%u, %u, %s) returns %u\n", __func__, + categories, step, alg, i); + return i; +} + +static int +search_ip5tuples(__attribute__((unused)) void *arg) +{ + uint64_t pkt, start, tm; + uint32_t i, lcore; + + lcore = rte_lcore_id(); + start = rte_rdtsc(); + pkt = 0; + + for (i = 0; i != config.iter_num; i++) { + pkt += search_ip5tuples_once(config.run_categories, + config.trace_step, config.alg.name); + } + + tm = rte_rdtsc() - start; + dump_verbose(DUMP_NONE, stdout, + "%s @lcore %u: %" PRIu32 " iterations, %" PRIu64 " pkts, %" + PRIu32 " categories, %" PRIu64 " cycles, %#Lf cycles/pkt\n", + __func__, lcore, i, pkt, config.run_categories, + tm, (pkt == 0) ? 0 : (long double)tm / pkt); + + return 0; +} + +static unsigned long +get_ulong_opt(const char *opt, const char *name, size_t min, size_t max) +{ + unsigned long val; + char *end; + + errno = 0; + val = strtoul(opt, &end, 0); + if (errno != 0 || end[0] != 0 || val > max || val < min) + rte_exit(-EINVAL, "invalid value: \"%s\" for option: %s\n", + opt, name); + return val; +} + +static void +get_alg_opt(const char *opt, const char *name) +{ + uint32_t i; + + for (i = 0; i != RTE_DIM(acl_alg); i++) { + if (strcmp(opt, acl_alg[i].name) == 0) { + config.alg = acl_alg[i]; + return; + } + } + + rte_exit(-EINVAL, "invalid value: \"%s\" for option: %s\n", + opt, name); +} + +static void +print_usage(const char *prgname) +{ + uint32_t i, n, rc; + char buf[PATH_MAX]; + + n = 0; + buf[0] = 0; + + for (i = 0; i < RTE_DIM(acl_alg) - 1; i++) { + rc = snprintf(buf + n, sizeof(buf) - n, "%s|", + acl_alg[i].name); + if (rc > sizeof(buf) - n) + break; + n += rc; + } + + snprintf(buf + n, sizeof(buf) - n, "%s", acl_alg[i].name); + + fprintf(stdout, + PRINT_USAGE_START + "--" OPT_RULE_FILE "=\n" + "[--" OPT_TRACE_FILE "=]\n" + "[--" OPT_RULE_NUM + "=]\n" + "[--" OPT_TRACE_NUM + "=]\n" + "[--" OPT_TRACE_STEP + "=]\n" + "[--" OPT_BLD_CATEGORIES + "=]\n" + "[--" OPT_RUN_CATEGORIES + "= " + "should be either 1 or multiple of %zu, " + "but not greater then %u]\n" + "[--" OPT_MAX_SIZE + "= " + "leave 0 for default behaviour]\n" + "[--" OPT_ITER_NUM "=]\n" + "[--" OPT_VERBOSE "=]\n" + "[--" OPT_SEARCH_ALG "=%s]\n" + "[--" OPT_IPV6 "=]\n", + prgname, RTE_ACL_RESULTS_MULTIPLIER, + (uint32_t)RTE_ACL_MAX_CATEGORIES, + buf); +} + +static void +dump_config(FILE *f) +{ + fprintf(f, "%s:\n", __func__); + fprintf(f, "%s:%s\n", OPT_RULE_FILE, config.rule_file); + fprintf(f, "%s:%s\n", OPT_TRACE_FILE, config.trace_file); + fprintf(f, "%s:%u\n", OPT_RULE_NUM, config.nb_rules); + fprintf(f, "%s:%u\n", OPT_TRACE_NUM, config.nb_traces); + fprintf(f, "%s:%u\n", OPT_TRACE_STEP, config.trace_step); + fprintf(f, "%s:%u\n", OPT_BLD_CATEGORIES, config.bld_categories); + fprintf(f, "%s:%u\n", OPT_RUN_CATEGORIES, config.run_categories); + fprintf(f, "%s:%zu\n", OPT_MAX_SIZE, config.max_size); + fprintf(f, "%s:%u\n", OPT_ITER_NUM, config.iter_num); + fprintf(f, "%s:%u\n", OPT_VERBOSE, config.verbose); + fprintf(f, "%s:%u(%s)\n", OPT_SEARCH_ALG, config.alg.alg, + config.alg.name); + fprintf(f, "%s:%u\n", OPT_IPV6, config.ipv6); +} + +static void +check_config(void) +{ + if (config.rule_file == NULL) { + print_usage(config.prgname); + rte_exit(-EINVAL, "mandatory option %s is not specified\n", + OPT_RULE_FILE); + } +} + + +static void +get_input_opts(int argc, char **argv) +{ + static struct option lgopts[] = { + {OPT_RULE_FILE, 1, 0, 0}, + {OPT_TRACE_FILE, 1, 0, 0}, + {OPT_TRACE_NUM, 1, 0, 0}, + {OPT_RULE_NUM, 1, 0, 0}, + {OPT_MAX_SIZE, 1, 0, 0}, + {OPT_TRACE_STEP, 1, 0, 0}, + {OPT_BLD_CATEGORIES, 1, 0, 0}, + {OPT_RUN_CATEGORIES, 1, 0, 0}, + {OPT_ITER_NUM, 1, 0, 0}, + {OPT_VERBOSE, 1, 0, 0}, + {OPT_SEARCH_ALG, 1, 0, 0}, + {OPT_IPV6, 0, 0, 0}, + {NULL, 0, 0, 0} + }; + + int opt, opt_idx; + + while ((opt = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) { + + if (opt != 0) { + print_usage(config.prgname); + rte_exit(-EINVAL, "unknown option: %c", opt); + } + + if (strcmp(lgopts[opt_idx].name, OPT_RULE_FILE) == 0) { + config.rule_file = optarg; + } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_FILE) == 0) { + config.trace_file = optarg; + } else if (strcmp(lgopts[opt_idx].name, OPT_RULE_NUM) == 0) { + config.nb_rules = get_ulong_opt(optarg, + lgopts[opt_idx].name, 1, RTE_ACL_MAX_INDEX + 1); + } else if (strcmp(lgopts[opt_idx].name, OPT_MAX_SIZE) == 0) { + config.max_size = get_ulong_opt(optarg, + lgopts[opt_idx].name, 0, SIZE_MAX); + } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_NUM) == 0) { + config.nb_traces = get_ulong_opt(optarg, + lgopts[opt_idx].name, 1, UINT32_MAX); + } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_STEP) == 0) { + config.trace_step = get_ulong_opt(optarg, + lgopts[opt_idx].name, 1, TRACE_STEP_MAX); + } else if (strcmp(lgopts[opt_idx].name, + OPT_BLD_CATEGORIES) == 0) { + config.bld_categories = get_ulong_opt(optarg, + lgopts[opt_idx].name, 1, + RTE_ACL_MAX_CATEGORIES); + } else if (strcmp(lgopts[opt_idx].name, + OPT_RUN_CATEGORIES) == 0) { + config.run_categories = get_ulong_opt(optarg, + lgopts[opt_idx].name, 1, + RTE_ACL_MAX_CATEGORIES); + } else if (strcmp(lgopts[opt_idx].name, OPT_ITER_NUM) == 0) { + config.iter_num = get_ulong_opt(optarg, + lgopts[opt_idx].name, 1, INT32_MAX); + } else if (strcmp(lgopts[opt_idx].name, OPT_VERBOSE) == 0) { + config.verbose = get_ulong_opt(optarg, + lgopts[opt_idx].name, DUMP_NONE, DUMP_MAX); + } else if (strcmp(lgopts[opt_idx].name, + OPT_SEARCH_ALG) == 0) { + get_alg_opt(optarg, lgopts[opt_idx].name); + } else if (strcmp(lgopts[opt_idx].name, OPT_IPV6) == 0) { + config.ipv6 = 1; + } + } + config.trace_sz = config.ipv6 ? sizeof(struct ipv6_5tuple) : + sizeof(struct ipv4_5tuple); + +} + +int +main(int argc, char **argv) +{ + int ret; + uint32_t lcore; + + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_panic("Cannot init EAL\n"); + + argc -= ret; + argv += ret; + + config.prgname = argv[0]; + + get_input_opts(argc, argv); + dump_config(stdout); + check_config(); + + acx_init(); + + if (config.trace_file != NULL) + tracef_init(); + + RTE_LCORE_FOREACH_SLAVE(lcore) + rte_eal_remote_launch(search_ip5tuples, NULL, lcore); + + search_ip5tuples(NULL); + + rte_eal_mp_wait_lcore(); + + rte_acl_free(config.acx); + return 0; +} diff --git a/test/test-pipeline/Makefile b/test/test-pipeline/Makefile new file mode 100644 index 0000000000..4bab6dc6c4 --- /dev/null +++ b/test/test-pipeline/Makefile @@ -0,0 +1,64 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2015 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_PIPELINE),y) + +# +# library name +# +APP = testpipeline + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +# +# all source are stored in SRCS-y +# +SRCS-y := main.c +SRCS-y += config.c +SRCS-y += init.c +SRCS-y += runtime.c +SRCS-y += pipeline_stub.c +SRCS-y += pipeline_hash.c +SRCS-y += pipeline_lpm.c +SRCS-y += pipeline_lpm_ipv6.c + +# include ACL lib if available +SRCS-$(CONFIG_RTE_LIBRTE_ACL) += pipeline_acl.c + +# this application needs libraries first +DEPDIRS-y += lib drivers + +include $(RTE_SDK)/mk/rte.app.mk + +endif diff --git a/test/test-pipeline/config.c b/test/test-pipeline/config.c new file mode 100644 index 0000000000..dd80ed6991 --- /dev/null +++ b/test/test-pipeline/config.c @@ -0,0 +1,264 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" + +struct app_params app; + +static const char usage[] = "\n"; + +void +app_print_usage(void) +{ + printf(usage); +} + +static int +app_parse_port_mask(const char *arg) +{ + char *end = NULL; + uint64_t port_mask; + uint32_t i; + + if (arg[0] == '\0') + return -1; + + port_mask = strtoul(arg, &end, 16); + if ((end == NULL) || (*end != '\0')) + return -2; + + if (port_mask == 0) + return -3; + + app.n_ports = 0; + for (i = 0; i < 64; i++) { + if ((port_mask & (1LLU << i)) == 0) + continue; + + if (app.n_ports >= APP_MAX_PORTS) + return -4; + + app.ports[app.n_ports] = i; + app.n_ports++; + } + + if (!rte_is_power_of_2(app.n_ports)) + return -5; + + return 0; +} + +struct { + const char *name; + uint32_t value; +} app_args_table[] = { + {"none", e_APP_PIPELINE_NONE}, + {"stub", e_APP_PIPELINE_STUB}, + {"hash-8-ext", e_APP_PIPELINE_HASH_KEY8_EXT}, + {"hash-8-lru", e_APP_PIPELINE_HASH_KEY8_LRU}, + {"hash-16-ext", e_APP_PIPELINE_HASH_KEY16_EXT}, + {"hash-16-lru", e_APP_PIPELINE_HASH_KEY16_LRU}, + {"hash-32-ext", e_APP_PIPELINE_HASH_KEY32_EXT}, + {"hash-32-lru", e_APP_PIPELINE_HASH_KEY32_LRU}, + {"hash-spec-8-ext", e_APP_PIPELINE_HASH_SPEC_KEY8_EXT}, + {"hash-spec-8-lru", e_APP_PIPELINE_HASH_SPEC_KEY8_LRU}, + {"hash-spec-16-ext", e_APP_PIPELINE_HASH_SPEC_KEY16_EXT}, + {"hash-spec-16-lru", e_APP_PIPELINE_HASH_SPEC_KEY16_LRU}, + {"hash-spec-32-ext", e_APP_PIPELINE_HASH_SPEC_KEY32_EXT}, + {"hash-spec-32-lru", e_APP_PIPELINE_HASH_SPEC_KEY32_LRU}, + {"acl", e_APP_PIPELINE_ACL}, + {"lpm", e_APP_PIPELINE_LPM}, + {"lpm-ipv6", e_APP_PIPELINE_LPM_IPV6}, + {"hash-cuckoo-8", e_APP_PIPELINE_HASH_CUCKOO_KEY8}, + {"hash-cuckoo-16", e_APP_PIPELINE_HASH_CUCKOO_KEY16}, + {"hash-cuckoo-32", e_APP_PIPELINE_HASH_CUCKOO_KEY32}, + {"hash-cuckoo-48", e_APP_PIPELINE_HASH_CUCKOO_KEY48}, + {"hash-cuckoo-64", e_APP_PIPELINE_HASH_CUCKOO_KEY64}, + {"hash-cuckoo-80", e_APP_PIPELINE_HASH_CUCKOO_KEY80}, + {"hash-cuckoo-96", e_APP_PIPELINE_HASH_CUCKOO_KEY96}, + {"hash-cuckoo-112", e_APP_PIPELINE_HASH_CUCKOO_KEY112}, + {"hash-cuckoo-128", e_APP_PIPELINE_HASH_CUCKOO_KEY128}, +}; + +int +app_parse_args(int argc, char **argv) +{ + int opt, ret; + char **argvopt; + int option_index; + char *prgname = argv[0]; + static struct option lgopts[] = { + {"none", 0, 0, 0}, + {"stub", 0, 0, 0}, + {"hash-8-ext", 0, 0, 0}, + {"hash-8-lru", 0, 0, 0}, + {"hash-16-ext", 0, 0, 0}, + {"hash-16-lru", 0, 0, 0}, + {"hash-32-ext", 0, 0, 0}, + {"hash-32-lru", 0, 0, 0}, + {"hash-spec-8-ext", 0, 0, 0}, + {"hash-spec-8-lru", 0, 0, 0}, + {"hash-spec-16-ext", 0, 0, 0}, + {"hash-spec-16-lru", 0, 0, 0}, + {"hash-spec-32-ext", 0, 0, 0}, + {"hash-spec-32-lru", 0, 0, 0}, + {"acl", 0, 0, 0}, + {"lpm", 0, 0, 0}, + {"lpm-ipv6", 0, 0, 0}, + {"hash-cuckoo-8", 0, 0, 0}, + {"hash-cuckoo-16", 0, 0, 0}, + {"hash-cuckoo-32", 0, 0, 0}, + {"hash-cuckoo-48", 0, 0, 0}, + {"hash-cuckoo-64", 0, 0, 0}, + {"hash-cuckoo-80", 0, 0, 0}, + {"hash-cuckoo-96", 0, 0, 0}, + {"hash-cuckoo-112", 0, 0, 0}, + {"hash-cuckoo-128", 0, 0, 0}, + {NULL, 0, 0, 0} + }; + uint32_t lcores[3], n_lcores, lcore_id, pipeline_type_provided; + + /* EAL args */ + n_lcores = 0; + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (rte_lcore_is_enabled(lcore_id) == 0) + continue; + + if (n_lcores >= 3) { + RTE_LOG(ERR, USER1, "Number of cores must be 3\n"); + app_print_usage(); + return -1; + } + + lcores[n_lcores] = lcore_id; + n_lcores++; + } + + if (n_lcores != 3) { + RTE_LOG(ERR, USER1, "Number of cores must be 3\n"); + app_print_usage(); + return -1; + } + + app.core_rx = lcores[0]; + app.core_worker = lcores[1]; + app.core_tx = lcores[2]; + + /* Non-EAL args */ + argvopt = argv; + + app.pipeline_type = e_APP_PIPELINE_HASH_KEY16_LRU; + pipeline_type_provided = 0; + + while ((opt = getopt_long(argc, argvopt, "p:", + lgopts, &option_index)) != EOF) { + switch (opt) { + case 'p': + if (app_parse_port_mask(optarg) < 0) { + app_print_usage(); + return -1; + } + break; + + case 0: /* long options */ + if (!pipeline_type_provided) { + uint32_t i; + + for (i = 0; i < e_APP_PIPELINES; i++) { + if (!strcmp(lgopts[option_index].name, + app_args_table[i].name)) { + app.pipeline_type = + app_args_table[i].value; + pipeline_type_provided = 1; + break; + } + } + + break; + } + + app_print_usage(); + return -1; + + default: + return -1; + } + } + + if (optind >= 0) + argv[optind - 1] = prgname; + + ret = optind - 1; + optind = 0; /* reset getopt lib */ + return ret; +} diff --git a/test/test-pipeline/init.c b/test/test-pipeline/init.c new file mode 100644 index 0000000000..aef082fc3a --- /dev/null +++ b/test/test-pipeline/init.c @@ -0,0 +1,280 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" + +struct app_params app = { + /* Ports*/ + .n_ports = APP_MAX_PORTS, + .port_rx_ring_size = 128, + .port_tx_ring_size = 512, + + /* Rings */ + .ring_rx_size = 128, + .ring_tx_size = 128, + + /* Buffer pool */ + .pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM, + .pool_size = 32 * 1024, + .pool_cache_size = 256, + + /* Burst sizes */ + .burst_size_rx_read = 64, + .burst_size_rx_write = 64, + .burst_size_worker_read = 64, + .burst_size_worker_write = 64, + .burst_size_tx_read = 64, + .burst_size_tx_write = 64, +}; + +static struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + .header_split = 0, /* Header Split disabled */ + .hw_ip_checksum = 1, /* IP checksum offload enabled */ + .hw_vlan_filter = 0, /* VLAN filtering disabled */ + .jumbo_frame = 0, /* Jumbo Frame Support disabled */ + .hw_strip_crc = 0, /* CRC stripped by hardware */ + }, + .rx_adv_conf = { + .rss_conf = { + .rss_key = NULL, + .rss_hf = ETH_RSS_IP, + }, + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, +}; + +static struct rte_eth_rxconf rx_conf = { + .rx_thresh = { + .pthresh = 8, + .hthresh = 8, + .wthresh = 4, + }, + .rx_free_thresh = 64, + .rx_drop_en = 0, +}; + +static struct rte_eth_txconf tx_conf = { + .tx_thresh = { + .pthresh = 36, + .hthresh = 0, + .wthresh = 0, + }, + .tx_free_thresh = 0, + .tx_rs_thresh = 0, +}; + +static void +app_init_mbuf_pools(void) +{ + /* Init the buffer pool */ + RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n"); + app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size, + app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id()); + if (app.pool == NULL) + rte_panic("Cannot create mbuf pool\n"); +} + +static void +app_init_rings(void) +{ + uint32_t i; + + for (i = 0; i < app.n_ports; i++) { + char name[32]; + + snprintf(name, sizeof(name), "app_ring_rx_%u", i); + + app.rings_rx[i] = rte_ring_create( + name, + app.ring_rx_size, + rte_socket_id(), + RING_F_SP_ENQ | RING_F_SC_DEQ); + + if (app.rings_rx[i] == NULL) + rte_panic("Cannot create RX ring %u\n", i); + } + + for (i = 0; i < app.n_ports; i++) { + char name[32]; + + snprintf(name, sizeof(name), "app_ring_tx_%u", i); + + app.rings_tx[i] = rte_ring_create( + name, + app.ring_tx_size, + rte_socket_id(), + RING_F_SP_ENQ | RING_F_SC_DEQ); + + if (app.rings_tx[i] == NULL) + rte_panic("Cannot create TX ring %u\n", i); + } + +} + +static void +app_ports_check_link(void) +{ + uint32_t all_ports_up, i; + + all_ports_up = 1; + + for (i = 0; i < app.n_ports; i++) { + struct rte_eth_link link; + uint8_t port; + + port = (uint8_t) app.ports[i]; + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(port, &link); + RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n", + port, + link.link_speed / 1000, + link.link_status ? "UP" : "DOWN"); + + if (link.link_status == ETH_LINK_DOWN) + all_ports_up = 0; + } + + if (all_ports_up == 0) + rte_panic("Some NIC ports are DOWN\n"); +} + +static void +app_init_ports(void) +{ + uint32_t i; + + /* Init NIC ports, then start the ports */ + for (i = 0; i < app.n_ports; i++) { + uint8_t port; + int ret; + + port = (uint8_t) app.ports[i]; + RTE_LOG(INFO, USER1, "Initializing NIC port %u ...\n", port); + + /* Init port */ + ret = rte_eth_dev_configure( + port, + 1, + 1, + &port_conf); + if (ret < 0) + rte_panic("Cannot init NIC port %u (%d)\n", port, ret); + + rte_eth_promiscuous_enable(port); + + /* Init RX queues */ + ret = rte_eth_rx_queue_setup( + port, + 0, + app.port_rx_ring_size, + rte_eth_dev_socket_id(port), + &rx_conf, + app.pool); + if (ret < 0) + rte_panic("Cannot init RX for port %u (%d)\n", + (uint32_t) port, ret); + + /* Init TX queues */ + ret = rte_eth_tx_queue_setup( + port, + 0, + app.port_tx_ring_size, + rte_eth_dev_socket_id(port), + &tx_conf); + if (ret < 0) + rte_panic("Cannot init TX for port %u (%d)\n", + (uint32_t) port, ret); + + /* Start port */ + ret = rte_eth_dev_start(port); + if (ret < 0) + rte_panic("Cannot start port %u (%d)\n", port, ret); + } + + app_ports_check_link(); +} + +void +app_init(void) +{ + app_init_mbuf_pools(); + app_init_rings(); + app_init_ports(); + + RTE_LOG(INFO, USER1, "Initialization completed\n"); +} diff --git a/test/test-pipeline/main.c b/test/test-pipeline/main.c new file mode 100644 index 0000000000..71ab6ad985 --- /dev/null +++ b/test/test-pipeline/main.c @@ -0,0 +1,188 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" + +int +main(int argc, char **argv) +{ + uint32_t lcore; + int ret; + + /* Init EAL */ + ret = rte_eal_init(argc, argv); + if (ret < 0) + return -1; + argc -= ret; + argv += ret; + + /* Parse application arguments (after the EAL ones) */ + ret = app_parse_args(argc, argv); + if (ret < 0) { + app_print_usage(); + return -1; + } + + /* Init */ + app_init(); + + /* Launch per-lcore init on every lcore */ + rte_eal_mp_remote_launch(app_lcore_main_loop, NULL, CALL_MASTER); + RTE_LCORE_FOREACH_SLAVE(lcore) { + if (rte_eal_wait_lcore(lcore) < 0) + return -1; + } + + return 0; +} + +int +app_lcore_main_loop(__attribute__((unused)) void *arg) +{ + unsigned lcore; + + lcore = rte_lcore_id(); + + if (lcore == app.core_rx) { + switch (app.pipeline_type) { + case e_APP_PIPELINE_ACL: + app_main_loop_rx(); + return 0; + + default: + app_main_loop_rx_metadata(); + return 0; + } + } + + if (lcore == app.core_worker) { + switch (app.pipeline_type) { + case e_APP_PIPELINE_STUB: + app_main_loop_worker_pipeline_stub(); + return 0; + + case e_APP_PIPELINE_HASH_KEY8_EXT: + case e_APP_PIPELINE_HASH_KEY8_LRU: + case e_APP_PIPELINE_HASH_KEY16_EXT: + case e_APP_PIPELINE_HASH_KEY16_LRU: + case e_APP_PIPELINE_HASH_KEY32_EXT: + case e_APP_PIPELINE_HASH_KEY32_LRU: + case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT: + case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU: + case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT: + case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU: + case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT: + case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU: + /* cases for cuckoo hash table types */ + case e_APP_PIPELINE_HASH_CUCKOO_KEY8: + case e_APP_PIPELINE_HASH_CUCKOO_KEY16: + case e_APP_PIPELINE_HASH_CUCKOO_KEY32: + case e_APP_PIPELINE_HASH_CUCKOO_KEY48: + case e_APP_PIPELINE_HASH_CUCKOO_KEY64: + case e_APP_PIPELINE_HASH_CUCKOO_KEY80: + case e_APP_PIPELINE_HASH_CUCKOO_KEY96: + case e_APP_PIPELINE_HASH_CUCKOO_KEY112: + case e_APP_PIPELINE_HASH_CUCKOO_KEY128: + app_main_loop_worker_pipeline_hash(); + return 0; + + case e_APP_PIPELINE_ACL: +#ifndef RTE_LIBRTE_ACL + rte_exit(EXIT_FAILURE, "ACL not present in build\n"); +#else + app_main_loop_worker_pipeline_acl(); + return 0; +#endif + + case e_APP_PIPELINE_LPM: + app_main_loop_worker_pipeline_lpm(); + return 0; + + case e_APP_PIPELINE_LPM_IPV6: + app_main_loop_worker_pipeline_lpm_ipv6(); + return 0; + + case e_APP_PIPELINE_NONE: + default: + app_main_loop_worker(); + return 0; + } + } + + if (lcore == app.core_tx) { + app_main_loop_tx(); + return 0; + } + + return 0; +} diff --git a/test/test-pipeline/main.h b/test/test-pipeline/main.h new file mode 100644 index 0000000000..3685849278 --- /dev/null +++ b/test/test-pipeline/main.h @@ -0,0 +1,152 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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. + */ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#ifndef APP_MBUF_ARRAY_SIZE +#define APP_MBUF_ARRAY_SIZE 256 +#endif + +struct app_mbuf_array { + struct rte_mbuf *array[APP_MBUF_ARRAY_SIZE]; + uint16_t n_mbufs; +}; + +#ifndef APP_MAX_PORTS +#define APP_MAX_PORTS 4 +#endif + +struct app_params { + /* CPU cores */ + uint32_t core_rx; + uint32_t core_worker; + uint32_t core_tx; + + /* Ports*/ + uint32_t ports[APP_MAX_PORTS]; + uint32_t n_ports; + uint32_t port_rx_ring_size; + uint32_t port_tx_ring_size; + + /* Rings */ + struct rte_ring *rings_rx[APP_MAX_PORTS]; + struct rte_ring *rings_tx[APP_MAX_PORTS]; + uint32_t ring_rx_size; + uint32_t ring_tx_size; + + /* Internal buffers */ + struct app_mbuf_array mbuf_rx; + struct app_mbuf_array mbuf_tx[APP_MAX_PORTS]; + + /* Buffer pool */ + struct rte_mempool *pool; + uint32_t pool_buffer_size; + uint32_t pool_size; + uint32_t pool_cache_size; + + /* Burst sizes */ + uint32_t burst_size_rx_read; + uint32_t burst_size_rx_write; + uint32_t burst_size_worker_read; + uint32_t burst_size_worker_write; + uint32_t burst_size_tx_read; + uint32_t burst_size_tx_write; + + /* App behavior */ + uint32_t pipeline_type; +} __rte_cache_aligned; + +extern struct app_params app; + +int app_parse_args(int argc, char **argv); +void app_print_usage(void); +void app_init(void); +int app_lcore_main_loop(void *arg); + +/* Pipeline */ +enum { + e_APP_PIPELINE_NONE = 0, + e_APP_PIPELINE_STUB, + + e_APP_PIPELINE_HASH_KEY8_EXT, + e_APP_PIPELINE_HASH_KEY8_LRU, + e_APP_PIPELINE_HASH_KEY16_EXT, + e_APP_PIPELINE_HASH_KEY16_LRU, + e_APP_PIPELINE_HASH_KEY32_EXT, + e_APP_PIPELINE_HASH_KEY32_LRU, + + e_APP_PIPELINE_HASH_SPEC_KEY8_EXT, + e_APP_PIPELINE_HASH_SPEC_KEY8_LRU, + e_APP_PIPELINE_HASH_SPEC_KEY16_EXT, + e_APP_PIPELINE_HASH_SPEC_KEY16_LRU, + e_APP_PIPELINE_HASH_SPEC_KEY32_EXT, + e_APP_PIPELINE_HASH_SPEC_KEY32_LRU, + + e_APP_PIPELINE_ACL, + e_APP_PIPELINE_LPM, + e_APP_PIPELINE_LPM_IPV6, + + e_APP_PIPELINE_HASH_CUCKOO_KEY8, + e_APP_PIPELINE_HASH_CUCKOO_KEY16, + e_APP_PIPELINE_HASH_CUCKOO_KEY32, + e_APP_PIPELINE_HASH_CUCKOO_KEY48, + e_APP_PIPELINE_HASH_CUCKOO_KEY64, + e_APP_PIPELINE_HASH_CUCKOO_KEY80, + e_APP_PIPELINE_HASH_CUCKOO_KEY96, + e_APP_PIPELINE_HASH_CUCKOO_KEY112, + e_APP_PIPELINE_HASH_CUCKOO_KEY128, + e_APP_PIPELINES +}; + +void app_main_loop_rx(void); +void app_main_loop_rx_metadata(void); +uint64_t test_hash(void *key, uint32_t key_size, uint64_t seed); + +void app_main_loop_worker(void); +void app_main_loop_worker_pipeline_stub(void); +void app_main_loop_worker_pipeline_hash(void); +void app_main_loop_worker_pipeline_acl(void); +void app_main_loop_worker_pipeline_lpm(void); +void app_main_loop_worker_pipeline_lpm_ipv6(void); + +void app_main_loop_tx(void); + +#define APP_FLUSH 0 +#ifndef APP_FLUSH +#define APP_FLUSH 0x3FF +#endif + +#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset)) + +#endif /* _MAIN_H_ */ diff --git a/test/test-pipeline/pipeline_acl.c b/test/test-pipeline/pipeline_acl.c new file mode 100644 index 0000000000..22d5f362a7 --- /dev/null +++ b/test/test-pipeline/pipeline_acl.c @@ -0,0 +1,277 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "main.h" + +enum { + PROTO_FIELD_IPV4, + SRC_FIELD_IPV4, + DST_FIELD_IPV4, + SRCP_FIELD_IPV4, + DSTP_FIELD_IPV4, + NUM_FIELDS_IPV4 +}; + +/* + * Here we define the 'shape' of the data we're searching for, + * by defining the meta-data of the ACL rules. + * in this case, we're defining 5 tuples. IP addresses, ports, + * and protocol. + */ +struct rte_acl_field_def ipv4_field_formats[NUM_FIELDS_IPV4] = { + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint8_t), + .field_index = PROTO_FIELD_IPV4, + .input_index = PROTO_FIELD_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, next_proto_id), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = SRC_FIELD_IPV4, + .input_index = SRC_FIELD_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, src_addr), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = DST_FIELD_IPV4, + .input_index = DST_FIELD_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, dst_addr), + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = SRCP_FIELD_IPV4, + .input_index = SRCP_FIELD_IPV4, + .offset = sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr), + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = DSTP_FIELD_IPV4, + .input_index = SRCP_FIELD_IPV4, + .offset = sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr) + + sizeof(uint16_t), + }, +}; + + + +void +app_main_loop_worker_pipeline_acl(void) { + struct rte_pipeline_params pipeline_params = { + .name = "pipeline", + .socket_id = rte_socket_id(), + }; + + struct rte_pipeline *p; + uint32_t port_in_id[APP_MAX_PORTS]; + uint32_t port_out_id[APP_MAX_PORTS]; + uint32_t table_id; + uint32_t i; + + RTE_LOG(INFO, USER1, + "Core %u is doing work (pipeline with ACL table)\n", + rte_lcore_id()); + + /* Pipeline configuration */ + p = rte_pipeline_create(&pipeline_params); + if (p == NULL) + rte_panic("Unable to configure the pipeline\n"); + + /* Input port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_reader_params port_ring_params = { + .ring = app.rings_rx[i], + }; + + struct rte_pipeline_port_in_params port_params = { + .ops = &rte_port_ring_reader_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + .burst_size = app.burst_size_worker_read, + }; + + if (rte_pipeline_port_in_create(p, &port_params, + &port_in_id[i])) + rte_panic("Unable to configure input port for " + "ring %d\n", i); + } + + /* Output port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_writer_params port_ring_params = { + .ring = app.rings_tx[i], + .tx_burst_sz = app.burst_size_worker_write, + }; + + struct rte_pipeline_port_out_params port_params = { + .ops = &rte_port_ring_writer_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + }; + + if (rte_pipeline_port_out_create(p, &port_params, + &port_out_id[i])) + rte_panic("Unable to configure output port for " + "ring %d\n", i); + } + + /* Table configuration */ + { + struct rte_table_acl_params table_acl_params = { + .name = "test", /* unique identifier for acl contexts */ + .n_rules = 1 << 5, + .n_rule_fields = DIM(ipv4_field_formats), + }; + + /* Copy in the rule meta-data defined above into the params */ + memcpy(table_acl_params.field_format, ipv4_field_formats, + sizeof(ipv4_field_formats)); + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_acl_ops, + .arg_create = &table_acl_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the ACL table\n"); + } + + /* Interconnecting ports and tables */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], + table_id)) + rte_panic("Unable to connect input port %u to " + "table %u\n", port_in_id[i], table_id); + + /* Add entries to tables */ + for (i = 0; i < app.n_ports; i++) { + struct rte_pipeline_table_entry table_entry = { + .action = RTE_PIPELINE_ACTION_PORT, + {.port_id = port_out_id[i & (app.n_ports - 1)]}, + }; + struct rte_table_acl_rule_add_params rule_params; + struct rte_pipeline_table_entry *entry_ptr; + int key_found, ret; + + memset(&rule_params, 0, sizeof(rule_params)); + + /* Set the rule values */ + rule_params.field_value[SRC_FIELD_IPV4].value.u32 = 0; + rule_params.field_value[SRC_FIELD_IPV4].mask_range.u32 = 0; + rule_params.field_value[DST_FIELD_IPV4].value.u32 = + i << (24 - __builtin_popcount(app.n_ports - 1)); + rule_params.field_value[DST_FIELD_IPV4].mask_range.u32 = + 8 + __builtin_popcount(app.n_ports - 1); + rule_params.field_value[SRCP_FIELD_IPV4].value.u16 = 0; + rule_params.field_value[SRCP_FIELD_IPV4].mask_range.u16 = + UINT16_MAX; + rule_params.field_value[DSTP_FIELD_IPV4].value.u16 = 0; + rule_params.field_value[DSTP_FIELD_IPV4].mask_range.u16 = + UINT16_MAX; + rule_params.field_value[PROTO_FIELD_IPV4].value.u8 = 0; + rule_params.field_value[PROTO_FIELD_IPV4].mask_range.u8 = 0; + + rule_params.priority = 0; + + uint32_t dst_addr = rule_params.field_value[DST_FIELD_IPV4]. + value.u32; + uint32_t dst_mask = + rule_params.field_value[DST_FIELD_IPV4].mask_range.u32; + + printf("Adding rule to ACL table (IPv4 destination = " + "%u.%u.%u.%u/%u => port out = %u)\n", + (dst_addr & 0xFF000000) >> 24, + (dst_addr & 0x00FF0000) >> 16, + (dst_addr & 0x0000FF00) >> 8, + dst_addr & 0x000000FF, + dst_mask, + table_entry.port_id); + + /* For ACL, add needs an rte_table_acl_rule_add_params struct */ + ret = rte_pipeline_table_entry_add(p, table_id, &rule_params, + &table_entry, &key_found, &entry_ptr); + if (ret < 0) + rte_panic("Unable to add entry to table %u (%d)\n", + table_id, ret); + } + + /* Enable input ports */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_enable(p, port_in_id[i])) + rte_panic("Unable to enable input port %u\n", + port_in_id[i]); + + /* Check pipeline consistency */ + if (rte_pipeline_check(p) < 0) + rte_panic("Pipeline consistency check failed\n"); + + /* Run-time */ +#if APP_FLUSH == 0 + for ( ; ; ) + rte_pipeline_run(p); +#else + for (i = 0; ; i++) { + rte_pipeline_run(p); + + if ((i & APP_FLUSH) == 0) + rte_pipeline_flush(p); + } +#endif +} diff --git a/test/test-pipeline/pipeline_hash.c b/test/test-pipeline/pipeline_hash.c new file mode 100644 index 0000000000..10d28695ef --- /dev/null +++ b/test/test-pipeline/pipeline_hash.c @@ -0,0 +1,552 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "main.h" + +static void +translate_options(uint32_t *special, uint32_t *ext, uint32_t *key_size) +{ + switch (app.pipeline_type) { + case e_APP_PIPELINE_HASH_KEY8_EXT: + *special = 0; *ext = 1; *key_size = 8; return; + case e_APP_PIPELINE_HASH_KEY8_LRU: + *special = 0; *ext = 0; *key_size = 8; return; + case e_APP_PIPELINE_HASH_KEY16_EXT: + *special = 0; *ext = 1; *key_size = 16; return; + case e_APP_PIPELINE_HASH_KEY16_LRU: + *special = 0; *ext = 0; *key_size = 16; return; + case e_APP_PIPELINE_HASH_KEY32_EXT: + *special = 0; *ext = 1; *key_size = 32; return; + case e_APP_PIPELINE_HASH_KEY32_LRU: + *special = 0; *ext = 0; *key_size = 32; return; + + case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT: + *special = 1; *ext = 1; *key_size = 8; return; + case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU: + *special = 1; *ext = 0; *key_size = 8; return; + case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT: + *special = 1; *ext = 1; *key_size = 16; return; + case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU: + *special = 1; *ext = 0; *key_size = 16; return; + case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT: + *special = 1; *ext = 1; *key_size = 32; return; + case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU: + *special = 1; *ext = 0; *key_size = 32; return; + + case e_APP_PIPELINE_HASH_CUCKOO_KEY8: + *special = 0; *ext = 0; *key_size = 8; return; + case e_APP_PIPELINE_HASH_CUCKOO_KEY16: + *special = 0; *ext = 0; *key_size = 16; return; + case e_APP_PIPELINE_HASH_CUCKOO_KEY32: + *special = 0; *ext = 0; *key_size = 32; return; + case e_APP_PIPELINE_HASH_CUCKOO_KEY48: + *special = 0; *ext = 0; *key_size = 48; return; + case e_APP_PIPELINE_HASH_CUCKOO_KEY64: + *special = 0; *ext = 0; *key_size = 64; return; + case e_APP_PIPELINE_HASH_CUCKOO_KEY80: + *special = 0; *ext = 0; *key_size = 80; return; + case e_APP_PIPELINE_HASH_CUCKOO_KEY96: + *special = 0; *ext = 0; *key_size = 96; return; + case e_APP_PIPELINE_HASH_CUCKOO_KEY112: + *special = 0; *ext = 0; *key_size = 112; return; + case e_APP_PIPELINE_HASH_CUCKOO_KEY128: + *special = 0; *ext = 0; *key_size = 128; return; + + default: + rte_panic("Invalid hash table type or key size\n"); + } +} +void +app_main_loop_worker_pipeline_hash(void) { + struct rte_pipeline_params pipeline_params = { + .name = "pipeline", + .socket_id = rte_socket_id(), + }; + + struct rte_pipeline *p; + uint32_t port_in_id[APP_MAX_PORTS]; + uint32_t port_out_id[APP_MAX_PORTS]; + uint32_t table_id; + uint32_t i; + uint32_t special, ext, key_size; + + translate_options(&special, &ext, &key_size); + + RTE_LOG(INFO, USER1, "Core %u is doing work " + "(pipeline with hash table, %s, %s, %d-byte key)\n", + rte_lcore_id(), + special ? "specialized" : "non-specialized", + ext ? "extendible bucket" : "LRU", + key_size); + + /* Pipeline configuration */ + p = rte_pipeline_create(&pipeline_params); + if (p == NULL) + rte_panic("Unable to configure the pipeline\n"); + + /* Input port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_reader_params port_ring_params = { + .ring = app.rings_rx[i], + }; + + struct rte_pipeline_port_in_params port_params = { + .ops = &rte_port_ring_reader_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + .burst_size = app.burst_size_worker_read, + }; + + if (rte_pipeline_port_in_create(p, &port_params, + &port_in_id[i])) + rte_panic("Unable to configure input port for " + "ring %d\n", i); + } + + /* Output port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_writer_params port_ring_params = { + .ring = app.rings_tx[i], + .tx_burst_sz = app.burst_size_worker_write, + }; + + struct rte_pipeline_port_out_params port_params = { + .ops = &rte_port_ring_writer_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + }; + + if (rte_pipeline_port_out_create(p, &port_params, + &port_out_id[i])) + rte_panic("Unable to configure output port for " + "ring %d\n", i); + } + + /* Table configuration */ + switch (app.pipeline_type) { + case e_APP_PIPELINE_HASH_KEY8_EXT: + case e_APP_PIPELINE_HASH_KEY16_EXT: + case e_APP_PIPELINE_HASH_KEY32_EXT: + { + struct rte_table_hash_ext_params table_hash_params = { + .key_size = key_size, + .n_keys = 1 << 24, + .n_buckets = 1 << 22, + .n_buckets_ext = 1 << 21, + .f_hash = test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_ext_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table\n"); + } + break; + + case e_APP_PIPELINE_HASH_KEY8_LRU: + case e_APP_PIPELINE_HASH_KEY16_LRU: + case e_APP_PIPELINE_HASH_KEY32_LRU: + { + struct rte_table_hash_lru_params table_hash_params = { + .key_size = key_size, + .n_keys = 1 << 24, + .n_buckets = 1 << 22, + .f_hash = test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_lru_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table\n"); + } + break; + + case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT: + { + struct rte_table_hash_key8_ext_params table_hash_params = { + .n_entries = 1 << 24, + .n_entries_ext = 1 << 23, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .f_hash = test_hash, + .seed = 0, + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_key8_ext_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table\n"); + } + break; + + case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU: + { + struct rte_table_hash_key8_lru_params table_hash_params = { + .n_entries = 1 << 24, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .f_hash = test_hash, + .seed = 0, + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_key8_lru_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table\n"); + } + break; + + case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT: + { + struct rte_table_hash_key16_ext_params table_hash_params = { + .n_entries = 1 << 24, + .n_entries_ext = 1 << 23, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .f_hash = test_hash, + .seed = 0, + .key_mask = NULL, + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_key16_ext_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table)\n"); + } + break; + + case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU: + { + struct rte_table_hash_key16_lru_params table_hash_params = { + .n_entries = 1 << 24, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .f_hash = test_hash, + .seed = 0, + .key_mask = NULL, + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_key16_lru_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table\n"); + } + break; + + case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT: + { + struct rte_table_hash_key32_ext_params table_hash_params = { + .n_entries = 1 << 24, + .n_entries_ext = 1 << 23, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .f_hash = test_hash, + .seed = 0, + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_key32_ext_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table\n"); + } + break; + + + case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU: + { + struct rte_table_hash_key32_lru_params table_hash_params = { + .n_entries = 1 << 24, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .f_hash = test_hash, + .seed = 0, + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_key32_lru_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table\n"); + } + break; + + case e_APP_PIPELINE_HASH_CUCKOO_KEY8: + case e_APP_PIPELINE_HASH_CUCKOO_KEY16: + case e_APP_PIPELINE_HASH_CUCKOO_KEY32: + case e_APP_PIPELINE_HASH_CUCKOO_KEY48: + case e_APP_PIPELINE_HASH_CUCKOO_KEY64: + case e_APP_PIPELINE_HASH_CUCKOO_KEY80: + case e_APP_PIPELINE_HASH_CUCKOO_KEY96: + case e_APP_PIPELINE_HASH_CUCKOO_KEY112: + case e_APP_PIPELINE_HASH_CUCKOO_KEY128: + { + char hash_name[RTE_HASH_NAMESIZE]; + + snprintf(hash_name, sizeof(hash_name), "RTE_TH_CUCKOO_%d", + app.pipeline_type); + + struct rte_table_hash_cuckoo_params table_hash_params = { + .key_size = key_size, + .n_keys = (1 << 24) + 1, + .f_hash = test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .name = hash_name, + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_hash_cuckoo_dosig_ops, + .arg_create = &table_hash_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the hash table\n"); + } + break; + + default: + rte_panic("Invalid hash table type or key size\n"); + } + + /* Interconnecting ports and tables */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], + table_id)) + rte_panic("Unable to connect input port %u to " + "table %u\n", port_in_id[i], table_id); + + /* Add entries to tables */ + for (i = 0; i < (1 << 24); i++) { + struct rte_pipeline_table_entry entry = { + .action = RTE_PIPELINE_ACTION_PORT, + {.port_id = port_out_id[i & (app.n_ports - 1)]}, + }; + struct rte_pipeline_table_entry *entry_ptr; + uint8_t key[32]; + uint32_t *k32 = (uint32_t *) key; + int key_found, status; + + memset(key, 0, sizeof(key)); + k32[0] = rte_be_to_cpu_32(i); + + status = rte_pipeline_table_entry_add(p, table_id, key, &entry, + &key_found, &entry_ptr); + if (status < 0) + rte_panic("Unable to add entry to table %u (%d)\n", + table_id, status); + } + + /* Enable input ports */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_enable(p, port_in_id[i])) + rte_panic("Unable to enable input port %u\n", + port_in_id[i]); + + /* Check pipeline consistency */ + if (rte_pipeline_check(p) < 0) + rte_panic("Pipeline consistency check failed\n"); + + /* Run-time */ +#if APP_FLUSH == 0 + for ( ; ; ) + rte_pipeline_run(p); +#else + for (i = 0; ; i++) { + rte_pipeline_run(p); + + if ((i & APP_FLUSH) == 0) + rte_pipeline_flush(p); + } +#endif +} + +uint64_t test_hash( + void *key, + __attribute__((unused)) uint32_t key_size, + __attribute__((unused)) uint64_t seed) +{ + uint32_t *k32 = (uint32_t *) key; + uint32_t ip_dst = rte_be_to_cpu_32(k32[0]); + uint64_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30); + + return signature; +} + +void +app_main_loop_rx_metadata(void) { + uint32_t i, j; + int ret; + + RTE_LOG(INFO, USER1, "Core %u is doing RX (with meta-data)\n", + rte_lcore_id()); + + for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) { + uint16_t n_mbufs; + + n_mbufs = rte_eth_rx_burst( + app.ports[i], + 0, + app.mbuf_rx.array, + app.burst_size_rx_read); + + if (n_mbufs == 0) + continue; + + for (j = 0; j < n_mbufs; j++) { + struct rte_mbuf *m; + uint8_t *m_data, *key; + struct ipv4_hdr *ip_hdr; + struct ipv6_hdr *ipv6_hdr; + uint32_t ip_dst; + uint8_t *ipv6_dst; + uint32_t *signature, *k32; + + m = app.mbuf_rx.array[j]; + m_data = rte_pktmbuf_mtod(m, uint8_t *); + signature = RTE_MBUF_METADATA_UINT32_PTR(m, + APP_METADATA_OFFSET(0)); + key = RTE_MBUF_METADATA_UINT8_PTR(m, + APP_METADATA_OFFSET(32)); + + if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) { + ip_hdr = (struct ipv4_hdr *) + &m_data[sizeof(struct ether_hdr)]; + ip_dst = ip_hdr->dst_addr; + + k32 = (uint32_t *) key; + k32[0] = ip_dst & 0xFFFFFF00; + } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) { + ipv6_hdr = (struct ipv6_hdr *) + &m_data[sizeof(struct ether_hdr)]; + ipv6_dst = ipv6_hdr->dst_addr; + + memcpy(key, ipv6_dst, 16); + } else + continue; + + *signature = test_hash(key, 0, 0); + } + + do { + ret = rte_ring_sp_enqueue_bulk( + app.rings_rx[i], + (void **) app.mbuf_rx.array, + n_mbufs); + } while (ret < 0); + } +} diff --git a/test/test-pipeline/pipeline_lpm.c b/test/test-pipeline/pipeline_lpm.c new file mode 100644 index 0000000000..ecea6b3b80 --- /dev/null +++ b/test/test-pipeline/pipeline_lpm.c @@ -0,0 +1,202 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "main.h" + +#ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s +#define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256 +#endif + +void +app_main_loop_worker_pipeline_lpm(void) { + struct rte_pipeline_params pipeline_params = { + .name = "pipeline", + .socket_id = rte_socket_id(), + }; + + struct rte_pipeline *p; + uint32_t port_in_id[APP_MAX_PORTS]; + uint32_t port_out_id[APP_MAX_PORTS]; + uint32_t table_id; + uint32_t i; + + RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with " + "LPM table)\n", rte_lcore_id()); + + /* Pipeline configuration */ + p = rte_pipeline_create(&pipeline_params); + if (p == NULL) + rte_panic("Unable to configure the pipeline\n"); + + /* Input port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_reader_params port_ring_params = { + .ring = app.rings_rx[i], + }; + + struct rte_pipeline_port_in_params port_params = { + .ops = &rte_port_ring_reader_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + .burst_size = app.burst_size_worker_read, + }; + + if (rte_pipeline_port_in_create(p, &port_params, + &port_in_id[i])) + rte_panic("Unable to configure input port for " + "ring %d\n", i); + } + + /* Output port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_writer_params port_ring_params = { + .ring = app.rings_tx[i], + .tx_burst_sz = app.burst_size_worker_write, + }; + + struct rte_pipeline_port_out_params port_params = { + .ops = &rte_port_ring_writer_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + }; + + if (rte_pipeline_port_out_create(p, &port_params, + &port_out_id[i])) + rte_panic("Unable to configure output port for " + "ring %d\n", i); + } + + /* Table configuration */ + { + struct rte_table_lpm_params table_lpm_params = { + .name = "LPM", + .n_rules = 1 << 24, + .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s, + .flags = 0, + .entry_unique_size = + sizeof(struct rte_pipeline_table_entry), + .offset = APP_METADATA_OFFSET(32), + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_lpm_ops, + .arg_create = &table_lpm_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the LPM table\n"); + } + + /* Interconnecting ports and tables */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], + table_id)) + rte_panic("Unable to connect input port %u to " + "table %u\n", port_in_id[i], table_id); + + /* Add entries to tables */ + for (i = 0; i < app.n_ports; i++) { + struct rte_pipeline_table_entry entry = { + .action = RTE_PIPELINE_ACTION_PORT, + {.port_id = port_out_id[i & (app.n_ports - 1)]}, + }; + + struct rte_table_lpm_key key = { + .ip = i << (24 - __builtin_popcount(app.n_ports - 1)), + .depth = 8 + __builtin_popcount(app.n_ports - 1), + }; + + struct rte_pipeline_table_entry *entry_ptr; + + int key_found, status; + + printf("Adding rule to LPM table (IPv4 destination = %" + PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8 + " => port out = %" PRIu32 ")\n", + (key.ip & 0xFF000000) >> 24, + (key.ip & 0x00FF0000) >> 16, + (key.ip & 0x0000FF00) >> 8, + key.ip & 0x000000FF, + key.depth, + i); + + status = rte_pipeline_table_entry_add(p, table_id, &key, &entry, + &key_found, &entry_ptr); + if (status < 0) + rte_panic("Unable to add entry to table %u (%d)\n", + table_id, status); + } + + /* Enable input ports */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_enable(p, port_in_id[i])) + rte_panic("Unable to enable input port %u\n", + port_in_id[i]); + + /* Check pipeline consistency */ + if (rte_pipeline_check(p) < 0) + rte_panic("Pipeline consistency check failed\n"); + + /* Run-time */ +#if APP_FLUSH == 0 + for ( ; ; ) + rte_pipeline_run(p); +#else + for (i = 0; ; i++) { + rte_pipeline_run(p); + + if ((i & APP_FLUSH) == 0) + rte_pipeline_flush(p); + } +#endif +} diff --git a/test/test-pipeline/pipeline_lpm_ipv6.c b/test/test-pipeline/pipeline_lpm_ipv6.c new file mode 100644 index 0000000000..3352e89df7 --- /dev/null +++ b/test/test-pipeline/pipeline_lpm_ipv6.c @@ -0,0 +1,200 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "main.h" + +void +app_main_loop_worker_pipeline_lpm_ipv6(void) { + struct rte_pipeline_params pipeline_params = { + .name = "pipeline", + .socket_id = rte_socket_id(), + }; + + struct rte_pipeline *p; + uint32_t port_in_id[APP_MAX_PORTS]; + uint32_t port_out_id[APP_MAX_PORTS]; + uint32_t table_id; + uint32_t i; + + RTE_LOG(INFO, USER1, + "Core %u is doing work (pipeline with IPv6 LPM table)\n", + rte_lcore_id()); + + /* Pipeline configuration */ + p = rte_pipeline_create(&pipeline_params); + if (p == NULL) + rte_panic("Unable to configure the pipeline\n"); + + /* Input port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_reader_params port_ring_params = { + .ring = app.rings_rx[i], + }; + + struct rte_pipeline_port_in_params port_params = { + .ops = &rte_port_ring_reader_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + .burst_size = app.burst_size_worker_read, + }; + + if (rte_pipeline_port_in_create(p, &port_params, + &port_in_id[i])) + rte_panic("Unable to configure input port for " + "ring %d\n", i); + } + + /* Output port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_writer_params port_ring_params = { + .ring = app.rings_tx[i], + .tx_burst_sz = app.burst_size_worker_write, + }; + + struct rte_pipeline_port_out_params port_params = { + .ops = &rte_port_ring_writer_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + }; + + if (rte_pipeline_port_out_create(p, &port_params, + &port_out_id[i])) + rte_panic("Unable to configure output port for " + "ring %d\n", i); + } + + /* Table configuration */ + { + struct rte_table_lpm_ipv6_params table_lpm_ipv6_params = { + .name = "LPM", + .n_rules = 1 << 24, + .number_tbl8s = 1 << 21, + .entry_unique_size = + sizeof(struct rte_pipeline_table_entry), + .offset = APP_METADATA_OFFSET(32), + }; + + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_lpm_ipv6_ops, + .arg_create = &table_lpm_ipv6_params, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id)) + rte_panic("Unable to configure the IPv6 LPM table\n"); + } + + /* Interconnecting ports and tables */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], + table_id)) + rte_panic("Unable to connect input port %u to " + "table %u\n", port_in_id[i], table_id); + + /* Add entries to tables */ + for (i = 0; i < app.n_ports; i++) { + struct rte_pipeline_table_entry entry = { + .action = RTE_PIPELINE_ACTION_PORT, + {.port_id = port_out_id[i & (app.n_ports - 1)]}, + }; + + struct rte_table_lpm_ipv6_key key; + struct rte_pipeline_table_entry *entry_ptr; + uint32_t ip; + int key_found, status; + + key.depth = 8 + __builtin_popcount(app.n_ports - 1); + + ip = rte_bswap32(i << (24 - + __builtin_popcount(app.n_ports - 1))); + memcpy(key.ip, &ip, sizeof(uint32_t)); + + printf("Adding rule to IPv6 LPM table (IPv6 destination = " + "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:" + "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%u => " + "port out = %u)\n", + key.ip[0], key.ip[1], key.ip[2], key.ip[3], + key.ip[4], key.ip[5], key.ip[6], key.ip[7], + key.ip[8], key.ip[9], key.ip[10], key.ip[11], + key.ip[12], key.ip[13], key.ip[14], key.ip[15], + key.depth, i); + + status = rte_pipeline_table_entry_add(p, table_id, &key, &entry, + &key_found, &entry_ptr); + if (status < 0) + rte_panic("Unable to add entry to table %u (%d)\n", + table_id, status); + } + + /* Enable input ports */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_enable(p, port_in_id[i])) + rte_panic("Unable to enable input port %u\n", + port_in_id[i]); + + /* Check pipeline consistency */ + if (rte_pipeline_check(p) < 0) + rte_panic("Pipeline consistency check failed\n"); + + /* Run-time */ +#if APP_FLUSH == 0 + for ( ; ; ) + rte_pipeline_run(p); +#else + for (i = 0; ; i++) { + rte_pipeline_run(p); + + if ((i & APP_FLUSH) == 0) + rte_pipeline_flush(p); + } +#endif +} diff --git a/test/test-pipeline/pipeline_stub.c b/test/test-pipeline/pipeline_stub.c new file mode 100644 index 0000000000..ba710ca6ae --- /dev/null +++ b/test/test-pipeline/pipeline_stub.c @@ -0,0 +1,164 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include +#include + +#include +#include +#include +#include + +#include "main.h" + +void +app_main_loop_worker_pipeline_stub(void) { + struct rte_pipeline_params pipeline_params = { + .name = "pipeline", + .socket_id = rte_socket_id(), + }; + + struct rte_pipeline *p; + uint32_t port_in_id[APP_MAX_PORTS]; + uint32_t port_out_id[APP_MAX_PORTS]; + uint32_t table_id[APP_MAX_PORTS]; + uint32_t i; + + RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with stub " + "tables)\n", rte_lcore_id()); + + /* Pipeline configuration */ + p = rte_pipeline_create(&pipeline_params); + if (p == NULL) + rte_panic("Unable to configure the pipeline\n"); + + /* Input port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_reader_params port_ring_params = { + .ring = app.rings_rx[i], + }; + + struct rte_pipeline_port_in_params port_params = { + .ops = &rte_port_ring_reader_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + .burst_size = app.burst_size_worker_read, + }; + + if (rte_pipeline_port_in_create(p, &port_params, + &port_in_id[i])) + rte_panic("Unable to configure input port for " + "ring %d\n", i); + } + + /* Output port configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_port_ring_writer_params port_ring_params = { + .ring = app.rings_tx[i], + .tx_burst_sz = app.burst_size_worker_write, + }; + + struct rte_pipeline_port_out_params port_params = { + .ops = &rte_port_ring_writer_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + }; + + if (rte_pipeline_port_out_create(p, &port_params, + &port_out_id[i])) + rte_panic("Unable to configure output port for " + "ring %d\n", i); + } + + /* Table configuration */ + for (i = 0; i < app.n_ports; i++) { + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_stub_ops, + .arg_create = NULL, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id[i])) + rte_panic("Unable to configure table %u\n", i); + } + + /* Interconnecting ports and tables */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], + table_id[i])) + rte_panic("Unable to connect input port %u to " + "table %u\n", port_in_id[i], table_id[i]); + + /* Add entries to tables */ + for (i = 0; i < app.n_ports; i++) { + struct rte_pipeline_table_entry entry = { + .action = RTE_PIPELINE_ACTION_PORT, + {.port_id = port_out_id[i ^ 1]}, + }; + struct rte_pipeline_table_entry *default_entry_ptr; + + if (rte_pipeline_table_default_entry_add(p, table_id[i], &entry, + &default_entry_ptr)) + rte_panic("Unable to add default entry to table %u\n", + table_id[i]); + } + + /* Enable input ports */ + for (i = 0; i < app.n_ports; i++) + if (rte_pipeline_port_in_enable(p, port_in_id[i])) + rte_panic("Unable to enable input port %u\n", + port_in_id[i]); + + /* Check pipeline consistency */ + if (rte_pipeline_check(p) < 0) + rte_panic("Pipeline consistency check failed\n"); + + /* Run-time */ +#if APP_FLUSH == 0 + for ( ; ; ) + rte_pipeline_run(p); +#else + for (i = 0; ; i++) { + rte_pipeline_run(p); + + if ((i & APP_FLUSH) == 0) + rte_pipeline_flush(p); + } +#endif +} diff --git a/test/test-pipeline/runtime.c b/test/test-pipeline/runtime.c new file mode 100644 index 0000000000..42a6142c42 --- /dev/null +++ b/test/test-pipeline/runtime.c @@ -0,0 +1,184 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" + +void +app_main_loop_rx(void) { + uint32_t i; + int ret; + + RTE_LOG(INFO, USER1, "Core %u is doing RX\n", rte_lcore_id()); + + for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) { + uint16_t n_mbufs; + + n_mbufs = rte_eth_rx_burst( + app.ports[i], + 0, + app.mbuf_rx.array, + app.burst_size_rx_read); + + if (n_mbufs == 0) + continue; + + do { + ret = rte_ring_sp_enqueue_bulk( + app.rings_rx[i], + (void **) app.mbuf_rx.array, + n_mbufs); + } while (ret < 0); + } +} + +void +app_main_loop_worker(void) { + struct app_mbuf_array *worker_mbuf; + uint32_t i; + + RTE_LOG(INFO, USER1, "Core %u is doing work (no pipeline)\n", + rte_lcore_id()); + + worker_mbuf = rte_malloc_socket(NULL, sizeof(struct app_mbuf_array), + RTE_CACHE_LINE_SIZE, rte_socket_id()); + if (worker_mbuf == NULL) + rte_panic("Worker thread: cannot allocate buffer space\n"); + + for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) { + int ret; + + ret = rte_ring_sc_dequeue_bulk( + app.rings_rx[i], + (void **) worker_mbuf->array, + app.burst_size_worker_read); + + if (ret == -ENOENT) + continue; + + do { + ret = rte_ring_sp_enqueue_bulk( + app.rings_tx[i ^ 1], + (void **) worker_mbuf->array, + app.burst_size_worker_write); + } while (ret < 0); + } +} + +void +app_main_loop_tx(void) { + uint32_t i; + + RTE_LOG(INFO, USER1, "Core %u is doing TX\n", rte_lcore_id()); + + for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) { + uint16_t n_mbufs, n_pkts; + int ret; + + n_mbufs = app.mbuf_tx[i].n_mbufs; + + ret = rte_ring_sc_dequeue_bulk( + app.rings_tx[i], + (void **) &app.mbuf_tx[i].array[n_mbufs], + app.burst_size_tx_read); + + if (ret == -ENOENT) + continue; + + n_mbufs += app.burst_size_tx_read; + + if (n_mbufs < app.burst_size_tx_write) { + app.mbuf_tx[i].n_mbufs = n_mbufs; + continue; + } + + n_pkts = rte_eth_tx_burst( + app.ports[i], + 0, + app.mbuf_tx[i].array, + n_mbufs); + + if (n_pkts < n_mbufs) { + uint16_t k; + + for (k = n_pkts; k < n_mbufs; k++) { + struct rte_mbuf *pkt_to_free; + + pkt_to_free = app.mbuf_tx[i].array[k]; + rte_pktmbuf_free(pkt_to_free); + } + } + + app.mbuf_tx[i].n_mbufs = 0; + } +} diff --git a/test/test/Makefile b/test/test/Makefile new file mode 100644 index 0000000000..1a5e03dc68 --- /dev/null +++ b/test/test/Makefile @@ -0,0 +1,253 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2017 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_APP_TEST),y) + +# default rule +all: + +# 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_ and end_ +# for referencing by the C code. +# +# Parameters: , +define linked_resource +SRCS-y += $(1).res.o +$(1).res.o: $(2) + @ echo ' MKRES $$@' + $Q [ "$$( 3: + testlist = sys.argv[3].split(',') + testlist = [test.lower() for test in testlist] + if testlist[0].startswith('-'): + testlist[0] = testlist[0].lstrip('-') + test_blacklist = testlist + else: + test_whitelist = testlist + +cmdline = "%s -c f -n 4" % (sys.argv[1]) + +print(cmdline) + +runner = autotest_runner.AutotestRunner(cmdline, target, test_blacklist, + test_whitelist) + +for test_group in autotest_data.parallel_test_group_list: + runner.add_parallel_test_group(test_group) + +for test_group in autotest_data.non_parallel_test_group_list: + runner.add_non_parallel_test_group(test_group) + +num_fails = runner.run_all_tests() + +sys.exit(num_fails) diff --git a/test/test/autotest_data.py b/test/test/autotest_data.py new file mode 100644 index 0000000000..0cd598bda4 --- /dev/null +++ b/test/test/autotest_data.py @@ -0,0 +1,469 @@ +# 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. + +# Test data for autotests + +from glob import glob +from autotest_test_funcs import * + + +# quick and dirty function to find out number of sockets +def num_sockets(): + result = len(glob("/sys/devices/system/node/node*")) + if result == 0: + return 1 + return result + + +# Assign given number to each socket +# e.g. 32 becomes 32,32 or 32,32,32,32 +def per_sockets(num): + return ",".join([str(num)] * num_sockets()) + +# groups of tests that can be run in parallel +# the grouping has been found largely empirically +parallel_test_group_list = [ + { + "Prefix": "group_1", + "Memory": per_sockets(8), + "Tests": + [ + { + "Name": "Cycles autotest", + "Command": "cycles_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Timer autotest", + "Command": "timer_autotest", + "Func": timer_autotest, + "Report": None, + }, + { + "Name": "Debug autotest", + "Command": "debug_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Errno autotest", + "Command": "errno_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Meter autotest", + "Command": "meter_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Common autotest", + "Command": "common_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Resource autotest", + "Command": "resource_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "group_2", + "Memory": "16", + "Tests": + [ + { + "Name": "Memory autotest", + "Command": "memory_autotest", + "Func": memory_autotest, + "Report": None, + }, + { + "Name": "Read/write lock autotest", + "Command": "rwlock_autotest", + "Func": rwlock_autotest, + "Report": None, + }, + { + "Name": "Logs autotest", + "Command": "logs_autotest", + "Func": logs_autotest, + "Report": None, + }, + { + "Name": "CPU flags autotest", + "Command": "cpuflags_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Version autotest", + "Command": "version_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "EAL filesystem autotest", + "Command": "eal_fs_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "EAL flags autotest", + "Command": "eal_flags_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Hash autotest", + "Command": "hash_autotest", + "Func": default_autotest, + "Report": None, + }, + ], + }, + { + "Prefix": "group_3", + "Memory": per_sockets(512), + "Tests": + [ + { + "Name": "LPM autotest", + "Command": "lpm_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "LPM6 autotest", + "Command": "lpm6_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Memcpy autotest", + "Command": "memcpy_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Memzone autotest", + "Command": "memzone_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "String autotest", + "Command": "string_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Alarm autotest", + "Command": "alarm_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "group_4", + "Memory": per_sockets(128), + "Tests": + [ + { + "Name": "PCI autotest", + "Command": "pci_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Malloc autotest", + "Command": "malloc_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Multi-process autotest", + "Command": "multiprocess_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Mbuf autotest", + "Command": "mbuf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Per-lcore autotest", + "Command": "per_lcore_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Ring autotest", + "Command": "ring_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "group_5", + "Memory": "32", + "Tests": + [ + { + "Name": "Spinlock autotest", + "Command": "spinlock_autotest", + "Func": spinlock_autotest, + "Report": None, + }, + { + "Name": "Byte order autotest", + "Command": "byteorder_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "TAILQ autotest", + "Command": "tailq_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Command-line autotest", + "Command": "cmdline_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Interrupts autotest", + "Command": "interrupt_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "group_6", + "Memory": per_sockets(512), + "Tests": + [ + { + "Name": "Function reentrancy autotest", + "Command": "func_reentrancy_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Mempool autotest", + "Command": "mempool_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Atomics autotest", + "Command": "atomic_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Prefetch autotest", + "Command": "prefetch_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Red autotest", + "Command": "red_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "group_7", + "Memory": "64", + "Tests": + [ + { + "Name": "PMD ring autotest", + "Command": "ring_pmd_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Access list control autotest", + "Command": "acl_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Sched autotest", + "Command": "sched_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, +] + +# tests that should not be run when any other tests are running +non_parallel_test_group_list = [ + + { + "Prefix": "kni", + "Memory": "512", + "Tests": + [ + { + "Name": "KNI autotest", + "Command": "kni_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "mempool_perf", + "Memory": per_sockets(256), + "Tests": + [ + { + "Name": "Mempool performance autotest", + "Command": "mempool_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "memcpy_perf", + "Memory": per_sockets(512), + "Tests": + [ + { + "Name": "Memcpy performance autotest", + "Command": "memcpy_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "hash_perf", + "Memory": per_sockets(512), + "Tests": + [ + { + "Name": "Hash performance autotest", + "Command": "hash_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "power", + "Memory": "16", + "Tests": + [ + { + "Name": "Power autotest", + "Command": "power_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "power_acpi_cpufreq", + "Memory": "16", + "Tests": + [ + { + "Name": "Power ACPI cpufreq autotest", + "Command": "power_acpi_cpufreq_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "power_kvm_vm", + "Memory": "16", + "Tests": + [ + { + "Name": "Power KVM VM autotest", + "Command": "power_kvm_vm_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { + "Prefix": "timer_perf", + "Memory": per_sockets(512), + "Tests": + [ + { + "Name": "Timer performance autotest", + "Command": "timer_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + + # + # Please always make sure that ring_perf is the last test! + # + { + "Prefix": "ring_perf", + "Memory": per_sockets(512), + "Tests": + [ + { + "Name": "Ring performance autotest", + "Command": "ring_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, +] diff --git a/test/test/autotest_runner.py b/test/test/autotest_runner.py new file mode 100644 index 0000000000..fc882ec05c --- /dev/null +++ b/test/test/autotest_runner.py @@ -0,0 +1,428 @@ +# 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. + +# The main logic behind running autotests in parallel + +import StringIO +import csv +import multiprocessing +import pexpect +import re +import subprocess +import sys +import time + +# wait for prompt + + +def wait_prompt(child): + try: + child.sendline() + result = child.expect(["RTE>>", pexpect.TIMEOUT, pexpect.EOF], + timeout=120) + except: + return False + if result == 0: + return True + else: + return False + +# run a test group +# each result tuple in results list consists of: +# result value (0 or -1) +# result string +# test name +# total test run time (double) +# raw test log +# test report (if not available, should be None) +# +# this function needs to be outside AutotestRunner class +# because otherwise Pool won't work (or rather it will require +# quite a bit of effort to make it work). + + +def run_test_group(cmdline, test_group): + results = [] + child = None + start_time = time.time() + startuplog = None + + # run test app + try: + # prepare logging of init + startuplog = StringIO.StringIO() + + print >>startuplog, "\n%s %s\n" % ("=" * 20, test_group["Prefix"]) + print >>startuplog, "\ncmdline=%s" % cmdline + + child = pexpect.spawn(cmdline, logfile=startuplog) + + # wait for target to boot + if not wait_prompt(child): + child.close() + + results.append((-1, + "Fail [No prompt]", + "Start %s" % test_group["Prefix"], + time.time() - start_time, + startuplog.getvalue(), + None)) + + # mark all tests as failed + for test in test_group["Tests"]: + results.append((-1, "Fail [No prompt]", test["Name"], + time.time() - start_time, "", None)) + # exit test + return results + + except: + results.append((-1, + "Fail [Can't run]", + "Start %s" % test_group["Prefix"], + time.time() - start_time, + startuplog.getvalue(), + None)) + + # mark all tests as failed + for t in test_group["Tests"]: + results.append((-1, "Fail [Can't run]", t["Name"], + time.time() - start_time, "", None)) + # exit test + return results + + # startup was successful + results.append((0, "Success", "Start %s" % test_group["Prefix"], + time.time() - start_time, startuplog.getvalue(), None)) + + # parse the binary for available test commands + binary = cmdline.split()[0] + stripped = 'not stripped' not in subprocess.check_output(['file', binary]) + if not stripped: + symbols = subprocess.check_output(['nm', binary]).decode('utf-8') + avail_cmds = re.findall('test_register_(\w+)', symbols) + + # run all tests in test group + for test in test_group["Tests"]: + + # create log buffer for each test + # in multiprocessing environment, the logging would be + # interleaved and will create a mess, hence the buffering + logfile = StringIO.StringIO() + child.logfile = logfile + + result = () + + # make a note when the test started + start_time = time.time() + + try: + # print test name to log buffer + print >>logfile, "\n%s %s\n" % ("-" * 20, test["Name"]) + + # run test function associated with the test + if stripped or test["Command"] in avail_cmds: + result = test["Func"](child, test["Command"]) + else: + result = (0, "Skipped [Not Available]") + + # make a note when the test was finished + end_time = time.time() + + # append test data to the result tuple + result += (test["Name"], end_time - start_time, + logfile.getvalue()) + + # call report function, if any defined, and supply it with + # target and complete log for test run + if test["Report"]: + report = test["Report"](self.target, log) + + # append report to results tuple + result += (report,) + else: + # report is None + result += (None,) + except: + # make a note when the test crashed + end_time = time.time() + + # mark test as failed + result = (-1, "Fail [Crash]", test["Name"], + end_time - start_time, logfile.getvalue(), None) + finally: + # append the results to the results list + results.append(result) + + # regardless of whether test has crashed, try quitting it + try: + child.sendline("quit") + child.close() + # if the test crashed, just do nothing instead + except: + # nop + pass + + # return test results + return results + + +# class representing an instance of autotests run +class AutotestRunner: + cmdline = "" + parallel_test_groups = [] + non_parallel_test_groups = [] + logfile = None + csvwriter = None + target = "" + start = None + n_tests = 0 + fails = 0 + log_buffers = [] + blacklist = [] + whitelist = [] + + def __init__(self, cmdline, target, blacklist, whitelist): + self.cmdline = cmdline + self.target = target + self.blacklist = blacklist + self.whitelist = whitelist + + # log file filename + logfile = "%s.log" % target + csvfile = "%s.csv" % target + + self.logfile = open(logfile, "w") + csvfile = open(csvfile, "w") + self.csvwriter = csv.writer(csvfile) + + # prepare results table + self.csvwriter.writerow(["test_name", "test_result", "result_str"]) + + # set up cmdline string + def __get_cmdline(self, test): + cmdline = self.cmdline + + # append memory limitations for each test + # otherwise tests won't run in parallel + if "i686" not in self.target: + cmdline += " --socket-mem=%s" % test["Memory"] + else: + # affinitize startup so that tests don't fail on i686 + cmdline = "taskset 1 " + cmdline + cmdline += " -m " + str(sum(map(int, test["Memory"].split(",")))) + + # set group prefix for autotest group + # otherwise they won't run in parallel + cmdline += " --file-prefix=%s" % test["Prefix"] + + return cmdline + + def add_parallel_test_group(self, test_group): + self.parallel_test_groups.append(test_group) + + def add_non_parallel_test_group(self, test_group): + self.non_parallel_test_groups.append(test_group) + + def __process_results(self, results): + # this iterates over individual test results + for i, result in enumerate(results): + + # increase total number of tests that were run + # do not include "start" test + if i > 0: + self.n_tests += 1 + + # unpack result tuple + test_result, result_str, test_name, \ + test_time, log, report = result + + # get total run time + cur_time = time.time() + total_time = int(cur_time - self.start) + + # print results, test run time and total time since start + result = ("%s:" % test_name).ljust(30) + result += result_str.ljust(29) + result += "[%02dm %02ds]" % (test_time / 60, test_time % 60) + + # don't print out total time every line, it's the same anyway + if i == len(results) - 1: + print(result, + "[%02dm %02ds]" % (total_time / 60, total_time % 60)) + else: + print(result) + + # if test failed and it wasn't a "start" test + if test_result < 0 and not i == 0: + self.fails += 1 + + # collect logs + self.log_buffers.append(log) + + # create report if it exists + if report: + try: + f = open("%s_%s_report.rst" % + (self.target, test_name), "w") + except IOError: + print("Report for %s could not be created!" % test_name) + else: + with f: + f.write(report) + + # write test result to CSV file + if i != 0: + self.csvwriter.writerow([test_name, test_result, result_str]) + + # this function iterates over test groups and removes each + # test that is not in whitelist/blacklist + def __filter_groups(self, test_groups): + groups_to_remove = [] + + # filter out tests from parallel test groups + for i, test_group in enumerate(test_groups): + + # iterate over a copy so that we could safely delete individual + # tests + for test in test_group["Tests"][:]: + test_id = test["Command"] + + # dump tests are specified in full e.g. "Dump_mempool" + if "_autotest" in test_id: + test_id = test_id[:-len("_autotest")] + + # filter out blacklisted/whitelisted tests + if self.blacklist and test_id in self.blacklist: + test_group["Tests"].remove(test) + continue + if self.whitelist and test_id not in self.whitelist: + test_group["Tests"].remove(test) + continue + + # modify or remove original group + if len(test_group["Tests"]) > 0: + test_groups[i] = test_group + else: + # remember which groups should be deleted + # put the numbers backwards so that we start + # deleting from the end, not from the beginning + groups_to_remove.insert(0, i) + + # remove test groups that need to be removed + for i in groups_to_remove: + del test_groups[i] + + return test_groups + + # iterate over test groups and run tests associated with them + def run_all_tests(self): + # filter groups + self.parallel_test_groups = \ + self.__filter_groups(self.parallel_test_groups) + self.non_parallel_test_groups = \ + self.__filter_groups(self.non_parallel_test_groups) + + # create a pool of worker threads + pool = multiprocessing.Pool(processes=1) + + results = [] + + # whatever happens, try to save as much logs as possible + try: + + # create table header + print("") + print("Test name".ljust(30), "Test result".ljust(29), + "Test".center(9), "Total".center(9)) + print("=" * 80) + + # make a note of tests start time + self.start = time.time() + + # assign worker threads to run test groups + for test_group in self.parallel_test_groups: + result = pool.apply_async(run_test_group, + [self.__get_cmdline(test_group), + test_group]) + results.append(result) + + # iterate while we have group execution results to get + while len(results) > 0: + + # iterate over a copy to be able to safely delete results + # this iterates over a list of group results + for group_result in results[:]: + + # if the thread hasn't finished yet, continue + if not group_result.ready(): + continue + + res = group_result.get() + + self.__process_results(res) + + # remove result from results list once we're done with it + results.remove(group_result) + + # run non_parallel tests. they are run one by one, synchronously + for test_group in self.non_parallel_test_groups: + group_result = run_test_group( + self.__get_cmdline(test_group), test_group) + + self.__process_results(group_result) + + # get total run time + cur_time = time.time() + total_time = int(cur_time - self.start) + + # print out summary + print("=" * 80) + print("Total run time: %02dm %02ds" % (total_time / 60, + total_time % 60)) + if self.fails != 0: + print("Number of failed tests: %s" % str(self.fails)) + + # write summary to logfile + self.logfile.write("Summary\n") + self.logfile.write("Target: ".ljust(15) + "%s\n" % self.target) + self.logfile.write("Tests: ".ljust(15) + "%i\n" % self.n_tests) + self.logfile.write("Failed tests: ".ljust( + 15) + "%i\n" % self.fails) + except: + print("Exception occurred") + print(sys.exc_info()) + self.fails = 1 + + # drop logs from all executions to a logfile + for buf in self.log_buffers: + self.logfile.write(buf.replace("\r", "")) + + return self.fails diff --git a/test/test/autotest_test_funcs.py b/test/test/autotest_test_funcs.py new file mode 100644 index 0000000000..1c5f3909ea --- /dev/null +++ b/test/test/autotest_test_funcs.py @@ -0,0 +1,302 @@ +# 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. + +# Test functions + +import pexpect + +# default autotest, used to run most tests +# waits for "Test OK" + + +def default_autotest(child, test_name): + child.sendline(test_name) + result = child.expect(["Test OK", "Test Failed", + "Command not found", pexpect.TIMEOUT], timeout=900) + if result == 1: + return -1, "Fail" + elif result == 2: + return -1, "Fail [Not found]" + elif result == 3: + return -1, "Fail [Timeout]" + return 0, "Success" + +# autotest used to run dump commands +# just fires the command + + +def dump_autotest(child, test_name): + child.sendline(test_name) + return 0, "Success" + +# memory autotest +# reads output and waits for Test OK + + +def memory_autotest(child, test_name): + child.sendline(test_name) + regexp = "phys:0x[0-9a-f]*, len:([0-9]*), virt:0x[0-9a-f]*, " \ + "socket_id:[0-9]*" + index = child.expect([regexp, pexpect.TIMEOUT], timeout=180) + if index != 0: + return -1, "Fail [Timeout]" + size = int(child.match.groups()[0], 16) + if size <= 0: + return -1, "Fail [Bad size]" + index = child.expect(["Test OK", "Test Failed", + pexpect.TIMEOUT], timeout=10) + if index == 1: + return -1, "Fail" + elif index == 2: + return -1, "Fail [Timeout]" + return 0, "Success" + + +def spinlock_autotest(child, test_name): + i = 0 + ir = 0 + child.sendline(test_name) + while True: + index = child.expect(["Test OK", + "Test Failed", + "Hello from core ([0-9]*) !", + "Hello from within recursive locks " + "from ([0-9]*) !", + pexpect.TIMEOUT], timeout=5) + # ok + if index == 0: + break + + # message, check ordering + elif index == 2: + if int(child.match.groups()[0]) < i: + return -1, "Fail [Bad order]" + i = int(child.match.groups()[0]) + elif index == 3: + if int(child.match.groups()[0]) < ir: + return -1, "Fail [Bad order]" + ir = int(child.match.groups()[0]) + + # fail + elif index == 4: + return -1, "Fail [Timeout]" + elif index == 1: + return -1, "Fail" + + return 0, "Success" + + +def rwlock_autotest(child, test_name): + i = 0 + child.sendline(test_name) + while True: + index = child.expect(["Test OK", + "Test Failed", + "Hello from core ([0-9]*) !", + "Global write lock taken on master " + "core ([0-9]*)", + pexpect.TIMEOUT], timeout=10) + # ok + if index == 0: + if i != 0xffff: + return -1, "Fail [Message is missing]" + break + + # message, check ordering + elif index == 2: + if int(child.match.groups()[0]) < i: + return -1, "Fail [Bad order]" + i = int(child.match.groups()[0]) + + # must be the last message, check ordering + elif index == 3: + i = 0xffff + + elif index == 4: + return -1, "Fail [Timeout]" + + # fail + else: + return -1, "Fail" + + return 0, "Success" + + +def logs_autotest(child, test_name): + child.sendline(test_name) + + log_list = [ + "TESTAPP1: error message", + "TESTAPP1: critical message", + "TESTAPP2: critical message", + "TESTAPP1: error message", + ] + + for log_msg in log_list: + index = child.expect([log_msg, + "Test OK", + "Test Failed", + pexpect.TIMEOUT], timeout=10) + + if index == 3: + return -1, "Fail [Timeout]" + # not ok + elif index != 0: + return -1, "Fail" + + index = child.expect(["Test OK", + "Test Failed", + pexpect.TIMEOUT], timeout=10) + + return 0, "Success" + + +def timer_autotest(child, test_name): + child.sendline(test_name) + + index = child.expect(["Start timer stress tests", + "Test Failed", + pexpect.TIMEOUT], timeout=5) + + if index == 1: + return -1, "Fail" + elif index == 2: + return -1, "Fail [Timeout]" + + index = child.expect(["Start timer stress tests 2", + "Test Failed", + pexpect.TIMEOUT], timeout=5) + + if index == 1: + return -1, "Fail" + elif index == 2: + return -1, "Fail [Timeout]" + + index = child.expect(["Start timer basic tests", + "Test Failed", + pexpect.TIMEOUT], timeout=5) + + if index == 1: + return -1, "Fail" + elif index == 2: + return -1, "Fail [Timeout]" + + lcore_tim0 = -1 + lcore_tim1 = -1 + lcore_tim2 = -1 + lcore_tim3 = -1 + + while True: + index = child.expect(["TESTTIMER: ([0-9]*): callback id=([0-9]*) " + "count=([0-9]*) on core ([0-9]*)", + "Test OK", + "Test Failed", + pexpect.TIMEOUT], timeout=10) + + if index == 1: + break + + if index == 2: + return -1, "Fail" + elif index == 3: + return -1, "Fail [Timeout]" + + try: + id = int(child.match.groups()[1]) + cnt = int(child.match.groups()[2]) + lcore = int(child.match.groups()[3]) + except: + return -1, "Fail [Cannot parse]" + + # timer0 always expires on the same core when cnt < 20 + if id == 0: + if lcore_tim0 == -1: + lcore_tim0 = lcore + elif lcore != lcore_tim0 and cnt < 20: + return -1, "Fail [lcore != lcore_tim0 (%d, %d)]" \ + % (lcore, lcore_tim0) + if cnt > 21: + return -1, "Fail [tim0 cnt > 21]" + + # timer1 each time expires on a different core + if id == 1: + if lcore == lcore_tim1: + return -1, "Fail [lcore == lcore_tim1 (%d, %d)]" \ + % (lcore, lcore_tim1) + lcore_tim1 = lcore + if cnt > 10: + return -1, "Fail [tim1 cnt > 30]" + + # timer0 always expires on the same core + if id == 2: + if lcore_tim2 == -1: + lcore_tim2 = lcore + elif lcore != lcore_tim2: + return -1, "Fail [lcore != lcore_tim2 (%d, %d)]" \ + % (lcore, lcore_tim2) + if cnt > 30: + return -1, "Fail [tim2 cnt > 30]" + + # timer0 always expires on the same core + if id == 3: + if lcore_tim3 == -1: + lcore_tim3 = lcore + elif lcore != lcore_tim3: + return -1, "Fail [lcore_tim3 changed (%d -> %d)]" \ + % (lcore, lcore_tim3) + if cnt > 30: + return -1, "Fail [tim3 cnt > 30]" + + # must be 2 different cores + if lcore_tim0 == lcore_tim3: + return -1, "Fail [lcore_tim0 (%d) == lcore_tim3 (%d)]" \ + % (lcore_tim0, lcore_tim3) + + return 0, "Success" + + +def ring_autotest(child, test_name): + child.sendline(test_name) + index = child.expect(["Test OK", "Test Failed", + pexpect.TIMEOUT], timeout=2) + if index == 1: + return -1, "Fail" + elif index == 2: + return -1, "Fail [Timeout]" + + child.sendline("set_watermark test 100") + child.sendline("dump_ring test") + index = child.expect([" watermark=100", + pexpect.TIMEOUT], timeout=1) + if index != 0: + return -1, "Fail [Bad watermark]" + + return 0, "Success" diff --git a/test/test/commands.c b/test/test/commands.c new file mode 100644 index 0000000000..2df46b054e --- /dev/null +++ b/test/test/commands.c @@ -0,0 +1,453 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2014 6WIND S.A. + * 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 +#include +#include +#include +#include +#include +#include +#ifndef __linux__ +#ifndef __FreeBSD__ +#include +#endif +#endif +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/****************/ + +static struct test_commands_list commands_list = + TAILQ_HEAD_INITIALIZER(commands_list); + +void +add_test_command(struct test_command *t) +{ + TAILQ_INSERT_TAIL(&commands_list, t, next); +} + +struct cmd_autotest_result { + cmdline_fixed_string_t autotest; +}; + +static void cmd_autotest_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct test_command *t; + struct cmd_autotest_result *res = parsed_result; + int ret = 0; + + TAILQ_FOREACH(t, &commands_list, next) { + if (!strcmp(res->autotest, t->command)) + ret = t->callback(); + } + + if (ret == 0) + printf("Test OK\n"); + else + printf("Test Failed\n"); + fflush(stdout); +} + +cmdline_parse_token_string_t cmd_autotest_autotest = + TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest, + ""); + +cmdline_parse_inst_t cmd_autotest = { + .f = cmd_autotest_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "launch autotest", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_autotest_autotest, + NULL, + }, +}; + +/****************/ + +struct cmd_dump_result { + cmdline_fixed_string_t dump; +}; + +static void +dump_struct_sizes(void) +{ +#define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t)); + DUMP_SIZE(struct rte_mbuf); + DUMP_SIZE(struct rte_mempool); + DUMP_SIZE(struct rte_ring); +#undef DUMP_SIZE +} + +static void cmd_dump_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_dump_result *res = parsed_result; + + if (!strcmp(res->dump, "dump_physmem")) + rte_dump_physmem_layout(stdout); + else if (!strcmp(res->dump, "dump_memzone")) + rte_memzone_dump(stdout); + else if (!strcmp(res->dump, "dump_struct_sizes")) + dump_struct_sizes(); + else if (!strcmp(res->dump, "dump_ring")) + rte_ring_list_dump(stdout); + else if (!strcmp(res->dump, "dump_mempool")) + rte_mempool_list_dump(stdout); + else if (!strcmp(res->dump, "dump_devargs")) + rte_eal_devargs_dump(stdout); +} + +cmdline_parse_token_string_t cmd_dump_dump = + TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, + "dump_physmem#dump_memzone#" + "dump_struct_sizes#dump_ring#dump_mempool#" + "dump_devargs"); + +cmdline_parse_inst_t cmd_dump = { + .f = cmd_dump_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "dump status", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_dump_dump, + NULL, + }, +}; + +/****************/ + +struct cmd_dump_one_result { + cmdline_fixed_string_t dump; + cmdline_fixed_string_t name; +}; + +static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_dump_one_result *res = parsed_result; + + if (!strcmp(res->dump, "dump_ring")) { + struct rte_ring *r; + r = rte_ring_lookup(res->name); + if (r == NULL) { + cmdline_printf(cl, "Cannot find ring\n"); + return; + } + rte_ring_dump(stdout, r); + } + else if (!strcmp(res->dump, "dump_mempool")) { + struct rte_mempool *mp; + mp = rte_mempool_lookup(res->name); + if (mp == NULL) { + cmdline_printf(cl, "Cannot find mempool\n"); + return; + } + rte_mempool_dump(stdout, mp); + } +} + +cmdline_parse_token_string_t cmd_dump_one_dump = + TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump, + "dump_ring#dump_mempool"); + +cmdline_parse_token_string_t cmd_dump_one_name = + TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL); + +cmdline_parse_inst_t cmd_dump_one = { + .f = cmd_dump_one_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "dump one ring/mempool: dump_ring|dump_mempool ", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_dump_one_dump, + (void *)&cmd_dump_one_name, + NULL, + }, +}; + +/****************/ + +struct cmd_set_ring_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t name; + uint32_t value; +}; + +static void cmd_set_ring_parsed(void *parsed_result, struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_ring_result *res = parsed_result; + struct rte_ring *r; + int ret; + + r = rte_ring_lookup(res->name); + if (r == NULL) { + cmdline_printf(cl, "Cannot find ring\n"); + return; + } + + if (!strcmp(res->set, "set_watermark")) { + ret = rte_ring_set_water_mark(r, res->value); + if (ret != 0) + cmdline_printf(cl, "Cannot set water mark\n"); + } +} + +cmdline_parse_token_string_t cmd_set_ring_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, set, + "set_watermark"); + +cmdline_parse_token_string_t cmd_set_ring_name = + TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, name, NULL); + +cmdline_parse_token_num_t cmd_set_ring_value = + TOKEN_NUM_INITIALIZER(struct cmd_set_ring_result, value, UINT32); + +cmdline_parse_inst_t cmd_set_ring = { + .f = cmd_set_ring_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "set watermark: " + "set_watermark ", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_set_ring_set, + (void *)&cmd_set_ring_name, + (void *)&cmd_set_ring_value, + NULL, + }, +}; + +/****************/ + +struct cmd_quit_result { + cmdline_fixed_string_t quit; +}; + +static void +cmd_quit_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + cmdline_quit(cl); +} + +cmdline_parse_token_string_t cmd_quit_quit = + TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, + "quit"); + +cmdline_parse_inst_t cmd_quit = { + .f = cmd_quit_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "exit application", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_quit_quit, + NULL, + }, +}; + +/****************/ + +struct cmd_set_rxtx_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t mode; +}; + +static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_rxtx_result *res = parsed_result; + if (test_set_rxtx_conf(res->mode) < 0) + cmdline_printf(cl, "Cannot find such mode\n"); +} + +cmdline_parse_token_string_t cmd_set_rxtx_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set, + "set_rxtx_mode"); + +cmdline_parse_token_string_t cmd_set_rxtx_mode = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL); + +cmdline_parse_inst_t cmd_set_rxtx = { + .f = cmd_set_rxtx_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "set rxtx routine: " + "set_rxtx ", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_set_rxtx_set, + (void *)&cmd_set_rxtx_mode, + NULL, + }, +}; + +/****************/ + +struct cmd_set_rxtx_anchor { + cmdline_fixed_string_t set; + cmdline_fixed_string_t type; +}; + +static void +cmd_set_rxtx_anchor_parsed(void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_rxtx_anchor *res = parsed_result; + if (test_set_rxtx_anchor(res->type) < 0) + cmdline_printf(cl, "Cannot find such anchor\n"); +} + +cmdline_parse_token_string_t cmd_set_rxtx_anchor_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, set, + "set_rxtx_anchor"); + +cmdline_parse_token_string_t cmd_set_rxtx_anchor_type = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, type, NULL); + +cmdline_parse_inst_t cmd_set_rxtx_anchor = { + .f = cmd_set_rxtx_anchor_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "set rxtx anchor: " + "set_rxtx_anchor ", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_set_rxtx_anchor_set, + (void *)&cmd_set_rxtx_anchor_type, + NULL, + }, +}; + +/****************/ + +/* for stream control */ +struct cmd_set_rxtx_sc { + cmdline_fixed_string_t set; + cmdline_fixed_string_t type; +}; + +static void +cmd_set_rxtx_sc_parsed(void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_rxtx_sc *res = parsed_result; + if (test_set_rxtx_sc(res->type) < 0) + cmdline_printf(cl, "Cannot find such stream control\n"); +} + +cmdline_parse_token_string_t cmd_set_rxtx_sc_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set, + "set_rxtx_sc"); + +cmdline_parse_token_string_t cmd_set_rxtx_sc_type = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL); + +cmdline_parse_inst_t cmd_set_rxtx_sc = { + .f = cmd_set_rxtx_sc_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "set rxtx stream control: " + "set_rxtx_sc ", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_set_rxtx_sc_set, + (void *)&cmd_set_rxtx_sc_type, + NULL, + }, +}; + +/****************/ + + +cmdline_parse_ctx_t main_ctx[] = { + (cmdline_parse_inst_t *)&cmd_autotest, + (cmdline_parse_inst_t *)&cmd_dump, + (cmdline_parse_inst_t *)&cmd_dump_one, + (cmdline_parse_inst_t *)&cmd_set_ring, + (cmdline_parse_inst_t *)&cmd_quit, + (cmdline_parse_inst_t *)&cmd_set_rxtx, + (cmdline_parse_inst_t *)&cmd_set_rxtx_anchor, + (cmdline_parse_inst_t *)&cmd_set_rxtx_sc, + NULL, +}; + +int commands_init(void) +{ + struct test_command *t; + char *commands, *ptr; + int commands_len = 0; + + TAILQ_FOREACH(t, &commands_list, next) { + commands_len += strlen(t->command) + 1; + } + + commands = malloc(commands_len + 1); + if (!commands) + return -1; + + ptr = commands; + TAILQ_FOREACH(t, &commands_list, next) { + ptr += sprintf(ptr, "%s#", t->command); + } + ptr--; + ptr[0] = '\0'; + + cmd_autotest_autotest.string_data.str = commands; + return 0; +} diff --git a/test/test/packet_burst_generator.c b/test/test/packet_burst_generator.c new file mode 100644 index 0000000000..a93c3b5999 --- /dev/null +++ b/test/test/packet_burst_generator.c @@ -0,0 +1,285 @@ +/*- + * 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 +#include + +#include "packet_burst_generator.h" + +#define UDP_SRC_PORT 1024 +#define UDP_DST_PORT 1024 + + +#define IP_DEFTTL 64 /* from RFC 1340. */ +#define IP_VERSION 0x40 +#define IP_HDRLEN 0x05 /* default IP header length == five 32-bits words. */ +#define IP_VHL_DEF (IP_VERSION | IP_HDRLEN) + +static void +copy_buf_to_pkt_segs(void *buf, unsigned len, struct rte_mbuf *pkt, + unsigned offset) +{ + struct rte_mbuf *seg; + void *seg_buf; + unsigned copy_len; + + seg = pkt; + while (offset >= seg->data_len) { + offset -= seg->data_len; + seg = seg->next; + } + copy_len = seg->data_len - offset; + seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset); + while (len > copy_len) { + rte_memcpy(seg_buf, buf, (size_t) copy_len); + len -= copy_len; + buf = ((char *) buf + copy_len); + seg = seg->next; + seg_buf = rte_pktmbuf_mtod(seg, void *); + } + rte_memcpy(seg_buf, buf, (size_t) len); +} + +static inline void +copy_buf_to_pkt(void *buf, unsigned len, struct rte_mbuf *pkt, unsigned offset) +{ + if (offset + len <= pkt->data_len) { + rte_memcpy(rte_pktmbuf_mtod_offset(pkt, char *, offset), buf, + (size_t) len); + return; + } + copy_buf_to_pkt_segs(buf, len, pkt, offset); +} + +void +initialize_eth_header(struct ether_hdr *eth_hdr, struct ether_addr *src_mac, + struct ether_addr *dst_mac, uint16_t ether_type, + uint8_t vlan_enabled, uint16_t van_id) +{ + ether_addr_copy(dst_mac, ð_hdr->d_addr); + ether_addr_copy(src_mac, ð_hdr->s_addr); + + if (vlan_enabled) { + struct vlan_hdr *vhdr = (struct vlan_hdr *)((uint8_t *)eth_hdr + + sizeof(struct ether_hdr)); + + eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_VLAN); + + vhdr->eth_proto = rte_cpu_to_be_16(ether_type); + vhdr->vlan_tci = van_id; + } else { + eth_hdr->ether_type = rte_cpu_to_be_16(ether_type); + } +} + +void +initialize_arp_header(struct arp_hdr *arp_hdr, struct ether_addr *src_mac, + struct ether_addr *dst_mac, uint32_t src_ip, uint32_t dst_ip, + uint32_t opcode) +{ + arp_hdr->arp_hrd = rte_cpu_to_be_16(ARP_HRD_ETHER); + arp_hdr->arp_pro = rte_cpu_to_be_16(ETHER_TYPE_IPv4); + arp_hdr->arp_hln = ETHER_ADDR_LEN; + arp_hdr->arp_pln = sizeof(uint32_t); + arp_hdr->arp_op = rte_cpu_to_be_16(opcode); + ether_addr_copy(src_mac, &arp_hdr->arp_data.arp_sha); + arp_hdr->arp_data.arp_sip = src_ip; + ether_addr_copy(dst_mac, &arp_hdr->arp_data.arp_tha); + arp_hdr->arp_data.arp_tip = dst_ip; +} + +uint16_t +initialize_udp_header(struct udp_hdr *udp_hdr, uint16_t src_port, + uint16_t dst_port, uint16_t pkt_data_len) +{ + uint16_t pkt_len; + + pkt_len = (uint16_t) (pkt_data_len + sizeof(struct udp_hdr)); + + udp_hdr->src_port = rte_cpu_to_be_16(src_port); + udp_hdr->dst_port = rte_cpu_to_be_16(dst_port); + udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len); + udp_hdr->dgram_cksum = 0; /* No UDP checksum. */ + + return pkt_len; +} + + +uint16_t +initialize_ipv6_header(struct ipv6_hdr *ip_hdr, uint8_t *src_addr, + uint8_t *dst_addr, uint16_t pkt_data_len) +{ + ip_hdr->vtc_flow = 0; + ip_hdr->payload_len = pkt_data_len; + ip_hdr->proto = IPPROTO_UDP; + ip_hdr->hop_limits = IP_DEFTTL; + + rte_memcpy(ip_hdr->src_addr, src_addr, sizeof(ip_hdr->src_addr)); + rte_memcpy(ip_hdr->dst_addr, dst_addr, sizeof(ip_hdr->dst_addr)); + + return (uint16_t) (pkt_data_len + sizeof(struct ipv6_hdr)); +} + +uint16_t +initialize_ipv4_header(struct ipv4_hdr *ip_hdr, uint32_t src_addr, + uint32_t dst_addr, uint16_t pkt_data_len) +{ + uint16_t pkt_len; + unaligned_uint16_t *ptr16; + uint32_t ip_cksum; + + /* + * Initialize IP header. + */ + pkt_len = (uint16_t) (pkt_data_len + sizeof(struct ipv4_hdr)); + + ip_hdr->version_ihl = IP_VHL_DEF; + ip_hdr->type_of_service = 0; + ip_hdr->fragment_offset = 0; + ip_hdr->time_to_live = IP_DEFTTL; + ip_hdr->next_proto_id = IPPROTO_UDP; + ip_hdr->packet_id = 0; + ip_hdr->total_length = rte_cpu_to_be_16(pkt_len); + ip_hdr->src_addr = rte_cpu_to_be_32(src_addr); + ip_hdr->dst_addr = rte_cpu_to_be_32(dst_addr); + + /* + * Compute IP header checksum. + */ + ptr16 = (unaligned_uint16_t *)ip_hdr; + ip_cksum = 0; + ip_cksum += ptr16[0]; ip_cksum += ptr16[1]; + ip_cksum += ptr16[2]; ip_cksum += ptr16[3]; + ip_cksum += ptr16[4]; + ip_cksum += ptr16[6]; ip_cksum += ptr16[7]; + ip_cksum += ptr16[8]; ip_cksum += ptr16[9]; + + /* + * Reduce 32 bit checksum to 16 bits and complement it. + */ + ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) + + (ip_cksum & 0x0000FFFF); + ip_cksum %= 65536; + ip_cksum = (~ip_cksum) & 0x0000FFFF; + if (ip_cksum == 0) + ip_cksum = 0xFFFF; + ip_hdr->hdr_checksum = (uint16_t) ip_cksum; + + return pkt_len; +} + + + +/* + * The maximum number of segments per packet is used when creating + * scattered transmit packets composed of a list of mbufs. + */ +#define RTE_MAX_SEGS_PER_PKT 255 /**< pkt.nb_segs is a 8-bit unsigned char. */ + + +int +generate_packet_burst(struct rte_mempool *mp, struct rte_mbuf **pkts_burst, + struct ether_hdr *eth_hdr, uint8_t vlan_enabled, void *ip_hdr, + uint8_t ipv4, struct udp_hdr *udp_hdr, int nb_pkt_per_burst, + uint8_t pkt_len, uint8_t nb_pkt_segs) +{ + int i, nb_pkt = 0; + size_t eth_hdr_size; + + struct rte_mbuf *pkt_seg; + struct rte_mbuf *pkt; + + for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) { + pkt = rte_pktmbuf_alloc(mp); + if (pkt == NULL) { +nomore_mbuf: + if (nb_pkt == 0) + return -1; + break; + } + + pkt->data_len = pkt_len; + pkt_seg = pkt; + for (i = 1; i < nb_pkt_segs; i++) { + pkt_seg->next = rte_pktmbuf_alloc(mp); + if (pkt_seg->next == NULL) { + pkt->nb_segs = i; + rte_pktmbuf_free(pkt); + goto nomore_mbuf; + } + pkt_seg = pkt_seg->next; + pkt_seg->data_len = pkt_len; + } + pkt_seg->next = NULL; /* Last segment of packet. */ + + /* + * Copy headers in first packet segment(s). + */ + if (vlan_enabled) + eth_hdr_size = sizeof(struct ether_hdr) + sizeof(struct vlan_hdr); + else + eth_hdr_size = sizeof(struct ether_hdr); + + copy_buf_to_pkt(eth_hdr, eth_hdr_size, pkt, 0); + + if (ipv4) { + copy_buf_to_pkt(ip_hdr, sizeof(struct ipv4_hdr), pkt, eth_hdr_size); + copy_buf_to_pkt(udp_hdr, sizeof(*udp_hdr), pkt, eth_hdr_size + + sizeof(struct ipv4_hdr)); + } else { + copy_buf_to_pkt(ip_hdr, sizeof(struct ipv6_hdr), pkt, eth_hdr_size); + copy_buf_to_pkt(udp_hdr, sizeof(*udp_hdr), pkt, eth_hdr_size + + sizeof(struct ipv6_hdr)); + } + + /* + * Complete first mbuf of packet and append it to the + * burst of packets to be transmitted. + */ + pkt->nb_segs = nb_pkt_segs; + pkt->pkt_len = pkt_len; + pkt->l2_len = eth_hdr_size; + + if (ipv4) { + pkt->vlan_tci = ETHER_TYPE_IPv4; + pkt->l3_len = sizeof(struct ipv4_hdr); + } else { + pkt->vlan_tci = ETHER_TYPE_IPv6; + pkt->l3_len = sizeof(struct ipv6_hdr); + } + + pkts_burst[nb_pkt] = pkt; + } + + return nb_pkt; +} diff --git a/test/test/packet_burst_generator.h b/test/test/packet_burst_generator.h new file mode 100644 index 0000000000..edc104417b --- /dev/null +++ b/test/test/packet_burst_generator.h @@ -0,0 +1,88 @@ +/*- + * 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 PACKET_BURST_GENERATOR_H_ +#define PACKET_BURST_GENERATOR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + + +#define IPV4_ADDR(a, b, c, d)(((a & 0xff) << 24) | ((b & 0xff) << 16) | \ + ((c & 0xff) << 8) | (d & 0xff)) + +#define PACKET_BURST_GEN_PKT_LEN 60 +#define PACKET_BURST_GEN_PKT_LEN_128 128 + +void +initialize_eth_header(struct ether_hdr *eth_hdr, struct ether_addr *src_mac, + struct ether_addr *dst_mac, uint16_t ether_type, + uint8_t vlan_enabled, uint16_t van_id); + +void +initialize_arp_header(struct arp_hdr *arp_hdr, struct ether_addr *src_mac, + struct ether_addr *dst_mac, uint32_t src_ip, uint32_t dst_ip, + uint32_t opcode); + +uint16_t +initialize_udp_header(struct udp_hdr *udp_hdr, uint16_t src_port, + uint16_t dst_port, uint16_t pkt_data_len); + + +uint16_t +initialize_ipv6_header(struct ipv6_hdr *ip_hdr, uint8_t *src_addr, + uint8_t *dst_addr, uint16_t pkt_data_len); + +uint16_t +initialize_ipv4_header(struct ipv4_hdr *ip_hdr, uint32_t src_addr, + uint32_t dst_addr, uint16_t pkt_data_len); + +int +generate_packet_burst(struct rte_mempool *mp, struct rte_mbuf **pkts_burst, + struct ether_hdr *eth_hdr, uint8_t vlan_enabled, void *ip_hdr, + uint8_t ipv4, struct udp_hdr *udp_hdr, int nb_pkt_per_burst, + uint8_t pkt_len, uint8_t nb_pkt_segs); + +#ifdef __cplusplus +} +#endif + + +#endif /* PACKET_BURST_GENERATOR_H_ */ diff --git a/test/test/process.h b/test/test/process.h new file mode 100644 index 0000000000..4f8d121162 --- /dev/null +++ b/test/test/process.h @@ -0,0 +1,103 @@ +/*- + * 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 _PROCESS_H_ +#define _PROCESS_H_ + +#ifdef RTE_EXEC_ENV_BSDAPP +#define self "curproc" +#define exe "file" +#else +#define self "self" +#define exe "exe" +#endif + +/* + * launches a second copy of the test process using the given argv parameters, + * which should include argv[0] as the process name. To identify in the + * subprocess the source of the call, the env_value parameter is set in the + * environment as $RTE_TEST + */ +static inline int +process_dup(const char *const argv[], int numargs, const char *env_value) +{ + int num; +#ifdef RTE_LIBRTE_XEN_DOM0 + char *argv_cpy[numargs + 2]; +#else + char *argv_cpy[numargs + 1]; +#endif + int i, fd, status; + char path[32]; + + pid_t pid = fork(); + if (pid < 0) + return -1; + else if (pid == 0) { + /* make a copy of the arguments to be passed to exec */ + for (i = 0; i < numargs; i++) + argv_cpy[i] = strdup(argv[i]); +#ifdef RTE_LIBRTE_XEN_DOM0 + argv_cpy[i] = strdup("--xen-dom0"); + argv_cpy[i + 1] = NULL; + num = numargs + 1; +#else + argv_cpy[i] = NULL; + num = numargs; +#endif + + /* close all open file descriptors, check /proc/self/fd to only + * call close on open fds. Exclude fds 0, 1 and 2*/ + for (fd = getdtablesize(); fd > 2; fd-- ) { + snprintf(path, sizeof(path), "/proc/" exe "/fd/%d", fd); + if (access(path, F_OK) == 0) + close(fd); + } + printf("Running binary with argv[]:"); + for (i = 0; i < num; i++) + printf("'%s' ", argv_cpy[i]); + printf("\n"); + + /* set the environment variable */ + if (setenv(RECURSIVE_ENV_VAR, env_value, 1) != 0) + rte_panic("Cannot export environment variable\n"); + if (execv("/proc/" self "/" exe, argv_cpy) < 0) + rte_panic("Cannot exec\n"); + } + /* parent process does a wait */ + while (wait(&status) != pid) + ; + return status; +} + +#endif /* _PROCESS_H_ */ diff --git a/test/test/resource.c b/test/test/resource.c new file mode 100644 index 0000000000..0e2b62cd8b --- /dev/null +++ b/test/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 +#include +#include +#include + +#include + +#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 +#include + +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/test/test/resource.h b/test/test/resource.h new file mode 100644 index 0000000000..1e96122133 --- /dev/null +++ b/test/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 +#include +#include + +#include +#include + +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_ and end_ 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/test/test/test.c b/test/test/test.c new file mode 100644 index 0000000000..cd0e784589 --- /dev/null +++ b/test/test/test.c @@ -0,0 +1,237 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef RTE_LIBRTE_CMDLINE +#include +#include +#include +#include +extern cmdline_parse_ctx_t main_ctx[]; +#endif + +#include +#include +#include +#include +#include +#include +#ifdef RTE_LIBRTE_TIMER +#include +#endif + +#include "test.h" + +#define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1 + +const char *prgname; /* to be set to argv[0] */ + +static const char *recursive_call; /* used in linuxapp for MP and other tests */ + +static int +no_action(void){ return 0; } + +static int +do_recursive_call(void) +{ + unsigned i; + struct { + const char *env_var; + int (*action_fn)(void); + } actions[] = { + { "run_secondary_instances", test_mp_secondary }, + { "test_missing_c_flag", no_action }, + { "test_master_lcore_flag", no_action }, + { "test_invalid_n_flag", no_action }, + { "test_no_hpet_flag", no_action }, + { "test_whitelist_flag", no_action }, + { "test_invalid_b_flag", no_action }, + { "test_invalid_vdev_flag", no_action }, + { "test_invalid_r_flag", no_action }, +#ifdef RTE_LIBRTE_XEN_DOM0 + { "test_dom0_misc_flags", no_action }, +#else + { "test_misc_flags", no_action }, +#endif + { "test_memory_flags", no_action }, + { "test_file_prefix", no_action }, + { "test_no_huge_flag", no_action }, + }; + + if (recursive_call == NULL) + return -1; + for (i = 0; i < sizeof(actions)/sizeof(actions[0]); i++) { + if (strcmp(actions[i].env_var, recursive_call) == 0) + return (actions[i].action_fn)(); + } + printf("ERROR - missing action to take for %s\n", recursive_call); + return -1; +} + +int +main(int argc, char **argv) +{ +#ifdef RTE_LIBRTE_CMDLINE + struct cmdline *cl; +#endif + int ret; + + ret = rte_eal_init(argc, argv); + if (ret < 0) + return -1; + +#ifdef RTE_LIBRTE_TIMER + rte_timer_subsystem_init(); +#endif + + if (commands_init() < 0) + return -1; + + argv += ret; + + prgname = argv[0]; + + if ((recursive_call = getenv(RECURSIVE_ENV_VAR)) != NULL) + return do_recursive_call(); + +#ifdef RTE_LIBEAL_USE_HPET + if (rte_eal_hpet_init(1) < 0) +#endif + RTE_LOG(INFO, APP, + "HPET is not enabled, using TSC as default timer\n"); + + +#ifdef RTE_LIBRTE_CMDLINE + cl = cmdline_stdin_new(main_ctx, "RTE>>"); + if (cl == NULL) { + return -1; + } + cmdline_interact(cl); + cmdline_stdin_exit(cl); +#endif + + return 0; +} + + +int +unit_test_suite_runner(struct unit_test_suite *suite) +{ + int test_success; + unsigned total = 0, executed = 0, skipped = 0, succeeded = 0, failed = 0; + + if (suite->suite_name) { + printf(" + ------------------------------------------------------- +\n"); + printf(" + Test Suite : %s\n", suite->suite_name); + } + + if (suite->setup) + if (suite->setup() != 0) + goto suite_summary; + + printf(" + ------------------------------------------------------- +\n"); + + while (suite->unit_test_cases[total].testcase) { + if (!suite->unit_test_cases[total].enabled) { + skipped++; + total++; + continue; + } else { + executed++; + } + + /* run test case setup */ + if (suite->unit_test_cases[total].setup) + test_success = suite->unit_test_cases[total].setup(); + else + test_success = TEST_SUCCESS; + + if (test_success == TEST_SUCCESS) { + /* run the test case */ + test_success = suite->unit_test_cases[total].testcase(); + if (test_success == TEST_SUCCESS) + succeeded++; + else + failed++; + } else { + failed++; + } + + /* run the test case teardown */ + if (suite->unit_test_cases[total].teardown) + suite->unit_test_cases[total].teardown(); + + if (test_success == TEST_SUCCESS) + printf(" + TestCase [%2d] : %s\n", total, + suite->unit_test_cases[total].success_msg ? + suite->unit_test_cases[total].success_msg : + "passed"); + else + printf(" + TestCase [%2d] : %s\n", total, + suite->unit_test_cases[total].fail_msg ? + suite->unit_test_cases[total].fail_msg : + "failed"); + + total++; + } + + /* Run test suite teardown */ + if (suite->teardown) + suite->teardown(); + + goto suite_summary; + +suite_summary: + printf(" + ------------------------------------------------------- +\n"); + printf(" + Test Suite Summary \n"); + printf(" + Tests Total : %2d\n", total); + printf(" + Tests Skipped : %2d\n", skipped); + printf(" + Tests Executed : %2d\n", executed); + printf(" + Tests Passed : %2d\n", succeeded); + printf(" + Tests Failed : %2d\n", failed); + printf(" + ------------------------------------------------------- +\n"); + + if (failed) + return -1; + + return 0; +} diff --git a/test/test/test.h b/test/test/test.h new file mode 100644 index 0000000000..82831f4e6c --- /dev/null +++ b/test/test/test.h @@ -0,0 +1,267 @@ +/*- + * 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 _TEST_H_ +#define _TEST_H_ + +#include +#include + +#include +#include + +#define TEST_SUCCESS (0) +#define TEST_FAILED (-1) + +/* Before including test.h file you can define + * TEST_TRACE_FAILURE(_file, _line, _func) macro to better trace/debug test + * failures. Mostly useful in test development phase. */ +#ifndef TEST_TRACE_FAILURE +# define TEST_TRACE_FAILURE(_file, _line, _func) +#endif + +#define TEST_ASSERT(cond, msg, ...) do { \ + if (!(cond)) { \ + 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_EQUAL(a, b, msg, ...) do { \ + if (!(a == 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 (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: " \ + 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 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)) { \ + 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_SUCCESS(val, msg, ...) do { \ + typeof(val) _val = (val); \ + if (!(_val == 0)) { \ + printf("TestCase %s() line %d failed (err %d): " \ + msg "\n", __func__, __LINE__, _val, \ + ##__VA_ARGS__); \ + TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ + return TEST_FAILED; \ + } \ +} while (0) + +#define TEST_ASSERT_FAIL(val, msg, ...) do { \ + if (!(val != 0)) { \ + 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_NULL(val, msg, ...) do { \ + if (!(val == NULL)) { \ + 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_NULL(val, msg, ...) do { \ + if (!(val != NULL)) { \ + printf("TestCase %s() line %d failed: " \ + msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ + TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ + return TEST_FAILED; \ + } \ +} while (0) + +struct unit_test_case { + int (*setup)(void); + void (*teardown)(void); + int (*testcase)(void); + const char *success_msg; + const char *fail_msg; + unsigned enabled; +}; + +#define TEST_CASE(fn) { NULL, NULL, fn, #fn " succeeded", #fn " failed", 1 } + +#define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, name " succeeded", \ + name " failed", 1 } + +#define TEST_CASE_ST(setup, teardown, testcase) \ + { setup, teardown, testcase, #testcase " succeeded", \ + #testcase " failed ", 1 } + + +#define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, #fn " succeeded", \ + #fn " failed", 0 } + +#define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \ + { setup, teardown, testcase, #testcase " succeeded", \ + #testcase " failed ", 0 } + +#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); + void (*teardown)(void); + struct unit_test_case unit_test_cases[]; +}; + +int unit_test_suite_runner(struct unit_test_suite *suite); + +#define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE" + +#include +#include + +extern const char *prgname; + +int commands_init(void); + +int test_pci(void); +int test_pci_run; + +int test_mp_secondary(void); + +int test_set_rxtx_conf(cmdline_fixed_string_t mode); +int test_set_rxtx_anchor(cmdline_fixed_string_t type); +int test_set_rxtx_sc(cmdline_fixed_string_t type); + +typedef int (test_callback)(void); +TAILQ_HEAD(test_commands_list, test_command); +struct test_command { + TAILQ_ENTRY(test_command) next; + const char *command; + test_callback *callback; +}; + +void add_test_command(struct test_command *t); + +/* Register a test function with its command string */ +#define REGISTER_TEST_COMMAND(cmd, func) \ + static struct test_command test_struct_##cmd = { \ + .command = RTE_STR(cmd), \ + .callback = func, \ + }; \ + static void __attribute__((constructor, used)) \ + test_register_##cmd(void) \ + { \ + add_test_command(&test_struct_##cmd); \ + } + +#endif diff --git a/test/test/test_acl.c b/test/test/test_acl.c new file mode 100644 index 0000000000..c6b511fb19 --- /dev/null +++ b/test/test/test_acl.c @@ -0,0 +1,1652 @@ +/*- + * 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 +#include + +#include "test.h" + +#include +#include +#include +#include +#include +#include + +#include "test_acl.h" + +#define BIT_SIZEOF(x) (sizeof(x) * CHAR_BIT) + +#define LEN RTE_ACL_MAX_CATEGORIES + +RTE_ACL_RULE_DEF(acl_ipv4vlan_rule, RTE_ACL_IPV4VLAN_NUM_FIELDS); + +struct rte_acl_param acl_param = { + .name = "acl_ctx", + .socket_id = SOCKET_ID_ANY, + .rule_size = RTE_ACL_IPV4VLAN_RULE_SZ, + .max_rule_num = 0x30000, +}; + +struct rte_acl_ipv4vlan_rule acl_rule = { + .data = { .priority = 1, .category_mask = 0xff }, + .src_port_low = 0, + .src_port_high = UINT16_MAX, + .dst_port_low = 0, + .dst_port_high = UINT16_MAX, +}; + +const uint32_t ipv4_7tuple_layout[RTE_ACL_IPV4VLAN_NUM] = { + offsetof(struct ipv4_7tuple, proto), + offsetof(struct ipv4_7tuple, vlan), + offsetof(struct ipv4_7tuple, ip_src), + offsetof(struct ipv4_7tuple, ip_dst), + offsetof(struct ipv4_7tuple, port_src), +}; + + +/* byteswap to cpu or network order */ +static void +bswap_test_data(struct ipv4_7tuple *data, int len, int to_be) +{ + int i; + + for (i = 0; i < len; i++) { + + if (to_be) { + /* swap all bytes so that they are in network order */ + data[i].ip_dst = rte_cpu_to_be_32(data[i].ip_dst); + data[i].ip_src = rte_cpu_to_be_32(data[i].ip_src); + data[i].port_dst = rte_cpu_to_be_16(data[i].port_dst); + data[i].port_src = rte_cpu_to_be_16(data[i].port_src); + data[i].vlan = rte_cpu_to_be_16(data[i].vlan); + data[i].domain = rte_cpu_to_be_16(data[i].domain); + } else { + data[i].ip_dst = rte_be_to_cpu_32(data[i].ip_dst); + data[i].ip_src = rte_be_to_cpu_32(data[i].ip_src); + data[i].port_dst = rte_be_to_cpu_16(data[i].port_dst); + data[i].port_src = rte_be_to_cpu_16(data[i].port_src); + data[i].vlan = rte_be_to_cpu_16(data[i].vlan); + data[i].domain = rte_be_to_cpu_16(data[i].domain); + } + } +} + +static int +acl_ipv4vlan_check_rule(const struct rte_acl_ipv4vlan_rule *rule) +{ + if (rule->src_port_low > rule->src_port_high || + rule->dst_port_low > rule->dst_port_high || + rule->src_mask_len > BIT_SIZEOF(rule->src_addr) || + rule->dst_mask_len > BIT_SIZEOF(rule->dst_addr)) + return -EINVAL; + return 0; +} + +static void +acl_ipv4vlan_convert_rule(const struct rte_acl_ipv4vlan_rule *ri, + struct acl_ipv4vlan_rule *ro) +{ + ro->data = ri->data; + + ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto; + ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan; + ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain; + ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr; + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr; + ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low; + ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low; + + ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask; + ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask; + ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 = + ri->domain_mask; + ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = + ri->src_mask_len; + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len; + ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 = + ri->src_port_high; + ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 = + ri->dst_port_high; +} + +/* + * Add ipv4vlan rules to an existing ACL context. + * This function is not multi-thread safe. + * + * @param ctx + * ACL context to add patterns to. + * @param rules + * Array of rules to add to the ACL context. + * Note that all fields in rte_acl_ipv4vlan_rule structures are expected + * to be in host byte order. + * @param num + * Number of elements in the input array of rules. + * @return + * - -ENOMEM if there is no space in the ACL context for these rules. + * - -EINVAL if the parameters are invalid. + * - Zero if operation completed successfully. + */ +static int +rte_acl_ipv4vlan_add_rules(struct rte_acl_ctx *ctx, + const struct rte_acl_ipv4vlan_rule *rules, + uint32_t num) +{ + int32_t rc; + uint32_t i; + struct acl_ipv4vlan_rule rv; + + if (ctx == NULL || rules == NULL) + return -EINVAL; + + /* check input rules. */ + for (i = 0; i != num; i++) { + rc = acl_ipv4vlan_check_rule(rules + i); + if (rc != 0) { + RTE_LOG(ERR, ACL, "%s: rule #%u is invalid\n", + __func__, i + 1); + return rc; + } + } + + /* perform conversion to the internal format and add to the context. */ + for (i = 0, rc = 0; i != num && rc == 0; i++) { + acl_ipv4vlan_convert_rule(rules + i, &rv); + rc = rte_acl_add_rules(ctx, (struct rte_acl_rule *)&rv, 1); + } + + return rc; +} + +static void +acl_ipv4vlan_config(struct rte_acl_config *cfg, + const uint32_t layout[RTE_ACL_IPV4VLAN_NUM], + uint32_t num_categories) +{ + static const struct rte_acl_field_def + ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = { + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint8_t), + .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD, + .input_index = RTE_ACL_IPV4VLAN_PROTO, + }, + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint16_t), + .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD, + .input_index = RTE_ACL_IPV4VLAN_VLAN, + }, + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint16_t), + .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD, + .input_index = RTE_ACL_IPV4VLAN_VLAN, + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD, + .input_index = RTE_ACL_IPV4VLAN_SRC, + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = RTE_ACL_IPV4VLAN_DST_FIELD, + .input_index = RTE_ACL_IPV4VLAN_DST, + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD, + .input_index = RTE_ACL_IPV4VLAN_PORTS, + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD, + .input_index = RTE_ACL_IPV4VLAN_PORTS, + }, + }; + + memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs)); + cfg->num_fields = RTE_DIM(ipv4_defs); + + cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_PROTO]; + cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_VLAN]; + cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_VLAN] + + cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size; + cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_SRC]; + cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_DST]; + cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_PORTS]; + cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_PORTS] + + cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size; + + cfg->num_categories = num_categories; +} + +/* + * Analyze set of ipv4vlan rules and build required internal + * run-time structures. + * This function is not multi-thread safe. + * + * @param ctx + * ACL context to build. + * @param layout + * Layout of input data to search through. + * @param num_categories + * Maximum number of categories to use in that build. + * @return + * - -ENOMEM if couldn't allocate enough memory. + * - -EINVAL if the parameters are invalid. + * - Negative error code if operation failed. + * - Zero if operation completed successfully. + */ +static int +rte_acl_ipv4vlan_build(struct rte_acl_ctx *ctx, + const uint32_t layout[RTE_ACL_IPV4VLAN_NUM], + uint32_t num_categories) +{ + struct rte_acl_config cfg; + + if (ctx == NULL || layout == NULL) + return -EINVAL; + + memset(&cfg, 0, sizeof(cfg)); + acl_ipv4vlan_config(&cfg, layout, num_categories); + return rte_acl_build(ctx, &cfg); +} + +/* + * Test scalar and SSE ACL lookup. + */ +static int +test_classify_run(struct rte_acl_ctx *acx) +{ + int ret, i; + uint32_t result, count; + uint32_t results[RTE_DIM(acl_test_data) * RTE_ACL_MAX_CATEGORIES]; + const uint8_t *data[RTE_DIM(acl_test_data)]; + + /* swap all bytes in the data to network order */ + bswap_test_data(acl_test_data, RTE_DIM(acl_test_data), 1); + + /* store pointers to test data */ + for (i = 0; i < (int) RTE_DIM(acl_test_data); i++) + data[i] = (uint8_t *)&acl_test_data[i]; + + /** + * these will run quite a few times, it's necessary to test code paths + * from num=0 to num>8 + */ + for (count = 0; count <= RTE_DIM(acl_test_data); count++) { + ret = rte_acl_classify(acx, data, results, + count, RTE_ACL_MAX_CATEGORIES); + if (ret != 0) { + printf("Line %i: SSE classify failed!\n", __LINE__); + goto err; + } + + /* check if we allow everything we should allow */ + for (i = 0; i < (int) count; i++) { + result = + results[i * RTE_ACL_MAX_CATEGORIES + ACL_ALLOW]; + if (result != acl_test_data[i].allow) { + printf("Line %i: Error in allow results at %i " + "(expected %"PRIu32" got %"PRIu32")!\n", + __LINE__, i, acl_test_data[i].allow, + result); + ret = -EINVAL; + goto err; + } + } + + /* check if we deny everything we should deny */ + for (i = 0; i < (int) count; i++) { + result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_DENY]; + if (result != acl_test_data[i].deny) { + printf("Line %i: Error in deny results at %i " + "(expected %"PRIu32" got %"PRIu32")!\n", + __LINE__, i, acl_test_data[i].deny, + result); + ret = -EINVAL; + goto err; + } + } + } + + /* make a quick check for scalar */ + ret = rte_acl_classify_alg(acx, data, results, + RTE_DIM(acl_test_data), RTE_ACL_MAX_CATEGORIES, + RTE_ACL_CLASSIFY_SCALAR); + if (ret != 0) { + printf("Line %i: scalar classify failed!\n", __LINE__); + goto err; + } + + /* check if we allow everything we should allow */ + for (i = 0; i < (int) RTE_DIM(acl_test_data); i++) { + result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_ALLOW]; + if (result != acl_test_data[i].allow) { + printf("Line %i: Error in allow results at %i " + "(expected %"PRIu32" got %"PRIu32")!\n", + __LINE__, i, acl_test_data[i].allow, + result); + ret = -EINVAL; + goto err; + } + } + + /* check if we deny everything we should deny */ + for (i = 0; i < (int) RTE_DIM(acl_test_data); i++) { + result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_DENY]; + if (result != acl_test_data[i].deny) { + printf("Line %i: Error in deny results at %i " + "(expected %"PRIu32" got %"PRIu32")!\n", + __LINE__, i, acl_test_data[i].deny, + result); + ret = -EINVAL; + goto err; + } + } + + ret = 0; + +err: + /* swap data back to cpu order so that next time tests don't fail */ + bswap_test_data(acl_test_data, RTE_DIM(acl_test_data), 0); + return ret; +} + +static int +test_classify_buid(struct rte_acl_ctx *acx, + const struct rte_acl_ipv4vlan_rule *rules, uint32_t num) +{ + int ret; + + /* add rules to the context */ + ret = rte_acl_ipv4vlan_add_rules(acx, rules, num); + if (ret != 0) { + printf("Line %i: Adding rules to ACL context failed!\n", + __LINE__); + return ret; + } + + /* try building the context */ + ret = rte_acl_ipv4vlan_build(acx, ipv4_7tuple_layout, + RTE_ACL_MAX_CATEGORIES); + if (ret != 0) { + printf("Line %i: Building ACL context failed!\n", __LINE__); + return ret; + } + + return 0; +} + +#define TEST_CLASSIFY_ITER 4 + +/* + * Test scalar and SSE ACL lookup. + */ +static int +test_classify(void) +{ + struct rte_acl_ctx *acx; + int i, ret; + + acx = rte_acl_create(&acl_param); + if (acx == NULL) { + printf("Line %i: Error creating ACL context!\n", __LINE__); + return -1; + } + + ret = 0; + for (i = 0; i != TEST_CLASSIFY_ITER; i++) { + + if ((i & 1) == 0) + rte_acl_reset(acx); + else + rte_acl_reset_rules(acx); + + ret = test_classify_buid(acx, acl_test_rules, + RTE_DIM(acl_test_rules)); + if (ret != 0) { + printf("Line %i, iter: %d: " + "Adding rules to ACL context failed!\n", + __LINE__, i); + break; + } + + ret = test_classify_run(acx); + if (ret != 0) { + printf("Line %i, iter: %d: %s failed!\n", + __LINE__, i, __func__); + break; + } + + /* reset rules and make sure that classify still works ok. */ + rte_acl_reset_rules(acx); + ret = test_classify_run(acx); + if (ret != 0) { + printf("Line %i, iter: %d: %s failed!\n", + __LINE__, i, __func__); + break; + } + } + + rte_acl_free(acx); + return ret; +} + +static int +test_build_ports_range(void) +{ + static const struct rte_acl_ipv4vlan_rule test_rules[] = { + { + /* match all packets. */ + .data = { + .userdata = 1, + .category_mask = ACL_ALLOW_MASK, + .priority = 101, + }, + .src_port_low = 0, + .src_port_high = UINT16_MAX, + .dst_port_low = 0, + .dst_port_high = UINT16_MAX, + }, + { + /* match all packets with dst ports [54-65280]. */ + .data = { + .userdata = 2, + .category_mask = ACL_ALLOW_MASK, + .priority = 102, + }, + .src_port_low = 0, + .src_port_high = UINT16_MAX, + .dst_port_low = 54, + .dst_port_high = 65280, + }, + { + /* match all packets with dst ports [0-52]. */ + .data = { + .userdata = 3, + .category_mask = ACL_ALLOW_MASK, + .priority = 103, + }, + .src_port_low = 0, + .src_port_high = UINT16_MAX, + .dst_port_low = 0, + .dst_port_high = 52, + }, + { + /* match all packets with dst ports [53]. */ + .data = { + .userdata = 4, + .category_mask = ACL_ALLOW_MASK, + .priority = 99, + }, + .src_port_low = 0, + .src_port_high = UINT16_MAX, + .dst_port_low = 53, + .dst_port_high = 53, + }, + { + /* match all packets with dst ports [65279-65535]. */ + .data = { + .userdata = 5, + .category_mask = ACL_ALLOW_MASK, + .priority = 98, + }, + .src_port_low = 0, + .src_port_high = UINT16_MAX, + .dst_port_low = 65279, + .dst_port_high = UINT16_MAX, + }, + }; + + static struct ipv4_7tuple test_data[] = { + { + .proto = 6, + .ip_src = IPv4(10, 1, 1, 1), + .ip_dst = IPv4(192, 168, 0, 33), + .port_dst = 53, + .allow = 1, + }, + { + .proto = 6, + .ip_src = IPv4(127, 84, 33, 1), + .ip_dst = IPv4(1, 2, 3, 4), + .port_dst = 65281, + .allow = 1, + }, + }; + + struct rte_acl_ctx *acx; + int32_t ret, i, j; + uint32_t results[RTE_DIM(test_data)]; + const uint8_t *data[RTE_DIM(test_data)]; + + acx = rte_acl_create(&acl_param); + if (acx == NULL) { + printf("Line %i: Error creating ACL context!\n", __LINE__); + return -1; + } + + /* swap all bytes in the data to network order */ + bswap_test_data(test_data, RTE_DIM(test_data), 1); + + /* store pointers to test data */ + for (i = 0; i != RTE_DIM(test_data); i++) + data[i] = (uint8_t *)&test_data[i]; + + for (i = 0; i != RTE_DIM(test_rules); i++) { + rte_acl_reset(acx); + ret = test_classify_buid(acx, test_rules, i + 1); + if (ret != 0) { + printf("Line %i, iter: %d: " + "Adding rules to ACL context failed!\n", + __LINE__, i); + break; + } + ret = rte_acl_classify(acx, data, results, + RTE_DIM(data), 1); + if (ret != 0) { + printf("Line %i, iter: %d: classify failed!\n", + __LINE__, i); + break; + } + + /* check results */ + for (j = 0; j != RTE_DIM(results); j++) { + if (results[j] != test_data[j].allow) { + printf("Line %i: Error in allow results at %i " + "(expected %"PRIu32" got %"PRIu32")!\n", + __LINE__, j, test_data[j].allow, + results[j]); + ret = -EINVAL; + } + } + } + + bswap_test_data(test_data, RTE_DIM(test_data), 0); + + rte_acl_free(acx); + return ret; +} + +static void +convert_rule(const struct rte_acl_ipv4vlan_rule *ri, + struct acl_ipv4vlan_rule *ro) +{ + ro->data = ri->data; + + ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto; + ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan; + ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain; + ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr; + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr; + ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low; + ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low; + + ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask; + ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask; + ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 = + ri->domain_mask; + ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = + ri->src_mask_len; + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len; + ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 = + ri->src_port_high; + ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 = + ri->dst_port_high; +} + +/* + * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to + * RTE_ACL_FIELD_TYPE_BITMASK. + */ +static void +convert_rule_1(const struct rte_acl_ipv4vlan_rule *ri, + struct acl_ipv4vlan_rule *ro) +{ + uint32_t v; + + convert_rule(ri, ro); + v = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32; + ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = + RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v)); + v = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32; + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = + RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v)); +} + +/* + * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to + * RTE_ACL_FIELD_TYPE_RANGE. + */ +static void +convert_rule_2(const struct rte_acl_ipv4vlan_rule *ri, + struct acl_ipv4vlan_rule *ro) +{ + uint32_t hi, lo, mask; + + convert_rule(ri, ro); + + mask = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32; + mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask)); + lo = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 & mask; + hi = lo + ~mask; + ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = lo; + ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = hi; + + mask = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32; + mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask)); + lo = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 & mask; + hi = lo + ~mask; + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = lo; + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = hi; +} + +/* + * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields. + */ +static void +convert_rule_3(const struct rte_acl_ipv4vlan_rule *ri, + struct acl_ipv4vlan_rule *ro) +{ + struct rte_acl_field t1, t2; + + convert_rule(ri, ro); + + t1 = ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD]; + t2 = ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD]; + + ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD] = + ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD]; + ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD] = + ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD]; + + ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD] = t1; + ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD] = t2; +} + +/* + * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules. + */ +static void +convert_rule_4(const struct rte_acl_ipv4vlan_rule *ri, + struct acl_ipv4vlan_rule *ro) +{ + struct rte_acl_field t; + + convert_rule(ri, ro); + + t = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD]; + ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD] = + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD]; + + ro->field[RTE_ACL_IPV4VLAN_DST_FIELD] = t; +} + +static void +ipv4vlan_config(struct rte_acl_config *cfg, + const uint32_t layout[RTE_ACL_IPV4VLAN_NUM], + uint32_t num_categories) +{ + static const struct rte_acl_field_def + ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = { + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint8_t), + .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD, + .input_index = RTE_ACL_IPV4VLAN_PROTO, + }, + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint16_t), + .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD, + .input_index = RTE_ACL_IPV4VLAN_VLAN, + }, + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint16_t), + .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD, + .input_index = RTE_ACL_IPV4VLAN_VLAN, + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD, + .input_index = RTE_ACL_IPV4VLAN_SRC, + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = RTE_ACL_IPV4VLAN_DST_FIELD, + .input_index = RTE_ACL_IPV4VLAN_DST, + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD, + .input_index = RTE_ACL_IPV4VLAN_PORTS, + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD, + .input_index = RTE_ACL_IPV4VLAN_PORTS, + }, + }; + + memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs)); + cfg->num_fields = RTE_DIM(ipv4_defs); + + cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_PROTO]; + cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_VLAN]; + cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_VLAN] + + cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size; + cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_SRC]; + cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_DST]; + cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_PORTS]; + cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = + layout[RTE_ACL_IPV4VLAN_PORTS] + + cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size; + + cfg->num_categories = num_categories; +} + +static int +convert_rules(struct rte_acl_ctx *acx, + void (*convert)(const struct rte_acl_ipv4vlan_rule *, + struct acl_ipv4vlan_rule *), + const struct rte_acl_ipv4vlan_rule *rules, uint32_t num) +{ + int32_t rc; + uint32_t i; + struct acl_ipv4vlan_rule r; + + for (i = 0; i != num; i++) { + convert(rules + i, &r); + rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1); + if (rc != 0) { + printf("Line %i: Adding rule %u to ACL context " + "failed with error code: %d\n", + __LINE__, i, rc); + return rc; + } + } + + return 0; +} + +static void +convert_config(struct rte_acl_config *cfg) +{ + ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); +} + +/* + * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK. + */ +static void +convert_config_1(struct rte_acl_config *cfg) +{ + ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); + cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK; + cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK; +} + +/* + * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE. + */ +static void +convert_config_2(struct rte_acl_config *cfg) +{ + ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); + cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE; + cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE; +} + +/* + * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions. + */ +static void +convert_config_3(struct rte_acl_config *cfg) +{ + struct rte_acl_field_def t1, t2; + + ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); + + t1 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD]; + t2 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD]; + + /* swap VLAN1 and SRCP rule definition. */ + cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD] = + cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD]; + cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].field_index = t1.field_index; + cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].input_index = t1.input_index; + + /* swap VLAN2 and DSTP rule definition. */ + cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD] = + cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD]; + cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].field_index = t2.field_index; + cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].input_index = t2.input_index; + + cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].type = t1.type; + cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size = t1.size; + cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = t1.offset; + + cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].type = t2.type; + cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].size = t2.size; + cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = t2.offset; +} + +/* + * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions. + */ +static void +convert_config_4(struct rte_acl_config *cfg) +{ + struct rte_acl_field_def t; + + ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES); + + t = cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD]; + + cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD] = + cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD]; + cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].field_index = t.field_index; + cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].input_index = t.input_index; + + cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = t.type; + cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].size = t.size; + cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = t.offset; +} + + +static int +build_convert_rules(struct rte_acl_ctx *acx, + void (*config)(struct rte_acl_config *), + size_t max_size) +{ + struct rte_acl_config cfg; + + memset(&cfg, 0, sizeof(cfg)); + config(&cfg); + cfg.max_size = max_size; + return rte_acl_build(acx, &cfg); +} + +static int +test_convert_rules(const char *desc, + void (*config)(struct rte_acl_config *), + void (*convert)(const struct rte_acl_ipv4vlan_rule *, + struct acl_ipv4vlan_rule *)) +{ + struct rte_acl_ctx *acx; + int32_t rc; + uint32_t i; + static const size_t mem_sizes[] = {0, -1}; + + printf("running %s(%s)\n", __func__, desc); + + acx = rte_acl_create(&acl_param); + if (acx == NULL) { + printf("Line %i: Error creating ACL context!\n", __LINE__); + return -1; + } + + rc = convert_rules(acx, convert, acl_test_rules, + RTE_DIM(acl_test_rules)); + if (rc != 0) + printf("Line %i: Error converting ACL rules!\n", __LINE__); + + for (i = 0; rc == 0 && i != RTE_DIM(mem_sizes); i++) { + + rc = build_convert_rules(acx, config, mem_sizes[i]); + if (rc != 0) { + printf("Line %i: Error @ build_convert_rules(%zu)!\n", + __LINE__, mem_sizes[i]); + break; + } + + rc = test_classify_run(acx); + if (rc != 0) + printf("%s failed at line %i, max_size=%zu\n", + __func__, __LINE__, mem_sizes[i]); + } + + rte_acl_free(acx); + return rc; +} + +static int +test_convert(void) +{ + static const struct { + const char *desc; + void (*config)(struct rte_acl_config *); + void (*convert)(const struct rte_acl_ipv4vlan_rule *, + struct acl_ipv4vlan_rule *); + } convert_param[] = { + { + "acl_ipv4vlan_tuple", + convert_config, + convert_rule, + }, + { + "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type " + "for IPv4", + convert_config_1, + convert_rule_1, + }, + { + "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type " + "for IPv4", + convert_config_2, + convert_rule_2, + }, + { + "acl_ipv4vlan_tuple: swap VLAN and PORTs order", + convert_config_3, + convert_rule_3, + }, + { + "acl_ipv4vlan_tuple: swap SRC and DST IPv4 order", + convert_config_4, + convert_rule_4, + }, + }; + + uint32_t i; + int32_t rc; + + for (i = 0; i != RTE_DIM(convert_param); i++) { + rc = test_convert_rules(convert_param[i].desc, + convert_param[i].config, + convert_param[i].convert); + if (rc != 0) { + printf("%s for test-case: %s failed, error code: %d;\n", + __func__, convert_param[i].desc, rc); + return rc; + } + } + + return 0; +} + +/* + * Test wrong layout behavior + * This test supplies the ACL context with invalid layout, which results in + * ACL matching the wrong stuff. However, it should match the wrong stuff + * the right way. We switch around source and destination addresses, + * source and destination ports, and protocol will point to first byte of + * destination port. + */ +static int +test_invalid_layout(void) +{ + struct rte_acl_ctx *acx; + int ret, i; + + uint32_t results[RTE_DIM(invalid_layout_data)]; + const uint8_t *data[RTE_DIM(invalid_layout_data)]; + + const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = { + /* proto points to destination port's first byte */ + offsetof(struct ipv4_7tuple, port_dst), + + 0, /* VLAN not used */ + + /* src and dst addresses are swapped */ + offsetof(struct ipv4_7tuple, ip_dst), + offsetof(struct ipv4_7tuple, ip_src), + + /* + * we can't swap ports here, so we will swap + * them in the data + */ + offsetof(struct ipv4_7tuple, port_src), + }; + + acx = rte_acl_create(&acl_param); + if (acx == NULL) { + printf("Line %i: Error creating ACL context!\n", __LINE__); + return -1; + } + + /* putting a lot of rules into the context results in greater + * coverage numbers. it doesn't matter if they are identical */ + for (i = 0; i < 1000; i++) { + /* add rules to the context */ + ret = rte_acl_ipv4vlan_add_rules(acx, invalid_layout_rules, + RTE_DIM(invalid_layout_rules)); + if (ret != 0) { + printf("Line %i: Adding rules to ACL context failed!\n", + __LINE__); + rte_acl_free(acx); + return -1; + } + } + + /* try building the context */ + ret = rte_acl_ipv4vlan_build(acx, layout, 1); + if (ret != 0) { + printf("Line %i: Building ACL context failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* swap all bytes in the data to network order */ + bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 1); + + /* prepare data */ + for (i = 0; i < (int) RTE_DIM(invalid_layout_data); i++) { + data[i] = (uint8_t *)&invalid_layout_data[i]; + } + + /* classify tuples */ + ret = rte_acl_classify_alg(acx, data, results, + RTE_DIM(results), 1, RTE_ACL_CLASSIFY_SCALAR); + if (ret != 0) { + printf("Line %i: SSE classify failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + for (i = 0; i < (int) RTE_DIM(results); i++) { + if (results[i] != invalid_layout_data[i].allow) { + printf("Line %i: Wrong results at %i " + "(result=%u, should be %u)!\n", + __LINE__, i, results[i], + invalid_layout_data[i].allow); + goto err; + } + } + + /* classify tuples (scalar) */ + ret = rte_acl_classify_alg(acx, data, results, RTE_DIM(results), 1, + RTE_ACL_CLASSIFY_SCALAR); + + if (ret != 0) { + printf("Line %i: Scalar classify failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + for (i = 0; i < (int) RTE_DIM(results); i++) { + if (results[i] != invalid_layout_data[i].allow) { + printf("Line %i: Wrong results at %i " + "(result=%u, should be %u)!\n", + __LINE__, i, results[i], + invalid_layout_data[i].allow); + goto err; + } + } + + rte_acl_free(acx); + + /* swap data back to cpu order so that next time tests don't fail */ + bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0); + + return 0; +err: + + /* swap data back to cpu order so that next time tests don't fail */ + bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0); + + rte_acl_free(acx); + + return -1; +} + +/* + * Test creating and finding ACL contexts, and adding rules + */ +static int +test_create_find_add(void) +{ + struct rte_acl_param param; + struct rte_acl_ctx *acx, *acx2, *tmp; + struct rte_acl_ipv4vlan_rule rules[LEN]; + + const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0}; + + const char *acx_name = "acx"; + const char *acx2_name = "acx2"; + int i, ret; + + /* create two contexts */ + memcpy(¶m, &acl_param, sizeof(param)); + param.max_rule_num = 2; + + param.name = acx_name; + acx = rte_acl_create(¶m); + if (acx == NULL) { + printf("Line %i: Error creating %s!\n", __LINE__, acx_name); + return -1; + } + + param.name = acx2_name; + acx2 = rte_acl_create(¶m); + if (acx2 == NULL || acx2 == acx) { + printf("Line %i: Error creating %s!\n", __LINE__, acx2_name); + rte_acl_free(acx); + return -1; + } + + /* try to create third one, with an existing name */ + param.name = acx_name; + tmp = rte_acl_create(¶m); + if (tmp != acx) { + printf("Line %i: Creating context with existing name " + "test failed!\n", + __LINE__); + if (tmp) + rte_acl_free(tmp); + goto err; + } + + param.name = acx2_name; + tmp = rte_acl_create(¶m); + if (tmp != acx2) { + printf("Line %i: Creating context with existing " + "name test 2 failed!\n", + __LINE__); + if (tmp) + rte_acl_free(tmp); + goto err; + } + + /* try to find existing ACL contexts */ + tmp = rte_acl_find_existing(acx_name); + if (tmp != acx) { + printf("Line %i: Finding %s failed!\n", __LINE__, acx_name); + if (tmp) + rte_acl_free(tmp); + goto err; + } + + tmp = rte_acl_find_existing(acx2_name); + if (tmp != acx2) { + printf("Line %i: Finding %s failed!\n", __LINE__, acx2_name); + if (tmp) + rte_acl_free(tmp); + goto err; + } + + /* try to find non-existing context */ + tmp = rte_acl_find_existing("invalid"); + if (tmp != NULL) { + printf("Line %i: Non-existent ACL context found!\n", __LINE__); + goto err; + } + + /* free context */ + rte_acl_free(acx); + + + /* create valid (but severely limited) acx */ + memcpy(¶m, &acl_param, sizeof(param)); + param.max_rule_num = LEN; + + acx = rte_acl_create(¶m); + if (acx == NULL) { + printf("Line %i: Error creating %s!\n", __LINE__, param.name); + goto err; + } + + /* create dummy acl */ + for (i = 0; i < LEN; i++) { + memcpy(&rules[i], &acl_rule, + sizeof(struct rte_acl_ipv4vlan_rule)); + /* skip zero */ + rules[i].data.userdata = i + 1; + /* one rule per category */ + rules[i].data.category_mask = 1 << i; + } + + /* try filling up the context */ + ret = rte_acl_ipv4vlan_add_rules(acx, rules, LEN); + if (ret != 0) { + printf("Line %i: Adding %i rules to ACL context failed!\n", + __LINE__, LEN); + goto err; + } + + /* try adding to a (supposedly) full context */ + ret = rte_acl_ipv4vlan_add_rules(acx, rules, 1); + if (ret == 0) { + printf("Line %i: Adding rules to full ACL context should" + "have failed!\n", __LINE__); + goto err; + } + + /* try building the context */ + ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES); + if (ret != 0) { + printf("Line %i: Building ACL context failed!\n", __LINE__); + goto err; + } + + rte_acl_free(acx); + rte_acl_free(acx2); + + return 0; +err: + rte_acl_free(acx); + rte_acl_free(acx2); + return -1; +} + +/* + * test various invalid rules + */ +static int +test_invalid_rules(void) +{ + struct rte_acl_ctx *acx; + int ret; + + struct rte_acl_ipv4vlan_rule rule; + + acx = rte_acl_create(&acl_param); + if (acx == NULL) { + printf("Line %i: Error creating ACL context!\n", __LINE__); + return -1; + } + + /* test inverted high/low source and destination ports. + * originally, there was a problem with memory consumption when using + * such rules. + */ + /* create dummy acl */ + memcpy(&rule, &acl_rule, sizeof(struct rte_acl_ipv4vlan_rule)); + rule.data.userdata = 1; + rule.dst_port_low = 0xfff0; + rule.dst_port_high = 0x0010; + + /* add rules to context and try to build it */ + ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1); + if (ret == 0) { + printf("Line %i: Adding rules to ACL context " + "should have failed!\n", __LINE__); + goto err; + } + + rule.dst_port_low = 0x0; + rule.dst_port_high = 0xffff; + rule.src_port_low = 0xfff0; + rule.src_port_high = 0x0010; + + /* add rules to context and try to build it */ + ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1); + if (ret == 0) { + printf("Line %i: Adding rules to ACL context " + "should have failed!\n", __LINE__); + goto err; + } + + rule.dst_port_low = 0x0; + rule.dst_port_high = 0xffff; + rule.src_port_low = 0x0; + rule.src_port_high = 0xffff; + + rule.dst_mask_len = 33; + + /* add rules to context and try to build it */ + ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1); + if (ret == 0) { + printf("Line %i: Adding rules to ACL context " + "should have failed!\n", __LINE__); + goto err; + } + + rule.dst_mask_len = 0; + rule.src_mask_len = 33; + + /* add rules to context and try to build it */ + ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1); + if (ret == 0) { + printf("Line %i: Adding rules to ACL context " + "should have failed!\n", __LINE__); + goto err; + } + + rte_acl_free(acx); + + return 0; + +err: + rte_acl_free(acx); + + return -1; +} + +/* + * test functions by passing invalid or + * non-workable parameters. + * + * we do very limited testing of classify functions here + * because those are performance-critical and + * thus don't do much parameter checking. + */ +static int +test_invalid_parameters(void) +{ + struct rte_acl_param param; + struct rte_acl_ctx *acx; + struct rte_acl_ipv4vlan_rule rule; + int result; + + uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0}; + + + /** + * rte_ac_create() + */ + + /* NULL param */ + acx = rte_acl_create(NULL); + if (acx != NULL) { + printf("Line %i: ACL context creation with NULL param " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* zero rule size */ + memcpy(¶m, &acl_param, sizeof(param)); + param.rule_size = 0; + + acx = rte_acl_create(¶m); + if (acx == NULL) { + printf("Line %i: ACL context creation with zero rule len " + "failed!\n", __LINE__); + return -1; + } else + rte_acl_free(acx); + + /* zero max rule num */ + memcpy(¶m, &acl_param, sizeof(param)); + param.max_rule_num = 0; + + acx = rte_acl_create(¶m); + if (acx == NULL) { + printf("Line %i: ACL context creation with zero rule num " + "failed!\n", __LINE__); + return -1; + } else + rte_acl_free(acx); + + /* invalid NUMA node */ + memcpy(¶m, &acl_param, sizeof(param)); + param.socket_id = RTE_MAX_NUMA_NODES + 1; + + acx = rte_acl_create(¶m); + if (acx != NULL) { + printf("Line %i: ACL context creation with invalid NUMA " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* NULL name */ + memcpy(¶m, &acl_param, sizeof(param)); + param.name = NULL; + + acx = rte_acl_create(¶m); + if (acx != NULL) { + printf("Line %i: ACL context creation with NULL name " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /** + * rte_acl_find_existing + */ + + acx = rte_acl_find_existing(NULL); + if (acx != NULL) { + printf("Line %i: NULL ACL context found!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /** + * rte_acl_ipv4vlan_add_rules + */ + + /* initialize everything */ + memcpy(¶m, &acl_param, sizeof(param)); + acx = rte_acl_create(¶m); + if (acx == NULL) { + printf("Line %i: ACL context creation failed!\n", __LINE__); + return -1; + } + + memcpy(&rule, &acl_rule, sizeof(rule)); + + /* NULL context */ + result = rte_acl_ipv4vlan_add_rules(NULL, &rule, 1); + if (result == 0) { + printf("Line %i: Adding rules with NULL ACL context " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* NULL rule */ + result = rte_acl_ipv4vlan_add_rules(acx, NULL, 1); + if (result == 0) { + printf("Line %i: Adding NULL rule to ACL context " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* zero count (should succeed) */ + result = rte_acl_ipv4vlan_add_rules(acx, &rule, 0); + if (result != 0) { + printf("Line %i: Adding 0 rules to ACL context failed!\n", + __LINE__); + rte_acl_free(acx); + return -1; + } + + /* free ACL context */ + rte_acl_free(acx); + + + /** + * rte_acl_ipv4vlan_build + */ + + /* reinitialize context */ + memcpy(¶m, &acl_param, sizeof(param)); + acx = rte_acl_create(¶m); + if (acx == NULL) { + printf("Line %i: ACL context creation failed!\n", __LINE__); + return -1; + } + + /* NULL context */ + result = rte_acl_ipv4vlan_build(NULL, layout, 1); + if (result == 0) { + printf("Line %i: Building with NULL context " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* NULL layout */ + result = rte_acl_ipv4vlan_build(acx, NULL, 1); + if (result == 0) { + printf("Line %i: Building with NULL layout " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* zero categories (should not fail) */ + result = rte_acl_ipv4vlan_build(acx, layout, 0); + if (result == 0) { + printf("Line %i: Building with 0 categories should fail!\n", + __LINE__); + rte_acl_free(acx); + return -1; + } + + /* SSE classify test */ + + /* cover zero categories in classify (should not fail) */ + result = rte_acl_classify(acx, NULL, NULL, 0, 0); + if (result != 0) { + printf("Line %i: SSE classify with zero categories " + "failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* cover invalid but positive categories in classify */ + result = rte_acl_classify(acx, NULL, NULL, 0, 3); + if (result == 0) { + printf("Line %i: SSE classify with 3 categories " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* scalar classify test */ + + /* cover zero categories in classify (should not fail) */ + result = rte_acl_classify_alg(acx, NULL, NULL, 0, 0, + RTE_ACL_CLASSIFY_SCALAR); + if (result != 0) { + printf("Line %i: Scalar classify with zero categories " + "failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* cover invalid but positive categories in classify */ + result = rte_acl_classify(acx, NULL, NULL, 0, 3); + if (result == 0) { + printf("Line %i: Scalar classify with 3 categories " + "should have failed!\n", __LINE__); + rte_acl_free(acx); + return -1; + } + + /* free ACL context */ + rte_acl_free(acx); + + + /** + * make sure void functions don't crash with NULL parameters + */ + + rte_acl_free(NULL); + + rte_acl_dump(NULL); + + return 0; +} + +/** + * Various tests that don't test much but improve coverage + */ +static int +test_misc(void) +{ + struct rte_acl_param param; + struct rte_acl_ctx *acx; + + /* create context */ + memcpy(¶m, &acl_param, sizeof(param)); + + acx = rte_acl_create(¶m); + if (acx == NULL) { + printf("Line %i: Error creating ACL context!\n", __LINE__); + return -1; + } + + /* dump context with rules - useful for coverage */ + rte_acl_list_dump(); + + rte_acl_dump(acx); + + rte_acl_free(acx); + + return 0; +} + +static int +test_acl(void) +{ + if (test_invalid_parameters() < 0) + return -1; + if (test_invalid_rules() < 0) + return -1; + if (test_create_find_add() < 0) + return -1; + if (test_invalid_layout() < 0) + return -1; + if (test_misc() < 0) + return -1; + if (test_classify() < 0) + return -1; + if (test_build_ports_range() < 0) + return -1; + if (test_convert() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(acl_autotest, test_acl); diff --git a/test/test/test_acl.h b/test/test/test_acl.h new file mode 100644 index 0000000000..421f3109b3 --- /dev/null +++ b/test/test/test_acl.h @@ -0,0 +1,692 @@ +/*- + * 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 TEST_ACL_H_ +#define TEST_ACL_H_ + +struct ipv4_7tuple { + uint16_t vlan; + uint16_t domain; + uint8_t proto; + uint32_t ip_src; + uint32_t ip_dst; + uint16_t port_src; + uint16_t port_dst; + uint32_t allow; + uint32_t deny; +}; + +/** + * Legacy support for 7-tuple IPv4 and VLAN rule. + * This structure and corresponding API is deprecated. + */ +struct rte_acl_ipv4vlan_rule { + struct rte_acl_rule_data data; /**< Miscellaneous data for the rule. */ + uint8_t proto; /**< IPv4 protocol ID. */ + uint8_t proto_mask; /**< IPv4 protocol ID mask. */ + uint16_t vlan; /**< VLAN ID. */ + uint16_t vlan_mask; /**< VLAN ID mask. */ + uint16_t domain; /**< VLAN domain. */ + uint16_t domain_mask; /**< VLAN domain mask. */ + uint32_t src_addr; /**< IPv4 source address. */ + uint32_t src_mask_len; /**< IPv4 source address mask. */ + uint32_t dst_addr; /**< IPv4 destination address. */ + uint32_t dst_mask_len; /**< IPv4 destination address mask. */ + uint16_t src_port_low; /**< L4 source port low. */ + uint16_t src_port_high; /**< L4 source port high. */ + uint16_t dst_port_low; /**< L4 destination port low. */ + uint16_t dst_port_high; /**< L4 destination port high. */ +}; + +/** + * Specifies fields layout inside rte_acl_rule for rte_acl_ipv4vlan_rule. + */ +enum { + RTE_ACL_IPV4VLAN_PROTO_FIELD, + RTE_ACL_IPV4VLAN_VLAN1_FIELD, + RTE_ACL_IPV4VLAN_VLAN2_FIELD, + RTE_ACL_IPV4VLAN_SRC_FIELD, + RTE_ACL_IPV4VLAN_DST_FIELD, + RTE_ACL_IPV4VLAN_SRCP_FIELD, + RTE_ACL_IPV4VLAN_DSTP_FIELD, + RTE_ACL_IPV4VLAN_NUM_FIELDS +}; + +/** + * Macro to define rule size for rte_acl_ipv4vlan_rule. + */ +#define RTE_ACL_IPV4VLAN_RULE_SZ \ + RTE_ACL_RULE_SZ(RTE_ACL_IPV4VLAN_NUM_FIELDS) + +/* + * That effectively defines order of IPV4VLAN classifications: + * - PROTO + * - VLAN (TAG and DOMAIN) + * - SRC IP ADDRESS + * - DST IP ADDRESS + * - PORTS (SRC and DST) + */ +enum { + RTE_ACL_IPV4VLAN_PROTO, + RTE_ACL_IPV4VLAN_VLAN, + RTE_ACL_IPV4VLAN_SRC, + RTE_ACL_IPV4VLAN_DST, + RTE_ACL_IPV4VLAN_PORTS, + RTE_ACL_IPV4VLAN_NUM +}; + +/* rules for invalid layout test */ +struct rte_acl_ipv4vlan_rule invalid_layout_rules[] = { + /* test src and dst address */ + { + .data = {.userdata = 1, .category_mask = 1}, + .src_addr = IPv4(10,0,0,0), + .src_mask_len = 24, + }, + { + .data = {.userdata = 2, .category_mask = 1}, + .dst_addr = IPv4(10,0,0,0), + .dst_mask_len = 24, + }, + /* test src and dst ports */ + { + .data = {.userdata = 3, .category_mask = 1}, + .dst_port_low = 100, + .dst_port_high = 100, + }, + { + .data = {.userdata = 4, .category_mask = 1}, + .src_port_low = 100, + .src_port_high = 100, + }, + /* test proto */ + { + .data = {.userdata = 5, .category_mask = 1}, + .proto = 0xf, + .proto_mask = 0xf + }, + { + .data = {.userdata = 6, .category_mask = 1}, + .dst_port_low = 0xf, + .dst_port_high = 0xf, + } +}; + +/* these might look odd because they don't match up the rules. This is + * intentional, as the invalid layout test presumes returning the correct + * results using the wrong data layout. + */ +struct ipv4_7tuple invalid_layout_data[] = { + {.ip_src = IPv4(10,0,1,0)}, /* should not match */ + {.ip_src = IPv4(10,0,0,1), .allow = 2}, /* should match 2 */ + {.port_src = 100, .allow = 4}, /* should match 4 */ + {.port_dst = 0xf, .allow = 6}, /* should match 6 */ +}; + +#define ACL_ALLOW 0 +#define ACL_DENY 1 +#define ACL_ALLOW_MASK 0x1 +#define ACL_DENY_MASK 0x2 + +/* ruleset for ACL unit test */ +struct rte_acl_ipv4vlan_rule acl_test_rules[] = { +/* destination IP addresses */ + /* matches all packets traveling to 192.168.0.0/16 */ + { + .data = {.userdata = 1, .category_mask = ACL_ALLOW_MASK, + .priority = 230}, + .dst_addr = IPv4(192,168,0,0), + .dst_mask_len = 16, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets traveling to 192.168.1.0/24 */ + { + .data = {.userdata = 2, .category_mask = ACL_ALLOW_MASK, + .priority = 330}, + .dst_addr = IPv4(192,168,1,0), + .dst_mask_len = 24, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets traveling to 192.168.1.50 */ + { + .data = {.userdata = 3, .category_mask = ACL_DENY_MASK, + .priority = 230}, + .dst_addr = IPv4(192,168,1,50), + .dst_mask_len = 32, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + +/* source IP addresses */ + /* matches all packets traveling from 10.0.0.0/8 */ + { + .data = {.userdata = 4, .category_mask = ACL_ALLOW_MASK, + .priority = 240}, + .src_addr = IPv4(10,0,0,0), + .src_mask_len = 8, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets traveling from 10.1.1.0/24 */ + { + .data = {.userdata = 5, .category_mask = ACL_ALLOW_MASK, + .priority = 340}, + .src_addr = IPv4(10,1,1,0), + .src_mask_len = 24, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets traveling from 10.1.1.1 */ + { + .data = {.userdata = 6, .category_mask = ACL_DENY_MASK, + .priority = 240}, + .src_addr = IPv4(10,1,1,1), + .src_mask_len = 32, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + +/* VLAN tag */ + /* matches all packets with lower 7 bytes of VLAN tag equal to 0x64 */ + { + .data = {.userdata = 7, .category_mask = ACL_ALLOW_MASK, + .priority = 260}, + .vlan = 0x64, + .vlan_mask = 0x7f, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets with VLAN tags that have 0x5 in them */ + { + .data = {.userdata = 8, .category_mask = ACL_ALLOW_MASK, + .priority = 260}, + .vlan = 0x5, + .vlan_mask = 0x5, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets with VLAN tag 5 */ + { + .data = {.userdata = 9, .category_mask = ACL_DENY_MASK, + .priority = 360}, + .vlan = 0x5, + .vlan_mask = 0xffff, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + +/* VLAN domain */ + /* matches all packets with lower 7 bytes of domain equal to 0x64 */ + { + .data = {.userdata = 10, .category_mask = ACL_ALLOW_MASK, + .priority = 250}, + .domain = 0x64, + .domain_mask = 0x7f, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets with domains that have 0x5 in them */ + { + .data = {.userdata = 11, .category_mask = ACL_ALLOW_MASK, + .priority = 350}, + .domain = 0x5, + .domain_mask = 0x5, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets with domain 5 */ + { + .data = {.userdata = 12, .category_mask = ACL_DENY_MASK, + .priority = 350}, + .domain = 0x5, + .domain_mask = 0xffff, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + +/* destination port */ + /* matches everything with dst port 80 */ + { + .data = {.userdata = 13, .category_mask = ACL_ALLOW_MASK, + .priority = 310}, + .dst_port_low = 80, + .dst_port_high = 80, + .src_port_low = 0, + .src_port_high = 0xffff, + }, + /* matches everything with dst port 22-1023 */ + { + .data = {.userdata = 14, .category_mask = ACL_ALLOW_MASK, + .priority = 210}, + .dst_port_low = 22, + .dst_port_high = 1023, + .src_port_low = 0, + .src_port_high = 0xffff, + }, + /* matches everything with dst port 1020 */ + { + .data = {.userdata = 15, .category_mask = ACL_DENY_MASK, + .priority = 310}, + .dst_port_low = 1020, + .dst_port_high = 1020, + .src_port_low = 0, + .src_port_high = 0xffff, + }, + /* matches everything with dst portrange 1000-2000 */ + { + .data = {.userdata = 16, .category_mask = ACL_DENY_MASK, + .priority = 210}, + .dst_port_low = 1000, + .dst_port_high = 2000, + .src_port_low = 0, + .src_port_high = 0xffff, + }, + +/* source port */ + /* matches everything with src port 80 */ + { + .data = {.userdata = 17, .category_mask = ACL_ALLOW_MASK, + .priority = 320}, + .src_port_low = 80, + .src_port_high = 80, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches everything with src port 22-1023 */ + { + .data = {.userdata = 18, .category_mask = ACL_ALLOW_MASK, + .priority = 220}, + .src_port_low = 22, + .src_port_high = 1023, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches everything with src port 1020 */ + { + .data = {.userdata = 19, .category_mask = ACL_DENY_MASK, + .priority = 320}, + .src_port_low = 1020, + .src_port_high = 1020, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches everything with src portrange 1000-2000 */ + { + .data = {.userdata = 20, .category_mask = ACL_DENY_MASK, + .priority = 220}, + .src_port_low = 1000, + .src_port_high = 2000, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + +/* protocol number */ + /* matches all packets with protocol number either 0x64 or 0xE4 */ + { + .data = {.userdata = 21, .category_mask = ACL_ALLOW_MASK, + .priority = 270}, + .proto = 0x64, + .proto_mask = 0x7f, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets with protocol that have 0x5 in them */ + { + .data = {.userdata = 22, .category_mask = ACL_ALLOW_MASK, + .priority = 1}, + .proto = 0x5, + .proto_mask = 0x5, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + /* matches all packets with protocol 5 */ + { + .data = {.userdata = 23, .category_mask = ACL_DENY_MASK, + .priority = 370}, + .proto = 0x5, + .proto_mask = 0xff, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 0, + .dst_port_high = 0xffff, + }, + +/* rules combining various fields */ + { + .data = {.userdata = 24, .category_mask = ACL_ALLOW_MASK, + .priority = 400}, + /** make sure that unmasked bytes don't fail! */ + .dst_addr = IPv4(1,2,3,4), + .dst_mask_len = 16, + .src_addr = IPv4(5,6,7,8), + .src_mask_len = 24, + .proto = 0x5, + .proto_mask = 0xff, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 22, + .dst_port_high = 1024, + .vlan = 0x8100, + .vlan_mask = 0xffff, + .domain = 0x64, + .domain_mask = 0xffff, + }, + { + .data = {.userdata = 25, .category_mask = ACL_DENY_MASK, + .priority = 400}, + .dst_addr = IPv4(5,6,7,8), + .dst_mask_len = 24, + .src_addr = IPv4(1,2,3,4), + .src_mask_len = 16, + .proto = 0x5, + .proto_mask = 0xff, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 22, + .dst_port_high = 1024, + .vlan = 0x8100, + .vlan_mask = 0xffff, + .domain = 0x64, + .domain_mask = 0xffff, + }, + { + .data = {.userdata = 26, .category_mask = ACL_ALLOW_MASK, + .priority = 500}, + .dst_addr = IPv4(1,2,3,4), + .dst_mask_len = 8, + .src_addr = IPv4(5,6,7,8), + .src_mask_len = 32, + .proto = 0x5, + .proto_mask = 0xff, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 22, + .dst_port_high = 1024, + .vlan = 0x64, + .vlan_mask = 0xffff, + }, + { + .data = {.userdata = 27, .category_mask = ACL_DENY_MASK, + .priority = 500}, + .dst_addr = IPv4(5,6,7,8), + .dst_mask_len = 32, + .src_addr = IPv4(1,2,3,4), + .src_mask_len = 8, + .proto = 0x5, + .proto_mask = 0xff, + .src_port_low = 0, + .src_port_high = 0xffff, + .dst_port_low = 22, + .dst_port_high = 1024, + .vlan = 0x64, + .vlan_mask = 0xffff, + }, +}; + +/* data for ACL unit test */ +struct ipv4_7tuple acl_test_data[] = { +/* testing single rule aspects */ + {.ip_src = IPv4(10,0,0,0), .allow = 4}, /* should match 4 */ + {.ip_src = IPv4(10,1,1,2), .allow = 5}, /* should match 5 */ + {.ip_src = IPv4(10,1,1,1), .allow = 5, + .deny = 6}, /* should match 5, 6 */ + {.ip_dst = IPv4(10,0,0,0)}, /* should not match */ + {.ip_dst = IPv4(10,1,1,2)}, /* should not match */ + {.ip_dst = IPv4(10,1,1,1)}, /* should not match */ + + {.ip_src = IPv4(192,168,2,50)}, /* should not match */ + {.ip_src = IPv4(192,168,1,2)}, /* should not match */ + {.ip_src = IPv4(192,168,1,50)}, /* should not match */ + {.ip_dst = IPv4(192,168,2,50), .allow = 1}, /* should match 1 */ + {.ip_dst = IPv4(192,168,1,49), .allow = 2}, /* should match 2 */ + {.ip_dst = IPv4(192,168,1,50), .allow = 2, + .deny = 3}, /* should match 2, 3 */ + + {.vlan = 0x64, .allow = 7}, /* should match 7 */ + {.vlan = 0xfE4, .allow = 7}, /* should match 7 */ + {.vlan = 0xE2}, /* should not match */ + {.vlan = 0xD, .allow = 8}, /* should match 8 */ + {.vlan = 0x6}, /* should not match */ + {.vlan = 0x5, .allow = 8, .deny = 9}, /* should match 8, 9 */ + + {.domain = 0x64, .allow = 10}, /* should match 10 */ + {.domain = 0xfE4, .allow = 10}, /* should match 10 */ + {.domain = 0xE2}, /* should not match */ + {.domain = 0xD, .allow = 11}, /* should match 11 */ + {.domain = 0x6}, /* should not match */ + {.domain = 0x5, .allow = 11, .deny = 12}, /* should match 11, 12 */ + + {.port_dst = 80, .allow = 13}, /* should match 13 */ + {.port_dst = 79, .allow = 14}, /* should match 14 */ + {.port_dst = 81, .allow = 14}, /* should match 14 */ + {.port_dst = 21}, /* should not match */ + {.port_dst = 1024, .deny = 16}, /* should match 16 */ + {.port_dst = 1020, .allow = 14, .deny = 15}, /* should match 14, 15 */ + + {.port_src = 80, .allow = 17}, /* should match 17 */ + {.port_src = 79, .allow = 18}, /* should match 18 */ + {.port_src = 81, .allow = 18}, /* should match 18 */ + {.port_src = 21}, /* should not match */ + {.port_src = 1024, .deny = 20}, /* should match 20 */ + {.port_src = 1020, .allow = 18, .deny = 19}, /* should match 18, 19 */ + + {.proto = 0x64, .allow = 21}, /* should match 21 */ + {.proto = 0xE4, .allow = 21}, /* should match 21 */ + {.proto = 0xE2}, /* should not match */ + {.proto = 0xD, .allow = 22}, /* should match 22 */ + {.proto = 0x6}, /* should not match */ + {.proto = 0x5, .allow = 22, .deny = 23}, /* should match 22, 23 */ + +/* testing matching multiple rules at once */ + {.vlan = 0x5, .ip_src = IPv4(10,1,1,1), + .allow = 5, .deny = 9}, /* should match 5, 9 */ + {.vlan = 0x5, .ip_src = IPv4(192,168,2,50), + .allow = 8, .deny = 9}, /* should match 8, 9 */ + {.vlan = 0x55, .ip_src = IPv4(192,168,1,49), + .allow = 8}, /* should match 8 */ + {.port_dst = 80, .port_src = 1024, + .allow = 13, .deny = 20}, /* should match 13,20 */ + {.port_dst = 79, .port_src = 1024, + .allow = 14, .deny = 20}, /* should match 14,20 */ + {.proto = 0x5, .ip_dst = IPv4(192,168,2,50), + .allow = 1, .deny = 23}, /* should match 1, 23 */ + + {.proto = 0x5, .ip_dst = IPv4(192,168,1,50), + .allow = 2, .deny = 23}, /* should match 2, 23 */ + {.vlan = 0x64, .domain = 0x5, + .allow = 11, .deny = 12}, /* should match 11, 12 */ + {.proto = 0x5, .port_src = 80, + .allow = 17, .deny = 23}, /* should match 17, 23 */ + {.proto = 0x5, .port_dst = 80, + .allow = 13, .deny = 23}, /* should match 13, 23 */ + {.proto = 0x51, .port_src = 5000}, /* should not match */ + {.ip_src = IPv4(192,168,1,50), + .ip_dst = IPv4(10,0,0,0), + .proto = 0x51, + .port_src = 5000, + .port_dst = 5000}, /* should not match */ + +/* test full packet rules */ + { + .ip_dst = IPv4(1,2,100,200), + .ip_src = IPv4(5,6,7,254), + .proto = 0x5, + .vlan = 0x8100, + .domain = 0x64, + .port_src = 12345, + .port_dst = 80, + .allow = 24, + .deny = 23 + }, /* should match 23, 24 */ + { + .ip_dst = IPv4(5,6,7,254), + .ip_src = IPv4(1,2,100,200), + .proto = 0x5, + .vlan = 0x8100, + .domain = 0x64, + .port_src = 12345, + .port_dst = 80, + .allow = 13, + .deny = 25 + }, /* should match 13, 25 */ + { + .ip_dst = IPv4(1,10,20,30), + .ip_src = IPv4(5,6,7,8), + .proto = 0x5, + .vlan = 0x64, + .port_src = 12345, + .port_dst = 80, + .allow = 26, + .deny = 23 + }, /* should match 23, 26 */ + { + .ip_dst = IPv4(5,6,7,8), + .ip_src = IPv4(1,10,20,30), + .proto = 0x5, + .vlan = 0x64, + .port_src = 12345, + .port_dst = 80, + .allow = 13, + .deny = 27 + }, /* should match 13, 27 */ + { + .ip_dst = IPv4(2,2,3,4), + .ip_src = IPv4(4,6,7,8), + .proto = 0x5, + .vlan = 0x64, + .port_src = 12345, + .port_dst = 80, + .allow = 13, + .deny = 23 + }, /* should match 13, 23 */ + { + .ip_dst = IPv4(1,2,3,4), + .ip_src = IPv4(4,6,7,8), + .proto = 0x5, + .vlan = 0x64, + .port_src = 12345, + .port_dst = 80, + .allow = 13, + .deny = 23 + }, /* should match 13, 23 */ + + +/* visual separator! */ + { + .ip_dst = IPv4(1,2,100,200), + .ip_src = IPv4(5,6,7,254), + .proto = 0x55, + .vlan = 0x8000, + .domain = 0x6464, + .port_src = 12345, + .port_dst = 8080, + .allow = 10 + }, /* should match 10 */ + { + .ip_dst = IPv4(5,6,7,254), + .ip_src = IPv4(1,2,100,200), + .proto = 0x55, + .vlan = 0x8100, + .domain = 0x6464, + .port_src = 12345, + .port_dst = 180, + .allow = 10 + }, /* should match 10 */ + { + .ip_dst = IPv4(1,10,20,30), + .ip_src = IPv4(5,6,7,8), + .proto = 0x55, + .vlan = 0x64, + .port_src = 12345, + .port_dst = 180, + .allow = 7 + }, /* should match 7 */ + { + .ip_dst = IPv4(5,6,7,8), + .ip_src = IPv4(1,10,20,30), + .proto = 0x55, + .vlan = 0x64, + .port_src = 12345, + .port_dst = 180, + .allow = 7 + }, /* should match 7 */ + { + .ip_dst = IPv4(2,2,3,4), + .ip_src = IPv4(4,6,7,8), + .proto = 0x55, + .vlan = 0x64, + .port_src = 12345, + .port_dst = 180, + .allow = 7 + }, /* should match 7 */ + { + .ip_dst = IPv4(1,2,3,4), + .ip_src = IPv4(4,6,7,8), + .proto = 0x50, + .vlan = 0x6466, + .port_src = 12345, + .port_dst = 12345, + }, /* should not match */ +}; + +#endif /* TEST_ACL_H_ */ diff --git a/test/test/test_alarm.c b/test/test/test_alarm.c new file mode 100644 index 0000000000..ecb2f6d457 --- /dev/null +++ b/test/test/test_alarm.c @@ -0,0 +1,256 @@ +/*- + * 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 +#include + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define US_PER_MS 1000 + +#define RTE_TEST_ALARM_TIMEOUT 10 /* ms */ +#define RTE_TEST_CHECK_PERIOD 3 /* ms */ + +static volatile int flag; + +static void +test_alarm_callback(void *cb_arg) +{ + flag = 1; + printf("Callback setting flag - OK. [cb_arg = %p]\n", cb_arg); +} + +static rte_atomic32_t cb_count; + +static void +test_multi_cb(void *arg) +{ + rte_atomic32_inc(&cb_count); + printf("In %s - arg = %p\n", __func__, arg); +} + +static volatile int recursive_error = 0; + +static void +test_remove_in_callback(void *arg) +{ + printf("In %s - arg = %p\n", __func__, arg); + if (rte_eal_alarm_cancel(test_remove_in_callback, arg) || + rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1)) { + printf("Error - cancelling callback from within function succeeded!\n"); + recursive_error = 1; + } + flag = (int)((uintptr_t)arg); +} + +static volatile int flag_2; + +static void +test_remove_in_callback_2(void *arg) +{ + if (rte_eal_alarm_cancel(test_remove_in_callback_2, arg) || rte_eal_alarm_cancel(test_remove_in_callback_2, (void *)-1)) { + printf("Error - cancelling callback of test_remove_in_callback_2\n"); + return; + } + flag_2 = 1; +} + +static int +test_multi_alarms(void) +{ + int rm_count = 0; + cb_count.cnt = 0; + + printf("Expect 6 callbacks in order...\n"); + /* add two alarms in order */ + 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(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(65); + if (cb_count.cnt != 6) { + printf("Missing callbacks\n"); + /* remove any callbacks that might remain */ + rte_eal_alarm_cancel(test_multi_cb, (void *)-1); + return -1; + } + + cb_count.cnt = 0; + printf("Expect only callbacks with args 1 and 3...\n"); + /* Add 3 flags, then delete one */ + 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(35); + if (cb_count.cnt != 2 || rm_count != 1) { + printf("Error: invalid flags count or alarm removal failure" + " - flags value = %d, expected = %d\n", + (int)cb_count.cnt, 2); + /* remove any callbacks that might remain */ + rte_eal_alarm_cancel(test_multi_cb, (void *)-1); + return -1; + } + + 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(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"); + rte_eal_alarm_cancel(test_multi_cb, (void *) -1); + return -1; + } + rm_count = rte_eal_alarm_cancel(test_multi_cb, (void *) -1); + if (rm_count != 3) { + printf("Error removing all pending alarm callbacks\n"); + return -1; + } + + /* Test that we cannot cancel an alarm from within the callback itself + * Also test that we can cancel head-of-line callbacks ok.*/ + flag = 0; + recursive_error = 0; + 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(15); + if (flag != 0) { + printf("Error, cancelling head-of-list leads to premature callback\n"); + return -1; + } + rte_delay_ms(10); + if (flag != 2) { + printf("Error - expected callback not called\n"); + rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1); + return -1; + } + if (recursive_error == 1) + return -1; + + /* 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(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"); + return -1; + } + rm_count = rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1); + if (rm_count != 2) { + printf("Error, cannot cancel all for the same callback\n"); + return -1; + } + + return 0; +} + +static int +test_alarm(void) +{ + int count = 0; + + /* check if the callback will be called */ + printf("check if the callback will be called\n"); + flag = 0; + if (rte_eal_alarm_set(RTE_TEST_ALARM_TIMEOUT * US_PER_MS, + test_alarm_callback, NULL) < 0) { + printf("fail to set alarm callback\n"); + return -1; + } + while (flag == 0 && count ++ < 6) + rte_delay_ms(RTE_TEST_CHECK_PERIOD); + + if (flag == 0){ + printf("Callback not called\n"); + return -1; + } + + /* check if it will fail to set alarm with wrong us value */ + printf("check if it will fail to set alarm with wrong ms values\n"); + if (rte_eal_alarm_set(0, test_alarm_callback, + NULL) >= 0) { + printf("should not be successful with 0 us value\n"); + return -1; + } + if (rte_eal_alarm_set(UINT64_MAX - 1, test_alarm_callback, + NULL) >= 0) { + printf("should not be successful with (UINT64_MAX-1) us value\n"); + return -1; + } + + /* check if it will fail to set alarm with null callback parameter */ + printf("check if it will fail to set alarm with null callback parameter\n"); + if (rte_eal_alarm_set(RTE_TEST_ALARM_TIMEOUT, NULL, NULL) >= 0) { + printf("should not be successful to set alarm with null callback parameter\n"); + return -1; + } + + /* check if it will fail to remove alarm with null callback parameter */ + printf("check if it will fail to remove alarm with null callback parameter\n"); + if (rte_eal_alarm_cancel(NULL, NULL) == 0) { + printf("should not be successful to remove alarm with null callback parameter"); + return -1; + } + + if (test_multi_alarms() != 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(alarm_autotest, test_alarm); diff --git a/test/test/test_atomic.c b/test/test/test_atomic.c new file mode 100644 index 0000000000..b5e7e1b78f --- /dev/null +++ b/test/test/test_atomic.c @@ -0,0 +1,377 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * Atomic Variables + * ================ + * + * - The main test function performs three subtests. The first test + * checks that the usual inc/dec/add/sub functions are working + * correctly: + * + * - Initialize 16-bit, 32-bit and 64-bit atomic variables to specific + * values. + * + * - These variables are incremented and decremented on each core at + * the same time in ``test_atomic_usual()``. + * + * - The function checks that once all lcores finish their function, + * the value of the atomic variables are still the same. + * + * - The second test verifies the behavior of "test and set" functions. + * + * - Initialize 16-bit, 32-bit and 64-bit atomic variables to zero. + * + * - Invoke ``test_atomic_tas()`` on each lcore: before doing anything + * else. The cores are waiting a synchro using ``while + * (rte_atomic32_read(&val) == 0)`` which is triggered by the main test + * function. Then all cores do a + * ``rte_atomicXX_test_and_set()`` at the same time. If it is successful, + * it increments another atomic counter. + * + * - The main function checks that the atomic counter was incremented + * twice only (one for 16-bit, one for 32-bit and one for 64-bit values). + * + * - Test "add/sub and return" + * + * - Initialize 16-bit, 32-bit and 64-bit atomic variables to zero. + * + * - Invoke ``test_atomic_addsub_return()`` on each lcore. Before doing + * anything else, the cores are waiting a synchro. Each lcore does + * this operation several times:: + * + * tmp = rte_atomicXX_add_return(&a, 1); + * atomic_add(&count, tmp); + * tmp = rte_atomicXX_sub_return(&a, 1); + * atomic_sub(&count, tmp+1); + * + * - At the end of the test, the *count* value must be 0. + */ + +#define NUM_ATOMIC_TYPES 3 + +#define N 10000 + +static rte_atomic16_t a16; +static rte_atomic32_t a32; +static rte_atomic64_t a64; +static rte_atomic64_t count; +static rte_atomic32_t synchro; + +static int +test_atomic_usual(__attribute__((unused)) void *arg) +{ + unsigned i; + + while (rte_atomic32_read(&synchro) == 0) + ; + + for (i = 0; i < N; i++) + rte_atomic16_inc(&a16); + for (i = 0; i < N; i++) + rte_atomic16_dec(&a16); + for (i = 0; i < (N / 5); i++) + rte_atomic16_add(&a16, 5); + for (i = 0; i < (N / 5); i++) + rte_atomic16_sub(&a16, 5); + + for (i = 0; i < N; i++) + rte_atomic32_inc(&a32); + for (i = 0; i < N; i++) + rte_atomic32_dec(&a32); + for (i = 0; i < (N / 5); i++) + rte_atomic32_add(&a32, 5); + for (i = 0; i < (N / 5); i++) + rte_atomic32_sub(&a32, 5); + + for (i = 0; i < N; i++) + rte_atomic64_inc(&a64); + for (i = 0; i < N; i++) + rte_atomic64_dec(&a64); + for (i = 0; i < (N / 5); i++) + rte_atomic64_add(&a64, 5); + for (i = 0; i < (N / 5); i++) + rte_atomic64_sub(&a64, 5); + + return 0; +} + +static int +test_atomic_tas(__attribute__((unused)) void *arg) +{ + while (rte_atomic32_read(&synchro) == 0) + ; + + if (rte_atomic16_test_and_set(&a16)) + rte_atomic64_inc(&count); + if (rte_atomic32_test_and_set(&a32)) + rte_atomic64_inc(&count); + if (rte_atomic64_test_and_set(&a64)) + rte_atomic64_inc(&count); + + return 0; +} + +static int +test_atomic_addsub_and_return(__attribute__((unused)) void *arg) +{ + uint32_t tmp16; + uint32_t tmp32; + uint64_t tmp64; + unsigned i; + + while (rte_atomic32_read(&synchro) == 0) + ; + + for (i = 0; i < N; i++) { + tmp16 = rte_atomic16_add_return(&a16, 1); + rte_atomic64_add(&count, tmp16); + + tmp16 = rte_atomic16_sub_return(&a16, 1); + rte_atomic64_sub(&count, tmp16+1); + + tmp32 = rte_atomic32_add_return(&a32, 1); + rte_atomic64_add(&count, tmp32); + + tmp32 = rte_atomic32_sub_return(&a32, 1); + rte_atomic64_sub(&count, tmp32+1); + + tmp64 = rte_atomic64_add_return(&a64, 1); + rte_atomic64_add(&count, tmp64); + + tmp64 = rte_atomic64_sub_return(&a64, 1); + rte_atomic64_sub(&count, tmp64+1); + } + + return 0; +} + +/* + * rte_atomic32_inc_and_test() would increase a 32 bits counter by one and then + * test if that counter is equal to 0. It would return true if the counter is 0 + * and false if the counter is not 0. rte_atomic64_inc_and_test() could do the + * same thing but for a 64 bits counter. + * Here checks that if the 32/64 bits counter is equal to 0 after being atomically + * increased by one. If it is, increase the variable of "count" by one which would + * be checked as the result later. + * + */ +static int +test_atomic_inc_and_test(__attribute__((unused)) void *arg) +{ + while (rte_atomic32_read(&synchro) == 0) + ; + + if (rte_atomic16_inc_and_test(&a16)) { + rte_atomic64_inc(&count); + } + if (rte_atomic32_inc_and_test(&a32)) { + rte_atomic64_inc(&count); + } + if (rte_atomic64_inc_and_test(&a64)) { + rte_atomic64_inc(&count); + } + + return 0; +} + +/* + * rte_atomicXX_dec_and_test() should decrease a 32 bits counter by one and then + * test if that counter is equal to 0. It should return true if the counter is 0 + * and false if the counter is not 0. + * This test checks if the counter is equal to 0 after being atomically + * decreased by one. If it is, increase the value of "count" by one which is to + * be checked as the result later. + */ +static int +test_atomic_dec_and_test(__attribute__((unused)) void *arg) +{ + while (rte_atomic32_read(&synchro) == 0) + ; + + if (rte_atomic16_dec_and_test(&a16)) + rte_atomic64_inc(&count); + + if (rte_atomic32_dec_and_test(&a32)) + rte_atomic64_inc(&count); + + if (rte_atomic64_dec_and_test(&a64)) + rte_atomic64_inc(&count); + + return 0; +} + +static int +test_atomic(void) +{ + rte_atomic16_init(&a16); + rte_atomic32_init(&a32); + rte_atomic64_init(&a64); + rte_atomic64_init(&count); + rte_atomic32_init(&synchro); + + rte_atomic16_set(&a16, 1UL << 10); + rte_atomic32_set(&a32, 1UL << 10); + rte_atomic64_set(&a64, 1ULL << 33); + + printf("usual inc/dec/add/sub functions\n"); + + rte_eal_mp_remote_launch(test_atomic_usual, NULL, SKIP_MASTER); + rte_atomic32_set(&synchro, 1); + rte_eal_mp_wait_lcore(); + rte_atomic32_set(&synchro, 0); + + if (rte_atomic16_read(&a16) != 1UL << 10) { + printf("Atomic16 usual functions failed\n"); + return -1; + } + + if (rte_atomic32_read(&a32) != 1UL << 10) { + printf("Atomic32 usual functions failed\n"); + return -1; + } + + if (rte_atomic64_read(&a64) != 1ULL << 33) { + printf("Atomic64 usual functions failed\n"); + return -1; + } + + printf("test and set\n"); + + rte_atomic64_set(&a64, 0); + rte_atomic32_set(&a32, 0); + rte_atomic16_set(&a16, 0); + rte_atomic64_set(&count, 0); + rte_eal_mp_remote_launch(test_atomic_tas, NULL, SKIP_MASTER); + rte_atomic32_set(&synchro, 1); + rte_eal_mp_wait_lcore(); + rte_atomic32_set(&synchro, 0); + + if (rte_atomic64_read(&count) != NUM_ATOMIC_TYPES) { + printf("Atomic test and set failed\n"); + return -1; + } + + printf("add/sub and return\n"); + + rte_atomic64_set(&a64, 0); + rte_atomic32_set(&a32, 0); + rte_atomic16_set(&a16, 0); + rte_atomic64_set(&count, 0); + rte_eal_mp_remote_launch(test_atomic_addsub_and_return, NULL, + SKIP_MASTER); + rte_atomic32_set(&synchro, 1); + rte_eal_mp_wait_lcore(); + rte_atomic32_set(&synchro, 0); + + if (rte_atomic64_read(&count) != 0) { + printf("Atomic add/sub+return failed\n"); + return -1; + } + + /* + * Set a64, a32 and a16 with the same value of minus "number of slave + * lcores", launch all slave lcores to atomically increase by one and + * test them respectively. + * Each lcore should have only one chance to increase a64 by one and + * then check if it is equal to 0, but there should be only one lcore + * that finds that it is 0. It is similar for a32 and a16. + * Then a variable of "count", initialized to zero, is increased by + * one if a64, a32 or a16 is 0 after being increased and tested + * atomically. + * We can check if "count" is finally equal to 3 to see if all slave + * lcores performed "atomic inc and test" right. + */ + printf("inc and test\n"); + + rte_atomic64_clear(&a64); + rte_atomic32_clear(&a32); + rte_atomic16_clear(&a16); + rte_atomic32_clear(&synchro); + rte_atomic64_clear(&count); + + rte_atomic64_set(&a64, (int64_t)(1 - (int64_t)rte_lcore_count())); + rte_atomic32_set(&a32, (int32_t)(1 - (int32_t)rte_lcore_count())); + rte_atomic16_set(&a16, (int16_t)(1 - (int16_t)rte_lcore_count())); + rte_eal_mp_remote_launch(test_atomic_inc_and_test, NULL, SKIP_MASTER); + rte_atomic32_set(&synchro, 1); + rte_eal_mp_wait_lcore(); + rte_atomic32_clear(&synchro); + + if (rte_atomic64_read(&count) != NUM_ATOMIC_TYPES) { + printf("Atomic inc and test failed %d\n", (int)count.cnt); + return -1; + } + + /* + * Same as above, but this time we set the values to "number of slave + * lcores", and decrement instead of increment. + */ + printf("dec and test\n"); + + rte_atomic32_clear(&synchro); + rte_atomic64_clear(&count); + + rte_atomic64_set(&a64, (int64_t)(rte_lcore_count() - 1)); + rte_atomic32_set(&a32, (int32_t)(rte_lcore_count() - 1)); + rte_atomic16_set(&a16, (int16_t)(rte_lcore_count() - 1)); + rte_eal_mp_remote_launch(test_atomic_dec_and_test, NULL, SKIP_MASTER); + rte_atomic32_set(&synchro, 1); + rte_eal_mp_wait_lcore(); + rte_atomic32_clear(&synchro); + + if (rte_atomic64_read(&count) != NUM_ATOMIC_TYPES) { + printf("Atomic dec and test failed\n"); + return -1; + } + + return 0; +} + +REGISTER_TEST_COMMAND(atomic_autotest, test_atomic); diff --git a/test/test/test_byteorder.c b/test/test/test_byteorder.c new file mode 100644 index 0000000000..8ae311420b --- /dev/null +++ b/test/test/test_byteorder.c @@ -0,0 +1,95 @@ +/*- + * 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 +#include +#include +#include + +#include + +#include "test.h" + +static volatile uint16_t u16 = 0x1337; +static volatile uint32_t u32 = 0xdeadbeefUL; +static volatile uint64_t u64 = 0xdeadcafebabefaceULL; + +/* + * Byteorder functions + * =================== + * + * - check that optimized byte swap functions are working for each + * size (16, 32, 64 bits) + */ + +static int +test_byteorder(void) +{ + uint16_t res_u16; + uint32_t res_u32; + uint64_t res_u64; + + res_u16 = rte_bswap16(u16); + printf("%"PRIx16" -> %"PRIx16"\n", u16, res_u16); + if (res_u16 != 0x3713) + return -1; + + res_u32 = rte_bswap32(u32); + printf("%"PRIx32" -> %"PRIx32"\n", u32, res_u32); + if (res_u32 != 0xefbeaddeUL) + return -1; + + res_u64 = rte_bswap64(u64); + printf("%"PRIx64" -> %"PRIx64"\n", u64, res_u64); + if (res_u64 != 0xcefabebafecaaddeULL) + return -1; + + res_u16 = rte_bswap16(0x1337); + printf("const %"PRIx16" -> %"PRIx16"\n", 0x1337, res_u16); + if (res_u16 != 0x3713) + return -1; + + res_u32 = rte_bswap32(0xdeadbeefUL); + printf("const %"PRIx32" -> %"PRIx32"\n", (uint32_t) 0xdeadbeef, res_u32); + if (res_u32 != 0xefbeaddeUL) + return -1; + + res_u64 = rte_bswap64(0xdeadcafebabefaceULL); + printf("const %"PRIx64" -> %"PRIx64"\n", (uint64_t) 0xdeadcafebabefaceULL, res_u64); + if (res_u64 != 0xcefabebafecaaddeULL) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(byteorder_autotest, test_byteorder); diff --git a/test/test/test_cmdline.c b/test/test/test_cmdline.c new file mode 100644 index 0000000000..38c7256f82 --- /dev/null +++ b/test/test/test_cmdline.c @@ -0,0 +1,92 @@ +/*- + * 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 + +#include "test.h" +#include "test_cmdline.h" + +static int +test_cmdline(void) +{ + printf("Testind parsing ethernet addresses...\n"); + if (test_parse_etheraddr_valid() < 0) + return -1; + if (test_parse_etheraddr_invalid_data() < 0) + return -1; + if (test_parse_etheraddr_invalid_param() < 0) + return -1; + printf("Testind parsing port lists...\n"); + if (test_parse_portlist_valid() < 0) + return -1; + if (test_parse_portlist_invalid_data() < 0) + return -1; + if (test_parse_portlist_invalid_param() < 0) + return -1; + printf("Testind parsing numbers...\n"); + if (test_parse_num_valid() < 0) + return -1; + if (test_parse_num_invalid_data() < 0) + return -1; + if (test_parse_num_invalid_param() < 0) + return -1; + printf("Testing parsing IP addresses...\n"); + if (test_parse_ipaddr_valid() < 0) + return -1; + if (test_parse_ipaddr_invalid_data() < 0) + return -1; + if (test_parse_ipaddr_invalid_param() < 0) + return -1; + printf("Testing parsing strings...\n"); + if (test_parse_string_valid() < 0) + return -1; + if (test_parse_string_invalid_data() < 0) + return -1; + if (test_parse_string_invalid_param() < 0) + return -1; + printf("Testing circular buffer...\n"); + if (test_cirbuf_char() < 0) + return -1; + if (test_cirbuf_string() < 0) + return -1; + if (test_cirbuf_align() < 0) + return -1; + if (test_cirbuf_invalid_param() < 0) + return -1; + printf("Testing library functions...\n"); + if (test_cmdline_lib() < 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(cmdline_autotest, test_cmdline); diff --git a/test/test/test_cmdline.h b/test/test/test_cmdline.h new file mode 100644 index 0000000000..0ee91c1739 --- /dev/null +++ b/test/test/test_cmdline.h @@ -0,0 +1,73 @@ +/*- + * 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 TEST_CMDLINE_H_ +#define TEST_CMDLINE_H_ + +#define CMDLINE_TEST_BUFSIZE 64 + +/* cmdline_parse_num tests */ +int test_parse_num_valid(void); +int test_parse_num_invalid_data(void); +int test_parse_num_invalid_param(void); + +/* cmdline_parse_etheraddr tests */ +int test_parse_etheraddr_valid(void); +int test_parse_etheraddr_invalid_data(void); +int test_parse_etheraddr_invalid_param(void); + +/* cmdline_parse_portlist tests */ +int test_parse_portlist_valid(void); +int test_parse_portlist_invalid_data(void); +int test_parse_portlist_invalid_param(void); + +/* cmdline_parse_ipaddr tests */ +int test_parse_ipaddr_valid(void); +int test_parse_ipaddr_invalid_data(void); +int test_parse_ipaddr_invalid_param(void); + +/* cmdline_parse_string tests */ +int test_parse_string_valid(void); +int test_parse_string_invalid_data(void); +int test_parse_string_invalid_param(void); + +/* cmdline_cirbuf tests */ +int test_cirbuf_invalid_param(void); +int test_cirbuf_char(void); +int test_cirbuf_string(void); +int test_cirbuf_align(void); + +/* test the rest of the library */ +int test_cmdline_lib(void); + +#endif /* TEST_CMDLINE_H_ */ diff --git a/test/test/test_cmdline_cirbuf.c b/test/test/test_cmdline_cirbuf.c new file mode 100644 index 0000000000..87f83cc6d9 --- /dev/null +++ b/test/test/test_cmdline_cirbuf.c @@ -0,0 +1,1330 @@ +/*- + * 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 +#include +#include + +#include + +#include + +#include "test_cmdline.h" + +/* different length strings */ +#define CIRBUF_STR_HEAD " HEAD" +#define CIRBUF_STR_TAIL "TAIL" + +/* miscelaneous tests - they make bullseye happy */ +static int +test_cirbuf_string_misc(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + char tmp[CMDLINE_TEST_BUFSIZE]; + + /* initialize buffers */ + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + + /* + * initialize circular buffer + */ + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* + * add strings to head and tail, but read only tail + * this results in read operation that does not transcend + * from buffer end to buffer beginning (in other words, + * strlen <= cb->maxlen - cb->end) + */ + + /* add string to head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to add string to head!\n"); + return -1; + } + /* add string to tail */ + if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to add string to head!\n"); + return -1; + } + /* read string from tail */ + if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to get string from tail!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) { + printf("Error: tail strings do not match!\n"); + return -1; + } + /* clear buffers */ + memset(tmp, 0, sizeof(tmp)); + memset(buf, 0, sizeof(buf)); + + + + /* + * add a string to buffer when start/end is at end of buffer + */ + + /* + * reinitialize circular buffer with start at the end of cirbuf + */ + if (cirbuf_init(&cb, buf, CMDLINE_TEST_BUFSIZE - 2, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + + /* add string to tail */ + if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to add string to tail!\n"); + return -1; + } + /* read string from tail */ + if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to get string from tail!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) { + printf("Error: tail strings do not match!\n"); + return -1; + } + /* clear tmp buffer */ + memset(tmp, 0, sizeof(tmp)); + + + /* add string to head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to add string to head!\n"); + return -1; + } + /* read string from tail */ + if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to get string from head!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) { + printf("Error: headstrings do not match!\n"); + return -1; + } + + return 0; +} + +/* test adding and deleting strings */ +static int +test_cirbuf_string_add_del(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + char tmp[CMDLINE_TEST_BUFSIZE]; + + /* initialize buffers */ + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + + /* + * initialize circular buffer + */ + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* add string to head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to add string to head!\n"); + return -1; + } + /* read string from head */ + if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to get string from head!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) { + printf("Error: head strings do not match!\n"); + return -1; + } + /* clear tmp buffer */ + memset(tmp, 0, sizeof(tmp)); + /* read string from tail */ + if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to get string from head!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) { + printf("Error: head strings do not match!\n"); + return -1; + } + /* delete string from head*/ + if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_HEAD)) < 0) { + printf("Error: failed to delete string from head!\n"); + return -1; + } + /* verify string was deleted */ + if (cirbuf_del_head_safe(&cb) == 0) { + printf("Error: buffer should have been empty!\n"); + return -1; + } + /* clear tmp buffer */ + memset(tmp, 0, sizeof(tmp)); + + + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* add string to tail */ + if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to add string to tail!\n"); + return -1; + } + /* get string from tail */ + if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to get string from tail!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) { + printf("Error: tail strings do not match!\n"); + return -1; + } + /* clear tmp buffer */ + memset(tmp, 0, sizeof(tmp)); + /* get string from head */ + if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to get string from tail!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) { + printf("Error: tail strings do not match!\n"); + return -1; + } + /* delete string from tail */ + if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL)) < 0) { + printf("Error: failed to delete string from tail!\n"); + return -1; + } + /* verify string was deleted */ + if (cirbuf_del_tail_safe(&cb) == 0) { + printf("Error: buffer should have been empty!\n"); + return -1; + } + + return 0; +} + +/* test adding from head and deleting from tail, and vice versa */ +static int +test_cirbuf_string_add_del_reverse(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + char tmp[CMDLINE_TEST_BUFSIZE]; + + /* initialize buffers */ + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + + /* + * initialize circular buffer + */ + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* add string to head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to add string to head!\n"); + return -1; + } + /* delete string from tail */ + if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_HEAD)) < 0) { + printf("Error: failed to delete string from tail!\n"); + return -1; + } + /* verify string was deleted */ + if (cirbuf_del_tail_safe(&cb) == 0) { + printf("Error: buffer should have been empty!\n"); + return -1; + } + /* clear tmp buffer */ + memset(tmp, 0, sizeof(tmp)); + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* add string to tail */ + if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to add string to tail!\n"); + return -1; + } + /* delete string from head */ + if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_TAIL)) < 0) { + printf("Error: failed to delete string from head!\n"); + return -1; + } + /* verify string was deleted */ + if (cirbuf_del_head_safe(&cb) == 0) { + printf("Error: buffer should have been empty!\n"); + return -1; + } + + return 0; +} + +/* try to write more than available */ +static int +test_cirbuf_string_add_boundaries(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + unsigned i; + + /* initialize buffers */ + memset(buf, 0, sizeof(buf)); + + /* + * initialize circular buffer + */ + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* fill the buffer from tail */ + for (i = 0; i < CMDLINE_TEST_BUFSIZE - sizeof(CIRBUF_STR_TAIL) + 1; i++) + cirbuf_add_tail_safe(&cb, 't'); + + /* try adding a string to tail */ + if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) + > 0) { + printf("Error: buffer should have been full!\n"); + return -1; + } + /* try adding a string to head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) + > 0) { + printf("Error: buffer should have been full!\n"); + return -1; + } + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* fill the buffer from head */ + for (i = 0; i < CMDLINE_TEST_BUFSIZE - sizeof(CIRBUF_STR_HEAD) + 1; i++) + cirbuf_add_head_safe(&cb, 'h'); + + /* try adding a string to head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) + > 0) { + printf("Error: buffer should have been full!\n"); + return -1; + } + /* try adding a string to tail */ + if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) + > 0) { + printf("Error: buffer should have been full!\n"); + return -1; + } + + return 0; +} + +/* try to read/delete more than written */ +static int +test_cirbuf_string_get_del_boundaries(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + char tmp[CMDLINE_TEST_BUFSIZE]; + + /* initialize buffers */ + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + + /* + * initialize circular buffer + */ + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + + /* add string to head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to add string to head!\n"); + return -1; + } + /* read more than written (head) */ + if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) + 1) + != sizeof(CIRBUF_STR_HEAD)) { + printf("Error: unexpected result when reading too much data!\n"); + return -1; + } + /* read more than written (tail) */ + if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) + 1) + != sizeof(CIRBUF_STR_HEAD)) { + printf("Error: unexpected result when reading too much data!\n"); + return -1; + } + /* delete more than written (head) */ + if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_HEAD) + 1) == 0) { + printf("Error: unexpected result when deleting too much data!\n"); + return -1; + } + /* delete more than written (tail) */ + if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_HEAD) + 1) == 0) { + printf("Error: unexpected result when deleting too much data!\n"); + return -1; + } + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* add string to tail */ + if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) + != (sizeof(CIRBUF_STR_TAIL))) { + printf("Error: failed to add string to tail!\n"); + return -1; + } + /* read more than written (tail) */ + if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL) + 1) + != sizeof(CIRBUF_STR_TAIL)) { + printf("Error: unexpected result when reading too much data!\n"); + return -1; + } + /* read more than written (head) */ + if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_TAIL) + 1) + != sizeof(CIRBUF_STR_TAIL)) { + printf("Error: unexpected result when reading too much data!\n"); + return -1; + } + /* delete more than written (tail) */ + if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL) + 1) == 0) { + printf("Error: unexpected result when deleting too much data!\n"); + return -1; + } + /* delete more than written (head) */ + if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL) + 1) == 0) { + printf("Error: unexpected result when deleting too much data!\n"); + return -1; + } + + return 0; +} + +/* try to read/delete less than written */ +static int +test_cirbuf_string_get_del_partial(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + char tmp[CMDLINE_TEST_BUFSIZE]; + char tmp2[CMDLINE_TEST_BUFSIZE]; + + /* initialize buffers */ + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + memset(tmp2, 0, sizeof(tmp)); + + snprintf(tmp2, sizeof(tmp2), "%s", CIRBUF_STR_HEAD); + + /* + * initialize circular buffer + */ + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* add string to head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) + != (sizeof(CIRBUF_STR_HEAD))) { + printf("Error: failed to add string to head!\n"); + return -1; + } + /* read less than written (head) */ + if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1) + != sizeof(CIRBUF_STR_HEAD) - 1) { + printf("Error: unexpected result when reading from head!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, tmp2, sizeof(CIRBUF_STR_HEAD) - 1) != 0) { + printf("Error: strings mismatch!\n"); + return -1; + } + memset(tmp, 0, sizeof(tmp)); + /* read less than written (tail) */ + if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1) + != sizeof(CIRBUF_STR_HEAD) - 1) { + printf("Error: unexpected result when reading from tail!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 1) != 0) { + printf("Error: strings mismatch!\n"); + return -1; + } + + /* + * verify correct deletion + */ + + /* clear buffer */ + memset(tmp, 0, sizeof(tmp)); + + /* delete less than written (head) */ + if (cirbuf_del_buf_head(&cb, 1) != 0) { + printf("Error: delete from head failed!\n"); + return -1; + } + /* read from head */ + if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1) + != sizeof(CIRBUF_STR_HEAD) - 1) { + printf("Error: unexpected result when reading from head!\n"); + return -1; + } + /* since we deleted from head, first char should be deleted */ + if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 1) != 0) { + printf("Error: strings mismatch!\n"); + return -1; + } + /* clear buffer */ + memset(tmp, 0, sizeof(tmp)); + + /* delete less than written (tail) */ + if (cirbuf_del_buf_tail(&cb, 1) != 0) { + printf("Error: delete from tail failed!\n"); + return -1; + } + /* read from tail */ + if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 2) + != sizeof(CIRBUF_STR_HEAD) - 2) { + printf("Error: unexpected result when reading from head!\n"); + return -1; + } + /* since we deleted from tail, last char should be deleted */ + if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 2) != 0) { + printf("Error: strings mismatch!\n"); + return -1; + } + + return 0; +} + +/* test cmdline_cirbuf char add/del functions */ +static int +test_cirbuf_char_add_del(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + char tmp[CMDLINE_TEST_BUFSIZE]; + + /* clear buffer */ + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + + /* + * initialize circular buffer + */ + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* + * try to delete something from cirbuf. since it's empty, + * these should fail. + */ + if (cirbuf_del_head_safe(&cb) == 0) { + printf("Error: deleting from empty cirbuf head succeeded!\n"); + return -1; + } + if (cirbuf_del_tail_safe(&cb) == 0) { + printf("Error: deleting from empty cirbuf tail succeeded!\n"); + return -1; + } + + /* + * add, verify and delete. these should pass. + */ + if (cirbuf_add_head_safe(&cb,'h') < 0) { + printf("Error: adding to cirbuf head failed!\n"); + return -1; + } + if (cirbuf_get_head(&cb) != 'h') { + printf("Error: wrong head content!\n"); + return -1; + } + if (cirbuf_del_head_safe(&cb) < 0) { + printf("Error: deleting from cirbuf head failed!\n"); + return -1; + } + if (cirbuf_add_tail_safe(&cb,'t') < 0) { + printf("Error: adding to cirbuf tail failed!\n"); + return -1; + } + if (cirbuf_get_tail(&cb) != 't') { + printf("Error: wrong tail content!\n"); + return -1; + } + if (cirbuf_del_tail_safe(&cb) < 0) { + printf("Error: deleting from cirbuf tail failed!\n"); + return -1; + } + /* do the same for unsafe versions. those are void. */ + cirbuf_add_head(&cb,'h'); + if (cirbuf_get_head(&cb) != 'h') { + printf("Error: wrong head content!\n"); + return -1; + } + cirbuf_del_head(&cb); + + /* test if char has been deleted. we can't call cirbuf_get_head + * because it's unsafe, but we can call cirbuf_get_buf_head. + */ + if (cirbuf_get_buf_head(&cb, tmp, 1) > 0) { + printf("Error: buffer should have been empty!\n"); + return -1; + } + + cirbuf_add_tail(&cb,'t'); + if (cirbuf_get_tail(&cb) != 't') { + printf("Error: wrong tail content!\n"); + return -1; + } + cirbuf_del_tail(&cb); + + /* test if char has been deleted. we can't call cirbuf_get_tail + * because it's unsafe, but we can call cirbuf_get_buf_tail. + */ + if (cirbuf_get_buf_tail(&cb, tmp, 1) > 0) { + printf("Error: buffer should have been empty!\n"); + return -1; + } + + return 0; +} + +/* test filling up buffer with chars */ +static int +test_cirbuf_char_fill(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + unsigned i; + + /* clear buffer */ + memset(buf, 0, sizeof(buf)); + + /* + * initialize circular buffer + */ + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* + * fill the buffer from head or tail, verify contents, test boundaries + * and clear the buffer + */ + + /* fill the buffer from tail */ + for (i = 0; i < CMDLINE_TEST_BUFSIZE; i++) + cirbuf_add_tail_safe(&cb, 't'); + /* verify that contents of the buffer are what they are supposed to be */ + for (i = 0; i < sizeof(buf); i++) { + if (buf[i] != 't') { + printf("Error: wrong content in buffer!\n"); + return -1; + } + } + /* try to add to a full buffer from tail */ + if (cirbuf_add_tail_safe(&cb, 't') == 0) { + printf("Error: buffer should have been full!\n"); + return -1; + } + /* try to add to a full buffer from head */ + if (cirbuf_add_head_safe(&cb, 'h') == 0) { + printf("Error: buffer should have been full!\n"); + return -1; + } + /* delete buffer from tail */ + for(i = 0; i < CMDLINE_TEST_BUFSIZE; i++) + cirbuf_del_tail_safe(&cb); + /* try to delete from an empty buffer */ + if (cirbuf_del_tail_safe(&cb) >= 0) { + printf("Error: buffer should have been empty!\n"); + return -1; + } + + /* fill the buffer from head */ + for (i = 0; i < CMDLINE_TEST_BUFSIZE; i++) + cirbuf_add_head_safe(&cb, 'h'); + /* verify that contents of the buffer are what they are supposed to be */ + for (i = 0; i < sizeof(buf); i++) { + if (buf[i] != 'h') { + printf("Error: wrong content in buffer!\n"); + return -1; + } + } + /* try to add to a full buffer from head */ + if (cirbuf_add_head_safe(&cb,'h') >= 0) { + printf("Error: buffer should have been full!\n"); + return -1; + } + /* try to add to a full buffer from tail */ + if (cirbuf_add_tail_safe(&cb, 't') == 0) { + printf("Error: buffer should have been full!\n"); + return -1; + } + /* delete buffer from head */ + for(i = 0; i < CMDLINE_TEST_BUFSIZE; i++) + cirbuf_del_head_safe(&cb); + /* try to delete from an empty buffer */ + if (cirbuf_del_head_safe(&cb) >= 0) { + printf("Error: buffer should have been empty!\n"); + return -1; + } + + /* + * fill the buffer from both head and tail, with alternating characters, + * verify contents and clear the buffer + */ + + /* fill half of buffer from tail */ + for (i = 0; i < CMDLINE_TEST_BUFSIZE / 2; i++) + cirbuf_add_tail_safe(&cb, (char) (i % 2 ? 't' : 'T')); + /* fill other half of the buffer from head */ + for (i = 0; i < CMDLINE_TEST_BUFSIZE / 2; i++) + cirbuf_add_head_safe(&cb, (char) (i % 2 ? 'H' : 'h')); /* added in reverse */ + + /* verify that contents of the buffer are what they are supposed to be */ + for (i = 0; i < sizeof(buf) / 2; i++) { + if (buf[i] != (char) (i % 2 ? 't' : 'T')) { + printf("Error: wrong content in buffer at %u!\n", i); + return -1; + } + } + for (i = sizeof(buf) / 2; i < sizeof(buf); i++) { + if (buf[i] != (char) (i % 2 ? 'h' : 'H')) { + printf("Error: wrong content in buffer %u!\n", i); + return -1; + } + } + + return 0; +} + +/* test left alignment */ +static int +test_cirbuf_align_left(void) +{ +#define HALF_OFFSET CMDLINE_TEST_BUFSIZE / 2 +#define SMALL_OFFSET HALF_OFFSET / 2 +/* resulting buffer lengths for each of the test cases */ +#define LEN1 HALF_OFFSET - SMALL_OFFSET - 1 +#define LEN2 HALF_OFFSET + SMALL_OFFSET + 2 +#define LEN3 HALF_OFFSET - SMALL_OFFSET +#define LEN4 HALF_OFFSET + SMALL_OFFSET - 1 + + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + char tmp[CMDLINE_TEST_BUFSIZE]; + unsigned i; + + /* + * align left when start < end and start in left half + */ + + /* + * initialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* push end into left half */ + for (i = 0; i < HALF_OFFSET - 1; i++) + cirbuf_add_tail_safe(&cb, 't'); + + /* push start into left half < end */ + for (i = 0; i < SMALL_OFFSET; i++) + cirbuf_del_head_safe(&cb); + + /* align */ + if (cirbuf_align_left(&cb) < 0) { + printf("Error: alignment failed!\n"); + return -1; + } + + /* verify result */ + if (cb.start != 0 || cb.len != LEN1 || cb.end != cb.len - 1) { + printf("Error: buffer alignment is wrong!\n"); + return -1; + } + + /* + * align left when start > end and start in left half + */ + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* push start into left half */ + for (i = 0; i < HALF_OFFSET + 2; i++) + cirbuf_add_head_safe(&cb, 'h'); + + /* push end into left half > start */ + for (i = 0; i < SMALL_OFFSET; i++) + cirbuf_add_tail_safe(&cb, 't'); + + /* align */ + if (cirbuf_align_left(&cb) < 0) { + printf("Error: alignment failed!\n"); + return -1; + } + + /* verify result */ + if (cb.start != 0 || cb.len != LEN2 || cb.end != cb.len - 1) { + printf("Error: buffer alignment is wrong!"); + return -1; + } + + /* + * align left when start < end and start in right half + */ + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* push start into the right half */ + for (i = 0; i < HALF_OFFSET; i++) + cirbuf_add_head_safe(&cb, 'h'); + + /* push end into left half > start */ + for (i = 0; i < SMALL_OFFSET; i++) + cirbuf_del_tail_safe(&cb); + + /* align */ + if (cirbuf_align_left(&cb) < 0) { + printf("Error: alignment failed!\n"); + return -1; + } + + /* verify result */ + if (cb.start != 0 || cb.len != LEN3 || cb.end != cb.len - 1) { + printf("Error: buffer alignment is wrong!"); + return -1; + } + + /* + * align left when start > end and start in right half + */ + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* push start into the right half */ + for (i = 0; i < HALF_OFFSET - 1; i++) + cirbuf_add_head_safe(&cb, 'h'); + + /* push end into left half < start */ + for (i = 0; i < SMALL_OFFSET; i++) + cirbuf_add_tail_safe(&cb, 't'); + + /* align */ + if (cirbuf_align_left(&cb) < 0) { + printf("Error: alignment failed!\n"); + return -1; + } + + /* verify result */ + if (cb.start != 0 || cb.len != LEN4 || + cb.end != cb.len - 1) { + printf("Error: buffer alignment is wrong!"); + return -1; + } + + /* + * Verify that alignment doesn't corrupt data + */ + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* add string to tail and head */ + if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, + sizeof(CIRBUF_STR_HEAD)) < 0 || cirbuf_add_buf_tail(&cb, + CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) < 0) { + printf("Error: failed to add strings!\n"); + return -1; + } + + /* align */ + if (cirbuf_align_left(&cb) < 0) { + printf("Error: alignment failed!\n"); + return -1; + } + + /* get string from head */ + if (cirbuf_get_buf_head(&cb, tmp, + sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) { + printf("Error: failed to read string from head!\n"); + return -1; + } + + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL, + sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) { + printf("Error: strings mismatch!\n"); + return -1; + } + + /* reset tmp buffer */ + memset(tmp, 0, sizeof(tmp)); + + /* get string from tail */ + if (cirbuf_get_buf_tail(&cb, tmp, + sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) { + printf("Error: failed to read string from head!\n"); + return -1; + } + + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL, + sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) { + printf("Error: strings mismatch!\n"); + return -1; + } + + return 0; +} + +/* test right alignment */ +static int +test_cirbuf_align_right(void) +{ +#define END_OFFSET CMDLINE_TEST_BUFSIZE - 1 + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + char tmp[CMDLINE_TEST_BUFSIZE]; + unsigned i; + + + /* + * align right when start < end and start in left half + */ + + /* + * initialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to initialize circular buffer!\n"); + return -1; + } + + /* push end into left half */ + for (i = 0; i < HALF_OFFSET - 1; i++) + cirbuf_add_tail_safe(&cb, 't'); + + /* push start into left half < end */ + for (i = 0; i < SMALL_OFFSET; i++) + cirbuf_del_head_safe(&cb); + + /* align */ + cirbuf_align_right(&cb); + + /* verify result */ + if (cb.start != END_OFFSET || cb.len != LEN1 || cb.end != cb.len - 2) { + printf("Error: buffer alignment is wrong!\n"); + return -1; + } + + /* + * align right when start > end and start in left half + */ + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* push start into left half */ + for (i = 0; i < HALF_OFFSET + 2; i++) + cirbuf_add_head_safe(&cb, 'h'); + + /* push end into left half > start */ + for (i = 0; i < SMALL_OFFSET; i++) + cirbuf_add_tail_safe(&cb, 't'); + + /* align */ + cirbuf_align_right(&cb); + + /* verify result */ + if (cb.start != END_OFFSET || cb.len != LEN2 || cb.end != cb.len - 2) { + printf("Error: buffer alignment is wrong!"); + return -1; + } + + /* + * align right when start < end and start in right half + */ + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* push start into the right half */ + for (i = 0; i < HALF_OFFSET; i++) + cirbuf_add_head_safe(&cb, 'h'); + + /* push end into left half > start */ + for (i = 0; i < SMALL_OFFSET; i++) + cirbuf_del_tail_safe(&cb); + + /* align */ + cirbuf_align_right(&cb); + + /* verify result */ + if (cb.end != END_OFFSET || cb.len != LEN3 || cb.start != cb.end - cb.len + 1) { + printf("Error: buffer alignment is wrong!"); + return -1; + } + + /* + * align right when start > end and start in right half + */ + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* push start into the right half */ + for (i = 0; i < HALF_OFFSET - 1; i++) + cirbuf_add_head_safe(&cb, 'h'); + + /* push end into left half < start */ + for (i = 0; i < SMALL_OFFSET; i++) + cirbuf_add_tail_safe(&cb, 't'); + + /* align */ + cirbuf_align_right(&cb); + + /* verify result */ + if (cb.end != END_OFFSET || cb.len != LEN4 || cb.start != cb.end - cb.len + 1) { + printf("Error: buffer alignment is wrong!"); + return -1; + } + + /* + * Verify that alignment doesn't corrupt data + */ + + /* + * reinitialize circular buffer + */ + memset(buf, 0, sizeof(buf)); + if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) { + printf("Error: failed to reinitialize circular buffer!\n"); + return -1; + } + + /* add string to tail and head */ + if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, + sizeof(CIRBUF_STR_TAIL)) < 0 || cirbuf_add_buf_head(&cb, + CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) < 0) { + printf("Error: failed to add strings!\n"); + return -1; + } + + /* align */ + if (cirbuf_align_right(&cb) < 0) { + printf("Error: alignment failed!\n"); + return -1; + } + + /* get string from head */ + if (cirbuf_get_buf_head(&cb, tmp, + sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) { + printf("Error: failed to read string from head!\n"); + return -1; + } + + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL, + sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) { + printf("Error: strings mismatch!\n"); + return -1; + } + + /* reset tmp buffer */ + memset(tmp, 0, sizeof(tmp)); + + /* get string from tail */ + if (cirbuf_get_buf_tail(&cb, tmp, + sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) { + printf("Error: failed to read string from head!\n"); + return -1; + } + /* verify string */ + if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL, + sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) { + printf("Error: strings mismatch!\n"); + return -1; + } + + return 0; +} + +/* call functions with invalid parameters */ +int +test_cirbuf_invalid_param(void) +{ + struct cirbuf cb; + char buf[CMDLINE_TEST_BUFSIZE]; + + /* null cirbuf */ + if (cirbuf_init(0, buf, 0, sizeof(buf)) == 0) + return -1; + /* null buffer */ + if (cirbuf_init(&cb, 0, 0, sizeof(buf)) == 0) + return -1; + /* null cirbuf */ + if (cirbuf_add_head_safe(0, 'h') == 0) + return -1; + if (cirbuf_add_tail_safe(0, 't') == 0) + return -1; + if (cirbuf_del_head_safe(0) == 0) + return -1; + if (cirbuf_del_tail_safe(0) == 0) + return -1; + /* null buffer */ + if (cirbuf_add_buf_head(&cb, 0, 0) == 0) + return -1; + if (cirbuf_add_buf_tail(&cb, 0, 0) == 0) + return -1; + /* null cirbuf */ + if (cirbuf_add_buf_head(0, buf, 0) == 0) + return -1; + if (cirbuf_add_buf_tail(0, buf, 0) == 0) + return -1; + /* null size */ + if (cirbuf_add_buf_head(&cb, buf, 0) == 0) + return -1; + if (cirbuf_add_buf_tail(&cb, buf, 0) == 0) + return -1; + /* null cirbuf */ + if (cirbuf_del_buf_head(0, 0) == 0) + return -1; + if (cirbuf_del_buf_tail(0, 0) == 0) + return -1; + /* null size */ + if (cirbuf_del_buf_head(&cb, 0) == 0) + return -1; + if (cirbuf_del_buf_tail(&cb, 0) == 0) + return -1; + /* null cirbuf */ + if (cirbuf_get_buf_head(0, 0, 0) == 0) + return -1; + if (cirbuf_get_buf_tail(0, 0, 0) == 0) + return -1; + /* null buffer */ + if (cirbuf_get_buf_head(&cb, 0, 0) == 0) + return -1; + if (cirbuf_get_buf_tail(&cb, 0, 0) == 0) + return -1; + /* null size, this is valid but should return 0 */ + if (cirbuf_get_buf_head(&cb, buf, 0) != 0) + return -1; + if (cirbuf_get_buf_tail(&cb, buf, 0) != 0) + return -1; + /* null cirbuf */ + if (cirbuf_align_left(0) == 0) + return -1; + if (cirbuf_align_right(0) == 0) + return -1; + + return 0; +} + +/* test cmdline_cirbuf char functions */ +int +test_cirbuf_char(void) +{ + int ret; + + ret = test_cirbuf_char_add_del(); + if (ret < 0) + return -1; + + ret = test_cirbuf_char_fill(); + if (ret < 0) + return -1; + + return 0; +} + +/* test cmdline_cirbuf string functions */ +int +test_cirbuf_string(void) +{ + if (test_cirbuf_string_add_del() < 0) + return -1; + + if (test_cirbuf_string_add_del_reverse() < 0) + return -1; + + if (test_cirbuf_string_add_boundaries() < 0) + return -1; + + if (test_cirbuf_string_get_del_boundaries() < 0) + return -1; + + if (test_cirbuf_string_get_del_partial() < 0) + return -1; + + if (test_cirbuf_string_misc() < 0) + return -1; + + return 0; +} + +/* test cmdline_cirbuf align functions */ +int +test_cirbuf_align(void) +{ + if (test_cirbuf_align_left() < 0) + return -1; + if (test_cirbuf_align_right() < 0) + return -1; + return 0; +} diff --git a/test/test/test_cmdline_etheraddr.c b/test/test/test_cmdline_etheraddr.c new file mode 100644 index 0000000000..e4f42317f2 --- /dev/null +++ b/test/test/test_cmdline_etheraddr.c @@ -0,0 +1,247 @@ +/*- + * 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 +#include +#include + +#include +#include + +#include +#include + +#include "test_cmdline.h" + +struct ether_addr_str { + const char * str; + uint64_t address; +}; + +/* valid strings */ +const struct ether_addr_str ether_addr_valid_strs[] = { + {"01:23:45:67:89:AB", 0xAB8967452301ULL}, + {"4567:89AB:CDEF", 0xEFCDAB896745ULL}, +}; + +/* valid strings with various garbage at the end. + * these strings are still valid because parser checks for + * end of token, which is either space chars, null char or + * a hash sign. + */ +const char * ether_addr_garbage_strs[] = { + "00:11:22:33:44:55\0garbage", + "00:11:22:33:44:55#garbage", + "00:11:22:33:44:55 garbage", + "00:11:22:33:44:55\tgarbage", + "00:11:22:33:44:55\ngarbage", + "00:11:22:33:44:55\rgarbage", + "00:11:22:33:44:55#", + "00:11:22:33:44:55 ", + "00:11:22:33:44:55\t", + "00:11:22:33:44:55\n", + "00:11:22:33:44:55\r", +}; +#define GARBAGE_ETHERADDR 0x554433221100ULL /* corresponding address */ + + +const char * ether_addr_invalid_strs[] = { + /* valid chars, invalid syntax */ + "0123:45:67:89:AB", + "01:23:4567:89:AB", + "01:23:45:67:89AB", + "012:345:678:9AB", + "01:23:45:67:89:ABC", + "01:23:45:67:89:A", + "01:23:45:67:89", + "01:23:45:67:89:AB:CD", + /* invalid chars, valid syntax */ + "IN:VA:LI:DC:HA:RS", + "INVA:LIDC:HARS", + /* misc */ + "01 23 45 67 89 AB", + "01.23.45.67.89.AB", + "01,23,45,67,89,AB", + "01:23:45\0:67:89:AB", + "01:23:45#:67:89:AB", + "random invalid text", + "random text", + "", + "\0", + " ", +}; + +#define ETHERADDR_VALID_STRS_SIZE \ + (sizeof(ether_addr_valid_strs) / sizeof(ether_addr_valid_strs[0])) +#define ETHERADDR_GARBAGE_STRS_SIZE \ + (sizeof(ether_addr_garbage_strs) / sizeof(ether_addr_garbage_strs[0])) +#define ETHERADDR_INVALID_STRS_SIZE \ + (sizeof(ether_addr_invalid_strs) / sizeof(ether_addr_invalid_strs[0])) + + + +static int +is_addr_different(const struct ether_addr addr, uint64_t num) +{ + int i; + for (i = 0; i < ETHER_ADDR_LEN; i++, num >>= 8) + if (addr.addr_bytes[i] != (num & 0xFF)) { + return 1; + } + return 0; +} + +/* test invalid parameters */ +int +test_parse_etheraddr_invalid_param(void) +{ + char buf[CMDLINE_TEST_BUFSIZE]; + struct ether_addr result; + int ret = 0; + + /* try all null */ + ret = cmdline_parse_etheraddr(NULL, NULL, NULL, 0); + if (ret != -1) { + printf("Error: parser accepted null parameters!\n"); + return -1; + } + + /* try null buf */ + ret = cmdline_parse_etheraddr(NULL, NULL, (void*)&result, + sizeof(result)); + if (ret != -1) { + printf("Error: parser accepted null string!\n"); + return -1; + } + + /* try null result */ + + /* copy string to buffer */ + snprintf(buf, sizeof(buf), "%s", + ether_addr_valid_strs[0].str); + + ret = cmdline_parse_etheraddr(NULL, buf, NULL, 0); + if (ret == -1) { + printf("Error: parser rejected null result!\n"); + return -1; + } + + /* token is not used in ether_parse anyway so there's no point in + * testing it */ + + /* test help function */ + memset(&buf, 0, sizeof(buf)); + + /* coverage! */ + ret = cmdline_get_help_etheraddr(NULL, buf, sizeof(buf)); + if (ret < 0) { + printf("Error: help function failed with valid parameters!\n"); + return -1; + } + + return 0; +} + +/* test valid parameters but invalid data */ +int +test_parse_etheraddr_invalid_data(void) +{ + int ret = 0; + unsigned i; + struct ether_addr result; + + /* test full strings */ + for (i = 0; i < ETHERADDR_INVALID_STRS_SIZE; i++) { + + memset(&result, 0, sizeof(struct ether_addr)); + + ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i], + (void*)&result, sizeof(result)); + if (ret != -1) { + printf("Error: parsing %s succeeded!\n", + ether_addr_invalid_strs[i]); + return -1; + } + } + + return 0; +} + +/* test valid parameters and data */ +int +test_parse_etheraddr_valid(void) +{ + int ret = 0; + unsigned i; + struct ether_addr result; + + /* test full strings */ + for (i = 0; i < ETHERADDR_VALID_STRS_SIZE; i++) { + + memset(&result, 0, sizeof(struct ether_addr)); + + ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str, + (void*)&result, sizeof(result)); + if (ret < 0) { + printf("Error: parsing %s failed!\n", + ether_addr_valid_strs[i].str); + return -1; + } + if (is_addr_different(result, ether_addr_valid_strs[i].address)) { + printf("Error: parsing %s failed: address mismatch!\n", + ether_addr_valid_strs[i].str); + return -1; + } + } + + /* test garbage strings */ + for (i = 0; i < ETHERADDR_GARBAGE_STRS_SIZE; i++) { + + memset(&result, 0, sizeof(struct ether_addr)); + + ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i], + (void*)&result, sizeof(result)); + if (ret < 0) { + printf("Error: parsing %s failed!\n", + ether_addr_garbage_strs[i]); + return -1; + } + if (is_addr_different(result, GARBAGE_ETHERADDR)) { + printf("Error: parsing %s failed: address mismatch!\n", + ether_addr_garbage_strs[i]); + return -1; + } + } + + return 0; +} diff --git a/test/test/test_cmdline_ipaddr.c b/test/test/test_cmdline_ipaddr.c new file mode 100644 index 0000000000..471d2ff140 --- /dev/null +++ b/test/test/test_cmdline_ipaddr.c @@ -0,0 +1,722 @@ +/*- + * 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 +#include +#include +#include + +#ifndef __linux__ +#ifndef __FreeBSD__ +#include +#else +#include +#endif +#endif + +#include + +#include +#include + +#include "test_cmdline.h" + +#define IP4(a,b,c,d) {((uint32_t)(((a) & 0xff)) | \ + (((b) & 0xff) << 8) | \ + (((c) & 0xff) << 16) | \ + ((d) & 0xff) << 24)} + +#define U16_SWAP(x) \ + (((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)) + +/* create IPv6 address, swapping bytes where needed */ +#ifndef s6_addr16 +# define s6_addr16 __u6_addr.__u6_addr16 +#endif +#define IP6(a,b,c,d,e,f,g,h) .ipv6 = \ + {.s6_addr16 = \ + {U16_SWAP(a),U16_SWAP(b),U16_SWAP(c),U16_SWAP(d),\ + U16_SWAP(e),U16_SWAP(f),U16_SWAP(g),U16_SWAP(h)}} + +/** these are defined in netinet/in.h but not present in linux headers */ +#ifndef NIPQUAD + +#define NIPQUAD_FMT "%u.%u.%u.%u" +#define NIPQUAD(addr) \ + (unsigned)((unsigned char *)&addr)[0], \ + (unsigned)((unsigned char *)&addr)[1], \ + (unsigned)((unsigned char *)&addr)[2], \ + (unsigned)((unsigned char *)&addr)[3] + +#define NIP6_FMT "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x" +#define NIP6(addr) \ + (unsigned)((addr).s6_addr[0]), \ + (unsigned)((addr).s6_addr[1]), \ + (unsigned)((addr).s6_addr[2]), \ + (unsigned)((addr).s6_addr[3]), \ + (unsigned)((addr).s6_addr[4]), \ + (unsigned)((addr).s6_addr[5]), \ + (unsigned)((addr).s6_addr[6]), \ + (unsigned)((addr).s6_addr[7]), \ + (unsigned)((addr).s6_addr[8]), \ + (unsigned)((addr).s6_addr[9]), \ + (unsigned)((addr).s6_addr[10]), \ + (unsigned)((addr).s6_addr[11]), \ + (unsigned)((addr).s6_addr[12]), \ + (unsigned)((addr).s6_addr[13]), \ + (unsigned)((addr).s6_addr[14]), \ + (unsigned)((addr).s6_addr[15]) + +#endif + + + +struct ipaddr_str { + const char * str; + cmdline_ipaddr_t addr; + unsigned flags; +}; + +const struct ipaddr_str ipaddr_valid_strs[] = { + {"0.0.0.0", {AF_INET, {IP4(0,0,0,0)}, 0}, + CMDLINE_IPADDR_V4}, + {"0.0.0.0/0", {AF_INET, {IP4(0,0,0,0)}, 0}, + CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, + {"0.0.0.0/24", {AF_INET, {IP4(0,0,0,0)}, 24}, + CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, + {"192.168.1.0/24", {AF_INET, {IP4(192,168,1,0)}, 24}, + CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, + {"012.34.56.78/24", {AF_INET, {IP4(12,34,56,78)}, 24}, + CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, + {"34.56.78.90/1", {AF_INET, {IP4(34,56,78,90)}, 1}, + CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK}, + {"::", {AF_INET6, {IP6(0,0,0,0,0,0,0,0)}, 0}, + CMDLINE_IPADDR_V6}, + {"::1", {AF_INET6, {IP6(0,0,0,0,0,0,0,1)}, 0}, + CMDLINE_IPADDR_V6}, + {"::1/32", {AF_INET6, {IP6(0,0,0,0,0,0,0,1)}, 32}, + CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, + {"::/32", {AF_INET6, {IP6(0,0,0,0,0,0,0,0)}, 32}, + CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, + /* RFC5952 requests that only lowercase should be used */ + {"1234:5678:90ab:cdef:4321:8765:BA09:FEDC", {AF_INET6, + {IP6(0x1234,0x5678,0x90AB,0xCDEF,0x4321,0x8765,0xBA09,0xFEDC)}, + 0}, + CMDLINE_IPADDR_V6}, + {"1234::1234/64", {AF_INET6, + {IP6(0x1234,0,0,0,0,0,0,0x1234)}, + 64}, + CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, + {"1234::/64", {AF_INET6, + {IP6(0x1234,0,0,0,0,0,0,0)}, + 64}, + CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, + {"1:1::1/32", {AF_INET6, + {IP6(1,1,0,0,0,0,0,1)}, + 32}, + CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, + {"1:2:3:4::/64", {AF_INET6, + {IP6(1,2,3,4,0,0,0,0)}, + 64}, + CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, + {"::ffff:192.168.1.0/64", {AF_INET6, + {IP6(0,0,0,0,0,0xFFFF,0xC0A8,0x100)}, + 64}, + CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK}, + /* RFC5952 requests not using :: to skip one block of zeros*/ + {"1::2:3:4:5:6:7", {AF_INET6, + {IP6(1,0,2,3,4,5,6,7)}, + 0}, + CMDLINE_IPADDR_V6}, +}; + +const char * ipaddr_garbage_addr4_strs[] = { + /* IPv4 */ + "192.168.1.0 garbage", + "192.168.1.0\0garbage", + "192.168.1.0#garbage", + "192.168.1.0\tgarbage", + "192.168.1.0\rgarbage", + "192.168.1.0\ngarbage", +}; +#define IPv4_GARBAGE_ADDR IP4(192,168,1,0) + +const char * ipaddr_garbage_addr6_strs[] = { + /* IPv6 */ + "1:2:3:4::8 garbage", + "1:2:3:4::8#garbage", + "1:2:3:4::8\0garbage", + "1:2:3:4::8\rgarbage", + "1:2:3:4::8\ngarbage", + "1:2:3:4::8\tgarbage", +}; +#define IPv6_GARBAGE_ADDR {IP6(1,2,3,4,0,0,0,8)} + +const char * ipaddr_garbage_network4_strs[] = { + /* IPv4 */ + "192.168.1.0/24 garbage", + "192.168.1.0/24\0garbage", + "192.168.1.0/24#garbage", + "192.168.1.0/24\tgarbage", + "192.168.1.0/24\rgarbage", + "192.168.1.0/24\ngarbage", +}; +#define IPv4_GARBAGE_PREFIX 24 + +const char * ipaddr_garbage_network6_strs[] = { + /* IPv6 */ + "1:2:3:4::8/64 garbage", + "1:2:3:4::8/64#garbage", + "1:2:3:4::8/64\0garbage", + "1:2:3:4::8/64\rgarbage", + "1:2:3:4::8/64\ngarbage", + "1:2:3:4::8/64\tgarbage", +}; +#define IPv6_GARBAGE_PREFIX 64 + + + +const char * ipaddr_invalid_strs[] = { + /** IPv4 **/ + + /* invalid numbers */ + "0.0.0.-1", + "0.0.-1.0", + "0.-1.0.0", + "-1.0.0.0", + "0.0.0.-1/24", + "256.123.123.123", + "255.256.123.123", + "255.255.256.123", + "255.255.255.256", + "256.123.123.123/24", + "255.256.123.123/24", + "255.255.256.123/24", + "255.255.255.256/24", + /* invalid network mask */ + "1.2.3.4/33", + "1.2.3.4/33231313", + "1.2.3.4/-1", + "1.2.3.4/24/33", + "1.2.3.4/24/-1", + "1.2.3.4/24/", + /* wrong format */ + "1/24" + "/24" + "123.123.123", + "123.123.123.", + "123.123.123.123.", + "123.123.123..123", + "123.123.123.123.123", + ".123.123.123", + ".123.123.123.123", + "123.123.123/24", + "123.123.123./24", + "123.123.123.123./24", + "123.123.123..123/24", + "123.123.123.123.123/24", + ".123.123.123/24", + ".123.123.123.123/24", + /* invalid characters */ + "123.123.123.12F", + "123.123.12F.123", + "123.12F.123.123", + "12F.123.123.123", + "12J.123.123.123", + "123,123,123,123", + "123!123!123!12F", + "123.123.123.123/4F", + + /** IPv6 **/ + + /* wrong format */ + "::fffff", + "ffff:", + "1:2:3:4:5:6:7:192.168.1.1", + "1234:192.168.1.1:ffff::", + "1:2:3:4:5:6:7:890ab", + "1:2:3:4:5:6:7890a:b", + "1:2:3:4:5:67890:a:b", + "1:2:3:4:56789:0:a:b", + "1:2:3:45678:9:0:a:b", + "1:2:34567:8:9:0:a:b", + "1:23456:7:8:9:0:a:b", + "12345:6:7:8:9:0:a:b", + "1:::2", + "1::::2", + "::fffff/64", + "1::2::3", + "1::2::3/64", + ":1:2", + ":1:2/64", + ":1::2", + ":1::2/64", + "1::2:3:4:5:6:7:8/64", + + /* invalid network mask */ + "1:2:3:4:5:6:7:8/129", + "1:2:3:4:5:6:7:8/-1", + + /* invalid characters */ + "a:b:c:d:e:f:g::", + + /** misc **/ + + /* too long */ + "1234:1234:1234:1234:1234:1234:1234:1234:1234:1234:1234" + "random invalid text", + "", + "\0", + " ", +}; + +#define IPADDR_VALID_STRS_SIZE \ + (sizeof(ipaddr_valid_strs) / sizeof(ipaddr_valid_strs[0])) +#define IPADDR_GARBAGE_ADDR4_STRS_SIZE \ + (sizeof(ipaddr_garbage_addr4_strs) / sizeof(ipaddr_garbage_addr4_strs[0])) +#define IPADDR_GARBAGE_ADDR6_STRS_SIZE \ + (sizeof(ipaddr_garbage_addr6_strs) / sizeof(ipaddr_garbage_addr6_strs[0])) +#define IPADDR_GARBAGE_NETWORK4_STRS_SIZE \ + (sizeof(ipaddr_garbage_network4_strs) / sizeof(ipaddr_garbage_network4_strs[0])) +#define IPADDR_GARBAGE_NETWORK6_STRS_SIZE \ + (sizeof(ipaddr_garbage_network6_strs) / sizeof(ipaddr_garbage_network6_strs[0])) +#define IPADDR_INVALID_STRS_SIZE \ + (sizeof(ipaddr_invalid_strs) / sizeof(ipaddr_invalid_strs[0])) + +static void +dump_addr(cmdline_ipaddr_t addr) +{ + switch (addr.family) { + case AF_INET: + { + printf(NIPQUAD_FMT " prefixlen=%u\n", + NIPQUAD(addr.addr.ipv4.s_addr), addr.prefixlen); + break; + } + case AF_INET6: + { + printf(NIP6_FMT " prefixlen=%u\n", + NIP6(addr.addr.ipv6), addr.prefixlen); + break; + } + default: + printf("Can't dump: unknown address family.\n"); + return; + } +} + + +static int +is_addr_different(cmdline_ipaddr_t addr1, cmdline_ipaddr_t addr2) +{ + if (addr1.family != addr2.family) + return 1; + + if (addr1.prefixlen != addr2.prefixlen) + return 1; + + switch (addr1.family) { + /* IPv4 */ + case AF_INET: + if (memcmp(&addr1.addr.ipv4, &addr2.addr.ipv4, + sizeof(struct in_addr)) != 0) + return 1; + break; + /* IPv6 */ + case AF_INET6: + { + if (memcmp(&addr1.addr.ipv6, &addr2.addr.ipv6, + sizeof(struct in6_addr)) != 0) + return 1; + break; + } + /* thing that should not be */ + default: + return -1; + } + return 0; +} + +static int +can_parse_addr(unsigned addr_flags, unsigned test_flags) +{ + if ((test_flags & addr_flags) == addr_flags) { + /* if we are not trying to parse network addresses */ + if (test_flags < CMDLINE_IPADDR_NETWORK) + return 1; + /* if this is a network address */ + else if (addr_flags & CMDLINE_IPADDR_NETWORK) + return 1; + } + return 0; +} + +int +test_parse_ipaddr_valid(void) +{ + cmdline_parse_token_ipaddr_t token; + char buf[CMDLINE_TEST_BUFSIZE]; + cmdline_ipaddr_t result; + unsigned i; + uint8_t flags; + int ret; + + /* cover all cases in help */ + for (flags = 0x1; flags < 0x8; flags++) { + token.ipaddr_data.flags = flags; + + memset(buf, 0, sizeof(buf)); + + if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)) == -1) { + printf("Error: help rejected valid parameters!\n"); + return -1; + } + } + + /* test valid strings */ + for (i = 0; i < IPADDR_VALID_STRS_SIZE; i++) { + + /* test each valid string against different flags */ + for (flags = 1; flags < 0x8; flags++) { + + /* skip bad flag */ + if (flags == CMDLINE_IPADDR_NETWORK) + continue; + + /* clear out everything */ + memset(buf, 0, sizeof(buf)); + memset(&result, 0, sizeof(result)); + memset(&token, 0, sizeof(token)); + + token.ipaddr_data.flags = flags; + + cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + ipaddr_valid_strs[i].str, (void*)&result, + sizeof(result)); + + /* if should have passed, or should have failed */ + if ((ret < 0) == + (can_parse_addr(ipaddr_valid_strs[i].flags, flags))) { + printf("Error: unexpected behavior when parsing %s as %s!\n", + ipaddr_valid_strs[i].str, buf); + printf("Parsed result: "); + dump_addr(result); + printf("Expected result: "); + dump_addr(ipaddr_valid_strs[i].addr); + return -1; + } + if (ret != -1 && + is_addr_different(result, ipaddr_valid_strs[i].addr)) { + printf("Error: result mismatch when parsing %s as %s!\n", + ipaddr_valid_strs[i].str, buf); + printf("Parsed result: "); + dump_addr(result); + printf("Expected result: "); + dump_addr(ipaddr_valid_strs[i].addr); + return -1; + } + } + } + + /* test garbage ipv4 address strings */ + for (i = 0; i < IPADDR_GARBAGE_ADDR4_STRS_SIZE; i++) { + + struct in_addr tmp = IPv4_GARBAGE_ADDR; + + /* test each valid string against different flags */ + for (flags = 1; flags < 0x8; flags++) { + + /* skip bad flag */ + if (flags == CMDLINE_IPADDR_NETWORK) + continue; + + /* clear out everything */ + memset(buf, 0, sizeof(buf)); + memset(&result, 0, sizeof(result)); + memset(&token, 0, sizeof(token)); + + token.ipaddr_data.flags = flags; + + cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + ipaddr_garbage_addr4_strs[i], (void*)&result, + sizeof(result)); + + /* if should have passed, or should have failed */ + if ((ret < 0) == + (can_parse_addr(CMDLINE_IPADDR_V4, flags))) { + printf("Error: unexpected behavior when parsing %s as %s!\n", + ipaddr_garbage_addr4_strs[i], buf); + return -1; + } + if (ret != -1 && + memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) { + printf("Error: result mismatch when parsing %s as %s!\n", + ipaddr_garbage_addr4_strs[i], buf); + return -1; + } + } + } + + /* test garbage ipv6 address strings */ + for (i = 0; i < IPADDR_GARBAGE_ADDR6_STRS_SIZE; i++) { + + cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR}; + + /* test each valid string against different flags */ + for (flags = 1; flags < 0x8; flags++) { + + /* skip bad flag */ + if (flags == CMDLINE_IPADDR_NETWORK) + continue; + + /* clear out everything */ + memset(buf, 0, sizeof(buf)); + memset(&result, 0, sizeof(result)); + memset(&token, 0, sizeof(token)); + + token.ipaddr_data.flags = flags; + + cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + ipaddr_garbage_addr6_strs[i], (void*)&result, + sizeof(result)); + + /* if should have passed, or should have failed */ + if ((ret < 0) == + (can_parse_addr(CMDLINE_IPADDR_V6, flags))) { + printf("Error: unexpected behavior when parsing %s as %s!\n", + ipaddr_garbage_addr6_strs[i], buf); + return -1; + } + if (ret != -1 && + memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) { + printf("Error: result mismatch when parsing %s as %s!\n", + ipaddr_garbage_addr6_strs[i], buf); + return -1; + } + } + } + + + /* test garbage ipv4 network strings */ + for (i = 0; i < IPADDR_GARBAGE_NETWORK4_STRS_SIZE; i++) { + + struct in_addr tmp = IPv4_GARBAGE_ADDR; + + /* test each valid string against different flags */ + for (flags = 1; flags < 0x8; flags++) { + + /* skip bad flag */ + if (flags == CMDLINE_IPADDR_NETWORK) + continue; + + /* clear out everything */ + memset(buf, 0, sizeof(buf)); + memset(&result, 0, sizeof(result)); + memset(&token, 0, sizeof(token)); + + token.ipaddr_data.flags = flags; + + cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + ipaddr_garbage_network4_strs[i], (void*)&result, + sizeof(result)); + + /* if should have passed, or should have failed */ + if ((ret < 0) == + (can_parse_addr(CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK, flags))) { + printf("Error: unexpected behavior when parsing %s as %s!\n", + ipaddr_garbage_network4_strs[i], buf); + return -1; + } + if (ret != -1 && + memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) { + printf("Error: result mismatch when parsing %s as %s!\n", + ipaddr_garbage_network4_strs[i], buf); + return -1; + } + } + } + + /* test garbage ipv6 address strings */ + for (i = 0; i < IPADDR_GARBAGE_NETWORK6_STRS_SIZE; i++) { + + cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR}; + + /* test each valid string against different flags */ + for (flags = 1; flags < 0x8; flags++) { + + /* skip bad flag */ + if (flags == CMDLINE_IPADDR_NETWORK) + continue; + + /* clear out everything */ + memset(buf, 0, sizeof(buf)); + memset(&result, 0, sizeof(result)); + memset(&token, 0, sizeof(token)); + + token.ipaddr_data.flags = flags; + + cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + ipaddr_garbage_network6_strs[i], (void*)&result, + sizeof(result)); + + /* if should have passed, or should have failed */ + if ((ret < 0) == + (can_parse_addr(CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK, flags))) { + printf("Error: unexpected behavior when parsing %s as %s!\n", + ipaddr_garbage_network6_strs[i], buf); + return -1; + } + if (ret != -1 && + memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) { + printf("Error: result mismatch when parsing %s as %s!\n", + ipaddr_garbage_network6_strs[i], buf); + return -1; + } + } + } + + return 0; +} + +int +test_parse_ipaddr_invalid_data(void) +{ + cmdline_parse_token_ipaddr_t token; + char buf[CMDLINE_TEST_BUFSIZE]; + cmdline_ipaddr_t result; + unsigned i; + uint8_t flags; + int ret; + + memset(&result, 0, sizeof(result)); + + /* test invalid strings */ + for (i = 0; i < IPADDR_INVALID_STRS_SIZE; i++) { + + /* test each valid string against different flags */ + for (flags = 1; flags < 0x8; flags++) { + + /* skip bad flag */ + if (flags == CMDLINE_IPADDR_NETWORK) + continue; + + /* clear out everything */ + memset(buf, 0, sizeof(buf)); + memset(&token, 0, sizeof(token)); + + token.ipaddr_data.flags = flags; + + cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + ipaddr_invalid_strs[i], (void*)&result, + sizeof(result)); + + if (ret != -1) { + printf("Error: parsing %s as %s succeeded!\n", + ipaddr_invalid_strs[i], buf); + printf("Parsed result: "); + dump_addr(result); + return -1; + } + } + } + + return 0; +} + +int +test_parse_ipaddr_invalid_param(void) +{ + cmdline_parse_token_ipaddr_t token; + char buf[CMDLINE_TEST_BUFSIZE]; + cmdline_ipaddr_t result; + + snprintf(buf, sizeof(buf), "1.2.3.4"); + token.ipaddr_data.flags = CMDLINE_IPADDR_V4; + + /* null token */ + if (cmdline_parse_ipaddr(NULL, buf, (void*)&result, + sizeof(result)) != -1) { + printf("Error: parser accepted invalid parameters!\n"); + return -1; + } + /* null buffer */ + if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + NULL, (void*)&result, sizeof(result)) != -1) { + printf("Error: parser accepted invalid parameters!\n"); + return -1; + } + /* empty buffer */ + if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + "", (void*)&result, sizeof(result)) != -1) { + printf("Error: parser accepted invalid parameters!\n"); + return -1; + } + /* null result */ + if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token, + buf, NULL, 0) == -1) { + printf("Error: parser rejected null result!\n"); + return -1; + } + + /* null token */ + if (cmdline_get_help_ipaddr(NULL, buf, 0) != -1) { + printf("Error: help accepted invalid parameters!\n"); + return -1; + } + /* null buffer */ + if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token, + NULL, 0) != -1) { + printf("Error: help accepted invalid parameters!\n"); + return -1; + } + return 0; +} diff --git a/test/test/test_cmdline_lib.c b/test/test/test_cmdline_lib.c new file mode 100644 index 0000000000..65b823a726 --- /dev/null +++ b/test/test/test_cmdline_lib.c @@ -0,0 +1,263 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "test_cmdline.h" + +/****************************************************************/ +/* static functions required for some tests */ +static void +valid_buffer(__attribute__((unused))struct rdline *rdl, + __attribute__((unused))const char *buf, + __attribute__((unused)) unsigned int size) +{ +} + +static int +complete_buffer(__attribute__((unused)) struct rdline *rdl, + __attribute__((unused)) const char *buf, + __attribute__((unused)) char *dstbuf, + __attribute__((unused)) unsigned int dstsize, + __attribute__((unused)) int *state) +{ + return 0; +} + +/****************************************************************/ + +static int +test_cmdline_parse_fns(void) +{ + struct cmdline cl; + int i = 0; + char dst[CMDLINE_TEST_BUFSIZE]; + + if (cmdline_parse(NULL, "buffer") >= 0) + goto error; + if (cmdline_parse(&cl, NULL) >= 0) + goto error; + + if (cmdline_complete(NULL, "buffer", &i, dst, sizeof(dst)) >= 0) + goto error; + if (cmdline_complete(&cl, NULL, &i, dst, sizeof(dst)) >= 0) + goto error; + if (cmdline_complete(&cl, "buffer", NULL, dst, sizeof(dst)) >= 0) + goto error; + if (cmdline_complete(&cl, "buffer", &i, NULL, sizeof(dst)) >= 0) + goto error; + + return 0; + +error: + printf("Error: function accepted null parameter!\n"); + return -1; +} + +static int +test_cmdline_rdline_fns(void) +{ + struct rdline rdl; + rdline_write_char_t *wc = &cmdline_write_char; + rdline_validate_t *v = &valid_buffer; + rdline_complete_t *c = &complete_buffer; + + if (rdline_init(NULL, wc, v, c) >= 0) + goto error; + if (rdline_init(&rdl, NULL, v, c) >= 0) + goto error; + if (rdline_init(&rdl, wc, NULL, c) >= 0) + goto error; + if (rdline_init(&rdl, wc, v, NULL) >= 0) + goto error; + if (rdline_char_in(NULL, 0) >= 0) + goto error; + if (rdline_get_buffer(NULL) != NULL) + goto error; + if (rdline_add_history(NULL, "history") >= 0) + goto error; + if (rdline_add_history(&rdl, NULL) >= 0) + goto error; + if (rdline_get_history_item(NULL, 0) != NULL) + goto error; + + /* void functions */ + rdline_newline(NULL, "prompt"); + rdline_newline(&rdl, NULL); + rdline_stop(NULL); + rdline_quit(NULL); + rdline_restart(NULL); + rdline_redisplay(NULL); + rdline_reset(NULL); + rdline_clear_history(NULL); + + return 0; + +error: + printf("Error: function accepted null parameter!\n"); + return -1; +} + +static int +test_cmdline_vt100_fns(void) +{ + if (vt100_parser(NULL, 0) >= 0) { + printf("Error: function accepted null parameter!\n"); + return -1; + } + + /* void functions */ + vt100_init(NULL); + + return 0; +} + +static int +test_cmdline_socket_fns(void) +{ + cmdline_parse_ctx_t ctx; + + if (cmdline_stdin_new(NULL, "prompt") != NULL) + goto error; + if (cmdline_stdin_new(&ctx, NULL) != NULL) + goto error; + if (cmdline_file_new(NULL, "prompt", "/dev/null") != NULL) + goto error; + if (cmdline_file_new(&ctx, NULL, "/dev/null") != NULL) + goto error; + if (cmdline_file_new(&ctx, "prompt", NULL) != NULL) + goto error; + if (cmdline_file_new(&ctx, "prompt", "-/invalid/~/path") != NULL) { + printf("Error: succeeded in opening invalid file for reading!"); + return -1; + } + if (cmdline_file_new(&ctx, "prompt", "/dev/null") == NULL) { + printf("Error: failed to open /dev/null for reading!"); + return -1; + } + + /* void functions */ + cmdline_stdin_exit(NULL); + + return 0; +error: + printf("Error: function accepted null parameter!\n"); + return -1; +} + +static int +test_cmdline_fns(void) +{ + cmdline_parse_ctx_t ctx; + struct cmdline cl, *tmp; + + memset(&ctx, 0, sizeof(ctx)); + tmp = cmdline_new(&ctx, "test", -1, -1); + if (tmp == NULL) + goto error; + + if (cmdline_new(NULL, "prompt", 0, 0) != NULL) + goto error; + if (cmdline_new(&ctx, NULL, 0, 0) != NULL) + goto error; + if (cmdline_in(NULL, "buffer", CMDLINE_TEST_BUFSIZE) >= 0) + goto error; + if (cmdline_in(&cl, NULL, CMDLINE_TEST_BUFSIZE) >= 0) + goto error; + if (cmdline_write_char(NULL, 0) >= 0) + goto error; + + /* void functions */ + cmdline_set_prompt(NULL, "prompt"); + cmdline_free(NULL); + cmdline_printf(NULL, "format"); + /* this should fail as stream handles are invalid */ + cmdline_printf(tmp, "format"); + cmdline_interact(NULL); + cmdline_quit(NULL); + + /* check if void calls change anything when they should fail */ + cl = *tmp; + + cmdline_printf(&cl, NULL); + if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch; + cmdline_set_prompt(&cl, NULL); + if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch; + cmdline_in(&cl, NULL, CMDLINE_TEST_BUFSIZE); + if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch; + + cmdline_free(tmp); + + return 0; + +error: + printf("Error: function accepted null parameter!\n"); + return -1; +mismatch: + printf("Error: data changed!\n"); + return -1; +} + +/* test library functions. the point of these tests is not so much to test + * functions' behaviour as it is to make sure there are no segfaults if + * they are called with invalid parameters. + */ +int +test_cmdline_lib(void) +{ + if (test_cmdline_parse_fns() < 0) + return -1; + if (test_cmdline_rdline_fns() < 0) + return -1; + if (test_cmdline_vt100_fns() < 0) + return -1; + if (test_cmdline_socket_fns() < 0) + return -1; + if (test_cmdline_fns() < 0) + return -1; + return 0; +} diff --git a/test/test/test_cmdline_num.c b/test/test/test_cmdline_num.c new file mode 100644 index 0000000000..04263d39e9 --- /dev/null +++ b/test/test/test_cmdline_num.c @@ -0,0 +1,622 @@ +/*- + * 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 +#include +#include + +#include + +#include +#include + +#include "test_cmdline.h" + +struct num_unsigned_str { + const char * str; + uint64_t result; +}; + +struct num_signed_str { + const char * str; + int64_t result; +}; + +const struct num_unsigned_str num_valid_positive_strs[] = { + /* decimal positive */ + {"0", 0 }, + {"127", INT8_MAX }, + {"128", INT8_MAX + 1 }, + {"255", UINT8_MAX }, + {"256", UINT8_MAX + 1 }, + {"32767", INT16_MAX }, + {"32768", INT16_MAX + 1 }, + {"65535", UINT16_MAX }, + {"65536", UINT16_MAX + 1 }, + {"2147483647", INT32_MAX }, + {"2147483648", INT32_MAX + 1U }, + {"4294967295", UINT32_MAX }, + {"4294967296", UINT32_MAX + 1ULL }, + {"9223372036854775807", INT64_MAX }, + {"9223372036854775808", INT64_MAX + 1ULL}, + {"18446744073709551615", UINT64_MAX }, + /* hexadecimal (no leading zeroes) */ + {"0x0", 0 }, + {"0x7F", INT8_MAX }, + {"0x80", INT8_MAX + 1 }, + {"0xFF", UINT8_MAX }, + {"0x100", UINT8_MAX + 1 }, + {"0x7FFF", INT16_MAX }, + {"0x8000", INT16_MAX + 1 }, + {"0xFFFF", UINT16_MAX }, + {"0x10000", UINT16_MAX + 1 }, + {"0x7FFFFFFF", INT32_MAX }, + {"0x80000000", INT32_MAX + 1U }, + {"0xFFFFFFFF", UINT32_MAX }, + {"0x100000000", UINT32_MAX + 1ULL }, + {"0x7FFFFFFFFFFFFFFF", INT64_MAX }, + {"0x8000000000000000", INT64_MAX + 1ULL}, + {"0xFFFFFFFFFFFFFFFF", UINT64_MAX }, + /* hexadecimal (with leading zeroes) */ + {"0x00", 0 }, + {"0x7F", INT8_MAX }, + {"0x80", INT8_MAX + 1 }, + {"0xFF", UINT8_MAX }, + {"0x0100", UINT8_MAX + 1 }, + {"0x7FFF", INT16_MAX }, + {"0x8000", INT16_MAX + 1 }, + {"0xFFFF", UINT16_MAX }, + {"0x00010000", UINT16_MAX + 1 }, + {"0x7FFFFFFF", INT32_MAX }, + {"0x80000000", INT32_MAX + 1U }, + {"0xFFFFFFFF", UINT32_MAX }, + {"0x0000000100000000", UINT32_MAX + 1ULL }, + {"0x7FFFFFFFFFFFFFFF", INT64_MAX }, + {"0x8000000000000000", INT64_MAX + 1ULL}, + {"0xFFFFFFFFFFFFFFFF", UINT64_MAX }, + /* check all characters */ + {"0x1234567890ABCDEF", 0x1234567890ABCDEFULL }, + {"0x1234567890abcdef", 0x1234567890ABCDEFULL }, + /* binary (no leading zeroes) */ + {"0b0", 0 }, + {"0b1111111", INT8_MAX }, + {"0b10000000", INT8_MAX + 1 }, + {"0b11111111", UINT8_MAX }, + {"0b100000000", UINT8_MAX + 1 }, + {"0b111111111111111", INT16_MAX }, + {"0b1000000000000000", INT16_MAX + 1 }, + {"0b1111111111111111", UINT16_MAX }, + {"0b10000000000000000", UINT16_MAX + 1 }, + {"0b1111111111111111111111111111111", INT32_MAX }, + {"0b10000000000000000000000000000000", INT32_MAX + 1U }, + {"0b11111111111111111111111111111111", UINT32_MAX }, + {"0b100000000000000000000000000000000", UINT32_MAX + 1ULL }, + {"0b111111111111111111111111111111111111111111111111111111111111111", + INT64_MAX }, + {"0b1000000000000000000000000000000000000000000000000000000000000000", + INT64_MAX + 1ULL}, + {"0b1111111111111111111111111111111111111111111111111111111111111111", + UINT64_MAX }, + /* binary (with leading zeroes) */ + {"0b01111111", INT8_MAX }, + {"0b0000000100000000", UINT8_MAX + 1 }, + {"0b0111111111111111", INT16_MAX }, + {"0b00000000000000010000000000000000", UINT16_MAX + 1 }, + {"0b01111111111111111111111111111111", INT32_MAX }, + {"0b0000000000000000000000000000000100000000000000000000000000000000", + UINT32_MAX + 1ULL }, + {"0b0111111111111111111111111111111111111111111111111111111111111111", + INT64_MAX }, + /* octal */ + {"00", 0 }, + {"0177", INT8_MAX }, + {"0200", INT8_MAX + 1 }, + {"0377", UINT8_MAX }, + {"0400", UINT8_MAX + 1 }, + {"077777", INT16_MAX }, + {"0100000", INT16_MAX + 1 }, + {"0177777", UINT16_MAX }, + {"0200000", UINT16_MAX + 1 }, + {"017777777777", INT32_MAX }, + {"020000000000", INT32_MAX + 1U }, + {"037777777777", UINT32_MAX }, + {"040000000000", UINT32_MAX + 1ULL }, + {"0777777777777777777777", INT64_MAX }, + {"01000000000000000000000", INT64_MAX + 1ULL}, + {"01777777777777777777777", UINT64_MAX }, + /* check all numbers */ + {"012345670", 012345670 }, + {"076543210", 076543210 }, +}; + +const struct num_signed_str num_valid_negative_strs[] = { + /* deciman negative */ + {"-128", INT8_MIN }, + {"-129", INT8_MIN - 1 }, + {"-32768", INT16_MIN }, + {"-32769", INT16_MIN - 1 }, + {"-2147483648", INT32_MIN }, + {"-2147483649", INT32_MIN - 1LL }, + {"-9223372036854775808", INT64_MIN }, +}; + +const struct num_unsigned_str num_garbage_positive_strs[] = { + /* valid strings with garbage on the end, should still be valid */ + /* decimal */ + {"9223372036854775807\0garbage", INT64_MAX }, + {"9223372036854775807\tgarbage", INT64_MAX }, + {"9223372036854775807\rgarbage", INT64_MAX }, + {"9223372036854775807\ngarbage", INT64_MAX }, + {"9223372036854775807#garbage", INT64_MAX }, + {"9223372036854775807 garbage", INT64_MAX }, + /* hex */ + {"0x7FFFFFFFFFFFFFFF\0garbage", INT64_MAX }, + {"0x7FFFFFFFFFFFFFFF\tgarbage", INT64_MAX }, + {"0x7FFFFFFFFFFFFFFF\rgarbage", INT64_MAX }, + {"0x7FFFFFFFFFFFFFFF\ngarbage", INT64_MAX }, + {"0x7FFFFFFFFFFFFFFF#garbage", INT64_MAX }, + {"0x7FFFFFFFFFFFFFFF garbage", INT64_MAX }, + /* binary */ + {"0b1111111111111111111111111111111\0garbage", INT32_MAX }, + {"0b1111111111111111111111111111111\rgarbage", INT32_MAX }, + {"0b1111111111111111111111111111111\tgarbage", INT32_MAX }, + {"0b1111111111111111111111111111111\ngarbage", INT32_MAX }, + {"0b1111111111111111111111111111111#garbage", INT32_MAX }, + {"0b1111111111111111111111111111111 garbage", INT32_MAX }, + /* octal */ + {"01777777777777777777777\0garbage", UINT64_MAX }, + {"01777777777777777777777\rgarbage", UINT64_MAX }, + {"01777777777777777777777\tgarbage", UINT64_MAX }, + {"01777777777777777777777\ngarbage", UINT64_MAX }, + {"01777777777777777777777#garbage", UINT64_MAX }, + {"01777777777777777777777 garbage", UINT64_MAX }, +}; + +const struct num_signed_str num_garbage_negative_strs[] = { + /* valid strings with garbage on the end, should still be valid */ + {"-9223372036854775808\0garbage", INT64_MIN }, + {"-9223372036854775808\rgarbage", INT64_MIN }, + {"-9223372036854775808\tgarbage", INT64_MIN }, + {"-9223372036854775808\ngarbage", INT64_MIN }, + {"-9223372036854775808#garbage", INT64_MIN }, + {"-9223372036854775808 garbage", INT64_MIN }, +}; + +const char * num_invalid_strs[] = { + "18446744073709551616", /* out of range unsigned */ + "-9223372036854775809", /* out of range negative signed */ + "0x10000000000000000", /* out of range hex */ + /* out of range binary */ + "0b10000000000000000000000000000000000000000000000000000000000000000", + "020000000000000000000000", /* out of range octal */ + /* wrong chars */ + "0123456239", + "0x1234580AGE", + "0b0111010101g001", + "0b01110101017001", + /* false negative numbers */ + "-12345F623", + "-0x1234580A", + "-0b0111010101", + /* too long (128+ chars) */ + "0b1111000011110000111100001111000011110000111100001111000011110000" + "1111000011110000111100001111000011110000111100001111000011110000", + "1E3", + "0A", + "-B", + "+4", + "1.23G", + "", + " ", + "#", + "\r", + "\t", + "\n", + "\0", +}; + +#define NUM_POSITIVE_STRS_SIZE \ + (sizeof(num_valid_positive_strs) / sizeof(num_valid_positive_strs[0])) +#define NUM_NEGATIVE_STRS_SIZE \ + (sizeof(num_valid_negative_strs) / sizeof(num_valid_negative_strs[0])) +#define NUM_POSITIVE_GARBAGE_STRS_SIZE \ + (sizeof(num_garbage_positive_strs) / sizeof(num_garbage_positive_strs[0])) +#define NUM_NEGATIVE_GARBAGE_STRS_SIZE \ + (sizeof(num_garbage_negative_strs) / sizeof(num_garbage_negative_strs[0])) +#define NUM_INVALID_STRS_SIZE \ + (sizeof(num_invalid_strs) / sizeof(num_invalid_strs[0])) + + + +static int +can_parse_unsigned(uint64_t expected_result, enum cmdline_numtype type) +{ + switch (type) { + case UINT8: + if (expected_result > UINT8_MAX) + return 0; + break; + case UINT16: + if (expected_result > UINT16_MAX) + return 0; + break; + case UINT32: + if (expected_result > UINT32_MAX) + return 0; + break; + case INT8: + if (expected_result > INT8_MAX) + return 0; + break; + case INT16: + if (expected_result > INT16_MAX) + return 0; + break; + case INT32: + if (expected_result > INT32_MAX) + return 0; + break; + case INT64: + if (expected_result > INT64_MAX) + return 0; + break; + default: + return 1; + } + return 1; +} + +static int +can_parse_signed(int64_t expected_result, enum cmdline_numtype type) +{ + switch (type) { + case UINT8: + if (expected_result > UINT8_MAX || expected_result < 0) + return 0; + break; + case UINT16: + if (expected_result > UINT16_MAX || expected_result < 0) + return 0; + break; + case UINT32: + if (expected_result > UINT32_MAX || expected_result < 0) + return 0; + break; + case UINT64: + if (expected_result < 0) + return 0; + case INT8: + if (expected_result > INT8_MAX || expected_result < INT8_MIN) + return 0; + break; + case INT16: + if (expected_result > INT16_MAX || expected_result < INT16_MIN) + return 0; + break; + case INT32: + if (expected_result > INT32_MAX || expected_result < INT32_MIN) + return 0; + break; + default: + return 1; + } + return 1; +} + +/* test invalid parameters */ +int +test_parse_num_invalid_param(void) +{ + char buf[CMDLINE_TEST_BUFSIZE]; + uint32_t result; + cmdline_parse_token_num_t token; + int ret = 0; + + /* set up a token */ + token.num_data.type = UINT32; + + /* copy string to buffer */ + snprintf(buf, sizeof(buf), "%s", + num_valid_positive_strs[0].str); + + /* try all null */ + ret = cmdline_parse_num(NULL, NULL, NULL, 0); + if (ret != -1) { + printf("Error: parser accepted null parameters!\n"); + return -1; + } + + /* try null token */ + ret = cmdline_parse_num(NULL, buf, (void*)&result, sizeof(result)); + if (ret != -1) { + printf("Error: parser accepted null token!\n"); + return -1; + } + + /* try null buf */ + ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, NULL, + (void*)&result, sizeof(result)); + if (ret != -1) { + printf("Error: parser accepted null string!\n"); + return -1; + } + + /* try null result */ + ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, buf, + NULL, 0); + if (ret == -1) { + printf("Error: parser rejected null result!\n"); + return -1; + } + + /* test help function */ + memset(&buf, 0, sizeof(buf)); + + /* try all null */ + ret = cmdline_get_help_num(NULL, NULL, 0); + if (ret != -1) { + printf("Error: help function accepted null parameters!\n"); + return -1; + } + + /* try null token */ + ret = cmdline_get_help_num(NULL, buf, sizeof(buf)); + if (ret != -1) { + printf("Error: help function accepted null token!\n"); + return -1; + } + + /* coverage! */ + ret = cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, buf, sizeof(buf)); + if (ret < 0) { + printf("Error: help function failed with valid parameters!\n"); + return -1; + } + + return 0; +} +/* test valid parameters but invalid data */ +int +test_parse_num_invalid_data(void) +{ + enum cmdline_numtype type; + int ret = 0; + unsigned i; + char buf[CMDLINE_TEST_BUFSIZE]; + uint64_t result; /* pick largest buffer */ + cmdline_parse_token_num_t token; + + /* cycle through all possible parsed types */ + for (type = UINT8; type <= INT64; type++) { + token.num_data.type = type; + + /* test full strings */ + for (i = 0; i < NUM_INVALID_STRS_SIZE; i++) { + + memset(&result, 0, sizeof(uint64_t)); + memset(&buf, 0, sizeof(buf)); + + ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, + num_invalid_strs[i], (void*)&result, sizeof(result)); + if (ret != -1) { + /* get some info about what we are trying to parse */ + cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + printf("Error: parsing %s as %s succeeded!\n", + num_invalid_strs[i], buf); + return -1; + } + } + } + return 0; +} + +/* test valid parameters and data */ +int +test_parse_num_valid(void) +{ + int ret = 0; + enum cmdline_numtype type; + unsigned i; + char buf[CMDLINE_TEST_BUFSIZE]; + uint64_t result; + cmdline_parse_token_num_t token; + + /** valid strings **/ + + /* cycle through all possible parsed types */ + for (type = UINT8; type <= INT64; type++) { + token.num_data.type = type; + + /* test positive strings */ + for (i = 0; i < NUM_POSITIVE_STRS_SIZE; i++) { + result = 0; + memset(&buf, 0, sizeof(buf)); + + cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, + num_valid_positive_strs[i].str, + (void*)&result, sizeof(result)); + + /* if it should have passed but didn't, or if it should have failed but didn't */ + if ((ret < 0) == (can_parse_unsigned(num_valid_positive_strs[i].result, type) > 0)) { + printf("Error: parser behaves unexpectedly when parsing %s as %s!\n", + num_valid_positive_strs[i].str, buf); + return -1; + } + /* check if result matches what it should have matched + * since unsigned numbers don't care about number of bits, we can just convert + * everything to uint64_t without any worries. */ + if (ret > 0 && num_valid_positive_strs[i].result != result) { + printf("Error: parsing %s as %s failed: result mismatch!\n", + num_valid_positive_strs[i].str, buf); + return -1; + } + } + + /* test negative strings */ + for (i = 0; i < NUM_NEGATIVE_STRS_SIZE; i++) { + result = 0; + memset(&buf, 0, sizeof(buf)); + + cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, + num_valid_negative_strs[i].str, + (void*)&result, sizeof(result)); + + /* if it should have passed but didn't, or if it should have failed but didn't */ + if ((ret < 0) == (can_parse_signed(num_valid_negative_strs[i].result, type) > 0)) { + printf("Error: parser behaves unexpectedly when parsing %s as %s!\n", + num_valid_negative_strs[i].str, buf); + return -1; + } + /* check if result matches what it should have matched + * the result is signed in this case, so we have to account for that */ + if (ret > 0) { + /* detect negative */ + switch (type) { + case INT8: + result = (int8_t) result; + break; + case INT16: + result = (int16_t) result; + break; + case INT32: + result = (int32_t) result; + break; + default: + break; + } + if (num_valid_negative_strs[i].result == (int64_t) result) + continue; + printf("Error: parsing %s as %s failed: result mismatch!\n", + num_valid_negative_strs[i].str, buf); + return -1; + } + } + } + + /** garbage strings **/ + + /* cycle through all possible parsed types */ + for (type = UINT8; type <= INT64; type++) { + token.num_data.type = type; + + /* test positive garbage strings */ + for (i = 0; i < NUM_POSITIVE_GARBAGE_STRS_SIZE; i++) { + result = 0; + memset(&buf, 0, sizeof(buf)); + + cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, + num_garbage_positive_strs[i].str, + (void*)&result, sizeof(result)); + + /* if it should have passed but didn't, or if it should have failed but didn't */ + if ((ret < 0) == (can_parse_unsigned(num_garbage_positive_strs[i].result, type) > 0)) { + printf("Error: parser behaves unexpectedly when parsing %s as %s!\n", + num_garbage_positive_strs[i].str, buf); + return -1; + } + /* check if result matches what it should have matched + * since unsigned numbers don't care about number of bits, we can just convert + * everything to uint64_t without any worries. */ + if (ret > 0 && num_garbage_positive_strs[i].result != result) { + printf("Error: parsing %s as %s failed: result mismatch!\n", + num_garbage_positive_strs[i].str, buf); + return -1; + } + } + + /* test negative strings */ + for (i = 0; i < NUM_NEGATIVE_GARBAGE_STRS_SIZE; i++) { + result = 0; + memset(&buf, 0, sizeof(buf)); + + cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, + num_garbage_negative_strs[i].str, + (void*)&result, sizeof(result)); + + /* if it should have passed but didn't, or if it should have failed but didn't */ + if ((ret < 0) == (can_parse_signed(num_garbage_negative_strs[i].result, type) > 0)) { + printf("Error: parser behaves unexpectedly when parsing %s as %s!\n", + num_garbage_negative_strs[i].str, buf); + return -1; + } + /* check if result matches what it should have matched + * the result is signed in this case, so we have to account for that */ + if (ret > 0) { + /* detect negative */ + switch (type) { + case INT8: + if (result & (INT8_MAX + 1)) + result |= 0xFFFFFFFFFFFFFF00ULL; + break; + case INT16: + if (result & (INT16_MAX + 1)) + result |= 0xFFFFFFFFFFFF0000ULL; + break; + case INT32: + if (result & (INT32_MAX + 1ULL)) + result |= 0xFFFFFFFF00000000ULL; + break; + default: + break; + } + if (num_garbage_negative_strs[i].result == (int64_t) result) + continue; + printf("Error: parsing %s as %s failed: result mismatch!\n", + num_garbage_negative_strs[i].str, buf); + return -1; + } + } + } + + memset(&buf, 0, sizeof(buf)); + + /* coverage! */ + cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, + buf, sizeof(buf)); + + return 0; +} diff --git a/test/test/test_cmdline_portlist.c b/test/test/test_cmdline_portlist.c new file mode 100644 index 0000000000..b9664b0ed6 --- /dev/null +++ b/test/test/test_cmdline_portlist.c @@ -0,0 +1,250 @@ +/*- + * 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 +#include +#include + +#include +#include + +#include "test_cmdline.h" + +struct portlist_str { + const char * str; + uint32_t portmap; +}; + +/* valid strings */ +const struct portlist_str portlist_valid_strs[] = { + {"0", 0x1U }, + {"0-10", 0x7FFU}, + {"10-20", 0x1FFC00U}, + {"all", UINT32_MAX}, + {"0,1,2,3", 0xFU}, + {"0,1-5", 0x3FU}, + {"0,0,0", 0x1U}, + {"31,0-10,15", 0x800087FFU}, + {"0000", 0x1U}, + {"00,01,02,03", 0xFU}, + {"000,001,002,003", 0xFU}, +}; + +/* valid strings but with garbage at the end. + * these strings should still be valid because parser checks + * for end of token, which is either a space/tab, a newline/return, + * or a hash sign. + */ + +const char * portlist_garbage_strs[] = { + "0-31 garbage", + "0-31#garbage", + "0-31\0garbage", + "0-31\ngarbage", + "0-31\rgarbage", + "0-31\tgarbage", + "0,1,2,3-31 garbage", + "0,1,2,3-31#garbage", + "0,1,2,3-31\0garbage", + "0,1,2,3-31\ngarbage", + "0,1,2,3-31\rgarbage", + "0,1,2,3-31\tgarbage", + "all garbage", + "all#garbage", + "all\0garbage", + "all\ngarbage", + "all\rgarbage", + "all\tgarbage", +}; + +/* invalid strings */ +const char * portlist_invalid_strs[] = { + /* valid syntax, invalid chars */ + "A-B", + "0-S", + "1,2,3,4,Q", + "A-4,3-15", + "0-31invalid", + /* valid chars, invalid syntax */ + "1, 2", + "1- 4", + ",2", + ",2 ", + "-1, 4", + "5-1", + "2-", + /* misc */ + "-" + "a", + "A", + ",", + "#", + " ", + "\0", + "", + /* too long */ + "0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1," + "0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2", +}; + +#define PORTLIST_VALID_STRS_SIZE \ + (sizeof(portlist_valid_strs) / sizeof(portlist_valid_strs[0])) +#define PORTLIST_GARBAGE_STRS_SIZE \ + (sizeof(portlist_garbage_strs) / sizeof(portlist_garbage_strs[0])) +#define PORTLIST_INVALID_STRS_SIZE \ + (sizeof(portlist_invalid_strs) / sizeof(portlist_invalid_strs[0])) + + + + +/* test invalid parameters */ +int +test_parse_portlist_invalid_param(void) +{ + cmdline_portlist_t result; + char buf[CMDLINE_TEST_BUFSIZE]; + int ret; + + memset(&buf, 0, sizeof(buf)); + memset(&result, 0, sizeof(cmdline_portlist_t)); + + /* try all null */ + ret = cmdline_parse_portlist(NULL, NULL, NULL, 0); + if (ret != -1) { + printf("Error: parser accepted null parameters!\n"); + return -1; + } + + /* try null buf */ + ret = cmdline_parse_portlist(NULL, NULL, (void*)&result, + sizeof(result)); + if (ret != -1) { + printf("Error: parser accepted null string!\n"); + return -1; + } + + /* try null result */ + ret = cmdline_parse_portlist(NULL, portlist_valid_strs[0].str, NULL, 0); + if (ret == -1) { + printf("Error: parser rejected null result!\n"); + return -1; + } + + /* token is not used in ether_parse anyway so there's no point in + * testing it */ + + /* test help function */ + + /* coverage! */ + ret = cmdline_get_help_portlist(NULL, buf, sizeof(buf)); + if (ret < 0) { + printf("Error: help function failed with valid parameters!\n"); + return -1; + } + + return 0; +} + +/* test valid parameters but invalid data */ +int +test_parse_portlist_invalid_data(void) +{ + int ret = 0; + unsigned i; + cmdline_portlist_t result; + + /* test invalid strings */ + for (i = 0; i < PORTLIST_INVALID_STRS_SIZE; i++) { + + memset(&result, 0, sizeof(cmdline_portlist_t)); + + ret = cmdline_parse_portlist(NULL, portlist_invalid_strs[i], + (void*)&result, sizeof(result)); + if (ret != -1) { + printf("Error: parsing %s succeeded!\n", + portlist_invalid_strs[i]); + return -1; + } + } + + return 0; +} + +/* test valid parameters and data */ +int +test_parse_portlist_valid(void) +{ + int ret = 0; + unsigned i; + cmdline_portlist_t result; + + /* test full strings */ + for (i = 0; i < PORTLIST_VALID_STRS_SIZE; i++) { + + memset(&result, 0, sizeof(cmdline_portlist_t)); + + ret = cmdline_parse_portlist(NULL, portlist_valid_strs[i].str, + (void*)&result, sizeof(result)); + if (ret < 0) { + printf("Error: parsing %s failed!\n", + portlist_valid_strs[i].str); + return -1; + } + if (result.map != portlist_valid_strs[i].portmap) { + printf("Error: parsing %s failed: map mismatch!\n", + portlist_valid_strs[i].str); + return -1; + } + } + + /* test garbage strings */ + for (i = 0; i < PORTLIST_GARBAGE_STRS_SIZE; i++) { + + memset(&result, 0, sizeof(cmdline_portlist_t)); + + ret = cmdline_parse_portlist(NULL, portlist_garbage_strs[i], + (void*)&result, sizeof(result)); + if (ret < 0) { + printf("Error: parsing %s failed!\n", + portlist_garbage_strs[i]); + return -1; + } + if (result.map != UINT32_MAX) { + printf("Error: parsing %s failed: map mismatch!\n", + portlist_garbage_strs[i]); + return -1; + } + } + + return 0; +} diff --git a/test/test/test_cmdline_string.c b/test/test/test_cmdline_string.c new file mode 100644 index 0000000000..c5bb9c0cc1 --- /dev/null +++ b/test/test/test_cmdline_string.c @@ -0,0 +1,412 @@ +/*- + * 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 +#include +#include + +#include +#include + +#include +#include + +#include "test_cmdline.h" + +/* structures needed to run tests */ + +struct string_elt_str { + const char * str; /* parsed string */ + const char * result; /* expected string */ + int idx; /* position at which result is expected to be */ +}; + +struct string_elt_str string_elt_strs[] = { + {"one#two#three", "three", 2}, + {"one#two with spaces#three", "three", 2}, + {"one#two\twith\ttabs#three", "three", 2}, + {"one#two\rwith\rreturns#three", "three", 2}, + {"one#two\nwith\nnewlines#three", "three", 2}, + {"one#two#three", "one", 0}, + {"one#two#three", "two", 1}, + {"one#two\0three", "two", 1}, + {"one#two with spaces#three", "two with spaces", 1}, + {"one#two\twith\ttabs#three", "two\twith\ttabs", 1}, + {"one#two\rwith\rreturns#three", "two\rwith\rreturns", 1}, + {"one#two\nwith\nnewlines#three", "two\nwith\nnewlines", 1}, +}; + +#if (CMDLINE_TEST_BUFSIZE < STR_TOKEN_SIZE) \ +|| (CMDLINE_TEST_BUFSIZE < STR_MULTI_TOKEN_SIZE) +#undef CMDLINE_TEST_BUFSIZE +#define CMDLINE_TEST_BUFSIZE RTE_MAX(STR_TOKEN_SIZE, STR_MULTI_TOKEN_SIZE) +#endif + +struct string_nb_str { + const char * str; /* parsed string */ + int nb_strs; /* expected number of strings in str */ +}; + +struct string_nb_str string_nb_strs[] = { + {"one#two#three", 3}, + {"one", 1}, + {"one# \t two \r # three \n #four", 4}, +}; + + + +struct string_parse_str { + const char * str; /* parsed string */ + const char * fixed_str; /* parsing mode (any, fixed or multi) */ + const char * result; /* expected result */ +}; + +struct string_parse_str string_parse_strs[] = { + {"one", NULL, "one"}, /* any string */ + {"two", "one#two#three", "two"}, /* multiple choice string */ + {"three", "three", "three"}, /* fixed string */ + {"three", "one#two with\rgarbage\tcharacters\n#three", "three"}, + {"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 */ +}; + + + +struct string_invalid_str { + const char * str; /* parsed string */ + const char * fixed_str; /* parsing mode (any, fixed or multi) */ +}; + +struct string_invalid_str string_invalid_strs[] = { + {"invalid", "one"}, /* fixed string */ + {"invalid", "one#two#three"}, /* multiple choice string */ + {"invalid", "invalidone"}, /* string that starts the same */ + {"invalidone", "invalid"}, /* string that starts the same */ + {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" + "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" + "toolong!!!", NULL }, + {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" + "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" + "toolong!!!", "fixed" }, + {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" + "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" + "toolong!!!", "multi#choice#string" }, + {"invalid", + "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" + "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" + "toolong!!!" }, + {"", "invalid"} +}; + + + +const char * string_help_strs[] = { + NULL, + "fixed_str", + "multi#str", +}; + + + +#define STRING_PARSE_STRS_SIZE \ + (sizeof(string_parse_strs) / sizeof(string_parse_strs[0])) +#define STRING_HELP_STRS_SIZE \ + (sizeof(string_help_strs) / sizeof(string_help_strs[0])) +#define STRING_ELT_STRS_SIZE \ + (sizeof(string_elt_strs) / sizeof(string_elt_strs[0])) +#define STRING_NB_STRS_SIZE \ + (sizeof(string_nb_strs) / sizeof(string_nb_strs[0])) +#define STRING_INVALID_STRS_SIZE \ + (sizeof(string_invalid_strs) / sizeof(string_invalid_strs[0])) + +#define SMALL_BUF 8 + +/* test invalid parameters */ +int +test_parse_string_invalid_param(void) +{ + cmdline_parse_token_string_t token; + int result; + char buf[CMDLINE_TEST_BUFSIZE]; + + memset(&token, 0, sizeof(token)); + + snprintf(buf, sizeof(buf), "buffer"); + + /* test null token */ + if (cmdline_get_help_string( + NULL, buf, 0) != -1) { + printf("Error: function accepted null token!\n"); + return -1; + } + if (cmdline_complete_get_elt_string( + NULL, 0, buf, 0) != -1) { + printf("Error: function accepted null token!\n"); + return -1; + } + if (cmdline_complete_get_nb_string(NULL) != -1) { + printf("Error: function accepted null token!\n"); + return -1; + } + if (cmdline_parse_string(NULL, buf, NULL, 0) != -1) { + printf("Error: function accepted null token!\n"); + return -1; + } + /* test null buffer */ + if (cmdline_complete_get_elt_string( + (cmdline_parse_token_hdr_t*)&token, 0, NULL, 0) != -1) { + printf("Error: function accepted null buffer!\n"); + return -1; + } + if (cmdline_parse_string( + (cmdline_parse_token_hdr_t*)&token, NULL, + (void*)&result, sizeof(result)) != -1) { + printf("Error: function accepted null buffer!\n"); + return -1; + } + if (cmdline_get_help_string( + (cmdline_parse_token_hdr_t*)&token, NULL, 0) != -1) { + printf("Error: function accepted null buffer!\n"); + return -1; + } + /* test null result */ + if (cmdline_parse_string( + (cmdline_parse_token_hdr_t*)&token, buf, NULL, 0) == -1) { + printf("Error: function rejected null result!\n"); + return -1; + } + /* test negative index */ + if (cmdline_complete_get_elt_string( + (cmdline_parse_token_hdr_t*)&token, -1, buf, 0) != -1) { + printf("Error: function accepted negative index!\n"); + return -1; + } + return 0; +} + +/* test valid parameters but invalid data */ +int +test_parse_string_invalid_data(void) +{ + cmdline_parse_token_string_t token; + cmdline_parse_token_string_t help_token; + char buf[CMDLINE_TEST_BUFSIZE]; + char help_str[CMDLINE_TEST_BUFSIZE]; + char small_buf[SMALL_BUF]; + unsigned i; + + /* test parsing invalid strings */ + for (i = 0; i < STRING_INVALID_STRS_SIZE; i++) { + memset(&token, 0, sizeof(token)); + memset(buf, 0, sizeof(buf)); + + /* prepare test token data */ + token.string_data.str = string_invalid_strs[i].fixed_str; + + if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token, + string_invalid_strs[i].str, (void*)buf, + sizeof(buf)) != -1) { + memset(help_str, 0, sizeof(help_str)); + memset(&help_token, 0, sizeof(help_token)); + + help_token.string_data.str = string_invalid_strs[i].fixed_str; + + /* get parse type so we can give a good error message */ + cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str, + sizeof(help_str)); + + printf("Error: parsing %s as %s succeeded!\n", + string_invalid_strs[i].str, help_str); + return -1; + } + } + + /* misc tests (big comments signify test cases) */ + memset(&token, 0, sizeof(token)); + memset(small_buf, 0, sizeof(small_buf)); + + /* + * try to get element from a null token + */ + token.string_data.str = NULL; + if (cmdline_complete_get_elt_string( + (cmdline_parse_token_hdr_t*)&token, 1, + buf, sizeof(buf)) != -1) { + printf("Error: getting token from null token string!\n"); + return -1; + } + + /* + * try to get element into a buffer that is too small + */ + token.string_data.str = "too_small_buffer"; + if (cmdline_complete_get_elt_string( + (cmdline_parse_token_hdr_t*)&token, 0, + small_buf, sizeof(small_buf)) != -1) { + printf("Error: writing token into too small a buffer succeeded!\n"); + return -1; + } + + /* + * get help string written into a buffer smaller than help string + * truncation should occur + */ + token.string_data.str = NULL; + if (cmdline_get_help_string( + (cmdline_parse_token_hdr_t*)&token, + small_buf, sizeof(small_buf)) == -1) { + printf("Error: writing help string into too small a buffer failed!\n"); + return -1; + } + /* get help string for "any string" so we can compare it with small_buf */ + cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str, + sizeof(help_str)); + if (strncmp(small_buf, help_str, sizeof(small_buf) - 1)) { + printf("Error: help string mismatch!\n"); + return -1; + } + /* check null terminator */ + if (small_buf[sizeof(small_buf) - 1] != '\0') { + printf("Error: small buffer doesn't have a null terminator!\n"); + return -1; + } + + /* + * try to count tokens in a null token + */ + token.string_data.str = NULL; + if (cmdline_complete_get_nb_string( + (cmdline_parse_token_hdr_t*)&token) != 0) { + printf("Error: getting token count from null token succeeded!\n"); + return -1; + } + + return 0; +} + +/* test valid parameters and data */ +int +test_parse_string_valid(void) +{ + cmdline_parse_token_string_t token; + cmdline_parse_token_string_t help_token; + char buf[CMDLINE_TEST_BUFSIZE]; + char help_str[CMDLINE_TEST_BUFSIZE]; + unsigned i; + + /* test parsing strings */ + for (i = 0; i < STRING_PARSE_STRS_SIZE; i++) { + memset(&token, 0, sizeof(token)); + memset(buf, 0, sizeof(buf)); + + token.string_data.str = string_parse_strs[i].fixed_str; + + if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token, + string_parse_strs[i].str, (void*)buf, + sizeof(buf)) < 0) { + + /* clean help data */ + memset(&help_token, 0, sizeof(help_token)); + memset(help_str, 0, sizeof(help_str)); + + /* prepare help token */ + help_token.string_data.str = string_parse_strs[i].fixed_str; + + /* get help string so that we get an informative error message */ + cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str, + sizeof(help_str)); + + printf("Error: parsing %s as %s failed!\n", + string_parse_strs[i].str, help_str); + return -1; + } + if (strcmp(buf, string_parse_strs[i].result) != 0) { + printf("Error: result mismatch!\n"); + return -1; + } + } + + /* get number of string tokens and verify it's correct */ + for (i = 0; i < STRING_NB_STRS_SIZE; i++) { + memset(&token, 0, sizeof(token)); + + token.string_data.str = string_nb_strs[i].str; + + if (cmdline_complete_get_nb_string( + (cmdline_parse_token_hdr_t*)&token) < + string_nb_strs[i].nb_strs) { + printf("Error: strings count mismatch!\n"); + return -1; + } + } + + /* get token at specified position and verify it's correct */ + for (i = 0; i < STRING_ELT_STRS_SIZE; i++) { + memset(&token, 0, sizeof(token)); + memset(buf, 0, sizeof(buf)); + + token.string_data.str = string_elt_strs[i].str; + + if (cmdline_complete_get_elt_string( + (cmdline_parse_token_hdr_t*)&token, string_elt_strs[i].idx, + buf, sizeof(buf)) < 0) { + printf("Error: getting string element failed!\n"); + return -1; + } + if (strncmp(buf, string_elt_strs[i].result, + sizeof(buf)) != 0) { + printf("Error: result mismatch!\n"); + return -1; + } + } + + /* cover all cases with help strings */ + for (i = 0; i < STRING_HELP_STRS_SIZE; i++) { + memset(&help_token, 0, sizeof(help_token)); + memset(help_str, 0, sizeof(help_str)); + help_token.string_data.str = string_help_strs[i]; + if (cmdline_get_help_string((cmdline_parse_token_hdr_t*)&help_token, + help_str, sizeof(help_str)) < 0) { + printf("Error: help operation failed!\n"); + return -1; + } + } + + return 0; +} diff --git a/test/test/test_common.c b/test/test/test_common.c new file mode 100644 index 0000000000..8effa2f9ed --- /dev/null +++ b/test/test/test_common.c @@ -0,0 +1,172 @@ +/*- + * 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 +#include +#include +#include + +#include "test.h" + +#define MAX_NUM 1 << 20 + +#define FAIL(x)\ + {printf(x "() test failed!\n");\ + return -1;} + +/* this is really a sanity check */ +static int +test_macros(int __rte_unused unused_parm) +{ +#define SMALLER 0x1000U +#define BIGGER 0x2000U +#define PTR_DIFF BIGGER - SMALLER +#define FAIL_MACRO(x)\ + {printf(#x "() test failed!\n");\ + return -1;} + + uintptr_t unused = 0; + + RTE_SET_USED(unused); + + if ((uintptr_t)RTE_PTR_ADD(SMALLER, PTR_DIFF) != BIGGER) + FAIL_MACRO(RTE_PTR_ADD); + if ((uintptr_t)RTE_PTR_SUB(BIGGER, PTR_DIFF) != SMALLER) + FAIL_MACRO(RTE_PTR_SUB); + if (RTE_PTR_DIFF(BIGGER, SMALLER) != PTR_DIFF) + FAIL_MACRO(RTE_PTR_DIFF); + if (RTE_MAX(SMALLER, BIGGER) != BIGGER) + FAIL_MACRO(RTE_MAX); + if (RTE_MIN(SMALLER, BIGGER) != SMALLER) + FAIL_MACRO(RTE_MIN); + + if (strncmp(RTE_STR(test), "test", sizeof("test"))) + FAIL_MACRO(RTE_STR); + + return 0; +} + +static int +test_misc(void) +{ + char memdump[] = "memdump_test"; + if (rte_bsf32(129)) + FAIL("rte_bsf32"); + + rte_memdump(stdout, "test", memdump, sizeof(memdump)); + rte_hexdump(stdout, "test", memdump, sizeof(memdump)); + + rte_pause(); + + return 0; +} + +static int +test_align(void) +{ +#define FAIL_ALIGN(x, i, p)\ + {printf(x "() test failed: %u %u\n", i, p);\ + return -1;} +#define ERROR_FLOOR(res, i, pow) \ + (res % pow) || /* check if not aligned */ \ + ((res / pow) != (i / pow)) /* check if correct alignment */ +#define ERROR_CEIL(res, i, pow) \ + (res % pow) || /* check if not aligned */ \ + ((i % pow) == 0 ? /* check if ceiling is invoked */ \ + val / pow != i / pow : /* if aligned */ \ + val / pow != (i / pow) + 1) /* if not aligned, hence +1 */ + + uint32_t i, p, val; + + for (i = 1, p = 1; i <= MAX_NUM; i ++) { + if (rte_align32pow2(i) != p) + FAIL_ALIGN("rte_align32pow2", i, p); + if (i == p) + p <<= 1; + } + + for (p = 2; p <= MAX_NUM; p <<= 1) { + + if (!rte_is_power_of_2(p)) + FAIL("rte_is_power_of_2"); + + for (i = 1; i <= MAX_NUM; i++) { + /* align floor */ + if (RTE_ALIGN_FLOOR((uintptr_t)i, p) % p) + FAIL_ALIGN("RTE_ALIGN_FLOOR", i, p); + + val = RTE_PTR_ALIGN_FLOOR((uintptr_t) i, p); + if (ERROR_FLOOR(val, i, p)) + FAIL_ALIGN("RTE_PTR_ALIGN_FLOOR", i, p); + + val = RTE_ALIGN_FLOOR(i, p); + if (ERROR_FLOOR(val, i, p)) + FAIL_ALIGN("RTE_ALIGN_FLOOR", i, p); + + /* align ceiling */ + val = RTE_PTR_ALIGN((uintptr_t) i, p); + if (ERROR_CEIL(val, i, p)) + FAIL_ALIGN("RTE_PTR_ALIGN", i, p); + + val = RTE_ALIGN(i, p); + if (ERROR_CEIL(val, i, p)) + FAIL_ALIGN("RTE_ALIGN", i, p); + + val = RTE_ALIGN_CEIL(i, p); + if (ERROR_CEIL(val, i, p)) + FAIL_ALIGN("RTE_ALIGN_CEIL", i, p); + + val = RTE_PTR_ALIGN_CEIL((uintptr_t)i, p); + if (ERROR_CEIL(val, i, p)) + FAIL_ALIGN("RTE_PTR_ALIGN_CEIL", i, p); + + /* by this point we know that val is aligned to p */ + if (!rte_is_aligned((void*)(uintptr_t) val, p)) + FAIL("rte_is_aligned"); + } + } + return 0; +} + +static int +test_common(void) +{ + int ret = 0; + ret |= test_align(); + ret |= test_macros(0); + ret |= test_misc(); + + return ret; +} + +REGISTER_TEST_COMMAND(common_autotest, test_common); diff --git a/test/test/test_cpuflags.c b/test/test/test_cpuflags.c new file mode 100644 index 0000000000..0e5ebe788a --- /dev/null +++ b/test/test/test_cpuflags.c @@ -0,0 +1,202 @@ +/*- + * 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 + +#include +#include +#include +#include + +#include "test.h" + + +/* convenience define */ +#define CHECK_FOR_FLAG(x) \ + result = rte_cpu_get_flag_enabled(x); \ + printf("%s\n", cpu_flag_result(result)); \ + if (result == -ENOENT) \ + return -1; + +/* + * Helper function to display result + */ +static inline const char * +cpu_flag_result(int result) +{ + switch (result) { + case 0: + return "NOT PRESENT"; + case 1: + return "OK"; + default: + return "ERROR"; + } +} + + + +/* + * CPUID test + * =========== + * + * - Check flags from different registers with rte_cpu_get_flag_enabled() + * - Check if register and CPUID functions fail properly + */ + +static int +test_cpuflags(void) +{ + int result; + printf("\nChecking for flags from different registers...\n"); + +#ifdef RTE_ARCH_PPC_64 + printf("Check for PPC64:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_PPC64); + + printf("Check for PPC32:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_PPC32); + + printf("Check for VSX:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_VSX); + + printf("Check for DFP:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_DFP); + + printf("Check for FPU:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_FPU); + + printf("Check for SMT:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SMT); + + printf("Check for MMU:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_MMU); + + printf("Check for ALTIVEC:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_ALTIVEC); + + printf("Check for ARCH_2_06:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_ARCH_2_06); + + printf("Check for ARCH_2_07:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_ARCH_2_07); + + printf("Check for ICACHE_SNOOP:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_ICACHE_SNOOP); +#endif + +#if defined(RTE_ARCH_ARM) + printf("Check for NEON:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_NEON); +#endif + +#if defined(RTE_ARCH_ARM64) + printf("Check for FP:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_FP); + + printf("Check for ASIMD:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_NEON); + + printf("Check for EVTSTRM:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_EVTSTRM); + + printf("Check for AES:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_AES); + + printf("Check for PMULL:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_PMULL); + + printf("Check for SHA1:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SHA1); + + printf("Check for SHA2:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SHA2); + + printf("Check for CRC32:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_CRC32); + + printf("Check for ATOMICS:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_ATOMICS); +#endif + +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) + printf("Check for SSE:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SSE); + + printf("Check for SSE2:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SSE2); + + printf("Check for SSE3:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SSE3); + + printf("Check for SSE4.1:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SSE4_1); + + printf("Check for SSE4.2:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SSE4_2); + + printf("Check for AVX:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_AVX); + + printf("Check for AVX2:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_AVX2); + + printf("Check for TRBOBST:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_TRBOBST); + + printf("Check for ENERGY_EFF:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_ENERGY_EFF); + + printf("Check for LAHF_SAHF:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_LAHF_SAHF); + + printf("Check for 1GB_PG:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_1GB_PG); + + printf("Check for INVTSC:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_INVTSC); +#endif + + /* + * Check if invalid data is handled properly + */ + printf("\nCheck for invalid flag:\t"); + result = rte_cpu_get_flag_enabled(RTE_CPUFLAG_NUMFLAGS); + printf("%s\n", cpu_flag_result(result)); + if (result != -ENOENT) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(cpuflags_autotest, test_cpuflags); diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c new file mode 100644 index 0000000000..357a92eafa --- /dev/null +++ b/test/test/test_cryptodev.c @@ -0,0 +1,8221 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015-2017 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 +#include +#include +#include +#include + +#include +#include +#include + +#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER +#include +#include +#endif + +#include "test.h" +#include "test_cryptodev.h" + +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.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_zuc_test_vectors.h" +#include "test_cryptodev_zuc_hash_test_vectors.h" +#include "test_cryptodev_gcm_test_vectors.h" +#include "test_cryptodev_hmac_test_vectors.h" + +static enum rte_cryptodev_type gbl_cryptodev_type; + +struct crypto_testsuite_params { + struct rte_mempool *mbuf_pool; + struct rte_mempool *large_mbuf_pool; + struct rte_mempool *op_mpool; + struct rte_cryptodev_config conf; + struct rte_cryptodev_qp_conf qp_conf; + + uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS]; + uint8_t valid_dev_count; +}; + +struct crypto_unittest_params { + struct rte_crypto_sym_xform cipher_xform; + struct rte_crypto_sym_xform auth_xform; + + struct rte_cryptodev_sym_session *sess; + + struct rte_crypto_op *op; + + struct rte_mbuf *obuf, *ibuf; + + uint8_t *digest; +}; + +#define ALIGN_POW2_ROUNDUP(num, align) \ + (((num) + (align) - 1) & ~((align) - 1)) + +/* + * Forward declarations. + */ +static int +test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + struct crypto_unittest_params *ut_params, uint8_t *cipher_key, + uint8_t *hmac_key); + +static int +test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, + struct crypto_unittest_params *ut_params, + struct crypto_testsuite_params *ts_param, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); + +static struct rte_mbuf * +setup_test_string(struct rte_mempool *mpool, + const char *string, size_t len, uint8_t blocksize) +{ + struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); + size_t t_len = len - (blocksize ? (len % blocksize) : 0); + + memset(m->buf_addr, 0, m->buf_len); + if (m) { + char *dst = rte_pktmbuf_append(m, t_len); + + if (!dst) { + rte_pktmbuf_free(m); + return NULL; + } + if (string != NULL) + rte_memcpy(dst, string, t_len); + else + memset(dst, 0, t_len); + } + + return m; +} + +/* Get number of bytes in X bits (rounding up) */ +static uint32_t +ceil_byte_length(uint32_t num_bits) +{ + if (num_bits % 8) + return ((num_bits >> 3) + 1); + else + return (num_bits >> 3); +} + +static struct rte_crypto_op * +process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op) +{ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + printf("Error sending packet for encryption"); + return NULL; + } + + op = NULL; + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) + rte_pause(); + + return op; +} + +static struct crypto_testsuite_params testsuite_params = { NULL }; +static struct crypto_unittest_params unittest_params; + +static int +testsuite_setup(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info info; + uint32_t i = 0, nb_devs, dev_id; + int ret; + uint16_t qp_id; + + memset(ts_params, 0, sizeof(*ts_params)); + + ts_params->mbuf_pool = rte_mempool_lookup("CRYPTO_MBUFPOOL"); + if (ts_params->mbuf_pool == NULL) { + /* Not already created so create */ + ts_params->mbuf_pool = rte_pktmbuf_pool_create( + "CRYPTO_MBUFPOOL", + NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, + rte_socket_id()); + if (ts_params->mbuf_pool == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n"); + return TEST_FAILED; + } + } + + ts_params->large_mbuf_pool = rte_mempool_lookup( + "CRYPTO_LARGE_MBUFPOOL"); + if (ts_params->large_mbuf_pool == NULL) { + /* Not already created so create */ + ts_params->large_mbuf_pool = rte_pktmbuf_pool_create( + "CRYPTO_LARGE_MBUFPOOL", + 1, 0, 0, UINT16_MAX, + rte_socket_id()); + if (ts_params->large_mbuf_pool == NULL) { + RTE_LOG(ERR, USER1, + "Can't create CRYPTO_LARGE_MBUFPOOL\n"); + return TEST_FAILED; + } + } + + ts_params->op_mpool = rte_crypto_op_pool_create( + "MBUF_CRYPTO_SYM_OP_POOL", + RTE_CRYPTO_OP_TYPE_SYMMETRIC, + NUM_MBUFS, MBUF_CACHE_SIZE, + DEFAULT_NUM_XFORMS * + sizeof(struct rte_crypto_sym_xform), + rte_socket_id()); + if (ts_params->op_mpool == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); + return TEST_FAILED; + } + + /* Create 2 AESNI MB devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_MB_PMD) { +#ifndef RTE_LIBRTE_PMD_AESNI_MB + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_MB must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_AESNI_MB_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + } + } + } + + /* Create 2 AESNI GCM devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_GCM_PMD) { +#ifndef RTE_LIBRTE_PMD_AESNI_GCM + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_GCM must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_AESNI_GCM_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + TEST_ASSERT_SUCCESS(rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD), NULL), + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD)); + } + } + } + + /* Create 2 SNOW 3G devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_SNOW3G_PMD) { +#ifndef RTE_LIBRTE_PMD_SNOW3G + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_SNOW3G must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_SNOW3G_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + TEST_ASSERT_SUCCESS(rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD), NULL), + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD)); + } + } + } + + /* Create 2 KASUMI devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_KASUMI_PMD) { +#ifndef RTE_LIBRTE_PMD_KASUMI + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_KASUMI must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + 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( + RTE_STR(CRYPTODEV_NAME_KASUMI_PMD), NULL), + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_KASUMI_PMD)); + } + } + } + + /* Create 2 ZUC devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_ZUC_PMD) { +#ifndef RTE_LIBRTE_PMD_ZUC + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_ZUC must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_ZUC_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + TEST_ASSERT_SUCCESS(rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_ZUC_PMD), NULL), + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_ZUC_PMD)); + } + } + } + + /* Create 2 NULL devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_NULL_PMD) { +#ifndef RTE_LIBRTE_PMD_NULL_CRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_NULL_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + int dev_id = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_NULL_PMD), NULL); + + TEST_ASSERT(dev_id >= 0, + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_NULL_PMD)); + } + } + } + + /* Create 2 OPENSSL devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_OPENSSL_PMD) { +#ifndef RTE_LIBRTE_PMD_OPENSSL + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_OPENSSL must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_OPENSSL_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + } + } + } + + /* Create 2 ARMv8 devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_ARMV8_PMD) { +#ifndef RTE_LIBRTE_PMD_ARMV8_CRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_ARMV8_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); + } + } + } + +#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER + if (gbl_cryptodev_type == RTE_CRYPTODEV_SCHEDULER_PMD) { + +#ifndef RTE_LIBRTE_PMD_AESNI_MB + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_MB must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_SCHEDULER_PMD); + if (nb_devs < 1) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD), + NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)); + } + } +#endif /* RTE_LIBRTE_PMD_CRYPTO_SCHEDULER */ + +#ifndef RTE_LIBRTE_PMD_QAT + if (gbl_cryptodev_type == RTE_CRYPTODEV_QAT_SYM_PMD) { + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " + "in config file to run this testsuite.\n"); + return TEST_FAILED; + } +#endif + + nb_devs = rte_cryptodev_count(); + if (nb_devs < 1) { + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); + return TEST_FAILED; + } + + /* Create list of valid crypto devs */ + for (i = 0; i < nb_devs; i++) { + rte_cryptodev_info_get(i, &info); + if (info.dev_type == gbl_cryptodev_type) + ts_params->valid_devs[ts_params->valid_dev_count++] = i; + } + + if (ts_params->valid_dev_count < 1) + return TEST_FAILED; + + /* Set up all the qps on the first of the valid devices found */ + + dev_id = ts_params->valid_devs[0]; + + rte_cryptodev_info_get(dev_id, &info); + + ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs; + ts_params->conf.socket_id = SOCKET_ID_ANY; + ts_params->conf.session_mp.nb_objs = info.sym.max_nb_sessions; + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, + &ts_params->conf), + "Failed to configure cryptodev %u with %u qps", + dev_id, ts_params->conf.nb_queue_pairs); + + ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; + + for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + dev_id, qp_id, &ts_params->qp_conf, + rte_cryptodev_socket_id(dev_id)), + "Failed to setup queue pair %u on cryptodev %u", + qp_id, dev_id); + } + + return TEST_SUCCESS; +} + +static void +testsuite_teardown(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + + if (ts_params->mbuf_pool != NULL) { + RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", + 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_avail_count(ts_params->op_mpool)); + } + +} + +static int +ut_setup(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + uint16_t qp_id; + + /* Clear unit test parameters before running test */ + memset(ut_params, 0, sizeof(*ut_params)); + + /* Reconfigure device to default parameters */ + ts_params->conf.socket_id = SOCKET_ID_ANY; + ts_params->conf.session_mp.nb_objs = DEFAULT_NUM_OPS_INFLIGHT; + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], + &ts_params->conf), + "Failed to configure cryptodev %u", + ts_params->valid_devs[0]); + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs ; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, + &ts_params->qp_conf, + rte_cryptodev_socket_id(ts_params->valid_devs[0])), + "Failed to setup queue pair %u on cryptodev %u", + qp_id, ts_params->valid_devs[0]); + } + + + rte_cryptodev_stats_reset(ts_params->valid_devs[0]); + + /* Start the device */ + TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_devs[0]), + "Failed to start cryptodev %u", + ts_params->valid_devs[0]); + + return TEST_SUCCESS; +} + +static void +ut_teardown(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + struct rte_cryptodev_stats stats; + + /* free crypto session structure */ + if (ut_params->sess) { + rte_cryptodev_sym_session_free(ts_params->valid_devs[0], + ut_params->sess); + ut_params->sess = NULL; + } + + /* free crypto operation structure */ + if (ut_params->op) + rte_crypto_op_free(ut_params->op); + + /* + * free mbuf - both obuf and ibuf are usually the same, + * 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; + } + + if (ts_params->mbuf_pool != NULL) + RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", + rte_mempool_avail_count(ts_params->mbuf_pool)); + + rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats); + + /* Stop the device */ + rte_cryptodev_stop(ts_params->valid_devs[0]); +} + +static int +test_device_configure_invalid_dev_id(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + uint16_t dev_id, num_devs = 0; + + TEST_ASSERT((num_devs = rte_cryptodev_count()) >= 1, + "Need at least %d devices for test", 1); + + /* valid dev_id values */ + dev_id = ts_params->valid_devs[ts_params->valid_dev_count - 1]; + + /* Stop the device in case it's started so it can be configured */ + rte_cryptodev_stop(ts_params->valid_devs[dev_id]); + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, &ts_params->conf), + "Failed test for rte_cryptodev_configure: " + "invalid dev_num %u", dev_id); + + /* invalid dev_id values */ + dev_id = num_devs; + + TEST_ASSERT_FAIL(rte_cryptodev_configure(dev_id, &ts_params->conf), + "Failed test for rte_cryptodev_configure: " + "invalid dev_num %u", dev_id); + + dev_id = 0xff; + + TEST_ASSERT_FAIL(rte_cryptodev_configure(dev_id, &ts_params->conf), + "Failed test for rte_cryptodev_configure:" + "invalid dev_num %u", dev_id); + + return TEST_SUCCESS; +} + +static int +test_device_configure_invalid_queue_pair_ids(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + uint16_t orig_nb_qps = ts_params->conf.nb_queue_pairs; + + /* Stop the device in case it's started so it can be configured */ + rte_cryptodev_stop(ts_params->valid_devs[0]); + + /* valid - one queue pairs */ + ts_params->conf.nb_queue_pairs = 1; + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], + &ts_params->conf), + "Failed to configure cryptodev: dev_id %u, qp_id %u", + ts_params->valid_devs[0], ts_params->conf.nb_queue_pairs); + + + /* valid - max value queue pairs */ + ts_params->conf.nb_queue_pairs = MAX_NUM_QPS_PER_QAT_DEVICE; + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], + &ts_params->conf), + "Failed to configure cryptodev: dev_id %u, qp_id %u", + ts_params->valid_devs[0], ts_params->conf.nb_queue_pairs); + + + /* invalid - zero queue pairs */ + ts_params->conf.nb_queue_pairs = 0; + + TEST_ASSERT_FAIL(rte_cryptodev_configure(ts_params->valid_devs[0], + &ts_params->conf), + "Failed test for rte_cryptodev_configure, dev_id %u," + " invalid qps: %u", + ts_params->valid_devs[0], + ts_params->conf.nb_queue_pairs); + + + /* invalid - max value supported by field queue pairs */ + ts_params->conf.nb_queue_pairs = UINT16_MAX; + + TEST_ASSERT_FAIL(rte_cryptodev_configure(ts_params->valid_devs[0], + &ts_params->conf), + "Failed test for rte_cryptodev_configure, dev_id %u," + " invalid qps: %u", + ts_params->valid_devs[0], + ts_params->conf.nb_queue_pairs); + + + /* invalid - max value + 1 queue pairs */ + ts_params->conf.nb_queue_pairs = MAX_NUM_QPS_PER_QAT_DEVICE + 1; + + TEST_ASSERT_FAIL(rte_cryptodev_configure(ts_params->valid_devs[0], + &ts_params->conf), + "Failed test for rte_cryptodev_configure, dev_id %u," + " invalid qps: %u", + ts_params->valid_devs[0], + ts_params->conf.nb_queue_pairs); + + /* revert to original testsuite value */ + ts_params->conf.nb_queue_pairs = orig_nb_qps; + + return TEST_SUCCESS; +} + +static int +test_queue_pair_descriptor_setup(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_qp_conf qp_conf = { + .nb_descriptors = MAX_NUM_OPS_INFLIGHT + }; + + uint16_t qp_id; + + /* Stop the device in case it's started so it can be configured */ + rte_cryptodev_stop(ts_params->valid_devs[0]); + + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + ts_params->conf.session_mp.nb_objs = dev_info.sym.max_nb_sessions; + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], + &ts_params->conf), "Failed to configure cryptodev %u", + ts_params->valid_devs[0]); + + + /* + * Test various ring sizes on this device. memzones can't be + * freed so are re-used if ring is released and re-created. + */ + qp_conf.nb_descriptors = MIN_NUM_OPS_INFLIGHT; /* min size*/ + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, &qp_conf, + rte_cryptodev_socket_id( + ts_params->valid_devs[0])), + "Failed test for " + "rte_cryptodev_queue_pair_setup: num_inflights " + "%u on qp %u on cryptodev %u", + qp_conf.nb_descriptors, qp_id, + ts_params->valid_devs[0]); + } + + qp_conf.nb_descriptors = (uint32_t)(MAX_NUM_OPS_INFLIGHT / 2); + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, &qp_conf, + rte_cryptodev_socket_id( + ts_params->valid_devs[0])), + "Failed test for" + " rte_cryptodev_queue_pair_setup: num_inflights" + " %u on qp %u on cryptodev %u", + qp_conf.nb_descriptors, qp_id, + ts_params->valid_devs[0]); + } + + qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT; /* valid */ + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, &qp_conf, + rte_cryptodev_socket_id( + ts_params->valid_devs[0])), + "Failed test for " + "rte_cryptodev_queue_pair_setup: num_inflights" + " %u on qp %u on cryptodev %u", + qp_conf.nb_descriptors, qp_id, + ts_params->valid_devs[0]); + } + + /* invalid number of descriptors - max supported + 2 */ + qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT + 2; + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { + TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, &qp_conf, + rte_cryptodev_socket_id( + ts_params->valid_devs[0])), + "Unexpectedly passed test for " + "rte_cryptodev_queue_pair_setup:" + "num_inflights %u on qp %u on cryptodev %u", + qp_conf.nb_descriptors, qp_id, + ts_params->valid_devs[0]); + } + + /* invalid number of descriptors - max value of parameter */ + qp_conf.nb_descriptors = UINT32_MAX-1; + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { + TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, &qp_conf, + rte_cryptodev_socket_id( + ts_params->valid_devs[0])), + "Unexpectedly passed test for " + "rte_cryptodev_queue_pair_setup:" + "num_inflights %u on qp %u on cryptodev %u", + qp_conf.nb_descriptors, qp_id, + ts_params->valid_devs[0]); + } + + qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, &qp_conf, + rte_cryptodev_socket_id( + ts_params->valid_devs[0])), + "Failed test for" + " rte_cryptodev_queue_pair_setup:" + "num_inflights %u on qp %u on cryptodev %u", + qp_conf.nb_descriptors, qp_id, + ts_params->valid_devs[0]); + } + + /* invalid number of descriptors - max supported + 1 */ + qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT + 1; + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) { + TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, &qp_conf, + rte_cryptodev_socket_id( + ts_params->valid_devs[0])), + "Unexpectedly passed test for " + "rte_cryptodev_queue_pair_setup:" + "num_inflights %u on qp %u on cryptodev %u", + qp_conf.nb_descriptors, qp_id, + ts_params->valid_devs[0]); + } + + /* test invalid queue pair id */ + qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; /*valid */ + + qp_id = DEFAULT_NUM_QPS_PER_QAT_DEVICE; /*invalid */ + + TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], + qp_id, &qp_conf, + rte_cryptodev_socket_id(ts_params->valid_devs[0])), + "Failed test for rte_cryptodev_queue_pair_setup:" + "invalid qp %u on cryptodev %u", + qp_id, ts_params->valid_devs[0]); + + qp_id = 0xffff; /*invalid*/ + + TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], + qp_id, &qp_conf, + rte_cryptodev_socket_id(ts_params->valid_devs[0])), + "Failed test for rte_cryptodev_queue_pair_setup:" + "invalid qp %u on cryptodev %u", + qp_id, ts_params->valid_devs[0]); + + return TEST_SUCCESS; +} + +/* ***** Plaintext data for tests ***** */ + +const char catch_22_quote_1[] = + "There was only one catch and that was Catch-22, which " + "specified that a concern for one's safety in the face of " + "dangers that were real and immediate was the process of a " + "rational mind. Orr was crazy and could be grounded. All he " + "had to do was ask; and as soon as he did, he would no longer " + "be crazy and would have to fly more missions. Orr would be " + "crazy to fly more missions and sane if he didn't, but if he " + "was sane he had to fly them. If he flew them he was crazy " + "and didn't have to; but if he didn't want to he was sane and " + "had to. Yossarian was moved very deeply by the absolute " + "simplicity of this clause of Catch-22 and let out a " + "respectful whistle. \"That's some catch, that Catch-22\", he " + "observed. \"It's the best there is,\" Doc Daneeka agreed."; + +const char catch_22_quote[] = + "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."; + +#define QUOTE_480_BYTES (480) +#define QUOTE_512_BYTES (512) +#define QUOTE_768_BYTES (768) +#define QUOTE_1024_BYTES (1024) + + + +/* ***** SHA1 Hash Tests ***** */ + +#define HMAC_KEY_LENGTH_SHA1 (DIGEST_BYTE_LENGTH_SHA1) + +static uint8_t hmac_sha1_key[] = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD }; + +/* ***** SHA224 Hash Tests ***** */ + +#define HMAC_KEY_LENGTH_SHA224 (DIGEST_BYTE_LENGTH_SHA224) + + +/* ***** AES-CBC Cipher Tests ***** */ + +#define CIPHER_KEY_LENGTH_AES_CBC (16) +#define CIPHER_IV_LENGTH_AES_CBC (CIPHER_KEY_LENGTH_AES_CBC) + +static uint8_t aes_cbc_key[] = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A }; + +static uint8_t aes_cbc_iv[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; + + +/* ***** AES-CBC / HMAC-SHA1 Hash Tests ***** */ + +static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_ciphertext[] = { + 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 +}; + +static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { + 0x9a, 0x4f, 0x88, 0x1b, 0xb6, 0x8f, 0xd8, 0x60, + 0x42, 0x1a, 0x7d, 0x3d, 0xf5, 0x82, 0x80, 0xf1, + 0x18, 0x8c, 0x1d, 0x32 +}; + + +/* Multisession Vector context Test */ +/*Begin Session 0 */ +static uint8_t ms_aes_cbc_key0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher0[] = { + 0x3C, 0xE4, 0xEE, 0x42, 0xB6, 0x9B, 0xC3, 0x38, + 0x5F, 0xAD, 0x54, 0xDC, 0xA8, 0x32, 0x81, 0xDC, + 0x7A, 0x6F, 0x85, 0x58, 0x07, 0x35, 0xED, 0xEB, + 0xAD, 0x79, 0x79, 0x96, 0xD3, 0x0E, 0xA6, 0xD9, + 0xAA, 0x86, 0xA4, 0x8F, 0xB5, 0xD6, 0x6E, 0x6D, + 0x0C, 0x91, 0x2F, 0xC4, 0x67, 0x98, 0x0E, 0xC4, + 0x8D, 0x83, 0x68, 0x69, 0xC4, 0xD3, 0x94, 0x34, + 0xC4, 0x5D, 0x60, 0x55, 0x22, 0x87, 0x8F, 0x6F, + 0x17, 0x8E, 0x75, 0xE4, 0x02, 0xF5, 0x1B, 0x99, + 0xC8, 0x39, 0xA9, 0xAB, 0x23, 0x91, 0x12, 0xED, + 0x08, 0xE7, 0xD9, 0x25, 0x89, 0x24, 0x4F, 0x8D, + 0x68, 0xF3, 0x10, 0x39, 0x0A, 0xEE, 0x45, 0x24, + 0xDF, 0x7A, 0x9D, 0x00, 0x25, 0xE5, 0x35, 0x71, + 0x4E, 0x40, 0x59, 0x6F, 0x0A, 0x13, 0xB3, 0x72, + 0x1D, 0x98, 0x63, 0x94, 0x89, 0xA5, 0x39, 0x8E, + 0xD3, 0x9C, 0x8A, 0x7F, 0x71, 0x2F, 0xC7, 0xCD, + 0x81, 0x05, 0xDC, 0xC0, 0x8D, 0xCE, 0x6D, 0x18, + 0x30, 0xC4, 0x72, 0x51, 0xF0, 0x27, 0xC8, 0xF6, + 0x60, 0x5B, 0x7C, 0xB2, 0xE3, 0x49, 0x0C, 0x29, + 0xC6, 0x9F, 0x39, 0x57, 0x80, 0x55, 0x24, 0x2C, + 0x9B, 0x0F, 0x5A, 0xB3, 0x89, 0x55, 0x31, 0x96, + 0x0D, 0xCD, 0xF6, 0x51, 0x03, 0x2D, 0x89, 0x26, + 0x74, 0x44, 0xD6, 0xE8, 0xDC, 0xEA, 0x44, 0x55, + 0x64, 0x71, 0x9C, 0x9F, 0x5D, 0xBA, 0x39, 0x46, + 0xA8, 0x17, 0xA1, 0x9C, 0x52, 0x9D, 0xBC, 0x6B, + 0x4A, 0x98, 0xE6, 0xEA, 0x33, 0xEC, 0x58, 0xB4, + 0x43, 0xF0, 0x32, 0x45, 0xA4, 0xC1, 0x55, 0xB7, + 0x5D, 0xB5, 0x59, 0xB2, 0xE3, 0x96, 0xFF, 0xA5, + 0xAF, 0xE1, 0x86, 0x1B, 0x42, 0xE6, 0x3B, 0xA0, + 0x90, 0x4A, 0xE8, 0x8C, 0x21, 0x7F, 0x36, 0x1E, + 0x5B, 0x65, 0x25, 0xD1, 0xC1, 0x5A, 0xCA, 0x3D, + 0x10, 0xED, 0x2D, 0x79, 0xD0, 0x0F, 0x58, 0x44, + 0x69, 0x81, 0xF5, 0xD4, 0xC9, 0x0F, 0x90, 0x76, + 0x1F, 0x54, 0xD2, 0xD5, 0x97, 0xCE, 0x2C, 0xE3, + 0xEF, 0xF4, 0xB7, 0xC6, 0x3A, 0x87, 0x7F, 0x83, + 0x2A, 0xAF, 0xCD, 0x90, 0x12, 0xA7, 0x7D, 0x85, + 0x1D, 0x62, 0xD3, 0x85, 0x25, 0x05, 0xDB, 0x45, + 0x92, 0xA3, 0xF6, 0xA2, 0xA8, 0x41, 0xE4, 0x25, + 0x86, 0x87, 0x67, 0x24, 0xEC, 0x89, 0x23, 0x2A, + 0x9B, 0x20, 0x4D, 0x93, 0xEE, 0xE2, 0x2E, 0xC1, + 0x0B, 0x15, 0x33, 0xCF, 0x00, 0xD1, 0x1A, 0xDA, + 0x93, 0xFD, 0x28, 0x21, 0x5B, 0xCF, 0xD1, 0xF3, + 0x5A, 0x81, 0xBA, 0x82, 0x5E, 0x2F, 0x61, 0xB4, + 0x05, 0x71, 0xB5, 0xF4, 0x39, 0x3C, 0x1F, 0x60, + 0x00, 0x7A, 0xC4, 0xF8, 0x35, 0x20, 0x6C, 0x3A, + 0xCC, 0x03, 0x8F, 0x7B, 0xA2, 0xB6, 0x65, 0x8A, + 0xB6, 0x5F, 0xFD, 0x25, 0xD3, 0x5F, 0x92, 0xF9, + 0xAE, 0x17, 0x9B, 0x5E, 0x6E, 0x9A, 0xE4, 0x55, + 0x10, 0x25, 0x07, 0xA4, 0xAF, 0x21, 0x69, 0x13, + 0xD8, 0xFA, 0x31, 0xED, 0xF7, 0xA7, 0xA7, 0x3B, + 0xB8, 0x96, 0x8E, 0x10, 0x86, 0x74, 0xD8, 0xB1, + 0x34, 0x9E, 0x9B, 0x6A, 0x26, 0xA8, 0xD4, 0xD0, + 0xB5, 0xF6, 0xDE, 0xE7, 0xCA, 0x06, 0xDC, 0xA3, + 0x6F, 0xEE, 0x6B, 0x1E, 0xB5, 0x30, 0x99, 0x23, + 0xF9, 0x76, 0xF0, 0xA0, 0xCF, 0x3B, 0x94, 0x7B, + 0x19, 0x8D, 0xA5, 0x0C, 0x18, 0xA6, 0x1D, 0x07, + 0x89, 0xBE, 0x5B, 0x61, 0xE5, 0xF1, 0x42, 0xDB, + 0xD4, 0x2E, 0x02, 0x1F, 0xCE, 0xEF, 0x92, 0xB1, + 0x1B, 0x56, 0x50, 0xF2, 0x16, 0xE5, 0xE7, 0x4F, + 0xFD, 0xBB, 0x3E, 0xD2, 0xFC, 0x3C, 0xC6, 0x0F, + 0xF9, 0x12, 0x4E, 0xCB, 0x1E, 0x0C, 0x15, 0x84, + 0x2A, 0x14, 0x8A, 0x02, 0xE4, 0x7E, 0x95, 0x5B, + 0x86, 0xDB, 0x9B, 0x62, 0x5B, 0x19, 0xD2, 0x17, + 0xFA, 0x13, 0xBB, 0x6B, 0x3F, 0x45, 0x9F, 0xBF +}; + + +static uint8_t ms_hmac_key0[] = { + 0xFF, 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 +}; + +static const uint8_t ms_hmac_digest0[] = { + 0x43, 0x52, 0xED, 0x34, 0xAB, 0x36, 0xB2, 0x51, + 0xFB, 0xA3, 0xA6, 0x7C, 0x38, 0xFC, 0x42, 0x8F, + 0x57, 0x64, 0xAB, 0x81, 0xA7, 0x89, 0xB7, 0x6C, + 0xA0, 0xDC, 0xB9, 0x4D, 0xC4, 0x30, 0xF9, 0xD4, + 0x10, 0x82, 0x55, 0xD0, 0xAB, 0x32, 0xFB, 0x56, + 0x0D, 0xE4, 0x68, 0x3D, 0x76, 0xD0, 0x7B, 0xE4, + 0xA6, 0x2C, 0x34, 0x9E, 0x8C, 0x41, 0xF8, 0x23, + 0x28, 0x1B, 0x3A, 0x90, 0x26, 0x34, 0x47, 0x90 + }; + +/* End Session 0 */ +/* Begin session 1 */ + +static uint8_t ms_aes_cbc_key1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher1[] = { + 0x5A, 0x7A, 0x67, 0x5D, 0xB8, 0xE1, 0xDC, 0x71, + 0x39, 0xA8, 0x74, 0x93, 0x9C, 0x4C, 0xFE, 0x23, + 0x61, 0xCD, 0xA4, 0xB3, 0xD9, 0xCE, 0x99, 0x09, + 0x2A, 0x23, 0xF3, 0x29, 0xBF, 0x4C, 0xB4, 0x6A, + 0x1B, 0x6B, 0x73, 0x4D, 0x48, 0x0C, 0xCF, 0x6C, + 0x5E, 0x34, 0x9E, 0x7F, 0xBC, 0x8F, 0xCC, 0x8F, + 0x75, 0x1D, 0x3D, 0x77, 0x10, 0x76, 0xC8, 0xB9, + 0x99, 0x6F, 0xD6, 0x56, 0x75, 0xA9, 0xB2, 0x66, + 0xC2, 0x24, 0x2B, 0x9C, 0xFE, 0x40, 0x8E, 0x43, + 0x20, 0x97, 0x1B, 0xFA, 0xD0, 0xCF, 0x04, 0xAB, + 0xBB, 0xF6, 0x5D, 0xF5, 0xA0, 0x19, 0x7C, 0x23, + 0x5D, 0x80, 0x8C, 0x49, 0xF6, 0x76, 0x88, 0x29, + 0x27, 0x4C, 0x59, 0x2B, 0x43, 0xA6, 0xB2, 0x26, + 0x27, 0x78, 0xBE, 0x1B, 0xE1, 0x4F, 0x5A, 0x1F, + 0xFC, 0x68, 0x08, 0xE7, 0xC4, 0xD1, 0x34, 0x68, + 0xB7, 0x13, 0x14, 0x41, 0x62, 0x6B, 0x1F, 0x77, + 0x0C, 0x68, 0x1D, 0x0D, 0xED, 0x89, 0xAA, 0xD8, + 0x97, 0x02, 0xBA, 0x5E, 0xD4, 0x84, 0x25, 0x97, + 0x03, 0xA5, 0xA6, 0x13, 0x66, 0x02, 0xF4, 0xC3, + 0xF3, 0xD3, 0xCC, 0x95, 0xC3, 0x87, 0x46, 0x90, + 0x1F, 0x6E, 0x14, 0xA8, 0x00, 0xF2, 0x6F, 0xD5, + 0xA1, 0xAD, 0xD5, 0x40, 0xA2, 0x0F, 0x32, 0x7E, + 0x99, 0xA3, 0xF5, 0x53, 0xC3, 0x26, 0xA1, 0x45, + 0x01, 0x88, 0x57, 0x84, 0x3E, 0x7B, 0x4E, 0x0B, + 0x3C, 0xB5, 0x3E, 0x9E, 0xE9, 0x78, 0x77, 0xC5, + 0xC0, 0x89, 0xA8, 0xF8, 0xF1, 0xA5, 0x2D, 0x5D, + 0xF9, 0xC6, 0xFB, 0xCB, 0x05, 0x23, 0xBD, 0x6E, + 0x5E, 0x14, 0xC6, 0x57, 0x73, 0xCF, 0x98, 0xBD, + 0x10, 0x8B, 0x18, 0xA6, 0x01, 0x5B, 0x13, 0xAE, + 0x8E, 0xDE, 0x1F, 0xB5, 0xB7, 0x40, 0x6C, 0xC1, + 0x1E, 0xA1, 0x19, 0x20, 0x9E, 0x95, 0xE0, 0x2F, + 0x1C, 0xF5, 0xD9, 0xD0, 0x2B, 0x1E, 0x82, 0x25, + 0x62, 0xB4, 0xEB, 0xA1, 0x1F, 0xCE, 0x44, 0xA1, + 0xCB, 0x92, 0x01, 0x6B, 0xE4, 0x26, 0x23, 0xE3, + 0xC5, 0x67, 0x35, 0x55, 0xDA, 0xE5, 0x27, 0xEE, + 0x8D, 0x12, 0x84, 0xB7, 0xBA, 0xA7, 0x1C, 0xD6, + 0x32, 0x3F, 0x67, 0xED, 0xFB, 0x5B, 0x8B, 0x52, + 0x46, 0x8C, 0xF9, 0x69, 0xCD, 0xAE, 0x79, 0xAA, + 0x37, 0x78, 0x49, 0xEB, 0xC6, 0x8E, 0x76, 0x63, + 0x84, 0xFF, 0x9D, 0x22, 0x99, 0x51, 0xB7, 0x5E, + 0x83, 0x4C, 0x8B, 0xDF, 0x5A, 0x07, 0xCC, 0xBA, + 0x42, 0xA5, 0x98, 0xB6, 0x47, 0x0E, 0x66, 0xEB, + 0x23, 0x0E, 0xBA, 0x44, 0xA8, 0xAA, 0x20, 0x71, + 0x79, 0x9C, 0x77, 0x5F, 0xF5, 0xFE, 0xEC, 0xEF, + 0xC6, 0x64, 0x3D, 0x84, 0xD0, 0x2B, 0xA7, 0x0A, + 0xC3, 0x72, 0x5B, 0x9C, 0xFA, 0xA8, 0x87, 0x95, + 0x94, 0x11, 0x38, 0xA7, 0x1E, 0x58, 0xE3, 0x73, + 0xC6, 0xC9, 0xD1, 0x7B, 0x92, 0xDB, 0x0F, 0x49, + 0x74, 0xC2, 0xA2, 0x0E, 0x35, 0x57, 0xAC, 0xDB, + 0x9A, 0x1C, 0xCF, 0x5A, 0x32, 0x3E, 0x26, 0x9B, + 0xEC, 0xB3, 0xEF, 0x9C, 0xFE, 0xBE, 0x52, 0xAC, + 0xB1, 0x29, 0xDD, 0xFD, 0x07, 0xE2, 0xEE, 0xED, + 0xE4, 0x46, 0x37, 0xFE, 0xD1, 0xDC, 0xCD, 0x02, + 0xF9, 0x31, 0xB0, 0xFB, 0x36, 0xB7, 0x34, 0xA4, + 0x76, 0xE8, 0x57, 0xBF, 0x99, 0x92, 0xC7, 0xAF, + 0x98, 0x10, 0xE2, 0x70, 0xCA, 0xC9, 0x2B, 0x82, + 0x06, 0x96, 0x88, 0x0D, 0xB3, 0xAC, 0x9E, 0x6D, + 0x43, 0xBC, 0x5B, 0x31, 0xCF, 0x65, 0x8D, 0xA6, + 0xC7, 0xFE, 0x73, 0xE1, 0x54, 0xF7, 0x10, 0xF9, + 0x86, 0xF7, 0xDF, 0xA1, 0xA1, 0xD8, 0xAE, 0x35, + 0xB3, 0x90, 0xDC, 0x6F, 0x43, 0x7A, 0x8B, 0xE0, + 0xFE, 0x8F, 0x33, 0x4D, 0x29, 0x6C, 0x45, 0x53, + 0x73, 0xDD, 0x21, 0x0B, 0x85, 0x30, 0xB5, 0xA5, + 0xF3, 0x5D, 0xEC, 0x79, 0x61, 0x9D, 0x9E, 0xB3 + +}; + +static uint8_t ms_hmac_key1[] = { + 0xFE, 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 +}; + +static const uint8_t ms_hmac_digest1[] = { + 0xCE, 0x6E, 0x5F, 0x77, 0x96, 0x9A, 0xB1, 0x69, + 0x2D, 0x5E, 0xF3, 0x2F, 0x32, 0x10, 0xCB, 0x50, + 0x0E, 0x09, 0x56, 0x25, 0x07, 0x34, 0xC9, 0x20, + 0xEC, 0x13, 0x43, 0x23, 0x5C, 0x08, 0x8B, 0xCD, + 0xDC, 0x86, 0x8C, 0xEE, 0x0A, 0x95, 0x2E, 0xB9, + 0x8C, 0x7B, 0x02, 0x7A, 0xD4, 0xE1, 0x49, 0xB4, + 0x45, 0xB5, 0x52, 0x37, 0xC6, 0xFF, 0xFE, 0xAA, + 0x0A, 0x87, 0xB8, 0x51, 0xF9, 0x2A, 0x01, 0x8F +}; +/* End Session 1 */ +/* Begin Session 2 */ +static uint8_t ms_aes_cbc_key2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher2[] = { + 0xBB, 0x3C, 0x68, 0x25, 0xFD, 0xB6, 0xA2, 0x91, + 0x20, 0x56, 0xF6, 0x30, 0x35, 0xFC, 0x9E, 0x97, + 0xF2, 0x90, 0xFC, 0x7E, 0x3E, 0x0A, 0x75, 0xC8, + 0x4C, 0xF2, 0x2D, 0xAC, 0xD3, 0x93, 0xF0, 0xC5, + 0x14, 0x88, 0x8A, 0x23, 0xC2, 0x59, 0x9A, 0x98, + 0x4B, 0xD5, 0x2C, 0xDA, 0x43, 0xA9, 0x34, 0x69, + 0x7C, 0x6D, 0xDB, 0xDC, 0xCB, 0xC0, 0xA0, 0x09, + 0xA7, 0x86, 0x16, 0x4B, 0xBF, 0xA8, 0xB6, 0xCF, + 0x7F, 0x74, 0x1F, 0x22, 0xF0, 0xF6, 0xBB, 0x44, + 0x8B, 0x4C, 0x9E, 0x23, 0xF8, 0x9F, 0xFC, 0x5B, + 0x9E, 0x9C, 0x2A, 0x79, 0x30, 0x8F, 0xBF, 0xA9, + 0x68, 0xA1, 0x20, 0x71, 0x7C, 0x77, 0x22, 0x34, + 0x07, 0xCD, 0xC6, 0xF6, 0x50, 0x0A, 0x08, 0x99, + 0x17, 0x98, 0xE3, 0x93, 0x8A, 0xB0, 0xEE, 0xDF, + 0xC2, 0xBA, 0x3B, 0x44, 0x73, 0xDF, 0xDD, 0xDC, + 0x14, 0x4D, 0x3B, 0xBB, 0x5E, 0x58, 0xC1, 0x26, + 0xA7, 0xAE, 0x47, 0xF3, 0x24, 0x6D, 0x4F, 0xD3, + 0x6E, 0x3E, 0x33, 0xE6, 0x7F, 0xCA, 0x50, 0xAF, + 0x5D, 0x3D, 0xA0, 0xDD, 0xC9, 0xF3, 0x30, 0xD3, + 0x6E, 0x8B, 0x2E, 0x12, 0x24, 0x34, 0xF0, 0xD3, + 0xC7, 0x8D, 0x23, 0x29, 0xAA, 0x05, 0xE1, 0xFA, + 0x2E, 0xF6, 0x8D, 0x37, 0x86, 0xC0, 0x6D, 0x13, + 0x2D, 0x98, 0xF3, 0x52, 0x39, 0x22, 0xCE, 0x38, + 0xC2, 0x1A, 0x72, 0xED, 0xFB, 0xCC, 0xE4, 0x71, + 0x5A, 0x0C, 0x0D, 0x09, 0xF8, 0xE8, 0x1B, 0xBC, + 0x53, 0xC8, 0xD8, 0x8F, 0xE5, 0x98, 0x5A, 0xB1, + 0x06, 0xA6, 0x5B, 0xE6, 0xA2, 0x88, 0x21, 0x9E, + 0x36, 0xC0, 0x34, 0xF9, 0xFB, 0x3B, 0x0A, 0x22, + 0x00, 0x00, 0x39, 0x48, 0x8D, 0x23, 0x74, 0x62, + 0x72, 0x91, 0xE6, 0x36, 0xAA, 0x77, 0x9C, 0x72, + 0x9D, 0xA8, 0xC3, 0xA9, 0xD5, 0x44, 0x72, 0xA6, + 0xB9, 0x28, 0x8F, 0x64, 0x4C, 0x8A, 0x64, 0xE6, + 0x4E, 0xFA, 0xEF, 0x87, 0xDE, 0x7B, 0x22, 0x44, + 0xB0, 0xDF, 0x2E, 0x5F, 0x0B, 0xA5, 0xF2, 0x24, + 0x07, 0x5C, 0x2D, 0x39, 0xB7, 0x3D, 0x8A, 0xE5, + 0x0E, 0x9D, 0x4E, 0x50, 0xED, 0x03, 0x99, 0x8E, + 0xF0, 0x06, 0x55, 0x4E, 0xA2, 0x24, 0xE7, 0x17, + 0x46, 0xDF, 0x6C, 0xCD, 0xC6, 0x44, 0xE8, 0xF9, + 0xB9, 0x1B, 0x36, 0xF6, 0x7F, 0x10, 0xA4, 0x7D, + 0x90, 0xBD, 0xE4, 0xAA, 0xD6, 0x9E, 0x18, 0x9D, + 0x22, 0x35, 0xD6, 0x55, 0x54, 0xAA, 0xF7, 0x22, + 0xA3, 0x3E, 0xEF, 0xC8, 0xA2, 0x34, 0x8D, 0xA9, + 0x37, 0x63, 0xA6, 0xC3, 0x57, 0xCB, 0x0C, 0x49, + 0x7D, 0x02, 0xBE, 0xAA, 0x13, 0x75, 0xB7, 0x4E, + 0x52, 0x62, 0xA5, 0xC2, 0x33, 0xC7, 0x6C, 0x1B, + 0xF6, 0x34, 0xF6, 0x09, 0xA5, 0x0C, 0xC7, 0xA2, + 0x61, 0x48, 0x62, 0x7D, 0x17, 0x15, 0xE3, 0x95, + 0xC8, 0x63, 0xD2, 0xA4, 0x43, 0xA9, 0x49, 0x07, + 0xB2, 0x3B, 0x2B, 0x62, 0x7D, 0xCB, 0x51, 0xB3, + 0x25, 0x33, 0x47, 0x0E, 0x14, 0x67, 0xDC, 0x6A, + 0x9B, 0x51, 0xAC, 0x9D, 0x8F, 0xA2, 0x2B, 0x57, + 0x8C, 0x5C, 0x5F, 0x76, 0x23, 0x92, 0x0F, 0x84, + 0x46, 0x0E, 0x40, 0x85, 0x38, 0x60, 0xFA, 0x61, + 0x20, 0xC5, 0xE3, 0xF1, 0x70, 0xAC, 0x1B, 0xBF, + 0xC4, 0x2B, 0xC5, 0x67, 0xD1, 0x43, 0xC5, 0x17, + 0x74, 0x71, 0x69, 0x6F, 0x82, 0x89, 0x19, 0x8A, + 0x70, 0x43, 0x92, 0x01, 0xC4, 0x63, 0x7E, 0xB1, + 0x59, 0x4E, 0xCD, 0xEA, 0x93, 0xA4, 0x52, 0x53, + 0x9B, 0x61, 0x5B, 0xD2, 0x3E, 0x19, 0x39, 0xB7, + 0x32, 0xEA, 0x8E, 0xF8, 0x1D, 0x76, 0x5C, 0xB2, + 0x73, 0x2D, 0x91, 0xC0, 0x18, 0xED, 0x25, 0x2A, + 0x53, 0x64, 0xF0, 0x92, 0x31, 0x55, 0x21, 0xA8, + 0x24, 0xA9, 0xD1, 0x02, 0xF6, 0x6C, 0x2B, 0x70, + 0xA9, 0x59, 0xC1, 0xD6, 0xC3, 0x57, 0x5B, 0x92 +}; + +static uint8_t ms_hmac_key2[] = { + 0xFC, 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 +}; + +static const uint8_t ms_hmac_digest2[] = { + 0xA5, 0x0F, 0x9C, 0xFB, 0x08, 0x62, 0x59, 0xFF, + 0x80, 0x2F, 0xEB, 0x4B, 0xE1, 0x46, 0x21, 0xD6, + 0x02, 0x98, 0xF2, 0x8E, 0xF4, 0xEC, 0xD4, 0x77, + 0x86, 0x4C, 0x31, 0x28, 0xC8, 0x25, 0x80, 0x27, + 0x3A, 0x72, 0x5D, 0x6A, 0x56, 0x8A, 0xD3, 0x82, + 0xB0, 0xEC, 0x31, 0x6D, 0x8B, 0x6B, 0xB4, 0x24, + 0xE7, 0x62, 0xC1, 0x52, 0xBC, 0x14, 0x1B, 0x8E, + 0xEC, 0x9A, 0xF1, 0x47, 0x80, 0xD2, 0xB0, 0x59 +}; + +/* End Session 2 */ + + +static int +test_AES_CBC_HMAC_SHA1_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_SHA1); + 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_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->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; + + /* Set crypto operation authentication parameters */ + 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; + + /* Set crypto operation cipher parameters */ + 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"); + + /* Validate obuf */ + uint8_t *ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, + 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; +} + +/* ***** AES-CBC / HMAC-SHA512 Hash Tests ***** */ + +#define HMAC_KEY_LENGTH_SHA512 (DIGEST_BYTE_LENGTH_SHA512) + +static uint8_t hmac_sha512_key[] = { + 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 }; + +static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = { + 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 }; + + + +static int +test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key); + +static int +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, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); + + +static int +test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key) +{ + + /* 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 = cipher_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_SHA512_HMAC; + ut_params->auth_xform.auth.key.data = hmac_key; + ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; + ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; + + return TEST_SUCCESS; +} + + +static int +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, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv) +{ + /* Generate test mbuf data and digest */ + ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, + (const char *) + cipher, + 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, + 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"); + + rte_crypto_op_attach_sym_session(ut_params->op, 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_offset( + ut_params->ibuf, 0); + sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; + + rte_memcpy(sym_op->cipher.iv.data, 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"); + + /* Validate obuf */ + TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, + "Digest verification failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_mb_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_AESNI_MB_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_mb_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_AESNI_MB_PMD, + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_mb_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_AESNI_MB_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER + +static int +test_AES_cipheronly_scheduler_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_SCHEDULER_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_scheduler_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_SCHEDULER_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_scheduler_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_SCHEDULER_PMD, + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +#endif /* RTE_LIBRTE_PMD_CRYPTO_SCHEDULER */ + +static int +test_AES_chain_openssl_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_OPENSSL_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_openssl_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_OPENSSL_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_openssl_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_OPENSSL_PMD, + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_armv8_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_ARMV8_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +/* ***** SNOW 3G Tests ***** */ +static int +create_wireless_algo_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_algorithm algo) +{ + uint8_t hash_key[key_len]; + + struct crypto_unittest_params *ut_params = &unittest_params; + + memcpy(hash_key, key, key_len); + + 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 = 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; + ut_params->auth_xform.auth.add_auth_data_length = aad_len; + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + return 0; +} + +static int +create_wireless_algo_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]; + + struct crypto_unittest_params *ut_params = &unittest_params; + + memcpy(cipher_key, key, key_len); + + /* 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 = 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; + + TEST_HEXDUMP(stdout, "key:", key, key_len); + + /* Create Crypto session */ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params-> + cipher_xform); + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + return 0; +} + +static int +create_wireless_algo_cipher_operation(const uint8_t *iv, const unsigned iv_len, + const unsigned cipher_len, + 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; + unsigned iv_pad_len = 0; + + /* 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 pktmbuf offload"); + + /* 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; + + /* iv */ + 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"); + + memset(sym_op->cipher.iv.data, 0, iv_pad_len); + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = iv_pad_len; + + rte_memcpy(sym_op->cipher.iv.data, iv, iv_len); + sym_op->cipher.data.length = cipher_len; + sym_op->cipher.data.offset = cipher_offset; + return 0; +} + +static int +create_wireless_algo_cipher_operation_oop(const uint8_t *iv, const uint8_t iv_len, + const unsigned cipher_len, + 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; + unsigned iv_pad_len = 0; + + /* 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 pktmbuf offload"); + + /* 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 = ut_params->obuf; + + /* iv */ + 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"); + + /* For OOP operation both buffers must have the same size */ + if (ut_params->obuf) + rte_pktmbuf_prepend(ut_params->obuf, iv_pad_len); + + memset(sym_op->cipher.iv.data, 0, iv_pad_len); + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = iv_pad_len; + + rte_memcpy(sym_op->cipher.iv.data, iv, iv_len); + sym_op->cipher.data.length = cipher_len; + sym_op->cipher.data.offset = cipher_offset; + return 0; +} + +static int +create_wireless_algo_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]; + + struct crypto_unittest_params *ut_params = &unittest_params; + + memcpy(cipher_auth_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 = auth_op; + 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; + ut_params->auth_xform.auth.digest_length = auth_len; + ut_params->auth_xform.auth.add_auth_data_length = aad_len; + + /* 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 = 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; + + TEST_HEXDUMP(stdout, "key:", key, key_len); + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->cipher_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + return 0; +} + +static int +create_wireless_algo_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; + + memcpy(auth_cipher_key, key, key_len); + + /* Setup Authentication Parameters */ + 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 = 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; + ut_params->auth_xform.auth.add_auth_data_length = aad_len; + + /* 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 = 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; + + TEST_HEXDUMP(stdout, "key:", key, key_len); + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_wireless_algo_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; + + struct crypto_unittest_params *ut_params = &unittest_params; + + unsigned aad_buffer_len; + + /* 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 pktmbuf offload"); + + /* 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; + + /* aad */ + /* + * Always allocate the aad up to the block size. + * 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 (8 bytes for KASUMI and 16 bytes for SNOW 3G). + */ + 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, + "no room to prepend aad"); + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys( + ut_params->ibuf); + sym_op->auth.aad.length = aad_len; + + memset(sym_op->auth.aad.data, 0, aad_buffer_len); + rte_memcpy(sym_op->auth.aad.data, aad, aad_len); + + TEST_HEXDUMP(stdout, "aad:", + sym_op->auth.aad.data, aad_len); + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, auth_tag_len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + ut_params->digest = sym_op->auth.digest.data; + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, data_pad_len + aad_len); + sym_op->auth.digest.length = auth_tag_len; + if (op == RTE_CRYPTO_AUTH_OP_GENERATE) + memset(sym_op->auth.digest.data, 0, auth_tag_len); + else + rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->auth.data.length = auth_len; + sym_op->auth.data.offset = auth_offset; + + return 0; +} + +static int +create_wireless_algo_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) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + unsigned iv_pad_len = 0; + unsigned aad_buffer_len; + + /* 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 pktmbuf offload"); + /* 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; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, auth_tag_len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + ut_params->digest = sym_op->auth.digest.data; + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, data_pad_len); + sym_op->auth.digest.length = auth_tag_len; + if (op == RTE_CRYPTO_AUTH_OP_GENERATE) + memset(sym_op->auth.digest.data, 0, auth_tag_len); + else + rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + /* aad */ + /* + * Always allocate the aad up to the block size. + * 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 (8 bytes for KASUMI and 16 bytes for SNOW 3G). + */ + 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); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, + "no room to prepend aad"); + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys( + ut_params->ibuf); + sym_op->auth.aad.length = aad_len; + memset(sym_op->auth.aad.data, 0, aad_buffer_len); + rte_memcpy(sym_op->auth.aad.data, aad, aad_len); + TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data, aad_len); + + /* iv */ + 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); + + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + memset(sym_op->cipher.iv.data, 0, iv_pad_len); + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = iv_pad_len; + rte_memcpy(sym_op->cipher.iv.data, iv, iv_len); + sym_op->cipher.data.length = cipher_len; + sym_op->cipher.data.offset = cipher_offset + auth_offset; + sym_op->auth.data.length = auth_len; + sym_op->auth.data.offset = auth_offset + cipher_offset; + + return 0; +} + +static int +create_wireless_algo_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, + 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; + + unsigned iv_pad_len = 0; + unsigned aad_buffer_len = 0; + + /* 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 pktmbuf offload"); + + /* 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; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, auth_tag_len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, data_pad_len); + sym_op->auth.digest.length = auth_tag_len; + + memset(sym_op->auth.digest.data, 0, auth_tag_len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + /* aad */ + /* + * Always allocate the aad up to the block size. + * 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 (8 bytes for KASUMI 16 bytes). + */ + 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); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, + "no room to prepend aad"); + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys( + ut_params->ibuf); + sym_op->auth.aad.length = aad_len; + memset(sym_op->auth.aad.data, 0, aad_buffer_len); + rte_memcpy(sym_op->auth.aad.data, aad, aad_len); + TEST_HEXDUMP(stdout, "aad:", + sym_op->auth.aad.data, aad_len); + + /* iv */ + 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); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + memset(sym_op->cipher.iv.data, 0, iv_pad_len); + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = iv_pad_len; + + rte_memcpy(sym_op->cipher.iv.data, iv, iv_len); + + sym_op->cipher.data.length = cipher_len; + sym_op->cipher.data.offset = auth_offset + cipher_offset; + + sym_op->auth.data.length = auth_len; + sym_op->auth.data.offset = auth_offset + cipher_offset; + + return 0; +} + +static int +test_snow3g_authentication(const struct snow3g_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 SNOW 3G session */ + retval = create_wireless_algo_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_SNOW3G_UIA2); + 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, 16); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_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) + 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 + tdata->aad.len; + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ut_params->digest, + tdata->digest.data, + DIGEST_BYTE_LENGTH_SNOW3G_UIA2, + "SNOW 3G Generated auth tag not as expected"); + + return 0; +} + +static int +test_snow3g_authentication_verify(const struct snow3g_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 SNOW 3G session */ + retval = create_wireless_algo_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_SNOW3G_UIA2); + 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, 16); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_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) + 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_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_wireless_algo_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_wireless_algo_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_wireless_algo_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_wireless_algo_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) +{ + return test_snow3g_authentication(&snow3g_hash_test_case_1); +} + +static int +test_snow3g_hash_generate_test_case_2(void) +{ + return test_snow3g_authentication(&snow3g_hash_test_case_2); +} + +static int +test_snow3g_hash_generate_test_case_3(void) +{ + return test_snow3g_authentication(&snow3g_hash_test_case_3); +} + +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); + +} + +static int +test_snow3g_hash_verify_test_case_2(void) +{ + return test_snow3g_authentication_verify(&snow3g_hash_test_case_2); +} + +static int +test_snow3g_hash_verify_test_case_3(void) +{ + return test_snow3g_authentication_verify(&snow3g_hash_test_case_3); +} + +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_generate_test_case_6(void) +{ + return test_kasumi_authentication(&kasumi_hash_test_case_6); +} + +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_wireless_algo_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_wireless_algo_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_sgl(const struct kasumi_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + + unsigned int plaintext_pad_len; + unsigned int plaintext_len; + + uint8_t buffer[10000]; + const uint8_t *ciphertext; + + struct rte_cryptodev_info dev_info; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { + printf("Device doesn't support scatter-gather. " + "Test Skipped.\n"); + return 0; + } + + /* Create KASUMI session */ + retval = create_wireless_algo_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; + + 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); + + ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, + plaintext_pad_len, 10, 0); + + pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data); + + /* Create KASUMI operation */ + retval = create_wireless_algo_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_read(ut_params->obuf, tdata->iv.len, + plaintext_len, buffer); + else + ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len, + plaintext_len, buffer); + + /* Validate obuf */ + 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_wireless_algo_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_wireless_algo_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_encryption_oop_sgl(const struct kasumi_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + unsigned int plaintext_pad_len; + unsigned int plaintext_len; + + const uint8_t *ciphertext; + uint8_t buffer[2048]; + + struct rte_cryptodev_info dev_info; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { + printf("Device doesn't support scatter-gather. " + "Test Skipped.\n"); + return 0; + } + + /* Create KASUMI session */ + retval = create_wireless_algo_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; + + 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); + + ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, + plaintext_pad_len, 10, 0); + ut_params->obuf = create_segmented_mbuf(ts_params->mbuf_pool, + plaintext_pad_len, 3, 0); + + /* Append data which is padded to a multiple */ + /* of the algorithms block size */ + pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data); + + /* Create KASUMI operation */ + retval = create_wireless_algo_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_read(ut_params->obuf, tdata->iv.len, + plaintext_pad_len, buffer); + else + ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len, + plaintext_pad_len, buffer); + + /* 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_wireless_algo_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_wireless_algo_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_wireless_algo_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_wireless_algo_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; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *plaintext, *ciphertext; + unsigned plaintext_pad_len; + unsigned plaintext_len; + + /* Create SNOW 3G session */ + retval = create_wireless_algo_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); + + /* 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); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_cipher_operation(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, plaintext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validDataLenInBits.len, + "SNOW 3G Ciphertext data not as expected"); + return 0; +} + + +static int +test_snow3g_encryption_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; + unsigned plaintext_pad_len; + unsigned plaintext_len; + + /* Create SNOW 3G session */ + retval = create_wireless_algo_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, plaintext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_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, plaintext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validDataLenInBits.len, + "SNOW 3G Ciphertext data not as expected"); + return 0; +} + +static int +test_snow3g_encryption_oop_sgl(const struct snow3g_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + unsigned int plaintext_pad_len; + unsigned int plaintext_len; + uint8_t buffer[10000]; + const uint8_t *ciphertext; + + struct rte_cryptodev_info dev_info; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { + printf("Device doesn't support scatter-gather. " + "Test Skipped.\n"); + return 0; + } + + /* Create SNOW 3G session */ + retval = create_wireless_algo_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; + + 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); + + ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, + plaintext_pad_len, 10, 0); + ut_params->obuf = create_segmented_mbuf(ts_params->mbuf_pool, + plaintext_pad_len, 3, 0); + + 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"); + + pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_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_read(ut_params->obuf, tdata->iv.len, + plaintext_len, buffer); + else + ciphertext = rte_pktmbuf_read(ut_params->ibuf, tdata->iv.len, + plaintext_len, buffer); + + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validDataLenInBits.len, + "SNOW 3G 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 SNOW 3G session */ + retval = create_wireless_algo_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 + extra_offset); + /* + * 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, (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 SNOW 3G operation */ + retval = create_wireless_algo_cipher_operation_oop(tdata->iv.data, + tdata->iv.len, + tdata->validCipherLenInBits.len, + tdata->validCipherOffsetLenInBits.len + + extra_offset, + 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; + +#ifdef RTE_APP_TEST_DEBUG + 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_BIT_OFFSET( + ciphertext, + expected_ciphertext_shifted, + tdata->validDataLenInBits.len, + extra_offset, + "SNOW 3G 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; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + + uint8_t *plaintext, *ciphertext; + unsigned ciphertext_pad_len; + unsigned ciphertext_len; + + /* Create SNOW 3G session */ + retval = create_wireless_algo_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; + + 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, 16); + 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 SNOW 3G operation */ + retval = create_wireless_algo_cipher_operation(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) + 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->validDataLenInBits.len, + "SNOW 3G Plaintext data not as expected"); + return 0; +} + +static int test_snow3g_decryption_oop(const struct snow3g_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 ciphertext_pad_len; + unsigned ciphertext_len; + + /* Create SNOW 3G session */ + retval = create_wireless_algo_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; + + 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"); + TEST_ASSERT_NOT_NULL(ut_params->obuf, + "Failed to allocate output buffer"); + + /* Clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->obuf)); + + 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); + + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, ciphertext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_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) + 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->validDataLenInBits.len, + "SNOW 3G Plaintext data not as expected"); + return 0; +} + +static int +test_snow3g_cipher_auth(const struct snow3g_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 SNOW 3G session */ + retval = create_wireless_algo_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) + 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, 16); + 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 SNOW 3G operation */ + retval = create_wireless_algo_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 + ); + 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; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->iv.len + tdata->aad.len; + else + ciphertext = plaintext; + + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validDataLenInBits.len, + "SNOW 3G Ciphertext data not as expected"); + + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len + tdata->aad.len + tdata->iv.len; + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ut_params->digest, + tdata->digest.data, + DIGEST_BYTE_LENGTH_SNOW3G_UIA2, + "SNOW 3G Generated auth tag not as expected"); + return 0; +} +static int +test_snow3g_auth_cipher(const struct snow3g_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 SNOW 3G session */ + retval = create_wireless_algo_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) + 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, 16); + 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 SNOW 3G operation */ + retval = create_wireless_algo_auth_cipher_operation( + tdata->digest.len, + tdata->iv.data, tdata->iv.len, + tdata->aad.data, tdata->aad.len, + plaintext_pad_len, + tdata->validCipherLenInBits.len, + tdata->validCipherOffsetLenInBits.len, + tdata->validAuthLenInBits.len, + tdata->validAuthOffsetLenInBits.len, + RTE_CRYPTO_AUTH_SNOW3G_UIA2, + 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; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->aad.len + tdata->iv.len; + else + ciphertext = plaintext; + + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len + tdata->aad.len + tdata->iv.len; + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validDataLenInBits.len, + "SNOW 3G Ciphertext data not as expected"); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ut_params->digest, + tdata->digest.data, + DIGEST_BYTE_LENGTH_SNOW3G_UIA2, + "SNOW 3G Generated auth tag not as expected"); + return 0; +} + +static int +test_kasumi_auth_cipher(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_wireless_algo_auth_cipher_session( + ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_KASUMI_F9, + RTE_CRYPTO_CIPHER_KASUMI_F8, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->digest.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, 16); + 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_wireless_algo_auth_cipher_operation(tdata->digest.len, + tdata->iv.data, tdata->iv.len, + tdata->aad.data, tdata->aad.len, + plaintext_pad_len, + tdata->validCipherLenInBits.len, + tdata->validCipherOffsetLenInBits.len, + tdata->validAuthLenInBits.len, + tdata->validAuthOffsetLenInBits.len, + RTE_CRYPTO_AUTH_KASUMI_F9, + 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_src; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->iv.len + tdata->aad.len; + else + ciphertext = plaintext; + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validCipherLenInBits.len, + "KASUMI Ciphertext data not as expected"); + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len + tdata->aad.len + tdata->iv.len; + + /* 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_cipher_auth(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_wireless_algo_cipher_auth_session( + ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_KASUMI_F9, + RTE_CRYPTO_CIPHER_KASUMI_F8, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->digest.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, 16); + 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_wireless_algo_cipher_hash_operation(tdata->digest.data, + tdata->digest.len, tdata->aad.data, + tdata->aad.len, + plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_KASUMI_F9, + RTE_CRYPTO_CIPHER_KASUMI_F8, + tdata->iv.data, tdata->iv.len, + tdata->validCipherLenInBits.len, + tdata->validCipherOffsetLenInBits.len, + 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; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->aad.len + tdata->iv.len; + else + ciphertext = plaintext; + + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len + tdata->aad.len + tdata->iv.len; + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validCipherLenInBits.len, + "KASUMI Ciphertext data not as expected"); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ut_params->digest, + tdata->digest.data, + DIGEST_BYTE_LENGTH_SNOW3G_UIA2, + "KASUMI Generated auth tag not as expected"); + return 0; +} + +static int +test_zuc_encryption(const struct zuc_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 ZUC session */ + retval = create_wireless_algo_cipher_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_CIPHER_ZUC_EEA3, + 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 ZUC operation */ + retval = create_wireless_algo_cipher_operation(tdata->iv.data, tdata->iv.len, + tdata->plaintext.len, + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_ZUC_EEA3); + 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, + "ZUC Ciphertext data not as expected"); + return 0; +} + +static int +test_zuc_encryption_sgl(const struct zuc_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + + unsigned int plaintext_pad_len; + unsigned int plaintext_len; + const uint8_t *ciphertext; + uint8_t ciphertext_buffer[2048]; + struct rte_cryptodev_info dev_info; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { + printf("Device doesn't support scatter-gather. " + "Test Skipped.\n"); + return 0; + } + + 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); + + ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, + plaintext_pad_len, 10, 0); + + pktmbuf_write(ut_params->ibuf, 0, plaintext_len, + tdata->plaintext.data); + + /* Create ZUC session */ + retval = create_wireless_algo_cipher_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_CIPHER_ZUC_EEA3, + tdata->key.data, tdata->key.len); + if (retval < 0) + return retval; + + /* Clear mbuf payload */ + + pktmbuf_write(ut_params->ibuf, 0, plaintext_len, tdata->plaintext.data); + + /* Create ZUC operation */ + retval = create_wireless_algo_cipher_operation(tdata->iv.data, + tdata->iv.len, tdata->plaintext.len, + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_ZUC_EEA3); + 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_read(ut_params->obuf, + tdata->iv.len, plaintext_len, ciphertext_buffer); + else + ciphertext = rte_pktmbuf_read(ut_params->ibuf, + tdata->iv.len, plaintext_len, ciphertext_buffer); + + /* Validate obuf */ + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validCipherLenInBits.len, + "ZUC Ciphertext data not as expected"); + + return 0; +} + +static int +test_zuc_authentication(const struct zuc_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 ZUC session */ + retval = create_wireless_algo_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_ZUC_EIA3); + 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 ZUC operation */ + retval = create_wireless_algo_hash_operation(NULL, tdata->digest.len, + tdata->aad.data, tdata->aad.len, + plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_ZUC_EIA3, + 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, + "ZUC Generated auth tag not as expected"); + + return 0; +} + +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_sgl(void) +{ + return test_kasumi_encryption_sgl(&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_1_oop_sgl(void) +{ + return test_kasumi_encryption_oop_sgl(&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); +} + +static int +test_snow3g_encryption_test_case_1_oop(void) +{ + return test_snow3g_encryption_oop(&snow3g_test_case_1); +} + +static int +test_snow3g_encryption_test_case_1_oop_sgl(void) +{ + return test_snow3g_encryption_oop_sgl(&snow3g_test_case_1); +} + + +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); +} + +static int +test_snow3g_encryption_test_case_3(void) +{ + return test_snow3g_encryption(&snow3g_test_case_3); +} + +static int +test_snow3g_encryption_test_case_4(void) +{ + return test_snow3g_encryption(&snow3g_test_case_4); +} + +static int +test_snow3g_encryption_test_case_5(void) +{ + return test_snow3g_encryption(&snow3g_test_case_5); +} + +static int +test_snow3g_decryption_test_case_1(void) +{ + return test_snow3g_decryption(&snow3g_test_case_1); +} + +static int +test_snow3g_decryption_test_case_1_oop(void) +{ + return test_snow3g_decryption_oop(&snow3g_test_case_1); +} + +static int +test_snow3g_decryption_test_case_2(void) +{ + return test_snow3g_decryption(&snow3g_test_case_2); +} + +static int +test_snow3g_decryption_test_case_3(void) +{ + return test_snow3g_decryption(&snow3g_test_case_3); +} + +static int +test_snow3g_decryption_test_case_4(void) +{ + return test_snow3g_decryption(&snow3g_test_case_4); +} + +static int +test_snow3g_decryption_test_case_5(void) +{ + return test_snow3g_decryption(&snow3g_test_case_5); +} +static int +test_snow3g_cipher_auth_test_case_1(void) +{ + return test_snow3g_cipher_auth(&snow3g_test_case_3); +} + +static int +test_snow3g_auth_cipher_test_case_1(void) +{ + return test_snow3g_auth_cipher(&snow3g_test_case_6); +} + +static int +test_kasumi_auth_cipher_test_case_1(void) +{ + return test_kasumi_auth_cipher(&kasumi_test_case_3); +} + +static int +test_kasumi_cipher_auth_test_case_1(void) +{ + return test_kasumi_cipher_auth(&kasumi_test_case_6); +} + +static int +test_zuc_encryption_test_case_1(void) +{ + return test_zuc_encryption(&zuc_test_case_1); +} + +static int +test_zuc_encryption_test_case_2(void) +{ + return test_zuc_encryption(&zuc_test_case_2); +} + +static int +test_zuc_encryption_test_case_3(void) +{ + return test_zuc_encryption(&zuc_test_case_3); +} + +static int +test_zuc_encryption_test_case_4(void) +{ + return test_zuc_encryption(&zuc_test_case_4); +} + +static int +test_zuc_encryption_test_case_5(void) +{ + return test_zuc_encryption(&zuc_test_case_5); +} + +static int +test_zuc_encryption_test_case_6_sgl(void) +{ + return test_zuc_encryption_sgl(&zuc_test_case_1); +} + +static int +test_zuc_hash_generate_test_case_1(void) +{ + return test_zuc_authentication(&zuc_hash_test_case_1); +} + +static int +test_zuc_hash_generate_test_case_2(void) +{ + return test_zuc_authentication(&zuc_hash_test_case_2); +} + +static int +test_zuc_hash_generate_test_case_3(void) +{ + return test_zuc_authentication(&zuc_hash_test_case_3); +} + +static int +test_zuc_hash_generate_test_case_4(void) +{ + return test_zuc_authentication(&zuc_hash_test_case_4); +} + +static int +test_zuc_hash_generate_test_case_5(void) +{ + return test_zuc_authentication(&zuc_hash_test_case_5); +} + +static int +test_3DES_chain_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_DES_cipheronly_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_openssl_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_OPENSSL_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_openssl_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_OPENSSL_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +/* ***** AES-GCM Tests ***** */ + +static int +create_gcm_session(uint8_t dev_id, enum rte_crypto_cipher_operation op, + const uint8_t *key, const uint8_t key_len, + const uint8_t aad_len, const uint8_t auth_len, + enum rte_crypto_auth_operation auth_op) +{ + uint8_t cipher_key[key_len]; + + struct crypto_unittest_params *ut_params = &unittest_params; + + memcpy(cipher_key, key, key_len); + + /* 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_GCM; + ut_params->auth_xform.auth.op = auth_op; + 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; + + 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.algo = RTE_CRYPTO_AUTH_AES_GCM; + + ut_params->auth_xform.auth.digest_length = auth_len; + ut_params->auth_xform.auth.add_auth_data_length = aad_len; + ut_params->auth_xform.auth.key.length = 0; + ut_params->auth_xform.auth.key.data = NULL; + + if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { + ut_params->cipher_xform.next = &ut_params->auth_xform; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->cipher_xform); + } else {/* Create Crypto session*/ + ut_params->auth_xform.next = &ut_params->cipher_xform; + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + } + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_gcm_xforms(struct rte_crypto_op *op, + enum rte_crypto_cipher_operation cipher_op, + uint8_t *key, const uint8_t key_len, + const uint8_t aad_len, const uint8_t auth_len, + enum rte_crypto_auth_operation auth_op) +{ + TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(op, 2), + "failed to allocate space for crypto transforms"); + + struct rte_crypto_sym_op *sym_op = op->sym; + + /* Setup Cipher Parameters */ + sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + sym_op->xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_GCM; + sym_op->xform->cipher.op = cipher_op; + sym_op->xform->cipher.key.data = key; + sym_op->xform->cipher.key.length = key_len; + + TEST_HEXDUMP(stdout, "key:", key, key_len); + + /* Setup Authentication Parameters */ + sym_op->xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH; + sym_op->xform->next->auth.algo = RTE_CRYPTO_AUTH_AES_GCM; + sym_op->xform->next->auth.op = auth_op; + sym_op->xform->next->auth.digest_length = auth_len; + sym_op->xform->next->auth.add_auth_data_length = aad_len; + sym_op->xform->next->auth.key.length = 0; + sym_op->xform->next->auth.key.data = NULL; + sym_op->xform->next->next = NULL; + + return 0; +} + +static int +create_gcm_operation(enum rte_crypto_cipher_operation op, + const struct gcm_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + uint8_t *plaintext, *ciphertext; + unsigned int iv_pad_len, aad_pad_len, plaintext_pad_len; + + /* 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"); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* Append aad data */ + aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); + sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + aad_pad_len); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, + "no room to append aad"); + + sym_op->auth.aad.length = tdata->aad.len; + sym_op->auth.aad.phys_addr = + rte_pktmbuf_mtophys(ut_params->ibuf); + memcpy(sym_op->auth.aad.data, tdata->aad.data, tdata->aad.len); + TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data, + sym_op->auth.aad.length); + + /* Prepend iv */ + iv_pad_len = RTE_ALIGN_CEIL(tdata->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"); + + memset(sym_op->cipher.iv.data, 0, iv_pad_len); + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = tdata->iv.len; + + rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, tdata->iv.len); + TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data, + sym_op->cipher.iv.length); + + /* Append plaintext/ciphertext */ + if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { + plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext"); + + memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len); + TEST_HEXDUMP(stdout, "plaintext:", plaintext, + tdata->plaintext.len); + + if (ut_params->obuf) { + ciphertext = (uint8_t *)rte_pktmbuf_append( + ut_params->obuf, + plaintext_pad_len + aad_pad_len + + iv_pad_len); + TEST_ASSERT_NOT_NULL(ciphertext, + "no room to append ciphertext"); + + memset(ciphertext + aad_pad_len + iv_pad_len, 0, + tdata->ciphertext.len); + } + } else { + plaintext_pad_len = RTE_ALIGN_CEIL(tdata->ciphertext.len, 16); + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + TEST_ASSERT_NOT_NULL(ciphertext, + "no room to append ciphertext"); + + memcpy(ciphertext, tdata->ciphertext.data, + tdata->ciphertext.len); + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, + tdata->ciphertext.len); + + if (ut_params->obuf) { + plaintext = (uint8_t *)rte_pktmbuf_append( + ut_params->obuf, + plaintext_pad_len + aad_pad_len + + iv_pad_len); + TEST_ASSERT_NOT_NULL(plaintext, + "no room to append plaintext"); + + memset(plaintext + aad_pad_len + iv_pad_len, 0, + tdata->plaintext.len); + } + } + + /* Append digest data */ + if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->obuf ? ut_params->obuf : + ut_params->ibuf, + tdata->auth_tag.len); + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append digest"); + memset(sym_op->auth.digest.data, 0, tdata->auth_tag.len); + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->obuf ? ut_params->obuf : + ut_params->ibuf, + plaintext_pad_len + + aad_pad_len + iv_pad_len); + sym_op->auth.digest.length = tdata->auth_tag.len; + } else { + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, tdata->auth_tag.len); + 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, + plaintext_pad_len + aad_pad_len + iv_pad_len); + sym_op->auth.digest.length = tdata->auth_tag.len; + + rte_memcpy(sym_op->auth.digest.data, tdata->auth_tag.data, + tdata->auth_tag.len); + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + } + + sym_op->cipher.data.length = tdata->plaintext.len; + sym_op->cipher.data.offset = aad_pad_len + iv_pad_len; + + sym_op->auth.data.length = tdata->plaintext.len; + sym_op->auth.data.offset = aad_pad_len + iv_pad_len; + + return 0; +} + +static int +test_mb_AES_GCM_authenticated_encryption(const struct gcm_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *ciphertext, *auth_tag; + uint16_t plaintext_pad_len; + uint32_t i; + + /* Create GCM session */ + retval = create_gcm_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + RTE_CRYPTO_AUTH_OP_GENERATE); + if (retval < 0) + return retval; + + if (tdata->aad.len > MBUF_SIZE) { + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool); + /* Populate full size of add data */ + for (i = 32; i < GCM_MAX_AAD_LENGTH; i += 32) + memcpy(&tdata->aad.data[i], &tdata->aad.data[0], 32); + } else + 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)); + + /* Create GCM operation */ + retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata); + if (retval < 0) + return retval; + + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + ut_params->op->sym->m_src = ut_params->ibuf; + + /* 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"); + + plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); + + if (ut_params->op->sym->m_dst) { + ciphertext = rte_pktmbuf_mtod(ut_params->op->sym->m_dst, + uint8_t *); + auth_tag = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, + uint8_t *, plaintext_pad_len); + } else { + ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, + uint8_t *, + ut_params->op->sym->cipher.data.offset); + auth_tag = ciphertext + plaintext_pad_len; + } + + 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, + tdata->ciphertext.data, + tdata->ciphertext.len, + "GCM Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + tdata->auth_tag.data, + tdata->auth_tag.len, + "GCM Generated auth tag not as expected"); + + return 0; + +} + +static int +test_mb_AES_GCM_authenticated_encryption_test_case_1(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_1); +} + +static int +test_mb_AES_GCM_authenticated_encryption_test_case_2(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_2); +} + +static int +test_mb_AES_GCM_authenticated_encryption_test_case_3(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_3); +} + +static int +test_mb_AES_GCM_authenticated_encryption_test_case_4(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_4); +} + +static int +test_mb_AES_GCM_authenticated_encryption_test_case_5(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_5); +} + +static int +test_mb_AES_GCM_authenticated_encryption_test_case_6(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_6); +} + +static int +test_mb_AES_GCM_authenticated_encryption_test_case_7(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_7); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_256_1(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_1); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_256_2(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_2); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_256_3(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_3); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_256_4(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_4); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_256_5(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_5); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_256_6(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_6); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_256_7(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_7); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_aad_1(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_aad_1); +} + +static int +test_mb_AES_GCM_auth_encryption_test_case_aad_2(void) +{ + return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_aad_2); +} + +static int +test_mb_AES_GCM_authenticated_decryption(const struct gcm_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *plaintext; + uint32_t i; + + /* Create GCM session */ + retval = create_gcm_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_DECRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + RTE_CRYPTO_AUTH_OP_VERIFY); + if (retval < 0) + return retval; + + /* alloc mbuf and set payload */ + if (tdata->aad.len > MBUF_SIZE) { + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool); + /* Populate full size of add data */ + for (i = 32; i < GCM_MAX_AAD_LENGTH; i += 32) + memcpy(&tdata->aad.data[i], &tdata->aad.data[0], 32); + } else + 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)); + + /* Create GCM operation */ + retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata); + if (retval < 0) + return retval; + + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + ut_params->op->sym->m_src = ut_params->ibuf; + + /* 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"); + + if (ut_params->op->sym->m_dst) + plaintext = rte_pktmbuf_mtod(ut_params->op->sym->m_dst, + uint8_t *); + else + plaintext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, + uint8_t *, + ut_params->op->sym->cipher.data.offset); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + plaintext, + tdata->plaintext.data, + tdata->plaintext.len, + "GCM plaintext data not as expected"); + + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_SUCCESS, + "GCM authentication failed"); + return 0; +} + +static int +test_mb_AES_GCM_authenticated_decryption_test_case_1(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_1); +} + +static int +test_mb_AES_GCM_authenticated_decryption_test_case_2(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_2); +} + +static int +test_mb_AES_GCM_authenticated_decryption_test_case_3(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_3); +} + +static int +test_mb_AES_GCM_authenticated_decryption_test_case_4(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_4); +} + +static int +test_mb_AES_GCM_authenticated_decryption_test_case_5(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_5); +} + +static int +test_mb_AES_GCM_authenticated_decryption_test_case_6(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_6); +} + +static int +test_mb_AES_GCM_authenticated_decryption_test_case_7(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_7); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_256_1(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_1); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_256_2(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_2); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_256_3(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_3); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_256_4(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_4); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_256_5(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_5); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_256_6(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_6); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_256_7(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_7); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_aad_1(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_aad_1); +} + +static int +test_mb_AES_GCM_auth_decryption_test_case_aad_2(void) +{ + return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_aad_2); +} + +static int +test_AES_GCM_authenticated_encryption_oop(const struct gcm_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *ciphertext, *auth_tag; + uint16_t plaintext_pad_len; + + /* Create GCM session */ + retval = create_gcm_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + RTE_CRYPTO_AUTH_OP_GENERATE); + 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)); + memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->obuf)); + + /* Create GCM operation */ + retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata); + if (retval < 0) + return retval; + + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + ut_params->op->sym->m_src = ut_params->ibuf; + ut_params->op->sym->m_dst = ut_params->obuf; + + /* 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"); + + plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); + + ciphertext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *, + ut_params->op->sym->cipher.data.offset); + auth_tag = ciphertext + plaintext_pad_len; + + 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, + tdata->ciphertext.data, + tdata->ciphertext.len, + "GCM Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + tdata->auth_tag.data, + tdata->auth_tag.len, + "GCM Generated auth tag not as expected"); + + return 0; + +} + +static int +test_mb_AES_GCM_authenticated_encryption_oop(void) +{ + return test_AES_GCM_authenticated_encryption_oop(&gcm_test_case_5); +} + +static int +test_AES_GCM_authenticated_decryption_oop(const struct gcm_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *plaintext; + + /* Create GCM session */ + retval = create_gcm_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_DECRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + RTE_CRYPTO_AUTH_OP_VERIFY); + if (retval < 0) + return retval; + + /* alloc mbuf and set payload */ + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->obuf)); + + /* Create GCM operation */ + retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata); + if (retval < 0) + return retval; + + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + ut_params->op->sym->m_src = ut_params->ibuf; + ut_params->op->sym->m_dst = ut_params->obuf; + + /* 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"); + + plaintext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *, + ut_params->op->sym->cipher.data.offset); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + plaintext, + tdata->plaintext.data, + tdata->plaintext.len, + "GCM plaintext data not as expected"); + + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_SUCCESS, + "GCM authentication failed"); + return 0; +} + +static int +test_mb_AES_GCM_authenticated_decryption_oop(void) +{ + return test_AES_GCM_authenticated_decryption_oop(&gcm_test_case_5); +} + +static int +test_AES_GCM_authenticated_encryption_sessionless( + const struct gcm_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *ciphertext, *auth_tag; + uint16_t plaintext_pad_len; + uint8_t key[tdata->key.len + 1]; + + 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)); + + /* Create GCM operation */ + retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata); + if (retval < 0) + return retval; + + /* Create GCM xforms */ + memcpy(key, tdata->key.data, tdata->key.len); + retval = create_gcm_xforms(ut_params->op, + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + key, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + RTE_CRYPTO_AUTH_OP_GENERATE); + if (retval < 0) + return retval; + + ut_params->op->sym->m_src = ut_params->ibuf; + + TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type, + RTE_CRYPTO_SYM_OP_SESSIONLESS, + "crypto op session type not sessionless"); + + /* 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_NOT_NULL(ut_params->op, "failed crypto process"); + + TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, + "crypto op status not success"); + + plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); + + ciphertext = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, + ut_params->op->sym->cipher.data.offset); + auth_tag = ciphertext + plaintext_pad_len; + + 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, + tdata->ciphertext.data, + tdata->ciphertext.len, + "GCM Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + tdata->auth_tag.data, + tdata->auth_tag.len, + "GCM Generated auth tag not as expected"); + + return 0; + +} + +static int +test_mb_AES_GCM_authenticated_encryption_sessionless(void) +{ + return test_AES_GCM_authenticated_encryption_sessionless( + &gcm_test_case_5); +} + +static int +test_AES_GCM_authenticated_decryption_sessionless( + const struct gcm_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *plaintext; + uint8_t key[tdata->key.len + 1]; + + /* 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)); + + /* Create GCM operation */ + retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata); + if (retval < 0) + return retval; + + /* Create GCM xforms */ + memcpy(key, tdata->key.data, tdata->key.len); + retval = create_gcm_xforms(ut_params->op, + RTE_CRYPTO_CIPHER_OP_DECRYPT, + key, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + RTE_CRYPTO_AUTH_OP_VERIFY); + if (retval < 0) + return retval; + + ut_params->op->sym->m_src = ut_params->ibuf; + + TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type, + RTE_CRYPTO_SYM_OP_SESSIONLESS, + "crypto op session type not sessionless"); + + /* 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_NOT_NULL(ut_params->op, "failed crypto process"); + + TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, + "crypto op status not success"); + + plaintext = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, + ut_params->op->sym->cipher.data.offset); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + plaintext, + tdata->plaintext.data, + tdata->plaintext.len, + "GCM plaintext data not as expected"); + + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_SUCCESS, + "GCM authentication failed"); + return 0; +} + +static int +test_mb_AES_GCM_authenticated_decryption_sessionless(void) +{ + return test_AES_GCM_authenticated_decryption_sessionless( + &gcm_test_case_5); +} + +static int +test_stats(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_stats stats; + struct rte_cryptodev *dev; + cryptodev_stats_get_t temp_pfn; + + rte_cryptodev_stats_reset(ts_params->valid_devs[0]); + TEST_ASSERT((rte_cryptodev_stats_get(ts_params->valid_devs[0] + 600, + &stats) == -ENODEV), + "rte_cryptodev_stats_get invalid dev failed"); + TEST_ASSERT((rte_cryptodev_stats_get(ts_params->valid_devs[0], 0) != 0), + "rte_cryptodev_stats_get invalid Param failed"); + dev = &rte_cryptodevs[ts_params->valid_devs[0]]; + temp_pfn = dev->dev_ops->stats_get; + dev->dev_ops->stats_get = (cryptodev_stats_get_t)0; + TEST_ASSERT((rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats) + == -ENOTSUP), + "rte_cryptodev_stats_get invalid Param failed"); + dev->dev_ops->stats_get = temp_pfn; + + /* Test expected values */ + ut_setup(); + test_AES_CBC_HMAC_SHA1_encrypt_digest(); + ut_teardown(); + TEST_ASSERT_SUCCESS(rte_cryptodev_stats_get(ts_params->valid_devs[0], + &stats), + "rte_cryptodev_stats_get failed"); + TEST_ASSERT((stats.enqueued_count == 1), + "rte_cryptodev_stats_get returned unexpected enqueued stat"); + TEST_ASSERT((stats.dequeued_count == 1), + "rte_cryptodev_stats_get returned unexpected enqueued stat"); + TEST_ASSERT((stats.enqueue_err_count == 0), + "rte_cryptodev_stats_get returned unexpected enqueued stat"); + TEST_ASSERT((stats.dequeue_err_count == 0), + "rte_cryptodev_stats_get returned unexpected enqueued stat"); + + /* invalid device but should ignore and not reset device stats*/ + rte_cryptodev_stats_reset(ts_params->valid_devs[0] + 300); + TEST_ASSERT_SUCCESS(rte_cryptodev_stats_get(ts_params->valid_devs[0], + &stats), + "rte_cryptodev_stats_get failed"); + TEST_ASSERT((stats.enqueued_count == 1), + "rte_cryptodev_stats_get returned unexpected enqueued stat"); + + /* check that a valid reset clears stats */ + rte_cryptodev_stats_reset(ts_params->valid_devs[0]); + TEST_ASSERT_SUCCESS(rte_cryptodev_stats_get(ts_params->valid_devs[0], + &stats), + "rte_cryptodev_stats_get failed"); + TEST_ASSERT((stats.enqueued_count == 0), + "rte_cryptodev_stats_get returned unexpected enqueued stat"); + TEST_ASSERT((stats.dequeued_count == 0), + "rte_cryptodev_stats_get returned unexpected enqueued stat"); + + return TEST_SUCCESS; +} + +static int MD5_HMAC_create_session(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + enum rte_crypto_auth_operation op, + const struct HMAC_MD5_vector *test_case) +{ + uint8_t key[64]; + + memcpy(key, test_case->key.data, test_case->key.len); + + 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_MD5_HMAC; + + ut_params->auth_xform.auth.digest_length = MD5_DIGEST_LEN; + ut_params->auth_xform.auth.add_auth_data_length = 0; + ut_params->auth_xform.auth.key.length = test_case->key.len; + ut_params->auth_xform.auth.key.data = key; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->valid_devs[0], &ut_params->auth_xform); + + if (ut_params->sess == NULL) + return TEST_FAILED; + + 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)); + + return 0; +} + +static int MD5_HMAC_create_op(struct crypto_unittest_params *ut_params, + const struct HMAC_MD5_vector *test_case, + uint8_t **plaintext) +{ + uint16_t plaintext_pad_len; + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + plaintext_pad_len = RTE_ALIGN_CEIL(test_case->plaintext.len, + 16); + + *plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + memcpy(*plaintext, test_case->plaintext.data, + test_case->plaintext.len); + + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, MD5_DIGEST_LEN); + 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, plaintext_pad_len); + sym_op->auth.digest.length = MD5_DIGEST_LEN; + + if (ut_params->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) { + rte_memcpy(sym_op->auth.digest.data, test_case->auth_tag.data, + test_case->auth_tag.len); + } + + sym_op->auth.data.offset = 0; + sym_op->auth.data.length = test_case->plaintext.len; + + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + ut_params->op->sym->m_src = ut_params->ibuf; + + return 0; +} + +static int +test_MD5_HMAC_generate(const struct HMAC_MD5_vector *test_case) +{ + uint16_t plaintext_pad_len; + uint8_t *plaintext, *auth_tag; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + if (MD5_HMAC_create_session(ts_params, ut_params, + RTE_CRYPTO_AUTH_OP_GENERATE, test_case)) + return TEST_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"); + + plaintext_pad_len = RTE_ALIGN_CEIL(test_case->plaintext.len, + 16); + + if (MD5_HMAC_create_op(ut_params, test_case, &plaintext)) + return TEST_FAILED; + + 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"); + + if (ut_params->op->sym->m_dst) { + auth_tag = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, + uint8_t *, plaintext_pad_len); + } else { + auth_tag = plaintext + plaintext_pad_len; + } + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + test_case->auth_tag.data, + test_case->auth_tag.len, + "HMAC_MD5 generated tag not as expected"); + + return TEST_SUCCESS; +} + +static int +test_MD5_HMAC_verify(const struct HMAC_MD5_vector *test_case) +{ + uint8_t *plaintext; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + if (MD5_HMAC_create_session(ts_params, ut_params, + RTE_CRYPTO_AUTH_OP_VERIFY, test_case)) { + return TEST_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"); + + if (MD5_HMAC_create_op(ut_params, test_case, &plaintext)) + return TEST_FAILED; + + 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, + "HMAC_MD5 crypto op processing failed"); + + return TEST_SUCCESS; +} + +static int +test_MD5_HMAC_generate_case_1(void) +{ + return test_MD5_HMAC_generate(&HMAC_MD5_test_case_1); +} + +static int +test_MD5_HMAC_verify_case_1(void) +{ + return test_MD5_HMAC_verify(&HMAC_MD5_test_case_1); +} + +static int +test_MD5_HMAC_generate_case_2(void) +{ + return test_MD5_HMAC_generate(&HMAC_MD5_test_case_2); +} + +static int +test_MD5_HMAC_verify_case_2(void) +{ + return test_MD5_HMAC_verify(&HMAC_MD5_test_case_2); +} + +static int +test_multi_session(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_sym_session **sessions; + + uint16_t i; + + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params, + aes_cbc_key, hmac_sha512_key); + + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + sessions = rte_malloc(NULL, + (sizeof(struct rte_cryptodev_sym_session *) * + dev_info.sym.max_nb_sessions) + 1, 0); + + /* Create multiple crypto sessions*/ + for (i = 0; i < dev_info.sym.max_nb_sessions; i++) { + sessions[i] = rte_cryptodev_sym_session_create( + ts_params->valid_devs[0], + &ut_params->auth_xform); + TEST_ASSERT_NOT_NULL(sessions[i], + "Session creation failed at session number %u", + i); + + /* Attempt to send a request on each session */ + TEST_ASSERT_SUCCESS( test_AES_CBC_HMAC_SHA512_decrypt_perform( + sessions[i], + ut_params, + ts_params, + catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + aes_cbc_iv), + "Failed to perform decrypt on request number %u.", i); + /* free crypto operation structure */ + if (ut_params->op) + rte_crypto_op_free(ut_params->op); + + /* + * free mbuf - both obuf and ibuf are usually the same, + * 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 */ + sessions[i] = rte_cryptodev_sym_session_create(ts_params->valid_devs[0], + &ut_params->auth_xform); + TEST_ASSERT_NULL(sessions[i], + "Session creation succeeded unexpectedly!"); + + for (i = 0; i < dev_info.sym.max_nb_sessions; i++) + rte_cryptodev_sym_session_free(ts_params->valid_devs[0], + sessions[i]); + + rte_free(sessions); + + return TEST_SUCCESS; +} + +struct multi_session_params { + struct crypto_unittest_params ut_params; + uint8_t *cipher_key; + uint8_t *hmac_key; + const uint8_t *cipher; + const uint8_t *digest; + uint8_t *iv; +}; + +#define MB_SESSION_NUMBER 3 + +static int +test_multi_session_random_usage(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_sym_session **sessions; + uint32_t i, j; + struct multi_session_params ut_paramz[] = { + + { + .cipher_key = ms_aes_cbc_key0, + .hmac_key = ms_hmac_key0, + .cipher = ms_aes_cbc_cipher0, + .digest = ms_hmac_digest0, + .iv = ms_aes_cbc_iv0 + }, + { + .cipher_key = ms_aes_cbc_key1, + .hmac_key = ms_hmac_key1, + .cipher = ms_aes_cbc_cipher1, + .digest = ms_hmac_digest1, + .iv = ms_aes_cbc_iv1 + }, + { + .cipher_key = ms_aes_cbc_key2, + .hmac_key = ms_hmac_key2, + .cipher = ms_aes_cbc_cipher2, + .digest = ms_hmac_digest2, + .iv = ms_aes_cbc_iv2 + }, + + }; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + sessions = rte_malloc(NULL, + (sizeof(struct rte_cryptodev_sym_session *) + * dev_info.sym.max_nb_sessions) + 1, 0); + + for (i = 0; i < MB_SESSION_NUMBER; i++) { + rte_memcpy(&ut_paramz[i].ut_params, &testsuite_params, + sizeof(struct crypto_unittest_params)); + + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + &ut_paramz[i].ut_params, + ut_paramz[i].cipher_key, ut_paramz[i].hmac_key); + + /* Create multiple crypto sessions*/ + sessions[i] = rte_cryptodev_sym_session_create( + ts_params->valid_devs[0], + &ut_paramz[i].ut_params.auth_xform); + + TEST_ASSERT_NOT_NULL(sessions[i], + "Session creation failed at session number %u", + i); + + } + + srand(time(NULL)); + for (i = 0; i < 40000; i++) { + + j = rand() % MB_SESSION_NUMBER; + + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform( + sessions[j], + &ut_paramz[j].ut_params, + ts_params, ut_paramz[j].cipher, + ut_paramz[j].digest, + ut_paramz[j].iv), + "Failed to perform decrypt on request number %u.", i); + + if (ut_paramz[j].ut_params.op) + rte_crypto_op_free(ut_paramz[j].ut_params.op); + + /* + * free mbuf - both obuf and ibuf are usually the same, + * so check if they point at the same address is necessary, + * to avoid freeing the mbuf twice. + */ + if (ut_paramz[j].ut_params.obuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.obuf); + if (ut_paramz[j].ut_params.ibuf + == ut_paramz[j].ut_params.obuf) + ut_paramz[j].ut_params.ibuf = 0; + ut_paramz[j].ut_params.obuf = 0; + } + if (ut_paramz[j].ut_params.ibuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.ibuf); + ut_paramz[j].ut_params.ibuf = 0; + } + } + + for (i = 0; i < MB_SESSION_NUMBER; i++) + rte_cryptodev_sym_session_free(ts_params->valid_devs[0], + sessions[i]); + + rte_free(sessions); + + return TEST_SUCCESS; +} + +static int +test_null_cipher_only_operation(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 = NULL; + + ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_NULL; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + /* 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"); + + /* 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->cipher.data.offset = 0; + 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_src, uint8_t *), + catch_22_quote, + QUOTE_512_BYTES, + "Ciphertext data not as expected"); + + return TEST_SUCCESS; +} + +static int +test_null_auth_only_operation(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 HMAC Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.next = NULL; + + ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_NULL; + ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + + /* 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; + + sym_op->m_src = ut_params->ibuf; + + sym_op->auth.data.offset = 0; + 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, "no crypto operation returned"); + + TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, + "crypto operation processing failed"); + + return TEST_SUCCESS; +} + +static int +test_null_cipher_auth_operation(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_NULL; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + /* Setup HMAC Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.next = NULL; + + ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_NULL; + ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + + /* 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"); + + /* 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; + + sym_op->m_src = ut_params->ibuf; + + sym_op->cipher.data.offset = 0; + sym_op->cipher.data.length = QUOTE_512_BYTES; + + sym_op->auth.data.offset = 0; + 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, "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_src, uint8_t *), + catch_22_quote, + QUOTE_512_BYTES, + "Ciphertext data not as expected"); + + return TEST_SUCCESS; +} + +static int +test_null_auth_cipher_operation(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 = NULL; + + ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_NULL; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + /* 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.algo = RTE_CRYPTO_AUTH_NULL; + ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + + /* 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"); + + /* 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; + + sym_op->m_src = ut_params->ibuf; + + sym_op->cipher.data.offset = 0; + sym_op->cipher.data.length = QUOTE_512_BYTES; + + sym_op->auth.data.offset = 0; + 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, "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_src, uint8_t *), + catch_22_quote, + QUOTE_512_BYTES, + "Ciphertext data not as expected"); + + return TEST_SUCCESS; +} + + +static int +test_null_invalid_operation(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + /* 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_ENCRYPT; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->valid_devs[0], &ut_params->cipher_xform); + TEST_ASSERT_NULL(ut_params->sess, + "Session creation succeeded unexpectedly"); + + + /* Setup HMAC Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.next = NULL; + + ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; + ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->valid_devs[0], &ut_params->auth_xform); + TEST_ASSERT_NULL(ut_params->sess, + "Session creation succeeded unexpectedly"); + + return TEST_SUCCESS; +} + + +#define NULL_BURST_LENGTH (32) + +static int +test_null_burst_operation(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + unsigned i, burst_len = NULL_BURST_LENGTH; + + struct rte_crypto_op *burst[NULL_BURST_LENGTH] = { NULL }; + struct rte_crypto_op *burst_dequeued[NULL_BURST_LENGTH] = { NULL }; + + /* 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_NULL; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + /* Setup HMAC Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.next = NULL; + + ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_NULL; + ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + + /* 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"); + + TEST_ASSERT_EQUAL(rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, burst, burst_len), + burst_len, "failed to generate burst of crypto ops"); + + /* Generate an operation for each mbuf in burst */ + for (i = 0; i < burst_len; i++) { + struct rte_mbuf *m = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + TEST_ASSERT_NOT_NULL(m, "Failed to allocate mbuf"); + + unsigned *data = (unsigned *)rte_pktmbuf_append(m, + sizeof(unsigned)); + *data = i; + + rte_crypto_op_attach_sym_session(burst[i], ut_params->sess); + + burst[i]->sym->m_src = m; + } + + /* Process crypto operation */ + TEST_ASSERT_EQUAL(rte_cryptodev_enqueue_burst(ts_params->valid_devs[0], + 0, burst, burst_len), + burst_len, + "Error enqueuing burst"); + + TEST_ASSERT_EQUAL(rte_cryptodev_dequeue_burst(ts_params->valid_devs[0], + 0, burst_dequeued, burst_len), + burst_len, + "Error dequeuing burst"); + + + for (i = 0; i < burst_len; i++) { + TEST_ASSERT_EQUAL( + *rte_pktmbuf_mtod(burst[i]->sym->m_src, uint32_t *), + *rte_pktmbuf_mtod(burst_dequeued[i]->sym->m_src, + uint32_t *), + "data not as expected"); + + rte_pktmbuf_free(burst[i]->sym->m_src); + rte_crypto_op_free(burst[i]); + } + + return TEST_SUCCESS; +} + +static void +generate_gmac_large_plaintext(uint8_t *data) +{ + uint16_t i; + + for (i = 32; i < GMAC_LARGE_PLAINTEXT_LENGTH; i += 32) + memcpy(&data[i], &data[0], 32); +} + +static int +create_gmac_operation(enum rte_crypto_auth_operation op, + const struct gmac_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + struct rte_crypto_sym_op *sym_op; + + unsigned iv_pad_len; + unsigned aad_pad_len; + + iv_pad_len = RTE_ALIGN_CEIL(tdata->iv.len, 16); + aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); + + /* + * Runtime generate the large plain text instead of use hard code + * plain text vector. It is done to avoid create huge source file + * with the test vector. + */ + if (tdata->aad.len == GMAC_LARGE_PLAINTEXT_LENGTH) + generate_gmac_large_plaintext(tdata->aad.data); + + /* 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"); + + sym_op = ut_params->op->sym; + sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + aad_pad_len); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, + "no room to append aad"); + + sym_op->auth.aad.length = tdata->aad.len; + sym_op->auth.aad.phys_addr = + rte_pktmbuf_mtophys(ut_params->ibuf); + memcpy(sym_op->auth.aad.data, tdata->aad.data, tdata->aad.len); + + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, tdata->gmac_tag.len); + 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, aad_pad_len); + sym_op->auth.digest.length = tdata->gmac_tag.len; + + if (op == RTE_CRYPTO_AUTH_OP_VERIFY) { + rte_memcpy(sym_op->auth.digest.data, tdata->gmac_tag.data, + tdata->gmac_tag.len); + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + } + + 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"); + + memset(sym_op->cipher.iv.data, 0, iv_pad_len); + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = tdata->iv.len; + + rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, tdata->iv.len); + + TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data, iv_pad_len); + + sym_op->cipher.data.length = 0; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.offset = 0; + sym_op->auth.data.length = 0; + + return 0; +} + +static int create_gmac_session(uint8_t dev_id, + enum rte_crypto_cipher_operation op, + const struct gmac_test_data *tdata, + enum rte_crypto_auth_operation auth_op) +{ + uint8_t cipher_key[tdata->key.len]; + + struct crypto_unittest_params *ut_params = &unittest_params; + + memcpy(cipher_key, tdata->key.data, tdata->key.len); + + /* For GMAC we 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_GCM; + ut_params->cipher_xform.cipher.op = op; + ut_params->cipher_xform.cipher.key.data = cipher_key; + ut_params->cipher_xform.cipher.key.length = tdata->key.len; + + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.next = NULL; + + ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_AES_GMAC; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.auth.digest_length = tdata->gmac_tag.len; + ut_params->auth_xform.auth.add_auth_data_length = 0; + ut_params->auth_xform.auth.key.length = 0; + ut_params->auth_xform.auth.key.data = NULL; + + ut_params->cipher_xform.next = &ut_params->auth_xform; + + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->cipher_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +test_AES_GMAC_authentication(const struct gmac_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + + uint8_t *auth_tag, *p; + uint16_t aad_pad_len; + + TEST_ASSERT_NOT_EQUAL(tdata->gmac_tag.len, 0, + "No GMAC length in the source data"); + + retval = create_gmac_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + tdata, RTE_CRYPTO_AUTH_OP_GENERATE); + + if (retval < 0) + return retval; + + if (tdata->aad.len > MBUF_SIZE) + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool); + else + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); + + p = rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *); + + retval = create_gmac_operation(RTE_CRYPTO_AUTH_OP_GENERATE, + tdata); + + if (retval < 0) + return retval; + + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + ut_params->op->sym->m_src = ut_params->ibuf; + + 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"); + + if (ut_params->op->sym->m_dst) { + auth_tag = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, + uint8_t *, aad_pad_len); + } else { + auth_tag = p + aad_pad_len; + } + + TEST_HEXDUMP(stdout, "auth tag:", auth_tag, tdata->gmac_tag.len); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + tdata->gmac_tag.data, + tdata->gmac_tag.len, + "GMAC Generated auth tag not as expected"); + + return 0; +} + +static int +test_AES_GMAC_authentication_test_case_1(void) +{ + return test_AES_GMAC_authentication(&gmac_test_case_1); +} + +static int +test_AES_GMAC_authentication_test_case_2(void) +{ + return test_AES_GMAC_authentication(&gmac_test_case_2); +} + +static int +test_AES_GMAC_authentication_test_case_3(void) +{ + return test_AES_GMAC_authentication(&gmac_test_case_3); +} + +static int +test_AES_GMAC_authentication_test_case_4(void) +{ + return test_AES_GMAC_authentication(&gmac_test_case_4); +} + +static int +test_AES_GMAC_authentication_verify(const struct gmac_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + int retval; + + TEST_ASSERT_NOT_EQUAL(tdata->gmac_tag.len, 0, + "No GMAC length in the source data"); + + retval = create_gmac_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_DECRYPT, + tdata, RTE_CRYPTO_AUTH_OP_VERIFY); + + if (retval < 0) + return retval; + + if (tdata->aad.len > MBUF_SIZE) + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool); + else + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + retval = create_gmac_operation(RTE_CRYPTO_AUTH_OP_VERIFY, + tdata); + + if (retval < 0) + return retval; + + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + ut_params->op->sym->m_src = ut_params->ibuf; + + 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"); + + return 0; + +} + +static int +test_AES_GMAC_authentication_verify_test_case_1(void) +{ + return test_AES_GMAC_authentication_verify(&gmac_test_case_1); +} + +static int +test_AES_GMAC_authentication_verify_test_case_2(void) +{ + return test_AES_GMAC_authentication_verify(&gmac_test_case_2); +} + +static int +test_AES_GMAC_authentication_verify_test_case_3(void) +{ + return test_AES_GMAC_authentication_verify(&gmac_test_case_3); +} + +static int +test_AES_GMAC_authentication_verify_test_case_4(void) +{ + return test_AES_GMAC_authentication_verify(&gmac_test_case_4); +} + +struct test_crypto_vector { + enum rte_crypto_cipher_algorithm crypto_algo; + + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; + + struct { + uint8_t data[64]; + unsigned int len; + } iv; + + struct { + const uint8_t *data; + unsigned int len; + } plaintext; + + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + const uint8_t *data; + unsigned int len; + } aad; + + struct { + uint8_t data[128]; + unsigned int len; + } digest; +}; + +static const struct test_crypto_vector +hmac_sha1_test_crypto_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .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 = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct test_crypto_vector +aes128_gmac_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_AES_GMAC, + .crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .aad = { + .data = plaintext_hash, + .len = 512 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B + }, + .len = 12 + }, + .cipher_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x00, 0x99, 0x8B, 0x30, 0x7E, 0x74, 0x56, + 0x32, 0xA7, 0x87, 0xB5, 0xE9, 0xB2, 0x34, 0x5A + }, + .len = 16 + } +}; + +static const struct test_crypto_vector +aes128cbc_hmac_sha1_test_vector = { + .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 = plaintext_hash, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .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 + } +}; + +static void +data_corruption(uint8_t *data) +{ + data[0] += 1; +} + +static void +tag_corruption(uint8_t *data, unsigned int tag_offset) +{ + data[tag_offset] += 1; +} + +static int +create_auth_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op) +{ + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = NULL; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_cipher_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op, + enum rte_crypto_cipher_operation cipher_op) +{ + uint8_t cipher_key[reference->cipher_key.len + 1]; + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(cipher_key, reference->cipher_key.data, + reference->cipher_key.len); + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + 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 = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* 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 = reference->crypto_algo; + ut_params->cipher_xform.cipher.op = cipher_op; + ut_params->cipher_xform.cipher.key.data = cipher_key; + ut_params->cipher_xform.cipher.key.length = reference->cipher_key.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* 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 pktmbuf offload"); + + /* 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; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->plaintext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->auth.data.length = reference->plaintext.len; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_auth_GMAC_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* 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 pktmbuf offload"); + + /* 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; + + /* aad */ + sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->aad.len); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, "no room to append AAD"); + memcpy(sym_op->auth.aad.data, reference->aad.data, reference->aad.len); + + TEST_HEXDUMP(stdout, "AAD:", sym_op->auth.aad.data, reference->aad.len); + + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->auth.aad.length = reference->aad.len; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = 0; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.length = 0; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_cipher_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* 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 pktmbuf offload"); + + /* 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; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = reference->ciphertext.len; + sym_op->cipher.data.offset = reference->iv.len; + + sym_op->auth.data.length = reference->ciphertext.len; + sym_op->auth.data.offset = reference->iv.len; + + return 0; +} + +static int +create_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +create_auth_verify_GMAC_operation( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_GMAC_operation(ts_params, ut_params, reference, 0); +} + +static int +create_cipher_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_cipher_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_fail_when_data_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *plaintext; + + /* Create session */ + retval = create_auth_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->plaintext.len); + TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext"); + memcpy(plaintext, reference->plaintext.data, reference->plaintext.len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len); + + /* Create operation */ + retval = create_auth_verify_operation(ts_params, ut_params, reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(plaintext); + else + tag_corruption(plaintext, reference->plaintext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_GMAC_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + /* Create operation */ + retval = create_auth_verify_GMAC_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ut_params->op->sym->auth.aad.data); + else + tag_corruption(ut_params->op->sym->auth.aad.data, + reference->aad.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authenticated_decryption_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *ciphertext; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->ciphertext.len); + TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext"); + memcpy(ciphertext, reference->ciphertext.data, + reference->ciphertext.len); + + /* Create operation */ + retval = create_cipher_auth_verify_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ciphertext); + else + tag_corruption(ciphertext, reference->ciphertext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +create_gcm_operation_SGL(enum rte_crypto_cipher_operation op, + const struct gcm_test_data *tdata, + void *digest_mem, uint64_t digest_phys) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + const unsigned int auth_tag_len = tdata->auth_tag.len; + const unsigned int iv_len = tdata->iv.len; + const unsigned int aad_len = tdata->aad.len; + + unsigned int iv_pad_len = 0; + + /* 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"); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + sym_op->auth.digest.data = digest_mem; + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append digest"); + + sym_op->auth.digest.phys_addr = digest_phys; + sym_op->auth.digest.length = auth_tag_len; + + if (op == RTE_CRYPTO_CIPHER_OP_DECRYPT) { + rte_memcpy(sym_op->auth.digest.data, tdata->auth_tag.data, + auth_tag_len); + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + } + + 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"); + + memset(sym_op->cipher.iv.data, 0, iv_pad_len); + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = iv_len; + + rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, iv_pad_len); + + sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, aad_len); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, + "no room to prepend aad"); + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys( + ut_params->ibuf); + sym_op->auth.aad.length = aad_len; + + memset(sym_op->auth.aad.data, 0, aad_len); + rte_memcpy(sym_op->auth.aad.data, tdata->aad.data, aad_len); + + 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 = tdata->plaintext.len; + sym_op->cipher.data.offset = aad_len + iv_pad_len; + + sym_op->auth.data.offset = aad_len + iv_pad_len; + sym_op->auth.data.length = tdata->plaintext.len; + + return 0; +} + +#define SGL_MAX_NO 16 + +static int +test_AES_GCM_authenticated_encryption_SGL(const struct gcm_test_data *tdata, + const int oop, uint32_t fragsz, uint32_t fragsz_oop) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + struct rte_mbuf *buf, *buf_oop = NULL, *buf_last_oop = NULL; + int retval; + int to_trn = 0; + int to_trn_tbl[SGL_MAX_NO]; + int segs = 1; + unsigned int trn_data = 0; + uint8_t *plaintext, *ciphertext, *auth_tag; + + if (fragsz > tdata->plaintext.len) + fragsz = tdata->plaintext.len; + + uint16_t plaintext_len = fragsz; + uint16_t frag_size_oop = fragsz_oop ? fragsz_oop : fragsz; + + if (fragsz_oop > tdata->plaintext.len) + frag_size_oop = tdata->plaintext.len; + + int ecx = 0; + void *digest_mem = NULL; + + uint32_t prepend_len = ALIGN_POW2_ROUNDUP(tdata->iv.len, 16) + + tdata->aad.len; + + if (tdata->plaintext.len % fragsz != 0) { + if (tdata->plaintext.len / fragsz + 1 > SGL_MAX_NO) + return 1; + } else { + if (tdata->plaintext.len / fragsz > SGL_MAX_NO) + return 1; + } + + /* + * For out-op-place we need to alloc another mbuf + */ + if (oop) { + ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + rte_pktmbuf_append(ut_params->obuf, + frag_size_oop + prepend_len); + buf_oop = ut_params->obuf; + } + + /* Create GCM session */ + retval = create_gcm_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + RTE_CRYPTO_AUTH_OP_GENERATE); + 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 = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_len); + + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + trn_data += plaintext_len; + + buf = ut_params->ibuf; + + /* + * Loop until no more fragments + */ + + while (trn_data < tdata->plaintext.len) { + ++segs; + to_trn = (tdata->plaintext.len - trn_data < fragsz) ? + (tdata->plaintext.len - trn_data) : fragsz; + + to_trn_tbl[ecx++] = to_trn; + + buf->next = rte_pktmbuf_alloc(ts_params->mbuf_pool); + buf = buf->next; + + memset(rte_pktmbuf_mtod(buf, uint8_t *), 0, + rte_pktmbuf_tailroom(buf)); + + /* OOP */ + if (oop && !fragsz_oop) { + buf_last_oop = buf_oop->next = + rte_pktmbuf_alloc(ts_params->mbuf_pool); + buf_oop = buf_oop->next; + memset(rte_pktmbuf_mtod(buf_oop, uint8_t *), + 0, rte_pktmbuf_tailroom(buf_oop)); + rte_pktmbuf_append(buf_oop, to_trn); + } + + plaintext = (uint8_t *)rte_pktmbuf_append(buf, + to_trn); + + memcpy(plaintext, tdata->plaintext.data + trn_data, + to_trn); + trn_data += to_trn; + if (trn_data == tdata->plaintext.len) { + if (oop) { + if (!fragsz_oop) + digest_mem = rte_pktmbuf_append(buf_oop, + tdata->auth_tag.len); + } else + digest_mem = (uint8_t *)rte_pktmbuf_append(buf, + tdata->auth_tag.len); + } + } + + uint64_t digest_phys = 0; + + ut_params->ibuf->nb_segs = segs; + + segs = 1; + if (fragsz_oop && oop) { + to_trn = 0; + ecx = 0; + + if (frag_size_oop == tdata->plaintext.len) { + digest_mem = rte_pktmbuf_append(ut_params->obuf, + tdata->auth_tag.len); + + digest_phys = rte_pktmbuf_mtophys_offset( + ut_params->obuf, + tdata->plaintext.len + prepend_len); + } + + trn_data = frag_size_oop; + while (trn_data < tdata->plaintext.len) { + ++segs; + to_trn = + (tdata->plaintext.len - trn_data < + frag_size_oop) ? + (tdata->plaintext.len - trn_data) : + frag_size_oop; + + to_trn_tbl[ecx++] = to_trn; + + buf_last_oop = buf_oop->next = + rte_pktmbuf_alloc(ts_params->mbuf_pool); + buf_oop = buf_oop->next; + memset(rte_pktmbuf_mtod(buf_oop, uint8_t *), + 0, rte_pktmbuf_tailroom(buf_oop)); + rte_pktmbuf_append(buf_oop, to_trn); + + trn_data += to_trn; + + if (trn_data == tdata->plaintext.len) { + digest_mem = rte_pktmbuf_append(buf_oop, + tdata->auth_tag.len); + } + } + + ut_params->obuf->nb_segs = segs; + } + + /* + * Place digest at the end of the last buffer + */ + if (!digest_phys) + digest_phys = rte_pktmbuf_mtophys(buf) + to_trn; + if (oop && buf_last_oop) + digest_phys = rte_pktmbuf_mtophys(buf_last_oop) + to_trn; + + if (!digest_mem && !oop) { + digest_mem = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + + tdata->auth_tag.len); + digest_phys = rte_pktmbuf_mtophys_offset(ut_params->ibuf, + tdata->plaintext.len); + } + + /* Create GCM opertaion */ + retval = create_gcm_operation_SGL(RTE_CRYPTO_CIPHER_OP_ENCRYPT, + tdata, digest_mem, digest_phys); + + if (retval < 0) + return retval; + + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + ut_params->op->sym->m_src = ut_params->ibuf; + if (oop) + ut_params->op->sym->m_dst = ut_params->obuf; + + /* 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"); + + + ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, + uint8_t *, prepend_len); + if (oop) { + ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, + uint8_t *, prepend_len); + } + + if (fragsz_oop) + fragsz = fragsz_oop; + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ciphertext, + tdata->ciphertext.data, + fragsz, + "GCM Ciphertext data not as expected"); + + buf = ut_params->op->sym->m_src->next; + if (oop) + buf = ut_params->op->sym->m_dst->next; + + unsigned int off = fragsz; + + ecx = 0; + while (buf) { + ciphertext = rte_pktmbuf_mtod(buf, + uint8_t *); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ciphertext, + tdata->ciphertext.data + off, + to_trn_tbl[ecx], + "GCM Ciphertext data not as expected"); + + off += to_trn_tbl[ecx++]; + buf = buf->next; + } + + auth_tag = digest_mem; + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + tdata->auth_tag.data, + tdata->auth_tag.len, + "GCM Generated auth tag not as expected"); + + return 0; +} + +#define IN_PLACE 0 +#define OUT_OF_PLACE 1 + +static int +test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_400B(void) +{ + return test_AES_GCM_authenticated_encryption_SGL( + &gcm_test_case_SGL_1, OUT_OF_PLACE, 400, 400); +} + +static int +test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B(void) +{ + return test_AES_GCM_authenticated_encryption_SGL( + &gcm_test_case_SGL_1, OUT_OF_PLACE, 1500, 2000); +} + +static int +test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg(void) +{ + return test_AES_GCM_authenticated_encryption_SGL( + &gcm_test_case_8, OUT_OF_PLACE, 400, + gcm_test_case_8.plaintext.len); +} + +static int +test_AES_GCM_auth_encrypt_SGL_in_place_1500B(void) +{ + + return test_AES_GCM_authenticated_encryption_SGL( + &gcm_test_case_SGL_1, IN_PLACE, 1500, 0); +} + +static int +test_authentication_verify_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_GMAC_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_GMAC_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authenticated_decryption_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authenticated_decryption_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +authentication_verify_HMAC_SHA1_fail_data_corrupt(void) +{ + return test_authentication_verify_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_HMAC_SHA1_fail_tag_corrupt(void) +{ + return test_authentication_verify_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_data_corrupt(void) +{ + return test_authentication_verify_GMAC_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_tag_corrupt(void) +{ + return test_authentication_verify_GMAC_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt(void) +{ + return test_authenticated_decryption_fail_when_data_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt(void) +{ + return test_authenticated_decryption_fail_when_tag_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER + +/* global AESNI slave IDs for the scheduler test */ +uint8_t aesni_ids[2]; + +static int +test_scheduler_attach_slave_op(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + uint8_t sched_id = ts_params->valid_devs[0]; + uint32_t nb_devs, qp_id, i, nb_devs_attached = 0; + int ret; + struct rte_cryptodev_config config = { + .nb_queue_pairs = 8, + .socket_id = SOCKET_ID_ANY, + .session_mp = { + .nb_objs = 2048, + .cache_size = 256 + } + }; + struct rte_cryptodev_qp_conf qp_conf = {2048}; + + /* create 2 AESNI_MB if necessary */ + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_AESNI_MB_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + } + } + + /* attach 2 AESNI_MB cdevs */ + for (i = 0; i < rte_cryptodev_count() && nb_devs_attached < 2; + i++) { + struct rte_cryptodev_info info; + + rte_cryptodev_info_get(i, &info); + if (info.dev_type != RTE_CRYPTODEV_AESNI_MB_PMD) + continue; + + ret = rte_cryptodev_configure(i, &config); + TEST_ASSERT(ret == 0, + "Failed to configure device %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + + for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + i, qp_id, &qp_conf, + rte_cryptodev_socket_id(i)), + "Failed to setup queue pair %u on " + "cryptodev %u", qp_id, i); + } + + ret = rte_cryptodev_scheduler_slave_attach(sched_id, + (uint8_t)i); + + TEST_ASSERT(ret == 0, + "Failed to attach device %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + + aesni_ids[nb_devs_attached] = (uint8_t)i; + + nb_devs_attached++; + } + + return 0; +} + +static int +test_scheduler_detach_slave_op(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + uint8_t sched_id = ts_params->valid_devs[0]; + uint32_t i; + int ret; + + for (i = 0; i < 2; i++) { + ret = rte_cryptodev_scheduler_slave_detach(sched_id, + aesni_ids[i]); + TEST_ASSERT(ret == 0, + "Failed to detach device %u", aesni_ids[i]); + } + + return 0; +} + +static int +test_scheduler_mode_op(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + uint8_t sched_id = ts_params->valid_devs[0]; + struct rte_cryptodev_scheduler_ops op = {0}; + struct rte_cryptodev_scheduler dummy_scheduler = { + .description = "dummy scheduler to test mode", + .name = "dummy scheduler", + .mode = CDEV_SCHED_MODE_USERDEFINED, + .ops = &op + }; + int ret; + + /* set user defined mode */ + ret = rte_cryptodev_scheduler_load_user_scheduler(sched_id, + &dummy_scheduler); + TEST_ASSERT(ret == 0, + "Failed to set cdev %u to user defined mode", sched_id); + + /* set round robin mode */ + ret = rte_crpytodev_scheduler_mode_set(sched_id, + CDEV_SCHED_MODE_ROUNDROBIN); + TEST_ASSERT(ret == 0, + "Failed to set cdev %u to round-robin mode", sched_id); + TEST_ASSERT(rte_crpytodev_scheduler_mode_get(sched_id) == + CDEV_SCHED_MODE_ROUNDROBIN, "Scheduling Mode " + "not match"); + + return 0; +} + +static struct unit_test_suite cryptodev_scheduler_testsuite = { + .suite_name = "Crypto Device Scheduler Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), + TEST_CASE_ST(NULL, NULL, test_scheduler_mode_op), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_chain_scheduler_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_scheduler_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_scheduler_all), + TEST_CASE_ST(NULL, NULL, test_scheduler_detach_slave_op), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +#endif /* RTE_LIBRTE_PMD_CRYPTO_SCHEDULER */ + +static struct unit_test_suite cryptodev_qat_testsuite = { + .suite_name = "Crypto QAT Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_dev_id), + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_queue_pair_ids), + TEST_CASE_ST(ut_setup, ut_teardown, + test_queue_pair_descriptor_setup), + TEST_CASE_ST(ut_setup, ut_teardown, + test_multi_session), + + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_DES_cipheronly_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_stats), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encrypt_SGL_in_place_1500B), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_400B), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + + /** SNOW 3G encrypt only (UEA2) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_4), + 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), + + /** SNOW 3G decrypt only (UEA2) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_generate_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_generate_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_generate_test_case_3), + 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), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_cipher_auth_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_auth_cipher_test_case_1), + + /** HMAC_MD5 Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_MD5_HMAC_generate_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_MD5_HMAC_verify_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_MD5_HMAC_generate_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_MD5_HMAC_verify_case_2), + + /** NULL tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_auth_only_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_cipher_only_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_cipher_auth_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_auth_cipher_operation), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_6), + + /** KASUMI tests */ + 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_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_auth_cipher_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_cipher_auth_test_case_1), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_tag_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_tag_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_aesni_mb_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_AES_chain_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_cipheronly_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_mb_all), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_openssl_testsuite = { + .suite_name = "Crypto Device OPENSSL Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), + TEST_CASE_ST(ut_setup, ut_teardown, + test_multi_session_random_usage), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_chain_openssl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_openssl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_chain_openssl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_openssl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_openssl_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_4), + + /** Scatter-Gather */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_tag_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_tag_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_aesni_gcm_testsuite = { + .suite_name = "Crypto Device AESNI GCM Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GCM Authenticated Encryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_256_7), + + /** AES GCM Authenticated Decryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_256_7), + + /** AES GCM Authenticated Encryption big aad size */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_aad_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_encryption_test_case_aad_2), + + /** AES GCM Authenticated Decryption big aad size */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_aad_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_auth_decryption_test_case_aad_2), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_4), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_tag_corrupt), + + /** Out of place tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_oop), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_oop), + + /** Session-less tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_sessionless), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_sessionless), + + /** Scatter-Gather */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +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_1_sgl), + 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_encryption_test_case_1_oop_sgl), + + + 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_generate_test_case_6), + 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_CASE_ST(ut_setup, ut_teardown, + test_kasumi_auth_cipher_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_cipher_auth_test_case_1), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; +static struct unit_test_suite cryptodev_sw_snow3g_testsuite = { + .suite_name = "Crypto Device SW SNOW 3G Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + /** SNOW 3G encrypt only (UEA2) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_4), + 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_encryption_test_case_1_oop_sgl), + 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), + + /** SNOW 3G decrypt only (UEA2) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_generate_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + 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_cipher_auth_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_auth_cipher_test_case_1), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_sw_zuc_testsuite = { + .suite_name = "Crypto Device SW ZUC Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + /** ZUC encrypt only (EEA3) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_hash_generate_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_hash_generate_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_hash_generate_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_hash_generate_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_hash_generate_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_encryption_test_case_6_sgl), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_null_testsuite = { + .suite_name = "Crypto Device NULL Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_auth_only_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_cipher_only_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_cipher_auth_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_auth_cipher_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_invalid_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_burst_operation), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_armv8_testsuite = { + .suite_name = "Crypto Device ARMv8 Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_armv8_all), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_cryptodev_qat(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_QAT_SYM_PMD; + return unit_test_suite_runner(&cryptodev_qat_testsuite); +} + +static int +test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_MB_PMD; + + return unit_test_suite_runner(&cryptodev_aesni_mb_testsuite); +} + +static int +test_cryptodev_openssl(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_OPENSSL_PMD; + + return unit_test_suite_runner(&cryptodev_openssl_testsuite); +} + +static int +test_cryptodev_aesni_gcm(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_GCM_PMD; + + return unit_test_suite_runner(&cryptodev_aesni_gcm_testsuite); +} + +static int +test_cryptodev_null(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_NULL_PMD; + + return unit_test_suite_runner(&cryptodev_null_testsuite); +} + +static int +test_cryptodev_sw_snow3g(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_SNOW3G_PMD; + + return unit_test_suite_runner(&cryptodev_sw_snow3g_testsuite); +} + +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 int +test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_ZUC_PMD; + + return unit_test_suite_runner(&cryptodev_sw_zuc_testsuite); +} + +static int +test_cryptodev_armv8(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_ARMV8_PMD; + + return unit_test_suite_runner(&cryptodev_armv8_testsuite); +} + +#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER + +static int +test_cryptodev_scheduler(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_SCHEDULER_PMD; + return unit_test_suite_runner(&cryptodev_scheduler_testsuite); +} + +REGISTER_TEST_COMMAND(cryptodev_scheduler_autotest, test_cryptodev_scheduler); + +#endif + +REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat); +REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb); +REGISTER_TEST_COMMAND(cryptodev_openssl_autotest, test_cryptodev_openssl); +REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_autotest, test_cryptodev_aesni_gcm); +REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null); +REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g); +REGISTER_TEST_COMMAND(cryptodev_sw_kasumi_autotest, test_cryptodev_sw_kasumi); +REGISTER_TEST_COMMAND(cryptodev_sw_zuc_autotest, test_cryptodev_sw_zuc); +REGISTER_TEST_COMMAND(cryptodev_sw_armv8_autotest, test_cryptodev_armv8); diff --git a/test/test/test_cryptodev.h b/test/test/test_cryptodev.h new file mode 100644 index 0000000000..67354a955a --- /dev/null +++ b/test/test/test_cryptodev.h @@ -0,0 +1,212 @@ +/*- + * 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. + */ +#ifndef TEST_CRYPTODEV_H_ +#define TEST_CRYPTODEV_H_ + +#define HEX_DUMP 0 + +#define FALSE 0 +#define TRUE 1 + +#define MAX_NUM_OPS_INFLIGHT (4096) +#define MIN_NUM_OPS_INFLIGHT (128) +#define DEFAULT_NUM_OPS_INFLIGHT (128) + +#define MAX_NUM_QPS_PER_QAT_DEVICE (2) +#define DEFAULT_NUM_QPS_PER_QAT_DEVICE (2) +#define DEFAULT_BURST_SIZE (64) +#define DEFAULT_NUM_XFORMS (2) +#define NUM_MBUFS (8191) +#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) + +#define BYTE_LENGTH(x) (x/8) +/* HASH DIGEST LENGTHS */ +#define DIGEST_BYTE_LENGTH_MD5 (BYTE_LENGTH(128)) +#define DIGEST_BYTE_LENGTH_SHA1 (BYTE_LENGTH(160)) +#define DIGEST_BYTE_LENGTH_SHA224 (BYTE_LENGTH(224)) +#define DIGEST_BYTE_LENGTH_SHA256 (BYTE_LENGTH(256)) +#define DIGEST_BYTE_LENGTH_SHA384 (BYTE_LENGTH(384)) +#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 DIGEST_BYTE_LENGTH_AES_GCM (BYTE_LENGTH(128)) + +#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) + +/** + * Write (spread) data from buffer to mbuf data + * + * @param mbuf + * Destination mbuf + * @param offset + * Start offset in mbuf + * @param len + * Number of bytes to copy + * @param buffer + * Continuous source buffer + */ +static inline void +pktmbuf_write(struct rte_mbuf *mbuf, int offset, int len, const uint8_t *buffer) +{ + int n = len; + int l; + struct rte_mbuf *m; + char *dst; + + for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next) + offset -= m->data_len; + + l = m->data_len - offset; + + /* copy data from first segment */ + dst = rte_pktmbuf_mtod_offset(m, char *, offset); + if (len <= l) { + rte_memcpy(dst, buffer, len); + return; + } + + rte_memcpy(dst, buffer, l); + buffer += l; + n -= l; + + for (m = m->next; (m != NULL) && (n > 0); m = m->next) { + dst = rte_pktmbuf_mtod(m, char *); + l = m->data_len; + if (n < l) { + rte_memcpy(dst, buffer, n); + return; + } + rte_memcpy(dst, buffer, l); + buffer += l; + n -= l; + } +} + +static inline uint8_t * +pktmbuf_mtod_offset(struct rte_mbuf *mbuf, int offset) { + struct rte_mbuf *m; + + for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next) + offset -= m->data_len; + + if (m == NULL) { + printf("pktmbuf_mtod_offset: offset out of buffer\n"); + return NULL; + } + return rte_pktmbuf_mtod_offset(m, uint8_t *, offset); +} + +static inline phys_addr_t +pktmbuf_mtophys_offset(struct rte_mbuf *mbuf, int offset) { + struct rte_mbuf *m; + + for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next) + offset -= m->data_len; + + if (m == NULL) { + printf("pktmbuf_mtophys_offset: offset out of buffer\n"); + return 0; + } + return rte_pktmbuf_mtophys_offset(m, offset); +} + +static inline struct rte_mbuf * +create_segmented_mbuf(struct rte_mempool *mbuf_pool, int pkt_len, + int nb_segs, uint8_t pattern) { + + struct rte_mbuf *m = NULL, *mbuf = NULL; + uint8_t *dst; + int data_len = 0; + int i, size; + int t_len; + + if (pkt_len < 1) { + printf("Packet size must be 1 or more (is %d)\n", pkt_len); + return NULL; + } + + if (nb_segs < 1) { + printf("Number of segments must be 1 or more (is %d)\n", + nb_segs); + return NULL; + } + + t_len = pkt_len >= nb_segs ? pkt_len / nb_segs : 1; + size = pkt_len; + + /* Create chained mbuf_src and fill it generated data */ + for (i = 0; size > 0; i++) { + + m = rte_pktmbuf_alloc(mbuf_pool); + if (i == 0) + mbuf = m; + + if (m == NULL) { + printf("Cannot create segment for source mbuf"); + goto fail; + } + + /* Make sure if tailroom is zeroed */ + memset(m->buf_addr, pattern, m->buf_len); + + data_len = size > t_len ? t_len : size; + dst = (uint8_t *)rte_pktmbuf_append(m, data_len); + if (dst == NULL) { + printf("Cannot append %d bytes to the mbuf\n", + data_len); + goto fail; + } + + if (mbuf != m) + rte_pktmbuf_chain(mbuf, m); + + size -= data_len; + + } + return mbuf; + +fail: + if (mbuf) + rte_pktmbuf_free(mbuf); + return NULL; +} + +#endif /* TEST_CRYPTODEV_H_ */ diff --git a/test/test/test_cryptodev_aes_test_vectors.h b/test/test/test_cryptodev_aes_test_vectors.h new file mode 100644 index 0000000000..f3fbef1aeb --- /dev/null +++ b/test/test/test_cryptodev_aes_test_vectors.h @@ -0,0 +1,1333 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2016-2017 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_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_AES_TEST_VECTORS_H_ + +/* test vectors */ +static const uint8_t plaintext_aes128ctr[] = { + 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 +}; + +static const uint8_t ciphertext64_aes128ctr[] = { + 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 +}; + +static const uint8_t plaintext_aes192ctr[] = { + 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, +}; + +static const uint8_t ciphertext64_aes192ctr[] = { + 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 +}; + +static const uint8_t plaintext_aes256ctr[] = { + 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 +}; + +static const uint8_t ciphertext64_aes256ctr[] = { + 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 +}; + +static const uint8_t plaintext_aes_common[] = { + "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." +}; + +static const uint8_t ciphertext512_aes128cbc[] = { + 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 +}; + +/* AES128-CTR-SHA1 test vector */ +static const struct blockcipher_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 = plaintext_aes128ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes128ctr, + .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 blockcipher_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 = plaintext_aes192ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes192ctr, + .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 blockcipher_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 = plaintext_aes256ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes256ctr, + .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 blockcipher_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 = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .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 blockcipher_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 = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .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 blockcipher_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 = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .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 blockcipher_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 = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .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 blockcipher_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 = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .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 blockcipher_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 = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .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 + } +}; + +static const uint8_t ciphertext512_aes192cbc[] = { + 0x45, 0xEE, 0x9A, 0xEA, 0x3C, 0x03, 0xFC, 0x4C, + 0x84, 0x36, 0xB0, 0xDA, 0xB0, 0xDC, 0xF3, 0x5B, + 0x75, 0xA7, 0xBE, 0x0E, 0xC0, 0x8D, 0x6C, 0xF8, + 0xC1, 0x0F, 0xD0, 0x35, 0x1D, 0x82, 0xAE, 0x7C, + 0x57, 0xC5, 0x7A, 0x55, 0x87, 0x1B, 0xD4, 0x03, + 0x0A, 0x64, 0xC9, 0xE0, 0xF4, 0xC7, 0x6F, 0x57, + 0x52, 0xC6, 0x73, 0xBA, 0x84, 0x0B, 0x5B, 0x89, + 0x21, 0xD2, 0x9B, 0x88, 0x68, 0xF5, 0xA9, 0x7F, + 0x3F, 0x49, 0xEB, 0xF4, 0xD4, 0x52, 0xD2, 0x64, + 0x80, 0xB2, 0x53, 0xDA, 0x19, 0xF6, 0x10, 0x24, + 0x23, 0x26, 0x7A, 0x7C, 0x07, 0x57, 0x4B, 0x0E, + 0x58, 0x49, 0x61, 0xD1, 0xDC, 0x9A, 0x32, 0x6B, + 0x0F, 0x43, 0x9E, 0x4D, 0xB4, 0x07, 0x4E, 0xB3, + 0x51, 0x74, 0xDE, 0x29, 0xBC, 0x98, 0xF9, 0xDF, + 0x78, 0x9A, 0x18, 0x9C, 0xD6, 0x7A, 0x55, 0x7C, + 0xE6, 0x1D, 0x5C, 0x1A, 0x99, 0xD2, 0xC3, 0x7B, + 0x9F, 0x96, 0x74, 0x2D, 0xE0, 0xEF, 0xD1, 0xE3, + 0x08, 0x9F, 0xAF, 0xE6, 0xED, 0xCA, 0xE1, 0xEA, + 0x23, 0x6F, 0x7C, 0x81, 0xA8, 0xC0, 0x5B, 0x8B, + 0x53, 0x90, 0x51, 0x2D, 0x0F, 0xF6, 0x7D, 0xA7, + 0x1C, 0xBD, 0x83, 0x84, 0x54, 0xA4, 0x15, 0xFB, + 0x3E, 0x25, 0xA7, 0x3A, 0x0A, 0x73, 0xD9, 0x88, + 0x6F, 0x80, 0x78, 0x95, 0x7F, 0x60, 0xAA, 0x86, + 0x8A, 0xFC, 0xDF, 0xC1, 0xCB, 0xDE, 0xBB, 0x25, + 0x52, 0x20, 0xC6, 0x79, 0xD4, 0x0F, 0x25, 0xE7, + 0xDB, 0xB2, 0x17, 0xA4, 0x6F, 0x3C, 0x6F, 0x91, + 0xF6, 0x44, 0x1E, 0xB6, 0x85, 0xBC, 0x7A, 0x14, + 0x10, 0x72, 0xBD, 0x16, 0x63, 0x39, 0x9E, 0x7B, + 0x84, 0x5B, 0x17, 0x61, 0xB1, 0x5D, 0x82, 0x0B, + 0x6D, 0x37, 0xD7, 0x79, 0xB8, 0x24, 0x91, 0x30, + 0x82, 0x91, 0x02, 0xB1, 0x18, 0x4B, 0xE0, 0xF4, + 0x13, 0x1B, 0xB2, 0x4C, 0xDA, 0xB8, 0x99, 0x96, + 0x83, 0x2F, 0xBE, 0x53, 0x8D, 0xDE, 0xFA, 0xAD, + 0xF6, 0x5C, 0xDB, 0xE5, 0x66, 0x26, 0x8F, 0x13, + 0x2B, 0x76, 0x47, 0x73, 0xDE, 0x1A, 0x74, 0xA6, + 0x30, 0xAF, 0x42, 0xA0, 0xE5, 0xD2, 0x8F, 0xC2, + 0xED, 0x3E, 0x9E, 0x29, 0x54, 0x3C, 0xDE, 0x9F, + 0x5D, 0x30, 0x2B, 0x63, 0xFB, 0xE3, 0xB1, 0x07, + 0xEE, 0x74, 0x4A, 0xAF, 0xB1, 0x20, 0x8D, 0xEC, + 0xE6, 0x78, 0x16, 0x8D, 0xA4, 0x6E, 0x34, 0x7D, + 0x47, 0xFB, 0x0B, 0xC1, 0x32, 0xD7, 0x0D, 0x6C, + 0x6F, 0x93, 0x9C, 0x5E, 0xEF, 0x1F, 0x9C, 0x45, + 0x80, 0x6B, 0x74, 0xA6, 0x81, 0xF2, 0xF6, 0xFA, + 0xAA, 0x9D, 0x4F, 0xCA, 0xB5, 0x90, 0x59, 0xB0, + 0x3B, 0xF2, 0xF0, 0x75, 0xFD, 0x8A, 0xD8, 0x97, + 0x65, 0x88, 0x56, 0x4C, 0x44, 0xDF, 0x73, 0xF7, + 0x56, 0x9C, 0x48, 0x7E, 0xB0, 0x1F, 0x1D, 0x7D, + 0x6A, 0x11, 0xF5, 0xC2, 0xF4, 0x17, 0xEF, 0x58, + 0xD8, 0x2A, 0xAF, 0x56, 0x2F, 0xCF, 0xEC, 0xA4, + 0x58, 0x8B, 0x60, 0xCE, 0xD4, 0x0F, 0x9C, 0x21, + 0xEC, 0x3E, 0x74, 0x7B, 0x81, 0x3D, 0x69, 0xC6, + 0x5E, 0x12, 0x83, 0xE9, 0xEF, 0x81, 0x58, 0x36, + 0x6A, 0x60, 0x0F, 0x54, 0x28, 0x11, 0xF9, 0x64, + 0x36, 0xAD, 0x79, 0xF5, 0x1C, 0x74, 0xD0, 0xC3, + 0x7B, 0x61, 0xE1, 0x92, 0xB0, 0x13, 0x91, 0x87, + 0x32, 0x1F, 0xF2, 0x5A, 0xDA, 0x25, 0x69, 0xEB, + 0xD7, 0x32, 0x7F, 0xF5, 0x23, 0x21, 0x54, 0x47, + 0x7B, 0x1B, 0x33, 0xB0, 0x3D, 0xF6, 0xE2, 0x7E, + 0x3E, 0xA2, 0x9E, 0xCA, 0x48, 0x0B, 0x4A, 0x29, + 0x81, 0xD4, 0x4E, 0xD5, 0x69, 0xFB, 0xCD, 0x37, + 0x8A, 0xC1, 0x5B, 0x50, 0xFF, 0xB5, 0x7D, 0x43, + 0x0F, 0xAE, 0xA6, 0xC2, 0xE5, 0x8F, 0x45, 0xB2, + 0x85, 0x99, 0x02, 0xA2, 0x9B, 0xBE, 0x90, 0x43, + 0x4F, 0x2F, 0x50, 0xE2, 0x77, 0x62, 0xD9, 0xCC +}; + +/** AES-192-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_10 = { + .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, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes192cbc, + .len = 512 + } +}; + +static const uint8_t ciphertext512_aes256cbc[] = { + 0xF3, 0xDD, 0xF0, 0x0B, 0xFF, 0xA2, 0x6A, 0x04, + 0xBE, 0xDA, 0x52, 0xA6, 0xFE, 0x6B, 0xA6, 0xA7, + 0x48, 0x1D, 0x7D, 0x98, 0x65, 0xDB, 0xEF, 0x06, + 0x26, 0xB5, 0x8E, 0xEB, 0x05, 0x0E, 0x77, 0x98, + 0x17, 0x8E, 0xD0, 0xD4, 0x7B, 0x92, 0x8F, 0x5C, + 0xD0, 0x74, 0x5C, 0xA8, 0x4B, 0x54, 0xB6, 0x2F, + 0x83, 0x72, 0x2C, 0xFF, 0x72, 0xE9, 0xE4, 0x15, + 0x4C, 0x32, 0xAF, 0xC8, 0xC9, 0x89, 0x3C, 0x6E, + 0x31, 0xD5, 0xC0, 0x16, 0xC0, 0x31, 0x7D, 0x11, + 0xAB, 0xCB, 0xDE, 0xD2, 0xD6, 0xAA, 0x76, 0x5E, + 0xBA, 0xF6, 0xE2, 0x92, 0xCB, 0x86, 0x07, 0xFA, + 0xD4, 0x9E, 0x83, 0xED, 0xFD, 0xB8, 0x70, 0x54, + 0x6B, 0xBE, 0xEC, 0x72, 0xDD, 0x28, 0x5E, 0x95, + 0x78, 0xA5, 0x28, 0x43, 0x3D, 0x6D, 0xB1, 0xD9, + 0x69, 0x1F, 0xC9, 0x66, 0x0E, 0x32, 0x44, 0x08, + 0xD2, 0xAE, 0x2C, 0x43, 0xF2, 0xD0, 0x7D, 0x26, + 0x70, 0xE5, 0xA1, 0xCA, 0x37, 0xE9, 0x7D, 0xC7, + 0xA3, 0xFA, 0x81, 0x91, 0x64, 0xAA, 0x64, 0x91, + 0x9A, 0x95, 0x2D, 0xC9, 0xF9, 0xCE, 0xFE, 0x9F, + 0xC4, 0xD8, 0x81, 0xBE, 0x57, 0x84, 0xC5, 0x02, + 0xDB, 0x30, 0xC1, 0xD9, 0x0E, 0xA0, 0xA6, 0x00, + 0xD6, 0xF3, 0x52, 0x7E, 0x0D, 0x23, 0x6B, 0x2B, + 0x34, 0x99, 0x1F, 0x70, 0x27, 0x6D, 0x58, 0x84, + 0x93, 0x77, 0xB8, 0x3E, 0xF1, 0x71, 0x58, 0x42, + 0x8B, 0x2B, 0xC8, 0x6D, 0x05, 0x84, 0xFF, 0x4E, + 0x85, 0xEF, 0x4A, 0x9D, 0x91, 0x6A, 0xD5, 0xE1, + 0xAF, 0x01, 0xEB, 0x83, 0x8F, 0x23, 0x7C, 0x7F, + 0x12, 0x91, 0x05, 0xF0, 0x4E, 0xD9, 0x17, 0x62, + 0x75, 0xBB, 0xAC, 0x97, 0xEE, 0x3B, 0x4E, 0xC7, + 0xE5, 0x92, 0xF8, 0x9D, 0x4C, 0xF9, 0xEE, 0x55, + 0x18, 0xBB, 0xCC, 0xB4, 0xF2, 0x59, 0xB9, 0xFC, + 0x7A, 0x0F, 0x98, 0xD4, 0x8B, 0xFE, 0xF7, 0x83, + 0x46, 0xE2, 0x83, 0x33, 0x3E, 0x95, 0x8D, 0x17, + 0x1E, 0x85, 0xF8, 0x8C, 0x51, 0xB0, 0x6C, 0xB5, + 0x5E, 0x95, 0xBA, 0x4B, 0x69, 0x1B, 0x48, 0x69, + 0x0B, 0x8F, 0xA5, 0x18, 0x13, 0xB9, 0x77, 0xD1, + 0x80, 0x32, 0x32, 0x6D, 0x53, 0xA1, 0x95, 0x40, + 0x96, 0x8A, 0xCC, 0xA3, 0x69, 0xF8, 0x9F, 0xB5, + 0x8E, 0xD2, 0x68, 0x07, 0x4F, 0xA7, 0xEC, 0xF8, + 0x20, 0x21, 0x58, 0xF8, 0xD8, 0x9E, 0x5F, 0x40, + 0xBA, 0xB9, 0x76, 0x57, 0x3B, 0x17, 0xAD, 0xEE, + 0xCB, 0xDF, 0x07, 0xC1, 0xDF, 0x66, 0xA8, 0x0D, + 0xC2, 0xCE, 0x8F, 0x79, 0xC3, 0x32, 0xE0, 0x8C, + 0xFE, 0x5A, 0xF3, 0x55, 0x27, 0x73, 0x6F, 0xA1, + 0x54, 0xC6, 0xFC, 0x28, 0x9D, 0xBE, 0x97, 0xB9, + 0x54, 0x97, 0x72, 0x3A, 0x61, 0xAF, 0x6F, 0xDE, + 0xF8, 0x0E, 0xBB, 0x6B, 0x96, 0x84, 0xDD, 0x9B, + 0x62, 0xBA, 0x47, 0xB5, 0xC9, 0x3B, 0x4E, 0x8C, + 0x78, 0x2A, 0xCC, 0x0A, 0x69, 0x54, 0x25, 0x5E, + 0x8B, 0xAC, 0x56, 0xD9, 0xFE, 0x48, 0xBA, 0xCE, + 0xA9, 0xCE, 0xA6, 0x1D, 0xBF, 0x3E, 0x3C, 0x66, + 0x40, 0x71, 0x79, 0xAD, 0x5B, 0x26, 0xAD, 0xBE, + 0x58, 0x13, 0x64, 0x60, 0x7C, 0x05, 0xFC, 0xE3, + 0x51, 0x7A, 0xF2, 0xCC, 0x54, 0x16, 0x2C, 0xA4, + 0xCE, 0x5F, 0x59, 0x12, 0x77, 0xEB, 0xD9, 0x23, + 0xE3, 0x86, 0xFB, 0xD7, 0x48, 0x76, 0x9D, 0xE3, + 0x89, 0x87, 0x39, 0xFA, 0x7B, 0x21, 0x0B, 0x76, + 0xB2, 0xED, 0x1C, 0x27, 0x4B, 0xD5, 0x27, 0x05, + 0x8C, 0x7D, 0x58, 0x6C, 0xCA, 0xA5, 0x54, 0x9A, + 0x0F, 0xCB, 0xE9, 0x88, 0x31, 0xAD, 0x49, 0xEE, + 0x38, 0xFB, 0xC9, 0xFB, 0xB4, 0x7A, 0x00, 0x58, + 0x20, 0x32, 0xD3, 0x53, 0x5A, 0xDD, 0x74, 0x95, + 0x60, 0x59, 0x09, 0xAE, 0x7E, 0xEC, 0x74, 0xA3, + 0xB7, 0x1C, 0x6D, 0xF2, 0xAE, 0x79, 0xA4, 0x7C +}; + +/** AES-256-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_11 = { + .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, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0, + 0x37, 0x07, 0xB8, 0x23, 0xA2, 0xA3, 0xB5, 0x8D + }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes256cbc, + .len = 512 + } +}; + +/** AES-128-CBC SHA256 HMAC test vector (160 bytes) */ +static const struct blockcipher_test_data aes_test_data_12 = { + .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 = plaintext_aes_common, + .len = 160 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 160 + }, + .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 = { + 0x92, 0xEC, 0x65, 0x9A, 0x52, 0xCC, 0x50, 0xA5, + 0xEE, 0x0E, 0xDF, 0x1E, 0xA4, 0xC9, 0xC1, 0x04, + 0xD5, 0xDC, 0x78, 0x90, 0xF4, 0xE3, 0x35, 0x62, + 0xAD, 0x95, 0x45, 0x28, 0x5C, 0xF8, 0x8C, 0x0B + }, + .len = 32, + .truncated_len = 16 + } +}; + +/** AES-128-CBC SHA1 HMAC test vector (160 bytes) */ +static const struct blockcipher_test_data aes_test_data_13 = { + .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 = plaintext_aes_common, + .len = 160 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 160 + }, + .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 = { + 0x4F, 0x16, 0xEA, 0xF7, 0x4A, 0x88, 0xD3, 0xE0, + 0x0E, 0x12, 0x8B, 0xE7, 0x05, 0xD0, 0x86, 0x48, + 0x22, 0x43, 0x30, 0xA7 + }, + .len = 20, + .truncated_len = 12 + } +}; + +static const struct blockcipher_test_case aes_chain_test_cases[] = { + { + .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-192-CTR XCBC Encryption Digest", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-192-CTR XCBC Decryption Digest Verify " + "Scatter Gather", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | + BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "(short buffers)", + .test_data = &aes_test_data_13, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "Scatter Gather", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | + BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify (short buffers)", + .test_data = &aes_test_data_13, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest " + "(short buffers)", + .test_data = &aes_test_data_12, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify (short buffers)", + .test_data = &aes_test_data_12, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " + "Scatter Gather Sessionless", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS | + BLOCKCIPHER_TEST_FEATURE_SG | + BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " + "Verify", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " + "Verify Scatter Gather", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | + BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC XCBC Encryption Digest", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " + "Verify", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " + "Verify", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = + "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, +}; + +static const struct blockcipher_test_case aes_cipheronly_test_cases[] = { + { + .test_descr = "AES-128-CBC Encryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CBC Decryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-192-CBC Encryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-192-CBC Encryption Scater gather", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | + BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "AES-192-CBC Decryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-256-CBC Encryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-256-CBC Decryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CTR Encryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-128-CTR Decryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-192-CTR Encryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-192-CTR Decryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-256-CTR Encryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "AES-256-CTR Decryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, +}; + +#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_blockcipher.c b/test/test/test_cryptodev_blockcipher.c new file mode 100644 index 0000000000..da87368a78 --- /dev/null +++ b/test/test/test_cryptodev_blockcipher.c @@ -0,0 +1,683 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015-2017 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 +#include +#include +#include +#include + +#include +#include +#include + +#include "test.h" +#include "test_cryptodev.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" +#include "test_cryptodev.h" + +static int +test_blockcipher_one_case(const struct blockcipher_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; + struct rte_cryptodev_info dev_info; + + int status = TEST_SUCCESS; + const struct blockcipher_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; + uint8_t src_pattern = 0xa5; + uint8_t dst_pattern = 0xb6; + uint8_t tmp_src_buf[MBUF_SIZE]; + uint8_t tmp_dst_buf[MBUF_SIZE]; + + int nb_segs = 1; + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) { + rte_cryptodev_info_get(dev_id, &dev_info); + if (!(dev_info.feature_flags & + RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) { + printf("Device doesn't support scatter-gather. " + "Test Skipped.\n"); + return 0; + } + nb_segs = 3; + } + + 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: + case RTE_CRYPTODEV_OPENSSL_PMD: + case RTE_CRYPTODEV_ARMV8_PMD: /* Fall through */ + digest_len = tdata->digest.len; + break; + case RTE_CRYPTODEV_AESNI_MB_PMD: + case RTE_CRYPTODEV_SCHEDULER_PMD: + digest_len = tdata->digest.truncated_len; + break; + default: + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Unsupported PMD type"); + status = TEST_FAILED; + goto error_exit; + } + + /* preparing data */ + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + buf_len += tdata->iv.len; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + buf_len += digest_len; + + /* for contiguous mbuf, nb_segs is 1 */ + ibuf = create_segmented_mbuf(mbuf_pool, + tdata->ciphertext.len, nb_segs, src_pattern); + if (ibuf == NULL) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Cannot create source mbuf"); + status = TEST_FAILED; + goto error_exit; + } + + /* only encryption requires plaintext.data input, + * decryption/(digest gen)/(digest verify) use ciphertext.data + * to be computed + */ + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) + pktmbuf_write(ibuf, 0, tdata->plaintext.len, + tdata->plaintext.data); + else + pktmbuf_write(ibuf, 0, tdata->ciphertext.len, + tdata->ciphertext.data); + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + rte_memcpy(rte_pktmbuf_prepend(ibuf, tdata->iv.len), + tdata->iv.data, tdata->iv.len); + } + buf_p = rte_pktmbuf_append(ibuf, digest_len); + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + rte_memcpy(buf_p, tdata->digest.data, digest_len); + else + memset(buf_p, 0, digest_len); + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + obuf = rte_pktmbuf_alloc(mbuf_pool); + if (!obuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + memset(obuf->buf_addr, dst_pattern, obuf->buf_len); + + buf_p = rte_pktmbuf_append(obuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_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, BLOCKCIPHER_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 & BLOCKCIPHER_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 & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + uint32_t n_xforms = 0; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + n_xforms++; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + n_xforms++; + + if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) + == NULL) { + snprintf(test_msg, BLOCKCIPHER_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, BLOCKCIPHER_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 == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) { + if (t->feature_mask & BLOCKCIPHER_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 == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) { + if (t->feature_mask & BLOCKCIPHER_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 == BLOCKCIPHER_TEST_OP_ENCRYPT) || + (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + cipher_xform = op->sym->xform; + else + init_xform = cipher_xform; + cipher_xform->next = NULL; + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) || + (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + auth_xform = op->sym->xform; + else + init_xform = auth_xform; + auth_xform->next = NULL; + } else { + snprintf(test_msg, BLOCKCIPHER_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 & BLOCKCIPHER_TEST_OP_CIPHER) { + cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform->cipher.algo = tdata->crypto_algo; + if (t->op_mask & BLOCKCIPHER_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 & BLOCKCIPHER_TEST_OP_AUTH) { + uint32_t auth_data_offset = 0; + uint32_t digest_offset = tdata->ciphertext.len; + + if (t->op_mask & BLOCKCIPHER_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 & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + sym_op->auth.digest.data = pktmbuf_mtod_offset + (iobuf, digest_offset); + sym_op->auth.digest.phys_addr = + pktmbuf_mtophys_offset(iobuf, + digest_offset); + } else { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + sym_op->auth.digest.data = pktmbuf_mtod_offset + (sym_op->m_src, digest_offset); + sym_op->auth.digest.phys_addr = + 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 & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + sess = rte_cryptodev_sym_session_create(dev_id, + init_xform); + if (!sess) { + snprintf(test_msg, BLOCKCIPHER_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); + } + + TEST_HEXDUMP(stdout, "m_src(before):", + sym_op->m_src->buf_addr, sym_op->m_src->buf_len); + rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr, + sym_op->m_src->buf_len); + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + TEST_HEXDUMP(stdout, "m_dst(before):", + sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len); + rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr, + sym_op->m_dst->buf_len); + } + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, BLOCKCIPHER_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, BLOCKCIPHER_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(after):", + sym_op->m_src->buf_addr, sym_op->m_src->buf_len); + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) + TEST_HEXDUMP(stdout, "m_dst(after):", + sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len); + + /* Verify results */ + if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + else + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + uint8_t buffer[2048]; + const uint8_t *compare_ref; + uint32_t compare_len; + + if (t->op_mask & BLOCKCIPHER_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(rte_pktmbuf_read(iobuf, tdata->iv.len, compare_len, + buffer), compare_ref, compare_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + uint8_t *auth_res; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + auth_res = pktmbuf_mtod_offset(iobuf, + tdata->iv.len + tdata->ciphertext.len); + else + auth_res = pktmbuf_mtod_offset(iobuf, + tdata->ciphertext.len); + + if (memcmp(auth_res, tdata->digest.data, digest_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Generated " + "digest data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + /* The only parts that should have changed in the buffer are + * plaintext/ciphertext and digest. + * In OOP only the dest buffer should change. + */ + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + struct rte_mbuf *mbuf; + uint8_t value; + uint32_t head_unchanged_len = 0, changed_len = 0; + uint32_t i; + + mbuf = sym_op->m_src; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) { + /* white-box test: PMDs use some of the + * tailroom as temp storage in verify case + */ + head_unchanged_len = rte_pktmbuf_headroom(mbuf) + + rte_pktmbuf_data_len(mbuf); + changed_len = digest_len; + } else { + head_unchanged_len = mbuf->buf_len; + changed_len = 0; + } + + for (i = 0; i < mbuf->buf_len; i++) { + if (i == head_unchanged_len) + i += changed_len; + value = *((uint8_t *)(mbuf->buf_addr)+i); + if (value != tmp_src_buf[i]) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)", + __LINE__, value, tmp_src_buf[i]); + status = TEST_FAILED; + goto error_exit; + } + } + + mbuf = sym_op->m_dst; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { + head_unchanged_len = rte_pktmbuf_headroom(mbuf) + + sym_op->auth.data.offset; + changed_len = sym_op->auth.data.length; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) + changed_len += sym_op->auth.digest.length; + } else { + /* cipher-only */ + head_unchanged_len = rte_pktmbuf_headroom(mbuf) + + sym_op->cipher.data.offset; + changed_len = sym_op->cipher.data.length; + } + + for (i = 0; i < mbuf->buf_len; i++) { + if (i == head_unchanged_len) + i += changed_len; + value = *((uint8_t *)(mbuf->buf_addr)+i); + if (value != tmp_dst_buf[i]) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: OOP dst outer mbuf data " + "(0x%x) not as expected (0x%x)", + __LINE__, value, tmp_dst_buf[i]); + status = TEST_FAILED; + goto error_exit; + } + } + } else { + /* In-place operation */ + struct rte_mbuf *mbuf; + uint8_t value; + uint32_t head_unchanged_len = 0, changed_len = 0; + uint32_t i; + + mbuf = sym_op->m_src; + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + head_unchanged_len = rte_pktmbuf_headroom(mbuf) + + sym_op->cipher.data.offset; + changed_len = sym_op->cipher.data.length; + } else { + /* auth-only */ + head_unchanged_len = rte_pktmbuf_headroom(mbuf) + + sym_op->auth.data.offset + + sym_op->auth.data.length; + changed_len = 0; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) + changed_len += sym_op->auth.digest.length; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) { + /* white-box test: PMDs use some of the + * tailroom as temp storage in verify case + */ + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + /* This is simplified, not checking digest*/ + changed_len += digest_len*2; + } else { + head_unchanged_len += digest_len; + changed_len += digest_len; + } + } + + for (i = 0; i < mbuf->buf_len; i++) { + if (i == head_unchanged_len) + i += changed_len; + value = *((uint8_t *)(mbuf->buf_addr)+i); + if (value != tmp_src_buf[i]) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: outer mbuf data (0x%x) " + "not as expected (0x%x)", + __LINE__, value, tmp_src_buf[i]); + status = TEST_FAILED; + goto error_exit; + } + } + } + + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS"); + +error_exit: + if (!(t->feature_mask & BLOCKCIPHER_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_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type) +{ + int status, overall_status = TEST_SUCCESS; + uint32_t i, test_index = 0; + char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1]; + uint32_t n_test_cases = 0; + uint32_t target_pmd_mask = 0; + const struct blockcipher_test_case *tcs = NULL; + + switch (test_type) { + case BLKCIPHER_AES_CHAIN_TYPE: + n_test_cases = sizeof(aes_chain_test_cases) / + sizeof(aes_chain_test_cases[0]); + tcs = aes_chain_test_cases; + break; + case BLKCIPHER_AES_CIPHERONLY_TYPE: + n_test_cases = sizeof(aes_cipheronly_test_cases) / + sizeof(aes_cipheronly_test_cases[0]); + tcs = aes_cipheronly_test_cases; + break; + case BLKCIPHER_3DES_CHAIN_TYPE: + n_test_cases = sizeof(triple_des_chain_test_cases) / + sizeof(triple_des_chain_test_cases[0]); + tcs = triple_des_chain_test_cases; + break; + case BLKCIPHER_3DES_CIPHERONLY_TYPE: + n_test_cases = sizeof(triple_des_cipheronly_test_cases) / + sizeof(triple_des_cipheronly_test_cases[0]); + tcs = triple_des_cipheronly_test_cases; + break; + case BLKCIPHER_DES_CIPHERONLY_TYPE: + n_test_cases = sizeof(des_cipheronly_test_cases) / + sizeof(des_cipheronly_test_cases[0]); + tcs = des_cipheronly_test_cases; + break; + case BLKCIPHER_AUTHONLY_TYPE: + n_test_cases = sizeof(hash_test_cases) / + sizeof(hash_test_cases[0]); + tcs = hash_test_cases; + break; + default: + break; + } + + switch (cryptodev_type) { + case RTE_CRYPTODEV_AESNI_MB_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; + break; + case RTE_CRYPTODEV_QAT_SYM_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; + break; + case RTE_CRYPTODEV_OPENSSL_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL; + break; + case RTE_CRYPTODEV_ARMV8_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8; + break; + case RTE_CRYPTODEV_SCHEDULER_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER; + break; + default: + TEST_ASSERT(0, "Unrecognized cryptodev type"); + break; + } + + for (i = 0; i < n_test_cases; i++) { + const struct blockcipher_test_case *tc = &tcs[i]; + + if (!(tc->pmd_mask & target_pmd_mask)) + continue; + + status = test_blockcipher_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 & BLOCKCIPHER_TEST_FEATURE_STOPPER) + break; + } + } + + return overall_status; +} diff --git a/test/test/test_cryptodev_blockcipher.h b/test/test/test_cryptodev_blockcipher.h new file mode 100644 index 0000000000..053aaa1cda --- /dev/null +++ b/test/test/test_cryptodev_blockcipher.h @@ -0,0 +1,129 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016-2017 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_BLOCKCIPHER_H_ +#define TEST_CRYPTODEV_BLOCKCIPHER_H_ + +#ifndef BLOCKCIPHER_TEST_MSG_LEN +#define BLOCKCIPHER_TEST_MSG_LEN 256 +#endif + +#define BLOCKCIPHER_TEST_OP_ENCRYPT 0x01 +#define BLOCKCIPHER_TEST_OP_DECRYPT 0x02 +#define BLOCKCIPHER_TEST_OP_AUTH_GEN 0x04 +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY 0x08 + +#define BLOCKCIPHER_TEST_FEATURE_OOP 0x01 +#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS 0x02 +#define BLOCKCIPHER_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ +#define BLOCKCIPHER_TEST_FEATURE_SG 0x08 /* Scatter Gather */ + +#define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL 0x0004 /* SW OPENSSL flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_ARMV8 0x0008 /* ARMv8 flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER 0x0010 /* Scheduler */ + +#define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_DECRYPT) + +#define BLOCKCIPHER_TEST_OP_AUTH (BLOCKCIPHER_TEST_OP_AUTH_GEN | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_GEN) + +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC (BLOCKCIPHER_TEST_OP_DECRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +enum blockcipher_test_type { + BLKCIPHER_AES_CHAIN_TYPE, /* use aes_chain_test_cases[] */ + BLKCIPHER_AES_CIPHERONLY_TYPE, /* use aes_cipheronly_test_cases[] */ + BLKCIPHER_3DES_CHAIN_TYPE, /* use triple_des_chain_test_cases[] */ + BLKCIPHER_3DES_CIPHERONLY_TYPE, /* triple_des_cipheronly_test_cases[] */ + BLKCIPHER_AUTHONLY_TYPE, /* use hash_test_cases[] */ + BLKCIPHER_DES_CIPHERONLY_TYPE /* use des_cipheronly_test_cases[] */ +}; + +struct blockcipher_test_case { + const char *test_descr; /* test description */ + const struct blockcipher_test_data *test_data; + uint8_t op_mask; /* operation mask */ + uint8_t feature_mask; + uint32_t pmd_mask; +}; + +struct blockcipher_test_data { + enum rte_crypto_cipher_algorithm crypto_algo; + + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned int len; + } iv; + + struct { + const uint8_t *data; + unsigned int len; + } plaintext; + + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + uint8_t data[128]; + unsigned int len; /* for qat */ + unsigned int truncated_len; /* for mb */ + } digest; +}; + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type); + +#endif /* TEST_CRYPTODEV_BLOCKCIPHER_H_ */ diff --git a/test/test/test_cryptodev_des_test_vectors.h b/test/test/test_cryptodev_des_test_vectors.h new file mode 100644 index 0000000000..388d87e182 --- /dev/null +++ b/test/test/test_cryptodev_des_test_vectors.h @@ -0,0 +1,1065 @@ +/* + * 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_DES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_DES_TEST_VECTORS_H_ + +static const uint8_t plaintext_des[] = { + "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." +}; + +static const uint8_t ciphertext512_des128ctr[] = { + 0x13, 0x39, 0x3B, 0xBC, 0x1D, 0xE3, 0x23, 0x09, + 0x9B, 0x08, 0xD1, 0x09, 0x52, 0x93, 0x78, 0x29, + 0x11, 0x21, 0xBA, 0x01, 0x15, 0xCD, 0xEC, 0xAA, + 0x79, 0x77, 0x58, 0xAE, 0xAE, 0xBC, 0x97, 0x33, + 0x94, 0xA9, 0x2D, 0xC0, 0x0A, 0xA9, 0xA4, 0x4B, + 0x19, 0x07, 0x88, 0x06, 0x7E, 0x81, 0x0F, 0xB5, + 0x60, 0xCF, 0xA7, 0xC3, 0x2A, 0x43, 0xFF, 0x16, + 0x3A, 0x5F, 0x11, 0x2D, 0x11, 0x38, 0x37, 0x94, + 0x2A, 0xC8, 0x3D, 0x20, 0xBB, 0x93, 0x95, 0x54, + 0x12, 0xFF, 0x0C, 0x47, 0x89, 0x7D, 0x73, 0xD1, + 0x2E, 0x3A, 0x80, 0x52, 0xA8, 0x92, 0x93, 0x99, + 0x16, 0xB8, 0x12, 0x1B, 0x8B, 0xA8, 0xC1, 0x81, + 0x95, 0x18, 0x82, 0xD6, 0x5A, 0xA7, 0xFE, 0xCF, + 0xC4, 0xAC, 0x85, 0x91, 0x0C, 0x2F, 0x1D, 0x10, + 0x9A, 0x65, 0x07, 0xB0, 0x2E, 0x5A, 0x2D, 0x48, + 0x26, 0xF8, 0x17, 0x7A, 0x53, 0xD6, 0xB8, 0xDF, + 0xB1, 0x10, 0x48, 0x7E, 0x8F, 0xBE, 0x2E, 0xA1, + 0x0D, 0x9E, 0xA9, 0xF1, 0x3B, 0x3B, 0x33, 0xCD, + 0xDC, 0x52, 0x7E, 0xC0, 0x0E, 0xA0, 0xD8, 0xA7, + 0xC6, 0x34, 0x5A, 0xAA, 0x29, 0x8B, 0xA9, 0xAC, + 0x1F, 0x78, 0xAD, 0xEE, 0x34, 0x59, 0x30, 0xFB, + 0x2A, 0x20, 0x3D, 0x4D, 0x30, 0xA7, 0x7D, 0xD8, + 0xA0, 0xC6, 0xA2, 0xD3, 0x9A, 0xFB, 0x50, 0x97, + 0x4D, 0x25, 0xA2, 0x37, 0x51, 0x54, 0xB7, 0xEB, + 0xED, 0x77, 0xDB, 0x94, 0x35, 0x8B, 0x70, 0x95, + 0x4A, 0x00, 0xA7, 0xF1, 0x8A, 0x66, 0x0E, 0xC6, + 0x05, 0x7B, 0x69, 0x05, 0x42, 0x03, 0x96, 0x2C, + 0x55, 0x00, 0x1B, 0xC0, 0x19, 0x4D, 0x0D, 0x2E, + 0xF5, 0x81, 0x11, 0x64, 0xCA, 0xBB, 0xF2, 0x0F, + 0x9C, 0x60, 0xE2, 0xCC, 0x02, 0x6E, 0x83, 0xD5, + 0x24, 0xF4, 0x12, 0x0E, 0x6A, 0xEA, 0x4F, 0x6C, + 0x79, 0x69, 0x65, 0x67, 0xDB, 0xF7, 0xEA, 0x98, + 0x5D, 0x56, 0x98, 0xB7, 0x88, 0xE7, 0x23, 0xC9, + 0x17, 0x32, 0x92, 0x33, 0x5A, 0x0C, 0x15, 0x20, + 0x3B, 0x1C, 0xF9, 0x0F, 0x4D, 0xD1, 0xE8, 0xE6, + 0x9E, 0x5E, 0x24, 0x1B, 0xA4, 0xB8, 0xB9, 0xE9, + 0x2F, 0xFC, 0x89, 0xB4, 0xB9, 0xF4, 0xA6, 0xAD, + 0x55, 0xF4, 0xDF, 0x58, 0x63, 0x25, 0xE3, 0x41, + 0x70, 0xDF, 0x10, 0xE7, 0x13, 0x87, 0x8D, 0xB3, + 0x62, 0x4F, 0xF5, 0x86, 0x85, 0x8F, 0x59, 0xF0, + 0x21, 0x0E, 0x8F, 0x11, 0xAD, 0xBF, 0xDD, 0x61, + 0x68, 0x3F, 0x54, 0x57, 0x49, 0x38, 0xC8, 0x24, + 0x8E, 0x0A, 0xAC, 0xCA, 0x2C, 0x36, 0x3E, 0x5F, + 0x0A, 0xCE, 0xFD, 0x1A, 0x60, 0x63, 0x5A, 0xE6, + 0x06, 0x64, 0xB5, 0x94, 0x3C, 0xC9, 0xAF, 0x7C, + 0xCD, 0x49, 0x10, 0xCF, 0xAF, 0x0E, 0x2E, 0x79, + 0x27, 0xB2, 0x67, 0x02, 0xED, 0xEE, 0x80, 0x77, + 0x7C, 0x6D, 0x4B, 0xDB, 0xCF, 0x8D, 0x68, 0x00, + 0x2E, 0xD9, 0xF0, 0x8E, 0x08, 0xBF, 0xA6, 0x9B, + 0xFE, 0xA4, 0xFB, 0x19, 0x46, 0xAF, 0x1B, 0xA9, + 0xF8, 0x22, 0x81, 0x21, 0x97, 0xFC, 0xC0, 0x8A, + 0x26, 0x58, 0x13, 0x29, 0xB6, 0x69, 0x94, 0x4B, + 0xAB, 0xB3, 0x88, 0x0D, 0xA9, 0x48, 0x0E, 0xE8, + 0x70, 0xFC, 0xA1, 0x21, 0xC4, 0x2C, 0xE5, 0x99, + 0xB4, 0xF1, 0x6F, 0xB2, 0x4B, 0x4B, 0xCD, 0x48, + 0x15, 0x47, 0x2D, 0x72, 0x39, 0x99, 0x9D, 0x24, + 0x0C, 0x8B, 0xDC, 0xA1, 0xEE, 0xF6, 0xF4, 0x73, + 0xC3, 0xB8, 0x0C, 0x23, 0x0D, 0xA7, 0xC4, 0x7D, + 0x27, 0xE2, 0x14, 0x11, 0x53, 0x19, 0xE7, 0xCA, + 0x94, 0x4E, 0x0D, 0x2C, 0xF7, 0x36, 0x47, 0xDB, + 0x77, 0x3C, 0x22, 0xAC, 0xBE, 0xE1, 0x06, 0x55, + 0xE5, 0xDD, 0x8B, 0x65, 0xE8, 0xE9, 0x91, 0x52, + 0x59, 0x97, 0xFC, 0x8C, 0xEE, 0x96, 0x22, 0x60, + 0xEE, 0xBF, 0x82, 0xF0, 0xCA, 0x14, 0xF9, 0xD3 +}; + +static const struct blockcipher_test_data +triple_des128ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .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 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .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 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xC3, 0x40, 0xD5, 0xD9, 0x8F, 0x8A, 0xC0, 0xF0, + 0x46, 0x28, 0x02, 0x01, 0xB5, 0xC1, 0x87, 0x4D, + 0xAC, 0xFE, 0x48, 0x76 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .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 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .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 = { + 0xF1, 0xC1, 0xDB, 0x4D, 0xFA, 0x7F, 0x2F, 0xE5, + 0xF8, 0x49, 0xEA, 0x1D, 0x7F, 0xCB, 0x42, 0x59, + 0xC4, 0x1E, 0xB1, 0x18 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192ctr[] = { + 0xFF, 0x32, 0x52, 0x97, 0x10, 0xBF, 0x0B, 0x10, + 0x68, 0x0F, 0x4F, 0x56, 0x8B, 0x2C, 0x7B, 0x8E, + 0x39, 0x1E, 0x1A, 0x2F, 0x83, 0xDE, 0x5E, 0x35, + 0xC8, 0x4B, 0xDF, 0xD5, 0xBC, 0x84, 0x50, 0x1A, + 0x02, 0xDF, 0xB3, 0x11, 0xE4, 0xDA, 0xB8, 0x0E, + 0x47, 0xC6, 0x0C, 0x51, 0x09, 0x62, 0x9C, 0x5D, + 0x71, 0x40, 0x49, 0xD8, 0x55, 0xBD, 0x7D, 0x90, + 0x71, 0xC5, 0xF7, 0x07, 0x6F, 0x08, 0x71, 0x2A, + 0xB1, 0x77, 0x9B, 0x0F, 0xA1, 0xB0, 0xD6, 0x10, + 0xB2, 0xE5, 0x31, 0xEC, 0x21, 0x13, 0x89, 0x2A, + 0x09, 0x7E, 0x30, 0xDB, 0xA0, 0xF0, 0xDC, 0xE4, + 0x74, 0x64, 0x39, 0xA3, 0xB0, 0xB1, 0x80, 0x66, + 0x52, 0xD4, 0x4E, 0xC9, 0x5A, 0x52, 0x6A, 0xC7, + 0xB5, 0x2B, 0x61, 0xD5, 0x17, 0xD5, 0xF3, 0xCC, + 0x41, 0x61, 0xD2, 0xA6, 0xF4, 0x51, 0x24, 0x3A, + 0x63, 0x5D, 0x23, 0xB1, 0xF0, 0x22, 0xE7, 0x45, + 0xFA, 0x5F, 0x7E, 0x99, 0x00, 0x11, 0x28, 0x35, + 0xA3, 0xF4, 0x61, 0x94, 0x0E, 0x98, 0xCE, 0x35, + 0xDD, 0x91, 0x1B, 0x0B, 0x4D, 0xEE, 0xFF, 0xFF, + 0x0B, 0xD4, 0xDC, 0x56, 0xFC, 0x71, 0xE9, 0xEC, + 0xE8, 0x36, 0x51, 0xF8, 0x8B, 0x6A, 0xE1, 0x8C, + 0x2B, 0x25, 0x91, 0x91, 0x9B, 0x92, 0x76, 0xB5, + 0x3D, 0x26, 0xA8, 0x53, 0xEA, 0x30, 0x5B, 0x4D, + 0xDA, 0x16, 0xDA, 0x7D, 0x04, 0x88, 0xF5, 0x22, + 0xA8, 0x0C, 0xB9, 0x41, 0xC7, 0x91, 0x64, 0x86, + 0x99, 0x7D, 0x18, 0xB9, 0x67, 0xA2, 0x6E, 0x05, + 0x1A, 0x82, 0x8F, 0xA2, 0xEB, 0x4D, 0x0B, 0x8C, + 0x88, 0x2D, 0xBA, 0x77, 0x87, 0x32, 0x50, 0x3C, + 0x4C, 0xD8, 0xD3, 0x50, 0x39, 0xFA, 0xDF, 0x48, + 0x3E, 0x30, 0xF5, 0x76, 0x06, 0xB0, 0x1A, 0x05, + 0x60, 0x2C, 0xD3, 0xA0, 0x63, 0x1A, 0x19, 0x2D, + 0x6B, 0x76, 0xF2, 0x31, 0x4C, 0xA7, 0xE6, 0x5C, + 0x1B, 0x23, 0x20, 0x41, 0x32, 0xE5, 0x83, 0x47, + 0x04, 0xB6, 0x3E, 0xE0, 0xFD, 0x49, 0x1E, 0x1B, + 0x75, 0x10, 0x11, 0x46, 0xE9, 0xF9, 0x96, 0x9A, + 0xD7, 0x59, 0xFE, 0x38, 0x31, 0xFE, 0x79, 0xC4, + 0xC8, 0x46, 0x88, 0xDE, 0x2E, 0xAE, 0x20, 0xED, + 0x77, 0x50, 0x40, 0x38, 0x26, 0xD3, 0x35, 0xF6, + 0x29, 0x55, 0x6A, 0x6B, 0x38, 0x69, 0xFE, 0x90, + 0x5B, 0xA7, 0xFA, 0x6B, 0x73, 0x4F, 0xB9, 0x5D, + 0xDC, 0x6F, 0x98, 0xC3, 0x6A, 0xC4, 0xB5, 0x09, + 0xC5, 0x84, 0xA5, 0x6A, 0x84, 0xA4, 0xB3, 0x8A, + 0x5F, 0xCA, 0x92, 0x64, 0x9E, 0xC3, 0x0F, 0x84, + 0x8B, 0x2D, 0x48, 0xC6, 0x67, 0xAE, 0x07, 0xE0, + 0x28, 0x38, 0x6D, 0xC4, 0x4D, 0x13, 0x87, 0xE0, + 0xB2, 0x2F, 0xAA, 0xC0, 0xCF, 0x68, 0xD7, 0x9C, + 0xB8, 0x07, 0xE4, 0x51, 0xD7, 0x75, 0x86, 0xFA, + 0x0C, 0x50, 0x74, 0x68, 0x00, 0x64, 0x2A, 0x27, + 0x59, 0xE9, 0x80, 0xEB, 0xC2, 0xA3, 0xFA, 0x58, + 0xCC, 0x03, 0xE7, 0x7B, 0x66, 0x53, 0xFF, 0x90, + 0xA0, 0x85, 0xE2, 0xF8, 0x82, 0xFE, 0xC6, 0x2B, + 0xFF, 0x5E, 0x70, 0x85, 0x34, 0xB7, 0x22, 0x38, + 0xDB, 0xBC, 0x15, 0x30, 0x59, 0xC1, 0x48, 0x42, + 0xE5, 0x38, 0x8D, 0x37, 0x59, 0xDB, 0xA3, 0x20, + 0x17, 0x36, 0x1D, 0x4B, 0xBF, 0x4E, 0xA4, 0x35, + 0xCC, 0xFE, 0xF5, 0x7A, 0x73, 0xB4, 0x6D, 0x20, + 0x1D, 0xC0, 0xE5, 0x21, 0x5C, 0xD2, 0x8A, 0x65, + 0x08, 0xB6, 0x63, 0xAC, 0x9A, 0x1E, 0x3F, 0x3C, + 0xAB, 0xB6, 0x6D, 0x34, 0xB2, 0x3A, 0x08, 0xDA, + 0x29, 0x63, 0xD1, 0xA4, 0x83, 0x52, 0xB0, 0x63, + 0x1B, 0x89, 0x35, 0x57, 0x59, 0x2C, 0x0F, 0x72, + 0x72, 0xFD, 0xA0, 0xAC, 0xDB, 0xB4, 0xA3, 0xA1, + 0x18, 0x10, 0x12, 0x97, 0x99, 0x63, 0x38, 0x98, + 0x96, 0xB5, 0x16, 0x07, 0x4E, 0xE9, 0x2C, 0x97 +}; + +static const struct blockcipher_test_data +triple_des192ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xEA, 0x62, 0xB9, 0xB2, 0x78, 0x6C, 0x8E, 0xDB, + 0xA3, 0xB6, 0xFF, 0x23, 0x3A, 0x47, 0xD8, 0xC8, + 0xED, 0x5E, 0x20, 0x1D + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .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 = { + 0x32, 0xD5, 0x19, 0x8F, 0x79, 0x3A, 0xAA, 0x7B, + 0x70, 0x67, 0x4E, 0x63, 0x88, 0xA3, 0x9A, 0x82, + 0x07, 0x33, 0x12, 0x94 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des128cbc[] = { + 0x28, 0x2a, 0xff, 0x15, 0x5c, 0xdf, 0xd9, 0x6b, + 0x54, 0xbc, 0x7b, 0xfb, 0xc5, 0x64, 0x4d, 0xdd, + 0x3e, 0xf2, 0x9e, 0xb7, 0x53, 0x65, 0x37, 0x05, + 0xe0, 0xdf, 0xae, 0xf7, 0xc9, 0x27, 0xe4, 0xec, + 0x11, 0x27, 0xc2, 0x9e, 0x02, 0x4e, 0x03, 0x3b, + 0x33, 0xf2, 0x66, 0x08, 0x24, 0x5f, 0xab, 0xc2, + 0x7e, 0x21, 0x19, 0x5d, 0x51, 0xc3, 0xe2, 0x97, + 0x6f, 0x2e, 0xb4, 0xaa, 0x34, 0x70, 0x88, 0x78, + 0x4e, 0xe7, 0x3d, 0xe1, 0x9f, 0x87, 0x1c, 0x8b, + 0xac, 0x8d, 0xa1, 0x1a, 0xcd, 0xb0, 0xf8, 0xb6, + 0x24, 0x36, 0xe3, 0x8c, 0x07, 0xe7, 0xe4, 0x92, + 0x13, 0x86, 0x6f, 0x13, 0xec, 0x04, 0x5c, 0xe9, + 0xb9, 0xca, 0x45, 0x8a, 0x2c, 0x46, 0xda, 0x54, + 0x1d, 0xb5, 0x81, 0xb1, 0xcd, 0xf3, 0x7d, 0x11, + 0x6b, 0xb3, 0x0a, 0x45, 0xe5, 0x6e, 0x51, 0x3e, + 0x2c, 0xac, 0x7c, 0xbc, 0xa7, 0x7e, 0x22, 0x4d, + 0xe6, 0x02, 0xe3, 0x3f, 0x77, 0xd7, 0x73, 0x72, + 0x0e, 0xfb, 0x42, 0x85, 0x80, 0xdf, 0xa8, 0x91, + 0x60, 0x40, 0x48, 0xcd, 0x1b, 0xd9, 0xbf, 0x2f, + 0xf2, 0xdf, 0xd0, 0xbd, 0x3f, 0x82, 0xce, 0x15, + 0x9d, 0x6e, 0xc6, 0x59, 0x6f, 0x27, 0x0d, 0xf9, + 0x26, 0xe2, 0x11, 0x29, 0x50, 0xc3, 0x0a, 0xb7, + 0xde, 0x9d, 0xe9, 0x55, 0xa1, 0xe9, 0x01, 0x33, + 0x56, 0x51, 0xa7, 0x3a, 0x9e, 0x63, 0xc5, 0x08, + 0x01, 0x3b, 0x03, 0x4b, 0xc6, 0xc4, 0xa1, 0xc0, + 0xc0, 0xd0, 0x0e, 0x48, 0xe5, 0x4c, 0x55, 0x6b, + 0x4a, 0xc1, 0x0a, 0x24, 0x4b, 0xd0, 0x02, 0xf4, + 0x31, 0x63, 0x11, 0xbd, 0xa6, 0x1f, 0xf4, 0xae, + 0x23, 0x5a, 0x40, 0x7e, 0x0e, 0x4e, 0x63, 0x8b, + 0x66, 0x3d, 0x55, 0x46, 0x6e, 0x5c, 0x76, 0xa7, + 0x68, 0x31, 0xce, 0x5d, 0xca, 0xe2, 0xb4, 0xb0, + 0xc1, 0x1f, 0x66, 0x18, 0x75, 0x64, 0x73, 0xa9, + 0x9e, 0xd5, 0x0e, 0x0e, 0xf7, 0x77, 0x61, 0xf8, + 0x89, 0xc6, 0xcf, 0x0c, 0x41, 0xd3, 0x8f, 0xfd, + 0x22, 0x52, 0x4f, 0x94, 0x5c, 0x19, 0x11, 0x3a, + 0xb5, 0x63, 0xe8, 0x81, 0x33, 0x13, 0x54, 0x3c, + 0x93, 0x36, 0xb5, 0x5b, 0x51, 0xaf, 0x51, 0xa2, + 0x08, 0xae, 0x83, 0x15, 0x77, 0x07, 0x28, 0x0d, + 0x98, 0xe1, 0x2f, 0x69, 0x0e, 0xfb, 0x9a, 0x2e, + 0x27, 0x27, 0xb0, 0xd5, 0xce, 0xf8, 0x16, 0x55, + 0xfd, 0xaa, 0xd7, 0x1a, 0x1b, 0x2e, 0x4c, 0x86, + 0x7a, 0x6a, 0x90, 0xf7, 0x0a, 0x07, 0xd3, 0x81, + 0x4b, 0x75, 0x6a, 0x79, 0xdb, 0x63, 0x45, 0x0f, + 0x31, 0x7e, 0xd0, 0x2a, 0x14, 0xff, 0xee, 0xcc, + 0x97, 0x8a, 0x7d, 0x74, 0xbd, 0x9d, 0xaf, 0x00, + 0xdb, 0x7e, 0xf3, 0xe6, 0x22, 0x76, 0x77, 0x58, + 0xba, 0x1c, 0x06, 0x96, 0xfb, 0x6f, 0x41, 0x71, + 0x66, 0x98, 0xae, 0x31, 0x7d, 0x29, 0x18, 0x71, + 0x0e, 0xe4, 0x98, 0x7e, 0x59, 0x5a, 0xc9, 0x78, + 0x9c, 0xfb, 0x6c, 0x81, 0x44, 0xb4, 0x0f, 0x5e, + 0x18, 0x53, 0xb8, 0x6f, 0xbc, 0x3b, 0x15, 0xf0, + 0x10, 0xdd, 0x0d, 0x4b, 0x0a, 0x36, 0x0e, 0xb4, + 0x76, 0x0f, 0x16, 0xa7, 0x5c, 0x9d, 0xcf, 0xb0, + 0x6d, 0x38, 0x02, 0x07, 0x05, 0xe9, 0xe9, 0x46, + 0x08, 0xb8, 0x52, 0xd6, 0xd9, 0x4c, 0x81, 0x63, + 0x1d, 0xe2, 0x5b, 0xd0, 0xf6, 0x5e, 0x1e, 0x81, + 0x48, 0x08, 0x66, 0x3a, 0x85, 0xed, 0x65, 0xfe, + 0xe8, 0x05, 0x7a, 0xe1, 0xe6, 0x12, 0xf2, 0x52, + 0x83, 0xdd, 0x82, 0xbe, 0xf6, 0x34, 0x8a, 0x6f, + 0xc5, 0x83, 0xcd, 0x3f, 0xbe, 0x58, 0x8b, 0x11, + 0x78, 0xdc, 0x0c, 0x83, 0x72, 0x5d, 0x05, 0x2a, + 0x01, 0x29, 0xee, 0x48, 0x9a, 0x67, 0x00, 0x6e, + 0x14, 0x60, 0x2d, 0x00, 0x52, 0x87, 0x98, 0x5e, + 0x43, 0xfe, 0xf1, 0x10, 0x14, 0xf1, 0x91, 0xcc +}; + + +static const uint8_t ciphertext512_des[] = { + 0x1A, 0x46, 0xDB, 0x69, 0x43, 0x45, 0x0F, 0x2F, + 0xDC, 0x27, 0xF9, 0x41, 0x0E, 0x01, 0x58, 0xB4, + 0x5E, 0xCC, 0x13, 0xF5, 0x92, 0x99, 0xE4, 0xF2, + 0xD5, 0xF9, 0x16, 0xFE, 0x0F, 0x7E, 0xDE, 0xA0, + 0xF5, 0x32, 0xFE, 0x20, 0x67, 0x93, 0xCA, 0xE1, + 0x8E, 0x4D, 0x72, 0xA3, 0x50, 0x72, 0x14, 0x15, + 0x70, 0xE7, 0xAB, 0x49, 0x25, 0x88, 0x0E, 0x01, + 0x5C, 0x52, 0x87, 0xE2, 0x27, 0xDC, 0xD4, 0xD1, + 0x14, 0x1B, 0x08, 0x9F, 0x42, 0x48, 0x93, 0xA9, + 0xD1, 0x2F, 0x2C, 0x69, 0x48, 0x16, 0x59, 0xCF, + 0x8B, 0xF6, 0x8B, 0xD9, 0x34, 0xD4, 0xD7, 0xE4, + 0xAE, 0x35, 0xFD, 0xDA, 0x73, 0xBE, 0xDC, 0x6B, + 0x10, 0x90, 0x75, 0x2D, 0x4C, 0x14, 0x37, 0x8B, + 0xC8, 0xC7, 0xDF, 0x6E, 0x6F, 0xED, 0xF3, 0xE3, + 0xD3, 0x21, 0x29, 0xCD, 0x06, 0xB6, 0x5B, 0xF4, + 0xB9, 0xBD, 0x77, 0xA2, 0xF7, 0x91, 0xF4, 0x95, + 0xF0, 0xE0, 0x62, 0x03, 0x46, 0xAE, 0x1B, 0xEB, + 0xE2, 0xA9, 0xCF, 0xB9, 0x0E, 0x3B, 0xB9, 0xDA, + 0x5C, 0x1B, 0x45, 0x3F, 0xDD, 0xCC, 0xCC, 0xB3, + 0xF0, 0xDD, 0x36, 0x26, 0x11, 0x57, 0x97, 0xA7, + 0xF6, 0xF4, 0xE1, 0x4F, 0xBB, 0x31, 0xBB, 0x07, + 0x4B, 0xA3, 0xB4, 0x83, 0xF9, 0x23, 0xA1, 0xCD, + 0x8C, 0x1C, 0x76, 0x92, 0x45, 0xA5, 0xEB, 0x7D, + 0xEB, 0x22, 0x88, 0xB1, 0x9F, 0xFB, 0xE9, 0x06, + 0x8F, 0x67, 0xA6, 0x8A, 0xB7, 0x0B, 0xCD, 0x8F, + 0x34, 0x40, 0x4F, 0x4F, 0xAD, 0xA0, 0xF2, 0xDC, + 0x2C, 0x53, 0xE1, 0xCA, 0xA5, 0x7A, 0x03, 0xEF, + 0x08, 0x00, 0xCC, 0x52, 0xA6, 0xAB, 0x56, 0xD2, + 0xF1, 0xCD, 0xC7, 0xED, 0xBE, 0xCB, 0x78, 0x37, + 0x4B, 0x61, 0xA9, 0xD2, 0x3C, 0x8D, 0xCC, 0xFD, + 0x21, 0xFD, 0x0F, 0xE4, 0x4E, 0x3D, 0x6F, 0x8F, + 0x2A, 0xEC, 0x69, 0xFA, 0x20, 0x50, 0x99, 0x35, + 0xA1, 0xCC, 0x3B, 0xFD, 0xD6, 0xAC, 0xE9, 0xBE, + 0x14, 0xF1, 0xBC, 0x71, 0x70, 0xFE, 0x13, 0xD1, + 0x48, 0xCC, 0xBE, 0x7B, 0xCB, 0xC0, 0x20, 0xD9, + 0x28, 0xD7, 0xD4, 0x0F, 0x66, 0x7A, 0x60, 0xAB, + 0x20, 0xA9, 0x23, 0x41, 0x03, 0x34, 0xC3, 0x63, + 0x91, 0x69, 0x02, 0xD5, 0xBC, 0x41, 0xDA, 0xA8, + 0xD1, 0x48, 0xC9, 0x8E, 0x4F, 0xCD, 0x0F, 0x21, + 0x5B, 0x4D, 0x5F, 0xF5, 0x1B, 0x2A, 0x44, 0x10, + 0x16, 0xA7, 0xFD, 0xC0, 0x55, 0xE1, 0x98, 0xBB, + 0x76, 0xB5, 0xAB, 0x39, 0x6B, 0x9B, 0xAB, 0x85, + 0x45, 0x4B, 0x9C, 0x64, 0x7D, 0x78, 0x3F, 0x61, + 0x22, 0xB1, 0xDE, 0x0E, 0x39, 0x2B, 0x21, 0x26, + 0xE2, 0x1D, 0x5A, 0xD7, 0xAC, 0xDF, 0xD4, 0x12, + 0x69, 0xD1, 0xE8, 0x9B, 0x1A, 0xCE, 0x6C, 0xA0, + 0x3B, 0x23, 0xDC, 0x03, 0x2B, 0x97, 0x16, 0xD0, + 0xD0, 0x46, 0x98, 0x36, 0x53, 0xCE, 0x88, 0x6E, + 0xCA, 0x2C, 0x15, 0x0E, 0x49, 0xED, 0xBE, 0xE5, + 0xBF, 0xBD, 0x7B, 0xC2, 0x21, 0xE1, 0x09, 0xFF, + 0x71, 0xA8, 0xBE, 0x8F, 0xB4, 0x1D, 0x25, 0x5C, + 0x37, 0xCA, 0x26, 0xD2, 0x1E, 0x63, 0xE1, 0x7F, + 0x0D, 0x89, 0x10, 0xEF, 0x78, 0xB0, 0xDB, 0xD0, + 0x72, 0x44, 0x60, 0x1D, 0xCF, 0x7C, 0x25, 0x1A, + 0xBB, 0xC3, 0x92, 0x53, 0x8E, 0x9F, 0x27, 0xC7, + 0xE8, 0x08, 0xFC, 0x5D, 0x50, 0x3E, 0xFC, 0xB0, + 0x00, 0xE2, 0x48, 0xB2, 0x4B, 0xF8, 0xF2, 0xE3, + 0xD3, 0x8B, 0x71, 0x64, 0xB8, 0xF0, 0x6E, 0x4A, + 0x23, 0xA0, 0xA4, 0x88, 0xA4, 0x36, 0x45, 0x6B, + 0x5A, 0xE7, 0x57, 0x65, 0xEA, 0xC9, 0xF8, 0xE8, + 0x7A, 0x80, 0x22, 0x67, 0x1A, 0x05, 0xF2, 0x78, + 0x81, 0x17, 0xCD, 0x87, 0xFB, 0x0D, 0x25, 0x84, + 0x49, 0x06, 0x25, 0xCE, 0xFC, 0x38, 0x06, 0x18, + 0x2E, 0x1D, 0xE1, 0x33, 0x97, 0xB6, 0x7E, 0xAB, +}; + + +static const struct blockcipher_test_data +triple_des128cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_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 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_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 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x94, 0x45, 0x7B, 0xDF, 0xFE, 0x80, 0xB9, 0xA6, + 0xA0, 0x7A, 0xE8, 0x93, 0x40, 0x7B, 0x85, 0x02, + 0x1C, 0xD7, 0xE8, 0x87 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_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 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .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 = { + 0x7E, 0xBA, 0xFF, 0x86, 0x8D, 0x65, 0xCD, 0x08, + 0x76, 0x34, 0x94, 0xE9, 0x9A, 0xCD, 0xB2, 0xBB, + 0xBF, 0x65, 0xF5, 0x42 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192cbc[] = { + 0xd0, 0xc9, 0xdc, 0x51, 0x29, 0x97, 0x03, 0x64, + 0xcd, 0x22, 0xba, 0x3d, 0x2b, 0xbc, 0x21, 0x37, + 0x7b, 0x1e, 0x29, 0x23, 0xeb, 0x51, 0x6e, 0xac, + 0xbe, 0x5b, 0xd3, 0x67, 0xe0, 0x3f, 0xc3, 0xb5, + 0xe3, 0x04, 0x17, 0x42, 0x2b, 0xaa, 0xdd, 0xd6, + 0x0e, 0x69, 0xd0, 0x8f, 0x8a, 0xfc, 0xb4, 0x55, + 0x67, 0x06, 0x51, 0xbb, 0x00, 0x57, 0xee, 0x95, + 0x28, 0x79, 0x3f, 0xd9, 0x97, 0x2b, 0xb0, 0x02, + 0x35, 0x08, 0xce, 0x7a, 0xc3, 0x43, 0x2c, 0x87, + 0xaa, 0x97, 0x6a, 0xad, 0xf0, 0x26, 0xea, 0x1d, + 0xbb, 0x08, 0xe9, 0x52, 0x11, 0xd3, 0xaf, 0x36, + 0x17, 0x14, 0x21, 0xb2, 0xbc, 0x42, 0x51, 0x33, + 0x27, 0x8c, 0xd8, 0x45, 0xb9, 0x76, 0xa0, 0x11, + 0x24, 0x34, 0xde, 0x4d, 0x13, 0x67, 0x1b, 0xc3, + 0x31, 0x12, 0x66, 0x56, 0x59, 0xd2, 0xb1, 0x8f, + 0xec, 0x1e, 0xc0, 0x10, 0x7a, 0x86, 0xb1, 0x60, + 0xc3, 0x01, 0xd6, 0xa8, 0x55, 0xad, 0x58, 0x63, + 0xca, 0x68, 0xa9, 0x33, 0xe3, 0x93, 0x90, 0x7d, + 0x8f, 0xca, 0xf8, 0x1c, 0xc2, 0x9e, 0xfb, 0xde, + 0x9c, 0xc7, 0xf2, 0x6c, 0xff, 0xcc, 0x39, 0x17, + 0x49, 0x33, 0x0d, 0x7c, 0xed, 0x07, 0x99, 0x91, + 0x91, 0x6c, 0x5f, 0x3f, 0x02, 0x09, 0xdc, 0x70, + 0xf9, 0x3b, 0x8d, 0xaa, 0xf4, 0xbc, 0x0e, 0xec, + 0xf2, 0x26, 0xfb, 0xb2, 0x1c, 0x31, 0xae, 0xc6, + 0x72, 0xe8, 0x0b, 0x75, 0x05, 0x57, 0x58, 0x98, + 0x92, 0x37, 0x27, 0x8e, 0x3b, 0x0c, 0x25, 0xfb, + 0xcf, 0x82, 0x02, 0xd5, 0x0b, 0x1f, 0x89, 0x49, + 0xcd, 0x0f, 0xa1, 0xa7, 0x08, 0x63, 0x56, 0xa7, + 0x1f, 0x80, 0x3a, 0xef, 0x24, 0x89, 0x57, 0x1a, + 0x02, 0xdc, 0x2e, 0x51, 0xbd, 0x4a, 0x10, 0x23, + 0xfc, 0x02, 0x1a, 0x3f, 0x34, 0xbf, 0x1c, 0x98, + 0x1a, 0x40, 0x0a, 0x96, 0x8e, 0x41, 0xd5, 0x09, + 0x55, 0x37, 0xe9, 0x25, 0x11, 0x83, 0xf8, 0xf3, + 0xd4, 0xb0, 0xdb, 0x16, 0xd7, 0x51, 0x7e, 0x94, + 0xf7, 0xb4, 0x26, 0xe0, 0xf4, 0x80, 0x01, 0x65, + 0x51, 0xeb, 0xbc, 0xb0, 0x65, 0x8f, 0xdd, 0xb5, + 0xf7, 0x00, 0xec, 0x40, 0xab, 0x7d, 0x96, 0xcc, + 0x8d, 0xec, 0x89, 0x80, 0x31, 0x39, 0xa2, 0x5c, + 0xb0, 0x55, 0x4c, 0xee, 0xdd, 0x15, 0x2b, 0xa9, + 0x86, 0x4e, 0x23, 0x14, 0x36, 0xc5, 0x57, 0xf5, + 0xe3, 0xe8, 0x89, 0xc9, 0xb7, 0xf8, 0xeb, 0x08, + 0xe5, 0x93, 0x12, 0x5c, 0x0f, 0x79, 0xa1, 0x86, + 0xe4, 0xc2, 0xeb, 0xa6, 0xa0, 0x50, 0x6a, 0xec, + 0xd3, 0xce, 0x50, 0x78, 0x4e, 0x4f, 0x93, 0xd8, + 0xdc, 0xb4, 0xec, 0x02, 0xe9, 0xbd, 0x17, 0x99, + 0x1e, 0x16, 0x4e, 0xd7, 0xb0, 0x07, 0x02, 0x55, + 0x63, 0x24, 0x4f, 0x7b, 0x8f, 0xc5, 0x7a, 0x12, + 0x29, 0xff, 0x5d, 0xc1, 0xe7, 0xae, 0x48, 0xc8, + 0x57, 0x53, 0xe7, 0xcd, 0x10, 0x6c, 0x19, 0xfc, + 0xcc, 0xb9, 0xb1, 0xbe, 0x48, 0x9f, 0x2d, 0x3f, + 0x39, 0x2e, 0xdd, 0x71, 0xde, 0x1b, 0x54, 0xee, + 0x7d, 0x94, 0x8f, 0x27, 0x23, 0xe9, 0x74, 0x92, + 0x14, 0x93, 0x84, 0x65, 0xc9, 0x22, 0x7c, 0xa8, + 0x1b, 0x72, 0x73, 0xb1, 0x23, 0xa0, 0x6b, 0xcc, + 0xb5, 0x22, 0x06, 0x15, 0xe5, 0x96, 0x03, 0x4a, + 0x52, 0x8d, 0x1d, 0xbf, 0x3e, 0x82, 0x45, 0x9c, + 0x75, 0x9e, 0xa9, 0x3a, 0x97, 0xb6, 0x5d, 0xc4, + 0x75, 0x67, 0xa1, 0xf3, 0x0f, 0x7a, 0xfd, 0x71, + 0x58, 0x04, 0xf9, 0xa7, 0xc2, 0x56, 0x74, 0x04, + 0x74, 0x68, 0x6d, 0x8a, 0xf6, 0x6c, 0x5d, 0xd8, + 0xb5, 0xed, 0x70, 0x23, 0x32, 0x4d, 0x75, 0x92, + 0x88, 0x7b, 0x39, 0x37, 0x02, 0x4b, 0xb2, 0x1c, + 0x1f, 0x7e, 0x5b, 0x1b, 0x10, 0xfc, 0x17, 0x21, + 0x66, 0x62, 0x63, 0xc2, 0xcd, 0x16, 0x96, 0x3e +}; + +static const struct blockcipher_test_data +triple_des192cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x53, 0x27, 0xC0, 0xE6, 0xD6, 0x1B, 0xD6, 0x45, + 0x94, 0x2D, 0xCE, 0x8B, 0x29, 0xA3, 0x52, 0x14, + 0xC1, 0x6B, 0x87, 0x99 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .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 = { + 0xBA, 0xAC, 0x74, 0x19, 0x43, 0xB0, 0x72, 0xB8, + 0x08, 0xF5, 0x24, 0xC4, 0x09, 0xBD, 0x48, 0xC1, + 0x3C, 0x50, 0x1C, 0xDD + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +des_cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2 + }, + .len = 8 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des, + .len = 512 + }, +}; + +static const struct blockcipher_test_case des_cipheronly_test_cases[] = { + { + .test_descr = "DES-CBC Encryption", + .test_data = &des_cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "DES-CBC Decryption", + .test_data = &des_cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + +}; + +static const struct blockcipher_test_case triple_des_chain_test_cases[] = { + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC SHA1 Encryption Digest", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "3DES-128-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC SHA1 Encryption Digest", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "3DES-192-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR SHA1 Encryption Digest", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "3DES-128-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR SHA1 Encryption Digest", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "3DES-192-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest" + " Verify OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest" + " Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = + "3DES-128-CBC HMAC-SHA1 Decryption Digest" + " Verify Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, +}; + +static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { + { + .test_descr = "3DES-128-CBC Encryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC Decryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Encryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Decryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Encryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Decryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Encryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Decryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + } +}; + +#endif /* TEST_CRYPTODEV_DES_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_gcm_test_vectors.h b/test/test/test_cryptodev_gcm_test_vectors.h new file mode 100644 index 0000000000..5764edb118 --- /dev/null +++ b/test/test/test_cryptodev_gcm_test_vectors.h @@ -0,0 +1,3051 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 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_GCM_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ + +#define GMAC_LARGE_PLAINTEXT_LENGTH 65344 +#define GCM_MAX_AAD_LENGTH 65536 +#define GCM_LARGE_AAD_LENGTH 65296 + +static uint8_t gcm_aad_zero_text[GCM_MAX_AAD_LENGTH] = { 0 }; + +static uint8_t gcm_aad_text[GCM_MAX_AAD_LENGTH] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0x00, 0xf1, 0xe2, 0xd3, 0xc4, 0xb5, 0xa6, 0x97, + 0x88, 0x79, 0x6a, 0x5b, 0x4c, 0x3d, 0x2e, 0x1f }; + + +struct gcm_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; + unsigned len; + } aad; + + struct { + uint8_t data[8096]; + unsigned len; + } plaintext; + + struct { + uint8_t data[8096]; + unsigned len; + } ciphertext; + + struct { + uint8_t data[16]; + unsigned len; + } auth_tag; +}; + +struct gmac_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; + unsigned len; + } aad; + + struct { + uint8_t *data; + unsigned len; + } plaintext; + + struct { + uint8_t data[16]; + unsigned len; + } gmac_tag; + +}; + +/** AES-128 Test Vectors */ +static const struct gcm_test_data gcm_test_case_1 = { + .key = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0x00 }, + .len = 0 + }, + .ciphertext = { + .data = { + 0x00 + }, + .len = 0 + }, + .auth_tag = { + .data = { + 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, + .len = 16 + } +}; + +/** AES-128 Test Vectors */ +static const struct gcm_test_data gcm_test_case_2 = { + .key = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .len = 16 + }, + .ciphertext = { + .data = { + 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, + .len = 16 + }, + .auth_tag = { + .data = { + 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, + .len = 16 + } +}; + +/** AES-128 Test Vectors */ +static const struct gcm_test_data gcm_test_case_3 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, + .len = 64 + }, + .ciphertext = { + .data = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 + }, + .len = 64 + }, + .auth_tag = { + .data = { + 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, + .len = 16 + } +}; + +/** AES-128 Test Vectors */ +static const struct gcm_test_data gcm_test_case_4 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 8 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 + }, + .len = 60 + }, + .ciphertext = { + .data = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 + }, + .len = 60 + }, + .auth_tag = { + .data = { + 0xA2, 0xA4, 0x35, 0x75, 0xDC, 0xB0, 0x57, 0x74, + 0x07, 0x02, 0x30, 0xC2, 0xE7, 0x52, 0x02, 0x00 + }, + .len = 16 + } + +}; + +/** AES-128 Test Vectors */ +static const struct gcm_test_data gcm_test_case_5 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_text, + .len = 8 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 + }, + .len = 60 + }, + .ciphertext = { + .data = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 + }, + .len = 60 + }, + .auth_tag = { + .data = { + 0xC5, 0x2D, 0xFB, 0x54, 0xAF, 0xBB, 0x07, 0xA1, + 0x9A, 0xFF, 0xBE, 0xE0, 0x61, 0x4C, 0xE7, 0xA5 + }, + .len = 16 + } + +}; + +/** AES-128 Test Vectors */ +static const struct gcm_test_data gcm_test_case_6 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 + }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 12 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 + }, + .len = 60 + }, + .ciphertext = { + .data = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 + }, + .len = 60 + }, + .auth_tag = { + .data = { + 0x74, 0xFC, 0xFA, 0x29, 0x3E, 0x60, 0xCC, 0x66, + 0x09, 0xD6, 0xFD, 0x00, 0xC8, 0x86, 0xD5, 0x42 + }, + .len = 16 + } +}; + +/** AES-128 Test Vectors */ +static const struct gcm_test_data gcm_test_case_7 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 + }, + .len = 12 + }, + .aad = { + .data = gcm_aad_text, + .len = 12 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 + }, + .len = 60 + }, + .ciphertext = { + .data = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 + }, + .len = 60 + }, + .auth_tag = { + .data = { + 0xE9, 0xE4, 0xAB, 0x76, 0xB7, 0xFF, 0xEA, 0xDC, + 0x69, 0x79, 0x38, 0xA2, 0x0D, 0xCA, 0xF5, 0x92 + }, + .len = 16 + } +}; + +static const struct gcm_test_data gcm_test_case_8 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 + }, + .len = 12 + }, + .aad = { + .data = gcm_aad_text, + .len = 12 + }, + .plaintext = { + .data = { + 0xC5, 0x34, 0x2E, 0x83, 0xEB, 0x4C, 0x02, 0x03, + 0xF7, 0xB2, 0x57, 0x35, 0x26, 0x81, 0x63, 0xAE, + 0x1F, 0xCD, 0x2D, 0x02, 0x91, 0x5A, 0xDB, 0x3A, + 0xF1, 0x38, 0xD8, 0x75, 0x86, 0x20, 0xCC, 0x1E, + 0xE6, 0xDC, 0xFF, 0xB5, 0xEA, 0x0E, 0x18, 0x7A, + 0x86, 0x6C, 0xAB, 0x39, 0x2D, 0x90, 0xAC, 0x77, + 0x5D, 0xED, 0x65, 0xB3, 0x05, 0x29, 0xBB, 0x09, + 0xD0, 0x21, 0x74, 0x6A, 0x67, 0x1C, 0x95, 0x42, + 0x55, 0xAD, 0xC8, 0x91, 0x28, 0xFE, 0x16, 0x9A, + 0xE1, 0xCB, 0xCD, 0x68, 0x3B, 0xDF, 0x3E, 0x3A, + 0x34, 0xFE, 0x9B, 0xFB, 0xF5, 0x15, 0x2A, 0x29, + 0x18, 0x99, 0x24, 0xBF, 0xB6, 0x43, 0xDB, 0xD1, + 0x69, 0x26, 0x1E, 0x31, 0x2C, 0x8C, 0x3C, 0x6B, + 0x7F, 0x06, 0xA6, 0x03, 0xE2, 0x1A, 0x50, 0xFE, + 0x7C, 0x69, 0xE5, 0x5F, 0x35, 0x93, 0xE9, 0x20, + 0x14, 0xB1, 0xCA, 0x61, 0xE7, 0x9C, 0x89, 0x08, + 0xD6, 0xB1, 0xC2, 0x63, 0x1B, 0x86, 0x5E, 0xF1, + 0xF5, 0x23, 0x0E, 0x9B, 0xE5, 0xBD, 0x5D, 0x04, + 0xF7, 0xEF, 0x8E, 0x46, 0xB0, 0x11, 0x4F, 0x69, + 0x62, 0x35, 0x51, 0xB7, 0x24, 0xA2, 0x31, 0xD0, + 0x32, 0x4E, 0xB8, 0x44, 0xC7, 0x59, 0xDE, 0x25, + 0xEA, 0x2D, 0x00, 0x0E, 0xF1, 0x07, 0xBA, 0xBB, + 0x9A, 0xBC, 0x4F, 0x57, 0xB7, 0x13, 0x57, 0xEF, + 0xD9, 0xF6, 0x80, 0x69, 0xEA, 0xE8, 0x47, 0x9C, + 0x51, 0x71, 0xE6, 0x8F, 0x69, 0x29, 0xB4, 0x60, + 0xE8, 0x50, 0xE5, 0xD0, 0x9B, 0xD2, 0x62, 0x6F, + 0x09, 0x5C, 0xD1, 0x4B, 0x85, 0xE2, 0xFD, 0xD3, + 0xEB, 0x28, 0x55, 0x77, 0x97, 0xCA, 0xD6, 0xA8, + 0xDC, 0x35, 0x68, 0xF7, 0x6A, 0xCF, 0x48, 0x3F, + 0x49, 0x31, 0x00, 0x65, 0xB7, 0x31, 0x1A, 0x49, + 0x75, 0xDE, 0xCE, 0x7F, 0x18, 0xB5, 0x31, 0x9A, + 0x64, 0x6D, 0xE5, 0x49, 0x1D, 0x6D, 0xF2, 0x21, + 0x9F, 0xF5, 0xFF, 0x7C, 0x41, 0x30, 0x33, 0x06, + 0x7B, 0xA4, 0xD8, 0x99, 0xF6, 0xCC, 0xDF, 0xC4, + 0x3F, 0xF3, 0xCD, 0xE7, 0x74, 0xC4, 0x4A, 0x19, + 0x5C, 0xCA, 0x42, 0x31, 0xF1, 0x3B, 0x65, 0x1C, + 0x3D, 0x56, 0x08, 0xBE, 0x15, 0x37, 0x23, 0x50, + 0xD6, 0xA3, 0x57, 0x64, 0x25, 0xBE, 0xDA, 0xC2, + 0x4E, 0xF5, 0x1A, 0xAD, 0x6F, 0x43, 0x78, 0x21, + 0xF9, 0x36, 0x39, 0x1F, 0x5F, 0xF7, 0x1B, 0xA0, + 0xEE, 0x8B, 0x4F, 0x8A, 0x9D, 0xD8, 0xED, 0x37, + 0xCE, 0x0D, 0x70, 0xE0, 0x3F, 0xE7, 0x11, 0x30, + 0x17, 0x1D, 0x03, 0x5E, 0xA0, 0x3D, 0x3F, 0x9E, + 0xF5, 0xD3, 0x74, 0x2E, 0xC1, 0xD6, 0xFF, 0xF7, + 0x2E, 0xE7, 0x80, 0x88, 0xCF, 0x0E, 0x7F, 0x12, + 0x71, 0x62, 0xC7, 0xF1, 0xC4, 0x2B, 0x64, 0x5D, + 0x1C, 0x9A, 0xB4, 0xCB, 0xB8, 0x24, 0xB3, 0x0B, + 0x33, 0xF2, 0x8A, 0x8F, 0x76, 0xC8, 0x81, 0xDA, + 0x1A, 0x10, 0xB5, 0xA9, 0xCD, 0xDC, 0x1A, 0x02, + 0xC1, 0xAE, 0x4F, 0x02, 0x1B, 0x13, 0x96, 0x5A, + 0x2E, 0x03, 0xA2, 0x68, 0xB2, 0x29, 0xAC, 0x28, + 0xB8, 0xDC, 0xD5, 0x27, 0x55, 0xEC, 0x43, 0xDC, + 0xB7, 0x49, 0x1D, 0xE1, 0x30, 0x25, 0x81, 0xA6, + 0x90, 0x1F, 0x75, 0xBA, 0x19, 0x1E, 0xF7, 0xC5, + 0x77, 0x35, 0xEE, 0x68, 0x71, 0x22, 0xA0, 0xB4, + 0xCC, 0x99, 0x86, 0x1B, 0x1B, 0xC8, 0x27, 0xFC, + 0x6D, 0x8D, 0xE7, 0x8B, 0xC3, 0x40, 0x3D, 0xA8, + 0xCB, 0x9B, 0xC4, 0x12, 0x07, 0xDD, 0xA1, 0x92, + 0xE5, 0x80, 0x7A, 0xF4, 0xDB, 0x4C, 0xE6, 0xEE, + 0xF9, 0xD5, 0x1C, 0x20, 0x18, 0xD3, 0x8F, 0xDF, + 0x1C, 0xD3, 0x51, 0x4E, 0x0E, 0xED, 0x06, 0x61, + 0xF7, 0xBA, 0x81, 0x3A, 0x2F, 0xEA, 0xED, 0x70, + 0xA9, 0xD9, 0x54, 0x4D, 0xFC, 0x1D, 0x19, 0xEA, + 0xA6, 0x39, 0x8C, 0x6C, 0x78, 0xA8, 0x05, 0xEB, + 0xF2, 0xB5, 0xDE, 0x06, 0x9D, 0x8A, 0x78, 0x2A, + 0xF5, 0x50, 0xA4, 0xBD, 0x9B, 0xDA, 0xCA, 0x66, + 0xC0, 0x23, 0xAB, 0xE8, 0x95, 0x7E, 0xC9, 0xD2, + 0x6F, 0x09, 0xF2, 0x9A, 0x17, 0x89, 0xDA, 0x47, + 0x65, 0x8C, 0x20, 0xFA, 0x4E, 0x86, 0x18, 0xEB, + 0x7C, 0x08, 0xEC, 0x8A, 0x05, 0x54, 0x96, 0xD2, + 0x7A, 0x8A, 0x81, 0x58, 0x75, 0x8C, 0x7B, 0x02, + 0xEE, 0x1F, 0x51, 0x88, 0xD0, 0xD1, 0x90, 0x99, + 0x0C, 0xAE, 0x51, 0x2E, 0x54, 0x3E, 0xB1, 0x7D, + 0xBC, 0xE8, 0x54, 0x93, 0x6D, 0x10, 0x3C, 0xC6, + 0x71, 0xF6, 0xF5, 0x0B, 0x07, 0x0A, 0x6E, 0x59, + 0x20, 0x45, 0x21, 0x7D, 0x37, 0x64, 0x92, 0x09, + 0xA7, 0xE2, 0x34, 0x6F, 0xFC, 0xCC, 0x66, 0x0E, + 0x88, 0x1B, 0x19, 0x86, 0x11, 0xD7, 0x81, 0x25, + 0xF1, 0x8A, 0x03, 0xB7, 0x7A, 0xF0, 0x98, 0x4A, + 0x5C, 0xA1, 0x6D, 0x85, 0xA4, 0x8C, 0x4B, 0x65, + 0x9F, 0x72, 0x64, 0x14, 0xBA, 0x74, 0xEE, 0xA3, + 0x88, 0xFE, 0x1B, 0xCF, 0x11, 0x4F, 0xD1, 0xAC, + 0xFA, 0x14, 0xC3, 0xA7, 0xDD, 0x06, 0x85, 0x4E, + 0x64, 0x06, 0x92, 0x9C, 0xDF, 0x06, 0x09, 0xF1, + 0x4D, 0xE8, 0xF8, 0x2F, 0x69, 0xB6, 0x8A, 0xAF, + 0x25, 0x21, 0xB5, 0x48, 0x59, 0xF8, 0x9D, 0x60, + 0xAE, 0x42, 0x11, 0x7A, 0x68, 0x4D, 0x7E, 0x76, + 0xB0, 0xD2, 0xE3, 0xD9, 0x24, 0x16, 0x20, 0x0A, + 0xEB, 0xE0, 0x68, 0xCB, 0xBC, 0xAB, 0x67, 0xE4, + 0xF3, 0x25, 0x1F, 0xD3, 0x85, 0xA7, 0x1D, 0x7E, + 0x3C, 0x63, 0xCB, 0xC2, 0x50, 0x90, 0x0F, 0x4B, + 0x6E, 0x68, 0x06, 0x84, 0x65, 0xF7, 0xD0, 0xD4, + 0x12, 0xED, 0xFA, 0xC9, 0x40, 0xE2, 0xC0, 0xC9, + 0x46, 0x22, 0x47, 0x5E, 0x6D, 0xC1, 0x63, 0xDB, + 0x51, 0x98, 0xDA, 0x1A, 0xC4, 0xB9, 0xED, 0xE9, + 0x09, 0xB9, 0xCF, 0x91, 0x04, 0x1C, 0x63, 0xD8, + 0xC5, 0xA5, 0xAE, 0x53, 0x7B, 0xA1, 0x29, 0x83, + 0x37, 0xFB, 0xBF, 0x96, 0xBB, 0x24, 0x3D, 0x77, + 0x8C, 0x0F, 0xB3, 0x4B, 0x66, 0x9C, 0x54, 0xBB, + 0xF6, 0xDD, 0xD1, 0xB4, 0xD2, 0xF6, 0xAA, 0xED, + 0x18, 0x56, 0x63, 0x3E, 0x0B, 0xCA, 0xAB, 0x70, + 0xBB, 0x63, 0xEA, 0xB1, 0x00, 0x65, 0x90, 0x18, + 0xB8, 0x63, 0xA2, 0xF2, 0xB6, 0x1E, 0x61, 0x7B, + 0xD5, 0x01, 0xD9, 0x4D, 0xC9, 0x9D, 0x99, 0xC1, + 0x57, 0x9D, 0x6F, 0xAE, 0x64, 0xE4, 0x0C, 0x7E, + 0xFA, 0x15, 0x5E, 0xB6, 0x43, 0xB8, 0x8B, 0x89, + 0x87, 0xCD, 0x4F, 0xAD, 0x30, 0x1E, 0xA5, 0x03, + 0x7A, 0xC2, 0x10, 0x42, 0x14, 0x88, 0xD6, 0x7A, + 0x6D, 0x56, 0x52, 0x2E, 0x8D, 0x1B, 0x5D, 0x36, + 0x27, 0xA0, 0x21, 0x4B, 0x64, 0xF0, 0xC5, 0x41, + 0xAD, 0x05, 0x4A, 0x24, 0xE4, 0x70, 0x88, 0x63, + 0x12, 0xD0, 0xBC, 0x05, 0x38, 0xD9, 0x41, 0x68, + 0x9F, 0x16, 0x9A, 0x54, 0x09, 0x21, 0x64, 0x36, + 0x63, 0x97, 0x3A, 0xB5, 0xE0, 0x25, 0x43, 0x8A, + 0x6A, 0x59, 0x97, 0xC1, 0x31, 0xA5, 0x66, 0xD2, + 0xF0, 0x1C, 0xDF, 0x97, 0x51, 0xD0, 0x61, 0xBA, + 0x55, 0x5F, 0xD7, 0x0D, 0xD4, 0x75, 0x8E, 0x79, + 0x04, 0x75, 0x00, 0xB9, 0xC0, 0x7A, 0x66, 0x05, + 0x9F, 0x2B, 0x44, 0x42, 0x75, 0x0F, 0xD5, 0x15, + 0xD6, 0x16, 0x8F, 0x6C, 0x6E, 0xD4, 0x37, 0xCF, + 0xB4, 0xDA, 0x93, 0x00, 0x11, 0xFB, 0xBE, 0xEE, + 0x3B, 0x6D, 0x1D, 0xBA, 0x33, 0xD1, 0x52, 0x8B, + 0x16, 0x39, 0x42, 0x27, 0xE6, 0x56, 0x4C, 0x41, + 0x91, 0xB0, 0x98, 0xAE, 0x9B, 0x2D, 0x9B, 0x23, + 0x80, 0x4C, 0xEA, 0x98, 0x57, 0x95, 0x28, 0x94, + 0x43, 0xD3, 0x88, 0x12, 0xDF, 0x89, 0x5A, 0x7B, + 0xC5, 0xCB, 0x36, 0x54, 0x65, 0x74, 0xB8, 0x4E, + 0xE2, 0x4D, 0x01, 0xD5, 0x9C, 0x82, 0xB9, 0x1A, + 0x09, 0xD2, 0xCE, 0x04, 0x36, 0xD8, 0x41, 0xAC, + 0x4C, 0xAD, 0xC6, 0x52, 0x91, 0x1A, 0x06, 0x6D, + 0xFC, 0xAB, 0x29, 0x93, 0x87, 0x88, 0xB9, 0x8C, + 0xFA, 0x57, 0x2B, 0x05, 0x03, 0xD0, 0x18, 0xED, + 0x7A, 0x7B, 0x81, 0x6A, 0x97, 0x65, 0x5B, 0x90, + 0xDE, 0xA9, 0xFC, 0x8F, 0xFC, 0xBB, 0x98, 0xD8, + 0xFA, 0x32, 0x3F, 0x3F, 0x7F, 0x74, 0x65, 0x38, + 0xC4, 0x28, 0xEC, 0x27, 0x1F, 0x28, 0x01, 0xB1, + 0xAF, 0x2B, 0x8A, 0x05, 0x38, 0x7B, 0x77, 0xC9, + 0x61, 0x77, 0x34, 0x2C, 0x22, 0xE5, 0xEB, 0xDC, + 0x9D, 0x18, 0x6E, 0x23, 0x25, 0x52, 0x69, 0xB7, + 0x05, 0xDB, 0x66, 0x5D, 0xEA, 0x76, 0x83, 0x82, + 0x97, 0x39, 0xAF, 0xC0, 0x50, 0x81, 0x18, 0x0D, + 0x22, 0xFA, 0xB7, 0x44, 0x5C, 0x3F, 0x69, 0xF3, + 0xAC, 0xC5, 0x63, 0x9F, 0xD8, 0x72, 0x7E, 0x9A, + 0xC2, 0xEB, 0x79, 0xD0, 0x74, 0x65, 0xE8, 0xCA, + 0xFD, 0xA8, 0x7D, 0x23, 0x07, 0x99, 0x3E, 0xAF, + 0xDB, 0x67, 0x10, 0xC0, 0xE5, 0x61, 0x77, 0xC6, + 0x8D, 0xC4, 0x0E, 0xAA, 0x55, 0xE3, 0xC0, 0xC7, + 0xA5, 0x36, 0x28, 0x61, 0xDB, 0x16, 0x96, 0x5E, + 0x01, 0x47, 0x82, 0xE3, 0xEB, 0x20, 0x3F, 0x10, + 0xFA, 0x5A, 0xBC, 0xD3, 0xF9, 0xCE, 0x04, 0x87, + 0x51, 0x07, 0xF9, 0xD0, 0xE7, 0x6D, 0xCB, 0xCC, + 0xC4, 0x15, 0x00, 0xE2, 0xDC, 0x8E, 0x7B, 0x5C, + 0x9A, 0xF2, 0x78, 0x70, 0x4D, 0xA1, 0xAA, 0xB5, + 0x13, 0xCC, 0x71, 0x66, 0x5A, 0x79, 0x13, 0x3B, + 0x12, 0xCD, 0x40, 0x30, 0x5A, 0x49, 0xD4, 0x20, + 0xED, 0xCF, 0x4A, 0x75, 0xE6, 0xD5, 0xDD, 0x0F, + 0xD4, 0xBE, 0x98, 0x9F, 0xD7, 0x1F, 0xC0, 0x02, + 0x31, 0xFA, 0x67, 0x37, 0x25, 0x86, 0x56, 0x85, + 0x2B, 0xA2, 0x57, 0xCD, 0x8E, 0x74, 0xE7, 0x69, + 0xEE, 0x33, 0x5A, 0x3F, 0xCD, 0x1E, 0xE3, 0xB9, + 0xAA, 0x52, 0xF5, 0x22, 0x4E, 0xE3, 0xFF, 0xC8, + 0xE3, 0x13, 0xA3, 0x9A, 0x63, 0x23, 0xC3, 0xD7, + 0xE5, 0x88, 0x3E, 0x0A, 0x4B, 0xA5, 0x01, 0xE6, + 0x13, 0xCF, 0xED, 0xEE, 0x2A, 0x58, 0x09, 0x3F, + 0x2F, 0x28, 0xE7, 0xC4, 0x6B, 0xEC, 0x49, 0x51, + 0x79, 0x8F, 0xD5, 0x19, 0x5D, 0xA5, 0x10, 0xCE, + 0x8E, 0xF6, 0x26, 0x78, 0x7A, 0xA8, 0x11, 0x52, + 0x5F, 0x97, 0x14, 0xC9, 0x29, 0x87, 0xB8, 0xA0, + 0x2D, 0xE6, 0xA7, 0x2A, 0xD4, 0xFF, 0xEB, 0xBA, + 0xFD, 0x58, 0x39, 0x33, 0xB1, 0xCE, 0x0E, 0x78, + 0x67, 0x1E, 0xA1, 0x92, 0x77, 0x63, 0xF8, 0xC0, + 0x02, 0x49, 0x73, 0xC0, 0xA1, 0x26, 0x83, 0x04, + 0x9A, 0x5D, 0x85, 0x68, 0x2A, 0x2F, 0xCB, 0x88, + 0x8D, 0x14, 0xB1, 0x33, 0xFA, 0xFB, 0xE9, 0x05, + 0xBE, 0x24, 0x1A, 0x6B, 0x29, 0x2B, 0x3F, 0x52, + 0x8F, 0xFB, 0xE6, 0x02, 0x77, 0x50, 0x71, 0xDB, + 0xE9, 0x92, 0x3F, 0xE1, 0x20, 0x62, 0x80, 0xAE, + 0xA4, 0x98, 0xC6, 0xCD, 0xE0, 0xB1, 0xC3, 0x33, + 0xB1, 0xC5, 0x91, 0x3C, 0x19, 0x34, 0xA8, 0xD9, + 0xB3, 0x25, 0x69, 0xE3, 0x9C, 0x5F, 0x78, 0xD0, + 0x83, 0x1F, 0xAB, 0x85, 0x13, 0x56, 0x69, 0xB5, + 0x06, 0x47, 0x62, 0x37, 0x27, 0x15, 0x14, 0x05, + 0x4A, 0xF4, 0x6A, 0x68, 0x2A, 0x6A, 0xC3, 0x5A, + 0xDF, 0xB5, 0xAE, 0x2F, 0x8D, 0x8F, 0x21, 0xDB, + 0x33, 0x00, 0x9B, 0xD4, 0xC4, 0x08, 0x3B, 0x81, + 0x63, 0x4C, 0xB0, 0x39, 0x4C, 0x0A, 0xD5, 0x71, + 0x3E, 0x5A, 0x50, 0x58, 0x9C, 0x07, 0x89, 0x79, + 0x79, 0x2F, 0x0B, 0xD9, 0x50, 0xBC, 0xCF, 0x46, + 0x7A, 0x68, 0x5C, 0xBF, 0x1E, 0x49, 0x77, 0x92, + 0x85, 0x11, 0x39, 0xA6, 0x2F, 0xDA, 0x7B, 0xFA, + 0x72, 0x87, 0x06, 0xCD, 0x84, 0x41, 0x20, 0x1B, + 0x66, 0x3F, 0x42, 0x0C, 0x9E, 0x19, 0xD3, 0x18, + 0x57, 0xA0, 0xEE, 0x16, 0x3A, 0xC7, 0xF9, 0xD3, + 0x8B, 0xC9, 0x24, 0x70, 0x70, 0x51, 0x7C, 0x06, + 0x68, 0xD3, 0x29, 0xC9, 0x85, 0x9A, 0x1C, 0xE6, + 0x8C, 0x17, 0xF4, 0x88, 0xDF, 0xEA, 0xFF, 0x44, + 0x8D, 0x54, 0xBE, 0x22, 0x07, 0xA5, 0x7C, 0x0C, + 0xF4, 0x8D, 0xB1, 0x0C, 0x07, 0xED, 0xBD, 0x28, + 0x19, 0xDA, 0x07, 0x71, 0xA8, 0xA1, 0xE0, 0xDD, + 0xEE, 0x08, 0x18, 0xA5, 0xBD, 0xDD, 0x32, 0x0B, + 0x70, 0x1C, 0xD9, 0xEE, 0x19, 0xC2, 0xAE, 0x5C, + 0xE3, 0x02, 0x74, 0x70, 0x96, 0x61, 0xB1, 0x73, + 0x3B, 0xD6, 0x74, 0xC0, 0x82, 0xA9, 0x1F, 0xE0, + 0xF1, 0x22, 0x50, 0xF3, 0x9F, 0xE5, 0x13, 0x92, + 0xFC, 0x0A, 0x1A, 0x3C, 0xB4, 0x46, 0xFB, 0x81, + 0x00, 0x84, 0xA4, 0x5E, 0x6B, 0x8C, 0x25, 0x6E, + 0xD7, 0xB7, 0x3B, 0x01, 0x65, 0xFB, 0x0B, 0x46, + 0x67, 0x27, 0x2D, 0x51, 0xAD, 0xB5, 0xE0, 0x85, + 0xC2, 0x95, 0xA3, 0xE3, 0x68, 0x4D, 0x9E, 0x8C, + 0x11, 0x53, 0xF0, 0xB2, 0x85, 0xFA, 0x52, 0x4E, + 0xEC, 0xF9, 0xB7, 0x3C, 0x89, 0x2C, 0x4D, 0x32, + 0x9A, 0xCB, 0x17, 0xF3, 0x16, 0xBF, 0x44, 0x40, + 0xE9, 0x5E, 0x51, 0x8C, 0x1E, 0x52, 0x0A, 0xC2, + 0xCD, 0xA5, 0xAA, 0x03, 0x27, 0xB0, 0x8F, 0x64, + 0xDB, 0xD7, 0x03, 0x01, 0x8A, 0x24, 0x28, 0x7E, + 0x53, 0x6F, 0x24, 0xFD, 0xAA, 0xE3, 0x78, 0xB6, + 0xA5, 0x5D, 0x5A, 0x67, 0x20, 0xE2, 0xBE, 0x3A, + 0x2B, 0xE7, 0x86, 0x11, 0xDD, 0x96, 0xCB, 0x09, + 0x65, 0xA0, 0x36, 0xF9, 0xB0, 0x20, 0x21, 0x8E, + 0xDB, 0xC0, 0x73, 0xC7, 0x79, 0xD8, 0xDA, 0xC2, + 0x66, 0x13, 0x64, 0x34, 0x0C, 0xE1, 0x22, 0x24, + 0x61, 0x67, 0x08, 0x39, 0x97, 0x3F, 0x33, 0x96, + 0xF2, 0x44, 0x18, 0x75, 0xBB, 0xF5, 0x6A, 0x5C, + 0x2C, 0xAE, 0x2A, 0x79, 0x3D, 0x47, 0x19, 0x53, + 0x50, 0x6C, 0x9F, 0xB3, 0x82, 0x55, 0x09, 0x78, + 0x7B, 0xAD, 0xBC, 0x05, 0x6F, 0xC8, 0x3D, 0xB6, + 0x7B, 0x30, 0xE6, 0xBB, 0x8B, 0xD0, 0x2F, 0xA6, + 0x15, 0xCC, 0x77, 0x8C, 0x21, 0xBA, 0x03, 0xED, + 0x56, 0x85, 0x82, 0x4F, 0x97, 0x8C, 0x59, 0x4F, + 0x53, 0x5A, 0xD2, 0x70, 0xD9, 0x07, 0xB3, 0xBD, + 0x1D, 0x3E, 0x97, 0xD4, 0x7D, 0x93, 0x35, 0xA4, + 0x82, 0x6E, 0xEA, 0x4B, 0xC8, 0x6C, 0xF5, 0xE6, + 0xEB, 0xAF, 0x11, 0xB0, 0xB4, 0x71, 0x8F, 0x7B, + 0xC4, 0x8C, 0xE2, 0x66, 0x51, 0x31, 0x99, 0x01, + 0x5B, 0xE7, 0x48, 0xF8, 0x4C, 0xE3, 0x9A, 0x77, + 0xF1, 0xC6, 0x09, 0xDE, 0x76, 0xD4, 0xE3, 0x5C, + 0xDF, 0xA3, 0xEC, 0x3C, 0x86, 0x7C, 0xA5, 0x3F, + 0x8D, 0x2A, 0xF3, 0x0B, 0x54, 0xB7, 0x54, 0xA2, + 0xC1, 0x69, 0xC0, 0x6F, 0x1C, 0x1C, 0x76, 0xD8, + 0x9F, 0x7A, 0x32, 0xB0, 0xA1, 0xA6, 0x9B, 0xB7, + 0x21, 0x56, 0x28, 0x2D, 0xB6, 0x97, 0x03, 0x5E, + 0x65, 0xE3, 0x74, 0x9A, 0x96, 0x7A, 0xF9, 0xF5, + 0xDD, 0x85, 0xCA, 0x4C, 0xB4, 0x03, 0x6A, 0xCD, + 0xB6, 0x01, 0xDC, 0x8B, 0xD8, 0x73, 0x8F, 0x4D, + 0x7F, 0xD6, 0x71, 0xEC, 0xD7, 0xC6, 0x0B, 0x5F, + 0x09, 0x21, 0xB2, 0x78, 0xA8, 0xAF, 0xAD, 0x2C, + 0xD4, 0x93, 0x9F, 0x71, 0xF7, 0x05, 0x89, 0x42, + 0xC9, 0x15, 0x6F, 0x2D, 0xE0, 0xBA, 0xC3, 0xD6, + 0xBF, 0xAC, 0xF8, 0x24, 0x58, 0x79, 0xA9, 0xC4, + 0xB4, 0x49, 0x3E, 0x0B, 0x9E, 0x5E, 0xE4, 0xA6, + 0x8B, 0xE8, 0xDE, 0xFB, 0x4A, 0xF1, 0x69, 0x9D, + 0x4F, 0x77, 0x83, 0x78, 0x55, 0x19, 0x42, 0x45, + 0xBF, 0xBD, 0xBD, 0x12, 0x0F, 0xEF, 0x8D, 0x04, + 0xD8, 0x5C, 0xF2, 0xC9, 0xF1, 0xA6, 0xE0, 0x3E, + 0x22, 0xA8, 0xA2, 0x5E, 0x66, 0xE9, 0xAB, 0xB4, + 0x71, 0xBE, 0x4B, 0x3F, 0xBE, 0xC4, 0xBA, 0x4A + }, + .len = 2048 + }, + .ciphertext = { + .data = { + 0x5E, 0x86, 0x02, 0x64, 0x32, 0xBF, 0x70, 0xC2, + 0x19, 0x99, 0x7F, 0x47, 0x0D, 0xA4, 0x91, 0xA8, + 0x7A, 0xC0, 0xA5, 0x7E, 0xA8, 0x6C, 0x88, 0x00, + 0xEA, 0xB5, 0x96, 0x6B, 0x25, 0xBD, 0xE7, 0x42, + 0xDB, 0x35, 0xE7, 0x92, 0x2B, 0x00, 0x82, 0x35, + 0xD4, 0x2C, 0xCF, 0x47, 0xC8, 0xB2, 0xB3, 0x57, + 0xF7, 0x24, 0x83, 0x7F, 0xC5, 0x2E, 0xF1, 0xC9, + 0x57, 0x1A, 0xEF, 0xC2, 0x3A, 0x8C, 0x1E, 0x92, + 0x88, 0x05, 0xAF, 0x55, 0xE6, 0x0C, 0xA7, 0x6B, + 0x59, 0x62, 0x32, 0x21, 0xF1, 0xFF, 0xB5, 0x5B, + 0x22, 0x26, 0x6F, 0x0A, 0x36, 0xDC, 0x0D, 0x16, + 0x3B, 0x4E, 0x7C, 0xA3, 0x75, 0x30, 0x3F, 0xB0, + 0x99, 0x38, 0x42, 0x8E, 0x89, 0xA3, 0x7C, 0x99, + 0x2F, 0x0A, 0xA1, 0xC7, 0xFD, 0x2D, 0x21, 0x8F, + 0xBD, 0xD4, 0x11, 0xEA, 0x55, 0xF5, 0x6A, 0x50, + 0x90, 0x3B, 0x60, 0x57, 0xE1, 0x86, 0x1E, 0x50, + 0x28, 0x67, 0x3F, 0xD2, 0xF3, 0xBD, 0xFA, 0xEE, + 0xD6, 0x5A, 0x38, 0x30, 0xA3, 0xDD, 0x78, 0xC4, + 0x37, 0x59, 0x52, 0xC0, 0x92, 0x54, 0xC7, 0x53, + 0xF0, 0xE6, 0xA9, 0x63, 0x1F, 0x9B, 0x97, 0xFB, + 0x40, 0x23, 0xFE, 0x52, 0x6A, 0xF0, 0x3A, 0x94, + 0xEB, 0x6A, 0x9E, 0x8F, 0xC5, 0x05, 0x9C, 0x04, + 0x1B, 0x00, 0x34, 0x96, 0x12, 0xDA, 0x60, 0xC6, + 0xAA, 0x1A, 0x3E, 0xEB, 0x70, 0x17, 0x10, 0xBC, + 0xF5, 0xC2, 0xE2, 0x71, 0xF3, 0xB8, 0x1D, 0xCE, + 0x47, 0x94, 0x21, 0x71, 0x34, 0x8C, 0xCC, 0xDD, + 0x27, 0xCE, 0x6F, 0x68, 0xFF, 0x91, 0x4E, 0xC4, + 0xA0, 0xCA, 0xB0, 0x4F, 0x17, 0x53, 0x73, 0x92, + 0x6C, 0xA8, 0x16, 0x06, 0xE3, 0xD9, 0x92, 0x99, + 0xBE, 0xB0, 0x7D, 0x56, 0xF2, 0x72, 0x30, 0xDA, + 0xC4, 0x4E, 0xF4, 0xA6, 0x8F, 0xD2, 0xC7, 0x8A, + 0xA2, 0xFC, 0xF5, 0x63, 0x17, 0x48, 0x56, 0x4D, + 0xBE, 0x94, 0xFE, 0xF5, 0xB1, 0xA9, 0x96, 0xAB, + 0x3F, 0x2D, 0xD4, 0x15, 0xEE, 0x4F, 0xFA, 0x2C, + 0xBE, 0x91, 0xB7, 0xBC, 0x18, 0xC8, 0xDB, 0x02, + 0x20, 0x29, 0xF1, 0xC1, 0x88, 0x8C, 0x8D, 0xD1, + 0xB3, 0x4E, 0x93, 0x96, 0xDD, 0x22, 0xAB, 0x55, + 0xB5, 0x9F, 0x8B, 0x20, 0xAE, 0xC6, 0x0E, 0x26, + 0xC6, 0xFE, 0x2D, 0x5F, 0x95, 0x89, 0x06, 0x15, + 0x3D, 0x88, 0x16, 0xEC, 0x9B, 0x4A, 0x1B, 0x5D, + 0x2E, 0xB2, 0x13, 0x56, 0x9F, 0x33, 0xB3, 0x45, + 0xBF, 0x5F, 0x25, 0x7E, 0x75, 0x22, 0xD2, 0xE6, + 0x9F, 0xAC, 0x2D, 0xFD, 0x99, 0xC2, 0x9B, 0xFC, + 0xD7, 0x7A, 0x9B, 0x05, 0x30, 0x0F, 0xB7, 0x4A, + 0xFE, 0x24, 0xDD, 0x39, 0x9B, 0xBB, 0x2F, 0xDD, + 0xF9, 0xFB, 0xCA, 0x6C, 0x87, 0xBA, 0x73, 0xD4, + 0x85, 0x7B, 0xB2, 0x6F, 0x5C, 0xD8, 0xFB, 0xE9, + 0x41, 0x24, 0x3A, 0x3B, 0x4F, 0x91, 0x77, 0xA2, + 0x35, 0x78, 0xE5, 0x4C, 0xFE, 0x8B, 0x04, 0x03, + 0xD3, 0x84, 0xA9, 0x1C, 0xA7, 0x7C, 0x45, 0x13, + 0x7D, 0xC5, 0x0A, 0x2F, 0x02, 0xF8, 0x56, 0xD5, + 0x5F, 0x35, 0xED, 0x06, 0xBF, 0x67, 0xBA, 0x51, + 0x02, 0x95, 0x36, 0xF2, 0x9A, 0xBA, 0x9D, 0xF6, + 0xD6, 0x77, 0x50, 0xC9, 0xFC, 0x1E, 0x32, 0xB5, + 0x2F, 0xEA, 0x3C, 0x76, 0xB4, 0xE1, 0xCC, 0x42, + 0xEB, 0x71, 0x79, 0xD3, 0x7D, 0xB7, 0xC0, 0x88, + 0x25, 0x81, 0xE8, 0xC0, 0xB8, 0x38, 0x7E, 0x7B, + 0xFD, 0x18, 0xAB, 0x08, 0xB2, 0x71, 0xA5, 0xAD, + 0xA7, 0xBE, 0x48, 0x5F, 0x86, 0xE2, 0x41, 0x3D, + 0x7C, 0x37, 0x7A, 0xAB, 0xDB, 0xE0, 0x3B, 0x3D, + 0xB6, 0xE8, 0x23, 0x7C, 0xF1, 0x8F, 0xBA, 0xB7, + 0xE9, 0x78, 0x0B, 0xCA, 0x67, 0xA8, 0x10, 0x36, + 0xEB, 0x72, 0xED, 0xDD, 0xF0, 0x5C, 0x74, 0x8E, + 0xE5, 0x2A, 0xAE, 0x6E, 0xC4, 0xF1, 0xFC, 0xD8, + 0xEE, 0x56, 0x07, 0x88, 0x02, 0xDC, 0x9D, 0xB7, + 0xF9, 0x13, 0xE1, 0xE1, 0x9D, 0x89, 0x26, 0x0B, + 0x23, 0x74, 0x4A, 0x43, 0xAA, 0xA0, 0xA8, 0x97, + 0x85, 0x15, 0x58, 0xAB, 0x2B, 0xB5, 0xDA, 0x1A, + 0xBA, 0x29, 0x62, 0xCF, 0xDD, 0xA3, 0xBA, 0x9D, + 0x7D, 0x83, 0xA5, 0x18, 0xD4, 0x03, 0x0F, 0x61, + 0x9F, 0xB1, 0x7E, 0xEC, 0xD2, 0x6E, 0xAF, 0xCF, + 0x1E, 0xC1, 0x88, 0x97, 0x99, 0xD6, 0xBF, 0x47, + 0xB9, 0x0A, 0x69, 0x11, 0x3A, 0x55, 0x8B, 0x1D, + 0x2D, 0xFF, 0x78, 0xC8, 0xDE, 0x82, 0x29, 0xD6, + 0x08, 0x3C, 0xC4, 0xCB, 0x2F, 0x01, 0xD0, 0xE8, + 0xB1, 0x75, 0x5E, 0x23, 0xE0, 0x37, 0x7C, 0x1C, + 0xB6, 0xD9, 0x47, 0xDE, 0x23, 0x87, 0xD3, 0x68, + 0x47, 0x46, 0x78, 0xF3, 0xBF, 0x54, 0xA3, 0xB9, + 0x54, 0xD5, 0xC5, 0x0A, 0x7C, 0x92, 0x2A, 0xC2, + 0x14, 0x76, 0xA6, 0x5C, 0x6D, 0x0B, 0x94, 0x56, + 0x00, 0x6B, 0x5C, 0x27, 0xDE, 0x77, 0x9B, 0xF1, + 0xB1, 0x8C, 0xA7, 0x49, 0x77, 0xFC, 0x4E, 0x29, + 0x23, 0x8F, 0x2F, 0xF7, 0x83, 0x8D, 0x36, 0xD9, + 0xAB, 0x0E, 0x78, 0xF5, 0x90, 0x05, 0xB9, 0x79, + 0x70, 0x88, 0x59, 0x6F, 0xE2, 0xC5, 0xD7, 0x80, + 0x95, 0x04, 0x29, 0xE0, 0xFA, 0x37, 0xE8, 0x8B, + 0xC5, 0x21, 0x51, 0x1A, 0x62, 0xCE, 0x93, 0xAF, + 0x1A, 0xFE, 0xC3, 0x6F, 0x86, 0x94, 0x5E, 0x13, + 0xA6, 0x9A, 0x26, 0xF0, 0xB5, 0x7C, 0x41, 0x9A, + 0x80, 0xB8, 0x84, 0x5A, 0x55, 0xA9, 0xB0, 0x6A, + 0xFA, 0xEB, 0x46, 0x32, 0x0B, 0xE2, 0x9C, 0x65, + 0x86, 0x11, 0x39, 0x7E, 0xAF, 0x93, 0x19, 0x09, + 0x70, 0x40, 0x80, 0x14, 0xBA, 0x1D, 0xB3, 0x62, + 0x5B, 0xF3, 0x9A, 0x21, 0x98, 0x7E, 0x63, 0xB6, + 0x1A, 0xBD, 0x65, 0x98, 0x35, 0x2A, 0xA9, 0x76, + 0x29, 0x59, 0x84, 0x25, 0x81, 0xB8, 0xDE, 0x25, + 0x32, 0x10, 0x50, 0xB7, 0xD3, 0xB3, 0x69, 0xC8, + 0xE1, 0x33, 0xCB, 0x9E, 0x9C, 0x7A, 0x7C, 0xD2, + 0x6C, 0x92, 0x97, 0xA9, 0xFA, 0xAF, 0x30, 0xBA, + 0x9A, 0xB3, 0x3D, 0x9A, 0xE5, 0x0A, 0x9B, 0x8D, + 0x89, 0xE2, 0x2B, 0xB8, 0xBC, 0xF0, 0x23, 0xFF, + 0x7B, 0x0D, 0x00, 0x36, 0xEE, 0x79, 0xCB, 0xA5, + 0x70, 0x4C, 0x66, 0x02, 0x79, 0x2E, 0x5B, 0x83, + 0xCE, 0x55, 0x8B, 0x89, 0xD6, 0xE3, 0x71, 0x63, + 0xBC, 0xB1, 0x5F, 0x67, 0xB4, 0x7E, 0x05, 0x0D, + 0xAC, 0x6D, 0x4E, 0x2C, 0xA5, 0xF4, 0x47, 0x89, + 0xAC, 0x5E, 0xBE, 0x2F, 0xFC, 0x9B, 0x2F, 0x0B, + 0xBE, 0x63, 0x54, 0x97, 0xBB, 0x23, 0x27, 0xCD, + 0xB9, 0xB2, 0x28, 0x0D, 0xA4, 0x78, 0x2C, 0xAB, + 0xD1, 0xC9, 0x94, 0x40, 0x54, 0xF2, 0x35, 0x61, + 0x49, 0x01, 0x87, 0x55, 0xA5, 0xB5, 0x1E, 0x84, + 0x92, 0x9E, 0xC1, 0xA4, 0x0B, 0x66, 0x2B, 0xF8, + 0xAF, 0xC3, 0x1E, 0xAF, 0x66, 0x3F, 0x6F, 0x5F, + 0x70, 0xEC, 0x25, 0x29, 0xE4, 0x65, 0xB2, 0x04, + 0x47, 0xF6, 0x3C, 0xB5, 0x5F, 0x66, 0x9F, 0xA4, + 0x1B, 0xFC, 0xA2, 0xD5, 0x3E, 0x84, 0xBA, 0x88, + 0x0D, 0xF1, 0x6A, 0xF2, 0xF6, 0x1D, 0xF1, 0xA3, + 0x45, 0xB2, 0x51, 0xD8, 0xA2, 0x8F, 0x55, 0xA6, + 0x89, 0xC4, 0x15, 0xD5, 0x73, 0xA8, 0xB1, 0x31, + 0x66, 0x9E, 0xC1, 0x43, 0xE1, 0x5D, 0x4E, 0x04, + 0x84, 0x8F, 0xF2, 0xBC, 0xE1, 0x4E, 0x4D, 0x60, + 0x81, 0xCA, 0x53, 0x34, 0x95, 0x17, 0x3B, 0xAE, + 0x8F, 0x95, 0xA7, 0xC6, 0x47, 0xC6, 0xAC, 0x32, + 0x12, 0x39, 0xCA, 0xEF, 0xE0, 0x07, 0xBF, 0x17, + 0x4F, 0xDC, 0x1B, 0x4E, 0x3C, 0x84, 0xF1, 0x9F, + 0x43, 0x70, 0x19, 0xE6, 0xF3, 0x8B, 0x8B, 0x5D, + 0xDB, 0xD2, 0x9D, 0xD4, 0xB2, 0x30, 0x45, 0x55, + 0xA2, 0x67, 0xA2, 0x76, 0x4A, 0x74, 0xAD, 0x88, + 0x71, 0xE6, 0x3E, 0x13, 0x06, 0x30, 0x17, 0xE1, + 0xEF, 0xAC, 0x71, 0xFB, 0x43, 0xCD, 0xF6, 0xFA, + 0x0E, 0x4C, 0x4E, 0x16, 0xF6, 0x6A, 0x09, 0x86, + 0x6B, 0xEA, 0x47, 0x6C, 0x70, 0xE7, 0xAD, 0xA2, + 0xE0, 0xFD, 0x7F, 0xF0, 0x5C, 0x21, 0x53, 0x0F, + 0x28, 0xA1, 0x43, 0xE1, 0x06, 0xCA, 0x0B, 0x31, + 0x88, 0x22, 0xA6, 0xE6, 0x34, 0x5B, 0xE6, 0xCF, + 0x25, 0x81, 0x63, 0xFF, 0x78, 0x66, 0x85, 0x19, + 0xE2, 0x0A, 0x7E, 0x81, 0x8A, 0x17, 0x1A, 0x18, + 0x8A, 0x5F, 0x5D, 0x9E, 0x82, 0x13, 0x10, 0xB9, + 0xD3, 0xE6, 0x93, 0x1C, 0xE4, 0x2C, 0xCB, 0x49, + 0x1E, 0xB6, 0x36, 0x13, 0xBF, 0x28, 0xEE, 0xCC, + 0x49, 0xF5, 0x79, 0xFC, 0x20, 0x65, 0xBD, 0xE8, + 0xF0, 0x1B, 0x4E, 0xC0, 0x0D, 0x3E, 0x89, 0x91, + 0xCC, 0x64, 0x10, 0xC0, 0x2A, 0x2B, 0xA3, 0xFA, + 0x60, 0x3D, 0xC3, 0x52, 0x2F, 0x93, 0xDE, 0xB7, + 0x6E, 0x8A, 0xDF, 0x6C, 0x08, 0xCC, 0x8B, 0x3B, + 0xC8, 0x50, 0xEF, 0x58, 0x64, 0x9A, 0x3D, 0x16, + 0x70, 0x94, 0x11, 0xD8, 0x94, 0x2B, 0x70, 0x91, + 0x10, 0x70, 0x88, 0xF0, 0x40, 0x75, 0x9A, 0x2B, + 0x39, 0xA1, 0x27, 0x3F, 0x2E, 0x91, 0xEA, 0xA1, + 0xCC, 0x12, 0xC1, 0x7F, 0x73, 0x8C, 0x5C, 0x6B, + 0xFC, 0xC5, 0x6A, 0x1C, 0x05, 0xF1, 0x3D, 0x30, + 0x82, 0x4A, 0x65, 0x35, 0xCE, 0x80, 0x10, 0xBB, + 0x41, 0x94, 0xFB, 0x84, 0x80, 0x7B, 0x91, 0xC4, + 0x4D, 0xA3, 0x5F, 0xB9, 0xFB, 0xF9, 0xC9, 0x1D, + 0x4F, 0x99, 0x1C, 0x1F, 0x47, 0x44, 0x89, 0x0E, + 0xED, 0x6D, 0xB5, 0x85, 0x41, 0x94, 0xEF, 0xF9, + 0x2E, 0xA0, 0xC8, 0xCA, 0xFB, 0x44, 0x02, 0xC6, + 0xBF, 0x96, 0x87, 0x80, 0x1D, 0xEF, 0x2A, 0x81, + 0xAB, 0xB2, 0x56, 0xDF, 0x54, 0x8B, 0xAB, 0xAF, + 0xFE, 0x18, 0x8C, 0xAA, 0xD4, 0x00, 0x17, 0xBE, + 0xCF, 0x06, 0xE5, 0xA6, 0xBF, 0x5A, 0x52, 0x3B, + 0x4E, 0xF5, 0x65, 0x60, 0x95, 0xDE, 0x8A, 0x25, + 0x88, 0xA5, 0x24, 0x96, 0x29, 0x13, 0x0D, 0x19, + 0x45, 0x95, 0x91, 0x08, 0xD2, 0x9C, 0x4C, 0x34, + 0x42, 0xF0, 0xA5, 0x72, 0xEB, 0xFB, 0x5E, 0xAA, + 0x68, 0x80, 0x82, 0xAC, 0x34, 0xAD, 0x89, 0xF6, + 0xAF, 0x54, 0x82, 0xCF, 0x98, 0x8C, 0x75, 0x63, + 0x8D, 0xBD, 0x1C, 0x2A, 0xD7, 0x00, 0xA7, 0x8E, + 0xB9, 0x33, 0xB6, 0x3B, 0x95, 0x9A, 0x59, 0x1D, + 0x3F, 0x23, 0x6B, 0x18, 0xF8, 0x4F, 0x1A, 0x8D, + 0xC0, 0x26, 0x9F, 0x87, 0x61, 0xB6, 0xC6, 0x60, + 0x38, 0x22, 0x73, 0x1C, 0x99, 0x23, 0xEF, 0xD9, + 0xFD, 0xCB, 0x54, 0x74, 0xBB, 0x77, 0x14, 0xA3, + 0xA9, 0xE6, 0x7C, 0x7E, 0x03, 0x3A, 0x13, 0x6E, + 0x1D, 0x6F, 0x64, 0xB3, 0xFA, 0xFB, 0x52, 0xDE, + 0xDF, 0x08, 0xFB, 0x6F, 0xC5, 0xFA, 0x51, 0x6A, + 0x69, 0x29, 0x9B, 0x96, 0xE8, 0x16, 0xC8, 0xD1, + 0xE4, 0x19, 0xBD, 0x14, 0x74, 0x27, 0xE7, 0x10, + 0xF0, 0xC3, 0xE2, 0xA7, 0x60, 0x48, 0xBF, 0xDD, + 0xC4, 0x0D, 0xD0, 0xF2, 0xEF, 0xA6, 0xC9, 0xA2, + 0x73, 0xD1, 0xCF, 0x41, 0xE1, 0x3B, 0xE5, 0x49, + 0x91, 0x5D, 0x09, 0xFD, 0x1D, 0x95, 0x29, 0xDB, + 0x52, 0x48, 0xEB, 0xF5, 0x1D, 0xF8, 0x06, 0x67, + 0x75, 0xF2, 0x57, 0xA4, 0x20, 0x60, 0xEA, 0xB0, + 0x85, 0x93, 0x7C, 0xDD, 0x52, 0x01, 0xD4, 0x57, + 0xA8, 0x31, 0x2D, 0xF9, 0x0A, 0xD2, 0x2A, 0xD1, + 0x34, 0x18, 0x35, 0x16, 0xB6, 0x8B, 0x0F, 0x0B, + 0xCF, 0x50, 0x80, 0xFE, 0x76, 0xCC, 0x4F, 0x30, + 0x98, 0x19, 0x16, 0x3D, 0x01, 0xEA, 0x8D, 0x8A, + 0x3D, 0xDC, 0xFB, 0x1F, 0x77, 0x8D, 0x72, 0x76, + 0x02, 0x3C, 0x5D, 0xEE, 0x55, 0x13, 0x5B, 0x6E, + 0x5A, 0x2D, 0xD5, 0x77, 0xD7, 0x01, 0x84, 0x7D, + 0x21, 0x8C, 0xDD, 0x94, 0x7D, 0x31, 0x3D, 0xF0, + 0xE7, 0x28, 0xF5, 0x72, 0x36, 0x60, 0xE0, 0x59, + 0x5F, 0xFE, 0x38, 0xF8, 0x2F, 0xDB, 0x9E, 0x55, + 0x5A, 0xD6, 0xBA, 0x6C, 0x87, 0xF3, 0xC0, 0x76, + 0x5F, 0xA3, 0x0A, 0xC3, 0xA3, 0x8D, 0x0E, 0x52, + 0xA8, 0xDA, 0x26, 0x3A, 0xF9, 0x3E, 0x36, 0xB1, + 0x06, 0xF8, 0x20, 0x2D, 0x1C, 0x0B, 0x93, 0xBB, + 0xD3, 0x64, 0x77, 0xCE, 0x11, 0xFC, 0xA2, 0x0E, + 0x1B, 0x5B, 0x9E, 0x13, 0x9F, 0x20, 0x8B, 0xAA, + 0xCD, 0x72, 0xD7, 0xA6, 0xF3, 0x1E, 0x4F, 0x72, + 0xC6, 0x49, 0x0F, 0x7B, 0xF0, 0x4C, 0x61, 0x1F, + 0x43, 0x0D, 0x4F, 0x0D, 0x33, 0x13, 0xED, 0x63, + 0xE5, 0xDB, 0x71, 0xAB, 0xA4, 0x83, 0xEF, 0xDC, + 0x86, 0x9D, 0x4B, 0xBD, 0x1B, 0x8A, 0xFE, 0x39, + 0xA8, 0x8B, 0xBA, 0x4C, 0x85, 0x28, 0xFC, 0xB3, + 0x62, 0x85, 0xD2, 0xF0, 0x38, 0xD0, 0x4B, 0xA4, + 0xD1, 0x3B, 0xD4, 0xD0, 0x2C, 0x78, 0x6C, 0x6A, + 0xC2, 0x64, 0x2C, 0x31, 0x4A, 0xD8, 0x69, 0x24, + 0xED, 0x77, 0x7D, 0x68, 0x9A, 0xA1, 0x78, 0x81, + 0xD9, 0x7E, 0x6C, 0xFE, 0x0A, 0x0D, 0x76, 0xF7, + 0x4B, 0x58, 0xE7, 0xC9, 0xB5, 0x11, 0x07, 0x87, + 0x88, 0x6A, 0x9F, 0x3D, 0xE0, 0xEE, 0xCC, 0x60, + 0x6B, 0x6B, 0xE6, 0xB5, 0x54, 0x8B, 0x32, 0x1F, + 0x04, 0x1D, 0x0E, 0x9E, 0xFA, 0x6D, 0xB0, 0xE0, + 0x6D, 0xF9, 0x79, 0xB4, 0xAB, 0x5E, 0xDF, 0x23, + 0x7F, 0x95, 0xAD, 0x80, 0x17, 0x23, 0x90, 0x1F, + 0xF0, 0xC3, 0xD9, 0x2D, 0xAC, 0x3F, 0x63, 0xF5, + 0x77, 0xC5, 0x05, 0xAC, 0x06, 0xB6, 0xA1, 0xB4, + 0xA2, 0x40, 0xB3, 0x99, 0x34, 0x7D, 0x31, 0xD4, + 0xB1, 0xD4, 0xC1, 0xBB, 0x71, 0x1E, 0xDA, 0x3F, + 0xA9, 0x12, 0x68, 0xFA, 0x5B, 0x20, 0x24, 0x6D, + 0x4D, 0x72, 0x43, 0x18, 0xBF, 0x66, 0x71, 0x69, + 0x26, 0x7D, 0x77, 0x78, 0xF8, 0xE5, 0x20, 0xAE, + 0x56, 0x6C, 0x0F, 0x72, 0x94, 0x42, 0x85, 0x4F, + 0xE4, 0xFB, 0x32, 0x26, 0x1B, 0x1C, 0x6E, 0x0B, + 0xF0, 0xB8, 0x58, 0x00, 0xD2, 0x36, 0x64, 0xAD, + 0xA9, 0x00, 0xCE, 0x35, 0x3C, 0x88, 0x79, 0x94, + 0x0C, 0x0C, 0x9B, 0xF2, 0xDA, 0xBD, 0xCA, 0x93, + 0x37, 0x26, 0xD3, 0x08, 0x54, 0xD2, 0x0D, 0xBC, + 0x5D, 0x43, 0x5F, 0xCF, 0x28, 0xB5, 0xAA, 0x15, + 0x28, 0x46, 0x45, 0x6B, 0xE8, 0xDF, 0xE8, 0xCE, + 0x8F, 0xC0, 0x1A, 0x53, 0x63, 0x3B, 0x53, 0x75, + 0xDD, 0x43, 0x1F, 0x07, 0x0A, 0xD5, 0xA1, 0x2A, + 0x6E, 0x28, 0xE1, 0xD7, 0xD0, 0x09, 0xCF, 0x62, + 0xC1, 0x5F, 0x21, 0xDB, 0xC5, 0x40, 0x99, 0x48, + 0x87, 0x6E, 0x11, 0xF5, 0x5A, 0x4E, 0xBC, 0xF9, + 0xA8, 0x02, 0x7C, 0x47, 0x39, 0xA5, 0xD8, 0x52, + 0xB1, 0x80, 0xDC, 0xFE, 0x08, 0x4B, 0x5D, 0x09, + 0xDE, 0x06, 0xF3, 0x2A, 0xAD, 0x14, 0x76, 0x40, + 0x2F, 0x82, 0x28, 0x6A, 0xB6, 0x43, 0xEF, 0x71, + 0x63, 0xC2, 0x56, 0xEB, 0x3B, 0x4B, 0x52, 0x2F, + 0x93, 0xD3, 0x18, 0x3E, 0x18, 0xA8, 0xF7, 0x58, + 0xFC, 0x8B, 0x3D, 0x4D, 0x4B, 0x72, 0xBD, 0xF7, + 0x04, 0xC9, 0xB8, 0xD7, 0x6C, 0x8C, 0x67, 0xBB, + 0x4C, 0x9B, 0x57, 0xF7, 0x22, 0x4E, 0x41, 0xB6, + 0xFD, 0xD9, 0xF8, 0x41, 0x62, 0x0F, 0xFF, 0xAA, + 0xC6, 0x87, 0x95, 0xFF, 0xFD, 0x58, 0xD9, 0xB2, + 0xBA, 0x47, 0x61, 0x24, 0xEA, 0x92, 0x6E, 0x74, + 0xB3, 0xDA, 0xE5, 0x83, 0x99, 0x24, 0xB1, 0x71, + 0x2A, 0x33, 0xB2, 0xD5, 0x8F, 0xF0, 0x32, 0xCE, + 0x37, 0xCF, 0xC7, 0x1C, 0xE8, 0xDE, 0x46, 0x78, + 0x96, 0x97, 0xF6, 0x73, 0x90, 0xE5, 0x71, 0x05, + 0xEA, 0x0D, 0xC2, 0x1D, 0x9E, 0x43, 0x34, 0xBC, + 0x8F, 0x45, 0xE5, 0x08, 0xCA, 0x20, 0x0C, 0x84 + }, + .len = 2048 + }, + .auth_tag = { + .data = { + 0xD0, 0x62, 0x1F, 0x20, 0x1C, 0xE8, 0xDD, 0x36, + 0x00, 0x74, 0xF6, 0xD7, 0xFD, 0x2C, 0xA0, 0xAF + }, + .len = 16 + } +}; + +/** AES-256 Test Vectors */ +static const struct gcm_test_data gcm_test_case_256_1 = { + .key = { + .data = { + 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 }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { 0x00 }, + .len = 0 + }, + .ciphertext = { + .data = { 0x00 }, + .len = 0 + }, + .auth_tag = { + .data = { + 0x53, 0x0F, 0x8A, 0xFB, 0xC7, 0x45, 0x36, 0xB9, + 0xA9, 0x63, 0xB4, 0xF1, 0xC4, 0xCB, 0x73, 0x8B }, + .len = 16 + } +}; + +/** AES-256 Test Vectors */ +static const struct gcm_test_data gcm_test_case_256_2 = { + .key = { + .data = { + 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 }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .len = 16 + }, + .ciphertext = { + .data = { + 0xCE, 0xA7, 0x40, 0x3D, 0x4D, 0x60, 0x6B, 0x6E, + 0x07, 0x4E, 0xC5, 0xD3, 0xBA, 0xF3, 0x9D, 0x18 }, + .len = 16 + }, + .auth_tag = { + .data = { + 0xD0, 0xD1, 0xC8, 0xA7, 0x99, 0x99, 0x6B, 0xF0, + 0x26, 0x5B, 0x98, 0xB5, 0xD4, 0x8A, 0xB9, 0x19 }, + .len = 16 + } +}; + +/** AES-256 Test Vectors */ +static const struct gcm_test_data gcm_test_case_256_3 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, + .len = 32 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, + .len = 64 + }, + .ciphertext = { + .data = { + 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, + 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, + 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, + 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, + 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, + 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, + 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, + 0xFA, 0x47, 0xC8, 0x2E, 0xF0, 0x68, 0xE1, 0x3E }, + .len = 64 + }, + .auth_tag = { + .data = { + 0x64, 0xAF, 0x1D, 0xFB, 0xE8, 0x0D, 0x37, 0xD8, + 0x92, 0xC3, 0xB9, 0x1D, 0xD3, 0x08, 0xAB, 0xFC }, + .len = 16 + } +}; + +/** AES-256 Test Vectors */ +static const struct gcm_test_data gcm_test_case_256_4 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, + .len = 32 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 8 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 }, + .len = 60 + }, + .ciphertext = { + .data = { + 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, + 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, + 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, + 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, + 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, + 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, + 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, + 0xFA, 0x47, 0xC8, 0x2E }, + .len = 60 + }, + .auth_tag = { + .data = { + 0x63, 0x16, 0x91, 0xAE, 0x17, 0x05, 0x5E, 0xA6, + 0x6D, 0x0A, 0x51, 0xE2, 0x50, 0x21, 0x85, 0x4A }, + .len = 16 + } + +}; + +/** AES-256 Test Vectors */ +static const struct gcm_test_data gcm_test_case_256_5 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, + .len = 32 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_text, + .len = 8 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 }, + .len = 60 + }, + .ciphertext = { + .data = { + 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, + 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, + 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, + 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, + 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, + 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, + 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, + 0xFA, 0x47, 0xC8, 0x2E }, + .len = 60 + }, + .auth_tag = { + .data = { + 0xA7, 0x99, 0xAC, 0xB8, 0x27, 0xDA, 0xB1, 0x82, + 0x79, 0xFD, 0x83, 0x73, 0x52, 0x4D, 0xDB, 0xF1 }, + .len = 16 + } + +}; + +/** AES-256 Test Vectors */ +static const struct gcm_test_data gcm_test_case_256_6 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, + .len = 32 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 12 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 }, + .len = 60 + }, + .ciphertext = { + .data = { + 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, + 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, + 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, + 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, + 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, + 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, + 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, + 0xFA, 0x47, 0xC8, 0x2E }, + .len = 60 + }, + .auth_tag = { + .data = { + 0x5D, 0xA5, 0x0E, 0x53, 0x64, 0x7F, 0x3F, 0xAE, + 0x1A, 0x1F, 0xC0, 0xB0, 0xD8, 0xBE, 0xF2, 0x64 }, + .len = 16 + } +}; + +/** AES-256 Test Vectors */ +static const struct gcm_test_data gcm_test_case_256_7 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, + .len = 32 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_text, + .len = 12 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 }, + .len = 60 + }, + .ciphertext = { + .data = { + 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, + 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, + 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, + 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, + 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, + 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, + 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, + 0xFA, 0x47, 0xC8, 0x2E }, + .len = 60 + }, + .auth_tag = { + .data = { + 0x4E, 0xD0, 0x91, 0x95, 0x83, 0xA9, 0x38, 0x72, + 0x09, 0xA9, 0xCE, 0x5F, 0x89, 0x06, 0x4E, 0xC8 }, + .len = 16 + } +}; + +/** variable AAD AES-128 Test Vectors */ +static const struct gcm_test_data gcm_test_case_aad_1 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_text, + .len = GCM_LARGE_AAD_LENGTH + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, + .len = 64 + }, + .ciphertext = { + .data = { + 0x42, 0x83, 0x1E, 0xC2, 0x21, 0x77, 0x74, 0x24, + 0x4B, 0x72, 0x21, 0xB7, 0x84, 0xD0, 0xD4, 0x9C, + 0xE3, 0xAA, 0x21, 0x2F, 0x2C, 0x02, 0xA4, 0xE0, + 0x35, 0xC1, 0x7E, 0x23, 0x29, 0xAC, 0xA1, 0x2E, + 0x21, 0xD5, 0x14, 0xB2, 0x54, 0x66, 0x93, 0x1C, + 0x7D, 0x8F, 0x6A, 0x5A, 0xAC, 0x84, 0xAA, 0x05, + 0x1B, 0xA3, 0x0B, 0x39, 0x6A, 0x0A, 0xAC, 0x97, + 0x3D, 0x58, 0xE0, 0x91, 0x47, 0x3F, 0x59, 0x85 + }, + .len = 64 + }, + .auth_tag = { + .data = { + 0xCA, 0x70, 0xAF, 0x96, 0xA8, 0x5D, 0x40, 0x47, + 0x0C, 0x3C, 0x48, 0xF5, 0xF0, 0xF5, 0xA5, 0x7D + }, + .len = 16 + } +}; + +/** variable AAD AES-256 Test Vectors */ +static const struct gcm_test_data gcm_test_case_aad_2 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a }, + .len = 32 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_text, + .len = GCM_LARGE_AAD_LENGTH + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, + .len = 64 + }, + .ciphertext = { + .data = { + 0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA, + 0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E, + 0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04, + 0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9, + 0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5, + 0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0, + 0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB, + 0xFA, 0x47, 0xC8, 0x2E, 0xF0, 0x68, 0xE1, 0x3E + }, + .len = 64 + }, + .auth_tag = { + .data = { + 0xBA, 0x06, 0xDA, 0xA1, 0x91, 0xE1, 0xFE, 0x22, + 0x59, 0xDA, 0x67, 0xAF, 0x9D, 0xA5, 0x43, 0x94 + }, + .len = 16 + } +}; + +/** GMAC Test Vectors */ +static uint8_t gmac_plaintext[GMAC_LARGE_PLAINTEXT_LENGTH] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 +}; + +static const struct gmac_test_data gmac_test_case_1 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gmac_plaintext, + .len = 160 + }, + .plaintext = { + .data = NULL, + .len = 0 + }, + .gmac_tag = { + .data = { + 0x4C, 0x0C, 0x4F, 0x47, 0x2D, 0x78, 0xF6, 0xD8, + 0x03, 0x53, 0x20, 0x2F, 0x1A, 0xDF, 0x90, 0xD0 + }, + .len = 16 + }, +}; + +static const struct gmac_test_data gmac_test_case_2 = { + .key = { + .data = { + 0xaa, 0x74, 0x0a, 0xbf, 0xad, 0xcd, 0xa7, 0x79, + 0x22, 0x0d, 0x3b, 0x40, 0x6c, 0x5d, 0x7e, 0xc0, + 0x9a, 0x77, 0xfe, 0x9d, 0x94, 0x10, 0x45, 0x39, + }, + .len = 24 + }, + .iv = { + .data = { + 0xab, 0x22, 0x65, 0xb4, 0xc1, 0x68, 0x95, + 0x55, 0x61, 0xf0, 0x43, 0x15, }, + .len = 12 + }, + .aad = { + .data = gmac_plaintext, + .len = 80 + }, + .plaintext = { + .data = NULL, + .len = 0 + }, + .gmac_tag = { + .data = { + 0xCF, 0x82, 0x80, 0x64, 0x02, 0x46, 0xF4, 0xFB, + 0x33, 0xAE, 0x1D, 0x90, 0xEA, 0x48, 0x83, 0xDB + }, + .len = 16 + }, +}; + +static const struct gmac_test_data gmac_test_case_3 = { + .key = { + .data = { + 0xb5, 0x48, 0xe4, 0x93, 0x4f, 0x5c, 0x64, 0xd3, + 0xc0, 0xf0, 0xb7, 0x8f, 0x7b, 0x4d, 0x88, 0x24, + 0xaa, 0xc4, 0x6b, 0x3c, 0x8d, 0x2c, 0xc3, 0x5e, + 0xe4, 0xbf, 0xb2, 0x54, 0xe4, 0xfc, 0xba, 0xf7, + }, + .len = 32 + }, + .iv = { + .data = { + 0x2e, 0xed, 0xe1, 0xdc, 0x64, 0x47, 0xc7, + 0xaf, 0xc4, 0x41, 0x53, 0x58, + }, + .len = 12 + }, + .aad = { + .data = gmac_plaintext, + .len = 65 + }, + .plaintext = { + .data = NULL, + .len = 0 + }, + .gmac_tag = { + .data = { + 0x77, 0x46, 0x0D, 0x6F, 0xB1, 0x87, 0xDB, 0xA9, + 0x46, 0xAD, 0xCD, 0xFB, 0xB7, 0xF9, 0x13, 0xA1 + }, + .len = 16 + }, +}; + +/******* GCM PERF VECTORS ***********/ + +struct cryptodev_perf_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[64]; + unsigned len; + } aad; + + struct { + uint8_t data[2048]; + unsigned len; + } plaintext; + + struct { + uint8_t data[2048]; + unsigned len; + } ciphertext; + + struct { + uint8_t data[16]; + unsigned len; + } auth_tag; + + struct { + uint32_t size; + uint8_t data[16]; + unsigned len; + } auth_tags[7]; + +}; + +/* 2048B */ +static const struct cryptodev_perf_test_data AES_GCM_128_12IV_0AAD = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = { 0 }, + .len = 0 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 + }, + .len = 2048 + }, + .ciphertext = { + .data = { + 0x42, 0x83, 0x1E, 0xC2, 0x21, 0x77, 0x74, 0x24, + 0x4B, 0x72, 0x21, 0xB7, 0x84, 0xD0, 0xD4, 0x9C, + 0xE3, 0xAA, 0x21, 0x2F, 0x2C, 0x02, 0xA4, 0xE0, + 0x35, 0xC1, 0x7E, 0x23, 0x29, 0xAC, 0xA1, 0x2E, + 0x21, 0xD5, 0x14, 0xB2, 0x54, 0x66, 0x93, 0x1C, + 0x7D, 0x8F, 0x6A, 0x5A, 0xAC, 0x84, 0xAA, 0x05, + 0x1B, 0xA3, 0x0B, 0x39, 0x6A, 0x0A, 0xAC, 0x97, + 0x3D, 0x58, 0xE0, 0x91, 0x47, 0x3F, 0x59, 0x85, + 0x04, 0x99, 0x55, 0xE1, 0x36, 0x76, 0xB7, 0x14, + 0x1D, 0xF0, 0xF6, 0x8C, 0x65, 0xD5, 0xAD, 0xFB, + 0x90, 0x7F, 0x5D, 0xA2, 0xD6, 0xFD, 0xD0, 0xE5, + 0x0D, 0x9B, 0x68, 0x21, 0x49, 0x42, 0x6E, 0x13, + 0xEC, 0x22, 0x50, 0x2A, 0x30, 0x47, 0x49, 0xA1, + 0x7F, 0xC3, 0x09, 0xE0, 0x56, 0x91, 0xC4, 0x54, + 0x70, 0xD7, 0x19, 0x40, 0xCA, 0x6B, 0x65, 0x27, + 0x3E, 0xE9, 0xD1, 0x0F, 0x1C, 0xB5, 0x45, 0x0D, + 0x27, 0xE7, 0xCF, 0x94, 0x10, 0xBF, 0xA2, 0xFA, + 0x86, 0x20, 0x3F, 0x6E, 0xE9, 0x95, 0x03, 0x5A, + 0x46, 0x11, 0x75, 0xD5, 0x37, 0x71, 0x7F, 0xE0, + 0xBC, 0x9F, 0xC8, 0xE9, 0xB1, 0x08, 0x2C, 0x59, + 0x6E, 0x51, 0x4A, 0x83, 0x38, 0xC1, 0xED, 0xE2, + 0x2E, 0x88, 0x90, 0xA5, 0x7D, 0xA4, 0x93, 0x9A, + 0x30, 0xD6, 0x96, 0x34, 0x0F, 0xC4, 0xD1, 0x7E, + 0xC9, 0x8F, 0xC5, 0xBB, 0x80, 0x50, 0x85, 0x75, + 0x7D, 0x82, 0x36, 0xDB, 0x62, 0x15, 0xAF, 0x4B, + 0x0A, 0x9D, 0xCD, 0x64, 0x00, 0xAB, 0x88, 0x28, + 0xA8, 0x35, 0x17, 0x70, 0x6F, 0x47, 0x44, 0xCD, + 0x65, 0xAE, 0xD5, 0x05, 0x0A, 0xA8, 0x2F, 0x48, + 0xAC, 0xA1, 0x72, 0x64, 0x1C, 0x7E, 0xD3, 0xF5, + 0xD8, 0x4E, 0x73, 0x17, 0x0C, 0xE5, 0x9F, 0xB6, + 0x00, 0xFA, 0xD7, 0x2C, 0x3D, 0x6A, 0x10, 0x47, + 0x7C, 0xF2, 0x6B, 0x13, 0x10, 0x8A, 0x76, 0x39, + 0xF8, 0x50, 0x33, 0xAC, 0x08, 0x1D, 0xA3, 0x48, + 0xE1, 0xD0, 0x05, 0x49, 0xB7, 0x76, 0x03, 0x72, + 0x07, 0xC5, 0xD3, 0x08, 0x79, 0x38, 0x66, 0xC1, + 0x52, 0xAF, 0x83, 0xCD, 0xF3, 0x86, 0x62, 0xBF, + 0x92, 0x24, 0x97, 0xBD, 0x5D, 0x7D, 0x81, 0x56, + 0x4C, 0xF3, 0xD2, 0x60, 0xC2, 0xDE, 0x61, 0xC1, + 0x39, 0x61, 0xDA, 0x07, 0x50, 0xC7, 0x98, 0x63, + 0x7E, 0xDD, 0x54, 0xCA, 0xDE, 0x12, 0xD2, 0xA8, + 0x19, 0x08, 0x6E, 0xF9, 0xFA, 0x6F, 0x58, 0x97, + 0xD4, 0x0B, 0x5C, 0x5B, 0xE5, 0x30, 0xE5, 0x4C, + 0x0E, 0x16, 0x87, 0xF0, 0x2C, 0xCB, 0x53, 0xB8, + 0x0C, 0xE5, 0xDF, 0x16, 0x7B, 0xE8, 0xC2, 0xCF, + 0xCC, 0xFF, 0x51, 0x24, 0xC1, 0xDD, 0x59, 0x9C, + 0xA7, 0x56, 0x03, 0xB9, 0x0A, 0x37, 0xA2, 0xAC, + 0x28, 0x8B, 0xEB, 0x51, 0x4E, 0xF1, 0xAE, 0xB5, + 0xC8, 0xB5, 0xCB, 0x8D, 0x23, 0xF6, 0x24, 0x2D, + 0xF6, 0x59, 0x62, 0xC0, 0xCB, 0xD3, 0x18, 0xE4, + 0xB7, 0x73, 0xEF, 0xDB, 0x13, 0x9A, 0xF5, 0xD3, + 0xD5, 0x61, 0x01, 0x14, 0xA5, 0xE5, 0x0D, 0x27, + 0xC9, 0xA5, 0x08, 0x1C, 0x60, 0xBA, 0x73, 0xFF, + 0xA9, 0xE0, 0x27, 0x86, 0x3F, 0xF7, 0x15, 0x03, + 0x69, 0xA7, 0x2B, 0x57, 0xAC, 0xA6, 0x70, 0x55, + 0xE9, 0xB5, 0x3F, 0xEB, 0x6F, 0xCE, 0x8A, 0xA1, + 0x9D, 0x8B, 0x84, 0xF1, 0x7C, 0xD0, 0x35, 0x21, + 0x91, 0x3D, 0x3D, 0x6E, 0x83, 0xFC, 0x45, 0x36, + 0x93, 0xDA, 0x66, 0xDF, 0x1A, 0x59, 0x22, 0xA5, + 0xC4, 0x99, 0x9B, 0xF8, 0x48, 0x9A, 0x50, 0x09, + 0xAB, 0xAE, 0x56, 0xB6, 0x49, 0x02, 0x3E, 0x90, + 0xB6, 0x07, 0x7E, 0xA7, 0x6A, 0x0A, 0xB5, 0x85, + 0x31, 0x0D, 0x84, 0xD4, 0x01, 0xE4, 0x48, 0x63, + 0xF3, 0xC1, 0x54, 0x65, 0xA6, 0x4C, 0x8B, 0x33, + 0xF9, 0x70, 0x59, 0x3B, 0xA6, 0xF6, 0x2B, 0x66, + 0xC5, 0xD2, 0xEB, 0xAB, 0x67, 0xD2, 0xE3, 0x78, + 0xA9, 0x1A, 0x4C, 0x99, 0xA9, 0xA6, 0xCA, 0xF7, + 0x65, 0xF0, 0x48, 0xF8, 0x2A, 0xEA, 0x96, 0x9F, + 0xC4, 0x50, 0x9A, 0x0C, 0xB6, 0x0D, 0x8A, 0x2F, + 0xC3, 0x99, 0x4E, 0xA0, 0x06, 0x4D, 0xAB, 0x25, + 0x2E, 0x44, 0x47, 0xB6, 0x98, 0xF1, 0x2C, 0x96, + 0x54, 0x51, 0x12, 0x41, 0x0D, 0xEF, 0x32, 0x9A, + 0x4A, 0xBD, 0xA2, 0x26, 0x53, 0xA8, 0xFD, 0x8B, + 0x6C, 0x95, 0x0A, 0x1A, 0x96, 0xEF, 0x3C, 0x85, + 0x34, 0x4E, 0x25, 0x9E, 0x1C, 0x67, 0x33, 0x8A, + 0xFF, 0x6D, 0x98, 0x93, 0x3D, 0x3F, 0x49, 0x6B, + 0xBF, 0x7C, 0x4F, 0x63, 0x5D, 0x62, 0x64, 0x67, + 0x0D, 0x07, 0x7F, 0x24, 0x4A, 0x23, 0xBC, 0x35, + 0xE0, 0x92, 0x6F, 0x51, 0xE7, 0x25, 0x97, 0xB9, + 0x14, 0x35, 0x2B, 0x48, 0xAC, 0x6F, 0x54, 0xDF, + 0xF2, 0xB4, 0xB0, 0xE0, 0xD3, 0x28, 0x0D, 0x66, + 0x46, 0x28, 0x0A, 0x16, 0x9C, 0x87, 0x73, 0xB7, + 0x9C, 0x2B, 0xB5, 0x43, 0xC9, 0x46, 0xB9, 0x1F, + 0x5F, 0x3C, 0x45, 0x03, 0x4B, 0xBF, 0x44, 0x4D, + 0xE1, 0x44, 0xDA, 0x54, 0xC5, 0x32, 0x3A, 0xFA, + 0x21, 0x5C, 0xAD, 0xD5, 0x1E, 0x1B, 0x54, 0x7C, + 0x9F, 0xEA, 0x92, 0x8C, 0xEA, 0x69, 0xC0, 0xCE, + 0xDA, 0x09, 0xAD, 0x95, 0xA0, 0x8E, 0x0B, 0x8E, + 0x10, 0x4F, 0x5B, 0x8F, 0xB8, 0x2D, 0xAC, 0x4C, + 0x94, 0x4B, 0x7C, 0x1E, 0xF1, 0x53, 0x20, 0x9B, + 0xD6, 0xC4, 0x92, 0x4C, 0x7F, 0xFB, 0x8B, 0x8E, + 0x40, 0x2F, 0x24, 0xA3, 0x4E, 0x46, 0x64, 0xF4, + 0xC6, 0x35, 0x0F, 0xC7, 0x40, 0x55, 0x43, 0xAF, + 0x7E, 0x91, 0x76, 0x48, 0x6F, 0x97, 0x7A, 0xF8, + 0x32, 0x1E, 0xD3, 0x5B, 0xBC, 0x19, 0xB5, 0x48, + 0xFA, 0x4F, 0x52, 0x77, 0x5B, 0x9E, 0xA2, 0xC8, + 0x9A, 0x83, 0x30, 0x8D, 0x9F, 0x0B, 0x6F, 0xA8, + 0x2E, 0x84, 0xCC, 0xC1, 0x50, 0x96, 0x46, 0xAE, + 0x73, 0x91, 0x7D, 0xCD, 0x88, 0xAB, 0x67, 0x3F, + 0x66, 0x3A, 0x8D, 0xB1, 0x89, 0x07, 0x93, 0xDB, + 0x42, 0x22, 0xDC, 0x13, 0xBD, 0xCD, 0xBB, 0x12, + 0x8D, 0x88, 0x44, 0x13, 0x22, 0x52, 0x81, 0xDC, + 0xEF, 0xA1, 0xE4, 0xA3, 0xA7, 0xBA, 0xEE, 0x98, + 0x79, 0x45, 0x29, 0x05, 0x65, 0x3D, 0xDC, 0xAF, + 0xA1, 0x37, 0x29, 0xFD, 0x05, 0xD1, 0x3A, 0xF7, + 0x32, 0x1D, 0x02, 0xEC, 0x28, 0x1E, 0x0F, 0x96, + 0xF3, 0x21, 0x19, 0x5F, 0x49, 0xB9, 0xEA, 0x9A, + 0xAD, 0x34, 0x58, 0xD1, 0xD9, 0xB1, 0x7D, 0xD2, + 0xEA, 0xED, 0x74, 0xE8, 0x25, 0x9A, 0x7B, 0xC5, + 0xC8, 0xD8, 0x76, 0xB6, 0xBC, 0x0B, 0x78, 0xCE, + 0xD9, 0xA6, 0xBB, 0x2F, 0x79, 0xA4, 0x45, 0x05, + 0x55, 0x6E, 0x20, 0x84, 0xEB, 0xC8, 0x70, 0xB0, + 0x3A, 0x2D, 0x06, 0x98, 0x29, 0x10, 0xB8, 0xC5, + 0xE9, 0xE4, 0xB6, 0xDE, 0x97, 0x9A, 0x0D, 0x8C, + 0xB6, 0x22, 0x16, 0x59, 0xAB, 0xB5, 0xD7, 0x14, + 0xAB, 0x08, 0x02, 0x27, 0x7B, 0xF7, 0x0E, 0xAC, + 0xC5, 0xAC, 0x4D, 0x7F, 0xE5, 0x65, 0x51, 0x40, + 0x44, 0x92, 0xB1, 0x6A, 0xB7, 0x00, 0x76, 0x89, + 0x6E, 0x08, 0x5F, 0x45, 0x2B, 0x53, 0x86, 0x86, + 0xA7, 0x85, 0xBC, 0x62, 0xAC, 0xAA, 0x82, 0x73, + 0x0A, 0xEB, 0x35, 0x16, 0x95, 0x26, 0xAB, 0x9E, + 0xE9, 0x64, 0x53, 0x99, 0x08, 0x31, 0xF5, 0x6B, + 0x1F, 0xFE, 0x47, 0x4B, 0x09, 0x33, 0x4F, 0xBF, + 0x1F, 0x0B, 0x4C, 0xB2, 0xB4, 0xA4, 0x17, 0xA9, + 0xAD, 0xC5, 0x62, 0x7C, 0xF1, 0x1B, 0xAE, 0x46, + 0xD3, 0xAC, 0xFD, 0x43, 0xFE, 0x79, 0xD0, 0x58, + 0x2F, 0x6C, 0x9F, 0xD0, 0x65, 0xA4, 0x64, 0x03, + 0xAF, 0x73, 0x46, 0x75, 0x7D, 0x49, 0x1B, 0x4C, + 0xFA, 0x49, 0xD8, 0x9A, 0xCC, 0x59, 0xC6, 0xC7, + 0xA1, 0x05, 0xC2, 0x32, 0xC8, 0x6C, 0x50, 0xA8, + 0x06, 0x58, 0xBE, 0x6C, 0x7D, 0x22, 0xD6, 0x0D, + 0x74, 0x40, 0xCE, 0xD6, 0x64, 0xD6, 0x47, 0xD0, + 0xBF, 0xF1, 0x5C, 0x54, 0xF9, 0x06, 0x3F, 0x3D, + 0x86, 0xBA, 0xF2, 0x0F, 0x5E, 0x2C, 0x01, 0xCC, + 0xD9, 0xC7, 0xB1, 0x4A, 0xB3, 0xD7, 0x26, 0xCC, + 0xC3, 0x7A, 0x74, 0x2C, 0xE1, 0x22, 0x65, 0xA0, + 0x5B, 0xCA, 0xF4, 0xE1, 0x7D, 0xE1, 0x56, 0xFD, + 0x94, 0x10, 0xC6, 0xA1, 0x4A, 0xE8, 0x6B, 0x34, + 0x4E, 0x71, 0x60, 0x77, 0x0F, 0x03, 0xDD, 0xFF, + 0xC8, 0x59, 0x54, 0x6C, 0xD4, 0x4A, 0x55, 0x24, + 0x35, 0x21, 0x60, 0x73, 0xDF, 0x6F, 0xE7, 0x3C, + 0xC2, 0xF0, 0xDA, 0xA9, 0xE5, 0x8C, 0xAC, 0xB6, + 0xFD, 0x2E, 0xF7, 0xA0, 0x18, 0xA7, 0x55, 0x47, + 0xD1, 0xCB, 0x9E, 0xAA, 0x58, 0x54, 0x3B, 0x37, + 0x18, 0xB5, 0xC1, 0xBB, 0x41, 0x59, 0xE4, 0x28, + 0x4A, 0x13, 0x90, 0x6A, 0xF7, 0xD1, 0xB3, 0x71, + 0xB6, 0x6E, 0xF6, 0x5D, 0x2E, 0x0E, 0x6C, 0x4A, + 0x7B, 0xF7, 0xB6, 0x21, 0xD4, 0xFC, 0x47, 0x8C, + 0x9B, 0x0A, 0x90, 0xAC, 0x11, 0x52, 0x86, 0x07, + 0x24, 0xDA, 0xA9, 0x49, 0x50, 0xD9, 0xDC, 0xE2, + 0x19, 0x87, 0x73, 0x88, 0xC3, 0xE4, 0xED, 0xC9, + 0x1C, 0xA8, 0x7E, 0x39, 0x48, 0x91, 0x10, 0xAB, + 0xFC, 0x3C, 0x1E, 0xEE, 0x08, 0xA1, 0xB9, 0xB2, + 0x02, 0x57, 0xB1, 0xD1, 0x35, 0x5E, 0x3D, 0x94, + 0xFB, 0x36, 0x27, 0x1A, 0x0E, 0x75, 0xFC, 0xBC, + 0xDB, 0xF3, 0xF5, 0x7C, 0x08, 0x39, 0xAA, 0xF4, + 0x2E, 0xEE, 0xCF, 0xCD, 0x2D, 0x70, 0xB8, 0x84, + 0xE6, 0x22, 0x5C, 0xC0, 0xB9, 0x33, 0xCB, 0x97, + 0xA1, 0xA3, 0xEE, 0x93, 0x71, 0xCF, 0xC9, 0x21, + 0x31, 0x7A, 0xEC, 0xE7, 0x70, 0xF2, 0xAA, 0x91, + 0xAA, 0x48, 0xAD, 0xAC, 0x03, 0xB1, 0x26, 0x52, + 0xBC, 0x65, 0x22, 0xA1, 0x09, 0x3D, 0xAB, 0x16, + 0x08, 0xBF, 0xCF, 0x3F, 0x59, 0x08, 0x6F, 0x68, + 0xEB, 0x8A, 0xB3, 0xCF, 0x77, 0x82, 0xFB, 0x25, + 0x78, 0x16, 0x4C, 0xDB, 0x72, 0xF5, 0xCF, 0x79, + 0x71, 0xE4, 0x4E, 0x23, 0x15, 0x7F, 0x1E, 0xA8, + 0x3E, 0xC0, 0x59, 0x91, 0x20, 0xAE, 0x2C, 0x1D, + 0x90, 0xC8, 0x49, 0x42, 0x48, 0x29, 0x82, 0x66, + 0x68, 0x49, 0x73, 0xDA, 0xE4, 0x28, 0xCD, 0x7B, + 0x4D, 0xE4, 0x23, 0x34, 0xB9, 0xE1, 0xB4, 0x42, + 0x67, 0x22, 0x5B, 0xEE, 0xE6, 0x74, 0x32, 0x6F, + 0x21, 0x9F, 0x97, 0x46, 0x03, 0xE1, 0xC9, 0x7A, + 0x14, 0x27, 0x30, 0xE1, 0xB2, 0x34, 0xE6, 0xAF, + 0x7B, 0xAA, 0xDD, 0x89, 0x04, 0x30, 0xD6, 0x78, + 0x0B, 0x3D, 0xC3, 0x69, 0xB0, 0x67, 0x4F, 0x4E, + 0x12, 0x21, 0x93, 0x2D, 0x79, 0xDD, 0x8B, 0xDB, + 0xEA, 0x90, 0x66, 0x54, 0xA8, 0x05, 0xF2, 0xE4, + 0x59, 0x8A, 0x96, 0x52, 0x30, 0xF0, 0x4E, 0x9A, + 0xE5, 0xD8, 0x72, 0x1C, 0x3B, 0x63, 0x02, 0xB9, + 0xC7, 0xA1, 0xDA, 0xC8, 0x6C, 0x48, 0xE0, 0xDE, + 0x59, 0x64, 0x89, 0x2C, 0xF9, 0xC8, 0x3B, 0x00, + 0xEC, 0xF2, 0x68, 0x51, 0x67, 0x05, 0x85, 0xAF, + 0xB8, 0xD5, 0x65, 0xEE, 0x73, 0x26, 0x88, 0xFB, + 0xA9, 0xD6, 0x6C, 0x68, 0x9D, 0x9F, 0x23, 0x6A, + 0x10, 0x24, 0x82, 0xB2, 0xB7, 0x40, 0x19, 0x3E, + 0x6F, 0xA2, 0xD5, 0x2C, 0x6E, 0x8D, 0xE9, 0x33, + 0x6E, 0x24, 0x94, 0x05, 0xE9, 0x2D, 0xD9, 0x3A, + 0x8C, 0xE5, 0xCC, 0x1D, 0x3F, 0xB8, 0x71, 0xA8, + 0x98, 0x33, 0xBB, 0x1A, 0xAC, 0x41, 0x0A, 0x04, + 0xFE, 0x4D, 0x46, 0x17, 0x8A, 0xCB, 0xF3, 0x4B, + 0x97, 0x02, 0xCC, 0x9D, 0x11, 0xF1, 0xBC, 0xA9, + 0xC1, 0xD1, 0xB6, 0xD6, 0x7B, 0x5F, 0x9D, 0x22, + 0x86, 0x71, 0xEC, 0x42, 0x53, 0xB7, 0x85, 0x30, + 0xAF, 0x1D, 0x01, 0xA7, 0xBF, 0x72, 0xC2, 0xC6, + 0xC9, 0xB8, 0xD8, 0xC7, 0xE9, 0xC4, 0xBA, 0xC5, + 0xB1, 0x8A, 0xB8, 0x62, 0xBF, 0x75, 0x75, 0x69, + 0xF8, 0x8D, 0x7E, 0xD9, 0xD2, 0x28, 0xB5, 0x40, + 0xCE, 0xCB, 0xB8, 0x74, 0x31, 0x40, 0x7B, 0x0D, + 0x73, 0x98, 0x99, 0x12, 0xB7, 0x75, 0x3E, 0xBC, + 0xAE, 0x48, 0xCA, 0xA9, 0x1E, 0xA7, 0x95, 0x31, + 0x87, 0x0F, 0x14, 0x52, 0xB6, 0x8E, 0x42, 0x50, + 0xB2, 0x76, 0x75, 0xD8, 0x7E, 0x66, 0x23, 0x13, + 0x8B, 0x29, 0xAA, 0x13, 0xCA, 0x8A, 0xD8, 0x9B, + 0x7B, 0x38, 0xD2, 0xE8, 0x67, 0xD1, 0x89, 0x25, + 0x9C, 0x63, 0x2F, 0xC3, 0x26, 0xC7, 0x74, 0x83, + 0x05, 0xED, 0x67, 0x02, 0x85, 0xAD, 0x1D, 0x0E, + 0xA9, 0xD6, 0xE1, 0xC7, 0x39, 0xA0, 0x6E, 0x72, + 0xCE, 0x56, 0x6C, 0xB8, 0x4A, 0xDE, 0x11, 0xA2, + 0xBF, 0xC1, 0x84, 0x98, 0x8F, 0xCA, 0x79, 0x74, + 0xCA, 0x9F, 0x45, 0x16, 0xBC, 0xB1, 0xF4, 0x03, + 0x76, 0x6E, 0xD5, 0x46, 0x60, 0xD7, 0x1D, 0xF0, + 0x87, 0x29, 0x63, 0x07, 0x06, 0xB9, 0xC2, 0x69, + 0x6D, 0xF9, 0x4B, 0x30, 0x96, 0x83, 0xB8, 0xC5, + 0xBE, 0x3A, 0xBA, 0xD0, 0x3E, 0x2B, 0x04, 0x16, + 0x6A, 0x00, 0x3B, 0x1A, 0x8E, 0xF8, 0xF6, 0x21, + 0x01, 0xD6, 0x08, 0x41, 0x74, 0xA2, 0xFC, 0x36, + 0xED, 0x11, 0x51, 0x5A, 0x4A, 0x21, 0x1A, 0x03, + 0x11, 0x95, 0x11, 0xF6, 0x73, 0x38, 0x67, 0xFC, + 0xF1, 0x2B, 0x22, 0x54, 0x65, 0x40, 0x7D, 0x8C, + 0x13, 0xC4, 0x46, 0x87, 0x09, 0x2B, 0xB5, 0xA1, + 0x82, 0x49, 0x46, 0x56, 0xF5, 0x5F, 0xF1, 0x04, + 0xD8, 0x6F, 0xDB, 0x38, 0xAD, 0xF4, 0x1A, 0xA3, + 0xFF, 0x7C, 0xC7, 0xA6, 0xAF, 0x87, 0x5C, 0x8C, + 0xEA, 0x3C, 0x9D, 0x7A, 0x4A, 0xD8, 0xA8, 0x66, + 0xDB, 0xBF, 0x12, 0x58, 0x98, 0x8E, 0xBA, 0x6F, + 0xAF, 0x20, 0xDA, 0xEE, 0x82, 0x34, 0x2F, 0x33, + 0x88, 0x98, 0xBA, 0xB2, 0x54, 0x7F, 0x9E, 0x63, + 0x19, 0x6C, 0x7D, 0xCE, 0x85, 0xF8, 0xB6, 0x77, + 0xCB, 0x38, 0x1F, 0xB1, 0x79, 0xBD, 0xED, 0x32, + 0xE3, 0xB9, 0x40, 0xEF, 0x3E, 0x6C, 0x29, 0x88, + 0x70, 0x99, 0x47, 0xA6, 0x4A, 0x1C, 0xCC, 0x0B, + 0x9B, 0x72, 0xA9, 0x29, 0x83, 0x4C, 0xDE, 0x4F, + 0x65, 0x4E, 0xCE, 0xBD, 0xFA, 0x76, 0x8D, 0xA6, + 0x1A, 0xD8, 0x66, 0xFE, 0xA4, 0x2A, 0x61, 0x50, + 0xEE, 0x15, 0xF1, 0xF0, 0x9D, 0xFF, 0xEC, 0xEE, + 0x00, 0x03, 0xFE, 0xAC, 0x53, 0x02, 0xCC, 0x87, + 0xB1, 0xA2, 0xD8, 0x34, 0x2C, 0xEC, 0xA6, 0x4C, + 0x02, 0xC0, 0xC1, 0x72, 0xD6, 0x54, 0x35, 0x24, + 0x25, 0x8B, 0xEC, 0xDA, 0x47, 0x5F, 0x5D, 0x7E, + 0xD8, 0x01, 0x51, 0xDD, 0x8F, 0xB4, 0x48, 0xDD, + 0x94, 0x99, 0x95, 0x77, 0xB3, 0x42, 0x14, 0xEB, + 0x26, 0x61, 0xE9, 0x22, 0xE3, 0x07, 0x73, 0xFB, + 0xEF, 0x38, 0x55, 0x35, 0x8F, 0xCC, 0x30, 0x1E, + 0x38, 0xE0, 0x35, 0xF4, 0x9A, 0x7C, 0xCF, 0x38, + 0x0B, 0x9E, 0xF4, 0x88, 0x4A, 0xEA, 0xF2, 0x67, + 0x9F, 0x61, 0x40, 0x34, 0x09, 0xDC, 0xBF, 0xFB, + 0x22, 0x27, 0x04, 0x8B, 0x8D, 0x85, 0x7F, 0xB2, + 0x29, 0x62, 0x25, 0x73, 0x7F, 0x46, 0x2E, 0xA3, + 0x8E, 0xAF, 0xEC, 0x55, 0x98, 0x1A, 0xEE, 0x29, + 0xA0, 0x1A, 0x5F, 0xFE, 0x5D, 0xA5, 0x76, 0x93, + 0xAB, 0x57, 0x56, 0xEA, 0xDB, 0x39, 0xAC, 0x48, + 0xBE, 0x95, 0x92, 0x2B, 0xC6, 0xE1, 0x2F, 0x36, + 0x4B, 0x08, 0x01, 0x90, 0x50, 0xD8, 0xFA, 0xF9, + 0x94, 0x4E, 0x76, 0x9B, 0x72, 0x59, 0xC2, 0x2F, + 0x61, 0x04, 0x0A, 0x9E, 0x28, 0xE5, 0x24, 0x1E, + 0x79, 0xCF, 0x8D, 0xB6, 0x52, 0xA7, 0x79, 0x5F, + 0x44, 0x98, 0xD5, 0x0E, 0x6E, 0x4B, 0x64, 0x9B, + }, + .len = 2048 + }, + .auth_tags[0] = { + .size = 64, + .data = { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, + .len = 16 + }, + .auth_tags[1] = { + .size = 128, + .data = { 0xE9, 0xA9, 0x75, 0xB6, 0xEF, 0x6F, 0x8C, 0xF1, + 0xB3, 0xA9, 0x19, 0xA4, 0xAE, 0x66, 0xBD, 0x9E }, + .len = 16 + }, + .auth_tags[2] = { + .size = 256, + .data = { 0x29, 0xC3, 0x18, 0x96, 0x54, 0xCB, 0xF5, 0xAA, + 0x4E, 0x62, 0xB6, 0xFF, 0x45, 0xA6, 0x18, 0x0C }, + .len = 16 + }, + .auth_tags[3] = { + .size = 512, + .data = { 0x3B, 0xD7, 0xC3, 0x5F, 0xE4, 0x1B, 0xC2, 0xBC, + 0xE9, 0xAC, 0xF2, 0xCE, 0xA7, 0x7B, 0x1D, 0x70 }, + .len = 16 + }, + .auth_tags[4] = { + .size = 1024, + .data = { 0xCC, 0xBB, 0xBC, 0xCF, 0x86, 0x01, 0x4D, 0x93, + 0x4B, 0x68, 0x55, 0x19, 0xA1, 0x40, 0xCD, 0xEA }, + .len = 16 + }, + .auth_tags[5] = { + .size = 1536, + .data = { 0x67, 0x31, 0x11, 0xA2, 0x58, 0xB5, 0x1C, 0x23, + 0xC0, 0x41, 0x05, 0x30, 0xC6, 0xBA, 0xFA, 0x88 }, + .len = 16 + }, + .auth_tags[6] = { + .size = 2048, + .data = { 0x03, 0x9C, 0x6B, 0xB9, 0x57, 0xBF, 0x6E, 0x86, + 0x3A, 0x09, 0x5F, 0x08, 0xA9, 0xE4, 0xF2, 0x1F }, + .len = 16 + }, + .auth_tag = { + .data = { + 0x03, 0x9C, 0x6B, 0xB9, 0x57, 0xBF, 0x6E, 0x86, + 0x3A, 0x09, 0x5F, 0x08, 0xA9, 0xE4, 0xF2, 0x1F + }, + .len = 16 + }, +}; + +static const struct gmac_test_data gmac_test_case_4 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 + }, + .len = 12 + }, + .aad = { + .data = gmac_plaintext, + .len = GMAC_LARGE_PLAINTEXT_LENGTH + }, + .plaintext = { + .data = NULL, + .len = 0 + }, + .gmac_tag = { + .data = { + 0x3f, 0x07, 0xcb, 0xb9, 0x86, 0x3a, 0xea, 0xc2, + 0x2f, 0x3a, 0x2a, 0x93, 0xd8, 0x09, 0x6b, 0xda + }, + .len = 16 + } +}; + +static const struct gcm_test_data gcm_test_case_SGL_1 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + .len = 12 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x54, + 0xd7, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9c, + 0xd8, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9b, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + + }, + .len = 3120 + }, + .ciphertext = { + .data = { + 0x42, 0x83, 0x1E, 0xC2, 0x21, 0x77, 0x74, 0x24, + 0x4B, 0x72, 0x21, 0xB7, 0x84, 0xD0, 0xD4, 0x9C, + 0xE3, 0xAA, 0x21, 0x2F, 0x2C, 0x02, 0xA4, 0xE0, + 0x35, 0xC1, 0x7E, 0x23, 0x29, 0xAC, 0xA1, 0x2E, + 0x21, 0xD5, 0x14, 0xB2, 0x54, 0x66, 0x93, 0x1C, + 0x7D, 0x8F, 0x6A, 0x5A, 0xAC, 0x84, 0xAA, 0x05, + 0x1B, 0xA3, 0x0B, 0x39, 0x6A, 0x0A, 0xAC, 0x97, + 0x3D, 0x58, 0xE0, 0x91, 0x47, 0x3F, 0x59, 0x85, + 0x05, 0x99, 0x55, 0xE1, 0x36, 0x76, 0xB7, 0x14, + 0x1D, 0xF0, 0xF6, 0x8C, 0x65, 0xD5, 0xAD, 0xFA, + 0x90, 0x7F, 0x5D, 0xA2, 0xD6, 0xFD, 0xD0, 0xE5, + 0x0D, 0x9B, 0x68, 0x21, 0x49, 0x42, 0x6E, 0x13, + 0xEC, 0x22, 0x50, 0x2A, 0x30, 0x47, 0x49, 0xA1, + 0x7F, 0xC3, 0x09, 0xE0, 0x56, 0x91, 0xC4, 0x54, + 0x70, 0xD7, 0x19, 0x40, 0xCA, 0x6B, 0x65, 0x27, + 0x3E, 0xE9, 0xD1, 0x0F, 0x1C, 0xB5, 0x45, 0x0C, + 0x29, 0xE7, 0xCF, 0x94, 0x10, 0xBF, 0xA2, 0xFA, + 0x86, 0x20, 0x3F, 0x6E, 0xE9, 0x95, 0x03, 0x5C, + 0x46, 0x11, 0x75, 0xD5, 0x37, 0x71, 0x7F, 0xE0, + 0xBC, 0x9F, 0xC8, 0xE9, 0xB1, 0x08, 0x2C, 0x59, + 0x6E, 0x51, 0x4A, 0x83, 0x38, 0xC1, 0xED, 0xE2, + 0x2E, 0x88, 0x90, 0xA5, 0x7D, 0xA4, 0x93, 0x9A, + 0x30, 0xD6, 0x96, 0x34, 0x0F, 0xC4, 0xD1, 0x7E, + 0xC9, 0x8F, 0xC5, 0xBB, 0x80, 0x50, 0x85, 0x73, + 0x8B, 0x7C, 0x0A, 0xDA, 0xD3, 0x37, 0x1C, 0x8B, + 0x1E, 0xAE, 0x29, 0x54, 0x05, 0x53, 0x48, 0xE5, + 0x94, 0xF1, 0xC5, 0x1A, 0x60, 0xDC, 0x61, 0x43, + 0xCD, 0x45, 0x4C, 0x6B, 0x95, 0xAD, 0x52, 0xE0, + 0x9E, 0xD1, 0x4E, 0xCC, 0x03, 0x27, 0x50, 0xD4, + 0xEB, 0xBD, 0x71, 0xA6, 0xD0, 0x2B, 0x23, 0xC0, + 0x9E, 0x5F, 0x34, 0xFD, 0xDE, 0xC1, 0x43, 0x35, + 0x77, 0xFB, 0xFD, 0xDF, 0xA0, 0x28, 0x42, 0x3B, + 0x0F, 0x2D, 0x31, 0xB4, 0x7A, 0xA8, 0x2F, 0xDF, + 0x58, 0xB5, 0x00, 0x19, 0x8D, 0xEB, 0x2C, 0xBB, + 0xAE, 0xAD, 0x74, 0x7F, 0x25, 0xAA, 0x24, 0x3E, + 0xCD, 0x89, 0x5E, 0x05, 0xD3, 0xBA, 0x0E, 0x9A, + 0x34, 0x7B, 0xE0, 0x11, 0xD2, 0xBA, 0x5A, 0x51, + 0xB4, 0x0D, 0xEE, 0x61, 0x73, 0xFC, 0xD2, 0x01, + 0x2D, 0x52, 0x3E, 0x37, 0x55, 0x3F, 0x58, 0xA8, + 0x1C, 0x8F, 0x1D, 0xD6, 0x3C, 0x39, 0x06, 0x18, + 0x65, 0x60, 0x55, 0x19, 0xAD, 0x1E, 0x78, 0xE9, + 0xF7, 0xF5, 0xFC, 0xCD, 0x5F, 0xF1, 0x34, 0x0C, + 0xA6, 0xFD, 0x1E, 0x9E, 0xB3, 0xCE, 0x2E, 0x10, + 0xFB, 0x98, 0xDD, 0x0E, 0x09, 0x5D, 0x4E, 0x58, + 0x75, 0x9A, 0x54, 0x74, 0xFB, 0x40, 0x76, 0x55, + 0x0E, 0x3E, 0xA4, 0xCE, 0x56, 0xA5, 0xE0, 0x53, + 0xB7, 0xAD, 0x36, 0x99, 0x6E, 0xCD, 0xC2, 0x90, + 0x6E, 0xEA, 0xBC, 0x21, 0xAC, 0x31, 0xFF, 0x2B, + 0x00, 0xA7, 0x5E, 0xC1, 0x7A, 0xF1, 0xAB, 0x24, + 0xA3, 0x40, 0x0B, 0xEB, 0x16, 0x62, 0x35, 0x1E, + 0xE9, 0xA5, 0xD3, 0x7E, 0xAA, 0x7E, 0x28, 0xA8, + 0x3F, 0xD8, 0x0A, 0x04, 0x12, 0x0F, 0xFF, 0x68, + 0x10, 0x85, 0x22, 0xD6, 0x05, 0x6A, 0x3A, 0xCB, + 0xC0, 0xCF, 0x8C, 0x20, 0xF0, 0x34, 0x32, 0xAA, + 0x76, 0x93, 0xE2, 0x23, 0x4F, 0xF2, 0xE6, 0x84, + 0x3B, 0xD4, 0xF3, 0x5D, 0xF3, 0x17, 0xEE, 0x27, + 0x67, 0xC3, 0x01, 0x6F, 0x32, 0xDE, 0xF6, 0xF6, + 0x87, 0xE9, 0x82, 0xEF, 0x1F, 0xA1, 0xE2, 0x68, + 0xF8, 0x5D, 0x49, 0x92, 0x47, 0x01, 0x75, 0x87, + 0x52, 0xD3, 0x54, 0xAE, 0x3B, 0xB7, 0xB2, 0x07, + 0x0F, 0x62, 0x7B, 0xF7, 0x50, 0x97, 0x9A, 0x4A, + 0x98, 0x65, 0x23, 0xA3, 0x5D, 0x76, 0x0A, 0x9C, + 0x6C, 0xE7, 0x89, 0xAD, 0x86, 0x70, 0xE7, 0x16, + 0x5F, 0x2F, 0x2E, 0x97, 0x29, 0x31, 0xF0, 0x60, + 0x33, 0x2C, 0xD7, 0xAA, 0xD6, 0xF0, 0x50, 0xB8, + 0xBD, 0x29, 0xA8, 0xA9, 0xAC, 0x5E, 0x0A, 0x3A, + 0x59, 0x34, 0x9A, 0x92, 0x25, 0x71, 0xB3, 0x16, + 0xC5, 0xD3, 0xA4, 0x15, 0x75, 0x9A, 0xB5, 0x78, + 0x6E, 0xCF, 0xAF, 0xC0, 0x39, 0x28, 0x44, 0x21, + 0xBB, 0xE8, 0x32, 0xAB, 0xCB, 0xF8, 0x4B, 0xE7, + 0x63, 0x9C, 0x56, 0xE7, 0xB2, 0xD6, 0x23, 0x17, + 0xDE, 0x92, 0xE9, 0x22, 0xC3, 0x36, 0xA5, 0xAC, + 0xA9, 0x98, 0x34, 0xAA, 0xFB, 0x03, 0x33, 0x33, + 0xBE, 0xD8, 0x22, 0x7F, 0xFA, 0x34, 0xA0, 0x35, + 0xC8, 0xA0, 0xDC, 0x35, 0x82, 0x06, 0x58, 0xE6, + 0xBF, 0x7C, 0x4F, 0x63, 0x5D, 0x62, 0x64, 0x67, + 0x0D, 0x07, 0x7F, 0x24, 0x4A, 0x23, 0xBC, 0x35, + 0xE0, 0x92, 0x6F, 0x51, 0xE7, 0x25, 0x97, 0xB9, + 0x14, 0x35, 0x2B, 0x48, 0xAC, 0x6F, 0x54, 0xDF, + 0xF2, 0xB4, 0xB0, 0xE0, 0xD3, 0x28, 0x0D, 0x67, + 0x48, 0x28, 0x0A, 0x16, 0x9C, 0x87, 0x73, 0xB7, + 0x9C, 0x2B, 0xB5, 0x43, 0xC9, 0x46, 0xB9, 0x19, + 0x01, 0xAA, 0xDE, 0x75, 0xA6, 0x0F, 0xB5, 0x72, + 0x6A, 0x51, 0xE3, 0xAC, 0xE0, 0xF6, 0x96, 0x13, + 0xBB, 0xC7, 0x08, 0x13, 0x9E, 0x47, 0xAA, 0xF5, + 0x9E, 0x69, 0xAC, 0x95, 0x29, 0xFE, 0xFF, 0x99, + 0xB2, 0x52, 0x72, 0x45, 0xF2, 0x07, 0xEB, 0x3C, + 0x0F, 0x75, 0x29, 0x73, 0x0D, 0x77, 0x58, 0x83, + 0xCB, 0xDD, 0xE7, 0x68, 0x1C, 0xE3, 0xD1, 0xA4, + 0x5D, 0xD1, 0xAB, 0xB4, 0x5A, 0x3F, 0x27, 0x66, + 0xDA, 0xB4, 0x81, 0x65, 0xCE, 0x1A, 0x9A, 0x7D, + 0xC7, 0xB6, 0x31, 0xDE, 0x83, 0xC2, 0x7C, 0xF8, + 0xD3, 0xC7, 0x97, 0x28, 0x50, 0xF2, 0x95, 0xFC, + 0xA7, 0xB2, 0xA6, 0x46, 0xEF, 0x10, 0xD2, 0x38, + 0x93, 0x14, 0x8D, 0xA7, 0x09, 0x17, 0x42, 0x7A, + 0x85, 0xB9, 0x42, 0x71, 0x2A, 0x51, 0x9B, 0x66, + 0x71, 0x12, 0x57, 0xB7, 0xBD, 0x26, 0xB7, 0x91, + 0xF8, 0x84, 0x44, 0x35, 0xAD, 0x6F, 0xCB, 0xD7, + 0xFC, 0xA1, 0x28, 0x77, 0x09, 0x5B, 0x6D, 0x52, + 0x43, 0xA1, 0xE2, 0x0A, 0x7E, 0x5A, 0x84, 0x45, + 0x20, 0xDE, 0xA5, 0x73, 0x1D, 0x37, 0x6E, 0xD8, + 0x7A, 0x0D, 0x91, 0xBE, 0xF4, 0xB3, 0x89, 0xE9, + 0x1F, 0x1E, 0xF6, 0xD5, 0x37, 0xB4, 0x3C, 0x1D, + 0xBE, 0x0D, 0x5B, 0x01, 0xB0, 0x8B, 0xCE, 0x3E, + 0x6D, 0x8B, 0x99, 0x9A, 0xC5, 0xAE, 0xFE, 0xA9, + 0x78, 0x34, 0x20, 0xA7, 0x6C, 0x7D, 0x46, 0x72, + 0x37, 0xAF, 0xFD, 0x17, 0x59, 0xED, 0x83, 0x5B, + 0xEB, 0x6E, 0x4A, 0xF1, 0xE6, 0x0D, 0x44, 0x92, + 0x65, 0x8E, 0x97, 0xD6, 0x83, 0x6E, 0x97, 0xCA, + 0x4C, 0x0A, 0xCE, 0x32, 0x2A, 0xAD, 0x22, 0x73, + 0xCB, 0xCB, 0xC3, 0x55, 0x08, 0x63, 0x23, 0xC2, + 0x31, 0x24, 0x90, 0x54, 0x99, 0xB2, 0x8C, 0xC7, + 0x8A, 0xB6, 0xFF, 0xC2, 0x75, 0xB1, 0xD9, 0x3D, + 0x95, 0xDC, 0xB6, 0xCF, 0x11, 0x74, 0x06, 0x54, + 0x03, 0xE3, 0x9B, 0x49, 0xE4, 0xF2, 0x73, 0x04, + 0xF7, 0xDC, 0x71, 0xD7, 0xFA, 0x3C, 0xD2, 0x61, + 0x77, 0x61, 0xB3, 0xDB, 0x6B, 0xCE, 0xCA, 0xFF, + 0xF0, 0xAD, 0xBC, 0x94, 0xC8, 0xF8, 0xD5, 0xF4, + 0x38, 0xA3, 0x61, 0xAA, 0x8C, 0x96, 0xEE, 0x56, + 0xAC, 0xB4, 0x42, 0xBA, 0x1A, 0xE1, 0x70, 0x98, + 0x1F, 0x9A, 0x6F, 0x98, 0xB9, 0x13, 0x46, 0xAB, + 0x0B, 0xCD, 0xA3, 0x7B, 0x0C, 0xCB, 0x8F, 0x72, + 0x23, 0xCF, 0x9E, 0xD8, 0xBB, 0x3F, 0x32, 0x27, + 0x54, 0xB8, 0x60, 0x64, 0x83, 0xAE, 0x22, 0xD1, + 0x6A, 0xC9, 0xF8, 0x13, 0xC4, 0xE4, 0xFF, 0x97, + 0xD8, 0x92, 0xA3, 0xD1, 0xD4, 0x86, 0xD7, 0xC3, + 0xBB, 0x40, 0xA2, 0x45, 0x78, 0xB1, 0xDB, 0x80, + 0xC6, 0x8D, 0x0A, 0xF0, 0xC3, 0xC2, 0xE3, 0x48, + 0xA1, 0x05, 0xC2, 0x32, 0xC8, 0x6C, 0x50, 0xA8, + 0x06, 0x58, 0xBE, 0x6C, 0x7D, 0x22, 0xD6, 0x0D, + 0x74, 0x40, 0xCE, 0xD6, 0x64, 0xD6, 0x47, 0xD0, + 0xBF, 0xF1, 0x5C, 0x54, 0xF9, 0x06, 0x3F, 0x3D, + 0x86, 0xBA, 0xF2, 0x0F, 0x5E, 0x2C, 0x01, 0xCC, + 0xD9, 0xC7, 0xB1, 0x4A, 0xB3, 0xD7, 0x26, 0xCC, + 0xC3, 0x7A, 0x74, 0x2C, 0xE1, 0x22, 0x65, 0xA0, + 0x5B, 0xCA, 0xF4, 0xE1, 0x7D, 0xE1, 0x56, 0xFD, + 0x95, 0x10, 0xC6, 0xA1, 0x4A, 0xE8, 0x6B, 0x34, + 0x4E, 0x71, 0x60, 0x77, 0x0F, 0x03, 0xDD, 0xFE, + 0xC8, 0x59, 0x54, 0x6C, 0xD4, 0x4A, 0x55, 0x24, + 0x35, 0x21, 0x60, 0x73, 0xDF, 0x6F, 0xE7, 0x3C, + 0xC2, 0xF0, 0xDA, 0xA9, 0xE5, 0x8C, 0xAC, 0xB6, + 0xFD, 0x2E, 0xF7, 0xA0, 0x18, 0xA7, 0x55, 0x47, + 0xD1, 0xCB, 0x9E, 0xAA, 0x58, 0x54, 0x3B, 0x37, + 0x18, 0xB5, 0xC1, 0xBB, 0x41, 0x59, 0xE4, 0x29, + 0x44, 0x13, 0x90, 0x6A, 0xF7, 0xD1, 0xB3, 0x71, + 0xB6, 0x6E, 0xF6, 0x5D, 0x2E, 0x0E, 0x6C, 0x4C, + 0x7B, 0xF7, 0xB6, 0x21, 0xD4, 0xFC, 0x47, 0x8C, + 0x9B, 0x0A, 0x90, 0xAC, 0x11, 0x52, 0x86, 0x07, + 0x24, 0xDA, 0xA9, 0x49, 0x50, 0xD9, 0xDC, 0xE2, + 0x19, 0x87, 0x73, 0x88, 0xC3, 0xE4, 0xED, 0xC9, + 0x1C, 0xA8, 0x7E, 0x39, 0x48, 0x91, 0x10, 0xAB, + 0xFC, 0x3C, 0x1E, 0xEE, 0x08, 0xA1, 0xB9, 0xB4, + 0xF4, 0xA9, 0x8D, 0xD0, 0x84, 0x7C, 0x8E, 0x54, + 0xEF, 0x05, 0xC3, 0x2A, 0x0B, 0x8D, 0x3C, 0x71, + 0xE7, 0x37, 0x27, 0x16, 0x07, 0xA2, 0x8F, 0x7A, + 0x86, 0x05, 0x56, 0xA3, 0xB2, 0x75, 0xC5, 0x2C, + 0xD4, 0x52, 0x60, 0x68, 0xA6, 0x6A, 0x48, 0xB6, + 0x92, 0x50, 0xEC, 0x22, 0xAD, 0x01, 0x75, 0x57, + 0xAF, 0xDF, 0x0F, 0x36, 0x93, 0x59, 0xF9, 0xE3, + 0xA1, 0x41, 0x3B, 0x60, 0xB3, 0x13, 0x12, 0x50, + 0x4B, 0x18, 0x20, 0xB9, 0x7B, 0x88, 0x27, 0x81, + 0xB1, 0xDA, 0xCA, 0x6F, 0x63, 0x95, 0x40, 0xA1, + 0x42, 0xE2, 0x14, 0xB8, 0x2B, 0x10, 0xB9, 0xDA, + 0xE7, 0x30, 0x91, 0x13, 0x52, 0xC9, 0xA3, 0x5C, + 0xD7, 0xBB, 0x39, 0x8F, 0x9A, 0xB8, 0xC5, 0xAF, + 0xC6, 0x3E, 0x65, 0x90, 0x91, 0x8C, 0x9F, 0xDD, + 0x84, 0xFB, 0xAD, 0x72, 0x4D, 0xD1, 0x42, 0xAD, + 0x0A, 0x1B, 0x3A, 0xC6, 0x06, 0x03, 0x19, 0xCB, + 0x31, 0x8C, 0x18, 0xD4, 0xEE, 0x90, 0x94, 0x3C, + 0x44, 0xDC, 0xFB, 0x78, 0x5C, 0xB5, 0xE3, 0x2F, + 0x89, 0x74, 0x0E, 0x28, 0x9C, 0xE4, 0xB4, 0xD2, + 0xE3, 0x5A, 0x32, 0xF9, 0xC0, 0x81, 0x6A, 0x38, + 0xC2, 0xCF, 0xD8, 0xD9, 0x3E, 0xAD, 0xF9, 0xB1, + 0xA2, 0x55, 0x64, 0x1E, 0xEC, 0xF5, 0x0D, 0xB1, + 0x8D, 0x07, 0x4E, 0xE5, 0x59, 0xE1, 0xE7, 0xFE, + 0x4C, 0xCF, 0x11, 0xF8, 0x27, 0xC2, 0x29, 0xE2, + 0xAF, 0x74, 0xAA, 0x53, 0x81, 0xD2, 0xFD, 0x5A, + 0xF1, 0xEB, 0x96, 0x2C, 0x3E, 0x9B, 0xC2, 0x74, + 0xFB, 0x65, 0x08, 0xA2, 0x63, 0xD3, 0xC5, 0x51, + 0xAF, 0x19, 0x8B, 0x34, 0x8B, 0x7D, 0xB7, 0x97, + 0x55, 0x97, 0x6D, 0x01, 0x5D, 0x98, 0xAA, 0x67, + 0x11, 0xBD, 0xC2, 0x99, 0x2F, 0xB4, 0xCA, 0x04, + 0x36, 0xF0, 0xB1, 0xA0, 0xBD, 0xA3, 0x4F, 0x4F, + 0xB6, 0x7B, 0xF5, 0x1E, 0x38, 0x87, 0xC2, 0x38, + 0x99, 0x5C, 0xE9, 0x2D, 0xDF, 0xAF, 0x5A, 0xF3, + 0x7A, 0x17, 0x70, 0x35, 0xEC, 0xD5, 0x19, 0xF7, + 0xB0, 0x21, 0x1E, 0x77, 0x30, 0x23, 0x54, 0x26, + 0x61, 0x4E, 0xB9, 0x02, 0xDE, 0xF4, 0x86, 0x93, + 0x47, 0x28, 0x43, 0x47, 0xB0, 0x56, 0xDC, 0x84, + 0x3E, 0x6A, 0x6B, 0xEA, 0x4D, 0x63, 0xFE, 0x56, + 0x5E, 0xF7, 0x6B, 0x1E, 0x5B, 0x63, 0xF1, 0x07, + 0x20, 0x2E, 0x9B, 0xEE, 0xDC, 0x70, 0x5E, 0x36, + 0x59, 0xE3, 0x3D, 0xA6, 0x0E, 0x50, 0x71, 0x06, + 0xDD, 0x8B, 0x3C, 0xF7, 0xEC, 0x3C, 0x7A, 0x08, + 0x8D, 0x4E, 0x6A, 0x08, 0xB0, 0xEE, 0x50, 0xE0, + 0xF9, 0x0E, 0x40, 0xC0, 0x11, 0xBF, 0x8A, 0x17, + 0x63, 0x9D, 0x59, 0x14, 0x0E, 0x25, 0x94, 0x09, + 0xE6, 0x34, 0xEC, 0x0F, 0xE4, 0x7C, 0x59, 0xCD, + 0x99, 0x85, 0x8E, 0x0F, 0xA1, 0x9E, 0x84, 0xBC, + 0x13, 0x20, 0x5F, 0x56, 0x26, 0x10, 0x1A, 0x77, + 0x77, 0x7B, 0x4B, 0x68, 0x13, 0x8A, 0x2C, 0xA5, + 0x01, 0xBF, 0xAD, 0xF2, 0x2C, 0xD9, 0x4B, 0x24, + 0x4C, 0xF5, 0x96, 0x4E, 0xD8, 0xE8, 0x98, 0xA8, + 0x9C, 0x63, 0x2F, 0xC3, 0x26, 0xC7, 0x74, 0x83, + 0x05, 0xED, 0x67, 0x02, 0x85, 0xAD, 0x1D, 0x0E, + 0xA9, 0xD6, 0xE1, 0xC7, 0x39, 0xA0, 0x6E, 0x72, + 0xCE, 0x56, 0x6C, 0xB8, 0x4A, 0xDE, 0x11, 0xA2, + 0xBF, 0xC1, 0x84, 0x98, 0x8F, 0xCA, 0x79, 0x75, + 0xC4, 0x9F, 0x45, 0x16, 0xBC, 0xB1, 0xF4, 0x03, + 0x76, 0x6E, 0xD5, 0x46, 0x60, 0xD7, 0x1D, 0xF6, + 0xD9, 0xBF, 0xF8, 0x71, 0xEB, 0x09, 0x33, 0x56, + 0xE6, 0xEC, 0x72, 0xC8, 0xB3, 0x47, 0x14, 0x2C, + 0x24, 0xA1, 0x1F, 0x16, 0xBE, 0x77, 0xFA, 0x9F, + 0x6B, 0x83, 0x05, 0x03, 0x4D, 0x6F, 0xC9, 0x76, + 0x69, 0x8D, 0xD7, 0x91, 0x26, 0x2B, 0x1C, 0x84, + 0xF2, 0x2B, 0x23, 0xA6, 0xFF, 0x7B, 0xEE, 0xCC, + 0x4E, 0x03, 0x8A, 0x80, 0x9E, 0x88, 0x96, 0xC3, + 0x7A, 0x3E, 0x1B, 0xAC, 0x40, 0x84, 0xD1, 0x64, + 0x89, 0x5F, 0xE3, 0x41, 0x89, 0x77, 0x4B, 0x28, + 0x83, 0xCA, 0x78, 0x4F, 0x36, 0xC8, 0xCE, 0x53, + 0x75, 0x39, 0x3A, 0x58, 0x92, 0x91, 0xF5, 0xA7, + 0x6A, 0xD0, 0xB2, 0xBB, 0xFC, 0x8E, 0x3B, 0xFC, + 0x83, 0x67, 0x42, 0xAA, 0x18, 0x51, 0x48, 0xD4, + 0xC4, 0x85, 0x60, 0xA4, 0x2D, 0xD4, 0x4E, 0xA1, + 0xF0, 0xB6, 0x41, 0x98, 0x6F, 0x84, 0xDE, 0x0C, + 0x03, 0x8D, 0x83, 0x4A, 0x71, 0xBB, 0x32, 0x8B, + 0x83, 0xF7, 0xD8, 0x08, 0x05, 0xA4, 0x48, 0xFE, + 0xCA, 0xBB, 0x21, 0xA8, 0xBA, 0x2A, 0xD2, 0x65, + 0x4E, 0xEF, 0xA1, 0x8F, 0x01, 0x09, 0xC6, 0x8C, + 0xE5, 0x35, 0x32, 0xBB, 0x19, 0x15, 0xAB, 0x7A, + 0xFD, 0x29, 0x76, 0xF9, 0xD1, 0xC5, 0x3E, 0xFD, + 0x7A, 0x74, 0xBC, 0x41, 0x4F, 0x2C, 0x79, 0x6F, + 0x45, 0x4E, 0xFD, 0x88, 0x49, 0x9A, 0x90, 0x6F, + 0x65, 0x00, 0xC8, 0x08, 0xB8, 0x3B, 0x40, 0x06, + 0x9A, 0x98, 0x5B, 0x6A, 0xD3, 0x5E, 0x32, 0x0E, + 0xB0, 0x21, 0xE6, 0x2D, 0xEF, 0x7B, 0x99, 0x1B, + 0xAF, 0x96, 0x20, 0x12, 0xE9, 0x31, 0xDA, 0x20, + 0xB0, 0x27, 0x99, 0xC7, 0x14, 0x56, 0x3A, 0x08, + 0x46, 0xA4, 0xB2, 0x0C, 0x6C, 0x1F, 0x1B, 0xAF, + 0x9F, 0x90, 0x03, 0xBB, 0x03, 0xE0, 0x20, 0xE9, + 0x45, 0x33, 0xA0, 0x3E, 0x01, 0x2C, 0xA7, 0x4A, + 0xCC, 0xC6, 0xF5, 0xA3, 0x35, 0x0D, 0xE1, 0x5E, + 0x90, 0x0B, 0xAC, 0x9A, 0x05, 0x79, 0xB2, 0x90, + 0x39, 0xEE, 0xC8, 0x20, 0x55, 0xB3, 0x71, 0x46, + 0xAC, 0x92, 0x42, 0x85, 0xD5, 0x12, 0x03, 0x8D, + 0xBC, 0x82, 0xE7, 0x5A, 0x6E, 0x2E, 0x2C, 0xC0, + 0xB6, 0x44, 0xF8, 0xBB, 0x5F, 0x7A, 0x42, 0x86, + 0x28, 0xF0, 0x9B, 0xF9, 0x17, 0xDD, 0x35, 0x2F, + 0x56, 0xE4, 0x63, 0xFF, 0xEC, 0x87, 0xC5, 0x53, + 0xBF, 0x64, 0xB2, 0xDA, 0xDE, 0xC1, 0x6C, 0x85, + 0x82, 0x51, 0x40, 0x41, 0xC9, 0x7A, 0x0A, 0xB8, + 0xB2, 0x75, 0x03, 0x88, 0x22, 0x6D, 0x76, 0x6E, + 0x2D, 0x2B, 0x73, 0xCB, 0x48, 0xC4, 0xED, 0xE0, + 0x96, 0xFA, 0x36, 0x9F, 0x99, 0xC7, 0x97, 0xDE, + 0x6D, 0xFC, 0x69, 0x86, 0x57, 0x5F, 0xB9, 0x93, + 0x78, 0x5C, 0x07, 0x64, 0x61, 0xD0, 0x41, 0x14, + 0x32, 0xED, 0xC0, 0xE4, 0xAC, 0xFC, 0x10, 0x0D, + 0xAF, 0xEE, 0xDA, 0xB3, 0x6D, 0xB8, 0x7C, 0x10, + 0xD5, 0x3B, 0x88, 0xE1, 0x15, 0xE1, 0xA4, 0x27, + 0xFE, 0xEE, 0x0A, 0xC8, 0x95, 0xCF, 0xCA, 0x99, + 0x98, 0x1D, 0xF3, 0x0E, 0xB8, 0x03, 0xD5, 0x51, + 0x4B, 0x56, 0xB9, 0x07, 0x85, 0x58, 0x17, 0x51, + 0x16, 0xC4, 0x86, 0xBB, 0xD3, 0x50, 0x01, 0x0E, + 0x7B, 0x9C, 0xEF, 0xF0, 0x28, 0x4A, 0xD7, 0x3D, + 0x1E, 0x3A, 0xBB, 0xCF, 0x2C, 0x90, 0x12, 0x2A, + 0xB3, 0x90, 0x72, 0xE3, 0x93, 0x81, 0xE8, 0xA4, + 0xEF, 0x8F, 0xD9, 0x45, 0x4F, 0xB1, 0xD0, 0x21, + 0xDA, 0x20, 0x5C, 0xE9, 0x41, 0x41, 0x4E, 0x48, + 0x95, 0x4D, 0x5A, 0xB3, 0xE5, 0x8B, 0xFC, 0xDE, + 0xB9, 0x7B, 0x93, 0xBE, 0xA2, 0x74, 0x1B, 0xFA, + 0xED, 0xCC, 0x0E, 0xDD, 0x96, 0x13, 0x2C, 0xAC, + 0xDE, 0x2B, 0x2D, 0x8A, 0x30, 0x5A, 0xB8, 0x4B, + 0x08, 0x2C, 0x74, 0xF7, 0xB4, 0x45, 0xD3, 0xA5, + 0x62, 0x87, 0xCA, 0x16, 0xEB, 0x49, 0x46, 0x0C, + 0x87, 0x7F, 0x11, 0x1D, 0x22, 0x66, 0x0A, 0x38, + 0x90, 0x3A, 0x31, 0x38, 0x73, 0xB2, 0xD5, 0x5E, + 0x06, 0xC4, 0x1E, 0x3D, 0xB7, 0x52, 0xB8, 0xE5, + 0xC0, 0xF9, 0x72, 0xBC, 0x7A, 0x8A, 0xD3, 0xB4, + 0x1D, 0xA9, 0x93, 0x3B, 0x7E, 0xFF, 0x8E, 0xA0, + 0x96, 0x52, 0xE9, 0x9E, 0x60, 0x4C, 0x02, 0x90, + 0xE5, 0x46, 0x92, 0xB3, 0xB8, 0x24, 0xE9, 0xD0, + 0xCE, 0xD3, 0x0B, 0xCD, 0x8B, 0xE8, 0x72, 0xEA, + 0x6E, 0xBF, 0x2B, 0x99, 0x6F, 0xC0, 0x65, 0xE8, + 0x92, 0x30, 0x03, 0x28, 0xA9, 0xB0, 0xA7, 0x03, + 0x92, 0x2C, 0xC8, 0x38, 0x8C, 0x38, 0x56, 0xEE, + 0xDB, 0x39, 0xBD, 0x7E, 0xE9, 0x8D, 0xDB, 0xC1, + 0xD5, 0x71, 0xC7, 0x84, 0xF3, 0xB2, 0x23, 0x22, + 0xB5, 0x98, 0xB3, 0x36, 0xF1, 0xC4, 0xB1, 0xA4, + 0xF2, 0x84, 0x24, 0xE5, 0x97, 0x48, 0x34, 0x43, + 0xEF, 0xD9, 0xF4, 0x10, 0xE4, 0x13, 0xEE, 0x6C, + 0xE7, 0x5D, 0x9B, 0xBA, 0x35, 0xF5, 0x7D, 0xE5, + 0xBF, 0x8A, 0xCC, 0x3D, 0x28, 0xCF, 0xE8, 0x90, + 0xE3, 0xCF, 0x01, 0x69, 0xD7, 0xC0, 0xD2, 0x2C, + 0xC2, 0x9B, 0x89, 0xF2, 0xA9, 0x83, 0xA2, 0xA9, + 0x12, 0xAA, 0x56, 0xD8, 0xCB, 0xA5, 0x8B, 0x0A, + 0x03, 0xC1, 0xE1, 0x8E, 0x02, 0x36, 0x3D, 0x8F, + 0x58, 0x4D, 0xEB, 0x93, 0x91, 0xC6, 0xE7, 0x22, + 0xCE, 0xA8, 0x02, 0xD2, 0x82, 0x0D, 0x43, 0x4D, + 0x4E, 0x11, 0xF8, 0x7B, 0x45, 0xD0, 0x23, 0xF7, + 0x14, 0x35, 0x16, 0xA4, 0x0B, 0xAD, 0xFE, 0xE2, + 0x2B, 0xFD, 0xF7, 0x17, 0xA9, 0x93, 0x77, 0x82, + 0x45, 0x6E, 0x51, 0x1F, 0x5C, 0x2C, 0x5F, 0xFF, + 0x1A, 0xA3, 0x0E, 0x29, 0xA5, 0x1D, 0xFD, 0x0E, + 0xDD, 0x14, 0xF6, 0x69, 0x20, 0x15, 0xFD, 0xBB, + 0xF8, 0xAF, 0x3D, 0xF3, 0xCC, 0xB8, 0x7E, 0x64, + 0xED, 0x99, 0xF3, 0x1D, 0xFC, 0x96, 0xA2, 0x0A, + 0x9C, 0xC2, 0x9B, 0xD7, 0x03, 0xA6, 0x79, 0x3B, + 0x16, 0x0C, 0x6C, 0x5C, 0x2B, 0x61, 0x0E, 0x48, + 0x96, 0x5C, 0x46, 0x7F, 0xC3, 0xCD, 0x3C, 0x10, + 0x30, 0x8F, 0xC4, 0xB5, 0x92, 0x46, 0x1C, 0xDF, + 0x10, 0xEE, 0x43, 0x27, 0x42, 0x70, 0xD2, 0xC4, + 0x5E, 0x77, 0x78, 0x0E, 0x0E, 0xC3, 0x8B, 0x72, + 0xA0, 0xFC, 0x4C, 0x0F, 0x5D, 0xBE, 0xBE, 0x07, + 0x5B, 0x53, 0x38, 0xC8, 0x96, 0x82, 0x2D, 0x2D, + 0x8E, 0xA8, 0x6C, 0x68, 0x34, 0x42, 0x31, 0x90, + 0xD6, 0x4D, 0x29, 0xA9, 0x90, 0x95, 0x19, 0xD6, + 0x8F, 0x2F, 0xF4, 0xD3, 0x71, 0x21, 0xB7, 0x7D, + 0x51, 0xA6, 0x15, 0xE5, 0xDA, 0x08, 0x6A, 0x23, + 0xDE, 0x6C, 0xBA, 0xCF, 0x84, 0xF1, 0x47, 0x25, + 0x4A, 0xF1, 0x2F, 0x24, 0xED, 0x3B, 0xED, 0xF0, + 0xA7, 0x48, 0xAE, 0x58, 0x7F, 0x0B, 0x3B, 0x78, + 0xCE, 0x94, 0x32, 0x82, 0x63, 0x22, 0x67, 0xAA, + 0x45, 0x37, 0xCC, 0x43, 0xD5, 0x10, 0x59, 0x5B, + 0x09, 0xC6, 0x1C, 0x32, 0xCD, 0x19, 0xA2, 0x3C, + 0x2B, 0x84, 0x03, 0xD5, 0x97, 0x20, 0xE7, 0xFB, + 0x2D, 0x0A, 0x3C, 0x5C, 0xFD, 0x39, 0x9C, 0xDE, + 0x02, 0x3D, 0xC7, 0xDD, 0x51, 0xDE, 0x99, 0xB3, + 0x65, 0x00, 0x60, 0xCF, 0xAE, 0xCD, 0xE2, 0x83, + 0xD5, 0x36, 0x2C, 0x89, 0x28, 0x6D, 0xC3, 0x6A, + 0x80, 0xCD, 0x1A, 0xC3, 0x75, 0x11, 0x7E, 0x65, + 0x2A, 0x44, 0x9D, 0xB5, 0x12, 0x2A, 0x78, 0xD0, + 0x4D, 0xF8, 0x5E, 0xBF, 0xEC, 0x6B, 0x60, 0xD2, + 0x89, 0x92, 0x5E, 0x17, 0xDA, 0x33, 0x83, 0xDB, + 0xED, 0xF4, 0x5E, 0x82, 0xE9, 0x04, 0xD7, 0xE0, + 0xA4, 0x1B, 0xFE, 0x32, 0x93, 0x05, 0x2C, 0xCF, + 0xA2, 0xAE, 0x83, 0xCA, 0x2F, 0x5E, 0x47, 0x1C, + 0x85, 0x0D, 0x01, 0xE5, 0x44, 0x3D, 0xE4, 0x58, + 0x8E, 0xC0, 0x46, 0x05, 0x95, 0xBE, 0x59, 0xED, + 0x0F, 0x7B, 0xA1, 0xF7, 0xDB, 0x2C, 0x79, 0x86, + 0xE9, 0x54, 0x98, 0xA6, 0x2A, 0xD0, 0xFE, 0xC9, + 0x59, 0x1D, 0x31, 0xC6, 0x27, 0x83, 0x2C, 0x12, + 0x9C, 0xE1, 0x43, 0x3C, 0xEC, 0x65, 0x3B, 0xEF, + 0xFD, 0x92, 0xBC, 0x0E, 0x38, 0xBA, 0x56, 0x1C, + 0xC0, 0x81, 0x9E, 0xBE, 0x76, 0x59, 0x88, 0xA4, + 0x0C, 0x6B, 0xD9, 0x7C, 0xD6, 0x8C, 0x32, 0xCD, + 0x3F, 0xB6, 0xEF, 0xBF, 0xA6, 0xC7, 0xC9, 0xD3, + 0x02, 0xB0, 0x3B, 0xFF, 0xFC, 0x4A, 0x97, 0x14, + 0xFF, 0xF2, 0x48, 0xFE, 0x1B, 0xCE, 0x7D, 0x24, + 0xA1, 0xD6, 0x03, 0xB0, 0x2F, 0xAA, 0xF7, 0x71, + 0xC9, 0x0E, 0xCB, 0x57, 0xBA, 0xEF, 0xB5, 0x65, + 0xE1, 0x44, 0xE4, 0x6A, 0xEB, 0xE8, 0x2B, 0x8F, + 0x06, 0x23, 0x7A, 0xA9, 0x70, 0xAE, 0x48, 0x65, + 0x94, 0xEE, 0xA5, 0x94, 0x78, 0x7D, 0x09, 0xF8, + 0xB5, 0x4D, 0x64, 0x67, 0x10, 0x16, 0xA2, 0xFC, + 0x49, 0x93, 0x76, 0x71, 0xED, 0x56, 0x25, 0xB5, + 0x87, 0xE8, 0x84, 0x16, 0x55, 0xE1, 0x1E, 0x34, + 0xE3, 0xB2, 0x49, 0x8F, 0xDC, 0xDA, 0xC3, 0x17, + 0x82, 0x0E, 0x19, 0xD7, 0xE0, 0x09, 0xD7, 0xD9, + 0x59, 0x6B, 0x55, 0x60, 0x1C, 0x1B, 0x02, 0xE8, + 0xD1, 0x90, 0xF6, 0x3E, 0x94, 0x4A, 0x12, 0x0C, + 0xBB, 0x69, 0xFD, 0x7C, 0xA0, 0xDD, 0x5F, 0x93, + 0x9F, 0xFE, 0x2E, 0x79, 0xDB, 0xBE, 0x6F, 0x85, + 0xAD, 0x9B, 0xDE, 0xAA, 0x10, 0xCA, 0xDB, 0xF2, + 0xF9, 0xD0, 0x54, 0x15, 0x00, 0xF0, 0x6F, 0x86, + 0x16, 0xF6, 0xA8, 0xA4, 0x08, 0x7B, 0x50, 0xF1, + 0x35, 0xAC, 0xB6, 0xBB, 0x8B, 0xA0, 0x86, 0x3B, + 0x3B, 0xDA, 0x9F, 0x89, 0xB5, 0x9C, 0x44, 0x41, + 0x6A, 0xFD, 0x8A, 0x79, 0xA0, 0xFB, 0x7D, 0x1B, + 0xE8, 0xC4, 0xA7, 0x3F, 0x66, 0x97, 0xA9, 0xF8, + 0xEA, 0x0C, 0x30, 0x81, 0x63, 0xE4, 0xE3, 0x84, + 0x62, 0xC5, 0x19, 0xFB, 0x00, 0xD6, 0x72, 0xE6, + 0xC9, 0x6C, 0xDB, 0xEB, 0xF3, 0x6F, 0xDB, 0xE7, + 0x00, 0x53, 0xCE, 0x1D, 0xE5, 0xF5, 0x53, 0x18, + 0xE5, 0xAA, 0xDA, 0x90, 0x7B, 0xCB, 0x2B, 0x74, + 0xED, 0x70, 0xFE, 0x90, 0xA8, 0xC8, 0x80, 0x2B, + 0x93, 0x08, 0xDB, 0x6A, 0x0F, 0x3D, 0xA1, 0xFA, + 0xB6, 0x63, 0x18, 0xF8, 0x43, 0x68, 0x00, 0xD0, + 0x7A, 0x97, 0xCD, 0x5B, 0xB2, 0x84, 0x90, 0x06, + 0xB9, 0x81, 0xC5, 0x81, 0x05, 0x55, 0x8C, 0xC4, + 0x03, 0x89, 0xF5, 0x63, 0x87, 0x39, 0xEC, 0xD6, + 0x89, 0x01, 0xE7, 0x1C, 0x4C, 0xDF, 0x5D, 0x65, + 0xFE, 0x4B, 0x91, 0x04, 0x5B, 0x0E, 0x03, 0x38, + 0x2F, 0x21, 0xA8, 0x36, 0x58, 0x93, 0xAD, 0x1F, + 0xEB, 0xC3, 0x91, 0x90, 0x9B, 0x95, 0xCD, 0x53, + 0x81, 0xAA, 0xA9, 0x48, 0x4D, 0x2B, 0x22, 0xC7, + 0xBE, 0x1B, 0x38, 0x21, 0xA1, 0xFE, 0x23, 0xB4, + 0xAC, 0x66, 0x92, 0x9E, 0xF2, 0x27, 0xDC, 0x23, + 0x70, 0x6E, 0xBA, 0xF9, 0xED, 0x3B, 0xCE, 0x63, + 0xAD, 0x68, 0xF2, 0x80, 0xFA, 0x1B, 0x14, 0xB5, + 0xB4, 0x07, 0xE3, 0x5A, 0x81, 0x74, 0xE1, 0xF2, + }, + .len = 3120 + }, + .auth_tag = { + .data = { + 0xEA, 0xE9, 0x10, 0xB6, 0xB7, 0xAB, 0xEA, 0x90, + 0x8A, 0xD5, 0x63, 0x88, 0xDB, 0x2B, 0x8F, 0x23, + }, + .len = 16 + } +}; + +#endif /* TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_hash_test_vectors.h b/test/test/test_cryptodev_hash_test_vectors.h new file mode 100644 index 0000000000..3214f9a6e7 --- /dev/null +++ b/test/test/test_cryptodev_hash_test_vectors.h @@ -0,0 +1,521 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2016-2017 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_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ + +static const uint8_t plaintext_hash[] = { + "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." +}; + +static const struct blockcipher_test_data +md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB3, 0xE6, 0xBB, 0x50, 0x41, 0x35, 0x3C, 0x6B, + 0x7A, 0xFF, 0xD2, 0x64, 0xAF, 0xD5, 0x1C, 0xB2 + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +hmac_md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD + }, + .len = 16 + }, + .digest = { + .data = { + 0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE, + 0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B + }, + .len = 16, + .truncated_len = 12 + } +}; + +static const struct blockcipher_test_data +sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xA2, 0x8D, 0x40, 0x78, 0xDD, 0x9F, 0xBB, 0xD5, + 0x35, 0x62, 0xFB, 0xFA, 0x93, 0xFD, 0x7D, 0x70, + 0xA6, 0x7D, 0x45, 0xCA + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +hmac_sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .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 = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20, + .truncated_len = 12 + } +}; + +static const struct blockcipher_test_data +sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x91, 0xE7, 0xCD, 0x75, 0x14, 0x9C, 0xA9, 0xE9, + 0x2E, 0x46, 0x12, 0x20, 0x22, 0xF9, 0x68, 0x28, + 0x39, 0x26, 0xDF, 0xB5, 0x78, 0x62, 0xB2, 0x6E, + 0x5E, 0x8F, 0x25, 0x84 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +hmac_sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C + }, + .len = 28 + }, + .digest = { + .data = { + 0x70, 0x0F, 0x04, 0x4D, 0x22, 0x02, 0x7D, 0x31, + 0x36, 0xDA, 0x77, 0x19, 0xB9, 0x66, 0x37, 0x7B, + 0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F, + 0x92, 0xF6, 0xAA, 0x19 + }, + .len = 28, + .truncated_len = 14 + } +}; + +static const struct blockcipher_test_data +sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x7F, 0xF1, 0x0C, 0xF5, 0x90, 0x97, 0x19, 0x0F, + 0x00, 0xE4, 0x83, 0x01, 0xCA, 0x59, 0x00, 0x2E, + 0x1F, 0xC7, 0x84, 0xEE, 0x76, 0xA6, 0x39, 0x15, + 0x76, 0x2F, 0x87, 0xF9, 0x01, 0x06, 0xF3, 0xB7 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +hmac_sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC + }, + .len = 32 + }, + .digest = { + .data = { + 0xAF, 0x8F, 0x70, 0x1B, 0x4B, 0xAF, 0x34, 0xCB, + 0x02, 0x24, 0x48, 0x45, 0x83, 0x52, 0x8F, 0x22, + 0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77, + 0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17 + }, + .len = 32, + .truncated_len = 16 + } +}; + +static const struct blockcipher_test_data +sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x1D, 0xE7, 0x3F, 0x55, 0x86, 0xFE, 0x48, 0x9F, + 0xAC, 0xC6, 0x85, 0x32, 0xFA, 0x8E, 0xA6, 0x77, + 0x25, 0x84, 0xA5, 0x98, 0x8D, 0x0B, 0x80, 0xF4, + 0xEB, 0x2C, 0xFB, 0x6C, 0xEA, 0x7B, 0xFD, 0xD5, + 0xAD, 0x41, 0xAB, 0x15, 0xB0, 0x03, 0x15, 0xEC, + 0x9E, 0x3D, 0xED, 0xCB, 0x80, 0x7B, 0xF4, 0xB6 + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +hmac_sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89 + }, + .len = 48 + }, + .digest = { + .data = { + 0xE2, 0x83, 0x18, 0x55, 0xB5, 0x8D, 0x94, 0x9B, + 0x01, 0xB6, 0xE2, 0x57, 0x7A, 0x62, 0xF5, 0xF4, + 0xAB, 0x39, 0xF3, 0x3C, 0x28, 0xA0, 0x0F, 0xCC, + 0xEE, 0x1C, 0xF1, 0xF8, 0x69, 0xF1, 0x24, 0x3B, + 0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0, + 0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E + }, + .len = 48, + .truncated_len = 24 + } +}; + +static const struct blockcipher_test_data +sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB9, 0xBA, 0x28, 0x48, 0x3C, 0xC2, 0xD3, 0x65, + 0x4A, 0xD6, 0x00, 0x1D, 0xCE, 0x61, 0x64, 0x54, + 0x45, 0x8C, 0x64, 0x0E, 0xED, 0x0E, 0xD8, 0x1C, + 0x72, 0xCE, 0xD2, 0x44, 0x91, 0xC8, 0xEB, 0xC7, + 0x99, 0xC5, 0xCA, 0x89, 0x72, 0x64, 0x96, 0x41, + 0xC8, 0xEA, 0xB2, 0x4E, 0xD1, 0x21, 0x13, 0x49, + 0x64, 0x4E, 0x15, 0x68, 0x12, 0x67, 0x26, 0x0F, + 0x2C, 0x3C, 0x83, 0x25, 0x27, 0x86, 0xF0, 0xDB + }, + .len = 64 + } +}; + +static const struct blockcipher_test_data +hmac_sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89, + 0xDE, 0xAA, 0x36, 0x44, 0x98, 0x93, 0x97, 0x1E, + 0x6D, 0x53, 0x83, 0x87, 0xB3, 0xB7, 0x56, 0x41 + }, + .len = 64 + }, + .digest = { + .data = { + 0xB8, 0x0B, 0x35, 0x97, 0x3F, 0x24, 0x3F, 0x05, + 0x2A, 0x7F, 0x2F, 0xD8, 0xD7, 0x56, 0x58, 0xAD, + 0x6F, 0x8D, 0x1F, 0x4C, 0x30, 0xF9, 0xA8, 0x29, + 0x7A, 0xE0, 0x8D, 0x88, 0xF5, 0x2E, 0x94, 0xF5, + 0x06, 0xF7, 0x5D, 0x57, 0x32, 0xA8, 0x49, 0x29, + 0xEA, 0x6B, 0x6D, 0x95, 0xBD, 0x76, 0xF5, 0x79, + 0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87, + 0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20 + }, + .len = 64, + .truncated_len = 32 + } +}; + +static const struct blockcipher_test_case hash_test_cases[] = { + { + .test_descr = "MD5 Digest", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "MD5 Digest Verify", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "HMAC-MD5 Digest", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "HMAC-MD5 Digest Verify", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "SHA1 Digest", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "SHA1 Digest Verify", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "HMAC-SHA1 Digest", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "HMAC-SHA1 Digest Verify", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "SHA224 Digest", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "SHA224 Digest Verify", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "HMAC-SHA224 Digest", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "HMAC-SHA224 Digest Verify", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "SHA256 Digest", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "SHA256 Digest Verify", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "HMAC-SHA256 Digest", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "HMAC-SHA256 Digest Verify", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "SHA384 Digest", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "SHA384 Digest Verify", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "HMAC-SHA384 Digest", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "HMAC-SHA384 Digest Verify", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "SHA512 Digest", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "SHA512 Digest Verify", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL + }, + { + .test_descr = "HMAC-SHA512 Digest", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, + { + .test_descr = "HMAC-SHA512 Digest Verify", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER + }, +}; + +#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_hmac_test_vectors.h b/test/test/test_cryptodev_hmac_test_vectors.h new file mode 100644 index 0000000000..d30215fda8 --- /dev/null +++ b/test/test/test_cryptodev_hmac_test_vectors.h @@ -0,0 +1,121 @@ +/*- + * 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 APP_TEST_TEST_CRYPTODEV_HMAC_TEST_VECTORS_H_ +#define APP_TEST_TEST_CRYPTODEV_HMAC_TEST_VECTORS_H_ + +/* *** MD5 test vectors *** */ + +#define MD5_DIGEST_LEN 16 + +struct HMAC_MD5_vector { + struct { + uint8_t data[64]; + uint16_t len; + } key; + + struct { + uint8_t data[1024]; + uint16_t len; + } plaintext; + + struct { + uint8_t data[16]; + uint16_t len; + } auth_tag; +}; + +static const struct +HMAC_MD5_vector HMAC_MD5_test_case_1 = { + .key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD + }, + .len = 16 + }, + .plaintext = { + .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_tag = { + .data = { + 0x67, 0x83, 0xE1, 0x0F, 0xB0, 0xBF, 0x33, 0x49, + 0x22, 0x04, 0x89, 0xDF, 0x86, 0xD0, 0x5F, 0x0C + }, + .len = MD5_DIGEST_LEN + } +}; + +static const struct +HMAC_MD5_vector HMAC_MD5_test_case_2 = { + .key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD + }, + .len = 32 + }, + .plaintext = { + .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_tag = { + .data = { + 0x39, 0x24, 0x70, 0x7A, 0x30, 0x38, 0x1E, 0x2B, + 0x9F, 0x6B, 0xD9, 0x3C, 0xAD, 0xC2, 0x73, 0x52 + }, + .len = MD5_DIGEST_LEN + } +}; + +#endif /* APP_TEST_TEST_CRYPTODEV_HMAC_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_kasumi_hash_test_vectors.h b/test/test/test_cryptodev_kasumi_hash_test_vectors.h new file mode 100644 index 0000000000..69742faaa0 --- /dev/null +++ b/test/test/test_cryptodev_kasumi_hash_test_vectors.h @@ -0,0 +1,337 @@ +/*- + * 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 + } +}; + +struct kasumi_hash_test_data kasumi_hash_test_case_6 = { + .key = { + .data = { + 0x83, 0xFD, 0x23, 0xA2, 0x44, 0xA7, 0x4C, 0xF3, + 0x58, 0xDA, 0x30, 0x19, 0xF1, 0x72, 0x26, 0x35 + }, + .len = 16 + }, + .aad = { + .data = { + 0x36, 0xAF, 0x61, 0x44, 0x4F, 0x30, 0x2A, 0xD2 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x35, 0xC6, 0x87, 0x16, 0x63, 0x3C, 0x66, 0xFB, + 0x75, 0x0C, 0x26, 0x68, 0x65, 0xD5, 0x3C, 0x11, + 0xEA, 0x05, 0xB1, 0xE9, 0xFA, 0x49, 0xC8, 0x39, + 0x8D, 0x48, 0xE1, 0xEF, 0xA5, 0x90, 0x9D, 0x39, + 0x47, 0x90, 0x28, 0x37, 0xF5, 0xAE, 0x96, 0xD5, + 0xA0, 0x5B, 0xC8, 0xD6, 0x1C, 0xA8, 0xDB, 0xEF, + 0x1B, 0x13, 0xA4, 0xB4, 0xAB, 0xFE, 0x4F, 0xB1, + 0x00, 0x60, 0x45, 0xB6, 0x74, 0xBB, 0x54, 0x72, + 0x93, 0x04, 0xC3, 0x82, 0xBE, 0x53, 0xA5, 0xAF, + 0x05, 0x55, 0x61, 0x76, 0xF6, 0xEA, 0xA2, 0xEF, + 0x1D, 0x05, 0xE4, 0xB0, 0x83, 0x18, 0x1E, 0xE6, + 0x74, 0xCD, 0xA5, 0xA4, 0x85, 0xF7, 0x4D, 0x7A, + 0xC0 + }, + .len = 776 + }, + .validAuthLenInBits = { + .len = 768 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0x95, 0xAE, 0x41, 0xBA}, + .len = 4 + } +}; + +struct kasumi_hash_test_data kasumi_hash_test_case_7 = { + .key = { + .data = { + 0x5A, 0xCB, 0x1D, 0x64, 0x4C, 0x0D, 0x51, 0x20, + 0x4E, 0xA5, 0xF1, 0x45, 0x10, 0x10, 0xD8, 0x52 + }, + .len = 16 + }, + .aad = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + }, + .len = 8 + }, + .plaintext = { + .data = { + 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, + 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 + }, + .len = 128 + }, + .validAuthLenInBits = { + .len = 120 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0x87, 0x5F, 0xE4, 0x89}, + .len = 4 + } +}; +#endif /* TEST_CRYPTODEV_KASUMI_HASH_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_kasumi_test_vectors.h b/test/test/test_cryptodev_kasumi_test_vectors.h new file mode 100644 index 0000000000..ef1dc6f32e --- /dev/null +++ b/test/test/test_cryptodev_kasumi_test_vectors.h @@ -0,0 +1,407 @@ +/*- + * 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; + + /* Includes: COUNT (4 bytes) and FRESH (4 bytes) */ + struct { + uint8_t data[8]; + unsigned len; + } aad; + + struct { + uint8_t data[1024]; /* Data may include direction bit */ + unsigned len; /* length must be in Bits */ + } plaintext; + + struct { + unsigned len; + } validDataLenInBits; + + struct { + uint8_t data[1024]; + unsigned len; /* length must be in Bits */ + } ciphertext; + + struct { + unsigned len; + } validCipherLenInBits; + + struct { + unsigned len; + } validCipherOffsetLenInBits; + + /* 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_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 + }, + .aad = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, + 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 + }, + .len = 128 + }, + .ciphertext = { + .data = { + 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, + 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25 + }, + .len = 120 + }, + .validDataLenInBits = { + .len = 128 + }, + .validCipherLenInBits = { + .len = 120 + }, + .validCipherOffsetLenInBits = { + .len = 64 + }, + .validAuthLenInBits = { + .len = 120 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0x87, 0x5F, 0xE4, 0x89}, + .len = 4 + } +}; + +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 + }, +}; + +struct kasumi_test_data kasumi_test_case_6 = { + .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 + }, + .aad = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, + 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 + }, + .len = 128 + }, + .ciphertext = { + .data = { + 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, + 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25 + }, + .len = 120 + }, + .validDataLenInBits = { + .len = 128 + }, + .validCipherLenInBits = { + .len = 120 + }, + .validCipherOffsetLenInBits = { + .len = 64 + }, + .validAuthLenInBits = { + .len = 120 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0x0F, 0xD2, 0xAA, 0xB5}, + .len = 4 + } +}; + +#endif /* TEST_CRYPTODEV_KASUMI_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_perf.c b/test/test/test_cryptodev_perf.c new file mode 100644 index 0000000000..7f1adf874d --- /dev/null +++ b/test/test/test_cryptodev_perf.c @@ -0,0 +1,4797 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include + +#include "test.h" +#include "test_cryptodev.h" +#include "test_cryptodev_gcm_test_vectors.h" + + +#define PERF_NUM_OPS_INFLIGHT (128) +#define DEFAULT_NUM_REQS_TO_SUBMIT (10000000) + +struct crypto_testsuite_params { + struct rte_mempool *mbuf_mp; + struct rte_mempool *op_mpool; + + uint16_t nb_queue_pairs; + + struct rte_cryptodev_config conf; + struct rte_cryptodev_qp_conf qp_conf; + uint8_t dev_id; +}; + +enum chain_mode { + CIPHER_HASH, + HASH_CIPHER, + CIPHER_ONLY, + HASH_ONLY +}; + + +struct symmetric_op { + const uint8_t *iv_data; + uint32_t iv_len; + + const uint8_t *aad_data; + uint32_t aad_len; + + const uint8_t *p_data; + uint32_t p_len; + + const uint8_t *c_data; + uint32_t c_len; + + const uint8_t *t_data; + uint32_t t_len; + +}; + +struct symmetric_session_attrs { + enum rte_crypto_cipher_operation cipher; + enum rte_crypto_auth_operation auth; + + enum rte_crypto_cipher_algorithm cipher_algorithm; + const uint8_t *key_cipher_data; + uint32_t key_cipher_len; + + enum rte_crypto_auth_algorithm auth_algorithm; + const uint8_t *key_auth_data; + uint32_t key_auth_len; + + uint32_t digest_len; +}; + +#define ALIGN_POW2_ROUNDUP(num, align) \ + (((num) + (align) - 1) & ~((align) - 1)) + +/* + * This struct is needed to avoid unnecessary allocation or checking + * of allocation of crypto params with current alloc on the fly + * implementation. + */ + +struct crypto_params { + uint8_t *aad; + uint8_t *iv; + uint8_t *digest; +}; + +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; + + struct symmetric_session_attrs *session_attrs; + + struct symmetric_op *symmetric_op; +}; + +#define MAX_NUM_OF_OPS_PER_UT (128) + +struct crypto_unittest_params { + struct rte_crypto_sym_xform cipher_xform; + struct rte_crypto_sym_xform auth_xform; + + struct rte_cryptodev_sym_session *sess; + + struct rte_crypto_op *op; + + struct rte_mbuf *obuf[MAX_NUM_OF_OPS_PER_UT]; + struct rte_mbuf *ibuf[MAX_NUM_OF_OPS_PER_UT]; + + 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 int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo); +static struct rte_cryptodev_sym_session * +test_perf_create_openssl_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo); +static struct rte_cryptodev_sym_session * +test_perf_create_armv8_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int 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 inline struct rte_crypto_op * +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len, enum chain_mode chain); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len, enum chain_mode chain __rte_unused); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len, enum chain_mode chain __rte_unused); +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 RTE_STR(CRYPTODEV_NAME_NULL_PMD); break; + case RTE_CRYPTODEV_AESNI_GCM_PMD: + return RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD); + case RTE_CRYPTODEV_AESNI_MB_PMD: + return RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD); + case RTE_CRYPTODEV_QAT_SYM_PMD: + return RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD); + case RTE_CRYPTODEV_SNOW3G_PMD: + return RTE_STR(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) +{ + struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); + size_t t_len = len - (blocksize ? (len % blocksize) : 0); + + if (m) { + char *dst = rte_pktmbuf_append(m, t_len); + + if (!dst) { + rte_pktmbuf_free(m); + return NULL; + } + + rte_memcpy(dst, (const void *)data, t_len); + } + return m; +} + +static struct crypto_testsuite_params testsuite_params = { NULL }; +static struct crypto_unittest_params unittest_params; +static enum rte_cryptodev_type gbl_cryptodev_perftest_devtype; + +static int +testsuite_setup(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info info; + unsigned i, nb_devs, valid_dev_id = 0; + int ret; + uint16_t qp_id; + + ts_params->mbuf_mp = rte_mempool_lookup("CRYPTO_PERF_MBUFPOOL"); + if (ts_params->mbuf_mp == NULL) { + /* Not already created so create */ + ts_params->mbuf_mp = rte_pktmbuf_pool_create( + "CRYPTO_PERF_MBUFPOOL", + NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, + rte_socket_id()); + if (ts_params->mbuf_mp == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_PERF_MBUFPOOL\n"); + return TEST_FAILED; + } + } + + + ts_params->op_mpool = rte_crypto_op_pool_create("CRYPTO_OP_POOL", + RTE_CRYPTO_OP_TYPE_SYMMETRIC, + NUM_MBUFS, MBUF_CACHE_SIZE, + DEFAULT_NUM_XFORMS * + sizeof(struct rte_crypto_sym_xform), + rte_socket_id()); + if (ts_params->op_mpool == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); + return TEST_FAILED; + } + + /* Create 2 AESNI MB devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_AESNI_MB_PMD) { +#ifndef RTE_LIBRTE_PMD_AESNI_MB + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_MB must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_AESNI_MB_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + } + } + } + + /* Create 2 AESNI GCM devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_AESNI_GCM_PMD) { +#ifndef RTE_LIBRTE_PMD_AESNI_GCM + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_GCM must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_AESNI_GCM_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD)); + } + } + } + + /* Create 2 SNOW3G devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_SNOW3G_PMD) { +#ifndef RTE_LIBRTE_PMD_SNOW3G + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_SNOW3G must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + 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( + RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD)); + } + } + } + + /* Create 2 OPENSSL devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_OPENSSL_PMD) { +#ifndef RTE_LIBRTE_PMD_OPENSSL + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_OPENSSL must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_OPENSSL_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + } + } + } + + /* Create 2 ARMv8 devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_ARMV8_PMD) { +#ifndef RTE_LIBRTE_PMD_ARMV8_CRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_ARMV8_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); + } + } + } + +#ifndef RTE_LIBRTE_PMD_QAT + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_QAT_SYM_PMD) { + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " + "in config file to run this testsuite.\n"); + return TEST_FAILED; + } +#endif + + nb_devs = rte_cryptodev_count(); + if (nb_devs < 1) { + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); + return TEST_FAILED; + } + + /* Search for the first valid */ + for (i = 0; i < nb_devs; i++) { + rte_cryptodev_info_get(i, &info); + if (info.dev_type == gbl_cryptodev_perftest_devtype) { + ts_params->dev_id = i; + valid_dev_id = 1; + break; + } + } + + if (!valid_dev_id) + return TEST_FAILED; + + /* + * Using Crypto Device Id 0 by default. + * Set up all the qps on this device + */ + + rte_cryptodev_info_get(ts_params->dev_id, &info); + + ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs; + ts_params->conf.socket_id = SOCKET_ID_ANY; + ts_params->conf.session_mp.nb_objs = info.sym.max_nb_sessions; + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->dev_id, + &ts_params->conf), + "Failed to configure cryptodev %u", + ts_params->dev_id); + + ts_params->qp_conf.nb_descriptors = PERF_NUM_OPS_INFLIGHT; + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs ; qp_id++) { + + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + ts_params->dev_id, qp_id, + &ts_params->qp_conf, + rte_cryptodev_socket_id(ts_params->dev_id)), + "Failed to setup queue pair %u on cryptodev %u", + qp_id, ts_params->dev_id); + } + + return TEST_SUCCESS; +} +static void +testsuite_teardown(void) +{ + struct crypto_testsuite_params *ts_params = + &testsuite_params; + + if (ts_params->mbuf_mp != NULL) + RTE_LOG(DEBUG, USER1, "CRYPTO_PERF_MBUFPOOL count %u\n", + 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 +ut_setup(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + /* Clear unit test parameters before running test */ + memset(ut_params, 0, sizeof(*ut_params)); + + rte_cryptodev_stats_reset(ts_params->dev_id); + + /* Start the device */ + TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->dev_id), + "Failed to start cryptodev %u", + ts_params->dev_id); + + return TEST_SUCCESS; +} + +static void +ut_teardown(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + struct rte_cryptodev_stats stats; + + unsigned i; + + /* free crypto session structure */ + if (ut_params->sess) + rte_cryptodev_sym_session_free(ts_params->dev_id, + ut_params->sess); + + /* free crypto operation structure */ + if (ut_params->op) + rte_crypto_op_free(ut_params->op); + + for (i = 0; i < MAX_NUM_OF_OPS_PER_UT; i++) { + if (ut_params->obuf[i]) + rte_pktmbuf_free(ut_params->obuf[i]); + else if (ut_params->ibuf[i]) + rte_pktmbuf_free(ut_params->ibuf[i]); + } + + if (ts_params->mbuf_mp != NULL) + RTE_LOG(DEBUG, USER1, "CRYPTO_PERF_MBUFPOOL count %u\n", + rte_mempool_avail_count(ts_params->mbuf_mp)); + + rte_cryptodev_stats_get(ts_params->dev_id, &stats); + + /* Stop the device */ + rte_cryptodev_stop(ts_params->dev_id); +} + +const char plaintext_quote[] = + "THE COUNT OF MONTE CRISTO by Alexandre Dumas, Pere Chapter 1. " + "Marseilles--The Arrival. On the 24th of February, 1815, the " + "look-out at Notre-Dame de la Garde signalled the three-master," + " the Pharaon from Smyrna, Trieste, and Naples. As usual, a " + "pilot put off immediately, and rounding the Chateau d'If, got " + "on board the vessel between Cape Morgion and Rion island. " + "Immediately, and according to custom, the ramparts of Fort " + "Saint-Jean were covered with spectators; it is always an event " + "at Marseilles for a ship to come into port, especially when " + "this ship, like the Pharaon, has been built, rigged, and laden" + " at the old Phocee docks, and belongs to an owner of the city." + " The ship drew on and had safely passed the strait, which some" + " volcanic shock has made between the Calasareigne and Jaros " + "islands; had doubled Pomegue, and approached the harbor under" + " topsails, jib, and spanker, but so slowly and sedately that" + " the idlers, with that instinct which is the forerunner of " + "evil, asked one another what misfortune could have happened " + "on board. However, those experienced in navigation saw plainly" + " that if any accident had occurred, it was not to the vessel " + "herself, for she bore down with all the evidence of being " + "skilfully handled, the anchor a-cockbill, the jib-boom guys " + "already eased off, and standing by the side of the pilot, who" + " was steering the Pharaon towards the narrow entrance of the" + " inner port, was a young man, who, with activity and vigilant" + " eye, watched every motion of the ship, and repeated each " + "direction of the pilot. The vague disquietude which prevailed " + "among the spectators had so much affected one of the crowd " + "that he did not await the arrival of the vessel in harbor, but" + " jumping into a small skiff, desired to be pulled alongside " + "the Pharaon, which he reached as she rounded into La Reserve " + "basin. When the young man on board saw this person approach, " + "he left his station by the pilot, and, hat in hand, leaned " + "over the ship's bulwarks. He was a fine, tall, slim young " + "fellow of eighteen or twenty, with black eyes, and hair as " + "dark as a raven's wing; and his whole appearance bespoke that " + "calmness and resolution peculiar to men accustomed from their " + "cradle to contend with danger. \"Ah, is it you, Dantes?\" " + "cried the man in the skiff. \"What's the matter? and why have " + "you such an air of sadness aboard?\" \"A great misfortune, M. " + "Morrel,\" replied the young man,--\"a great misfortune, for me" + " especially! Off Civita Vecchia we lost our brave Captain " + "Leclere.\" \"And the cargo?\" inquired the owner, eagerly. " + "\"Is all safe, M. Morrel; and I think you will be satisfied on" + " that head. But poor Captain Leclere--\" \"What happened to " + "him?\" asked the owner, with an air of considerable " + "resignation. \"What happened to the worthy captain?\" \"He " + "died.\" \"Fell into the sea?\" \"No, sir, he died of " + "brain-fever in dreadful agony.\" Then turning to the crew, " + "he said, \"Bear a hand there, to take in sail!\" All hands " + "obeyed, and at once the eight or ten seamen who composed the " + "crew, sprang to their respective stations at the spanker " + "brails and outhaul, topsail sheets and halyards, the jib " + "downhaul, and the topsail clewlines and buntlines. The young " + "sailor gave a look to see that his orders were promptly and " + "accurately obeyed, and then turned again to the owner. \"And " + "how did this misfortune occur?\" inquired the latter, resuming" + " the interrupted conversation. \"Alas, sir, in the most " + "unexpected manner. After a long talk with the harbor-master, " + "Captain Leclere left Naples greatly disturbed in mind. In " + "twenty-four hours he was attacked by a fever, and died three " + "days afterwards. We performed the usual burial service, and he" + " is at his rest, sewn up in his hammock with a thirty-six " + "pound shot at his head and his heels, off El Giglio island. " + "We bring to his widow his sword and cross of honor. It was " + "worth while, truly,\" added the young man with a melancholy " + "smile, \"to make war against the English for ten years, and " + "to die in his bed at last, like everybody else."; + +#define QUOTE_LEN_64B (64) +#define QUOTE_LEN_128B (128) +#define QUOTE_LEN_256B (256) +#define QUOTE_LEN_512B (512) +#define QUOTE_LEN_768B (768) +#define QUOTE_LEN_1024B (1024) +#define QUOTE_LEN_1280B (1280) +#define QUOTE_LEN_1536B (1536) +#define QUOTE_LEN_1792B (1792) +#define QUOTE_LEN_2048B (2048) + + +/* ***** AES-CBC / HMAC-SHA256 Performance Tests ***** */ + +#define HMAC_KEY_LENGTH_SHA256 (DIGEST_BYTE_LENGTH_SHA256) + +#define CIPHER_KEY_LENGTH_AES_CBC (16) +#define CIPHER_IV_LENGTH_AES_CBC (CIPHER_KEY_LENGTH_AES_CBC) + +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_128_iv[] = { + 0xf5, 0xd3, 0x89, 0x0f, 0x47, 0x00, 0xcb, 0x52, + 0x42, 0x1a, 0x7d, 0x3d, 0xf5, 0x82, 0x80, 0xf1 }; + +static uint8_t hmac_sha256_key[] = { + 0xff, 0xcb, 0x37, 0x30, 0x1d, 0x4a, 0xc2, 0x41, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x9a, 0x4f, 0x88, 0x1b, 0xb6, 0x8f, 0xd8, 0x60 }; + + +/* Cipher text output */ + +static const uint8_t AES_CBC_ciphertext_64B[] = { + 0x05, 0x15, 0x77, 0x32, 0xc9, 0x66, 0x91, 0x50, + 0x93, 0x9f, 0xbb, 0x4e, 0x2e, 0x5a, 0x02, 0xd0, + 0x2d, 0x9d, 0x31, 0x5d, 0xc8, 0x9e, 0x86, 0x36, + 0x54, 0x5c, 0x50, 0xe8, 0x75, 0x54, 0x74, 0x5e, + 0xd5, 0xa2, 0x84, 0x21, 0x2d, 0xc5, 0xf8, 0x1c, + 0x55, 0x1a, 0xba, 0x91, 0xce, 0xb5, 0xa3, 0x1e, + 0x31, 0xbf, 0xe9, 0xa1, 0x97, 0x5c, 0x2b, 0xd6, + 0x57, 0xa5, 0x9f, 0xab, 0xbd, 0xb0, 0x9b, 0x9c +}; + +static const uint8_t AES_CBC_ciphertext_128B[] = { + 0x79, 0x92, 0x65, 0xc8, 0xfb, 0x0a, 0xc7, 0xc4, + 0x9b, 0x3b, 0xbe, 0x69, 0x7f, 0x7c, 0xf4, 0x4e, + 0xa5, 0x0d, 0xf6, 0x33, 0xc4, 0xdf, 0xf3, 0x0d, + 0xdb, 0xb9, 0x68, 0x34, 0xb0, 0x0d, 0xbd, 0xb9, + 0xa7, 0xf3, 0x86, 0x50, 0x2a, 0xbe, 0x50, 0x5d, + 0xb3, 0xbe, 0x72, 0xf9, 0x02, 0xb1, 0x69, 0x0b, + 0x8c, 0x96, 0x4c, 0x3c, 0x0c, 0x1e, 0x76, 0xe5, + 0x7e, 0x75, 0xdd, 0xd0, 0xa9, 0x75, 0x00, 0x13, + 0x6b, 0x1e, 0xc0, 0xad, 0xfc, 0x03, 0xb5, 0x99, + 0xdc, 0x37, 0x35, 0xfc, 0x16, 0x34, 0xfd, 0xb4, + 0xea, 0x1e, 0xb6, 0x51, 0xdf, 0xab, 0x87, 0xd6, + 0x87, 0x41, 0xfa, 0x1c, 0xc6, 0x78, 0xa6, 0x3c, + 0x1d, 0x76, 0xfe, 0xff, 0x65, 0xfc, 0x63, 0x1e, + 0x1f, 0xe2, 0x7c, 0x9b, 0xa2, 0x72, 0xc3, 0x34, + 0x23, 0xdf, 0x01, 0xf0, 0xfd, 0x02, 0x8b, 0x97, + 0x00, 0x2b, 0x97, 0x4e, 0xab, 0x98, 0x21, 0x3c +}; + +static const uint8_t AES_CBC_ciphertext_256B[] = { + 0xc7, 0x71, 0x2b, 0xed, 0x2c, 0x97, 0x59, 0xfa, + 0xcf, 0x5a, 0xb9, 0x31, 0x92, 0xe0, 0xc9, 0x92, + 0xc0, 0x2d, 0xd5, 0x9c, 0x84, 0xbf, 0x70, 0x36, + 0x13, 0x48, 0xe0, 0xb1, 0xbf, 0x6c, 0xcd, 0x91, + 0xa0, 0xc3, 0x57, 0x6c, 0x3f, 0x0e, 0x34, 0x41, + 0xe7, 0x9c, 0xc0, 0xec, 0x18, 0x0c, 0x05, 0x52, + 0x78, 0xe2, 0x3c, 0x6e, 0xdf, 0xa5, 0x49, 0xc7, + 0xf2, 0x55, 0x00, 0x8f, 0x65, 0x6d, 0x4b, 0xd0, + 0xcb, 0xd4, 0xd2, 0x0b, 0xea, 0xf4, 0xb0, 0x85, + 0x61, 0x9e, 0x36, 0xc0, 0x71, 0xb7, 0x80, 0xad, + 0x40, 0x78, 0xb4, 0x70, 0x2b, 0xe8, 0x80, 0xc5, + 0x19, 0x35, 0x96, 0x55, 0x3b, 0x40, 0x03, 0xbb, + 0x9f, 0xa6, 0xc2, 0x82, 0x92, 0x04, 0xc3, 0xa6, + 0x96, 0xc4, 0x7f, 0x4c, 0x3e, 0x3c, 0x79, 0x82, + 0x88, 0x8b, 0x3f, 0x8b, 0xc5, 0x9f, 0x44, 0xbe, + 0x71, 0xe7, 0x09, 0xa2, 0x40, 0xa2, 0x23, 0x4e, + 0x9f, 0x31, 0xab, 0x6f, 0xdf, 0x59, 0x40, 0xe1, + 0x12, 0x15, 0x55, 0x4b, 0xea, 0x3f, 0xa1, 0x41, + 0x4f, 0xaf, 0xcd, 0x27, 0x2a, 0x61, 0xa1, 0x9e, + 0x82, 0x30, 0x05, 0x05, 0x55, 0xce, 0x99, 0xd3, + 0x8f, 0x3f, 0x86, 0x79, 0xdc, 0x9f, 0x33, 0x07, + 0x75, 0x26, 0xc8, 0x72, 0x81, 0x0f, 0x9b, 0xf7, + 0xb1, 0xfb, 0xd3, 0x91, 0x36, 0x08, 0xab, 0x26, + 0x70, 0x53, 0x0c, 0x99, 0xfd, 0xa9, 0x07, 0xb4, + 0xe9, 0xce, 0xc1, 0xd6, 0xd2, 0x2c, 0x71, 0x80, + 0xec, 0x59, 0x61, 0x0b, 0x24, 0xf0, 0x6d, 0x33, + 0x73, 0x45, 0x6e, 0x80, 0x03, 0x45, 0xf2, 0x76, + 0xa5, 0x8a, 0xc9, 0xcf, 0xaf, 0x4a, 0xed, 0x35, + 0xc0, 0x97, 0x52, 0xc5, 0x00, 0xdf, 0xef, 0xc7, + 0x9f, 0xf2, 0xe8, 0x15, 0x3e, 0xb3, 0x30, 0xe7, + 0x00, 0xd0, 0x4e, 0xeb, 0x79, 0xf6, 0xf6, 0xcf, + 0xf0, 0xe7, 0x61, 0xd5, 0x3d, 0x6a, 0x73, 0x9d +}; + +static const uint8_t AES_CBC_ciphertext_512B[] = { + 0xb4, 0xc6, 0xc6, 0x5f, 0x7e, 0xca, 0x05, 0x70, + 0x21, 0x7b, 0x92, 0x9e, 0x23, 0xe7, 0x92, 0xb8, + 0x27, 0x3d, 0x20, 0x29, 0x57, 0xfa, 0x1f, 0x26, + 0x0a, 0x04, 0x34, 0xa6, 0xf2, 0xdc, 0x44, 0xb6, + 0x43, 0x40, 0x62, 0xde, 0x0c, 0xde, 0x1c, 0x30, + 0x43, 0x85, 0x0b, 0xe8, 0x93, 0x1f, 0xa1, 0x2a, + 0x8a, 0x27, 0x35, 0x39, 0x14, 0x9f, 0x37, 0x64, + 0x59, 0xb5, 0x0e, 0x96, 0x82, 0x5d, 0x63, 0x45, + 0xd6, 0x93, 0x89, 0x46, 0xe4, 0x71, 0x31, 0xeb, + 0x0e, 0xd1, 0x7b, 0xda, 0x90, 0xb5, 0x81, 0xac, + 0x76, 0x54, 0x54, 0x85, 0x0b, 0xa9, 0x46, 0x9c, + 0xf0, 0xfd, 0xde, 0x5d, 0xa8, 0xe3, 0xee, 0xe9, + 0xf4, 0x9d, 0x34, 0x76, 0x39, 0xe7, 0xc3, 0x4a, + 0x84, 0x38, 0x92, 0x61, 0xf1, 0x12, 0x9f, 0x05, + 0xda, 0xdb, 0xc1, 0xd4, 0xb0, 0xa0, 0x27, 0x19, + 0xa0, 0x56, 0x5d, 0x9b, 0xcc, 0x47, 0x7c, 0x15, + 0x1d, 0x52, 0x66, 0xd5, 0xff, 0xef, 0x12, 0x23, + 0x86, 0xe2, 0xee, 0x81, 0x2c, 0x3d, 0x7d, 0x28, + 0xd5, 0x42, 0xdf, 0xdb, 0x75, 0x1c, 0xeb, 0xdf, + 0x13, 0x23, 0xd5, 0x17, 0x89, 0xea, 0xd7, 0x01, + 0xff, 0x57, 0x6a, 0x44, 0x61, 0xf4, 0xea, 0xbe, + 0x97, 0x9b, 0xc2, 0xb1, 0x9c, 0x5d, 0xff, 0x4f, + 0x73, 0x2d, 0x3f, 0x57, 0x28, 0x38, 0xbf, 0x3d, + 0x9f, 0xda, 0x49, 0x55, 0x8f, 0xb2, 0x77, 0xec, + 0x0f, 0xbc, 0xce, 0xb8, 0xc6, 0xe1, 0x03, 0xed, + 0x35, 0x9c, 0xf2, 0x4d, 0xa4, 0x29, 0x6c, 0xd6, + 0x6e, 0x05, 0x53, 0x46, 0xc1, 0x41, 0x09, 0x36, + 0x0b, 0x7d, 0xf4, 0x9e, 0x0f, 0xba, 0x86, 0x33, + 0xdd, 0xf1, 0xa7, 0xf7, 0xd5, 0x29, 0xa8, 0xa7, + 0x4d, 0xce, 0x0c, 0xf5, 0xb4, 0x6c, 0xd8, 0x27, + 0xb0, 0x87, 0x2a, 0x6f, 0x7f, 0x3f, 0x8f, 0xc3, + 0xe2, 0x3e, 0x94, 0xcf, 0x61, 0x4a, 0x09, 0x3d, + 0xf9, 0x55, 0x19, 0x31, 0xf2, 0xd2, 0x4a, 0x3e, + 0xc1, 0xf5, 0xed, 0x7c, 0x45, 0xb0, 0x0c, 0x7b, + 0xdd, 0xa6, 0x0a, 0x26, 0x66, 0xec, 0x85, 0x49, + 0x00, 0x38, 0x05, 0x7c, 0x9c, 0x1c, 0x92, 0xf5, + 0xf7, 0xdb, 0x5d, 0xbd, 0x61, 0x0c, 0xc9, 0xaf, + 0xfd, 0x57, 0x3f, 0xee, 0x2b, 0xad, 0x73, 0xef, + 0xa3, 0xc1, 0x66, 0x26, 0x44, 0x5e, 0xf9, 0x12, + 0x86, 0x66, 0xa9, 0x61, 0x75, 0xa1, 0xbc, 0x40, + 0x7f, 0xa8, 0x08, 0x02, 0xc0, 0x76, 0x0e, 0x76, + 0xb3, 0x26, 0x3d, 0x1c, 0x40, 0x65, 0xe4, 0x18, + 0x0f, 0x62, 0x17, 0x8f, 0x1e, 0x61, 0xb8, 0x08, + 0x83, 0x54, 0x42, 0x11, 0x03, 0x30, 0x8e, 0xb7, + 0xc1, 0x9c, 0xec, 0x69, 0x52, 0x95, 0xfb, 0x7b, + 0x1a, 0x0c, 0x20, 0x24, 0xf7, 0xb8, 0x38, 0x0c, + 0xb8, 0x7b, 0xb6, 0x69, 0x70, 0xd0, 0x61, 0xb9, + 0x70, 0x06, 0xc2, 0x5b, 0x20, 0x47, 0xf7, 0xd9, + 0x32, 0xc2, 0xf2, 0x90, 0xb6, 0x4d, 0xcd, 0x3c, + 0x6d, 0x74, 0xea, 0x82, 0x35, 0x1b, 0x08, 0x44, + 0xba, 0xb7, 0x33, 0x82, 0x33, 0x27, 0x54, 0x77, + 0x6e, 0x58, 0xfe, 0x46, 0x5a, 0xb4, 0x88, 0x53, + 0x8d, 0x9b, 0xb1, 0xab, 0xdf, 0x04, 0xe1, 0xfb, + 0xd7, 0x1e, 0xd7, 0x38, 0x64, 0x54, 0xba, 0xb0, + 0x6c, 0x84, 0x7a, 0x0f, 0xa7, 0x80, 0x6b, 0x86, + 0xd9, 0xc9, 0xc6, 0x31, 0x95, 0xfa, 0x8a, 0x2c, + 0x14, 0xe1, 0x85, 0x66, 0x27, 0xfd, 0x63, 0x3e, + 0xf0, 0xfa, 0x81, 0xc9, 0x89, 0x4f, 0xe2, 0x6a, + 0x8c, 0x17, 0xb5, 0xc7, 0x9f, 0x5d, 0x3f, 0x6b, + 0x3f, 0xcd, 0x13, 0x7a, 0x3c, 0xe6, 0x4e, 0xfa, + 0x7a, 0x10, 0xb8, 0x7c, 0x40, 0xec, 0x93, 0x11, + 0x1f, 0xd0, 0x9e, 0xc3, 0x56, 0xb9, 0xf5, 0x21, + 0x18, 0x41, 0x31, 0xea, 0x01, 0x8d, 0xea, 0x1c, + 0x95, 0x5e, 0x56, 0x33, 0xbc, 0x7a, 0x3f, 0x6f +}; + +static const uint8_t AES_CBC_ciphertext_768B[] = { + 0x3e, 0x7f, 0x9e, 0x4c, 0x88, 0x15, 0x68, 0x69, + 0x10, 0x09, 0xe1, 0xa7, 0x0f, 0x27, 0x88, 0x2d, + 0x90, 0x73, 0x4f, 0x67, 0xd3, 0x8b, 0xaf, 0xa1, + 0x2c, 0x37, 0xa5, 0x6c, 0x7c, 0xbd, 0x95, 0x4c, + 0x82, 0xcf, 0x05, 0x49, 0x16, 0x5c, 0xe7, 0x06, + 0xd4, 0xcb, 0x55, 0x65, 0x9a, 0xd0, 0xe1, 0x46, + 0x3a, 0x37, 0x71, 0xad, 0xb0, 0xb4, 0x99, 0x1e, + 0x23, 0x57, 0x48, 0x96, 0x9c, 0xc5, 0xc4, 0xdb, + 0x64, 0x3e, 0xc9, 0x7f, 0x90, 0x5a, 0xa0, 0x08, + 0x75, 0x4c, 0x09, 0x06, 0x31, 0x6e, 0x59, 0x29, + 0xfc, 0x2f, 0x72, 0xde, 0xf2, 0x40, 0x5a, 0xfe, + 0xd3, 0x66, 0x64, 0xb8, 0x9c, 0xc9, 0xa6, 0x1f, + 0xc3, 0x52, 0xcd, 0xb5, 0xd1, 0x4f, 0x43, 0x3f, + 0xf4, 0x59, 0x25, 0xc4, 0xdd, 0x3e, 0x58, 0x7c, + 0x21, 0xd6, 0x21, 0xce, 0xa4, 0xbe, 0x08, 0x23, + 0x46, 0x68, 0xc0, 0x00, 0x91, 0x47, 0xca, 0x9b, + 0xe0, 0xb4, 0xe3, 0xab, 0xbf, 0xcf, 0x68, 0x26, + 0x97, 0x23, 0x09, 0x93, 0x64, 0x8f, 0x57, 0x59, + 0xe2, 0x41, 0x7c, 0xa2, 0x48, 0x7e, 0xd5, 0x2c, + 0x54, 0x09, 0x1b, 0x07, 0x94, 0xca, 0x39, 0x83, + 0xdd, 0xf4, 0x7a, 0x1d, 0x2d, 0xdd, 0x67, 0xf7, + 0x3c, 0x30, 0x89, 0x3e, 0xc1, 0xdc, 0x1d, 0x8f, + 0xfc, 0xb1, 0xe9, 0x13, 0x31, 0xb0, 0x16, 0xdb, + 0x88, 0xf2, 0x32, 0x7e, 0x73, 0xa3, 0xdf, 0x08, + 0x6b, 0x53, 0x92, 0x08, 0xc9, 0x9d, 0x98, 0xb2, + 0xf4, 0x8c, 0xb1, 0x95, 0xdc, 0xb6, 0xfc, 0xec, + 0xf1, 0xc9, 0x0d, 0x6d, 0x42, 0x2c, 0xf5, 0x38, + 0x29, 0xf4, 0xd8, 0x98, 0x0f, 0xb0, 0x81, 0xa5, + 0xaa, 0xe6, 0x1f, 0x6e, 0x87, 0x32, 0x1b, 0x02, + 0x07, 0x57, 0x38, 0x83, 0xf3, 0xe4, 0x54, 0x7c, + 0xa8, 0x43, 0xdf, 0x3f, 0x42, 0xfd, 0x67, 0x28, + 0x06, 0x4d, 0xea, 0xce, 0x1f, 0x84, 0x4a, 0xcd, + 0x8c, 0x61, 0x5e, 0x8f, 0x61, 0xed, 0x84, 0x03, + 0x53, 0x6a, 0x9e, 0xbf, 0x68, 0x83, 0xa7, 0x42, + 0x56, 0x57, 0xcd, 0x45, 0x29, 0xfc, 0x7b, 0x07, + 0xfc, 0xe9, 0xb9, 0x42, 0xfd, 0x29, 0xd5, 0xfd, + 0x98, 0x11, 0xd1, 0x8d, 0x67, 0x29, 0x47, 0x61, + 0xd8, 0x27, 0x37, 0x79, 0x29, 0xd1, 0x94, 0x6f, + 0x8d, 0xf3, 0x1b, 0x3d, 0x6a, 0xb1, 0x59, 0xef, + 0x1b, 0xd4, 0x70, 0x0e, 0xac, 0xab, 0xa0, 0x2b, + 0x1f, 0x5e, 0x04, 0xf0, 0x0e, 0x35, 0x72, 0x90, + 0xfc, 0xcf, 0x86, 0x43, 0xea, 0x45, 0x6d, 0x22, + 0x63, 0x06, 0x1a, 0x58, 0xd7, 0x2d, 0xc5, 0xb0, + 0x60, 0x69, 0xe8, 0x53, 0xc2, 0xa2, 0x57, 0x83, + 0xc4, 0x31, 0xb4, 0xc6, 0xb3, 0xa1, 0x77, 0xb3, + 0x1c, 0xca, 0x89, 0x3f, 0xf5, 0x10, 0x3b, 0x36, + 0x31, 0x7d, 0x00, 0x46, 0x00, 0x92, 0xa0, 0xa0, + 0x34, 0xd8, 0x5e, 0x62, 0xa9, 0xe0, 0x23, 0x37, + 0x50, 0x85, 0xc7, 0x3a, 0x20, 0xa3, 0x98, 0xc0, + 0xac, 0x20, 0x06, 0x0f, 0x17, 0x3c, 0xfc, 0x43, + 0x8c, 0x9d, 0xec, 0xf5, 0x9a, 0x35, 0x96, 0xf7, + 0xb7, 0x4c, 0xf9, 0x69, 0xf8, 0xd4, 0x1e, 0x9e, + 0xf9, 0x7c, 0xc4, 0xd2, 0x11, 0x14, 0x41, 0xb9, + 0x89, 0xd6, 0x07, 0xd2, 0x37, 0x07, 0x5e, 0x5e, + 0xae, 0x60, 0xdc, 0xe4, 0xeb, 0x38, 0x48, 0x6d, + 0x95, 0x8d, 0x71, 0xf2, 0xba, 0xda, 0x5f, 0x08, + 0x9d, 0x4a, 0x0f, 0x56, 0x90, 0x64, 0xab, 0xb6, + 0x88, 0x22, 0xa8, 0x90, 0x1f, 0x76, 0x2c, 0x83, + 0x43, 0xce, 0x32, 0x55, 0x45, 0x84, 0x57, 0x43, + 0xf9, 0xa8, 0xd1, 0x4f, 0xe3, 0xc1, 0x72, 0x9c, + 0xeb, 0x64, 0xf7, 0xe4, 0x61, 0x2b, 0x93, 0xd1, + 0x1f, 0xbb, 0x5c, 0xff, 0xa1, 0x59, 0x69, 0xcf, + 0xf7, 0xaf, 0x58, 0x45, 0xd5, 0x3e, 0x98, 0x7d, + 0x26, 0x39, 0x5c, 0x75, 0x3c, 0x4a, 0xbf, 0x5e, + 0x12, 0x10, 0xb0, 0x93, 0x0f, 0x86, 0x82, 0xcf, + 0xb2, 0xec, 0x70, 0x5c, 0x0b, 0xad, 0x5d, 0x63, + 0x65, 0x32, 0xa6, 0x04, 0x58, 0x03, 0x91, 0x2b, + 0xdb, 0x8f, 0xd3, 0xa3, 0x2b, 0x3a, 0xf5, 0xa1, + 0x62, 0x6c, 0xb6, 0xf0, 0x13, 0x3b, 0x8c, 0x07, + 0x10, 0x82, 0xc9, 0x56, 0x24, 0x87, 0xfc, 0x56, + 0xe8, 0xef, 0x90, 0x8b, 0xd6, 0x48, 0xda, 0x53, + 0x04, 0x49, 0x41, 0xa4, 0x67, 0xe0, 0x33, 0x24, + 0x6b, 0x9c, 0x07, 0x55, 0x4c, 0x5d, 0xe9, 0x35, + 0xfa, 0xbd, 0xea, 0xa8, 0x3f, 0xe9, 0xf5, 0x20, + 0x5c, 0x60, 0x0f, 0x0d, 0x24, 0xcb, 0x1a, 0xd6, + 0xe8, 0x5c, 0xa8, 0x42, 0xae, 0xd0, 0xd2, 0xf2, + 0xa8, 0xbe, 0xea, 0x0f, 0x8d, 0xfb, 0x81, 0xa3, + 0xa4, 0xef, 0xb7, 0x3e, 0x91, 0xbd, 0x26, 0x0f, + 0x8e, 0xf1, 0xb2, 0xa5, 0x47, 0x06, 0xfa, 0x40, + 0x8b, 0x31, 0x7a, 0x5a, 0x74, 0x2a, 0x0a, 0x7c, + 0x62, 0x5d, 0x39, 0xa4, 0xae, 0x14, 0x85, 0x08, + 0x5b, 0x20, 0x85, 0xf1, 0x57, 0x6e, 0x71, 0x13, + 0x4e, 0x2b, 0x49, 0x87, 0x01, 0xdf, 0x37, 0xed, + 0x28, 0xee, 0x4d, 0xa1, 0xf4, 0xb3, 0x3b, 0xba, + 0x2d, 0xb3, 0x46, 0x17, 0x84, 0x80, 0x9d, 0xd7, + 0x93, 0x1f, 0x28, 0x7c, 0xf5, 0xf9, 0xd6, 0x85, + 0x8c, 0xa5, 0x44, 0xe9, 0x2c, 0x65, 0x51, 0x5f, + 0x53, 0x7a, 0x09, 0xd9, 0x30, 0x16, 0x95, 0x89, + 0x9c, 0x0b, 0xef, 0x90, 0x6d, 0x23, 0xd3, 0x48, + 0x57, 0x3b, 0x55, 0x69, 0x96, 0xfc, 0xf7, 0x52, + 0x92, 0x38, 0x36, 0xbf, 0xa9, 0x0a, 0xbb, 0x68, + 0x45, 0x08, 0x25, 0xee, 0x59, 0xfe, 0xee, 0xf2, + 0x2c, 0xd4, 0x5f, 0x78, 0x59, 0x0d, 0x90, 0xf1, + 0xd7, 0xe4, 0x39, 0x0e, 0x46, 0x36, 0xf5, 0x75, + 0x03, 0x3c, 0x28, 0xfb, 0xfa, 0x8f, 0xef, 0xc9, + 0x61, 0x00, 0x94, 0xc3, 0xd2, 0x0f, 0xd9, 0xda +}; + +static const uint8_t AES_CBC_ciphertext_1024B[] = { + 0x7d, 0x01, 0x7e, 0x2f, 0x92, 0xb3, 0xea, 0x72, + 0x4a, 0x3f, 0x10, 0xf9, 0x2b, 0xb0, 0xd5, 0xb9, + 0x19, 0x68, 0x94, 0xe9, 0x93, 0xe9, 0xd5, 0x26, + 0x20, 0x44, 0xe2, 0x47, 0x15, 0x8d, 0x75, 0x48, + 0x8e, 0xe4, 0x40, 0x81, 0xb5, 0x06, 0xa8, 0xb8, + 0x0e, 0x0f, 0x3b, 0xbc, 0x5b, 0xbe, 0x3b, 0xa2, + 0x2a, 0x0c, 0x48, 0x98, 0x19, 0xdf, 0xe9, 0x25, + 0x75, 0xab, 0x93, 0x44, 0xb1, 0x72, 0x70, 0xbb, + 0x20, 0xcf, 0x78, 0xe9, 0x4d, 0xc6, 0xa9, 0xa9, + 0x84, 0x78, 0xc5, 0xc0, 0xc4, 0xc9, 0x79, 0x1a, + 0xbc, 0x61, 0x25, 0x5f, 0xac, 0x01, 0x03, 0xb7, + 0xef, 0x07, 0xf2, 0x62, 0x98, 0xee, 0xe3, 0xad, + 0x94, 0x75, 0x30, 0x67, 0xb9, 0x15, 0x00, 0xe7, + 0x11, 0x32, 0x2e, 0x6b, 0x55, 0x9f, 0xac, 0x68, + 0xde, 0x61, 0x05, 0x80, 0x01, 0xf3, 0xad, 0xab, + 0xaf, 0x45, 0xe0, 0xf4, 0x68, 0x5c, 0xc0, 0x52, + 0x92, 0xc8, 0x21, 0xb6, 0xf5, 0x8a, 0x1d, 0xbb, + 0xfc, 0x4a, 0x11, 0x62, 0xa2, 0xc4, 0xf1, 0x2d, + 0x0e, 0xb2, 0xc7, 0x17, 0x34, 0xb4, 0x2a, 0x54, + 0x81, 0xc2, 0x1e, 0xcf, 0x51, 0x0a, 0x76, 0x54, + 0xf1, 0x48, 0x0d, 0x5c, 0xcd, 0x38, 0x3e, 0x38, + 0x3e, 0xf8, 0x46, 0x1d, 0x00, 0xf5, 0x62, 0xe1, + 0x5c, 0xb7, 0x8d, 0xce, 0xd0, 0x3f, 0xbb, 0x22, + 0xf1, 0xe5, 0xb1, 0xa0, 0x58, 0x5e, 0x3c, 0x0f, + 0x15, 0xd1, 0xac, 0x3e, 0xc7, 0x72, 0xc4, 0xde, + 0x8b, 0x95, 0x3e, 0x91, 0xf7, 0x1d, 0x04, 0x9a, + 0xc8, 0xe4, 0xbf, 0xd3, 0x22, 0xca, 0x4a, 0xdc, + 0xb6, 0x16, 0x79, 0x81, 0x75, 0x2f, 0x6b, 0xa7, + 0x04, 0x98, 0xa7, 0x4e, 0xc1, 0x19, 0x90, 0x33, + 0x33, 0x3c, 0x7f, 0xdd, 0xac, 0x09, 0x0c, 0xc3, + 0x91, 0x34, 0x74, 0xab, 0xa5, 0x35, 0x0a, 0x13, + 0xc3, 0x56, 0x67, 0x6d, 0x1a, 0x3e, 0xbf, 0x56, + 0x06, 0x67, 0x15, 0x5f, 0xfc, 0x8b, 0xa2, 0x3c, + 0x5e, 0xaf, 0x56, 0x1f, 0xe3, 0x2e, 0x9d, 0x0a, + 0xf9, 0x9b, 0xc7, 0xb5, 0x03, 0x1c, 0x68, 0x99, + 0xfa, 0x3c, 0x37, 0x59, 0xc1, 0xf7, 0x6a, 0x83, + 0x22, 0xee, 0xca, 0x7f, 0x7d, 0x49, 0xe6, 0x48, + 0x84, 0x54, 0x7a, 0xff, 0xb3, 0x72, 0x21, 0xd8, + 0x7a, 0x5d, 0xb1, 0x4b, 0xcc, 0x01, 0x6f, 0x90, + 0xc6, 0x68, 0x1c, 0x2c, 0xa1, 0xe2, 0x74, 0x40, + 0x26, 0x9b, 0x57, 0x53, 0xa3, 0x7c, 0x0b, 0x0d, + 0xcf, 0x05, 0x5d, 0x62, 0x4f, 0x75, 0x06, 0x62, + 0x1f, 0x26, 0x32, 0xaa, 0x25, 0xcc, 0x26, 0x8d, + 0xae, 0x01, 0x47, 0xa3, 0x00, 0x42, 0xe2, 0x4c, + 0xee, 0x29, 0xa2, 0x81, 0xa0, 0xfd, 0xeb, 0xff, + 0x9a, 0x66, 0x6e, 0x47, 0x5b, 0xab, 0x93, 0x5a, + 0x02, 0x6d, 0x6f, 0xf2, 0x6e, 0x02, 0x9d, 0xb1, + 0xab, 0x56, 0xdc, 0x8b, 0x9b, 0x17, 0xa8, 0xfb, + 0x87, 0x42, 0x7c, 0x91, 0x1e, 0x14, 0xc6, 0x6f, + 0xdc, 0xf0, 0x27, 0x30, 0xfa, 0x3f, 0xc4, 0xad, + 0x57, 0x85, 0xd2, 0xc9, 0x32, 0x2c, 0x13, 0xa6, + 0x04, 0x04, 0x50, 0x05, 0x2f, 0x72, 0xd9, 0x44, + 0x55, 0x6e, 0x93, 0x40, 0xed, 0x7e, 0xd4, 0x40, + 0x3e, 0x88, 0x3b, 0x8b, 0xb6, 0xeb, 0xc6, 0x5d, + 0x9c, 0x99, 0xa1, 0xcf, 0x30, 0xb2, 0xdc, 0x48, + 0x8a, 0x01, 0xa7, 0x61, 0x77, 0x50, 0x14, 0xf3, + 0x0c, 0x49, 0x53, 0xb3, 0xb4, 0xb4, 0x28, 0x41, + 0x4a, 0x2d, 0xd2, 0x4d, 0x2a, 0x30, 0x31, 0x83, + 0x03, 0x5e, 0xaa, 0xd3, 0xa3, 0xd1, 0xa1, 0xca, + 0x62, 0xf0, 0xe1, 0xf2, 0xff, 0xf0, 0x19, 0xa6, + 0xde, 0x22, 0x47, 0xb5, 0x28, 0x7d, 0xf7, 0x07, + 0x16, 0x0d, 0xb1, 0x55, 0x81, 0x95, 0xe5, 0x1d, + 0x4d, 0x78, 0xa9, 0x3e, 0xce, 0xe3, 0x1c, 0xf9, + 0x47, 0xc8, 0xec, 0xc5, 0xc5, 0x93, 0x4c, 0x34, + 0x20, 0x6b, 0xee, 0x9a, 0xe6, 0x86, 0x57, 0x58, + 0xd5, 0x58, 0xf1, 0x33, 0x10, 0x29, 0x9e, 0x93, + 0x2f, 0xf5, 0x90, 0x00, 0x17, 0x67, 0x4f, 0x39, + 0x18, 0xe1, 0xcf, 0x55, 0x78, 0xbb, 0xe6, 0x29, + 0x3e, 0x77, 0xd5, 0x48, 0xb7, 0x42, 0x72, 0x53, + 0x27, 0xfa, 0x5b, 0xe0, 0x36, 0x14, 0x97, 0xb8, + 0x9b, 0x3c, 0x09, 0x77, 0xc1, 0x0a, 0xe4, 0xa2, + 0x63, 0xfc, 0xbe, 0x5c, 0x17, 0xcf, 0x01, 0xf5, + 0x03, 0x0f, 0x17, 0xbc, 0x93, 0xdd, 0x5f, 0xe2, + 0xf3, 0x08, 0xa8, 0xb1, 0x85, 0xb6, 0x34, 0x3f, + 0x87, 0x42, 0xa5, 0x42, 0x3b, 0x0e, 0xd6, 0x83, + 0x6a, 0xfd, 0x5d, 0xc9, 0x67, 0xd5, 0x51, 0xc9, + 0x2a, 0x4e, 0x91, 0xb0, 0x59, 0xb2, 0x0f, 0xa2, + 0xe6, 0x47, 0x73, 0xc2, 0xa2, 0xae, 0xbb, 0xc8, + 0x42, 0xa3, 0x2a, 0x27, 0x29, 0x48, 0x8c, 0x54, + 0x6c, 0xec, 0x00, 0x2a, 0x42, 0xa3, 0x7a, 0x0f, + 0x12, 0x66, 0x6b, 0x96, 0xf6, 0xd0, 0x56, 0x4f, + 0x49, 0x5c, 0x47, 0xec, 0x05, 0x62, 0x54, 0xb2, + 0x64, 0x5a, 0x69, 0x1f, 0x19, 0xb4, 0x84, 0x5c, + 0xbe, 0x48, 0x8e, 0xfc, 0x58, 0x21, 0xce, 0xfa, + 0xaa, 0x84, 0xd2, 0xc1, 0x08, 0xb3, 0x87, 0x0f, + 0x4f, 0xa3, 0x3a, 0xb6, 0x44, 0xbe, 0x2e, 0x9a, + 0xdd, 0xb5, 0x44, 0x80, 0xca, 0xf4, 0xc3, 0x6e, + 0xba, 0x93, 0x77, 0xe0, 0x53, 0xfb, 0x37, 0xfb, + 0x88, 0xc3, 0x1f, 0x25, 0xde, 0x3e, 0x11, 0xf4, + 0x89, 0xe7, 0xd1, 0x3b, 0xb4, 0x23, 0xcb, 0x70, + 0xba, 0x35, 0x97, 0x7c, 0xbe, 0x84, 0x13, 0xcf, + 0xe0, 0x4d, 0x33, 0x91, 0x71, 0x85, 0xbb, 0x4b, + 0x97, 0x32, 0x5d, 0xa0, 0xb9, 0x8f, 0xdc, 0x27, + 0x5a, 0xeb, 0x71, 0xf1, 0xd5, 0x0d, 0x65, 0xb4, + 0x22, 0x81, 0xde, 0xa7, 0x58, 0x20, 0x0b, 0x18, + 0x11, 0x76, 0x5c, 0xe6, 0x6a, 0x2c, 0x99, 0x69, + 0xdc, 0xed, 0x67, 0x08, 0x5d, 0x5e, 0xe9, 0x1e, + 0x55, 0x70, 0xc1, 0x5a, 0x76, 0x1b, 0x8d, 0x2e, + 0x0d, 0xf9, 0xcc, 0x30, 0x8c, 0x44, 0x0f, 0x63, + 0x8c, 0x42, 0x8a, 0x9f, 0x4c, 0xd1, 0x48, 0x28, + 0x8a, 0xf5, 0x56, 0x2e, 0x23, 0x12, 0xfe, 0x67, + 0x9a, 0x13, 0x65, 0x75, 0x83, 0xf1, 0x3c, 0x98, + 0x07, 0x6b, 0xb7, 0x27, 0x5b, 0xf0, 0x70, 0xda, + 0x30, 0xf8, 0x74, 0x4e, 0x7a, 0x32, 0x84, 0xcc, + 0x0e, 0xcd, 0x80, 0x8b, 0x82, 0x31, 0x9a, 0x48, + 0xcf, 0x75, 0x00, 0x1f, 0x4f, 0xe0, 0x8e, 0xa3, + 0x6a, 0x2c, 0xd4, 0x73, 0x4c, 0x63, 0x7c, 0xa6, + 0x4d, 0x5e, 0xfd, 0x43, 0x3b, 0x27, 0xe1, 0x5e, + 0xa3, 0xa9, 0x5c, 0x3b, 0x60, 0xdd, 0xc6, 0x8d, + 0x5a, 0xf1, 0x3e, 0x89, 0x4b, 0x24, 0xcf, 0x01, + 0x3a, 0x2d, 0x44, 0xe7, 0xda, 0xe7, 0xa1, 0xac, + 0x11, 0x05, 0x0c, 0xa9, 0x7a, 0x82, 0x8c, 0x5c, + 0x29, 0x68, 0x9c, 0x73, 0x13, 0xcc, 0x67, 0x32, + 0x11, 0x5e, 0xe5, 0xcc, 0x8c, 0xf5, 0xa7, 0x52, + 0x83, 0x9a, 0x70, 0xef, 0xde, 0x55, 0x9c, 0xc7, + 0x8a, 0xed, 0xad, 0x28, 0x4a, 0xc5, 0x92, 0x6d, + 0x8e, 0x47, 0xca, 0xe3, 0xf8, 0x77, 0xb5, 0x26, + 0x64, 0x84, 0xc2, 0xf1, 0xd7, 0xae, 0x0c, 0xb9, + 0x39, 0x0f, 0x43, 0x6b, 0xe9, 0xe0, 0x09, 0x4b, + 0xe5, 0xe3, 0x17, 0xa6, 0x68, 0x69, 0x46, 0xf4, + 0xf0, 0x68, 0x7f, 0x2f, 0x1c, 0x7e, 0x4c, 0xd2, + 0xb5, 0xc6, 0x16, 0x85, 0xcf, 0x02, 0x4c, 0x89, + 0x0b, 0x25, 0xb0, 0xeb, 0xf3, 0x77, 0x08, 0x6a, + 0x46, 0x5c, 0xf6, 0x2f, 0xf1, 0x24, 0xc3, 0x4d, + 0x80, 0x60, 0x4d, 0x69, 0x98, 0xde, 0xc7, 0xa1, + 0xf6, 0x4e, 0x18, 0x0c, 0x2a, 0xb0, 0xb2, 0xe0, + 0x46, 0xe7, 0x49, 0x37, 0xc8, 0x5a, 0x23, 0x24, + 0xe3, 0x0f, 0xcc, 0x92, 0xb4, 0x8d, 0xdc, 0x9e +}; + +static const uint8_t AES_CBC_ciphertext_1280B[] = { + 0x91, 0x99, 0x5e, 0x9e, 0x84, 0xff, 0x59, 0x45, + 0xc1, 0xf4, 0xbc, 0x9c, 0xb9, 0x30, 0x6c, 0x51, + 0x73, 0x52, 0xb4, 0x44, 0x09, 0x79, 0xe2, 0x89, + 0x75, 0xeb, 0x54, 0x26, 0xce, 0xd8, 0x24, 0x98, + 0xaa, 0xf8, 0x13, 0x16, 0x68, 0x58, 0xc4, 0x82, + 0x0e, 0x31, 0xd3, 0x6a, 0x13, 0x58, 0x31, 0xe9, + 0x3a, 0xc1, 0x8b, 0xc5, 0x3f, 0x50, 0x42, 0xd1, + 0x93, 0xe4, 0x9b, 0x65, 0x2b, 0xf4, 0x1d, 0x9e, + 0x2d, 0xdb, 0x48, 0xef, 0x9a, 0x01, 0x68, 0xb6, + 0xea, 0x7a, 0x2b, 0xad, 0xfe, 0x77, 0x44, 0x7e, + 0x5a, 0xc5, 0x64, 0xb4, 0xfe, 0x5c, 0x80, 0xf3, + 0x20, 0x7e, 0xaf, 0x5b, 0xf8, 0xd1, 0x38, 0xa0, + 0x8d, 0x09, 0x77, 0x06, 0xfe, 0xf5, 0xf4, 0xe4, + 0xee, 0xb8, 0x95, 0x27, 0xed, 0x07, 0xb8, 0xaa, + 0x25, 0xb4, 0xe1, 0x4c, 0xeb, 0x3f, 0xdb, 0x39, + 0x66, 0x28, 0x1b, 0x60, 0x42, 0x8b, 0x99, 0xd9, + 0x49, 0xd6, 0x8c, 0xa4, 0x9d, 0xd8, 0x93, 0x58, + 0x8f, 0xfa, 0xd3, 0xf7, 0x37, 0x9c, 0x88, 0xab, + 0x16, 0x50, 0xfe, 0x01, 0x1f, 0x88, 0x48, 0xbe, + 0x21, 0xa9, 0x90, 0x9e, 0x73, 0xe9, 0x82, 0xf7, + 0xbf, 0x4b, 0x43, 0xf4, 0xbf, 0x22, 0x3c, 0x45, + 0x47, 0x95, 0x5b, 0x49, 0x71, 0x07, 0x1c, 0x8b, + 0x49, 0xa4, 0xa3, 0x49, 0xc4, 0x5f, 0xb1, 0xf5, + 0xe3, 0x6b, 0xf1, 0xdc, 0xea, 0x92, 0x7b, 0x29, + 0x40, 0xc9, 0x39, 0x5f, 0xdb, 0xbd, 0xf3, 0x6a, + 0x09, 0x9b, 0x2a, 0x5e, 0xc7, 0x0b, 0x25, 0x94, + 0x55, 0x71, 0x9c, 0x7e, 0x0e, 0xb4, 0x08, 0x12, + 0x8c, 0x6e, 0x77, 0xb8, 0x29, 0xf1, 0xc6, 0x71, + 0x04, 0x40, 0x77, 0x18, 0x3f, 0x01, 0x09, 0x9c, + 0x23, 0x2b, 0x5d, 0x2a, 0x88, 0x20, 0x23, 0x59, + 0x74, 0x2a, 0x67, 0x8f, 0xb7, 0xba, 0x38, 0x9f, + 0x0f, 0xcf, 0x94, 0xdf, 0xe1, 0x8f, 0x35, 0x5e, + 0x34, 0x0c, 0x32, 0x92, 0x2b, 0x23, 0x81, 0xf4, + 0x73, 0xa0, 0x5a, 0x2a, 0xbd, 0xa6, 0x6b, 0xae, + 0x43, 0xe2, 0xdc, 0x01, 0xc1, 0xc6, 0xc3, 0x04, + 0x06, 0xbb, 0xb0, 0x89, 0xb3, 0x4e, 0xbd, 0x81, + 0x1b, 0x03, 0x63, 0x93, 0xed, 0x4e, 0xf6, 0xe5, + 0x94, 0x6f, 0xd6, 0xf3, 0x20, 0xf3, 0xbc, 0x30, + 0xc5, 0xd6, 0xbe, 0x1c, 0x05, 0x34, 0x26, 0x4d, + 0x46, 0x5e, 0x56, 0x63, 0xfb, 0xdb, 0xcd, 0xed, + 0xb0, 0x7f, 0x83, 0x94, 0x55, 0x54, 0x2f, 0xab, + 0xc9, 0xb7, 0x16, 0x4f, 0x9e, 0x93, 0x25, 0xd7, + 0x9f, 0x39, 0x2b, 0x63, 0xcf, 0x1e, 0xa3, 0x0e, + 0x28, 0x47, 0x8a, 0x5f, 0x40, 0x02, 0x89, 0x1f, + 0x83, 0xe7, 0x87, 0xd1, 0x90, 0x17, 0xb8, 0x27, + 0x64, 0xe1, 0xe1, 0x48, 0x5a, 0x55, 0x74, 0x99, + 0x27, 0x9d, 0x05, 0x67, 0xda, 0x70, 0x12, 0x8f, + 0x94, 0x96, 0xfd, 0x36, 0xa4, 0x1d, 0x22, 0xe5, + 0x0b, 0xe5, 0x2f, 0x38, 0x55, 0xa3, 0x5d, 0x0b, + 0xcf, 0xd4, 0xa9, 0xb8, 0xd6, 0x9a, 0x16, 0x2e, + 0x6c, 0x4a, 0x25, 0x51, 0x7a, 0x09, 0x48, 0xdd, + 0xf0, 0xa3, 0x5b, 0x08, 0x1e, 0x2f, 0x03, 0x91, + 0x80, 0xe8, 0x0f, 0xe9, 0x5a, 0x2f, 0x90, 0xd3, + 0x64, 0xed, 0xd7, 0x51, 0x17, 0x66, 0x53, 0x40, + 0x43, 0x74, 0xef, 0x0a, 0x0d, 0x49, 0x41, 0xf2, + 0x67, 0x6e, 0xea, 0x14, 0xc8, 0x74, 0xd6, 0xa9, + 0xb9, 0x6a, 0xe3, 0xec, 0x7d, 0xe8, 0x6a, 0x21, + 0x3a, 0x52, 0x42, 0xfe, 0x9a, 0x15, 0x6d, 0x60, + 0x64, 0x88, 0xc5, 0xb2, 0x8b, 0x15, 0x2c, 0xff, + 0xe2, 0x35, 0xc3, 0xee, 0x9f, 0xcd, 0x82, 0xd9, + 0x14, 0x35, 0x2a, 0xb7, 0xf5, 0x2f, 0x7b, 0xbc, + 0x01, 0xfd, 0xa8, 0xe0, 0x21, 0x4e, 0x73, 0xf9, + 0xf2, 0xb0, 0x79, 0xc9, 0x10, 0x52, 0x8f, 0xa8, + 0x3e, 0x3b, 0xbe, 0xc5, 0xde, 0xf6, 0x53, 0xe3, + 0x1c, 0x25, 0x3a, 0x1f, 0x13, 0xbf, 0x13, 0xbb, + 0x94, 0xc2, 0x97, 0x43, 0x64, 0x47, 0x8f, 0x76, + 0xd7, 0xaa, 0xeb, 0xa4, 0x03, 0x50, 0x0c, 0x10, + 0x50, 0xd8, 0xf7, 0x75, 0x52, 0x42, 0xe2, 0x94, + 0x67, 0xf4, 0x60, 0xfb, 0x21, 0x9b, 0x7a, 0x05, + 0x50, 0x7c, 0x1b, 0x4a, 0x8b, 0x29, 0xe1, 0xac, + 0xd7, 0x99, 0xfd, 0x0d, 0x65, 0x92, 0xcd, 0x23, + 0xa7, 0x35, 0x8e, 0x13, 0xf2, 0xe4, 0x10, 0x74, + 0xc6, 0x4f, 0x19, 0xf7, 0x01, 0x0b, 0x46, 0xab, + 0xef, 0x8d, 0x4a, 0x4a, 0xfa, 0xda, 0xf3, 0xfb, + 0x40, 0x28, 0x88, 0xa2, 0x65, 0x98, 0x4d, 0x88, + 0xc7, 0xbf, 0x00, 0xc8, 0xd0, 0x91, 0xcb, 0x89, + 0x2f, 0xb0, 0x85, 0xfc, 0xa1, 0xc1, 0x9e, 0x83, + 0x88, 0xad, 0x95, 0xc0, 0x31, 0xa0, 0xad, 0xa2, + 0x42, 0xb5, 0xe7, 0x55, 0xd4, 0x93, 0x5a, 0x74, + 0x4e, 0x41, 0xc3, 0xcf, 0x96, 0x83, 0x46, 0xa1, + 0xb7, 0x5b, 0xb1, 0x34, 0x67, 0x4e, 0xb1, 0xd7, + 0x40, 0x20, 0x72, 0xe9, 0xc8, 0x74, 0xb7, 0xde, + 0x72, 0x29, 0x77, 0x4c, 0x74, 0x7e, 0xcc, 0x18, + 0xa5, 0x8d, 0x79, 0x8c, 0xd6, 0x6e, 0xcb, 0xd9, + 0xe1, 0x61, 0xe7, 0x36, 0xbc, 0x37, 0xea, 0xee, + 0xd8, 0x3c, 0x5e, 0x7c, 0x47, 0x50, 0xd5, 0xec, + 0x37, 0xc5, 0x63, 0xc3, 0xc9, 0x99, 0x23, 0x9f, + 0x64, 0x39, 0xdf, 0x13, 0x96, 0x6d, 0xea, 0x08, + 0x0c, 0x27, 0x2d, 0xfe, 0x0f, 0xc2, 0xa3, 0x97, + 0x04, 0x12, 0x66, 0x0d, 0x94, 0xbf, 0xbe, 0x3e, + 0xb9, 0xcf, 0x8e, 0xc1, 0x9d, 0xb1, 0x64, 0x17, + 0x54, 0x92, 0x3f, 0x0a, 0x51, 0xc8, 0xf5, 0x82, + 0x98, 0x73, 0x03, 0xc0, 0x5a, 0x51, 0x01, 0x67, + 0xb4, 0x01, 0x04, 0x06, 0xbc, 0x37, 0xde, 0x96, + 0x23, 0x3c, 0xce, 0x98, 0x3f, 0xd6, 0x51, 0x1b, + 0x01, 0x83, 0x0a, 0x1c, 0xf9, 0xeb, 0x7e, 0x72, + 0xa9, 0x51, 0x23, 0xc8, 0xd7, 0x2f, 0x12, 0xbc, + 0x08, 0xac, 0x07, 0xe7, 0xa7, 0xe6, 0x46, 0xae, + 0x54, 0xa3, 0xc2, 0xf2, 0x05, 0x2d, 0x06, 0x5e, + 0xfc, 0xe2, 0xa2, 0x23, 0xac, 0x86, 0xf2, 0x54, + 0x83, 0x4a, 0xb6, 0x48, 0x93, 0xa1, 0x78, 0xc2, + 0x07, 0xec, 0x82, 0xf0, 0x74, 0xa9, 0x18, 0xe9, + 0x53, 0x44, 0x49, 0xc2, 0x94, 0xf8, 0x94, 0x92, + 0x08, 0x3f, 0xbf, 0xa6, 0xe5, 0xc6, 0x03, 0x8a, + 0xc6, 0x90, 0x48, 0x6c, 0xee, 0xbd, 0x44, 0x92, + 0x1f, 0x2a, 0xce, 0x1d, 0xb8, 0x31, 0xa2, 0x9d, + 0x24, 0x93, 0xa8, 0x9f, 0x36, 0x00, 0x04, 0x7b, + 0xcb, 0x93, 0x59, 0xa1, 0x53, 0xdb, 0x13, 0x7a, + 0x54, 0xb1, 0x04, 0xdb, 0xce, 0x48, 0x4f, 0xe5, + 0x2f, 0xcb, 0xdf, 0x8f, 0x50, 0x7c, 0xfc, 0x76, + 0x80, 0xb4, 0xdc, 0x3b, 0xc8, 0x98, 0x95, 0xf5, + 0x50, 0xba, 0x70, 0x5a, 0x97, 0xd5, 0xfc, 0x98, + 0x4d, 0xf3, 0x61, 0x0f, 0xcf, 0xac, 0x49, 0x0a, + 0xdb, 0xc1, 0x42, 0x8f, 0xb6, 0x29, 0xd5, 0x65, + 0xef, 0x83, 0xf1, 0x30, 0x4b, 0x84, 0xd0, 0x69, + 0xde, 0xd2, 0x99, 0xe5, 0xec, 0xd3, 0x90, 0x86, + 0x39, 0x2a, 0x6e, 0xd5, 0x32, 0xe3, 0x0d, 0x2d, + 0x01, 0x8b, 0x17, 0x55, 0x1d, 0x65, 0x57, 0xbf, + 0xd8, 0x75, 0xa4, 0x85, 0xb6, 0x4e, 0x35, 0x14, + 0x58, 0xe4, 0x89, 0xb8, 0x7a, 0x58, 0x86, 0x0c, + 0xbd, 0x8b, 0x05, 0x7b, 0x63, 0xc0, 0x86, 0x80, + 0x33, 0x46, 0xd4, 0x9b, 0xb6, 0x0a, 0xeb, 0x6c, + 0xae, 0xd6, 0x57, 0x7a, 0xc7, 0x59, 0x33, 0xa0, + 0xda, 0xa4, 0x12, 0xbf, 0x52, 0x22, 0x05, 0x8d, + 0xeb, 0xee, 0xd5, 0xec, 0xea, 0x29, 0x9b, 0x76, + 0x95, 0x50, 0x6d, 0x99, 0xe1, 0x45, 0x63, 0x09, + 0x16, 0x5f, 0xb0, 0xf2, 0x5b, 0x08, 0x33, 0xdd, + 0x8f, 0xb7, 0x60, 0x7a, 0x8e, 0xc6, 0xfc, 0xac, + 0xa9, 0x56, 0x2c, 0xa9, 0x8b, 0x74, 0x33, 0xad, + 0x2a, 0x7e, 0x96, 0xb6, 0xba, 0x22, 0x28, 0xcf, + 0x4d, 0x96, 0xb7, 0xd1, 0xfa, 0x99, 0x4a, 0x61, + 0xe6, 0x84, 0xd1, 0x94, 0xca, 0xf5, 0x86, 0xb0, + 0xba, 0x34, 0x7a, 0x04, 0xcc, 0xd4, 0x81, 0xcd, + 0xd9, 0x86, 0xb6, 0xe0, 0x5a, 0x6f, 0x9b, 0x99, + 0xf0, 0xdf, 0x49, 0xae, 0x6d, 0xc2, 0x54, 0x67, + 0xe0, 0xb4, 0x34, 0x2d, 0x1c, 0x46, 0xdf, 0x73, + 0x3b, 0x45, 0x43, 0xe7, 0x1f, 0xa3, 0x36, 0x35, + 0x25, 0x33, 0xd9, 0xc0, 0x54, 0x38, 0x6e, 0x6b, + 0x80, 0xcf, 0x50, 0xa4, 0xb6, 0x21, 0x17, 0xfd, + 0x9b, 0x5c, 0x36, 0xca, 0xcc, 0x73, 0x73, 0xad, + 0xe0, 0x57, 0x77, 0x90, 0x0e, 0x7f, 0x0f, 0x87, + 0x7f, 0xdb, 0x73, 0xbf, 0xda, 0xc2, 0xb3, 0x05, + 0x22, 0x06, 0xf5, 0xa3, 0xfc, 0x1e, 0x8f, 0xda, + 0xcf, 0x49, 0xd6, 0xb3, 0x66, 0x2c, 0xb5, 0x00, + 0xaf, 0x85, 0x6e, 0xb8, 0x5b, 0x8c, 0xa1, 0xa4, + 0x21, 0xce, 0x40, 0xf3, 0x98, 0xac, 0xec, 0x88, + 0x62, 0x43, 0x2a, 0xac, 0xca, 0xcf, 0xb9, 0x30, + 0xeb, 0xfc, 0xef, 0xf0, 0x6e, 0x64, 0x6d, 0xe7, + 0x54, 0x88, 0x6b, 0x22, 0x29, 0xbe, 0xa5, 0x8c, + 0x31, 0x23, 0x3b, 0x4a, 0x80, 0x37, 0xe6, 0xd0, + 0x05, 0xfc, 0x10, 0x0e, 0xdd, 0xbb, 0x00, 0xc5, + 0x07, 0x20, 0x59, 0xd3, 0x41, 0x17, 0x86, 0x46, + 0xab, 0x68, 0xf6, 0x48, 0x3c, 0xea, 0x5a, 0x06, + 0x30, 0x21, 0x19, 0xed, 0x74, 0xbe, 0x0b, 0x97, + 0xee, 0x91, 0x35, 0x94, 0x1f, 0xcb, 0x68, 0x7f, + 0xe4, 0x48, 0xb0, 0x16, 0xfb, 0xf0, 0x74, 0xdb, + 0x06, 0x59, 0x2e, 0x5a, 0x9c, 0xce, 0x8f, 0x7d, + 0xba, 0x48, 0xd5, 0x3f, 0x5c, 0xb0, 0xc2, 0x33, + 0x48, 0x60, 0x17, 0x08, 0x85, 0xba, 0xff, 0xb9, + 0x34, 0x0a, 0x3d, 0x8f, 0x21, 0x13, 0x12, 0x1b +}; + +static const uint8_t AES_CBC_ciphertext_1536B[] = { + 0x89, 0x93, 0x05, 0x99, 0xa9, 0xed, 0xea, 0x62, + 0xc9, 0xda, 0x51, 0x15, 0xce, 0x42, 0x91, 0xc3, + 0x80, 0xc8, 0x03, 0x88, 0xc2, 0x63, 0xda, 0x53, + 0x1a, 0xf3, 0xeb, 0xd5, 0xba, 0x6f, 0x23, 0xb2, + 0xed, 0x8f, 0x89, 0xb1, 0xb3, 0xca, 0x90, 0x7a, + 0xdd, 0x3f, 0xf6, 0xca, 0x86, 0x58, 0x54, 0xbc, + 0xab, 0x0f, 0xf4, 0xab, 0x6d, 0x5d, 0x42, 0xd0, + 0x17, 0x49, 0x17, 0xd1, 0x93, 0xea, 0xe8, 0x22, + 0xc1, 0x34, 0x9f, 0x3a, 0x3b, 0xaa, 0xe9, 0x1b, + 0x93, 0xff, 0x6b, 0x68, 0xba, 0xe6, 0xd2, 0x39, + 0x3d, 0x55, 0x34, 0x8f, 0x98, 0x86, 0xb4, 0xd8, + 0x7c, 0x0d, 0x3e, 0x01, 0x63, 0x04, 0x01, 0xff, + 0x16, 0x0f, 0x51, 0x5f, 0x73, 0x53, 0xf0, 0x3a, + 0x38, 0xb4, 0x4d, 0x8d, 0xaf, 0xa3, 0xca, 0x2f, + 0x6f, 0xdf, 0xc0, 0x41, 0x6c, 0x48, 0x60, 0x1a, + 0xe4, 0xe7, 0x8a, 0x65, 0x6f, 0x8d, 0xd7, 0xe1, + 0x10, 0xab, 0x78, 0x5b, 0xb9, 0x69, 0x1f, 0xe0, + 0x5c, 0xf1, 0x19, 0x12, 0x21, 0xc7, 0x51, 0xbc, + 0x61, 0x5f, 0xc0, 0x36, 0x17, 0xc0, 0x28, 0xd9, + 0x51, 0xcb, 0x43, 0xd9, 0xfa, 0xd1, 0xad, 0x79, + 0x69, 0x86, 0x49, 0xc5, 0xe5, 0x69, 0x27, 0xce, + 0x22, 0xd0, 0xe1, 0x6a, 0xf9, 0x02, 0xca, 0x6c, + 0x34, 0xc7, 0xb8, 0x02, 0xc1, 0x38, 0x7f, 0xd5, + 0x15, 0xf5, 0xd6, 0xeb, 0xf9, 0x30, 0x40, 0x43, + 0xea, 0x87, 0xde, 0x35, 0xf6, 0x83, 0x59, 0x09, + 0x68, 0x62, 0x00, 0x87, 0xb8, 0xe7, 0xca, 0x05, + 0x0f, 0xac, 0x42, 0x58, 0x45, 0xaa, 0xc9, 0x9b, + 0xfd, 0x2a, 0xda, 0x65, 0x33, 0x93, 0x9d, 0xc6, + 0x93, 0x8d, 0xe2, 0xc5, 0x71, 0xc1, 0x5c, 0x13, + 0xde, 0x7b, 0xd4, 0xb9, 0x4c, 0x35, 0x61, 0x85, + 0x90, 0x78, 0xf7, 0x81, 0x98, 0x45, 0x99, 0x24, + 0x58, 0x73, 0x28, 0xf8, 0x31, 0xab, 0x54, 0x2e, + 0xc0, 0x38, 0x77, 0x25, 0x5c, 0x06, 0x9c, 0xc3, + 0x69, 0x21, 0x92, 0x76, 0xe1, 0x16, 0xdc, 0xa9, + 0xee, 0xb6, 0x80, 0x66, 0x43, 0x11, 0x24, 0xb3, + 0x07, 0x17, 0x89, 0x0f, 0xcb, 0xe0, 0x60, 0xa8, + 0x9d, 0x06, 0x4b, 0x6e, 0x72, 0xb7, 0xbc, 0x4f, + 0xb8, 0xc0, 0x80, 0xa2, 0xfb, 0x46, 0x5b, 0x8f, + 0x11, 0x01, 0x92, 0x9d, 0x37, 0x09, 0x98, 0xc8, + 0x0a, 0x46, 0xae, 0x12, 0xac, 0x61, 0x3f, 0xe7, + 0x41, 0x1a, 0xaa, 0x2e, 0xdc, 0xd7, 0x2a, 0x47, + 0xee, 0xdf, 0x08, 0xd1, 0xff, 0xea, 0x13, 0xc6, + 0x05, 0xdb, 0x29, 0xcc, 0x03, 0xba, 0x7b, 0x6d, + 0x40, 0xc1, 0xc9, 0x76, 0x75, 0x03, 0x7a, 0x71, + 0xc9, 0x5f, 0xd9, 0xe0, 0x61, 0x69, 0x36, 0x8f, + 0xb2, 0xbc, 0x28, 0xf3, 0x90, 0x71, 0xda, 0x5f, + 0x08, 0xd5, 0x0d, 0xc1, 0xe6, 0xbd, 0x2b, 0xc6, + 0x6c, 0x42, 0xfd, 0xbf, 0x10, 0xe8, 0x5f, 0x87, + 0x3d, 0x21, 0x42, 0x85, 0x01, 0x0a, 0xbf, 0x8e, + 0x49, 0xd3, 0x9c, 0x89, 0x3b, 0xea, 0xe1, 0xbf, + 0xe9, 0x9b, 0x5e, 0x0e, 0xb8, 0xeb, 0xcd, 0x3a, + 0xf6, 0x29, 0x41, 0x35, 0xdd, 0x9b, 0x13, 0x24, + 0xe0, 0x1d, 0x8a, 0xcb, 0x20, 0xf8, 0x41, 0x51, + 0x3e, 0x23, 0x8c, 0x67, 0x98, 0x39, 0x53, 0x77, + 0x2a, 0x68, 0xf4, 0x3c, 0x7e, 0xd6, 0xc4, 0x6e, + 0xf1, 0x53, 0xe9, 0xd8, 0x5c, 0xc1, 0xa9, 0x38, + 0x6f, 0x5e, 0xe4, 0xd4, 0x29, 0x1c, 0x6c, 0xee, + 0x2f, 0xea, 0xde, 0x61, 0x71, 0x5a, 0xea, 0xce, + 0x23, 0x6e, 0x1b, 0x16, 0x43, 0xb7, 0xc0, 0xe3, + 0x87, 0xa1, 0x95, 0x1e, 0x97, 0x4d, 0xea, 0xa6, + 0xf7, 0x25, 0xac, 0x82, 0x2a, 0xd3, 0xa6, 0x99, + 0x75, 0xdd, 0xc1, 0x55, 0x32, 0x6b, 0xea, 0x33, + 0x88, 0xce, 0x06, 0xac, 0x15, 0x39, 0x19, 0xa3, + 0x59, 0xaf, 0x7a, 0x1f, 0xd9, 0x72, 0x5e, 0xf7, + 0x4c, 0xf3, 0x5d, 0x6b, 0xf2, 0x16, 0x92, 0xa8, + 0x9e, 0x3d, 0xd4, 0x4c, 0x72, 0x55, 0x4e, 0x4a, + 0xf7, 0x8b, 0x2f, 0x67, 0x5a, 0x90, 0xb7, 0xcf, + 0x16, 0xd3, 0x7b, 0x5a, 0x9a, 0xc8, 0x9f, 0xbf, + 0x01, 0x76, 0x3b, 0x86, 0x2c, 0x2a, 0x78, 0x10, + 0x70, 0x05, 0x38, 0xf9, 0xdd, 0x2a, 0x1d, 0x00, + 0x25, 0xb7, 0x10, 0xac, 0x3b, 0x3c, 0x4d, 0x3c, + 0x01, 0x68, 0x3c, 0x5a, 0x29, 0xc2, 0xa0, 0x1b, + 0x95, 0x67, 0xf9, 0x0a, 0x60, 0xb7, 0x11, 0x9c, + 0x40, 0x45, 0xd7, 0xb0, 0xda, 0x49, 0x87, 0xcd, + 0xb0, 0x9b, 0x61, 0x8c, 0xf4, 0x0d, 0x94, 0x1d, + 0x79, 0x66, 0x13, 0x0b, 0xc6, 0x6b, 0x19, 0xee, + 0xa0, 0x6b, 0x64, 0x7d, 0xc4, 0xff, 0x98, 0x72, + 0x60, 0xab, 0x7f, 0x0f, 0x4d, 0x5d, 0x6b, 0xc3, + 0xba, 0x5e, 0x0d, 0x04, 0xd9, 0x59, 0x17, 0xd0, + 0x64, 0xbe, 0xfb, 0x58, 0xfc, 0xed, 0x18, 0xf6, + 0xac, 0x19, 0xa4, 0xfd, 0x16, 0x59, 0x80, 0x58, + 0xb8, 0x0f, 0x79, 0x24, 0x60, 0x18, 0x62, 0xa9, + 0xa3, 0xa0, 0xe8, 0x81, 0xd6, 0xec, 0x5b, 0xfe, + 0x5b, 0xb8, 0xa4, 0x00, 0xa9, 0xd0, 0x90, 0x17, + 0xe5, 0x50, 0x3d, 0x2b, 0x12, 0x6e, 0x2a, 0x13, + 0x65, 0x7c, 0xdf, 0xdf, 0xa7, 0xdd, 0x9f, 0x78, + 0x5f, 0x8f, 0x4e, 0x90, 0xa6, 0x10, 0xe4, 0x7b, + 0x68, 0x6b, 0xfd, 0xa9, 0x6d, 0x47, 0xfa, 0xec, + 0x42, 0x35, 0x07, 0x12, 0x3e, 0x78, 0x23, 0x15, + 0xff, 0xe2, 0x65, 0xc7, 0x47, 0x89, 0x2f, 0x97, + 0x7c, 0xd7, 0x6b, 0x69, 0x35, 0x79, 0x6f, 0x85, + 0xb4, 0xa9, 0x75, 0x04, 0x32, 0x9a, 0xfe, 0xf0, + 0xce, 0xe3, 0xf1, 0xab, 0x15, 0x47, 0xe4, 0x9c, + 0xc1, 0x48, 0x32, 0x3c, 0xbe, 0x44, 0x72, 0xc9, + 0xaa, 0x50, 0x37, 0xa6, 0xbe, 0x41, 0xcf, 0xe8, + 0x17, 0x4e, 0x37, 0xbe, 0xf1, 0x34, 0x2c, 0xd9, + 0x60, 0x48, 0x09, 0xa5, 0x26, 0x00, 0x31, 0x77, + 0x4e, 0xac, 0x7c, 0x89, 0x75, 0xe3, 0xde, 0x26, + 0x4c, 0x32, 0x54, 0x27, 0x8e, 0x92, 0x26, 0x42, + 0x85, 0x76, 0x01, 0x76, 0x62, 0x4c, 0x29, 0xe9, + 0x38, 0x05, 0x51, 0x54, 0x97, 0xa3, 0x03, 0x59, + 0x5e, 0xec, 0x0c, 0xe4, 0x96, 0xb7, 0x15, 0xa8, + 0x41, 0x06, 0x2b, 0x78, 0x95, 0x24, 0xf6, 0x32, + 0xc5, 0xec, 0xd7, 0x89, 0x28, 0x1e, 0xec, 0xb1, + 0xc7, 0x21, 0x0c, 0xd3, 0x80, 0x7c, 0x5a, 0xe6, + 0xb1, 0x3a, 0x52, 0x33, 0x84, 0x4e, 0x32, 0x6e, + 0x7a, 0xf6, 0x43, 0x15, 0x5b, 0xa6, 0xba, 0xeb, + 0xa8, 0xe4, 0xff, 0x4f, 0xbd, 0xbd, 0xa8, 0x5e, + 0xbe, 0x27, 0xaf, 0xc5, 0xf7, 0x9e, 0xdf, 0x48, + 0x22, 0xca, 0x6a, 0x0b, 0x3c, 0xd7, 0xe0, 0xdc, + 0xf3, 0x71, 0x08, 0xdc, 0x28, 0x13, 0x08, 0xf2, + 0x08, 0x1d, 0x9d, 0x7b, 0xd9, 0xde, 0x6f, 0xe6, + 0xe8, 0x88, 0x18, 0xc2, 0xcd, 0x93, 0xc5, 0x38, + 0x21, 0x68, 0x4c, 0x9a, 0xfb, 0xb6, 0x18, 0x16, + 0x73, 0x2c, 0x1d, 0x6f, 0x95, 0xfb, 0x65, 0x4f, + 0x7c, 0xec, 0x8d, 0x6c, 0xa8, 0xc0, 0x55, 0x28, + 0xc6, 0xc3, 0xea, 0xeb, 0x05, 0xf5, 0x65, 0xeb, + 0x53, 0xe1, 0x54, 0xef, 0xb8, 0x64, 0x98, 0x2d, + 0x98, 0x9e, 0xc8, 0xfe, 0xa2, 0x07, 0x30, 0xf7, + 0xf7, 0xae, 0xdb, 0x32, 0xf8, 0x71, 0x9d, 0x06, + 0xdf, 0x9b, 0xda, 0x61, 0x7d, 0xdb, 0xae, 0x06, + 0x24, 0x63, 0x74, 0xb6, 0xf3, 0x1b, 0x66, 0x09, + 0x60, 0xff, 0x2b, 0x29, 0xf5, 0xa9, 0x9d, 0x61, + 0x5d, 0x55, 0x10, 0x82, 0x21, 0xbb, 0x64, 0x0d, + 0xef, 0x5c, 0xe3, 0x30, 0x1b, 0x60, 0x1e, 0x5b, + 0xfe, 0x6c, 0xf5, 0x15, 0xa3, 0x86, 0x27, 0x58, + 0x46, 0x00, 0x20, 0xcb, 0x86, 0x9a, 0x52, 0x29, + 0x20, 0x68, 0x4d, 0x67, 0x88, 0x70, 0xc2, 0x31, + 0xd8, 0xbb, 0xa5, 0xa7, 0x88, 0x7f, 0x66, 0xbc, + 0xaa, 0x0f, 0xe1, 0x78, 0x7b, 0x97, 0x3c, 0xb7, + 0xd7, 0xd8, 0x04, 0xe0, 0x09, 0x60, 0xc8, 0xd0, + 0x9e, 0xe5, 0x6b, 0x31, 0x7f, 0x88, 0xfe, 0xc3, + 0xfd, 0x89, 0xec, 0x76, 0x4b, 0xb3, 0xa7, 0x37, + 0x03, 0xb7, 0xc6, 0x10, 0x7c, 0x9d, 0x0c, 0x75, + 0xd3, 0x08, 0x14, 0x94, 0x03, 0x42, 0x25, 0x26, + 0x85, 0xf7, 0xf0, 0x90, 0x06, 0x3e, 0x6f, 0x60, + 0x52, 0x55, 0xd5, 0x0f, 0x79, 0x64, 0x69, 0x69, + 0x46, 0xf9, 0x7f, 0x7f, 0x03, 0xf1, 0x1f, 0xdb, + 0x39, 0x05, 0xba, 0x4a, 0x8f, 0x17, 0xe7, 0xba, + 0xe2, 0x07, 0x7c, 0x1d, 0x9e, 0xbc, 0x94, 0xc0, + 0x61, 0x59, 0x8e, 0x72, 0xaf, 0xfc, 0x99, 0xe4, + 0xd5, 0xa8, 0xee, 0x0a, 0x48, 0x2d, 0x82, 0x8b, + 0x34, 0x54, 0x8a, 0xce, 0xc7, 0xfa, 0xdd, 0xba, + 0x54, 0xdf, 0xb3, 0x30, 0x33, 0x73, 0x2e, 0xd5, + 0x52, 0xab, 0x49, 0x91, 0x4e, 0x0a, 0xd6, 0x2f, + 0x67, 0xe4, 0xdd, 0x64, 0x48, 0x16, 0xd9, 0x85, + 0xaa, 0x52, 0xa5, 0x0b, 0xd3, 0xb4, 0x2d, 0x77, + 0x5e, 0x52, 0x77, 0x17, 0xcf, 0xbe, 0x88, 0x04, + 0x01, 0x52, 0xe2, 0xf1, 0x46, 0xe2, 0x91, 0x30, + 0x65, 0xcf, 0xc0, 0x65, 0x45, 0xc3, 0x7e, 0xf4, + 0x2e, 0xb5, 0xaf, 0x6f, 0xab, 0x1a, 0xfa, 0x70, + 0x35, 0xb8, 0x4f, 0x2d, 0x78, 0x90, 0x33, 0xb5, + 0x9a, 0x67, 0xdb, 0x2f, 0x28, 0x32, 0xb6, 0x54, + 0xab, 0x4c, 0x6b, 0x85, 0xed, 0x6c, 0x3e, 0x05, + 0x2a, 0xc7, 0x32, 0xe8, 0xf5, 0xa3, 0x7b, 0x4e, + 0x7b, 0x58, 0x24, 0x73, 0xf7, 0xfd, 0xc7, 0xc8, + 0x6c, 0x71, 0x68, 0xb1, 0xf6, 0xc5, 0x9e, 0x1e, + 0xe3, 0x5c, 0x25, 0xc0, 0x5b, 0x3e, 0x59, 0xa1, + 0x18, 0x5a, 0xe8, 0xb5, 0xd1, 0x44, 0x13, 0xa3, + 0xe6, 0x05, 0x76, 0xd2, 0x8d, 0x6e, 0x54, 0x68, + 0x0c, 0xa4, 0x7b, 0x8b, 0xd3, 0x8c, 0x42, 0x13, + 0x87, 0xda, 0xdf, 0x8f, 0xa5, 0x83, 0x7a, 0x42, + 0x99, 0xb7, 0xeb, 0xe2, 0x79, 0xe0, 0xdb, 0xda, + 0x33, 0xa8, 0x50, 0x3a, 0xd7, 0xe7, 0xd3, 0x61, + 0x18, 0xb8, 0xaa, 0x2d, 0xc8, 0xd8, 0x2c, 0x28, + 0xe5, 0x97, 0x0a, 0x7c, 0x6c, 0x7f, 0x09, 0xd7, + 0x88, 0x80, 0xac, 0x12, 0xed, 0xf8, 0xc6, 0xb5, + 0x2d, 0xd6, 0x63, 0x9b, 0x98, 0x35, 0x26, 0xde, + 0xf6, 0x31, 0xee, 0x7e, 0xa0, 0xfb, 0x16, 0x98, + 0xb1, 0x96, 0x1d, 0xee, 0xe3, 0x2f, 0xfb, 0x41, + 0xdd, 0xea, 0x10, 0x1e, 0x03, 0x89, 0x18, 0xd2, + 0x47, 0x0c, 0xa0, 0x57, 0xda, 0x76, 0x3a, 0x37, + 0x2c, 0xe4, 0xf9, 0x77, 0xc8, 0x43, 0x5f, 0xcb, + 0xd6, 0x85, 0xf7, 0x22, 0xe4, 0x32, 0x25, 0xa8, + 0xdc, 0x21, 0xc0, 0xf5, 0x95, 0xb2, 0xf8, 0x83, + 0xf0, 0x65, 0x61, 0x15, 0x48, 0x94, 0xb7, 0x03, + 0x7f, 0x66, 0xa1, 0x39, 0x1f, 0xdd, 0xce, 0x96, + 0xfe, 0x58, 0x81, 0x3d, 0x41, 0x11, 0x87, 0x13, + 0x26, 0x1b, 0x6d, 0xf3, 0xca, 0x2e, 0x2c, 0x76, + 0xd3, 0x2f, 0x6d, 0x49, 0x70, 0x53, 0x05, 0x96, + 0xcc, 0x30, 0x2b, 0x83, 0xf2, 0xc6, 0xb2, 0x4b, + 0x22, 0x13, 0x95, 0x42, 0xeb, 0x56, 0x4d, 0x22, + 0xe6, 0x43, 0x6f, 0xba, 0xe7, 0x3b, 0xe5, 0x59, + 0xce, 0x57, 0x88, 0x85, 0xb6, 0xbf, 0x15, 0x37, + 0xb3, 0x7a, 0x7e, 0xc4, 0xbc, 0x99, 0xfc, 0xe4, + 0x89, 0x00, 0x68, 0x39, 0xbc, 0x5a, 0xba, 0xab, + 0x52, 0xab, 0xe6, 0x81, 0xfd, 0x93, 0x62, 0xe9, + 0xb7, 0x12, 0xd1, 0x18, 0x1a, 0xb9, 0x55, 0x4a, + 0x0f, 0xae, 0x35, 0x11, 0x04, 0x27, 0xf3, 0x42, + 0x4e, 0xca, 0xdf, 0x9f, 0x12, 0x62, 0xea, 0x03, + 0xc0, 0xa9, 0x22, 0x7b, 0x6c, 0x6c, 0xe3, 0xdf, + 0x16, 0xad, 0x03, 0xc9, 0xfe, 0xa4, 0xdd, 0x4f +}; + +static const uint8_t AES_CBC_ciphertext_1792B[] = { + 0x59, 0xcc, 0xfe, 0x8f, 0xb4, 0x9d, 0x0e, 0xd1, + 0x85, 0xfc, 0x9b, 0x43, 0xc1, 0xb7, 0x54, 0x67, + 0x01, 0xef, 0xb8, 0x71, 0x36, 0xdb, 0x50, 0x48, + 0x7a, 0xea, 0xcf, 0xce, 0xba, 0x30, 0x10, 0x2e, + 0x96, 0x2b, 0xfd, 0xcf, 0x00, 0xe3, 0x1f, 0xac, + 0x66, 0x14, 0x30, 0x86, 0x49, 0xdb, 0x01, 0x8b, + 0x07, 0xdd, 0x00, 0x9d, 0x0d, 0x5c, 0x19, 0x11, + 0xe8, 0x44, 0x2b, 0x25, 0x70, 0xed, 0x7c, 0x33, + 0x0d, 0xe3, 0x34, 0x93, 0x63, 0xad, 0x26, 0xb1, + 0x11, 0x91, 0x34, 0x2e, 0x1d, 0x50, 0xaa, 0xd4, + 0xef, 0x3a, 0x6d, 0xd7, 0x33, 0x20, 0x0d, 0x3f, + 0x9b, 0xdd, 0xc3, 0xa5, 0xc5, 0xf1, 0x99, 0xdc, + 0xea, 0x52, 0xda, 0x55, 0xea, 0xa2, 0x7a, 0xc5, + 0x78, 0x44, 0x4a, 0x02, 0x33, 0x19, 0x62, 0x37, + 0xf8, 0x8b, 0xd1, 0x0c, 0x21, 0xdf, 0x40, 0x19, + 0x81, 0xea, 0xfb, 0x1c, 0xa7, 0xcc, 0x60, 0xfe, + 0x63, 0x25, 0x8f, 0xf3, 0x73, 0x0f, 0x45, 0xe6, + 0x6a, 0x18, 0xbf, 0xbe, 0xad, 0x92, 0x2a, 0x1e, + 0x15, 0x65, 0x6f, 0xef, 0x92, 0xcd, 0x0e, 0x19, + 0x3d, 0x42, 0xa8, 0xfc, 0x0d, 0x32, 0x58, 0xe0, + 0x56, 0x9f, 0xd6, 0x9b, 0x8b, 0xec, 0xe0, 0x45, + 0x4d, 0x7e, 0x73, 0x87, 0xff, 0x74, 0x92, 0x59, + 0x60, 0x13, 0x93, 0xda, 0xec, 0xbf, 0xfa, 0x20, + 0xb6, 0xe7, 0xdf, 0xc7, 0x10, 0xf5, 0x79, 0xb4, + 0xd7, 0xac, 0xaf, 0x2b, 0x37, 0x52, 0x30, 0x1d, + 0xbe, 0x0f, 0x60, 0x77, 0x3d, 0x03, 0x63, 0xa9, + 0xae, 0xb1, 0xf3, 0xca, 0xca, 0xb4, 0x21, 0xd7, + 0x6f, 0x2e, 0x5e, 0x9b, 0x68, 0x53, 0x80, 0xab, + 0x30, 0x23, 0x0a, 0x72, 0x6b, 0xb1, 0xd8, 0x25, + 0x5d, 0x3a, 0x62, 0x9b, 0x4f, 0x59, 0x3b, 0x79, + 0xa8, 0x9e, 0x08, 0x6d, 0x37, 0xb0, 0xfc, 0x42, + 0x51, 0x25, 0x86, 0xbd, 0x54, 0x5a, 0x95, 0x20, + 0x6c, 0xac, 0xb9, 0x30, 0x1c, 0x03, 0xc9, 0x49, + 0x38, 0x55, 0x31, 0x49, 0xed, 0xa9, 0x0e, 0xc3, + 0x65, 0xb4, 0x68, 0x6b, 0x07, 0x4c, 0x0a, 0xf9, + 0x21, 0x69, 0x7c, 0x9f, 0x28, 0x80, 0xe9, 0x49, + 0x22, 0x7c, 0xec, 0x97, 0xf7, 0x70, 0xb4, 0xb8, + 0x25, 0xe7, 0x80, 0x2c, 0x43, 0x24, 0x8a, 0x2e, + 0xac, 0xa2, 0x84, 0x20, 0xe7, 0xf4, 0x6b, 0x86, + 0x37, 0x05, 0xc7, 0x59, 0x04, 0x49, 0x2a, 0x99, + 0x80, 0x46, 0x32, 0x19, 0xe6, 0x30, 0xce, 0xc0, + 0xef, 0x6e, 0xec, 0xe5, 0x2f, 0x24, 0xc1, 0x78, + 0x45, 0x02, 0xd3, 0x64, 0x99, 0xf5, 0xc7, 0xbc, + 0x8f, 0x8c, 0x75, 0xb1, 0x0a, 0xc8, 0xc3, 0xbd, + 0x5e, 0x7e, 0xbd, 0x0e, 0xdf, 0x4b, 0x96, 0x6a, + 0xfd, 0x03, 0xdb, 0xd1, 0x31, 0x1e, 0x27, 0xf9, + 0xe5, 0x83, 0x9a, 0xfc, 0x13, 0x4c, 0xd3, 0x04, + 0xdb, 0xdb, 0x3f, 0x35, 0x93, 0x4e, 0x14, 0x6b, + 0x00, 0x5c, 0xb6, 0x11, 0x50, 0xee, 0x61, 0x5c, + 0x10, 0x5c, 0xd0, 0x90, 0x02, 0x2e, 0x12, 0xe0, + 0x50, 0x44, 0xad, 0x75, 0xcd, 0x94, 0xcf, 0x92, + 0xcb, 0xe3, 0xe8, 0x77, 0x4b, 0xd7, 0x1a, 0x7c, + 0xdd, 0x6b, 0x49, 0x21, 0x7c, 0xe8, 0x2c, 0x25, + 0x49, 0x86, 0x1e, 0x54, 0xae, 0xfc, 0x0e, 0x80, + 0xb1, 0xd5, 0xa5, 0x23, 0xcf, 0xcc, 0x0e, 0x11, + 0xe2, 0x7c, 0x3c, 0x25, 0x78, 0x64, 0x03, 0xa1, + 0xdd, 0x9f, 0x74, 0x12, 0x7b, 0x21, 0xb5, 0x73, + 0x15, 0x3c, 0xed, 0xad, 0x07, 0x62, 0x21, 0x79, + 0xd4, 0x2f, 0x0d, 0x72, 0xe9, 0x7c, 0x6b, 0x96, + 0x6e, 0xe5, 0x36, 0x4a, 0xd2, 0x38, 0xe1, 0xff, + 0x6e, 0x26, 0xa4, 0xac, 0x83, 0x07, 0xe6, 0x67, + 0x74, 0x6c, 0xec, 0x8b, 0x4b, 0x79, 0x33, 0x50, + 0x2f, 0x8f, 0xa0, 0x8f, 0xfa, 0x38, 0x6a, 0xa2, + 0x3a, 0x42, 0x85, 0x15, 0x90, 0xd0, 0xb3, 0x0d, + 0x8a, 0xe4, 0x60, 0x03, 0xef, 0xf9, 0x65, 0x8a, + 0x4e, 0x50, 0x8c, 0x65, 0xba, 0x61, 0x16, 0xc3, + 0x93, 0xb7, 0x75, 0x21, 0x98, 0x25, 0x60, 0x6e, + 0x3d, 0x68, 0xba, 0x7c, 0xe4, 0xf3, 0xd9, 0x9b, + 0xfb, 0x7a, 0xed, 0x1f, 0xb3, 0x4b, 0x88, 0x74, + 0x2c, 0xb8, 0x8c, 0x22, 0x95, 0xce, 0x90, 0xf1, + 0xdb, 0x80, 0xa6, 0x39, 0xae, 0x82, 0xa1, 0xef, + 0x75, 0xec, 0xfe, 0xf1, 0xe8, 0x04, 0xfd, 0x99, + 0x1b, 0x5f, 0x45, 0x87, 0x4f, 0xfa, 0xa2, 0x3e, + 0x3e, 0xb5, 0x01, 0x4b, 0x46, 0xeb, 0x13, 0x9a, + 0xe4, 0x7d, 0x03, 0x87, 0xb1, 0x59, 0x91, 0x8e, + 0x37, 0xd3, 0x16, 0xce, 0xef, 0x4b, 0xe9, 0x46, + 0x8d, 0x2a, 0x50, 0x2f, 0x41, 0xd3, 0x7b, 0xcf, + 0xf0, 0xb7, 0x8b, 0x65, 0x0f, 0xa3, 0x27, 0x10, + 0xe9, 0xa9, 0xe9, 0x2c, 0xbe, 0xbb, 0x82, 0xe3, + 0x7b, 0x0b, 0x81, 0x3e, 0xa4, 0x6a, 0x4f, 0x3b, + 0xd5, 0x61, 0xf8, 0x47, 0x04, 0x99, 0x5b, 0xff, + 0xf3, 0x14, 0x6e, 0x57, 0x5b, 0xbf, 0x1b, 0xb4, + 0x3f, 0xf9, 0x31, 0xf6, 0x95, 0xd5, 0x10, 0xa9, + 0x72, 0x28, 0x23, 0xa9, 0x6a, 0xa2, 0xcf, 0x7d, + 0xe3, 0x18, 0x95, 0xda, 0xbc, 0x6f, 0xe9, 0xd8, + 0xef, 0x49, 0x3f, 0xd3, 0xef, 0x1f, 0xe1, 0x50, + 0xe8, 0x8a, 0xc0, 0xce, 0xcc, 0xb7, 0x5e, 0x0e, + 0x8b, 0x95, 0x80, 0xfd, 0x58, 0x2a, 0x9b, 0xc8, + 0xb4, 0x17, 0x04, 0x46, 0x74, 0xd4, 0x68, 0x91, + 0x33, 0xc8, 0x31, 0x15, 0x84, 0x16, 0x35, 0x03, + 0x64, 0x6d, 0xa9, 0x4e, 0x20, 0xeb, 0xa9, 0x3f, + 0x21, 0x5e, 0x9b, 0x09, 0xc3, 0x45, 0xf8, 0x7c, + 0x59, 0x62, 0x29, 0x9a, 0x5c, 0xcf, 0xb4, 0x27, + 0x5e, 0x13, 0xea, 0xb3, 0xef, 0xd9, 0x01, 0x2a, + 0x65, 0x5f, 0x14, 0xf4, 0xbf, 0x28, 0x89, 0x3d, + 0xdd, 0x9d, 0x52, 0xbd, 0x9e, 0x5b, 0x3b, 0xd2, + 0xc2, 0x81, 0x35, 0xb6, 0xac, 0xdd, 0x27, 0xc3, + 0x7b, 0x01, 0x5a, 0x6d, 0x4c, 0x5e, 0x2c, 0x30, + 0xcb, 0x3a, 0xfa, 0xc1, 0xd7, 0x31, 0x67, 0x3e, + 0x08, 0x6a, 0xe8, 0x8c, 0x75, 0xac, 0x1a, 0x6a, + 0x52, 0xf7, 0x51, 0xcd, 0x85, 0x3f, 0x3c, 0xa7, + 0xea, 0xbc, 0xd7, 0x18, 0x9e, 0x27, 0x73, 0xe6, + 0x2b, 0x58, 0xb6, 0xd2, 0x29, 0x68, 0xd5, 0x8f, + 0x00, 0x4d, 0x55, 0xf6, 0x61, 0x5a, 0xcc, 0x51, + 0xa6, 0x5e, 0x85, 0xcb, 0x0b, 0xfd, 0x06, 0xca, + 0xf5, 0xbf, 0x0d, 0x13, 0x74, 0x78, 0x6d, 0x9e, + 0x20, 0x11, 0x84, 0x3e, 0x78, 0x17, 0x04, 0x4f, + 0x64, 0x2c, 0x3b, 0x3e, 0x93, 0x7b, 0x58, 0x33, + 0x07, 0x52, 0xf7, 0x60, 0x6a, 0xa8, 0x3b, 0x19, + 0x27, 0x7a, 0x93, 0xc5, 0x53, 0xad, 0xec, 0xf6, + 0xc8, 0x94, 0xee, 0x92, 0xea, 0xee, 0x7e, 0xea, + 0xb9, 0x5f, 0xac, 0x59, 0x5d, 0x2e, 0x78, 0x53, + 0x72, 0x81, 0x92, 0xdd, 0x1c, 0x63, 0xbe, 0x02, + 0xeb, 0xa8, 0x1b, 0x2a, 0x6e, 0x72, 0xe3, 0x2d, + 0x84, 0x0d, 0x8a, 0x22, 0xf6, 0xba, 0xab, 0x04, + 0x8e, 0x04, 0x24, 0xdb, 0xcc, 0xe2, 0x69, 0xeb, + 0x4e, 0xfa, 0x6b, 0x5b, 0xc8, 0xc0, 0xd9, 0x25, + 0xcb, 0x40, 0x8d, 0x4b, 0x8e, 0xa0, 0xd4, 0x72, + 0x98, 0x36, 0x46, 0x3b, 0x4f, 0x5f, 0x96, 0x84, + 0x03, 0x28, 0x86, 0x4d, 0xa1, 0x8a, 0xd7, 0xb2, + 0x5b, 0x27, 0x01, 0x80, 0x62, 0x49, 0x56, 0xb9, + 0xa0, 0xa1, 0xe3, 0x6e, 0x22, 0x2a, 0x5d, 0x03, + 0x86, 0x40, 0x36, 0x22, 0x5e, 0xd2, 0xe5, 0xc0, + 0x6b, 0xfa, 0xac, 0x80, 0x4e, 0x09, 0x99, 0xbc, + 0x2f, 0x9b, 0xcc, 0xf3, 0x4e, 0xf7, 0x99, 0x98, + 0x11, 0x6e, 0x6f, 0x62, 0x22, 0x6b, 0x92, 0x95, + 0x3b, 0xc3, 0xd2, 0x8e, 0x0f, 0x07, 0xc2, 0x51, + 0x5c, 0x4d, 0xb2, 0x6e, 0xc0, 0x27, 0x73, 0xcd, + 0x57, 0xb7, 0xf0, 0xe9, 0x2e, 0xc8, 0xe2, 0x0c, + 0xd1, 0xb5, 0x0f, 0xff, 0xf9, 0xec, 0x38, 0xba, + 0x97, 0xd6, 0x94, 0x9b, 0xd1, 0x79, 0xb6, 0x6a, + 0x01, 0x17, 0xe4, 0x7e, 0xa6, 0xd5, 0x86, 0x19, + 0xae, 0xf3, 0xf0, 0x62, 0x73, 0xc0, 0xf0, 0x0a, + 0x7a, 0x96, 0x93, 0x72, 0x89, 0x7e, 0x25, 0x57, + 0xf8, 0xf7, 0xd5, 0x1e, 0xe5, 0xac, 0xd6, 0x38, + 0x4f, 0xe8, 0x81, 0xd1, 0x53, 0x41, 0x07, 0x2d, + 0x58, 0x34, 0x1c, 0xef, 0x74, 0x2e, 0x61, 0xca, + 0xd3, 0xeb, 0xd6, 0x93, 0x0a, 0xf2, 0xf2, 0x86, + 0x9c, 0xe3, 0x7a, 0x52, 0xf5, 0x42, 0xf1, 0x8b, + 0x10, 0xf2, 0x25, 0x68, 0x7e, 0x61, 0xb1, 0x19, + 0xcf, 0x8f, 0x5a, 0x53, 0xb7, 0x68, 0x4f, 0x1a, + 0x71, 0xe9, 0x83, 0x91, 0x3a, 0x78, 0x0f, 0xf7, + 0xd4, 0x74, 0xf5, 0x06, 0xd2, 0x88, 0xb0, 0x06, + 0xe5, 0xc0, 0xfb, 0xb3, 0x91, 0xad, 0xc0, 0x84, + 0x31, 0xf2, 0x3a, 0xcf, 0x63, 0xe6, 0x4a, 0xd3, + 0x78, 0xbe, 0xde, 0x73, 0x3e, 0x02, 0x8e, 0xb8, + 0x3a, 0xf6, 0x55, 0xa7, 0xf8, 0x5a, 0xb5, 0x0e, + 0x0c, 0xc5, 0xe5, 0x66, 0xd5, 0xd2, 0x18, 0xf3, + 0xef, 0xa5, 0xc9, 0x68, 0x69, 0xe0, 0xcd, 0x00, + 0x33, 0x99, 0x6e, 0xea, 0xcb, 0x06, 0x7a, 0xe1, + 0xe1, 0x19, 0x0b, 0xe7, 0x08, 0xcd, 0x09, 0x1b, + 0x85, 0xec, 0xc4, 0xd4, 0x75, 0xf0, 0xd6, 0xfb, + 0x84, 0x95, 0x07, 0x44, 0xca, 0xa5, 0x2a, 0x6c, + 0xc2, 0x00, 0x58, 0x08, 0x87, 0x9e, 0x0a, 0xd4, + 0x06, 0xe2, 0x91, 0x5f, 0xb7, 0x1b, 0x11, 0xfa, + 0x85, 0xfc, 0x7c, 0xf2, 0x0f, 0x6e, 0x3c, 0x8a, + 0xe1, 0x0f, 0xa0, 0x33, 0x84, 0xce, 0x81, 0x4d, + 0x32, 0x4d, 0xeb, 0x41, 0xcf, 0x5a, 0x05, 0x60, + 0x47, 0x6c, 0x2a, 0xc4, 0x17, 0xd5, 0x16, 0x3a, + 0xe4, 0xe7, 0xab, 0x84, 0x94, 0x22, 0xff, 0x56, + 0xb0, 0x0c, 0x92, 0x6c, 0x19, 0x11, 0x4c, 0xb3, + 0xed, 0x58, 0x48, 0x84, 0x2a, 0xe2, 0x19, 0x2a, + 0xe1, 0xc0, 0x56, 0x82, 0x3c, 0x83, 0xb4, 0x58, + 0x2d, 0xf0, 0xb5, 0x1e, 0x76, 0x85, 0x51, 0xc2, + 0xe4, 0x95, 0x27, 0x96, 0xd1, 0x90, 0xc3, 0x17, + 0x75, 0xa1, 0xbb, 0x46, 0x5f, 0xa6, 0xf2, 0xef, + 0x71, 0x56, 0x92, 0xc5, 0x8a, 0x85, 0x52, 0xe4, + 0x63, 0x21, 0x6f, 0x55, 0x85, 0x2b, 0x6b, 0x0d, + 0xc9, 0x92, 0x77, 0x67, 0xe3, 0xff, 0x2a, 0x2b, + 0x90, 0x01, 0x3d, 0x74, 0x63, 0x04, 0x61, 0x3c, + 0x8e, 0xf8, 0xfc, 0x04, 0xdd, 0x21, 0x85, 0x92, + 0x1e, 0x4d, 0x51, 0x8d, 0xb5, 0x6b, 0xf1, 0xda, + 0x96, 0xf5, 0x8e, 0x3c, 0x38, 0x5a, 0xac, 0x9b, + 0xba, 0x0c, 0x84, 0x5d, 0x50, 0x12, 0xc7, 0xc5, + 0x7a, 0xcb, 0xb1, 0xfa, 0x16, 0x93, 0xdf, 0x98, + 0xda, 0x3f, 0x49, 0xa3, 0x94, 0x78, 0x70, 0xc7, + 0x0b, 0xb6, 0x91, 0xa6, 0x16, 0x2e, 0xcf, 0xfd, + 0x51, 0x6a, 0x5b, 0xad, 0x7a, 0xdd, 0xa9, 0x48, + 0x48, 0xac, 0xd6, 0x45, 0xbc, 0x23, 0x31, 0x1d, + 0x86, 0x54, 0x8a, 0x7f, 0x04, 0x97, 0x71, 0x9e, + 0xbc, 0x2e, 0x6b, 0xd9, 0x33, 0xc8, 0x20, 0xc9, + 0xe0, 0x25, 0x86, 0x59, 0x15, 0xcf, 0x63, 0xe5, + 0x99, 0xf1, 0x24, 0xf1, 0xba, 0xc4, 0x15, 0x02, + 0xe2, 0xdb, 0xfe, 0x4a, 0xf8, 0x3b, 0x91, 0x13, + 0x8d, 0x03, 0x81, 0x9f, 0xb3, 0x3f, 0x04, 0x03, + 0x58, 0xc0, 0xef, 0x27, 0x82, 0x14, 0xd2, 0x7f, + 0x93, 0x70, 0xb7, 0xb2, 0x02, 0x21, 0xb3, 0x07, + 0x7f, 0x1c, 0xef, 0x88, 0xee, 0x29, 0x7a, 0x0b, + 0x3d, 0x75, 0x5a, 0x93, 0xfe, 0x7f, 0x14, 0xf7, + 0x4e, 0x4b, 0x7f, 0x21, 0x02, 0xad, 0xf9, 0x43, + 0x29, 0x1a, 0xe8, 0x1b, 0xf5, 0x32, 0xb2, 0x96, + 0xe6, 0xe8, 0x96, 0x20, 0x9b, 0x96, 0x8e, 0x7b, + 0xfe, 0xd8, 0xc9, 0x9c, 0x65, 0x16, 0xd6, 0x68, + 0x95, 0xf8, 0x22, 0xe2, 0xae, 0x84, 0x03, 0xfd, + 0x87, 0xa2, 0x72, 0x79, 0x74, 0x95, 0xfa, 0xe1, + 0xfe, 0xd0, 0x4e, 0x3d, 0x39, 0x2e, 0x67, 0x55, + 0x71, 0x6c, 0x89, 0x33, 0x49, 0x0c, 0x1b, 0x46, + 0x92, 0x31, 0x6f, 0xa6, 0xf0, 0x09, 0xbd, 0x2d, + 0xe2, 0xca, 0xda, 0x18, 0x33, 0xce, 0x67, 0x37, + 0xfd, 0x6f, 0xcb, 0x9d, 0xbd, 0x42, 0xbc, 0xb2, + 0x9c, 0x28, 0xcd, 0x65, 0x3c, 0x61, 0xbc, 0xde, + 0x9d, 0xe1, 0x2a, 0x3e, 0xbf, 0xee, 0x3c, 0xcb, + 0xb1, 0x50, 0xa9, 0x2c, 0xbe, 0xb5, 0x43, 0xd0, + 0xec, 0x29, 0xf9, 0x16, 0x6f, 0x31, 0xd9, 0x9b, + 0x92, 0xb1, 0x32, 0xae, 0x0f, 0xb6, 0x9d, 0x0e, + 0x25, 0x7f, 0x89, 0x1f, 0x1d, 0x01, 0x68, 0xab, + 0x3d, 0xd1, 0x74, 0x5b, 0x4c, 0x38, 0x7f, 0x3d, + 0x33, 0xa5, 0xa2, 0x9f, 0xda, 0x84, 0xa5, 0x82, + 0x2d, 0x16, 0x66, 0x46, 0x08, 0x30, 0x14, 0x48, + 0x5e, 0xca, 0xe3, 0xf4, 0x8c, 0xcb, 0x32, 0xc6, + 0xf1, 0x43, 0x62, 0xc6, 0xef, 0x16, 0xfa, 0x43, + 0xae, 0x9c, 0x53, 0xe3, 0x49, 0x45, 0x80, 0xfd, + 0x1d, 0x8c, 0xa9, 0x6d, 0x77, 0x76, 0xaa, 0x40, + 0xc4, 0x4e, 0x7b, 0x78, 0x6b, 0xe0, 0x1d, 0xce, + 0x56, 0x3d, 0xf0, 0x11, 0xfe, 0x4f, 0x6a, 0x6d, + 0x0f, 0x4f, 0x90, 0x38, 0x92, 0x17, 0xfa, 0x56, + 0x12, 0xa6, 0xa1, 0x0a, 0xea, 0x2f, 0x50, 0xf9, + 0x60, 0x66, 0x6c, 0x7d, 0x5a, 0x08, 0x8e, 0x3c, + 0xf3, 0xf0, 0x33, 0x02, 0x11, 0x02, 0xfe, 0x4c, + 0x56, 0x2b, 0x9f, 0x0c, 0xbd, 0x65, 0x8a, 0x83, + 0xde, 0x7c, 0x05, 0x26, 0x93, 0x19, 0xcc, 0xf3, + 0x71, 0x0e, 0xad, 0x2f, 0xb3, 0xc9, 0x38, 0x50, + 0x64, 0xd5, 0x4c, 0x60, 0x5f, 0x02, 0x13, 0x34, + 0xc9, 0x75, 0xc4, 0x60, 0xab, 0x2e, 0x17, 0x7d +}; + +static const uint8_t AES_CBC_ciphertext_2048B[] = { + 0x8b, 0x55, 0xbd, 0xfd, 0x2b, 0x35, 0x76, 0x5c, + 0xd1, 0x90, 0xd7, 0x6a, 0x63, 0x1e, 0x39, 0x71, + 0x0d, 0x5c, 0xd8, 0x03, 0x00, 0x75, 0xf1, 0x07, + 0x03, 0x8d, 0x76, 0xeb, 0x3b, 0x00, 0x1e, 0x33, + 0x88, 0xfc, 0x8f, 0x08, 0x4d, 0x33, 0xf1, 0x3c, + 0xee, 0xd0, 0x5d, 0x19, 0x8b, 0x3c, 0x50, 0x86, + 0xfd, 0x8d, 0x58, 0x21, 0xb4, 0xae, 0x0f, 0x81, + 0xe9, 0x9f, 0xc9, 0xc0, 0x90, 0xf7, 0x04, 0x6f, + 0x39, 0x1d, 0x8a, 0x3f, 0x8d, 0x32, 0x23, 0xb5, + 0x1f, 0xcc, 0x8a, 0x12, 0x2d, 0x46, 0x82, 0x5e, + 0x6a, 0x34, 0x8c, 0xb1, 0x93, 0x70, 0x3b, 0xde, + 0x55, 0xaf, 0x16, 0x35, 0x99, 0x84, 0xd5, 0x88, + 0xc9, 0x54, 0xb1, 0xb2, 0xd3, 0xeb, 0x9e, 0x55, + 0x9a, 0xa9, 0xa7, 0xf5, 0xda, 0x29, 0xcf, 0xe1, + 0x98, 0x64, 0x45, 0x77, 0xf2, 0x12, 0x69, 0x8f, + 0x78, 0xd8, 0x82, 0x41, 0xb2, 0x9f, 0xe2, 0x1c, + 0x63, 0x9b, 0x24, 0x81, 0x67, 0x95, 0xa2, 0xff, + 0x26, 0x9d, 0x65, 0x48, 0x61, 0x30, 0x66, 0x41, + 0x68, 0x84, 0xbb, 0x59, 0x14, 0x8e, 0x9a, 0x62, + 0xb6, 0xca, 0xda, 0xbe, 0x7c, 0x41, 0x52, 0x6e, + 0x1b, 0x86, 0xbf, 0x08, 0xeb, 0x37, 0x84, 0x60, + 0xe4, 0xc4, 0x1e, 0xa8, 0x4c, 0x84, 0x60, 0x2f, + 0x70, 0x90, 0xf2, 0x26, 0xe7, 0x65, 0x0c, 0xc4, + 0x58, 0x36, 0x8e, 0x4d, 0xdf, 0xff, 0x9a, 0x39, + 0x93, 0x01, 0xcf, 0x6f, 0x6d, 0xde, 0xef, 0x79, + 0xb0, 0xce, 0xe2, 0x98, 0xdb, 0x85, 0x8d, 0x62, + 0x9d, 0xb9, 0x63, 0xfd, 0xf0, 0x35, 0xb5, 0xa9, + 0x1b, 0xf9, 0xe5, 0xd4, 0x2e, 0x22, 0x2d, 0xcc, + 0x42, 0xbf, 0x0e, 0x51, 0xf7, 0x15, 0x07, 0x32, + 0x75, 0x5b, 0x74, 0xbb, 0x00, 0xef, 0xd4, 0x66, + 0x8b, 0xad, 0x71, 0x53, 0x94, 0xd7, 0x7d, 0x2c, + 0x40, 0x3e, 0x69, 0xa0, 0x4c, 0x86, 0x5e, 0x06, + 0xed, 0xdf, 0x22, 0xe2, 0x24, 0x25, 0x4e, 0x9b, + 0x5f, 0x49, 0x74, 0xba, 0xed, 0xb1, 0xa6, 0xeb, + 0xae, 0x3f, 0xc6, 0x9e, 0x0b, 0x29, 0x28, 0x9a, + 0xb6, 0xb2, 0x74, 0x58, 0xec, 0xa6, 0x4a, 0xed, + 0xe5, 0x10, 0x00, 0x85, 0xe1, 0x63, 0x41, 0x61, + 0x30, 0x7c, 0x97, 0xcf, 0x75, 0xcf, 0xb6, 0xf3, + 0xf7, 0xda, 0x35, 0x3f, 0x85, 0x8c, 0x64, 0xca, + 0xb7, 0xea, 0x7f, 0xe4, 0xa3, 0x4d, 0x30, 0x84, + 0x8c, 0x9c, 0x80, 0x5a, 0x50, 0xa5, 0x64, 0xae, + 0x26, 0xd3, 0xb5, 0x01, 0x73, 0x36, 0x8a, 0x92, + 0x49, 0xc4, 0x1a, 0x94, 0x81, 0x9d, 0xf5, 0x6c, + 0x50, 0xe1, 0x58, 0x0b, 0x75, 0xdd, 0x6b, 0x6a, + 0xca, 0x69, 0xea, 0xc3, 0x33, 0x90, 0x9f, 0x3b, + 0x65, 0x5d, 0x5e, 0xee, 0x31, 0xb7, 0x32, 0xfd, + 0x56, 0x83, 0xb6, 0xfb, 0xa8, 0x04, 0xfc, 0x1e, + 0x11, 0xfb, 0x02, 0x23, 0x53, 0x49, 0x45, 0xb1, + 0x07, 0xfc, 0xba, 0xe7, 0x5f, 0x5d, 0x2d, 0x7f, + 0x9e, 0x46, 0xba, 0xe9, 0xb0, 0xdb, 0x32, 0x04, + 0xa4, 0xa7, 0x98, 0xab, 0x91, 0xcd, 0x02, 0x05, + 0xf5, 0x74, 0x31, 0x98, 0x83, 0x3d, 0x33, 0x11, + 0x0e, 0xe3, 0x8d, 0xa8, 0xc9, 0x0e, 0xf3, 0xb9, + 0x47, 0x67, 0xe9, 0x79, 0x2b, 0x34, 0xcd, 0x9b, + 0x45, 0x75, 0x29, 0xf0, 0xbf, 0xcc, 0xda, 0x3a, + 0x91, 0xb2, 0x15, 0x27, 0x7a, 0xe5, 0xf5, 0x6a, + 0x5e, 0xbe, 0x2c, 0x98, 0xe8, 0x40, 0x96, 0x4f, + 0x8a, 0x09, 0xfd, 0xf6, 0xb2, 0xe7, 0x45, 0xb6, + 0x08, 0xc1, 0x69, 0xe1, 0xb3, 0xc4, 0x24, 0x34, + 0x07, 0x85, 0xd5, 0xa9, 0x78, 0xca, 0xfa, 0x4b, + 0x01, 0x19, 0x4d, 0x95, 0xdc, 0xa5, 0xc1, 0x9c, + 0xec, 0x27, 0x5b, 0xa6, 0x54, 0x25, 0xbd, 0xc8, + 0x0a, 0xb7, 0x11, 0xfb, 0x4e, 0xeb, 0x65, 0x2e, + 0xe1, 0x08, 0x9c, 0x3a, 0x45, 0x44, 0x33, 0xef, + 0x0d, 0xb9, 0xff, 0x3e, 0x68, 0x9c, 0x61, 0x2b, + 0x11, 0xb8, 0x5c, 0x47, 0x0f, 0x94, 0xf2, 0xf8, + 0x0b, 0xbb, 0x99, 0x18, 0x85, 0xa3, 0xba, 0x44, + 0xf3, 0x79, 0xb3, 0x63, 0x2c, 0x1f, 0x2a, 0x35, + 0x3b, 0x23, 0x98, 0xab, 0xf4, 0x16, 0x36, 0xf8, + 0xde, 0x86, 0xa4, 0xd4, 0x75, 0xff, 0x51, 0xf9, + 0xeb, 0x42, 0x5f, 0x55, 0xe2, 0xbe, 0xd1, 0x5b, + 0xb5, 0x38, 0xeb, 0xb4, 0x4d, 0xec, 0xec, 0x99, + 0xe1, 0x39, 0x43, 0xaa, 0x64, 0xf7, 0xc9, 0xd8, + 0xf2, 0x9a, 0x71, 0x43, 0x39, 0x17, 0xe8, 0xa8, + 0xa2, 0xe2, 0xa4, 0x2c, 0x18, 0x11, 0x49, 0xdf, + 0x18, 0xdd, 0x85, 0x6e, 0x65, 0x96, 0xe2, 0xba, + 0xa1, 0x0a, 0x2c, 0xca, 0xdc, 0x5f, 0xe4, 0xf4, + 0x35, 0x03, 0xb2, 0xa9, 0xda, 0xcf, 0xb7, 0x6d, + 0x65, 0x82, 0x82, 0x67, 0x9d, 0x0e, 0xf3, 0xe8, + 0x85, 0x6c, 0x69, 0xb8, 0x4c, 0xa6, 0xc6, 0x2e, + 0x40, 0xb5, 0x54, 0x28, 0x95, 0xe4, 0x57, 0xe0, + 0x5b, 0xf8, 0xde, 0x59, 0xe0, 0xfd, 0x89, 0x48, + 0xac, 0x56, 0x13, 0x54, 0xb9, 0x1b, 0xf5, 0x59, + 0x97, 0xb6, 0xb3, 0xe8, 0xac, 0x2d, 0xfc, 0xd2, + 0xea, 0x57, 0x96, 0x57, 0xa8, 0x26, 0x97, 0x2c, + 0x01, 0x89, 0x56, 0xea, 0xec, 0x8c, 0x53, 0xd5, + 0xd7, 0x9e, 0xc9, 0x98, 0x0b, 0xad, 0x03, 0x75, + 0xa0, 0x6e, 0x98, 0x8b, 0x97, 0x8d, 0x8d, 0x85, + 0x7d, 0x74, 0xa7, 0x2d, 0xde, 0x67, 0x0c, 0xcd, + 0x54, 0xb8, 0x15, 0x7b, 0xeb, 0xf5, 0x84, 0xb9, + 0x78, 0xab, 0xd8, 0x68, 0x91, 0x1f, 0x6a, 0xa6, + 0x28, 0x22, 0xf7, 0x00, 0x49, 0x00, 0xbe, 0x41, + 0x71, 0x0a, 0xf5, 0xe7, 0x9f, 0xb4, 0x11, 0x41, + 0x3f, 0xcd, 0xa9, 0xa9, 0x01, 0x8b, 0x6a, 0xeb, + 0x54, 0x4c, 0x58, 0x92, 0x68, 0x02, 0x0e, 0xe9, + 0xed, 0x65, 0x4c, 0xfb, 0x95, 0x48, 0x58, 0xa2, + 0xaa, 0x57, 0x69, 0x13, 0x82, 0x0c, 0x2c, 0x4b, + 0x5d, 0x4e, 0x18, 0x30, 0xef, 0x1c, 0xb1, 0x9d, + 0x05, 0x05, 0x02, 0x1c, 0x97, 0xc9, 0x48, 0xfe, + 0x5e, 0x7b, 0x77, 0xa3, 0x1f, 0x2a, 0x81, 0x42, + 0xf0, 0x4b, 0x85, 0x12, 0x9c, 0x1f, 0x44, 0xb1, + 0x14, 0x91, 0x92, 0x65, 0x77, 0xb1, 0x87, 0xa2, + 0xfc, 0xa4, 0xe7, 0xd2, 0x9b, 0xf2, 0x17, 0xf0, + 0x30, 0x1c, 0x8d, 0x33, 0xbc, 0x25, 0x28, 0x48, + 0xfd, 0x30, 0x79, 0x0a, 0x99, 0x3e, 0xb4, 0x0f, + 0x1e, 0xa6, 0x68, 0x76, 0x19, 0x76, 0x29, 0xac, + 0x5d, 0xb8, 0x1e, 0x42, 0xd6, 0x85, 0x04, 0xbf, + 0x64, 0x1c, 0x2d, 0x53, 0xe9, 0x92, 0x78, 0xf8, + 0xc3, 0xda, 0x96, 0x92, 0x10, 0x6f, 0x45, 0x85, + 0xaf, 0x5e, 0xcc, 0xa8, 0xc0, 0xc6, 0x2e, 0x73, + 0x51, 0x3f, 0x5e, 0xd7, 0x52, 0x33, 0x71, 0x12, + 0x6d, 0x85, 0xee, 0xea, 0x85, 0xa8, 0x48, 0x2b, + 0x40, 0x64, 0x6d, 0x28, 0x73, 0x16, 0xd7, 0x82, + 0xd9, 0x90, 0xed, 0x1f, 0xa7, 0x5c, 0xb1, 0x5c, + 0x27, 0xb9, 0x67, 0x8b, 0xb4, 0x17, 0x13, 0x83, + 0x5f, 0x09, 0x72, 0x0a, 0xd7, 0xa0, 0xec, 0x81, + 0x59, 0x19, 0xb9, 0xa6, 0x5a, 0x37, 0x34, 0x14, + 0x47, 0xf6, 0xe7, 0x6c, 0xd2, 0x09, 0x10, 0xe7, + 0xdd, 0xbb, 0x02, 0xd1, 0x28, 0xfa, 0x01, 0x2c, + 0x93, 0x64, 0x2e, 0x1b, 0x4c, 0x02, 0x52, 0xcb, + 0x07, 0xa1, 0xb6, 0x46, 0x02, 0x80, 0xd9, 0x8f, + 0x5c, 0x62, 0xbe, 0x78, 0x9e, 0x75, 0xc4, 0x97, + 0x91, 0x39, 0x12, 0x65, 0xb9, 0x3b, 0xc2, 0xd1, + 0xaf, 0xf2, 0x1f, 0x4e, 0x4d, 0xd1, 0xf0, 0x9f, + 0xb7, 0x12, 0xfd, 0xe8, 0x75, 0x18, 0xc0, 0x9d, + 0x8c, 0x70, 0xff, 0x77, 0x05, 0xb6, 0x1a, 0x1f, + 0x96, 0x48, 0xf6, 0xfe, 0xd5, 0x5d, 0x98, 0xa5, + 0x72, 0x1c, 0x84, 0x76, 0x3e, 0xb8, 0x87, 0x37, + 0xdd, 0xd4, 0x3a, 0x45, 0xdd, 0x09, 0xd8, 0xe7, + 0x09, 0x2f, 0x3e, 0x33, 0x9e, 0x7b, 0x8c, 0xe4, + 0x85, 0x12, 0x4e, 0xf8, 0x06, 0xb7, 0xb1, 0x85, + 0x24, 0x96, 0xd8, 0xfe, 0x87, 0x92, 0x81, 0xb1, + 0xa3, 0x38, 0xb9, 0x56, 0xe1, 0xf6, 0x36, 0x41, + 0xbb, 0xd6, 0x56, 0x69, 0x94, 0x57, 0xb3, 0xa4, + 0xca, 0xa4, 0xe1, 0x02, 0x3b, 0x96, 0x71, 0xe0, + 0xb2, 0x2f, 0x85, 0x48, 0x1b, 0x4a, 0x41, 0x80, + 0x4b, 0x9c, 0xe0, 0xc9, 0x39, 0xb8, 0xb1, 0xca, + 0x64, 0x77, 0x46, 0x58, 0xe6, 0x84, 0xd5, 0x2b, + 0x65, 0xce, 0xe9, 0x09, 0xa3, 0xaa, 0xfb, 0x83, + 0xa9, 0x28, 0x68, 0xfd, 0xcd, 0xfd, 0x76, 0x83, + 0xe1, 0x20, 0x22, 0x77, 0x3a, 0xa3, 0xb2, 0x93, + 0x14, 0x91, 0xfc, 0xe2, 0x17, 0x63, 0x2b, 0xa6, + 0x29, 0x38, 0x7b, 0x9b, 0x8b, 0x15, 0x77, 0xd6, + 0xaa, 0x92, 0x51, 0x53, 0x50, 0xff, 0xa0, 0x35, + 0xa0, 0x59, 0x7d, 0xf0, 0x11, 0x23, 0x49, 0xdf, + 0x5a, 0x21, 0xc2, 0xfe, 0x35, 0xa0, 0x1d, 0xe2, + 0xae, 0xa2, 0x8a, 0x61, 0x5b, 0xf7, 0xf1, 0x1c, + 0x1c, 0xec, 0xc4, 0xf6, 0xdc, 0xaa, 0xc8, 0xc2, + 0xe5, 0xa1, 0x2e, 0x14, 0xe5, 0xc6, 0xc9, 0x73, + 0x03, 0x78, 0xeb, 0xed, 0xe0, 0x3e, 0xc5, 0xf4, + 0xf1, 0x50, 0xb2, 0x01, 0x91, 0x96, 0xf5, 0xbb, + 0xe1, 0x32, 0xcd, 0xa8, 0x66, 0xbf, 0x73, 0x85, + 0x94, 0xd6, 0x7e, 0x68, 0xc5, 0xe4, 0xed, 0xd5, + 0xe3, 0x67, 0x4c, 0xa5, 0xb3, 0x1f, 0xdf, 0xf8, + 0xb3, 0x73, 0x5a, 0xac, 0xeb, 0x46, 0x16, 0x24, + 0xab, 0xca, 0xa4, 0xdd, 0x87, 0x0e, 0x24, 0x83, + 0x32, 0x04, 0x4c, 0xd8, 0xda, 0x7d, 0xdc, 0xe3, + 0x01, 0x93, 0xf3, 0xc1, 0x5b, 0xbd, 0xc3, 0x1d, + 0x40, 0x62, 0xde, 0x94, 0x03, 0x85, 0x91, 0x2a, + 0xa0, 0x25, 0x10, 0xd3, 0x32, 0x9f, 0x93, 0x00, + 0xa7, 0x8a, 0xfa, 0x77, 0x7c, 0xaf, 0x4d, 0xc8, + 0x7a, 0xf3, 0x16, 0x2b, 0xba, 0xeb, 0x74, 0x51, + 0xb8, 0xdd, 0x32, 0xad, 0x68, 0x7d, 0xdd, 0xca, + 0x60, 0x98, 0xc9, 0x9b, 0xb6, 0x5d, 0x4d, 0x3a, + 0x66, 0x8a, 0xbe, 0x05, 0xf9, 0x0c, 0xc5, 0xba, + 0x52, 0x82, 0x09, 0x1f, 0x5a, 0x66, 0x89, 0x69, + 0xa3, 0x5d, 0x93, 0x50, 0x7d, 0x44, 0xc3, 0x2a, + 0xb8, 0xab, 0xec, 0xa6, 0x5a, 0xae, 0x4a, 0x6a, + 0xcd, 0xfd, 0xb6, 0xff, 0x3d, 0x98, 0x05, 0xd9, + 0x5b, 0x29, 0xc4, 0x6f, 0xe0, 0x76, 0xe2, 0x3f, + 0xec, 0xd7, 0xa4, 0x91, 0x63, 0xf5, 0x4e, 0x4b, + 0xab, 0x20, 0x8c, 0x3a, 0x41, 0xed, 0x8b, 0x4b, + 0xb9, 0x01, 0x21, 0xc0, 0x6d, 0xfd, 0x70, 0x5b, + 0x20, 0x92, 0x41, 0x89, 0x74, 0xb7, 0xe9, 0x8b, + 0xfc, 0x6d, 0x17, 0x3f, 0x7f, 0x89, 0x3d, 0x6b, + 0x8f, 0xbc, 0xd2, 0x57, 0xe9, 0xc9, 0x6e, 0xa7, + 0x19, 0x26, 0x18, 0xad, 0xef, 0xb5, 0x87, 0xbf, + 0xb8, 0xa8, 0xd6, 0x7d, 0xdd, 0x5f, 0x94, 0x54, + 0x09, 0x92, 0x2b, 0xf5, 0x04, 0xf7, 0x36, 0x69, + 0x8e, 0xf4, 0xdc, 0x1d, 0x6e, 0x55, 0xbb, 0xe9, + 0x13, 0x05, 0x83, 0x35, 0x9c, 0xed, 0xcf, 0x8c, + 0x26, 0x8c, 0x7b, 0xc7, 0x0b, 0xba, 0xfd, 0xe2, + 0x84, 0x5c, 0x2a, 0x79, 0x43, 0x99, 0xb2, 0xc3, + 0x82, 0x87, 0xc8, 0xcd, 0x37, 0x6d, 0xa1, 0x2b, + 0x39, 0xb2, 0x38, 0x99, 0xd9, 0xfc, 0x02, 0x15, + 0x55, 0x21, 0x62, 0x59, 0xeb, 0x00, 0x86, 0x08, + 0x20, 0xbe, 0x1a, 0x62, 0x4d, 0x7e, 0xdf, 0x68, + 0x73, 0x5b, 0x5f, 0xaf, 0x84, 0x96, 0x2e, 0x1f, + 0x6b, 0x03, 0xc9, 0xa6, 0x75, 0x18, 0xe9, 0xd4, + 0xbd, 0xc8, 0xec, 0x9a, 0x5a, 0xb3, 0x99, 0xab, + 0x5f, 0x7c, 0x08, 0x7f, 0x69, 0x4d, 0x52, 0xa2, + 0x30, 0x17, 0x3b, 0x16, 0x15, 0x1b, 0x11, 0x62, + 0x3e, 0x80, 0x4b, 0x85, 0x7c, 0x9c, 0xd1, 0x3a, + 0x13, 0x01, 0x5e, 0x45, 0xf1, 0xc8, 0x5f, 0xcd, + 0x0e, 0x21, 0xf5, 0x82, 0xd4, 0x7b, 0x5c, 0x45, + 0x27, 0x6b, 0xef, 0xfe, 0xb8, 0xc0, 0x6f, 0xdc, + 0x60, 0x7b, 0xe4, 0xd5, 0x75, 0x71, 0xe6, 0xe8, + 0x7d, 0x6b, 0x6d, 0x80, 0xaf, 0x76, 0x41, 0x58, + 0xb7, 0xac, 0xb7, 0x13, 0x2f, 0x81, 0xcc, 0xf9, + 0x19, 0x97, 0xe8, 0xee, 0x40, 0x91, 0xfc, 0x89, + 0x13, 0x1e, 0x67, 0x9a, 0xdb, 0x8f, 0x8f, 0xc7, + 0x4a, 0xc9, 0xaf, 0x2f, 0x67, 0x01, 0x3c, 0xb8, + 0xa8, 0x3e, 0x78, 0x93, 0x1b, 0xdf, 0xbb, 0x34, + 0x0b, 0x1a, 0xfa, 0xc2, 0x2d, 0xc5, 0x1c, 0xec, + 0x97, 0x4f, 0x48, 0x41, 0x15, 0x0e, 0x75, 0xed, + 0x66, 0x8c, 0x17, 0x7f, 0xb1, 0x48, 0x13, 0xc1, + 0xfb, 0x60, 0x06, 0xf9, 0x72, 0x41, 0x3e, 0xcf, + 0x6e, 0xb6, 0xc8, 0xeb, 0x4b, 0x5a, 0xd2, 0x0c, + 0x28, 0xda, 0x02, 0x7a, 0x46, 0x21, 0x42, 0xb5, + 0x34, 0xda, 0xcb, 0x5e, 0xbd, 0x66, 0x5c, 0xca, + 0xff, 0x52, 0x43, 0x89, 0xf9, 0x10, 0x9a, 0x9e, + 0x9b, 0xe3, 0xb0, 0x51, 0xe9, 0xf3, 0x0a, 0x35, + 0x77, 0x54, 0xcc, 0xac, 0xa6, 0xf1, 0x2e, 0x36, + 0x89, 0xac, 0xc5, 0xc6, 0x62, 0x5a, 0xc0, 0x6d, + 0xc4, 0xe1, 0xf7, 0x64, 0x30, 0xff, 0x11, 0x40, + 0x13, 0x89, 0xd8, 0xd7, 0x73, 0x3f, 0x93, 0x08, + 0x68, 0xab, 0x66, 0x09, 0x1a, 0xea, 0x78, 0xc9, + 0x52, 0xf2, 0xfd, 0x93, 0x1b, 0x94, 0xbe, 0x5c, + 0xe5, 0x00, 0x6e, 0x00, 0xb9, 0xea, 0x27, 0xaa, + 0xb3, 0xee, 0xe3, 0xc8, 0x6a, 0xb0, 0xc1, 0x8e, + 0x9b, 0x54, 0x40, 0x10, 0x96, 0x06, 0xe8, 0xb3, + 0xf5, 0x55, 0x77, 0xd7, 0x5c, 0x94, 0xc1, 0x74, + 0xf3, 0x07, 0x64, 0xac, 0x1c, 0xde, 0xc7, 0x22, + 0xb0, 0xbf, 0x2a, 0x5a, 0xc0, 0x8f, 0x8a, 0x83, + 0x50, 0xc2, 0x5e, 0x97, 0xa0, 0xbe, 0x49, 0x7e, + 0x47, 0xaf, 0xa7, 0x20, 0x02, 0x35, 0xa4, 0x57, + 0xd9, 0x26, 0x63, 0xdb, 0xf1, 0x34, 0x42, 0x89, + 0x36, 0xd1, 0x77, 0x6f, 0xb1, 0xea, 0x79, 0x7e, + 0x95, 0x10, 0x5a, 0xee, 0xa3, 0xae, 0x6f, 0xba, + 0xa9, 0xef, 0x5a, 0x7e, 0x34, 0x03, 0x04, 0x07, + 0x92, 0xd6, 0x07, 0x79, 0xaa, 0x14, 0x90, 0x97, + 0x05, 0x4d, 0xa6, 0x27, 0x10, 0x5c, 0x25, 0x24, + 0xcb, 0xcc, 0xf6, 0x77, 0x9e, 0x43, 0x23, 0xd4, + 0x98, 0xef, 0x22, 0xa8, 0xad, 0xf2, 0x26, 0x08, + 0x59, 0x69, 0xa4, 0xc3, 0x97, 0xe0, 0x5c, 0x6f, + 0xeb, 0x3d, 0xd4, 0x62, 0x6e, 0x80, 0x61, 0x02, + 0xf4, 0xfc, 0x94, 0x79, 0xbb, 0x4e, 0x6d, 0xd7, + 0x30, 0x5b, 0x10, 0x11, 0x5a, 0x3d, 0xa7, 0x50, + 0x1d, 0x9a, 0x13, 0x5f, 0x4f, 0xa8, 0xa7, 0xb6, + 0x39, 0xc7, 0xea, 0xe6, 0x19, 0x61, 0x69, 0xc7, + 0x9a, 0x3a, 0xeb, 0x9d, 0xdc, 0xf7, 0x06, 0x37, + 0xbd, 0xac, 0xe3, 0x18, 0xff, 0xfe, 0x11, 0xdb, + 0x67, 0x42, 0xb4, 0xea, 0xa8, 0xbd, 0xb0, 0x76, + 0xd2, 0x74, 0x32, 0xc2, 0xa4, 0x9c, 0xe7, 0x60, + 0xc5, 0x30, 0x9a, 0x57, 0x66, 0xcd, 0x0f, 0x02, + 0x4c, 0xea, 0xe9, 0xd3, 0x2a, 0x5c, 0x09, 0xc2, + 0xff, 0x6a, 0xde, 0x5d, 0xb7, 0xe9, 0x75, 0x6b, + 0x29, 0x94, 0xd6, 0xf7, 0xc3, 0xdf, 0xfb, 0x70, + 0xec, 0xb5, 0x8c, 0xb0, 0x78, 0x7a, 0xee, 0x52, + 0x5f, 0x8c, 0xae, 0x85, 0xe5, 0x98, 0xa2, 0xb7, + 0x7c, 0x02, 0x2a, 0xcc, 0x9e, 0xde, 0x99, 0x5f, + 0x84, 0x20, 0xbb, 0xdc, 0xf2, 0xd2, 0x13, 0x46, + 0x3c, 0xd6, 0x4d, 0xe7, 0x50, 0xef, 0x55, 0xc3, + 0x96, 0x9f, 0xec, 0x6c, 0xd8, 0xe2, 0xea, 0xed, + 0xc7, 0x33, 0xc9, 0xb3, 0x1c, 0x4f, 0x1d, 0x83, + 0x1d, 0xe4, 0xdd, 0xb2, 0x24, 0x8f, 0xf9, 0xf5 +}; + + +static const uint8_t HMAC_SHA256_ciphertext_64B_digest[] = { + 0xc5, 0x6d, 0x4f, 0x29, 0xf4, 0xd2, 0xcc, 0x87, + 0x3c, 0x81, 0x02, 0x6d, 0x38, 0x7a, 0x67, 0x3e, + 0x95, 0x9c, 0x5c, 0x8f, 0xda, 0x5c, 0x06, 0xe0, + 0x65, 0xf1, 0x6c, 0x51, 0x52, 0x49, 0x3e, 0x5f +}; + +static const uint8_t HMAC_SHA256_ciphertext_128B_digest[] = { + 0x76, 0x64, 0x2d, 0x69, 0x71, 0x5d, 0x6a, 0xd8, + 0x9f, 0x74, 0x11, 0x2f, 0x58, 0xe0, 0x4a, 0x2f, + 0x6c, 0x88, 0x5e, 0x4d, 0x9c, 0x79, 0x83, 0x1c, + 0x8a, 0x14, 0xd0, 0x07, 0xfb, 0xbf, 0x6c, 0x8f +}; + +static const uint8_t HMAC_SHA256_ciphertext_256B_digest[] = { + 0x05, 0xa7, 0x44, 0xcd, 0x91, 0x8c, 0x95, 0xcf, + 0x7b, 0x8f, 0xd3, 0x90, 0x86, 0x7e, 0x7b, 0xb9, + 0x05, 0xd6, 0x6e, 0x7a, 0xc1, 0x7b, 0x26, 0xff, + 0xd3, 0x4b, 0xe0, 0x22, 0x8b, 0xa8, 0x47, 0x52 +}; + +static const uint8_t HMAC_SHA256_ciphertext_512B_digest[] = { + 0x08, 0xb7, 0x29, 0x54, 0x18, 0x7e, 0x97, 0x49, + 0xc6, 0x7c, 0x9f, 0x94, 0xa5, 0x4f, 0xa2, 0x25, + 0xd0, 0xe2, 0x30, 0x7b, 0xad, 0x93, 0xc9, 0x12, + 0x0f, 0xf0, 0xf0, 0x71, 0xc2, 0xf6, 0x53, 0x8f +}; + +static const uint8_t HMAC_SHA256_ciphertext_768B_digest[] = { + 0xe4, 0x3e, 0x73, 0x93, 0x03, 0xaf, 0x6f, 0x9c, + 0xca, 0x57, 0x3b, 0x4a, 0x6e, 0x83, 0x58, 0xf5, + 0x66, 0xc2, 0xb4, 0xa7, 0xe0, 0xee, 0x63, 0x6b, + 0x48, 0xb7, 0x50, 0x45, 0x69, 0xdf, 0x5c, 0x5b +}; + +static const uint8_t HMAC_SHA256_ciphertext_1024B_digest[] = { + 0x03, 0xb9, 0x96, 0x26, 0xdc, 0x1c, 0xab, 0xe2, + 0xf5, 0x70, 0x55, 0x15, 0x67, 0x6e, 0x48, 0x11, + 0xe7, 0x67, 0xea, 0xfa, 0x5c, 0x6b, 0x28, 0x22, + 0xc9, 0x0e, 0x67, 0x04, 0xb3, 0x71, 0x7f, 0x88 +}; + +static const uint8_t HMAC_SHA256_ciphertext_1280B_digest[] = { + 0x01, 0x91, 0xb8, 0x78, 0xd3, 0x21, 0x74, 0xa5, + 0x1c, 0x8b, 0xd4, 0xd2, 0xc0, 0x49, 0xd7, 0xd2, + 0x16, 0x46, 0x66, 0x85, 0x50, 0x6d, 0x08, 0xcc, + 0xc7, 0x0a, 0xa3, 0x71, 0xcc, 0xde, 0xee, 0xdc +}; + +static const uint8_t HMAC_SHA256_ciphertext_1536B_digest[] = { + 0xf2, 0xe5, 0xe9, 0x57, 0x53, 0xd7, 0x69, 0x28, + 0x7b, 0x69, 0xb5, 0x49, 0xa3, 0x31, 0x56, 0x5f, + 0xa4, 0xe9, 0x87, 0x26, 0x2f, 0xe0, 0x2d, 0xd6, + 0x08, 0x44, 0x01, 0x71, 0x0c, 0x93, 0x85, 0x84 +}; + +static const uint8_t HMAC_SHA256_ciphertext_1792B_digest[] = { + 0xf6, 0x57, 0x62, 0x01, 0xbf, 0x2d, 0xea, 0x4a, + 0xef, 0x43, 0x85, 0x60, 0x18, 0xdf, 0x8b, 0xb4, + 0x60, 0xc0, 0xfd, 0x2f, 0x90, 0x15, 0xe6, 0x91, + 0x56, 0x61, 0x68, 0x7f, 0x5e, 0x92, 0xa8, 0xdd +}; + +static const uint8_t HMAC_SHA256_ciphertext_2048B_digest[] = { + 0x81, 0x1a, 0x29, 0xbc, 0x6b, 0x9f, 0xbb, 0xb8, + 0xef, 0x71, 0x7b, 0x1f, 0x6f, 0xd4, 0x7e, 0x68, + 0x3a, 0x9c, 0xb9, 0x98, 0x22, 0x81, 0xfa, 0x95, + 0xee, 0xbc, 0x7f, 0x23, 0x29, 0x88, 0x76, 0xb8 +}; + +struct crypto_data_params { + const char *name; + uint16_t length; + const char *plaintext; + struct crypto_expected_output { + const uint8_t *ciphertext; + const uint8_t *digest; + } expected; +}; + +#define MAX_PACKET_SIZE_INDEX 10 + +struct crypto_data_params aes_cbc_hmac_sha256_output[MAX_PACKET_SIZE_INDEX] = { + { "64B", 64, &plaintext_quote[sizeof(plaintext_quote) - 1 - 64], + { AES_CBC_ciphertext_64B, HMAC_SHA256_ciphertext_64B_digest } }, + { "128B", 128, &plaintext_quote[sizeof(plaintext_quote) - 1 - 128], + { AES_CBC_ciphertext_128B, HMAC_SHA256_ciphertext_128B_digest } }, + { "256B", 256, &plaintext_quote[sizeof(plaintext_quote) - 1 - 256], + { AES_CBC_ciphertext_256B, HMAC_SHA256_ciphertext_256B_digest } }, + { "512B", 512, &plaintext_quote[sizeof(plaintext_quote) - 1 - 512], + { AES_CBC_ciphertext_512B, HMAC_SHA256_ciphertext_512B_digest } }, + { "768B", 768, &plaintext_quote[sizeof(plaintext_quote) - 1 - 768], + { AES_CBC_ciphertext_768B, HMAC_SHA256_ciphertext_768B_digest } }, + { "1024B", 1024, &plaintext_quote[sizeof(plaintext_quote) - 1 - 1024], + { AES_CBC_ciphertext_1024B, HMAC_SHA256_ciphertext_1024B_digest } }, + { "1280B", 1280, &plaintext_quote[sizeof(plaintext_quote) - 1 - 1280], + { AES_CBC_ciphertext_1280B, HMAC_SHA256_ciphertext_1280B_digest } }, + { "1536B", 1536, &plaintext_quote[sizeof(plaintext_quote) - 1 - 1536], + { AES_CBC_ciphertext_1536B, HMAC_SHA256_ciphertext_1536B_digest } }, + { "1792B", 1792, &plaintext_quote[sizeof(plaintext_quote) - 1 - 1792], + { AES_CBC_ciphertext_1792B, HMAC_SHA256_ciphertext_1792B_digest } }, + { "2048B", 2048, &plaintext_quote[sizeof(plaintext_quote) - 1 - 2048], + { AES_CBC_ciphertext_2048B, HMAC_SHA256_ciphertext_2048B_digest } } +}; + +static int +test_perf_crypto_qp_vary_burst_size(uint16_t dev_num) +{ + uint32_t num_to_submit = 4096; + 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, burst_received; + uint32_t i, burst_size, num_sent, num_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; + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices available. Is kernel driver loaded?\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; + + 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_128_key; + ut_params->cipher_xform.cipher.key.length = CIPHER_IV_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_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->dev_id, + &ut_params->cipher_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + /* Generate Crypto op data structure(s) */ + for (i = 0; i < num_to_submit ; i++) { + struct rte_mbuf *m = setup_test_string(ts_params->mbuf_mp, + data_params[0].expected.ciphertext, + data_params[0].length, 0); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); + + 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"); + + rte_memcpy(ut_params->digest, data_params[0].expected.digest, + DIGEST_BYTE_LENGTH_SHA256); + + + struct rte_crypto_op *op = + rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + + rte_crypto_op_attach_sym_session(op, ut_params->sess); + + op->sym->auth.digest.data = ut_params->digest; + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, + data_params[0].length); + op->sym->auth.digest.length = DIGEST_BYTE_LENGTH_SHA256; + + op->sym->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; + op->sym->auth.data.length = data_params[0].length; + + + 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; + + 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; + op->sym->cipher.data.length = data_params[0].length; + + op->sym->m_src = m; + + c_ops[i] = op; + } + + printf("\nTest to measure the IA cycle cost using AES128_CBC_SHA256_HMAC " + "algorithm with a constant request size of %u.", + data_params[0].length); + printf("\nThis test will keep retries at 0 and only measure IA cycle " + "cost for each request."); + printf("\nDev No\tQP No\tNum Sent\tNum Received\tTx/Rx burst"); + printf("\tRetries (Device Busy)\tAverage IA cycle cost " + "(assuming 0 retries)"); + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 0; + num_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(dev_num, + 0, &c_ops[num_sent], + ((num_to_submit-num_sent) < burst_size) ? + num_to_submit-num_sent : burst_size); + if (burst_sent == 0) + retries++; + else + num_sent += burst_sent; + end_cycles = rte_rdtsc_precise(); + 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( + dev_num, 0, proc_ops, burst_size); + if (burst_received == 0) + failed_polls++; + else + num_received += burst_received; + end_cycles = rte_rdtsc_precise(); + total_cycles += end_cycles - start_cycles; + } + + while (num_received != num_to_submit) { + if (gbl_cryptodev_perftest_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, burst_size); + if (burst_received == 0) + failed_polls++; + else + num_received += burst_received; + } + + printf("\n%u\t%u\t%u\t\t%u\t\t%u", dev_num, 0, + num_sent, num_received, burst_size); + printf("\t\t%"PRIu64, retries); + printf("\t\t\t%"PRIu64, total_cycles/num_received); + } + 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_optimise_cyclecount(struct perf_test_params *pparams) +{ + 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; + 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 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"); + + 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"); + + 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"); + + c_ops[i] = op; + } + + 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"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 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]); + } + rte_cryptodev_sym_session_free(ts_params->dev_id, sess); + + 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 int +test_perf_openssl_optimise_cyclecount(struct perf_test_params *pparams) +{ + 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; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, + unsigned int, unsigned int, + enum chain_mode); + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_openssl_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 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"); + + 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"); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = + test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + op = test_perf_set_crypto_op(op, m, sess, pparams->buf_size, + digest_length, pparams->chain); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); + + c_ops[i] = op; + } + + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " + "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), + pparams->cipher_key_length, + auth_algo_name(pparams->auth_algo), + pparams->buf_size); + printf("\nOps Tx\tOps Rx\tOps/burst "); + printf("Retries EmptyPolls\tIACycles/CyOp\tIACycles/Burst\t" + "IACycles/Byte"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 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) { + /* Sending 0 length burst to flush sw crypto device */ + 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]); + } + rte_cryptodev_sym_session_free(ts_params->dev_id, sess); + + return TEST_SUCCESS; +} + +static int +test_perf_armv8_optimise_cyclecount(struct perf_test_params *pparams) +{ + 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; + uint32_t nb_ops; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_armv8_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 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"); + + 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"); + + op = test_perf_set_crypto_op_aes(op, m, sess, pparams->buf_size, + digest_length, pparams->chain); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); + + c_ops[i] = op; + } + + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " + "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), + pparams->cipher_key_length, + 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"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 0; + num_ops_received = 0; + retries = 0; + failed_polls = 0; + burst_size = i; + total_cycles = 0; + while (num_sent < num_to_submit) { + if ((num_to_submit - num_sent) < burst_size) + nb_ops = num_to_submit - num_sent; + else + nb_ops = burst_size; + + start_cycles = rte_rdtsc(); + burst_sent = rte_cryptodev_enqueue_burst( + ts_params->dev_id, + 0, &c_ops[num_sent], + nb_ops); + end_cycles = rte_rdtsc(); + + if (burst_sent == 0) + retries++; + num_sent += burst_sent; + total_cycles += (end_cycles - start_cycles); + + start_cycles = rte_rdtsc(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, + burst_size); + end_cycles = rte_rdtsc(); + 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) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst( + ts_params->dev_id, 0, NULL, 0); + + start_cycles = rte_rdtsc(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc(); + + 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 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; + case RTE_CRYPTO_AUTH_AES_GCM: + return 0; + 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; + case RTE_CRYPTO_AUTH_AES_GCM: + return DIGEST_BYTE_LENGTH_AES_GCM; + default: + return 0; + } +} + +static uint8_t aes_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_iv[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static uint8_t triple_des_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, +}; + +static uint8_t triple_des_iv[] = { + 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_key; + cipher_xform.cipher.key.length = cipher_key_len; + if (chain != CIPHER_ONLY) { + /* 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); + case CIPHER_ONLY: + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + default: + return NULL; + } +} + +#define SNOW3G_CIPHER_IV_LENGTH 16 + +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.add_auth_data_length = SNOW3G_CIPHER_IV_LENGTH; + 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; + } +} + +static struct rte_cryptodev_sym_session * +test_perf_create_openssl_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int 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; + + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + cipher_xform.cipher.key.data = triple_des_key; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + cipher_xform.cipher.key.data = aes_key; + break; + default: + return NULL; + } + + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup Auth Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + switch (auth_algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + auth_xform.auth.key.data = hmac_sha_key; + break; + case RTE_CRYPTO_AUTH_AES_GCM: + auth_xform.auth.key.data = NULL; + break; + default: + return NULL; + } + + 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_armv8_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int 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; + + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_AES_CBC: + cipher_xform.cipher.key.data = aes_cbc_128_key; + break; + default: + return NULL; + } + + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup Auth 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.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Encrypt and hash the result */ + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + /* 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; + /* Hash encrypted message and decrypt */ + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + +#define AES_BLOCK_SIZE 16 +#define AES_CIPHER_IV_LENGTH 16 + +#define TRIPLE_DES_BLOCK_SIZE 8 +#define TRIPLE_DES_CIPHER_IV_LENGTH 8 + +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_aes(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len, enum chain_mode chain) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + if (chain == CIPHER_ONLY) { + op->sym->auth.digest.data = NULL; + op->sym->auth.digest.phys_addr = 0; + op->sym->auth.digest.length = 0; + op->sym->auth.aad.data = NULL; + op->sym->auth.aad.length = 0; + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = 0; + } else { + op->sym->auth.digest.data = rte_pktmbuf_mtod_offset(m, + uint8_t *, AES_CIPHER_IV_LENGTH + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, + AES_CIPHER_IV_LENGTH + data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; + op->sym->auth.data.offset = AES_CIPHER_IV_LENGTH; + op->sym->auth.data.length = data_len; + } + + + /* Cipher Parameters */ + op->sym->cipher.iv.data = rte_pktmbuf_mtod(m, uint8_t *); + op->sym->cipher.iv.phys_addr = rte_pktmbuf_mtophys(m); + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; + + rte_memcpy(op->sym->cipher.iv.data, aes_iv, AES_CIPHER_IV_LENGTH); + + op->sym->cipher.data.offset = AES_CIPHER_IV_LENGTH; + op->sym->cipher.data.length = data_len; + + op->sym->m_src = m; + + return op; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len, enum chain_mode chain __rte_unused) +{ + 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 = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = AES_BLOCK_SIZE; + op->sym->auth.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->m_src = m; + + 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; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_snow3g_cipher(struct rte_crypto_op *op, + struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, + unsigned data_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Cipher Parameters */ + op->sym->cipher.iv.data = rte_pktmbuf_mtod(m, uint8_t *); + op->sym->cipher.iv.length = SNOW3G_CIPHER_IV_LENGTH; + rte_memcpy(op->sym->cipher.iv.data, snow3g_iv, SNOW3G_CIPHER_IV_LENGTH); + op->sym->cipher.iv.phys_addr = rte_pktmbuf_mtophys(m); + + op->sym->cipher.data.offset = SNOW3G_CIPHER_IV_LENGTH; + op->sym->cipher.data.length = data_len << 3; + + op->sym->m_src = m; + + return op; +} + + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_snow3g_hash(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 *)rte_pktmbuf_mtod_offset(m, uint8_t *, + data_len); + op->sym->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(m, data_len + + SNOW3G_CIPHER_IV_LENGTH); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = rte_pktmbuf_mtod(m, uint8_t *); + op->sym->auth.aad.length = SNOW3G_CIPHER_IV_LENGTH; + rte_memcpy(op->sym->auth.aad.data, snow3g_iv, + SNOW3G_CIPHER_IV_LENGTH); + op->sym->auth.aad.phys_addr = rte_pktmbuf_mtophys(m); + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = SNOW3G_CIPHER_IV_LENGTH; + op->sym->auth.data.length = data_len << 3; + + op->sym->m_src = m; + + return op; +} + + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len, enum chain_mode chain __rte_unused) +{ + 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 = triple_des_iv; + op->sym->auth.aad.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = triple_des_iv; + op->sym->cipher.iv.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = data_len; + + op->sym->cipher.data.offset = TRIPLE_DES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - TRIPLE_DES_BLOCK_SIZE; + + 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; + + 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 * 8]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + 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; + } + + /* 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; + } + + /* Make room for Digest and IV in mbuf */ + if (pparams->chain != CIPHER_ONLY) + rte_pktmbuf_append(mbufs[i], digest_length); + rte_pktmbuf_prepend(mbufs[i], AES_CIPHER_IV_LENGTH); + } + + + 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_aes(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], + sess, pparams->buf_size, digest_length, + pparams->chain); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, 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 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]); + rte_cryptodev_sym_session_free(dev_id, sess); + + 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++) { + /* + * Buffer size + iv/aad len is allocated, for perf tests they + * are equal + digest len. + */ + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size + SNOW3G_CIPHER_IV_LENGTH + + digest_length); + + 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++) { + if (pparams->chain == HASH_ONLY) + ops[i+op_offset] = + test_perf_set_crypto_op_snow3g_hash(ops[i+op_offset], + mbufs[i + + (pparams->burst_size * (j % NUM_MBUF_SETS))], + sess, + pparams->buf_size, digest_length); + else if (pparams->chain == CIPHER_ONLY) + ops[i+op_offset] = + test_perf_set_crypto_op_snow3g_cipher(ops[i+op_offset], + mbufs[i + + (pparams->burst_size * (j % NUM_MBUF_SETS))], + sess, + pparams->buf_size); + else + return 1; + } + + /* 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]); + rte_cryptodev_sym_session_free(dev_id, sess); + + printf("\n"); + return TEST_SUCCESS; +} + +static int +test_perf_openssl(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; + + unsigned int 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; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, + unsigned int, unsigned int, + enum chain_mode); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_openssl_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; + + 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, + pparams->chain); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, 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 throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) + / 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]); + rte_cryptodev_sym_session_free(dev_id, sess); + + printf("\n"); + return TEST_SUCCESS; +} + +static int +test_perf_armv8(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; + uint16_t burst_size; + uint16_t ops_needed; + + 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; + + unsigned int 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"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_armv8_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(); + + while (total_enqueued < pparams->total_operations) { + if ((total_enqueued + pparams->burst_size) <= + pparams->total_operations) + burst_size = pparams->burst_size; + else + burst_size = pparams->total_operations - total_enqueued; + + 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_aes(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], sess, + pparams->buf_size, digest_length, + pparams->chain); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, 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(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) + * rte_get_tsc_hz(); + double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) + / 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; +} + +/* + + 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_ONLY, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_NULL + }, + { + .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_snow3G_vary_pkt_size(void) +{ + 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_openssl_vary_pkt_size(void) +{ + unsigned int total_operations = 10000; + unsigned int burst_size = { 64 }; + unsigned int 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_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + 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)\tRetries\t" + "EmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_openssl(testsuite_params.dev_id, 0, + ¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_openssl_vary_burst_size(void) +{ + unsigned int total_operations = 4096; + uint16_t buf_lengths[] = { 40 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + 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_openssl_optimise_cyclecount(¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_armv8_vary_pkt_size(void) +{ + unsigned int total_operations = 100000; + unsigned int burst_size = { 64 }; + unsigned int 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 = HASH_CIPHER, + + .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 = HASH_CIPHER, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_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)\tRetries\t" + "EmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_armv8(testsuite_params.dev_id, 0, + ¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_armv8_vary_burst_size(void) +{ + unsigned int total_operations = 4096; + uint16_t buf_lengths[] = { 64 }; + 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 = HASH_CIPHER, + + .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 = HASH_CIPHER, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC + }, + }; + + 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_armv8_optimise_cyclecount(¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_aes_cbc_vary_burst_size(void) +{ + return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id); +} + + +static struct rte_cryptodev_sym_session * +test_perf_create_session(uint8_t dev_id, struct perf_test_params *pparams) +{ + static struct rte_cryptodev_sym_session *sess; + struct rte_crypto_sym_xform cipher_xform = { 0 }; + struct rte_crypto_sym_xform auth_xform = { 0 }; + + uint8_t cipher_key[pparams->session_attrs->key_cipher_len]; + uint8_t auth_key[pparams->session_attrs->key_auth_len]; + + memcpy(cipher_key, pparams->session_attrs->key_cipher_data, + pparams->session_attrs->key_cipher_len); + memcpy(auth_key, pparams->session_attrs->key_auth_data, + pparams->session_attrs->key_auth_len); + + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.next = NULL; + + cipher_xform.cipher.algo = pparams->session_attrs->cipher_algorithm; + cipher_xform.cipher.op = pparams->session_attrs->cipher; + cipher_xform.cipher.key.data = cipher_key; + cipher_xform.cipher.key.length = pparams->session_attrs->key_cipher_len; + + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.next = NULL; + + auth_xform.auth.op = pparams->session_attrs->auth; + auth_xform.auth.algo = pparams->session_attrs->auth_algorithm; + + auth_xform.auth.digest_length = pparams->session_attrs->digest_len; + auth_xform.auth.key.length = pparams->session_attrs->key_auth_len; + + + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + if (cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { + cipher_xform.next = &auth_xform; + sess = rte_cryptodev_sym_session_create(dev_id, + &cipher_xform); + } else { + auth_xform.next = &cipher_xform; + sess = rte_cryptodev_sym_session_create(dev_id, + &auth_xform); + } + + return sess; +} + +static inline struct rte_crypto_op * +perf_gcm_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, + struct crypto_params *m_hlp, + struct perf_test_params *params) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + uint16_t iv_pad_len = ALIGN_POW2_ROUNDUP(params->symmetric_op->iv_len, + 16); + + op->sym->auth.digest.data = m_hlp->digest; + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + m, + params->symmetric_op->aad_len + + iv_pad_len + + params->symmetric_op->p_len); + + op->sym->auth.digest.length = params->symmetric_op->t_len; + + op->sym->auth.aad.data = m_hlp->aad; + op->sym->auth.aad.length = params->symmetric_op->aad_len; + op->sym->auth.aad.phys_addr = rte_pktmbuf_mtophys_offset( + m, + iv_pad_len); + + rte_memcpy(op->sym->auth.aad.data, params->symmetric_op->aad_data, + params->symmetric_op->aad_len); + + op->sym->cipher.iv.data = m_hlp->iv; + rte_memcpy(op->sym->cipher.iv.data, params->symmetric_op->iv_data, + params->symmetric_op->iv_len); + if (params->symmetric_op->iv_len == 12) + op->sym->cipher.iv.data[15] = 1; + + op->sym->cipher.iv.length = params->symmetric_op->iv_len; + + op->sym->auth.data.offset = + iv_pad_len + params->symmetric_op->aad_len; + op->sym->auth.data.length = params->symmetric_op->p_len; + + op->sym->cipher.data.offset = + iv_pad_len + params->symmetric_op->aad_len; + op->sym->cipher.data.length = params->symmetric_op->p_len; + + op->sym->m_src = m; + + return op; +} + +static struct rte_mbuf * +test_perf_create_pktmbuf_fill(struct rte_mempool *mpool, + struct perf_test_params *params, + unsigned buf_sz, struct crypto_params *m_hlp) +{ + struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); + uint16_t iv_pad_len = + ALIGN_POW2_ROUNDUP(params->symmetric_op->iv_len, 16); + uint16_t aad_len = params->symmetric_op->aad_len; + uint16_t digest_size = params->symmetric_op->t_len; + char *p; + + p = rte_pktmbuf_append(m, aad_len); + if (p == NULL) { + rte_pktmbuf_free(m); + return NULL; + } + m_hlp->aad = (uint8_t *)p; + + p = rte_pktmbuf_append(m, iv_pad_len); + if (p == NULL) { + rte_pktmbuf_free(m); + return NULL; + } + m_hlp->iv = (uint8_t *)p; + + p = rte_pktmbuf_append(m, buf_sz); + if (p == NULL) { + rte_pktmbuf_free(m); + return NULL; + } + rte_memcpy(p, params->symmetric_op->p_data, buf_sz); + + p = rte_pktmbuf_append(m, digest_size); + if (p == NULL) { + rte_pktmbuf_free(m); + return NULL; + } + m_hlp->digest = (uint8_t *)p; + + return m; +} + +static int +perf_AES_GCM(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams, uint32_t test_ops) +{ + int j = 0; + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_sym_session *sess; + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; + uint32_t total_operations = pparams->total_operations; + + 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 i = 0, l = 0, m = 0; + uint16_t burst = pparams->burst_size * NUM_MBUF_SETS; + uint16_t ops_unused = 0; + + struct rte_mbuf *mbufs[burst]; + struct crypto_params m_hlp[burst]; + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices available. " + "Is kernel driver loaded?\n"); + return TEST_FAILED; + } + + sess = test_perf_create_session(dev_id, pparams); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + for (i = 0; i < burst; i++) { + mbufs[i] = test_perf_create_pktmbuf_fill( + ts_params->mbuf_mp, + pparams, pparams->symmetric_op->p_len, + &m_hlp[i]); + } + + if (test_ops) + total_operations = test_ops; + + tsc_start = rte_rdtsc_precise(); + while (total_enqueued < total_operations) { + uint16_t burst_size = + total_enqueued+pparams->burst_size <= total_operations ? + pparams->burst_size : 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"); + } else { + for (i = 0; i < ops_needed; i++) + ops[i] = perf_gcm_set_crypto_op(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], + sess, &m_hlp[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], pparams); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, 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 < 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++) { + if (test_ops) { + uint16_t iv_pad_len = ALIGN_POW2_ROUNDUP + (pparams->symmetric_op->iv_len, 16); + uint8_t *pkt = rte_pktmbuf_mtod( + proc_ops[m]->sym->m_src, + uint8_t *); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + pparams->symmetric_op->c_data, + pkt + iv_pad_len + + pparams->symmetric_op->aad_len, + pparams->symmetric_op->c_len, + "GCM Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + pparams->symmetric_op->t_data, + pkt + iv_pad_len + + pparams->symmetric_op->aad_len + + pparams->symmetric_op->c_len, + pparams->symmetric_op->t_len, + "GCM MAC data not as expected"); + + } + 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->symmetric_op->p_len * 8) + / 1000000000; + + if (!test_ops) { + printf("\n%u\t\t%6.2f\t%16.2f\t%8"PRIu64"\t%10"PRIu64, + pparams->symmetric_op->p_len, + ops_s/1000000, throughput, retries, failed_polls); + } + + for (i = 0; i < burst; i++) + rte_pktmbuf_free(mbufs[i]); + rte_cryptodev_sym_session_free(dev_id, sess); + + return 0; +} + +static int +test_perf_AES_GCM(int continual_buf_len, int continual_size) +{ + uint16_t i, j, k, loops = 1; + + uint16_t buf_lengths[] = { 64, 128, 256, 512, 1024, 1536, 2048 }; + + static const struct cryptodev_perf_test_data *gcm_tests[] = { + &AES_GCM_128_12IV_0AAD + }; + + if (continual_buf_len) + loops = continual_size; + + int TEST_CASES_GCM = RTE_DIM(gcm_tests); + + const unsigned burst_size = 32; + + struct symmetric_op ops_set[TEST_CASES_GCM]; + struct perf_test_params params_set[TEST_CASES_GCM]; + struct symmetric_session_attrs session_attrs[TEST_CASES_GCM]; + static const struct cryptodev_perf_test_data *gcm_test; + + for (i = 0; i < TEST_CASES_GCM; ++i) { + + gcm_test = gcm_tests[i]; + + session_attrs[i].cipher = + RTE_CRYPTO_CIPHER_OP_ENCRYPT; + session_attrs[i].cipher_algorithm = + RTE_CRYPTO_CIPHER_AES_GCM; + session_attrs[i].key_cipher_data = + gcm_test->key.data; + session_attrs[i].key_cipher_len = + gcm_test->key.len; + session_attrs[i].auth_algorithm = + RTE_CRYPTO_AUTH_AES_GCM; + session_attrs[i].auth = + RTE_CRYPTO_AUTH_OP_GENERATE; + session_attrs[i].key_auth_data = NULL; + session_attrs[i].key_auth_len = 0; + session_attrs[i].digest_len = + gcm_test->auth_tag.len; + + ops_set[i].aad_data = gcm_test->aad.data; + ops_set[i].aad_len = gcm_test->aad.len; + ops_set[i].iv_data = gcm_test->iv.data; + ops_set[i].iv_len = gcm_test->iv.len; + ops_set[i].p_data = gcm_test->plaintext.data; + ops_set[i].p_len = buf_lengths[i]; + ops_set[i].c_data = gcm_test->ciphertext.data; + ops_set[i].c_len = buf_lengths[i]; + ops_set[i].t_data = gcm_test->auth_tags[i].data; + ops_set[i].t_len = gcm_test->auth_tags[i].len; + + params_set[i].chain = CIPHER_HASH; + params_set[i].session_attrs = &session_attrs[i]; + params_set[i].symmetric_op = &ops_set[i]; + if (continual_buf_len) + params_set[i].total_operations = 0xFFFFFF; + else + params_set[i].total_operations = 1000000; + + params_set[i].burst_size = burst_size; + + } + + if (continual_buf_len) + printf("\nCipher algo: %s Cipher hash: %s cipher key size: %ub" + " burst size: %u", "AES_GCM", "AES_GCM", + gcm_test->key.len << 3, burst_size); + + for (i = 0; i < RTE_DIM(gcm_tests); i++) { + + if (!continual_buf_len) { + printf("\nCipher algo: %s Cipher hash: %s cipher key size: %ub" + " burst size: %u", "AES_GCM", "AES_GCM", + gcm_test->key.len << 3, burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\t" + " Retries\tEmptyPolls"); + } + + uint16_t len = RTE_DIM(buf_lengths); + uint16_t p = 0; + + if (continual_buf_len) { + for (k = 0; k < RTE_DIM(buf_lengths); k++) + if (buf_lengths[k] == continual_buf_len) { + len = k + 1; + p = k; + break; + } + } + for (j = p; j < len; ++j) { + + params_set[i].symmetric_op->c_len = buf_lengths[j]; + params_set[i].symmetric_op->p_len = buf_lengths[j]; + + ops_set[i].t_data = gcm_tests[i]->auth_tags[j].data; + ops_set[i].t_len = gcm_tests[i]->auth_tags[j].len; + + /* Run is twice, one for encryption/hash checks, + * one for perf + */ + if (perf_AES_GCM(testsuite_params.dev_id, 0, + ¶ms_set[i], 1)) + return TEST_FAILED; + + for (k = 0; k < loops; k++) { + if (continual_buf_len) + printf("\n\nBuffer Size(B)\tOPS(M)\t" + "Throughput(Gbps)\t" + "Retries\tEmptyPolls"); + if (perf_AES_GCM(testsuite_params.dev_id, 0, + ¶ms_set[i], 0)) + return TEST_FAILED; + if (continual_buf_len) + printf("\n\nCompleted loop %i of %i ...", + k+1, loops); + } + } + + } + printf("\n"); + return 0; +} + +static int test_cryptodev_perf_AES_GCM(void) +{ + return test_perf_AES_GCM(0, 0); +} +/* + * This function calls AES GCM performance tests providing + * size of packet as an argument. If size of packet is not + * in the buf_lengths array, all sizes will be used + */ +static int test_continual_perf_AES_GCM(void) +{ + return test_perf_AES_GCM(1024, 10); +} + +static int +test_perf_continual_performance_test(void) +{ + unsigned int total_operations = 0xFFFFFF; + unsigned int total_loops = 10; + unsigned int burst_size = 32; + uint8_t i; + + struct perf_test_params params_set = { + .total_operations = total_operations, + .burst_size = burst_size, + .buf_size = 1024, + + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }; + + for (i = 1; i <= total_loops; ++i) { + printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." + " burst_size: %d ops\n", + chain_mode_name(params_set.chain), + cipher_algo_name(params_set.cipher_algo), + auth_algo_name(params_set.auth_algo), + params_set.cipher_key_length, + burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\t" + "Retries\tEmptyPolls\n"); + test_perf_aes_sha(testsuite_params.dev_id, 0, + ¶ms_set); + printf("\nCompleted loop %i of %i ...", i, total_loops); + } + return 0; +} + +static struct unit_test_suite cryptodev_qat_continual_testsuite = { + .suite_name = "Crypto Device Continual Performance Test", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_continual_performance_test), + TEST_CASE_ST(ut_setup, ut_teardown, + test_continual_perf_AES_GCM), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +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_aes_cbc_encrypt_digest_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_cryptodev_perf_AES_GCM), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_aes_cbc_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_gcm_testsuite = { + .suite_name = "Crypto Device AESNI GCM Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_cryptodev_perf_AES_GCM), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +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_snow3G_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_openssl_testsuite = { + .suite_name = "Crypto Device OPENSSL Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_openssl_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_openssl_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_armv8_testsuite = { + .suite_name = "Crypto Device ARMv8 Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_armv8_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_armv8_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +perftest_aesni_gcm_cryptodev(void) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_AESNI_GCM_PMD; + + return unit_test_suite_runner(&cryptodev_gcm_testsuite); +} + +static int +perftest_aesni_mb_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_AESNI_MB_PMD; + + return unit_test_suite_runner(&cryptodev_aes_testsuite); +} + +static int +perftest_qat_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + 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 int +perftest_openssl_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_OPENSSL_PMD; + + return unit_test_suite_runner(&cryptodev_openssl_testsuite); +} + +static int +perftest_qat_continual_cryptodev(void) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_QAT_SYM_PMD; + + return unit_test_suite_runner(&cryptodev_qat_continual_testsuite); +} + +static int +perftest_sw_armv8_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_ARMV8_PMD; + + return unit_test_suite_runner(&cryptodev_armv8_testsuite); +} + +REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perftest, perftest_qat_snow3g_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_perftest, perftest_aesni_gcm_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_openssl_perftest, + perftest_openssl_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_qat_continual_perftest, + perftest_qat_continual_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_sw_armv8_perftest, + perftest_sw_armv8_cryptodev); diff --git a/test/test/test_cryptodev_snow3g_hash_test_vectors.h b/test/test/test_cryptodev_snow3g_hash_test_vectors.h new file mode 100644 index 0000000000..a8a47db577 --- /dev/null +++ b/test/test/test_cryptodev_snow3g_hash_test_vectors.h @@ -0,0 +1,548 @@ +/*- + * 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_SNOW3G_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_SNOW3G_HASH_TEST_VECTORS_H_ + +struct snow3g_hash_test_data { + struct { + uint8_t data[64]; + unsigned len; + } key; + + struct { + uint8_t data[64]; + unsigned len; + } aad; + + struct { + uint8_t data[2056]; + unsigned len; /* length must be in Bits */ + } plaintext; + + struct { + unsigned len; + } validAuthLenInBits; + + struct { + unsigned len; + } validAuthOffsetLenInBits; + + struct { + uint8_t data[64]; + unsigned len; + } digest; +}; + +struct snow3g_hash_test_data snow3g_hash_test_case_1 = { + .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, + 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD + }, + .len = 16 + }, + .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 + }, + .len = 384 + }, + .validAuthLenInBits = { + .len = 384 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0x38, 0xB5, 0x54, 0xC0 }, + .len = 4 + } +}; + +struct snow3g_hash_test_data snow3g_hash_test_case_2 = { + .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, + 0xA9, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0xF7, 0x37 + }, + .len = 16 + }, + .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 + }, + .len = 1000 + }, + .validAuthLenInBits = { + .len = 1000 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0x06, 0x17, 0x45, 0xAE}, + .len = 4 + } +}; + +struct snow3g_hash_test_data snow3g_hash_test_case_3 = { + .key = { + .data = { + 0xB3, 0x12, 0x0F, 0xFD, 0xB2, 0xCF, 0x6A, 0xF4, + 0xE7, 0x3E, 0xAF, 0x2E, 0xF4, 0xEB, 0xEC, 0x69 + }, + .len = 16 + }, + .aad = { + .data = { + 0x29, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0x77, 0x37, + 0xA9, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0xF7, 0x37 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0xE0, 0x95, 0x80, 0x45, 0xF3, 0xA0, 0xBB, 0xA4, + 0xE3, 0x96, 0x83, 0x46, 0xF0, 0xA3, 0xB8, 0xA7, + 0xC0, 0x2A, 0x01, 0x8A, 0xE6, 0x40, 0x76, 0x52, + 0x26, 0xB9, 0x87, 0xC9, 0x13, 0xE6, 0xCB, 0xF0, + 0x83, 0x57, 0x00, 0x16, 0xCF, 0x83, 0xEF, 0xBC, + 0x61, 0xC0, 0x82, 0x51, 0x3E, 0x21, 0x56, 0x1A, + 0x42, 0x7C, 0x00, 0x9D, 0x28, 0xC2, 0x98, 0xEF, + 0xAC, 0xE7, 0x8E, 0xD6, 0xD5, 0x6C, 0x2D, 0x45, + 0x05, 0xAD, 0x03, 0x2E, 0x9C, 0x04, 0xDC, 0x60, + 0xE7, 0x3A, 0x81, 0x69, 0x6D, 0xA6, 0x65, 0xC6, + 0xC4, 0x86, 0x03, 0xA5, 0x7B, 0x45, 0xAB, 0x33, + 0x22, 0x15, 0x85, 0xE6, 0x8E, 0xE3, 0x16, 0x91, + 0x87, 0xFB, 0x02, 0x39, 0x52, 0x86, 0x32, 0xDD, + 0x65, 0x6C, 0x80, 0x7E, 0xA3, 0x24, 0x8B, 0x7B, + 0x46, 0xD0, 0x02, 0xB2, 0xB5, 0xC7, 0x45, 0x8E, + 0xB8, 0x5B, 0x9C, 0xE9, 0x58, 0x79, 0xE0, 0x34, + 0x08, 0x59, 0x05, 0x5E, 0x3B, 0x0A, 0xBB, 0xC3, + 0xEA, 0xCE, 0x87, 0x19, 0xCA, 0xA8, 0x02, 0x65, + 0xC9, 0x72, 0x05, 0xD5, 0xDC, 0x4B, 0xCC, 0x90, + 0x2F, 0xE1, 0x83, 0x96, 0x29, 0xED, 0x71, 0x32, + 0x8A, 0x0F, 0x04, 0x49, 0xF5, 0x88, 0x55, 0x7E, + 0x68, 0x98, 0x86, 0x0E, 0x04, 0x2A, 0xEC, 0xD8, + 0x4B, 0x24, 0x04, 0xC2, 0x12, 0xC9, 0x22, 0x2D, + 0xA5, 0xBF, 0x8A, 0x89, 0xEF, 0x67, 0x97, 0x87, + 0x0C, 0xF5, 0x07, 0x71, 0xA6, 0x0F, 0x66, 0xA2, + 0xEE, 0x62, 0x85, 0x36, 0x57, 0xAD, 0xDF, 0x04, + 0xCD, 0xDE, 0x07, 0xFA, 0x41, 0x4E, 0x11, 0xF1, + 0x2B, 0x4D, 0x81, 0xB9, 0xB4, 0xE8, 0xAC, 0x53, + 0x8E, 0xA3, 0x06, 0x66, 0x68, 0x8D, 0x88, 0x1F, + 0x6C, 0x34, 0x84, 0x21, 0x99, 0x2F, 0x31, 0xB9, + 0x4F, 0x88, 0x06, 0xED, 0x8F, 0xCC, 0xFF, 0x4C, + 0x91, 0x23, 0xB8, 0x96, 0x42, 0x52, 0x7A, 0xD6, + 0x13, 0xB1, 0x09, 0xBF, 0x75, 0x16, 0x74, 0x85, + 0xF1, 0x26, 0x8B, 0xF8, 0x84, 0xB4, 0xCD, 0x23, + 0xD2, 0x9A, 0x09, 0x34, 0x92, 0x57, 0x03, 0xD6, + 0x34, 0x09, 0x8F, 0x77, 0x67, 0xF1, 0xBE, 0x74, + 0x91, 0xE7, 0x08, 0xA8, 0xBB, 0x94, 0x9A, 0x38, + 0x73, 0x70, 0x8A, 0xEF, 0x4A, 0x36, 0x23, 0x9E, + 0x50, 0xCC, 0x08, 0x23, 0x5C, 0xD5, 0xED, 0x6B, + 0xBE, 0x57, 0x86, 0x68, 0xA1, 0x7B, 0x58, 0xC1, + 0x17, 0x1D, 0x0B, 0x90, 0xE8, 0x13, 0xA9, 0xE4, + 0xF5, 0x8A, 0x89, 0xD7, 0x19, 0xB1, 0x10, 0x42, + 0xD6, 0x36, 0x0B, 0x1B, 0x0F, 0x52, 0xDE, 0xB7, + 0x30, 0xA5, 0x8D, 0x58, 0xFA, 0xF4, 0x63, 0x15, + 0x95, 0x4B, 0x0A, 0x87, 0x26, 0x91, 0x47, 0x59, + 0x77, 0xDC, 0x88, 0xC0, 0xD7, 0x33, 0xFE, 0xFF, + 0x54, 0x60, 0x0A, 0x0C, 0xC1, 0xD0, 0x30, 0x0A, + 0xAA, 0xEB, 0x94, 0x57, 0x2C, 0x6E, 0x95, 0xB0, + 0x1A, 0xE9, 0x0D, 0xE0, 0x4F, 0x1D, 0xCE, 0x47, + 0xF8, 0x7E, 0x8F, 0xA7, 0xBE, 0xBF, 0x77, 0xE1, + 0xDB, 0xC2, 0x0D, 0x6B, 0xA8, 0x5C, 0xB9, 0x14, + 0x3D, 0x51, 0x8B, 0x28, 0x5D, 0xFA, 0x04, 0xB6, + 0x98, 0xBF, 0x0C, 0xF7, 0x81, 0x9F, 0x20, 0xFA, + 0x7A, 0x28, 0x8E, 0xB0, 0x70, 0x3D, 0x99, 0x5C, + 0x59, 0x94, 0x0C, 0x7C, 0x66, 0xDE, 0x57, 0xA9, + 0xB7, 0x0F, 0x82, 0x37, 0x9B, 0x70, 0xE2, 0x03, + 0x1E, 0x45, 0x0F, 0xCF, 0xD2, 0x18, 0x13, 0x26, + 0xFC, 0xD2, 0x8D, 0x88, 0x23, 0xBA, 0xAA, 0x80, + 0xDF, 0x6E, 0x0F, 0x44, 0x35, 0x59, 0x64, 0x75, + 0x39, 0xFD, 0x89, 0x07, 0xC0, 0xFF, 0xD9, 0xD7, + 0x9C, 0x13, 0x0E, 0xD8, 0x1C, 0x9A, 0xFD, 0x9B, + 0x7E, 0x84, 0x8C, 0x9F, 0xED, 0x38, 0x44, 0x3D, + 0x5D, 0x38, 0x0E, 0x53, 0xFB, 0xDB, 0x8A, 0xC8, + 0xC3, 0xD3, 0xF0, 0x68, 0x76, 0x05, 0x4F, 0x12, + 0x24, 0x61, 0x10, 0x7D, 0xE9, 0x2F, 0xEA, 0x09, + 0xC6, 0xF6, 0x92, 0x3A, 0x18, 0x8D, 0x53, 0xAF, + 0xE5, 0x4A, 0x10, 0xF6, 0x0E, 0x6E, 0x9D, 0x5A, + 0x03, 0xD9, 0x96, 0xB5, 0xFB, 0xC8, 0x20, 0xF8, + 0xA6, 0x37, 0x11, 0x6A, 0x27, 0xAD, 0x04, 0xB4, + 0x44, 0xA0, 0x93, 0x2D, 0xD6, 0x0F, 0xBD, 0x12, + 0x67, 0x1C, 0x11, 0xE1, 0xC0, 0xEC, 0x73, 0xE7, + 0x89, 0x87, 0x9F, 0xAA, 0x3D, 0x42, 0xC6, 0x4D, + 0x20, 0xCD, 0x12, 0x52, 0x74, 0x2A, 0x37, 0x68, + 0xC2, 0x5A, 0x90, 0x15, 0x85, 0x88, 0x8E, 0xCE, + 0xE1, 0xE6, 0x12, 0xD9, 0x93, 0x6B, 0x40, 0x3B, + 0x07, 0x75, 0x94, 0x9A, 0x66, 0xCD, 0xFD, 0x99, + 0xA2, 0x9B, 0x13, 0x45, 0xBA, 0xA8, 0xD9, 0xD5, + 0x40, 0x0C, 0x91, 0x02, 0x4B, 0x0A, 0x60, 0x73, + 0x63, 0xB0, 0x13, 0xCE, 0x5D, 0xE9, 0xAE, 0x86, + 0x9D, 0x3B, 0x8D, 0x95, 0xB0, 0x57, 0x0B, 0x3C, + 0x2D, 0x39, 0x14, 0x22, 0xD3, 0x24, 0x50, 0xCB, + 0xCF, 0xAE, 0x96, 0x65, 0x22, 0x86, 0xE9, 0x6D, + 0xEC, 0x12, 0x14, 0xA9, 0x34, 0x65, 0x27, 0x98, + 0x0A, 0x81, 0x92, 0xEA, 0xC1, 0xC3, 0x9A, 0x3A, + 0xAF, 0x6F, 0x15, 0x35, 0x1D, 0xA6, 0xBE, 0x76, + 0x4D, 0xF8, 0x97, 0x72, 0xEC, 0x04, 0x07, 0xD0, + 0x6E, 0x44, 0x15, 0xBE, 0xFA, 0xE7, 0xC9, 0x25, + 0x80, 0xDF, 0x9B, 0xF5, 0x07, 0x49, 0x7C, 0x8F, + 0x29, 0x95, 0x16, 0x0D, 0x4E, 0x21, 0x8D, 0xAA, + 0xCB, 0x02, 0x94, 0x4A, 0xBF, 0x83, 0x34, 0x0C, + 0xE8, 0xBE, 0x16, 0x86, 0xA9, 0x60, 0xFA, 0xF9, + 0x0E, 0x2D, 0x90, 0xC5, 0x5C, 0xC6, 0x47, 0x5B, + 0xAB, 0xC3, 0x17, 0x1A, 0x80, 0xA3, 0x63, 0x17, + 0x49, 0x54, 0x95, 0x5D, 0x71, 0x01, 0xDA, 0xB1, + 0x6A, 0xE8, 0x17, 0x91, 0x67, 0xE2, 0x14, 0x44, + 0xB4, 0x43, 0xA9, 0xEA, 0xAA, 0x7C, 0x91, 0xDE, + 0x36, 0xD1, 0x18, 0xC3, 0x9D, 0x38, 0x9F, 0x8D, + 0xD4, 0x46, 0x9A, 0x84, 0x6C, 0x9A, 0x26, 0x2B, + 0xF7, 0xFA, 0x18, 0x48, 0x7A, 0x79, 0xE8, 0xDE, + 0x11, 0x69, 0x9E, 0x0B, 0x8F, 0xDF, 0x55, 0x7C, + 0xB4, 0x87, 0x19, 0xD4, 0x53, 0xBA, 0x71, 0x30, + 0x56, 0x10, 0x9B, 0x93, 0xA2, 0x18, 0xC8, 0x96, + 0x75, 0xAC, 0x19, 0x5F, 0xB4, 0xFB, 0x06, 0x63, + 0x9B, 0x37, 0x97, 0x14, 0x49, 0x55, 0xB3, 0xC9, + 0x32, 0x7D, 0x1A, 0xEC, 0x00, 0x3D, 0x42, 0xEC, + 0xD0, 0xEA, 0x98, 0xAB, 0xF1, 0x9F, 0xFB, 0x4A, + 0xF3, 0x56, 0x1A, 0x67, 0xE7, 0x7C, 0x35, 0xBF, + 0x15, 0xC5, 0x9C, 0x24, 0x12, 0xDA, 0x88, 0x1D, + 0xB0, 0x2B, 0x1B, 0xFB, 0xCE, 0xBF, 0xAC, 0x51, + 0x52, 0xBC, 0x99, 0xBC, 0x3F, 0x1D, 0x15, 0xF7, + 0x71, 0x00, 0x1B, 0x70, 0x29, 0xFE, 0xDB, 0x02, + 0x8F, 0x8B, 0x85, 0x2B, 0xC4, 0x40, 0x7E, 0xB8, + 0x3F, 0x89, 0x1C, 0x9C, 0xA7, 0x33, 0x25, 0x4F, + 0xDD, 0x1E, 0x9E, 0xDB, 0x56, 0x91, 0x9C, 0xE9, + 0xFE, 0xA2, 0x1C, 0x17, 0x40, 0x72, 0x52, 0x1C, + 0x18, 0x31, 0x9A, 0x54, 0xB5, 0xD4, 0xEF, 0xBE, + 0xBD, 0xDF, 0x1D, 0x8B, 0x69, 0xB1, 0xCB, 0xF2, + 0x5F, 0x48, 0x9F, 0xCC, 0x98, 0x13, 0x72, 0x54, + 0x7C, 0xF4, 0x1D, 0x00, 0x8E, 0xF0, 0xBC, 0xA1, + 0x92, 0x6F, 0x93, 0x4B, 0x73, 0x5E, 0x09, 0x0B, + 0x3B, 0x25, 0x1E, 0xB3, 0x3A, 0x36, 0xF8, 0x2E, + 0xD9, 0xB2, 0x9C, 0xF4, 0xCB, 0x94, 0x41, 0x88, + 0xFA, 0x0E, 0x1E, 0x38, 0xDD, 0x77, 0x8F, 0x7D, + 0x1C, 0x9D, 0x98, 0x7B, 0x28, 0xD1, 0x32, 0xDF, + 0xB9, 0x73, 0x1F, 0xA4, 0xF4, 0xB4, 0x16, 0x93, + 0x5B, 0xE4, 0x9D, 0xE3, 0x05, 0x16, 0xAF, 0x35, + 0x78, 0x58, 0x1F, 0x2F, 0x13, 0xF5, 0x61, 0xC0, + 0x66, 0x33, 0x61, 0x94, 0x1E, 0xAB, 0x24, 0x9A, + 0x4B, 0xC1, 0x23, 0xF8, 0xD1, 0x5C, 0xD7, 0x11, + 0xA9, 0x56, 0xA1, 0xBF, 0x20, 0xFE, 0x6E, 0xB7, + 0x8A, 0xEA, 0x23, 0x73, 0x36, 0x1D, 0xA0, 0x42, + 0x6C, 0x79, 0xA5, 0x30, 0xC3, 0xBB, 0x1D, 0xE0, + 0xC9, 0x97, 0x22, 0xEF, 0x1F, 0xDE, 0x39, 0xAC, + 0x2B, 0x00, 0xA0, 0xA8, 0xEE, 0x7C, 0x80, 0x0A, + 0x08, 0xBC, 0x22, 0x64, 0xF8, 0x9F, 0x4E, 0xFF, + 0xE6, 0x27, 0xAC, 0x2F, 0x05, 0x31, 0xFB, 0x55, + 0x4F, 0x6D, 0x21, 0xD7, 0x4C, 0x59, 0x0A, 0x70, + 0xAD, 0xFA, 0xA3, 0x90, 0xBD, 0xFB, 0xB3, 0xD6, + 0x8E, 0x46, 0x21, 0x5C, 0xAB, 0x18, 0x7D, 0x23, + 0x68, 0xD5, 0xA7, 0x1F, 0x5E, 0xBE, 0xC0, 0x81, + 0xCD, 0x3B, 0x20, 0xC0, 0x82, 0xDB, 0xE4, 0xCD, + 0x2F, 0xAC, 0xA2, 0x87, 0x73, 0x79, 0x5D, 0x6B, + 0x0C, 0x10, 0x20, 0x4B, 0x65, 0x9A, 0x93, 0x9E, + 0xF2, 0x9B, 0xBE, 0x10, 0x88, 0x24, 0x36, 0x24, + 0x42, 0x99, 0x27, 0xA7, 0xEB, 0x57, 0x6D, 0xD3, + 0xA0, 0x0E, 0xA5, 0xE0, 0x1A, 0xF5, 0xD4, 0x75, + 0x83, 0xB2, 0x27, 0x2C, 0x0C, 0x16, 0x1A, 0x80, + 0x65, 0x21, 0xA1, 0x6F, 0xF9, 0xB0, 0xA7, 0x22, + 0xC0, 0xCF, 0x26, 0xB0, 0x25, 0xD5, 0x83, 0x6E, + 0x22, 0x58, 0xA4, 0xF7, 0xD4, 0x77, 0x3A, 0xC8, + 0x01, 0xE4, 0x26, 0x3B, 0xC2, 0x94, 0xF4, 0x3D, + 0xEF, 0x7F, 0xA8, 0x70, 0x3F, 0x3A, 0x41, 0x97, + 0x46, 0x35, 0x25, 0x88, 0x76, 0x52, 0xB0, 0xB2, + 0xA4, 0xA2, 0xA7, 0xCF, 0x87, 0xF0, 0x09, 0x14, + 0x87, 0x1E, 0x25, 0x03, 0x91, 0x13, 0xC7, 0xE1, + 0x61, 0x8D, 0xA3, 0x40, 0x64, 0xB5, 0x7A, 0x43, + 0xC4, 0x63, 0x24, 0x9F, 0xB8, 0xD0, 0x5E, 0x0F, + 0x26, 0xF4, 0xA6, 0xD8, 0x49, 0x72, 0xE7, 0xA9, + 0x05, 0x48, 0x24, 0x14, 0x5F, 0x91, 0x29, 0x5C, + 0xDB, 0xE3, 0x9A, 0x6F, 0x92, 0x0F, 0xAC, 0xC6, + 0x59, 0x71, 0x2B, 0x46, 0xA5, 0x4B, 0xA2, 0x95, + 0xBB, 0xE6, 0xA9, 0x01, 0x54, 0xE9, 0x1B, 0x33, + 0x98, 0x5A, 0x2B, 0xCD, 0x42, 0x0A, 0xD5, 0xC6, + 0x7E, 0xC9, 0xAD, 0x8E, 0xB7, 0xAC, 0x68, 0x64, + 0xDB, 0x27, 0x2A, 0x51, 0x6B, 0xC9, 0x4C, 0x28, + 0x39, 0xB0, 0xA8, 0x16, 0x9A, 0x6B, 0xF5, 0x8E, + 0x1A, 0x0C, 0x2A, 0xDA, 0x8C, 0x88, 0x3B, 0x7B, + 0xF4, 0x97, 0xA4, 0x91, 0x71, 0x26, 0x8E, 0xD1, + 0x5D, 0xDD, 0x29, 0x69, 0x38, 0x4E, 0x7F, 0xF4, + 0xBF, 0x4A, 0xAB, 0x2E, 0xC9, 0xEC, 0xC6, 0x52, + 0x9C, 0xF6, 0x29, 0xE2, 0xDF, 0x0F, 0x08, 0xA7, + 0x7A, 0x65, 0xAF, 0xA1, 0x2A, 0xA9, 0xB5, 0x05, + 0xDF, 0x8B, 0x28, 0x7E, 0xF6, 0xCC, 0x91, 0x49, + 0x3D, 0x1C, 0xAA, 0x39, 0x07, 0x6E, 0x28, 0xEF, + 0x1E, 0xA0, 0x28, 0xF5, 0x11, 0x8D, 0xE6, 0x1A, + 0xE0, 0x2B, 0xB6, 0xAE, 0xFC, 0x33, 0x43, 0xA0, + 0x50, 0x29, 0x2F, 0x19, 0x9F, 0x40, 0x18, 0x57, + 0xB2, 0xBE, 0xAD, 0x5E, 0x6E, 0xE2, 0xA1, 0xF1, + 0x91, 0x02, 0x2F, 0x92, 0x78, 0x01, 0x6F, 0x04, + 0x77, 0x91, 0xA9, 0xD1, 0x8D, 0xA7, 0xD2, 0xA6, + 0xD2, 0x7F, 0x2E, 0x0E, 0x51, 0xC2, 0xF6, 0xEA, + 0x30, 0xE8, 0xAC, 0x49, 0xA0, 0x60, 0x4F, 0x4C, + 0x13, 0x54, 0x2E, 0x85, 0xB6, 0x83, 0x81, 0xB9, + 0xFD, 0xCF, 0xA0, 0xCE, 0x4B, 0x2D, 0x34, 0x13, + 0x54, 0x85, 0x2D, 0x36, 0x02, 0x45, 0xC5, 0x36, + 0xB6, 0x12, 0xAF, 0x71, 0xF3, 0xE7, 0x7C, 0x90, + 0x95, 0xAE, 0x2D, 0xBD, 0xE5, 0x04, 0xB2, 0x65, + 0x73, 0x3D, 0xAB, 0xFE, 0x10, 0xA2, 0x0F, 0xC7, + 0xD6, 0xD3, 0x2C, 0x21, 0xCC, 0xC7, 0x2B, 0x8B, + 0x34, 0x44, 0xAE, 0x66, 0x3D, 0x65, 0x92, 0x2D, + 0x17, 0xF8, 0x2C, 0xAA, 0x2B, 0x86, 0x5C, 0xD8, + 0x89, 0x13, 0xD2, 0x91, 0xA6, 0x58, 0x99, 0x02, + 0x6E, 0xA1, 0x32, 0x84, 0x39, 0x72, 0x3C, 0x19, + 0x8C, 0x36, 0xB0, 0xC3, 0xC8, 0xD0, 0x85, 0xBF, + 0xAF, 0x8A, 0x32, 0x0F, 0xDE, 0x33, 0x4B, 0x4A, + 0x49, 0x19, 0xB4, 0x4C, 0x2B, 0x95, 0xF6, 0xE8, + 0xEC, 0xF7, 0x33, 0x93, 0xF7, 0xF0, 0xD2, 0xA4, + 0x0E, 0x60, 0xB1, 0xD4, 0x06, 0x52, 0x6B, 0x02, + 0x2D, 0xDC, 0x33, 0x18, 0x10, 0xB1, 0xA5, 0xF7, + 0xC3, 0x47, 0xBD, 0x53, 0xED, 0x1F, 0x10, 0x5D, + 0x6A, 0x0D, 0x30, 0xAB, 0xA4, 0x77, 0xE1, 0x78, + 0x88, 0x9A, 0xB2, 0xEC, 0x55, 0xD5, 0x58, 0xDE, + 0xAB, 0x26, 0x30, 0x20, 0x43, 0x36, 0x96, 0x2B, + 0x4D, 0xB5, 0xB6, 0x63, 0xB6, 0x90, 0x2B, 0x89, + 0xE8, 0x5B, 0x31, 0xBC, 0x6A, 0xF5, 0x0F, 0xC5, + 0x0A, 0xCC, 0xB3, 0xFB, 0x9B, 0x57, 0xB6, 0x63, + 0x29, 0x70, 0x31, 0x37, 0x8D, 0xB4, 0x78, 0x96, + 0xD7, 0xFB, 0xAF, 0x6C, 0x60, 0x0A, 0xDD, 0x2C, + 0x67, 0xF9, 0x36, 0xDB, 0x03, 0x79, 0x86, 0xDB, + 0x85, 0x6E, 0xB4, 0x9C, 0xF2, 0xDB, 0x3F, 0x7D, + 0xA6, 0xD2, 0x36, 0x50, 0xE4, 0x38, 0xF1, 0x88, + 0x40, 0x41, 0xB0, 0x13, 0x11, 0x9E, 0x4C, 0x2A, + 0xE5, 0xAF, 0x37, 0xCC, 0xCD, 0xFB, 0x68, 0x66, + 0x07, 0x38, 0xB5, 0x8B, 0x3C, 0x59, 0xD1, 0xC0, + 0x24, 0x84, 0x37, 0x47, 0x2A, 0xBA, 0x1F, 0x35, + 0xCA, 0x1F, 0xB9, 0x0C, 0xD7, 0x14, 0xAA, 0x9F, + 0x63, 0x55, 0x34, 0xF4, 0x9E, 0x7C, 0x5B, 0xBA, + 0x81, 0xC2, 0xB6, 0xB3, 0x6F, 0xDE, 0xE2, 0x1C, + 0xA2, 0x7E, 0x34, 0x7F, 0x79, 0x3D, 0x2C, 0xE9, + 0x44, 0xED, 0xB2, 0x3C, 0x8C, 0x9B, 0x91, 0x4B, + 0xE1, 0x03, 0x35, 0xE3, 0x50, 0xFE, 0xB5, 0x07, + 0x03, 0x94, 0xB7, 0xA4, 0xA1, 0x5C, 0x0C, 0xA1, + 0x20, 0x28, 0x35, 0x68, 0xB7, 0xBF, 0xC2, 0x54, + 0xFE, 0x83, 0x8B, 0x13, 0x7A, 0x21, 0x47, 0xCE, + 0x7C, 0x11, 0x3A, 0x3A, 0x4D, 0x65, 0x49, 0x9D, + 0x9E, 0x86, 0xB8, 0x7D, 0xBC, 0xC7, 0xF0, 0x3B, + 0xBD, 0x3A, 0x3A, 0xB1, 0xAA, 0x24, 0x3E, 0xCE, + 0x5B, 0xA9, 0xBC, 0xF2, 0x5F, 0x82, 0x83, 0x6C, + 0xFE, 0x47, 0x3B, 0x2D, 0x83, 0xE7, 0xA7, 0x20, + 0x1C, 0xD0, 0xB9, 0x6A, 0x72, 0x45, 0x1E, 0x86, + 0x3F, 0x6C, 0x3B, 0xA6, 0x64, 0xA6, 0xD0, 0x73, + 0xD1, 0xF7, 0xB5, 0xED, 0x99, 0x08, 0x65, 0xD9, + 0x78, 0xBD, 0x38, 0x15, 0xD0, 0x60, 0x94, 0xFC, + 0x9A, 0x2A, 0xBA, 0x52, 0x21, 0xC2, 0x2D, 0x5A, + 0xB9, 0x96, 0x38, 0x9E, 0x37, 0x21, 0xE3, 0xAF, + 0x5F, 0x05, 0xBE, 0xDD, 0xC2, 0x87, 0x5E, 0x0D, + 0xFA, 0xEB, 0x39, 0x02, 0x1E, 0xE2, 0x7A, 0x41, + 0x18, 0x7C, 0xBB, 0x45, 0xEF, 0x40, 0xC3, 0xE7, + 0x3B, 0xC0, 0x39, 0x89, 0xF9, 0xA3, 0x0D, 0x12, + 0xC5, 0x4B, 0xA7, 0xD2, 0x14, 0x1D, 0xA8, 0xA8, + 0x75, 0x49, 0x3E, 0x65, 0x77, 0x6E, 0xF3, 0x5F, + 0x97, 0xDE, 0xBC, 0x22, 0x86, 0xCC, 0x4A, 0xF9, + 0xB4, 0x62, 0x3E, 0xEE, 0x90, 0x2F, 0x84, 0x0C, + 0x52, 0xF1, 0xB8, 0xAD, 0x65, 0x89, 0x39, 0xAE, + 0xF7, 0x1F, 0x3F, 0x72, 0xB9, 0xEC, 0x1D, 0xE2, + 0x15, 0x88, 0xBD, 0x35, 0x48, 0x4E, 0xA4, 0x44, + 0x36, 0x34, 0x3F, 0xF9, 0x5E, 0xAD, 0x6A, 0xB1, + 0xD8, 0xAF, 0xB1, 0xB2, 0xA3, 0x03, 0xDF, 0x1B, + 0x71, 0xE5, 0x3C, 0x4A, 0xEA, 0x6B, 0x2E, 0x3E, + 0x93, 0x72, 0xBE, 0x0D, 0x1B, 0xC9, 0x97, 0x98, + 0xB0, 0xCE, 0x3C, 0xC1, 0x0D, 0x2A, 0x59, 0x6D, + 0x56, 0x5D, 0xBA, 0x82, 0xF8, 0x8C, 0xE4, 0xCF, + 0xF3, 0xB3, 0x3D, 0x5D, 0x24, 0xE9, 0xC0, 0x83, + 0x11, 0x24, 0xBF, 0x1A, 0xD5, 0x4B, 0x79, 0x25, + 0x32, 0x98, 0x3D, 0xD6, 0xC3, 0xA8, 0xB7, 0xD0 + }, + .len = 16448 + }, + .validAuthLenInBits = { + .len = 16448 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0x17, 0x9F, 0x2F, 0xA6}, + .len = 4 + } +}; + +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/test/test/test_cryptodev_snow3g_test_vectors.h b/test/test/test_cryptodev_snow3g_test_vectors.h new file mode 100644 index 0000000000..51917c14cb --- /dev/null +++ b/test/test/test_cryptodev_snow3g_test_vectors.h @@ -0,0 +1,443 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 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_SNOW3G_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_SNOW3G_TEST_VECTORS_H_ + +struct snow3g_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; + } validDataLenInBits; + + struct { + unsigned len; + } validCipherLenInBits; + + struct { + unsigned len; + } validCipherOffsetLenInBits; + + struct { + unsigned len; + } validAuthLenInBits; + + struct { + unsigned len; + } validAuthOffsetLenInBits; + + struct { + uint8_t data[64]; + unsigned len; + } aad; + + struct { + uint8_t data[64]; + unsigned len; + } digest; +}; +struct snow3g_test_data snow3g_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, + 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .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 = { + 0x8C, 0xEB, 0xA6, 0x29, 0x43, 0xDC, 0xED, 0x3A, + 0x09, 0x90, 0xB0, 0x6E, 0xA1, 0xB0, 0xA2, 0xC4, + 0xFB, 0x3C, 0xED, 0xC7, 0x1B, 0x36, 0x9F, 0x42, + 0xBA, 0x64, 0xC1, 0xEB, 0x66, 0x65, 0xE7, 0x2A, + 0xA1, 0xC9, 0xBB, 0x0D, 0xEA, 0xA2, 0x0F, 0xE8, + 0x60, 0x58, 0xB8, 0xBA, 0xEE, 0x2C, 0x2E, 0x7F, + 0x0B, 0xEC, 0xCE, 0x48, 0xB5, 0x29, 0x32, 0xA5, + 0x3C, 0x9D, 0x5F, 0x93, 0x1A, 0x3A, 0x7C, 0x53, + 0x22, 0x59, 0xAF, 0x43, 0x25, 0xE2, 0xA6, 0x5E, + 0x30, 0x84, 0xAD, 0x5F, 0x6A, 0x51, 0x3B, 0x7B, + 0xDD, 0xC1, 0xB6, 0x5F, 0x0A, 0xA0, 0xD9, 0x7A, + 0x05, 0x3D, 0xB5, 0x5A, 0x88, 0xC4, 0xC4, 0xF9, + 0x60, 0x5E, 0x41, 0x40 + }, + .len = 800 + }, + .validDataLenInBits = { + .len = 798 + }, + .validCipherLenInBits = { + .len = 800 + }, + .validCipherOffsetLenInBits = { + .len = 128 + }, + .aad = { + .data = { + 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00, + 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00 + }, + .len = 16 + } +}; + +struct snow3g_test_data snow3g_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, + 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .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 = { + 0xE0, 0xDA, 0x15, 0xCA, 0x8E, 0x25, 0x54, 0xF5, + 0xE5, 0x6C, 0x94, 0x68, 0xDC, 0x6C, 0x7C, 0x12, + 0x9C, 0x56, 0x8A, 0xA5, 0x03, 0x23, 0x17, 0xE0, + 0x4E, 0x07, 0x29, 0x64, 0x6C, 0xAB, 0xEF, 0xA6, + 0x89, 0x86, 0x4C, 0x41, 0x0F, 0x24, 0xF9, 0x19, + 0xE6, 0x1E, 0x3D, 0xFD, 0xFA, 0xD7, 0x7E, 0x56, + 0x0D, 0xB0, 0xA9, 0xCD, 0x36, 0xC3, 0x4A, 0xE4, + 0x18, 0x14, 0x90, 0xB2, 0x9F, 0x5F, 0xA2, 0xFC + }, + .len = 512 + }, + .validDataLenInBits = { + .len = 510 + }, + .validCipherLenInBits = { + .len = 512 + }, + .validCipherOffsetLenInBits = { + .len = 128 + }, + .aad = { + .data = { + 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00, + 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00 + }, + .len = 16 + } +}; + +struct snow3g_test_data snow3g_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, + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, + 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8 + }, + .len = 120 + }, + .ciphertext = { + .data = { + 0xBA, 0x0F, 0x31, 0x30, 0x03, 0x34, 0xC5, 0x6B, + 0x52, 0xA7, 0x49, 0x7C, 0xBA, 0xC0, 0x46 + }, + .len = 120 + }, + .validDataLenInBits = { + .len = 120 + }, + .validCipherLenInBits = { + .len = 120 + }, + .validCipherOffsetLenInBits = { + .len = 128 + }, + .aad = { + .data = { + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .digest = { + .data = {0xE8, 0x60, 0x5A, 0x3E}, + .len = 4 + }, + .validAuthLenInBits = { + .len = 120 + }, + .validAuthOffsetLenInBits = { + .len = 128 + } +}; + +struct snow3g_test_data snow3g_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, + 0x39, 0x8A, 0x59, 0xB4, 0x2C, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .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 = { + 0x98, 0x9B, 0x71, 0x9C, 0xDC, 0x33, 0xCE, 0xB7, + 0xCF, 0x27, 0x6A, 0x52, 0x82, 0x7C, 0xEF, 0x94, + 0xA5, 0x6C, 0x40, 0xC0, 0xAB, 0x9D, 0x81, 0xF7, + 0xA2, 0xA9, 0xBA, 0xC6, 0x0E, 0x11, 0xC4, 0xB0 + }, + .len = 256 + }, + .validDataLenInBits = { + .len = 253 + }, + .validCipherLenInBits = { + .len = 256 + }, + .validCipherOffsetLenInBits = { + .len = 128 + } +}; + +struct snow3g_test_data snow3g_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, + 0x72, 0xA4, 0xF2, 0x0F, 0x48, 0x00, 0x00, 0x00 + }, + .len = 16}, + .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 = { + 0x58, 0x92, 0xBB, 0xA8, 0x8B, 0xBB, 0xCA, 0xAE, + 0xAE, 0x76, 0x9A, 0xA0, 0x6B, 0x68, 0x3D, 0x3A, + 0x17, 0xCC, 0x04, 0xA3, 0x69, 0x88, 0x16, 0x97, + 0x43, 0x5E, 0x44, 0xFE, 0xD5, 0xFF, 0x9A, 0xF5, + 0x7B, 0x9E, 0x89, 0x0D, 0x4D, 0x5C, 0x64, 0x70, + 0x98, 0x85, 0xD4, 0x8A, 0xE4, 0x06, 0x90, 0xEC, + 0x04, 0x3B, 0xAA, 0xE9, 0x70, 0x57, 0x96, 0xE4, + 0xA9, 0xFF, 0x5A, 0x4B, 0x8D, 0x8B, 0x36, 0xD7, + 0xF3, 0xFE, 0x57, 0xCC, 0x6C, 0xFD, 0x6C, 0xD0, + 0x05, 0xCD, 0x38, 0x52, 0xA8, 0x5E, 0x94, 0xCE, + 0x6B, 0xCD, 0x90, 0xD0, 0xD0, 0x78, 0x39, 0xCE, + 0x09, 0x73, 0x35, 0x44, 0xCA, 0x8E, 0x35, 0x08, + 0x43, 0x24, 0x85, 0x50, 0x92, 0x2A, 0xC1, 0x28, + 0x18 + }, + .len = 840 + }, + .validDataLenInBits = { + .len = 837 + }, + .validCipherLenInBits = { + .len = 840 + }, + .validCipherOffsetLenInBits = { + .len = 128 + } +}; +struct snow3g_test_data snow3g_test_case_6 = { + .key = { + .data = { + 0xC7, 0x36, 0xC6, 0xAA, 0xB2, 0x2B, 0xFF, 0xF9, + 0x1E, 0x26, 0x98, 0xD2, 0xE2, 0x2A, 0xD5, 0x7E + }, + .len = 16 + }, + .iv = { + .data = { + 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, + 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD + }, + .len = 16 + }, + .aad = { + .data = { + 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, + 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD + }, + .len = 16 + }, + .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 + }, + .len = 384 + }, + .ciphertext = { + .data = { + 0x95, 0x2E, 0x5A, 0xE1, 0x50, 0xB8, 0x59, 0x2A, + 0x9B, 0xA0, 0x38, 0xA9, 0x8E, 0x2F, 0xED, 0xAB, + 0xFD, 0xC8, 0x3B, 0x47, 0x46, 0x0B, 0x50, 0x16, + 0xEC, 0x88, 0x45, 0xB6, 0x05, 0xC7, 0x54, 0xF8, + 0xBD, 0x91, 0xAA, 0xB6, 0xA4, 0xDC, 0x64, 0xB4, + 0xCB, 0xEB, 0x97, 0x06, 0x4C, 0xF7, 0x02, 0x3D + }, + .len = 384 + }, + .digest = { + .data = {0x38, 0xB5, 0x54, 0xC0 }, + .len = 4 + }, + .validDataLenInBits = { + .len = 384 + }, + .validCipherLenInBits = { + .len = 384 + }, + .validCipherOffsetLenInBits = { + .len = 128 + }, + .validAuthLenInBits = { + .len = 384 + }, + .validAuthOffsetLenInBits = { + .len = 128 + } +}; + +#endif /* TEST_CRYPTODEV_SNOW3G_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_zuc_hash_test_vectors.h b/test/test/test_cryptodev_zuc_hash_test_vectors.h new file mode 100644 index 0000000000..988452cbbd --- /dev/null +++ b/test/test/test_cryptodev_zuc_hash_test_vectors.h @@ -0,0 +1,359 @@ +/*- + * 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_ZUC_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_ZUC_HASH_TEST_VECTORS_H_ + +struct zuc_hash_test_data { + struct { + uint8_t data[64]; + unsigned len; + } key; + + struct { + uint8_t data[64]; + unsigned len; + } aad; + + struct { + uint8_t data[2056]; + unsigned len; /* length must be in Bits */ + } plaintext; + + struct { + unsigned len; + } validAuthLenInBits; + + struct { + unsigned len; + } validAuthOffsetLenInBits; + + struct { + uint8_t data[64]; + unsigned len; + } digest; +}; + +struct zuc_hash_test_data zuc_hash_test_case_1 = { + .key = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .aad = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = {0x00}, + .len = 8 + }, + .validAuthLenInBits = { + .len = 1 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0xC8, 0xA9, 0x59, 0x5E}, + .len = 4 + } +}; + +struct zuc_hash_test_data zuc_hash_test_case_2 = { + .key = { + .data = { + 0x47, 0x05, 0x41, 0x25, 0x56, 0x1E, 0xB2, 0xDD, + 0xA9, 0x40, 0x59, 0xDA, 0x05, 0x09, 0x78, 0x50 + }, + .len = 16 + }, + .aad = { + .data = { + 0x56, 0x1E, 0xB2, 0xDD, 0xA0, 0x00, 0x00, 0x00, + 0x56, 0x1E, 0xB2, 0xDD, 0xA0, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }, + .len = 96 + }, + .validAuthLenInBits = { + .len = 90 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0x67, 0x19, 0xA0, 0x88}, + .len = 4 + } +}; + +struct zuc_hash_test_data zuc_hash_test_case_3 = { + .key = { + .data = { + 0xC9, 0xE6, 0xCE, 0xC4, 0x60, 0x7C, 0x72, 0xDB, + 0x00, 0x0A, 0xEF, 0xA8, 0x83, 0x85, 0xAB, 0x0A + }, + .len = 16 + }, + .aad = { + .data = { + 0xA9, 0x40, 0x59, 0xDA, 0x50, 0x00, 0x00, 0x00, + 0x29, 0x40, 0x59, 0xDA, 0x50, 0x00, 0x80, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x98, 0x3B, 0x41, 0xD4, 0x7D, 0x78, 0x0C, 0x9E, + 0x1A, 0xD1, 0x1D, 0x7E, 0xB7, 0x03, 0x91, 0xB1, + 0xDE, 0x0B, 0x35, 0xDA, 0x2D, 0xC6, 0x2F, 0x83, + 0xE7, 0xB7, 0x8D, 0x63, 0x06, 0xCA, 0x0E, 0xA0, + 0x7E, 0x94, 0x1B, 0x7B, 0xE9, 0x13, 0x48, 0xF9, + 0xFC, 0xB1, 0x70, 0xE2, 0x21, 0x7F, 0xEC, 0xD9, + 0x7F, 0x9F, 0x68, 0xAD, 0xB1, 0x6E, 0x5D, 0x7D, + 0x21, 0xE5, 0x69, 0xD2, 0x80, 0xED, 0x77, 0x5C, + 0xEB, 0xDE, 0x3F, 0x40, 0x93, 0xC5, 0x38, 0x81, + 0x00 + }, + .len = 584 + }, + .validAuthLenInBits = { + .len = 577 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0xFA, 0xE8, 0xFF, 0x0B}, + .len = 4 + } +}; + +struct zuc_hash_test_data zuc_hash_test_case_4 = { + .key = { + .data = { + 0xC8, 0xA4, 0x82, 0x62, 0xD0, 0xC2, 0xE2, 0xBA, + 0xC4, 0xB9, 0x6E, 0xF7, 0x7E, 0x80, 0xCA, 0x59 + }, + .len = 16 + }, + .aad = { + .data = { + 0x05, 0x09, 0x78, 0x50, 0x80, 0x00, 0x00, 0x00, + 0x85, 0x09, 0x78, 0x50, 0x80, 0x00, 0x80, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0xB5, 0x46, 0x43, 0x0B, 0xF8, 0x7B, 0x4F, 0x1E, + 0xE8, 0x34, 0x70, 0x4C, 0xD6, 0x95, 0x1C, 0x36, + 0xE2, 0x6F, 0x10, 0x8C, 0xF7, 0x31, 0x78, 0x8F, + 0x48, 0xDC, 0x34, 0xF1, 0x67, 0x8C, 0x05, 0x22, + 0x1C, 0x8F, 0xA7, 0xFF, 0x2F, 0x39, 0xF4, 0x77, + 0xE7, 0xE4, 0x9E, 0xF6, 0x0A, 0x4E, 0xC2, 0xC3, + 0xDE, 0x24, 0x31, 0x2A, 0x96, 0xAA, 0x26, 0xE1, + 0xCF, 0xBA, 0x57, 0x56, 0x38, 0x38, 0xB2, 0x97, + 0xF4, 0x7E, 0x85, 0x10, 0xC7, 0x79, 0xFD, 0x66, + 0x54, 0xB1, 0x43, 0x38, 0x6F, 0xA6, 0x39, 0xD3, + 0x1E, 0xDB, 0xD6, 0xC0, 0x6E, 0x47, 0xD1, 0x59, + 0xD9, 0x43, 0x62, 0xF2, 0x6A, 0xEE, 0xED, 0xEE, + 0x0E, 0x4F, 0x49, 0xD9, 0xBF, 0x84, 0x12, 0x99, + 0x54, 0x15, 0xBF, 0xAD, 0x56, 0xEE, 0x82, 0xD1, + 0xCA, 0x74, 0x63, 0xAB, 0xF0, 0x85, 0xB0, 0x82, + 0xB0, 0x99, 0x04, 0xD6, 0xD9, 0x90, 0xD4, 0x3C, + 0xF2, 0xE0, 0x62, 0xF4, 0x08, 0x39, 0xD9, 0x32, + 0x48, 0xB1, 0xEB, 0x92, 0xCD, 0xFE, 0xD5, 0x30, + 0x0B, 0xC1, 0x48, 0x28, 0x04, 0x30, 0xB6, 0xD0, + 0xCA, 0xA0, 0x94, 0xB6, 0xEC, 0x89, 0x11, 0xAB, + 0x7D, 0xC3, 0x68, 0x24, 0xB8, 0x24, 0xDC, 0x0A, + 0xF6, 0x68, 0x2B, 0x09, 0x35, 0xFD, 0xE7, 0xB4, + 0x92, 0xA1, 0x4D, 0xC2, 0xF4, 0x36, 0x48, 0x03, + 0x8D, 0xA2, 0xCF, 0x79, 0x17, 0x0D, 0x2D, 0x50, + 0x13, 0x3F, 0xD4, 0x94, 0x16, 0xCB, 0x6E, 0x33, + 0xBE, 0xA9, 0x0B, 0x8B, 0xF4, 0x55, 0x9B, 0x03, + 0x73, 0x2A, 0x01, 0xEA, 0x29, 0x0E, 0x6D, 0x07, + 0x4F, 0x79, 0xBB, 0x83, 0xC1, 0x0E, 0x58, 0x00, + 0x15, 0xCC, 0x1A, 0x85, 0xB3, 0x6B, 0x55, 0x01, + 0x04, 0x6E, 0x9C, 0x4B, 0xDC, 0xAE, 0x51, 0x35, + 0x69, 0x0B, 0x86, 0x66, 0xBD, 0x54, 0xB7, 0xA7, + 0x03, 0xEA, 0x7B, 0x6F, 0x22, 0x0A, 0x54, 0x69, + 0xA5, 0x68, 0x02, 0x7E + }, + .len = 2080 + }, + .validAuthLenInBits = { + .len = 2079 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0x00, 0x4A, 0xC4, 0xD6}, + .len = 4 + } +}; + +struct zuc_hash_test_data zuc_hash_test_case_5 = { + .key = { + .data = { + 0x6B, 0x8B, 0x08, 0xEE, 0x79, 0xE0, 0xB5, 0x98, + 0x2D, 0x6D, 0x12, 0x8E, 0xA9, 0xF2, 0x20, 0xCB + }, + .len = 16 + }, + .aad = { + .data = { + 0x56, 0x1E, 0xB2, 0xDD, 0xE0, 0x00, 0x00, 0x00, + 0x56, 0x1E, 0xB2, 0xDD, 0xE0, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x5B, 0xAD, 0x72, 0x47, 0x10, 0xBA, 0x1C, 0x56, + 0xD5, 0xA3, 0x15, 0xF8, 0xD4, 0x0F, 0x6E, 0x09, + 0x37, 0x80, 0xBE, 0x8E, 0x8D, 0xE0, 0x7B, 0x69, + 0x92, 0x43, 0x20, 0x18, 0xE0, 0x8E, 0xD9, 0x6A, + 0x57, 0x34, 0xAF, 0x8B, 0xAD, 0x8A, 0x57, 0x5D, + 0x3A, 0x1F, 0x16, 0x2F, 0x85, 0x04, 0x5C, 0xC7, + 0x70, 0x92, 0x55, 0x71, 0xD9, 0xF5, 0xB9, 0x4E, + 0x45, 0x4A, 0x77, 0xC1, 0x6E, 0x72, 0x93, 0x6B, + 0xF0, 0x16, 0xAE, 0x15, 0x74, 0x99, 0xF0, 0x54, + 0x3B, 0x5D, 0x52, 0xCA, 0xA6, 0xDB, 0xEA, 0xB6, + 0x97, 0xD2, 0xBB, 0x73, 0xE4, 0x1B, 0x80, 0x75, + 0xDC, 0xE7, 0x9B, 0x4B, 0x86, 0x04, 0x4F, 0x66, + 0x1D, 0x44, 0x85, 0xA5, 0x43, 0xDD, 0x78, 0x60, + 0x6E, 0x04, 0x19, 0xE8, 0x05, 0x98, 0x59, 0xD3, + 0xCB, 0x2B, 0x67, 0xCE, 0x09, 0x77, 0x60, 0x3F, + 0x81, 0xFF, 0x83, 0x9E, 0x33, 0x18, 0x59, 0x54, + 0x4C, 0xFB, 0xC8, 0xD0, 0x0F, 0xEF, 0x1A, 0x4C, + 0x85, 0x10, 0xFB, 0x54, 0x7D, 0x6B, 0x06, 0xC6, + 0x11, 0xEF, 0x44, 0xF1, 0xBC, 0xE1, 0x07, 0xCF, + 0xA4, 0x5A, 0x06, 0xAA, 0xB3, 0x60, 0x15, 0x2B, + 0x28, 0xDC, 0x1E, 0xBE, 0x6F, 0x7F, 0xE0, 0x9B, + 0x05, 0x16, 0xF9, 0xA5, 0xB0, 0x2A, 0x1B, 0xD8, + 0x4B, 0xB0, 0x18, 0x1E, 0x2E, 0x89, 0xE1, 0x9B, + 0xD8, 0x12, 0x59, 0x30, 0xD1, 0x78, 0x68, 0x2F, + 0x38, 0x62, 0xDC, 0x51, 0xB6, 0x36, 0xF0, 0x4E, + 0x72, 0x0C, 0x47, 0xC3, 0xCE, 0x51, 0xAD, 0x70, + 0xD9, 0x4B, 0x9B, 0x22, 0x55, 0xFB, 0xAE, 0x90, + 0x65, 0x49, 0xF4, 0x99, 0xF8, 0xC6, 0xD3, 0x99, + 0x47, 0xED, 0x5E, 0x5D, 0xF8, 0xE2, 0xDE, 0xF1, + 0x13, 0x25, 0x3E, 0x7B, 0x08, 0xD0, 0xA7, 0x6B, + 0x6B, 0xFC, 0x68, 0xC8, 0x12, 0xF3, 0x75, 0xC7, + 0x9B, 0x8F, 0xE5, 0xFD, 0x85, 0x97, 0x6A, 0xA6, + 0xD4, 0x6B, 0x4A, 0x23, 0x39, 0xD8, 0xAE, 0x51, + 0x47, 0xF6, 0x80, 0xFB, 0xE7, 0x0F, 0x97, 0x8B, + 0x38, 0xEF, 0xFD, 0x7B, 0x2F, 0x78, 0x66, 0xA2, + 0x25, 0x54, 0xE1, 0x93, 0xA9, 0x4E, 0x98, 0xA6, + 0x8B, 0x74, 0xBD, 0x25, 0xBB, 0x2B, 0x3F, 0x5F, + 0xB0, 0xA5, 0xFD, 0x59, 0x88, 0x7F, 0x9A, 0xB6, + 0x81, 0x59, 0xB7, 0x17, 0x8D, 0x5B, 0x7B, 0x67, + 0x7C, 0xB5, 0x46, 0xBF, 0x41, 0xEA, 0xDC, 0xA2, + 0x16, 0xFC, 0x10, 0x85, 0x01, 0x28, 0xF8, 0xBD, + 0xEF, 0x5C, 0x8D, 0x89, 0xF9, 0x6A, 0xFA, 0x4F, + 0xA8, 0xB5, 0x48, 0x85, 0x56, 0x5E, 0xD8, 0x38, + 0xA9, 0x50, 0xFE, 0xE5, 0xF1, 0xC3, 0xB0, 0xA4, + 0xF6, 0xFB, 0x71, 0xE5, 0x4D, 0xFD, 0x16, 0x9E, + 0x82, 0xCE, 0xCC, 0x72, 0x66, 0xC8, 0x50, 0xE6, + 0x7C, 0x5E, 0xF0, 0xBA, 0x96, 0x0F, 0x52, 0x14, + 0x06, 0x0E, 0x71, 0xEB, 0x17, 0x2A, 0x75, 0xFC, + 0x14, 0x86, 0x83, 0x5C, 0xBE, 0xA6, 0x53, 0x44, + 0x65, 0xB0, 0x55, 0xC9, 0x6A, 0x72, 0xE4, 0x10, + 0x52, 0x24, 0x18, 0x23, 0x25, 0xD8, 0x30, 0x41, + 0x4B, 0x40, 0x21, 0x4D, 0xAA, 0x80, 0x91, 0xD2, + 0xE0, 0xFB, 0x01, 0x0A, 0xE1, 0x5C, 0x6D, 0xE9, + 0x08, 0x50, 0x97, 0x3B, 0xDF, 0x1E, 0x42, 0x3B, + 0xE1, 0x48, 0xA2, 0x37, 0xB8, 0x7A, 0x0C, 0x9F, + 0x34, 0xD4, 0xB4, 0x76, 0x05, 0xB8, 0x03, 0xD7, + 0x43, 0xA8, 0x6A, 0x90, 0x39, 0x9A, 0x4A, 0xF3, + 0x96, 0xD3, 0xA1, 0x20, 0x0A, 0x62, 0xF3, 0xD9, + 0x50, 0x79, 0x62, 0xE8, 0xE5, 0xBE, 0xE6, 0xD3, + 0xDA, 0x2B, 0xB3, 0xF7, 0x23, 0x76, 0x64, 0xAC, + 0x7A, 0x29, 0x28, 0x23, 0x90, 0x0B, 0xC6, 0x35, + 0x03, 0xB2, 0x9E, 0x80, 0xD6, 0x3F, 0x60, 0x67, + 0xBF, 0x8E, 0x17, 0x16, 0xAC, 0x25, 0xBE, 0xBA, + 0x35, 0x0D, 0xEB, 0x62, 0xA9, 0x9F, 0xE0, 0x31, + 0x85, 0xEB, 0x4F, 0x69, 0x93, 0x7E, 0xCD, 0x38, + 0x79, 0x41, 0xFD, 0xA5, 0x44, 0xBA, 0x67, 0xDB, + 0x09, 0x11, 0x77, 0x49, 0x38, 0xB0, 0x18, 0x27, + 0xBC, 0xC6, 0x9C, 0x92, 0xB3, 0xF7, 0x72, 0xA9, + 0xD2, 0x85, 0x9E, 0xF0, 0x03, 0x39, 0x8B, 0x1F, + 0x6B, 0xBA, 0xD7, 0xB5, 0x74, 0xF7, 0x98, 0x9A, + 0x1D, 0x10, 0xB2, 0xDF, 0x79, 0x8E, 0x0D, 0xBF, + 0x30, 0xD6, 0x58, 0x74, 0x64, 0xD2, 0x48, 0x78, + 0xCD, 0x00, 0xC0, 0xEA, 0xEE, 0x8A, 0x1A, 0x0C, + 0xC7, 0x53, 0xA2, 0x79, 0x79, 0xE1, 0x1B, 0x41, + 0xDB, 0x1D, 0xE3, 0xD5, 0x03, 0x8A, 0xFA, 0xF4, + 0x9F, 0x5C, 0x68, 0x2C, 0x37, 0x48, 0xD8, 0xA3, + 0xA9, 0xEC, 0x54, 0xE6, 0xA3, 0x71, 0x27, 0x5F, + 0x16, 0x83, 0x51, 0x0F, 0x8E, 0x4F, 0x90, 0x93, + 0x8F, 0x9A, 0xB6, 0xE1, 0x34, 0xC2, 0xCF, 0xDF, + 0x48, 0x41, 0xCB, 0xA8, 0x8E, 0x0C, 0xFF, 0x2B, + 0x0B, 0xCC, 0x8E, 0x6A, 0xDC, 0xB7, 0x11, 0x09, + 0xB5, 0x19, 0x8F, 0xEC, 0xF1, 0xBB, 0x7E, 0x5C, + 0x53, 0x1A, 0xCA, 0x50, 0xA5, 0x6A, 0x8A, 0x3B, + 0x6D, 0xE5, 0x98, 0x62, 0xD4, 0x1F, 0xA1, 0x13, + 0xD9, 0xCD, 0x95, 0x78, 0x08, 0xF0, 0x85, 0x71, + 0xD9, 0xA4, 0xBB, 0x79, 0x2A, 0xF2, 0x71, 0xF6, + 0xCC, 0x6D, 0xBB, 0x8D, 0xC7, 0xEC, 0x36, 0xE3, + 0x6B, 0xE1, 0xED, 0x30, 0x81, 0x64, 0xC3, 0x1C, + 0x7C, 0x0A, 0xFC, 0x54, 0x1C + }, + .len = 5672 + }, + .validAuthLenInBits = { + .len = 5670 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0x0C, 0xA1, 0x27, 0x92}, + .len = 4 + } +}; + +#endif /* TEST_CRYPTODEV_ZUC_HASH_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_zuc_test_vectors.h b/test/test/test_cryptodev_zuc_test_vectors.h new file mode 100644 index 0000000000..03a3d1f459 --- /dev/null +++ b/test/test/test_cryptodev_zuc_test_vectors.h @@ -0,0 +1,582 @@ +/*- + * 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_ZUC_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ + +struct zuc_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; + } validDataLenInBits; + + struct { + unsigned len; + } validCipherLenInBits; + + struct { + unsigned len; + } validCipherOffsetLenInBits; + + struct { + unsigned len; + } validAuthLenInBits; + + struct { + unsigned len; + } validAuthOffsetLenInBits; + + struct { + uint8_t data[64]; + unsigned len; + } aad; + + struct { + uint8_t data[64]; + unsigned len; + } digest; +}; +struct zuc_test_data zuc_test_case_1 = { + .key = { + .data = { + 0x17, 0x3D, 0x14, 0xBA, 0x50, 0x03, 0x73, 0x1D, + 0x7A, 0x60, 0x04, 0x94, 0x70, 0xF0, 0x0A, 0x29 + }, + .len = 16 + }, + .iv = { + .data = { + 0x66, 0x03, 0x54, 0x92, 0x78, 0x00, 0x00, 0x00, + 0x66, 0x03, 0x54, 0x92, 0x78, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x6C, 0xF6, 0x53, 0x40, 0x73, 0x55, 0x52, 0xAB, + 0x0C, 0x97, 0x52, 0xFA, 0x6F, 0x90, 0x25, 0xFE, + 0x0B, 0xD6, 0x75, 0xD9, 0x00, 0x58, 0x75, 0xB2, + 0x00 + }, + .len = 200 + }, + .ciphertext = { + .data = { + 0xA6, 0xC8, 0x5F, 0xC6, 0x6A, 0xFB, 0x85, 0x33, + 0xAA, 0xFC, 0x25, 0x18, 0xDF, 0xE7, 0x84, 0x94, + 0x0E, 0xE1, 0xE4, 0xB0, 0x30, 0x23, 0x8C, 0xC8, + 0x00 + }, + .len = 200 + }, + .validDataLenInBits = { + .len = 193 + }, + .validCipherLenInBits = { + .len = 193 + }, + .validCipherOffsetLenInBits = { + .len = 128 + } +}; + +struct zuc_test_data zuc_test_case_2 = { + .key = { + .data = { + 0xE5, 0xBD, 0x3E, 0xA0, 0xEB, 0x55, 0xAD, 0xE8, + 0x66, 0xC6, 0xAC, 0x58, 0xBD, 0x54, 0x30, 0x2A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x05, 0x68, 0x23, 0xC4, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x68, 0x23, 0xC4, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x14, 0xA8, 0xEF, 0x69, 0x3D, 0x67, 0x85, 0x07, + 0xBB, 0xE7, 0x27, 0x0A, 0x7F, 0x67, 0xFF, 0x50, + 0x06, 0xC3, 0x52, 0x5B, 0x98, 0x07, 0xE4, 0x67, + 0xC4, 0xE5, 0x60, 0x00, 0xBA, 0x33, 0x8F, 0x5D, + 0x42, 0x95, 0x59, 0x03, 0x67, 0x51, 0x82, 0x22, + 0x46, 0xC8, 0x0D, 0x3B, 0x38, 0xF0, 0x7F, 0x4B, + 0xE2, 0xD8, 0xFF, 0x58, 0x05, 0xF5, 0x13, 0x22, + 0x29, 0xBD, 0xE9, 0x3B, 0xBB, 0xDC, 0xAF, 0x38, + 0x2B, 0xF1, 0xEE, 0x97, 0x2F, 0xBF, 0x99, 0x77, + 0xBA, 0xDA, 0x89, 0x45, 0x84, 0x7A, 0x2A, 0x6C, + 0x9A, 0xD3, 0x4A, 0x66, 0x75, 0x54, 0xE0, 0x4D, + 0x1F, 0x7F, 0xA2, 0xC3, 0x32, 0x41, 0xBD, 0x8F, + 0x01, 0xBA, 0x22, 0x0D + }, + .len = 800 + }, + .ciphertext = { + .data = { + 0x13, 0x1D, 0x43, 0xE0, 0xDE, 0xA1, 0xBE, 0x5C, + 0x5A, 0x1B, 0xFD, 0x97, 0x1D, 0x85, 0x2C, 0xBF, + 0x71, 0x2D, 0x7B, 0x4F, 0x57, 0x96, 0x1F, 0xEA, + 0x32, 0x08, 0xAF, 0xA8, 0xBC, 0xA4, 0x33, 0xF4, + 0x56, 0xAD, 0x09, 0xC7, 0x41, 0x7E, 0x58, 0xBC, + 0x69, 0xCF, 0x88, 0x66, 0xD1, 0x35, 0x3F, 0x74, + 0x86, 0x5E, 0x80, 0x78, 0x1D, 0x20, 0x2D, 0xFB, + 0x3E, 0xCF, 0xF7, 0xFC, 0xBC, 0x3B, 0x19, 0x0F, + 0xE8, 0x2A, 0x20, 0x4E, 0xD0, 0xE3, 0x50, 0xFC, + 0x0F, 0x6F, 0x26, 0x13, 0xB2, 0xF2, 0xBC, 0xA6, + 0xDF, 0x5A, 0x47, 0x3A, 0x57, 0xA4, 0xA0, 0x0D, + 0x98, 0x5E, 0xBA, 0xD8, 0x80, 0xD6, 0xF2, 0x38, + 0x64, 0xA0, 0x7B, 0x01 + }, + .len = 800 + }, + .validDataLenInBits = { + .len = 800 + }, + .validCipherLenInBits = { + .len = 800 + }, + .validCipherOffsetLenInBits = { + .len = 128 + } +}; + +struct zuc_test_data zuc_test_case_3 = { + .key = { + .data = { + 0xD4, 0x55, 0x2A, 0x8F, 0xD6, 0xE6, 0x1C, 0xC8, + 0x1A, 0x20, 0x09, 0x14, 0x1A, 0x29, 0xC1, 0x0B + }, + .len = 16 + }, + .iv = { + .data = { + 0x76, 0x45, 0x2E, 0xC1, 0x14, 0x00, 0x00, 0x00, + 0x76, 0x45, 0x2E, 0xC1, 0x14, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x38, 0xF0, 0x7F, 0x4B, 0xE2, 0xD8, 0xFF, 0x58, + 0x05, 0xF5, 0x13, 0x22, 0x29, 0xBD, 0xE9, 0x3B, + 0xBB, 0xDC, 0xAF, 0x38, 0x2B, 0xF1, 0xEE, 0x97, + 0x2F, 0xBF, 0x99, 0x77, 0xBA, 0xDA, 0x89, 0x45, + 0x84, 0x7A, 0x2A, 0x6C, 0x9A, 0xD3, 0x4A, 0x66, + 0x75, 0x54, 0xE0, 0x4D, 0x1F, 0x7F, 0xA2, 0xC3, + 0x32, 0x41, 0xBD, 0x8F, 0x01, 0xBA, 0x22, 0x0D, + 0x3C, 0xA4, 0xEC, 0x41, 0xE0, 0x74, 0x59, 0x5F, + 0x54, 0xAE, 0x2B, 0x45, 0x4F, 0xD9, 0x71, 0x43, + 0x20, 0x43, 0x60, 0x19, 0x65, 0xCC, 0xA8, 0x5C, + 0x24, 0x17, 0xED, 0x6C, 0xBE, 0xC3, 0xBA, 0xDA, + 0x84, 0xFC, 0x8A, 0x57, 0x9A, 0xEA, 0x78, 0x37, + 0xB0, 0x27, 0x11, 0x77, 0x24, 0x2A, 0x64, 0xDC, + 0x0A, 0x9D, 0xE7, 0x1A, 0x8E, 0xDE, 0xE8, 0x6C, + 0xA3, 0xD4, 0x7D, 0x03, 0x3D, 0x6B, 0xF5, 0x39, + 0x80, 0x4E, 0xCA, 0x86, 0xC5, 0x84, 0xA9, 0x05, + 0x2D, 0xE4, 0x6A, 0xD3, 0xFC, 0xED, 0x65, 0x54, + 0x3B, 0xD9, 0x02, 0x07, 0x37, 0x2B, 0x27, 0xAF, + 0xB7, 0x92, 0x34, 0xF5, 0xFF, 0x43, 0xEA, 0x87, + 0x08, 0x20, 0xE2, 0xC2, 0xB7, 0x8A, 0x8A, 0xAE, + 0x61, 0xCC, 0xE5, 0x2A, 0x05, 0x15, 0xE3, 0x48, + 0xD1, 0x96, 0x66, 0x4A, 0x34, 0x56, 0xB1, 0x82, + 0xA0, 0x7C, 0x40, 0x6E, 0x4A, 0x20, 0x79, 0x12, + 0x71, 0xCF, 0xED, 0xA1, 0x65, 0xD5, 0x35, 0xEC, + 0x5E, 0xA2, 0xD4, 0xDF, 0x40 + }, + .len = 1576 + }, + .ciphertext = { + .data = { + 0x83, 0x83, 0xB0, 0x22, 0x9F, 0xCC, 0x0B, 0x9D, + 0x22, 0x95, 0xEC, 0x41, 0xC9, 0x77, 0xE9, 0xC2, + 0xBB, 0x72, 0xE2, 0x20, 0x37, 0x81, 0x41, 0xF9, + 0xC8, 0x31, 0x8F, 0x3A, 0x27, 0x0D, 0xFB, 0xCD, + 0xEE, 0x64, 0x11, 0xC2, 0xB3, 0x04, 0x4F, 0x17, + 0x6D, 0xC6, 0xE0, 0x0F, 0x89, 0x60, 0xF9, 0x7A, + 0xFA, 0xCD, 0x13, 0x1A, 0xD6, 0xA3, 0xB4, 0x9B, + 0x16, 0xB7, 0xBA, 0xBC, 0xF2, 0xA5, 0x09, 0xEB, + 0xB1, 0x6A, 0x75, 0xDC, 0xAB, 0x14, 0xFF, 0x27, + 0x5D, 0xBE, 0xEE, 0xA1, 0xA2, 0xB1, 0x55, 0xF9, + 0xD5, 0x2C, 0x26, 0x45, 0x2D, 0x01, 0x87, 0xC3, + 0x10, 0xA4, 0xEE, 0x55, 0xBE, 0xAA, 0x78, 0xAB, + 0x40, 0x24, 0x61, 0x5B, 0xA9, 0xF5, 0xD5, 0xAD, + 0xC7, 0x72, 0x8F, 0x73, 0x56, 0x06, 0x71, 0xF0, + 0x13, 0xE5, 0xE5, 0x50, 0x08, 0x5D, 0x32, 0x91, + 0xDF, 0x7D, 0x5F, 0xEC, 0xED, 0xDE, 0xD5, 0x59, + 0x64, 0x1B, 0x6C, 0x2F, 0x58, 0x52, 0x33, 0xBC, + 0x71, 0xE9, 0x60, 0x2B, 0xD2, 0x30, 0x58, 0x55, + 0xBB, 0xD2, 0x5F, 0xFA, 0x7F, 0x17, 0xEC, 0xBC, + 0x04, 0x2D, 0xAA, 0xE3, 0x8C, 0x1F, 0x57, 0xAD, + 0x8E, 0x8E, 0xBD, 0x37, 0x34, 0x6F, 0x71, 0xBE, + 0xFD, 0xBB, 0x74, 0x32, 0xE0, 0xE0, 0xBB, 0x2C, + 0xFC, 0x09, 0xBC, 0xD9, 0x65, 0x70, 0xCB, 0x0C, + 0x0C, 0x39, 0xDF, 0x5E, 0x29, 0x29, 0x4E, 0x82, + 0x70, 0x3A, 0x63, 0x7F, 0x80 + }, + .len = 1576 + }, + .validDataLenInBits = { + .len = 1570 + }, + .validCipherLenInBits = { + .len = 1570 + }, + .validCipherOffsetLenInBits = { + .len = 128 + }, + .aad = { + .data = { + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .digest = { + .data = {0xE8, 0x60, 0x5A, 0x3E}, + .len = 4 + }, + .validAuthLenInBits = { + .len = 120 + }, + .validAuthOffsetLenInBits = { + .len = 128 + } +}; + +struct zuc_test_data zuc_test_case_4 = { + .key = { + .data = { + 0xDB, 0x84, 0xB4, 0xFB, 0xCC, 0xDA, 0x56, 0x3B, + 0x66, 0x22, 0x7B, 0xFE, 0x45, 0x6F, 0x0F, 0x77 + }, + .len = 16 + }, + .iv = { + .data = { + 0xE4, 0x85, 0x0F, 0xE1, 0x84, 0x00, 0x00, 0x00, + 0xE4, 0x85, 0x0F, 0xE1, 0x84, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0xE5, 0x39, 0xF3, 0xB8, 0x97, 0x32, 0x40, 0xDA, + 0x03, 0xF2, 0xB8, 0xAA, 0x05, 0xEE, 0x0A, 0x00, + 0xDB, 0xAF, 0xC0, 0xE1, 0x82, 0x05, 0x5D, 0xFE, + 0x3D, 0x73, 0x83, 0xD9, 0x2C, 0xEF, 0x40, 0xE9, + 0x29, 0x28, 0x60, 0x5D, 0x52, 0xD0, 0x5F, 0x4F, + 0x90, 0x18, 0xA1, 0xF1, 0x89, 0xAE, 0x39, 0x97, + 0xCE, 0x19, 0x15, 0x5F, 0xB1, 0x22, 0x1D, 0xB8, + 0xBB, 0x09, 0x51, 0xA8, 0x53, 0xAD, 0x85, 0x2C, + 0xE1, 0x6C, 0xFF, 0x07, 0x38, 0x2C, 0x93, 0xA1, + 0x57, 0xDE, 0x00, 0xDD, 0xB1, 0x25, 0xC7, 0x53, + 0x9F, 0xD8, 0x50, 0x45, 0xE4, 0xEE, 0x07, 0xE0, + 0xC4, 0x3F, 0x9E, 0x9D, 0x6F, 0x41, 0x4F, 0xC4, + 0xD1, 0xC6, 0x29, 0x17, 0x81, 0x3F, 0x74, 0xC0, + 0x0F, 0xC8, 0x3F, 0x3E, 0x2E, 0xD7, 0xC4, 0x5B, + 0xA5, 0x83, 0x52, 0x64, 0xB4, 0x3E, 0x0B, 0x20, + 0xAF, 0xDA, 0x6B, 0x30, 0x53, 0xBF, 0xB6, 0x42, + 0x3B, 0x7F, 0xCE, 0x25, 0x47, 0x9F, 0xF5, 0xF1, + 0x39, 0xDD, 0x9B, 0x5B, 0x99, 0x55, 0x58, 0xE2, + 0xA5, 0x6B, 0xE1, 0x8D, 0xD5, 0x81, 0xCD, 0x01, + 0x7C, 0x73, 0x5E, 0x6F, 0x0D, 0x0D, 0x97, 0xC4, + 0xDD, 0xC1, 0xD1, 0xDA, 0x70, 0xC6, 0xDB, 0x4A, + 0x12, 0xCC, 0x92, 0x77, 0x8E, 0x2F, 0xBB, 0xD6, + 0xF3, 0xBA, 0x52, 0xAF, 0x91, 0xC9, 0xC6, 0xB6, + 0x4E, 0x8D, 0xA4, 0xF7, 0xA2, 0xC2, 0x66, 0xD0, + 0x2D, 0x00, 0x17, 0x53, 0xDF, 0x08, 0x96, 0x03, + 0x93, 0xC5, 0xD5, 0x68, 0x88, 0xBF, 0x49, 0xEB, + 0x5C, 0x16, 0xD9, 0xA8, 0x04, 0x27, 0xA4, 0x16, + 0xBC, 0xB5, 0x97, 0xDF, 0x5B, 0xFE, 0x6F, 0x13, + 0x89, 0x0A, 0x07, 0xEE, 0x13, 0x40, 0xE6, 0x47, + 0x6B, 0x0D, 0x9A, 0xA8, 0xF8, 0x22, 0xAB, 0x0F, + 0xD1, 0xAB, 0x0D, 0x20, 0x4F, 0x40, 0xB7, 0xCE, + 0x6F, 0x2E, 0x13, 0x6E, 0xB6, 0x74, 0x85, 0xE5, + 0x07, 0x80, 0x4D, 0x50, 0x45, 0x88, 0xAD, 0x37, + 0xFF, 0xD8, 0x16, 0x56, 0x8B, 0x2D, 0xC4, 0x03, + 0x11, 0xDF, 0xB6, 0x54, 0xCD, 0xEA, 0xD4, 0x7E, + 0x23, 0x85, 0xC3, 0x43, 0x62, 0x03, 0xDD, 0x83, + 0x6F, 0x9C, 0x64, 0xD9, 0x74, 0x62, 0xAD, 0x5D, + 0xFA, 0x63, 0xB5, 0xCF, 0xE0, 0x8A, 0xCB, 0x95, + 0x32, 0x86, 0x6F, 0x5C, 0xA7, 0x87, 0x56, 0x6F, + 0xCA, 0x93, 0xE6, 0xB1, 0x69, 0x3E, 0xE1, 0x5C, + 0xF6, 0xF7, 0xA2, 0xD6, 0x89, 0xD9, 0x74, 0x17, + 0x98, 0xDC, 0x1C, 0x23, 0x8E, 0x1B, 0xE6, 0x50, + 0x73, 0x3B, 0x18, 0xFB, 0x34, 0xFF, 0x88, 0x0E, + 0x16, 0xBB, 0xD2, 0x1B, 0x47, 0xAC + }, + .len = 2800 + }, + .ciphertext = { + .data = { + 0x4B, 0xBF, 0xA9, 0x1B, 0xA2, 0x5D, 0x47, 0xDB, + 0x9A, 0x9F, 0x19, 0x0D, 0x96, 0x2A, 0x19, 0xAB, + 0x32, 0x39, 0x26, 0xB3, 0x51, 0xFB, 0xD3, 0x9E, + 0x35, 0x1E, 0x05, 0xDA, 0x8B, 0x89, 0x25, 0xE3, + 0x0B, 0x1C, 0xCE, 0x0D, 0x12, 0x21, 0x10, 0x10, + 0x95, 0x81, 0x5C, 0xC7, 0xCB, 0x63, 0x19, 0x50, + 0x9E, 0xC0, 0xD6, 0x79, 0x40, 0x49, 0x19, 0x87, + 0xE1, 0x3F, 0x0A, 0xFF, 0xAC, 0x33, 0x2A, 0xA6, + 0xAA, 0x64, 0x62, 0x6D, 0x3E, 0x9A, 0x19, 0x17, + 0x51, 0x9E, 0x0B, 0x97, 0xB6, 0x55, 0xC6, 0xA1, + 0x65, 0xE4, 0x4C, 0xA9, 0xFE, 0xAC, 0x07, 0x90, + 0xD2, 0xA3, 0x21, 0xAD, 0x3D, 0x86, 0xB7, 0x9C, + 0x51, 0x38, 0x73, 0x9F, 0xA3, 0x8D, 0x88, 0x7E, + 0xC7, 0xDE, 0xF4, 0x49, 0xCE, 0x8A, 0xBD, 0xD3, + 0xE7, 0xF8, 0xDC, 0x4C, 0xA9, 0xE7, 0xB7, 0x33, + 0x14, 0xAD, 0x31, 0x0F, 0x90, 0x25, 0xE6, 0x19, + 0x46, 0xB3, 0xA5, 0x6D, 0xC6, 0x49, 0xEC, 0x0D, + 0xA0, 0xD6, 0x39, 0x43, 0xDF, 0xF5, 0x92, 0xCF, + 0x96, 0x2A, 0x7E, 0xFB, 0x2C, 0x85, 0x24, 0xE3, + 0x5A, 0x2A, 0x6E, 0x78, 0x79, 0xD6, 0x26, 0x04, + 0xEF, 0x26, 0x86, 0x95, 0xFA, 0x40, 0x03, 0x02, + 0x7E, 0x22, 0xE6, 0x08, 0x30, 0x77, 0x52, 0x20, + 0x64, 0xBD, 0x4A, 0x5B, 0x90, 0x6B, 0x5F, 0x53, + 0x12, 0x74, 0xF2, 0x35, 0xED, 0x50, 0x6C, 0xFF, + 0x01, 0x54, 0xC7, 0x54, 0x92, 0x8A, 0x0C, 0xE5, + 0x47, 0x6F, 0x2C, 0xB1, 0x02, 0x0A, 0x12, 0x22, + 0xD3, 0x2C, 0x14, 0x55, 0xEC, 0xAE, 0xF1, 0xE3, + 0x68, 0xFB, 0x34, 0x4D, 0x17, 0x35, 0xBF, 0xBE, + 0xDE, 0xB7, 0x1D, 0x0A, 0x33, 0xA2, 0xA5, 0x4B, + 0x1D, 0xA5, 0xA2, 0x94, 0xE6, 0x79, 0x14, 0x4D, + 0xDF, 0x11, 0xEB, 0x1A, 0x3D, 0xE8, 0xCF, 0x0C, + 0xC0, 0x61, 0x91, 0x79, 0x74, 0xF3, 0x5C, 0x1D, + 0x9C, 0xA0, 0xAC, 0x81, 0x80, 0x7F, 0x8F, 0xCC, + 0xE6, 0x19, 0x9A, 0x6C, 0x77, 0x12, 0xDA, 0x86, + 0x50, 0x21, 0xB0, 0x4C, 0xE0, 0x43, 0x95, 0x16, + 0xF1, 0xA5, 0x26, 0xCC, 0xDA, 0x9F, 0xD9, 0xAB, + 0xBD, 0x53, 0xC3, 0xA6, 0x84, 0xF9, 0xAE, 0x1E, + 0x7E, 0xE6, 0xB1, 0x1D, 0xA1, 0x38, 0xEA, 0x82, + 0x6C, 0x55, 0x16, 0xB5, 0xAA, 0xDF, 0x1A, 0xBB, + 0xE3, 0x6F, 0xA7, 0xFF, 0xF9, 0x2E, 0x3A, 0x11, + 0x76, 0x06, 0x4E, 0x8D, 0x95, 0xF2, 0xE4, 0x88, + 0x2B, 0x55, 0x00, 0xB9, 0x32, 0x28, 0xB2, 0x19, + 0x4A, 0x47, 0x5C, 0x1A, 0x27, 0xF6, 0x3F, 0x9F, + 0xFD, 0x26, 0x49, 0x89, 0xA1, 0xBC + }, + .len = 2800 + }, + .validDataLenInBits = { + .len = 2798 + }, + .validCipherLenInBits = { + .len = 2798 + }, + .validCipherOffsetLenInBits = { + .len = 128 + } +}; + +struct zuc_test_data zuc_test_case_5 = { + .key = { + .data = { + 0xE1, 0x3F, 0xED, 0x21, 0xB4, 0x6E, 0x4E, 0x7E, + 0xC3, 0x12, 0x53, 0xB2, 0xBB, 0x17, 0xB3, 0xE0 + }, + .len = 16 + }, + .iv = { + .data = { + 0x27, 0x38, 0xCD, 0xAA, 0xD0, 0x00, 0x00, 0x00, + 0x27, 0x38, 0xCD, 0xAA, 0xD0, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x8D, 0x74, 0xE2, 0x0D, 0x54, 0x89, 0x4E, 0x06, + 0xD3, 0xCB, 0x13, 0xCB, 0x39, 0x33, 0x06, 0x5E, + 0x86, 0x74, 0xBE, 0x62, 0xAD, 0xB1, 0xC7, 0x2B, + 0x3A, 0x64, 0x69, 0x65, 0xAB, 0x63, 0xCB, 0x7B, + 0x78, 0x54, 0xDF, 0xDC, 0x27, 0xE8, 0x49, 0x29, + 0xF4, 0x9C, 0x64, 0xB8, 0x72, 0xA4, 0x90, 0xB1, + 0x3F, 0x95, 0x7B, 0x64, 0x82, 0x7E, 0x71, 0xF4, + 0x1F, 0xBD, 0x42, 0x69, 0xA4, 0x2C, 0x97, 0xF8, + 0x24, 0x53, 0x70, 0x27, 0xF8, 0x6E, 0x9F, 0x4A, + 0xD8, 0x2D, 0x1D, 0xF4, 0x51, 0x69, 0x0F, 0xDD, + 0x98, 0xB6, 0xD0, 0x3F, 0x3A, 0x0E, 0xBE, 0x3A, + 0x31, 0x2D, 0x6B, 0x84, 0x0B, 0xA5, 0xA1, 0x82, + 0x0B, 0x2A, 0x2C, 0x97, 0x09, 0xC0, 0x90, 0xD2, + 0x45, 0xED, 0x26, 0x7C, 0xF8, 0x45, 0xAE, 0x41, + 0xFA, 0x97, 0x5D, 0x33, 0x33, 0xAC, 0x30, 0x09, + 0xFD, 0x40, 0xEB, 0xA9, 0xEB, 0x5B, 0x88, 0x57, + 0x14, 0xB7, 0x68, 0xB6, 0x97, 0x13, 0x8B, 0xAF, + 0x21, 0x38, 0x0E, 0xCA, 0x49, 0xF6, 0x44, 0xD4, + 0x86, 0x89, 0xE4, 0x21, 0x57, 0x60, 0xB9, 0x06, + 0x73, 0x9F, 0x0D, 0x2B, 0x3F, 0x09, 0x11, 0x33, + 0xCA, 0x15, 0xD9, 0x81, 0xCB, 0xE4, 0x01, 0xBA, + 0xF7, 0x2D, 0x05, 0xAC, 0xE0, 0x5C, 0xCC, 0xB2, + 0xD2, 0x97, 0xF4, 0xEF, 0x6A, 0x5F, 0x58, 0xD9, + 0x12, 0x46, 0xCF, 0xA7, 0x72, 0x15, 0xB8, 0x92, + 0xAB, 0x44, 0x1D, 0x52, 0x78, 0x45, 0x27, 0x95, + 0xCC, 0xB7, 0xF5, 0xD7, 0x90, 0x57, 0xA1, 0xC4, + 0xF7, 0x7F, 0x80, 0xD4, 0x6D, 0xB2, 0x03, 0x3C, + 0xB7, 0x9B, 0xED, 0xF8, 0xE6, 0x05, 0x51, 0xCE, + 0x10, 0xC6, 0x67, 0xF6, 0x2A, 0x97, 0xAB, 0xAF, + 0xAB, 0xBC, 0xD6, 0x77, 0x20, 0x18, 0xDF, 0x96, + 0xA2, 0x82, 0xEA, 0x73, 0x7C, 0xE2, 0xCB, 0x33, + 0x12, 0x11, 0xF6, 0x0D, 0x53, 0x54, 0xCE, 0x78, + 0xF9, 0x91, 0x8D, 0x9C, 0x20, 0x6C, 0xA0, 0x42, + 0xC9, 0xB6, 0x23, 0x87, 0xDD, 0x70, 0x96, 0x04, + 0xA5, 0x0A, 0xF1, 0x6D, 0x8D, 0x35, 0xA8, 0x90, + 0x6B, 0xE4, 0x84, 0xCF, 0x2E, 0x74, 0xA9, 0x28, + 0x99, 0x40, 0x36, 0x43, 0x53, 0x24, 0x9B, 0x27, + 0xB4, 0xC9, 0xAE, 0x29, 0xED, 0xDF, 0xC7, 0xDA, + 0x64, 0x18, 0x79, 0x1A, 0x4E, 0x7B, 0xAA, 0x06, + 0x60, 0xFA, 0x64, 0x51, 0x1F, 0x2D, 0x68, 0x5C, + 0xC3, 0xA5, 0xFF, 0x70, 0xE0, 0xD2, 0xB7, 0x42, + 0x92, 0xE3, 0xB8, 0xA0, 0xCD, 0x6B, 0x04, 0xB1, + 0xC7, 0x90, 0xB8, 0xEA, 0xD2, 0x70, 0x37, 0x08, + 0x54, 0x0D, 0xEA, 0x2F, 0xC0, 0x9C, 0x3D, 0xA7, + 0x70, 0xF6, 0x54, 0x49, 0xE8, 0x4D, 0x81, 0x7A, + 0x4F, 0x55, 0x10, 0x55, 0xE1, 0x9A, 0xB8, 0x50, + 0x18, 0xA0, 0x02, 0x8B, 0x71, 0xA1, 0x44, 0xD9, + 0x67, 0x91, 0xE9, 0xA3, 0x57, 0x79, 0x33, 0x50, + 0x4E, 0xEE, 0x00, 0x60, 0x34, 0x0C, 0x69, 0xD2, + 0x74, 0xE1, 0xBF, 0x9D, 0x80, 0x5D, 0xCB, 0xCC, + 0x1A, 0x6F, 0xAA, 0x97, 0x68, 0x00, 0xB6, 0xFF, + 0x2B, 0x67, 0x1D, 0xC4, 0x63, 0x65, 0x2F, 0xA8, + 0xA3, 0x3E, 0xE5, 0x09, 0x74, 0xC1, 0xC2, 0x1B, + 0xE0, 0x1E, 0xAB, 0xB2, 0x16, 0x74, 0x30, 0x26, + 0x9D, 0x72, 0xEE, 0x51, 0x1C, 0x9D, 0xDE, 0x30, + 0x79, 0x7C, 0x9A, 0x25, 0xD8, 0x6C, 0xE7, 0x4F, + 0x5B, 0x96, 0x1B, 0xE5, 0xFD, 0xFB, 0x68, 0x07, + 0x81, 0x40, 0x39, 0xE7, 0x13, 0x76, 0x36, 0xBD, + 0x1D, 0x7F, 0xA9, 0xE0, 0x9E, 0xFD, 0x20, 0x07, + 0x50, 0x59, 0x06, 0xA5, 0xAC, 0x45, 0xDF, 0xDE, + 0xED, 0x77, 0x57, 0xBB, 0xEE, 0x74, 0x57, 0x49, + 0xC2, 0x96, 0x33, 0x35, 0x0B, 0xEE, 0x0E, 0xA6, + 0xF4, 0x09, 0xDF, 0x45, 0x80, 0x16, 0x00 + }, + .len = 4024 + }, + .ciphertext = { + .data = { + 0x94, 0xEA, 0xA4, 0xAA, 0x30, 0xA5, 0x71, 0x37, + 0xDD, 0xF0, 0x9B, 0x97, 0xB2, 0x56, 0x18, 0xA2, + 0x0A, 0x13, 0xE2, 0xF1, 0x0F, 0xA5, 0xBF, 0x81, + 0x61, 0xA8, 0x79, 0xCC, 0x2A, 0xE7, 0x97, 0xA6, + 0xB4, 0xCF, 0x2D, 0x9D, 0xF3, 0x1D, 0xEB, 0xB9, + 0x90, 0x5C, 0xCF, 0xEC, 0x97, 0xDE, 0x60, 0x5D, + 0x21, 0xC6, 0x1A, 0xB8, 0x53, 0x1B, 0x7F, 0x3C, + 0x9D, 0xA5, 0xF0, 0x39, 0x31, 0xF8, 0xA0, 0x64, + 0x2D, 0xE4, 0x82, 0x11, 0xF5, 0xF5, 0x2F, 0xFE, + 0xA1, 0x0F, 0x39, 0x2A, 0x04, 0x76, 0x69, 0x98, + 0x5D, 0xA4, 0x54, 0xA2, 0x8F, 0x08, 0x09, 0x61, + 0xA6, 0xC2, 0xB6, 0x2D, 0xAA, 0x17, 0xF3, 0x3C, + 0xD6, 0x0A, 0x49, 0x71, 0xF4, 0x8D, 0x2D, 0x90, + 0x93, 0x94, 0xA5, 0x5F, 0x48, 0x11, 0x7A, 0xCE, + 0x43, 0xD7, 0x08, 0xE6, 0xB7, 0x7D, 0x3D, 0xC4, + 0x6D, 0x8B, 0xC0, 0x17, 0xD4, 0xD1, 0xAB, 0xB7, + 0x7B, 0x74, 0x28, 0xC0, 0x42, 0xB0, 0x6F, 0x2F, + 0x99, 0xD8, 0xD0, 0x7C, 0x98, 0x79, 0xD9, 0x96, + 0x00, 0x12, 0x7A, 0x31, 0x98, 0x5F, 0x10, 0x99, + 0xBB, 0xD7, 0xD6, 0xC1, 0x51, 0x9E, 0xDE, 0x8F, + 0x5E, 0xEB, 0x4A, 0x61, 0x0B, 0x34, 0x9A, 0xC0, + 0x1E, 0xA2, 0x35, 0x06, 0x91, 0x75, 0x6B, 0xD1, + 0x05, 0xC9, 0x74, 0xA5, 0x3E, 0xDD, 0xB3, 0x5D, + 0x1D, 0x41, 0x00, 0xB0, 0x12, 0xE5, 0x22, 0xAB, + 0x41, 0xF4, 0xC5, 0xF2, 0xFD, 0xE7, 0x6B, 0x59, + 0xCB, 0x8B, 0x96, 0xD8, 0x85, 0xCF, 0xE4, 0x08, + 0x0D, 0x13, 0x28, 0xA0, 0xD6, 0x36, 0xCC, 0x0E, + 0xDC, 0x05, 0x80, 0x0B, 0x76, 0xAC, 0xCA, 0x8F, + 0xEF, 0x67, 0x20, 0x84, 0xD1, 0xF5, 0x2A, 0x8B, + 0xBD, 0x8E, 0x09, 0x93, 0x32, 0x09, 0x92, 0xC7, + 0xFF, 0xBA, 0xE1, 0x7C, 0x40, 0x84, 0x41, 0xE0, + 0xEE, 0x88, 0x3F, 0xC8, 0xA8, 0xB0, 0x5E, 0x22, + 0xF5, 0xFF, 0x7F, 0x8D, 0x1B, 0x48, 0xC7, 0x4C, + 0x46, 0x8C, 0x46, 0x7A, 0x02, 0x8F, 0x09, 0xFD, + 0x7C, 0xE9, 0x11, 0x09, 0xA5, 0x70, 0xA2, 0xD5, + 0xC4, 0xD5, 0xF4, 0xFA, 0x18, 0xC5, 0xDD, 0x3E, + 0x45, 0x62, 0xAF, 0xE2, 0x4E, 0xF7, 0x71, 0x90, + 0x1F, 0x59, 0xAF, 0x64, 0x58, 0x98, 0xAC, 0xEF, + 0x08, 0x8A, 0xBA, 0xE0, 0x7E, 0x92, 0xD5, 0x2E, + 0xB2, 0xDE, 0x55, 0x04, 0x5B, 0xB1, 0xB7, 0xC4, + 0x16, 0x4E, 0xF2, 0xD7, 0xA6, 0xCA, 0xC1, 0x5E, + 0xEB, 0x92, 0x6D, 0x7E, 0xA2, 0xF0, 0x8B, 0x66, + 0xE1, 0xF7, 0x59, 0xF3, 0xAE, 0xE4, 0x46, 0x14, + 0x72, 0x5A, 0xA3, 0xC7, 0x48, 0x2B, 0x30, 0x84, + 0x4C, 0x14, 0x3F, 0xF8, 0x5B, 0x53, 0xF1, 0xE5, + 0x83, 0xC5, 0x01, 0x25, 0x7D, 0xDD, 0xD0, 0x96, + 0xB8, 0x12, 0x68, 0xDA, 0xA3, 0x03, 0xF1, 0x72, + 0x34, 0xC2, 0x33, 0x35, 0x41, 0xF0, 0xBB, 0x8E, + 0x19, 0x06, 0x48, 0xC5, 0x80, 0x7C, 0x86, 0x6D, + 0x71, 0x93, 0x22, 0x86, 0x09, 0xAD, 0xB9, 0x48, + 0x68, 0x6F, 0x7D, 0xE2, 0x94, 0xA8, 0x02, 0xCC, + 0x38, 0xF7, 0xFE, 0x52, 0x08, 0xF5, 0xEA, 0x31, + 0x96, 0xD0, 0x16, 0x7B, 0x9B, 0xDD, 0x02, 0xF0, + 0xD2, 0xA5, 0x22, 0x1C, 0xA5, 0x08, 0xF8, 0x93, + 0xAF, 0x5C, 0x4B, 0x4B, 0xB9, 0xF4, 0xF5, 0x20, + 0xFD, 0x84, 0x28, 0x9B, 0x3D, 0xBE, 0x7E, 0x61, + 0x49, 0x7A, 0x7E, 0x2A, 0x58, 0x40, 0x37, 0xEA, + 0x63, 0x7B, 0x69, 0x81, 0x12, 0x71, 0x74, 0xAF, + 0x57, 0xB4, 0x71, 0xDF, 0x4B, 0x27, 0x68, 0xFD, + 0x79, 0xC1, 0x54, 0x0F, 0xB3, 0xED, 0xF2, 0xEA, + 0x22, 0xCB, 0x69, 0xBE, 0xC0, 0xCF, 0x8D, 0x93, + 0x3D, 0x9C, 0x6F, 0xDD, 0x64, 0x5E, 0x85, 0x05, + 0x91, 0xCC, 0xA3, 0xD6, 0x2C, 0x0C, 0xC0 + }, + .len = 4024 + }, + .validDataLenInBits = { + .len = 4019 + }, + .validCipherLenInBits = { + .len = 4019 + }, + .validCipherOffsetLenInBits = { + .len = 128 + } +}; + +#endif /* TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ */ diff --git a/test/test/test_cycles.c b/test/test/test_cycles.c new file mode 100644 index 0000000000..f1897979d2 --- /dev/null +++ b/test/test/test_cycles.c @@ -0,0 +1,137 @@ +/*- + * 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 +#include + +#include +#include + +#include "test.h" + +#define N 10000 + +/* + * Cycles test + * =========== + * + * - Loop N times and check that the timer always increments and + * never decrements during this loop. + * + * - Wait one second using rte_usleep() and check that the increment + * of cycles is correct with regard to the frequency of the timer. + */ + +static int +test_cycles(void) +{ + unsigned i; + uint64_t start_cycles, cycles, prev_cycles; + uint64_t hz = rte_get_timer_hz(); + uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */ + + /* check that the timer is always incrementing */ + start_cycles = rte_get_timer_cycles(); + prev_cycles = start_cycles; + for (i=0; i max_inc) { + printf("increment too high or going backwards\n"); + return -1; + } + prev_cycles = cycles; + } + + /* check that waiting 1 second is precise */ + prev_cycles = rte_get_timer_cycles(); + rte_delay_us(1000000); + cycles = rte_get_timer_cycles(); + + if ((uint64_t)(cycles - prev_cycles) > (hz + max_inc)) { + printf("delay_us is not accurate: too long\n"); + return -1; + } + if ((uint64_t)(cycles - prev_cycles) < (hz - max_inc)) { + printf("delay_us is not accurate: too short\n"); + return -1; + } + + return 0; +} + +REGISTER_TEST_COMMAND(cycles_autotest, test_cycles); + +/* + * rte_delay_us_callback test + * + * - check if callback is correctly registered/unregistered + * + */ + +static unsigned int pattern; +static void my_rte_delay_us(unsigned int us) +{ + pattern += us; +} + +static int +test_user_delay_us(void) +{ + pattern = 0; + + rte_delay_us(2); + if (pattern != 0) + return -1; + + /* register custom delay function */ + rte_delay_us_callback_register(my_rte_delay_us); + + rte_delay_us(2); + if (pattern != 2) + return -1; + + rte_delay_us(3); + if (pattern != 5) + return -1; + + /* restore original delay function */ + rte_delay_us_callback_register(rte_delay_us_block); + + rte_delay_us(3); + if (pattern != 5) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(user_delay_us, test_user_delay_us); diff --git a/test/test/test_debug.c b/test/test/test_debug.c new file mode 100644 index 0000000000..0a3b2c468a --- /dev/null +++ b/test/test/test_debug.c @@ -0,0 +1,149 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include + +#include "test.h" + +/* + * Debug test + * ========== + */ + +/* use fork() to test rte_panic() */ +static int +test_panic(void) +{ + int pid; + int status; + + pid = fork(); + + if (pid == 0) + rte_panic("Test Debug\n"); + else if (pid < 0){ + printf("Fork Failed\n"); + return -1; + } + wait(&status); + if(status == 0){ + printf("Child process terminated normally!\n"); + return -1; + } else + printf("Child process terminated as expected - Test passed!\n"); + + return 0; +} + +/* use fork() to test rte_exit() */ +static int +test_exit_val(int exit_val) +{ + int pid; + int status; + + pid = fork(); + + if (pid == 0) + rte_exit(exit_val, __func__); + else if (pid < 0){ + printf("Fork Failed\n"); + return -1; + } + wait(&status); + printf("Child process status: %d\n", status); +#ifndef RTE_EAL_ALWAYS_PANIC_ON_ERROR + if(!WIFEXITED(status) || WEXITSTATUS(status) != (uint8_t)exit_val){ + printf("Child process terminated with incorrect status (expected = %d)!\n", + exit_val); + return -1; + } +#endif + return 0; +} + +static int +test_exit(void) +{ + int test_vals[] = { 0, 1, 2, 255, -1 }; + unsigned i; + for (i = 0; i < sizeof(test_vals) / sizeof(test_vals[0]); i++){ + if (test_exit_val(test_vals[i]) < 0) + return -1; + } + printf("%s Passed\n", __func__); + return 0; +} + +static void +dummy_app_usage(const char *progname) +{ + RTE_SET_USED(progname); +} + +static int +test_usage(void) +{ + if (rte_set_application_usage_hook(dummy_app_usage) != NULL) { + printf("Non-NULL value returned for initial usage hook\n"); + return -1; + } + if (rte_set_application_usage_hook(NULL) != dummy_app_usage) { + printf("Incorrect value returned for application usage hook\n"); + return -1; + } + return 0; +} + +static int +test_debug(void) +{ + rte_dump_stack(); + rte_dump_registers(); + if (test_panic() < 0) + return -1; + if (test_exit() < 0) + return -1; + if (test_usage() < 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(debug_autotest, test_debug); diff --git a/test/test/test_devargs.c b/test/test/test_devargs.c new file mode 100644 index 0000000000..63242f1caf --- /dev/null +++ b/test/test/test_devargs.c @@ -0,0 +1,134 @@ +/*- + * BSD LICENSE + * + * Copyright 2014 6WIND S.A. + * + * 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 6WIND S.A 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 +#include +#include +#include + +#include +#include + +#include "test.h" + +/* clear devargs list that was modified by the test */ +static void free_devargs_list(void) +{ + struct rte_devargs *devargs; + + while (!TAILQ_EMPTY(&devargs_list)) { + devargs = TAILQ_FIRST(&devargs_list); + TAILQ_REMOVE(&devargs_list, devargs, next); + free(devargs->args); + free(devargs); + } +} + +static int +test_devargs(void) +{ + struct rte_devargs_list save_devargs_list; + struct rte_devargs *devargs; + + /* save the real devargs_list, it is restored at the end of the test */ + save_devargs_list = devargs_list; + TAILQ_INIT(&devargs_list); + + /* test valid cases */ + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:00.1") < 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "0000:5:00.0") < 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "04:00.0,arg=val") < 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "0000:01:00.1") < 0) + goto fail; + if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 2) + goto fail; + if (rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 2) + goto fail; + if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "net_ring0") < 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "net_ring1,key=val,k2=val2") < 0) + goto fail; + if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 2) + goto fail; + free_devargs_list(); + + /* check virtual device with argument parsing */ + if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "net_ring1,k1=val,k2=val2") < 0) + goto fail; + devargs = TAILQ_FIRST(&devargs_list); + if (strncmp(devargs->virt.drv_name, "net_ring1", + sizeof(devargs->virt.drv_name)) != 0) + goto fail; + if (!devargs->args || strcmp(devargs->args, "k1=val,k2=val2") != 0) + goto fail; + free_devargs_list(); + + /* check PCI device with empty argument parsing */ + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "04:00.1") < 0) + goto fail; + devargs = TAILQ_FIRST(&devargs_list); + if (devargs->pci.addr.domain != 0 || + devargs->pci.addr.bus != 4 || + devargs->pci.addr.devid != 0 || + devargs->pci.addr.function != 1) + goto fail; + if (!devargs->args || strcmp(devargs->args, "") != 0) + goto fail; + free_devargs_list(); + + /* test error case: bad PCI address */ + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:1") == 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "00.1") == 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "foo") == 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, ",") == 0) + goto fail; + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "000f:0:0") == 0) + goto fail; + + devargs_list = save_devargs_list; + return 0; + + fail: + free_devargs_list(); + devargs_list = save_devargs_list; + return -1; +} + +REGISTER_TEST_COMMAND(devargs_autotest, test_devargs); diff --git a/test/test/test_distributor.c b/test/test/test_distributor.c new file mode 100644 index 0000000000..85cb8f3919 --- /dev/null +++ b/test/test/test_distributor.c @@ -0,0 +1,579 @@ +/*- + * 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 "test.h" + +#include +#include +#include +#include +#include +#include +#include + +#define ITER_POWER 20 /* log 2 of how many iterations we do when timing. */ +#define BURST 32 +#define BIG_BATCH 1024 + +/* statics - all zero-initialized by default */ +static volatile int quit; /**< general quit variable for all threads */ +static volatile int zero_quit; /**< var for when we just want thr0 to quit*/ +static volatile unsigned worker_idx; + +struct worker_stats { + volatile unsigned handled_packets; +} __rte_cache_aligned; +struct worker_stats worker_stats[RTE_MAX_LCORE]; + +/* returns the total count of the number of packets handled by the worker + * functions given below. + */ +static inline unsigned +total_packet_count(void) +{ + unsigned i, count = 0; + for (i = 0; i < worker_idx; i++) + count += worker_stats[i].handled_packets; + return count; +} + +/* resets the packet counts for a new test */ +static inline void +clear_packet_count(void) +{ + memset(&worker_stats, 0, sizeof(worker_stats)); +} + +/* this is the basic worker function for sanity test + * it does nothing but return packets and count them. + */ +static int +handle_work(void *arg) +{ + struct rte_mbuf *pkt = NULL; + struct rte_distributor *d = arg; + unsigned count = 0; + unsigned id = __sync_fetch_and_add(&worker_idx, 1); + + pkt = rte_distributor_get_pkt(d, id, NULL); + while (!quit) { + worker_stats[id].handled_packets++, count++; + pkt = rte_distributor_get_pkt(d, id, pkt); + } + worker_stats[id].handled_packets++, count++; + rte_distributor_return_pkt(d, id, pkt); + return 0; +} + +/* do basic sanity testing of the distributor. This test tests the following: + * - send 32 packets through distributor with the same tag and ensure they + * all go to the one worker + * - send 32 packets throught the distributor with two different tags and + * verify that they go equally to two different workers. + * - send 32 packets with different tags through the distributors and + * just verify we get all packets back. + * - send 1024 packets through the distributor, gathering the returned packets + * as we go. Then verify that we correctly got all 1024 pointers back again, + * not necessarily in the same order (as different flows). + */ +static int +sanity_test(struct rte_distributor *d, struct rte_mempool *p) +{ + struct rte_mbuf *bufs[BURST]; + unsigned i; + + printf("=== Basic distributor sanity tests ===\n"); + clear_packet_count(); + if (rte_mempool_get_bulk(p, (void *)bufs, BURST) != 0) { + printf("line %d: Error getting mbufs from pool\n", __LINE__); + return -1; + } + + /* now set all hash values in all buffers to zero, so all pkts go to the + * one worker thread */ + for (i = 0; i < BURST; i++) + bufs[i]->hash.usr = 0; + + rte_distributor_process(d, bufs, BURST); + rte_distributor_flush(d); + if (total_packet_count() != BURST) { + printf("Line %d: Error, not all packets flushed. " + "Expected %u, got %u\n", + __LINE__, BURST, total_packet_count()); + return -1; + } + + for (i = 0; i < rte_lcore_count() - 1; i++) + printf("Worker %u handled %u packets\n", i, + worker_stats[i].handled_packets); + printf("Sanity test with all zero hashes done.\n"); + if (worker_stats[0].handled_packets != BURST) + return -1; + + /* pick two flows and check they go correctly */ + if (rte_lcore_count() >= 3) { + clear_packet_count(); + for (i = 0; i < BURST; i++) + bufs[i]->hash.usr = (i & 1) << 8; + + rte_distributor_process(d, bufs, BURST); + rte_distributor_flush(d); + if (total_packet_count() != BURST) { + printf("Line %d: Error, not all packets flushed. " + "Expected %u, got %u\n", + __LINE__, BURST, total_packet_count()); + return -1; + } + + for (i = 0; i < rte_lcore_count() - 1; i++) + printf("Worker %u handled %u packets\n", i, + worker_stats[i].handled_packets); + printf("Sanity test with two hash values done\n"); + + if (worker_stats[0].handled_packets != 16 || + worker_stats[1].handled_packets != 16) + return -1; + } + + /* give a different hash value to each packet, + * so load gets distributed */ + clear_packet_count(); + for (i = 0; i < BURST; i++) + bufs[i]->hash.usr = i; + + rte_distributor_process(d, bufs, BURST); + rte_distributor_flush(d); + if (total_packet_count() != BURST) { + printf("Line %d: Error, not all packets flushed. " + "Expected %u, got %u\n", + __LINE__, BURST, total_packet_count()); + return -1; + } + + for (i = 0; i < rte_lcore_count() - 1; i++) + printf("Worker %u handled %u packets\n", i, + worker_stats[i].handled_packets); + printf("Sanity test with non-zero hashes done\n"); + + rte_mempool_put_bulk(p, (void *)bufs, BURST); + + /* sanity test with BIG_BATCH packets to ensure they all arrived back + * from the returned packets function */ + clear_packet_count(); + struct rte_mbuf *many_bufs[BIG_BATCH], *return_bufs[BIG_BATCH]; + unsigned num_returned = 0; + + /* flush out any remaining packets */ + rte_distributor_flush(d); + rte_distributor_clear_returns(d); + if (rte_mempool_get_bulk(p, (void *)many_bufs, BIG_BATCH) != 0) { + printf("line %d: Error getting mbufs from pool\n", __LINE__); + return -1; + } + for (i = 0; i < BIG_BATCH; i++) + many_bufs[i]->hash.usr = i << 2; + + for (i = 0; i < BIG_BATCH/BURST; i++) { + rte_distributor_process(d, &many_bufs[i*BURST], BURST); + num_returned += rte_distributor_returned_pkts(d, + &return_bufs[num_returned], + BIG_BATCH - num_returned); + } + rte_distributor_flush(d); + num_returned += rte_distributor_returned_pkts(d, + &return_bufs[num_returned], BIG_BATCH - num_returned); + + if (num_returned != BIG_BATCH) { + printf("line %d: Number returned is not the same as " + "number sent\n", __LINE__); + return -1; + } + /* big check - make sure all packets made it back!! */ + for (i = 0; i < BIG_BATCH; i++) { + unsigned j; + struct rte_mbuf *src = many_bufs[i]; + for (j = 0; j < BIG_BATCH; j++) + if (return_bufs[j] == src) + break; + + if (j == BIG_BATCH) { + printf("Error: could not find source packet #%u\n", i); + return -1; + } + } + printf("Sanity test of returned packets done\n"); + + rte_mempool_put_bulk(p, (void *)many_bufs, BIG_BATCH); + + printf("\n"); + return 0; +} + + +/* to test that the distributor does not lose packets, we use this worker + * function which frees mbufs when it gets them. The distributor thread does + * the mbuf allocation. If distributor drops packets we'll eventually run out + * of mbufs. + */ +static int +handle_work_with_free_mbufs(void *arg) +{ + struct rte_mbuf *pkt = NULL; + struct rte_distributor *d = arg; + unsigned count = 0; + unsigned id = __sync_fetch_and_add(&worker_idx, 1); + + pkt = rte_distributor_get_pkt(d, id, NULL); + while (!quit) { + worker_stats[id].handled_packets++, count++; + rte_pktmbuf_free(pkt); + pkt = rte_distributor_get_pkt(d, id, pkt); + } + worker_stats[id].handled_packets++, count++; + rte_distributor_return_pkt(d, id, pkt); + return 0; +} + +/* Perform a sanity test of the distributor with a large number of packets, + * where we allocate a new set of mbufs for each burst. The workers then + * free the mbufs. This ensures that we don't have any packet leaks in the + * library. + */ +static int +sanity_test_with_mbuf_alloc(struct rte_distributor *d, struct rte_mempool *p) +{ + unsigned i; + struct rte_mbuf *bufs[BURST]; + + printf("=== Sanity test with mbuf alloc/free ===\n"); + clear_packet_count(); + for (i = 0; i < ((1<hash.usr = (i+j) << 1; + rte_mbuf_refcnt_set(bufs[j], 1); + } + + rte_distributor_process(d, bufs, BURST); + } + + rte_distributor_flush(d); + if (total_packet_count() < (1<hash.usr = 0; + + rte_distributor_process(d, bufs, BURST); + /* at this point, we will have processed some packets and have a full + * backlog for the other ones at worker 0. + */ + + /* get more buffers to queue up, again setting them to the same flow */ + if (rte_mempool_get_bulk(p, (void *)bufs, BURST) != 0) { + printf("line %d: Error getting mbufs from pool\n", __LINE__); + return -1; + } + for (i = 0; i < BURST; i++) + bufs[i]->hash.usr = 0; + + /* get worker zero to quit */ + zero_quit = 1; + rte_distributor_process(d, bufs, BURST); + + /* flush the distributor */ + rte_distributor_flush(d); + if (total_packet_count() != BURST * 2) { + printf("Line %d: Error, not all packets flushed. " + "Expected %u, got %u\n", + __LINE__, BURST * 2, total_packet_count()); + return -1; + } + + for (i = 0; i < rte_lcore_count() - 1; i++) + printf("Worker %u handled %u packets\n", i, + worker_stats[i].handled_packets); + + printf("Sanity test with worker shutdown passed\n\n"); + return 0; +} + +/* Test that the flush function is able to move packets between workers when + * one worker shuts down.. + */ +static int +test_flush_with_worker_shutdown(struct rte_distributor *d, + struct rte_mempool *p) +{ + struct rte_mbuf *bufs[BURST]; + unsigned i; + + printf("=== Test flush fn with worker shutdown ===\n"); + + clear_packet_count(); + if (rte_mempool_get_bulk(p, (void *)bufs, BURST) != 0) { + printf("line %d: Error getting mbufs from pool\n", __LINE__); + return -1; + } + + /* now set all hash values in all buffers to zero, so all pkts go to the + * one worker thread */ + for (i = 0; i < BURST; i++) + bufs[i]->hash.usr = 0; + + rte_distributor_process(d, bufs, BURST); + /* at this point, we will have processed some packets and have a full + * backlog for the other ones at worker 0. + */ + + /* get worker zero to quit */ + zero_quit = 1; + + /* flush the distributor */ + rte_distributor_flush(d); + + zero_quit = 0; + if (total_packet_count() != BURST) { + printf("Line %d: Error, not all packets flushed. " + "Expected %u, got %u\n", + __LINE__, BURST, total_packet_count()); + return -1; + } + + for (i = 0; i < rte_lcore_count() - 1; i++) + printf("Worker %u handled %u packets\n", i, + worker_stats[i].handled_packets); + + printf("Flush test with worker shutdown passed\n\n"); + return 0; +} + +static +int test_error_distributor_create_name(void) +{ + struct rte_distributor *d = NULL; + char *name = NULL; + + d = rte_distributor_create(name, rte_socket_id(), + rte_lcore_count() - 1); + if (d != NULL || rte_errno != EINVAL) { + printf("ERROR: No error on create() with NULL name param\n"); + return -1; + } + + return 0; +} + + +static +int test_error_distributor_create_numworkers(void) +{ + struct rte_distributor *d = NULL; + d = rte_distributor_create("test_numworkers", rte_socket_id(), + RTE_MAX_LCORE + 10); + if (d != NULL || rte_errno != EINVAL) { + printf("ERROR: No error on create() with num_workers > MAX\n"); + return -1; + } + return 0; +} + + +/* Useful function which ensures that all worker functions terminate */ +static void +quit_workers(struct rte_distributor *d, struct rte_mempool *p) +{ + const unsigned num_workers = rte_lcore_count() - 1; + unsigned i; + struct rte_mbuf *bufs[RTE_MAX_LCORE]; + rte_mempool_get_bulk(p, (void *)bufs, num_workers); + + zero_quit = 0; + quit = 1; + for (i = 0; i < num_workers; i++) + bufs[i]->hash.usr = i << 1; + rte_distributor_process(d, bufs, num_workers); + + rte_mempool_put_bulk(p, (void *)bufs, num_workers); + + rte_distributor_process(d, NULL, 0); + rte_distributor_flush(d); + rte_eal_mp_wait_lcore(); + quit = 0; + worker_idx = 0; +} + +static int +test_distributor(void) +{ + static struct rte_distributor *d; + static struct rte_mempool *p; + + if (rte_lcore_count() < 2) { + printf("ERROR: not enough cores to test distributor\n"); + return -1; + } + + if (d == NULL) { + d = rte_distributor_create("Test_distributor", rte_socket_id(), + rte_lcore_count() - 1); + if (d == NULL) { + printf("Error creating distributor\n"); + return -1; + } + } else { + rte_distributor_flush(d); + rte_distributor_clear_returns(d); + } + + const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ? + (BIG_BATCH * 2) - 1 : (511 * rte_lcore_count()); + if (p == NULL) { + p = rte_pktmbuf_pool_create("DT_MBUF_POOL", nb_bufs, BURST, + 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + if (p == NULL) { + printf("Error creating mempool\n"); + return -1; + } + } + + rte_eal_mp_remote_launch(handle_work, d, SKIP_MASTER); + if (sanity_test(d, p) < 0) + goto err; + quit_workers(d, p); + + rte_eal_mp_remote_launch(handle_work_with_free_mbufs, d, SKIP_MASTER); + if (sanity_test_with_mbuf_alloc(d, p) < 0) + goto err; + quit_workers(d, p); + + if (rte_lcore_count() > 2) { + rte_eal_mp_remote_launch(handle_work_for_shutdown_test, d, + SKIP_MASTER); + if (sanity_test_with_worker_shutdown(d, p) < 0) + goto err; + quit_workers(d, p); + + rte_eal_mp_remote_launch(handle_work_for_shutdown_test, d, + SKIP_MASTER); + if (test_flush_with_worker_shutdown(d, p) < 0) + goto err; + quit_workers(d, p); + + } else { + printf("Not enough cores to run tests for worker shutdown\n"); + } + + if (test_error_distributor_create_numworkers() == -1 || + test_error_distributor_create_name() == -1) { + printf("rte_distributor_create parameter check tests failed"); + return -1; + } + + return 0; + +err: + quit_workers(d, p); + return -1; +} + +REGISTER_TEST_COMMAND(distributor_autotest, test_distributor); diff --git a/test/test/test_distributor_perf.c b/test/test/test_distributor_perf.c new file mode 100644 index 0000000000..7947fe9b16 --- /dev/null +++ b/test/test/test_distributor_perf.c @@ -0,0 +1,260 @@ +/*- + * 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 "test.h" + +#include +#include +#include +#include +#include +#include +#include + +#define ITER_POWER 20 /* log 2 of how many iterations we do when timing. */ +#define BURST 32 +#define BIG_BATCH 1024 + +/* static vars - zero initialized by default */ +static volatile int quit; +static volatile unsigned worker_idx; + +struct worker_stats { + volatile unsigned handled_packets; +} __rte_cache_aligned; +struct worker_stats worker_stats[RTE_MAX_LCORE]; + +/* worker thread used for testing the time to do a round-trip of a cache + * line between two cores and back again + */ +static void +flip_bit(volatile uint64_t *arg) +{ + uint64_t old_val = 0; + while (old_val != 2) { + while (!*arg) + rte_pause(); + old_val = *arg; + *arg = 0; + } +} + +/* test case to time the number of cycles to round-trip a cache line between + * two cores and back again. + */ +static void +time_cache_line_switch(void) +{ + /* allocate a full cache line for data, we use only first byte of it */ + uint64_t data[RTE_CACHE_LINE_SIZE*3 / sizeof(uint64_t)]; + + unsigned i, slaveid = rte_get_next_lcore(rte_lcore_id(), 0, 0); + volatile uint64_t *pdata = &data[0]; + *pdata = 1; + rte_eal_remote_launch((lcore_function_t *)flip_bit, &data[0], slaveid); + while (*pdata) + rte_pause(); + + const uint64_t start_time = rte_rdtsc(); + for (i = 0; i < (1 << ITER_POWER); i++) { + while (*pdata) + rte_pause(); + *pdata = 1; + } + const uint64_t end_time = rte_rdtsc(); + + while (*pdata) + rte_pause(); + *pdata = 2; + rte_eal_wait_lcore(slaveid); + printf("==== Cache line switch test ===\n"); + printf("Time for %u iterations = %"PRIu64" ticks\n", (1<> ITER_POWER); +} + +/* returns the total count of the number of packets handled by the worker + * functions given below. + */ +static unsigned +total_packet_count(void) +{ + unsigned i, count = 0; + for (i = 0; i < worker_idx; i++) + count += worker_stats[i].handled_packets; + return count; +} + +/* resets the packet counts for a new test */ +static void +clear_packet_count(void) +{ + memset(&worker_stats, 0, sizeof(worker_stats)); +} + +/* this is the basic worker function for performance tests. + * it does nothing but return packets and count them. + */ +static int +handle_work(void *arg) +{ + struct rte_mbuf *pkt = NULL; + struct rte_distributor *d = arg; + unsigned count = 0; + unsigned id = __sync_fetch_and_add(&worker_idx, 1); + + pkt = rte_distributor_get_pkt(d, id, NULL); + while (!quit) { + worker_stats[id].handled_packets++, count++; + pkt = rte_distributor_get_pkt(d, id, pkt); + } + worker_stats[id].handled_packets++, count++; + rte_distributor_return_pkt(d, id, pkt); + return 0; +} + +/* this basic performance test just repeatedly sends in 32 packets at a time + * to the distributor and verifies at the end that we got them all in the worker + * threads and finally how long per packet the processing took. + */ +static inline int +perf_test(struct rte_distributor *d, struct rte_mempool *p) +{ + unsigned i; + uint64_t start, end; + struct rte_mbuf *bufs[BURST]; + + clear_packet_count(); + if (rte_mempool_get_bulk(p, (void *)bufs, BURST) != 0) { + printf("Error getting mbufs from pool\n"); + return -1; + } + /* ensure we have different hash value for each pkt */ + for (i = 0; i < BURST; i++) + bufs[i]->hash.usr = i; + + start = rte_rdtsc(); + for (i = 0; i < (1<> ITER_POWER); + printf("Time per packet: %"PRIu64"\n\n", + ((end - start) >> ITER_POWER)/BURST); + rte_mempool_put_bulk(p, (void *)bufs, BURST); + + for (i = 0; i < rte_lcore_count() - 1; i++) + printf("Worker %u handled %u packets\n", i, + worker_stats[i].handled_packets); + printf("Total packets: %u (%x)\n", total_packet_count(), + total_packet_count()); + printf("=== Perf test done ===\n\n"); + + return 0; +} + +/* Useful function which ensures that all worker functions terminate */ +static void +quit_workers(struct rte_distributor *d, struct rte_mempool *p) +{ + const unsigned num_workers = rte_lcore_count() - 1; + unsigned i; + struct rte_mbuf *bufs[RTE_MAX_LCORE]; + rte_mempool_get_bulk(p, (void *)bufs, num_workers); + + quit = 1; + for (i = 0; i < num_workers; i++) + bufs[i]->hash.usr = i << 1; + rte_distributor_process(d, bufs, num_workers); + + rte_mempool_put_bulk(p, (void *)bufs, num_workers); + + rte_distributor_process(d, NULL, 0); + rte_eal_mp_wait_lcore(); + quit = 0; + worker_idx = 0; +} + +static int +test_distributor_perf(void) +{ + static struct rte_distributor *d; + static struct rte_mempool *p; + + if (rte_lcore_count() < 2) { + printf("ERROR: not enough cores to test distributor\n"); + return -1; + } + + /* first time how long it takes to round-trip a cache line */ + time_cache_line_switch(); + + if (d == NULL) { + d = rte_distributor_create("Test_perf", rte_socket_id(), + rte_lcore_count() - 1); + if (d == NULL) { + printf("Error creating distributor\n"); + return -1; + } + } else { + rte_distributor_flush(d); + rte_distributor_clear_returns(d); + } + + const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ? + (BIG_BATCH * 2) - 1 : (511 * rte_lcore_count()); + if (p == NULL) { + p = rte_pktmbuf_pool_create("DPT_MBUF_POOL", nb_bufs, BURST, + 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + if (p == NULL) { + printf("Error creating mempool\n"); + return -1; + } + } + + rte_eal_mp_remote_launch(handle_work, d, SKIP_MASTER); + if (perf_test(d, p) < 0) + return -1; + quit_workers(d, p); + + return 0; +} + +REGISTER_TEST_COMMAND(distributor_perf_autotest, test_distributor_perf); diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c new file mode 100644 index 0000000000..91b40664ba --- /dev/null +++ b/test/test/test_eal_flags.c @@ -0,0 +1,1444 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2014 6WIND S.A. + * 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 + +#include "test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "process.h" + +#ifdef RTE_LIBRTE_XEN_DOM0 +#define DEFAULT_MEM_SIZE "30" +#else +#define DEFAULT_MEM_SIZE "18" +#endif +#define mp_flag "--proc-type=secondary" +#define no_hpet "--no-hpet" +#define no_huge "--no-huge" +#define no_shconf "--no-shconf" +#define pci_whitelist "--pci-whitelist" +#define vdev "--vdev" +#define memtest "memtest" +#define memtest1 "memtest1" +#define memtest2 "memtest2" +#define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 10) +#define launch_proc(ARGV) process_dup(ARGV, \ + sizeof(ARGV)/(sizeof(ARGV[0])), __func__) + +enum hugepage_action { + HUGEPAGE_CHECK_EXISTS = 0, + HUGEPAGE_CHECK_LOCKED, + HUGEPAGE_DELETE, + HUGEPAGE_INVALID +}; + +/* if string contains a hugepage path */ +static int +get_hugepage_path(char * src, int src_len, char * dst, int dst_len) +{ +#define NUM_TOKENS 4 + char *tokens[NUM_TOKENS]; + + /* if we couldn't properly split the string */ + if (rte_strsplit(src, src_len, tokens, NUM_TOKENS, ' ') < NUM_TOKENS) + return 0; + + if (strncmp(tokens[2], "hugetlbfs", sizeof("hugetlbfs")) == 0) { + snprintf(dst, dst_len, "%s", tokens[1]); + return 1; + } + return 0; +} + +/* + * Cycles through hugepage directories and looks for hugepage + * files associated with a given prefix. Depending on value of + * action, the hugepages are checked if they exist, checked if + * they can be locked, or are simply deleted. + * + * Returns 1 if it finds at least one hugepage matching the action + * Returns 0 if no matching hugepages were found + * Returns -1 if it encounters an error + */ +static int +process_hugefiles(const char * prefix, enum hugepage_action action) +{ + FILE * hugedir_handle = NULL; + DIR * hugepage_dir = NULL; + struct dirent *dirent = NULL; + + char hugefile_prefix[PATH_MAX] = {0}; + char hugedir[PATH_MAX] = {0}; + char line[PATH_MAX] = {0}; + + int fd, lck_result, result = 0; + + const int prefix_len = snprintf(hugefile_prefix, + sizeof(hugefile_prefix), "%smap_", prefix); + if (prefix_len <= 0 || prefix_len >= (int)sizeof(hugefile_prefix) + || prefix_len >= (int)sizeof(dirent->d_name)) { + printf("Error creating hugefile filename prefix\n"); + return -1; + } + + /* get hugetlbfs mountpoints from /proc/mounts */ + hugedir_handle = fopen("/proc/mounts", "r"); + + if (hugedir_handle == NULL) { + printf("Error parsing /proc/mounts!\n"); + return -1; + } + + /* read and parse script output */ + while (fgets(line, sizeof(line), hugedir_handle) != NULL) { + + /* check if we have a hugepage filesystem path */ + if (!get_hugepage_path(line, sizeof(line), hugedir, sizeof(hugedir))) + continue; + + /* check if directory exists */ + if ((hugepage_dir = opendir(hugedir)) == NULL) { + fclose(hugedir_handle); + printf("Error reading %s: %s\n", hugedir, strerror(errno)); + return -1; + } + + while ((dirent = readdir(hugepage_dir)) != NULL) { + if (memcmp(dirent->d_name, hugefile_prefix, prefix_len) != 0) + continue; + + switch (action) { + case HUGEPAGE_CHECK_EXISTS: + { + /* file exists, return */ + result = 1; + goto end; + } + break; + case HUGEPAGE_DELETE: + { + char file_path[PATH_MAX] = {0}; + + snprintf(file_path, sizeof(file_path), + "%s/%s", hugedir, dirent->d_name); + + /* remove file */ + if (remove(file_path) < 0) { + printf("Error deleting %s - %s!\n", + dirent->d_name, strerror(errno)); + closedir(hugepage_dir); + result = -1; + goto end; + } + result = 1; + } + break; + case HUGEPAGE_CHECK_LOCKED: + { + /* try and lock the file */ + fd = openat(dirfd(hugepage_dir), dirent->d_name, O_RDONLY); + + /* this shouldn't happen */ + if (fd == -1) { + printf("Error opening %s - %s!\n", + dirent->d_name, strerror(errno)); + closedir(hugepage_dir); + result = -1; + goto end; + } + + /* non-blocking lock */ + lck_result = flock(fd, LOCK_EX | LOCK_NB); + + /* if lock succeeds, there's something wrong */ + if (lck_result != -1) { + result = 0; + + /* unlock the resulting lock */ + flock(fd, LOCK_UN); + close(fd); + closedir(hugepage_dir); + goto end; + } + result = 1; + close(fd); + } + break; + /* shouldn't happen */ + default: + goto end; + } /* switch */ + + } /* read hugepage directory */ + closedir(hugepage_dir); + } /* read /proc/mounts */ +end: + fclose(hugedir_handle); + return result; +} + +#ifdef RTE_EXEC_ENV_LINUXAPP +/* + * count the number of "node*" files in /sys/devices/system/node/ + */ +static int +get_number_of_sockets(void) +{ + struct dirent *dirent = NULL; + const char * nodedir = "/sys/devices/system/node/"; + DIR * dir = NULL; + int result = 0; + + /* check if directory exists */ + if ((dir = opendir(nodedir)) == NULL) { + /* if errno==ENOENT this means we don't have NUMA support */ + if (errno == ENOENT) { + printf("No NUMA nodes detected: assuming 1 available socket\n"); + return 1; + } + printf("Error opening %s: %s\n", nodedir, strerror(errno)); + return -1; + } + + while ((dirent = readdir(dir)) != NULL) + if (strncmp(dirent->d_name, "node", sizeof("node") - 1) == 0) + result++; + + closedir(dir); + return result; +} +#endif + +static char* +get_current_prefix(char * prefix, int size) +{ + char path[PATH_MAX] = {0}; + char buf[PATH_MAX] = {0}; + + /* get file for config (fd is always 3) */ + snprintf(path, sizeof(path), "/proc/self/fd/%d", 3); + + /* return NULL on error */ + if (readlink(path, buf, sizeof(buf)) == -1) + return NULL; + + /* get the basename */ + snprintf(buf, sizeof(buf), "%s", basename(buf)); + + /* copy string all the way from second char up to start of _config */ + snprintf(prefix, size, "%.*s", + (int)(strnlen(buf, sizeof(buf)) - sizeof("_config")), + &buf[1]); + + return prefix; +} + +/* + * Test that the app doesn't run with invalid whitelist option. + * Final tests ensures it does run with valid options as sanity check (one + * test for with Domain+BDF, second for just with BDF) + */ +static int +test_whitelist_flag(void) +{ + unsigned i; +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point */ + const char * prefix = ""; +#else + char prefix[PATH_MAX], tmp[PATH_MAX]; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); +#endif + + const char *wlinval[][11] = { + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "error", "", ""}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "0:0:0", "", ""}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "0:error:0.1", "", ""}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "0:0:0.1error", "", ""}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "error0:0:0.1", "", ""}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "0:0:0.1.2", "", ""}, + }; + /* Test with valid whitelist option */ + const char *wlval1[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "00FF:09:0B.3"}; + const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "09:0B.3", pci_whitelist, "0a:0b.1"}; + const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", + pci_whitelist, "09:0B.3,type=test", + pci_whitelist, "08:00.1,type=normal", + }; + + for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) { + if (launch_proc(wlinval[i]) == 0) { + printf("Error - process did run ok with invalid " + "whitelist parameter\n"); + return -1; + } + } + if (launch_proc(wlval1) != 0 ) { + printf("Error - process did not run ok with valid whitelist\n"); + return -1; + } + if (launch_proc(wlval2) != 0 ) { + printf("Error - process did not run ok with valid whitelist value set\n"); + return -1; + } + if (launch_proc(wlval3) != 0 ) { + printf("Error - process did not run ok with valid whitelist + args\n"); + return -1; + } + + return 0; +} + +/* + * Test that the app doesn't run with invalid blacklist option. + * Final test ensures it does run with valid options as sanity check + */ +static int +test_invalid_b_flag(void) +{ +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point */ + const char * prefix = ""; +#else + char prefix[PATH_MAX], tmp[PATH_MAX]; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); +#endif + + const char *blinval[][9] = { + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error"}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0"}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:error:0.1"}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1error"}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error0:0:0.1"}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1.2"}, + }; + /* Test with valid blacklist option */ + const char *blval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "FF:09:0B.3"}; + + int i; + + for (i = 0; i != sizeof (blinval) / sizeof (blinval[0]); i++) { + if (launch_proc(blinval[i]) == 0) { + printf("Error - process did run ok with invalid " + "blacklist parameter\n"); + return -1; + } + } + if (launch_proc(blval) != 0) { + printf("Error - process did not run ok with valid blacklist value\n"); + return -1; + } + return 0; +} + +/* + * Test that the app doesn't run with invalid vdev option. + * Final test ensures it does run with valid options as sanity check + */ +#ifdef RTE_LIBRTE_PMD_RING +static int +test_invalid_vdev_flag(void) +{ +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point, and we also need to + * run another primary process here */ + const char * prefix = no_shconf; +#else + const char * prefix = "--file-prefix=vdev"; +#endif + + /* Test with invalid vdev option */ + const char *vdevinval[] = {prgname, prefix, "-n", "1", + "-c", "1", vdev, "eth_dummy"}; + + /* Test with valid vdev option */ + const char *vdevval1[] = {prgname, prefix, "-n", "1", + "-c", "1", vdev, "net_ring0"}; + + const char *vdevval2[] = {prgname, prefix, "-n", "1", + "-c", "1", vdev, "net_ring0,args=test"}; + + const char *vdevval3[] = {prgname, prefix, "-n", "1", + "-c", "1", vdev, "net_ring0,nodeaction=r1:0:CREATE"}; + + if (launch_proc(vdevinval) == 0) { + printf("Error - process did run ok with invalid " + "vdev parameter\n"); + return -1; + } + + if (launch_proc(vdevval1) != 0) { + printf("Error - process did not run ok with valid vdev value\n"); + return -1; + } + + if (launch_proc(vdevval2) != 0) { + printf("Error - process did not run ok with valid vdev value," + "with dummy args\n"); + return -1; + } + + if (launch_proc(vdevval3) != 0) { + printf("Error - process did not run ok with valid vdev value," + "with valid args\n"); + return -1; + } + return 0; +} +#endif + +/* + * Test that the app doesn't run with invalid -r option. + */ +static int +test_invalid_r_flag(void) +{ +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point */ + const char * prefix = ""; +#else + char prefix[PATH_MAX], tmp[PATH_MAX]; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); +#endif + + const char *rinval[][9] = { + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "error"}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "0"}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "-1"}, + {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "17"}, + }; + /* Test with valid blacklist option */ + const char *rval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "16"}; + + int i; + + for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); i++) { + if (launch_proc(rinval[i]) == 0) { + printf("Error - process did run ok with invalid " + "-r (rank) parameter\n"); + return -1; + } + } + if (launch_proc(rval) != 0) { + printf("Error - process did not run ok with valid -r (rank) value\n"); + return -1; + } + return 0; +} + +/* + * Test that the app doesn't run without the coremask/corelist flags. In all cases + * should give an error and fail to run + */ +static int +test_missing_c_flag(void) +{ +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point */ + const char * prefix = ""; +#else + char prefix[PATH_MAX], tmp[PATH_MAX]; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); +#endif + + /* -c flag but no coremask value */ + const char *argv1[] = { prgname, prefix, mp_flag, "-n", "3", "-c"}; + /* No -c, -l or --lcores flag at all */ + const char *argv2[] = { prgname, prefix, mp_flag, "-n", "3"}; + /* bad coremask value */ + const char *argv3[] = { prgname, prefix, mp_flag, + "-n", "3", "-c", "error" }; + /* sanity check of tests - valid coremask value */ + const char *argv4[] = { prgname, prefix, mp_flag, + "-n", "3", "-c", "1" }; + /* -l flag but no corelist value */ + const char *argv5[] = { prgname, prefix, mp_flag, + "-n", "3", "-l"}; + const char *argv6[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", " " }; + /* bad corelist values */ + const char *argv7[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "error" }; + const char *argv8[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "1-" }; + const char *argv9[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "1," }; + const char *argv10[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "1#2" }; + /* sanity check test - valid corelist value */ + const char *argv11[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "1-2,3" }; + + /* --lcores flag but no lcores value */ + const char *argv12[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores" }; + const char *argv13[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", " " }; + /* bad lcores value */ + const char *argv14[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "1-3-5" }; + const char *argv15[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "0-1,,2" }; + const char *argv16[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "0-,1" }; + const char *argv17[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(0-,2-4)" }; + const char *argv18[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(-1,2)" }; + const char *argv19[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(2-4)@(2-4-6)" }; + const char *argv20[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(a,2)" }; + const char *argv21[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "1-3@(1,3)" }; + const char *argv22[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "3@((1,3)" }; + const char *argv23[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(4-7)=(1,3)" }; + const char *argv24[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "[4-7]@(1,3)" }; + /* sanity check of tests - valid lcores value */ + const char *argv25[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", + "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"}; + + if (launch_proc(argv2) != 0) { + printf("Error - " + "process did not run ok when missing -c flag\n"); + return -1; + } + + if (launch_proc(argv1) == 0 + || launch_proc(argv3) == 0) { + printf("Error - " + "process ran without error with invalid -c flag\n"); + return -1; + } + if (launch_proc(argv4) != 0) { + printf("Error - " + "process did not run ok with valid coremask value\n"); + return -1; + } + + /* start -l test */ + if (launch_proc(argv5) == 0 + || launch_proc(argv6) == 0 + || launch_proc(argv7) == 0 + || launch_proc(argv8) == 0 + || launch_proc(argv9) == 0 + || launch_proc(argv10) == 0) { + printf("Error - " + "process ran without error with invalid -l flag\n"); + return -1; + } + if (launch_proc(argv11) != 0) { + printf("Error - " + "process did not run ok with valid corelist value\n"); + return -1; + } + + /* start --lcores tests */ + if (launch_proc(argv12) == 0 || launch_proc(argv13) == 0 || + launch_proc(argv14) == 0 || launch_proc(argv15) == 0 || + launch_proc(argv16) == 0 || launch_proc(argv17) == 0 || + launch_proc(argv18) == 0 || launch_proc(argv19) == 0 || + launch_proc(argv20) == 0 || launch_proc(argv21) == 0 || + launch_proc(argv21) == 0 || launch_proc(argv22) == 0 || + launch_proc(argv23) == 0 || launch_proc(argv24) == 0) { + printf("Error - " + "process ran without error with invalid --lcore flag\n"); + return -1; + } + + if (launch_proc(argv25) != 0) { + printf("Error - " + "process did not run ok with valid corelist value\n"); + return -1; + } + + return 0; +} + +/* + * Test --master-lcore option with matching coremask + */ +static int +test_master_lcore_flag(void) +{ +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point */ + const char *prefix = ""; +#else + char prefix[PATH_MAX], tmp[PATH_MAX]; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); +#endif + + /* --master-lcore flag but no value */ + const char *argv1[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore"}; + /* --master-lcore flag with invalid value */ + const char *argv2[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "-1"}; + const char *argv3[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "X"}; + /* master lcore not in coremask */ + const char *argv4[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "2"}; + /* valid value */ + const char *argv5[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "1"}; + /* valid value set before coremask */ + const char *argv6[] = { prgname, prefix, mp_flag, "-n", "1", "--master-lcore", "1", "-c", "3"}; + + if (launch_proc(argv1) == 0 + || launch_proc(argv2) == 0 + || launch_proc(argv3) == 0 + || launch_proc(argv4) == 0) { + printf("Error - process ran without error with wrong --master-lcore\n"); + return -1; + } + if (launch_proc(argv5) != 0 + || launch_proc(argv6) != 0) { + printf("Error - process did not run ok with valid --master-lcore\n"); + return -1; + } + return 0; +} + +/* + * Test that the app doesn't run with invalid -n flag option. + * Final test ensures it does run with valid options as sanity check + * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf + * flags. + */ +static int +test_invalid_n_flag(void) +{ +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point */ + const char * prefix = ""; +#else + char prefix[PATH_MAX], tmp[PATH_MAX]; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); +#endif + + /* -n flag but no value */ + const char *argv1[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n"}; + /* bad numeric value */ + const char *argv2[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "e" }; + /* zero is invalid */ + const char *argv3[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "0" }; + /* sanity test - check with good value */ + const char *argv4[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "2" }; + /* sanity test - check with no -n flag */ + const char *argv5[] = { prgname, prefix, no_huge, no_shconf, "-c", "1"}; + + if (launch_proc(argv1) == 0 + || launch_proc(argv2) == 0 + || launch_proc(argv3) == 0) { + printf("Error - process ran without error when" + "invalid -n flag\n"); + return -1; + } + if (launch_proc(argv4) != 0) { + printf("Error - process did not run ok with valid num-channel value\n"); + return -1; + } + if (launch_proc(argv5) != 0) { + printf("Error - process did not run ok without -n flag\n"); + return -1; + } + + return 0; +} + +/* + * Test that the app runs with HPET, and without HPET + */ +static int +test_no_hpet_flag(void) +{ + char prefix[PATH_MAX], tmp[PATH_MAX]; + +#ifdef RTE_EXEC_ENV_BSDAPP + return 0; +#endif + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); + + /* With --no-hpet */ + const char *argv1[] = {prgname, prefix, mp_flag, no_hpet, "-c", "1", "-n", "2"}; + /* Without --no-hpet */ + const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-n", "2"}; + + if (launch_proc(argv1) != 0) { + printf("Error - process did not run ok with --no-hpet flag\n"); + return -1; + } + if (launch_proc(argv2) != 0) { + printf("Error - process did not run ok without --no-hpet flag\n"); + return -1; + } + return 0; +} + +/* + * Test that the app runs with --no-huge and doesn't run when --socket-mem are + * specified with --no-huge. + */ +static int +test_no_huge_flag(void) +{ +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point, and we also need to + * run another primary process here */ + const char * prefix = no_shconf; +#else + const char * prefix = "--file-prefix=nohuge"; +#endif + + /* With --no-huge */ + const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2"}; + /* With --no-huge and -m */ + const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", + "-m", DEFAULT_MEM_SIZE}; + + /* With --no-huge and --socket-mem */ + const char *argv3[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", + "--socket-mem=" DEFAULT_MEM_SIZE}; + /* With --no-huge, -m and --socket-mem */ + const char *argv4[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", + "-m", DEFAULT_MEM_SIZE, "--socket-mem=" DEFAULT_MEM_SIZE}; + if (launch_proc(argv1) != 0) { + printf("Error - process did not run ok with --no-huge flag\n"); + return -1; + } + if (launch_proc(argv2) != 0) { + printf("Error - process did not run ok with --no-huge and -m flags\n"); + return -1; + } +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target does not support NUMA, hence no --socket-mem tests */ + return 0; +#endif + + if (launch_proc(argv3) == 0) { + printf("Error - process run ok with --no-huge and --socket-mem " + "flags\n"); + return -1; + } + if (launch_proc(argv4) == 0) { + printf("Error - process run ok with --no-huge, -m and " + "--socket-mem flags\n"); + return -1; + } + return 0; +} + +#ifdef RTE_LIBRTE_XEN_DOM0 +static int +test_dom0_misc_flags(void) +{ + char prefix[PATH_MAX], tmp[PATH_MAX]; + + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); + + /* check that some general flags don't prevent things from working. + * All cases, apart from the first, app should run. + * No futher testing of output done. + */ + /* sanity check - failure with invalid option */ + const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"}; + + /* With --no-pci */ + const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"}; + /* With -v */ + const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"}; + /* With valid --syslog */ + const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1", + "--syslog", "syslog"}; + /* With empty --syslog (should fail) */ + const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"}; + /* With invalid --syslog */ + const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"}; + /* With no-sh-conf */ + const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "20", + "--no-shconf", "--file-prefix=noshconf" }; + + if (launch_proc(argv0) == 0) { + printf("Error - process ran ok with invalid flag\n"); + return -1; + } + if (launch_proc(argv1) != 0) { + printf("Error - process did not run ok with --no-pci flag\n"); + return -1; + } + if (launch_proc(argv2) != 0) { + printf("Error - process did not run ok with -v flag\n"); + return -1; + } + if (launch_proc(argv3) != 0) { + printf("Error - process did not run ok with --syslog flag\n"); + return -1; + } + if (launch_proc(argv4) == 0) { + printf("Error - process run ok with empty --syslog flag\n"); + return -1; + } + if (launch_proc(argv5) == 0) { + printf("Error - process run ok with invalid --syslog flag\n"); + return -1; + } + if (launch_proc(argv6) != 0) { + printf("Error - process did not run ok with --no-shconf flag\n"); + return -1; + } + + return 0; +} +#else +static int +test_misc_flags(void) +{ + char hugepath[PATH_MAX] = {0}; +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point */ + const char * prefix = ""; + const char * nosh_prefix = ""; +#else + char prefix[PATH_MAX], tmp[PATH_MAX]; + const char * nosh_prefix = "--file-prefix=noshconf"; + FILE * hugedir_handle = NULL; + char line[PATH_MAX] = {0}; + unsigned i, isempty = 1; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); + + /* + * get first valid hugepage path + */ + + /* get hugetlbfs mountpoints from /proc/mounts */ + hugedir_handle = fopen("/proc/mounts", "r"); + + if (hugedir_handle == NULL) { + printf("Error opening /proc/mounts!\n"); + return -1; + } + + /* read /proc/mounts */ + while (fgets(line, sizeof(line), hugedir_handle) != NULL) { + + /* find first valid hugepath */ + if (get_hugepage_path(line, sizeof(line), hugepath, sizeof(hugepath))) + break; + } + + fclose(hugedir_handle); + + /* check if path is not empty */ + for (i = 0; i < sizeof(hugepath); i++) + if (hugepath[i] != '\0') + isempty = 0; + + if (isempty) { + printf("No mounted hugepage dir found!\n"); + return -1; + } +#endif + + + /* check that some general flags don't prevent things from working. + * All cases, apart from the first, app should run. + * No futher testing of output done. + */ + /* sanity check - failure with invalid option */ + const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"}; + + /* With --no-pci */ + const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"}; + /* With -v */ + const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"}; + /* With valid --syslog */ + const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1", + "--syslog", "syslog"}; + /* With empty --syslog (should fail) */ + const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"}; + /* With invalid --syslog */ + const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"}; + /* With no-sh-conf */ + const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, + no_shconf, nosh_prefix }; + +#ifdef RTE_EXEC_ENV_BSDAPP + return 0; +#endif + /* With --huge-dir */ + const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, + "--file-prefix=hugedir", "--huge-dir", hugepath}; + /* With empty --huge-dir (should fail) */ + const char *argv8[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, + "--file-prefix=hugedir", "--huge-dir"}; + /* With invalid --huge-dir */ + const char *argv9[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, + "--file-prefix=hugedir", "--huge-dir", "invalid"}; + /* Secondary process with invalid --huge-dir (should run as flag has no + * effect on secondary processes) */ + const char *argv10[] = {prgname, prefix, mp_flag, "-c", "1", "--huge-dir", "invalid"}; + + /* try running with base-virtaddr param */ + const char *argv11[] = {prgname, "--file-prefix=virtaddr", + "-c", "1", "-n", "2", "--base-virtaddr=0x12345678"}; + + /* try running with --vfio-intr INTx flag */ + const char *argv12[] = {prgname, "--file-prefix=intr", + "-c", "1", "-n", "2", "--vfio-intr=legacy"}; + + /* try running with --vfio-intr MSI flag */ + const char *argv13[] = {prgname, "--file-prefix=intr", + "-c", "1", "-n", "2", "--vfio-intr=msi"}; + + /* try running with --vfio-intr MSI-X flag */ + const char *argv14[] = {prgname, "--file-prefix=intr", + "-c", "1", "-n", "2", "--vfio-intr=msix"}; + + /* try running with --vfio-intr invalid flag */ + const char *argv15[] = {prgname, "--file-prefix=intr", + "-c", "1", "-n", "2", "--vfio-intr=invalid"}; + + + if (launch_proc(argv0) == 0) { + printf("Error - process ran ok with invalid flag\n"); + return -1; + } + if (launch_proc(argv1) != 0) { + printf("Error - process did not run ok with --no-pci flag\n"); + return -1; + } + if (launch_proc(argv2) != 0) { + printf("Error - process did not run ok with -v flag\n"); + return -1; + } + if (launch_proc(argv3) != 0) { + printf("Error - process did not run ok with --syslog flag\n"); + return -1; + } + if (launch_proc(argv4) == 0) { + printf("Error - process run ok with empty --syslog flag\n"); + return -1; + } + if (launch_proc(argv5) == 0) { + printf("Error - process run ok with invalid --syslog flag\n"); + return -1; + } + if (launch_proc(argv6) != 0) { + printf("Error - process did not run ok with --no-shconf flag\n"); + return -1; + } +#ifdef RTE_EXEC_ENV_BSDAPP + return 0; +#endif + if (launch_proc(argv7) != 0) { + printf("Error - process did not run ok with --huge-dir flag\n"); + return -1; + } + if (launch_proc(argv8) == 0) { + printf("Error - process run ok with empty --huge-dir flag\n"); + return -1; + } + if (launch_proc(argv9) == 0) { + printf("Error - process run ok with invalid --huge-dir flag\n"); + return -1; + } + if (launch_proc(argv10) != 0) { + printf("Error - secondary process did not run ok with invalid --huge-dir flag\n"); + return -1; + } + if (launch_proc(argv11) != 0) { + printf("Error - process did not run ok with --base-virtaddr parameter\n"); + return -1; + } + if (launch_proc(argv12) != 0) { + printf("Error - process did not run ok with " + "--vfio-intr INTx parameter\n"); + return -1; + } + if (launch_proc(argv13) != 0) { + printf("Error - process did not run ok with " + "--vfio-intr MSI parameter\n"); + return -1; + } + if (launch_proc(argv14) != 0) { + printf("Error - process did not run ok with " + "--vfio-intr MSI-X parameter\n"); + return -1; + } + if (launch_proc(argv15) == 0) { + printf("Error - process run ok with " + "--vfio-intr invalid parameter\n"); + return -1; + } + return 0; +} +#endif + +static int +test_file_prefix(void) +{ + /* + * 1. check if current process hugefiles are locked + * 2. try to run secondary process without a corresponding primary process + * (while failing to run, it will also remove any unused hugepage files) + * 3. check if current process hugefiles are still in place and are locked + * 4. run a primary process with memtest1 prefix + * 5. check if memtest1 hugefiles are created + * 6. run a primary process with memtest2 prefix + * 7. check that only memtest2 hugefiles are present in the hugedir + */ + +#ifdef RTE_EXEC_ENV_BSDAPP + return 0; +#endif + + /* this should fail unless the test itself is run with "memtest" prefix */ + const char *argv0[] = {prgname, mp_flag, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, + "--file-prefix=" memtest }; + + /* primary process with memtest1 */ + const char *argv1[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, + "--file-prefix=" memtest1 }; + + /* primary process with memtest2 */ + const char *argv2[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, + "--file-prefix=" memtest2 }; + + char prefix[32]; + if (get_current_prefix(prefix, sizeof(prefix)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } +#ifdef RTE_LIBRTE_XEN_DOM0 + return 0; +#endif + + /* check if files for current prefix are present */ + if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) { + printf("Error - hugepage files for %s were not created!\n", prefix); + return -1; + } + + /* checks if files for current prefix are locked */ + if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) { + printf("Error - hugepages for current process aren't locked!\n"); + return -1; + } + + /* check if files for secondary process are present */ + if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) { + /* check if they are not locked */ + if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) { + printf("Error - hugepages for current process are locked!\n"); + return -1; + } + /* they aren't locked, delete them */ + else { + if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) { + printf("Error - deleting hugepages failed!\n"); + return -1; + } + } + } + + if (launch_proc(argv0) == 0) { + printf("Error - secondary process ran ok without primary process\n"); + return -1; + } + + /* check if files for current prefix are present */ + if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) { + printf("Error - hugepage files for %s were not created!\n", prefix); + return -1; + } + + /* checks if files for current prefix are locked */ + if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) { + printf("Error - hugepages for current process aren't locked!\n"); + return -1; + } + + if (launch_proc(argv1) != 0) { + printf("Error - failed to run with --file-prefix=%s\n", memtest); + return -1; + } + + /* check if memtest1_map0 is present */ + if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) { + printf("Error - hugepage files for %s were not created!\n", memtest1); + return -1; + } + + if (launch_proc(argv2) != 0) { + printf("Error - failed to run with --file-prefix=%s\n", memtest2); + return -1; + } + + /* check if hugefiles for memtest2 are present */ + if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) { + printf("Error - hugepage files for %s were not created!\n", memtest2); + return -1; + } + + /* check if hugefiles for memtest1 are present */ + if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { + printf("Error - hugepage files for %s were not deleted!\n", memtest1); + return -1; + } + + return 0; +} + +/* + * Tests for correct handling of -m and --socket-mem flags + */ +static int +test_memory_flags(void) +{ +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD target doesn't support prefixes at this point */ + const char * prefix = ""; +#else + char prefix[PATH_MAX], tmp[PATH_MAX]; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); +#endif + + /* valid -m flag and mp flag */ + const char *argv0[] = {prgname, prefix, mp_flag, "-c", "10", + "-n", "2", "-m", DEFAULT_MEM_SIZE}; + + /* valid -m flag */ + const char *argv1[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE}; + + /* invalid (zero) --socket-mem flag */ + const char *argv2[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, "--socket-mem=0,0,0,0"}; + + /* invalid (incomplete) --socket-mem flag */ + const char *argv3[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, "--socket-mem=2,2,"}; + + /* invalid (mixed with invalid data) --socket-mem flag */ + const char *argv4[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, "--socket-mem=2,2,Fred"}; + + /* invalid (with numeric value as last character) --socket-mem flag */ + const char *argv5[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, "--socket-mem=2,2,Fred0"}; + + /* invalid (with empty socket) --socket-mem flag */ + const char *argv6[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, "--socket-mem=2,,2"}; + + /* invalid (null) --socket-mem flag */ + const char *argv7[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, "--socket-mem="}; + + /* valid --socket-mem specified together with -m flag */ + const char *argv8[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE, "--socket-mem=2,2"}; + + /* construct an invalid socket mask with 2 megs on each socket plus + * extra 2 megs on socket that doesn't exist on current system */ + char invalid_socket_mem[SOCKET_MEM_STRLEN]; + char buf[SOCKET_MEM_STRLEN]; /* to avoid copying string onto itself */ + +#ifdef RTE_EXEC_ENV_BSDAPP + int i, num_sockets = 1; +#else + int i, num_sockets = get_number_of_sockets(); +#endif + + if (num_sockets <= 0 || num_sockets > RTE_MAX_NUMA_NODES) { + printf("Error - cannot get number of sockets!\n"); + return -1; + } + + snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "--socket-mem="); + + /* add one extra socket */ + for (i = 0; i < num_sockets + 1; i++) { + snprintf(buf, sizeof(buf), "%s%s", invalid_socket_mem, DEFAULT_MEM_SIZE); + snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf); + + if (num_sockets + 1 - i > 1) { + snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem); + snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf); + } + } + + /* construct a valid socket mask with 2 megs on each existing socket */ + char valid_socket_mem[SOCKET_MEM_STRLEN]; + + snprintf(valid_socket_mem, sizeof(valid_socket_mem), "--socket-mem="); + + /* add one extra socket */ + for (i = 0; i < num_sockets; i++) { + snprintf(buf, sizeof(buf), "%s%s", valid_socket_mem, DEFAULT_MEM_SIZE); + snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf); + + if (num_sockets - i > 1) { + snprintf(buf, sizeof(buf), "%s,", valid_socket_mem); + snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf); + } + } + + /* invalid --socket-mem flag (with extra socket) */ + const char *argv9[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, invalid_socket_mem}; + + /* valid --socket-mem flag */ + const char *argv10[] = {prgname, "-c", "10", "-n", "2", + "--file-prefix=" memtest, valid_socket_mem}; + + if (launch_proc(argv0) != 0) { + printf("Error - secondary process failed with valid -m flag !\n"); + return -1; + } + +#ifdef RTE_EXEC_ENV_BSDAPP + /* no other tests are applicable to BSD */ + return 0; +#endif + + if (launch_proc(argv1) != 0) { + printf("Error - process failed with valid -m flag!\n"); + return -1; + } +#ifdef RTE_LIBRTE_XEN_DOM0 + return 0; +#endif + if (launch_proc(argv2) == 0) { + printf("Error - process run ok with invalid (zero) --socket-mem!\n"); + return -1; + } + + if (launch_proc(argv3) == 0) { + printf("Error - process run ok with invalid " + "(incomplete) --socket-mem!\n"); + return -1; + } + + if (launch_proc(argv4) == 0) { + printf("Error - process run ok with invalid " + "(mixed with invalid input) --socket-mem!\n"); + return -1; + } + + if (launch_proc(argv5) == 0) { + printf("Error - process run ok with invalid " + "(mixed with invalid input with a numeric value as " + "last character) --socket-mem!\n"); + return -1; + } + + if (launch_proc(argv6) == 0) { + printf("Error - process run ok with invalid " + "(with empty socket) --socket-mem!\n"); + return -1; + } + + if (launch_proc(argv7) == 0) { + printf("Error - process run ok with invalid (null) --socket-mem!\n"); + return -1; + } + + if (launch_proc(argv8) == 0) { + printf("Error - process run ok with --socket-mem and -m specified!\n"); + return -1; + } + + if (launch_proc(argv9) == 0) { + printf("Error - process run ok with extra socket in --socket-mem!\n"); + return -1; + } + + if (launch_proc(argv10) != 0) { + printf("Error - process failed with valid --socket-mem!\n"); + return -1; + } + + return 0; +} + +static int +test_eal_flags(void) +{ + int ret = 0; + + ret = test_missing_c_flag(); + if (ret < 0) { + printf("Error in test_missing_c_flag()\n"); + return ret; + } + + ret = test_master_lcore_flag(); + if (ret < 0) { + printf("Error in test_master_lcore_flag()\n"); + return ret; + } + + ret = test_invalid_n_flag(); + if (ret < 0) { + printf("Error in test_invalid_n_flag()\n"); + return ret; + } + + ret = test_no_hpet_flag(); + if (ret < 0) { + printf("Error in test_no_hpet_flag()\n"); + return ret; + } + + ret = test_no_huge_flag(); + if (ret < 0) { + printf("Error in test_no_huge_flag()\n"); + return ret; + } + + ret = test_whitelist_flag(); + if (ret < 0) { + printf("Error in test_invalid_whitelist_flag()\n"); + return ret; + } + + ret = test_invalid_b_flag(); + if (ret < 0) { + printf("Error in test_invalid_b_flag()\n"); + return ret; + } + +#ifdef RTE_LIBRTE_PMD_RING + ret = test_invalid_vdev_flag(); + if (ret < 0) { + printf("Error in test_invalid_vdev_flag()\n"); + return ret; + } +#endif + ret = test_invalid_r_flag(); + if (ret < 0) { + printf("Error in test_invalid_r_flag()\n"); + return ret; + } + + ret = test_memory_flags(); + if (ret < 0) { + printf("Error in test_memory_flags()\n"); + return ret; + } + + ret = test_file_prefix(); + if (ret < 0) { + printf("Error in test_file_prefix()\n"); + return ret; + } + +#ifdef RTE_LIBRTE_XEN_DOM0 + ret = test_dom0_misc_flags(); +#else + ret = test_misc_flags(); +#endif + if (ret < 0) { + printf("Error in test_misc_flags()"); + return ret; + } + + return ret; +} + +REGISTER_TEST_COMMAND(eal_flags_autotest, test_eal_flags); diff --git a/test/test/test_eal_fs.c b/test/test/test_eal_fs.c new file mode 100644 index 0000000000..78978120cd --- /dev/null +++ b/test/test/test_eal_fs.c @@ -0,0 +1,206 @@ +/*- + * 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 "test.h" +#include +#include +#include +#include + +/* eal_filesystem.h is not a public header file, so use relative path */ +#include "../../lib/librte_eal/common/eal_filesystem.h" + +static int +test_parse_sysfs_value(void) +{ + char filename[PATH_MAX] = ""; + char proc_path[PATH_MAX]; + char file_template[] = "/tmp/eal_test_XXXXXX"; + int tmp_file_handle = -1; + FILE *fd = NULL; + unsigned valid_number; + unsigned long retval = 0; + +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD doesn't have /proc/pid/fd */ + return 0; +#endif + + printf("Testing function eal_parse_sysfs_value()\n"); + + /* get a temporary filename to use for all tests - create temp file handle and then + * use /proc to get the actual file that we can open */ + tmp_file_handle = mkstemp(file_template); + if (tmp_file_handle == -1) { + perror("mkstemp() failure"); + goto error; + } + snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", tmp_file_handle); + if (readlink(proc_path, filename, sizeof(filename)) < 0) { + perror("readlink() failure"); + goto error; + } + printf("Temporary file is: %s\n", filename); + + /* test we get an error value if we use file before it's created */ + printf("Test reading a missing file ...\n"); + if (eal_parse_sysfs_value("/dev/not-quite-null", &retval) == 0) { + printf("Error with eal_parse_sysfs_value() - returned success on reading empty file\n"); + goto error; + } + printf("Confirmed return error when reading empty file\n"); + + /* test reading a valid number value with "\n" on the end */ + printf("Test reading valid values ...\n"); + valid_number = 15; + fd = fopen(filename,"w"); + if (fd == NULL) { + printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); + goto error; + } + fprintf(fd,"%u\n", valid_number); + fclose(fd); + fd = NULL; + if (eal_parse_sysfs_value(filename, &retval) < 0) { + printf("eal_parse_sysfs_value() returned error - test failed\n"); + goto error; + } + if (retval != valid_number) { + printf("Invalid value read by eal_parse_sysfs_value() - test failed\n"); + goto error; + } + printf("Read '%u\\n' ok\n", valid_number); + + /* test reading a valid hex number value with "\n" on the end */ + valid_number = 25; + fd = fopen(filename,"w"); + if (fd == NULL) { + printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); + goto error; + } + fprintf(fd,"0x%x\n", valid_number); + fclose(fd); + fd = NULL; + if (eal_parse_sysfs_value(filename, &retval) < 0) { + printf("eal_parse_sysfs_value() returned error - test failed\n"); + goto error; + } + if (retval != valid_number) { + printf("Invalid value read by eal_parse_sysfs_value() - test failed\n"); + goto error; + } + printf("Read '0x%x\\n' ok\n", valid_number); + + printf("Test reading invalid values ...\n"); + + /* test reading an empty file - expect failure!*/ + fd = fopen(filename,"w"); + if (fd == NULL) { + printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); + goto error; + } + fclose(fd); + fd = NULL; + if (eal_parse_sysfs_value(filename, &retval) == 0) { + printf("eal_parse_sysfs_value() read invalid value - test failed\n"); + goto error; + } + + /* test reading a valid number value *without* "\n" on the end - expect failure!*/ + valid_number = 3; + fd = fopen(filename,"w"); + if (fd == NULL) { + printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); + goto error; + } + fprintf(fd,"%u", valid_number); + fclose(fd); + fd = NULL; + if (eal_parse_sysfs_value(filename, &retval) == 0) { + printf("eal_parse_sysfs_value() read invalid value - test failed\n"); + goto error; + } + + /* test reading a valid number value followed by string - expect failure!*/ + valid_number = 3; + fd = fopen(filename,"w"); + if (fd == NULL) { + printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); + goto error; + } + fprintf(fd,"%uJ\n", valid_number); + fclose(fd); + fd = NULL; + if (eal_parse_sysfs_value(filename, &retval) == 0) { + printf("eal_parse_sysfs_value() read invalid value - test failed\n"); + goto error; + } + + /* test reading a non-numeric value - expect failure!*/ + fd = fopen(filename,"w"); + if (fd == NULL) { + printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno)); + goto error; + } + fprintf(fd,"error\n"); + fclose(fd); + fd = NULL; + if (eal_parse_sysfs_value(filename, &retval) == 0) { + printf("eal_parse_sysfs_value() read invalid value - test failed\n"); + goto error; + } + + close(tmp_file_handle); + unlink(filename); + printf("eal_parse_sysfs_value() - OK\n"); + return 0; + +error: + if (fd) + fclose(fd); + if (tmp_file_handle > 0) + close(tmp_file_handle); + if (filename[0] != '\0') + unlink(filename); + return -1; +} + +static int +test_eal_fs(void) +{ + if (test_parse_sysfs_value() < 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(eal_fs_autotest, test_eal_fs); diff --git a/test/test/test_efd.c b/test/test/test_efd.c new file mode 100644 index 0000000000..de49e1d7e1 --- /dev/null +++ b/test/test/test_efd.c @@ -0,0 +1,500 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016-2017 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 +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define EFD_TEST_KEY_LEN 8 +#define TABLE_SIZE (1 << 21) +#define ITERATIONS 3 + +#if RTE_EFD_VALUE_NUM_BITS == 32 +#define VALUE_BITMASK 0xffffffff +#else +#define VALUE_BITMASK ((1 << RTE_EFD_VALUE_NUM_BITS) - 1) +#endif +static unsigned int test_socket_id; + +/* 5-tuple key type */ +struct flow_key { + uint32_t ip_src; + uint32_t ip_dst; + uint16_t port_src; + uint16_t port_dst; + uint8_t proto; +} __attribute__((packed)); +/* + * Print out result of unit test efd operation. + */ +#if defined(UNIT_TEST_EFD_VERBOSE) + +static void print_key_info(const char *msg, const struct flow_key *key, + efd_value_t val) +{ + const uint8_t *p = (const uint8_t *) key; + unsigned int i; + + printf("%s key:0x", msg); + for (i = 0; i < sizeof(struct flow_key); i++) + printf("%02X", p[i]); + + printf(" @ val %d\n", val); +} +#else + +static void print_key_info(__attribute__((unused)) const char *msg, + __attribute__((unused)) const struct flow_key *key, + __attribute__((unused)) efd_value_t val) +{ +} +#endif + +/* Keys used by unit test functions */ +static struct flow_key keys[5] = { + { + .ip_src = IPv4(0x03, 0x02, 0x01, 0x00), + .ip_dst = IPv4(0x07, 0x06, 0x05, 0x04), + .port_src = 0x0908, + .port_dst = 0x0b0a, + .proto = 0x0c, + }, + { + .ip_src = IPv4(0x13, 0x12, 0x11, 0x10), + .ip_dst = IPv4(0x17, 0x16, 0x15, 0x14), + .port_src = 0x1918, + .port_dst = 0x1b1a, + .proto = 0x1c, + }, + { + .ip_src = IPv4(0x23, 0x22, 0x21, 0x20), + .ip_dst = IPv4(0x27, 0x26, 0x25, 0x24), + .port_src = 0x2928, + .port_dst = 0x2b2a, + .proto = 0x2c, + }, + { + .ip_src = IPv4(0x33, 0x32, 0x31, 0x30), + .ip_dst = IPv4(0x37, 0x36, 0x35, 0x34), + .port_src = 0x3938, + .port_dst = 0x3b3a, + .proto = 0x3c, + }, + { + .ip_src = IPv4(0x43, 0x42, 0x41, 0x40), + .ip_dst = IPv4(0x47, 0x46, 0x45, 0x44), + .port_src = 0x4948, + .port_dst = 0x4b4a, + .proto = 0x4c, + } +}; +/* Array to store the data */ +efd_value_t data[5]; + +static inline uint8_t efd_get_all_sockets_bitmask(void) +{ + uint8_t all_cpu_sockets_bitmask = 0; + unsigned int i; + unsigned int next_lcore = rte_get_master_lcore(); + const int val_true = 1, val_false = 0; + for (i = 0; i < rte_lcore_count(); i++) { + all_cpu_sockets_bitmask |= 1 << rte_lcore_to_socket_id(next_lcore); + next_lcore = rte_get_next_lcore(next_lcore, val_false, val_true); + } + + return all_cpu_sockets_bitmask; +} + +/* + * Basic sequence of operations for a single key: + * - add + * - lookup (hit) + * - delete + * Note: lookup (miss) is not applicable since this is a filter + */ +static int test_add_delete(void) +{ + struct rte_efd_table *handle; + /* test with standard add/lookup/delete functions */ + efd_value_t prev_value; + printf("Entering %s\n", __func__); + + handle = rte_efd_create("test_add_delete", + TABLE_SIZE, sizeof(struct flow_key), + efd_get_all_sockets_bitmask(), test_socket_id); + TEST_ASSERT_NOT_NULL(handle, "Error creating the EFD table\n"); + + data[0] = mrand48() & VALUE_BITMASK; + TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[0], + data[0]), + "Error inserting the key"); + print_key_info("Add", &keys[0], data[0]); + + TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[0]), + data[0], + "failed to find key"); + + TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id, &keys[0], + &prev_value), + "failed to delete key"); + TEST_ASSERT_EQUAL(prev_value, data[0], + "failed to delete the expected value, got %d, " + "expected %d", prev_value, data[0]); + print_key_info("Del", &keys[0], data[0]); + + rte_efd_free(handle); + + return 0; +} + +/* + * Sequence of operations for a single key: + * - add + * - lookup: hit + * - add: update + * - lookup: hit (updated data) + * - delete: hit + */ +static int test_add_update_delete(void) +{ + struct rte_efd_table *handle; + printf("Entering %s\n", __func__); + /* test with standard add/lookup/delete functions */ + efd_value_t prev_value; + data[1] = mrand48() & VALUE_BITMASK; + + handle = rte_efd_create("test_add_update_delete", TABLE_SIZE, + sizeof(struct flow_key), + efd_get_all_sockets_bitmask(), test_socket_id); + TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n"); + + TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[1], + data[1]), "Error inserting the key"); + print_key_info("Add", &keys[1], data[1]); + + TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[1]), + data[1], "failed to find key"); + print_key_info("Lkp", &keys[1], data[1]); + + data[1] = data[1] + 1; + TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, &keys[1], + data[1]), "Error re-inserting the key"); + print_key_info("Add", &keys[1], data[1]); + + TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, &keys[1]), + data[1], "failed to find key"); + print_key_info("Lkp", &keys[1], data[1]); + + TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id, &keys[1], + &prev_value), "failed to delete key"); + TEST_ASSERT_EQUAL(prev_value, data[1], + "failed to delete the expected value, got %d, " + "expected %d", prev_value, data[1]); + print_key_info("Del", &keys[1], data[1]); + + + rte_efd_free(handle); + return 0; +} + +/* + * Sequence of operations for find existing EFD table + * + * - create table + * - find existing table: hit + * - find non-existing table: miss + * + */ +static int test_efd_find_existing(void) +{ + struct rte_efd_table *handle = NULL, *result = NULL; + + printf("Entering %s\n", __func__); + + /* Create EFD table. */ + handle = rte_efd_create("efd_find_existing", TABLE_SIZE, + sizeof(struct flow_key), + efd_get_all_sockets_bitmask(), test_socket_id); + TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n"); + + /* Try to find existing EFD table */ + result = rte_efd_find_existing("efd_find_existing"); + TEST_ASSERT_EQUAL(result, handle, "could not find existing efd table"); + + /* Try to find non-existing EFD table */ + result = rte_efd_find_existing("efd_find_non_existing"); + TEST_ASSERT_NULL(result, "found table that shouldn't exist"); + + /* Cleanup. */ + rte_efd_free(handle); + + return 0; +} + +/* + * Sequence of operations for 5 keys + * - add keys + * - lookup keys: hit (bulk) + * - add keys (update) + * - lookup keys: hit (updated data) + * - delete keys : hit + */ +static int test_five_keys(void) +{ + struct rte_efd_table *handle; + const void *key_array[5] = {0}; + efd_value_t result[5] = {0}; + efd_value_t prev_value; + unsigned int i; + printf("Entering %s\n", __func__); + + handle = rte_efd_create("test_five_keys", TABLE_SIZE, + sizeof(struct flow_key), + efd_get_all_sockets_bitmask(), test_socket_id); + TEST_ASSERT_NOT_NULL(handle, "Error creating the efd table\n"); + + /* Setup data */ + for (i = 0; i < 5; i++) + data[i] = mrand48() & VALUE_BITMASK; + + /* Add */ + for (i = 0; i < 5; i++) { + TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, + &keys[i], data[i]), + "Error inserting the key"); + print_key_info("Add", &keys[i], data[i]); + } + + /* Lookup */ + for (i = 0; i < 5; i++) + key_array[i] = &keys[i]; + + rte_efd_lookup_bulk(handle, test_socket_id, 5, + (const void **) (void *) &key_array, result); + + for (i = 0; i < 5; i++) { + TEST_ASSERT_EQUAL(result[i], data[i], + "bulk: failed to find key. Expected %d, got %d", + data[i], result[i]); + print_key_info("Lkp", &keys[i], data[i]); + } + + /* Modify data (bulk) */ + for (i = 0; i < 5; i++) + data[i] = data[i] + 1; + + /* Add - update */ + for (i = 0; i < 5; i++) { + TEST_ASSERT_SUCCESS(rte_efd_update(handle, test_socket_id, + &keys[i], data[i]), + "Error inserting the key"); + print_key_info("Add", &keys[i], data[i]); + } + + /* Lookup */ + for (i = 0; i < 5; i++) { + TEST_ASSERT_EQUAL(rte_efd_lookup(handle, test_socket_id, + &keys[i]), data[i], + "failed to find key"); + print_key_info("Lkp", &keys[i], data[i]); + } + + /* Delete */ + for (i = 0; i < 5; i++) { + TEST_ASSERT_SUCCESS(rte_efd_delete(handle, test_socket_id, + &keys[i], &prev_value), + "failed to delete key"); + TEST_ASSERT_EQUAL(prev_value, data[i], + "failed to delete the expected value, got %d, " + "expected %d", prev_value, data[i]); + print_key_info("Del", &keys[i], data[i]); + } + + + rte_efd_free(handle); + + return 0; +} + +/* + * Test to see the average table utilization (entries added/max entries) + * before hitting a random entry that cannot be added + */ +static int test_average_table_utilization(void) +{ + struct rte_efd_table *handle = NULL; + uint32_t num_rules_in = TABLE_SIZE; + uint8_t simple_key[EFD_TEST_KEY_LEN]; + unsigned int i, j; + unsigned int added_keys, average_keys_added = 0; + + printf("Evaluating table utilization and correctness, please wait\n"); + fflush(stdout); + + for (j = 0; j < ITERATIONS; j++) { + handle = rte_efd_create("test_efd", num_rules_in, + EFD_TEST_KEY_LEN, efd_get_all_sockets_bitmask(), + test_socket_id); + if (handle == NULL) { + printf("efd table creation failed\n"); + return -1; + } + + unsigned int succeeded = 0; + unsigned int lost_keys = 0; + + /* Add random entries until key cannot be added */ + for (added_keys = 0; added_keys < num_rules_in; added_keys++) { + + for (i = 0; i < EFD_TEST_KEY_LEN; i++) + simple_key[i] = rte_rand() & 0xFF; + + efd_value_t val = simple_key[0]; + + if (rte_efd_update(handle, test_socket_id, simple_key, + val)) + break; /* continue;*/ + if (rte_efd_lookup(handle, test_socket_id, simple_key) + != val) + lost_keys++; + else + succeeded++; + } + + average_keys_added += succeeded; + + /* Reset the table */ + rte_efd_free(handle); + + /* Print progress on operations */ + printf("Added %10u Succeeded %10u Lost %10u\n", + added_keys, succeeded, lost_keys); + fflush(stdout); + } + + average_keys_added /= ITERATIONS; + + printf("\nAverage table utilization = %.2f%% (%u/%u)\n", + ((double) average_keys_added / num_rules_in * 100), + average_keys_added, num_rules_in); + + return 0; +} + +/* + * Do tests for EFD creation with bad parameters. + */ +static int test_efd_creation_with_bad_parameters(void) +{ + struct rte_efd_table *handle, *tmp; + printf("Entering %s, **Errors are expected **\n", __func__); + + handle = rte_efd_create("creation_with_bad_parameters_0", TABLE_SIZE, 0, + efd_get_all_sockets_bitmask(), test_socket_id); + if (handle != NULL) { + rte_efd_free(handle); + printf("Impossible creating EFD table successfully " + "if key_len in parameter is zero\n"); + return -1; + } + + handle = rte_efd_create("creation_with_bad_parameters_1", TABLE_SIZE, + sizeof(struct flow_key), 0, test_socket_id); + if (handle != NULL) { + rte_efd_free(handle); + printf("Impossible creating EFD table successfully " + "with invalid socket bitmask\n"); + return -1; + } + + handle = rte_efd_create("creation_with_bad_parameters_2", TABLE_SIZE, + sizeof(struct flow_key), efd_get_all_sockets_bitmask(), + 255); + if (handle != NULL) { + rte_efd_free(handle); + printf("Impossible creating EFD table successfully " + "with invalid socket\n"); + return -1; + } + + /* test with same name should fail */ + handle = rte_efd_create("same_name", TABLE_SIZE, + sizeof(struct flow_key), + efd_get_all_sockets_bitmask(), 0); + if (handle == NULL) { + printf("Cannot create first EFD table with 'same_name'\n"); + return -1; + } + tmp = rte_efd_create("same_name", TABLE_SIZE, sizeof(struct flow_key), + efd_get_all_sockets_bitmask(), 0); + if (tmp != NULL) { + printf("Creation of EFD table with same name should fail\n"); + rte_efd_free(handle); + rte_efd_free(tmp); + return -1; + } + rte_efd_free(handle); + + printf("# Test successful. No more errors expected\n"); + + return 0; +} + +static int +test_efd(void) +{ + + /* Unit tests */ + if (test_add_delete() < 0) + return -1; + if (test_efd_find_existing() < 0) + return -1; + if (test_add_update_delete() < 0) + return -1; + if (test_five_keys() < 0) + return -1; + if (test_efd_creation_with_bad_parameters() < 0) + return -1; + if (test_average_table_utilization() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(efd_autotest, test_efd); diff --git a/test/test/test_efd_perf.c b/test/test/test_efd_perf.c new file mode 100644 index 0000000000..2b8a8eac5b --- /dev/null +++ b/test/test/test_efd_perf.c @@ -0,0 +1,414 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016-2017 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define NUM_KEYSIZES 10 +#define NUM_SHUFFLES 10 +#define MAX_KEYSIZE 64 +#define MAX_ENTRIES (1 << 19) +#define KEYS_TO_ADD (MAX_ENTRIES * 3 / 4) /* 75% table utilization */ +#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ + +#if RTE_EFD_VALUE_NUM_BITS == 32 +#define VALUE_BITMASK 0xffffffff +#else +#define VALUE_BITMASK ((1 << RTE_EFD_VALUE_NUM_BITS) - 1) +#endif +static unsigned int test_socket_id; + +static inline uint8_t efd_get_all_sockets_bitmask(void) +{ + uint8_t all_cpu_sockets_bitmask = 0; + unsigned int i; + unsigned int next_lcore = rte_get_master_lcore(); + const int val_true = 1, val_false = 0; + for (i = 0; i < rte_lcore_count(); i++) { + all_cpu_sockets_bitmask |= 1 << rte_lcore_to_socket_id(next_lcore); + next_lcore = rte_get_next_lcore(next_lcore, val_false, val_true); + } + + return all_cpu_sockets_bitmask; +} + +enum operations { + ADD = 0, + LOOKUP, + LOOKUP_MULTI, + DELETE, + NUM_OPERATIONS +}; + +struct efd_perf_params { + struct rte_efd_table *efd_table; + uint32_t key_size; + unsigned int cycle; +}; + +static uint32_t hashtest_key_lens[] = { + /* standard key sizes */ + 4, 8, 16, 32, 48, 64, + /* IPv4 SRC + DST + protocol, unpadded */ + 9, + /* IPv4 5-tuple, unpadded */ + 13, + /* IPv6 5-tuple, unpadded */ + 37, + /* IPv6 5-tuple, padded to 8-byte boundary */ + 40 +}; + +/* Array to store number of cycles per operation */ +uint64_t cycles[NUM_KEYSIZES][NUM_OPERATIONS]; + +/* Array to store the data */ +efd_value_t data[KEYS_TO_ADD]; + +/* Array to store all input keys */ +uint8_t keys[KEYS_TO_ADD][MAX_KEYSIZE]; + +/* Shuffle the keys that have been added, so lookups will be totally random */ +static void +shuffle_input_keys(struct efd_perf_params *params) +{ + efd_value_t temp_data; + unsigned int i; + uint32_t swap_idx; + uint8_t temp_key[MAX_KEYSIZE]; + + for (i = KEYS_TO_ADD - 1; i > 0; i--) { + swap_idx = rte_rand() % i; + + memcpy(temp_key, keys[i], hashtest_key_lens[params->cycle]); + temp_data = data[i]; + + memcpy(keys[i], keys[swap_idx], hashtest_key_lens[params->cycle]); + data[i] = data[swap_idx]; + + memcpy(keys[swap_idx], temp_key, hashtest_key_lens[params->cycle]); + data[swap_idx] = temp_data; + } +} + +static int key_compare(const void *key1, const void *key2) +{ + return memcmp(key1, key2, MAX_KEYSIZE); +} + +/* + * TODO: we could "error proof" these as done in test_hash_perf.c ln 165: + * + * The current setup may give errors if too full in some cases which we check + * for. However, since EFD allows for ~99% capacity, these errors are rare for + * #"KEYS_TO_ADD" which is 75% capacity. + */ +static int +setup_keys_and_data(struct efd_perf_params *params, unsigned int cycle) +{ + unsigned int i, j; + int num_duplicates; + + params->key_size = hashtest_key_lens[cycle]; + params->cycle = cycle; + + /* Reset all arrays */ + for (i = 0; i < params->key_size; i++) + keys[0][i] = 0; + + /* Generate a list of keys, some of which may be duplicates */ + for (i = 0; i < KEYS_TO_ADD; i++) { + for (j = 0; j < params->key_size; j++) + keys[i][j] = rte_rand() & 0xFF; + + data[i] = rte_rand() & VALUE_BITMASK; + } + + /* Remove duplicates from the keys array */ + do { + num_duplicates = 0; + + /* Sort the list of keys to make it easier to find duplicates */ + qsort(keys, KEYS_TO_ADD, MAX_KEYSIZE, key_compare); + + /* Sift through the list of keys and look for duplicates */ + int num_duplicates = 0; + for (i = 0; i < KEYS_TO_ADD - 1; i++) { + if (memcmp(keys[i], keys[i + 1], params->key_size) == 0) { + /* This key already exists, try again */ + num_duplicates++; + for (j = 0; j < params->key_size; j++) + keys[i][j] = rte_rand() & 0xFF; + } + } + } while (num_duplicates != 0); + + /* Shuffle the random values again */ + shuffle_input_keys(params); + + params->efd_table = rte_efd_create("test_efd_perf", + MAX_ENTRIES, params->key_size, + efd_get_all_sockets_bitmask(), test_socket_id); + TEST_ASSERT_NOT_NULL(params->efd_table, "Error creating the efd table\n"); + + return 0; +} + +static int +timed_adds(struct efd_perf_params *params) +{ + const uint64_t start_tsc = rte_rdtsc(); + unsigned int i, a; + int32_t ret; + + for (i = 0; i < KEYS_TO_ADD; i++) { + ret = rte_efd_update(params->efd_table, test_socket_id, keys[i], + data[i]); + if (ret != 0) { + printf("Error %d in rte_efd_update - key=0x", ret); + for (a = 0; a < params->key_size; a++) + printf("%02x", keys[i][a]); + printf(" value=%d\n", data[i]); + + return -1; + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[params->cycle][ADD] = time_taken / KEYS_TO_ADD; + return 0; +} + +static int +timed_lookups(struct efd_perf_params *params) +{ + unsigned int i, j, a; + const uint64_t start_tsc = rte_rdtsc(); + efd_value_t ret_data; + + for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) { + for (j = 0; j < KEYS_TO_ADD; j++) { + ret_data = rte_efd_lookup(params->efd_table, + test_socket_id, keys[j]); + if (ret_data != data[j]) { + printf("Value mismatch using rte_efd_lookup: " + "key #%d (0x", i); + for (a = 0; a < params->key_size; a++) + printf("%02x", keys[i][a]); + printf(")\n"); + printf(" Expected %d, got %d\n", data[i], + ret_data); + + return -1; + } + + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[params->cycle][LOOKUP] = time_taken / NUM_LOOKUPS; + + return 0; +} + +static int +timed_lookups_multi(struct efd_perf_params *params) +{ + unsigned int i, j, k, a; + efd_value_t result[RTE_EFD_BURST_MAX] = {0}; + const void *keys_burst[RTE_EFD_BURST_MAX]; + const uint64_t start_tsc = rte_rdtsc(); + + for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) { + for (j = 0; j < KEYS_TO_ADD / RTE_EFD_BURST_MAX; j++) { + for (k = 0; k < RTE_EFD_BURST_MAX; k++) + keys_burst[k] = keys[j * RTE_EFD_BURST_MAX + k]; + + rte_efd_lookup_bulk(params->efd_table, test_socket_id, + RTE_EFD_BURST_MAX, + keys_burst, result); + + for (k = 0; k < RTE_EFD_BURST_MAX; k++) { + uint32_t data_idx = j * RTE_EFD_BURST_MAX + k; + if (result[k] != data[data_idx]) { + printf("Value mismatch using " + "rte_efd_lookup_bulk: key #%d " + "(0x", i); + for (a = 0; a < params->key_size; a++) + printf("%02x", + keys[data_idx][a]); + printf(")\n"); + printf(" Expected %d, got %d\n", + data[data_idx], result[k]); + + return -1; + } + } + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[params->cycle][LOOKUP_MULTI] = time_taken / NUM_LOOKUPS; + + return 0; +} + +static int +timed_deletes(struct efd_perf_params *params) +{ + unsigned int i, a; + const uint64_t start_tsc = rte_rdtsc(); + int32_t ret; + + for (i = 0; i < KEYS_TO_ADD; i++) { + ret = rte_efd_delete(params->efd_table, test_socket_id, keys[i], + NULL); + + if (ret != 0) { + printf("Error %d in rte_efd_delete - key=0x", ret); + for (a = 0; a < params->key_size; a++) + printf("%02x", keys[i][a]); + printf("\n"); + + return -1; + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[params->cycle][DELETE] = time_taken / KEYS_TO_ADD; + + return 0; +} + +static void +perform_frees(struct efd_perf_params *params) +{ + if (params->efd_table != NULL) { + rte_efd_free(params->efd_table); + params->efd_table = NULL; + } +} + +static int +exit_with_fail(const char *testname, struct efd_perf_params *params, + unsigned int i) +{ + + printf("<<<<>>>>\n", + testname, hashtest_key_lens[params->cycle], i); + perform_frees(params); + return -1; +} + +static int +run_all_tbl_perf_tests(void) +{ + unsigned int i, j; + struct efd_perf_params params; + + printf("Measuring performance, please wait\n"); + fflush(stdout); + + test_socket_id = rte_socket_id(); + + for (i = 0; i < NUM_KEYSIZES; i++) { + + if (setup_keys_and_data(¶ms, i) < 0) { + printf("Could not create keys/data/table\n"); + return -1; + } + + if (timed_adds(¶ms) < 0) + return exit_with_fail("timed_adds", ¶ms, i); + + for (j = 0; j < NUM_SHUFFLES; j++) + shuffle_input_keys(¶ms); + + if (timed_lookups(¶ms) < 0) + return exit_with_fail("timed_lookups", ¶ms, i); + + if (timed_lookups_multi(¶ms) < 0) + return exit_with_fail("timed_lookups_multi", ¶ms, i); + + if (timed_deletes(¶ms) < 0) + return exit_with_fail("timed_deletes", ¶ms, i); + + /* Print a dot to show progress on operations */ + printf("."); + fflush(stdout); + + perform_frees(¶ms); + } + + printf("\nResults (in CPU cycles/operation)\n"); + printf("-----------------------------------\n"); + printf("\n%-18s%-18s%-18s%-18s%-18s\n", + "Keysize", "Add", "Lookup", "Lookup_bulk", "Delete"); + for (i = 0; i < NUM_KEYSIZES; i++) { + printf("%-18d", hashtest_key_lens[i]); + for (j = 0; j < NUM_OPERATIONS; j++) + printf("%-18"PRIu64, cycles[i][j]); + printf("\n"); + } + return 0; +} + +static int +test_efd_perf(void) +{ + + if (run_all_tbl_perf_tests() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(efd_perf_autotest, test_efd_perf); diff --git a/test/test/test_errno.c b/test/test/test_errno.c new file mode 100644 index 0000000000..388decbb2a --- /dev/null +++ b/test/test/test_errno.c @@ -0,0 +1,116 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +static int +test_errno(void) +{ + const char *rte_retval; + const char *libc_retval; +#ifdef RTE_EXEC_ENV_BSDAPP + /* BSD has a colon in the string, unlike linux */ + const char unknown_code_result[] = "Unknown error: %d"; +#else + const char unknown_code_result[] = "Unknown error %d"; +#endif + char expected_libc_retval[sizeof(unknown_code_result)+3]; + + /* use a small selection of standard errors for testing */ + int std_errs[] = {EAGAIN, EBADF, EACCES, EINTR, EINVAL}; + /* test ALL registered RTE error codes for overlap */ + int rte_errs[] = {E_RTE_SECONDARY, E_RTE_NO_CONFIG}; + unsigned i; + + rte_errno = 0; + if (rte_errno != 0) + return -1; + /* check for standard errors we return the same as libc */ + for (i = 0; i < sizeof(std_errs)/sizeof(std_errs[0]); i++){ + rte_retval = rte_strerror(std_errs[i]); + libc_retval = strerror(std_errs[i]); + printf("rte_strerror: '%s', strerror: '%s'\n", + rte_retval, libc_retval); + if (strcmp(rte_retval, libc_retval) != 0) + return -1; + } + /* for rte-specific errors ensure we return a different string + * and that the string for libc is for an unknown error + */ + for (i = 0; i < sizeof(rte_errs)/sizeof(rte_errs[0]); i++){ + rte_retval = rte_strerror(rte_errs[i]); + libc_retval = strerror(rte_errs[i]); + printf("rte_strerror: '%s', strerror: '%s'\n", + rte_retval, libc_retval); + if (strcmp(rte_retval, libc_retval) == 0) + return -1; + /* generate appropriate error string for unknown error number + * and then check that this is what we got back. If not, we have + * a duplicate error number that conflicts with errno.h */ + snprintf(expected_libc_retval, sizeof(expected_libc_retval), + unknown_code_result, rte_errs[i]); + if ((strcmp(expected_libc_retval, libc_retval) != 0) && + (strcmp("", libc_retval) != 0)){ + printf("Error, duplicate error code %d\n", rte_errs[i]); + return -1; + } + } + + /* ensure that beyond RTE_MAX_ERRNO, we always get an unknown code */ + rte_retval = rte_strerror(RTE_MAX_ERRNO + 1); + libc_retval = strerror(RTE_MAX_ERRNO + 1); + snprintf(expected_libc_retval, sizeof(expected_libc_retval), + unknown_code_result, RTE_MAX_ERRNO + 1); + printf("rte_strerror: '%s', strerror: '%s'\n", + rte_retval, libc_retval); + if ((strcmp(rte_retval, libc_retval) != 0) || + (strcmp(expected_libc_retval, libc_retval) != 0)){ + if (strcmp("", libc_retval) != 0){ + printf("Failed test for RTE_MAX_ERRNO + 1 value\n"); + return -1; + } + } + + return 0; +} + +REGISTER_TEST_COMMAND(errno_autotest, test_errno); diff --git a/test/test/test_func_reentrancy.c b/test/test/test_func_reentrancy.c new file mode 100644 index 0000000000..baa01ffc2c --- /dev/null +++ b/test/test/test_func_reentrancy.c @@ -0,0 +1,510 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef RTE_LIBRTE_HASH +#include +#include +#include +#endif /* RTE_LIBRTE_HASH */ + +#ifdef RTE_LIBRTE_LPM +#include +#endif /* RTE_LIBRTE_LPM */ + +#include + +#include "test.h" + +typedef int (*case_func_t)(void* arg); +typedef void (*case_clean_t)(unsigned lcore_id); + +#define MAX_STRING_SIZE (256) +#define MAX_ITER_TIMES (16) +#define MAX_LPM_ITER_TIMES (8) + +#define MEMPOOL_ELT_SIZE (sizeof(uint32_t)) +#define MEMPOOL_SIZE (4) + +#define MAX_LCORES RTE_MAX_MEMZONE / (MAX_ITER_TIMES * 4U) + +static rte_atomic32_t obj_count = RTE_ATOMIC32_INIT(0); +static rte_atomic32_t synchro = RTE_ATOMIC32_INIT(0); + +#define WAIT_SYNCHRO_FOR_SLAVES() do{ \ + if (lcore_self != rte_get_master_lcore()) \ + while (rte_atomic32_read(&synchro) == 0); \ +} while(0) + +/* + * rte_eal_init only init once + */ +static int +test_eal_init_once(__attribute__((unused)) void *arg) +{ + unsigned lcore_self = rte_lcore_id(); + + WAIT_SYNCHRO_FOR_SLAVES(); + + rte_atomic32_set(&obj_count, 1); /* silent the check in the caller */ + if (rte_eal_init(0, NULL) != -1) + return -1; + + return 0; +} + +/* + * ring create/lookup reentrancy test + */ +static int +ring_create_lookup(__attribute__((unused)) void *arg) +{ + unsigned lcore_self = rte_lcore_id(); + struct rte_ring * rp; + char ring_name[MAX_STRING_SIZE]; + int i; + + WAIT_SYNCHRO_FOR_SLAVES(); + + /* create the same ring simultaneously on all threads */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + rp = rte_ring_create("fr_test_once", 4096, SOCKET_ID_ANY, 0); + if (rp != NULL) + rte_atomic32_inc(&obj_count); + } + + /* create/lookup new ring several times */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(ring_name, sizeof(ring_name), "fr_test_%d_%d", lcore_self, i); + rp = rte_ring_create(ring_name, 4096, SOCKET_ID_ANY, 0); + if (NULL == rp) + return -1; + if (rte_ring_lookup(ring_name) != rp) + return -1; + } + + /* verify all ring created sucessful */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(ring_name, sizeof(ring_name), "fr_test_%d_%d", lcore_self, i); + if (rte_ring_lookup(ring_name) == NULL) + return -1; + } + + return 0; +} + +static void +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; +} + +static int +mempool_create_lookup(__attribute__((unused)) void *arg) +{ + unsigned lcore_self = rte_lcore_id(); + struct rte_mempool * mp; + char mempool_name[MAX_STRING_SIZE]; + int i; + + WAIT_SYNCHRO_FOR_SLAVES(); + + /* create the same mempool simultaneously on all threads */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + mp = rte_mempool_create("fr_test_once", MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, 0, 0, + NULL, NULL, + my_obj_init, NULL, + SOCKET_ID_ANY, 0); + if (mp != NULL) + rte_atomic32_inc(&obj_count); + } + + /* create/lookup new ring several times */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(mempool_name, sizeof(mempool_name), "fr_test_%d_%d", lcore_self, i); + mp = rte_mempool_create(mempool_name, MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, 0, 0, + NULL, NULL, + my_obj_init, NULL, + SOCKET_ID_ANY, 0); + if (NULL == mp) + return -1; + if (rte_mempool_lookup(mempool_name) != mp) + return -1; + } + + /* verify all ring created sucessful */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(mempool_name, sizeof(mempool_name), "fr_test_%d_%d", lcore_self, i); + if (rte_mempool_lookup(mempool_name) == NULL) + return -1; + } + + return 0; +} + +#ifdef RTE_LIBRTE_HASH +static void +hash_clean(unsigned lcore_id) +{ + char hash_name[MAX_STRING_SIZE]; + struct rte_hash *handle; + int i; + + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(hash_name, sizeof(hash_name), "fr_test_%d_%d", lcore_id, i); + + if ((handle = rte_hash_find_existing(hash_name)) != NULL) + rte_hash_free(handle); + } +} + +static int +hash_create_free(__attribute__((unused)) void *arg) +{ + unsigned lcore_self = rte_lcore_id(); + struct rte_hash *handle; + char hash_name[MAX_STRING_SIZE]; + int i; + struct rte_hash_parameters hash_params = { + .name = NULL, + .entries = 16, + .key_len = 4, + .hash_func = (rte_hash_function)rte_jhash_32b, + .hash_func_init_val = 0, + .socket_id = 0, + }; + + WAIT_SYNCHRO_FOR_SLAVES(); + + /* create the same hash simultaneously on all threads */ + hash_params.name = "fr_test_once"; + for (i = 0; i < MAX_ITER_TIMES; i++) { + handle = rte_hash_create(&hash_params); + if (handle != NULL) + rte_atomic32_inc(&obj_count); + } + + /* create mutiple times simultaneously */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(hash_name, sizeof(hash_name), "fr_test_%d_%d", lcore_self, i); + hash_params.name = hash_name; + + handle = rte_hash_create(&hash_params); + if (NULL == handle) + return -1; + + /* verify correct existing and then free all */ + if (handle != rte_hash_find_existing(hash_name)) + return -1; + + rte_hash_free(handle); + } + + /* verify free correct */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(hash_name, sizeof(hash_name), "fr_test_%d_%d", lcore_self, i); + + if (NULL != rte_hash_find_existing(hash_name)) + return -1; + } + + return 0; +} + +static void +fbk_clean(unsigned lcore_id) +{ + char fbk_name[MAX_STRING_SIZE]; + struct rte_fbk_hash_table *handle; + int i; + + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(fbk_name, sizeof(fbk_name), "fr_test_%d_%d", lcore_id, i); + + if ((handle = rte_fbk_hash_find_existing(fbk_name)) != NULL) + rte_fbk_hash_free(handle); + } +} + +static int +fbk_create_free(__attribute__((unused)) void *arg) +{ + unsigned lcore_self = rte_lcore_id(); + struct rte_fbk_hash_table *handle; + char fbk_name[MAX_STRING_SIZE]; + int i; + struct rte_fbk_hash_params fbk_params = { + .name = NULL, + .entries = 4, + .entries_per_bucket = 4, + .socket_id = 0, + .hash_func = rte_jhash_1word, + .init_val = RTE_FBK_HASH_INIT_VAL_DEFAULT, + }; + + WAIT_SYNCHRO_FOR_SLAVES(); + + /* create the same fbk hash table simultaneously on all threads */ + fbk_params.name = "fr_test_once"; + for (i = 0; i < MAX_ITER_TIMES; i++) { + handle = rte_fbk_hash_create(&fbk_params); + if (handle != NULL) + rte_atomic32_inc(&obj_count); + } + + /* create mutiple fbk tables simultaneously */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(fbk_name, sizeof(fbk_name), "fr_test_%d_%d", lcore_self, i); + fbk_params.name = fbk_name; + + handle = rte_fbk_hash_create(&fbk_params); + if (NULL == handle) + return -1; + + /* verify correct existing and then free all */ + if (handle != rte_fbk_hash_find_existing(fbk_name)) + return -1; + + rte_fbk_hash_free(handle); + } + + /* verify free correct */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + snprintf(fbk_name, sizeof(fbk_name), "fr_test_%d_%d", lcore_self, i); + + if (NULL != rte_fbk_hash_find_existing(fbk_name)) + return -1; + } + + return 0; +} +#endif /* RTE_LIBRTE_HASH */ + +#ifdef RTE_LIBRTE_LPM +static void +lpm_clean(unsigned lcore_id) +{ + char lpm_name[MAX_STRING_SIZE]; + struct rte_lpm *lpm; + int i; + + for (i = 0; i < MAX_LPM_ITER_TIMES; i++) { + snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_id, i); + + if ((lpm = rte_lpm_find_existing(lpm_name)) != NULL) + rte_lpm_free(lpm); + } +} + +static int +lpm_create_free(__attribute__((unused)) void *arg) +{ + unsigned lcore_self = rte_lcore_id(); + struct rte_lpm *lpm; + struct rte_lpm_config config; + + config.max_rules = 4; + config.number_tbl8s = 256; + config.flags = 0; + char lpm_name[MAX_STRING_SIZE]; + int i; + + WAIT_SYNCHRO_FOR_SLAVES(); + + /* create the same lpm simultaneously on all threads */ + for (i = 0; i < MAX_ITER_TIMES; i++) { + lpm = rte_lpm_create("fr_test_once", SOCKET_ID_ANY, &config); + if (lpm != NULL) + rte_atomic32_inc(&obj_count); + } + + /* create mutiple fbk tables simultaneously */ + for (i = 0; i < MAX_LPM_ITER_TIMES; i++) { + snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_self, i); + lpm = rte_lpm_create(lpm_name, SOCKET_ID_ANY, &config); + if (NULL == lpm) + return -1; + + /* verify correct existing and then free all */ + if (lpm != rte_lpm_find_existing(lpm_name)) + return -1; + + rte_lpm_free(lpm); + } + + /* verify free correct */ + for (i = 0; i < MAX_LPM_ITER_TIMES; i++) { + snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_self, i); + if (NULL != rte_lpm_find_existing(lpm_name)) + return -1; + } + + return 0; +} +#endif /* RTE_LIBRTE_LPM */ + +struct test_case{ + case_func_t func; + void* arg; + case_clean_t clean; + char name[MAX_STRING_SIZE]; +}; + +/* All test cases in the test suite */ +struct test_case test_cases[] = { + { test_eal_init_once, NULL, NULL, "eal init once" }, + { ring_create_lookup, NULL, NULL, "ring create/lookup" }, + { mempool_create_lookup, NULL, NULL, "mempool create/lookup" }, +#ifdef RTE_LIBRTE_HASH + { hash_create_free, NULL, hash_clean, "hash create/free" }, + { fbk_create_free, NULL, fbk_clean, "fbk create/free" }, +#endif /* RTE_LIBRTE_HASH */ +#ifdef RTE_LIBRTE_LPM + { lpm_create_free, NULL, lpm_clean, "lpm create/free" }, +#endif /* RTE_LIBRTE_LPM */ +}; + +/** + * launch test case in two separate thread + */ +static int +launch_test(struct test_case *pt_case) +{ + int ret = 0; + unsigned lcore_id; + unsigned cores_save = rte_lcore_count(); + unsigned cores = RTE_MIN(cores_save, MAX_LCORES); + unsigned count; + + if (pt_case->func == NULL) + return -1; + + rte_atomic32_set(&obj_count, 0); + rte_atomic32_set(&synchro, 0); + + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (cores == 1) + break; + cores--; + rte_eal_remote_launch(pt_case->func, pt_case->arg, lcore_id); + } + + rte_atomic32_set(&synchro, 1); + + if (pt_case->func(pt_case->arg) < 0) + ret = -1; + + cores = cores_save; + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (cores == 1) + break; + cores--; + if (rte_eal_wait_lcore(lcore_id) < 0) + ret = -1; + + if (pt_case->clean != NULL) + pt_case->clean(lcore_id); + } + + count = rte_atomic32_read(&obj_count); + if (count != 1) { + printf("%s: common object allocated %d times (should be 1)\n", + pt_case->name, count); + ret = -1; + } + + return ret; +} + +/** + * Main entry of func_reentrancy test + */ +static int +test_func_reentrancy(void) +{ + uint32_t case_id; + struct test_case *pt_case = NULL; + + if (rte_lcore_count() <= 1) { + printf("Not enough lcore for testing\n"); + return -1; + } + else if (rte_lcore_count() > MAX_LCORES) + printf("Too many lcores, some cores will be disabled\n"); + + for (case_id = 0; case_id < sizeof(test_cases)/sizeof(struct test_case); case_id ++) { + pt_case = &test_cases[case_id]; + if (pt_case->func == NULL) + continue; + + if (launch_test(pt_case) < 0) { + printf("Func-ReEnt CASE %"PRIu32": %s FAIL\n", case_id, pt_case->name); + return -1; + } + printf("Func-ReEnt CASE %"PRIu32": %s PASS\n", case_id, pt_case->name); + } + + return 0; +} + +REGISTER_TEST_COMMAND(func_reentrancy_autotest, test_func_reentrancy); diff --git a/test/test/test_hash.c b/test/test/test_hash.c new file mode 100644 index 0000000000..2c87efe692 --- /dev/null +++ b/test/test/test_hash.c @@ -0,0 +1,1517 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#include +#include +#include +#include + +/******************************************************************************* + * Hash function performance test configuration section. Each performance test + * will be performed HASHTEST_ITERATIONS times. + * + * The five arrays below control what tests are performed. Every combination + * from the array entries is tested. + */ +static rte_hash_function hashtest_funcs[] = {rte_jhash, rte_hash_crc}; +static uint32_t hashtest_initvals[] = {0}; +static uint32_t hashtest_key_lens[] = {0, 2, 4, 5, 6, 7, 8, 10, 11, 15, 16, 21, 31, 32, 33, 63, 64}; +#define MAX_KEYSIZE 64 +/******************************************************************************/ +#define LOCAL_FBK_HASH_ENTRIES_MAX (1 << 15) + +/* + * 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 RETURN_IF_ERROR_FBK(cond, str, ...) do { \ + if (cond) { \ + printf("ERROR line %d: " str "\n", __LINE__, ##__VA_ARGS__); \ + if (handle) rte_fbk_hash_free(handle); \ + return -1; \ + } \ +} while(0) + +/* 5-tuple key type */ +struct flow_key { + uint32_t ip_src; + uint32_t ip_dst; + uint16_t port_src; + uint16_t port_dst; + uint8_t proto; +} __attribute__((packed)); + +/* + * Hash function that always returns the same value, to easily test what + * happens when a bucket is full. + */ +static uint32_t pseudo_hash(__attribute__((unused)) const void *keys, + __attribute__((unused)) uint32_t key_len, + __attribute__((unused)) uint32_t init_val) +{ + return 3; +} + +/* + * Print out result of unit test hash operation. + */ +#if defined(UNIT_TEST_HASH_VERBOSE) +static void print_key_info(const char *msg, const struct flow_key *key, + int32_t pos) +{ + uint8_t *p = (uint8_t *)key; + unsigned i; + + printf("%s key:0x", msg); + for (i = 0; i < sizeof(struct flow_key); i++) { + printf("%02X", p[i]); + } + printf(" @ pos %d\n", pos); +} +#else +static void print_key_info(__attribute__((unused)) const char *msg, + __attribute__((unused)) const struct flow_key *key, + __attribute__((unused)) int32_t pos) +{ +} +#endif + +/* Keys used by unit test functions */ +static struct flow_key keys[5] = { { + .ip_src = IPv4(0x03, 0x02, 0x01, 0x00), + .ip_dst = IPv4(0x07, 0x06, 0x05, 0x04), + .port_src = 0x0908, + .port_dst = 0x0b0a, + .proto = 0x0c, +}, { + .ip_src = IPv4(0x13, 0x12, 0x11, 0x10), + .ip_dst = IPv4(0x17, 0x16, 0x15, 0x14), + .port_src = 0x1918, + .port_dst = 0x1b1a, + .proto = 0x1c, +}, { + .ip_src = IPv4(0x23, 0x22, 0x21, 0x20), + .ip_dst = IPv4(0x27, 0x26, 0x25, 0x24), + .port_src = 0x2928, + .port_dst = 0x2b2a, + .proto = 0x2c, +}, { + .ip_src = IPv4(0x33, 0x32, 0x31, 0x30), + .ip_dst = IPv4(0x37, 0x36, 0x35, 0x34), + .port_src = 0x3938, + .port_dst = 0x3b3a, + .proto = 0x3c, +}, { + .ip_src = IPv4(0x43, 0x42, 0x41, 0x40), + .ip_dst = IPv4(0x47, 0x46, 0x45, 0x44), + .port_src = 0x4948, + .port_dst = 0x4b4a, + .proto = 0x4c, +} }; + +/* Parameters used for hash table in unit test functions. Name set later. */ +static struct rte_hash_parameters ut_params = { + .entries = 64, + .key_len = sizeof(struct flow_key), /* 13 */ + .hash_func = rte_jhash, + .hash_func_init_val = 0, + .socket_id = 0, +}; + +#define CRC32_ITERATIONS (1U << 10) +#define CRC32_DWORDS (1U << 6) +/* + * Test if all CRC32 implementations yield the same hash value + */ +static int +test_crc32_hash_alg_equiv(void) +{ + uint32_t hash_val; + uint32_t init_val; + uint64_t data64[CRC32_DWORDS]; + unsigned i, j; + size_t data_len; + + printf("\n# CRC32 implementations equivalence test\n"); + for (i = 0; i < CRC32_ITERATIONS; i++) { + /* Randomizing data_len of data set */ + data_len = (size_t) ((rte_rand() % sizeof(data64)) + 1); + init_val = (uint32_t) rte_rand(); + + /* Fill the data set */ + for (j = 0; j < CRC32_DWORDS; j++) + data64[j] = rte_rand(); + + /* Calculate software CRC32 */ + rte_hash_crc_set_alg(CRC32_SW); + hash_val = rte_hash_crc(data64, data_len, init_val); + + /* Check against 4-byte-operand sse4.2 CRC32 if available */ + rte_hash_crc_set_alg(CRC32_SSE42); + if (hash_val != rte_hash_crc(data64, data_len, init_val)) { + printf("Failed checking CRC32_SW against CRC32_SSE42\n"); + break; + } + + /* Check against 8-byte-operand sse4.2 CRC32 if available */ + rte_hash_crc_set_alg(CRC32_SSE42_x64); + if (hash_val != rte_hash_crc(data64, data_len, init_val)) { + printf("Failed checking CRC32_SW against CRC32_SSE42_x64\n"); + break; + } + + /* Check against 8-byte-operand ARM64 CRC32 if available */ + rte_hash_crc_set_alg(CRC32_ARM64); + if (hash_val != rte_hash_crc(data64, data_len, init_val)) { + printf("Failed checking CRC32_SW against CRC32_ARM64\n"); + break; + } + } + + /* Resetting to best available algorithm */ + rte_hash_crc_set_alg(CRC32_SSE42_x64); + + if (i == CRC32_ITERATIONS) + return 0; + + printf("Failed test data (hex, %zu bytes total):\n", data_len); + for (j = 0; j < data_len; j++) + printf("%02X%c", ((uint8_t *)data64)[j], + ((j+1) % 16 == 0 || j == data_len - 1) ? '\n' : ' '); + + return -1; +} + +/* + * Test a hash function. + */ +static void run_hash_func_test(rte_hash_function f, uint32_t init_val, + uint32_t key_len) +{ + static uint8_t key[MAX_KEYSIZE]; + unsigned i; + + + for (i = 0; i < key_len; i++) + key[i] = (uint8_t) rte_rand(); + + /* just to be on the safe side */ + if (!f) + return; + + f(key, key_len, init_val); +} + +/* + * Test all hash functions. + */ +static void run_hash_func_tests(void) +{ + unsigned i, j, k; + + for (i = 0; + i < sizeof(hashtest_funcs) / sizeof(rte_hash_function); + i++) { + for (j = 0; + j < sizeof(hashtest_initvals) / sizeof(uint32_t); + j++) { + for (k = 0; + k < sizeof(hashtest_key_lens) / sizeof(uint32_t); + k++) { + run_hash_func_test(hashtest_funcs[i], + hashtest_initvals[j], + hashtest_key_lens[k]); + } + } + } +} + +/* + * Basic sequence of operations for a single key: + * - add + * - lookup (hit) + * - delete + * - lookup (miss) + */ +static int test_add_delete(void) +{ + struct rte_hash *handle; + /* test with standard add/lookup/delete functions */ + int pos0, expectedPos0; + + ut_params.name = "test1"; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + pos0 = rte_hash_add_key(handle, &keys[0]); + print_key_info("Add", &keys[0], pos0); + RETURN_IF_ERROR(pos0 < 0, "failed to add key (pos0=%d)", pos0); + expectedPos0 = pos0; + + pos0 = rte_hash_lookup(handle, &keys[0]); + print_key_info("Lkp", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != expectedPos0, + "failed to find key (pos0=%d)", pos0); + + pos0 = rte_hash_del_key(handle, &keys[0]); + print_key_info("Del", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != expectedPos0, + "failed to delete key (pos0=%d)", pos0); + + pos0 = rte_hash_lookup(handle, &keys[0]); + print_key_info("Lkp", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != -ENOENT, + "fail: found key after deleting! (pos0=%d)", pos0); + + rte_hash_free(handle); + + /* repeat test with precomputed hash functions */ + hash_sig_t hash_value; + int pos1, expectedPos1; + + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + hash_value = rte_hash_hash(handle, &keys[0]); + pos1 = rte_hash_add_key_with_hash(handle, &keys[0], hash_value); + print_key_info("Add", &keys[0], pos1); + RETURN_IF_ERROR(pos1 < 0, "failed to add key (pos1=%d)", pos1); + expectedPos1 = pos1; + + pos1 = rte_hash_lookup_with_hash(handle, &keys[0], hash_value); + print_key_info("Lkp", &keys[0], pos1); + RETURN_IF_ERROR(pos1 != expectedPos1, + "failed to find key (pos1=%d)", pos1); + + pos1 = rte_hash_del_key_with_hash(handle, &keys[0], hash_value); + print_key_info("Del", &keys[0], pos1); + RETURN_IF_ERROR(pos1 != expectedPos1, + "failed to delete key (pos1=%d)", pos1); + + pos1 = rte_hash_lookup_with_hash(handle, &keys[0], hash_value); + print_key_info("Lkp", &keys[0], pos1); + RETURN_IF_ERROR(pos1 != -ENOENT, + "fail: found key after deleting! (pos1=%d)", pos1); + + rte_hash_free(handle); + + return 0; +} + +/* + * Sequence of operations for a single key: + * - delete: miss + * - add + * - lookup: hit + * - add: update + * - lookup: hit (updated data) + * - delete: hit + * - delete: miss + * - lookup: miss + */ +static int test_add_update_delete(void) +{ + struct rte_hash *handle; + int pos0, expectedPos0; + + ut_params.name = "test2"; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + pos0 = rte_hash_del_key(handle, &keys[0]); + print_key_info("Del", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != -ENOENT, + "fail: found non-existent key (pos0=%d)", pos0); + + pos0 = rte_hash_add_key(handle, &keys[0]); + print_key_info("Add", &keys[0], pos0); + RETURN_IF_ERROR(pos0 < 0, "failed to add key (pos0=%d)", pos0); + expectedPos0 = pos0; + + pos0 = rte_hash_lookup(handle, &keys[0]); + print_key_info("Lkp", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != expectedPos0, + "failed to find key (pos0=%d)", pos0); + + pos0 = rte_hash_add_key(handle, &keys[0]); + print_key_info("Add", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != expectedPos0, + "failed to re-add key (pos0=%d)", pos0); + + pos0 = rte_hash_lookup(handle, &keys[0]); + print_key_info("Lkp", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != expectedPos0, + "failed to find key (pos0=%d)", pos0); + + pos0 = rte_hash_del_key(handle, &keys[0]); + print_key_info("Del", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != expectedPos0, + "failed to delete key (pos0=%d)", pos0); + + pos0 = rte_hash_del_key(handle, &keys[0]); + print_key_info("Del", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != -ENOENT, + "fail: deleted already deleted key (pos0=%d)", pos0); + + pos0 = rte_hash_lookup(handle, &keys[0]); + print_key_info("Lkp", &keys[0], pos0); + RETURN_IF_ERROR(pos0 != -ENOENT, + "fail: found key after deleting! (pos0=%d)", pos0); + + rte_hash_free(handle); + return 0; +} + +/* + * Sequence of operations for retrieving a key with its position + * + * - create table + * - add key + * - get the key with its position: hit + * - delete key + * - try to get the deleted key: miss + * + */ +static int test_hash_get_key_with_position(void) +{ + struct rte_hash *handle = NULL; + int pos, expectedPos, result; + void *key; + + ut_params.name = "hash_get_key_w_pos"; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + pos = rte_hash_add_key(handle, &keys[0]); + print_key_info("Add", &keys[0], pos); + RETURN_IF_ERROR(pos < 0, "failed to add key (pos0=%d)", pos); + expectedPos = pos; + + result = rte_hash_get_key_with_position(handle, pos, &key); + RETURN_IF_ERROR(result != 0, "error retrieving a key"); + + pos = rte_hash_del_key(handle, &keys[0]); + print_key_info("Del", &keys[0], pos); + RETURN_IF_ERROR(pos != expectedPos, + "failed to delete key (pos0=%d)", pos); + + result = rte_hash_get_key_with_position(handle, pos, &key); + RETURN_IF_ERROR(result != -ENOENT, "non valid key retrieved"); + + rte_hash_free(handle); + return 0; +} + +/* + * Sequence of operations for find existing hash table + * + * - create table + * - find existing table: hit + * - find non-existing table: miss + * + */ +static int test_hash_find_existing(void) +{ + struct rte_hash *handle = NULL, *result = NULL; + + /* Create hash table. */ + ut_params.name = "hash_find_existing"; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + /* Try to find existing hash table */ + result = rte_hash_find_existing("hash_find_existing"); + RETURN_IF_ERROR(result != handle, "could not find existing hash table"); + + /* Try to find non-existing hash table */ + result = rte_hash_find_existing("hash_find_non_existing"); + RETURN_IF_ERROR(!(result == NULL), "found table that shouldn't exist"); + + /* Cleanup. */ + rte_hash_free(handle); + + return 0; +} + +/* + * Sequence of operations for 5 keys + * - add keys + * - lookup keys: hit + * - add keys (update) + * - lookup keys: hit (updated data) + * - delete keys : hit + * - lookup keys: miss + */ +static int test_five_keys(void) +{ + struct rte_hash *handle; + const void *key_array[5] = {0}; + int pos[5]; + int expected_pos[5]; + unsigned i; + int ret; + + ut_params.name = "test3"; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + /* Add */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_add_key(handle, &keys[i]); + print_key_info("Add", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] < 0, + "failed to add key (pos[%u]=%d)", i, pos[i]); + expected_pos[i] = pos[i]; + } + + /* Lookup */ + for(i = 0; i < 5; i++) + key_array[i] = &keys[i]; + + 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]); + RETURN_IF_ERROR(pos[i] != expected_pos[i], + "failed to find key (pos[%u]=%d)", i, pos[i]); + } + + /* Add - update */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_add_key(handle, &keys[i]); + print_key_info("Add", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != expected_pos[i], + "failed to add key (pos[%u]=%d)", i, pos[i]); + } + + /* Lookup */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_lookup(handle, &keys[i]); + print_key_info("Lkp", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != expected_pos[i], + "failed to find key (pos[%u]=%d)", i, pos[i]); + } + + /* Delete */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_del_key(handle, &keys[i]); + print_key_info("Del", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != expected_pos[i], + "failed to delete key (pos[%u]=%d)", i, pos[i]); + } + + /* Lookup */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_lookup(handle, &keys[i]); + print_key_info("Lkp", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != -ENOENT, + "found non-existent key (pos[%u]=%d)", i, pos[i]); + } + + /* Lookup multi */ + 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]); + RETURN_IF_ERROR(pos[i] != -ENOENT, + "found not-existent key (pos[%u]=%d)", i, pos[i]); + } + + rte_hash_free(handle); + + return 0; +} + +/* + * Add keys to the same bucket until bucket full. + * - add 5 keys to the same bucket (hash created with 4 keys per bucket): + * first 4 successful, 5th successful, pushing existing item in bucket + * - lookup the 5 keys: 5 hits + * - add the 5 keys again: 5 OK + * - lookup the 5 keys: 5 hits (updated data) + * - delete the 5 keys: 5 OK + * - lookup the 5 keys: 5 misses + */ +static int test_full_bucket(void) +{ + struct rte_hash_parameters params_pseudo_hash = { + .name = "test4", + .entries = 64, + .key_len = sizeof(struct flow_key), /* 13 */ + .hash_func = pseudo_hash, + .hash_func_init_val = 0, + .socket_id = 0, + }; + struct rte_hash *handle; + int pos[5]; + int expected_pos[5]; + unsigned i; + + handle = rte_hash_create(¶ms_pseudo_hash); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + /* Fill bucket */ + for (i = 0; i < 4; i++) { + pos[i] = rte_hash_add_key(handle, &keys[i]); + print_key_info("Add", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] < 0, + "failed to add key (pos[%u]=%d)", i, pos[i]); + expected_pos[i] = pos[i]; + } + /* + * This should work and will push one of the items + * in the bucket because it is full + */ + pos[4] = rte_hash_add_key(handle, &keys[4]); + print_key_info("Add", &keys[4], pos[4]); + RETURN_IF_ERROR(pos[4] < 0, + "failed to add key (pos[4]=%d)", pos[4]); + expected_pos[4] = pos[4]; + + /* Lookup */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_lookup(handle, &keys[i]); + print_key_info("Lkp", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != expected_pos[i], + "failed to find key (pos[%u]=%d)", i, pos[i]); + } + + /* Add - update */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_add_key(handle, &keys[i]); + print_key_info("Add", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != expected_pos[i], + "failed to add key (pos[%u]=%d)", i, pos[i]); + } + + /* Lookup */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_lookup(handle, &keys[i]); + print_key_info("Lkp", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != expected_pos[i], + "failed to find key (pos[%u]=%d)", i, pos[i]); + } + + /* Delete 1 key, check other keys are still found */ + pos[1] = rte_hash_del_key(handle, &keys[1]); + print_key_info("Del", &keys[1], pos[1]); + RETURN_IF_ERROR(pos[1] != expected_pos[1], + "failed to delete key (pos[1]=%d)", pos[1]); + pos[3] = rte_hash_lookup(handle, &keys[3]); + print_key_info("Lkp", &keys[3], pos[3]); + RETURN_IF_ERROR(pos[3] != expected_pos[3], + "failed lookup after deleting key from same bucket " + "(pos[3]=%d)", pos[3]); + + /* Go back to previous state */ + pos[1] = rte_hash_add_key(handle, &keys[1]); + print_key_info("Add", &keys[1], pos[1]); + expected_pos[1] = pos[1]; + RETURN_IF_ERROR(pos[1] < 0, "failed to add key (pos[1]=%d)", pos[1]); + + /* Delete */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_del_key(handle, &keys[i]); + print_key_info("Del", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != expected_pos[i], + "failed to delete key (pos[%u]=%d)", i, pos[i]); + } + + /* Lookup */ + for (i = 0; i < 5; i++) { + pos[i] = rte_hash_lookup(handle, &keys[i]); + print_key_info("Lkp", &keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != -ENOENT, + "fail: found non-existent key (pos[%u]=%d)", i, pos[i]); + } + + rte_hash_free(handle); + + /* Cover the NULL case. */ + rte_hash_free(0); + return 0; +} + +/******************************************************************************/ +static int +fbk_hash_unit_test(void) +{ + struct rte_fbk_hash_params params = { + .name = "fbk_hash_test", + .entries = LOCAL_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = 4, + .socket_id = 0, + }; + + struct rte_fbk_hash_params invalid_params_1 = { + .name = "invalid_1", + .entries = LOCAL_FBK_HASH_ENTRIES_MAX + 1, /* Not power of 2 */ + .entries_per_bucket = 4, + .socket_id = 0, + }; + + struct rte_fbk_hash_params invalid_params_2 = { + .name = "invalid_2", + .entries = 4, + .entries_per_bucket = 3, /* Not power of 2 */ + .socket_id = 0, + }; + + struct rte_fbk_hash_params invalid_params_3 = { + .name = "invalid_3", + .entries = 0, /* Entries is 0 */ + .entries_per_bucket = 4, + .socket_id = 0, + }; + + struct rte_fbk_hash_params invalid_params_4 = { + .name = "invalid_4", + .entries = LOCAL_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = 0, /* Entries per bucket is 0 */ + .socket_id = 0, + }; + + struct rte_fbk_hash_params invalid_params_5 = { + .name = "invalid_5", + .entries = 4, + .entries_per_bucket = 8, /* Entries per bucket > entries */ + .socket_id = 0, + }; + + struct rte_fbk_hash_params invalid_params_6 = { + .name = "invalid_6", + .entries = RTE_FBK_HASH_ENTRIES_MAX * 2, /* Entries > max allowed */ + .entries_per_bucket = 4, + .socket_id = 0, + }; + + struct rte_fbk_hash_params invalid_params_7 = { + .name = "invalid_7", + .entries = RTE_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = RTE_FBK_HASH_ENTRIES_PER_BUCKET_MAX * 2, /* Entries > max allowed */ + .socket_id = 0, + }; + + struct rte_fbk_hash_params invalid_params_8 = { + .name = "invalid_7", + .entries = RTE_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = 4, + .socket_id = RTE_MAX_NUMA_NODES + 1, /* invalid socket */ + }; + + /* try to create two hashes with identical names + * in this case, trying to create a second one will not + * fail but will simply return pointer to the existing + * hash with that name. sort of like a "find hash by name" :-) + */ + struct rte_fbk_hash_params invalid_params_same_name_1 = { + .name = "same_name", /* hash with identical name */ + .entries = 4, + .entries_per_bucket = 2, + .socket_id = 0, + }; + + /* trying to create this hash should return a pointer to an existing hash */ + struct rte_fbk_hash_params invalid_params_same_name_2 = { + .name = "same_name", /* hash with identical name */ + .entries = RTE_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = 4, + .socket_id = 0, + }; + + /* this is a sanity check for "same name" test + * creating this hash will check if we are actually able to create + * multiple hashes with different names (instead of having just one). + */ + struct rte_fbk_hash_params different_name = { + .name = "different_name", /* different name */ + .entries = LOCAL_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = 4, + .socket_id = 0, + }; + + struct rte_fbk_hash_params params_jhash = { + .name = "valid", + .entries = LOCAL_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = 4, + .socket_id = 0, + .hash_func = rte_jhash_1word, /* Tests for different hash_func */ + .init_val = RTE_FBK_HASH_INIT_VAL_DEFAULT, + }; + + struct rte_fbk_hash_params params_nohash = { + .name = "valid nohash", + .entries = LOCAL_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = 4, + .socket_id = 0, + .hash_func = NULL, /* Tests for null hash_func */ + .init_val = RTE_FBK_HASH_INIT_VAL_DEFAULT, + }; + + struct rte_fbk_hash_table *handle, *tmp; + uint32_t keys[5] = + {0xc6e18639, 0xe67c201c, 0xd4c8cffd, 0x44728691, 0xd5430fa9}; + uint16_t vals[5] = {28108, 5699, 38490, 2166, 61571}; + int status; + unsigned i; + double used_entries; + + /* Try creating hashes with invalid parameters */ + printf("# Testing hash creation with invalid parameters " + "- expect error msgs\n"); + handle = rte_fbk_hash_create(&invalid_params_1); + RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + + handle = rte_fbk_hash_create(&invalid_params_2); + RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + + handle = rte_fbk_hash_create(&invalid_params_3); + RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + + handle = rte_fbk_hash_create(&invalid_params_4); + RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + + handle = rte_fbk_hash_create(&invalid_params_5); + RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + + handle = rte_fbk_hash_create(&invalid_params_6); + RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + + handle = rte_fbk_hash_create(&invalid_params_7); + RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + + handle = rte_fbk_hash_create(&invalid_params_8); + RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + + handle = rte_fbk_hash_create(&invalid_params_same_name_1); + RETURN_IF_ERROR_FBK(handle == NULL, "fbk hash creation should have succeeded"); + + tmp = rte_fbk_hash_create(&invalid_params_same_name_2); + if (tmp != NULL) + rte_fbk_hash_free(tmp); + RETURN_IF_ERROR_FBK(tmp != NULL, "fbk hash creation should have failed"); + + /* we are not freeing handle here because we need a hash list + * to be not empty for the next test */ + + /* create a hash in non-empty list - good for coverage */ + tmp = rte_fbk_hash_create(&different_name); + RETURN_IF_ERROR_FBK(tmp == NULL, "fbk hash creation should have succeeded"); + + /* free both hashes */ + rte_fbk_hash_free(handle); + rte_fbk_hash_free(tmp); + + /* Create empty jhash hash. */ + handle = rte_fbk_hash_create(¶ms_jhash); + RETURN_IF_ERROR_FBK(handle == NULL, "fbk jhash hash creation failed"); + + /* Cleanup. */ + rte_fbk_hash_free(handle); + + /* Create empty jhash hash. */ + handle = rte_fbk_hash_create(¶ms_nohash); + RETURN_IF_ERROR_FBK(handle == NULL, "fbk nohash hash creation failed"); + + /* Cleanup. */ + rte_fbk_hash_free(handle); + + /* Create empty hash. */ + handle = rte_fbk_hash_create(¶ms); + RETURN_IF_ERROR_FBK(handle == NULL, "fbk hash creation failed"); + + used_entries = rte_fbk_hash_get_load_factor(handle) * LOCAL_FBK_HASH_ENTRIES_MAX; + RETURN_IF_ERROR_FBK((unsigned)used_entries != 0, \ + "load factor right after creation is not zero but it should be"); + /* Add keys. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_add_key(handle, keys[i], vals[i]); + RETURN_IF_ERROR_FBK(status != 0, "fbk hash add failed"); + } + + used_entries = rte_fbk_hash_get_load_factor(handle) * LOCAL_FBK_HASH_ENTRIES_MAX; + RETURN_IF_ERROR_FBK((unsigned)used_entries != (unsigned)((((double)5)/LOCAL_FBK_HASH_ENTRIES_MAX)*LOCAL_FBK_HASH_ENTRIES_MAX), \ + "load factor now is not as expected"); + /* Find value of added keys. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_lookup(handle, keys[i]); + RETURN_IF_ERROR_FBK(status != vals[i], + "fbk hash lookup failed"); + } + + /* Change value of added keys. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_add_key(handle, keys[i], vals[4 - i]); + RETURN_IF_ERROR_FBK(status != 0, "fbk hash update failed"); + } + + /* Find new values. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_lookup(handle, keys[i]); + RETURN_IF_ERROR_FBK(status != vals[4-i], + "fbk hash lookup failed"); + } + + /* Delete keys individually. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_delete_key(handle, keys[i]); + RETURN_IF_ERROR_FBK(status != 0, "fbk hash delete failed"); + } + + used_entries = rte_fbk_hash_get_load_factor(handle) * LOCAL_FBK_HASH_ENTRIES_MAX; + RETURN_IF_ERROR_FBK((unsigned)used_entries != 0, \ + "load factor right after deletion is not zero but it should be"); + /* Lookup should now fail. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_lookup(handle, keys[i]); + RETURN_IF_ERROR_FBK(status == 0, + "fbk hash lookup should have failed"); + } + + /* Add keys again. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_add_key(handle, keys[i], vals[i]); + RETURN_IF_ERROR_FBK(status != 0, "fbk hash add failed"); + } + + /* Make sure they were added. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_lookup(handle, keys[i]); + RETURN_IF_ERROR_FBK(status != vals[i], + "fbk hash lookup failed"); + } + + /* Clear all entries. */ + rte_fbk_hash_clear_all(handle); + + /* Lookup should fail. */ + for (i = 0; i < 5; i++) { + status = rte_fbk_hash_lookup(handle, keys[i]); + RETURN_IF_ERROR_FBK(status == 0, + "fbk hash lookup should have failed"); + } + + /* coverage */ + + /* fill up the hash_table */ + for (i = 0; i < RTE_FBK_HASH_ENTRIES_MAX + 1; i++) + rte_fbk_hash_add_key(handle, i, (uint16_t) i); + + /* Find non-existent key in a full hashtable */ + status = rte_fbk_hash_lookup(handle, RTE_FBK_HASH_ENTRIES_MAX + 1); + RETURN_IF_ERROR_FBK(status != -ENOENT, + "fbk hash lookup succeeded"); + + /* Delete non-existent key in a full hashtable */ + status = rte_fbk_hash_delete_key(handle, RTE_FBK_HASH_ENTRIES_MAX + 1); + RETURN_IF_ERROR_FBK(status != -ENOENT, + "fbk hash delete succeeded"); + + /* Delete one key from a full hashtable */ + status = rte_fbk_hash_delete_key(handle, 1); + RETURN_IF_ERROR_FBK(status != 0, + "fbk hash delete failed"); + + /* Clear all entries. */ + rte_fbk_hash_clear_all(handle); + + /* Cleanup. */ + rte_fbk_hash_free(handle); + + /* Cover the NULL case. */ + rte_fbk_hash_free(0); + + return 0; +} + +/* + * Sequence of operations for find existing fbk hash table + * + * - create table + * - find existing table: hit + * - find non-existing table: miss + * + */ +static int test_fbk_hash_find_existing(void) +{ + struct rte_fbk_hash_params params = { + .name = "fbk_hash_find_existing", + .entries = LOCAL_FBK_HASH_ENTRIES_MAX, + .entries_per_bucket = 4, + .socket_id = 0, + }; + struct rte_fbk_hash_table *handle = NULL, *result = NULL; + + /* Create hash table. */ + handle = rte_fbk_hash_create(¶ms); + RETURN_IF_ERROR_FBK(handle == NULL, "fbk hash creation failed"); + + /* Try to find existing fbk hash table */ + result = rte_fbk_hash_find_existing("fbk_hash_find_existing"); + RETURN_IF_ERROR_FBK(result != handle, "could not find existing fbk hash table"); + + /* Try to find non-existing fbk hash table */ + result = rte_fbk_hash_find_existing("fbk_hash_find_non_existing"); + RETURN_IF_ERROR_FBK(!(result == NULL), "found fbk table that shouldn't exist"); + + /* Cleanup. */ + rte_fbk_hash_free(handle); + + return 0; +} + +#define BUCKET_ENTRIES 4 +/* + * Do tests for hash creation with bad parameters. + */ +static int test_hash_creation_with_bad_parameters(void) +{ + struct rte_hash *handle, *tmp; + struct rte_hash_parameters params; + + handle = rte_hash_create(NULL); + if (handle != NULL) { + rte_hash_free(handle); + printf("Impossible creating hash sucessfully without any parameter\n"); + return -1; + } + + memcpy(¶ms, &ut_params, sizeof(params)); + params.name = "creation_with_bad_parameters_0"; + params.entries = RTE_HASH_ENTRIES_MAX + 1; + handle = rte_hash_create(¶ms); + if (handle != NULL) { + rte_hash_free(handle); + printf("Impossible creating hash sucessfully with entries in parameter exceeded\n"); + return -1; + } + + memcpy(¶ms, &ut_params, sizeof(params)); + params.name = "creation_with_bad_parameters_2"; + params.entries = BUCKET_ENTRIES - 1; + handle = rte_hash_create(¶ms); + if (handle != NULL) { + rte_hash_free(handle); + printf("Impossible creating hash sucessfully if entries less than bucket_entries in parameter\n"); + return -1; + } + + memcpy(¶ms, &ut_params, sizeof(params)); + params.name = "creation_with_bad_parameters_3"; + params.key_len = 0; + handle = rte_hash_create(¶ms); + if (handle != NULL) { + rte_hash_free(handle); + printf("Impossible creating hash sucessfully if key_len in parameter is zero\n"); + return -1; + } + + memcpy(¶ms, &ut_params, sizeof(params)); + params.name = "creation_with_bad_parameters_4"; + params.socket_id = RTE_MAX_NUMA_NODES + 1; + handle = rte_hash_create(¶ms); + if (handle != NULL) { + rte_hash_free(handle); + printf("Impossible creating hash sucessfully with invalid socket\n"); + return -1; + } + + /* test with same name should fail */ + memcpy(¶ms, &ut_params, sizeof(params)); + params.name = "same_name"; + handle = rte_hash_create(¶ms); + if (handle == NULL) { + printf("Cannot create first hash table with 'same_name'\n"); + return -1; + } + tmp = rte_hash_create(¶ms); + if (tmp != NULL) { + printf("Creation of hash table with same name should fail\n"); + rte_hash_free(handle); + rte_hash_free(tmp); + return -1; + } + rte_hash_free(handle); + + printf("# Test successful. No more errors expected\n"); + + return 0; +} + +/* + * Do tests for hash creation with parameters that look incorrect + * but are actually valid. + */ +static int +test_hash_creation_with_good_parameters(void) +{ + struct rte_hash *handle; + struct rte_hash_parameters params; + + /* create with null hash function - should choose DEFAULT_HASH_FUNC */ + memcpy(¶ms, &ut_params, sizeof(params)); + params.name = "name"; + params.hash_func = NULL; + handle = rte_hash_create(¶ms); + if (handle == NULL) { + printf("Creating hash with null hash_func failed\n"); + return -1; + } + + rte_hash_free(handle); + + return 0; +} + +#define ITERATIONS 3 +/* + * Test to see the average table utilization (entries added/max entries) + * before hitting a random entry that cannot be added + */ +static int test_average_table_utilization(void) +{ + struct rte_hash *handle; + uint8_t simple_key[MAX_KEYSIZE]; + unsigned i, j; + unsigned added_keys, average_keys_added = 0; + int ret; + + printf("\n# Running test to determine average utilization" + "\n before adding elements begins to fail\n"); + printf("Measuring performance, please wait"); + fflush(stdout); + ut_params.entries = 1 << 16; + ut_params.name = "test_average_utilization"; + ut_params.hash_func = rte_jhash; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + for (j = 0; j < ITERATIONS; j++) { + ret = 0; + /* Add random entries until key cannot be added */ + for (added_keys = 0; ret >= 0; added_keys++) { + for (i = 0; i < ut_params.key_len; i++) + simple_key[i] = rte_rand() % 255; + ret = rte_hash_add_key(handle, simple_key); + } + if (ret != -ENOSPC) { + printf("Unexpected error when adding keys\n"); + rte_hash_free(handle); + return -1; + } + + average_keys_added += added_keys; + + /* Reset the table */ + rte_hash_reset(handle); + + /* Print a dot to show progress on operations */ + printf("."); + fflush(stdout); + } + + average_keys_added /= ITERATIONS; + + printf("\nAverage table utilization = %.2f%% (%u/%u)\n", + ((double) average_keys_added / ut_params.entries * 100), + average_keys_added, ut_params.entries); + rte_hash_free(handle); + + return 0; +} + +#define NUM_ENTRIES 256 +static int test_hash_iteration(void) +{ + struct rte_hash *handle; + unsigned i; + uint8_t keys[NUM_ENTRIES][MAX_KEYSIZE]; + const void *next_key; + void *next_data; + void *data[NUM_ENTRIES]; + unsigned added_keys; + uint32_t iter = 0; + int ret = 0; + + ut_params.entries = NUM_ENTRIES; + ut_params.name = "test_hash_iteration"; + ut_params.hash_func = rte_jhash; + ut_params.key_len = 16; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + /* Add random entries until key cannot be added */ + for (added_keys = 0; added_keys < NUM_ENTRIES; added_keys++) { + data[added_keys] = (void *) ((uintptr_t) rte_rand()); + for (i = 0; i < ut_params.key_len; i++) + keys[added_keys][i] = rte_rand() % 255; + ret = rte_hash_add_key_data(handle, keys[added_keys], data[added_keys]); + if (ret < 0) + break; + } + + /* Iterate through the hash table */ + while (rte_hash_iterate(handle, &next_key, &next_data, &iter) >= 0) { + /* Search for the key in the list of keys added */ + for (i = 0; i < NUM_ENTRIES; i++) { + if (memcmp(next_key, keys[i], ut_params.key_len) == 0) { + if (next_data != data[i]) { + printf("Data found in the hash table is" + "not the data added with the key\n"); + goto err; + } + added_keys--; + break; + } + } + if (i == NUM_ENTRIES) { + printf("Key found in the hash table was not added\n"); + goto err; + } + } + + /* Check if all keys have been iterated */ + if (added_keys != 0) { + printf("There were still %u keys to iterate\n", added_keys); + goto err; + } + + rte_hash_free(handle); + return 0; + +err: + rte_hash_free(handle); + return -1; +} + +static uint8_t key[16] = {0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f}; +static struct rte_hash_parameters hash_params_ex = { + .name = NULL, + .entries = 64, + .key_len = 0, + .hash_func = NULL, + .hash_func_init_val = 0, + .socket_id = 0, +}; + +/* + * add/delete key with jhash2 + */ +static int +test_hash_add_delete_jhash2(void) +{ + int ret = -1; + struct rte_hash *handle; + int32_t pos1, pos2; + + hash_params_ex.name = "hash_test_jhash2"; + hash_params_ex.key_len = 4; + hash_params_ex.hash_func = (rte_hash_function)rte_jhash_32b; + + handle = rte_hash_create(&hash_params_ex); + if (handle == NULL) { + printf("test_hash_add_delete_jhash2 fail to create hash\n"); + goto fail_jhash2; + } + pos1 = rte_hash_add_key(handle, (void *)&key[0]); + if (pos1 < 0) { + printf("test_hash_add_delete_jhash2 fail to add hash key\n"); + goto fail_jhash2; + } + + pos2 = rte_hash_del_key(handle, (void *)&key[0]); + if (pos2 < 0 || pos1 != pos2) { + printf("test_hash_add_delete_jhash2 delete different key from being added\n"); + goto fail_jhash2; + } + ret = 0; + +fail_jhash2: + if (handle != NULL) + rte_hash_free(handle); + + return ret; +} + +/* + * add/delete (2) key with jhash2 + */ +static int +test_hash_add_delete_2_jhash2(void) +{ + int ret = -1; + struct rte_hash *handle; + int32_t pos1, pos2; + + hash_params_ex.name = "hash_test_2_jhash2"; + hash_params_ex.key_len = 8; + hash_params_ex.hash_func = (rte_hash_function)rte_jhash_32b; + + handle = rte_hash_create(&hash_params_ex); + if (handle == NULL) + goto fail_2_jhash2; + + pos1 = rte_hash_add_key(handle, (void *)&key[0]); + if (pos1 < 0) + goto fail_2_jhash2; + + pos2 = rte_hash_del_key(handle, (void *)&key[0]); + if (pos2 < 0 || pos1 != pos2) + goto fail_2_jhash2; + + ret = 0; + +fail_2_jhash2: + if (handle != NULL) + rte_hash_free(handle); + + return ret; +} + +static uint32_t +test_hash_jhash_1word(const void *key, uint32_t length, uint32_t initval) +{ + const uint32_t *k = key; + + RTE_SET_USED(length); + + return rte_jhash_1word(k[0], initval); +} + +static uint32_t +test_hash_jhash_2word(const void *key, uint32_t length, uint32_t initval) +{ + const uint32_t *k = key; + + RTE_SET_USED(length); + + return rte_jhash_2words(k[0], k[1], initval); +} + +static uint32_t +test_hash_jhash_3word(const void *key, uint32_t length, uint32_t initval) +{ + const uint32_t *k = key; + + RTE_SET_USED(length); + + return rte_jhash_3words(k[0], k[1], k[2], initval); +} + +/* + * add/delete key with jhash 1word + */ +static int +test_hash_add_delete_jhash_1word(void) +{ + int ret = -1; + struct rte_hash *handle; + int32_t pos1, pos2; + + hash_params_ex.name = "hash_test_jhash_1word"; + hash_params_ex.key_len = 4; + hash_params_ex.hash_func = test_hash_jhash_1word; + + handle = rte_hash_create(&hash_params_ex); + if (handle == NULL) + goto fail_jhash_1word; + + pos1 = rte_hash_add_key(handle, (void *)&key[0]); + if (pos1 < 0) + goto fail_jhash_1word; + + pos2 = rte_hash_del_key(handle, (void *)&key[0]); + if (pos2 < 0 || pos1 != pos2) + goto fail_jhash_1word; + + ret = 0; + +fail_jhash_1word: + if (handle != NULL) + rte_hash_free(handle); + + return ret; +} + +/* + * add/delete key with jhash 2word + */ +static int +test_hash_add_delete_jhash_2word(void) +{ + int ret = -1; + struct rte_hash *handle; + int32_t pos1, pos2; + + hash_params_ex.name = "hash_test_jhash_2word"; + hash_params_ex.key_len = 8; + hash_params_ex.hash_func = test_hash_jhash_2word; + + handle = rte_hash_create(&hash_params_ex); + if (handle == NULL) + goto fail_jhash_2word; + + pos1 = rte_hash_add_key(handle, (void *)&key[0]); + if (pos1 < 0) + goto fail_jhash_2word; + + pos2 = rte_hash_del_key(handle, (void *)&key[0]); + if (pos2 < 0 || pos1 != pos2) + goto fail_jhash_2word; + + ret = 0; + +fail_jhash_2word: + if (handle != NULL) + rte_hash_free(handle); + + return ret; +} + +/* + * add/delete key with jhash 3word + */ +static int +test_hash_add_delete_jhash_3word(void) +{ + int ret = -1; + struct rte_hash *handle; + int32_t pos1, pos2; + + hash_params_ex.name = "hash_test_jhash_3word"; + hash_params_ex.key_len = 12; + hash_params_ex.hash_func = test_hash_jhash_3word; + + handle = rte_hash_create(&hash_params_ex); + if (handle == NULL) + goto fail_jhash_3word; + + pos1 = rte_hash_add_key(handle, (void *)&key[0]); + if (pos1 < 0) + goto fail_jhash_3word; + + pos2 = rte_hash_del_key(handle, (void *)&key[0]); + if (pos2 < 0 || pos1 != pos2) + goto fail_jhash_3word; + + ret = 0; + +fail_jhash_3word: + if (handle != NULL) + rte_hash_free(handle); + + return ret; +} + +/* + * Do all unit and performance tests. + */ +static int +test_hash(void) +{ + if (test_add_delete() < 0) + return -1; + if (test_hash_add_delete_jhash2() < 0) + return -1; + if (test_hash_add_delete_2_jhash2() < 0) + return -1; + if (test_hash_add_delete_jhash_1word() < 0) + return -1; + if (test_hash_add_delete_jhash_2word() < 0) + return -1; + if (test_hash_add_delete_jhash_3word() < 0) + return -1; + if (test_hash_get_key_with_position() < 0) + return -1; + if (test_hash_find_existing() < 0) + return -1; + if (test_add_update_delete() < 0) + return -1; + if (test_five_keys() < 0) + return -1; + if (test_full_bucket() < 0) + return -1; + + if (test_fbk_hash_find_existing() < 0) + return -1; + if (fbk_hash_unit_test() < 0) + return -1; + if (test_hash_creation_with_bad_parameters() < 0) + return -1; + if (test_hash_creation_with_good_parameters() < 0) + return -1; + if (test_average_table_utilization() < 0) + return -1; + if (test_hash_iteration() < 0) + return -1; + + run_hash_func_tests(); + + if (test_crc32_hash_alg_equiv() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(hash_autotest, test_hash); diff --git a/test/test/test_hash_functions.c b/test/test/test_hash_functions.c new file mode 100644 index 0000000000..9652b04d45 --- /dev/null +++ b/test/test/test_hash_functions.c @@ -0,0 +1,322 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * Hash values calculated for key sizes from array "hashtest_key_lens" + * and for initial values from array "hashtest_initvals. + * Each key will be formed by increasing each byte by 1: + * e.g.: key size = 4, key = 0x03020100 + * key size = 8, key = 0x0706050403020100 + */ +static uint32_t hash_values_jhash[2][12] = {{ + 0x8ba9414b, 0xdf0d39c9, + 0xe4cf1d42, 0xd4ccb93c, 0x5e84eafc, 0x21362cfe, + 0x2f4775ab, 0x9ff036cc, 0xeca51474, 0xbc9d6816, + 0x12926a31, 0x1c9fa888 +}, +{ + 0x5c62c303, 0x1b8cf784, + 0x8270ac65, 0x05fa6668, 0x762df861, 0xda088f2f, + 0x59614cd4, 0x7a94f690, 0xdc1e4993, 0x30825494, + 0x91d0e462, 0x768087fc +} +}; +static uint32_t hash_values_crc[2][12] = {{ + 0x00000000, 0xf26b8303, + 0x91545164, 0x06040eb1, 0x9bb99201, 0xcc4c4fe4, + 0x14a90993, 0xf8a5dd8c, 0xcaa1ad0b, 0x7ac1e03e, + 0x43f44466, 0x4a11475e +}, +{ + 0xbdfd3980, 0x70204542, + 0x98cd4c70, 0xd52c702f, 0x41fc0e1c, 0x3905f65c, + 0x94bff47f, 0x1bab102d, 0xf4a2c645, 0xbf441539, + 0x789c104f, 0x53028d3e +} +}; + +/******************************************************************************* + * Hash function performance test configuration section. Each performance test + * will be performed HASHTEST_ITERATIONS times. + * + * The three arrays below control what tests are performed. Every combination + * from the array entries is tested. + */ +#define HASHTEST_ITERATIONS 1000000 +#define MAX_KEYSIZE 64 +static rte_hash_function hashtest_funcs[] = {rte_jhash, rte_hash_crc}; +static uint32_t hashtest_initvals[] = {0, 0xdeadbeef}; +static uint32_t hashtest_key_lens[] = { + 1, 2, /* Unusual key sizes */ + 4, 8, 16, 32, 48, 64, /* standard key sizes */ + 9, /* IPv4 SRC + DST + protocol, unpadded */ + 13, /* IPv4 5-tuple, unpadded */ + 37, /* IPv6 5-tuple, unpadded */ + 40 /* IPv6 5-tuple, padded to 8-byte boundary */ +}; +/******************************************************************************/ + +/* + * To help print out name of hash functions. + */ +static const char * +get_hash_name(rte_hash_function f) +{ + if (f == rte_jhash) + return "jhash"; + + if (f == rte_hash_crc) + return "rte_hash_crc"; + + return "UnknownHash"; +} + +/* + * Test a hash function. + */ +static void +run_hash_func_perf_test(uint32_t key_len, uint32_t init_val, + rte_hash_function f) +{ + static uint8_t key[HASHTEST_ITERATIONS][MAX_KEYSIZE]; + uint64_t ticks, start, end; + unsigned i, j; + + for (i = 0; i < HASHTEST_ITERATIONS; i++) { + for (j = 0; j < key_len; j++) + key[i][j] = (uint8_t) rte_rand(); + } + + start = rte_rdtsc(); + for (i = 0; i < HASHTEST_ITERATIONS; i++) + f(key[i], key_len, init_val); + end = rte_rdtsc(); + ticks = end - start; + + printf("%-12s, %-18u, %-13u, %.02f\n", get_hash_name(f), (unsigned) key_len, + (unsigned) init_val, (double)ticks / HASHTEST_ITERATIONS); +} + +/* + * Test all hash functions. + */ +static void +run_hash_func_perf_tests(void) +{ + unsigned i, j, k; + + printf(" *** Hash function performance test results ***\n"); + printf(" Number of iterations for each test = %d\n", + HASHTEST_ITERATIONS); + printf("Hash Func. , Key Length (bytes), Initial value, Ticks/Op.\n"); + + for (i = 0; i < RTE_DIM(hashtest_initvals); i++) { + for (j = 0; j < RTE_DIM(hashtest_key_lens); j++) { + for (k = 0; k < RTE_DIM(hashtest_funcs); k++) { + run_hash_func_perf_test(hashtest_key_lens[j], + hashtest_initvals[i], + hashtest_funcs[k]); + } + } + } +} + +/* + * Verify that hash functions return what they are expected to return + * (using precalculated values stored above) + */ +static int +verify_precalculated_hash_func_tests(void) +{ + unsigned i, j; + uint8_t key[64]; + uint32_t hash; + + for (i = 0; i < 64; i++) + key[i] = (uint8_t) i; + + for (i = 0; i < sizeof(hashtest_key_lens) / sizeof(uint32_t); i++) { + for (j = 0; j < sizeof(hashtest_initvals) / sizeof(uint32_t); j++) { + hash = rte_jhash(key, hashtest_key_lens[i], + hashtest_initvals[j]); + if (hash != hash_values_jhash[j][i]) { + printf("jhash for %u bytes with initial value 0x%x." + "Expected 0x%x, but got 0x%x\n", + hashtest_key_lens[i], hashtest_initvals[j], + hash_values_jhash[j][i], hash); + return -1; + } + + hash = rte_hash_crc(key, hashtest_key_lens[i], + hashtest_initvals[j]); + if (hash != hash_values_crc[j][i]) { + printf("CRC for %u bytes with initial value 0x%x." + "Expected 0x%x, but got 0x%x\n", + hashtest_key_lens[i], hashtest_initvals[j], + hash_values_crc[j][i], hash); + return -1; + } + } + } + + return 0; +} + +/* + * Verify that rte_jhash and rte_jhash_32b return the same + */ +static int +verify_jhash_32bits(void) +{ + unsigned i, j; + uint8_t key[64]; + uint32_t hash, hash32; + + for (i = 0; i < 64; i++) + key[i] = rand() & 0xff; + + for (i = 0; i < sizeof(hashtest_key_lens) / sizeof(uint32_t); i++) { + for (j = 0; j < sizeof(hashtest_initvals) / sizeof(uint32_t); j++) { + /* Key size must be multiple of 4 (32 bits) */ + if ((hashtest_key_lens[i] & 0x3) == 0) { + hash = rte_jhash(key, hashtest_key_lens[i], + hashtest_initvals[j]); + /* Divide key length by 4 in rte_jhash for 32 bits */ + hash32 = rte_jhash_32b((const unaligned_uint32_t *)key, + hashtest_key_lens[i] >> 2, + hashtest_initvals[j]); + if (hash != hash32) { + printf("rte_jhash returns different value (0x%x)" + "than rte_jhash_32b (0x%x)\n", + hash, hash32); + return -1; + } + } + } + } + + return 0; +} + +/* + * Verify that rte_jhash and rte_jhash_1word, rte_jhash_2words + * and rte_jhash_3words return the same + */ +static int +verify_jhash_words(void) +{ + unsigned i; + uint32_t key[3]; + uint32_t hash, hash_words; + + for (i = 0; i < 3; i++) + key[i] = rand(); + + /* Test rte_jhash_1word */ + hash = rte_jhash(key, 4, 0); + hash_words = rte_jhash_1word(key[0], 0); + if (hash != hash_words) { + printf("rte_jhash returns different value (0x%x)" + "than rte_jhash_1word (0x%x)\n", + hash, hash_words); + return -1; + } + /* Test rte_jhash_2words */ + hash = rte_jhash(key, 8, 0); + hash_words = rte_jhash_2words(key[0], key[1], 0); + if (hash != hash_words) { + printf("rte_jhash returns different value (0x%x)" + "than rte_jhash_2words (0x%x)\n", + hash, hash_words); + return -1; + } + /* Test rte_jhash_3words */ + hash = rte_jhash(key, 12, 0); + hash_words = rte_jhash_3words(key[0], key[1], key[2], 0); + if (hash != hash_words) { + printf("rte_jhash returns different value (0x%x)" + "than rte_jhash_3words (0x%x)\n", + hash, hash_words); + return -1; + } + + return 0; +} + +/* + * Run all functional tests for hash functions + */ +static int +run_hash_func_tests(void) +{ + if (verify_precalculated_hash_func_tests() != 0) + return -1; + + if (verify_jhash_32bits() != 0) + return -1; + + if (verify_jhash_words() != 0) + return -1; + + return 0; + +} + +static int +test_hash_functions(void) +{ + if (run_hash_func_tests() != 0) + return -1; + + run_hash_func_perf_tests(); + + return 0; +} + +REGISTER_TEST_COMMAND(hash_functions_autotest, test_hash_functions); diff --git a/test/test/test_hash_multiwriter.c b/test/test/test_hash_multiwriter.c new file mode 100644 index 0000000000..4dcbd9d56d --- /dev/null +++ b/test/test/test_hash_multiwriter.c @@ -0,0 +1,281 @@ +/*- + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#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) +{ + 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; + if (test_hash_multiwriter() < 0) + return -1; + } + + printf("Test multi-writer without Hardware transactional memory\n"); + use_htm = 0; + if (test_hash_multiwriter() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(hash_multiwriter_autotest, test_hash_multiwriter_main); diff --git a/test/test/test_hash_perf.c b/test/test/test_hash_perf.c new file mode 100644 index 0000000000..c0051b20fb --- /dev/null +++ b/test/test/test_hash_perf.c @@ -0,0 +1,659 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define MAX_ENTRIES (1 << 19) +#define KEYS_TO_ADD (MAX_ENTRIES * 3 / 4) /* 75% table utilization */ +#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ +#define BUCKET_SIZE 4 +#define NUM_BUCKETS (MAX_ENTRIES / BUCKET_SIZE) +#define MAX_KEYSIZE 64 +#define NUM_KEYSIZES 10 +#define NUM_SHUFFLES 10 +#define BURST_SIZE 16 + +enum operations { + ADD = 0, + LOOKUP, + LOOKUP_MULTI, + DELETE, + NUM_OPERATIONS +}; + +static uint32_t hashtest_key_lens[] = { + /* standard key sizes */ + 4, 8, 16, 32, 48, 64, + /* IPv4 SRC + DST + protocol, unpadded */ + 9, + /* IPv4 5-tuple, unpadded */ + 13, + /* IPv6 5-tuple, unpadded */ + 37, + /* IPv6 5-tuple, padded to 8-byte boundary */ + 40 +}; + +struct rte_hash *h[NUM_KEYSIZES]; + +/* Array that stores if a slot is full */ +uint8_t slot_taken[MAX_ENTRIES]; + +/* Array to store number of cycles per operation */ +uint64_t cycles[NUM_KEYSIZES][NUM_OPERATIONS][2][2]; + +/* Array to store all input keys */ +uint8_t keys[KEYS_TO_ADD][MAX_KEYSIZE]; + +/* Array to store the precomputed hash for 'keys' */ +hash_sig_t signatures[KEYS_TO_ADD]; + +/* Array to store how many busy entries have each bucket */ +uint8_t buckets[NUM_BUCKETS]; + +/* Array to store the positions where keys are added */ +int32_t positions[KEYS_TO_ADD]; + +/* Parameters used for hash table in unit test functions. */ +static struct rte_hash_parameters ut_params = { + .entries = MAX_ENTRIES, + .hash_func = rte_jhash, + .hash_func_init_val = 0, +}; + +static int +create_table(unsigned with_data, unsigned table_index) +{ + char name[RTE_HASH_NAMESIZE]; + + if (with_data) + /* Table will store 8-byte data */ + sprintf(name, "test_hash%d_data", hashtest_key_lens[table_index]); + else + sprintf(name, "test_hash%d", hashtest_key_lens[table_index]); + + ut_params.name = name; + ut_params.key_len = hashtest_key_lens[table_index]; + ut_params.socket_id = rte_socket_id(); + h[table_index] = rte_hash_find_existing(name); + if (h[table_index] != NULL) + /* + * If table was already created, free it to create it again, + * so we force it is empty + */ + rte_hash_free(h[table_index]); + h[table_index] = rte_hash_create(&ut_params); + if (h[table_index] == NULL) { + printf("Error creating table\n"); + return -1; + } + return 0; + +} + +/* Shuffle the keys that have been added, so lookups will be totally random */ +static void +shuffle_input_keys(unsigned table_index) +{ + unsigned i; + uint32_t swap_idx; + uint8_t temp_key[MAX_KEYSIZE]; + hash_sig_t temp_signature; + int32_t temp_position; + + for (i = KEYS_TO_ADD - 1; i > 0; i--) { + swap_idx = rte_rand() % i; + + memcpy(temp_key, keys[i], hashtest_key_lens[table_index]); + temp_signature = signatures[i]; + temp_position = positions[i]; + + memcpy(keys[i], keys[swap_idx], hashtest_key_lens[table_index]); + signatures[i] = signatures[swap_idx]; + positions[i] = positions[swap_idx]; + + memcpy(keys[swap_idx], temp_key, hashtest_key_lens[table_index]); + signatures[swap_idx] = temp_signature; + positions[swap_idx] = temp_position; + } +} + +/* + * Looks for random keys which + * ALL can fit in hash table (no errors) + */ +static int +get_input_keys(unsigned with_pushes, unsigned table_index) +{ + unsigned i, j; + unsigned bucket_idx, incr, success = 1; + uint8_t k = 0; + int32_t ret; + const uint32_t bucket_bitmask = NUM_BUCKETS - 1; + + /* Reset all arrays */ + for (i = 0; i < MAX_ENTRIES; i++) + slot_taken[i] = 0; + + for (i = 0; i < NUM_BUCKETS; i++) + buckets[i] = 0; + + for (j = 0; j < hashtest_key_lens[table_index]; j++) + keys[0][j] = 0; + + /* + * Add only entries that are not duplicated and that fits in the table + * (cannot store more than BUCKET_SIZE entries in a bucket). + * Regardless a key has been added correctly or not (success), + * the next one to try will be increased by 1. + */ + for (i = 0; i < KEYS_TO_ADD;) { + incr = 0; + if (i != 0) { + keys[i][0] = ++k; + /* Overflow, need to increment the next byte */ + if (keys[i][0] == 0) + incr = 1; + for (j = 1; j < hashtest_key_lens[table_index]; j++) { + /* Do not increase next byte */ + if (incr == 0) + if (success == 1) + keys[i][j] = keys[i - 1][j]; + else + keys[i][j] = keys[i][j]; + /* Increase next byte by one */ + else { + if (success == 1) + keys[i][j] = keys[i-1][j] + 1; + else + keys[i][j] = keys[i][j] + 1; + if (keys[i][j] == 0) + incr = 1; + else + incr = 0; + } + } + } + success = 0; + signatures[i] = rte_hash_hash(h[table_index], keys[i]); + bucket_idx = signatures[i] & bucket_bitmask; + /* + * If we are not inserting keys in secondary location, + * when bucket is full, do not try to insert the key + */ + if (with_pushes == 0) + if (buckets[bucket_idx] == BUCKET_SIZE) + continue; + + /* If key can be added, leave in successful key arrays "keys" */ + ret = rte_hash_add_key_with_hash(h[table_index], keys[i], + signatures[i]); + if (ret >= 0) { + /* If key is already added, ignore the entry and do not store */ + if (slot_taken[ret]) + continue; + else { + /* Store the returned position and mark slot as taken */ + slot_taken[ret] = 1; + positions[i] = ret; + buckets[bucket_idx]++; + success = 1; + i++; + } + } + } + + /* Reset the table, so we can measure the time to add all the entries */ + rte_hash_free(h[table_index]); + h[table_index] = rte_hash_create(&ut_params); + + return 0; +} + +static int +timed_adds(unsigned with_hash, unsigned with_data, unsigned table_index) +{ + unsigned i; + const uint64_t start_tsc = rte_rdtsc(); + void *data; + int32_t ret; + + for (i = 0; i < KEYS_TO_ADD; i++) { + data = (void *) ((uintptr_t) signatures[i]); + if (with_hash && with_data) { + ret = rte_hash_add_key_with_hash_data(h[table_index], + (const void *) keys[i], + signatures[i], data); + if (ret < 0) { + printf("Failed to add key number %u\n", ret); + return -1; + } + } else if (with_hash && !with_data) { + ret = rte_hash_add_key_with_hash(h[table_index], + (const void *) keys[i], + signatures[i]); + if (ret >= 0) + positions[i] = ret; + else { + printf("Failed to add key number %u\n", ret); + return -1; + } + } else if (!with_hash && with_data) { + ret = rte_hash_add_key_data(h[table_index], + (const void *) keys[i], + data); + if (ret < 0) { + printf("Failed to add key number %u\n", ret); + return -1; + } + } else { + ret = rte_hash_add_key(h[table_index], keys[i]); + if (ret >= 0) + positions[i] = ret; + else { + printf("Failed to add key number %u\n", ret); + return -1; + } + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[table_index][ADD][with_hash][with_data] = time_taken/KEYS_TO_ADD; + + return 0; +} + +static int +timed_lookups(unsigned with_hash, unsigned with_data, unsigned table_index) +{ + unsigned i, j; + const uint64_t start_tsc = rte_rdtsc(); + void *ret_data; + void *expected_data; + int32_t ret; + + for (i = 0; i < NUM_LOOKUPS/KEYS_TO_ADD; i++) { + for (j = 0; j < KEYS_TO_ADD; j++) { + if (with_hash && with_data) { + ret = rte_hash_lookup_with_hash_data(h[table_index], + (const void *) keys[j], + signatures[j], &ret_data); + if (ret < 0) { + printf("Key number %u was not found\n", j); + return -1; + } + expected_data = (void *) ((uintptr_t) signatures[j]); + if (ret_data != expected_data) { + printf("Data returned for key number %u is %p," + " but should be %p\n", j, ret_data, + expected_data); + return -1; + } + } else if (with_hash && !with_data) { + ret = rte_hash_lookup_with_hash(h[table_index], + (const void *) keys[j], + signatures[j]); + if (ret < 0 || ret != positions[j]) { + printf("Key looked up in %d, should be in %d\n", + ret, positions[j]); + return -1; + } + } else if (!with_hash && with_data) { + ret = rte_hash_lookup_data(h[table_index], + (const void *) keys[j], &ret_data); + if (ret < 0) { + printf("Key number %u was not found\n", j); + return -1; + } + expected_data = (void *) ((uintptr_t) signatures[j]); + if (ret_data != expected_data) { + printf("Data returned for key number %u is %p," + " but should be %p\n", j, ret_data, + expected_data); + return -1; + } + } else { + ret = rte_hash_lookup(h[table_index], keys[j]); + if (ret < 0 || ret != positions[j]) { + printf("Key looked up in %d, should be in %d\n", + ret, positions[j]); + return -1; + } + } + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[table_index][LOOKUP][with_hash][with_data] = time_taken/NUM_LOOKUPS; + + return 0; +} + +static int +timed_lookups_multi(unsigned with_data, unsigned table_index) +{ + unsigned i, j, k; + int32_t positions_burst[BURST_SIZE]; + const void *keys_burst[BURST_SIZE]; + void *expected_data[BURST_SIZE]; + void *ret_data[BURST_SIZE]; + uint64_t hit_mask; + int ret; + + const uint64_t start_tsc = rte_rdtsc(); + + for (i = 0; i < NUM_LOOKUPS/KEYS_TO_ADD; i++) { + for (j = 0; j < KEYS_TO_ADD/BURST_SIZE; j++) { + for (k = 0; k < BURST_SIZE; k++) + keys_burst[k] = keys[j * BURST_SIZE + k]; + if (with_data) { + ret = rte_hash_lookup_bulk_data(h[table_index], + (const void **) keys_burst, + BURST_SIZE, + &hit_mask, + ret_data); + if (ret != BURST_SIZE) { + printf("Expect to find %u keys," + " but found %d\n", BURST_SIZE, ret); + return -1; + } + for (k = 0; k < BURST_SIZE; k++) { + if ((hit_mask & (1ULL << k)) == 0) { + printf("Key number %u not found\n", + j * BURST_SIZE + k); + return -1; + } + expected_data[k] = (void *) ((uintptr_t) signatures[j * BURST_SIZE + k]); + if (ret_data[k] != expected_data[k]) { + printf("Data returned for key number %u is %p," + " but should be %p\n", j * BURST_SIZE + k, + ret_data[k], expected_data[k]); + return -1; + } + } + } else { + rte_hash_lookup_bulk(h[table_index], + (const void **) keys_burst, + BURST_SIZE, + positions_burst); + for (k = 0; k < BURST_SIZE; k++) { + if (positions_burst[k] != positions[j * BURST_SIZE + k]) { + printf("Key looked up in %d, should be in %d\n", + positions_burst[k], + positions[j * BURST_SIZE + k]); + return -1; + } + } + } + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[table_index][LOOKUP_MULTI][0][with_data] = time_taken/NUM_LOOKUPS; + + return 0; +} + +static int +timed_deletes(unsigned with_hash, unsigned with_data, unsigned table_index) +{ + unsigned i; + const uint64_t start_tsc = rte_rdtsc(); + int32_t ret; + + for (i = 0; i < KEYS_TO_ADD; i++) { + /* There are no delete functions with data, so just call two functions */ + if (with_hash) + ret = rte_hash_del_key_with_hash(h[table_index], + (const void *) keys[i], + signatures[i]); + else + ret = rte_hash_del_key(h[table_index], + (const void *) keys[i]); + if (ret >= 0) + positions[i] = ret; + else { + printf("Failed to add key number %u\n", ret); + return -1; + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[table_index][DELETE][with_hash][with_data] = time_taken/KEYS_TO_ADD; + + return 0; +} + +static void +free_table(unsigned table_index) +{ + rte_hash_free(h[table_index]); +} + +static void +reset_table(unsigned table_index) +{ + rte_hash_reset(h[table_index]); +} + +static int +run_all_tbl_perf_tests(unsigned with_pushes) +{ + unsigned i, j, with_data, with_hash; + + printf("Measuring performance, please wait"); + fflush(stdout); + + for (with_data = 0; with_data <= 1; with_data++) { + for (i = 0; i < NUM_KEYSIZES; i++) { + if (create_table(with_data, i) < 0) + return -1; + + if (get_input_keys(with_pushes, i) < 0) + return -1; + for (with_hash = 0; with_hash <= 1; with_hash++) { + if (timed_adds(with_hash, with_data, i) < 0) + return -1; + + for (j = 0; j < NUM_SHUFFLES; j++) + shuffle_input_keys(i); + + if (timed_lookups(with_hash, with_data, i) < 0) + return -1; + + if (timed_lookups_multi(with_data, i) < 0) + return -1; + + if (timed_deletes(with_hash, with_data, i) < 0) + return -1; + + /* Print a dot to show progress on operations */ + printf("."); + fflush(stdout); + + reset_table(i); + } + free_table(i); + } + } + + printf("\nResults (in CPU cycles/operation)\n"); + printf("-----------------------------------\n"); + for (with_data = 0; with_data <= 1; with_data++) { + if (with_data) + printf("\n Operations with 8-byte data\n"); + else + printf("\n Operations without data\n"); + for (with_hash = 0; with_hash <= 1; with_hash++) { + if (with_hash) + printf("\nWith pre-computed hash values\n"); + else + printf("\nWithout pre-computed hash values\n"); + + printf("\n%-18s%-18s%-18s%-18s%-18s\n", + "Keysize", "Add", "Lookup", "Lookup_bulk", "Delete"); + for (i = 0; i < NUM_KEYSIZES; i++) { + printf("%-18d", hashtest_key_lens[i]); + for (j = 0; j < NUM_OPERATIONS; j++) + printf("%-18"PRIu64, cycles[i][j][with_hash][with_data]); + printf("\n"); + } + } + } + return 0; +} + +/* Control operation of performance testing of fbk hash. */ +#define LOAD_FACTOR 0.667 /* How full to make the hash table. */ +#define TEST_SIZE 1000000 /* How many operations to time. */ +#define TEST_ITERATIONS 30 /* How many measurements to take. */ +#define ENTRIES (1 << 15) /* How many entries. */ + +static int +fbk_hash_perf_test(void) +{ + struct rte_fbk_hash_params params = { + .name = "fbk_hash_test", + .entries = ENTRIES, + .entries_per_bucket = 4, + .socket_id = rte_socket_id(), + }; + struct rte_fbk_hash_table *handle = NULL; + uint32_t *keys = NULL; + unsigned indexes[TEST_SIZE]; + uint64_t lookup_time = 0; + unsigned added = 0; + unsigned value = 0; + uint32_t key; + uint16_t val; + unsigned i, j; + + handle = rte_fbk_hash_create(¶ms); + if (handle == NULL) { + printf("Error creating table\n"); + return -1; + } + + keys = rte_zmalloc(NULL, ENTRIES * sizeof(*keys), 0); + if (keys == NULL) { + printf("fbk hash: memory allocation for key store failed\n"); + return -1; + } + + /* Generate random keys and values. */ + for (i = 0; i < ENTRIES; i++) { + key = (uint32_t)rte_rand(); + key = ((uint64_t)key << 32) | (uint64_t)rte_rand(); + val = (uint16_t)rte_rand(); + + if (rte_fbk_hash_add_key(handle, key, val) == 0) { + keys[added] = key; + added++; + } + if (added > (LOAD_FACTOR * ENTRIES)) + break; + } + + for (i = 0; i < TEST_ITERATIONS; i++) { + uint64_t begin; + uint64_t end; + + /* Generate random indexes into keys[] array. */ + for (j = 0; j < TEST_SIZE; j++) + indexes[j] = rte_rand() % added; + + begin = rte_rdtsc(); + /* Do lookups */ + for (j = 0; j < TEST_SIZE; j++) + value += rte_fbk_hash_lookup(handle, keys[indexes[j]]); + + end = rte_rdtsc(); + lookup_time += (double)(end - begin); + } + + printf("\n\n *** FBK Hash function performance test results ***\n"); + /* + * The use of the 'value' variable ensures that the hash lookup is not + * being optimised out by the compiler. + */ + if (value != 0) + printf("Number of ticks per lookup = %g\n", + (double)lookup_time / + ((double)TEST_ITERATIONS * (double)TEST_SIZE)); + + rte_fbk_hash_free(handle); + + return 0; +} + +static int +test_hash_perf(void) +{ + unsigned with_pushes; + + for (with_pushes = 0; with_pushes <= 1; with_pushes++) { + if (with_pushes == 0) + printf("\nALL ELEMENTS IN PRIMARY LOCATION\n"); + else + printf("\nELEMENTS IN PRIMARY OR SECONDARY LOCATION\n"); + if (run_all_tbl_perf_tests(with_pushes) < 0) + return -1; + } + if (fbk_hash_perf_test() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(hash_perf_autotest, test_hash_perf); diff --git a/test/test/test_hash_scaling.c b/test/test/test_hash_scaling.c new file mode 100644 index 0000000000..46c48e549b --- /dev/null +++ b/test/test/test_hash_scaling.c @@ -0,0 +1,220 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 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 + +#include +#include +#include +#include +#include + +#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) + +enum locking_mode_t { + NORMAL_LOCK, + LOCK_ELISION, + NULL_LOCK +}; + +struct { + uint32_t num_iterations; + struct rte_hash *h; + rte_spinlock_t *lock; + int locking_mode; +} tbl_scaling_test_params; + +static rte_atomic64_t gcycles; + +static int test_hash_scaling_worker(__attribute__((unused)) void *arg) +{ + uint64_t i, key; + uint32_t thr_id = rte_sys_gettid(); + uint64_t begin, cycles = 0; + + switch (tbl_scaling_test_params.locking_mode) { + + case NORMAL_LOCK: + + for (i = 0; i < tbl_scaling_test_params.num_iterations; i++) { + /* different threads get different keys because + we use the thread-id in the key computation + */ + key = rte_hash_crc(&i, sizeof(i), thr_id); + begin = rte_rdtsc_precise(); + rte_spinlock_lock(tbl_scaling_test_params.lock); + rte_hash_add_key(tbl_scaling_test_params.h, &key); + rte_spinlock_unlock(tbl_scaling_test_params.lock); + cycles += rte_rdtsc_precise() - begin; + } + break; + + case LOCK_ELISION: + + for (i = 0; i < tbl_scaling_test_params.num_iterations; i++) { + key = rte_hash_crc(&i, sizeof(i), thr_id); + begin = rte_rdtsc_precise(); + rte_spinlock_lock_tm(tbl_scaling_test_params.lock); + rte_hash_add_key(tbl_scaling_test_params.h, &key); + rte_spinlock_unlock_tm(tbl_scaling_test_params.lock); + cycles += rte_rdtsc_precise() - begin; + } + break; + + default: + + for (i = 0; i < tbl_scaling_test_params.num_iterations; i++) { + key = rte_hash_crc(&i, sizeof(i), thr_id); + begin = rte_rdtsc_precise(); + rte_hash_add_key(tbl_scaling_test_params.h, &key); + cycles += rte_rdtsc_precise() - begin; + } + } + + rte_atomic64_add(&gcycles, cycles); + + return 0; +} + +/* + * Do scalability perf tests. + */ +static int +test_hash_scaling(int locking_mode) +{ + static unsigned calledCount = 1; + uint32_t num_iterations = 1024*1024; + uint64_t i, key; + struct rte_hash_parameters hash_params = { + .entries = num_iterations*2, + .key_len = sizeof(key), + .hash_func = rte_hash_crc, + .hash_func_init_val = 0, + .socket_id = rte_socket_id(), + .extra_flag = RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT + }; + struct rte_hash *handle; + char name[RTE_HASH_NAMESIZE]; + rte_spinlock_t lock; + + rte_spinlock_init(&lock); + + 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_scaling_test_params.num_iterations = + num_iterations/rte_lcore_count(); + tbl_scaling_test_params.h = handle; + tbl_scaling_test_params.lock = &lock; + tbl_scaling_test_params.locking_mode = locking_mode; + + rte_atomic64_init(&gcycles); + rte_atomic64_clear(&gcycles); + + /* fill up to initial size */ + for (i = 0; i < num_iterations; i++) { + key = rte_hash_crc(&i, sizeof(i), 0xabcdabcd); + rte_hash_add_key(tbl_scaling_test_params.h, &key); + } + + rte_eal_mp_remote_launch(test_hash_scaling_worker, NULL, CALL_MASTER); + rte_eal_mp_wait_lcore(); + + unsigned long long int cycles_per_operation = + rte_atomic64_read(&gcycles)/ + (tbl_scaling_test_params.num_iterations*rte_lcore_count()); + const char *lock_name; + + switch (locking_mode) { + case NORMAL_LOCK: + lock_name = "normal spinlock"; + break; + case LOCK_ELISION: + lock_name = "lock elision"; + break; + default: + lock_name = "null lock"; + } + printf("--------------------------------------------------------\n"); + printf("Cores: %d; %s mode -> cycles per operation: %llu\n", + rte_lcore_count(), lock_name, cycles_per_operation); + printf("--------------------------------------------------------\n"); + /* CSV output */ + printf(">>>%d,%s,%llu\n", rte_lcore_count(), lock_name, + cycles_per_operation); + + rte_hash_free(handle); + return 0; +} + +static int +test_hash_scaling_main(void) +{ + int r = 0; + + if (rte_lcore_count() == 1) + r = test_hash_scaling(NULL_LOCK); + + if (r == 0) + r = test_hash_scaling(NORMAL_LOCK); + + if (!rte_tm_supported()) { + printf("Hardware transactional memory (lock elision) is NOT supported\n"); + return r; + } + printf("Hardware transactional memory (lock elision) is supported\n"); + + if (r == 0) + r = test_hash_scaling(LOCK_ELISION); + + return r; +} + +REGISTER_TEST_COMMAND(hash_scaling_autotest, test_hash_scaling_main); diff --git a/test/test/test_interrupts.c b/test/test/test_interrupts.c new file mode 100644 index 0000000000..371101f088 --- /dev/null +++ b/test/test/test_interrupts.c @@ -0,0 +1,551 @@ +/*- + * 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 +#include +#include + +#include +#include +#include + +#include "test.h" + +#define TEST_INTERRUPT_CHECK_INTERVAL 100 /* ms */ + +/* predefined interrupt handle types */ +enum test_interrupt_handle_type { + TEST_INTERRUPT_HANDLE_INVALID, + TEST_INTERRUPT_HANDLE_VALID, + TEST_INTERRUPT_HANDLE_VALID_UIO, + TEST_INTERRUPT_HANDLE_VALID_ALARM, + TEST_INTERRUPT_HANDLE_CASE1, + TEST_INTERRUPT_HANDLE_MAX +}; + +/* flag of if callback is called */ +static volatile int flag; +static struct rte_intr_handle intr_handles[TEST_INTERRUPT_HANDLE_MAX]; +static enum test_interrupt_handle_type test_intr_type = + TEST_INTERRUPT_HANDLE_MAX; + +#ifdef RTE_EXEC_ENV_LINUXAPP +union intr_pipefds{ + struct { + int pipefd[2]; + }; + struct { + int readfd; + int writefd; + }; +}; + +static union intr_pipefds pfds; + +/** + * Check if the interrupt handle is valid. + */ +static inline int +test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle) +{ + if (!intr_handle || intr_handle->fd < 0) + return -1; + + return 0; +} + +/** + * Initialization for interrupt test. + */ +static int +test_interrupt_init(void) +{ + if (pipe(pfds.pipefd) < 0) + return -1; + + intr_handles[TEST_INTERRUPT_HANDLE_INVALID].fd = -1; + intr_handles[TEST_INTERRUPT_HANDLE_INVALID].type = + RTE_INTR_HANDLE_UNKNOWN; + + intr_handles[TEST_INTERRUPT_HANDLE_VALID].fd = pfds.readfd; + intr_handles[TEST_INTERRUPT_HANDLE_VALID].type = + RTE_INTR_HANDLE_UNKNOWN; + + intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO].fd = pfds.readfd; + intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO].type = + RTE_INTR_HANDLE_UIO; + + intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM].fd = pfds.readfd; + intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM].type = + RTE_INTR_HANDLE_ALARM; + + intr_handles[TEST_INTERRUPT_HANDLE_CASE1].fd = pfds.writefd; + intr_handles[TEST_INTERRUPT_HANDLE_CASE1].type = RTE_INTR_HANDLE_UIO; + + return 0; +} + +/** + * Deinitialization for interrupt test. + */ +static int +test_interrupt_deinit(void) +{ + close(pfds.pipefd[0]); + close(pfds.pipefd[1]); + + return 0; +} + +/** + * Write the pipe to simulate an interrupt. + */ +static int +test_interrupt_trigger_interrupt(void) +{ + if (write(pfds.writefd, "1", 1) < 0) + return -1; + + return 0; +} + +/** + * Check if two interrupt handles are the same. + */ +static int +test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l, + struct rte_intr_handle *intr_handle_r) +{ + if (!intr_handle_l || !intr_handle_r) + return -1; + + if (intr_handle_l->fd != intr_handle_r->fd || + intr_handle_l->type != intr_handle_r->type) + return -1; + + return 0; +} + +#else +/* to be implemented for bsd later */ +static inline int +test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle) +{ + RTE_SET_USED(intr_handle); + + return 0; +} + +static int +test_interrupt_init(void) +{ + return 0; +} + +static int +test_interrupt_deinit(void) +{ + return 0; +} + +static int +test_interrupt_trigger_interrupt(void) +{ + return 0; +} + +static int +test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l, + struct rte_intr_handle *intr_handle_r) +{ + (void)intr_handle_l; + (void)intr_handle_r; + + return 0; +} +#endif /* RTE_EXEC_ENV_LINUXAPP */ + +/** + * Callback for the test interrupt. + */ +static void +test_interrupt_callback(struct rte_intr_handle *intr_handle, void *arg) +{ + if (test_intr_type >= TEST_INTERRUPT_HANDLE_MAX) { + printf("invalid interrupt type\n"); + flag = -1; + return; + } + + if (test_interrupt_handle_sanity_check(intr_handle) < 0) { + printf("null or invalid intr_handle for %s\n", __func__); + flag = -1; + return; + } + + if (rte_intr_callback_unregister(intr_handle, + test_interrupt_callback, arg) >= 0) { + printf("%s: unexpectedly able to unregister itself\n", + __func__); + flag = -1; + return; + } + + if (test_interrupt_handle_compare(intr_handle, + &(intr_handles[test_intr_type])) == 0) + flag = 1; +} + +/** + * Callback for the test interrupt. + */ +static void +test_interrupt_callback_1(struct rte_intr_handle *intr_handle, + __attribute__((unused)) void *arg) +{ + if (test_interrupt_handle_sanity_check(intr_handle) < 0) { + printf("null or invalid intr_handle for %s\n", __func__); + flag = -1; + return; + } +} + +/** + * Tests for rte_intr_enable(). + */ +static int +test_interrupt_enable(void) +{ + struct rte_intr_handle test_intr_handle; + + /* check with null intr_handle */ + if (rte_intr_enable(NULL) == 0) { + printf("unexpectedly enable null intr_handle successfully\n"); + return -1; + } + + /* check with invalid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID]; + if (rte_intr_enable(&test_intr_handle) == 0) { + printf("unexpectedly enable invalid intr_handle " + "successfully\n"); + return -1; + } + + /* check with valid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; + if (rte_intr_enable(&test_intr_handle) == 0) { + printf("unexpectedly enable a specific intr_handle " + "successfully\n"); + return -1; + } + + /* check with specific valid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM]; + if (rte_intr_enable(&test_intr_handle) == 0) { + printf("unexpectedly enable a specific intr_handle " + "successfully\n"); + return -1; + } + + /* check with valid handler and its type */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1]; + if (rte_intr_enable(&test_intr_handle) < 0) { + printf("fail to enable interrupt on a simulated handler\n"); + return -1; + } + + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO]; + if (rte_intr_enable(&test_intr_handle) == 0) { + printf("unexpectedly enable a specific intr_handle " + "successfully\n"); + return -1; + } + + return 0; +} + +/** + * Tests for rte_intr_disable(). + */ +static int +test_interrupt_disable(void) +{ + struct rte_intr_handle test_intr_handle; + + /* check with null intr_handle */ + if (rte_intr_disable(NULL) == 0) { + printf("unexpectedly disable null intr_handle " + "successfully\n"); + return -1; + } + + /* check with invalid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID]; + if (rte_intr_disable(&test_intr_handle) == 0) { + printf("unexpectedly disable invalid intr_handle " + "successfully\n"); + return -1; + } + + /* check with valid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; + if (rte_intr_disable(&test_intr_handle) == 0) { + printf("unexpectedly disable a specific intr_handle " + "successfully\n"); + return -1; + } + + /* check with specific valid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM]; + if (rte_intr_disable(&test_intr_handle) == 0) { + printf("unexpectedly disable a specific intr_handle " + "successfully\n"); + return -1; + } + + /* check with valid handler and its type */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1]; + if (rte_intr_disable(&test_intr_handle) < 0) { + printf("fail to disable interrupt on a simulated handler\n"); + return -1; + } + + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO]; + if (rte_intr_disable(&test_intr_handle) == 0) { + printf("unexpectedly disable a specific intr_handle " + "successfully\n"); + return -1; + } + + return 0; +} + +/** + * Check the full path of a specified type of interrupt simulated. + */ +static int +test_interrupt_full_path_check(enum test_interrupt_handle_type intr_type) +{ + int count; + struct rte_intr_handle test_intr_handle; + + flag = 0; + test_intr_handle = intr_handles[intr_type]; + test_intr_type = intr_type; + if (rte_intr_callback_register(&test_intr_handle, + test_interrupt_callback, NULL) < 0) { + printf("fail to register callback\n"); + return -1; + } + + if (test_interrupt_trigger_interrupt() < 0) + return -1; + + /* check flag */ + for (count = 0; flag == 0 && count < 3; count++) + rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); + + rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); + if (rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback, NULL) < 0) + return -1; + + if (flag == 0) { + printf("callback has not been called\n"); + return -1; + } else if (flag < 0) { + printf("it has internal error in callback\n"); + return -1; + } + + return 0; +} + +/** + * Main function of testing interrupt. + */ +static int +test_interrupt(void) +{ + int ret = -1; + struct rte_intr_handle test_intr_handle; + + if (test_interrupt_init() < 0) { + printf("fail to initialize for testing interrupt\n"); + return -1; + } + + printf("Check unknown valid interrupt full path\n"); + if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID) < 0) { + printf("failure occured during checking unknown valid " + "interrupt full path\n"); + goto out; + } + + printf("Check valid UIO interrupt full path\n"); + if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID_UIO) + < 0) { + printf("failure occured during checking valid UIO interrupt " + "full path\n"); + goto out; + } + + printf("Check valid alarm interrupt full path\n"); + if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID_ALARM) + < 0) { + printf("failure occured during checking valid alarm " + "interrupt full path\n"); + goto out; + } + + printf("start register/unregister test\n"); + /* check if it will fail to register cb with intr_handle = NULL */ + if (rte_intr_callback_register(NULL, test_interrupt_callback, + NULL) == 0) { + printf("unexpectedly register successfully with null " + "intr_handle\n"); + goto out; + } + + /* check if it will fail to register cb with invalid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID]; + if (rte_intr_callback_register(&test_intr_handle, + test_interrupt_callback, NULL) == 0) { + printf("unexpectedly register successfully with invalid " + "intr_handle\n"); + goto out; + } + + /* check if it will fail to register without callback */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; + if (rte_intr_callback_register(&test_intr_handle, NULL, NULL) == 0) { + printf("unexpectedly register successfully with " + "null callback\n"); + goto out; + } + + /* check if it will fail to unregister cb with intr_handle = NULL */ + if (rte_intr_callback_unregister(NULL, + test_interrupt_callback, NULL) > 0) { + printf("unexpectedly unregister successfully with " + "null intr_handle\n"); + goto out; + } + + /* check if it will fail to unregister cb with invalid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID]; + if (rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback, NULL) > 0) { + printf("unexpectedly unregister successfully with " + "invalid intr_handle\n"); + goto out; + } + + /* check if it is ok to register the same intr_handle twice */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; + if (rte_intr_callback_register(&test_intr_handle, + test_interrupt_callback, NULL) < 0) { + printf("it fails to register test_interrupt_callback\n"); + goto out; + } + if (rte_intr_callback_register(&test_intr_handle, + test_interrupt_callback_1, NULL) < 0) { + printf("it fails to register test_interrupt_callback_1\n"); + goto out; + } + /* check if it will fail to unregister with invalid parameter */ + if (rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback, (void *)0xff) != 0) { + printf("unexpectedly unregisters successfully with " + "invalid arg\n"); + goto out; + } + if (rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback, NULL) <= 0) { + printf("it fails to unregister test_interrupt_callback\n"); + goto out; + } + if (rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback_1, (void *)-1) <= 0) { + printf("it fails to unregister test_interrupt_callback_1 " + "for all\n"); + goto out; + } + rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); + + printf("start interrupt enable/disable test\n"); + /* check interrupt enable/disable functions */ + if (test_interrupt_enable() < 0) { + printf("fail to check interrupt enabling\n"); + goto out; + } + rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); + + if (test_interrupt_disable() < 0) { + printf("fail to check interrupt disabling\n"); + goto out; + } + rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); + + ret = 0; + +out: + printf("Clearing for interrupt tests\n"); + /* clear registered callbacks */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID]; + rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback, (void *)-1); + rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback_1, (void *)-1); + + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO]; + rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback, (void *)-1); + rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback_1, (void *)-1); + + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM]; + rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback, (void *)-1); + rte_intr_callback_unregister(&test_intr_handle, + test_interrupt_callback_1, (void *)-1); + + rte_delay_ms(2 * TEST_INTERRUPT_CHECK_INTERVAL); + /* deinit */ + test_interrupt_deinit(); + + return ret; +} + +REGISTER_TEST_COMMAND(interrupt_autotest, test_interrupt); diff --git a/test/test/test_kni.c b/test/test/test_kni.c new file mode 100644 index 0000000000..309741cb35 --- /dev/null +++ b/test/test/test_kni.c @@ -0,0 +1,636 @@ +/*- + * 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 +#include +#include +#include +#include + +#include "test.h" + +#include +#include +#include +#include +#include + +#define NB_MBUF 8192 +#define MAX_PACKET_SZ 2048 +#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM) +#define PKT_BURST_SZ 32 +#define MEMPOOL_CACHE_SZ PKT_BURST_SZ +#define SOCKET 0 +#define NB_RXD 128 +#define NB_TXD 512 +#define KNI_TIMEOUT_MS 5000 /* ms */ + +#define IFCONFIG "/sbin/ifconfig " +#define TEST_KNI_PORT "test_kni_port" +#define KNI_TEST_MAX_PORTS 4 +/* The threshold number of mbufs to be transmitted or received. */ +#define KNI_NUM_MBUF_THRESHOLD 100 +static int kni_pkt_mtu = 0; + +struct test_kni_stats { + volatile uint64_t ingress; + volatile uint64_t egress; +}; + +static const struct rte_eth_rxconf rx_conf = { + .rx_thresh = { + .pthresh = 8, + .hthresh = 8, + .wthresh = 4, + }, + .rx_free_thresh = 0, +}; + +static const struct rte_eth_txconf tx_conf = { + .tx_thresh = { + .pthresh = 36, + .hthresh = 0, + .wthresh = 0, + }, + .tx_free_thresh = 0, + .tx_rs_thresh = 0, +}; + +static const struct rte_eth_conf port_conf = { + .rxmode = { + .header_split = 0, + .hw_ip_checksum = 0, + .hw_vlan_filter = 0, + .jumbo_frame = 0, + .hw_strip_crc = 0, + }, + .txmode = { + .mq_mode = ETH_DCB_NONE, + }, +}; + +static struct rte_kni_ops kni_ops = { + .change_mtu = NULL, + .config_network_if = NULL, +}; + +static unsigned lcore_master, lcore_ingress, lcore_egress; +static struct rte_kni *test_kni_ctx; +static struct test_kni_stats stats; + +static volatile uint32_t test_kni_processing_flag; + +static struct rte_mempool * +test_kni_create_mempool(void) +{ + struct rte_mempool * mp; + + mp = rte_mempool_lookup("kni_mempool"); + if (!mp) + mp = rte_pktmbuf_pool_create("kni_mempool", + NB_MBUF, + MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, + SOCKET); + + return mp; +} + +static struct rte_mempool * +test_kni_lookup_mempool(void) +{ + return rte_mempool_lookup("kni_mempool"); +} +/* Callback for request of changing MTU */ +static int +kni_change_mtu(uint8_t port_id, unsigned new_mtu) +{ + printf("Change MTU of port %d to %u\n", port_id, new_mtu); + kni_pkt_mtu = new_mtu; + printf("Change MTU of port %d to %i successfully.\n", + port_id, kni_pkt_mtu); + return 0; +} +/** + * This loop fully tests the basic functions of KNI. e.g. transmitting, + * receiving to, from kernel space, and kernel requests. + * + * This is the loop to transmit/receive mbufs to/from kernel interface with + * supported by KNI kernel module. The ingress lcore will allocate mbufs and + * transmit them to kernel space; while the egress lcore will receive the mbufs + * from kernel space and free them. + * On the master lcore, several commands will be run to check handling the + * kernel requests. And it will finally set the flag to exit the KNI + * transmitting/receiving to/from the kernel space. + * + * Note: To support this testing, the KNI kernel module needs to be insmodded + * in one of its loopback modes. + */ +static int +test_kni_loop(__rte_unused void *arg) +{ + int ret = 0; + unsigned nb_rx, nb_tx, num, i; + const unsigned lcore_id = rte_lcore_id(); + struct rte_mbuf *pkts_burst[PKT_BURST_SZ]; + + if (lcore_id == lcore_master) { + rte_delay_ms(KNI_TIMEOUT_MS); + /* tests of handling kernel request */ + if (system(IFCONFIG TEST_KNI_PORT" up") == -1) + ret = -1; + if (system(IFCONFIG TEST_KNI_PORT" mtu 1400") == -1) + ret = -1; + if (system(IFCONFIG TEST_KNI_PORT" down") == -1) + ret = -1; + rte_delay_ms(KNI_TIMEOUT_MS); + test_kni_processing_flag = 1; + } else if (lcore_id == lcore_ingress) { + struct rte_mempool *mp = test_kni_lookup_mempool(); + + if (mp == NULL) + return -1; + + while (1) { + if (test_kni_processing_flag) + break; + + for (nb_rx = 0; nb_rx < PKT_BURST_SZ; nb_rx++) { + pkts_burst[nb_rx] = rte_pktmbuf_alloc(mp); + if (!pkts_burst[nb_rx]) + break; + } + + num = rte_kni_tx_burst(test_kni_ctx, pkts_burst, + nb_rx); + stats.ingress += num; + rte_kni_handle_request(test_kni_ctx); + if (num < nb_rx) { + for (i = num; i < nb_rx; i++) { + rte_pktmbuf_free(pkts_burst[i]); + } + } + rte_delay_ms(10); + } + } else if (lcore_id == lcore_egress) { + while (1) { + if (test_kni_processing_flag) + break; + num = rte_kni_rx_burst(test_kni_ctx, pkts_burst, + PKT_BURST_SZ); + stats.egress += num; + for (nb_tx = 0; nb_tx < num; nb_tx++) + rte_pktmbuf_free(pkts_burst[nb_tx]); + rte_delay_ms(10); + } + } + + return ret; +} + +static int +test_kni_allocate_lcores(void) +{ + unsigned i, count = 0; + + lcore_master = rte_get_master_lcore(); + printf("master lcore: %u\n", lcore_master); + for (i = 0; i < RTE_MAX_LCORE; i++) { + if (count >=2 ) + break; + if (rte_lcore_is_enabled(i) && i != lcore_master) { + count ++; + if (count == 1) + lcore_ingress = i; + else if (count == 2) + lcore_egress = i; + } + } + printf("count: %u\n", count); + + return count == 2 ? 0 : -1; +} + +static int +test_kni_register_handler_mp(void) +{ +#define TEST_KNI_HANDLE_REQ_COUNT 10 /* 5s */ +#define TEST_KNI_HANDLE_REQ_INTERVAL 500 /* ms */ +#define TEST_KNI_MTU 1450 +#define TEST_KNI_MTU_STR " 1450" + int pid; + + pid = fork(); + if (pid < 0) { + printf("Failed to fork a process\n"); + return -1; + } else if (pid == 0) { + int i; + struct rte_kni *kni = rte_kni_get(TEST_KNI_PORT); + struct rte_kni_ops ops = { + .change_mtu = kni_change_mtu, + .config_network_if = NULL, + }; + + if (!kni) { + printf("Failed to get KNI named %s\n", TEST_KNI_PORT); + exit(-1); + } + + kni_pkt_mtu = 0; + + /* Check with the invalid parameters */ + if (rte_kni_register_handlers(kni, NULL) == 0) { + printf("Unexpectedly register successuflly " + "with NULL ops pointer\n"); + exit(-1); + } + if (rte_kni_register_handlers(NULL, &ops) == 0) { + printf("Unexpectedly register successfully " + "to NULL KNI device pointer\n"); + exit(-1); + } + + if (rte_kni_register_handlers(kni, &ops)) { + printf("Fail to register ops\n"); + exit(-1); + } + + /* Check registering again after it has been registered */ + if (rte_kni_register_handlers(kni, &ops) == 0) { + printf("Unexpectedly register successfully after " + "it has already been registered\n"); + exit(-1); + } + + /** + * Handle the request of setting MTU, + * with registered handlers. + */ + for (i = 0; i < TEST_KNI_HANDLE_REQ_COUNT; i++) { + rte_kni_handle_request(kni); + if (kni_pkt_mtu == TEST_KNI_MTU) + break; + rte_delay_ms(TEST_KNI_HANDLE_REQ_INTERVAL); + } + if (i >= TEST_KNI_HANDLE_REQ_COUNT) { + printf("MTU has not been set\n"); + exit(-1); + } + + kni_pkt_mtu = 0; + if (rte_kni_unregister_handlers(kni) < 0) { + printf("Fail to unregister ops\n"); + exit(-1); + } + + /* Check with invalid parameter */ + if (rte_kni_unregister_handlers(NULL) == 0) { + exit(-1); + } + + /** + * Handle the request of setting MTU, + * without registered handlers. + */ + for (i = 0; i < TEST_KNI_HANDLE_REQ_COUNT; i++) { + rte_kni_handle_request(kni); + if (kni_pkt_mtu != 0) + break; + rte_delay_ms(TEST_KNI_HANDLE_REQ_INTERVAL); + } + if (kni_pkt_mtu != 0) { + printf("MTU shouldn't be set\n"); + exit(-1); + } + + exit(0); + } else { + int p_ret, status; + + rte_delay_ms(1000); + if (system(IFCONFIG TEST_KNI_PORT " mtu" TEST_KNI_MTU_STR) + == -1) + return -1; + + rte_delay_ms(1000); + if (system(IFCONFIG TEST_KNI_PORT " mtu" TEST_KNI_MTU_STR) + == -1) + return -1; + + p_ret = wait(&status); + if (!WIFEXITED(status)) { + printf("Child process (%d) exit abnormally\n", p_ret); + return -1; + } + if (WEXITSTATUS(status) != 0) { + printf("Child process exit with failure\n"); + return -1; + } + } + + return 0; +} + +static int +test_kni_processing(uint8_t port_id, struct rte_mempool *mp) +{ + int ret = 0; + unsigned i; + struct rte_kni *kni; + struct rte_kni_conf conf; + struct rte_eth_dev_info info; + struct rte_kni_ops ops; + + if (!mp) + return -1; + + memset(&conf, 0, sizeof(conf)); + memset(&info, 0, sizeof(info)); + memset(&ops, 0, sizeof(ops)); + + rte_eth_dev_info_get(port_id, &info); + conf.addr = info.pci_dev->addr; + conf.id = info.pci_dev->id; + snprintf(conf.name, sizeof(conf.name), TEST_KNI_PORT); + + /* core id 1 configured for kernel thread */ + conf.core_id = 1; + conf.force_bind = 1; + conf.mbuf_size = MAX_PACKET_SZ; + conf.group_id = (uint16_t)port_id; + + ops = kni_ops; + ops.port_id = port_id; + + /* basic test of kni processing */ + kni = rte_kni_alloc(mp, &conf, &ops); + if (!kni) { + printf("fail to create kni\n"); + return -1; + } + + test_kni_ctx = kni; + test_kni_processing_flag = 0; + stats.ingress = 0; + stats.egress = 0; + + /** + * Check multiple processes support on + * registerring/unregisterring handlers. + */ + if (test_kni_register_handler_mp() < 0) { + printf("fail to check multiple process support\n"); + ret = -1; + goto fail_kni; + } + + rte_eal_mp_remote_launch(test_kni_loop, NULL, CALL_MASTER); + RTE_LCORE_FOREACH_SLAVE(i) { + if (rte_eal_wait_lcore(i) < 0) { + ret = -1; + goto fail_kni; + } + } + /** + * Check if the number of mbufs received from kernel space is equal + * to that of transmitted to kernel space + */ + if (stats.ingress < KNI_NUM_MBUF_THRESHOLD || + stats.egress < KNI_NUM_MBUF_THRESHOLD) { + printf("The ingress/egress number should not be " + "less than %u\n", (unsigned)KNI_NUM_MBUF_THRESHOLD); + ret = -1; + goto fail_kni; + } + + if (rte_kni_release(kni) < 0) { + printf("fail to release kni\n"); + return -1; + } + test_kni_ctx = NULL; + + /* test of releasing a released kni device */ + if (rte_kni_release(kni) == 0) { + printf("should not release a released kni device\n"); + return -1; + } + + /* test of reusing memzone */ + kni = rte_kni_alloc(mp, &conf, &ops); + if (!kni) { + printf("fail to create kni\n"); + return -1; + } + + /* Release the kni for following testing */ + if (rte_kni_release(kni) < 0) { + printf("fail to release kni\n"); + return -1; + } + + return ret; +fail_kni: + if (rte_kni_release(kni) < 0) { + printf("fail to release kni\n"); + ret = -1; + } + + return ret; +} + +static int +test_kni(void) +{ + int ret = -1; + uint8_t nb_ports, port_id; + struct rte_kni *kni; + struct rte_mempool *mp; + struct rte_kni_conf conf; + struct rte_eth_dev_info info; + struct rte_kni_ops ops; + + /* Initialize KNI subsytem */ + rte_kni_init(KNI_TEST_MAX_PORTS); + + if (test_kni_allocate_lcores() < 0) { + printf("No enough lcores for kni processing\n"); + return -1; + } + + mp = test_kni_create_mempool(); + if (!mp) { + printf("fail to create mempool for kni\n"); + return -1; + } + + nb_ports = rte_eth_dev_count(); + if (nb_ports == 0) { + printf("no supported nic port found\n"); + return -1; + } + + /* configuring port 0 for the test is enough */ + port_id = 0; + ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf); + if (ret < 0) { + printf("fail to configure port %d\n", port_id); + return -1; + } + + ret = rte_eth_rx_queue_setup(port_id, 0, NB_RXD, SOCKET, &rx_conf, mp); + if (ret < 0) { + printf("fail to setup rx queue for port %d\n", port_id); + return -1; + } + + ret = rte_eth_tx_queue_setup(port_id, 0, NB_TXD, SOCKET, &tx_conf); + if (ret < 0) { + printf("fail to setup tx queue for port %d\n", port_id); + return -1; + } + + ret = rte_eth_dev_start(port_id); + if (ret < 0) { + printf("fail to start port %d\n", port_id); + return -1; + } + rte_eth_promiscuous_enable(port_id); + + /* basic test of kni processing */ + ret = test_kni_processing(port_id, mp); + if (ret < 0) + goto fail; + + /* test of allocating KNI with NULL mempool pointer */ + memset(&info, 0, sizeof(info)); + memset(&conf, 0, sizeof(conf)); + memset(&ops, 0, sizeof(ops)); + rte_eth_dev_info_get(port_id, &info); + conf.addr = info.pci_dev->addr; + conf.id = info.pci_dev->id; + conf.group_id = (uint16_t)port_id; + conf.mbuf_size = MAX_PACKET_SZ; + + ops = kni_ops; + ops.port_id = port_id; + kni = rte_kni_alloc(NULL, &conf, &ops); + if (kni) { + ret = -1; + printf("unexpectedly creates kni successfully with NULL " + "mempool pointer\n"); + goto fail; + } + + /* test of allocating KNI without configurations */ + kni = rte_kni_alloc(mp, NULL, NULL); + if (kni) { + ret = -1; + printf("Unexpectedly allocate KNI device successfully " + "without configurations\n"); + goto fail; + } + + /* test of allocating KNI without a name */ + memset(&conf, 0, sizeof(conf)); + memset(&info, 0, sizeof(info)); + memset(&ops, 0, sizeof(ops)); + rte_eth_dev_info_get(port_id, &info); + conf.addr = info.pci_dev->addr; + conf.id = info.pci_dev->id; + conf.group_id = (uint16_t)port_id; + conf.mbuf_size = MAX_PACKET_SZ; + + ops = kni_ops; + ops.port_id = port_id; + kni = rte_kni_alloc(mp, &conf, &ops); + if (kni) { + ret = -1; + printf("Unexpectedly allocate a KNI device successfully " + "without a name\n"); + goto fail; + } + + /* test of releasing NULL kni context */ + ret = rte_kni_release(NULL); + if (ret == 0) { + ret = -1; + printf("unexpectedly release kni successfully\n"); + goto fail; + } + + /* test of handling request on NULL device pointer */ + ret = rte_kni_handle_request(NULL); + if (ret == 0) { + ret = -1; + printf("Unexpectedly handle request on NULL device pointer\n"); + goto fail; + } + + /* test of getting KNI device with pointer to NULL */ + kni = rte_kni_get(NULL); + if (kni) { + ret = -1; + printf("Unexpectedly get a KNI device with " + "NULL name pointer\n"); + goto fail; + } + + /* test of getting KNI device with an zero length name string */ + memset(&conf, 0, sizeof(conf)); + kni = rte_kni_get(conf.name); + if (kni) { + ret = -1; + printf("Unexpectedly get a KNI device with " + "zero length name string\n"); + goto fail; + } + + /* test of getting KNI device with an invalid string name */ + memset(&conf, 0, sizeof(conf)); + snprintf(conf.name, sizeof(conf.name), "testing"); + kni = rte_kni_get(conf.name); + if (kni) { + ret = -1; + printf("Unexpectedly get a KNI device with " + "a never used name string\n"); + goto fail; + } + ret = 0; + +fail: + rte_eth_dev_stop(port_id); + + return ret; +} + +REGISTER_TEST_COMMAND(kni_autotest, test_kni); diff --git a/test/test/test_kvargs.c b/test/test/test_kvargs.c new file mode 100644 index 0000000000..4d9e805b3a --- /dev/null +++ b/test/test/test_kvargs.c @@ -0,0 +1,235 @@ +/* + * Copyright 2014 6WIND S.A. + * + * 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 6WIND S.A. 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 +#include +#include + +#include +#include + +#include "test.h" + +/* incrementd in handler, to check it is properly called once per + * key/value association */ +static unsigned count; + +/* this handler increment the "count" variable at each call and check + * that the key is "check" and the value is "value%d" */ +static int check_handler(const char *key, const char *value, + __rte_unused void *opaque) +{ + char buf[16]; + + /* we check that the value is "check" */ + if (strcmp(key, "check")) + return -1; + + /* we check that the value is "value$(count)" */ + snprintf(buf, sizeof(buf), "value%d", count); + if (strncmp(buf, value, sizeof(buf))) + return -1; + + count ++; + return 0; +} + +/* test a valid case */ +static int test_valid_kvargs(void) +{ + struct rte_kvargs *kvlist; + const char *args; + const char *valid_keys_list[] = { "foo", "check", NULL }; + const char **valid_keys; + + /* empty args is valid */ + args = ""; + valid_keys = NULL; + kvlist = rte_kvargs_parse(args, valid_keys); + if (kvlist == NULL) { + printf("rte_kvargs_parse() error"); + goto fail; + } + rte_kvargs_free(kvlist); + + /* first test without valid_keys */ + args = "foo=1234,check=value0,check=value1"; + valid_keys = NULL; + kvlist = rte_kvargs_parse(args, valid_keys); + if (kvlist == NULL) { + printf("rte_kvargs_parse() error"); + goto fail; + } + /* call check_handler() for all entries with key="check" */ + count = 0; + if (rte_kvargs_process(kvlist, "check", check_handler, NULL) < 0) { + printf("rte_kvargs_process() error\n"); + rte_kvargs_free(kvlist); + goto fail; + } + if (count != 2) { + printf("invalid count value %d after rte_kvargs_process(check)\n", + count); + rte_kvargs_free(kvlist); + goto fail; + } + count = 0; + /* call check_handler() for all entries with key="unexistant_key" */ + if (rte_kvargs_process(kvlist, "unexistant_key", check_handler, NULL) < 0) { + printf("rte_kvargs_process() error\n"); + rte_kvargs_free(kvlist); + goto fail; + } + if (count != 0) { + printf("invalid count value %d after rte_kvargs_process(unexistant_key)\n", + count); + rte_kvargs_free(kvlist); + goto fail; + } + /* count all entries with key="foo" */ + count = rte_kvargs_count(kvlist, "foo"); + if (count != 1) { + printf("invalid count value %d after rte_kvargs_count(foo)\n", + count); + rte_kvargs_free(kvlist); + goto fail; + } + /* count all entries */ + count = rte_kvargs_count(kvlist, NULL); + if (count != 3) { + printf("invalid count value %d after rte_kvargs_count(NULL)\n", + count); + rte_kvargs_free(kvlist); + goto fail; + } + /* count all entries with key="unexistant_key" */ + count = rte_kvargs_count(kvlist, "unexistant_key"); + if (count != 0) { + printf("invalid count value %d after rte_kvargs_count(unexistant_key)\n", + count); + rte_kvargs_free(kvlist); + goto fail; + } + rte_kvargs_free(kvlist); + + /* second test using valid_keys */ + args = "foo=droids,check=value0,check=value1,check=wrong_value"; + valid_keys = valid_keys_list; + kvlist = rte_kvargs_parse(args, valid_keys); + if (kvlist == NULL) { + printf("rte_kvargs_parse() error"); + goto fail; + } + /* call check_handler() on all entries with key="check", it + * should fail as the value is not recognized by the handler */ + if (rte_kvargs_process(kvlist, "check", check_handler, NULL) == 0) { + printf("rte_kvargs_process() is success bu should not\n"); + rte_kvargs_free(kvlist); + goto fail; + } + count = rte_kvargs_count(kvlist, "check"); + if (count != 3) { + printf("invalid count value %d after rte_kvargs_count(check)\n", + count); + rte_kvargs_free(kvlist); + goto fail; + } + rte_kvargs_free(kvlist); + + return 0; + + fail: + printf("while processing <%s>", args); + if (valid_keys != NULL && *valid_keys != NULL) { + printf(" using valid_keys=<%s", *valid_keys); + while (*(++valid_keys) != NULL) + printf(",%s", *valid_keys); + printf(">"); + } + printf("\n"); + return -1; +} + +/* test several error cases */ +static int test_invalid_kvargs(void) +{ + struct rte_kvargs *kvlist; + /* list of argument that should fail */ + const char *args_list[] = { + "wrong-key=x", /* key not in valid_keys_list */ + "foo=1,foo=", /* empty value */ + "foo=1,,foo=2", /* empty key/value */ + "foo=1,foo", /* no value */ + "foo=1,=2", /* no key */ + ",=", /* also test with a smiley */ + NULL }; + const char **args; + const char *valid_keys_list[] = { "foo", "check", NULL }; + const char **valid_keys = valid_keys_list; + + for (args = args_list; *args != NULL; args++) { + + kvlist = rte_kvargs_parse(*args, valid_keys); + if (kvlist != NULL) { + printf("rte_kvargs_parse() returned 0 (but should not)\n"); + rte_kvargs_free(kvlist); + goto fail; + } + return 0; + } + + fail: + printf("while processing <%s>", *args); + if (valid_keys != NULL && *valid_keys != NULL) { + printf(" using valid_keys=<%s", *valid_keys); + while (*(++valid_keys) != NULL) + printf(",%s", *valid_keys); + printf(">"); + } + printf("\n"); + return -1; +} + +static int +test_kvargs(void) +{ + printf("== test valid case ==\n"); + if (test_valid_kvargs() < 0) + return -1; + printf("== test invalid case ==\n"); + if (test_invalid_kvargs() < 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(kvargs_autotest, test_kvargs); diff --git a/test/test/test_link_bonding.c b/test/test/test_link_bonding.c new file mode 100644 index 0000000000..32296604d2 --- /dev/null +++ b/test/test/test_link_bonding.c @@ -0,0 +1,5005 @@ +/*- + * 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 "unistd.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "virtual_pmd.h" +#include "packet_burst_generator.h" + +#include "test.h" + +#define TEST_MAX_NUMBER_OF_PORTS (6) + +#define RX_RING_SIZE 128 +#define RX_FREE_THRESH 32 +#define RX_PTHRESH 8 +#define RX_HTHRESH 8 +#define RX_WTHRESH 0 + +#define TX_RING_SIZE 512 +#define TX_FREE_THRESH 32 +#define TX_PTHRESH 32 +#define TX_HTHRESH 0 +#define TX_WTHRESH 0 +#define TX_RSBIT_THRESH 32 +#define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\ + ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \ + ETH_TXQ_FLAGS_NOXSUMTCP) + +#define MBUF_CACHE_SIZE (250) +#define BURST_SIZE (32) + +#define RTE_TEST_RX_DESC_MAX (2048) +#define RTE_TEST_TX_DESC_MAX (2048) +#define MAX_PKT_BURST (512) +#define DEF_PKT_BURST (16) + +#define BONDED_DEV_NAME ("unit_test_bond_dev") + +#define INVALID_SOCKET_ID (-1) +#define INVALID_PORT_ID (-1) +#define INVALID_BONDING_MODE (-1) + + +uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 }; +uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; + +struct link_bonding_unittest_params { + int8_t bonded_port_id; + int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS]; + uint8_t bonded_slave_count; + uint8_t bonding_mode; + + uint16_t nb_rx_q; + uint16_t nb_tx_q; + + struct rte_mempool *mbuf_pool; + + struct ether_addr *default_slave_mac; + struct ether_addr *default_bonded_mac; + + /* Packet Headers */ + struct ether_hdr *pkt_eth_hdr; + struct ipv4_hdr *pkt_ipv4_hdr; + struct ipv6_hdr *pkt_ipv6_hdr; + struct udp_hdr *pkt_udp_hdr; + +}; + +static struct ipv4_hdr pkt_ipv4_hdr; +static struct ipv6_hdr pkt_ipv6_hdr; +static struct udp_hdr pkt_udp_hdr; + +static struct link_bonding_unittest_params default_params = { + .bonded_port_id = -1, + .slave_port_ids = { -1 }, + .bonded_slave_count = 0, + .bonding_mode = BONDING_MODE_ROUND_ROBIN, + + .nb_rx_q = 1, + .nb_tx_q = 1, + + .mbuf_pool = NULL, + + .default_slave_mac = (struct ether_addr *)slave_mac, + .default_bonded_mac = (struct ether_addr *)bonded_mac, + + .pkt_eth_hdr = NULL, + .pkt_ipv4_hdr = &pkt_ipv4_hdr, + .pkt_ipv6_hdr = &pkt_ipv6_hdr, + .pkt_udp_hdr = &pkt_udp_hdr + +}; + +static struct link_bonding_unittest_params *test_params = &default_params; + +static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; +static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; +static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB }; + +static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98); +static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98); +static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97); + +static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, + 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA }; +static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, + 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA }; +static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, + 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB }; + +static uint16_t src_port = 1024; +static uint16_t dst_port_0 = 1024; +static uint16_t dst_port_1 = 2024; + +static uint16_t vlan_id = 0x100; + +struct rte_eth_rxmode rx_mode = { + .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */ + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled. */ + .hw_ip_checksum = 0, /**< IP checksum offload disabled. */ + .hw_vlan_filter = 1, /**< VLAN filtering enabled. */ + .hw_vlan_strip = 1, /**< VLAN strip enabled. */ + .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */ + .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */ +}; + +struct rte_fdir_conf fdir_conf = { + .mode = RTE_FDIR_MODE_NONE, + .pballoc = RTE_FDIR_PBALLOC_64K, + .status = RTE_FDIR_REPORT_STATUS, + .drop_queue = 127, +}; + +static struct rte_eth_conf default_pmd_conf = { + .rxmode = { + .mq_mode = ETH_MQ_RX_NONE, + .max_rx_pkt_len = ETHER_MAX_LEN, + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled */ + .hw_ip_checksum = 0, /**< IP checksum offload enabled */ + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ + .hw_strip_crc = 0, /**< CRC stripped by hardware */ + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, + .lpbk_mode = 0, +}; + +static const struct rte_eth_rxconf rx_conf_default = { + .rx_thresh = { + .pthresh = RX_PTHRESH, + .hthresh = RX_HTHRESH, + .wthresh = RX_WTHRESH, + }, + .rx_free_thresh = RX_FREE_THRESH, + .rx_drop_en = 0, +}; + +static struct rte_eth_txconf tx_conf_default = { + .tx_thresh = { + .pthresh = TX_PTHRESH, + .hthresh = TX_HTHRESH, + .wthresh = TX_WTHRESH, + }, + .tx_free_thresh = TX_FREE_THRESH, + .tx_rs_thresh = TX_RSBIT_THRESH, + .txq_flags = TX_Q_FLAGS + +}; + +static int +configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr) +{ + int q_id; + + if (en_isr) + default_pmd_conf.intr_conf.lsc = 1; + else + default_pmd_conf.intr_conf.lsc = 0; + + TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q, + test_params->nb_tx_q, &default_pmd_conf), + "rte_eth_dev_configure for port %d failed", port_id); + + for (q_id = 0; q_id < test_params->nb_rx_q; q_id++) + TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE, + rte_eth_dev_socket_id(port_id), &rx_conf_default, + test_params->mbuf_pool) , + "rte_eth_rx_queue_setup for port %d failed", port_id); + + for (q_id = 0; q_id < test_params->nb_tx_q; q_id++) + TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE, + rte_eth_dev_socket_id(port_id), &tx_conf_default), + "rte_eth_tx_queue_setup for port %d failed", port_id); + + if (start) + TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id), + "rte_eth_dev_start for port %d failed", port_id); + + return 0; +} + +static int slaves_initialized; + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER; + + +static int +test_setup(void) +{ + int i, nb_mbuf_per_pool; + struct ether_addr *mac_addr = (struct ether_addr *)slave_mac; + + /* Allocate ethernet packet header with space for VLAN header */ + if (test_params->pkt_eth_hdr == NULL) { + test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) + + sizeof(struct vlan_hdr)); + + TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr, + "Ethernet header struct allocation failed!"); + } + + nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST + + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; + if (test_params->mbuf_pool == NULL) { + test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", + nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, + RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + TEST_ASSERT_NOT_NULL(test_params->mbuf_pool, + "rte_mempool_create failed"); + } + + /* Create / Initialize virtual eth devs */ + if (!slaves_initialized) { + for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) { + char pmd_name[RTE_ETH_NAME_MAX_LEN]; + + mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i; + + snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i); + + test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name, + mac_addr, rte_socket_id(), 1); + TEST_ASSERT(test_params->slave_port_ids[i] >= 0, + "Failed to create virtual virtual ethdev %s", pmd_name); + + TEST_ASSERT_SUCCESS(configure_ethdev( + test_params->slave_port_ids[i], 1, 0), + "Failed to configure virtual ethdev %s", pmd_name); + } + slaves_initialized = 1; + } + + return 0; +} + +static int +test_create_bonded_device(void) +{ + int current_slave_count; + + uint8_t slaves[RTE_MAX_ETHPORTS]; + + /* Don't try to recreate bonded device if re-running test suite*/ + if (test_params->bonded_port_id == -1) { + test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME, + test_params->bonding_mode, rte_socket_id()); + + TEST_ASSERT(test_params->bonded_port_id >= 0, + "Failed to create bonded ethdev %s", BONDED_DEV_NAME); + + TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0), + "Failed to configure bonded ethdev %s", BONDED_DEV_NAME); + } + + TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id, + test_params->bonding_mode), "Failed to set ethdev %d to mode %d", + test_params->bonded_port_id, test_params->bonding_mode); + + current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + + TEST_ASSERT_EQUAL(current_slave_count, 0, + "Number of slaves %d is great than expected %d.", + current_slave_count, 0); + + current_slave_count = rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS); + + TEST_ASSERT_EQUAL(current_slave_count, 0, + "Number of active slaves %d is great than expected %d.", + current_slave_count, 0); + + return 0; +} + + +static int +test_create_bonded_device_with_invalid_params(void) +{ + int port_id; + + test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN; + + /* Invalid name */ + port_id = rte_eth_bond_create(NULL, test_params->bonding_mode, + rte_socket_id()); + TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly"); + + test_params->bonding_mode = INVALID_BONDING_MODE; + + /* Invalid bonding mode */ + port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode, + rte_socket_id()); + TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly."); + + test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN; + + /* Invalid socket id */ + port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode, + INVALID_SOCKET_ID); + TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly."); + + return 0; +} + +static int +test_add_slave_to_bonded_device(void) +{ + int current_slave_count; + + uint8_t slaves[RTE_MAX_ETHPORTS]; + + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id, + test_params->slave_port_ids[test_params->bonded_slave_count]), + "Failed to add slave (%d) to bonded port (%d).", + test_params->slave_port_ids[test_params->bonded_slave_count], + test_params->bonded_port_id); + + current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1, + "Number of slaves (%d) is greater than expected (%d).", + current_slave_count, test_params->bonded_slave_count + 1); + + current_slave_count = rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(current_slave_count, 0, + "Number of active slaves (%d) is not as expected (%d).\n", + current_slave_count, 0); + + test_params->bonded_slave_count++; + + return 0; +} + +static int +test_add_slave_to_invalid_bonded_device(void) +{ + /* Invalid port ID */ + TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5, + test_params->slave_port_ids[test_params->bonded_slave_count]), + "Expected call to failed as invalid port specified."); + + /* Non bonded device */ + TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0], + test_params->slave_port_ids[test_params->bonded_slave_count]), + "Expected call to failed as invalid port specified."); + + return 0; +} + + +static int +test_remove_slave_from_bonded_device(void) +{ + int current_slave_count; + struct ether_addr read_mac_addr, *mac_addr; + uint8_t slaves[RTE_MAX_ETHPORTS]; + + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id, + test_params->slave_port_ids[test_params->bonded_slave_count-1]), + "Failed to remove slave %d from bonded port (%d).", + test_params->slave_port_ids[test_params->bonded_slave_count-1], + test_params->bonded_port_id); + + + current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + + TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1, + "Number of slaves (%d) is great than expected (%d).\n", + current_slave_count, test_params->bonded_slave_count - 1); + + + mac_addr = (struct ether_addr *)slave_mac; + mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = + test_params->bonded_slave_count-1; + + rte_eth_macaddr_get( + test_params->slave_port_ids[test_params->bonded_slave_count-1], + &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)), + "bonded port mac address not set to that of primary port\n"); + + rte_eth_stats_reset( + test_params->slave_port_ids[test_params->bonded_slave_count-1]); + + virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id, + 0); + + test_params->bonded_slave_count--; + + return 0; +} + +static int +test_remove_slave_from_invalid_bonded_device(void) +{ + /* Invalid port ID */ + TEST_ASSERT_FAIL(rte_eth_bond_slave_remove( + test_params->bonded_port_id + 5, + test_params->slave_port_ids[test_params->bonded_slave_count - 1]), + "Expected call to failed as invalid port specified."); + + /* Non bonded device */ + TEST_ASSERT_FAIL(rte_eth_bond_slave_remove( + test_params->slave_port_ids[0], + test_params->slave_port_ids[test_params->bonded_slave_count - 1]), + "Expected call to failed as invalid port specified."); + + return 0; +} + +static int bonded_id = 2; + +static int +test_add_already_bonded_slave_to_bonded_device(void) +{ + int port_id, current_slave_count; + uint8_t slaves[RTE_MAX_ETHPORTS]; + char pmd_name[RTE_ETH_NAME_MAX_LEN]; + + test_add_slave_to_bonded_device(); + + current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(current_slave_count, 1, + "Number of slaves (%d) is not that expected (%d).", + current_slave_count, 1); + + snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id); + + port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode, + rte_socket_id()); + TEST_ASSERT(port_id >= 0, "Failed to create bonded device."); + + TEST_ASSERT(rte_eth_bond_slave_add(port_id, + test_params->slave_port_ids[test_params->bonded_slave_count - 1]) + < 0, + "Added slave (%d) to bonded port (%d) unexpectedly.", + test_params->slave_port_ids[test_params->bonded_slave_count-1], + port_id); + + return test_remove_slave_from_bonded_device(); +} + + +static int +test_get_slaves_from_bonded_device(void) +{ + int current_slave_count; + uint8_t slaves[RTE_MAX_ETHPORTS]; + + TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), + "Failed to add slave to bonded device"); + + /* Invalid port id */ + current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves, + RTE_MAX_ETHPORTS); + TEST_ASSERT(current_slave_count < 0, + "Invalid port id unexpectedly succeeded"); + + current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT(current_slave_count < 0, + "Invalid port id unexpectedly succeeded"); + + /* Invalid slaves pointer */ + current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, + NULL, RTE_MAX_ETHPORTS); + TEST_ASSERT(current_slave_count < 0, + "Invalid slave array unexpectedly succeeded"); + + current_slave_count = rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS); + TEST_ASSERT(current_slave_count < 0, + "Invalid slave array unexpectedly succeeded"); + + /* non bonded device*/ + current_slave_count = rte_eth_bond_slaves_get( + test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS); + TEST_ASSERT(current_slave_count < 0, + "Invalid port id unexpectedly succeeded"); + + current_slave_count = rte_eth_bond_active_slaves_get( + test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS); + TEST_ASSERT(current_slave_count < 0, + "Invalid port id unexpectedly succeeded"); + + TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(), + "Failed to remove slaves from bonded device"); + + return 0; +} + + +static int +test_add_remove_multiple_slaves_to_from_bonded_device(void) +{ + int i; + + for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) + TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), + "Failed to add slave to bonded device"); + + for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) + TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(), + "Failed to remove slaves from bonded device"); + + return 0; +} + +static void +enable_bonded_slaves(void) +{ + int i; + + for (i = 0; i < test_params->bonded_slave_count; i++) { + virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i], + 1); + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 1); + } +} + +static int +test_start_bonded_device(void) +{ + struct rte_eth_link link_status; + + int current_slave_count, current_bonding_mode, primary_port; + uint8_t slaves[RTE_MAX_ETHPORTS]; + + /* Add slave to bonded device*/ + TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), + "Failed to add slave to bonded device"); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), + "Failed to start bonded pmd eth device %d.", + test_params->bonded_port_id); + + /* Change link status of virtual pmd so it will be added to the active + * slave list of the bonded device*/ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[test_params->bonded_slave_count-1], 1); + + current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count, + "Number of slaves (%d) is not expected value (%d).", + current_slave_count, test_params->bonded_slave_count); + + current_slave_count = rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count, + "Number of active slaves (%d) is not expected value (%d).", + current_slave_count, test_params->bonded_slave_count); + + current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode, + "Bonded device mode (%d) is not expected value (%d).\n", + current_bonding_mode, test_params->bonding_mode); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0], + "Primary port (%d) is not expected value (%d).", + primary_port, test_params->slave_port_ids[0]); + + rte_eth_link_get(test_params->bonded_port_id, &link_status); + TEST_ASSERT_EQUAL(link_status.link_status, 1, + "Bonded port (%d) status (%d) is not expected value (%d).\n", + test_params->bonded_port_id, link_status.link_status, 1); + + return 0; +} + +static int +test_stop_bonded_device(void) +{ + int current_slave_count; + uint8_t slaves[RTE_MAX_ETHPORTS]; + + struct rte_eth_link link_status; + + rte_eth_dev_stop(test_params->bonded_port_id); + + rte_eth_link_get(test_params->bonded_port_id, &link_status); + TEST_ASSERT_EQUAL(link_status.link_status, 0, + "Bonded port (%d) status (%d) is not expected value (%d).", + test_params->bonded_port_id, link_status.link_status, 0); + + current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count, + "Number of slaves (%d) is not expected value (%d).", + current_slave_count, test_params->bonded_slave_count); + + current_slave_count = rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(current_slave_count, 0, + "Number of active slaves (%d) is not expected value (%d).", + current_slave_count, 0); + + return 0; +} + +static int +remove_slaves_and_stop_bonded_device(void) +{ + /* Clean up and remove slaves from bonded device */ + while (test_params->bonded_slave_count > 0) + TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(), + "test_remove_slave_from_bonded_device failed"); + + rte_eth_dev_stop(test_params->bonded_port_id); + rte_eth_stats_reset(test_params->bonded_port_id); + rte_eth_bond_mac_address_reset(test_params->bonded_port_id); + + return 0; +} + +static int +test_set_bonding_mode(void) +{ + int i, bonding_mode; + + int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN, + BONDING_MODE_ACTIVE_BACKUP, + BONDING_MODE_BALANCE, + BONDING_MODE_BROADCAST + }; + + /* Test supported link bonding modes */ + for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) { + /* Invalid port ID */ + TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID, + bonding_modes[i]), + "Expected call to failed as invalid port (%d) specified.", + INVALID_PORT_ID); + + /* Non bonded device */ + TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0], + bonding_modes[i]), + "Expected call to failed as invalid port (%d) specified.", + test_params->slave_port_ids[0]); + + TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id, + bonding_modes[i]), + "Failed to set link bonding mode on port (%d) to (%d).", + test_params->bonded_port_id, bonding_modes[i]); + + bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i], + "Link bonding mode (%d) of port (%d) is not expected value (%d).", + bonding_mode, test_params->bonded_port_id, + bonding_modes[i]); + + /* Invalid port ID */ + bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID); + TEST_ASSERT(bonding_mode < 0, + "Expected call to failed as invalid port (%d) specified.", + INVALID_PORT_ID); + + /* Non bonded device */ + bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]); + TEST_ASSERT(bonding_mode < 0, + "Expected call to failed as invalid port (%d) specified.", + test_params->slave_port_ids[0]); + } + + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_set_primary_slave(void) +{ + int i, j, retval; + struct ether_addr read_mac_addr; + struct ether_addr *expected_mac_addr; + + /* Add 4 slaves to bonded device */ + for (i = test_params->bonded_slave_count; i < 4; i++) + TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), + "Failed to add slave to bonded device."); + + TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id, + BONDING_MODE_ROUND_ROBIN), + "Failed to set link bonding mode on port (%d) to (%d).", + test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN); + + /* Invalid port ID */ + TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID, + test_params->slave_port_ids[i]), + "Expected call to failed as invalid port specified."); + + /* Non bonded device */ + TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i], + test_params->slave_port_ids[i]), + "Expected call to failed as invalid port specified."); + + /* Set slave as primary + * Verify slave it is now primary slave + * Verify that MAC address of bonded device is that of primary slave + * Verify that MAC address of all bonded slaves are that of primary slave + */ + for (i = 0; i < 4; i++) { + TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, + test_params->slave_port_ids[i]), + "Failed to set bonded port (%d) primary port to (%d)", + test_params->bonded_port_id, test_params->slave_port_ids[i]); + + retval = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT(retval >= 0, + "Failed to read primary port from bonded port (%d)\n", + test_params->bonded_port_id); + + TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i], + "Bonded port (%d) primary port (%d) not expected value (%d)\n", + test_params->bonded_port_id, retval, + test_params->slave_port_ids[i]); + + /* stop/start bonded eth dev to apply new MAC */ + rte_eth_dev_stop(test_params->bonded_port_id); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), + "Failed to start bonded port %d", + test_params->bonded_port_id); + + expected_mac_addr = (struct ether_addr *)&slave_mac; + expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i; + + /* Check primary slave MAC */ + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port mac address not set to that of primary port\n"); + + /* Check bonded MAC */ + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port mac address not set to that of primary port\n"); + + /* Check other slaves MACs */ + for (j = 0; j < 4; j++) { + if (j != i) { + rte_eth_macaddr_get(test_params->slave_port_ids[j], + &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port mac address not set to that of primary " + "port"); + } + } + } + + + /* Test with none existent port */ + TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10), + "read primary port from expectedly"); + + /* Test with slave port */ + TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]), + "read primary port from expectedly\n"); + + TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(), + "Failed to stop and remove slaves from bonded device"); + + /* No slaves */ + TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0, + "read primary port from expectedly\n"); + + return 0; +} + +static int +test_set_explicit_bonded_mac(void) +{ + int i; + struct ether_addr read_mac_addr; + struct ether_addr *mac_addr; + + uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 }; + + mac_addr = (struct ether_addr *)explicit_bonded_mac; + + /* Invalid port ID */ + TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr), + "Expected call to failed as invalid port specified."); + + /* Non bonded device */ + TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set( + test_params->slave_port_ids[0], mac_addr), + "Expected call to failed as invalid port specified."); + + /* NULL MAC address */ + TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set( + test_params->bonded_port_id, NULL), + "Expected call to failed as NULL MAC specified"); + + TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( + test_params->bonded_port_id, mac_addr), + "Failed to set MAC address on bonded port (%d)", + test_params->bonded_port_id); + + /* Add 4 slaves to bonded device */ + for (i = test_params->bonded_slave_count; i < 4; i++) { + TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), + "Failed to add slave to bonded device.\n"); + } + + /* Check bonded MAC */ + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)), + "bonded port mac address not set to that of primary port"); + + /* Check other slaves MACs */ + for (i = 0; i < 4; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port mac address not set to that of primary port"); + } + + /* test resetting mac address on bonded device */ + TEST_ASSERT_SUCCESS( + rte_eth_bond_mac_address_reset(test_params->bonded_port_id), + "Failed to reset MAC address on bonded port (%d)", + test_params->bonded_port_id); + + TEST_ASSERT_FAIL( + rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]), + "Reset MAC address on bonded port (%d) unexpectedly", + test_params->slave_port_ids[1]); + + /* test resetting mac address on bonded device with no slaves */ + TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(), + "Failed to remove slaves and stop bonded device"); + + TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id), + "Failed to reset MAC address on bonded port (%d)", + test_params->bonded_port_id); + + return 0; +} + +#define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3) + +static int +test_set_bonded_port_initialization_mac_assignment(void) +{ + int i, slave_count, bonded_port_id; + + uint8_t slaves[RTE_MAX_ETHPORTS]; + int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT]; + + struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr; + + /* Initialize default values for MAC addresses */ + memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr)); + memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr)); + + /* + * 1. a - Create / configure bonded / slave ethdevs + */ + bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test", + BONDING_MODE_ACTIVE_BACKUP, rte_socket_id()); + TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device"); + + TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0), + "Failed to configure bonded ethdev"); + + for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) { + char pmd_name[RTE_ETH_NAME_MAX_LEN]; + + slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100; + + snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i); + + slave_port_ids[i] = virtual_ethdev_create(pmd_name, + &slave_mac_addr, rte_socket_id(), 1); + + TEST_ASSERT(slave_port_ids[i] >= 0, + "Failed to create slave ethdev %s", pmd_name); + + TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0), + "Failed to configure virtual ethdev %s", + pmd_name); + } + + + /* + * 2. Add slave ethdevs to bonded device + */ + for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) { + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id, + slave_port_ids[i]), + "Failed to add slave (%d) to bonded port (%d).", + slave_port_ids[i], bonded_port_id); + } + + slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves, + RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count, + "Number of slaves (%d) is not as expected (%d)", + slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT); + + + /* + * 3. Set explicit MAC address on bonded ethdev + */ + bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF; + bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA; + + TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( + bonded_port_id, &bonded_mac_addr), + "Failed to set MAC address on bonded port (%d)", + bonded_port_id); + + + /* 4. a - Start bonded ethdev + * b - Enable slave devices + * c - Verify bonded/slaves ethdev MAC addresses + */ + TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id), + "Failed to start bonded pmd eth device %d.", + bonded_port_id); + + for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) { + virtual_ethdev_simulate_link_status_interrupt( + slave_port_ids[i], 1); + } + + rte_eth_macaddr_get(bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port mac address not as expected"); + + rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 0 mac address not as expected"); + + slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100; + rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 1 mac address not as expected"); + + slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100; + rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 2 mac address not as expected"); + + + /* 7. a - Change primary port + * b - Stop / Start bonded port + * d - Verify slave ethdev MAC addresses + */ + TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id, + slave_port_ids[2]), + "failed to set primary port on bonded device."); + + rte_eth_dev_stop(bonded_port_id); + TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id), + "Failed to start bonded pmd eth device %d.", + bonded_port_id); + + rte_eth_macaddr_get(bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port mac address not as expected"); + + slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100; + rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 0 mac address not as expected"); + + slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100; + rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 1 mac address not as expected"); + + rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 2 mac address not as expected"); + + /* 6. a - Stop bonded ethdev + * b - remove slave ethdevs + * c - Verify slave ethdevs MACs are restored + */ + rte_eth_dev_stop(bonded_port_id); + + for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) { + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id, + slave_port_ids[i]), + "Failed to remove slave %d from bonded port (%d).", + slave_port_ids[i], bonded_port_id); + } + + slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves, + RTE_MAX_ETHPORTS); + + TEST_ASSERT_EQUAL(slave_count, 0, + "Number of slaves (%d) is great than expected (%d).", + slave_count, 0); + + slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100; + rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 0 mac address not as expected"); + + slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100; + rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 1 mac address not as expected"); + + slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100; + rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port 2 mac address not as expected"); + + return 0; +} + + +static int +initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr, + uint8_t number_of_slaves, uint8_t enable_slave) +{ + /* Configure bonded device */ + TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, + bond_en_isr), "Failed to configure bonding port (%d) in mode %d " + "with (%d) slaves.", test_params->bonded_port_id, bonding_mode, + number_of_slaves); + + /* Add slaves to bonded device */ + while (number_of_slaves > test_params->bonded_slave_count) + TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(), + "Failed to add slave (%d to bonding port (%d).", + test_params->bonded_slave_count - 1, + test_params->bonded_port_id); + + /* Set link bonding mode */ + TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id, + bonding_mode), + "Failed to set link bonding mode on port (%d) to (%d).", + test_params->bonded_port_id, bonding_mode); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), + "Failed to start bonded pmd eth device %d.", + test_params->bonded_port_id); + + if (enable_slave) + enable_bonded_slaves(); + + return 0; +} + +static int +test_adding_slave_after_bonded_device_started(void) +{ + int i; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 0, 4, 0), + "Failed to add slaves to bonded device"); + + /* Enabled slave devices */ + for (i = 0; i < test_params->bonded_slave_count + 1; i++) { + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 1); + } + + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id, + test_params->slave_port_ids[test_params->bonded_slave_count]), + "Failed to add slave to bonded port.\n"); + + rte_eth_stats_reset( + test_params->slave_port_ids[test_params->bonded_slave_count]); + + test_params->bonded_slave_count++; + + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4 +#define TEST_LSC_WAIT_TIMEOUT_MS 500 + +int test_lsc_interrupt_count; + + +static void +test_bonding_lsc_event_callback(uint8_t port_id __rte_unused, + enum rte_eth_event_type type __rte_unused, void *param __rte_unused) +{ + pthread_mutex_lock(&mutex); + test_lsc_interrupt_count++; + + pthread_cond_signal(&cvar); + pthread_mutex_unlock(&mutex); +} + +static inline int +lsc_timeout(int wait_us) +{ + int retval = 0; + + struct timespec ts; + struct timeval tp; + + gettimeofday(&tp, NULL); + + /* Convert from timeval to timespec */ + ts.tv_sec = tp.tv_sec; + ts.tv_nsec = tp.tv_usec * 1000; + ts.tv_nsec += wait_us * 1000; + + pthread_mutex_lock(&mutex); + if (test_lsc_interrupt_count < 1) + retval = pthread_cond_timedwait(&cvar, &mutex, &ts); + + pthread_mutex_unlock(&mutex); + + if (retval == 0 && test_lsc_interrupt_count < 1) + return -1; + + return retval; +} + +static int +test_status_interrupt(void) +{ + int slave_count; + uint8_t slaves[RTE_MAX_ETHPORTS]; + + /* initialized bonding device with T slaves */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 1, + TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1), + "Failed to initialise bonded device"); + + test_lsc_interrupt_count = 0; + + /* register link status change interrupt callback */ + rte_eth_dev_callback_register(test_params->bonded_port_id, + RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, + &test_params->bonded_port_id); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + + TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT, + "Number of active slaves (%d) is not as expected (%d)", + slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT); + + /* Bring all 4 slaves link status to down and test that we have received a + * lsc interrupts */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[0], 0); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 0); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[2], 0); + + TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0, + "Received a link status change interrupt unexpectedly"); + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 0); + + TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0, + "timed out waiting for interrupt"); + + TEST_ASSERT(test_lsc_interrupt_count > 0, + "Did not receive link status change interrupt"); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + + TEST_ASSERT_EQUAL(slave_count, 0, + "Number of active slaves (%d) is not as expected (%d)", + slave_count, 0); + + /* bring one slave port up so link status will change */ + test_lsc_interrupt_count = 0; + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[0], 1); + + TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0, + "timed out waiting for interrupt"); + + /* test that we have received another lsc interrupt */ + TEST_ASSERT(test_lsc_interrupt_count > 0, + "Did not receive link status change interrupt"); + + /* Verify that calling the same slave lsc interrupt doesn't cause another + * lsc interrupt from bonded device */ + test_lsc_interrupt_count = 0; + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[0], 1); + + TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0, + "received unexpected interrupt"); + + TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0, + "Did not receive link status change interrupt"); + + + /* unregister lsc callback before exiting */ + rte_eth_dev_callback_unregister(test_params->bonded_port_id, + RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, + &test_params->bonded_port_id); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size, + uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac, + uint8_t toggle_ip_addr, uint8_t toggle_udp_port) +{ + uint16_t pktlen, generated_burst_size, ether_type; + void *ip_hdr; + + if (ipv4) + ether_type = ETHER_TYPE_IPv4; + else + ether_type = ETHER_TYPE_IPv6; + + if (toggle_dst_mac) + initialize_eth_header(test_params->pkt_eth_hdr, + (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, + ether_type, vlan, vlan_id); + else + initialize_eth_header(test_params->pkt_eth_hdr, + (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, + ether_type, vlan, vlan_id); + + + if (toggle_udp_port) + pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, + dst_port_1, 64); + else + pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, + dst_port_0, 64); + + if (ipv4) { + if (toggle_ip_addr) + pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, + dst_addr_1, pktlen); + else + pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, + dst_addr_0, pktlen); + + ip_hdr = test_params->pkt_ipv4_hdr; + } else { + if (toggle_ip_addr) + pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr, + (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1, + pktlen); + else + pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr, + (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0, + pktlen); + + ip_hdr = test_params->pkt_ipv6_hdr; + } + + /* Generate burst of packets to transmit */ + generated_burst_size = generate_packet_burst(test_params->mbuf_pool, + pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4, + test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128, + 1); + TEST_ASSERT_EQUAL(generated_burst_size, burst_size, + "Failed to generate packet burst"); + + return generated_burst_size; +} + +/** Round Robin Mode Tests */ + +static int +test_roundrobin_tx_burst(void) +{ + int i, burst_size; + struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; + struct rte_eth_stats port_stats; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 0, 2, 1), + "Failed to intialise bonded device"); + + burst_size = 20 * test_params->bonded_slave_count; + + TEST_ASSERT(burst_size <= MAX_PKT_BURST, + "Burst size specified is greater than supported."); + + /* Generate test bursts of packets to transmit */ + TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0), + burst_size, "failed to generate test burst"); + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size, + "tx burst failed"); + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "Bonded Port (%d) opackets value (%u) not as expected (%d)\n", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + burst_size); + + /* Verify slave ports tx stats */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)burst_size / test_params->bonded_slave_count, + "Slave Port (%d) opackets value (%u) not as expected (%d)\n", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + burst_size / test_params->bonded_slave_count); + } + + /* Put all slaves down and try and transmit */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 0); + } + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, + pkt_burst, burst_size), 0, + "tx burst return unexpected value"); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val) +{ + int i, refcnt; + + for (i = 0; i < nb_mbufs; i++) { + refcnt = rte_mbuf_refcnt_read(mbufs[i]); + TEST_ASSERT_EQUAL(refcnt, val, + "mbuf ref count (%d)is not the expected value (%d)", + refcnt, val); + } + return 0; +} + +static void +free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs) +{ + int i; + + for (i = 0; i < nb_mbufs; i++) + rte_pktmbuf_free(mbufs[i]); +} + +#define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2) +#define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64) +#define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22) +#define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1) + +static int +test_roundrobin_tx_burst_slave_tx_fail(void) +{ + struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; + struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST]; + + struct rte_eth_stats port_stats; + + int i, first_fail_idx, tx_count; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 0, + TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1), + "Failed to intialise bonded device"); + + /* Generate test bursts of packets to transmit */ + TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, + TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0), + TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, + "Failed to generate test packet burst"); + + /* Copy references to packets which we expect not to be transmitted */ + first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - + (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT * + TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) + + TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX; + + for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) { + expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx + + (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)]; + } + + /* Set virtual slave to only fail transmission of + * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */ + virtual_ethdev_tx_burst_fn_set_success( + test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], + 0); + + virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( + test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], + TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT); + + tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst, + TEST_RR_SLAVE_TX_FAIL_BURST_SIZE); + + TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - + TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, + "Transmitted (%d) an unexpected (%d) number of packets", tx_count, + TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - + TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT); + + /* Verify that failed packet are expected failed packets */ + for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) { + TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count], + "expected mbuf (%d) pointer %p not expected pointer %p", + i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]); + } + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - + TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, + "Bonded Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + TEST_RR_SLAVE_TX_FAIL_BURST_SIZE - + TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT); + + /* Verify slave ports tx stats */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + int slave_expected_tx_count; + + rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); + + slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE / + test_params->bonded_slave_count; + + if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX) + slave_expected_tx_count = slave_expected_tx_count - + TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; + + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)slave_expected_tx_count, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->slave_port_ids[i], + (unsigned int)port_stats.opackets, slave_expected_tx_count); + } + + /* Verify that all mbufs have a ref value of zero */ + TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count], + TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1), + "mbufs refcnts not as expected"); + free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_roundrobin_rx_burst_on_single_slave(void) +{ + struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + + struct rte_eth_stats port_stats; + + int i, j, burst_size = 25; + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 0, 4, 1), + "Failed to initialize bonded device with slaves"); + + /* Generate test bursts of packets to transmit */ + TEST_ASSERT_EQUAL(generate_test_burst( + gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size, + "burst generation failed"); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + /* Add rx data to slave */ + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &gen_pkt_burst[0], burst_size); + + /* Call rx burst on bonded device */ + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_rx_burst( + test_params->bonded_port_id, 0, rx_pkt_burst, + MAX_PKT_BURST), burst_size, + "round-robin rx burst failed"); + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, + "Bonded Port (%d) ipackets value (%u) not as expected (%d)", + test_params->bonded_port_id, + (unsigned int)port_stats.ipackets, burst_size); + + + + /* Verify bonded slave devices rx count */ + /* Verify slave ports tx stats */ + for (j = 0; j < test_params->bonded_slave_count; j++) { + rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); + + if (i == j) { + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, + "Slave Port (%d) ipackets value (%u) not as expected" + " (%d)", test_params->slave_port_ids[i], + (unsigned int)port_stats.ipackets, burst_size); + } else { + TEST_ASSERT_EQUAL(port_stats.ipackets, 0, + "Slave Port (%d) ipackets value (%u) not as expected" + " (%d)", test_params->slave_port_ids[i], + (unsigned int)port_stats.ipackets, 0); + } + + /* Reset bonded slaves stats */ + rte_eth_stats_reset(test_params->slave_port_ids[j]); + } + /* reset bonded device stats */ + rte_eth_stats_reset(test_params->bonded_port_id); + } + + /* free mbufs */ + for (i = 0; i < MAX_PKT_BURST; i++) { + if (gen_pkt_burst[i] != NULL) + rte_pktmbuf_free(gen_pkt_burst[i]); + + if (rx_pkt_burst[i] != NULL) + rte_pktmbuf_free(rx_pkt_burst[i]); + } + + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3) + +static int +test_roundrobin_rx_burst_on_multiple_slaves(void) +{ + struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; + + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_eth_stats port_stats; + + int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 }; + int i, nb_rx; + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 0, 4, 1), + "Failed to initialize bonded device with slaves"); + + /* Generate test bursts of packets to transmit */ + for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) { + TEST_ASSERT_EQUAL(generate_test_burst( + &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0), + burst_size[i], "burst generation failed"); + } + + /* Add rx data to slaves */ + for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) { + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &gen_pkt_burst[i][0], burst_size[i]); + } + + /* Call rx burst on bonded device */ + /* Send burst on bonded port */ + nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, + MAX_PKT_BURST); + TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2], + "round-robin rx burst failed (%d != %d)\n", nb_rx, + burst_size[0] + burst_size[1] + burst_size[2]); + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, + (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), + "Bonded Port (%d) ipackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.ipackets, + burst_size[0] + burst_size[1] + burst_size[2]); + + /* Verify bonded slave devices rx counts */ + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[0], + (unsigned int)port_stats.ipackets, burst_size[0]); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets, + burst_size[1]); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[2], + (unsigned int)port_stats.ipackets, burst_size[2]); + + rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, 0, + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[3], + (unsigned int)port_stats.ipackets, 0); + + /* free mbufs */ + for (i = 0; i < MAX_PKT_BURST; i++) { + if (rx_pkt_burst[i] != NULL) + rte_pktmbuf_free(rx_pkt_burst[i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_roundrobin_verify_mac_assignment(void) +{ + struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2; + + int i; + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); + rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2); + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 0, 4, 1), + "Failed to initialize bonded device with slaves"); + + /* Verify that all MACs are the same as first slave added to bonded dev */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[i]); + } + + /* change primary and verify that MAC addresses haven't changed */ + TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, + test_params->slave_port_ids[2]), + "Failed to set bonded port (%d) primary port to (%d)", + test_params->bonded_port_id, test_params->slave_port_ids[i]); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address has changed to that of primary" + " port without stop/start toggle of bonded device", + test_params->slave_port_ids[i]); + } + + /* stop / start bonded device and verify that primary MAC address is + * propagate to bonded device and slaves */ + rte_eth_dev_stop(test_params->bonded_port_id); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), + "Failed to start bonded device"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS( + memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of new primary port", + test_params->slave_port_ids[i]); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of new primary" + " port", test_params->slave_port_ids[i]); + } + + /* Set explicit MAC address */ + TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( + test_params->bonded_port_id, (struct ether_addr *)bonded_mac), + "Failed to set MAC"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of new primary port", + test_params->slave_port_ids[i]); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), "slave port (%d) mac address not set to" + " that of new primary port\n", test_params->slave_port_ids[i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_roundrobin_verify_promiscuous_enable_disable(void) +{ + int i, promiscuous_en; + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 0, 4, 1), + "Failed to initialize bonded device with slaves"); + + rte_eth_promiscuous_enable(test_params->bonded_port_id); + + promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(promiscuous_en, 1, + "Port (%d) promiscuous mode not enabled", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + promiscuous_en = rte_eth_promiscuous_get( + test_params->slave_port_ids[i]); + TEST_ASSERT_EQUAL(promiscuous_en, 1, + "slave port (%d) promiscuous mode not enabled", + test_params->slave_port_ids[i]); + } + + rte_eth_promiscuous_disable(test_params->bonded_port_id); + + promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(promiscuous_en, 0, + "Port (%d) promiscuous mode not disabled\n", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + promiscuous_en = rte_eth_promiscuous_get( + test_params->slave_port_ids[i]); + TEST_ASSERT_EQUAL(promiscuous_en, 0, + "Port (%d) promiscuous mode not disabled\n", + test_params->slave_port_ids[i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_RR_LINK_STATUS_SLAVE_COUNT (4) +#define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2) + +static int +test_roundrobin_verify_slave_link_status_change_behaviour(void) +{ + struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST]; + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + + struct rte_eth_stats port_stats; + uint8_t slaves[RTE_MAX_ETHPORTS]; + + int i, burst_size, slave_count; + + /* NULL all pointers in array to simplify cleanup */ + memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); + + /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves + * in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1), + "Failed to initialize bonded device with slaves"); + + /* Verify Current Slaves Count /Active Slave Count is */ + slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, + RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT, + "Number of slaves (%d) is not as expected (%d).", + slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT); + + /* Set 2 slaves eth_devs link status to down */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 0); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 0); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, + TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT, + "Number of active slaves (%d) is not as expected (%d).\n", + slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT); + + burst_size = 20; + + /* Verify that pkts are not sent on slaves with link status down: + * + * 1. Generate test burst of traffic + * 2. Transmit burst on bonded eth_dev + * 3. Verify stats for bonded eth_dev (opackets = burst_size) + * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0) + */ + TEST_ASSERT_EQUAL( + generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0), + burst_size, "generate_test_burst failed"); + + rte_eth_stats_reset(test_params->bonded_port_id); + + + TEST_ASSERT_EQUAL( + rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst, + burst_size), burst_size, "rte_eth_tx_burst failed"); + + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "Port (%d) opackets stats (%d) not expected (%d) value", + test_params->bonded_port_id, (int)port_stats.opackets, + burst_size); + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10, + "Port (%d) opackets stats (%d) not expected (%d) value", + test_params->slave_port_ids[0], (int)port_stats.opackets, 10); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0, + "Port (%d) opackets stats (%d) not expected (%d) value", + test_params->slave_port_ids[1], (int)port_stats.opackets, 0); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10, + "Port (%d) opackets stats (%d) not expected (%d) value", + test_params->slave_port_ids[2], (int)port_stats.opackets, 10); + + rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0, + "Port (%d) opackets stats (%d) not expected (%d) value", + test_params->slave_port_ids[3], (int)port_stats.opackets, 0); + + /* Verify that pkts are not sent on slaves with link status down: + * + * 1. Generate test bursts of traffic + * 2. Add bursts on to virtual eth_devs + * 3. Rx burst on bonded eth_dev, expected (burst_ size * + * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received + * 4. Verify stats for bonded eth_dev + * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0) + */ + for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) { + TEST_ASSERT_EQUAL(generate_test_burst( + &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), + burst_size, "failed to generate packet burst"); + + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &gen_pkt_burst[i][0], burst_size); + } + + TEST_ASSERT_EQUAL(rte_eth_rx_burst( + test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), + burst_size + burst_size, + "rte_eth_rx_burst failed"); + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size), + "(%d) port_stats.ipackets not as expected\n", + test_params->bonded_port_id); + + /* free mbufs */ + for (i = 0; i < MAX_PKT_BURST; i++) { + if (rx_pkt_burst[i] != NULL) + rte_pktmbuf_free(rx_pkt_burst[i]); + + if (gen_pkt_burst[1][i] != NULL) + rte_pktmbuf_free(gen_pkt_burst[1][i]); + + if (gen_pkt_burst[3][i] != NULL) + rte_pktmbuf_free(gen_pkt_burst[1][i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2) + +uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 }; + + +int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 }; + +static int +test_roundrobin_verfiy_polling_slave_link_status_change(void) +{ + struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac; + char slave_name[RTE_ETH_NAME_MAX_LEN]; + + int i; + + for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) { + /* Generate slave name / MAC address */ + snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i); + mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i; + + /* Create slave devices with no ISR Support */ + if (polling_test_slaves[i] == -1) { + polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr, + rte_socket_id(), 0); + TEST_ASSERT(polling_test_slaves[i] >= 0, + "Failed to create virtual virtual ethdev %s\n", slave_name); + + /* Configure slave */ + TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0), + "Failed to configure virtual ethdev %s(%d)", slave_name, + polling_test_slaves[i]); + } + + /* Add slave to bonded device */ + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id, + polling_test_slaves[i]), + "Failed to add slave %s(%d) to bonded device %d", + slave_name, polling_test_slaves[i], + test_params->bonded_port_id); + } + + /* Initialize bonded device */ + TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1), + "Failed to configure bonded device %d", + test_params->bonded_port_id); + + + /* Register link status change interrupt callback */ + rte_eth_dev_callback_register(test_params->bonded_port_id, + RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, + &test_params->bonded_port_id); + + /* link status change callback for first slave link up */ + test_lsc_interrupt_count = 0; + + virtual_ethdev_set_link_status(polling_test_slaves[0], 1); + + TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt"); + + + /* no link status change callback for second slave link up */ + test_lsc_interrupt_count = 0; + + virtual_ethdev_set_link_status(polling_test_slaves[1], 1); + + TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded"); + + /* link status change callback for both slave links down */ + test_lsc_interrupt_count = 0; + + virtual_ethdev_set_link_status(polling_test_slaves[0], 0); + virtual_ethdev_set_link_status(polling_test_slaves[1], 0); + + TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt"); + + /* Un-Register link status change interrupt callback */ + rte_eth_dev_callback_unregister(test_params->bonded_port_id, + RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, + &test_params->bonded_port_id); + + + /* Clean up and remove slaves from bonded device */ + for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) { + + TEST_ASSERT_SUCCESS( + rte_eth_bond_slave_remove(test_params->bonded_port_id, + polling_test_slaves[i]), + "Failed to remove slave %d from bonded port (%d)", + polling_test_slaves[i], test_params->bonded_port_id); + } + + return remove_slaves_and_stop_bonded_device(); +} + + +/** Active Backup Mode Tests */ + +static int +test_activebackup_tx_burst(void) +{ + int i, pktlen, primary_port, burst_size; + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + struct rte_eth_stats port_stats; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1), + "Failed to initialize bonded device with slaves"); + + initialize_eth_header(test_params->pkt_eth_hdr, + (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, + ETHER_TYPE_IPv4, 0, 0); + pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, + dst_port_0, 16); + pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, + dst_addr_0, pktlen); + + burst_size = 20 * test_params->bonded_slave_count; + + TEST_ASSERT(burst_size < MAX_PKT_BURST, + "Burst size specified is greater than supported."); + + /* Generate a burst of packets to transmit */ + TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst, + test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, + test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1), + burst_size, "failed to generate burst correctly"); + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst, + burst_size), burst_size, "tx burst failed"); + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "Bonded Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + burst_size); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + + /* Verify slave ports tx stats */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); + if (test_params->slave_port_ids[i] == primary_port) { + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, + (unsigned int)port_stats.opackets, + burst_size / test_params->bonded_slave_count); + } else { + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, + (unsigned int)port_stats.opackets, 0); + } + } + + /* Put all slaves down and try and transmit */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 0); + } + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, + pkts_burst, burst_size), 0, "Sending empty burst failed"); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4) + +static int +test_activebackup_rx_burst(void) +{ + struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + + struct rte_eth_stats port_stats; + + int primary_port; + + int i, j, burst_size = 17; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ACTIVE_BACKUP, 0, + TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1), + "Failed to initialize bonded device with slaves"); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT(primary_port >= 0, + "failed to get primary slave for bonded port (%d)", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + /* Generate test bursts of packets to transmit */ + TEST_ASSERT_EQUAL(generate_test_burst( + &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), + burst_size, "burst generation failed"); + + /* Add rx data to slave */ + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &gen_pkt_burst[0], burst_size); + + /* Call rx burst on bonded device */ + TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0, + &rx_pkt_burst[0], MAX_PKT_BURST), burst_size, + "rte_eth_rx_burst failed"); + + if (test_params->slave_port_ids[i] == primary_port) { + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, + "Bonded Port (%d) ipackets value (%u) not as expected (%d)", + test_params->bonded_port_id, + (unsigned int)port_stats.ipackets, burst_size); + + /* Verify bonded slave devices rx count */ + for (j = 0; j < test_params->bonded_slave_count; j++) { + rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); + if (i == j) { + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, + "Slave Port (%d) ipackets value (%u) not as " + "expected (%d)", test_params->slave_port_ids[i], + (unsigned int)port_stats.ipackets, burst_size); + } else { + TEST_ASSERT_EQUAL(port_stats.ipackets, 0, + "Slave Port (%d) ipackets value (%u) not as " + "expected (%d)\n", test_params->slave_port_ids[i], + (unsigned int)port_stats.ipackets, 0); + } + } + } else { + for (j = 0; j < test_params->bonded_slave_count; j++) { + rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, 0, + "Slave Port (%d) ipackets value (%u) not as expected " + "(%d)", test_params->slave_port_ids[i], + (unsigned int)port_stats.ipackets, 0); + } + } + + /* free mbufs */ + for (i = 0; i < MAX_PKT_BURST; i++) { + if (rx_pkt_burst[i] != NULL) { + rte_pktmbuf_free(rx_pkt_burst[i]); + rx_pkt_burst[i] = NULL; + } + } + + /* reset bonded device stats */ + rte_eth_stats_reset(test_params->bonded_port_id); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_activebackup_verify_promiscuous_enable_disable(void) +{ + int i, primary_port, promiscuous_en; + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1), + "Failed to initialize bonded device with slaves"); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT(primary_port >= 0, + "failed to get primary slave for bonded port (%d)", + test_params->bonded_port_id); + + rte_eth_promiscuous_enable(test_params->bonded_port_id); + + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, + "Port (%d) promiscuous mode not enabled", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + promiscuous_en = rte_eth_promiscuous_get( + test_params->slave_port_ids[i]); + if (primary_port == test_params->slave_port_ids[i]) { + TEST_ASSERT_EQUAL(promiscuous_en, 1, + "slave port (%d) promiscuous mode not enabled", + test_params->slave_port_ids[i]); + } else { + TEST_ASSERT_EQUAL(promiscuous_en, 0, + "slave port (%d) promiscuous mode enabled", + test_params->slave_port_ids[i]); + } + + } + + rte_eth_promiscuous_disable(test_params->bonded_port_id); + + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, + "Port (%d) promiscuous mode not disabled\n", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + promiscuous_en = rte_eth_promiscuous_get( + test_params->slave_port_ids[i]); + TEST_ASSERT_EQUAL(promiscuous_en, 0, + "slave port (%d) promiscuous mode not disabled\n", + test_params->slave_port_ids[i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_activebackup_verify_mac_assignment(void) +{ + struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1; + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); + rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1); + + /* Initialize bonded device with 2 slaves in active backup mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1), + "Failed to initialize bonded device with slaves"); + + /* Verify that bonded MACs is that of first slave and that the other slave + * MAC hasn't been changed */ + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected", + test_params->slave_port_ids[1]); + + /* change primary and verify that MAC addresses haven't changed */ + TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id, + test_params->slave_port_ids[1]), 0, + "Failed to set bonded port (%d) primary port to (%d)", + test_params->bonded_port_id, test_params->slave_port_ids[1]); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected", + test_params->slave_port_ids[1]); + + /* stop / start bonded device and verify that primary MAC address is + * propagated to bonded device and slaves */ + + rte_eth_dev_stop(test_params->bonded_port_id); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), + "Failed to start device"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[1]); + + /* Set explicit MAC address */ + TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( + test_params->bonded_port_id, (struct ether_addr *)bonded_mac), + "failed to set MAC address"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of bonded port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of bonded port", + test_params->slave_port_ids[1]); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_activebackup_verify_slave_link_status_change_failover(void) +{ + struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_eth_stats port_stats; + + uint8_t slaves[RTE_MAX_ETHPORTS]; + + int i, j, burst_size, slave_count, primary_port; + + burst_size = 21; + + memset(pkt_burst, 0, sizeof(pkt_burst)); + + /* Generate packet burst for testing */ + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, + "generate_test_burst failed"); + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ACTIVE_BACKUP, 0, + TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1), + "Failed to initialize bonded device with slaves"); + + /* Verify Current Slaves Count /Active Slave Count is */ + slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, + RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, 4, + "Number of slaves (%d) is not as expected (%d).", + slave_count, 4); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, 4, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 4); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0], + "Primary port not as expected"); + + /* Bring 2 slaves down and verify active slave count */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 0); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 0); + + TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 2); + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 1); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 1); + + + /* Bring primary port down, verify that active slave count is 3 and primary + * has changed */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[0], 0); + + TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), + 3, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 3); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2], + "Primary port not as expected"); + + /* Verify that pkts are sent on new primary slave */ + + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, &pkt_burst[0][0], + burst_size), burst_size, "rte_eth_tx_burst failed"); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[2]); + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "(%d) port_stats.opackets not as expected\n", + test_params->slave_port_ids[0]); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "(%d) port_stats.opackets not as expected\n", + test_params->slave_port_ids[1]); + + rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "(%d) port_stats.opackets not as expected\n", + test_params->slave_port_ids[3]); + + /* Generate packet burst for testing */ + + for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) { + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size, + "generate_test_burst failed"); + + virtual_ethdev_add_mbufs_to_rx_queue( + test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size); + } + + TEST_ASSERT_EQUAL(rte_eth_rx_burst( + test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), + burst_size, "rte_eth_rx_burst\n"); + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, + "(%d) port_stats.ipackets not as expected", + test_params->bonded_port_id); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[2]); + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[0]); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[1]); + + rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[3]); + + /* free mbufs */ + for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) { + for (j = 0; j < MAX_PKT_BURST; j++) { + if (pkt_burst[i][j] != NULL) { + rte_pktmbuf_free(pkt_burst[i][j]); + pkt_burst[i][j] = NULL; + } + } + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +/** Balance Mode Tests */ + +static int +test_balance_xmit_policy_configuration(void) +{ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1), + "Failed to initialize_bonded_device_with_slaves."); + + /* Invalid port id */ + TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set( + INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2), + "Expected call to failed as invalid port specified."); + + /* Set xmit policy on non bonded device */ + TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set( + test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2), + "Expected call to failed as invalid port specified."); + + + TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( + test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), + "Failed to set balance xmit policy."); + + TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), + BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected."); + + + TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( + test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23), + "Failed to set balance xmit policy."); + + TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), + BALANCE_XMIT_POLICY_LAYER23, + "balance xmit policy not as expected."); + + + TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( + test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34), + "Failed to set balance xmit policy."); + + TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), + BALANCE_XMIT_POLICY_LAYER34, + "balance xmit policy not as expected."); + + /* Invalid port id */ + TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID), + "Expected call to failed as invalid port specified."); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2) + +static int +test_balance_l2_tx_burst(void) +{ + struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; + int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 }; + + uint16_t pktlen; + int i; + struct rte_eth_stats port_stats; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1), + "Failed to initialize_bonded_device_with_slaves."); + + TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( + test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), + "Failed to set balance xmit policy."); + + initialize_eth_header(test_params->pkt_eth_hdr, + (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, + ETHER_TYPE_IPv4, 0, 0); + pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, + dst_port_0, 16); + pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, + dst_addr_0, pktlen); + + /* Generate a burst 1 of packets to transmit */ + TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0], + test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, + test_params->pkt_udp_hdr, burst_size[0], + PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0], + "failed to generate packet burst"); + + initialize_eth_header(test_params->pkt_eth_hdr, + (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, + ETHER_TYPE_IPv4, 0, 0); + + /* Generate a burst 2 of packets to transmit */ + TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0], + test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, + test_params->pkt_udp_hdr, burst_size[1], + PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1], + "failed to generate packet burst"); + + /* Send burst 1 on bonded port */ + for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) { + TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, + &pkts_burst[i][0], burst_size[i]), + burst_size[i], "Failed to transmit packet burst"); + } + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)(burst_size[0] + burst_size[1]), + "Bonded Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + burst_size[0] + burst_size[1]); + + + /* Verify slave ports tx stats */ + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0], + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, + burst_size[0]); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1], + "Slave Port (%d) opackets value (%u) not as expected (%d)\n", + test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, + burst_size[1]); + + /* Put all slaves down and try and transmit */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 0); + } + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]), + 0, "Expected zero packet"); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4, + uint8_t toggle_mac_addr, uint8_t toggle_ip_addr) +{ + int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2; + + struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST]; + struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST]; + + struct rte_eth_stats port_stats; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BALANCE, 0, 2, 1), + "Failed to initialize_bonded_device_with_slaves."); + + TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( + test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23), + "Failed to set balance xmit policy."); + + burst_size_1 = 20; + burst_size_2 = 10; + + TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST, + "Burst size specified is greater than supported."); + + /* Generate test bursts of packets to transmit */ + TEST_ASSERT_EQUAL(generate_test_burst( + pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0), + burst_size_1, "failed to generate packet burst"); + + TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4, + toggle_mac_addr, toggle_ip_addr, 0), burst_size_2, + "failed to generate packet burst"); + + /* Send burst 1 on bonded port */ + nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, + burst_size_1); + TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed"); + + /* Send burst 2 on bonded port */ + nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, + burst_size_2); + TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed"); + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2), + "Bonded Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + nb_tx_1 + nb_tx_2); + + /* Verify slave ports tx stats */ + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, + nb_tx_1); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, + nb_tx_2); + + /* Put all slaves down and try and transmit */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 0); + } + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, pkts_burst_1, + burst_size_1), 0, "Expected zero packet"); + + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void) +{ + return balance_l23_tx_burst(0, 1, 1, 0); +} + +static int +test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void) +{ + return balance_l23_tx_burst(1, 1, 0, 1); +} + +static int +test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void) +{ + return balance_l23_tx_burst(0, 0, 0, 1); +} + +static int +test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void) +{ + return balance_l23_tx_burst(1, 0, 0, 1); +} + +static int +test_balance_l23_tx_burst_toggle_mac_addr(void) +{ + return balance_l23_tx_burst(0, 0, 1, 0); +} + +static int +balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4, + uint8_t toggle_mac_addr, uint8_t toggle_ip_addr, + uint8_t toggle_udp_port) +{ + int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2; + + struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST]; + struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST]; + + struct rte_eth_stats port_stats; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BALANCE, 0, 2, 1), + "Failed to initialize_bonded_device_with_slaves."); + + TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( + test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34), + "Failed to set balance xmit policy."); + + burst_size_1 = 20; + burst_size_2 = 10; + + TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST, + "Burst size specified is greater than supported."); + + /* Generate test bursts of packets to transmit */ + TEST_ASSERT_EQUAL(generate_test_burst( + pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0), + burst_size_1, "failed to generate burst"); + + TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, + vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr, + toggle_udp_port), burst_size_2, "failed to generate burst"); + + /* Send burst 1 on bonded port */ + nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, + burst_size_1); + TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed"); + + /* Send burst 2 on bonded port */ + nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, + burst_size_2); + TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed"); + + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2), + "Bonded Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + nb_tx_1 + nb_tx_2); + + /* Verify slave ports tx stats */ + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, + nb_tx_1); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, + nb_tx_2); + + /* Put all slaves down and try and transmit */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 0); + } + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, pkts_burst_1, + burst_size_1), 0, "Expected zero packet"); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void) +{ + return balance_l34_tx_burst(0, 1, 0, 1, 0); +} + +static int +test_balance_l34_tx_burst_ipv4_toggle_udp_port(void) +{ + return balance_l34_tx_burst(0, 1, 0, 0, 1); +} + +static int +test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void) +{ + return balance_l34_tx_burst(1, 1, 0, 1, 0); +} + +static int +test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void) +{ + return balance_l34_tx_burst(0, 0, 0, 1, 0); +} + +static int +test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void) +{ + return balance_l34_tx_burst(1, 0, 0, 1, 0); +} + +static int +test_balance_l34_tx_burst_ipv6_toggle_udp_port(void) +{ + return balance_l34_tx_burst(0, 0, 0, 0, 1); +} + +#define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2) +#define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40) +#define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20) +#define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25) +#define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0) + +static int +test_balance_tx_burst_slave_tx_fail(void) +{ + struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1]; + struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2]; + + struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT]; + + struct rte_eth_stats port_stats; + + int i, first_tx_fail_idx, tx_count_1, tx_count_2; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BALANCE, 0, + TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1), + "Failed to intialise bonded device"); + + TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( + test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), + "Failed to set balance xmit policy."); + + + /* Generate test bursts for transmission */ + TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1, + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0), + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, + "Failed to generate test packet burst 1"); + + first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; + + /* copy mbuf referneces for expected transmission failures */ + for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++) + expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx]; + + TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0), + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, + "Failed to generate test packet burst 2"); + + + /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail + * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */ + virtual_ethdev_tx_burst_fn_set_success( + test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], + 0); + + virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( + test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); + + + /* Transmit burst 1 */ + tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1); + + TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, + "Transmitted (%d) packets, expected to transmit (%d) packets", + tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); + + /* Verify that failed packet are expected failed packets */ + for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) { + TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1], + "expected mbuf (%d) pointer %p not expected pointer %p", + i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]); + } + + /* Transmit burst 2 */ + tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); + + TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, + "Transmitted (%d) packets, expected to transmit (%d) packets", + tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); + + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) + + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2), + "Bonded Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) + + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); + + /* Verify slave ports tx stats */ + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t) + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->slave_port_ids[0], + (unsigned int)port_stats.opackets, + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); + + + + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, + "Slave Port (%d) opackets value (%u) not as expected (%d)", + test_params->slave_port_ids[1], + (unsigned int)port_stats.opackets, + TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); + + /* Verify that all mbufs have a ref value of zero */ + TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1], + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1), + "mbufs refcnts not as expected"); + + free_mbufs(&pkts_burst_1[tx_count_1], + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3) + +static int +test_balance_rx_burst(void) +{ + struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; + + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_eth_stats port_stats; + + int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 }; + int i, j; + + memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BALANCE, 0, 3, 1), + "Failed to intialise bonded device"); + + /* Generate test bursts of packets to transmit */ + for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { + TEST_ASSERT_EQUAL(generate_test_burst( + &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, + 0, 0), burst_size[i], + "failed to generate packet burst"); + } + + /* Add rx data to slaves */ + for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &gen_pkt_burst[i][0], burst_size[i]); + } + + /* Call rx burst on bonded device */ + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0, + rx_pkt_burst, MAX_PKT_BURST), + burst_size[0] + burst_size[1] + burst_size[2], + "balance rx burst failed\n"); + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, + (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), + "Bonded Port (%d) ipackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.ipackets, + burst_size[0] + burst_size[1] + burst_size[2]); + + + /* Verify bonded slave devices rx counts */ + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[0], + (unsigned int)port_stats.ipackets, burst_size[0]); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets, + burst_size[1]); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets, + burst_size[2]); + + rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, 0, + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets, + 0); + + /* free mbufs */ + for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { + for (j = 0; j < MAX_PKT_BURST; j++) { + if (gen_pkt_burst[i][j] != NULL) { + rte_pktmbuf_free(gen_pkt_burst[i][j]); + gen_pkt_burst[i][j] = NULL; + } + } + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_balance_verify_promiscuous_enable_disable(void) +{ + int i; + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BALANCE, 0, 4, 1), + "Failed to intialise bonded device"); + + rte_eth_promiscuous_enable(test_params->bonded_port_id); + + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, + "Port (%d) promiscuous mode not enabled", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( + test_params->slave_port_ids[i]), 1, + "Port (%d) promiscuous mode not enabled", + test_params->slave_port_ids[i]); + } + + rte_eth_promiscuous_disable(test_params->bonded_port_id); + + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, + "Port (%d) promiscuous mode not disabled", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( + test_params->slave_port_ids[i]), 0, + "Port (%d) promiscuous mode not disabled", + test_params->slave_port_ids[i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_balance_verify_mac_assignment(void) +{ + struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1; + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); + rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1); + + /* Initialize bonded device with 2 slaves in active backup mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BALANCE, 0, 2, 1), + "Failed to intialise bonded device"); + + /* Verify that bonded MACs is that of first slave and that the other slave + * MAC hasn't been changed */ + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[1]); + + /* change primary and verify that MAC addresses haven't changed */ + TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, + test_params->slave_port_ids[1]), + "Failed to set bonded port (%d) primary port to (%d)\n", + test_params->bonded_port_id, test_params->slave_port_ids[1]); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[1]); + + /* stop / start bonded device and verify that primary MAC address is + * propagated to bonded device and slaves */ + + rte_eth_dev_stop(test_params->bonded_port_id); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), + "Failed to start bonded device"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[1]); + + /* Set explicit MAC address */ + TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( + test_params->bonded_port_id, (struct ether_addr *)bonded_mac), + "failed to set MAC"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of bonded port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected\n", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of bonded port", + test_params->slave_port_ids[1]); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4) + +static int +test_balance_verify_slave_link_status_change_behaviour(void) +{ + struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST]; + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_eth_stats port_stats; + + uint8_t slaves[RTE_MAX_ETHPORTS]; + + int i, j, burst_size, slave_count; + + memset(pkt_burst, 0, sizeof(pkt_burst)); + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1), + "Failed to intialise bonded device"); + + TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( + test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), + "Failed to set balance xmit policy."); + + + /* Verify Current Slaves Count /Active Slave Count is */ + slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, + RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, + "Number of slaves (%d) is not as expected (%d).", + slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT); + + /* Set 2 slaves link status to down */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 0); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 0); + + TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 2); + + /* Send to sets of packet burst and verify that they are balanced across + * slaves */ + burst_size = 21; + + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, + "generate_test_burst failed"); + + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size, + "generate_test_burst failed"); + + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), + burst_size, "rte_eth_tx_burst failed"); + + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size), + burst_size, "rte_eth_tx_burst failed"); + + + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size), + "(%d) port_stats.opackets (%d) not as expected (%d).", + test_params->bonded_port_id, (int)port_stats.opackets, + burst_size + burst_size); + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "(%d) port_stats.opackets (%d) not as expected (%d).", + test_params->slave_port_ids[0], (int)port_stats.opackets, + burst_size); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "(%d) port_stats.opackets (%d) not as expected (%d).", + test_params->slave_port_ids[2], (int)port_stats.opackets, + burst_size); + + /* verify that all packets get send on primary slave when no other slaves + * are available */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[2], 0); + + TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 1); + + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size, + "generate_test_burst failed"); + + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size), + burst_size, "rte_eth_tx_burst failed"); + + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)(burst_size + burst_size + burst_size), + "(%d) port_stats.opackets (%d) not as expected (%d).\n", + test_params->bonded_port_id, (int)port_stats.opackets, + burst_size + burst_size + burst_size); + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size), + "(%d) port_stats.opackets (%d) not as expected (%d).", + test_params->slave_port_ids[0], (int)port_stats.opackets, + burst_size + burst_size); + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[0], 0); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 1); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[2], 1); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 1); + + for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) { + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size, + "Failed to generate packet burst"); + + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &pkt_burst[i][0], burst_size); + } + + /* Verify that pkts are not received on slaves with link status down */ + + rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, + MAX_PKT_BURST); + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3), + "(%d) port_stats.ipackets (%d) not as expected (%d)\n", + test_params->bonded_port_id, (int)port_stats.ipackets, + burst_size * 3); + + /* free mbufs allocate for rx testing */ + for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { + for (j = 0; j < MAX_PKT_BURST; j++) { + if (pkt_burst[i][j] != NULL) { + rte_pktmbuf_free(pkt_burst[i][j]); + pkt_burst[i][j] = NULL; + } + } + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_broadcast_tx_burst(void) +{ + int i, pktlen, burst_size; + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + + struct rte_eth_stats port_stats; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BROADCAST, 0, 2, 1), + "Failed to intialise bonded device"); + + initialize_eth_header(test_params->pkt_eth_hdr, + (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, + ETHER_TYPE_IPv4, 0, 0); + + pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, + dst_port_0, 16); + pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, + dst_addr_0, pktlen); + + burst_size = 20 * test_params->bonded_slave_count; + + TEST_ASSERT(burst_size < MAX_PKT_BURST, + "Burst size specified is greater than supported."); + + /* Generate a burst of packets to transmit */ + TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, + pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, + 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, + 1), burst_size, "Failed to generate packet burst"); + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, + pkts_burst, burst_size), burst_size, + "Bonded Port (%d) rx burst failed, packets transmitted value " + "not as expected (%d)", + test_params->bonded_port_id, burst_size); + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)burst_size * test_params->bonded_slave_count, + "Bonded Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + burst_size); + + /* Verify slave ports tx stats */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "Slave Port (%d) opackets value (%u) not as expected (%d)\n", + test_params->bonded_port_id, + (unsigned int)port_stats.opackets, burst_size); + } + + /* Put all slaves down and try and transmit */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 0); + } + + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, pkts_burst, burst_size), 0, + "transmitted an unexpected number of packets"); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + + +#define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3) +#define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40) +#define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15) +#define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10) + +static int +test_broadcast_tx_burst_slave_tx_fail(void) +{ + struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE]; + struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT]; + + struct rte_eth_stats port_stats; + + int i, tx_count; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BROADCAST, 0, + TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1), + "Failed to intialise bonded device"); + + /* Generate test bursts for transmission */ + TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst, + TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0), + TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, + "Failed to generate test packet burst"); + + for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) { + expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i]; + } + + /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail + * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */ + virtual_ethdev_tx_burst_fn_set_success( + test_params->slave_port_ids[0], + 0); + virtual_ethdev_tx_burst_fn_set_success( + test_params->slave_port_ids[1], + 0); + virtual_ethdev_tx_burst_fn_set_success( + test_params->slave_port_ids[2], + 0); + + virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( + test_params->slave_port_ids[0], + TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); + + virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( + test_params->slave_port_ids[1], + TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); + + virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( + test_params->slave_port_ids[2], + TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); + + /* Transmit burst */ + tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst, + TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE); + + TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, + "Transmitted (%d) packets, expected to transmit (%d) packets", + tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); + + /* Verify that failed packet are expected failed packets */ + for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) { + TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count], + "expected mbuf (%d) pointer %p not expected pointer %p", + i, expected_fail_pkts[i], pkts_burst[i + tx_count]); + } + + /* Verify slave ports tx stats */ + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT, + "Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); + + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, + "Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + + TEST_ASSERT_EQUAL(port_stats.opackets, + (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT, + "Port (%d) opackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.opackets, + TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - + TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); + + + /* Verify that all mbufs who transmission failed have a ref value of one */ + TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count], + TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1), + "mbufs refcnts not as expected"); + + free_mbufs(&pkts_burst[tx_count], + TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define BROADCAST_RX_BURST_NUM_OF_SLAVES (3) + +static int +test_broadcast_rx_burst(void) +{ + struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST]; + + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_eth_stats port_stats; + + int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 }; + int i, j; + + memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BROADCAST, 0, 3, 1), + "Failed to intialise bonded device"); + + /* Generate test bursts of packets to transmit */ + for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { + TEST_ASSERT_EQUAL(generate_test_burst( + &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0), + burst_size[i], "failed to generate packet burst"); + } + + /* Add rx data to slave 0 */ + for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &gen_pkt_burst[i][0], burst_size[i]); + } + + + /* Call rx burst on bonded device */ + /* Send burst on bonded port */ + TEST_ASSERT_EQUAL(rte_eth_rx_burst( + test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), + burst_size[0] + burst_size[1] + burst_size[2], + "rx burst failed"); + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, + (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), + "Bonded Port (%d) ipackets value (%u) not as expected (%d)", + test_params->bonded_port_id, (unsigned int)port_stats.ipackets, + burst_size[0] + burst_size[1] + burst_size[2]); + + + /* Verify bonded slave devices rx counts */ + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets, + burst_size[0]); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets, + burst_size[1]); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets, + burst_size[2]); + + rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, 0, + "Slave Port (%d) ipackets value (%u) not as expected (%d)", + test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets, + 0); + + /* free mbufs allocate for rx testing */ + for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { + for (j = 0; j < MAX_PKT_BURST; j++) { + if (gen_pkt_burst[i][j] != NULL) { + rte_pktmbuf_free(gen_pkt_burst[i][j]); + gen_pkt_burst[i][j] = NULL; + } + } + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_broadcast_verify_promiscuous_enable_disable(void) +{ + int i; + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BROADCAST, 0, 4, 1), + "Failed to intialise bonded device"); + + rte_eth_promiscuous_enable(test_params->bonded_port_id); + + + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, + "Port (%d) promiscuous mode not enabled", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( + test_params->slave_port_ids[i]), 1, + "Port (%d) promiscuous mode not enabled", + test_params->slave_port_ids[i]); + } + + rte_eth_promiscuous_disable(test_params->bonded_port_id); + + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, + "Port (%d) promiscuous mode not disabled", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( + test_params->slave_port_ids[i]), 0, + "Port (%d) promiscuous mode not disabled", + test_params->slave_port_ids[i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_broadcast_verify_mac_assignment(void) +{ + struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1; + + int i; + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); + rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1); + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BROADCAST, 0, 4, 1), + "Failed to intialise bonded device"); + + /* Verify that all MACs are the same as first slave added to bonded + * device */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[i]); + } + + /* change primary and verify that MAC addresses haven't changed */ + TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, + test_params->slave_port_ids[2]), + "Failed to set bonded port (%d) primary port to (%d)", + test_params->bonded_port_id, test_params->slave_port_ids[i]); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address has changed to that of primary " + "port without stop/start toggle of bonded device", + test_params->slave_port_ids[i]); + } + + /* stop / start bonded device and verify that primary MAC address is + * propagated to bonded device and slaves */ + + rte_eth_dev_stop(test_params->bonded_port_id); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), + "Failed to start bonded device"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of new primary port", + test_params->slave_port_ids[i]); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of new primary " + "port", test_params->slave_port_ids[i]); + } + + /* Set explicit MAC address */ + TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( + test_params->bonded_port_id, (struct ether_addr *)bonded_mac), + "Failed to set MAC address"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of new primary port", + test_params->slave_port_ids[i]); + + + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of new primary " + "port", test_params->slave_port_ids[i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4) +static int +test_broadcast_verify_slave_link_status_change_behaviour(void) +{ + struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST]; + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_eth_stats port_stats; + + uint8_t slaves[RTE_MAX_ETHPORTS]; + + int i, j, burst_size, slave_count; + + memset(pkt_burst, 0, sizeof(pkt_burst)); + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES, + 1), "Failed to intialise bonded device"); + + /* Verify Current Slaves Count /Active Slave Count is */ + slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, + RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, 4, + "Number of slaves (%d) is not as expected (%d).", + slave_count, 4); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, 4, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 4); + + /* Set 2 slaves link status to down */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 0); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 0); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, 2, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 2); + + for (i = 0; i < test_params->bonded_slave_count; i++) + rte_eth_stats_reset(test_params->slave_port_ids[i]); + + /* Verify that pkts are not sent on slaves with link status down */ + burst_size = 21; + + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size, + "generate_test_burst failed"); + + TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, + &pkt_burst[0][0], burst_size), burst_size, + "rte_eth_tx_burst failed\n"); + + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count), + "(%d) port_stats.opackets (%d) not as expected (%d)\n", + test_params->bonded_port_id, (int)port_stats.opackets, + burst_size * slave_count); + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[0]); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[1]); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[2]); + + + rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, 0, + "(%d) port_stats.opackets not as expected", + test_params->slave_port_ids[3]); + + + for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) { + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0), + burst_size, "failed to generate packet burst"); + + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &pkt_burst[i][0], burst_size); + } + + /* Verify that pkts are not received on slaves with link status down */ + TEST_ASSERT_EQUAL(rte_eth_rx_burst( + test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), + burst_size + burst_size, "rte_eth_rx_burst failed"); + + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size), + "(%d) port_stats.ipackets not as expected\n", + test_params->bonded_port_id); + + /* free mbufs allocate for rx testing */ + for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) { + for (j = 0; j < MAX_PKT_BURST; j++) { + if (pkt_burst[i][j] != NULL) { + rte_pktmbuf_free(pkt_burst[i][j]); + pkt_burst[i][j] = NULL; + } + } + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_reconfigure_bonded_device(void) +{ + test_params->nb_rx_q = 4; + test_params->nb_tx_q = 4; + + TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0), + "failed to reconfigure bonded device"); + + test_params->nb_rx_q = 2; + test_params->nb_tx_q = 2; + + TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0), + "failed to reconfigure bonded device with less rx/tx queues"); + + return 0; +} + + +static int +test_close_bonded_device(void) +{ + rte_eth_dev_close(test_params->bonded_port_id); + return 0; +} + +static void +testsuite_teardown(void) +{ + free(test_params->pkt_eth_hdr); + test_params->pkt_eth_hdr = NULL; + + /* Clean up and remove slaves from bonded device */ + remove_slaves_and_stop_bonded_device(); +} + +static void +free_virtualpmd_tx_queue(void) +{ + int i, slave_port, to_free_cnt; + struct rte_mbuf *pkts_to_free[MAX_PKT_BURST]; + + /* Free tx queue of virtual pmd */ + for (slave_port = 0; slave_port < test_params->bonded_slave_count; + slave_port++) { + to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue( + test_params->slave_port_ids[slave_port], + pkts_to_free, MAX_PKT_BURST); + for (i = 0; i < to_free_cnt; i++) + rte_pktmbuf_free(pkts_to_free[i]); + } +} + +static int +test_tlb_tx_burst(void) +{ + int i, burst_size, nb_tx; + uint64_t nb_tx2 = 0; + struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; + struct rte_eth_stats port_stats[32]; + uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0; + uint16_t pktlen; + + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves + (BONDING_MODE_TLB, 1, 3, 1), + "Failed to initialise bonded device"); + + burst_size = 20 * test_params->bonded_slave_count; + + TEST_ASSERT(burst_size < MAX_PKT_BURST, + "Burst size specified is greater than supported.\n"); + + + /* Generate bursts of packets */ + for (i = 0; i < 400000; i++) { + /*test two types of mac src own(bonding) and others */ + if (i % 2 == 0) { + initialize_eth_header(test_params->pkt_eth_hdr, + (struct ether_addr *)src_mac, + (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0); + } else { + initialize_eth_header(test_params->pkt_eth_hdr, + (struct ether_addr *)test_params->default_slave_mac, + (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0); + } + pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, + dst_port_0, 16); + pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, + dst_addr_0, pktlen); + generate_packet_burst(test_params->mbuf_pool, pkt_burst, + test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, + 1, test_params->pkt_udp_hdr, burst_size, 60, 1); + /* Send burst on bonded port */ + nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst, + burst_size); + nb_tx2 += nb_tx; + + free_virtualpmd_tx_queue(); + + TEST_ASSERT_EQUAL(nb_tx, burst_size, + "number of packet not equal burst size"); + + rte_delay_us(5); + } + + + /* Verify bonded port tx stats */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]); + + all_bond_opackets = port_stats[0].opackets; + all_bond_obytes = port_stats[0].obytes; + + TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2, + "Bonded Port (%d) opackets value (%u) not as expected (%d)\n", + test_params->bonded_port_id, (unsigned int)port_stats[0].opackets, + burst_size); + + + /* Verify slave ports tx stats */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]); + sum_ports_opackets += port_stats[i].opackets; + } + + TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets, + "Total packets sent by slaves is not equal to packets sent by bond interface"); + + /* checking if distribution of packets is balanced over slaves */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + TEST_ASSERT(port_stats[i].obytes > 0 && + port_stats[i].obytes < all_bond_obytes, + "Packets are not balanced over slaves"); + } + + /* Put all slaves down and try and transmit */ + for (i = 0; i < test_params->bonded_slave_count; i++) { + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[i], 0); + } + + /* Send burst on bonded port */ + nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst, + burst_size); + TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst"); + + /* Clean ugit checkout masterp and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4) + +static int +test_tlb_rx_burst(void) +{ + struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + + struct rte_eth_stats port_stats; + + int primary_port; + + uint16_t i, j, nb_rx, burst_size = 17; + + /* Initialize bonded device with 4 slaves in transmit load balancing mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_TLB, + TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1), + "Failed to initialize bonded device"); + + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT(primary_port >= 0, + "failed to get primary slave for bonded port (%d)", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + /* Generate test bursts of packets to transmit */ + TEST_ASSERT_EQUAL(generate_test_burst( + &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size, + "burst generation failed"); + + /* Add rx data to slave */ + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], + &gen_pkt_burst[0], burst_size); + + /* Call rx burst on bonded device */ + nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, + &rx_pkt_burst[0], MAX_PKT_BURST); + + TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n"); + + if (test_params->slave_port_ids[i] == primary_port) { + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, + "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n", + test_params->bonded_port_id, + (unsigned int)port_stats.ipackets, burst_size); + + /* Verify bonded slave devices rx count */ + for (j = 0; j < test_params->bonded_slave_count; j++) { + rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); + if (i == j) { + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, + "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", + test_params->slave_port_ids[i], + (unsigned int)port_stats.ipackets, burst_size); + } else { + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0, + "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", + test_params->slave_port_ids[i], + (unsigned int)port_stats.ipackets, 0); + } + } + } else { + for (j = 0; j < test_params->bonded_slave_count; j++) { + rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0, + "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", + test_params->slave_port_ids[i], + (unsigned int)port_stats.ipackets, 0); + } + } + + /* free mbufs */ + for (i = 0; i < burst_size; i++) + rte_pktmbuf_free(rx_pkt_burst[i]); + + /* reset bonded device stats */ + rte_eth_stats_reset(test_params->bonded_port_id); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_tlb_verify_promiscuous_enable_disable(void) +{ + int i, primary_port, promiscuous_en; + + /* Initialize bonded device with 4 slaves in transmit load balancing mode */ + TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves( + BONDING_MODE_TLB, 0, 4, 1), + "Failed to initialize bonded device"); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT(primary_port >= 0, + "failed to get primary slave for bonded port (%d)", + test_params->bonded_port_id); + + rte_eth_promiscuous_enable(test_params->bonded_port_id); + + promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(promiscuous_en, (int)1, + "Port (%d) promiscuous mode not enabled\n", + test_params->bonded_port_id); + for (i = 0; i < test_params->bonded_slave_count; i++) { + promiscuous_en = rte_eth_promiscuous_get( + test_params->slave_port_ids[i]); + if (primary_port == test_params->slave_port_ids[i]) { + TEST_ASSERT_EQUAL(promiscuous_en, (int)1, + "Port (%d) promiscuous mode not enabled\n", + test_params->bonded_port_id); + } else { + TEST_ASSERT_EQUAL(promiscuous_en, (int)0, + "Port (%d) promiscuous mode enabled\n", + test_params->bonded_port_id); + } + + } + + rte_eth_promiscuous_disable(test_params->bonded_port_id); + + promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(promiscuous_en, (int)0, + "Port (%d) promiscuous mode not disabled\n", + test_params->bonded_port_id); + + for (i = 0; i < test_params->bonded_slave_count; i++) { + promiscuous_en = rte_eth_promiscuous_get( + test_params->slave_port_ids[i]); + TEST_ASSERT_EQUAL(promiscuous_en, (int)0, + "slave port (%d) promiscuous mode not disabled\n", + test_params->slave_port_ids[i]); + } + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_tlb_verify_mac_assignment(void) +{ + struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1; + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0); + rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1); + + /* Initialize bonded device with 2 slaves in active backup mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_TLB, 0, 2, 1), + "Failed to initialize bonded device"); + + /* Verify that bonded MACs is that of first slave and that the other slave + * MAC hasn't been changed */ + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected", + test_params->slave_port_ids[1]); + + /* change primary and verify that MAC addresses haven't changed */ + TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id, + test_params->slave_port_ids[1]), 0, + "Failed to set bonded port (%d) primary port to (%d)", + test_params->bonded_port_id, test_params->slave_port_ids[1]); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected", + test_params->slave_port_ids[1]); + + /* stop / start bonded device and verify that primary MAC address is + * propagated to bonded device and slaves */ + + rte_eth_dev_stop(test_params->bonded_port_id); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), + "Failed to start device"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of primary port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of primary port", + test_params->slave_port_ids[1]); + + + /* Set explicit MAC address */ + TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( + test_params->bonded_port_id, (struct ether_addr *)bonded_mac), + "failed to set MAC addres"); + + rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "bonded port (%d) mac address not set to that of bonded port", + test_params->bonded_port_id); + + rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not as expected", + test_params->slave_port_ids[0]); + + rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr); + TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, + sizeof(read_mac_addr)), + "slave port (%d) mac address not set to that of bonded port", + test_params->slave_port_ids[1]); + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +static int +test_tlb_verify_slave_link_status_change_failover(void) +{ + struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; + struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; + struct rte_eth_stats port_stats; + + uint8_t slaves[RTE_MAX_ETHPORTS]; + + int i, j, burst_size, slave_count, primary_port; + + burst_size = 21; + + memset(pkt_burst, 0, sizeof(pkt_burst)); + + + + /* Initialize bonded device with 4 slaves in round robin mode */ + TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( + BONDING_MODE_TLB, 0, + TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1), + "Failed to initialize bonded device with slaves"); + + /* Verify Current Slaves Count /Active Slave Count is */ + slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, + RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, 4, + "Number of slaves (%d) is not as expected (%d).\n", + slave_count, 4); + + slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, + slaves, RTE_MAX_ETHPORTS); + TEST_ASSERT_EQUAL(slave_count, (int)4, + "Number of slaves (%d) is not as expected (%d).\n", + slave_count, 4); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0], + "Primary port not as expected"); + + /* Bring 2 slaves down and verify active slave count */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 0); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 0); + + TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 2); + + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[1], 1); + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[3], 1); + + + /* Bring primary port down, verify that active slave count is 3 and primary + * has changed */ + virtual_ethdev_simulate_link_status_interrupt( + test_params->slave_port_ids[0], 0); + + TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( + test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3, + "Number of active slaves (%d) is not as expected (%d).", + slave_count, 3); + + primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); + TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2], + "Primary port not as expected"); + rte_delay_us(500000); + /* Verify that pkts are sent on new primary slave */ + for (i = 0; i < 4; i++) { + TEST_ASSERT_EQUAL(generate_test_burst( + &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, + "generate_test_burst failed\n"); + TEST_ASSERT_EQUAL(rte_eth_tx_burst( + test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size, + "rte_eth_tx_burst failed\n"); + rte_delay_us(11000); + } + + rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); + TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0, + "(%d) port_stats.opackets not as expected\n", + test_params->slave_port_ids[0]); + + rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); + TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, + "(%d) port_stats.opackets not as expected\n", + test_params->slave_port_ids[1]); + + rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); + TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, + "(%d) port_stats.opackets not as expected\n", + test_params->slave_port_ids[2]); + + rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); + TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, + "(%d) port_stats.opackets not as expected\n", + test_params->slave_port_ids[3]); + + + /* Generate packet burst for testing */ + + for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) { + if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) != + burst_size) + return -1; + + virtual_ethdev_add_mbufs_to_rx_queue( + test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size); + } + + if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, + MAX_PKT_BURST) != burst_size) { + printf("rte_eth_rx_burst\n"); + return -1; + + } + + /* Verify bonded device rx count */ + rte_eth_stats_get(test_params->bonded_port_id, &port_stats); + TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, + "(%d) port_stats.ipackets not as expected\n", + test_params->bonded_port_id); + + /* free mbufs */ + + for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) { + for (j = 0; j < MAX_PKT_BURST; j++) { + if (pkt_burst[i][j] != NULL) { + rte_pktmbuf_free(pkt_burst[i][j]); + pkt_burst[i][j] = NULL; + } + } + } + + + /* Clean up and remove slaves from bonded device */ + return remove_slaves_and_stop_bonded_device(); +} + +#define TEST_ALB_SLAVE_COUNT 2 + +static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1}; +static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2}; +static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3}; +static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4}; + +static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0); +static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1); +static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2); +static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3); +static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4); + +static int +test_alb_change_mac_in_reply_sent(void) +{ + struct rte_mbuf *pkt; + struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; + + struct ether_hdr *eth_pkt; + struct arp_hdr *arp_pkt; + + int slave_idx, nb_pkts, pkt_idx; + int retval = 0; + + struct ether_addr bond_mac, client_mac; + struct ether_addr *slave_mac1, *slave_mac2; + + TEST_ASSERT_SUCCESS( + initialize_bonded_device_with_slaves(BONDING_MODE_ALB, + 0, TEST_ALB_SLAVE_COUNT, 1), + "Failed to initialize_bonded_device_with_slaves."); + + /* Flush tx queue */ + rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); + for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; + slave_idx++) { + nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( + test_params->slave_port_ids[slave_idx], pkts_sent, + MAX_PKT_BURST); + } + + ether_addr_copy( + rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, + &bond_mac); + + /* + * Generating four packets with different mac and ip addresses and sending + * them through the bonding port. + */ + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, + 0); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1, + ARP_OP_REPLY); + rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); + + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, + 0); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2, + ARP_OP_REPLY); + rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); + + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, + 0); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3, + ARP_OP_REPLY); + rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); + + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, + 0); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4, + ARP_OP_REPLY); + rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); + + slave_mac1 = + rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs; + slave_mac2 = + rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs; + + /* + * Checking if packets are properly distributed on bonding ports. Packets + * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1. + */ + for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { + nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( + test_params->slave_port_ids[slave_idx], pkts_sent, + MAX_PKT_BURST); + + for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { + eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + + if (slave_idx%2 == 0) { + if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) { + retval = -1; + goto test_end; + } + } else { + if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) { + retval = -1; + goto test_end; + } + } + } + } + +test_end: + retval += remove_slaves_and_stop_bonded_device(); + return retval; +} + +static int +test_alb_reply_from_client(void) +{ + struct ether_hdr *eth_pkt; + struct arp_hdr *arp_pkt; + + struct rte_mbuf *pkt; + struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; + + int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0; + int retval = 0; + + struct ether_addr bond_mac, client_mac; + struct ether_addr *slave_mac1, *slave_mac2; + + TEST_ASSERT_SUCCESS( + initialize_bonded_device_with_slaves(BONDING_MODE_ALB, + 0, TEST_ALB_SLAVE_COUNT, 1), + "Failed to initialize_bonded_device_with_slaves."); + + /* Flush tx queue */ + rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); + for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { + nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( + test_params->slave_port_ids[slave_idx], pkts_sent, + MAX_PKT_BURST); + } + + ether_addr_copy( + rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, + &bond_mac); + + /* + * Generating four packets with different mac and ip addresses and placing + * them in the rx queue to be received by the bonding driver on rx_burst. + */ + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, + 0); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host, + ARP_OP_REPLY); + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, + 1); + + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, + 0); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host, + ARP_OP_REPLY); + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, + 1); + + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, + 0); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host, + ARP_OP_REPLY); + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, + 1); + + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0, + 0); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host, + ARP_OP_REPLY); + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, + 1); + + /* + * Issue rx_burst and tx_burst to force bonding driver to send update ARP + * packets to every client in alb table. + */ + rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST); + rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); + + slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs; + slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs; + + /* + * Checking if update ARP packets were properly send on slave ports. + */ + for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { + nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( + test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST); + nb_pkts_sum += nb_pkts; + + for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { + eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *); + arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr)); + + if (slave_idx%2 == 0) { + if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) { + retval = -1; + goto test_end; + } + } else { + if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) { + retval = -1; + goto test_end; + } + } + } + } + + /* Check if proper number of packets was send */ + if (nb_pkts_sum < 4) { + retval = -1; + goto test_end; + } + +test_end: + retval += remove_slaves_and_stop_bonded_device(); + return retval; +} + +static int +test_alb_receive_vlan_reply(void) +{ + struct ether_hdr *eth_pkt; + struct vlan_hdr *vlan_pkt; + struct arp_hdr *arp_pkt; + + struct rte_mbuf *pkt; + struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; + + int slave_idx, nb_pkts, pkt_idx; + int retval = 0; + + struct ether_addr bond_mac, client_mac; + + TEST_ASSERT_SUCCESS( + initialize_bonded_device_with_slaves(BONDING_MODE_ALB, + 0, TEST_ALB_SLAVE_COUNT, 1), + "Failed to initialize_bonded_device_with_slaves."); + + /* Flush tx queue */ + rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); + for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { + nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( + test_params->slave_port_ids[slave_idx], pkts_sent, + MAX_PKT_BURST); + } + + ether_addr_copy( + rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, + &bond_mac); + + /* + * Generating packet with double VLAN header and placing it in the rx queue. + */ + pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); + memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN); + eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0, + 0); + vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1)); + vlan_pkt->vlan_tci = rte_cpu_to_be_16(1); + vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN); + vlan_pkt = vlan_pkt+1; + vlan_pkt->vlan_tci = rte_cpu_to_be_16(2); + vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP); + arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1)); + initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host, + ARP_OP_REPLY); + virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, + 1); + + rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST); + rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); + + /* + * Checking if VLAN headers in generated ARP Update packet are correct. + */ + for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { + nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( + test_params->slave_port_ids[slave_idx], pkts_sent, + MAX_PKT_BURST); + + for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { + eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *); + vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1)); + if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) { + retval = -1; + goto test_end; + } + if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) { + retval = -1; + goto test_end; + } + vlan_pkt = vlan_pkt+1; + if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) { + retval = -1; + goto test_end; + } + if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) { + retval = -1; + goto test_end; + } + } + } + +test_end: + retval += remove_slaves_and_stop_bonded_device(); + return retval; +} + +static int +test_alb_ipv4_tx(void) +{ + int burst_size, retval, pkts_send; + struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; + + retval = 0; + + TEST_ASSERT_SUCCESS( + initialize_bonded_device_with_slaves(BONDING_MODE_ALB, + 0, TEST_ALB_SLAVE_COUNT, 1), + "Failed to initialize_bonded_device_with_slaves."); + + burst_size = 32; + + /* Generate test bursts of packets to transmit */ + if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) { + retval = -1; + goto test_end; + } + + /* + * Checking if ipv4 traffic is transmitted via TLB policy. + */ + pkts_send = rte_eth_tx_burst( + test_params->bonded_port_id, 0, pkt_burst, burst_size); + if (pkts_send != burst_size) { + retval = -1; + goto test_end; + } + +test_end: + retval += remove_slaves_and_stop_bonded_device(); + return retval; +} + +static struct unit_test_suite link_bonding_test_suite = { + .suite_name = "Link Bonding Unit Test Suite", + .setup = test_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE(test_create_bonded_device), + TEST_CASE(test_create_bonded_device_with_invalid_params), + TEST_CASE(test_add_slave_to_bonded_device), + TEST_CASE(test_add_slave_to_invalid_bonded_device), + TEST_CASE(test_remove_slave_from_bonded_device), + TEST_CASE(test_remove_slave_from_invalid_bonded_device), + TEST_CASE(test_get_slaves_from_bonded_device), + TEST_CASE(test_add_already_bonded_slave_to_bonded_device), + TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device), + TEST_CASE(test_start_bonded_device), + TEST_CASE(test_stop_bonded_device), + TEST_CASE(test_set_bonding_mode), + TEST_CASE(test_set_primary_slave), + TEST_CASE(test_set_explicit_bonded_mac), + TEST_CASE(test_set_bonded_port_initialization_mac_assignment), + TEST_CASE(test_status_interrupt), + TEST_CASE(test_adding_slave_after_bonded_device_started), + TEST_CASE(test_roundrobin_tx_burst), + TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail), + TEST_CASE(test_roundrobin_rx_burst_on_single_slave), + TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves), + TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable), + TEST_CASE(test_roundrobin_verify_mac_assignment), + TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour), + TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change), + TEST_CASE(test_activebackup_tx_burst), + TEST_CASE(test_activebackup_rx_burst), + TEST_CASE(test_activebackup_verify_promiscuous_enable_disable), + TEST_CASE(test_activebackup_verify_mac_assignment), + TEST_CASE(test_activebackup_verify_slave_link_status_change_failover), + TEST_CASE(test_balance_xmit_policy_configuration), + TEST_CASE(test_balance_l2_tx_burst), + TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr), + TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr), + TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr), + TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr), + TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr), + TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr), + TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port), + TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr), + TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr), + TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr), + TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port), + TEST_CASE(test_balance_tx_burst_slave_tx_fail), + TEST_CASE(test_balance_rx_burst), + TEST_CASE(test_balance_verify_promiscuous_enable_disable), + TEST_CASE(test_balance_verify_mac_assignment), + TEST_CASE(test_balance_verify_slave_link_status_change_behaviour), + TEST_CASE(test_tlb_tx_burst), + TEST_CASE(test_tlb_rx_burst), + TEST_CASE(test_tlb_verify_mac_assignment), + TEST_CASE(test_tlb_verify_promiscuous_enable_disable), + TEST_CASE(test_tlb_verify_slave_link_status_change_failover), + TEST_CASE(test_alb_change_mac_in_reply_sent), + TEST_CASE(test_alb_reply_from_client), + TEST_CASE(test_alb_receive_vlan_reply), + TEST_CASE(test_alb_ipv4_tx), + TEST_CASE(test_broadcast_tx_burst), + TEST_CASE(test_broadcast_tx_burst_slave_tx_fail), + TEST_CASE(test_broadcast_rx_burst), + TEST_CASE(test_broadcast_verify_promiscuous_enable_disable), + TEST_CASE(test_broadcast_verify_mac_assignment), + TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour), + TEST_CASE(test_reconfigure_bonded_device), + TEST_CASE(test_close_bonded_device), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + + +static int +test_link_bonding(void) +{ + return unit_test_suite_runner(&link_bonding_test_suite); +} + +REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding); diff --git a/test/test/test_link_bonding_mode4.c b/test/test/test_link_bonding_mode4.c new file mode 100644 index 0000000000..53caa3e980 --- /dev/null +++ b/test/test/test_link_bonding_mode4.c @@ -0,0 +1,1602 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "packet_burst_generator.h" + +#include "test.h" + +#define SLAVE_COUNT (4) + +#define RX_RING_SIZE 128 +#define TX_RING_SIZE 512 + +#define MBUF_CACHE_SIZE (250) +#define BURST_SIZE (32) + +#define TEST_RX_DESC_MAX (2048) +#define TEST_TX_DESC_MAX (2048) +#define MAX_PKT_BURST (32) +#define DEF_PKT_BURST (16) + +#define BONDED_DEV_NAME ("unit_test_mode4_bond_dev") + +#define SLAVE_DEV_NAME_FMT ("unit_test_mode4_slave_%d") +#define SLAVE_RX_QUEUE_FMT ("unit_test_mode4_slave_%d_rx") +#define SLAVE_TX_QUEUE_FMT ("unit_test_mode4_slave_%d_tx") + +#define INVALID_SOCKET_ID (-1) +#define INVALID_PORT_ID (0xFF) +#define INVALID_BONDING_MODE (-1) + +static const struct ether_addr slave_mac_default = { + { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } +}; + +static const struct ether_addr parnter_mac_default = { + { 0x22, 0xBB, 0xFF, 0xBB, 0x00, 0x00 } +}; + +static const struct ether_addr parnter_system = { + { 0x33, 0xFF, 0xBB, 0xFF, 0x00, 0x00 } +}; + +static const struct ether_addr slow_protocol_mac_addr = { + { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 } +}; + +struct slave_conf { + struct rte_ring *rx_queue; + struct rte_ring *tx_queue; + uint8_t port_id; + uint8_t bonded : 1; + + uint8_t lacp_parnter_state; +}; + +struct ether_vlan_hdr { + struct ether_hdr pkt_eth_hdr; + struct vlan_hdr vlan_hdr; +}; + +struct link_bonding_unittest_params { + uint8_t bonded_port_id; + struct slave_conf slave_ports[SLAVE_COUNT]; + + struct rte_mempool *mbuf_pool; +}; + +#define TEST_DEFAULT_SLAVE_COUNT RTE_DIM(test_params.slave_ports) +#define TEST_RX_SLAVE_COUT TEST_DEFAULT_SLAVE_COUNT +#define TEST_TX_SLAVE_COUNT TEST_DEFAULT_SLAVE_COUNT +#define TEST_MARKER_SLAVE_COUT TEST_DEFAULT_SLAVE_COUNT +#define TEST_EXPIRED_SLAVE_COUNT TEST_DEFAULT_SLAVE_COUNT +#define TEST_PROMISC_SLAVE_COUNT TEST_DEFAULT_SLAVE_COUNT + +static struct link_bonding_unittest_params test_params = { + .bonded_port_id = INVALID_PORT_ID, + .slave_ports = { [0 ... SLAVE_COUNT - 1] = { .port_id = INVALID_PORT_ID} }, + + .mbuf_pool = NULL, +}; + +static struct rte_eth_conf default_pmd_conf = { + .rxmode = { + .mq_mode = ETH_MQ_RX_NONE, + .max_rx_pkt_len = ETHER_MAX_LEN, + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled */ + .hw_ip_checksum = 0, /**< IP checksum offload enabled */ + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ + .hw_strip_crc = 0, /**< CRC stripped by hardware */ + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, + .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++) + +/* Macro for iterating over every port that can be used as a slave + * in this test. + * _i variable used as an index in test_params->slave_ports + * _slave pointer to &test_params->slave_ports[_idx] + */ +#define FOR_EACH_PORT(_i, _port) \ + FOR_EACH(_i, _port, test_params.slave_ports, \ + RTE_DIM(test_params.slave_ports)) + +/* Macro for iterating over every port that can be used as a slave + * in this test and satisfy given condition. + * + * _i variable used as an index in test_params->slave_ports + * _slave pointer to &test_params->slave_ports[_idx] + * _condition condition that need to be checked + */ +#define FOR_EACH_PORT_IF(_i, _port, _condition) FOR_EACH_PORT((_i), (_port)) \ + if (!!(_condition)) + +/* Macro for iterating over every port that is currently a slave of a bonded + * device. + * _i variable used as an index in test_params->slave_ports + * _slave pointer to &test_params->slave_ports[_idx] + * */ +#define FOR_EACH_SLAVE(_i, _slave) \ + FOR_EACH_PORT_IF(_i, _slave, (_slave)->bonded != 0) + +/* + * Returns packets from slaves TX queue. + * slave slave port + * buffer for packets + * size size of buffer + * return number of packets or negative error number + */ +static int +slave_get_pkts(struct slave_conf *slave, struct rte_mbuf **buf, uint16_t size) +{ + return rte_ring_dequeue_burst(slave->tx_queue, (void **)buf, size); +} + +/* + * Injects given packets into slaves RX queue. + * slave slave port + * buffer for packets + * size number of packets to be injected + * return number of queued packets or negative error number + */ +static int +slave_put_pkts(struct slave_conf *slave, struct rte_mbuf **buf, uint16_t size) +{ + return rte_ring_enqueue_burst(slave->rx_queue, (void **)buf, size); +} + +static uint16_t +bond_rx(struct rte_mbuf **buf, uint16_t size) +{ + return rte_eth_rx_burst(test_params.bonded_port_id, 0, buf, size); +} + +static uint16_t +bond_tx(struct rte_mbuf **buf, uint16_t size) +{ + return rte_eth_tx_burst(test_params.bonded_port_id, 0, buf, size); +} + +static void +free_pkts(struct rte_mbuf **pkts, uint16_t count) +{ + uint16_t i; + + for (i = 0; i < count; i++) { + if (pkts[i] != NULL) + rte_pktmbuf_free(pkts[i]); + } +} + +static int +configure_ethdev(uint8_t port_id, uint8_t start) +{ + TEST_ASSERT(rte_eth_dev_configure(port_id, 1, 1, &default_pmd_conf) == 0, + "Failed to configure device %u", port_id); + + TEST_ASSERT(rte_eth_rx_queue_setup(port_id, 0, RX_RING_SIZE, + rte_eth_dev_socket_id(port_id), NULL, test_params.mbuf_pool) == 0, + "Failed to setup rx queue."); + + TEST_ASSERT(rte_eth_tx_queue_setup(port_id, 0, TX_RING_SIZE, + rte_eth_dev_socket_id(port_id), NULL) == 0, + "Failed to setup tx queue."); + + if (start) { + TEST_ASSERT(rte_eth_dev_start(port_id) == 0, + "Failed to start device (%d).", port_id); + } + return 0; +} + +static int +add_slave(struct slave_conf *slave, uint8_t start) +{ + struct ether_addr addr, addr_check; + + /* Some sanity check */ + RTE_VERIFY(test_params.slave_ports <= slave && + slave - test_params.slave_ports < (int)RTE_DIM(test_params.slave_ports)); + RTE_VERIFY(slave->bonded == 0); + RTE_VERIFY(slave->port_id != INVALID_PORT_ID); + + ether_addr_copy(&slave_mac_default, &addr); + addr.addr_bytes[ETHER_ADDR_LEN - 1] = slave->port_id; + + rte_eth_dev_mac_addr_remove(slave->port_id, &addr); + + TEST_ASSERT_SUCCESS(rte_eth_dev_mac_addr_add(slave->port_id, &addr, 0), + "Failed to set slave MAC address"); + + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params.bonded_port_id, + slave->port_id), + "Failed to add slave (idx=%u, id=%u) to bonding (id=%u)", + (uint8_t)(slave - test_params.slave_ports), slave->port_id, + test_params.bonded_port_id); + + slave->bonded = 1; + if (start) { + TEST_ASSERT_SUCCESS(rte_eth_dev_start(slave->port_id), + "Failed to start slave %u", slave->port_id); + } + + rte_eth_macaddr_get(slave->port_id, &addr_check); + TEST_ASSERT_EQUAL(is_same_ether_addr(&addr, &addr_check), 1, + "Slave MAC address is not as expected"); + + RTE_VERIFY(slave->lacp_parnter_state == 0); + return 0; +} + +static int +remove_slave(struct slave_conf *slave) +{ + ptrdiff_t slave_idx = slave - test_params.slave_ports; + + RTE_VERIFY(test_params.slave_ports <= slave && + slave_idx < (ptrdiff_t)RTE_DIM(test_params.slave_ports)); + + RTE_VERIFY(slave->bonded == 1); + RTE_VERIFY(slave->port_id != INVALID_PORT_ID); + + TEST_ASSERT_EQUAL(rte_ring_count(slave->rx_queue), 0, + "Slave %u tx queue not empty while removing from bonding.", + slave->port_id); + + TEST_ASSERT_EQUAL(rte_ring_count(slave->rx_queue), 0, + "Slave %u tx queue not empty while removing from bonding.", + slave->port_id); + + TEST_ASSERT_EQUAL(rte_eth_bond_slave_remove(test_params.bonded_port_id, + slave->port_id), 0, + "Failed to remove slave (idx=%u, id=%u) from bonding (id=%u)", + (uint8_t)slave_idx, slave->port_id, + test_params.bonded_port_id); + + slave->bonded = 0; + slave->lacp_parnter_state = 0; + 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 external_sm) +{ + uint8_t i; + + RTE_VERIFY(test_params.bonded_port_id != INVALID_PORT_ID); + + for (i = 0; i < slave_count; i++) { + TEST_ASSERT_SUCCESS(add_slave(&test_params.slave_ports[i], 1), + "Failed to add port %u to bonded device.\n", + test_params.slave_ports[i].port_id); + } + + /* Reset mode 4 configuration */ + rte_eth_bond_8023ad_setup(test_params.bonded_port_id, NULL); + rte_eth_promiscuous_disable(test_params.bonded_port_id); + + 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; +} + +static int +remove_slaves_and_stop_bonded_device(void) +{ + struct slave_conf *slave; + int retval; + uint8_t slaves[RTE_MAX_ETHPORTS]; + uint8_t i; + + rte_eth_dev_stop(test_params.bonded_port_id); + + FOR_EACH_SLAVE(i, slave) + remove_slave(slave); + + retval = rte_eth_bond_slaves_get(test_params.bonded_port_id, slaves, + RTE_DIM(slaves)); + + TEST_ASSERT_EQUAL(retval, 0, + "Expected bonded device %u have 0 slaves but returned %d.", + test_params.bonded_port_id, retval); + + FOR_EACH_PORT(i, slave) { + rte_eth_dev_stop(slave->port_id); + + TEST_ASSERT(slave->bonded == 0, + "Port id=%u is still marked as enslaved.", slave->port_id); + } + + return TEST_SUCCESS; +} + +static int +test_setup(void) +{ + int retval, nb_mbuf_per_pool; + char name[RTE_ETH_NAME_MAX_LEN]; + struct slave_conf *port; + const uint8_t socket_id = rte_socket_id(); + uint8_t i; + + if (test_params.mbuf_pool == NULL) { + nb_mbuf_per_pool = TEST_RX_DESC_MAX + DEF_PKT_BURST + + TEST_TX_DESC_MAX + MAX_PKT_BURST; + test_params.mbuf_pool = rte_pktmbuf_pool_create("TEST_MODE4", + nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, + RTE_MBUF_DEFAULT_BUF_SIZE, socket_id); + + TEST_ASSERT(test_params.mbuf_pool != NULL, + "rte_mempool_create failed\n"); + } + + /* Create / initialize ring eth devs. */ + FOR_EACH_PORT(i, port) { + port = &test_params.slave_ports[i]; + + if (port->rx_queue == NULL) { + retval = snprintf(name, RTE_DIM(name), SLAVE_RX_QUEUE_FMT, i); + TEST_ASSERT(retval <= (int)RTE_DIM(name) - 1, "Name too long"); + port->rx_queue = rte_ring_create(name, RX_RING_SIZE, socket_id, 0); + TEST_ASSERT(port->rx_queue != NULL, + "Failed to allocate rx ring '%s': %s", name, + rte_strerror(rte_errno)); + } + + if (port->tx_queue == NULL) { + retval = snprintf(name, RTE_DIM(name), SLAVE_TX_QUEUE_FMT, i); + TEST_ASSERT(retval <= (int)RTE_DIM(name) - 1, "Name too long"); + port->tx_queue = rte_ring_create(name, TX_RING_SIZE, socket_id, 0); + TEST_ASSERT_NOT_NULL(port->tx_queue, + "Failed to allocate tx ring '%s': %s", name, + rte_strerror(rte_errno)); + } + + if (port->port_id == INVALID_PORT_ID) { + retval = snprintf(name, RTE_DIM(name), SLAVE_DEV_NAME_FMT, i); + TEST_ASSERT(retval < (int)RTE_DIM(name) - 1, "Name too long"); + retval = rte_eth_from_rings(name, &port->rx_queue, 1, + &port->tx_queue, 1, socket_id); + TEST_ASSERT(retval >= 0, + "Failed to create ring ethdev '%s'\n", name); + + port->port_id = rte_eth_dev_count() - 1; + } + + retval = configure_ethdev(port->port_id, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to configure virtual ethdev %s\n", + name); + } + + if (test_params.bonded_port_id == INVALID_PORT_ID) { + retval = rte_eth_bond_create(BONDED_DEV_NAME, BONDING_MODE_8023AD, + socket_id); + + TEST_ASSERT(retval >= 0, "Failed to create bonded ethdev %s", + BONDED_DEV_NAME); + + test_params.bonded_port_id = retval; + TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bonded_port_id, 0), + "Failed to configure bonded ethdev %s", BONDED_DEV_NAME); + } else if (rte_eth_bond_mode_get(test_params.bonded_port_id) != + BONDING_MODE_8023AD) { + TEST_ASSERT(rte_eth_bond_mode_set(test_params.bonded_port_id, + BONDING_MODE_8023AD) == 0, + "Failed to set ethdev %d to mode %d", + test_params.bonded_port_id, BONDING_MODE_8023AD); + } + + return 0; +} + +static void +testsuite_teardown(void) +{ + struct slave_conf *port; + uint8_t i; + + /* Only stop ports. + * Any cleanup/reset state is done when particular test is + * started. */ + + rte_eth_dev_stop(test_params.bonded_port_id); + + FOR_EACH_PORT(i, port) + rte_eth_dev_stop(port->port_id); +} + +/* + * Check if given LACP packet. If it is, make make replay packet to force + * COLLECTING state. + * return 0 when pkt is LACP frame, 1 if it is not slow frame, 2 if it is slow + * frame but not LACP + */ +static int +make_lacp_reply(struct slave_conf *slave, struct rte_mbuf *pkt) +{ + struct ether_hdr *hdr; + struct slow_protocol_frame *slow_hdr; + struct lacpdu *lacp; + + /* look for LACP */ + hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *); + if (hdr->ether_type != rte_cpu_to_be_16(ETHER_TYPE_SLOW)) + return 1; + + slow_hdr = rte_pktmbuf_mtod(pkt, struct slow_protocol_frame *); + /* ignore packets of other types */ + if (slow_hdr->slow_protocol.subtype != SLOW_SUBTYPE_LACP) + return 2; + + slow_hdr = rte_pktmbuf_mtod(pkt, struct slow_protocol_frame *); + + /* Change source address to partner address */ + ether_addr_copy(&parnter_mac_default, &slow_hdr->eth_hdr.s_addr); + slow_hdr->eth_hdr.s_addr.addr_bytes[ETHER_ADDR_LEN - 1] = slave->port_id; + + lacp = (struct lacpdu *) &slow_hdr->slow_protocol; + /* Save last received state */ + slave->lacp_parnter_state = lacp->actor.state; + /* Change it into LACP replay by matching parameters. */ + memcpy(&lacp->partner.port_params, &lacp->actor.port_params, + sizeof(struct port_params)); + + lacp->partner.state = lacp->actor.state; + + ether_addr_copy(&parnter_system, &lacp->actor.port_params.system); + lacp->actor.state = STATE_LACP_ACTIVE | + STATE_SYNCHRONIZATION | + STATE_AGGREGATION | + STATE_COLLECTING | + STATE_DISTRIBUTING; + + return 0; +} + +/* + * Reads packets from given slave, search for LACP packet and reply them. + * + * Receives burst of packets from slave. Looks for LACP packet. Drops + * all other packets. Prepares response LACP and sends it back. + * + * return number of LACP received and replied, -1 on error. + */ +static int +bond_handshake_reply(struct slave_conf *slave) +{ + int retval; + struct rte_mbuf *rx_buf[MAX_PKT_BURST]; + struct rte_mbuf *lacp_tx_buf[MAX_PKT_BURST]; + uint16_t lacp_tx_buf_cnt = 0, i; + + retval = slave_get_pkts(slave, rx_buf, RTE_DIM(rx_buf)); + TEST_ASSERT(retval >= 0, "Getting slave %u packets failed.", + slave->port_id); + + for (i = 0; i < (uint16_t)retval; i++) { + if (make_lacp_reply(slave, rx_buf[i]) == 0) { + /* reply with actor's LACP */ + lacp_tx_buf[lacp_tx_buf_cnt++] = rx_buf[i]; + } else + rte_pktmbuf_free(rx_buf[i]); + } + + if (lacp_tx_buf_cnt == 0) + return 0; + + retval = slave_put_pkts(slave, lacp_tx_buf, lacp_tx_buf_cnt); + if (retval <= lacp_tx_buf_cnt) { + /* retval might be negative */ + for (i = RTE_MAX(0, retval); retval < lacp_tx_buf_cnt; retval++) + rte_pktmbuf_free(lacp_tx_buf[i]); + } + + TEST_ASSERT_EQUAL(retval, lacp_tx_buf_cnt, + "Failed to equeue lacp packets into slave %u tx queue.", + slave->port_id); + + return lacp_tx_buf_cnt; +} + +/* + * Function check if given slave tx queue contains packets that make mode 4 + * handshake complete. It will drain slave queue. + * return 0 if handshake not completed, 1 if handshake was complete, + */ +static int +bond_handshake_done(struct slave_conf *slave) +{ + const uint8_t expected_state = STATE_LACP_ACTIVE | STATE_SYNCHRONIZATION | + STATE_AGGREGATION | STATE_COLLECTING | STATE_DISTRIBUTING; + + return slave->lacp_parnter_state == expected_state; +} + +static unsigned +bond_get_update_timeout_ms(void) +{ + struct rte_eth_bond_8023ad_conf conf; + + rte_eth_bond_8023ad_conf_get(test_params.bonded_port_id, &conf); + return conf.update_timeout_ms; +} + +/* + * Exchanges LACP packets with partner to achieve dynamic port configuration. + * return TEST_SUCCESS if initial handshake succeed, TEST_FAILED otherwise. + */ +static int +bond_handshake(void) +{ + struct slave_conf *slave; + struct rte_mbuf *buf[MAX_PKT_BURST]; + uint16_t nb_pkts; + uint8_t all_slaves_done, i, j; + uint8_t status[RTE_DIM(test_params.slave_ports)] = { 0 }; + const unsigned delay = bond_get_update_timeout_ms(); + + /* Exchange LACP frames */ + all_slaves_done = 0; + for (i = 0; i < 30 && all_slaves_done == 0; ++i) { + rte_delay_ms(delay); + + all_slaves_done = 1; + FOR_EACH_SLAVE(j, slave) { + /* If response already send, skip slave */ + if (status[j] != 0) + continue; + + if (bond_handshake_reply(slave) < 0) { + all_slaves_done = 0; + break; + } + + status[j] = bond_handshake_done(slave); + if (status[j] == 0) + all_slaves_done = 0; + } + + nb_pkts = bond_tx(NULL, 0); + TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets transmitted unexpectedly"); + + nb_pkts = bond_rx(buf, RTE_DIM(buf)); + free_pkts(buf, nb_pkts); + TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets received unexpectedly"); + } + /* If response didn't send - report failure */ + TEST_ASSERT_EQUAL(all_slaves_done, 1, "Bond handshake failed\n"); + + /* If flags doesn't match - report failure */ + return all_slaves_done = 1 ? TEST_SUCCESS : TEST_FAILED; +} + +#define TEST_LACP_SLAVE_COUT RTE_DIM(test_params.slave_ports) +static int +test_mode4_lacp(void) +{ + int retval; + + retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + /* Test LACP handshake function */ + retval = bond_handshake(); + TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); + + return TEST_SUCCESS; +} + +static int +generate_packets(struct ether_addr *src_mac, + struct ether_addr *dst_mac, uint16_t count, struct rte_mbuf **buf) +{ + uint16_t pktlen = PACKET_BURST_GEN_PKT_LEN; + uint8_t vlan_enable = 0; + uint16_t vlan_id = 0; + uint8_t ip4_type = 1; /* 0 - ipv6 */ + + uint16_t src_port = 10, dst_port = 20; + + uint32_t ip_src[4] = { [0 ... 2] = 0xDEADBEEF, [3] = IPv4(192, 168, 0, 1) }; + uint32_t ip_dst[4] = { [0 ... 2] = 0xFEEDFACE, [3] = IPv4(192, 168, 0, 2) }; + + struct ether_hdr pkt_eth_hdr; + struct udp_hdr pkt_udp_hdr; + union { + struct ipv4_hdr v4; + struct ipv6_hdr v6; + } pkt_ip_hdr; + + int retval; + + initialize_eth_header(&pkt_eth_hdr, src_mac, dst_mac, ip4_type, + vlan_enable, vlan_id); + + if (ip4_type) + initialize_ipv4_header(&pkt_ip_hdr.v4, ip_src[3], ip_dst[3], pktlen); + else + initialize_ipv6_header(&pkt_ip_hdr.v6, (uint8_t *)ip_src, + (uint8_t *)&ip_dst, pktlen); + + initialize_udp_header(&pkt_udp_hdr, src_port, dst_port, 16); + + retval = generate_packet_burst(test_params.mbuf_pool, buf, + &pkt_eth_hdr, vlan_enable, &pkt_ip_hdr, 1, &pkt_udp_hdr, + count, pktlen, 1); + + if (retval > 0 && retval != count) + free_pkts(&buf[count - retval], retval); + + TEST_ASSERT_EQUAL(retval, count, "Failed to generate %u packets", + count); + + return count; +} + +static int +generate_and_put_packets(struct slave_conf *slave, struct ether_addr *src_mac, + struct ether_addr *dst_mac, uint16_t count) +{ + struct rte_mbuf *pkts[MAX_PKT_BURST]; + int retval; + + retval = generate_packets(src_mac, dst_mac, count, pkts); + if (retval != (int)count) + return retval; + + retval = slave_put_pkts(slave, pkts, count); + if (retval > 0 && retval != count) + free_pkts(&pkts[retval], count - retval); + + TEST_ASSERT_EQUAL(retval, count, + "Failed to enqueue packets into slave %u RX queue", slave->port_id); + + return TEST_SUCCESS; +} + +static int +test_mode4_rx(void) +{ + struct slave_conf *slave; + uint16_t i, j; + + uint16_t expected_pkts_cnt; + struct rte_mbuf *pkts[MAX_PKT_BURST]; + int retval; + unsigned delay; + + struct ether_hdr *hdr; + + struct ether_addr src_mac = { { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } }; + struct ether_addr dst_mac; + struct ether_addr bonded_mac; + + retval = initialize_bonded_device_with_slaves(TEST_PROMISC_SLAVE_COUNT, + 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + retval = bond_handshake(); + TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); + + rte_eth_macaddr_get(test_params.bonded_port_id, &bonded_mac); + ether_addr_copy(&bonded_mac, &dst_mac); + + /* Assert that dst address is not bonding address. Do not set the + * least significant bit of the zero byte as this would create a + * multicast address. + */ + dst_mac.addr_bytes[0] += 2; + + /* First try with promiscuous mode enabled. + * Add 2 packets to each slave. First with bonding MAC address, second with + * different. Check if we received all of them. */ + rte_eth_promiscuous_enable(test_params.bonded_port_id); + + expected_pkts_cnt = 0; + FOR_EACH_SLAVE(i, slave) { + retval = generate_and_put_packets(slave, &src_mac, &bonded_mac, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to slave %u", + slave->port_id); + + retval = generate_and_put_packets(slave, &src_mac, &dst_mac, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to slave %u", + slave->port_id); + + /* Expect 2 packets per slave */ + expected_pkts_cnt += 2; + } + + retval = rte_eth_rx_burst(test_params.bonded_port_id, 0, pkts, + RTE_DIM(pkts)); + + if (retval == expected_pkts_cnt) { + int cnt[2] = { 0, 0 }; + + for (i = 0; i < expected_pkts_cnt; i++) { + hdr = rte_pktmbuf_mtod(pkts[i], struct ether_hdr *); + cnt[is_same_ether_addr(&hdr->d_addr, &bonded_mac)]++; + } + + free_pkts(pkts, expected_pkts_cnt); + + /* For division by 2 expected_pkts_cnt must be even */ + RTE_VERIFY((expected_pkts_cnt & 1) == 0); + TEST_ASSERT(cnt[0] == expected_pkts_cnt / 2 && + cnt[1] == expected_pkts_cnt / 2, + "Expected %u packets with the same MAC and %u with different but " + "got %u with the same and %u with diffrent MAC", + expected_pkts_cnt / 2, expected_pkts_cnt / 2, cnt[1], cnt[0]); + } else if (retval > 0) + free_pkts(pkts, retval); + + TEST_ASSERT_EQUAL(retval, expected_pkts_cnt, + "Expected %u packets but received only %d", expected_pkts_cnt, retval); + + /* Now, disable promiscuous mode. When promiscuous mode is disabled we + * expect to receive only packets that are directed to bonding port. */ + rte_eth_promiscuous_disable(test_params.bonded_port_id); + + expected_pkts_cnt = 0; + FOR_EACH_SLAVE(i, slave) { + retval = generate_and_put_packets(slave, &src_mac, &bonded_mac, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to slave %u", + slave->port_id); + + retval = generate_and_put_packets(slave, &src_mac, &dst_mac, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to slave %u", + slave->port_id); + + /* Expect only one packet per slave */ + expected_pkts_cnt += 1; + } + + retval = rte_eth_rx_burst(test_params.bonded_port_id, 0, pkts, + RTE_DIM(pkts)); + + if (retval == expected_pkts_cnt) { + int eq_cnt = 0; + + for (i = 0; i < expected_pkts_cnt; i++) { + hdr = rte_pktmbuf_mtod(pkts[i], struct ether_hdr *); + eq_cnt += is_same_ether_addr(&hdr->d_addr, &bonded_mac); + } + + free_pkts(pkts, expected_pkts_cnt); + TEST_ASSERT_EQUAL(eq_cnt, expected_pkts_cnt, "Packet address mismatch"); + } else if (retval > 0) + free_pkts(pkts, retval); + + TEST_ASSERT_EQUAL(retval, expected_pkts_cnt, + "Expected %u packets but received only %d", expected_pkts_cnt, retval); + + /* Link down test: simulate link down for first slave. */ + delay = bond_get_update_timeout_ms(); + + uint8_t slave_down_id = INVALID_PORT_ID; + + /* Find first slave and make link down on it*/ + FOR_EACH_SLAVE(i, slave) { + rte_eth_dev_set_link_down(slave->port_id); + slave_down_id = slave->port_id; + break; + } + + RTE_VERIFY(slave_down_id != INVALID_PORT_ID); + + /* Give some time to rearrange bonding */ + for (i = 0; i < 3; i++) { + rte_delay_ms(delay); + bond_handshake(); + } + + TEST_ASSERT_SUCCESS(bond_handshake(), "Handshake after link down failed"); + + /* Put packet to each slave */ + FOR_EACH_SLAVE(i, slave) { + void *pkt = NULL; + + dst_mac.addr_bytes[ETHER_ADDR_LEN - 1] = slave->port_id; + retval = generate_and_put_packets(slave, &src_mac, &dst_mac, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to generate test packet burst."); + + src_mac.addr_bytes[ETHER_ADDR_LEN - 1] = slave->port_id; + retval = generate_and_put_packets(slave, &src_mac, &bonded_mac, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to generate test packet burst."); + + retval = bond_rx(pkts, RTE_DIM(pkts)); + + /* Clean anything */ + if (retval > 0) + free_pkts(pkts, retval); + + while (rte_ring_dequeue(slave->rx_queue, (void **)&pkt) == 0) + rte_pktmbuf_free(pkt); + + if (slave_down_id == slave->port_id) + TEST_ASSERT_EQUAL(retval, 0, "Packets received unexpectedly."); + else + TEST_ASSERT_NOT_EQUAL(retval, 0, + "Expected to receive some packets on slave %u.", + slave->port_id); + rte_eth_dev_start(slave->port_id); + + for (j = 0; j < 5; j++) { + TEST_ASSERT(bond_handshake_reply(slave) >= 0, + "Handshake after link up"); + + if (bond_handshake_done(slave) == 1) + break; + } + + TEST_ASSERT(j < 5, "Failed to agregate slave after link up"); + } + + remove_slaves_and_stop_bonded_device(); + return TEST_SUCCESS; +} + +static int +test_mode4_tx_burst(void) +{ + struct slave_conf *slave; + uint16_t i, j; + + uint16_t exp_pkts_cnt, pkts_cnt = 0; + struct rte_mbuf *pkts[MAX_PKT_BURST]; + int retval; + unsigned delay; + + 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, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + retval = bond_handshake(); + TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); + + rte_eth_macaddr_get(test_params.bonded_port_id, &bonded_mac); + + /* Prepare burst */ + for (pkts_cnt = 0; pkts_cnt < RTE_DIM(pkts); pkts_cnt++) { + dst_mac.addr_bytes[ETHER_ADDR_LEN - 1] = pkts_cnt; + retval = generate_packets(&bonded_mac, &dst_mac, 1, &pkts[pkts_cnt]); + + if (retval != 1) + free_pkts(pkts, pkts_cnt); + + TEST_ASSERT_EQUAL(retval, 1, "Failed to generate packet %u", pkts_cnt); + } + exp_pkts_cnt = pkts_cnt; + + /* Transmit packets on bonded device */ + retval = bond_tx(pkts, pkts_cnt); + if (retval > 0 && retval < pkts_cnt) + free_pkts(&pkts[retval], pkts_cnt - retval); + + TEST_ASSERT_EQUAL(retval, pkts_cnt, "TX on bonded device failed"); + + /* Check if packets were transmitted properly. Every slave should have + * at least one packet, and sum must match. Under normal operation + * there should be no LACP nor MARKER frames. */ + pkts_cnt = 0; + FOR_EACH_SLAVE(i, slave) { + uint16_t normal_cnt, slow_cnt; + + retval = slave_get_pkts(slave, pkts, RTE_DIM(pkts)); + normal_cnt = 0; + slow_cnt = 0; + + for (j = 0; j < retval; j++) { + if (make_lacp_reply(slave, pkts[j]) == 1) + normal_cnt++; + else + slow_cnt++; + } + + free_pkts(pkts, normal_cnt + slow_cnt); + TEST_ASSERT_EQUAL(slow_cnt, 0, + "slave %u unexpectedly transmitted %d SLOW packets", slave->port_id, + slow_cnt); + + TEST_ASSERT_NOT_EQUAL(normal_cnt, 0, + "slave %u did not transmitted any packets", slave->port_id); + + pkts_cnt += normal_cnt; + } + + TEST_ASSERT_EQUAL(exp_pkts_cnt, pkts_cnt, + "Expected %u packets but transmitted only %d", exp_pkts_cnt, pkts_cnt); + + /* Link down test: + * simulate link down for first slave. */ + delay = bond_get_update_timeout_ms(); + + uint8_t slave_down_id = INVALID_PORT_ID; + + FOR_EACH_SLAVE(i, slave) { + rte_eth_dev_set_link_down(slave->port_id); + slave_down_id = slave->port_id; + break; + } + + RTE_VERIFY(slave_down_id != INVALID_PORT_ID); + + /* Give some time to rearrange bonding. */ + for (i = 0; i < 3; i++) { + bond_handshake(); + rte_delay_ms(delay); + } + + TEST_ASSERT_SUCCESS(bond_handshake(), "Handshake after link down failed"); + + /* Prepare burst. */ + for (pkts_cnt = 0; pkts_cnt < RTE_DIM(pkts); pkts_cnt++) { + dst_mac.addr_bytes[ETHER_ADDR_LEN - 1] = pkts_cnt; + retval = generate_packets(&bonded_mac, &dst_mac, 1, &pkts[pkts_cnt]); + + if (retval != 1) + free_pkts(pkts, pkts_cnt); + + TEST_ASSERT_EQUAL(retval, 1, "Failed to generate test packet %u", + pkts_cnt); + } + exp_pkts_cnt = pkts_cnt; + + /* Transmit packets on bonded device. */ + retval = bond_tx(pkts, pkts_cnt); + if (retval > 0 && retval < pkts_cnt) + free_pkts(&pkts[retval], pkts_cnt - retval); + + TEST_ASSERT_EQUAL(retval, pkts_cnt, "TX on bonded device failed"); + + /* Check if packets was transmitted properly. Every slave should have + * at least one packet, and sum must match. Under normal operation + * there should be no LACP nor MARKER frames. */ + pkts_cnt = 0; + FOR_EACH_SLAVE(i, slave) { + uint16_t normal_cnt, slow_cnt; + + retval = slave_get_pkts(slave, pkts, RTE_DIM(pkts)); + normal_cnt = 0; + slow_cnt = 0; + + for (j = 0; j < retval; j++) { + if (make_lacp_reply(slave, pkts[j]) == 1) + normal_cnt++; + else + slow_cnt++; + } + + free_pkts(pkts, normal_cnt + slow_cnt); + + if (slave_down_id == slave->port_id) { + TEST_ASSERT_EQUAL(normal_cnt + slow_cnt, 0, + "slave %u enexpectedly transmitted %u packets", + normal_cnt + slow_cnt, slave->port_id); + } else { + TEST_ASSERT_EQUAL(slow_cnt, 0, + "slave %u unexpectedly transmitted %d SLOW packets", + slave->port_id, slow_cnt); + + TEST_ASSERT_NOT_EQUAL(normal_cnt, 0, + "slave %u did not transmitted any packets", slave->port_id); + } + + pkts_cnt += normal_cnt; + } + + TEST_ASSERT_EQUAL(exp_pkts_cnt, pkts_cnt, + "Expected %u packets but transmitted only %d", exp_pkts_cnt, pkts_cnt); + + return remove_slaves_and_stop_bonded_device(); +} + +static void +init_marker(struct rte_mbuf *pkt, struct slave_conf *slave) +{ + struct marker_header *marker_hdr = rte_pktmbuf_mtod(pkt, + struct marker_header *); + + /* Copy multicast destination address */ + ether_addr_copy(&slow_protocol_mac_addr, &marker_hdr->eth_hdr.d_addr); + + /* Init source address */ + ether_addr_copy(&parnter_mac_default, &marker_hdr->eth_hdr.s_addr); + marker_hdr->eth_hdr.s_addr.addr_bytes[ETHER_ADDR_LEN-1] = slave->port_id; + + marker_hdr->eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_SLOW); + + marker_hdr->marker.subtype = SLOW_SUBTYPE_MARKER; + marker_hdr->marker.version_number = 1; + marker_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_INFO; + marker_hdr->marker.info_length = + offsetof(struct marker, reserved_90) - + offsetof(struct marker, requester_port); + RTE_VERIFY(marker_hdr->marker.info_length == 16); + marker_hdr->marker.requester_port = slave->port_id + 1; + marker_hdr->marker.tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION; + marker_hdr->marker.terminator_length = 0; +} + +static int +test_mode4_marker(void) +{ + struct slave_conf *slave; + struct rte_mbuf *pkts[MAX_PKT_BURST]; + struct rte_mbuf *marker_pkt; + struct marker_header *marker_hdr; + + unsigned delay; + int retval; + uint16_t nb_pkts; + 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, + 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + /* Test LACP handshake function */ + retval = bond_handshake(); + TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); + + delay = bond_get_update_timeout_ms(); + FOR_EACH_SLAVE(i, slave) { + marker_pkt = rte_pktmbuf_alloc(test_params.mbuf_pool); + TEST_ASSERT_NOT_NULL(marker_pkt, "Failed to allocate marker packet"); + init_marker(marker_pkt, slave); + + retval = slave_put_pkts(slave, &marker_pkt, 1); + if (retval != 1) + rte_pktmbuf_free(marker_pkt); + + TEST_ASSERT_EQUAL(retval, 1, + "Failed to send marker packet to slave %u", slave->port_id); + + for (j = 0; j < 20; ++j) { + rte_delay_ms(delay); + retval = rte_eth_rx_burst(test_params.bonded_port_id, 0, pkts, + RTE_DIM(pkts)); + + if (retval > 0) + free_pkts(pkts, retval); + + TEST_ASSERT_EQUAL(retval, 0, "Received packets unexpectedly"); + + retval = rte_eth_tx_burst(test_params.bonded_port_id, 0, NULL, 0); + TEST_ASSERT_EQUAL(retval, 0, + "Requested TX of 0 packets but %d transmitted", retval); + + /* Check if LACP packet was send by state machines + First and only packet must be a maker response */ + retval = slave_get_pkts(slave, pkts, MAX_PKT_BURST); + if (retval == 0) + continue; + if (retval > 1) + free_pkts(pkts, retval); + + TEST_ASSERT_EQUAL(retval, 1, "failed to get slave packets"); + nb_pkts = retval; + + marker_hdr = rte_pktmbuf_mtod(pkts[0], struct marker_header *); + /* Check if it's slow packet*/ + if (marker_hdr->eth_hdr.ether_type != ethtype_slow_be) + retval = -1; + /* Check if it's marker packet */ + else if (marker_hdr->marker.subtype != SLOW_SUBTYPE_MARKER) + retval = -2; + else if (marker_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_RESP) + retval = -3; + + free_pkts(pkts, nb_pkts); + + TEST_ASSERT_NOT_EQUAL(retval, -1, "Unexpected protocol type"); + TEST_ASSERT_NOT_EQUAL(retval, -2, "Unexpected sub protocol type"); + TEST_ASSERT_NOT_EQUAL(retval, -3, "Unexpected marker type"); + break; + } + + TEST_ASSERT(j < 20, "Marker response not found"); + } + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); + + return TEST_SUCCESS; +} + +static int +test_mode4_expired(void) +{ + struct slave_conf *slave, *exp_slave = NULL; + struct rte_mbuf *pkts[MAX_PKT_BURST]; + int retval; + uint32_t old_delay; + + uint8_t i; + uint16_t j; + + struct rte_eth_bond_8023ad_conf conf; + + 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; + conf.slow_periodic_ms = 600; + conf.short_timeout_ms = 300; + conf.long_timeout_ms = 900; + conf.aggregate_wait_timeout_ms = 200; + conf.tx_period_ms = 100; + old_delay = conf.update_timeout_ms; + conf.update_timeout_ms = 10; + rte_eth_bond_8023ad_setup(test_params.bonded_port_id, &conf); + + /* Wait for new settings to be applied. */ + for (i = 0; i < old_delay/conf.update_timeout_ms * 2; i++) { + FOR_EACH_SLAVE(j, slave) + bond_handshake_reply(slave); + + rte_delay_ms(conf.update_timeout_ms); + } + + retval = bond_handshake(); + TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); + + /* Find first slave */ + FOR_EACH_SLAVE(i, slave) { + exp_slave = slave; + break; + } + + RTE_VERIFY(exp_slave != NULL); + + /* When one of partners do not send or respond to LACP frame in + * conf.long_timeout_ms time, internal state machines should detect this + * and transit to expired state. */ + for (j = 0; j < conf.long_timeout_ms/conf.update_timeout_ms + 2; j++) { + rte_delay_ms(conf.update_timeout_ms); + + retval = bond_tx(NULL, 0); + TEST_ASSERT_EQUAL(retval, 0, "Unexpectedly received %d packets", + retval); + + FOR_EACH_SLAVE(i, slave) { + retval = bond_handshake_reply(slave); + TEST_ASSERT(retval >= 0, "Handshake failed"); + + /* Remove replay for slave that supose to be expired. */ + if (slave == exp_slave) { + while (rte_ring_count(slave->rx_queue) > 0) { + void *pkt = NULL; + + rte_ring_dequeue(slave->rx_queue, &pkt); + rte_pktmbuf_free(pkt); + } + } + } + + retval = bond_rx(pkts, RTE_DIM(pkts)); + if (retval > 0) + free_pkts(pkts, retval); + + TEST_ASSERT_EQUAL(retval, 0, "Unexpectedly received %d packets", + retval); + } + + /* After test only expected slave should be in EXPIRED state */ + FOR_EACH_SLAVE(i, slave) { + if (slave == exp_slave) + TEST_ASSERT(slave->lacp_parnter_state & STATE_EXPIRED, + "Slave %u should be in expired.", slave->port_id); + else + TEST_ASSERT_EQUAL(bond_handshake_done(slave), 1, + "Slave %u should be operational.", slave->port_id); + } + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); + + return TEST_SUCCESS; +} + +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; + uint8_t i, env_state; + uint8_t slaves[RTE_DIM(test_params.slave_ports)]; + int slaves_count; + + env_state = 0; + FOR_EACH_PORT(i, port) { + if (rte_ring_count(port->rx_queue) != 0) + env_state |= 0x01; + + if (rte_ring_count(port->tx_queue) != 0) + env_state |= 0x02; + + if (port->bonded != 0) + env_state |= 0x04; + + if (port->lacp_parnter_state != 0) + env_state |= 0x08; + + if (env_state != 0) + break; + } + + slaves_count = rte_eth_bond_slaves_get(test_params.bonded_port_id, + slaves, RTE_DIM(slaves)); + + if (slaves_count != 0) + env_state |= 0x10; + + TEST_ASSERT_EQUAL(env_state, 0, + "Environment not clean (port %u):%s%s%s%s%s", + port->port_id, + env_state & 0x01 ? " slave rx queue not clean" : "", + env_state & 0x02 ? " slave tx queue not clean" : "", + env_state & 0x04 ? " port marked as enslaved" : "", + env_state & 0x80 ? " slave state is not reset" : "", + env_state & 0x10 ? " slave count not equal 0" : "."); + + + return TEST_SUCCESS; +} + +static int +test_mode4_executor(int (*test_func)(void)) +{ + struct slave_conf *port; + int test_result; + uint8_t i; + void *pkt; + + /* Check if environment is clean. Fail to launch a test if there was + * a critical error before that prevented to reset environment. */ + TEST_ASSERT_SUCCESS(check_environment(), + "Refusing to launch test in dirty environment."); + + RTE_VERIFY(test_func != NULL); + test_result = (*test_func)(); + + /* If test succeed check if environment wast left in good condition. */ + if (test_result == TEST_SUCCESS) + test_result = check_environment(); + + /* Reset environment in case test failed to do that. */ + if (test_result != TEST_SUCCESS) { + TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(), + "Failed to stop bonded device"); + + FOR_EACH_PORT(i, port) { + while (rte_ring_count(port->rx_queue) != 0) { + if (rte_ring_dequeue(port->rx_queue, &pkt) == 0) + rte_pktmbuf_free(pkt); + } + + while (rte_ring_count(port->tx_queue) != 0) { + if (rte_ring_dequeue(port->tx_queue, &pkt) == 0) + rte_pktmbuf_free(pkt); + } + } + } + + return test_result; +} + +static int +test_mode4_lacp_wrapper(void) +{ + return test_mode4_executor(&test_mode4_lacp); +} + +static int +test_mode4_marker_wrapper(void) +{ + return test_mode4_executor(&test_mode4_marker); +} + +static int +test_mode4_rx_wrapper(void) +{ + return test_mode4_executor(&test_mode4_rx); +} + +static int +test_mode4_tx_burst_wrapper(void) +{ + return test_mode4_executor(&test_mode4_tx_burst); +} + +static int +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, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_NAMED("test_mode4_lacp", test_mode4_lacp_wrapper), + TEST_CASE_NAMED("test_mode4_rx", test_mode4_rx_wrapper), + 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 */ + } +}; + +static int +test_link_bonding_mode4(void) +{ + return unit_test_suite_runner(&link_bonding_mode4_test_suite); +} + +REGISTER_TEST_COMMAND(link_bonding_mode4_autotest, test_link_bonding_mode4); diff --git a/test/test/test_link_bonding_rssconf.c b/test/test/test_link_bonding_rssconf.c new file mode 100644 index 0000000000..34f1c166ba --- /dev/null +++ b/test/test/test_link_bonding_rssconf.c @@ -0,0 +1,673 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "test.h" + +#define SLAVE_COUNT (4) + +#define RXTX_RING_SIZE 1024 +#define RXTX_QUEUE_COUNT 4 + +#define BONDED_DEV_NAME ("rssconf_bond_dev") + +#define SLAVE_DEV_NAME_FMT ("rssconf_slave%d") +#define SLAVE_RXTX_QUEUE_FMT ("rssconf_slave%d_q%d") + +#define NUM_MBUFS 8191 +#define MBUF_SIZE (1600 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) +#define MBUF_CACHE_SIZE 250 +#define BURST_SIZE 32 + +#define INVALID_SOCKET_ID (-1) +#define INVALID_PORT_ID (0xFF) +#define INVALID_BONDING_MODE (-1) + +struct slave_conf { + uint8_t port_id; + struct rte_eth_dev_info dev_info; + + struct rte_eth_rss_conf rss_conf; + uint8_t rss_key[40]; + struct rte_eth_rss_reta_entry64 reta_conf[512 / RTE_RETA_GROUP_SIZE]; + + uint8_t is_slave; + struct rte_ring *rxtx_queue[RXTX_QUEUE_COUNT]; +}; + +struct link_bonding_rssconf_unittest_params { + uint8_t bond_port_id; + struct rte_eth_dev_info bond_dev_info; + struct rte_eth_rss_reta_entry64 bond_reta_conf[512 / RTE_RETA_GROUP_SIZE]; + struct slave_conf slave_ports[SLAVE_COUNT]; + + struct rte_mempool *mbuf_pool; +}; + +static struct link_bonding_rssconf_unittest_params test_params = { + .bond_port_id = INVALID_PORT_ID, + .slave_ports = { + [0 ... SLAVE_COUNT - 1] = { .port_id = INVALID_PORT_ID, .is_slave = 0} + }, + .mbuf_pool = NULL, +}; + +/** + * Default port configuration with RSS turned off + */ +static struct rte_eth_conf default_pmd_conf = { + .rxmode = { + .mq_mode = ETH_MQ_RX_NONE, + .max_rx_pkt_len = ETHER_MAX_LEN, + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled */ + .hw_ip_checksum = 0, /**< IP checksum offload enabled */ + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ + .hw_strip_crc = 0, /**< CRC stripped by hardware */ + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, + .lpbk_mode = 0, +}; + +static struct rte_eth_conf rss_pmd_conf = { + .rxmode = { + .mq_mode = ETH_MQ_RX_RSS, + .max_rx_pkt_len = ETHER_MAX_LEN, + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled */ + .hw_ip_checksum = 0, /**< IP checksum offload enabled */ + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ + .hw_strip_crc = 0, /**< CRC stripped by hardware */ + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, + .rx_adv_conf = { + .rss_conf = { + .rss_key = NULL, + .rss_hf = ETH_RSS_IPV6, + }, + }, + .lpbk_mode = 0, +}; + +#define FOR_EACH(_i, _item, _array, _size) \ + for (_i = 0, _item = &_array[0]; _i < _size && (_item = &_array[_i]); _i++) + +/* Macro for iterating over every port that can be used as a slave + * in this test. + * _i variable used as an index in test_params->slave_ports + * _slave pointer to &test_params->slave_ports[_idx] + */ +#define FOR_EACH_PORT(_i, _port) \ + FOR_EACH(_i, _port, test_params.slave_ports, \ + RTE_DIM(test_params.slave_ports)) + +static int +configure_ethdev(uint8_t port_id, struct rte_eth_conf *eth_conf, uint8_t start) +{ + int rxq, txq; + + TEST_ASSERT(rte_eth_dev_configure(port_id, RXTX_QUEUE_COUNT, + RXTX_QUEUE_COUNT, eth_conf) == 0, "Failed to configure device %u", + port_id); + + for (rxq = 0; rxq < RXTX_QUEUE_COUNT; rxq++) { + TEST_ASSERT(rte_eth_rx_queue_setup(port_id, rxq, RXTX_RING_SIZE, + rte_eth_dev_socket_id(port_id), NULL, + test_params.mbuf_pool) == 0, "Failed to setup rx queue."); + } + + for (txq = 0; txq < RXTX_QUEUE_COUNT; txq++) { + TEST_ASSERT(rte_eth_tx_queue_setup(port_id, txq, RXTX_RING_SIZE, + rte_eth_dev_socket_id(port_id), NULL) == 0, + "Failed to setup tx queue."); + } + + if (start) { + TEST_ASSERT(rte_eth_dev_start(port_id) == 0, + "Failed to start device (%d).", port_id); + } + + return 0; +} + +/** + * Remove all slaves from bonding + */ +static int +remove_slaves(void) +{ + unsigned n; + struct slave_conf *port; + + FOR_EACH_PORT(n, port) { + port = &test_params.slave_ports[n]; + if (port->is_slave) { + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove( + test_params.bond_port_id, port->port_id), + "Cannot remove slave %d from bonding", port->port_id); + port->is_slave = 0; + } + } + + return 0; +} + +static int +remove_slaves_and_stop_bonded_device(void) +{ + TEST_ASSERT_SUCCESS(remove_slaves(), "Removing slaves"); + rte_eth_dev_stop(test_params.bond_port_id); + return TEST_SUCCESS; +} + +/** + * Add all slaves to bonding + */ +static int +bond_slaves(void) +{ + unsigned n; + struct slave_conf *port; + + FOR_EACH_PORT(n, port) { + port = &test_params.slave_ports[n]; + if (!port->is_slave) { + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params.bond_port_id, + port->port_id), "Cannot attach slave %d to the bonding", + port->port_id); + port->is_slave = 1; + } + } + + return 0; +} + +/** + * Set all RETA values in port_id to value + */ +static int +reta_set(uint8_t port_id, uint8_t value, int reta_size) +{ + struct rte_eth_rss_reta_entry64 reta_conf[512/RTE_RETA_GROUP_SIZE]; + int i, j; + + for (i = 0; i < reta_size / RTE_RETA_GROUP_SIZE; i++) { + /* select all fields to set */ + reta_conf[i].mask = ~0LL; + for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) + reta_conf[i].reta[j] = value; + } + + return rte_eth_dev_rss_reta_update(port_id, reta_conf, reta_size); +} + +/** + * Check if slaves RETA is synchronized with bonding port. Returns 1 if slave + * port is synced with bonding port. + */ +static int +reta_check_synced(struct slave_conf *port) +{ + unsigned i; + + for (i = 0; i < test_params.bond_dev_info.reta_size; + i++) { + + int index = i / RTE_RETA_GROUP_SIZE; + int shift = i % RTE_RETA_GROUP_SIZE; + + if (port->reta_conf[index].reta[shift] != + test_params.bond_reta_conf[index].reta[shift]) + return 0; + + } + + return 1; +} + +/** + * Fetch bonding ports RETA + */ +static int +bond_reta_fetch(void) { + unsigned j; + + for (j = 0; j < test_params.bond_dev_info.reta_size / RTE_RETA_GROUP_SIZE; + j++) + test_params.bond_reta_conf[j].mask = ~0LL; + + TEST_ASSERT_SUCCESS(rte_eth_dev_rss_reta_query(test_params.bond_port_id, + test_params.bond_reta_conf, test_params.bond_dev_info.reta_size), + "Cannot take bonding ports RSS configuration"); + return 0; +} + +/** + * Fetch slaves RETA + */ +static int +slave_reta_fetch(struct slave_conf *port) { + unsigned j; + + for (j = 0; j < port->dev_info.reta_size / RTE_RETA_GROUP_SIZE; j++) + port->reta_conf[j].mask = ~0LL; + + TEST_ASSERT_SUCCESS(rte_eth_dev_rss_reta_query(port->port_id, + port->reta_conf, port->dev_info.reta_size), + "Cannot take bonding ports RSS configuration"); + return 0; +} + +/** + * Remove and add slave to check if slaves configuration is synced with + * the bonding ports values after adding new slave. + */ +static int +slave_remove_and_add(void) +{ + struct slave_conf *port = &(test_params.slave_ports[0]); + + /* 1. Remove first slave from bonding */ + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params.bond_port_id, + port->port_id), "Cannot remove slave #d from bonding"); + + /* 2. Change removed (ex-)slave and bonding configuration to different + * values + */ + reta_set(test_params.bond_port_id, 1, test_params.bond_dev_info.reta_size); + bond_reta_fetch(); + + reta_set(port->port_id, 2, port->dev_info.reta_size); + slave_reta_fetch(port); + + TEST_ASSERT(reta_check_synced(port) == 0, + "Removed slave didn't should be synchronized with bonding port"); + + /* 3. Add (ex-)slave and check if configuration changed*/ + TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params.bond_port_id, + port->port_id), "Cannot add slave"); + + bond_reta_fetch(); + slave_reta_fetch(port); + + return reta_check_synced(port); +} + +/** + * Test configuration propagation over slaves. + */ +static int +test_propagate(void) +{ + unsigned i; + uint8_t n; + struct slave_conf *port; + uint8_t bond_rss_key[40]; + struct rte_eth_rss_conf bond_rss_conf; + + int retval = 0; + uint64_t rss_hf = 0; + uint64_t default_rss_hf = 0; + + rte_eth_dev_info_get(test_params.bond_port_id, &test_params.bond_dev_info); + + /* + * Test hash function propagation + */ + for (i = 0; i < sizeof(test_params.bond_dev_info.flow_type_rss_offloads)*8; + i++) { + + rss_hf = test_params.bond_dev_info.flow_type_rss_offloads & (1<port_id, + &port->rss_conf); + TEST_ASSERT_SUCCESS(retval, + "Cannot take slaves RSS configuration"); + + TEST_ASSERT(port->rss_conf.rss_hf == rss_hf, + "Hash function not propagated for slave %d", + port->port_id); + } + + default_rss_hf = rss_hf; + } + + } + + /* + * Test key propagation + */ + for (i = 1; i < 10; i++) { + + /* Set all keys to zero */ + FOR_EACH_PORT(n, port) { + port = &test_params.slave_ports[n]; + memset(port->rss_conf.rss_key, 0, 40); + retval = rte_eth_dev_rss_hash_update(port->port_id, + &port->rss_conf); + TEST_ASSERT_SUCCESS(retval, "Cannot set slaves RSS keys"); + } + + memset(bond_rss_key, i, sizeof(bond_rss_key)); + bond_rss_conf.rss_hf = default_rss_hf, + bond_rss_conf.rss_key = bond_rss_key; + bond_rss_conf.rss_key_len = 40; + + retval = rte_eth_dev_rss_hash_update(test_params.bond_port_id, + &bond_rss_conf); + TEST_ASSERT_SUCCESS(retval, "Cannot set bonded port RSS keys"); + + FOR_EACH_PORT(n, port) { + port = &test_params.slave_ports[n]; + + retval = rte_eth_dev_rss_hash_conf_get(port->port_id, + &(port->rss_conf)); + + TEST_ASSERT_SUCCESS(retval, + "Cannot take slaves RSS configuration"); + + /* compare keys */ + retval = memcmp(port->rss_conf.rss_key, bond_rss_key, + sizeof(bond_rss_key)); + TEST_ASSERT(retval == 0, "Key value not propagated for slave %d", + port->port_id); + } + } + + /* + * Test RETA propagation + */ + for (i = 0; i < RXTX_QUEUE_COUNT; i++) { + + /* Set all keys to zero */ + FOR_EACH_PORT(n, port) { + port = &test_params.slave_ports[n]; + retval = reta_set(port->port_id, (i + 1) % RXTX_QUEUE_COUNT, + port->dev_info.reta_size); + TEST_ASSERT_SUCCESS(retval, "Cannot set slaves RETA"); + } + + TEST_ASSERT_SUCCESS(reta_set(test_params.bond_port_id, + i % RXTX_QUEUE_COUNT, test_params.bond_dev_info.reta_size), + "Cannot set bonded port RETA"); + + bond_reta_fetch(); + + FOR_EACH_PORT(n, port) { + port = &test_params.slave_ports[n]; + + slave_reta_fetch(port); + TEST_ASSERT(reta_check_synced(port) == 1, "RETAs inconsistent"); + } + } + + return TEST_SUCCESS; +} + +/** + * Test propagation logic, when RX_RSS mq_mode is turned on for bonding port + */ +static int +test_rss(void) +{ + /** + * Configure bonding port in RSS mq mode + */ + TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id, + &rss_pmd_conf, 0), "Failed to configure bonding device\n"); + + rte_eth_dev_info_get(test_params.bond_port_id, &test_params.bond_dev_info); + + TEST_ASSERT_SUCCESS(bond_slaves(), "Bonding slaves failed"); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bond_port_id), + "Failed to start bonding port (%d).", test_params.bond_port_id); + + TEST_ASSERT_SUCCESS(test_propagate(), "Propagation test failed"); + + TEST_ASSERT(slave_remove_and_add() == 1, "New slave should be synced"); + + remove_slaves_and_stop_bonded_device(); + + return TEST_SUCCESS; +} + +/** + * Test propagation logic, when RX_RSS mq_mode is turned off for bonding port + */ +static int +test_rss_lazy(void) +{ + TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id, + &default_pmd_conf, 0), "Failed to configure bonding device\n"); + + rte_eth_dev_info_get(test_params.bond_port_id, &test_params.bond_dev_info); + + TEST_ASSERT_SUCCESS(bond_slaves(), "Bonding slaves failed"); + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bond_port_id), + "Failed to start bonding port (%d).", test_params.bond_port_id); + + TEST_ASSERT_SUCCESS(test_propagate(), "Propagation test failed"); + + TEST_ASSERT(slave_remove_and_add() == 0, "New slave shouldn't be synced"); + + remove_slaves_and_stop_bonded_device(); + + return TEST_SUCCESS; +} + +static int +test_setup(void) +{ + unsigned n; + int retval; + int port_id; + char name[256]; + struct slave_conf *port; + + if (test_params.mbuf_pool == NULL) { + + test_params.mbuf_pool = rte_mempool_create("RSS_MBUF_POOL", NUM_MBUFS * + SLAVE_COUNT, MBUF_SIZE, MBUF_CACHE_SIZE, + sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, + NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0); + + TEST_ASSERT(test_params.mbuf_pool != NULL, + "rte_mempool_create failed\n"); + } + + /* Create / initialize ring eth devs. */ + FOR_EACH_PORT(n, port) { + port = &test_params.slave_ports[n]; + + port_id = rte_eth_dev_count(); + snprintf(name, sizeof(name), SLAVE_DEV_NAME_FMT, port_id); + + retval = eth_dev_null_create(name, 0, 64, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to create null device '%s'\n", + name); + + port->port_id = port_id; + + port->rss_conf.rss_key = port->rss_key; + port->rss_conf.rss_key_len = 40; + + retval = configure_ethdev(port->port_id, &default_pmd_conf, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to configure virtual ethdev %s\n", + name); + + rte_eth_dev_info_get(port->port_id, &port->dev_info); + } + + if (test_params.bond_port_id == INVALID_PORT_ID) { + retval = rte_eth_bond_create(BONDED_DEV_NAME, 0, rte_socket_id()); + + TEST_ASSERT(retval >= 0, "Failed to create bonded ethdev %s", + BONDED_DEV_NAME); + + test_params.bond_port_id = retval; + + TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id, + &default_pmd_conf, 0), "Failed to configure bonding device\n"); + + rte_eth_dev_info_get(test_params.bond_port_id, + &test_params.bond_dev_info); + } + + return TEST_SUCCESS; +} + +static void +testsuite_teardown(void) +{ + struct slave_conf *port; + uint8_t i; + + /* Only stop ports. + * Any cleanup/reset state is done when particular test is + * started. */ + + rte_eth_dev_stop(test_params.bond_port_id); + + FOR_EACH_PORT(i, port) + rte_eth_dev_stop(port->port_id); +} + +static int +check_environment(void) +{ + return TEST_SUCCESS; +} + +static int +test_rssconf_executor(int (*test_func)(void)) +{ + int test_result; + + /* Check if environment is clean. Fail to launch a test if there was + * a critical error before that prevented to reset environment. */ + TEST_ASSERT_SUCCESS(check_environment(), + "Refusing to launch test in dirty environment."); + + RTE_VERIFY(test_func != NULL); + test_result = (*test_func)(); + + /* If test succeed check if environment wast left in good condition. */ + if (test_result == TEST_SUCCESS) + test_result = check_environment(); + + /* Reset environment in case test failed to do that. */ + if (test_result != TEST_SUCCESS) { + TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(), + "Failed to stop bonded device"); + } + + return test_result; +} + +static int +test_setup_wrapper(void) +{ + return test_rssconf_executor(&test_setup); +} + +static int +test_rss_wrapper(void) +{ + return test_rssconf_executor(&test_rss); +} + +static int +test_rss_lazy_wrapper(void) +{ + return test_rssconf_executor(&test_rss_lazy); +} + +static struct unit_test_suite link_bonding_rssconf_test_suite = { + .suite_name = "RSS Dynamic Configuration for Bonding Unit Test Suite", + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_NAMED("test_setup", test_setup_wrapper), + TEST_CASE_NAMED("test_rss", test_rss_wrapper), + TEST_CASE_NAMED("test_rss_lazy", test_rss_lazy_wrapper), + + TEST_CASES_END() + } +}; + +static int +test_link_bonding_rssconf(void) +{ + return unit_test_suite_runner(&link_bonding_rssconf_test_suite); +} + +REGISTER_TEST_COMMAND(link_bonding_rssconf_autotest, test_link_bonding_rssconf); diff --git a/test/test/test_logs.c b/test/test/test_logs.c new file mode 100644 index 0000000000..6985ddde3b --- /dev/null +++ b/test/test/test_logs.c @@ -0,0 +1,89 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define RTE_LOGTYPE_TESTAPP1 RTE_LOGTYPE_USER1 +#define RTE_LOGTYPE_TESTAPP2 RTE_LOGTYPE_USER2 + +/* + * Logs + * ==== + * + * - Enable log types. + * - Set log level. + * - Send logs with different types and levels, some should not be displayed. + */ + +static int +test_logs(void) +{ + /* enable these logs type */ + rte_set_log_type(RTE_LOGTYPE_TESTAPP1, 1); + rte_set_log_type(RTE_LOGTYPE_TESTAPP2, 1); + + /* 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 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 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; +} + +REGISTER_TEST_COMMAND(logs_autotest, test_logs); diff --git a/test/test/test_lpm.c b/test/test/test_lpm.c new file mode 100644 index 0000000000..41ae80fe16 --- /dev/null +++ b/test/test/test_lpm.c @@ -0,0 +1,1319 @@ +/*- + * 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 +#include +#include + +#include +#include + +#include "test.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) + +typedef int32_t (*rte_lpm_test)(void); + +static int32_t test0(void); +static int32_t test1(void); +static int32_t test2(void); +static int32_t test3(void); +static int32_t test4(void); +static int32_t test5(void); +static int32_t test6(void); +static int32_t test7(void); +static int32_t test8(void); +static int32_t test9(void); +static int32_t test10(void); +static int32_t test11(void); +static int32_t test12(void); +static int32_t test13(void); +static int32_t test14(void); +static int32_t test15(void); +static int32_t test16(void); +static int32_t test17(void); +static int32_t test18(void); + +rte_lpm_test tests[] = { +/* Test Cases */ + test0, + test1, + test2, + test3, + test4, + test5, + test6, + test7, + test8, + test9, + test10, + test11, + test12, + test13, + test14, + test15, + test16, + test17, + test18 +}; + +#define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0])) +#define MAX_DEPTH 32 +#define MAX_RULES 256 +#define NUMBER_TBL8S 256 +#define PASS 0 + +/* + * Check that rte_lpm_create fails gracefully for incorrect user input + * arguments + */ +int32_t +test0(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm_create: lpm name == NULL */ + lpm = rte_lpm_create(NULL, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm == NULL); + + /* rte_lpm_create: max_rules = 0 */ + /* Note: __func__ inserts the function name, in this case "test0". */ + config.max_rules = 0; + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm == NULL); + + /* socket_id < -1 is invalid */ + config.max_rules = MAX_RULES; + lpm = rte_lpm_create(__func__, -2, &config); + TEST_LPM_ASSERT(lpm == NULL); + + return PASS; +} + +/* + * Create lpm table then delete lpm table 100 times + * Use a slightly different rules size each time + * */ +int32_t +test1(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + int32_t i; + + /* rte_lpm_free: Free NULL */ + for (i = 0; i < 100; i++) { + config.max_rules = MAX_RULES - i; + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + rte_lpm_free(lpm); + } + + /* Can not test free so return success */ + return PASS; +} + +/* + * Call rte_lpm_free for NULL pointer user input. Note: free has no return and + * therefore it is impossible to check for failure but this test is added to + * increase function coverage metrics and to validate that freeing null does + * not crash. + */ +int32_t +test2(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + rte_lpm_free(lpm); + rte_lpm_free(NULL); + return PASS; +} + +/* + * Check that rte_lpm_add fails gracefully for incorrect user input arguments + */ +int32_t +test3(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip = IPv4(0, 0, 0, 0), next_hop = 100; + uint8_t depth = 24; + int32_t status = 0; + + /* rte_lpm_add: lpm == NULL */ + status = rte_lpm_add(NULL, ip, depth, next_hop); + TEST_LPM_ASSERT(status < 0); + + /*Create vaild lpm to use in rest of test. */ + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* rte_lpm_add: depth < 1 */ + status = rte_lpm_add(lpm, ip, 0, next_hop); + TEST_LPM_ASSERT(status < 0); + + /* rte_lpm_add: depth > MAX_DEPTH */ + status = rte_lpm_add(lpm, ip, (MAX_DEPTH + 1), next_hop); + TEST_LPM_ASSERT(status < 0); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Check that rte_lpm_delete fails gracefully for incorrect user input + * arguments + */ +int32_t +test4(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip = IPv4(0, 0, 0, 0); + uint8_t depth = 24; + int32_t status = 0; + + /* rte_lpm_delete: lpm == NULL */ + status = rte_lpm_delete(NULL, ip, depth); + TEST_LPM_ASSERT(status < 0); + + /*Create vaild lpm to use in rest of test. */ + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* rte_lpm_delete: depth < 1 */ + status = rte_lpm_delete(lpm, ip, 0); + TEST_LPM_ASSERT(status < 0); + + /* rte_lpm_delete: depth > MAX_DEPTH */ + status = rte_lpm_delete(lpm, ip, (MAX_DEPTH + 1)); + TEST_LPM_ASSERT(status < 0); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Check that rte_lpm_lookup fails gracefully for incorrect user input + * arguments + */ +int32_t +test5(void) +{ +#if defined(RTE_LIBRTE_LPM_DEBUG) + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip = IPv4(0, 0, 0, 0), next_hop_return = 0; + int32_t status = 0; + + /* rte_lpm_lookup: lpm == NULL */ + status = rte_lpm_lookup(NULL, ip, &next_hop_return); + TEST_LPM_ASSERT(status < 0); + + /*Create vaild lpm to use in rest of test. */ + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* rte_lpm_lookup: depth < 1 */ + status = rte_lpm_lookup(lpm, ip, NULL); + TEST_LPM_ASSERT(status < 0); + + rte_lpm_free(lpm); +#endif + return PASS; +} + + + +/* + * Call add, lookup and delete for a single rule with depth <= 24 + */ +int32_t +test6(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip = IPv4(0, 0, 0, 0), next_hop_add = 100, next_hop_return = 0; + uint8_t depth = 24; + int32_t status = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Call add, lookup and delete for a single rule with depth > 24 + */ + +int32_t +test7(void) +{ + xmm_t ipx4; + uint32_t hop[4]; + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip = IPv4(0, 0, 0, 0), next_hop_add = 100, next_hop_return = 0; + uint8_t depth = 32; + int32_t status = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + ipx4 = vect_set_epi32(ip, ip + 0x100, ip - 0x100, ip); + rte_lpm_lookupx4(lpm, ipx4, hop, UINT32_MAX); + TEST_LPM_ASSERT(hop[0] == next_hop_add); + TEST_LPM_ASSERT(hop[1] == UINT32_MAX); + TEST_LPM_ASSERT(hop[2] == UINT32_MAX); + TEST_LPM_ASSERT(hop[3] == next_hop_add); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Use rte_lpm_add to add rules which effect only the second half of the lpm + * table. Use all possible depths ranging from 1..32. Set the next hop = to the + * depth. Check lookup hit for on every add and check for lookup miss on the + * first half of the lpm table after each add. Finally delete all rules going + * backwards (i.e. from depth = 32 ..1) and carry out a lookup after each + * delete. The lookup should return the next_hop_add value related to the + * previous depth value (i.e. depth -1). + */ +int32_t +test8(void) +{ + xmm_t ipx4; + uint32_t hop[4]; + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip1 = IPv4(127, 255, 255, 255), ip2 = IPv4(128, 0, 0, 0); + uint32_t next_hop_add, next_hop_return; + uint8_t depth; + int32_t status = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* Loop with rte_lpm_add. */ + for (depth = 1; depth <= 32; depth++) { + /* Let the next_hop_add value = depth. Just for change. */ + next_hop_add = depth; + + status = rte_lpm_add(lpm, ip2, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + /* Check IP in first half of tbl24 which should be empty. */ + status = rte_lpm_lookup(lpm, ip1, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + status = rte_lpm_lookup(lpm, ip2, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add)); + + ipx4 = vect_set_epi32(ip2, ip1, ip2, ip1); + rte_lpm_lookupx4(lpm, ipx4, hop, UINT32_MAX); + TEST_LPM_ASSERT(hop[0] == UINT32_MAX); + TEST_LPM_ASSERT(hop[1] == next_hop_add); + TEST_LPM_ASSERT(hop[2] == UINT32_MAX); + TEST_LPM_ASSERT(hop[3] == next_hop_add); + } + + /* Loop with rte_lpm_delete. */ + for (depth = 32; depth >= 1; depth--) { + next_hop_add = (uint8_t) (depth - 1); + + status = rte_lpm_delete(lpm, ip2, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip2, &next_hop_return); + + if (depth != 1) { + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add)); + } else { + TEST_LPM_ASSERT(status == -ENOENT); + } + + status = rte_lpm_lookup(lpm, ip1, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + ipx4 = vect_set_epi32(ip1, ip1, ip2, ip2); + rte_lpm_lookupx4(lpm, ipx4, hop, UINT32_MAX); + if (depth != 1) { + TEST_LPM_ASSERT(hop[0] == next_hop_add); + TEST_LPM_ASSERT(hop[1] == next_hop_add); + } else { + TEST_LPM_ASSERT(hop[0] == UINT32_MAX); + TEST_LPM_ASSERT(hop[1] == UINT32_MAX); + } + TEST_LPM_ASSERT(hop[2] == UINT32_MAX); + TEST_LPM_ASSERT(hop[3] == UINT32_MAX); + } + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * - Add & lookup to hit invalid TBL24 entry + * - Add & lookup to hit valid TBL24 entry not extended + * - Add & lookup to hit valid extended TBL24 entry with invalid TBL8 entry + * - Add & lookup to hit valid extended TBL24 entry with valid TBL8 entry + * + */ +int32_t +test9(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip, ip_1, ip_2; + uint8_t depth, depth_1, depth_2; + uint32_t next_hop_add, next_hop_add_1, next_hop_add_2, next_hop_return; + int32_t status = 0; + + /* Add & lookup to hit invalid TBL24 entry */ + ip = IPv4(128, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_delete_all(lpm); + + /* Add & lookup to hit valid TBL24 entry not extended */ + ip = IPv4(128, 0, 0, 0); + depth = 23; + next_hop_add = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + depth = 24; + next_hop_add = 101; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + depth = 24; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + depth = 23; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_delete_all(lpm); + + /* Add & lookup to hit valid extended TBL24 entry with invalid TBL8 + * entry */ + ip = IPv4(128, 0, 0, 0); + depth = 32; + next_hop_add = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + ip = IPv4(128, 0, 0, 5); + depth = 32; + next_hop_add = 101; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + ip = IPv4(128, 0, 0, 0); + depth = 32; + next_hop_add = 100; + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_delete_all(lpm); + + /* Add & lookup to hit valid extended TBL24 entry with valid TBL8 + * entry */ + ip_1 = IPv4(128, 0, 0, 0); + depth_1 = 25; + next_hop_add_1 = 101; + + ip_2 = IPv4(128, 0, 0, 5); + depth_2 = 32; + next_hop_add_2 = 102; + + next_hop_return = 0; + + status = rte_lpm_add(lpm, ip_1, depth_1, next_hop_add_1); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip_1, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); + + status = rte_lpm_add(lpm, ip_2, depth_2, next_hop_add_2); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip_2, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_2)); + + status = rte_lpm_delete(lpm, ip_2, depth_2); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip_2, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); + + status = rte_lpm_delete(lpm, ip_1, depth_1); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip_1, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_free(lpm); + + return PASS; +} + + +/* + * - Add rule that covers a TBL24 range previously invalid & lookup (& delete & + * lookup) + * - Add rule that extends a TBL24 invalid entry & lookup (& delete & lookup) + * - Add rule that extends a TBL24 valid entry & lookup for both rules (& + * delete & lookup) + * - Add rule that updates the next hop in TBL24 & lookup (& delete & lookup) + * - Add rule that updates the next hop in TBL8 & lookup (& delete & lookup) + * - Delete a rule that is not present in the TBL24 & lookup + * - Delete a rule that is not present in the TBL8 & lookup + * + */ +int32_t +test10(void) +{ + + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip, next_hop_add, next_hop_return; + uint8_t depth; + int32_t status = 0; + + /* Add rule that covers a TBL24 range previously invalid & lookup + * (& delete & lookup) */ + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + ip = IPv4(128, 0, 0, 0); + depth = 16; + next_hop_add = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_delete_all(lpm); + + ip = IPv4(128, 0, 0, 0); + depth = 25; + next_hop_add = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + rte_lpm_delete_all(lpm); + + /* Add rule that extends a TBL24 valid entry & lookup for both rules + * (& delete & lookup) */ + + ip = IPv4(128, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + ip = IPv4(128, 0, 0, 10); + depth = 32; + next_hop_add = 101; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + ip = IPv4(128, 0, 0, 0); + next_hop_add = 100; + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + ip = IPv4(128, 0, 0, 0); + depth = 24; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + ip = IPv4(128, 0, 0, 10); + depth = 32; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_delete_all(lpm); + + /* Add rule that updates the next hop in TBL24 & lookup + * (& delete & lookup) */ + + ip = IPv4(128, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + next_hop_add = 101; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_delete_all(lpm); + + /* Add rule that updates the next hop in TBL8 & lookup + * (& delete & lookup) */ + + ip = IPv4(128, 0, 0, 0); + depth = 32; + next_hop_add = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + next_hop_add = 101; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_delete_all(lpm); + + /* Delete a rule that is not present in the TBL24 & lookup */ + + ip = IPv4(128, 0, 0, 0); + depth = 24; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status < 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_delete_all(lpm); + + /* Delete a rule that is not present in the TBL8 & lookup */ + + ip = IPv4(128, 0, 0, 0); + depth = 32; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status < 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Add two rules, lookup to hit the more specific one, lookup to hit the less + * specific one delete the less specific rule and lookup previous values again; + * add a more specific rule than the existing rule, lookup again + * + * */ +int32_t +test11(void) +{ + + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip, next_hop_add, next_hop_return; + uint8_t depth; + int32_t status = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + ip = IPv4(128, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + ip = IPv4(128, 0, 0, 10); + depth = 32; + next_hop_add = 101; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + ip = IPv4(128, 0, 0, 0); + next_hop_add = 100; + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + ip = IPv4(128, 0, 0, 0); + depth = 24; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + ip = IPv4(128, 0, 0, 10); + depth = 32; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * 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 + * and contraction. + * + * */ + +int32_t +test12(void) +{ + xmm_t ipx4; + uint32_t hop[4]; + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip, i, next_hop_add, next_hop_return; + uint8_t depth; + int32_t status = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + ip = IPv4(128, 0, 0, 0); + depth = 32; + next_hop_add = 100; + + for (i = 0; i < 1000; i++) { + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add)); + + ipx4 = vect_set_epi32(ip, ip + 1, ip, ip - 1); + rte_lpm_lookupx4(lpm, ipx4, hop, UINT32_MAX); + TEST_LPM_ASSERT(hop[0] == UINT32_MAX); + TEST_LPM_ASSERT(hop[1] == next_hop_add); + TEST_LPM_ASSERT(hop[2] == UINT32_MAX); + TEST_LPM_ASSERT(hop[3] == next_hop_add); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + } + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Add a rule to tbl24, lookup (hit), then add a rule that will extend this + * tbl24 entry, lookup (hit). delete the rule that caused the tbl24 extension, + * lookup (miss) and repeat for loop of 1000 times. This will check tbl8 + * extension and contraction. + * + * */ + +int32_t +test13(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip, i, next_hop_add_1, next_hop_add_2, next_hop_return; + uint8_t depth; + int32_t status = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + ip = IPv4(128, 0, 0, 0); + depth = 24; + next_hop_add_1 = 100; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add_1); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); + + depth = 32; + next_hop_add_2 = 101; + + for (i = 0; i < 1000; i++) { + status = rte_lpm_add(lpm, ip, depth, next_hop_add_2); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add_2)); + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add_1)); + } + + depth = 24; + + status = rte_lpm_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Fore TBL8 extension exhaustion. Add 256 rules that require a tbl8 extension. + * No more tbl8 extensions will be allowed. Now add one more rule that required + * a tbl8 extension and get fail. + * */ +int32_t +test14(void) +{ + + /* We only use depth = 32 in the loop below so we must make sure + * that we have enough storage for all rules at that depth*/ + + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = 256 * 32; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + uint32_t ip, next_hop_add, next_hop_return; + uint8_t depth; + int32_t status = 0; + + /* Add enough space for 256 rules for every depth */ + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + depth = 32; + next_hop_add = 100; + ip = IPv4(0, 0, 0, 0); + + /* Add 256 rules that require a tbl8 extension */ + for (; ip <= IPv4(0, 0, 255, 0); ip += 256) { + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add)); + } + + /* All tbl8 extensions have been used above. Try to add one more and + * we get a fail */ + ip = IPv4(1, 0, 0, 0); + depth = 32; + + status = rte_lpm_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status < 0); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Sequence of operations for find existing lpm table + * + * - create table + * - find existing table: hit + * - find non-existing table: miss + * + */ +int32_t +test15(void) +{ + struct rte_lpm *lpm = NULL, *result = NULL; + struct rte_lpm_config config; + + config.max_rules = 256 * 32; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* Create lpm */ + lpm = rte_lpm_create("lpm_find_existing", SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* Try to find existing lpm */ + result = rte_lpm_find_existing("lpm_find_existing"); + TEST_LPM_ASSERT(result == lpm); + + /* Try to find non-existing lpm */ + result = rte_lpm_find_existing("lpm_find_non_existing"); + TEST_LPM_ASSERT(result == NULL); + + /* Cleanup. */ + rte_lpm_delete_all(lpm); + rte_lpm_free(lpm); + + return PASS; +} + +/* + * test failure condition of overloading the tbl8 so no more will fit + * Check we get an error return value in that case + */ +int32_t +test16(void) +{ + uint32_t ip; + struct rte_lpm_config config; + + config.max_rules = 256 * 32; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + struct rte_lpm *lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + + /* ip loops through all possibilities for top 24 bits of address */ + for (ip = 0; ip < 0xFFFFFF; ip++) { + /* add an entry within a different tbl8 each time, since + * depth >24 and the top 24 bits are different */ + if (rte_lpm_add(lpm, (ip << 8) + 0xF0, 30, 0) < 0) + break; + } + + if (ip != NUMBER_TBL8S) { + printf("Error, unexpected failure with filling tbl8 groups\n"); + printf("Failed after %u additions, expected after %u\n", + (unsigned)ip, (unsigned)NUMBER_TBL8S); + } + + rte_lpm_free(lpm); + return 0; +} + +/* + * Test for overwriting of tbl8: + * - add rule /32 and lookup + * - add new rule /24 and lookup + * - add third rule /25 and lookup + * - lookup /32 and /24 rule to ensure the table has not been overwritten. + */ +int32_t +test17(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + const uint32_t ip_10_32 = IPv4(10, 10, 10, 2); + const uint32_t ip_10_24 = IPv4(10, 10, 10, 0); + const uint32_t ip_20_25 = IPv4(10, 10, 20, 2); + const uint8_t d_ip_10_32 = 32, + d_ip_10_24 = 24, + d_ip_20_25 = 25; + const uint32_t next_hop_ip_10_32 = 100, + next_hop_ip_10_24 = 105, + next_hop_ip_20_25 = 111; + uint32_t next_hop_return = 0; + int32_t status = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + if ((status = rte_lpm_add(lpm, ip_10_32, d_ip_10_32, + next_hop_ip_10_32)) < 0) + return -1; + + status = rte_lpm_lookup(lpm, ip_10_32, &next_hop_return); + uint32_t test_hop_10_32 = next_hop_return; + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); + + if ((status = rte_lpm_add(lpm, ip_10_24, d_ip_10_24, + next_hop_ip_10_24)) < 0) + return -1; + + status = rte_lpm_lookup(lpm, ip_10_24, &next_hop_return); + uint32_t test_hop_10_24 = next_hop_return; + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); + + if ((status = rte_lpm_add(lpm, ip_20_25, d_ip_20_25, + next_hop_ip_20_25)) < 0) + return -1; + + status = rte_lpm_lookup(lpm, ip_20_25, &next_hop_return); + uint32_t test_hop_20_25 = next_hop_return; + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_20_25); + + if (test_hop_10_32 == test_hop_10_24) { + printf("Next hop return equal\n"); + return -1; + } + + if (test_hop_10_24 == test_hop_20_25) { + printf("Next hop return equal\n"); + return -1; + } + + status = rte_lpm_lookup(lpm, ip_10_32, &next_hop_return); + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); + + status = rte_lpm_lookup(lpm, ip_10_24, &next_hop_return); + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); + + rte_lpm_free(lpm); + + return PASS; +} + +/* + * Test for recycle of tbl8 + * - step 1: add a rule with depth=28 (> 24) + * - step 2: add a rule with same 24-bit prefix and depth=23 (< 24) + * - step 3: delete the first rule + * - step 4: check tbl8 is freed + * - step 5: add a rule same as the first one (depth=28) + * - step 6: check same tbl8 is allocated + * - step 7: add a rule with same 24-bit prefix and depth=24 + * - step 8: delete the rule (depth=28) added in step 5 + * - step 9: check tbl8 is freed + * - step 10: add a rule with same 24-bit prefix and depth = 28 + * - setp 11: check same tbl8 is allocated again + */ +int32_t +test18(void) +{ +#define group_idx next_hop + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + uint32_t ip, next_hop; + uint8_t depth; + uint32_t tbl8_group_index; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + ip = IPv4(192, 168, 100, 100); + depth = 28; + next_hop = 1; + rte_lpm_add(lpm, ip, depth, next_hop); + + TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); + tbl8_group_index = lpm->tbl24[ip>>8].group_idx; + + depth = 23; + next_hop = 2; + rte_lpm_add(lpm, ip, depth, next_hop); + TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); + + depth = 28; + rte_lpm_delete(lpm, ip, depth); + + TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group); + + next_hop = 3; + rte_lpm_add(lpm, ip, depth, next_hop); + + TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); + TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl24[ip>>8].group_idx); + + depth = 24; + next_hop = 4; + rte_lpm_add(lpm, ip, depth, next_hop); + TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); + + depth = 28; + rte_lpm_delete(lpm, ip, depth); + + TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group); + + next_hop = 5; + rte_lpm_add(lpm, ip, depth, next_hop); + + TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group); + TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl24[ip>>8].group_idx); + + rte_lpm_free(lpm); +#undef group_idx + return PASS; +} + +/* + * Do all unit tests. + */ + +static int +test_lpm(void) +{ + unsigned i; + int status, global_status = 0; + + for (i = 0; i < NUM_LPM_TESTS; i++) { + status = tests[i](); + if (status < 0) { + printf("ERROR: LPM Test %u: FAIL\n", i); + global_status = status; + } + } + + return global_status; +} + +REGISTER_TEST_COMMAND(lpm_autotest, test_lpm); diff --git a/test/test/test_lpm6.c b/test/test/test_lpm6.c new file mode 100644 index 0000000000..61134f7003 --- /dev/null +++ b/test/test/test_lpm6.c @@ -0,0 +1,1770 @@ +/*- + * 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 +#include +#include +#include + +#include +#include + +#include "test.h" +#include "test_lpm6_data.h" + +#define TEST_LPM_ASSERT(cond) do { \ + if (!(cond)) { \ + printf("Error at line %d: \n", __LINE__); \ + return -1; \ + } \ +} while(0) + +typedef int32_t (* rte_lpm6_test)(void); + +static int32_t test0(void); +static int32_t test1(void); +static int32_t test2(void); +static int32_t test3(void); +static int32_t test4(void); +static int32_t test5(void); +static int32_t test6(void); +static int32_t test7(void); +static int32_t test8(void); +static int32_t test9(void); +static int32_t test10(void); +static int32_t test11(void); +static int32_t test12(void); +static int32_t test13(void); +static int32_t test14(void); +static int32_t test15(void); +static int32_t test16(void); +static int32_t test17(void); +static int32_t test18(void); +static int32_t test19(void); +static int32_t test20(void); +static int32_t test21(void); +static int32_t test22(void); +static int32_t test23(void); +static int32_t test24(void); +static int32_t test25(void); +static int32_t test26(void); +static int32_t test27(void); + +rte_lpm6_test tests6[] = { +/* Test Cases */ + test0, + test1, + test2, + test3, + test4, + test5, + test6, + test7, + test8, + test9, + test10, + test11, + test12, + test13, + test14, + test15, + test16, + test17, + test18, + test19, + test20, + test21, + test22, + test23, + test24, + test25, + test26, + test27, +}; + +#define NUM_LPM6_TESTS (sizeof(tests6)/sizeof(tests6[0])) +#define MAX_DEPTH 128 +#define MAX_RULES 1000000 +#define NUMBER_TBL8S (1 << 16) +#define MAX_NUM_TBL8S (1 << 21) +#define PASS 0 + +static void +IPv6(uint8_t *ip, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, + uint8_t b6, uint8_t b7, uint8_t b8, uint8_t b9, uint8_t b10, + uint8_t b11, uint8_t b12, uint8_t b13, uint8_t b14, uint8_t b15, + uint8_t b16) +{ + ip[0] = b1; + ip[1] = b2; + ip[2] = b3; + ip[3] = b4; + ip[4] = b5; + ip[5] = b6; + ip[6] = b7; + ip[7] = b8; + ip[8] = b9; + ip[9] = b10; + ip[10] = b11; + ip[11] = b12; + ip[12] = b13; + ip[13] = b14; + ip[14] = b15; + ip[15] = b16; +} + +/* + * Check that rte_lpm6_create fails gracefully for incorrect user input + * arguments + */ +int32_t +test0(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm6_create: lpm name == NULL */ + lpm = rte_lpm6_create(NULL, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm == NULL); + + /* rte_lpm6_create: max_rules = 0 */ + /* Note: __func__ inserts the function name, in this case "test0". */ + config.max_rules = 0; + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm == NULL); + + /* socket_id < -1 is invalid */ + config.max_rules = MAX_RULES; + lpm = rte_lpm6_create(__func__, -2, &config); + TEST_LPM_ASSERT(lpm == NULL); + + /* rte_lpm6_create: number_tbl8s is bigger than the maximum */ + config.number_tbl8s = MAX_NUM_TBL8S + 1; + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm == NULL); + + /* rte_lpm6_create: config = NULL */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, NULL); + TEST_LPM_ASSERT(lpm == NULL); + + return PASS; +} + +/* + * Creates two different LPM tables. Tries to create a third one with the same + * name as the first one and expects the create function to return the same + * pointer. + */ +int32_t +test1(void) +{ + struct rte_lpm6 *lpm1 = NULL, *lpm2 = NULL, *lpm3 = NULL; + struct rte_lpm6_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm6_create: lpm name == LPM1 */ + lpm1 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm1 != NULL); + + /* rte_lpm6_create: lpm name == LPM2 */ + lpm2 = rte_lpm6_create("LPM2", SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm2 != NULL); + + /* rte_lpm6_create: lpm name == LPM2 */ + lpm3 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm3 == NULL); + + rte_lpm6_free(lpm1); + rte_lpm6_free(lpm2); + + return PASS; +} + +/* + * Create lpm table then delete lpm table 20 times + * Use a slightly different rules size each time + */ +int32_t +test2(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + int32_t i; + + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm6_free: Free NULL */ + 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); + + rte_lpm6_free(lpm); + } + + /* Can not test free so return success */ + return PASS; +} + +/* + * Call rte_lpm6_free for NULL pointer user input. Note: free has no return and + * therefore it is impossible to check for failure but this test is added to + * increase function coverage metrics and to validate that freeing null does + * not crash. + */ +int32_t +test3(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + rte_lpm6_free(lpm); + rte_lpm6_free(NULL); + return PASS; +} + +/* + * Check that rte_lpm6_add fails gracefully for incorrect user input arguments + */ +int32_t +test4(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth = 24, next_hop = 100; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm6_add: lpm == NULL */ + status = rte_lpm6_add(NULL, ip, depth, next_hop); + TEST_LPM_ASSERT(status < 0); + + /*Create vaild lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* rte_lpm6_add: depth < 1 */ + status = rte_lpm6_add(lpm, ip, 0, next_hop); + TEST_LPM_ASSERT(status < 0); + + /* rte_lpm6_add: depth > MAX_DEPTH */ + status = rte_lpm6_add(lpm, ip, (MAX_DEPTH + 1), next_hop); + TEST_LPM_ASSERT(status < 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Check that rte_lpm6_delete fails gracefully for incorrect user input + * arguments + */ +int32_t +test5(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth = 24; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm_delete: lpm == NULL */ + status = rte_lpm6_delete(NULL, ip, depth); + TEST_LPM_ASSERT(status < 0); + + /*Create vaild lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* rte_lpm_delete: depth < 1 */ + status = rte_lpm6_delete(lpm, ip, 0); + TEST_LPM_ASSERT(status < 0); + + /* rte_lpm_delete: depth > MAX_DEPTH */ + status = rte_lpm6_delete(lpm, ip, (MAX_DEPTH + 1)); + TEST_LPM_ASSERT(status < 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Check that rte_lpm6_lookup fails gracefully for incorrect user input + * arguments + */ +int32_t +test6(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t next_hop_return = 0; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm6_lookup: lpm == NULL */ + status = rte_lpm6_lookup(NULL, ip, &next_hop_return); + TEST_LPM_ASSERT(status < 0); + + /*Create vaild lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* rte_lpm6_lookup: ip = NULL */ + status = rte_lpm6_lookup(lpm, NULL, &next_hop_return); + TEST_LPM_ASSERT(status < 0); + + /* rte_lpm6_lookup: next_hop = NULL */ + status = rte_lpm6_lookup(lpm, ip, NULL); + TEST_LPM_ASSERT(status < 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Checks that rte_lpm6_lookup_bulk_func fails gracefully for incorrect user + * input arguments + */ +int32_t +test7(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[10][16]; + int16_t next_hop_return[10]; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm6_lookup: lpm == NULL */ + status = rte_lpm6_lookup_bulk_func(NULL, ip, next_hop_return, 10); + TEST_LPM_ASSERT(status < 0); + + /*Create vaild lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* rte_lpm6_lookup: ip = NULL */ + status = rte_lpm6_lookup_bulk_func(lpm, NULL, next_hop_return, 10); + TEST_LPM_ASSERT(status < 0); + + /* rte_lpm6_lookup: next_hop = NULL */ + status = rte_lpm6_lookup_bulk_func(lpm, ip, NULL, 10); + TEST_LPM_ASSERT(status < 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Checks that rte_lpm6_delete_bulk_func fails gracefully for incorrect user + * input arguments + */ +int32_t +test8(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[10][16]; + uint8_t depth[10]; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* rte_lpm6_delete: lpm == NULL */ + status = rte_lpm6_delete_bulk_func(NULL, ip, depth, 10); + TEST_LPM_ASSERT(status < 0); + + /*Create vaild lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* rte_lpm6_delete: ip = NULL */ + status = rte_lpm6_delete_bulk_func(lpm, NULL, depth, 10); + TEST_LPM_ASSERT(status < 0); + + /* rte_lpm6_delete: next_hop = NULL */ + status = rte_lpm6_delete_bulk_func(lpm, ip, NULL, 10); + TEST_LPM_ASSERT(status < 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Call add, lookup and delete for a single rule with depth < 24. + * Check all the combinations for the first three bytes that result in a hit. + * Delete the rule and check that the same test returs a miss. + */ +int32_t +test9(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth = 16, next_hop_add = 100, next_hop_return = 0; + int32_t status = 0; + uint8_t i; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + for (i = 0; i < UINT8_MAX; i++) { + ip[2] = i; + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + } + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + for (i = 0; i < UINT8_MAX; i++) { + ip[2] = i; + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + } + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Adds max_rules + 1 and expects a failure. Deletes a rule, then adds + * another one and expects success. + */ +int32_t +test10(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth, next_hop_add = 100; + int32_t status = 0; + int i; + + config.max_rules = 127; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + for (i = 1; i < 128; i++) { + depth = (uint8_t)i; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + } + + depth = 128; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == -ENOSPC); + + depth = 127; + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + depth = 128; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Creates an LPM table with a small number of tbl8s and exhaust them in the + * middle of the process of creating a rule. + */ +int32_t +test11(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth, next_hop_add = 100; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = 16; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + depth = 128; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + ip[0] = 1; + depth = 25; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + depth = 33; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + depth = 41; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + depth = 49; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == -ENOSPC); + + depth = 41; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Creates an LPM table with a small number of tbl8s and exhaust them in the + * middle of the process of adding a rule when there is already an existing rule + * in that position and needs to be extended. + */ +int32_t +test12(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth, next_hop_add = 100; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = 16; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + depth = 128; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + ip[0] = 1; + depth = 41; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + depth = 49; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == -ENOSPC); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Creates an LPM table with max_rules = 2 and tries to add 3 rules. + * Delete one of the rules and tries to add the third one again. + */ +int32_t +test13(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth, next_hop_add = 100; + int32_t status = 0; + + config.max_rules = 2; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + depth = 1; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + depth = 2; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + depth = 3; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == -ENOSPC); + + depth = 2; + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + depth = 3; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * 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. + */ +int32_t +test14(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + 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; + + config.max_rules = MAX_RULES; + config.number_tbl8s = 256; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + for (i = 0; i < 256; i++) { + ip[0] = (uint8_t)i; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + } + + ip[0] = 255; + ip[1] = 1; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == -ENOSPC); + + ip[0] = 255; + ip[1] = 0; + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + ip[0] = 255; + ip[1] = 1; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Call add, lookup and delete for a single rule with depth = 24 + */ +int32_t +test15(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth = 24, next_hop_add = 100, next_hop_return = 0; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Call add, lookup and delete for a single rule with depth > 24 + */ +int32_t +test16(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth = 128, next_hop_add = 100, next_hop_return = 0; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Use rte_lpm6_add to add rules which effect only the second half of the lpm + * table. Use all possible depths ranging from 1..32. Set the next hop = to the + * depth. Check lookup hit for on every add and check for lookup miss on the + * first half of the lpm table after each add. Finally delete all rules going + * backwards (i.e. from depth = 32 ..1) and carry out a lookup after each + * delete. The lookup should return the next_hop_add value related to the + * previous depth value (i.e. depth -1). + */ +int32_t +test17(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip1[] = {127,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255}; + uint8_t ip2[] = {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t depth, next_hop_add, next_hop_return; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* Loop with rte_lpm6_add. */ + for (depth = 1; depth <= 16; depth++) { + /* Let the next_hop_add value = depth. Just for change. */ + next_hop_add = depth; + + status = rte_lpm6_add(lpm, ip2, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + /* Check IP in first half of tbl24 which should be empty. */ + status = rte_lpm6_lookup(lpm, ip1, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + status = rte_lpm6_lookup(lpm, ip2, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add)); + } + + /* Loop with rte_lpm6_delete. */ + for (depth = 16; depth >= 1; depth--) { + next_hop_add = (uint8_t) (depth - 1); + + status = rte_lpm6_delete(lpm, ip2, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip2, &next_hop_return); + + if (depth != 1) { + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add)); + } + else { + TEST_LPM_ASSERT(status == -ENOENT); + } + + status = rte_lpm6_lookup(lpm, ip1, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + } + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * - Add & lookup to hit invalid TBL24 entry + * - Add & lookup to hit valid TBL24 entry not extended + * - Add & lookup to hit valid extended TBL24 entry with invalid TBL8 entry + * - Add & lookup to hit valid extended TBL24 entry with valid TBL8 entry + */ +int32_t +test18(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[16], ip_1[16], ip_2[16]; + uint8_t depth, depth_1, depth_2, next_hop_add, next_hop_add_1, + next_hop_add_2, next_hop_return; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* Add & lookup to hit invalid TBL24 entry */ + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_delete_all(lpm); + + /* Add & lookup to hit valid TBL24 entry not extended */ + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 23; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + depth = 24; + next_hop_add = 101; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + depth = 24; + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + depth = 23; + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_delete_all(lpm); + + /* Add & lookup to hit valid extended TBL24 entry with invalid TBL8 + * entry. + */ + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 32; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + IPv6(ip, 128, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 32; + next_hop_add = 101; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 32; + next_hop_add = 100; + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_delete_all(lpm); + + /* Add & lookup to hit valid extended TBL24 entry with valid TBL8 + * entry + */ + IPv6(ip_1, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth_1 = 25; + next_hop_add_1 = 101; + + IPv6(ip_2, 128, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth_2 = 32; + next_hop_add_2 = 102; + + next_hop_return = 0; + + status = rte_lpm6_add(lpm, ip_1, depth_1, next_hop_add_1); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip_1, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); + + status = rte_lpm6_add(lpm, ip_2, depth_2, next_hop_add_2); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip_2, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_2)); + + status = rte_lpm6_delete(lpm, ip_2, depth_2); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip_2, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1)); + + status = rte_lpm6_delete(lpm, ip_1, depth_1); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip_1, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * - Add rule that covers a TBL24 range previously invalid & lookup (& delete & + * lookup) + * - Add rule that extends a TBL24 invalid entry & lookup (& delete & lookup) + * - Add rule that extends a TBL24 valid entry & lookup for both rules (& + * delete & lookup) + * - Add rule that updates the next hop in TBL24 & lookup (& delete & lookup) + * - Add rule that updates the next hop in TBL8 & lookup (& delete & lookup) + * - Delete a rule that is not present in the TBL24 & lookup + * - Delete a rule that is not present in the TBL8 & lookup + */ +int32_t +test19(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[16]; + uint8_t depth, next_hop_add, next_hop_return; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* Add rule that covers a TBL24 range previously invalid & lookup + * (& delete & lookup) + */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 16; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_delete_all(lpm); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 25; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + rte_lpm6_delete_all(lpm); + + /* + * Add rule that extends a TBL24 valid entry & lookup for both rules + * (& delete & lookup) + */ + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip, 128, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 32; + next_hop_add = 101; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + next_hop_add = 100; + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 24; + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + IPv6(ip, 128, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 32; + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_delete_all(lpm); + + /* + * Add rule that updates the next hop in TBL24 & lookup + * (& delete & lookup) + */ + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + next_hop_add = 101; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_delete_all(lpm); + + /* + * Add rule that updates the next hop in TBL8 & lookup + * (& delete & lookup) + */ + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 32; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + next_hop_add = 101; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_delete_all(lpm); + + /* Delete a rule that is not present in the TBL24 & lookup */ + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status < 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_delete_all(lpm); + + /* Delete a rule that is not present in the TBL8 & lookup */ + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 32; + next_hop_add = 100; + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status < 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Add two rules, lookup to hit the more specific one, lookup to hit the less + * specific one delete the less specific rule and lookup previous values again; + * add a more specific rule than the existing rule, lookup again + */ +int32_t +test20(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[16]; + uint8_t depth, next_hop_add, next_hop_return; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 24; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10); + depth = 128; + next_hop_add = 101; + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + next_hop_add = 100; + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 24; + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10); + depth = 128; + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Adds 3 rules and look them up through the lookup_bulk function. + * Includes in the lookup a fourth IP address that won't match + * and checks that the result is as expected. + */ +int32_t +test21(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip_batch[4][16]; + uint8_t depth, next_hop_add; + int16_t next_hop_return[4]; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + IPv6(ip_batch[0], 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 48; + next_hop_add = 100; + + status = rte_lpm6_add(lpm, ip_batch[0], depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip_batch[1], 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 48; + next_hop_add = 101; + + status = rte_lpm6_add(lpm, ip_batch[1], depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip_batch[2], 128, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 48; + next_hop_add = 102; + + status = rte_lpm6_add(lpm, ip_batch[2], depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip_batch[3], 128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, + next_hop_return, 4); + TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == 100 + && next_hop_return[1] == 101 && next_hop_return[2] == 102 + && next_hop_return[3] == -1); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Adds 5 rules and look them up. + * Use the delete_bulk function to delete two of them. Lookup again. + * Use the delete_bulk function to delete one more. Lookup again. + * Use the delete_bulk function to delete two more, one invalid. Lookup again. + * Use the delete_bulk function to delete the remaining one. Lookup again. + */ +int32_t +test22(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip_batch[5][16]; + uint8_t depth[5], next_hop_add; + int16_t next_hop_return[5]; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* Adds 5 rules and look them up */ + + IPv6(ip_batch[0], 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth[0] = 48; + next_hop_add = 101; + + status = rte_lpm6_add(lpm, ip_batch[0], depth[0], next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip_batch[1], 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth[1] = 48; + next_hop_add = 102; + + status = rte_lpm6_add(lpm, ip_batch[1], depth[1], next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip_batch[2], 128, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth[2] = 48; + next_hop_add = 103; + + status = rte_lpm6_add(lpm, ip_batch[2], depth[2], next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip_batch[3], 128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth[3] = 48; + next_hop_add = 104; + + status = rte_lpm6_add(lpm, ip_batch[3], depth[3], next_hop_add); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip_batch[4], 128, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth[4] = 48; + next_hop_add = 105; + + status = rte_lpm6_add(lpm, ip_batch[4], depth[4], next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, + next_hop_return, 5); + TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == 101 + && next_hop_return[1] == 102 && next_hop_return[2] == 103 + && next_hop_return[3] == 104 && next_hop_return[4] == 105); + + /* Use the delete_bulk function to delete two of them. Lookup again */ + + status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[0], depth, 2); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, + next_hop_return, 5); + TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1 + && next_hop_return[1] == -1 && next_hop_return[2] == 103 + && next_hop_return[3] == 104 && next_hop_return[4] == 105); + + /* Use the delete_bulk function to delete one more. Lookup again */ + + status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[2], depth, 1); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, + next_hop_return, 5); + TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1 + && next_hop_return[1] == -1 && next_hop_return[2] == -1 + && next_hop_return[3] == 104 && next_hop_return[4] == 105); + + /* Use the delete_bulk function to delete two, one invalid. Lookup again */ + + IPv6(ip_batch[4], 128, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[3], depth, 2); + TEST_LPM_ASSERT(status == 0); + + IPv6(ip_batch[4], 128, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, + next_hop_return, 5); + TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1 + && next_hop_return[1] == -1 && next_hop_return[2] == -1 + && next_hop_return[3] == -1 && next_hop_return[4] == 105); + + /* Use the delete_bulk function to delete the remaining one. Lookup again */ + + status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[4], depth, 1); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup_bulk_func(lpm, ip_batch, + next_hop_return, 5); + TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1 + && next_hop_return[1] == -1 && next_hop_return[2] == -1 + && next_hop_return[3] == -1 && next_hop_return[4] == -1); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Add an extended rule (i.e. depth greater than 24, lookup (hit), delete, + * lookup (miss) in a for loop of 30 times. This will check tbl8 extension + * and contraction. + */ +int32_t +test23(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint32_t i; + uint8_t ip[16]; + uint8_t depth, next_hop_add, next_hop_return; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + depth = 128; + next_hop_add = 100; + + for (i = 0; i < 30; i++) { + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT(status == -ENOENT); + } + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Sequence of operations for find existing lpm table + * + * - create table + * - find existing table: hit + * - find non-existing table: miss + */ +int32_t +test24(void) +{ + struct rte_lpm6 *lpm = NULL, *result = NULL; + struct rte_lpm6_config config; + + config.max_rules = 256 * 32; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + /* Create lpm */ + lpm = rte_lpm6_create("lpm_find_existing", SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* Try to find existing lpm */ + result = rte_lpm6_find_existing("lpm_find_existing"); + TEST_LPM_ASSERT(result == lpm); + + /* Try to find non-existing lpm */ + result = rte_lpm6_find_existing("lpm_find_non_existing"); + TEST_LPM_ASSERT(result == NULL); + + /* Cleanup. */ + rte_lpm6_delete_all(lpm); + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Add a set of random routes with random depths. + * Lookup different IP addresses that match the routes previously added. + * Checks that the next hop is the expected one. + * The routes, IP addresses and expected result for every case have been + * precalculated by using a python script and stored in a .h file. + */ +int32_t +test25(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[16]; + uint32_t i; + uint8_t depth, next_hop_add, next_hop_return, next_hop_expected; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + for (i = 0; i < 1000; i++) { + memcpy(ip, large_route_table[i].ip, 16); + depth = large_route_table[i].depth; + next_hop_add = large_route_table[i].next_hop; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + } + + /* generate large IPS table and expected next_hops */ + generate_large_ips_table(1); + + for (i = 0; i < 100000; i++) { + memcpy(ip, large_ips_table[i].ip, 16); + next_hop_expected = large_ips_table[i].next_hop; + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && + (next_hop_return == next_hop_expected)); + } + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Test for overwriting of tbl8: + * - add rule /32 and lookup + * - add new rule /24 and lookup + * - add third rule /25 and lookup + * - lookup /32 and /24 rule to ensure the table has not been overwritten. + */ +int32_t +test26(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip_10_32[] = {10, 10, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t ip_10_24[] = {10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t ip_20_25[] = {10, 10, 20, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t d_ip_10_32 = 32; + uint8_t d_ip_10_24 = 24; + uint8_t d_ip_20_25 = 25; + uint8_t next_hop_ip_10_32 = 100; + uint8_t next_hop_ip_10_24 = 105; + uint8_t next_hop_ip_20_25 = 111; + uint8_t next_hop_return = 0; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + if ((status = rte_lpm6_add(lpm, ip_10_32, d_ip_10_32, + next_hop_ip_10_32)) < 0) + return -1; + + status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return); + uint8_t test_hop_10_32 = next_hop_return; + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); + + if ((status = rte_lpm6_add(lpm, ip_10_24, d_ip_10_24, + next_hop_ip_10_24)) < 0) + return -1; + + status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return); + uint8_t test_hop_10_24 = next_hop_return; + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); + + if ((status = rte_lpm6_add(lpm, ip_20_25, d_ip_20_25, + next_hop_ip_20_25)) < 0) + return -1; + + status = rte_lpm6_lookup(lpm, ip_20_25, &next_hop_return); + uint8_t test_hop_20_25 = next_hop_return; + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_20_25); + + if (test_hop_10_32 == test_hop_10_24) { + printf("Next hop return equal\n"); + return -1; + } + + if (test_hop_10_24 == test_hop_20_25){ + printf("Next hop return equal\n"); + return -1; + } + + status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return); + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); + + status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return); + TEST_LPM_ASSERT(status == 0); + TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Add a rule that reaches the end of the tree. + * Add a rule that is more generic than the first one. + * Check every possible combination that produces a match for the second rule. + * This tests tbl expansion. + */ +int32_t +test27(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = {128,128,128,128,128,128,128,128,128,128,128,128,128,128,0,0}; + uint8_t depth = 128, next_hop_add = 100, next_hop_return; + int32_t status = 0; + int i, j; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + depth = 128; + next_hop_add = 128; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + depth = 112; + next_hop_add = 112; + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + for (i = 0; i < 256; i++) { + ip[14] = (uint8_t)i; + for (j = 0; j < 256; j++) { + ip[15] = (uint8_t)j; + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + if (i == 0 && j == 0) + TEST_LPM_ASSERT(status == 0 && next_hop_return == 128); + else + TEST_LPM_ASSERT(status == 0 && next_hop_return == 112); + } + } + + rte_lpm6_free(lpm); + + return PASS; +} + +/* + * Do all unit tests. + */ +static int +test_lpm6(void) +{ + unsigned i; + 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) { + printf("ERROR: LPM Test %s: FAIL\n", RTE_STR(tests6[i])); + global_status = status; + } + } + + return global_status; +} + +REGISTER_TEST_COMMAND(lpm6_autotest, test_lpm6); diff --git a/test/test/test_lpm6_data.h b/test/test/test_lpm6_data.h new file mode 100644 index 0000000000..c3573b2bfb --- /dev/null +++ b/test/test/test_lpm6_data.h @@ -0,0 +1,1188 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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. + */ +#ifndef _TEST_LPM_ROUTES_H_ +#define _TEST_LPM_ROUTES_H_ + +#include +#include + +struct rules_tbl_entry { + uint8_t ip[16]; + uint8_t depth; + uint8_t next_hop; +}; + +struct ips_tbl_entry { + uint8_t ip[16]; + uint8_t next_hop; +}; + +/* this large_route_table[ ] is the same as the one with same name + * in previous test_lpm6_routes.h . Because this table has only 1000 + * lines, keeping it doesn't make LPM6 test case so large and also + * make the algorithm to generate rule table unnecessary and the + * algorithm to genertate test input IPv6 and associated expected + * next_hop much simple. + */ + +static struct rules_tbl_entry large_route_table[] = { + {{66, 70, 154, 143, 197, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 146}, + {{107, 79, 18, 235, 142, 84, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 141}, + {{247, 132, 113, 1, 215, 247, 183, 239, 128, 0, 0, 0, 0, 0, 0, 0}, 67, 23}, + {{48, 19, 41, 12, 76, 101, 114, 160, 45, 103, 134, 146, 128, 0, 0, 0}, 97, 252}, + {{5, 70, 208, 170, 19, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 6}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 137}, + {{12, 188, 26, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 9}, + {{1, 235, 101, 202, 26, 92, 23, 22, 179, 223, 128, 0, 0, 0, 0, 0}, 82, 9}, + {{215, 19, 224, 102, 45, 133, 102, 249, 56, 20, 214, 219, 93, 125, 52, 0}, 120, 163}, + {{178, 183, 109, 64, 136, 84, 11, 53, 217, 102, 0, 0, 0, 0, 0, 0}, 79, 197}, + {{212, 39, 158, 71, 253, 98, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 249}, + {{92, 58, 159, 130, 105, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 88}, + {{118, 140, 65, 198, 212, 93, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 104}, + {{86, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 36}, + {{79, 135, 242, 193, 197, 11, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 239}, + {{163, 228, 239, 80, 41, 66, 176, 176, 0, 0, 0, 0, 0, 0, 0, 0}, 67, 201}, + {{31, 9, 231, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 94}, + {{108, 144, 205, 39, 215, 26, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 241}, + {{247, 217, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 239}, + {{24, 186, 73, 182, 240, 251, 125, 165, 0, 0, 0, 0, 0, 0, 0, 0}, 66, 151}, + {{245, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 12, 137}, + {{44, 94, 138, 224, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 231}, + {{184, 221, 109, 135, 225, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 11}, + {{51, 179, 136, 184, 30, 118, 24, 16, 26, 161, 206, 101, 0, 0, 0, 0}, 96, 20}, + {{48, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15, 68}, + {{143, 235, 237, 220, 89, 119, 187, 143, 209, 94, 46, 58, 120, 0, 0, 0}, 101, 64}, + {{121, 190, 90, 177, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 152}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 217}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 101}, + {{111, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15, 58}, + {{162, 23, 52, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 254}, + {{76, 103, 44, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 148}, + {{80, 85, 219, 214, 12, 4, 65, 129, 162, 148, 208, 78, 39, 69, 94, 184}, 126, 126}, + {{80, 54, 251, 28, 152, 23, 244, 192, 151, 83, 6, 144, 223, 213, 224, 128}, 123, 76}, + {{39, 232, 237, 103, 191, 188, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 240}, + {{20, 231, 89, 210, 167, 173, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 33}, + {{125, 67, 198, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 47}, + {{26, 239, 153, 5, 213, 121, 31, 114, 161, 46, 84, 15, 148, 160, 0, 0}, 109, 41}, + {{102, 212, 159, 118, 223, 115, 134, 172, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 72}, + {{85, 181, 241, 127, 3, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 43}, + {{61, 199, 131, 226, 3, 230, 94, 119, 240, 0, 0, 0, 0, 0, 0, 0}, 68, 26}, + {{0, 143, 160, 184, 162, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 139}, + {{170, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 219}, + {{61, 122, 24, 251, 124, 122, 202, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 105}, + {{33, 219, 226, 3, 180, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 210}, + {{51, 251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 151}, + {{106, 185, 11, 122, 197, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 28}, + {{192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 64}, + {{239, 195, 77, 239, 131, 156, 2, 246, 191, 178, 204, 160, 21, 213, 30, 128}, 121, 9}, + {{141, 207, 181, 99, 55, 245, 151, 228, 65, 50, 85, 16, 0, 0, 0, 0}, 92, 250}, + {{110, 159, 230, 251, 224, 210, 58, 49, 0, 0, 0, 0, 0, 0, 0, 0}, 66, 200}, + {{134, 26, 104, 32, 129, 41, 201, 50, 164, 69, 178, 156, 156, 133, 8, 218}, 127, 132}, + {{253, 207, 116, 105, 210, 166, 186, 99, 182, 0, 0, 0, 0, 0, 0, 0}, 71, 182}, + {{211, 73, 38, 80, 183, 168, 52, 138, 25, 214, 112, 8, 252, 0, 0, 0}, 102, 7}, + {{200, 244, 108, 238, 164, 141, 215, 39, 233, 249, 120, 80, 112, 0, 0, 0}, 100, 146}, + {{107, 44, 250, 202, 64, 37, 107, 105, 140, 0, 0, 0, 0, 0, 0, 0}, 70, 98}, + {{93, 86, 56, 27, 159, 195, 126, 39, 240, 201, 48, 0, 0, 0, 0, 0}, 86, 179}, + {{32, 202, 214, 242, 39, 141, 61, 146, 138, 96, 0, 0, 0, 0, 0, 0}, 77, 245}, + {{167, 77, 249, 28, 210, 196, 227, 241, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 2}, + {{241, 59, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 5}, + {{143, 68, 146, 210, 173, 155, 251, 173, 0, 0, 0, 0, 0, 0, 0, 0}, 66, 169}, + {{167, 180, 226, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 52}, + {{241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 177}, + {{238, 9, 168, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 74}, + {{203, 148, 16, 96, 125, 18, 86, 1, 91, 244, 251, 20, 31, 14, 75, 128}, 122, 212}, + {{111, 227, 137, 94, 65, 21, 77, 137, 119, 130, 159, 19, 159, 45, 18, 192}, 122, 238}, + {{59, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 18}, + {{110, 192, 255, 120, 84, 215, 3, 130, 38, 224, 0, 0, 0, 0, 0, 0}, 75, 155}, + {{152, 79, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 97}, + {{118, 186, 157, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 8}, + {{70, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 123}, + {{253, 119, 114, 227, 18, 243, 81, 61, 238, 107, 190, 144, 0, 0, 0, 0}, 92, 11}, + {{166, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 211}, + {{43, 95, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 116}, + {{94, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 57}, + {{182, 251, 195, 132, 66, 7, 208, 146, 223, 231, 211, 181, 25, 176, 0, 0}, 108, 178}, + {{152, 166, 111, 233, 194, 17, 230, 41, 221, 253, 69, 123, 108, 0, 0, 0}, 102, 93}, + {{106, 141, 235, 190, 82, 241, 152, 186, 195, 81, 86, 144, 0, 0, 0, 0}, 92, 3}, + {{32, 81, 210, 153, 151, 29, 11, 62, 127, 177, 194, 254, 103, 83, 58, 128}, 121, 162}, + {{79, 112, 224, 26, 174, 39, 98, 181, 115, 57, 209, 189, 136, 48, 0, 0}, 109, 125}, + {{106, 197, 83, 151, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 33}, + {{190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 254}, + {{156, 73, 249, 148, 55, 192, 20, 42, 142, 128, 0, 0, 0, 0, 0, 0}, 74, 66}, + {{64, 107, 36, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 4}, + {{115, 148, 71, 250, 158, 174, 168, 249, 106, 110, 196, 0, 0, 0, 0, 0}, 86, 122}, + {{18, 139, 152, 44, 38, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 59}, + {{55, 229, 117, 106, 146, 95, 74, 220, 122, 0, 84, 202, 183, 138, 120, 0}, 117, 99}, + {{153, 211, 3, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 41}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 112}, + {{49, 192, 102, 142, 216, 3, 114, 64, 165, 128, 168, 0, 0, 0, 0, 0}, 85, 255}, + {{201, 143, 240, 240, 209, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 106}, + {{158, 19, 164, 196, 87, 162, 33, 120, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 170}, + {{5, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 86}, + {{34, 170, 246, 62, 198, 85, 193, 227, 252, 68, 0, 0, 0, 0, 0, 0}, 79, 155}, + {{21, 52, 9, 86, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 35, 65}, + {{203, 81, 49, 171, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 39}, + {{211, 218, 87, 244, 93, 181, 118, 41, 156, 143, 254, 0, 0, 0, 0, 0}, 90, 162}, + {{77, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 69}, + {{158, 219, 219, 39, 4, 219, 100, 63, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 163}, + {{61, 50, 232, 1, 185, 252, 243, 54, 189, 240, 170, 192, 0, 0, 0, 0}, 90, 116}, + {{241, 143, 33, 19, 247, 55, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 19}, + {{61, 28, 61, 252, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 48}, + {{102, 112, 194, 108, 90, 253, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 230}, + {{74, 88, 58, 66, 172, 41, 144, 204, 195, 240, 0, 0, 0, 0, 0, 0}, 78, 155}, + {{44, 148, 187, 58, 190, 59, 190, 187, 124, 138, 222, 131, 0, 0, 0, 0}, 96, 158}, + {{67, 7, 216, 139, 93, 224, 20, 135, 186, 86, 209, 111, 60, 80, 0, 0}, 113, 252}, + {{209, 26, 12, 174, 5, 101, 164, 181, 237, 63, 192, 57, 54, 120, 0, 0}, 110, 176}, + {{4, 66, 232, 52, 239, 56, 48, 58, 192, 0, 0, 0, 0, 0, 0, 0}, 66, 211}, + {{158, 165, 2, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 15}, + {{85, 204, 245, 198, 68, 44, 39, 71, 32, 0, 0, 0, 0, 0, 0, 0}, 68, 95}, + {{181, 134, 25, 87, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 169}, + {{26, 230, 61, 36, 79, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 249}, + {{5, 170, 198, 139, 65, 186, 188, 45, 42, 253, 165, 89, 206, 0, 0, 0}, 105, 61}, + {{211, 245, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 63}, + {{117, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 43}, + {{103, 17, 123, 102, 70, 206, 90, 92, 124, 198, 0, 0, 0, 0, 0, 0}, 81, 228}, + {{192, 237, 88, 244, 53, 30, 61, 160, 143, 64, 0, 0, 0, 0, 0, 0}, 78, 165}, + {{199, 82, 217, 183, 2, 179, 195, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 3}, + {{157, 230, 79, 162, 57, 125, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 211}, + {{27, 67, 64, 235, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 210}, + {{72, 158, 163, 106, 193, 137, 190, 7, 250, 165, 249, 73, 64, 0, 0, 0}, 99, 61}, + {{34, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 120}, + {{215, 141, 95, 192, 189, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 94}, + {{31, 181, 56, 141, 120, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 153}, + {{153, 73, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 221}, + {{162, 107, 41, 189, 165, 155, 22, 139, 165, 72, 96, 0, 0, 0, 0, 0}, 87, 163}, + {{218, 17, 204, 165, 217, 251, 107, 45, 29, 15, 192, 167, 75, 0, 0, 0}, 106, 188}, + {{200, 124, 238, 213, 35, 228, 94, 141, 86, 187, 101, 60, 115, 52, 131, 16}, 124, 15}, + {{74, 237, 160, 56, 141, 217, 191, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 28}, + {{163, 47, 242, 103, 173, 217, 88, 154, 38, 200, 32, 0, 0, 0, 0, 0}, 84, 240}, + {{20, 227, 128, 28, 144, 147, 22, 13, 94, 129, 107, 88, 0, 0, 0, 0}, 93, 59}, + {{95, 144, 229, 107, 218, 125, 204, 233, 161, 42, 180, 64, 0, 0, 0, 0}, 90, 195}, + {{155, 220, 83, 208, 108, 16, 134, 156, 128, 0, 0, 0, 0, 0, 0, 0}, 66, 10}, + {{179, 138, 55, 80, 190, 153, 12, 237, 22, 120, 69, 0, 0, 0, 0, 0}, 88, 206}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 137}, + {{3, 119, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 225}, + {{13, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 223}, + {{117, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15, 29}, + {{164, 19, 195, 47, 136, 190, 156, 255, 30, 74, 143, 134, 162, 0, 0, 0}, 103, 166}, + {{40, 235, 94, 135, 135, 230, 71, 33, 64, 233, 0, 0, 0, 0, 0, 0}, 80, 178}, + {{222, 151, 166, 97, 129, 250, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 38}, + {{174, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 141}, + {{6, 189, 100, 150, 250, 13, 46, 98, 228, 139, 50, 52, 52, 196, 128, 0}, 116, 230}, + {{75, 252, 89, 205, 37, 52, 106, 79, 188, 120, 54, 119, 160, 0, 0, 0}, 99, 124}, + {{38, 18, 146, 6, 63, 64, 231, 10, 152, 199, 5, 143, 147, 4, 252, 0}, 118, 54}, + {{111, 119, 169, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 162}, + {{105, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 32}, + {{143, 57, 57, 101, 98, 182, 74, 227, 205, 143, 253, 237, 8, 0, 0, 0}, 102, 237}, + {{30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 215}, + {{14, 232, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 138}, + {{14, 53, 67, 216, 229, 155, 149, 139, 31, 253, 184, 126, 133, 108, 40, 0}, 118, 73}, + {{22, 58, 40, 143, 188, 132, 239, 14, 181, 252, 81, 192, 0, 0, 0, 0}, 90, 43}, + {{11, 222, 185, 243, 248, 150, 79, 230, 214, 213, 3, 23, 193, 196, 0, 0}, 112, 88}, + {{14, 226, 198, 117, 84, 93, 22, 96, 77, 241, 173, 68, 68, 204, 72, 0}, 119, 91}, + {{15, 103, 247, 219, 150, 142, 92, 50, 144, 0, 0, 0, 0, 0, 0, 0}, 69, 140}, + {{0, 213, 77, 244, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 65}, + {{178, 174, 174, 239, 72, 181, 36, 217, 40, 169, 12, 104, 149, 157, 125, 128}, 122, 201}, + {{118, 53, 55, 17, 97, 227, 243, 176, 2, 0, 0, 0, 0, 0, 0, 0}, 72, 69}, + {{21, 253, 4, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 35, 170}, + {{5, 249, 186, 133, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 192}, + {{47, 79, 35, 66, 11, 178, 161, 28, 87, 180, 45, 128, 0, 0, 0, 0}, 89, 21}, + {{242, 227, 20, 73, 150, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 35}, + {{121, 169, 102, 118, 157, 192, 154, 186, 126, 0, 0, 0, 0, 0, 0, 0}, 71, 235}, + {{9, 138, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 240}, + {{45, 173, 14, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 136}, + {{127, 47, 51, 201, 236, 45, 142, 80, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 186}, + {{247, 233, 34, 38, 181, 207, 127, 20, 224, 118, 59, 148, 0, 0, 0, 0}, 95, 174}, + {{126, 187, 198, 104, 245, 223, 219, 18, 31, 124, 0, 0, 0, 0, 0, 0}, 79, 153}, + {{3, 163, 107, 228, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 35, 118}, + {{167, 109, 2, 95, 11, 62, 45, 128, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 113}, + {{76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 58}, + {{58, 190, 204, 151, 222, 147, 47, 78, 38, 203, 9, 17, 64, 0, 0, 0}, 101, 206}, + {{254, 220, 254, 220, 204, 79, 35, 127, 242, 63, 106, 232, 127, 180, 0, 0}, 111, 42}, + {{77, 156, 8, 209, 181, 37, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 230}, + {{65, 89, 137, 76, 208, 199, 166, 90, 128, 0, 0, 0, 0, 0, 0, 0}, 67, 6}, + {{47, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 254}, + {{172, 154, 12, 108, 77, 37, 106, 8, 234, 7, 248, 212, 112, 160, 0, 0}, 108, 214}, + {{254, 117, 239, 244, 154, 89, 166, 241, 12, 108, 127, 153, 206, 160, 0, 0}, 107, 43}, + {{113, 160, 206, 52, 143, 12, 9, 148, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 178}, + {{178, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 179}, + {{229, 177, 28, 106, 59, 75, 182, 241, 36, 79, 224, 0, 0, 0, 0, 0}, 87, 236}, + {{156, 72, 93, 193, 50, 235, 75, 228, 88, 115, 89, 119, 128, 0, 0, 0}, 98, 184}, + {{28, 232, 28, 249, 83, 105, 211, 7, 136, 147, 231, 64, 0, 0, 0, 0}, 91, 95}, + {{217, 33, 23, 107, 74, 42, 135, 197, 144, 34, 40, 243, 13, 126, 36, 136}, 127, 152}, + {{64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 113}, + {{85, 172, 121, 126, 213, 57, 225, 54, 197, 73, 85, 251, 9, 64, 0, 0}, 108, 137}, + {{104, 46, 25, 71, 86, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 224}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 61}, + {{241, 113, 254, 106, 53, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 205}, + {{29, 36, 12, 244, 197, 127, 240, 8, 167, 134, 154, 248, 199, 123, 143, 240}, 124, 170}, + {{58, 29, 129, 94, 43, 139, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 117}, + {{213, 124, 147, 196, 7, 82, 67, 70, 228, 0, 0, 0, 0, 0, 0, 0}, 70, 225}, + {{164, 168, 161, 140, 87, 85, 250, 41, 34, 0, 0, 0, 0, 0, 0, 0}, 72, 34}, + {{186, 142, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 5}, + {{237, 249, 9, 70, 247, 97, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 92}, + {{155, 92, 145, 218, 125, 226, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 230}, + {{35, 169, 62, 156, 86, 4, 125, 219, 119, 113, 191, 75, 198, 113, 0, 0}, 112, 61}, + {{207, 63, 96, 186, 26, 68, 115, 161, 163, 59, 190, 166, 18, 78, 232, 0}, 117, 221}, + {{86, 40, 200, 199, 247, 86, 159, 179, 191, 184, 117, 173, 211, 158, 0, 128}, 121, 105}, + {{104, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 181}, + {{205, 35, 123, 178, 36, 64, 62, 153, 195, 250, 0, 0, 0, 0, 0, 0}, 79, 110}, + {{117, 40, 57, 157, 138, 160, 223, 59, 155, 145, 64, 0, 0, 0, 0, 0}, 86, 103}, + {{74, 166, 140, 146, 74, 72, 229, 99, 167, 124, 107, 117, 217, 14, 246, 64}, 123, 218}, + {{12, 222, 244, 183, 83, 146, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 146}, + {{11, 98, 146, 110, 95, 96, 80, 142, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 90}, + {{235, 5, 187, 199, 30, 170, 82, 187, 228, 159, 22, 25, 204, 112, 0, 0}, 108, 197}, + {{35, 96, 146, 145, 155, 116, 252, 181, 29, 205, 230, 246, 30, 0, 0, 0}, 103, 158}, + {{174, 38, 56, 244, 227, 102, 252, 237, 128, 86, 0, 0, 0, 0, 0, 0}, 81, 118}, + {{65, 134, 37, 58, 90, 125, 60, 84, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 95}, + {{253, 117, 135, 98, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 152}, + {{111, 115, 188, 184, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 239}, + {{202, 24, 89, 9, 149, 45, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 48}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 228}, + {{244, 98, 52, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 247}, + {{151, 167, 43, 178, 116, 194, 173, 126, 236, 98, 40, 0, 0, 0, 0, 0}, 85, 12}, + {{60, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 129}, + {{208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 50}, + {{126, 11, 216, 242, 7, 45, 121, 208, 110, 135, 210, 75, 59, 182, 228, 42}, 128, 250}, + {{217, 26, 184, 146, 3, 18, 240, 15, 135, 8, 0, 0, 0, 0, 0, 0}, 77, 249}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 230}, + {{145, 28, 29, 184, 2, 85, 234, 135, 98, 111, 136, 32, 0, 0, 0, 0}, 92, 228}, + {{108, 104, 255, 254, 34, 95, 72, 157, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 181}, + {{153, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 206}, + {{22, 250, 130, 201, 132, 248, 189, 108, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 122}, + {{158, 165, 234, 18, 44, 61, 82, 61, 235, 0, 0, 0, 0, 0, 0, 0}, 72, 81}, + {{236, 57, 124, 110, 124, 218, 82, 70, 142, 78, 18, 128, 0, 0, 0, 0}, 95, 175}, + {{94, 209, 200, 201, 149, 162, 248, 134, 239, 226, 1, 237, 16, 134, 56, 0}, 118, 170}, + {{187, 42, 31, 144, 236, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 174}, + {{90, 214, 185, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 104}, + {{194, 220, 211, 212, 211, 32, 196, 98, 71, 62, 153, 103, 80, 35, 128, 0}, 114, 113}, + {{24, 255, 158, 64, 180, 148, 10, 81, 243, 247, 0, 0, 0, 0, 0, 0}, 80, 89}, + {{231, 155, 100, 242, 112, 160, 160, 95, 98, 253, 219, 21, 239, 90, 0, 0}, 113, 151}, + {{225, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 108}, + {{136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 224}, + {{250, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 95}, + {{72, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 173}, + {{185, 51, 51, 167, 18, 44, 36, 59, 35, 135, 20, 104, 0, 0, 0, 0}, 93, 176}, + {{57, 146, 252, 60, 197, 68, 39, 162, 80, 198, 137, 50, 97, 92, 124, 0}, 119, 84}, + {{254, 46, 242, 105, 86, 94, 96, 14, 130, 176, 0, 0, 0, 0, 0, 0}, 78, 104}, + {{247, 202, 176, 76, 69, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 236}, + {{50, 233, 203, 77, 42, 21, 115, 163, 166, 138, 192, 52, 178, 37, 112, 0}, 116, 153}, + {{62, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 190}, + {{53, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 202}, + {{198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 54}, + {{189, 234, 106, 247, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 156}, + {{110, 24, 228, 65, 216, 147, 9, 48, 60, 179, 172, 91, 115, 185, 227, 96}, 126, 245}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 218}, + {{74, 177, 89, 218, 248, 18, 176, 39, 118, 173, 201, 152, 0, 0, 0, 0}, 93, 72}, + {{31, 13, 153, 92, 27, 122, 150, 232, 88, 95, 202, 171, 208, 158, 0, 0}, 112, 183}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 183}, + {{63, 37, 46, 158, 139, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 241}, + {{53, 209, 59, 13, 202, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 106}, + {{184, 44, 149, 221, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 180}, + {{222, 134, 37, 62, 223, 193, 39, 246, 15, 151, 200, 146, 0, 0, 0, 0}, 96, 142}, + {{199, 176, 189, 37, 233, 177, 252, 216, 94, 175, 253, 119, 96, 0, 0, 0}, 100, 6}, + {{44, 195, 201, 106, 209, 120, 122, 38, 43, 30, 142, 22, 196, 175, 100, 0}, 118, 33}, + {{33, 166, 10, 174, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 224}, + {{54, 1, 189, 195, 133, 49, 36, 80, 138, 200, 0, 0, 0, 0, 0, 0}, 78, 14}, + {{241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 149}, + {{221, 131, 4, 247, 112, 89, 187, 119, 219, 80, 122, 156, 216, 160, 0, 0}, 108, 131}, + {{102, 20, 46, 129, 202, 247, 129, 1, 237, 71, 103, 58, 217, 44, 4, 0}, 121, 133}, + {{107, 156, 151, 44, 215, 98, 171, 126, 85, 32, 42, 128, 0, 0, 0, 0}, 89, 33}, + {{54, 25, 70, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 204}, + {{149, 211, 242, 14, 112, 219, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 43}, + {{95, 26, 143, 193, 8, 76, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 168}, + {{63, 102, 244, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 180}, + {{64, 85, 124, 226, 59, 239, 64, 130, 68, 122, 93, 74, 32, 37, 0, 0}, 112, 208}, + {{113, 90, 253, 149, 3, 218, 34, 215, 3, 143, 192, 64, 0, 0, 0, 0}, 90, 25}, + {{75, 231, 33, 5, 11, 94, 117, 104, 150, 60, 72, 161, 96, 38, 0, 0}, 111, 50}, + {{52, 13, 248, 1, 251, 14, 50, 29, 212, 123, 130, 177, 101, 96, 0, 0}, 109, 110}, + {{248, 221, 150, 132, 252, 82, 96, 2, 80, 232, 97, 239, 253, 64, 0, 0}, 109, 21}, + {{136, 77, 164, 161, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 147}, + {{1, 33, 66, 254, 144, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 43, 56}, + {{181, 25, 186, 225, 109, 190, 76, 158, 118, 122, 20, 64, 125, 55, 8, 0}, 117, 144}, + {{191, 187, 160, 140, 17, 6, 80, 120, 236, 212, 104, 144, 128, 0, 0, 0}, 100, 198}, + {{201, 61, 150, 254, 70, 77, 214, 211, 171, 163, 245, 64, 0, 0, 0, 0}, 90, 235}, + {{143, 226, 190, 50, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 105}, + {{65, 168, 226, 36, 201, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 138}, + {{136, 40, 65, 90, 47, 16, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 122}, + {{94, 189, 224, 200, 170, 11, 79, 172, 0, 0, 0, 0, 0, 0, 0, 0}, 65, 193}, + {{236, 41, 169, 234, 14, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 43, 231}, + {{1, 40, 140, 95, 81, 173, 250, 248, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 250}, + {{83, 176, 146, 112, 89, 156, 57, 220, 125, 48, 44, 0, 0, 0, 0, 0}, 86, 24}, + {{76, 125, 228, 249, 243, 160, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 191}, + {{10, 203, 204, 49, 212, 115, 125, 4, 239, 122, 81, 34, 1, 198, 216, 0}, 117, 111}, + {{74, 214, 23, 44, 211, 40, 161, 61, 237, 190, 155, 59, 173, 42, 0, 0}, 111, 205}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 133}, + {{127, 0, 130, 61, 209, 5, 232, 35, 35, 42, 114, 52, 169, 234, 191, 0}, 122, 122}, + {{201, 107, 210, 13, 187, 62, 145, 28, 31, 189, 56, 0, 0, 0, 0, 0}, 87, 227}, + {{147, 171, 63, 145, 47, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 53}, + {{93, 232, 10, 97, 21, 243, 213, 135, 200, 0, 0, 0, 0, 0, 0, 0}, 72, 224}, + {{144, 121, 41, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 199}, + {{116, 105, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 79}, + {{142, 149, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 19}, + {{97, 0, 228, 158, 50, 233, 251, 249, 0, 66, 197, 226, 0, 0, 0, 0}, 96, 211}, + {{114, 228, 199, 155, 175, 104, 26, 213, 66, 249, 120, 218, 164, 252, 212, 0}, 120, 6}, + {{224, 166, 76, 200, 121, 60, 110, 65, 60, 95, 137, 190, 92, 218, 218, 0}, 121, 143}, + {{139, 219, 92, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 135}, + {{203, 237, 64, 189, 28, 13, 75, 197, 219, 243, 172, 3, 142, 32, 0, 0}, 109, 21}, + {{237, 186, 88, 254, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 220}, + {{182, 230, 93, 162, 129, 25, 56, 196, 112, 0, 0, 0, 0, 0, 0, 0}, 68, 151}, + {{245, 45, 69, 226, 90, 212, 254, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 111}, + {{107, 229, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 63}, + {{119, 208, 177, 235, 222, 252, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 112}, + {{178, 151, 220, 162, 120, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 48}, + {{109, 26, 95, 170, 166, 151, 137, 83, 226, 82, 5, 114, 253, 210, 18, 12}, 126, 100}, + {{126, 27, 252, 19, 219, 129, 121, 48, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 156}, + {{211, 195, 152, 145, 154, 93, 228, 215, 135, 101, 28, 82, 0, 0, 0, 0}, 95, 120}, + {{252, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 5}, + {{192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 103}, + {{64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 84}, + {{225, 179, 43, 43, 222, 145, 205, 238, 164, 158, 147, 229, 56, 0, 0, 0}, 101, 24}, + {{208, 127, 151, 24, 64, 113, 47, 85, 209, 79, 144, 0, 0, 0, 0, 0}, 86, 81}, + {{178, 144, 203, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 96}, + {{56, 227, 139, 4, 86, 87, 180, 1, 215, 167, 237, 156, 111, 64, 47, 0}, 121, 6}, + {{80, 76, 204, 119, 172, 169, 254, 81, 104, 166, 219, 44, 173, 161, 212, 0}, 119, 40}, + {{129, 141, 139, 34, 241, 101, 223, 144, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 143}, + {{85, 102, 137, 98, 65, 103, 54, 142, 144, 0, 0, 0, 0, 0, 0, 0}, 68, 69}, + {{56, 31, 159, 13, 201, 139, 161, 31, 89, 137, 4, 0, 0, 0, 0, 0}, 92, 48}, + {{229, 221, 54, 216, 223, 27, 196, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 115}, + {{5, 144, 176, 43, 180, 187, 20, 49, 59, 73, 108, 34, 83, 32, 192, 0}, 115, 130}, + {{24, 217, 205, 193, 74, 123, 160, 106, 103, 74, 200, 0, 0, 0, 0, 0}, 86, 57}, + {{247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 97}, + {{12, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 146}, + {{160, 28, 201, 119, 148, 93, 251, 118, 28, 179, 123, 52, 71, 232, 48, 0}, 117, 194}, + {{152, 126, 17, 54, 101, 56, 130, 1, 205, 41, 207, 90, 151, 123, 128, 0}, 114, 129}, + {{77, 165, 29, 239, 95, 242, 34, 1, 11, 204, 135, 239, 128, 0, 0, 0}, 97, 159}, + {{183, 108, 146, 118, 74, 190, 7, 141, 9, 92, 2, 2, 8, 218, 120, 0}, 117, 242}, + {{37, 152, 29, 239, 242, 53, 56, 143, 219, 22, 14, 158, 49, 0, 0, 0}, 104, 162}, + {{198, 53, 241, 102, 240, 244, 97, 203, 62, 128, 213, 214, 220, 0, 0, 0}, 102, 140}, + {{144, 89, 48, 42, 249, 231, 189, 178, 232, 199, 30, 58, 63, 57, 0, 0}, 113, 77}, + {{68, 212, 177, 123, 44, 224, 19, 172, 89, 87, 192, 0, 0, 0, 0, 0}, 82, 121}, + {{252, 29, 179, 224, 4, 121, 205, 67, 152, 0, 0, 0, 0, 0, 0, 0}, 69, 102}, + {{28, 110, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 28}, + {{24, 88, 231, 1, 4, 71, 71, 241, 252, 14, 197, 0, 0, 0, 0, 0}, 89, 154}, + {{63, 131, 43, 76, 58, 140, 163, 74, 158, 80, 0, 0, 0, 0, 0, 0}, 76, 39}, + {{56, 28, 147, 149, 98, 93, 216, 216, 203, 156, 0, 0, 0, 0, 0, 0}, 78, 163}, + {{134, 169, 6, 103, 161, 244, 134, 117, 16, 0, 0, 0, 0, 0, 0, 0}, 68, 42}, + {{143, 247, 125, 190, 106, 50, 204, 98, 250, 151, 161, 96, 0, 0, 0, 0}, 92, 207}, + {{235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 25}, + {{46, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 150}, + {{171, 35, 128, 117, 74, 29, 199, 67, 109, 176, 0, 0, 0, 0, 0, 0}, 76, 103}, + {{220, 233, 236, 112, 135, 136, 215, 43, 42, 0, 0, 0, 0, 0, 0, 0}, 71, 155}, + {{228, 11, 144, 117, 206, 192, 118, 25, 141, 78, 4, 105, 0, 0, 0, 0}, 96, 142}, + {{195, 67, 194, 229, 14, 53, 129, 7, 30, 208, 38, 100, 182, 59, 0, 0}, 112, 2}, + {{25, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 59}, + {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 112}, + {{26, 203, 217, 152, 16, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 166}, + {{250, 213, 14, 235, 110, 171, 174, 23, 102, 128, 0, 0, 0, 0, 0, 0}, 73, 62}, + {{175, 230, 160, 13, 187, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 176}, + {{92, 155, 156, 93, 191, 73, 28, 82, 187, 129, 57, 5, 16, 0, 0, 0}, 100, 6}, + {{45, 203, 3, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 26}, + {{120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 6}, + {{216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 13}, + {{135, 215, 0, 71, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 41}, + {{221, 149, 1, 40, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 135}, + {{95, 143, 255, 194, 2, 157, 191, 113, 10, 229, 204, 56, 0, 0, 0, 0}, 93, 171}, + {{202, 212, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 20}, + {{147, 203, 238, 120, 194, 23, 25, 58, 208, 177, 169, 0, 0, 0, 0, 0}, 89, 119}, + {{137, 170, 113, 252, 215, 194, 224, 146, 233, 87, 86, 192, 26, 46, 0, 0}, 112, 49}, + {{224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 141}, + {{250, 90, 241, 174, 163, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 132}, + {{66, 190, 202, 144, 122, 86, 22, 103, 107, 164, 57, 54, 228, 128, 0, 0}, 105, 176}, + {{76, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 12, 186}, + {{120, 246, 1, 52, 187, 163, 78, 105, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 93}, + {{137, 242, 136, 71, 98, 10, 53, 97, 160, 85, 132, 127, 185, 222, 0, 0}, 111, 242}, + {{255, 133, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 163}, + {{128, 177, 92, 155, 91, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 184}, + {{45, 120, 186, 192, 240, 199, 178, 95, 32, 0, 0, 0, 0, 0, 0, 0}, 68, 188}, + {{151, 98, 103, 254, 90, 6, 10, 109, 14, 158, 69, 29, 140, 237, 40, 232}, 126, 193}, + {{148, 164, 81, 85, 76, 14, 84, 64, 89, 176, 0, 0, 0, 0, 0, 0}, 78, 63}, + {{145, 187, 165, 136, 88, 30, 107, 191, 205, 120, 119, 216, 158, 123, 64, 0}, 115, 160}, + {{78, 120, 28, 243, 216, 180, 87, 19, 253, 16, 110, 33, 228, 24, 232, 0}, 117, 251}, + {{74, 6, 166, 166, 183, 157, 96, 84, 151, 0, 0, 0, 0, 0, 0, 0}, 72, 228}, + {{89, 96, 4, 221, 214, 253, 58, 49, 9, 0, 0, 0, 0, 0, 0, 0}, 72, 168}, + {{97, 9, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 194}, + {{213, 215, 45, 200, 170, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 166}, + {{5, 14, 92, 0, 28, 245, 130, 202, 32, 40, 207, 77, 166, 170, 246, 64}, 122, 210}, + {{77, 45, 43, 71, 202, 0, 157, 146, 59, 91, 225, 0, 0, 0, 0, 0}, 89, 254}, + {{101, 174, 94, 168, 162, 171, 71, 12, 16, 224, 0, 0, 0, 0, 0, 0}, 75, 49}, + {{58, 17, 187, 194, 87, 73, 215, 103, 180, 12, 40, 66, 0, 0, 0, 0}, 96, 95}, + {{160, 91, 68, 81, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 193}, + {{94, 112, 249, 13, 167, 245, 101, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 155}, + {{236, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15, 133}, + {{168, 243, 103, 221, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 10}, + {{86, 194, 218, 188, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 31}, + {{232, 3, 134, 67, 63, 196, 86, 14, 170, 243, 77, 134, 187, 140, 72, 18}, 127, 98}, + {{55, 253, 19, 201, 199, 71, 229, 218, 54, 64, 12, 162, 0, 0, 0, 0}, 96, 22}, + {{142, 34, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 214}, + {{213, 16, 208, 50, 100, 33, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 217}, + {{117, 237, 132, 185, 184, 246, 79, 42, 103, 98, 162, 243, 128, 0, 0, 0}, 98, 102}, + {{120, 25, 214, 222, 61, 157, 203, 102, 3, 146, 192, 0, 0, 0, 0, 0}, 83, 169}, + {{222, 46, 254, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 152}, + {{254, 70, 158, 171, 11, 245, 223, 97, 70, 17, 27, 192, 186, 0, 0, 0}, 103, 214}, + {{192, 128, 228, 17, 68, 20, 44, 31, 52, 34, 212, 1, 224, 0, 0, 0}, 99, 178}, + {{237, 229, 203, 8, 121, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 164}, + {{6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 15}, + {{71, 197, 251, 122, 138, 232, 12, 241, 116, 240, 0, 0, 0, 0, 0, 0}, 76, 94}, + {{18, 241, 135, 210, 233, 54, 121, 185, 4, 0, 0, 0, 0, 0, 0, 0}, 70, 239}, + {{32, 50, 213, 63, 73, 217, 180, 21, 187, 128, 0, 0, 0, 0, 0, 0}, 73, 82}, + {{203, 166, 233, 73, 92, 182, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 54}, + {{56, 162, 126, 4, 18, 195, 192, 64, 164, 156, 119, 196, 64, 0, 0, 0}, 98, 47}, + {{120, 87, 81, 136, 180, 179, 68, 148, 243, 38, 80, 0, 0, 0, 0, 0}, 84, 214}, + {{64, 244, 193, 50, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 215}, + {{91, 168, 253, 158, 131, 83, 159, 163, 113, 169, 112, 0, 0, 0, 0, 0}, 84, 153}, + {{159, 103, 102, 132, 111, 46, 18, 77, 36, 15, 137, 33, 177, 31, 243, 192}, 122, 245}, + {{123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 118}, + {{67, 81, 226, 190, 7, 79, 71, 250, 155, 245, 44, 81, 215, 213, 171, 224}, 123, 128}, + {{103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 7}, + {{246, 44, 168, 200, 198, 238, 52, 196, 125, 115, 0, 0, 0, 0, 0, 0}, 80, 152}, + {{205, 14, 186, 252, 239, 213, 59, 119, 105, 37, 140, 209, 4, 231, 0, 0}, 114, 248}, + {{70, 91, 254, 106, 94, 71, 170, 19, 158, 242, 192, 0, 0, 0, 0, 0}, 85, 143}, + {{250, 86, 233, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 159}, + {{122, 222, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 11}, + {{27, 224, 235, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 110}, + {{239, 100, 224, 3, 46, 127, 150, 251, 204, 120, 228, 64, 0, 0, 0, 0}, 97, 181}, + {{144, 115, 182, 206, 146, 13, 21, 111, 37, 70, 179, 129, 173, 82, 93, 128}, 121, 4}, + {{73, 190, 57, 243, 49, 51, 15, 209, 0, 0, 0, 0, 0, 0, 0, 0}, 67, 101}, + {{18, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 38}, + {{23, 37, 236, 177, 186, 7, 209, 135, 114, 44, 0, 0, 0, 0, 0, 0}, 78, 57}, + {{200, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 142}, + {{181, 255, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 184}, + {{135, 168, 6, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 91}, + {{200, 224, 33, 245, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 224}, + {{70, 111, 10, 62, 200, 224, 38, 204, 14, 164, 0, 0, 0, 0, 0, 0}, 78, 114}, + {{158, 133, 252, 18, 242, 12, 16, 60, 5, 52, 251, 179, 38, 235, 12, 0}, 118, 184}, + {{2, 23, 116, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 215}, + {{33, 25, 170, 74, 215, 134, 151, 181, 175, 232, 20, 155, 189, 242, 13, 0}, 120, 167}, + {{160, 186, 218, 183, 167, 84, 59, 152, 13, 137, 80, 128, 0, 0, 0, 0}, 89, 233}, + {{32, 141, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 101}, + {{207, 24, 202, 226, 191, 136, 78, 124, 160, 0, 0, 0, 0, 0, 0, 0}, 67, 139}, + {{210, 173, 172, 27, 197, 57, 114, 146, 169, 32, 0, 0, 0, 0, 0, 0}, 79, 32}, + {{95, 113, 12, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 57}, + {{129, 108, 186, 28, 19, 229, 96, 134, 199, 254, 199, 64, 0, 0, 0, 0}, 91, 151}, + {{103, 226, 38, 123, 35, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 0}, + {{41, 117, 43, 35, 208, 115, 73, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 227}, + {{42, 220, 61, 34, 199, 183, 42, 16, 223, 135, 0, 135, 213, 150, 100, 0}, 118, 124}, + {{165, 227, 96, 243, 112, 171, 117, 106, 50, 37, 82, 60, 80, 0, 0, 0}, 104, 228}, + {{158, 60, 111, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 64}, + {{124, 108, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 179}, + {{232, 68, 132, 159, 156, 103, 95, 190, 76, 0, 0, 0, 0, 0, 0, 0}, 70, 107}, + {{70, 77, 240, 209, 72, 63, 63, 45, 125, 79, 77, 41, 13, 0, 0, 0}, 104, 206}, + {{146, 254, 7, 5, 68, 240, 67, 237, 112, 0, 0, 0, 0, 0, 0, 0}, 68, 95}, + {{162, 223, 117, 27, 2, 156, 94, 170, 157, 114, 162, 50, 0, 0, 0, 0}, 96, 219}, + {{161, 62, 191, 68, 239, 73, 100, 37, 168, 254, 139, 202, 252, 65, 74, 0}, 119, 138}, + {{248, 122, 115, 81, 15, 158, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 84}, + {{8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 161}, + {{142, 96, 105, 133, 251, 57, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 25}, + {{138, 196, 139, 131, 233, 93, 65, 242, 86, 169, 7, 72, 82, 128, 0, 0}, 107, 113}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 46}, + {{175, 151, 75, 238, 26, 12, 100, 186, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 72}, + {{82, 205, 211, 176, 170, 79, 57, 153, 161, 218, 32, 48, 0, 0, 0, 0}, 93, 230}, + {{227, 123, 232, 74, 236, 202, 211, 121, 200, 8, 59, 189, 81, 219, 144, 0}, 117, 142}, + {{205, 196, 89, 90, 103, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 134}, + {{63, 145, 23, 127, 102, 216, 49, 36, 168, 164, 59, 133, 18, 146, 0, 0}, 112, 100}, + {{213, 72, 154, 16, 230, 236, 218, 203, 223, 51, 31, 251, 103, 64, 0, 0}, 109, 45}, + {{126, 148, 232, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 219}, + {{160, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 52}, + {{137, 38, 146, 20, 99, 188, 83, 123, 159, 159, 64, 0, 0, 0, 0, 0}, 83, 240}, + {{123, 228, 36, 44, 242, 29, 51, 228, 140, 60, 237, 0, 0, 0, 0, 0}, 90, 13}, + {{163, 169, 25, 89, 190, 114, 165, 158, 140, 210, 192, 0, 0, 0, 0, 0}, 84, 191}, + {{225, 38, 70, 89, 218, 236, 60, 5, 69, 163, 248, 50, 163, 64, 0, 0}, 106, 95}, + {{91, 94, 36, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 65}, + {{209, 238, 110, 0, 2, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 195}, + {{57, 17, 224, 164, 69, 95, 138, 172, 111, 55, 239, 167, 160, 0, 0, 0}, 103, 21}, + {{112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 114}, + {{102, 96, 223, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 92}, + {{137, 204, 150, 75, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 237}, + {{136, 56, 252, 240, 85, 48, 248, 231, 17, 49, 47, 238, 15, 233, 159, 184}, 125, 172}, + {{57, 31, 132, 123, 234, 255, 37, 82, 167, 204, 37, 158, 128, 0, 0, 0}, 98, 116}, + {{55, 198, 139, 219, 161, 156, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 54}, + {{44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 203}, + {{53, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 74}, + {{227, 62, 107, 236, 118, 156, 60, 34, 31, 179, 76, 221, 0, 0, 0, 0}, 96, 220}, + {{105, 40, 240, 216, 91, 61, 19, 128, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 219}, + {{96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 179}, + {{118, 142, 251, 249, 128, 105, 113, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 61, 194}, + {{101, 70, 196, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 187}, + {{245, 173, 165, 177, 200, 161, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 79}, + {{0, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 87}, + {{92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 126}, + {{125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 106}, + {{56, 59, 35, 82, 101, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 96}, + {{184, 72, 77, 251, 8, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 45}, + {{143, 74, 132, 205, 218, 247, 30, 160, 145, 199, 138, 12, 89, 220, 0, 0}, 110, 8}, + {{30, 178, 111, 225, 73, 79, 173, 52, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 226}, + {{224, 48, 154, 231, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 222}, + {{123, 144, 170, 143, 85, 169, 130, 245, 214, 0, 0, 0, 0, 0, 0, 0}, 71, 218}, + {{166, 224, 212, 100, 149, 55, 35, 210, 246, 108, 41, 245, 127, 174, 128, 0}, 116, 59}, + {{75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 80}, + {{197, 128, 190, 87, 47, 53, 92, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 177}, + {{249, 10, 76, 217, 225, 20, 124, 205, 44, 159, 190, 8, 0, 0, 0, 0}, 98, 44}, + {{180, 226, 0, 167, 137, 232, 174, 120, 113, 95, 22, 184, 0, 0, 0, 0}, 93, 206}, + {{123, 153, 102, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 64}, + {{5, 144, 206, 158, 239, 189, 171, 120, 69, 46, 128, 237, 0, 0, 0, 0}, 96, 236}, + {{159, 235, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 101}, + {{42, 194, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 49}, + {{205, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 179}, + {{19, 65, 141, 20, 127, 77, 70, 205, 151, 115, 157, 23, 118, 128, 0, 0}, 109, 112}, + {{96, 11, 214, 40, 245, 251, 61, 64, 128, 241, 183, 183, 0, 0, 0, 0}, 96, 31}, + {{120, 4, 235, 112, 34, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 111}, + {{110, 127, 207, 76, 100, 148, 130, 206, 249, 2, 104, 0, 0, 0, 0, 0}, 86, 65}, + {{226, 190, 191, 249, 173, 96, 127, 200, 62, 20, 0, 0, 0, 0, 0, 0}, 78, 222}, + {{89, 88, 182, 14, 78, 122, 213, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 4}, + {{167, 94, 163, 227, 28, 111, 117, 103, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 67}, + {{57, 220, 53, 116, 243, 184, 242, 134, 16, 70, 83, 61, 161, 128, 0, 0}, 109, 197}, + {{63, 235, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 121}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 167}, + {{15, 159, 42, 167, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 140}, + {{216, 252, 113, 40, 239, 46, 172, 48, 103, 250, 82, 179, 136, 64, 0, 0}, 106, 193}, + {{158, 147, 16, 44, 124, 56, 44, 48, 138, 64, 169, 0, 0, 0, 0, 0}, 90, 47}, + {{238, 238, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 187}, + {{63, 159, 177, 162, 106, 212, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 102}, + {{59, 40, 252, 185, 187, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 237}, + {{2, 218, 11, 68, 173, 196, 16, 223, 2, 18, 122, 215, 154, 0, 0, 0}, 103, 237}, + {{3, 9, 206, 73, 108, 196, 183, 119, 141, 162, 10, 180, 115, 32, 0, 0}, 107, 115}, + {{17, 227, 208, 146, 63, 201, 73, 239, 29, 79, 80, 0, 0, 0, 0, 0}, 84, 217}, + {{115, 180, 176, 241, 52, 209, 6, 64, 189, 76, 0, 0, 0, 0, 0, 0}, 79, 21}, + {{191, 88, 98, 245, 91, 46, 137, 254, 170, 80, 11, 55, 212, 28, 128, 0}, 113, 3}, + {{97, 141, 171, 175, 22, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 62}, + {{32, 204, 102, 191, 164, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 80}, + {{29, 133, 210, 252, 124, 66, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 184}, + {{207, 179, 54, 144, 116, 67, 29, 64, 13, 199, 0, 0, 0, 0, 0, 0}, 80, 197}, + {{129, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 63}, + {{50, 152, 249, 143, 174, 234, 240, 48, 158, 255, 80, 105, 0, 0, 0, 0}, 99, 62}, + {{105, 208, 95, 218, 44, 11, 87, 134, 109, 18, 138, 66, 17, 69, 128, 0}, 114, 231}, + {{151, 79, 158, 220, 122, 101, 210, 164, 64, 0, 0, 0, 0, 0, 0, 0}, 67, 158}, + {{236, 97, 87, 155, 254, 137, 122, 208, 168, 201, 194, 118, 224, 0, 0, 0}, 101, 118}, + {{14, 229, 193, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 237}, + {{46, 154, 50, 80, 92, 147, 158, 86, 1, 112, 0, 0, 0, 0, 0, 0}, 79, 15}, + {{88, 131, 21, 84, 62, 86, 7, 110, 142, 251, 242, 110, 194, 175, 247, 0}, 122, 84}, + {{229, 216, 111, 92, 173, 32, 63, 70, 36, 84, 6, 74, 136, 166, 38, 0}, 119, 205}, + {{121, 147, 216, 245, 37, 189, 146, 63, 145, 74, 128, 0, 0, 0, 0, 0}, 82, 220}, + {{44, 26, 254, 11, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 42}, + {{209, 114, 97, 249, 227, 159, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 144}, + {{184, 244, 43, 117, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 74}, + {{60, 81, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 89}, + {{18, 40, 21, 113, 226, 91, 195, 88, 161, 19, 142, 0, 0, 0, 0, 0}, 88, 77}, + {{57, 0, 212, 158, 56, 51, 108, 198, 59, 5, 137, 196, 0, 0, 0, 0}, 94, 2}, + {{168, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 75}, + {{64, 181, 254, 103, 1, 230, 117, 199, 128, 0, 0, 0, 0, 0, 0, 0}, 65, 18}, + {{212, 48, 214, 127, 78, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 246}, + {{155, 185, 236, 163, 204, 49, 129, 120, 183, 47, 10, 243, 65, 92, 192, 0}, 114, 10}, + {{94, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 207}, + {{19, 210, 136, 113, 73, 79, 132, 196, 224, 0, 0, 0, 0, 0, 0, 0}, 68, 41}, + {{24, 203, 246, 242, 241, 223, 150, 237, 213, 202, 11, 128, 0, 0, 0, 0}, 89, 102}, + {{115, 59, 171, 221, 172, 181, 170, 67, 115, 205, 44, 107, 162, 67, 56, 0}, 118, 118}, + {{250, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 146}, + {{203, 240, 28, 158, 182, 12, 86, 182, 142, 47, 143, 57, 239, 0, 0, 0}, 104, 122}, + {{196, 218, 109, 52, 2, 0, 64, 153, 34, 250, 240, 185, 117, 0, 0, 0}, 107, 6}, + {{137, 131, 191, 40, 72, 209, 74, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 18}, + {{236, 126, 167, 37, 185, 20, 34, 207, 76, 0, 0, 0, 0, 0, 0, 0}, 70, 83}, + {{129, 192, 245, 137, 251, 52, 75, 68, 81, 112, 146, 133, 64, 0, 0, 0}, 99, 90}, + {{7, 31, 148, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 140}, + {{112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 242}, + {{167, 50, 202, 179, 74, 146, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 31}, + {{44, 188, 186, 250, 229, 71, 28, 118, 35, 253, 245, 191, 199, 18, 0, 0}, 111, 9}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 230}, + {{156, 163, 215, 175, 71, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 50}, + {{67, 24, 151, 198, 242, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41, 34}, + {{134, 107, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 11}, + {{35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8, 71}, + {{46, 196, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 146}, + {{82, 172, 8, 26, 154, 34, 125, 188, 5, 149, 159, 44, 78, 222, 236, 176}, 124, 249}, + {{78, 157, 79, 70, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 143}, + {{231, 5, 210, 247, 198, 5, 157, 191, 206, 225, 149, 142, 207, 40, 0, 0}, 110, 17}, + {{38, 254, 235, 199, 191, 60, 43, 159, 190, 243, 203, 185, 184, 218, 132, 0}, 119, 60}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 162}, + {{95, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 12, 5}, + {{17, 128, 244, 178, 160, 78, 83, 92, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 139}, + {{18, 102, 62, 251, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 8}, + {{30, 75, 108, 40, 231, 166, 233, 220, 163, 176, 252, 210, 60, 30, 128, 0}, 114, 246}, + {{18, 3, 207, 64, 25, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 171}, + {{52, 83, 235, 61, 164, 236, 83, 173, 143, 105, 14, 0, 0, 0, 0, 0}, 88, 206}, + {{166, 175, 186, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 163}, + {{221, 154, 82, 98, 41, 126, 85, 52, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 166}, + {{94, 84, 182, 120, 204, 232, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 128}, + {{27, 174, 227, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 59}, + {{218, 12, 4, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 179}, + {{9, 5, 190, 195, 60, 216, 80, 150, 128, 117, 86, 128, 128, 112, 98, 208}, 124, 87}, + {{7, 226, 104, 112, 212, 9, 172, 124, 209, 121, 170, 229, 44, 178, 128, 0}, 114, 29}, + {{47, 71, 174, 76, 52, 83, 23, 18, 106, 48, 56, 32, 0, 0, 0, 0}, 91, 184}, + {{51, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 45}, + {{28, 182, 167, 124, 28, 22, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 144}, + {{34, 61, 14, 51, 253, 17, 19, 170, 49, 206, 188, 207, 247, 167, 192, 0}, 114, 119}, + {{2, 235, 18, 14, 195, 66, 237, 30, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 113}, + {{51, 182, 142, 133, 127, 96, 159, 132, 99, 161, 64, 0, 0, 0, 0, 0}, 82, 50}, + {{170, 145, 230, 123, 215, 189, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 207}, + {{151, 166, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 3}, + {{16, 141, 196, 129, 132, 207, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 13}, + {{205, 25, 184, 191, 201, 206, 109, 224, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 42}, + {{48, 114, 33, 103, 247, 255, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 31}, + {{179, 156, 119, 146, 125, 21, 42, 146, 237, 213, 191, 132, 0, 0, 0, 0}, 94, 30}, + {{179, 129, 186, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 94}, + {{17, 179, 217, 188, 128, 212, 4, 4, 152, 0, 0, 0, 0, 0, 0, 0}, 71, 190}, + {{132, 63, 74, 89, 209, 64, 63, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 238}, + {{16, 50, 248, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 20}, + {{189, 96, 58, 53, 191, 235, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 84}, + {{111, 98, 6, 65, 35, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 108}, + {{118, 223, 83, 220, 110, 122, 23, 112, 185, 155, 73, 0, 0, 0, 0, 0}, 89, 136}, + {{173, 191, 150, 197, 204, 35, 169, 79, 31, 214, 251, 240, 0, 0, 0, 0}, 93, 196}, + {{26, 76, 129, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 67}, + {{231, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 12, 104}, + {{93, 172, 223, 252, 203, 0, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 15}, + {{53, 142, 203, 124, 104, 51, 241, 12, 161, 17, 101, 245, 120, 110, 192, 199}, 128, 237}, + {{9, 77, 120, 197, 193, 10, 237, 174, 233, 2, 165, 11, 229, 47, 144, 0}, 116, 224}, + {{99, 161, 189, 88, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 179}, + {{18, 8, 76, 66, 2, 185, 206, 132, 224, 0, 0, 0, 0, 0, 0, 0}, 67, 84}, + {{169, 53, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 65}, + {{136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 178}, + {{131, 162, 144, 124, 12, 98, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 154}, + {{75, 50, 129, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 27, 106}, + {{212, 183, 40, 225, 152, 136, 174, 91, 0, 0, 0, 0, 0, 0, 0, 0}, 67, 125}, + {{158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 118}, + {{7, 48, 132, 149, 169, 212, 198, 137, 202, 0, 0, 0, 0, 0, 0, 0}, 73, 52}, + {{173, 195, 129, 163, 141, 249, 40, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 173}, + {{109, 79, 75, 219, 205, 182, 22, 245, 223, 17, 146, 78, 109, 119, 128, 0}, 113, 8}, + {{174, 195, 24, 182, 215, 198, 214, 86, 34, 128, 0, 0, 0, 0, 0, 0}, 74, 211}, + {{22, 40, 51, 109, 70, 91, 152, 56, 0, 0, 0, 0, 0, 0, 0, 0}, 61, 253}, + {{169, 115, 246, 126, 65, 118, 219, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 47}, + {{154, 37, 70, 124, 107, 123, 232, 241, 164, 142, 71, 226, 182, 126, 0, 0}, 112, 73}, + {{6, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 192}, + {{216, 167, 158, 158, 222, 19, 96, 28, 40, 6, 70, 12, 147, 27, 85, 240}, 128, 55}, + {{72, 222, 52, 69, 69, 206, 163, 106, 235, 206, 80, 128, 0, 0, 0, 0}, 94, 147}, + {{150, 112, 106, 56, 15, 243, 154, 97, 134, 110, 160, 20, 183, 144, 234, 8}, 125, 86}, + {{58, 186, 106, 58, 124, 171, 53, 85, 33, 100, 64, 0, 0, 0, 0, 0}, 82, 16}, + {{7, 195, 22, 31, 62, 217, 209, 46, 90, 49, 189, 50, 168, 126, 0, 0}, 111, 167}, + {{92, 44, 159, 198, 185, 94, 231, 177, 64, 0, 0, 0, 0, 0, 0, 0}, 67, 148}, + {{169, 108, 190, 162, 23, 39, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 66}, + {{161, 5, 3, 11, 158, 157, 166, 212, 246, 22, 140, 101, 92, 0, 0, 0}, 104, 70}, + {{71, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 166}, + {{48, 136, 194, 145, 57, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 109}, + {{144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 226}, + {{223, 209, 10, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 8}, + {{154, 79, 170, 9, 43, 139, 249, 176, 186, 72, 216, 0, 0, 0, 0, 0}, 85, 218}, + {{1, 8, 123, 205, 167, 134, 128, 102, 10, 72, 0, 0, 0, 0, 0, 0}, 78, 54}, + {{31, 105, 48, 77, 103, 187, 99, 67, 96, 0, 0, 0, 0, 0, 0, 0}, 67, 48}, + {{14, 73, 54, 76, 232, 35, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 244}, + {{14, 109, 251, 190, 36, 253, 99, 120, 94, 64, 0, 0, 0, 0, 0, 0}, 74, 50}, + {{122, 170, 9, 134, 124, 91, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 173}, + {{246, 10, 85, 88, 82, 217, 95, 56, 216, 203, 160, 0, 0, 0, 0, 0}, 84, 245}, + {{77, 100, 114, 207, 150, 177, 69, 134, 74, 131, 147, 117, 177, 64, 210, 128}, 121, 54}, + {{171, 123, 22, 138, 132, 229, 250, 81, 186, 227, 146, 27, 170, 205, 128, 0}, 113, 86}, + {{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 115}, + {{12, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 144}, + {{255, 124, 179, 165, 169, 250, 66, 171, 223, 125, 247, 0, 0, 0, 0, 0}, 89, 171}, + {{244, 235, 211, 10, 251, 255, 206, 6, 198, 12, 50, 136, 0, 0, 0, 0}, 93, 231}, + {{221, 77, 237, 41, 50, 33, 103, 24, 25, 127, 208, 0, 0, 0, 0, 0}, 88, 34}, + {{216, 69, 47, 53, 117, 24, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 225}, + {{180, 87, 25, 236, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 174}, + {{110, 32, 24, 34, 116, 133, 245, 128, 123, 95, 125, 122, 100, 129, 128, 0}, 113, 37}, + {{27, 117, 179, 112, 133, 137, 110, 193, 246, 201, 219, 65, 56, 234, 106, 128}, 121, 39}, + {{186, 117, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 59}, + {{243, 119, 54, 16, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 96}, + {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 147}, + {{78, 48, 117, 200, 245, 118, 115, 240, 170, 125, 84, 103, 33, 168, 0, 0}, 110, 56}, + {{201, 253, 184, 254, 143, 81, 95, 42, 243, 147, 96, 145, 23, 26, 0, 0}, 111, 234}, + {{41, 215, 84, 136, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 199}, + {{91, 244, 137, 184, 231, 95, 135, 10, 184, 0, 0, 0, 0, 0, 0, 0}, 69, 191}, + {{113, 31, 181, 245, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 235}, + {{181, 216, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 45}, + {{87, 26, 119, 229, 97, 255, 9, 43, 32, 0, 0, 0, 0, 0, 0, 0}, 67, 164}, + {{205, 112, 67, 163, 196, 148, 5, 105, 8, 138, 144, 3, 171, 213, 159, 128}, 121, 130}, + {{136, 27, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 166}, + {{2, 175, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 140}, + {{222, 131, 85, 218, 16, 229, 44, 230, 243, 76, 250, 139, 1, 203, 108, 0}, 118, 47}, + {{101, 180, 77, 142, 194, 73, 196, 246, 107, 100, 194, 72, 204, 124, 0, 0}, 111, 148}, + {{96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 103}, + {{46, 62, 191, 130, 110, 128, 235, 62, 68, 39, 58, 152, 207, 204, 96, 0}, 116, 94}, + {{111, 11, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 85}, + {{58, 43, 14, 93, 102, 210, 117, 208, 222, 171, 130, 41, 16, 16, 0, 0}, 109, 250}, + {{141, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 153}, + {{170, 153, 160, 170, 144, 235, 122, 8, 106, 34, 24, 32, 102, 57, 12, 168}, 125, 182}, + {{34, 113, 163, 107, 61, 177, 39, 172, 242, 2, 130, 0, 0, 0, 0, 0}, 94, 23}, + {{222, 191, 239, 110, 162, 191, 195, 181, 80, 50, 85, 240, 88, 32, 0, 0}, 108, 38}, + {{179, 82, 253, 151, 212, 0, 72, 253, 175, 22, 34, 78, 53, 32, 0, 0}, 110, 121}, + {{10, 162, 20, 46, 164, 64, 88, 1, 202, 204, 124, 0, 0, 0, 0, 0}, 87, 146}, + {{210, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 138}, + {{183, 200, 1, 2, 51, 6, 66, 142, 20, 77, 48, 244, 0, 0, 0, 0}, 94, 149}, + {{29, 20, 224, 57, 204, 161, 131, 254, 53, 133, 163, 0, 0, 0, 0, 0}, 88, 232}, + {{75, 58, 170, 52, 146, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 255}, + {{92, 21, 1, 113, 185, 88, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 148}, + {{103, 180, 222, 187, 129, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 117}, + {{32, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 237}, + {{7, 60, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 113}, + {{167, 122, 205, 185, 21, 199, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 162}, + {{21, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 225}, + {{92, 159, 167, 169, 136, 176, 95, 255, 87, 137, 112, 16, 0, 0, 0, 0}, 92, 210}, + {{84, 120, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 34}, + {{126, 5, 126, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 224}, + {{4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 143}, + {{239, 154, 181, 182, 189, 211, 244, 53, 144, 0, 0, 0, 0, 0, 0, 0}, 68, 216}, + {{254, 188, 139, 167, 135, 47, 147, 239, 187, 106, 228, 156, 234, 234, 102, 0}, 120, 239}, + {{225, 168, 138, 92, 193, 255, 47, 233, 11, 154, 205, 86, 209, 88, 0, 0}, 111, 54}, + {{223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 35}, + {{235, 252, 115, 10, 151, 104, 193, 207, 38, 228, 229, 245, 42, 13, 108, 0}, 119, 230}, + {{1, 137, 53, 36, 210, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 234}, + {{149, 182, 72, 197, 92, 229, 9, 10, 220, 128, 72, 19, 4, 58, 192, 0}, 115, 70}, + {{105, 73, 57, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 246}, + {{189, 61, 230, 24, 235, 82, 58, 102, 97, 111, 121, 252, 156, 94, 191, 166}, 127, 217}, + {{193, 108, 231, 86, 140, 14, 192, 4, 135, 80, 129, 166, 158, 61, 230, 20}, 128, 201}, + {{110, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 17, 49}, + {{3, 102, 36, 231, 15, 242, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 2}, + {{81, 189, 220, 168, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 64}, + {{168, 75, 133, 180, 91, 165, 77, 232, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 239}, + {{106, 179, 186, 109, 81, 234, 233, 167, 101, 160, 90, 102, 174, 234, 208, 0}, 116, 47}, + {{46, 105, 234, 21, 23, 247, 169, 33, 47, 5, 0, 0, 0, 0, 0, 0}, 80, 43}, + {{152, 144, 100, 142, 129, 23, 227, 50, 67, 81, 249, 116, 0, 0, 0, 0}, 94, 17}, + {{109, 74, 145, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 5}, + {{100, 243, 22, 230, 38, 44, 128, 86, 132, 57, 0, 0, 0, 0, 0, 0}, 81, 240}, + {{153, 251, 115, 65, 104, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 197}, + {{43, 113, 60, 224, 36, 20, 42, 161, 24, 223, 192, 0, 0, 0, 0, 0}, 84, 192}, + {{61, 77, 121, 176, 138, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 160}, + {{119, 194, 146, 49, 59, 242, 25, 220, 122, 104, 80, 0, 0, 0, 0, 0}, 84, 199}, + {{254, 162, 155, 47, 187, 3, 1, 114, 142, 191, 152, 44, 144, 26, 202, 0}, 127, 217}, + {{176, 1, 114, 42, 191, 145, 43, 1, 141, 18, 64, 0, 0, 0, 0, 0}, 83, 75}, + {{170, 244, 67, 132, 145, 163, 76, 213, 85, 237, 248, 22, 207, 64, 0, 0}, 106, 222}, + {{102, 190, 58, 32, 75, 15, 89, 163, 64, 7, 168, 0, 0, 0, 0, 0}, 85, 39}, + {{124, 170, 35, 47, 152, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 9}, + {{192, 221, 20, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 217}, + {{208, 178, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 142}, + {{188, 68, 77, 30, 68, 153, 102, 180, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 18}, + {{114, 178, 121, 188, 205, 233, 35, 77, 34, 197, 158, 174, 101, 0, 0, 0}, 104, 180}, + {{195, 98, 67, 12, 13, 43, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 205}, + {{146, 190, 42, 222, 14, 54, 28, 128, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 251}, + {{185, 202, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 178}, + {{138, 30, 129, 95, 224, 161, 120, 128, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 198}, + {{69, 181, 5, 227, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 84}, + {{90, 180, 0, 164, 227, 75, 174, 119, 128, 0, 0, 0, 0, 0, 0, 0}, 66, 128}, + {{20, 60, 58, 119, 245, 177, 162, 186, 13, 112, 211, 239, 128, 0, 0, 0}, 97, 75}, + {{158, 124, 157, 25, 230, 139, 51, 212, 76, 109, 236, 210, 48, 0, 0, 0}, 101, 192}, + {{125, 108, 242, 36, 94, 13, 36, 106, 90, 51, 83, 217, 131, 151, 0, 0}, 114, 60}, + {{222, 218, 162, 158, 15, 53, 191, 178, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 169}, + {{104, 202, 127, 109, 73, 16, 17, 12, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 10}, + {{172, 171, 246, 26, 176, 34, 22, 152, 246, 56, 173, 120, 105, 60, 92, 0}, 118, 64}, + {{190, 22, 171, 206, 109, 186, 179, 128, 253, 182, 108, 212, 220, 167, 171, 180}, 127, 182}, + {{119, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 29}, + {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 39}, + {{170, 144, 64, 2, 107, 166, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 93}, + {{234, 9, 96, 20, 156, 157, 1, 34, 88, 0, 0, 0, 0, 0, 0, 0}, 75, 228}, + {{147, 237, 16, 120, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 236}, + {{182, 189, 162, 158, 223, 90, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 190}, + {{116, 148, 142, 240, 10, 253, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 217}, + {{211, 73, 140, 69, 252, 27, 75, 46, 37, 6, 147, 32, 0, 0, 0, 0}, 93, 74}, + {{148, 61, 120, 49, 220, 65, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 61, 180}, + {{172, 35, 202, 180, 129, 75, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 91}, + {{215, 109, 147, 157, 32, 28, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 230}, + {{151, 26, 182, 112, 205, 220, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 175}, + {{73, 91, 93, 61, 196, 3, 66, 26, 149, 96, 0, 0, 0, 0, 0, 0}, 75, 171}, + {{203, 163, 52, 247, 28, 119, 56, 223, 138, 70, 174, 97, 77, 59, 46, 0}, 120, 202}, + {{251, 50, 228, 178, 202, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 113}, + {{217, 159, 164, 199, 14, 237, 170, 184, 100, 231, 92, 222, 0, 0, 0, 0}, 96, 187}, + {{16, 161, 85, 193, 202, 21, 3, 155, 63, 116, 124, 203, 34, 13, 215, 0}, 120, 38}, + {{111, 52, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 35}, + {{69, 12, 116, 151, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 115}, + {{187, 60, 97, 40, 112, 101, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 18}, + {{230, 194, 136, 255, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 34}, + {{179, 239, 170, 107, 3, 13, 212, 67, 177, 69, 8, 0, 0, 0, 0, 0}, 87, 75}, + {{11, 58, 130, 89, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 232}, + {{217, 178, 43, 203, 234, 20, 234, 186, 157, 88, 146, 192, 0, 0, 0, 0}, 91, 154}, + {{6, 180, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 195}, + {{157, 154, 218, 158, 39, 224, 103, 230, 164, 0, 0, 0, 0, 0, 0, 0}, 70, 122}, + {{225, 10, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 97}, + {{16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 220}, + {{166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 80}, + {{29, 190, 131, 215, 232, 246, 41, 226, 52, 192, 0, 0, 0, 0, 0, 0}, 77, 133}, + {{138, 74, 163, 93, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 38, 93}, + {{229, 64, 97, 41, 28, 243, 249, 185, 97, 35, 49, 27, 175, 24, 0, 0}, 110, 176}, + {{6, 73, 94, 160, 186, 216, 84, 117, 233, 169, 146, 234, 0, 0, 0, 0}, 95, 68}, + {{163, 40, 242, 81, 224, 35, 72, 194, 176, 78, 224, 174, 12, 0, 0, 0}, 103, 247}, + {{2, 205, 40, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 240}, + {{174, 225, 240, 160, 212, 8, 246, 67, 36, 0, 0, 0, 0, 0, 0, 0}, 74, 83}, + {{5, 117, 182, 141, 166, 249, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 132}, + {{46, 152, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 217}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 214}, + {{233, 202, 159, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 193}, + {{172, 54, 159, 5, 14, 245, 106, 182, 2, 0, 0, 0, 0, 0, 0, 0}, 71, 61}, + {{241, 222, 251, 114, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 65}, + {{31, 243, 190, 4, 207, 198, 249, 59, 167, 127, 93, 64, 0, 0, 0, 0}, 91, 108}, + {{201, 35, 222, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 244}, + {{187, 105, 13, 114, 238, 197, 145, 23, 169, 116, 91, 28, 0, 0, 0, 0}, 95, 194}, + {{251, 251, 121, 168, 152, 178, 147, 188, 229, 123, 154, 242, 190, 165, 173, 48}, 124, 82}, + {{66, 187, 191, 164, 31, 196, 40, 186, 148, 115, 134, 57, 222, 254, 48, 0}, 116, 45}, + {{209, 17, 111, 41, 154, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 224}, + {{40, 245, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 17}, + {{72, 121, 151, 83, 170, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 133}, + {{171, 172, 101, 238, 201, 148, 23, 81, 4, 11, 64, 0, 0, 0, 0, 0}, 85, 125}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 42}, + {{20, 46, 27, 93, 195, 184, 6, 162, 109, 225, 22, 152, 0, 0, 0, 0}, 96, 140}, + {{243, 122, 30, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 91}, + {{89, 250, 80, 72, 148, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 92}, + {{187, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 125}, + {{172, 160, 143, 114, 128, 239, 174, 133, 176, 154, 159, 134, 10, 0, 0, 0}, 106, 249}, + {{254, 202, 113, 112, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 202}, + {{80, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 107}, + {{222, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 13, 124}, + {{219, 138, 253, 12, 188, 197, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 57}, + {{124, 41, 173, 8, 202, 192, 61, 254, 174, 48, 239, 112, 0, 0, 0, 0}, 92, 181}, + {{195, 236, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 107}, + {{83, 82, 42, 244, 136, 191, 197, 81, 91, 154, 216, 85, 29, 150, 198, 22}, 128, 101}, + {{112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 102}, + {{44, 30, 219, 248, 214, 88, 225, 132, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 136}, + {{41, 171, 206, 178, 195, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 114}, + {{159, 15, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 215}, + {{42, 188, 37, 174, 86, 40, 4, 84, 174, 216, 0, 0, 0, 0, 0, 0}, 79, 249}, + {{185, 227, 85, 177, 219, 95, 250, 227, 69, 154, 118, 0, 0, 0, 0, 0}, 88, 29}, + {{22, 185, 238, 100, 25, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44, 71}, + {{122, 149, 117, 77, 88, 250, 187, 203, 136, 22, 85, 42, 105, 234, 79, 8}, 127, 112}, + {{93, 152, 229, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 31, 72}, + {{129, 37, 165, 167, 241, 24, 37, 40, 2, 128, 0, 0, 0, 0, 0, 0}, 73, 155}, + {{30, 202, 177, 3, 253, 202, 164, 248, 0, 0, 0, 0, 0, 0, 0, 0}, 61, 66}, + {{176, 25, 220, 120, 194, 228, 10, 45, 225, 142, 192, 96, 0, 0, 0, 0}, 91, 77}, + {{96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 109}, + {{82, 56, 12, 204, 61, 45, 147, 240, 221, 0, 0, 0, 0, 0, 0, 0}, 72, 37}, + {{242, 38, 240, 41, 140, 75, 250, 37, 175, 115, 97, 224, 0, 0, 0, 0}, 91, 56}, + {{251, 192, 23, 90, 135, 56, 252, 56, 79, 219, 80, 167, 22, 0, 0, 0}, 103, 5}, + {{62, 128, 139, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 15}, + {{214, 1, 84, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 183}, + {{207, 90, 237, 137, 171, 140, 227, 88, 250, 26, 197, 162, 163, 0, 0, 0}, 105, 171}, + {{196, 151, 235, 232, 114, 248, 1, 207, 193, 184, 186, 71, 157, 0, 0, 0}, 112, 202}, + {{152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 136}, + {{9, 174, 211, 200, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 37, 107}, + {{89, 150, 95, 28, 209, 13, 125, 159, 254, 244, 110, 0, 0, 0, 0, 0}, 87, 193}, + {{23, 28, 202, 10, 90, 158, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 4}, + {{48, 25, 180, 9, 84, 236, 6, 144, 30, 198, 41, 56, 0, 0, 0, 0}, 96, 68}, + {{252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7, 40}, + {{20, 165, 57, 130, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 255}, + {{167, 56, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 108}, + {{91, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 219}, + {{24, 46, 9, 4, 170, 150, 56, 130, 127, 120, 118, 104, 168, 48, 0, 0}, 108, 12}, + {{156, 60, 245, 247, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 84}, + {{148, 104, 187, 174, 129, 28, 127, 162, 92, 222, 52, 18, 0, 0, 0, 0}, 96, 33}, + {{38, 253, 182, 153, 233, 194, 159, 41, 94, 193, 254, 160, 0, 0, 0, 0}, 91, 199}, + {{156, 77, 105, 235, 145, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 52}, + {{100, 211, 238, 147, 65, 222, 99, 73, 252, 113, 46, 113, 52, 136, 0, 0}, 113, 184}, + {{13, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 124}, + {{29, 240, 141, 230, 78, 237, 25, 135, 131, 6, 65, 77, 77, 248, 0, 0}, 109, 128}, + {{15, 192, 109, 31, 149, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 255}, + {{80, 185, 170, 71, 41, 58, 158, 106, 253, 7, 2, 184, 173, 0, 0, 0}, 105, 146}, + {{16, 229, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 24, 172}, + {{169, 2, 153, 9, 169, 203, 245, 154, 184, 0, 0, 0, 0, 0, 0, 0}, 70, 116}, + {{144, 135, 239, 164, 142, 187, 64, 109, 0, 0, 0, 0, 0, 0, 0, 0}, 66, 189}, + {{170, 78, 252, 227, 242, 199, 130, 251, 200, 0, 0, 0, 0, 0, 0, 0}, 70, 10}, + {{232, 18, 15, 126, 166, 126, 58, 25, 209, 62, 76, 79, 0, 0, 0, 0}, 98, 184}, + {{170, 82, 72, 53, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 33, 98}, + {{152, 100, 37, 122, 242, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 37}, + {{174, 231, 230, 33, 71, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 174}, + {{74, 225, 252, 153, 202, 8, 162, 39, 64, 0, 0, 0, 0, 0, 0, 0}, 67, 251}, + {{167, 186, 101, 187, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 115}, + {{83, 7, 21, 122, 243, 67, 171, 146, 145, 160, 168, 103, 223, 64, 0, 0}, 107, 252}, + {{83, 132, 219, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 176}, + {{22, 113, 72, 102, 73, 16, 236, 57, 197, 122, 31, 0, 0, 0, 0, 0}, 91, 155}, + {{250, 59, 64, 35, 72, 112, 159, 85, 200, 5, 193, 39, 152, 185, 148, 16}, 124, 36}, + {{220, 21, 48, 164, 224, 121, 17, 69, 10, 118, 106, 0, 0, 0, 0, 0}, 88, 202}, + {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 208}, + {{247, 64, 83, 125, 195, 225, 50, 76, 18, 104, 0, 0, 0, 0, 0, 0}, 77, 158}, + {{78, 91, 31, 202, 189, 25, 13, 133, 220, 0, 0, 0, 0, 0, 0, 0}, 72, 136}, + {{105, 197, 26, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 191}, + {{14, 31, 154, 242, 241, 231, 55, 151, 223, 56, 134, 255, 113, 206, 69, 0}, 120, 126}, + {{247, 193, 58, 176, 16, 71, 31, 120, 213, 104, 231, 83, 26, 118, 91, 135}, 128, 139}, + {{136, 32, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 25, 216}, + {{100, 238, 112, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 29, 93}, + {{80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 196}, + {{233, 224, 254, 57, 33, 205, 140, 217, 181, 72, 0, 0, 0, 0, 0, 0}, 81, 119}, + {{107, 75, 65, 158, 128, 142, 191, 188, 188, 240, 148, 243, 116, 0, 0, 0}, 104, 93}, + {{39, 70, 120, 114, 69, 237, 95, 48, 233, 176, 91, 154, 0, 0, 0, 0}, 96, 183}, + {{10, 61, 43, 101, 64, 102, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 207}, + {{151, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 102}, + {{210, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 19, 36}, + {{52, 222, 249, 31, 108, 137, 199, 1, 242, 173, 184, 144, 0, 0, 0, 0}, 93, 41}, + {{123, 111, 88, 192, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 70}, + {{180, 82, 188, 125, 140, 8, 196, 74, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 218}, + {{77, 158, 34, 101, 196, 102, 56, 220, 42, 143, 181, 187, 240, 64, 161, 0}, 120, 226}, + {{88, 220, 222, 38, 23, 108, 5, 148, 185, 110, 20, 14, 67, 61, 0, 0}, 114, 25}, + {{90, 65, 220, 165, 197, 133, 110, 92, 228, 19, 2, 17, 0, 0, 0, 0}, 98, 6}, + {{35, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 26}, + {{103, 123, 49, 209, 228, 229, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 149}, + {{50, 244, 58, 191, 95, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 46, 127}, + {{140, 169, 75, 77, 78, 86, 40, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 62, 144}, + {{99, 176, 175, 83, 114, 50, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 56, 213}, + {{19, 208, 211, 76, 85, 176, 247, 64, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 115}, + {{153, 28, 188, 113, 211, 116, 7, 178, 136, 205, 96, 0, 0, 0, 0, 0}, 83, 146}, + {{160, 180, 220, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 58}, + {{234, 6, 112, 19, 61, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 222}, + {{97, 110, 34, 117, 149, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 16}, + {{99, 173, 119, 73, 250, 30, 144, 30, 128, 0, 0, 0, 0, 0, 0, 0}, 65, 169}, + {{169, 134, 111, 89, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 175}, + {{134, 80, 227, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 3}, + {{231, 243, 35, 80, 75, 207, 128, 137, 54, 170, 71, 238, 0, 0, 0, 0}, 96, 2}, + {{189, 190, 121, 135, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 193}, + {{143, 155, 216, 193, 239, 205, 204, 153, 143, 236, 69, 23, 200, 211, 0, 0}, 118, 151}, + {{32, 1, 115, 244, 33, 219, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 182}, + {{220, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 148}, + {{206, 87, 135, 235, 116, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 42, 53}, + {{152, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 11, 87}, + {{58, 146, 188, 233, 230, 236, 192, 214, 168, 128, 0, 0, 0, 0, 0, 0}, 73, 235}, + {{84, 220, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 51}, + {{106, 145, 142, 42, 186, 186, 58, 1, 48, 98, 165, 131, 48, 156, 192, 0}, 116, 11}, + {{53, 219, 120, 242, 166, 214, 81, 130, 64, 0, 0, 0, 0, 0, 0, 0}, 68, 28}, + {{240, 120, 76, 163, 32, 197, 181, 251, 98, 220, 29, 226, 0, 0, 0, 0}, 96, 73}, + {{234, 197, 12, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 216}, + {{191, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 16, 99}, + {{200, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 35}, + {{29, 129, 47, 83, 19, 75, 158, 1, 28, 24, 26, 147, 82, 119, 140, 100}, 127, 195}, + {{241, 174, 26, 53, 152, 112, 200, 134, 84, 187, 177, 176, 42, 64, 0, 0}, 108, 176}, + {{77, 171, 145, 48, 195, 84, 190, 36, 122, 199, 18, 0, 0, 0, 0, 0}, 87, 217}, + {{105, 104, 135, 53, 226, 118, 238, 169, 9, 253, 132, 162, 217, 123, 191, 96}, 126, 244}, + {{160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 125}, + {{41, 85, 143, 128, 91, 137, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 219}, + {{116, 110, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 165}, + {{75, 213, 44, 16, 43, 157, 34, 171, 98, 117, 109, 151, 5, 60, 224, 0}, 117, 6}, + {{229, 23, 116, 61, 80, 139, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 53, 47}, + {{83, 123, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 23, 73}, + {{151, 243, 45, 217, 216, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 47, 98}, + {{171, 184, 110, 211, 237, 114, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 52, 21}, + {{7, 246, 199, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 32, 142}, + {{103, 47, 70, 17, 31, 232, 44, 75, 145, 155, 100, 216, 0, 0, 0, 0}, 93, 34}, + {{65, 170, 169, 100, 167, 147, 142, 251, 20, 64, 0, 0, 0, 0, 0, 0}, 74, 41}, + {{235, 6, 229, 248, 151, 137, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 55, 80}, + {{156, 39, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 22, 11}, + {{92, 188, 82, 192, 142, 249, 190, 128, 0, 0, 0, 0, 0, 0, 0, 0}, 58, 254}, + {{253, 218, 181, 46, 134, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45, 95}, + {{189, 19, 31, 244, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 40, 8}, + {{30, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 14, 212}, + {{81, 226, 13, 173, 79, 123, 223, 124, 108, 80, 83, 238, 0, 0, 0, 0}, 95, 217}, + {{126, 211, 206, 82, 147, 215, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 15}, + {{42, 229, 135, 197, 196, 243, 94, 181, 133, 34, 16, 0, 0, 0, 0, 0}, 84, 66}, + {{68, 210, 158, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 122}, + {{183, 63, 223, 94, 81, 41, 203, 20, 236, 212, 220, 199, 0, 0, 0, 0}, 97, 12}, + {{131, 146, 2, 125, 174, 43, 231, 20, 194, 0, 0, 0, 0, 0, 0, 0}, 71, 171}, + {{31, 180, 246, 158, 28, 192, 236, 39, 237, 55, 74, 195, 171, 192, 0, 0}, 106, 42}, + {{179, 10, 70, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 28, 194}, + {{147, 51, 85, 185, 234, 209, 236, 87, 147, 17, 7, 68, 148, 32, 0, 0}, 107, 237}, + {{177, 178, 6, 40, 46, 166, 87, 198, 214, 234, 23, 224, 0, 0, 0, 0}, 93, 151}, + {{201, 53, 40, 20, 49, 4, 38, 139, 133, 217, 214, 134, 89, 200, 0, 0}, 109, 238}, + {{4, 26, 181, 37, 206, 129, 233, 32, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 128}, + {{81, 58, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 227}, + {{18, 238, 250, 161, 57, 246, 208, 118, 14, 76, 73, 25, 65, 22, 152, 120}, 127, 138}, + {{31, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 60}, + {{115, 195, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 18, 148}, + {{116, 22, 75, 33, 16, 129, 35, 124, 10, 112, 31, 213, 181, 108, 177, 46}, 128, 129}, + {{117, 214, 20, 80, 83, 51, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 202}, + {{120, 75, 124, 149, 120, 123, 242, 151, 181, 164, 128, 0, 0, 0, 0, 0}, 81, 88}, + {{87, 238, 168, 62, 88, 166, 52, 104, 219, 169, 93, 128, 0, 0, 0, 0}, 90, 3}, + {{237, 44, 224, 146, 52, 85, 245, 192, 65, 137, 37, 95, 156, 176, 0, 0}, 108, 243}, + {{214, 241, 51, 63, 73, 61, 193, 165, 23, 108, 0, 0, 0, 0, 0, 0}, 80, 95}, + {{87, 242, 21, 157, 45, 188, 36, 62, 66, 243, 64, 0, 0, 0, 0, 0}, 87, 255}, + {{0, 97, 220, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 48}, + {{227, 206, 189, 31, 222, 8, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 50, 38}, + {{174, 27, 0, 16, 13, 150, 33, 122, 154, 59, 236, 35, 248, 178, 64, 0}, 115, 20}, + {{39, 20, 125, 69, 252, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 43, 41}, + {{141, 232, 1, 12, 125, 229, 168, 14, 125, 116, 180, 0, 0, 0, 0, 0}, 92, 133}, + {{93, 238, 40, 228, 254, 203, 251, 6, 60, 82, 243, 242, 0, 0, 0, 0}, 95, 189}, + {{44, 115, 200, 17, 146, 223, 115, 253, 126, 206, 152, 90, 0, 0, 0, 0}, 95, 151}, + {{213, 58, 235, 255, 6, 163, 61, 10, 224, 0, 0, 0, 0, 0, 0, 0}, 68, 100}, + {{25, 86, 139, 116, 190, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 49, 118}, + {{113, 40, 65, 141, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 34, 164}, + {{149, 205, 200, 186, 19, 126, 215, 199, 94, 37, 100, 32, 128, 0, 0, 0}, 98, 71}, + {{39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 251}, + {{81, 87, 80, 173, 163, 166, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 51}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3, 185}, + {{140, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 144}, + {{6, 42, 1, 178, 250, 53, 186, 178, 114, 121, 192, 0, 0, 0, 0, 0}, 84, 51}, + {{2, 17, 234, 51, 169, 5, 219, 149, 245, 237, 4, 0, 0, 0, 0, 0}, 87, 32}, + {{112, 187, 173, 17, 229, 171, 225, 170, 8, 0, 0, 0, 0, 0, 0, 0}, 70, 137}, + {{203, 71, 140, 237, 113, 96, 123, 16, 0, 0, 0, 0, 0, 0, 0, 0}, 60, 2}, + {{99, 138, 207, 2, 244, 25, 211, 98, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 163}, + {{114, 42, 98, 246, 252, 48, 233, 118, 63, 226, 157, 226, 192, 0, 0, 0}, 100, 162}, + {{161, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 10, 192}, + {{233, 70, 240, 45, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 36, 185}, + {{28, 123, 31, 176, 235, 229, 169, 192, 0, 0, 0, 0, 0, 0, 0, 0}, 59, 51}, + {{146, 197, 243, 235, 243, 56, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 93}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 159}, + {{141, 92, 13, 27, 87, 241, 171, 143, 220, 0, 0, 0, 0, 0, 0, 0}, 72, 189}, + {{164, 151, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 21, 248}, + {{35, 188, 248, 79, 39, 151, 232, 215, 248, 245, 185, 144, 78, 102, 173, 128}, 123, 38}, + {{193, 232, 166, 60, 62, 80, 230, 225, 165, 240, 0, 0, 0, 0, 0, 0}, 76, 167}, + {{109, 229, 118, 155, 43, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 28}, + {{160, 62, 63, 212, 218, 138, 154, 108, 163, 127, 197, 237, 183, 44, 140, 192}, 125, 37}, + {{196, 37, 51, 146, 26, 85, 53, 31, 216, 141, 52, 218, 153, 32, 0, 0}, 107, 234}, + {{228, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 9, 70}, + {{154, 248, 20, 242, 154, 244, 63, 17, 121, 52, 70, 84, 118, 208, 0, 0}, 108, 50}, + {{41, 100, 27, 84, 106, 112, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 51, 171}, + {{81, 99, 197, 139, 30, 150, 230, 216, 81, 190, 84, 165, 29, 64, 128, 0}, 113, 236}, + {{112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 3}, + {{164, 119, 253, 126, 160, 249, 183, 191, 119, 111, 224, 0, 0, 0, 0, 0}, 86, 64}, + {{138, 58, 198, 254, 0, 197, 60, 91, 132, 199, 181, 251, 78, 160, 0, 0}, 108, 213}, + {{209, 89, 168, 236, 146, 169, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 54, 15}, + {{131, 210, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 20, 145}, + {{165, 190, 157, 7, 131, 5, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 57, 27}, + {{179, 226, 57, 204, 187, 70, 52, 81, 119, 162, 229, 42, 47, 185, 9, 162}, 127, 75}, + {{98, 235, 155, 51, 107, 167, 127, 137, 254, 246, 162, 171, 180, 13, 233, 0}, 123, 76}, + {{107, 79, 76, 90, 94, 151, 155, 31, 33, 115, 19, 204, 98, 115, 0, 0}, 113, 247}, + {{143, 46, 30, 175, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 43, 121}, + {{155, 85, 217, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 30, 214}, + {{58, 62, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 26, 221}, + {{92, 155, 53, 3, 39, 108, 155, 200, 0, 0, 0, 0, 0, 0, 0, 0}, 63, 102}, + {{64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 191}, + {{63, 134, 251, 59, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 39, 197}, + {{234, 149, 220, 106, 0, 144, 214, 128, 35, 102, 0, 0, 0, 0, 0, 0}, 79, 106}, +}; + +#define NUM_ROUTE_ENTRIES \ + (sizeof(large_route_table) / sizeof(large_route_table[0])) + +#define NUM_IPS_ENTRIES (NUM_ROUTE_ENTRIES * 100) + +/* clear the previous large_ips_table and reduce LPM6 test case much smaller, + * keep same size as previous one to make test case run similar input data. + */ +static struct ips_tbl_entry large_ips_table[NUM_IPS_ENTRIES]; + +/* let the most significant depth bits of ip_out[] same as ip_in[] + * in the same bit position. ip_out[] and ip_in[] are IPv6 address. + */ +static inline void mask_ip6_prefix(uint8_t *ip_out, + const uint8_t *ip_in, uint8_t depth) +{ + int k; + uint8_t mask_in, mask_out; + + for (k = 0; k < 16; k++) { + if (depth >= 8) + ip_out[k] = ip_in[k]; + else if (depth > 0) { + mask_in = (uint8_t)((unsigned int)(-1) << (8 - depth)); + mask_out = ~mask_in; + ip_out[k] = (ip_in[k] & mask_in) + | (ip_out[k] & mask_out); + } else + return; + + depth -= 8; + } +} + +/* check if IPv6 address ip[] match the rule with IPv6 address ip_rule[] + * and depth. if matched, return 0, else return -1. + */ +static inline int check_lpm6_rule(uint8_t *ip, + const uint8_t *ip_rule, uint8_t depth) +{ + int k; + uint8_t mask; + + for (k = 0; k < 16; k++) { + if (depth >= 8) { + if (ip[k] != ip_rule[k]) + return -1; + } else if (depth > 0) { + mask = (uint8_t)((unsigned int)(-1) << (8 - depth)); + if ((ip[k] & mask) == (ip_rule[k] & mask)) + return 0; + else + return -1; + } else + return 0; + + depth -= 8; + } + + return 0; +} + +/* check input IPv6 address ip[] with each one in rule[] and + * output the *next_hop from the matched item in rule[] with + * longest depth. The count of items in rule[ ] is rule_num. + * if found that some item in rule[] is matched return 0, + * else return -1; + */ +static int get_next_hop(uint8_t *ip, uint8_t *next_hop, + const struct rules_tbl_entry *rule, int rule_num) +{ + int i; + int result; + uint8_t max_depth = 0; + + for (i = 0; i < rule_num; i++) { + if (rule[i].depth >= max_depth) { + result = check_lpm6_rule(ip, rule[i].ip, rule[i].depth); + if (result == 0) { + *next_hop = rule[i].next_hop; + max_depth = rule[i].depth; + } + } + } + + if (max_depth > 0) + return 0; + else + return -1; +} + +/* the implementation of algorithm to generate large IPS table + * at run time. if gen_expected_nex_hop is non-zero, the expected + * next_hop of the IPv6 address of each item in IPS table is computed. + */ +static void generate_large_ips_table(int gen_expected_next_hop) +{ + uint32_t i, j, k; + + for (i = 0; i < NUM_IPS_ENTRIES; i++) { + for (j = 0; j < 16; j++) + large_ips_table[i].ip[j] = lrand48(); + } + + for (k = j = 0, i = 0; i < NUM_IPS_ENTRIES; i++) { + mask_ip6_prefix(large_ips_table[i].ip, + large_route_table[j].ip, large_route_table[j].depth); + k++; + if (k == (NUM_IPS_ENTRIES / NUM_ROUTE_ENTRIES)) { + j++; + k = 0; + } + if (j == NUM_ROUTE_ENTRIES) + j = 0; + } + + if (gen_expected_next_hop == 0) + return; + + for (k = 0; k < NUM_IPS_ENTRIES; k++) + get_next_hop(large_ips_table[k].ip, + &(large_ips_table[k].next_hop), + large_route_table, + NUM_ROUTE_ENTRIES); + +} + +#endif /* _TEST_LPM_ROUTES_H_ */ diff --git a/test/test/test_lpm6_perf.c b/test/test/test_lpm6_perf.c new file mode 100644 index 0000000000..0723081bb5 --- /dev/null +++ b/test/test/test_lpm6_perf.c @@ -0,0 +1,192 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include +#include + +#include "test.h" +#include "test_lpm6_data.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); + + /* Only generate IPv6 address of each item in large IPS table, + * here next_hop is not needed. + */ + generate_large_ips_table(0); + + 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; +} + +REGISTER_TEST_COMMAND(lpm6_perf_autotest, test_lpm6_perf); diff --git a/test/test/test_lpm_perf.c b/test/test/test_lpm_perf.c new file mode 100644 index 0000000000..e7e1281bda --- /dev/null +++ b/test/test/test_lpm_perf.c @@ -0,0 +1,513 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "test.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 + +#define MAX_RULE_NUM (1200000) + +struct route_rule { + uint32_t ip; + uint8_t depth; +}; + +struct route_rule large_route_table[MAX_RULE_NUM]; + +static uint32_t num_route_entries; +#define NUM_ROUTE_ENTRIES num_route_entries + +enum { + IP_CLASS_A, + IP_CLASS_B, + IP_CLASS_C +}; + +/* struct route_rule_count defines the total number of rules in following a/b/c + * each item in a[]/b[]/c[] is the number of common IP address class A/B/C, not + * including the ones for private local network. + */ +struct route_rule_count { + uint32_t a[RTE_LPM_MAX_DEPTH]; + uint32_t b[RTE_LPM_MAX_DEPTH]; + uint32_t c[RTE_LPM_MAX_DEPTH]; +}; + +/* All following numbers of each depth of each common IP class are just + * got from previous large constant table in app/test/test_lpm_routes.h . + * In order to match similar performance, they keep same depth and IP + * address coverage as previous constant table. These numbers don't + * include any private local IP address. As previous large const rule + * table was just dumped from a real router, there are no any IP address + * in class C or D. + */ +static struct route_rule_count rule_count = { + .a = { /* IP class A in which the most significant bit is 0 */ + 0, /* depth = 1 */ + 0, /* depth = 2 */ + 1, /* depth = 3 */ + 0, /* depth = 4 */ + 2, /* depth = 5 */ + 1, /* depth = 6 */ + 3, /* depth = 7 */ + 185, /* depth = 8 */ + 26, /* depth = 9 */ + 16, /* depth = 10 */ + 39, /* depth = 11 */ + 144, /* depth = 12 */ + 233, /* depth = 13 */ + 528, /* depth = 14 */ + 866, /* depth = 15 */ + 3856, /* depth = 16 */ + 3268, /* depth = 17 */ + 5662, /* depth = 18 */ + 17301, /* depth = 19 */ + 22226, /* depth = 20 */ + 11147, /* depth = 21 */ + 16746, /* depth = 22 */ + 17120, /* depth = 23 */ + 77578, /* depth = 24 */ + 401, /* depth = 25 */ + 656, /* depth = 26 */ + 1107, /* depth = 27 */ + 1121, /* depth = 28 */ + 2316, /* depth = 29 */ + 717, /* depth = 30 */ + 10, /* depth = 31 */ + 66 /* depth = 32 */ + }, + .b = { /* IP class A in which the most 2 significant bits are 10 */ + 0, /* depth = 1 */ + 0, /* depth = 2 */ + 0, /* depth = 3 */ + 0, /* depth = 4 */ + 1, /* depth = 5 */ + 1, /* depth = 6 */ + 1, /* depth = 7 */ + 3, /* depth = 8 */ + 3, /* depth = 9 */ + 30, /* depth = 10 */ + 25, /* depth = 11 */ + 168, /* depth = 12 */ + 305, /* depth = 13 */ + 569, /* depth = 14 */ + 1129, /* depth = 15 */ + 50800, /* depth = 16 */ + 1645, /* depth = 17 */ + 1820, /* depth = 18 */ + 3506, /* depth = 19 */ + 3258, /* depth = 20 */ + 3424, /* depth = 21 */ + 4971, /* depth = 22 */ + 6885, /* depth = 23 */ + 39771, /* depth = 24 */ + 424, /* depth = 25 */ + 170, /* depth = 26 */ + 433, /* depth = 27 */ + 92, /* depth = 28 */ + 366, /* depth = 29 */ + 377, /* depth = 30 */ + 2, /* depth = 31 */ + 200 /* depth = 32 */ + }, + .c = { /* IP class A in which the most 3 significant bits are 110 */ + 0, /* depth = 1 */ + 0, /* depth = 2 */ + 0, /* depth = 3 */ + 0, /* depth = 4 */ + 0, /* depth = 5 */ + 0, /* depth = 6 */ + 0, /* depth = 7 */ + 12, /* depth = 8 */ + 8, /* depth = 9 */ + 9, /* depth = 10 */ + 33, /* depth = 11 */ + 69, /* depth = 12 */ + 237, /* depth = 13 */ + 1007, /* depth = 14 */ + 1717, /* depth = 15 */ + 14663, /* depth = 16 */ + 8070, /* depth = 17 */ + 16185, /* depth = 18 */ + 48261, /* depth = 19 */ + 36870, /* depth = 20 */ + 33960, /* depth = 21 */ + 50638, /* depth = 22 */ + 61422, /* depth = 23 */ + 466549, /* depth = 24 */ + 1829, /* depth = 25 */ + 4824, /* depth = 26 */ + 4927, /* depth = 27 */ + 5914, /* depth = 28 */ + 10254, /* depth = 29 */ + 4905, /* depth = 30 */ + 1, /* depth = 31 */ + 716 /* depth = 32 */ + } +}; + +static void generate_random_rule_prefix(uint32_t ip_class, uint8_t depth) +{ +/* IP address class A, the most significant bit is 0 */ +#define IP_HEAD_MASK_A 0x00000000 +#define IP_HEAD_BIT_NUM_A 1 + +/* IP address class B, the most significant 2 bits are 10 */ +#define IP_HEAD_MASK_B 0x80000000 +#define IP_HEAD_BIT_NUM_B 2 + +/* IP address class C, the most significant 3 bits are 110 */ +#define IP_HEAD_MASK_C 0xC0000000 +#define IP_HEAD_BIT_NUM_C 3 + + uint32_t class_depth; + uint32_t range; + uint32_t mask; + uint32_t step; + uint32_t start; + uint32_t fixed_bit_num; + uint32_t ip_head_mask; + uint32_t rule_num; + uint32_t k; + struct route_rule *ptr_rule; + + if (ip_class == IP_CLASS_A) { /* IP Address class A */ + fixed_bit_num = IP_HEAD_BIT_NUM_A; + ip_head_mask = IP_HEAD_MASK_A; + rule_num = rule_count.a[depth - 1]; + } else if (ip_class == IP_CLASS_B) { /* IP Address class B */ + fixed_bit_num = IP_HEAD_BIT_NUM_B; + ip_head_mask = IP_HEAD_MASK_B; + rule_num = rule_count.b[depth - 1]; + } else { /* IP Address class C */ + fixed_bit_num = IP_HEAD_BIT_NUM_C; + ip_head_mask = IP_HEAD_MASK_C; + rule_num = rule_count.c[depth - 1]; + } + + if (rule_num == 0) + return; + + /* the number of rest bits which don't include the most significant + * fixed bits for this IP address class + */ + class_depth = depth - fixed_bit_num; + + /* range is the maximum number of rules for this depth and + * this IP address class + */ + range = 1 << class_depth; + + /* only mask the most depth significant generated bits + * except fixed bits for IP address class + */ + mask = range - 1; + + /* Widen coverage of IP address in generated rules */ + if (range <= rule_num) + step = 1; + else + step = round((double)range / rule_num); + + /* Only generate rest bits except the most significant + * fixed bits for IP address class + */ + start = lrand48() & mask; + ptr_rule = &large_route_table[num_route_entries]; + for (k = 0; k < rule_num; k++) { + ptr_rule->ip = (start << (RTE_LPM_MAX_DEPTH - depth)) + | ip_head_mask; + ptr_rule->depth = depth; + ptr_rule++; + start = (start + step) & mask; + } + num_route_entries += rule_num; +} + +static void insert_rule_in_random_pos(uint32_t ip, uint8_t depth) +{ + uint32_t pos; + int try_count = 0; + struct route_rule tmp; + + do { + pos = lrand48(); + try_count++; + } while ((try_count < 10) && (pos > num_route_entries)); + + if ((pos > num_route_entries) || (pos >= MAX_RULE_NUM)) + pos = num_route_entries >> 1; + + tmp = large_route_table[pos]; + large_route_table[pos].ip = ip; + large_route_table[pos].depth = depth; + if (num_route_entries < MAX_RULE_NUM) + large_route_table[num_route_entries++] = tmp; +} + +static void generate_large_route_rule_table(void) +{ + uint32_t ip_class; + uint8_t depth; + + num_route_entries = 0; + memset(large_route_table, 0, sizeof(large_route_table)); + + for (ip_class = IP_CLASS_A; ip_class <= IP_CLASS_C; ip_class++) { + for (depth = 1; depth <= RTE_LPM_MAX_DEPTH; depth++) { + generate_random_rule_prefix(ip_class, depth); + } + } + + /* Add following rules to keep same as previous large constant table, + * they are 4 rules with private local IP address and 1 all-zeros prefix + * with depth = 8. + */ + insert_rule_in_random_pos(IPv4(0, 0, 0, 0), 8); + insert_rule_in_random_pos(IPv4(10, 2, 23, 147), 32); + insert_rule_in_random_pos(IPv4(192, 168, 100, 10), 24); + insert_rule_in_random_pos(IPv4(192, 168, 25, 100), 24); + insert_rule_in_random_pos(IPv4(192, 168, 129, 124), 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 = 2000000; + config.number_tbl8s = 2048; + 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()); + + generate_large_route_rule_table(); + + 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; +} + +REGISTER_TEST_COMMAND(lpm_perf_autotest, test_lpm_perf); diff --git a/test/test/test_malloc.c b/test/test/test_malloc.c new file mode 100644 index 0000000000..0673d85b7e --- /dev/null +++ b/test/test/test_malloc.c @@ -0,0 +1,962 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define N 10000 + +/* + * Malloc + * ====== + * + * Allocate some dynamic memory from heap (3 areas). Check that areas + * don't overlap and that alignment constraints match. This test is + * done many times on different lcores simultaneously. + */ + +/* Test if memory overlaps: return 1 if true, or 0 if false. */ +static int +is_memory_overlap(void *p1, size_t len1, void *p2, size_t len2) +{ + unsigned long ptr1 = (unsigned long)p1; + unsigned long ptr2 = (unsigned long)p2; + + if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1) + return 1; + else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2) + return 1; + return 0; +} + +static int +is_aligned(void *p, int align) +{ + unsigned long addr = (unsigned long)p; + unsigned mask = align - 1; + + if (addr & mask) + return 0; + return 1; +} + +static int +test_align_overlap_per_lcore(__attribute__((unused)) void *arg) +{ + const unsigned align1 = 8, + align2 = 64, + align3 = 2048; + unsigned i,j; + void *p1 = NULL, *p2 = NULL, *p3 = NULL; + int ret = 0; + + for (i = 0; i < N; i++) { + p1 = rte_zmalloc("dummy", 1000, align1); + if (!p1){ + printf("rte_zmalloc returned NULL (i=%u)\n", i); + ret = -1; + break; + } + for(j = 0; j < 1000 ; j++) { + if( *(char *)p1 != 0) { + printf("rte_zmalloc didn't zero" + "the allocated memory\n"); + ret = -1; + } + } + p2 = rte_malloc("dummy", 1000, align2); + if (!p2){ + printf("rte_malloc returned NULL (i=%u)\n", i); + ret = -1; + rte_free(p1); + break; + } + p3 = rte_malloc("dummy", 1000, align3); + if (!p3){ + printf("rte_malloc returned NULL (i=%u)\n", i); + ret = -1; + rte_free(p1); + rte_free(p2); + break; + } + if (is_memory_overlap(p1, 1000, p2, 1000)) { + printf("p1 and p2 overlaps\n"); + ret = -1; + } + if (is_memory_overlap(p2, 1000, p3, 1000)) { + printf("p2 and p3 overlaps\n"); + ret = -1; + } + if (is_memory_overlap(p1, 1000, p3, 1000)) { + printf("p1 and p3 overlaps\n"); + ret = -1; + } + if (!is_aligned(p1, align1)) { + printf("p1 is not aligned\n"); + ret = -1; + } + if (!is_aligned(p2, align2)) { + printf("p2 is not aligned\n"); + ret = -1; + } + if (!is_aligned(p3, align3)) { + printf("p3 is not aligned\n"); + ret = -1; + } + rte_free(p1); + rte_free(p2); + rte_free(p3); + } + rte_malloc_dump_stats(stdout, "dummy"); + + return ret; +} + +static int +test_reordered_free_per_lcore(__attribute__((unused)) void *arg) +{ + const unsigned align1 = 8, + align2 = 64, + align3 = 2048; + unsigned i,j; + void *p1, *p2, *p3; + int ret = 0; + + for (i = 0; i < 30; i++) { + p1 = rte_zmalloc("dummy", 1000, align1); + if (!p1){ + printf("rte_zmalloc returned NULL (i=%u)\n", i); + ret = -1; + break; + } + for(j = 0; j < 1000 ; j++) { + if( *(char *)p1 != 0) { + printf("rte_zmalloc didn't zero" + "the allocated memory\n"); + ret = -1; + } + } + /* use calloc to allocate 1000 16-byte items this time */ + p2 = rte_calloc("dummy", 1000, 16, align2); + /* for third request use regular malloc again */ + p3 = rte_malloc("dummy", 1000, align3); + if (!p2 || !p3){ + printf("rte_malloc returned NULL (i=%u)\n", i); + ret = -1; + break; + } + if (is_memory_overlap(p1, 1000, p2, 1000)) { + printf("p1 and p2 overlaps\n"); + ret = -1; + } + if (is_memory_overlap(p2, 1000, p3, 1000)) { + printf("p2 and p3 overlaps\n"); + ret = -1; + } + if (is_memory_overlap(p1, 1000, p3, 1000)) { + printf("p1 and p3 overlaps\n"); + ret = -1; + } + if (!is_aligned(p1, align1)) { + printf("p1 is not aligned\n"); + ret = -1; + } + if (!is_aligned(p2, align2)) { + printf("p2 is not aligned\n"); + ret = -1; + } + if (!is_aligned(p3, align3)) { + printf("p3 is not aligned\n"); + ret = -1; + } + /* try freeing in every possible order */ + switch (i%6){ + case 0: + rte_free(p1); + rte_free(p2); + rte_free(p3); + break; + case 1: + rte_free(p1); + rte_free(p3); + rte_free(p2); + break; + case 2: + rte_free(p2); + rte_free(p1); + rte_free(p3); + break; + case 3: + rte_free(p2); + rte_free(p3); + rte_free(p1); + break; + case 4: + rte_free(p3); + rte_free(p1); + rte_free(p2); + break; + case 5: + rte_free(p3); + rte_free(p2); + rte_free(p1); + break; + } + } + rte_malloc_dump_stats(stdout, "dummy"); + + return ret; +} + +/* test function inside the malloc lib*/ +static int +test_str_to_size(void) +{ + struct { + const char *str; + uint64_t value; + } test_values[] = + {{ "5G", (uint64_t)5 * 1024 * 1024 *1024 }, + {"0x20g", (uint64_t)0x20 * 1024 * 1024 *1024}, + {"10M", 10 * 1024 * 1024}, + {"050m", 050 * 1024 * 1024}, + {"8K", 8 * 1024}, + {"15k", 15 * 1024}, + {"0200", 0200}, + {"0x103", 0x103}, + {"432", 432}, + {"-1", 0}, /* negative values return 0 */ + {" -2", 0}, + {" -3MB", 0}, + {"18446744073709551616", 0} /* ULLONG_MAX + 1 == out of range*/ + }; + unsigned i; + for (i = 0; i < sizeof(test_values)/sizeof(test_values[0]); i++) + if (rte_str_to_size(test_values[i].str) != test_values[i].value) + return -1; + return 0; +} + +static int +test_multi_alloc_statistics(void) +{ + int socket = 0; + struct rte_malloc_socket_stats pre_stats, post_stats ,first_stats, second_stats; + size_t size = 2048; + int align = 1024; +#ifndef RTE_LIBRTE_MALLOC_DEBUG + int trailer_size = 0; +#else + int trailer_size = RTE_CACHE_LINE_SIZE; +#endif + int overhead = RTE_CACHE_LINE_SIZE + trailer_size; + + rte_malloc_get_socket_stats(socket, &pre_stats); + + void *p1 = rte_malloc_socket("stats", size , align, socket); + if (!p1) + return -1; + rte_free(p1); + rte_malloc_dump_stats(stdout, "stats"); + + rte_malloc_get_socket_stats(socket,&post_stats); + /* Check statistics reported are correct */ + /* All post stats should be equal to pre stats after alloc freed */ + if ((post_stats.heap_totalsz_bytes != pre_stats.heap_totalsz_bytes) && + (post_stats.heap_freesz_bytes!=pre_stats.heap_freesz_bytes) && + (post_stats.heap_allocsz_bytes!=pre_stats.heap_allocsz_bytes)&& + (post_stats.alloc_count!=pre_stats.alloc_count)&& + (post_stats.free_count!=pre_stats.free_count)) { + printf("Malloc statistics are incorrect - freed alloc\n"); + return -1; + } + /* Check two consecutive allocations */ + size = 1024; + align = 0; + rte_malloc_get_socket_stats(socket,&pre_stats); + void *p2 = rte_malloc_socket("add", size ,align, socket); + if (!p2) + return -1; + rte_malloc_get_socket_stats(socket,&first_stats); + + void *p3 = rte_malloc_socket("add2", size,align, socket); + if (!p3) + return -1; + + rte_malloc_get_socket_stats(socket,&second_stats); + + rte_free(p2); + rte_free(p3); + + /* After freeing both allocations check stats return to original */ + rte_malloc_get_socket_stats(socket, &post_stats); + + if(second_stats.heap_totalsz_bytes != first_stats.heap_totalsz_bytes) { + printf("Incorrect heap statistics: Total size \n"); + return -1; + } + /* Check allocated size is equal to two additions plus overhead */ + if(second_stats.heap_allocsz_bytes != + size + overhead + first_stats.heap_allocsz_bytes) { + printf("Incorrect heap statistics: Allocated size \n"); + return -1; + } + /* Check that allocation count increments correctly i.e. +1 */ + if (second_stats.alloc_count != first_stats.alloc_count + 1) { + printf("Incorrect heap statistics: Allocated count \n"); + return -1; + } + + if (second_stats.free_count != first_stats.free_count){ + printf("Incorrect heap statistics: Free count \n"); + return -1; + } + + /* Make sure that we didn't touch our greatest chunk: 2 * 11M) */ + if (post_stats.greatest_free_size != pre_stats.greatest_free_size) { + printf("Incorrect heap statistics: Greatest free size \n"); + return -1; + } + /* Free size must equal the original free size minus the new allocation*/ + if (first_stats.heap_freesz_bytes <= second_stats.heap_freesz_bytes) { + printf("Incorrect heap statistics: Free size \n"); + return -1; + } + + if ((post_stats.heap_totalsz_bytes != pre_stats.heap_totalsz_bytes) && + (post_stats.heap_freesz_bytes!=pre_stats.heap_freesz_bytes) && + (post_stats.heap_allocsz_bytes!=pre_stats.heap_allocsz_bytes)&& + (post_stats.alloc_count!=pre_stats.alloc_count)&& + (post_stats.free_count!=pre_stats.free_count)) { + printf("Malloc statistics are incorrect - freed alloc\n"); + return -1; + } + return 0; +} + +static int +test_rte_malloc_type_limits(void) +{ + /* The type-limits functionality is not yet implemented, + * so always return 0 no matter what the retval. + */ + const char *typename = "limit_test"; + rte_malloc_set_limit(typename, 64 * 1024); + rte_malloc_dump_stats(stdout, typename); + return 0; +} + +static int +test_realloc(void) +{ + const char hello_str[] = "Hello, world!"; + const unsigned size1 = 1024; + const unsigned size2 = size1 + 1024; + const unsigned size3 = size2; + const unsigned size4 = size3 + 1024; + + /* test data is the same even if element is moved*/ + char *ptr1 = rte_zmalloc(NULL, size1, RTE_CACHE_LINE_SIZE); + if (!ptr1){ + printf("NULL pointer returned from rte_zmalloc\n"); + return -1; + } + snprintf(ptr1, size1, "%s" ,hello_str); + char *ptr2 = rte_realloc(ptr1, size2, RTE_CACHE_LINE_SIZE); + if (!ptr2){ + rte_free(ptr1); + printf("NULL pointer returned from rte_realloc\n"); + return -1; + } + if (ptr1 == ptr2){ + printf("unexpected - ptr1 == ptr2\n"); + } + if (strcmp(ptr2, hello_str) != 0){ + printf("Error - lost data from pointed area\n"); + rte_free(ptr2); + return -1; + } + unsigned i; + for (i = strnlen(hello_str, sizeof(hello_str)); i < size1; i++) + if (ptr2[i] != 0){ + printf("Bad data in realloc\n"); + rte_free(ptr2); + return -1; + } + /* now allocate third element, free the second + * and resize third. It should not move. (ptr1 is now invalid) + */ + char *ptr3 = rte_zmalloc(NULL, size3, RTE_CACHE_LINE_SIZE); + if (!ptr3){ + printf("NULL pointer returned from rte_zmalloc\n"); + rte_free(ptr2); + return -1; + } + for (i = 0; i < size3; i++) + if (ptr3[i] != 0){ + printf("Bad data in zmalloc\n"); + rte_free(ptr3); + rte_free(ptr2); + return -1; + } + rte_free(ptr2); + /* first resize to half the size of the freed block */ + char *ptr4 = rte_realloc(ptr3, size4, RTE_CACHE_LINE_SIZE); + if (!ptr4){ + printf("NULL pointer returned from rte_realloc\n"); + rte_free(ptr3); + return -1; + } + if (ptr3 != ptr4){ + printf("Unexpected - ptr4 != ptr3\n"); + rte_free(ptr4); + return -1; + } + /* now resize again to the full size of the freed block */ + ptr4 = rte_realloc(ptr3, size3 + size2 + size1, RTE_CACHE_LINE_SIZE); + if (ptr3 != ptr4){ + printf("Unexpected - ptr4 != ptr3 on second resize\n"); + rte_free(ptr4); + return -1; + } + rte_free(ptr4); + + /* now try a resize to a smaller size, see if it works */ + const unsigned size5 = 1024; + const unsigned size6 = size5 / 2; + char *ptr5 = rte_malloc(NULL, size5, RTE_CACHE_LINE_SIZE); + if (!ptr5){ + printf("NULL pointer returned from rte_malloc\n"); + return -1; + } + char *ptr6 = rte_realloc(ptr5, size6, RTE_CACHE_LINE_SIZE); + if (!ptr6){ + printf("NULL pointer returned from rte_realloc\n"); + rte_free(ptr5); + return -1; + } + if (ptr5 != ptr6){ + printf("Error, resizing to a smaller size moved data\n"); + rte_free(ptr6); + return -1; + } + rte_free(ptr6); + + /* check for behaviour changing alignment */ + const unsigned size7 = 1024; + const unsigned orig_align = RTE_CACHE_LINE_SIZE; + unsigned new_align = RTE_CACHE_LINE_SIZE * 2; + char *ptr7 = rte_malloc(NULL, size7, orig_align); + if (!ptr7){ + printf("NULL pointer returned from rte_malloc\n"); + return -1; + } + /* calc an alignment we don't already have */ + while(RTE_PTR_ALIGN(ptr7, new_align) == ptr7) + new_align *= 2; + char *ptr8 = rte_realloc(ptr7, size7, new_align); + if (!ptr8){ + printf("NULL pointer returned from rte_realloc\n"); + rte_free(ptr7); + return -1; + } + if (RTE_PTR_ALIGN(ptr8, new_align) != ptr8){ + printf("Failure to re-align data\n"); + rte_free(ptr8); + return -1; + } + rte_free(ptr8); + + /* test behaviour when there is a free block after current one, + * but its not big enough + */ + unsigned size9 = 1024, size10 = 1024; + unsigned size11 = size9 + size10 + 256; + char *ptr9 = rte_malloc(NULL, size9, RTE_CACHE_LINE_SIZE); + if (!ptr9){ + printf("NULL pointer returned from rte_malloc\n"); + return -1; + } + char *ptr10 = rte_malloc(NULL, size10, RTE_CACHE_LINE_SIZE); + if (!ptr10){ + printf("NULL pointer returned from rte_malloc\n"); + return -1; + } + rte_free(ptr9); + char *ptr11 = rte_realloc(ptr10, size11, RTE_CACHE_LINE_SIZE); + if (!ptr11){ + printf("NULL pointer returned from rte_realloc\n"); + rte_free(ptr10); + return -1; + } + if (ptr11 == ptr10){ + printf("Error, unexpected that realloc has not created new buffer\n"); + rte_free(ptr11); + return -1; + } + rte_free(ptr11); + + /* check we don't crash if we pass null to realloc + * We should get a malloc of the size requested*/ + const size_t size12 = 1024; + size_t size12_check; + char *ptr12 = rte_realloc(NULL, size12, RTE_CACHE_LINE_SIZE); + if (!ptr12){ + printf("NULL pointer returned from rte_realloc\n"); + return -1; + } + if (rte_malloc_validate(ptr12, &size12_check) < 0 || + size12_check != size12){ + rte_free(ptr12); + return -1; + } + rte_free(ptr12); + return 0; +} + +static int +test_random_alloc_free(void *_ __attribute__((unused))) +{ + struct mem_list { + struct mem_list *next; + char data[0]; + } *list_head = NULL; + unsigned i; + unsigned count = 0; + + rte_srand((unsigned)rte_rdtsc()); + + for (i = 0; i < N; i++){ + unsigned free_mem = 0; + size_t allocated_size; + while (!free_mem){ + const unsigned mem_size = sizeof(struct mem_list) + \ + rte_rand() % (64 * 1024); + const unsigned align = 1 << (rte_rand() % 12); /* up to 4k alignment */ + struct mem_list *entry = rte_malloc(NULL, + mem_size, align); + if (entry == NULL) + return -1; + if (RTE_PTR_ALIGN(entry, align)!= entry) + return -1; + if (rte_malloc_validate(entry, &allocated_size) == -1 + || allocated_size < mem_size) + return -1; + memset(entry->data, rte_lcore_id(), + mem_size - sizeof(*entry)); + entry->next = list_head; + if (rte_malloc_validate(entry, NULL) == -1) + return -1; + list_head = entry; + + count++; + /* switch to freeing the memory with a 20% probability */ + free_mem = ((rte_rand() % 10) >= 8); + } + while (list_head){ + struct mem_list *entry = list_head; + list_head = list_head->next; + rte_free(entry); + } + } + printf("Lcore %u allocated/freed %u blocks\n", rte_lcore_id(), count); + return 0; +} + +#define err_return() do { \ + printf("%s: %d - Error\n", __func__, __LINE__); \ + goto err_return; \ +} while (0) + +static int +test_rte_malloc_validate(void) +{ + const size_t request_size = 1024; + size_t allocated_size; + char *data_ptr = rte_malloc(NULL, request_size, RTE_CACHE_LINE_SIZE); +#ifdef RTE_LIBRTE_MALLOC_DEBUG + int retval; + char *over_write_vals = NULL; +#endif + + if (data_ptr == NULL) { + printf("%s: %d - Allocation error\n", __func__, __LINE__); + return -1; + } + + /* check that a null input returns -1 */ + if (rte_malloc_validate(NULL, NULL) != -1) + err_return(); + + /* check that we get ok on a valid pointer */ + if (rte_malloc_validate(data_ptr, &allocated_size) < 0) + err_return(); + + /* check that the returned size is ok */ + if (allocated_size < request_size) + err_return(); + +#ifdef RTE_LIBRTE_MALLOC_DEBUG + + /****** change the header to be bad */ + char save_buf[64]; + over_write_vals = (char *)((uintptr_t)data_ptr - sizeof(save_buf)); + /* first save the data as a backup before overwriting it */ + memcpy(save_buf, over_write_vals, sizeof(save_buf)); + memset(over_write_vals, 1, sizeof(save_buf)); + /* then run validate */ + retval = rte_malloc_validate(data_ptr, NULL); + /* finally restore the data again */ + memcpy(over_write_vals, save_buf, sizeof(save_buf)); + /* check we previously had an error */ + if (retval != -1) + err_return(); + + /* check all ok again */ + if (rte_malloc_validate(data_ptr, &allocated_size) < 0) + err_return(); + + /**** change the trailer to be bad */ + over_write_vals = (char *)((uintptr_t)data_ptr + allocated_size); + /* first save the data as a backup before overwriting it */ + memcpy(save_buf, over_write_vals, sizeof(save_buf)); + memset(over_write_vals, 1, sizeof(save_buf)); + /* then run validate */ + retval = rte_malloc_validate(data_ptr, NULL); + /* finally restore the data again */ + memcpy(over_write_vals, save_buf, sizeof(save_buf)); + if (retval != -1) + err_return(); + + /* check all ok again */ + if (rte_malloc_validate(data_ptr, &allocated_size) < 0) + err_return(); +#endif + + rte_free(data_ptr); + return 0; + +err_return: + /*clean up */ + rte_free(data_ptr); + return -1; +} + +static int +test_zero_aligned_alloc(void) +{ + char *p1 = rte_malloc(NULL,1024, 0); + if (!p1) + goto err_return; + if (!rte_is_aligned(p1, RTE_CACHE_LINE_SIZE)) + goto err_return; + rte_free(p1); + return 0; + +err_return: + /*clean up */ + if (p1) rte_free(p1); + return -1; +} + +static int +test_malloc_bad_params(void) +{ + const char *type = NULL; + size_t size = 0; + unsigned align = RTE_CACHE_LINE_SIZE; + + /* rte_malloc expected to return null with inappropriate size */ + char *bad_ptr = rte_malloc(type, size, align); + if (bad_ptr != NULL) + goto err_return; + + /* rte_malloc expected to return null with inappropriate alignment */ + align = 17; + size = 1024; + + bad_ptr = rte_malloc(type, size, align); + if (bad_ptr != NULL) + goto err_return; + + return 0; + +err_return: + /* clean up pointer */ + if (bad_ptr) + rte_free(bad_ptr); + return -1; +} + +/* Check if memory is avilable on a specific socket */ +static int +is_mem_on_socket(int32_t socket) +{ + const struct rte_memseg *ms = rte_eal_get_physmem_layout(); + unsigned i; + + for (i = 0; i < RTE_MAX_MEMSEG; i++) { + if (socket == ms[i].socket_id) + return 1; + } + return 0; +} + +/* + * Find what socket a memory address is on. Only works for addresses within + * memsegs, not heap or stack... + */ +static int32_t +addr_to_socket(void * addr) +{ + const struct rte_memseg *ms = rte_eal_get_physmem_layout(); + unsigned i; + + for (i = 0; i < RTE_MAX_MEMSEG; i++) { + if ((ms[i].addr <= addr) && + ((uintptr_t)addr < + ((uintptr_t)ms[i].addr + (uintptr_t)ms[i].len))) + return ms[i].socket_id; + } + return -1; +} + +/* Test using rte_[c|m|zm]alloc_socket() on a specific socket */ +static int +test_alloc_single_socket(int32_t socket) +{ + const char *type = NULL; + const size_t size = 10; + const unsigned align = 0; + char *mem = NULL; + int32_t desired_socket = (socket == SOCKET_ID_ANY) ? + (int32_t)rte_socket_id() : socket; + + /* Test rte_calloc_socket() */ + mem = rte_calloc_socket(type, size, sizeof(char), align, socket); + if (mem == NULL) + return -1; + if (addr_to_socket(mem) != desired_socket) { + rte_free(mem); + return -1; + } + rte_free(mem); + + /* Test rte_malloc_socket() */ + mem = rte_malloc_socket(type, size, align, socket); + if (mem == NULL) + return -1; + if (addr_to_socket(mem) != desired_socket) { + return -1; + } + rte_free(mem); + + /* Test rte_zmalloc_socket() */ + mem = rte_zmalloc_socket(type, size, align, socket); + if (mem == NULL) + return -1; + if (addr_to_socket(mem) != desired_socket) { + rte_free(mem); + return -1; + } + rte_free(mem); + + return 0; +} + +static int +test_alloc_socket(void) +{ + unsigned socket_count = 0; + unsigned i; + + if (test_alloc_single_socket(SOCKET_ID_ANY) < 0) + return -1; + + for (i = 0; i < RTE_MAX_NUMA_NODES; i++) { + if (is_mem_on_socket(i)) { + socket_count++; + if (test_alloc_single_socket(i) < 0) { + printf("Fail: rte_malloc_socket(..., %u) did not succeed\n", + i); + return -1; + } + } + else { + if (test_alloc_single_socket(i) == 0) { + printf("Fail: rte_malloc_socket(..., %u) succeeded\n", + i); + return -1; + } + } + } + + /* Print warnign if only a single socket, but don't fail the test */ + if (socket_count < 2) { + printf("WARNING: alloc_socket test needs memory on multiple sockets!\n"); + } + + return 0; +} + +static int +test_malloc(void) +{ + unsigned lcore_id; + int ret = 0; + + if (test_str_to_size() < 0){ + printf("test_str_to_size() failed\n"); + return -1; + } + else printf("test_str_to_size() passed\n"); + + if (test_zero_aligned_alloc() < 0){ + printf("test_zero_aligned_alloc() failed\n"); + return -1; + } + else printf("test_zero_aligned_alloc() passed\n"); + + if (test_malloc_bad_params() < 0){ + printf("test_malloc_bad_params() failed\n"); + return -1; + } + else printf("test_malloc_bad_params() passed\n"); + + if (test_realloc() < 0){ + printf("test_realloc() failed\n"); + return -1; + } + else printf("test_realloc() passed\n"); + + /*----------------------------*/ + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + rte_eal_remote_launch(test_align_overlap_per_lcore, NULL, lcore_id); + } + + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) + ret = -1; + } + if (ret < 0){ + printf("test_align_overlap_per_lcore() failed\n"); + return ret; + } + else printf("test_align_overlap_per_lcore() passed\n"); + + /*----------------------------*/ + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + rte_eal_remote_launch(test_reordered_free_per_lcore, NULL, lcore_id); + } + + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) + ret = -1; + } + if (ret < 0){ + printf("test_reordered_free_per_lcore() failed\n"); + return ret; + } + else printf("test_reordered_free_per_lcore() passed\n"); + + /*----------------------------*/ + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + rte_eal_remote_launch(test_random_alloc_free, NULL, lcore_id); + } + + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) + ret = -1; + } + if (ret < 0){ + printf("test_random_alloc_free() failed\n"); + return ret; + } + else printf("test_random_alloc_free() passed\n"); + + /*----------------------------*/ + ret = test_rte_malloc_type_limits(); + if (ret < 0){ + printf("test_rte_malloc_type_limits() failed\n"); + return ret; + } + /* TODO: uncomment following line once type limits are valid */ + /*else printf("test_rte_malloc_type_limits() passed\n");*/ + + /*----------------------------*/ + ret = test_rte_malloc_validate(); + if (ret < 0){ + printf("test_rte_malloc_validate() failed\n"); + return ret; + } + else printf("test_rte_malloc_validate() passed\n"); + + ret = test_alloc_socket(); + if (ret < 0){ + printf("test_alloc_socket() failed\n"); + return ret; + } + else printf("test_alloc_socket() passed\n"); + + ret = test_multi_alloc_statistics(); + if (ret < 0) { + printf("test_multi_alloc_statistics() failed\n"); + return ret; + } + else + printf("test_multi_alloc_statistics() passed\n"); + + return 0; +} + +REGISTER_TEST_COMMAND(malloc_autotest, test_malloc); diff --git a/test/test/test_mbuf.c b/test/test/test_mbuf.c new file mode 100644 index 0000000000..a2e9bc6cfb --- /dev/null +++ b/test/test/test_mbuf.c @@ -0,0 +1,1152 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define MBUF_DATA_SIZE 2048 +#define NB_MBUF 128 +#define MBUF_TEST_DATA_LEN 1464 +#define MBUF_TEST_DATA_LEN2 50 +#define MBUF_TEST_HDR1_LEN 20 +#define MBUF_TEST_HDR2_LEN 30 +#define MBUF_TEST_ALL_HDRS_LEN (MBUF_TEST_HDR1_LEN+MBUF_TEST_HDR2_LEN) + +/* size of private data for mbuf in pktmbuf_pool2 */ +#define MBUF2_PRIV_SIZE 128 + +#define REFCNT_MAX_ITER 64 +#define REFCNT_MAX_TIMEOUT 10 +#define REFCNT_MAX_REF (RTE_MAX_LCORE) +#define REFCNT_MBUF_NUM 64 +#define REFCNT_RING_SIZE (REFCNT_MBUF_NUM * REFCNT_MAX_REF) + +#define MAGIC_DATA 0x42424242 + +#define MAKE_STRING(x) # x + +static struct rte_mempool *pktmbuf_pool = NULL; +static struct rte_mempool *pktmbuf_pool2 = NULL; + +#ifdef RTE_MBUF_REFCNT_ATOMIC + +static struct rte_mempool *refcnt_pool = NULL; +static struct rte_ring *refcnt_mbuf_ring = NULL; +static volatile uint32_t refcnt_stop_slaves; +static unsigned refcnt_lcore[RTE_MAX_LCORE]; + +#endif + +/* + * MBUF + * ==== + * + * #. Allocate a mbuf pool. + * + * - The pool contains NB_MBUF elements, where each mbuf is MBUF_SIZE + * bytes long. + * + * #. Test multiple allocations of mbufs from this pool. + * + * - Allocate NB_MBUF and store pointers in a table. + * - If an allocation fails, return an error. + * - Free all these mbufs. + * - Repeat the same test to check that mbufs were freed correctly. + * + * #. Test data manipulation in pktmbuf. + * + * - Alloc an mbuf. + * - Append data using rte_pktmbuf_append(). + * - Test for error in rte_pktmbuf_append() when len is too large. + * - Trim data at the end of mbuf using rte_pktmbuf_trim(). + * - Test for error in rte_pktmbuf_trim() when len is too large. + * - Prepend a header using rte_pktmbuf_prepend(). + * - Test for error in rte_pktmbuf_prepend() when len is too large. + * - Remove data at the beginning of mbuf using rte_pktmbuf_adj(). + * - Test for error in rte_pktmbuf_adj() when len is too large. + * - Check that appended data is not corrupt. + * - Free the mbuf. + * - Between all these tests, check data_len and pkt_len, and + * that the mbuf is contiguous. + * - Repeat the test to check that allocation operations + * reinitialize the mbuf correctly. + * + * #. Test packet cloning + * - Clone a mbuf and verify the data + * - Clone the cloned mbuf and verify the data + * - Attach a mbuf to another that does not have the same priv_size. + */ + +#define GOTO_FAIL(str, ...) do { \ + printf("mbuf test FAILED (l.%d): <" str ">\n", \ + __LINE__, ##__VA_ARGS__); \ + goto fail; \ +} while(0) + +/* + * test data manipulation in mbuf with non-ascii data + */ +static int +test_pktmbuf_with_non_ascii_data(void) +{ + struct rte_mbuf *m = NULL; + char *data; + + m = rte_pktmbuf_alloc(pktmbuf_pool); + if (m == NULL) + GOTO_FAIL("Cannot allocate mbuf"); + if (rte_pktmbuf_pkt_len(m) != 0) + GOTO_FAIL("Bad length"); + + data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN); + if (data == NULL) + GOTO_FAIL("Cannot append data"); + if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) + GOTO_FAIL("Bad pkt length"); + if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) + GOTO_FAIL("Bad data length"); + memset(data, 0xff, rte_pktmbuf_pkt_len(m)); + if (!rte_pktmbuf_is_contiguous(m)) + GOTO_FAIL("Buffer should be continuous"); + rte_pktmbuf_dump(stdout, m, MBUF_TEST_DATA_LEN); + + rte_pktmbuf_free(m); + + return 0; + +fail: + if(m) { + rte_pktmbuf_free(m); + } + return -1; +} + +/* + * test data manipulation in mbuf + */ +static int +test_one_pktmbuf(void) +{ + struct rte_mbuf *m = NULL; + char *data, *data2, *hdr; + unsigned i; + + printf("Test pktmbuf API\n"); + + /* alloc a mbuf */ + + m = rte_pktmbuf_alloc(pktmbuf_pool); + if (m == NULL) + GOTO_FAIL("Cannot allocate mbuf"); + if (rte_pktmbuf_pkt_len(m) != 0) + GOTO_FAIL("Bad length"); + + rte_pktmbuf_dump(stdout, m, 0); + + /* append data */ + + data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN); + if (data == NULL) + GOTO_FAIL("Cannot append data"); + if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) + GOTO_FAIL("Bad pkt length"); + if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) + GOTO_FAIL("Bad data length"); + memset(data, 0x66, rte_pktmbuf_pkt_len(m)); + if (!rte_pktmbuf_is_contiguous(m)) + GOTO_FAIL("Buffer should be continuous"); + rte_pktmbuf_dump(stdout, m, MBUF_TEST_DATA_LEN); + rte_pktmbuf_dump(stdout, m, 2*MBUF_TEST_DATA_LEN); + + /* this append should fail */ + + data2 = rte_pktmbuf_append(m, (uint16_t)(rte_pktmbuf_tailroom(m) + 1)); + if (data2 != NULL) + GOTO_FAIL("Append should not succeed"); + + /* append some more data */ + + data2 = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2); + if (data2 == NULL) + GOTO_FAIL("Cannot append data"); + if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2) + GOTO_FAIL("Bad pkt length"); + if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2) + GOTO_FAIL("Bad data length"); + if (!rte_pktmbuf_is_contiguous(m)) + GOTO_FAIL("Buffer should be continuous"); + + /* trim data at the end of mbuf */ + + if (rte_pktmbuf_trim(m, MBUF_TEST_DATA_LEN2) < 0) + GOTO_FAIL("Cannot trim data"); + if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) + GOTO_FAIL("Bad pkt length"); + if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) + GOTO_FAIL("Bad data length"); + if (!rte_pktmbuf_is_contiguous(m)) + GOTO_FAIL("Buffer should be continuous"); + + /* this trim should fail */ + + if (rte_pktmbuf_trim(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) == 0) + GOTO_FAIL("trim should not succeed"); + + /* prepend one header */ + + hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR1_LEN); + if (hdr == NULL) + GOTO_FAIL("Cannot prepend"); + if (data - hdr != MBUF_TEST_HDR1_LEN) + GOTO_FAIL("Prepend failed"); + if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN) + GOTO_FAIL("Bad pkt length"); + if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN) + GOTO_FAIL("Bad data length"); + if (!rte_pktmbuf_is_contiguous(m)) + GOTO_FAIL("Buffer should be continuous"); + memset(hdr, 0x55, MBUF_TEST_HDR1_LEN); + + /* prepend another header */ + + hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR2_LEN); + if (hdr == NULL) + GOTO_FAIL("Cannot prepend"); + if (data - hdr != MBUF_TEST_ALL_HDRS_LEN) + GOTO_FAIL("Prepend failed"); + if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN) + GOTO_FAIL("Bad pkt length"); + if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN) + GOTO_FAIL("Bad data length"); + if (!rte_pktmbuf_is_contiguous(m)) + GOTO_FAIL("Buffer should be continuous"); + memset(hdr, 0x55, MBUF_TEST_HDR2_LEN); + + rte_mbuf_sanity_check(m, 1); + rte_mbuf_sanity_check(m, 0); + rte_pktmbuf_dump(stdout, m, 0); + + /* this prepend should fail */ + + hdr = rte_pktmbuf_prepend(m, (uint16_t)(rte_pktmbuf_headroom(m) + 1)); + if (hdr != NULL) + GOTO_FAIL("prepend should not succeed"); + + /* remove data at beginning of mbuf (adj) */ + + if (data != rte_pktmbuf_adj(m, MBUF_TEST_ALL_HDRS_LEN)) + GOTO_FAIL("rte_pktmbuf_adj failed"); + if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN) + GOTO_FAIL("Bad pkt length"); + if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN) + GOTO_FAIL("Bad data length"); + if (!rte_pktmbuf_is_contiguous(m)) + GOTO_FAIL("Buffer should be continuous"); + + /* this adj should fail */ + + if (rte_pktmbuf_adj(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) != NULL) + GOTO_FAIL("rte_pktmbuf_adj should not succeed"); + + /* check data */ + + if (!rte_pktmbuf_is_contiguous(m)) + GOTO_FAIL("Buffer should be continuous"); + + for (i=0; inext = rte_pktmbuf_alloc(pktmbuf_pool); + if (m->next == NULL) + GOTO_FAIL("Next Pkt Null\n"); + + rte_pktmbuf_append(m->next, sizeof(uint32_t)); + data = rte_pktmbuf_mtod(m->next, unaligned_uint32_t *); + *data = MAGIC_DATA; + + clone = rte_pktmbuf_clone(m, pktmbuf_pool); + if (clone == NULL) + GOTO_FAIL("cannot clone data\n"); + + data = rte_pktmbuf_mtod(clone, unaligned_uint32_t *); + if (*data != MAGIC_DATA) + GOTO_FAIL("invalid data in clone\n"); + + data = rte_pktmbuf_mtod(clone->next, unaligned_uint32_t *); + if (*data != MAGIC_DATA) + GOTO_FAIL("invalid data in clone->next\n"); + + if (rte_mbuf_refcnt_read(m) != 2) + GOTO_FAIL("invalid refcnt in m\n"); + + if (rte_mbuf_refcnt_read(m->next) != 2) + GOTO_FAIL("invalid refcnt in m->next\n"); + + /* try to clone the clone */ + + clone2 = rte_pktmbuf_clone(clone, pktmbuf_pool); + if (clone2 == NULL) + GOTO_FAIL("cannot clone the clone\n"); + + data = rte_pktmbuf_mtod(clone2, unaligned_uint32_t *); + if (*data != MAGIC_DATA) + GOTO_FAIL("invalid data in clone2\n"); + + data = rte_pktmbuf_mtod(clone2->next, unaligned_uint32_t *); + if (*data != MAGIC_DATA) + GOTO_FAIL("invalid data in clone2->next\n"); + + if (rte_mbuf_refcnt_read(m) != 3) + GOTO_FAIL("invalid refcnt in m\n"); + + if (rte_mbuf_refcnt_read(m->next) != 3) + GOTO_FAIL("invalid refcnt in m->next\n"); + + /* free mbuf */ + rte_pktmbuf_free(m); + rte_pktmbuf_free(clone); + rte_pktmbuf_free(clone2); + + m = NULL; + clone = NULL; + clone2 = NULL; + printf("%s ok\n", __func__); + return 0; + +fail: + if (m) + rte_pktmbuf_free(m); + if (clone) + rte_pktmbuf_free(clone); + if (clone2) + rte_pktmbuf_free(clone2); + return -1; +} + +static int +test_attach_from_different_pool(void) +{ + struct rte_mbuf *m = NULL; + struct rte_mbuf *clone = NULL; + struct rte_mbuf *clone2 = NULL; + char *data, *c_data, *c_data2; + + /* alloc a mbuf */ + m = rte_pktmbuf_alloc(pktmbuf_pool); + if (m == NULL) + GOTO_FAIL("cannot allocate mbuf"); + + if (rte_pktmbuf_pkt_len(m) != 0) + GOTO_FAIL("Bad length"); + + data = rte_pktmbuf_mtod(m, char *); + + /* allocate a new mbuf from the second pool, and attach it to the first + * mbuf */ + clone = rte_pktmbuf_alloc(pktmbuf_pool2); + if (clone == NULL) + GOTO_FAIL("cannot allocate mbuf from second pool\n"); + + /* check data room size and priv size, and erase priv */ + if (rte_pktmbuf_data_room_size(clone->pool) != 0) + GOTO_FAIL("data room size should be 0\n"); + if (rte_pktmbuf_priv_size(clone->pool) != MBUF2_PRIV_SIZE) + GOTO_FAIL("data room size should be %d\n", MBUF2_PRIV_SIZE); + memset(clone + 1, 0, MBUF2_PRIV_SIZE); + + /* save data pointer to compare it after detach() */ + c_data = rte_pktmbuf_mtod(clone, char *); + if (c_data != (char *)clone + sizeof(*clone) + MBUF2_PRIV_SIZE) + GOTO_FAIL("bad data pointer in clone"); + if (rte_pktmbuf_headroom(clone) != 0) + GOTO_FAIL("bad headroom in clone"); + + rte_pktmbuf_attach(clone, m); + + if (rte_pktmbuf_mtod(clone, char *) != data) + GOTO_FAIL("clone was not attached properly\n"); + if (rte_pktmbuf_headroom(clone) != RTE_PKTMBUF_HEADROOM) + GOTO_FAIL("bad headroom in clone after attach"); + if (rte_mbuf_refcnt_read(m) != 2) + GOTO_FAIL("invalid refcnt in m\n"); + + /* allocate a new mbuf from the second pool, and attach it to the first + * cloned mbuf */ + clone2 = rte_pktmbuf_alloc(pktmbuf_pool2); + if (clone2 == NULL) + GOTO_FAIL("cannot allocate clone2 from second pool\n"); + + /* check data room size and priv size, and erase priv */ + if (rte_pktmbuf_data_room_size(clone2->pool) != 0) + GOTO_FAIL("data room size should be 0\n"); + if (rte_pktmbuf_priv_size(clone2->pool) != MBUF2_PRIV_SIZE) + GOTO_FAIL("data room size should be %d\n", MBUF2_PRIV_SIZE); + memset(clone2 + 1, 0, MBUF2_PRIV_SIZE); + + /* save data pointer to compare it after detach() */ + c_data2 = rte_pktmbuf_mtod(clone2, char *); + if (c_data2 != (char *)clone2 + sizeof(*clone2) + MBUF2_PRIV_SIZE) + GOTO_FAIL("bad data pointer in clone2"); + if (rte_pktmbuf_headroom(clone2) != 0) + GOTO_FAIL("bad headroom in clone2"); + + rte_pktmbuf_attach(clone2, clone); + + if (rte_pktmbuf_mtod(clone2, char *) != data) + GOTO_FAIL("clone2 was not attached properly\n"); + if (rte_pktmbuf_headroom(clone2) != RTE_PKTMBUF_HEADROOM) + GOTO_FAIL("bad headroom in clone2 after attach"); + if (rte_mbuf_refcnt_read(m) != 3) + GOTO_FAIL("invalid refcnt in m\n"); + + /* detach the clones */ + 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); + rte_pktmbuf_free(clone); + rte_pktmbuf_free(m); + printf("%s ok\n", __func__); + return 0; + +fail: + if (m) + rte_pktmbuf_free(m); + if (clone) + rte_pktmbuf_free(clone); + if (clone2) + rte_pktmbuf_free(clone2); + return -1; +} +#undef GOTO_FAIL + +/* + * test allocation and free of mbufs + */ +static int +test_pktmbuf_pool(void) +{ + unsigned i; + struct rte_mbuf *m[NB_MBUF]; + int ret = 0; + + for (i=0; idata_off += 64; + } + + /* free them */ + for (i=0; idata_off != RTE_PKTMBUF_HEADROOM) { + printf("invalid data_off\n"); + ret = -1; + } + } + + /* free them */ + for (i=0; inext; + rte_pktmbuf_free_seg(mt); + } + } + } + + return ret; +} + +/* + * Stress test for rte_mbuf atomic refcnt. + * Implies that RTE_MBUF_REFCNT_ATOMIC is defined. + * For more efficency, recomended to run with RTE_LIBRTE_MBUF_DEBUG defined. + */ + +#ifdef RTE_MBUF_REFCNT_ATOMIC + +static int +test_refcnt_slave(__attribute__((unused)) void *arg) +{ + unsigned lcore, free; + void *mp = 0; + + lcore = rte_lcore_id(); + printf("%s started at lcore %u\n", __func__, lcore); + + free = 0; + while (refcnt_stop_slaves == 0) { + if (rte_ring_dequeue(refcnt_mbuf_ring, &mp) == 0) { + free++; + rte_pktmbuf_free((struct rte_mbuf *)mp); + } + } + + refcnt_lcore[lcore] += free; + printf("%s finished at lcore %u, " + "number of freed mbufs: %u\n", + __func__, lcore, free); + return 0; +} + +static void +test_refcnt_iter(unsigned lcore, unsigned iter) +{ + uint16_t ref; + unsigned i, n, tref, wn; + struct rte_mbuf *m; + + tref = 0; + + /* For each mbuf in the pool: + * - allocate mbuf, + * - 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_avail_count(refcnt_pool); + i != n && (m = rte_pktmbuf_alloc(refcnt_pool)) != NULL; + i++) { + ref = RTE_MAX(rte_rand() % REFCNT_MAX_REF, 1UL); + tref += ref; + if ((ref & 1) != 0) { + rte_pktmbuf_refcnt_update(m, ref); + while (ref-- != 0) + rte_ring_enqueue(refcnt_mbuf_ring, m); + } else { + while (ref-- != 0) { + rte_pktmbuf_refcnt_update(m, 1); + rte_ring_enqueue(refcnt_mbuf_ring, m); + } + } + rte_pktmbuf_free(m); + } + + if (i != n) + rte_panic("(lcore=%u, iter=%u): was able to allocate only " + "%u from %u mbufs\n", lcore, iter, i, n); + + /* wait till slave lcores will consume all mbufs */ + while (!rte_ring_empty(refcnt_mbuf_ring)) + ; + + /* check that all mbufs are back into mempool by now */ + for (wn = 0; wn != REFCNT_MAX_TIMEOUT; wn++) { + 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(100); + } + + rte_panic("(lcore=%u, iter=%u): after %us only " + "%u of %u mbufs left free\n", lcore, iter, wn, i, n); +} + +static int +test_refcnt_master(void) +{ + unsigned i, lcore; + + lcore = rte_lcore_id(); + printf("%s started at lcore %u\n", __func__, lcore); + + for (i = 0; i != REFCNT_MAX_ITER; i++) + test_refcnt_iter(lcore, i); + + refcnt_stop_slaves = 1; + rte_wmb(); + + printf("%s finished at lcore %u\n", __func__, lcore); + return 0; +} + +#endif + +static int +test_refcnt_mbuf(void) +{ +#ifdef RTE_MBUF_REFCNT_ATOMIC + + unsigned lnum, master, slave, tref; + + + if ((lnum = rte_lcore_count()) == 1) { + printf("skipping %s, number of lcores: %u is not enough\n", + __func__, lnum); + return 0; + } + + printf("starting %s, at %u lcores\n", __func__, lnum); + + /* create refcnt pool & ring if they don't exist */ + + if (refcnt_pool == NULL && + (refcnt_pool = rte_pktmbuf_pool_create( + MAKE_STRING(refcnt_pool), + REFCNT_MBUF_NUM, 0, 0, 0, + SOCKET_ID_ANY)) == NULL) { + printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n", + __func__); + return -1; + } + + if (refcnt_mbuf_ring == NULL && + (refcnt_mbuf_ring = rte_ring_create("refcnt_mbuf_ring", + rte_align32pow2(REFCNT_RING_SIZE), SOCKET_ID_ANY, + RING_F_SP_ENQ)) == NULL) { + printf("%s: cannot allocate " MAKE_STRING(refcnt_mbuf_ring) + "\n", __func__); + return -1; + } + + refcnt_stop_slaves = 0; + memset(refcnt_lcore, 0, sizeof (refcnt_lcore)); + + rte_eal_mp_remote_launch(test_refcnt_slave, NULL, SKIP_MASTER); + + test_refcnt_master(); + + rte_eal_mp_wait_lcore(); + + /* check that we porcessed all references */ + tref = 0; + master = rte_get_master_lcore(); + + RTE_LCORE_FOREACH_SLAVE(slave) + tref += refcnt_lcore[slave]; + + if (tref != refcnt_lcore[master]) + rte_panic("refernced mbufs: %u, freed mbufs: %u\n", + tref, refcnt_lcore[master]); + + rte_mempool_dump(stdout, refcnt_pool); + rte_ring_dump(stdout, refcnt_mbuf_ring); + +#endif + return 0; +} + +#include +#include + +/* use fork() to test mbuf errors panic */ +static int +verify_mbuf_check_panics(struct rte_mbuf *buf) +{ + int pid; + int status; + + pid = fork(); + + if (pid == 0) { + rte_mbuf_sanity_check(buf, 1); /* should panic */ + exit(0); /* return normally if it doesn't panic */ + } else if (pid < 0){ + printf("Fork Failed\n"); + return -1; + } + wait(&status); + if(status == 0) + return -1; + + return 0; +} + +static int +test_failing_mbuf_sanity_check(void) +{ + struct rte_mbuf *buf; + struct rte_mbuf badbuf; + + printf("Checking rte_mbuf_sanity_check for failure conditions\n"); + + /* get a good mbuf to use to make copies */ + buf = rte_pktmbuf_alloc(pktmbuf_pool); + if (buf == NULL) + return -1; + printf("Checking good mbuf initially\n"); + if (verify_mbuf_check_panics(buf) != -1) + return -1; + + printf("Now checking for error conditions\n"); + + if (verify_mbuf_check_panics(NULL)) { + printf("Error with NULL mbuf test\n"); + return -1; + } + + badbuf = *buf; + badbuf.pool = NULL; + if (verify_mbuf_check_panics(&badbuf)) { + printf("Error with bad-pool mbuf test\n"); + return -1; + } + + badbuf = *buf; + badbuf.buf_physaddr = 0; + if (verify_mbuf_check_panics(&badbuf)) { + printf("Error with bad-physaddr mbuf test\n"); + return -1; + } + + badbuf = *buf; + badbuf.buf_addr = NULL; + if (verify_mbuf_check_panics(&badbuf)) { + printf("Error with bad-addr mbuf test\n"); + return -1; + } + + badbuf = *buf; + badbuf.refcnt = 0; + if (verify_mbuf_check_panics(&badbuf)) { + printf("Error with bad-refcnt(0) mbuf test\n"); + return -1; + } + + badbuf = *buf; + badbuf.refcnt = UINT16_MAX; + if (verify_mbuf_check_panics(&badbuf)) { + printf("Error with bad-refcnt(MAX) mbuf test\n"); + return -1; + } + + return 0; +} + +static int +test_mbuf_linearize(int pkt_len, int nb_segs) { + + struct rte_mbuf *m = NULL, *mbuf = NULL; + uint8_t *data; + int data_len = 0; + int remain; + int seg, seg_len; + int i; + + if (pkt_len < 1) { + printf("Packet size must be 1 or more (is %d)\n", pkt_len); + return -1; + } + + if (nb_segs < 1) { + printf("Number of segments must be 1 or more (is %d)\n", + nb_segs); + return -1; + } + + seg_len = pkt_len / nb_segs; + if (seg_len == 0) + seg_len = 1; + + remain = pkt_len; + + /* Create chained mbuf_src and fill it generated data */ + for (seg = 0; remain > 0; seg++) { + + m = rte_pktmbuf_alloc(pktmbuf_pool); + if (m == NULL) { + printf("Cannot create segment for source mbuf"); + goto fail; + } + + /* Make sure if tailroom is zeroed */ + memset(rte_pktmbuf_mtod(m, uint8_t *), 0, + rte_pktmbuf_tailroom(m)); + + data_len = remain; + if (data_len > seg_len) + data_len = seg_len; + + data = (uint8_t *)rte_pktmbuf_append(m, data_len); + if (data == NULL) { + printf("Cannot append %d bytes to the mbuf\n", + data_len); + goto fail; + } + + for (i = 0; i < data_len; i++) + data[i] = (seg * seg_len + i) % 0x0ff; + + if (seg == 0) + mbuf = m; + else + rte_pktmbuf_chain(mbuf, m); + + remain -= data_len; + } + + /* Create destination buffer to store coalesced data */ + if (rte_pktmbuf_linearize(mbuf)) { + printf("Mbuf linearization failed\n"); + goto fail; + } + + if (!rte_pktmbuf_is_contiguous(mbuf)) { + printf("Source buffer should be contiguous after " + "linearization\n"); + goto fail; + } + + data = rte_pktmbuf_mtod(mbuf, uint8_t *); + + for (i = 0; i < pkt_len; i++) + if (data[i] != (i % 0x0ff)) { + printf("Incorrect data in linearized mbuf\n"); + goto fail; + } + + rte_pktmbuf_free(mbuf); + return 0; + +fail: + if (mbuf) + rte_pktmbuf_free(mbuf); + return -1; +} + +static int +test_mbuf_linearize_check(void) +{ + struct test_mbuf_array { + int size; + int nb_segs; + } mbuf_array[] = { + { 128, 1 }, + { 64, 64 }, + { 512, 10 }, + { 250, 11 }, + { 123, 8 }, + }; + unsigned int i; + + printf("Test mbuf linearize API\n"); + + for (i = 0; i < RTE_DIM(mbuf_array); i++) + if (test_mbuf_linearize(mbuf_array[i].size, + mbuf_array[i].nb_segs)) { + printf("Test failed for %d, %d\n", mbuf_array[i].size, + mbuf_array[i].nb_segs); + return -1; + } + + return 0; +} + +static int +test_mbuf(void) +{ + RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != RTE_CACHE_LINE_MIN_SIZE * 2); + + /* create pktmbuf pool if it does not exist */ + if (pktmbuf_pool == NULL) { + pktmbuf_pool = rte_pktmbuf_pool_create("test_pktmbuf_pool", + NB_MBUF, 32, 0, MBUF_DATA_SIZE, SOCKET_ID_ANY); + } + + if (pktmbuf_pool == NULL) { + printf("cannot allocate mbuf pool\n"); + return -1; + } + + /* create a specific pktmbuf pool with a priv_size != 0 and no data + * room size */ + if (pktmbuf_pool2 == NULL) { + pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2", + NB_MBUF, 32, MBUF2_PRIV_SIZE, 0, SOCKET_ID_ANY); + } + + if (pktmbuf_pool2 == NULL) { + printf("cannot allocate mbuf pool\n"); + return -1; + } + + /* test multiple mbuf alloc */ + if (test_pktmbuf_pool() < 0) { + printf("test_mbuf_pool() failed\n"); + return -1; + } + + /* do it another time to check that all mbufs were freed */ + if (test_pktmbuf_pool() < 0) { + printf("test_mbuf_pool() failed (2)\n"); + return -1; + } + + /* test that the pointer to the data on a packet mbuf is set properly */ + if (test_pktmbuf_pool_ptr() < 0) { + printf("test_pktmbuf_pool_ptr() failed\n"); + return -1; + } + + /* test data manipulation in mbuf */ + if (test_one_pktmbuf() < 0) { + printf("test_one_mbuf() failed\n"); + return -1; + } + + + /* + * do it another time, to check that allocation reinitialize + * the mbuf correctly + */ + if (test_one_pktmbuf() < 0) { + printf("test_one_mbuf() failed (2)\n"); + return -1; + } + + if (test_pktmbuf_with_non_ascii_data() < 0) { + printf("test_pktmbuf_with_non_ascii_data() failed\n"); + return -1; + } + + /* test free pktmbuf segment one by one */ + if (test_pktmbuf_free_segment() < 0) { + printf("test_pktmbuf_free_segment() failed.\n"); + return -1; + } + + if (testclone_testupdate_testdetach()<0){ + printf("testclone_and_testupdate() failed \n"); + return -1; + } + + if (test_attach_from_different_pool() < 0) { + printf("test_attach_from_different_pool() failed\n"); + return -1; + } + + if (test_refcnt_mbuf()<0){ + printf("test_refcnt_mbuf() failed \n"); + return -1; + } + + if (test_failing_mbuf_sanity_check() < 0) { + printf("test_failing_mbuf_sanity_check() failed\n"); + return -1; + } + + if (test_mbuf_linearize_check() < 0) { + printf("test_mbuf_linearize_check() failed\n"); + return -1; + } + return 0; +} + +REGISTER_TEST_COMMAND(mbuf_autotest, test_mbuf); diff --git a/test/test/test_memcpy.c b/test/test/test_memcpy.c new file mode 100644 index 0000000000..1d93dd53b1 --- /dev/null +++ b/test/test/test_memcpy.c @@ -0,0 +1,162 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include + +#include "test.h" + +/* + * Set this to the maximum buffer size you want to test. If it is 0, then the + * values in the buf_sizes[] array below will be used. + */ +#define TEST_VALUE_RANGE 0 + +/* List of buffer sizes to test */ +#if TEST_VALUE_RANGE == 0 +static size_t buf_sizes[] = { + 0, 1, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, + 256, 257, 320, 384, 511, 512, 513, 1023, 1024, 1025, 1518, 1522, 1600, + 2048, 3072, 4096, 5120, 6144, 7168, 8192 +}; +/* MUST be as large as largest packet size above */ +#define SMALL_BUFFER_SIZE 8192 +#else /* TEST_VALUE_RANGE != 0 */ +static size_t buf_sizes[TEST_VALUE_RANGE]; +#define SMALL_BUFFER_SIZE TEST_VALUE_RANGE +#endif /* TEST_VALUE_RANGE == 0 */ + +/* Data is aligned on this many bytes (power of 2) */ +#define ALIGNMENT_UNIT 32 + + +/* + * Create two buffers, and initialise one with random values. These are copied + * to the second buffer and then compared to see if the copy was successful. + * The bytes outside the copied area are also checked to make sure they were not + * changed. + */ +static int +test_single_memcpy(unsigned int off_src, unsigned int off_dst, size_t size) +{ + unsigned int i; + uint8_t dest[SMALL_BUFFER_SIZE + ALIGNMENT_UNIT]; + uint8_t src[SMALL_BUFFER_SIZE + ALIGNMENT_UNIT]; + void * ret; + + /* Setup buffers */ + for (i = 0; i < SMALL_BUFFER_SIZE + ALIGNMENT_UNIT; i++) { + dest[i] = 0; + src[i] = (uint8_t) rte_rand(); + } + + /* Do the copy */ + ret = rte_memcpy(dest + off_dst, src + off_src, size); + if (ret != (dest + off_dst)) { + printf("rte_memcpy() returned %p, not %p\n", + ret, dest + off_dst); + } + + /* Check nothing before offset is affected */ + for (i = 0; i < off_dst; i++) { + if (dest[i] != 0) { + printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): " + "[modified before start of dst].\n", + (unsigned)size, off_src, off_dst); + return -1; + } + } + + /* Check everything was copied */ + for (i = 0; i < size; i++) { + if (dest[i + off_dst] != src[i + off_src]) { + printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): " + "[didn't copy byte %u].\n", + (unsigned)size, off_src, off_dst, i); + return -1; + } + } + + /* Check nothing after copy was affected */ + for (i = size; i < SMALL_BUFFER_SIZE; i++) { + if (dest[i + off_dst] != 0) { + printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): " + "[copied too many].\n", + (unsigned)size, off_src, off_dst); + return -1; + } + } + return 0; +} + +/* + * Check functionality for various buffer sizes and data offsets/alignments. + */ +static int +func_test(void) +{ + unsigned int off_src, off_dst, i; + unsigned int num_buf_sizes = sizeof(buf_sizes) / sizeof(buf_sizes[0]); + int ret; + + for (off_src = 0; off_src < ALIGNMENT_UNIT; off_src++) { + for (off_dst = 0; off_dst < ALIGNMENT_UNIT; off_dst++) { + for (i = 0; i < num_buf_sizes; i++) { + ret = test_single_memcpy(off_src, off_dst, + buf_sizes[i]); + if (ret != 0) + return -1; + } + } + } + return 0; +} + +static int +test_memcpy(void) +{ + int ret; + + ret = func_test(); + if (ret != 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(memcpy_autotest, test_memcpy); diff --git a/test/test/test_memcpy_perf.c b/test/test/test_memcpy_perf.c new file mode 100644 index 0000000000..ff3aaaacad --- /dev/null +++ b/test/test/test_memcpy_perf.c @@ -0,0 +1,354 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "test.h" + +/* + * Set this to the maximum buffer size you want to test. If it is 0, then the + * values in the buf_sizes[] array below will be used. + */ +#define TEST_VALUE_RANGE 0 + +/* List of buffer sizes to test */ +#if TEST_VALUE_RANGE == 0 +static size_t buf_sizes[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, + 129, 191, 192, 193, 255, 256, 257, 319, 320, 321, 383, 384, 385, 447, 448, + 449, 511, 512, 513, 767, 768, 769, 1023, 1024, 1025, 1518, 1522, 1536, 1600, + 2048, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680, 8192 +}; +/* MUST be as large as largest packet size above */ +#define SMALL_BUFFER_SIZE 8192 +#else /* TEST_VALUE_RANGE != 0 */ +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) */ +#ifdef RTE_MACHINE_CPUFLAG_AVX512F +#define ALIGNMENT_UNIT 64 +#elif defined RTE_MACHINE_CPUFLAG_AVX2 +#define ALIGNMENT_UNIT 32 +#else /* RTE_MACHINE_CPUFLAG */ +#define ALIGNMENT_UNIT 16 +#endif /* RTE_MACHINE_CPUFLAG */ + +/* + * Pointers used in performance tests. The two large buffers are for uncached + * access where random addresses within the buffer are used for each + * memcpy. The two small buffers are for cached access. + */ +static uint8_t *large_buf_read, *large_buf_write; +static uint8_t *small_buf_read, *small_buf_write; + +/* Initialise data buffers. */ +static int +init_buffers(void) +{ + unsigned i; + + large_buf_read = rte_malloc("memcpy", LARGE_BUFFER_SIZE + ALIGNMENT_UNIT, ALIGNMENT_UNIT); + if (large_buf_read == NULL) + goto error_large_buf_read; + + large_buf_write = rte_malloc("memcpy", LARGE_BUFFER_SIZE + ALIGNMENT_UNIT, ALIGNMENT_UNIT); + if (large_buf_write == NULL) + goto error_large_buf_write; + + small_buf_read = rte_malloc("memcpy", SMALL_BUFFER_SIZE + ALIGNMENT_UNIT, ALIGNMENT_UNIT); + if (small_buf_read == NULL) + goto error_small_buf_read; + + small_buf_write = rte_malloc("memcpy", SMALL_BUFFER_SIZE + ALIGNMENT_UNIT, ALIGNMENT_UNIT); + if (small_buf_write == NULL) + goto error_small_buf_write; + + for (i = 0; i < LARGE_BUFFER_SIZE; i++) + large_buf_read[i] = rte_rand(); + for (i = 0; i < SMALL_BUFFER_SIZE; i++) + small_buf_read[i] = rte_rand(); + + return 0; + +error_small_buf_write: + rte_free(small_buf_read); +error_small_buf_read: + rte_free(large_buf_write); +error_large_buf_write: + rte_free(large_buf_read); +error_large_buf_read: + printf("ERROR: not enough memory\n"); + return -1; +} + +/* Cleanup data buffers */ +static void +free_buffers(void) +{ + rte_free(large_buf_read); + rte_free(large_buf_write); + rte_free(small_buf_read); + rte_free(small_buf_write); +} + +/* + * Get a random offset into large array, with enough space needed to perform + * max copy size. Offset is aligned, uoffset is used for unalignment setting. + */ +static inline size_t +get_rand_offset(size_t uoffset) +{ + return ((rte_rand() % (LARGE_BUFFER_SIZE - SMALL_BUFFER_SIZE)) & + ~(ALIGNMENT_UNIT - 1)) + uoffset; +} + +/* Fill in source and destination addresses. */ +static inline void +fill_addr_arrays(size_t *dst_addr, int is_dst_cached, size_t dst_uoffset, + size_t *src_addr, int is_src_cached, size_t src_uoffset) +{ + unsigned int i; + + for (i = 0; i < TEST_BATCH_SIZE; i++) { + dst_addr[i] = (is_dst_cached) ? dst_uoffset : get_rand_offset(dst_uoffset); + src_addr[i] = (is_src_cached) ? src_uoffset : get_rand_offset(src_uoffset); + } +} + +/* + * WORKAROUND: For some reason the first test doing an uncached write + * takes a very long time (~25 times longer than is expected). So we do + * it once without timing. + */ +static void +do_uncached_write(uint8_t *dst, int is_dst_cached, + const uint8_t *src, int is_src_cached, size_t size) +{ + unsigned i, j; + size_t dst_addrs[TEST_BATCH_SIZE], src_addrs[TEST_BATCH_SIZE]; + + for (i = 0; i < (TEST_ITERATIONS / TEST_BATCH_SIZE); i++) { + fill_addr_arrays(dst_addrs, is_dst_cached, 0, + src_addrs, is_src_cached, 0); + for (j = 0; j < TEST_BATCH_SIZE; j++) { + rte_memcpy(dst+dst_addrs[j], src+src_addrs[j], size); + } + } +} + +/* + * Run a single memcpy performance test. This is a macro to ensure that if + * the "size" parameter is a constant it won't be converted to a variable. + */ +#define SINGLE_PERF_TEST(dst, is_dst_cached, dst_uoffset, \ + src, is_src_cached, src_uoffset, size) \ +do { \ + unsigned int iter, t; \ + size_t dst_addrs[TEST_BATCH_SIZE], src_addrs[TEST_BATCH_SIZE]; \ + uint64_t start_time, total_time = 0; \ + uint64_t total_time2 = 0; \ + for (iter = 0; iter < (TEST_ITERATIONS / TEST_BATCH_SIZE); iter++) { \ + fill_addr_arrays(dst_addrs, is_dst_cached, dst_uoffset, \ + src_addrs, is_src_cached, src_uoffset); \ + start_time = rte_rdtsc(); \ + for (t = 0; t < TEST_BATCH_SIZE; t++) \ + rte_memcpy(dst+dst_addrs[t], src+src_addrs[t], size); \ + total_time += rte_rdtsc() - start_time; \ + } \ + for (iter = 0; iter < (TEST_ITERATIONS / TEST_BATCH_SIZE); iter++) { \ + fill_addr_arrays(dst_addrs, is_dst_cached, dst_uoffset, \ + src_addrs, is_src_cached, src_uoffset); \ + start_time = rte_rdtsc(); \ + for (t = 0; t < TEST_BATCH_SIZE; t++) \ + memcpy(dst+dst_addrs[t], src+src_addrs[t], size); \ + total_time2 += rte_rdtsc() - start_time; \ + } \ + printf("%8.0f -", (double)total_time /TEST_ITERATIONS); \ + printf("%5.0f", (double)total_time2 / TEST_ITERATIONS); \ +} while (0) + +/* Run aligned memcpy tests for each cached/uncached permutation */ +#define ALL_PERF_TESTS_FOR_SIZE(n) \ +do { \ + if (__builtin_constant_p(n)) \ + printf("\nC%6u", (unsigned)n); \ + else \ + printf("\n%7u", (unsigned)n); \ + SINGLE_PERF_TEST(small_buf_write, 1, 0, small_buf_read, 1, 0, n); \ + SINGLE_PERF_TEST(large_buf_write, 0, 0, small_buf_read, 1, 0, n); \ + SINGLE_PERF_TEST(small_buf_write, 1, 0, large_buf_read, 0, 0, n); \ + SINGLE_PERF_TEST(large_buf_write, 0, 0, large_buf_read, 0, 0, n); \ +} while (0) + +/* Run unaligned memcpy tests for each cached/uncached permutation */ +#define ALL_PERF_TESTS_FOR_SIZE_UNALIGNED(n) \ +do { \ + if (__builtin_constant_p(n)) \ + printf("\nC%6u", (unsigned)n); \ + else \ + printf("\n%7u", (unsigned)n); \ + SINGLE_PERF_TEST(small_buf_write, 1, 1, small_buf_read, 1, 5, n); \ + SINGLE_PERF_TEST(large_buf_write, 0, 1, small_buf_read, 1, 5, n); \ + SINGLE_PERF_TEST(small_buf_write, 1, 1, large_buf_read, 0, 5, n); \ + SINGLE_PERF_TEST(large_buf_write, 0, 1, large_buf_read, 0, 5, n); \ +} while (0) + +/* Run memcpy tests for constant length */ +#define ALL_PERF_TEST_FOR_CONSTANT \ +do { \ + TEST_CONSTANT(6U); TEST_CONSTANT(64U); TEST_CONSTANT(128U); \ + TEST_CONSTANT(192U); TEST_CONSTANT(256U); TEST_CONSTANT(512U); \ + TEST_CONSTANT(768U); TEST_CONSTANT(1024U); TEST_CONSTANT(1536U); \ +} while (0) + +/* Run all memcpy tests for aligned constant cases */ +static inline void +perf_test_constant_aligned(void) +{ +#define TEST_CONSTANT ALL_PERF_TESTS_FOR_SIZE + ALL_PERF_TEST_FOR_CONSTANT; +#undef TEST_CONSTANT +} + +/* Run all memcpy tests for unaligned constant cases */ +static inline void +perf_test_constant_unaligned(void) +{ +#define TEST_CONSTANT ALL_PERF_TESTS_FOR_SIZE_UNALIGNED + ALL_PERF_TEST_FOR_CONSTANT; +#undef TEST_CONSTANT +} + +/* Run all memcpy tests for aligned variable cases */ +static inline void +perf_test_variable_aligned(void) +{ + unsigned n = sizeof(buf_sizes) / sizeof(buf_sizes[0]); + unsigned i; + for (i = 0; i < n; i++) { + ALL_PERF_TESTS_FOR_SIZE((size_t)buf_sizes[i]); + } +} + +/* Run all memcpy tests for unaligned variable cases */ +static inline void +perf_test_variable_unaligned(void) +{ + unsigned n = sizeof(buf_sizes) / sizeof(buf_sizes[0]); + unsigned i; + for (i = 0; i < n; i++) { + ALL_PERF_TESTS_FOR_SIZE_UNALIGNED((size_t)buf_sizes[i]); + } +} + +/* Run all memcpy tests */ +static int +perf_test(void) +{ + int ret; + + ret = init_buffers(); + if (ret != 0) + return ret; + +#if TEST_VALUE_RANGE != 0 + /* Set up buf_sizes array, if required */ + unsigned i; + for (i = 0; i < TEST_VALUE_RANGE; i++) + buf_sizes[i] = i; +#endif + + /* See function comment */ + do_uncached_write(large_buf_write, 0, small_buf_read, 1, SMALL_BUFFER_SIZE); + + printf("\n** rte_memcpy() - memcpy perf. tests (C = compile-time constant) **\n" + "======= ============== ============== ============== ==============\n" + " Size Cache to cache Cache to mem Mem to cache Mem to mem\n" + "(bytes) (ticks) (ticks) (ticks) (ticks)\n" + "------- -------------- -------------- -------------- --------------"); + + printf("\n========================== %2dB aligned ============================", ALIGNMENT_UNIT); + /* Do aligned tests where size is a variable */ + perf_test_variable_aligned(); + printf("\n------- -------------- -------------- -------------- --------------"); + /* Do aligned tests where size is a compile-time constant */ + perf_test_constant_aligned(); + printf("\n=========================== Unaligned ============================="); + /* Do unaligned tests where size is a variable */ + perf_test_variable_unaligned(); + printf("\n------- -------------- -------------- -------------- --------------"); + /* Do unaligned tests where size is a compile-time constant */ + perf_test_constant_unaligned(); + printf("\n======= ============== ============== ============== ==============\n\n"); + + free_buffers(); + + return 0; +} + +static int +test_memcpy_perf(void) +{ + int ret; + + ret = perf_test(); + if (ret != 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(memcpy_perf_autotest, test_memcpy_perf); diff --git a/test/test/test_memory.c b/test/test/test_memory.c new file mode 100644 index 0000000000..921bdc8833 --- /dev/null +++ b/test/test/test_memory.c @@ -0,0 +1,89 @@ +/*- + * 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 +#include + +#include +#include + +#include "test.h" + +/* + * Memory + * ====== + * + * - Dump the mapped memory. The python-expect script checks that at + * least one line is dumped. + * + * - Check that memory size is different than 0. + * + * - Try to read all memory; it should not segfault. + */ + +static int +test_memory(void) +{ + uint64_t s; + unsigned i; + size_t j; + const struct rte_memseg *mem; + + /* + * dump the mapped memory: the python-expect script checks + * that at least one line is dumped + */ + printf("Dump memory layout\n"); + rte_dump_physmem_layout(stdout); + + /* check that memory size is != 0 */ + s = rte_eal_get_physmem_size(); + if (s == 0) { + printf("No memory detected\n"); + return -1; + } + + /* try to read memory (should not segfault) */ + mem = rte_eal_get_physmem_layout(); + for (i = 0; i < RTE_MAX_MEMSEG && mem[i].addr != NULL ; i++) { + + /* check memory */ + for (j = 0; j +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * Mempool + * ======= + * + * Basic tests: done on one core with and without cache: + * + * - Get one object, put one object + * - Get two objects, put two objects + * - Get all objects, test that their content is not modified and + * put them back in the pool. + */ + +#define MEMPOOL_ELT_SIZE 2048 +#define MAX_KEEP 16 +#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 rte_atomic32_t synchro; + +/* + * save the object number in the first 4 bytes of object data. All + * other bytes are set to 0. + */ +static void +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(struct rte_mempool *mp, int use_external_cache) +{ + uint32_t *objnum; + void **objtable; + void *obj, *obj2; + 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_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"); + /* 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->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 (rte_mempool_virt2phy(mp, obj) != rte_mem_virt2phy(obj)) + GOTO_ERR(ret, out); +#endif + + printf("put the object back\n"); + rte_mempool_generic_put(mp, &obj, 1, cache, 0); + rte_mempool_dump(stdout, mp); + + printf("get 2 objects\n"); + 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_generic_put(mp, &obj, 1, cache, 0); + rte_mempool_generic_put(mp, &obj2, 1, cache, 0); + rte_mempool_dump(stdout, mp); + + /* + * get many objects: we cannot get them all because the cache + * on other cores may not be empty. + */ + objtable = malloc(MEMPOOL_SIZE * sizeof(void *)); + if (objtable == NULL) + GOTO_ERR(ret, out); + + for (i = 0; i < MEMPOOL_SIZE; i++) { + if (rte_mempool_generic_get(mp, &objtable[i], 1, cache, 0) < 0) + break; + } + + /* + * for each object, check that its content was not modified, + * and put objects back in pool + */ + while (i--) { + obj = objtable[i]; + obj_data = obj; + objnum = obj; + if (*objnum > MEMPOOL_SIZE) { + printf("bad object number(%d)\n", *objnum); + ret = -1; + break; + } + for (j = sizeof(*objnum); j < mp->elt_size; j++) { + if (obj_data[j] != 0) + ret = -1; + } + + 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; +} + +static int test_mempool_creation_with_exceeded_cache_size(void) +{ + struct rte_mempool *mp_cov; + + 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; +} + +static struct rte_mempool *mp_spsc; +static rte_spinlock_t scsp_spinlock; +static void *scsp_obj_table[MAX_KEEP]; + +/* + * single producer function + */ +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() / 4; + + start_cycles = rte_get_timer_cycles(); + while (1) { + end_cycles = rte_get_timer_cycles(); + /* duration uses up, stop producing */ + if (start_cycles + duration < end_cycles) + break; + rte_spinlock_lock(&scsp_spinlock); + for (i = 0; i < MAX_KEEP; i ++) { + if (NULL != scsp_obj_table[i]) { + obj = scsp_obj_table[i]; + break; + } + } + rte_spinlock_unlock(&scsp_spinlock); + if (i >= MAX_KEEP) { + continue; + } + if (rte_mempool_from_obj(obj) != mp_spsc) { + printf("obj not owned by this mempool\n"); + RET_ERR(); + } + rte_mempool_put(mp_spsc, obj); + rte_spinlock_lock(&scsp_spinlock); + scsp_obj_table[i] = NULL; + rte_spinlock_unlock(&scsp_spinlock); + } + + return 0; +} + +/* + * single consumer function + */ +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() / 8; + + start_cycles = rte_get_timer_cycles(); + while (1) { + end_cycles = rte_get_timer_cycles(); + /* duration uses up, stop consuming */ + if (start_cycles + duration < end_cycles) + break; + rte_spinlock_lock(&scsp_spinlock); + for (i = 0; i < MAX_KEEP; i ++) { + if (NULL == scsp_obj_table[i]) + break; + } + rte_spinlock_unlock(&scsp_spinlock); + if (i >= MAX_KEEP) + continue; + if (rte_mempool_get(mp_spsc, &obj) < 0) + break; + rte_spinlock_lock(&scsp_spinlock); + scsp_obj_table[i] = obj; + rte_spinlock_unlock(&scsp_spinlock); + } + + return 0; +} + +/* + * 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) +{ + return test_mempool_single_consumer(); +} + +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*/ + return ; +} + +/* + * it tests the mempool operations based on singple producer and single consumer + */ +static int +test_mempool_sp_sc(void) +{ + int ret = 0; + unsigned lcore_id = rte_lcore_id(); + unsigned lcore_next; + + /* create a mempool with single producer/consumer ring */ + 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 (mp_spsc == NULL) + RET_ERR(); + } + if (rte_mempool_lookup("test_mempool_sp_sc") != mp_spsc) { + printf("Cannot lookup mempool from its name\n"); + rte_mempool_free(mp_spsc); + RET_ERR(); + } + lcore_next = rte_get_next_lcore(lcore_id, 0, 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) + ret = -1; + + if (rte_eal_wait_lcore(lcore_next) < 0) + ret = -1; + rte_mempool_free(mp_spsc); + + return ret; +} + +/* + * it tests some more basic of mempool + */ +static int +test_mempool_basic_ex(struct rte_mempool *mp) +{ + unsigned i; + void **obj; + void *err_obj; + int ret = -1; + + if (mp == NULL) + return ret; + + 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_in_use_count(mp)); + if (rte_mempool_full(mp) != 1) { + 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_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_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 should be empty\n"); + goto fail_mp_basic_ex; + } + + 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 should be full\n"); + goto fail_mp_basic_ex; + } + + ret = 0; + +fail_mp_basic_ex: + if (obj != NULL) + rte_free((void *)obj); + + return ret; +} + +static int +test_mempool_same_name_twice_creation(void) +{ + 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; +} + +/* + * BAsic test for mempool_xmem functions. + */ +static int +test_mempool_xmem_misc(void) +{ + uint32_t elt_num, total_size; + size_t sz; + ssize_t usz; + + elt_num = MAX_KEEP; + total_size = rte_mempool_calc_obj_size(MEMPOOL_ELT_SIZE, 0, NULL); + sz = rte_mempool_xmem_size(elt_num, total_size, MEMPOOL_PG_SHIFT_MAX); + + usz = rte_mempool_xmem_usage(NULL, elt_num, total_size, 0, 1, + MEMPOOL_PG_SHIFT_MAX); + + 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); + return -1; + } + + return 0; +} + +static void +walk_cb(struct rte_mempool *mp, void *userdata __rte_unused) +{ + printf("\t%s\n", mp->name); +} + +static int +test_mempool(void) +{ + struct rte_mempool *mp_cache = NULL; + struct rte_mempool *mp_nocache = NULL; + struct rte_mempool *mp_stack = NULL; + + rte_atomic32_init(&synchro); + + /* create a mempool (without cache) */ + 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) */ + 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"); + goto err; + } + + printf("Walk into mempools:\n"); + rte_mempool_walk(walk_cb, NULL); + + rte_mempool_list_dump(stdout); + + /* basic tests without cache */ + if (test_mempool_basic(mp_nocache, 0) < 0) + goto err; + + /* basic tests with cache */ + 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) + goto err; + + /* mempool operation test based on single producer and single comsumer */ + if (test_mempool_sp_sc() < 0) + goto err; + + if (test_mempool_creation_with_exceeded_cache_size() < 0) + goto err; + + if (test_mempool_same_name_twice_creation() < 0) + goto err; + + if (test_mempool_xmem_misc() < 0) + 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_stack); + return -1; +} + +REGISTER_TEST_COMMAND(mempool_autotest, test_mempool); diff --git a/test/test/test_mempool_perf.c b/test/test/test_mempool_perf.c new file mode 100644 index 0000000000..ebf1721ac3 --- /dev/null +++ b/test/test/test_mempool_perf.c @@ -0,0 +1,383 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * Mempool performance + * ======= + * + * Each core get *n_keep* objects per bulk of *n_get_bulk*. Then, + * objects are put back in the pool per bulk of *n_put_bulk*. + * + * This sequence is done during TIME_S seconds. + * + * This test is done on the following configurations: + * + * - Cores configuration (*cores*) + * + * - One core with cache + * - Two cores with cache + * - Max. cores with cache + * - 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*) + * + * - Bulk get from 1 to 32 + * - Bulk put from 1 to 32 + * + * - Number of kept objects (*n_keep*) + * + * - 32 + * - 128 + */ + +#define N 65536 +#define TIME_S 5 +#define MEMPOOL_ELT_SIZE 2048 +#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; + +/* number of objects in one bulk operation (get or put) */ +static unsigned n_get_bulk; +static unsigned n_put_bulk; + +/* number of objects retrived from mempool before putting them back */ +static unsigned n_keep; + +/* number of enqueues / dequeues */ +struct mempool_test_stats { + uint64_t enq_count; +} __rte_cache_aligned; + +static struct mempool_test_stats stats[RTE_MAX_LCORE]; + +/* + * save the object number in the first 4 bytes of object data. All + * other bytes are set to 0. + */ +static void +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; +} + +static int +per_lcore_mempool_test(__attribute__((unused)) void *arg) +{ + void *obj_table[MAX_KEEP]; + unsigned i, idx; + unsigned lcore_id = rte_lcore_id(); + 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) + GOTO_ERR(ret, out); + if (((n_keep / n_put_bulk) * n_put_bulk) != n_keep) + GOTO_ERR(ret, out); + + stats[lcore_id].enq_count = 0; + + /* wait synchro for slaves */ + if (lcore_id != rte_get_master_lcore()) + while (rte_atomic32_read(&synchro) == 0); + + start_cycles = rte_get_timer_cycles(); + + while (time_diff/hz < TIME_S) { + for (i = 0; likely(i < (N/n_keep)); i++) { + /* get n_keep objects by bulk of n_bulk */ + idx = 0; + while (idx < n_keep) { + ret = rte_mempool_generic_get(mp, + &obj_table[idx], + n_get_bulk, + cache, 0); + if (unlikely(ret < 0)) { + rte_mempool_dump(stdout, mp); + /* in this case, objects are lost... */ + GOTO_ERR(ret, out); + } + idx += n_get_bulk; + } + + /* put the objects back */ + idx = 0; + while (idx < n_keep) { + rte_mempool_generic_put(mp, &obj_table[idx], + n_put_bulk, + cache, 0); + idx += n_put_bulk; + } + } + end_cycles = rte_get_timer_cycles(); + time_diff = end_cycles - start_cycles; + stats[lcore_id].enq_count += N; + } + +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 */ +static int +launch_cores(unsigned cores) +{ + unsigned lcore_id; + uint64_t rate; + int ret; + unsigned cores_save = cores; + + rte_atomic32_set(&synchro, 0); + + /* reset stats */ + memset(stats, 0, sizeof(stats)); + + printf("mempool_autotest cache=%u cores=%u n_get_bulk=%u " + "n_put_bulk=%u n_keep=%u ", + use_external_cache ? + external_cache_size : (unsigned) mp->cache_size, + cores, n_get_bulk, n_put_bulk, n_keep); + + if (rte_mempool_avail_count(mp) != MEMPOOL_SIZE) { + printf("mempool is not full\n"); + return -1; + } + + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (cores == 1) + break; + cores--; + rte_eal_remote_launch(per_lcore_mempool_test, + NULL, lcore_id); + } + + /* start synchro and launch test on master */ + rte_atomic32_set(&synchro, 1); + + ret = per_lcore_mempool_test(NULL); + + cores = cores_save; + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (cores == 1) + break; + cores--; + if (rte_eal_wait_lcore(lcore_id) < 0) + ret = -1; + } + + if (ret < 0) { + printf("per-lcore test returned -1\n"); + return -1; + } + + rate = 0; + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) + rate += (stats[lcore_id].enq_count / TIME_S); + + printf("rate_persec=%" PRIu64 "\n", rate); + + return 0; +} + +/* for a given number of core, launch all test cases */ +static int +do_one_mempool_test(unsigned cores) +{ + unsigned bulk_tab_get[] = { 1, 4, 32, 0 }; + unsigned bulk_tab_put[] = { 1, 4, 32, 0 }; + unsigned keep_tab[] = { 32, 128, 0 }; + unsigned *get_bulk_ptr; + unsigned *put_bulk_ptr; + unsigned *keep_ptr; + int ret; + + for (get_bulk_ptr = bulk_tab_get; *get_bulk_ptr; get_bulk_ptr++) { + for (put_bulk_ptr = bulk_tab_put; *put_bulk_ptr; put_bulk_ptr++) { + for (keep_ptr = keep_tab; *keep_ptr; keep_ptr++) { + + n_get_bulk = *get_bulk_ptr; + n_put_bulk = *put_bulk_ptr; + n_keep = *keep_ptr; + ret = launch_cores(cores); + + if (ret < 0) + return -1; + } + } + } + return 0; +} + +static int +test_mempool_perf(void) +{ + rte_atomic32_init(&synchro); + + /* create a mempool (without cache) */ + if (mp_nocache == NULL) + mp_nocache = rte_mempool_create("perf_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; + + /* create a mempool (with cache) */ + if (mp_cache == NULL) + mp_cache = rte_mempool_create("perf_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; + + /* performance test with 1, 2 and max cores */ + printf("start performance test (without cache)\n"); + mp = mp_nocache; + + 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; + + /* performance test with 1, 2 and max cores */ + printf("start performance test (with cache)\n"); + mp = mp_cache; + + 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; + + /* 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; +} + +REGISTER_TEST_COMMAND(mempool_perf_autotest, test_mempool_perf); diff --git a/test/test/test_memzone.c b/test/test/test_memzone.c new file mode 100644 index 0000000000..7ae31cf746 --- /dev/null +++ b/test/test/test_memzone.c @@ -0,0 +1,875 @@ +/*- + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../lib/librte_eal/common/malloc_elem.h" + +#include "test.h" + +/* + * Memzone + * ======= + * + * - Search for three reserved zones or reserve them if they do not exist: + * + * - One is on any socket id. + * - The second is on socket 0. + * - The last one is on socket 1 (if socket 1 exists). + * + * - Check that the zones exist. + * + * - Check that the zones are cache-aligned. + * + * - Check that zones do not overlap. + * + * - Check that the zones are on the correct socket id. + * + * - Check that a lookup of the first zone returns the same pointer. + * + * - Check that it is not possible to create another zone with the + * same name as an existing zone. + * + * - Check flags for specific huge page size reservation + */ + +/* Test if memory overlaps: return 1 if true, or 0 if false. */ +static int +is_memory_overlap(phys_addr_t ptr1, size_t len1, phys_addr_t ptr2, size_t len2) +{ + if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1) + return 1; + else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2) + return 1; + return 0; +} + +static int +test_memzone_invalid_alignment(void) +{ + const struct rte_memzone * mz; + + mz = rte_memzone_lookup("invalid_alignment"); + if (mz != NULL) { + printf("Zone with invalid alignment has been reserved\n"); + return -1; + } + + mz = rte_memzone_reserve_aligned("invalid_alignment", 100, + SOCKET_ID_ANY, 0, 100); + if (mz != NULL) { + printf("Zone with invalid alignment has been reserved\n"); + return -1; + } + return 0; +} + +static int +test_memzone_reserving_zone_size_bigger_than_the_maximum(void) +{ + const struct rte_memzone * mz; + + mz = rte_memzone_lookup("zone_size_bigger_than_the_maximum"); + if (mz != NULL) { + printf("zone_size_bigger_than_the_maximum has been reserved\n"); + return -1; + } + + mz = rte_memzone_reserve("zone_size_bigger_than_the_maximum", (size_t)-1, + SOCKET_ID_ANY, 0); + if (mz != NULL) { + printf("It is impossible to reserve such big a memzone\n"); + return -1; + } + + return 0; +} + +static int +test_memzone_reserve_flags(void) +{ + const struct rte_memzone *mz; + const struct rte_memseg *ms; + int hugepage_2MB_avail = 0; + int hugepage_1GB_avail = 0; + int hugepage_16MB_avail = 0; + int hugepage_16GB_avail = 0; + const size_t size = 100; + int i = 0; + ms = rte_eal_get_physmem_layout(); + for (i = 0; i < RTE_MAX_MEMSEG; i++) { + if (ms[i].hugepage_sz == RTE_PGSIZE_2M) + hugepage_2MB_avail = 1; + if (ms[i].hugepage_sz == RTE_PGSIZE_1G) + hugepage_1GB_avail = 1; + if (ms[i].hugepage_sz == RTE_PGSIZE_16M) + hugepage_16MB_avail = 1; + if (ms[i].hugepage_sz == RTE_PGSIZE_16G) + hugepage_16GB_avail = 1; + } + /* Display the availability of 2MB ,1GB, 16MB, 16GB pages */ + if (hugepage_2MB_avail) + printf("2MB Huge pages available\n"); + if (hugepage_1GB_avail) + printf("1GB Huge pages available\n"); + if (hugepage_16MB_avail) + printf("16MB Huge pages available\n"); + if (hugepage_16GB_avail) + printf("16GB Huge pages available\n"); + /* + * If 2MB pages available, check that a small memzone is correctly + * reserved from 2MB huge pages when requested by the RTE_MEMZONE_2MB flag. + * Also check that RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an + * available page size (i.e 1GB ) when 2MB pages are unavailable. + */ + if (hugepage_2MB_avail) { + mz = rte_memzone_reserve("flag_zone_2M", size, SOCKET_ID_ANY, + RTE_MEMZONE_2MB); + if (mz == NULL) { + printf("MEMZONE FLAG 2MB\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_2M) { + printf("hugepage_sz not equal 2M\n"); + return -1; + } + + mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY, + RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY); + if (mz == NULL) { + printf("MEMZONE FLAG 2MB\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_2M) { + printf("hugepage_sz not equal 2M\n"); + return -1; + } + + /* Check if 1GB huge pages are unavailable, that function fails unless + * HINT flag is indicated + */ + if (!hugepage_1GB_avail) { + mz = rte_memzone_reserve("flag_zone_1G_HINT", size, SOCKET_ID_ANY, + RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY); + if (mz == NULL) { + printf("MEMZONE FLAG 1GB & HINT\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_2M) { + printf("hugepage_sz not equal 2M\n"); + return -1; + } + + mz = rte_memzone_reserve("flag_zone_1G", size, SOCKET_ID_ANY, + RTE_MEMZONE_1GB); + if (mz != NULL) { + printf("MEMZONE FLAG 1GB\n"); + return -1; + } + } + } + + /*As with 2MB tests above for 1GB huge page requests*/ + if (hugepage_1GB_avail) { + mz = rte_memzone_reserve("flag_zone_1G", size, SOCKET_ID_ANY, + RTE_MEMZONE_1GB); + if (mz == NULL) { + printf("MEMZONE FLAG 1GB\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_1G) { + printf("hugepage_sz not equal 1G\n"); + return -1; + } + + mz = rte_memzone_reserve("flag_zone_1G_HINT", size, SOCKET_ID_ANY, + RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY); + if (mz == NULL) { + printf("MEMZONE FLAG 1GB\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_1G) { + printf("hugepage_sz not equal 1G\n"); + return -1; + } + + /* Check if 1GB huge pages are unavailable, that function fails unless + * HINT flag is indicated + */ + if (!hugepage_2MB_avail) { + mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY, + RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY); + if (mz == NULL){ + printf("MEMZONE FLAG 2MB & HINT\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_1G) { + printf("hugepage_sz not equal 1G\n"); + return -1; + } + mz = rte_memzone_reserve("flag_zone_2M", size, SOCKET_ID_ANY, + RTE_MEMZONE_2MB); + if (mz != NULL) { + printf("MEMZONE FLAG 2MB\n"); + return -1; + } + } + + if (hugepage_2MB_avail && hugepage_1GB_avail) { + mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY, + RTE_MEMZONE_2MB|RTE_MEMZONE_1GB); + if (mz != NULL) { + printf("BOTH SIZES SET\n"); + return -1; + } + } + } + /* + * This option is for IBM Power. If 16MB pages available, check + * that a small memzone is correctly reserved from 16MB huge pages + * when requested by the RTE_MEMZONE_16MB flag. Also check that + * RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an available + * page size (i.e 16GB ) when 16MB pages are unavailable. + */ + if (hugepage_16MB_avail) { + mz = rte_memzone_reserve("flag_zone_16M", size, SOCKET_ID_ANY, + RTE_MEMZONE_16MB); + if (mz == NULL) { + printf("MEMZONE FLAG 16MB\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_16M) { + printf("hugepage_sz not equal 16M\n"); + return -1; + } + + mz = rte_memzone_reserve("flag_zone_16M_HINT", size, + SOCKET_ID_ANY, RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY); + if (mz == NULL) { + printf("MEMZONE FLAG 2MB\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_16M) { + printf("hugepage_sz not equal 16M\n"); + return -1; + } + + /* Check if 1GB huge pages are unavailable, that function fails + * unless HINT flag is indicated + */ + if (!hugepage_16GB_avail) { + mz = rte_memzone_reserve("flag_zone_16G_HINT", size, + SOCKET_ID_ANY, + RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY); + if (mz == NULL) { + printf("MEMZONE FLAG 16GB & HINT\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_16M) { + printf("hugepage_sz not equal 16M\n"); + return -1; + } + + mz = rte_memzone_reserve("flag_zone_16G", size, + SOCKET_ID_ANY, RTE_MEMZONE_16GB); + if (mz != NULL) { + printf("MEMZONE FLAG 16GB\n"); + return -1; + } + } + } + /*As with 16MB tests above for 16GB huge page requests*/ + if (hugepage_16GB_avail) { + mz = rte_memzone_reserve("flag_zone_16G", size, SOCKET_ID_ANY, + RTE_MEMZONE_16GB); + if (mz == NULL) { + printf("MEMZONE FLAG 16GB\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_16G) { + printf("hugepage_sz not equal 16G\n"); + return -1; + } + + mz = rte_memzone_reserve("flag_zone_16G_HINT", size, + SOCKET_ID_ANY, RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY); + if (mz == NULL) { + printf("MEMZONE FLAG 16GB\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_16G) { + printf("hugepage_sz not equal 16G\n"); + return -1; + } + + /* Check if 1GB huge pages are unavailable, that function fails + * unless HINT flag is indicated + */ + if (!hugepage_16MB_avail) { + mz = rte_memzone_reserve("flag_zone_16M_HINT", size, + SOCKET_ID_ANY, + RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY); + if (mz == NULL) { + printf("MEMZONE FLAG 16MB & HINT\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_16G) { + printf("hugepage_sz not equal 16G\n"); + return -1; + } + mz = rte_memzone_reserve("flag_zone_16M", size, + SOCKET_ID_ANY, RTE_MEMZONE_16MB); + if (mz != NULL) { + printf("MEMZONE FLAG 16MB\n"); + return -1; + } + } + + if (hugepage_16MB_avail && hugepage_16GB_avail) { + mz = rte_memzone_reserve("flag_zone_16M_HINT", size, + SOCKET_ID_ANY, + RTE_MEMZONE_16MB|RTE_MEMZONE_16GB); + if (mz != NULL) { + printf("BOTH SIZES SET\n"); + return -1; + } + } + } + return 0; +} + + +/* Find the heap with the greatest free block size */ +static size_t +find_max_block_free_size(const unsigned _align) +{ + struct rte_malloc_socket_stats stats; + unsigned i, align = _align; + size_t len = 0; + + for (i = 0; i < RTE_MAX_NUMA_NODES; i++) { + rte_malloc_get_socket_stats(i, &stats); + if (stats.greatest_free_size > len) + len = stats.greatest_free_size; + } + + if (align < RTE_CACHE_LINE_SIZE) + align = RTE_CACHE_LINE_ROUNDUP(align+1); + + if (len <= MALLOC_ELEM_OVERHEAD + align) + return 0; + + return len - MALLOC_ELEM_OVERHEAD - align; +} + +static int +test_memzone_reserve_max(void) +{ + const struct rte_memzone *mz; + size_t maxlen; + + maxlen = find_max_block_free_size(0); + + if (maxlen == 0) { + printf("There is no space left!\n"); + return 0; + } + + mz = rte_memzone_reserve("max_zone", 0, SOCKET_ID_ANY, 0); + if (mz == NULL){ + printf("Failed to reserve a big chunk of memory - %s\n", + rte_strerror(rte_errno)); + rte_dump_physmem_layout(stdout); + rte_memzone_dump(stdout); + return -1; + } + + if (mz->len != maxlen) { + printf("Memzone reserve with 0 size did not return bigest block\n"); + printf("Expected size = %zu, actual size = %zu\n", maxlen, mz->len); + rte_dump_physmem_layout(stdout); + rte_memzone_dump(stdout); + return -1; + } + return 0; +} + +static int +test_memzone_reserve_max_aligned(void) +{ + const struct rte_memzone *mz; + size_t maxlen = 0; + + /* random alignment */ + rte_srand((unsigned)rte_rdtsc()); + const unsigned align = 1 << ((rte_rand() % 8) + 5); /* from 128 up to 4k alignment */ + + maxlen = find_max_block_free_size(align); + + if (maxlen == 0) { + printf("There is no space left for biggest %u-aligned memzone!\n", align); + return 0; + } + + mz = rte_memzone_reserve_aligned("max_zone_aligned", 0, + SOCKET_ID_ANY, 0, align); + if (mz == NULL){ + printf("Failed to reserve a big chunk of memory - %s\n", + rte_strerror(rte_errno)); + rte_dump_physmem_layout(stdout); + rte_memzone_dump(stdout); + return -1; + } + + if (mz->len != maxlen) { + printf("Memzone reserve with 0 size and alignment %u did not return" + " bigest block\n", align); + printf("Expected size = %zu, actual size = %zu\n", + maxlen, mz->len); + rte_dump_physmem_layout(stdout); + rte_memzone_dump(stdout); + return -1; + } + return 0; +} + +static int +test_memzone_aligned(void) +{ + const struct rte_memzone *memzone_aligned_32; + const struct rte_memzone *memzone_aligned_128; + const struct rte_memzone *memzone_aligned_256; + const struct rte_memzone *memzone_aligned_512; + const struct rte_memzone *memzone_aligned_1024; + + /* memzone that should automatically be adjusted to align on 64 bytes */ + memzone_aligned_32 = rte_memzone_reserve_aligned("aligned_32", 100, + SOCKET_ID_ANY, 0, 32); + + /* memzone that is supposed to be aligned on a 128 byte boundary */ + memzone_aligned_128 = rte_memzone_reserve_aligned("aligned_128", 100, + SOCKET_ID_ANY, 0, 128); + + /* memzone that is supposed to be aligned on a 256 byte boundary */ + memzone_aligned_256 = rte_memzone_reserve_aligned("aligned_256", 100, + SOCKET_ID_ANY, 0, 256); + + /* memzone that is supposed to be aligned on a 512 byte boundary */ + memzone_aligned_512 = rte_memzone_reserve_aligned("aligned_512", 100, + SOCKET_ID_ANY, 0, 512); + + /* memzone that is supposed to be aligned on a 1024 byte boundary */ + memzone_aligned_1024 = rte_memzone_reserve_aligned("aligned_1024", 100, + SOCKET_ID_ANY, 0, 1024); + + printf("check alignments and lengths\n"); + if (memzone_aligned_32 == NULL) { + printf("Unable to reserve 64-byte aligned memzone!\n"); + return -1; + } + if ((memzone_aligned_32->phys_addr & RTE_CACHE_LINE_MASK) != 0) + return -1; + if (((uintptr_t) memzone_aligned_32->addr & RTE_CACHE_LINE_MASK) != 0) + return -1; + if ((memzone_aligned_32->len & RTE_CACHE_LINE_MASK) != 0) + return -1; + + if (memzone_aligned_128 == NULL) { + printf("Unable to reserve 128-byte aligned memzone!\n"); + return -1; + } + if ((memzone_aligned_128->phys_addr & 127) != 0) + return -1; + if (((uintptr_t) memzone_aligned_128->addr & 127) != 0) + return -1; + if ((memzone_aligned_128->len & RTE_CACHE_LINE_MASK) != 0) + return -1; + + if (memzone_aligned_256 == NULL) { + printf("Unable to reserve 256-byte aligned memzone!\n"); + return -1; + } + if ((memzone_aligned_256->phys_addr & 255) != 0) + return -1; + if (((uintptr_t) memzone_aligned_256->addr & 255) != 0) + return -1; + if ((memzone_aligned_256->len & RTE_CACHE_LINE_MASK) != 0) + return -1; + + if (memzone_aligned_512 == NULL) { + printf("Unable to reserve 512-byte aligned memzone!\n"); + return -1; + } + if ((memzone_aligned_512->phys_addr & 511) != 0) + return -1; + if (((uintptr_t) memzone_aligned_512->addr & 511) != 0) + return -1; + if ((memzone_aligned_512->len & RTE_CACHE_LINE_MASK) != 0) + return -1; + + if (memzone_aligned_1024 == NULL) { + printf("Unable to reserve 1024-byte aligned memzone!\n"); + return -1; + } + if ((memzone_aligned_1024->phys_addr & 1023) != 0) + return -1; + if (((uintptr_t) memzone_aligned_1024->addr & 1023) != 0) + return -1; + if ((memzone_aligned_1024->len & RTE_CACHE_LINE_MASK) != 0) + return -1; + + /* check that zones don't overlap */ + printf("check overlapping\n"); + if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len, + memzone_aligned_128->phys_addr, memzone_aligned_128->len)) + return -1; + if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len, + memzone_aligned_256->phys_addr, memzone_aligned_256->len)) + return -1; + if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len, + memzone_aligned_512->phys_addr, memzone_aligned_512->len)) + return -1; + if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len, + memzone_aligned_1024->phys_addr, memzone_aligned_1024->len)) + return -1; + if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len, + memzone_aligned_256->phys_addr, memzone_aligned_256->len)) + return -1; + if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len, + memzone_aligned_512->phys_addr, memzone_aligned_512->len)) + return -1; + if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len, + memzone_aligned_1024->phys_addr, memzone_aligned_1024->len)) + return -1; + if (is_memory_overlap(memzone_aligned_256->phys_addr, memzone_aligned_256->len, + memzone_aligned_512->phys_addr, memzone_aligned_512->len)) + return -1; + if (is_memory_overlap(memzone_aligned_256->phys_addr, memzone_aligned_256->len, + memzone_aligned_1024->phys_addr, memzone_aligned_1024->len)) + return -1; + if (is_memory_overlap(memzone_aligned_512->phys_addr, memzone_aligned_512->len, + memzone_aligned_1024->phys_addr, memzone_aligned_1024->len)) + return -1; + return 0; +} + +static int +check_memzone_bounded(const char *name, uint32_t len, uint32_t align, + uint32_t bound) +{ + const struct rte_memzone *mz; + phys_addr_t bmask; + + bmask = ~((phys_addr_t)bound - 1); + + if ((mz = rte_memzone_reserve_bounded(name, len, SOCKET_ID_ANY, 0, + align, bound)) == NULL) { + printf("%s(%s): memzone creation failed\n", + __func__, name); + return -1; + } + + if ((mz->phys_addr & ((phys_addr_t)align - 1)) != 0) { + printf("%s(%s): invalid phys addr alignment\n", + __func__, mz->name); + return -1; + } + + if (((uintptr_t) mz->addr & ((uintptr_t)align - 1)) != 0) { + printf("%s(%s): invalid virtual addr alignment\n", + __func__, mz->name); + return -1; + } + + if ((mz->len & RTE_CACHE_LINE_MASK) != 0 || mz->len < len || + mz->len < RTE_CACHE_LINE_SIZE) { + printf("%s(%s): invalid length\n", + __func__, mz->name); + return -1; + } + + if ((mz->phys_addr & bmask) != + ((mz->phys_addr + mz->len - 1) & bmask)) { + printf("%s(%s): invalid memzone boundary %u crossed\n", + __func__, mz->name, bound); + return -1; + } + + return 0; +} + +static int +test_memzone_bounded(void) +{ + const struct rte_memzone *memzone_err; + const char *name; + int rc; + + /* should fail as boundary is not power of two */ + name = "bounded_error_31"; + if ((memzone_err = rte_memzone_reserve_bounded(name, + 100, SOCKET_ID_ANY, 0, 32, UINT32_MAX)) != NULL) { + printf("%s(%s)created a memzone with invalid boundary " + "conditions\n", __func__, memzone_err->name); + return -1; + } + + /* should fail as len is greater then boundary */ + name = "bounded_error_32"; + if ((memzone_err = rte_memzone_reserve_bounded(name, + 100, SOCKET_ID_ANY, 0, 32, 32)) != NULL) { + printf("%s(%s)created a memzone with invalid boundary " + "conditions\n", __func__, memzone_err->name); + return -1; + } + + if ((rc = check_memzone_bounded("bounded_128", 100, 128, 128)) != 0) + return rc; + + if ((rc = check_memzone_bounded("bounded_256", 100, 256, 128)) != 0) + return rc; + + if ((rc = check_memzone_bounded("bounded_1K", 100, 64, 1024)) != 0) + return rc; + + if ((rc = check_memzone_bounded("bounded_1K_MAX", 0, 64, 1024)) != 0) + return rc; + + return 0; +} + +static int +test_memzone_free(void) +{ + const struct rte_memzone *mz[RTE_MAX_MEMZONE]; + int i; + char name[20]; + + mz[0] = rte_memzone_reserve("tempzone0", 2000, SOCKET_ID_ANY, 0); + mz[1] = rte_memzone_reserve("tempzone1", 4000, SOCKET_ID_ANY, 0); + + if (mz[0] > mz[1]) + return -1; + if (!rte_memzone_lookup("tempzone0")) + return -1; + if (!rte_memzone_lookup("tempzone1")) + return -1; + + if (rte_memzone_free(mz[0])) { + printf("Fail memzone free - tempzone0\n"); + return -1; + } + if (rte_memzone_lookup("tempzone0")) { + printf("Found previously free memzone - tempzone0\n"); + return -1; + } + mz[2] = rte_memzone_reserve("tempzone2", 2000, SOCKET_ID_ANY, 0); + + if (mz[2] > mz[1]) { + printf("tempzone2 should have gotten the free entry from tempzone0\n"); + return -1; + } + if (rte_memzone_free(mz[2])) { + printf("Fail memzone free - tempzone2\n"); + return -1; + } + if (rte_memzone_lookup("tempzone2")) { + printf("Found previously free memzone - tempzone2\n"); + return -1; + } + if (rte_memzone_free(mz[1])) { + printf("Fail memzone free - tempzone1\n"); + return -1; + } + if (rte_memzone_lookup("tempzone1")) { + printf("Found previously free memzone - tempzone1\n"); + return -1; + } + + i = 0; + do { + snprintf(name, sizeof(name), "tempzone%u", i); + mz[i] = rte_memzone_reserve(name, 1, SOCKET_ID_ANY, 0); + } while (mz[i++] != NULL); + + if (rte_memzone_free(mz[0])) { + printf("Fail memzone free - tempzone0\n"); + return -1; + } + mz[0] = rte_memzone_reserve("tempzone0new", 0, SOCKET_ID_ANY, 0); + + if (mz[0] == NULL) { + printf("Fail to create memzone - tempzone0new - when MAX memzones were " + "created and one was free\n"); + return -1; + } + + for (i = i - 2; i >= 0; i--) { + if (rte_memzone_free(mz[i])) { + printf("Fail memzone free - tempzone%d\n", i); + return -1; + } + } + + return 0; +} + +static int +test_memzone(void) +{ + const struct rte_memzone *memzone1; + const struct rte_memzone *memzone2; + const struct rte_memzone *memzone3; + const struct rte_memzone *memzone4; + const struct rte_memzone *mz; + + memzone1 = rte_memzone_reserve("testzone1", 100, + SOCKET_ID_ANY, 0); + + memzone2 = rte_memzone_reserve("testzone2", 1000, + 0, 0); + + memzone3 = rte_memzone_reserve("testzone3", 1000, + 1, 0); + + memzone4 = rte_memzone_reserve("testzone4", 1024, + SOCKET_ID_ANY, 0); + + /* memzone3 may be NULL if we don't have NUMA */ + if (memzone1 == NULL || memzone2 == NULL || memzone4 == NULL) + return -1; + + rte_memzone_dump(stdout); + + /* check cache-line alignments */ + printf("check alignments and lengths\n"); + + if ((memzone1->phys_addr & RTE_CACHE_LINE_MASK) != 0) + return -1; + if ((memzone2->phys_addr & RTE_CACHE_LINE_MASK) != 0) + return -1; + if (memzone3 != NULL && (memzone3->phys_addr & RTE_CACHE_LINE_MASK) != 0) + return -1; + if ((memzone1->len & RTE_CACHE_LINE_MASK) != 0 || memzone1->len == 0) + return -1; + if ((memzone2->len & RTE_CACHE_LINE_MASK) != 0 || memzone2->len == 0) + return -1; + if (memzone3 != NULL && ((memzone3->len & RTE_CACHE_LINE_MASK) != 0 || + memzone3->len == 0)) + return -1; + if (memzone4->len != 1024) + return -1; + + /* check that zones don't overlap */ + printf("check overlapping\n"); + + if (is_memory_overlap(memzone1->phys_addr, memzone1->len, + memzone2->phys_addr, memzone2->len)) + return -1; + if (memzone3 != NULL && + is_memory_overlap(memzone1->phys_addr, memzone1->len, + memzone3->phys_addr, memzone3->len)) + return -1; + if (memzone3 != NULL && + is_memory_overlap(memzone2->phys_addr, memzone2->len, + memzone3->phys_addr, memzone3->len)) + return -1; + + printf("check socket ID\n"); + + /* memzone2 must be on socket id 0 and memzone3 on socket 1 */ + if (memzone2->socket_id != 0) + return -1; + if (memzone3 != NULL && memzone3->socket_id != 1) + return -1; + + printf("test zone lookup\n"); + mz = rte_memzone_lookup("testzone1"); + if (mz != memzone1) + return -1; + + printf("test duplcate zone name\n"); + mz = rte_memzone_reserve("testzone1", 100, + SOCKET_ID_ANY, 0); + if (mz != NULL) + return -1; + + printf("test free memzone\n"); + if (test_memzone_free() < 0) + return -1; + + printf("test reserving memzone with bigger size than the maximum\n"); + if (test_memzone_reserving_zone_size_bigger_than_the_maximum() < 0) + return -1; + + printf("test memzone_reserve flags\n"); + if (test_memzone_reserve_flags() < 0) + return -1; + + printf("test alignment for memzone_reserve\n"); + if (test_memzone_aligned() < 0) + return -1; + + printf("test boundary alignment for memzone_reserve\n"); + if (test_memzone_bounded() < 0) + return -1; + + printf("test invalid alignment for memzone_reserve\n"); + if (test_memzone_invalid_alignment() < 0) + return -1; + + printf("test reserving the largest size memzone possible\n"); + if (test_memzone_reserve_max() < 0) + return -1; + + printf("test reserving the largest size aligned memzone possible\n"); + if (test_memzone_reserve_max_aligned() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(memzone_autotest, test_memzone); diff --git a/test/test/test_meter.c b/test/test/test_meter.c new file mode 100644 index 0000000000..26b0565788 --- /dev/null +++ b/test/test/test_meter.c @@ -0,0 +1,497 @@ +/*- + * 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 +#include +#include +#include +#include + +#include "test.h" + +#include +#include + +#define mlog(format, ...) do{\ + printf("Line %d:",__LINE__);\ + printf(format, ##__VA_ARGS__);\ + printf("\n");\ + }while(0); + +#define melog(format, ...) do{\ + printf("Line %d:",__LINE__);\ + printf(format, ##__VA_ARGS__);\ + printf(" failed!\n");\ + return -1;\ + }while(0); + +#define TM_TEST_SRTCM_CIR_DF 46000000 +#define TM_TEST_SRTCM_CBS_DF 2048 +#define TM_TEST_SRTCM_EBS_DF 4096 + +#define TM_TEST_TRTCM_CIR_DF 46000000 +#define TM_TEST_TRTCM_PIR_DF 69000000 +#define TM_TEST_TRTCM_CBS_DF 2048 +#define TM_TEST_TRTCM_PBS_DF 4096 + +static struct rte_meter_srtcm_params sparams = + {.cir = TM_TEST_SRTCM_CIR_DF, + .cbs = TM_TEST_SRTCM_CBS_DF, + .ebs = TM_TEST_SRTCM_EBS_DF,}; + +static struct rte_meter_trtcm_params tparams= + {.cir = TM_TEST_TRTCM_CIR_DF, + .pir = TM_TEST_TRTCM_PIR_DF, + .cbs = TM_TEST_TRTCM_CBS_DF, + .pbs = TM_TEST_TRTCM_PBS_DF,}; + +/** + * functional test for rte_meter_srtcm_config + */ +static inline int +tm_test_srtcm_config(void) +{ +#define SRTCM_CFG_MSG "srtcm_config" + struct rte_meter_srtcm sm; + struct rte_meter_srtcm_params sparams1; + + /* invalid parameter test */ + if(rte_meter_srtcm_config(NULL, NULL) == 0) + melog(SRTCM_CFG_MSG); + if(rte_meter_srtcm_config(&sm, NULL) == 0) + melog(SRTCM_CFG_MSG); + if(rte_meter_srtcm_config(NULL, &sparams) == 0) + melog(SRTCM_CFG_MSG); + + /* cbs and ebs can't both be zero */ + sparams1 = sparams; + sparams1.cbs = 0; + sparams1.ebs = 0; + if(rte_meter_srtcm_config(&sm, &sparams1) == 0) + melog(SRTCM_CFG_MSG); + + /* cir should never be 0 */ + sparams1 = sparams; + sparams1.cir = 0; + if(rte_meter_srtcm_config(&sm, &sparams1) == 0) + melog(SRTCM_CFG_MSG); + + /* one of ebs and cbs can be zero, should be successful */ + sparams1 = sparams; + sparams1.ebs = 0; + if(rte_meter_srtcm_config(&sm, &sparams1) != 0) + melog(SRTCM_CFG_MSG); + + sparams1 = sparams; + sparams1.cbs = 0; + if(rte_meter_srtcm_config(&sm, &sparams1) != 0) + melog(SRTCM_CFG_MSG); + + /* usual parameter, should be successful */ + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_CFG_MSG); + + return 0; + +} + +/** + * functional test for rte_meter_trtcm_config + */ +static inline int +tm_test_trtcm_config(void) +{ + struct rte_meter_trtcm tm; + struct rte_meter_trtcm_params tparams1; +#define TRTCM_CFG_MSG "trtcm_config" + + /* invalid parameter test */ + if(rte_meter_trtcm_config(NULL, NULL) == 0) + melog(TRTCM_CFG_MSG); + if(rte_meter_trtcm_config(&tm, NULL) == 0) + melog(TRTCM_CFG_MSG); + if(rte_meter_trtcm_config(NULL, &tparams) == 0) + melog(TRTCM_CFG_MSG); + + /* cir, cbs, pir and pbs never be zero */ + tparams1 = tparams; + tparams1.cir = 0; + if(rte_meter_trtcm_config(&tm, &tparams1) == 0) + melog(TRTCM_CFG_MSG); + + tparams1 = tparams; + tparams1.cbs = 0; + if(rte_meter_trtcm_config(&tm, &tparams1) == 0) + melog(TRTCM_CFG_MSG); + + tparams1 = tparams; + tparams1.pbs = 0; + if(rte_meter_trtcm_config(&tm, &tparams1) == 0) + melog(TRTCM_CFG_MSG); + + tparams1 = tparams; + tparams1.pir = 0; + if(rte_meter_trtcm_config(&tm, &tparams1) == 0) + melog(TRTCM_CFG_MSG); + + /* pir should be greater or equal to cir */ + tparams1 = tparams; + tparams1.pir = tparams1.cir - 1; + if(rte_meter_trtcm_config(&tm, &tparams1) == 0) + melog(TRTCM_CFG_MSG" pir < cir test"); + + /* usual parameter, should be successful */ + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_CFG_MSG); + + return 0; +} + +/** + * functional test for rte_meter_srtcm_color_blind_check + */ +static inline int +tm_test_srtcm_color_blind_check(void) +{ +#define SRTCM_BLIND_CHECK_MSG "srtcm_blind_check" + struct rte_meter_srtcm sm; + uint64_t time; + uint64_t hz = rte_get_tsc_hz(); + + /* Test green */ + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_srtcm_color_blind_check( + &sm, time, TM_TEST_SRTCM_CBS_DF - 1) + != e_RTE_METER_GREEN) + melog(SRTCM_BLIND_CHECK_MSG" GREEN"); + + /* Test yellow */ + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_srtcm_color_blind_check( + &sm, time, TM_TEST_SRTCM_CBS_DF + 1) + != e_RTE_METER_YELLOW) + melog(SRTCM_BLIND_CHECK_MSG" YELLOW"); + + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_srtcm_color_blind_check( + &sm, time, (uint32_t)sm.ebs - 1) != e_RTE_METER_YELLOW) + melog(SRTCM_BLIND_CHECK_MSG" YELLOW"); + + /* Test red */ + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_srtcm_color_blind_check( + &sm, time, TM_TEST_SRTCM_EBS_DF + 1) + != e_RTE_METER_RED) + melog(SRTCM_BLIND_CHECK_MSG" RED"); + + return 0; + +} + +/** + * functional test for rte_meter_trtcm_color_blind_check + */ +static inline int +tm_test_trtcm_color_blind_check(void) +{ +#define TRTCM_BLIND_CHECK_MSG "trtcm_blind_check" + + uint64_t time; + struct rte_meter_trtcm tm; + uint64_t hz = rte_get_tsc_hz(); + + /* Test green */ + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_trtcm_color_blind_check( + &tm, time, TM_TEST_TRTCM_CBS_DF - 1) + != e_RTE_METER_GREEN) + melog(TRTCM_BLIND_CHECK_MSG" GREEN"); + + /* Test yellow */ + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_trtcm_color_blind_check( + &tm, time, TM_TEST_TRTCM_CBS_DF + 1) + != e_RTE_METER_YELLOW) + melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); + + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_trtcm_color_blind_check( + &tm, time, TM_TEST_TRTCM_PBS_DF - 1) + != e_RTE_METER_YELLOW) + melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); + + /* Test red */ + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_trtcm_color_blind_check( + &tm, time, TM_TEST_TRTCM_PBS_DF + 1) + != e_RTE_METER_RED) + melog(TRTCM_BLIND_CHECK_MSG" RED"); + + return 0; +} + + +/** + * @in[4] : the flags packets carries. + * @in[4] : the flags function expect to return. + * It will do blind check at the time of 1 second from beginning. + * At the time, it will use packets length of cbs -1, cbs + 1, + * ebs -1 and ebs +1 with flag in[0], in[1], in[2] and in[3] to do + * aware check, expect flag out[0], out[1], out[2] and out[3] + */ + +static inline int +tm_test_srtcm_aware_check +(enum rte_meter_color in[4], enum rte_meter_color out[4]) +{ +#define SRTCM_AWARE_CHECK_MSG "srtcm_aware_check" + struct rte_meter_srtcm sm; + uint64_t time; + uint64_t hz = rte_get_tsc_hz(); + + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_srtcm_color_aware_check( + &sm, time, TM_TEST_SRTCM_CBS_DF - 1, in[0]) != out[0]) + melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]); + + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_srtcm_color_aware_check( + &sm, time, TM_TEST_SRTCM_CBS_DF + 1, in[1]) != out[1]) + melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]); + + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_srtcm_color_aware_check( + &sm, time, TM_TEST_SRTCM_EBS_DF - 1, in[2]) != out[2]) + melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]); + + if(rte_meter_srtcm_config(&sm, &sparams) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_srtcm_color_aware_check( + &sm, time, TM_TEST_SRTCM_EBS_DF + 1, in[3]) != out[3]) + melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]); + + return 0; +} + + +/** + * functional test for rte_meter_srtcm_color_aware_check + */ +static inline int +tm_test_srtcm_color_aware_check(void) +{ + enum rte_meter_color in[4], out[4]; + + /** + * test 4 points that will produce green, yellow, yellow, red flag + * if using blind check + */ + + /* previouly have a green, test points should keep unchanged */ + in[0] = in[1] = in[2] = in[3] = e_RTE_METER_GREEN; + out[0] = e_RTE_METER_GREEN; + out[1] = e_RTE_METER_YELLOW; + out[2] = e_RTE_METER_YELLOW; + out[3] = e_RTE_METER_RED; + if(tm_test_srtcm_aware_check(in, out) != 0) + return -1; + + /** + * previously have a yellow, green & yellow = yellow + * yellow & red = red + */ + in[0] = in[1] = in[2] = in[3] = e_RTE_METER_YELLOW; + out[0] = e_RTE_METER_YELLOW; + out[1] = e_RTE_METER_YELLOW; + out[2] = e_RTE_METER_YELLOW; + out[3] = e_RTE_METER_RED; + if(tm_test_srtcm_aware_check(in, out) != 0) + return -1; + + /** + * previously have a red, red & green = red + * red & yellow = red + */ + in[0] = in[1] = in[2] = in[3] = e_RTE_METER_RED; + out[0] = e_RTE_METER_RED; + out[1] = e_RTE_METER_RED; + out[2] = e_RTE_METER_RED; + out[3] = e_RTE_METER_RED; + if(tm_test_srtcm_aware_check(in, out) != 0) + return -1; + + return 0; +} + +/** + * @in[4] : the flags packets carries. + * @in[4] : the flags function expect to return. + * It will do blind check at the time of 1 second from beginning. + * At the time, it will use packets length of cbs -1, cbs + 1, + * ebs -1 and ebs +1 with flag in[0], in[1], in[2] and in[3] to do + * aware check, expect flag out[0], out[1], out[2] and out[3] + */ +static inline int +tm_test_trtcm_aware_check +(enum rte_meter_color in[4], enum rte_meter_color out[4]) +{ +#define TRTCM_AWARE_CHECK_MSG "trtcm_aware_check" + struct rte_meter_trtcm tm; + uint64_t time; + uint64_t hz = rte_get_tsc_hz(); + + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_trtcm_color_aware_check( + &tm, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0]) + melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]); + + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_trtcm_color_aware_check( + &tm, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1]) + melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]); + + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_trtcm_color_aware_check( + &tm, time, TM_TEST_TRTCM_PBS_DF - 1, in[2]) != out[2]) + melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]); + + if(rte_meter_trtcm_config(&tm, &tparams) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if(rte_meter_trtcm_color_aware_check( + &tm, time, TM_TEST_TRTCM_PBS_DF + 1, in[3]) != out[3]) + melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]); + + return 0; +} + + +/** + * functional test for rte_meter_trtcm_color_aware_check + */ + +static inline int +tm_test_trtcm_color_aware_check(void) +{ + enum rte_meter_color in[4], out[4]; + /** + * test 4 points that will produce green, yellow, yellow, red flag + * if using blind check + */ + + /* previouly have a green, test points should keep unchanged */ + in[0] = in[1] = in[2] = in[3] = e_RTE_METER_GREEN; + out[0] = e_RTE_METER_GREEN; + out[1] = e_RTE_METER_YELLOW; + out[2] = e_RTE_METER_YELLOW; + out[3] = e_RTE_METER_RED; + if(tm_test_trtcm_aware_check(in, out) != 0) + return -1; + + in[0] = in[1] = in[2] = in[3] = e_RTE_METER_YELLOW; + out[0] = e_RTE_METER_YELLOW; + out[1] = e_RTE_METER_YELLOW; + out[2] = e_RTE_METER_YELLOW; + out[3] = e_RTE_METER_RED; + if(tm_test_trtcm_aware_check(in, out) != 0) + return -1; + + in[0] = in[1] = in[2] = in[3] = e_RTE_METER_RED; + out[0] = e_RTE_METER_RED; + out[1] = e_RTE_METER_RED; + out[2] = e_RTE_METER_RED; + out[3] = e_RTE_METER_RED; + if(tm_test_trtcm_aware_check(in, out) != 0) + return -1; + + return 0; +} + +/** + * test main entrance for library meter + */ +static int +test_meter(void) +{ + if(tm_test_srtcm_config() != 0 ) + return -1; + + if(tm_test_trtcm_config() != 0 ) + return -1; + + if(tm_test_srtcm_color_blind_check() != 0) + return -1; + + if(tm_test_trtcm_color_blind_check()!= 0) + return -1; + + if(tm_test_srtcm_color_aware_check()!= 0) + return -1; + + if(tm_test_trtcm_color_aware_check()!= 0) + return -1; + + return 0; + +} + +REGISTER_TEST_COMMAND(meter_autotest, test_meter); diff --git a/test/test/test_mp_secondary.c b/test/test/test_mp_secondary.c new file mode 100644 index 0000000000..26c4afd67f --- /dev/null +++ b/test/test/test_mp_secondary.c @@ -0,0 +1,285 @@ +/*- + * 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 + +#include "test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef RTE_LIBRTE_HASH +#include +#include +#endif /* RTE_LIBRTE_HASH */ + +#ifdef RTE_LIBRTE_LPM +#include +#endif /* RTE_LIBRTE_LPM */ + +#include + +#include "process.h" + +#define launch_proc(ARGV) process_dup(ARGV, \ + sizeof(ARGV)/(sizeof(ARGV[0])), __func__) + +#ifdef RTE_EXEC_ENV_LINUXAPP +static char* +get_current_prefix(char * prefix, int size) +{ + char path[PATH_MAX] = {0}; + char buf[PATH_MAX] = {0}; + + /* get file for config (fd is always 3) */ + snprintf(path, sizeof(path), "/proc/self/fd/%d", 3); + + /* return NULL on error */ + if (readlink(path, buf, sizeof(buf)) == -1) + return NULL; + + /* get the basename */ + snprintf(buf, sizeof(buf), "%s", basename(buf)); + + /* copy string all the way from second char up to start of _config */ + snprintf(prefix, size, "%.*s", + (int)(strnlen(buf, sizeof(buf)) - sizeof("_config")), + &buf[1]); + + return prefix; +} +#endif + +/* + * This function is called in the primary i.e. main test, to spawn off secondary + * processes to run actual mp tests. Uses fork() and exec pair + */ +static int +run_secondary_instances(void) +{ + int ret = 0; + char coremask[10]; + +#ifdef RTE_EXEC_ENV_LINUXAPP + char tmp[PATH_MAX] = {0}; + char prefix[PATH_MAX] = {0}; + + get_current_prefix(tmp, sizeof(tmp)); + + snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); +#else + const char *prefix = ""; +#endif + + /* good case, using secondary */ + const char *argv1[] = { + prgname, "-c", coremask, "--proc-type=secondary", + prefix + }; + /* good case, using auto */ + const char *argv2[] = { + prgname, "-c", coremask, "--proc-type=auto", + prefix + }; + /* bad case, using invalid type */ + const char *argv3[] = { + prgname, "-c", coremask, "--proc-type=ERROR", + prefix + }; +#ifdef RTE_EXEC_ENV_LINUXAPP + /* bad case, using invalid file prefix */ + const char *argv4[] = { + prgname, "-c", coremask, "--proc-type=secondary", + "--file-prefix=ERROR" + }; +#endif + + snprintf(coremask, sizeof(coremask), "%x", \ + (1 << rte_get_master_lcore())); + + ret |= launch_proc(argv1); + ret |= launch_proc(argv2); + + ret |= !(launch_proc(argv3)); +#ifdef RTE_EXEC_ENV_LINUXAPP + ret |= !(launch_proc(argv4)); +#endif + + return ret; +} + +/* + * This function is run in the secondary instance to test that creation of + * objects fails in a secondary + */ +static int +run_object_creation_tests(void) +{ + const unsigned flags = 0; + const unsigned size = 1024; + const unsigned elt_size = 64; + const unsigned cache_size = 64; + const unsigned priv_data_size = 32; + + printf("### Testing object creation - expect lots of mz reserve errors!\n"); + + rte_errno = 0; + if ((rte_memzone_reserve("test_mz", size, rte_socket_id(), + flags) == NULL) && + (rte_memzone_lookup("test_mz") == NULL)) { + printf("Error: unexpected return value from rte_memzone_reserve\n"); + return -1; + } + printf("# Checked rte_memzone_reserve() OK\n"); + + rte_errno = 0; + if ((rte_ring_create( + "test_ring", size, rte_socket_id(), flags) == NULL) && + (rte_ring_lookup("test_ring") == NULL)){ + printf("Error: unexpected return value from rte_ring_create()\n"); + return -1; + } + printf("# Checked rte_ring_create() OK\n"); + + rte_errno = 0; + if ((rte_mempool_create("test_mp", size, elt_size, cache_size, + priv_data_size, NULL, NULL, NULL, NULL, + rte_socket_id(), flags) == NULL) && + (rte_mempool_lookup("test_mp") == NULL)){ + printf("Error: unexpected return value from rte_mempool_create()\n"); + return -1; + } + printf("# Checked rte_mempool_create() OK\n"); + +#ifdef RTE_LIBRTE_HASH + const struct rte_hash_parameters hash_params = { .name = "test_mp_hash" }; + rte_errno=0; + if ((rte_hash_create(&hash_params) != NULL) && + (rte_hash_find_existing(hash_params.name) == NULL)){ + printf("Error: unexpected return value from rte_hash_create()\n"); + return -1; + } + printf("# Checked rte_hash_create() OK\n"); + + const struct rte_fbk_hash_params fbk_params = { .name = "test_fbk_mp_hash" }; + rte_errno=0; + if ((rte_fbk_hash_create(&fbk_params) != NULL) && + (rte_fbk_hash_find_existing(fbk_params.name) == NULL)){ + printf("Error: unexpected return value from rte_fbk_hash_create()\n"); + return -1; + } + printf("# Checked rte_fbk_hash_create() OK\n"); +#endif + +#ifdef RTE_LIBRTE_LPM + rte_errno=0; + struct rte_lpm_config config; + + config.max_rules = rte_socket_id(); + config.number_tbl8s = 256; + config.flags = 0; + if ((rte_lpm_create("test_lpm", size, &config) != NULL) && + (rte_lpm_find_existing("test_lpm") == NULL)){ + printf("Error: unexpected return value from rte_lpm_create()\n"); + return -1; + } + 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"); + if (getuid() == 0) /* pci scans can fail as non-root */ + return -1; + } else + printf("PCI scan succeeded in secondary\n"); +#endif + + return 0; +} + +/* if called in a primary process, just spawns off a secondary process to + * run validation tests - which brings us right back here again... + * if called in a secondary process, this runs a series of API tests to check + * how things run in a secondary instance. + */ +int +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(); + } + + printf("IN SECONDARY PROCESS\n"); + + return run_object_creation_tests(); +} + +REGISTER_TEST_COMMAND(multiprocess_autotest, test_mp_secondary); diff --git a/test/test/test_pci.c b/test/test/test_pci.c new file mode 100644 index 0000000000..7985376066 --- /dev/null +++ b/test/test/test_pci.c @@ -0,0 +1,322 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2014 6WIND S.A. + * 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 +#include +#include +#include + +#include +#include +#include +#include + +#include "test.h" +#include "resource.h" + +/* Generic maximum number of drivers to have room to allocate all drivers */ +#define NUM_MAX_DRIVERS 256 + +/* + * PCI test + * ======== + * + * - Register a driver with a ``probe()`` function. + * + * - Dump all PCI devices. + * + * - Check that the ``probe()`` function is called at least once. + */ + +int test_pci_run = 0; /* value checked by the multiprocess test */ +static unsigned pci_dev_count; + +static int my_driver_init(struct rte_pci_driver *dr, + struct rte_pci_device *dev); + +/* IXGBE NICS */ +const struct rte_pci_id my_driver_id[] = { + {RTE_PCI_DEVICE(0x0001, 0x1234)}, + { .vendor_id = 0, /* sentinel */ }, +}; + +const struct rte_pci_id my_driver_id2[] = { + {RTE_PCI_DEVICE(0x0001, 0x4444)}, + {RTE_PCI_DEVICE(0x0002, 0xabcd)}, + { .vendor_id = 0, /* sentinel */ }, +}; + +struct rte_pci_driver my_driver = { + .driver = { + .name = "test_driver" + }, + .probe = my_driver_init, + .id_table = my_driver_id, + .drv_flags = 0, +}; + +struct rte_pci_driver my_driver2 = { + .driver = { + .name = "test_driver2" + }, + .probe = my_driver_init, + .id_table = my_driver_id2, + .drv_flags = 0, +}; + +static int +my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr, + struct rte_pci_device *dev) +{ + printf("My driver init called in %s\n", dr->driver.name); + printf("%x:%x:%x.%d", dev->addr.domain, dev->addr.bus, + dev->addr.devid, dev->addr.function); + printf(" - vendor:%x device:%x\n", dev->id.vendor_id, dev->id.device_id); + + pci_dev_count ++; + return 0; +} + +static void +blacklist_all_devices(void) +{ + struct rte_pci_device *dev = NULL; + unsigned i = 0; + char pci_addr_str[16]; + + TAILQ_FOREACH(dev, &pci_device_list, next) { + snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT, + dev->addr.domain, dev->addr.bus, dev->addr.devid, + dev->addr.function); + if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, + pci_addr_str) < 0) { + printf("Error: cannot blacklist <%s>", pci_addr_str); + break; + } + i++; + } + printf("%u devices blacklisted\n", i); +} + +/* clear devargs list that was modified by the test */ +static void free_devargs_list(void) +{ + struct rte_devargs *devargs; + + while (!TAILQ_EMPTY(&devargs_list)) { + devargs = TAILQ_FIRST(&devargs_list); + TAILQ_REMOVE(&devargs_list, devargs, next); + free(devargs->args); + free(devargs); + } +} + +/* 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_pci_device *dev; + struct rte_pci_driver *dr; + const struct resource *r; + int ret; + + 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 original devices & drivers lists */ + while (!TAILQ_EMPTY(&pci_driver_list)) { + dr = TAILQ_FIRST(&pci_driver_list); + rte_eal_pci_unregister(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); + + pci_dev_count = 0; + printf("Scan bus\n"); + rte_eal_pci_probe(); + + if (pci_dev_count == 0) { + printf("no device detected\n"); + return -1; + } + + /* save the real devargs_list */ + save_devargs_list = devargs_list; + TAILQ_INIT(&devargs_list); + + blacklist_all_devices(); + + pci_dev_count = 0; + printf("Scan bus with all devices blacklisted\n"); + rte_eal_pci_probe(); + + free_devargs_list(); + devargs_list = save_devargs_list; + + if (pci_dev_count != 0) { + printf("not all devices are blacklisted\n"); + return -1; + } + + test_pci_run = 1; + + rte_eal_pci_unregister(&my_driver); + rte_eal_pci_unregister(&my_driver2); + + 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; +} + +REGISTER_TEST_COMMAND(pci_autotest, test_pci); diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/class b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/class new file mode 100644 index 0000000000..2f9c1dada8 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/class @@ -0,0 +1 @@ +0x020000 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/config b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/config new file mode 100644 index 0000000000..7752421cf1 Binary files /dev/null and b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/config differ diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/consistent_dma_mask_bits b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/consistent_dma_mask_bits new file mode 100644 index 0000000000..900731ffd5 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/consistent_dma_mask_bits @@ -0,0 +1 @@ +64 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/device b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/device new file mode 100644 index 0000000000..48a629093b --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/device @@ -0,0 +1 @@ +0x1234 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/dma_mask_bits b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/dma_mask_bits new file mode 100644 index 0000000000..900731ffd5 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/dma_mask_bits @@ -0,0 +1 @@ +64 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/enable b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/enable new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/enable @@ -0,0 +1 @@ +1 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/irq b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/irq new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/irq @@ -0,0 +1 @@ +0 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/modalias b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/modalias new file mode 100644 index 0000000000..f4c76ed932 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/modalias @@ -0,0 +1 @@ +pci:v00008086d000010FBsv00008086sd00000003bc02sc00i00 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/msi_bus b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/msi_bus new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/msi_bus @@ -0,0 +1 @@ +1 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/numa_node b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/numa_node new file mode 100644 index 0000000000..3a2e3f4984 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/numa_node @@ -0,0 +1 @@ +-1 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/resource b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/resource new file mode 100644 index 0000000000..f3889296bf --- /dev/null +++ b/test/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/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_numvfs b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_numvfs new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_numvfs @@ -0,0 +1 @@ +0 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_totalvfs b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_totalvfs new file mode 100644 index 0000000000..4b9026d8e2 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_totalvfs @@ -0,0 +1 @@ +63 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_device b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_device new file mode 100644 index 0000000000..89a932cc4d --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_device @@ -0,0 +1 @@ +0x0003 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_vendor b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_vendor new file mode 100644 index 0000000000..446afb4b76 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_vendor @@ -0,0 +1 @@ +0x0001 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/uevent b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/uevent new file mode 100644 index 0000000000..1dbe34de5d --- /dev/null +++ b/test/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/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/vendor b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/vendor new file mode 100644 index 0000000000..446afb4b76 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/vendor @@ -0,0 +1 @@ +0x0001 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/class b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/class new file mode 100644 index 0000000000..22dd9361aa --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/class @@ -0,0 +1 @@ +0x100000 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/device b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/device new file mode 100644 index 0000000000..f61bbe633c --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/device @@ -0,0 +1 @@ +0xabcd diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/resource b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/resource new file mode 100644 index 0000000000..f3889296bf --- /dev/null +++ b/test/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/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_device b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_device new file mode 100644 index 0000000000..f61bbe633c --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_device @@ -0,0 +1 @@ +0xabcd diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_vendor b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_vendor new file mode 100644 index 0000000000..4321b81fb2 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_vendor @@ -0,0 +1 @@ +0x0002 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/vendor b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/vendor new file mode 100644 index 0000000000..4321b81fb2 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/vendor @@ -0,0 +1 @@ +0x0002 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/class b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/class new file mode 100644 index 0000000000..22dd9361aa --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/class @@ -0,0 +1 @@ +0x100000 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/device b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/device new file mode 100644 index 0000000000..ccaa498206 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/device @@ -0,0 +1 @@ +0x4444 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/resource b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/resource new file mode 100644 index 0000000000..f3889296bf --- /dev/null +++ b/test/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/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_device b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_device new file mode 100644 index 0000000000..ccaa498206 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_device @@ -0,0 +1 @@ +0x4444 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_vendor b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_vendor new file mode 100644 index 0000000000..446afb4b76 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_vendor @@ -0,0 +1 @@ +0x0001 diff --git a/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/vendor b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/vendor new file mode 100644 index 0000000000..446afb4b76 --- /dev/null +++ b/test/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/vendor @@ -0,0 +1 @@ +0x0001 diff --git a/test/test/test_per_lcore.c b/test/test/test_per_lcore.c new file mode 100644 index 0000000000..747513d47b --- /dev/null +++ b/test/test/test_per_lcore.c @@ -0,0 +1,139 @@ +/*- + * 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * Per-lcore variables and lcore launch + * ==================================== + * + * - Use ``rte_eal_mp_remote_launch()`` to call ``assign_vars()`` on + * every available lcore. In this function, a per-lcore variable is + * assigned to the lcore_id. + * + * - Use ``rte_eal_mp_remote_launch()`` to call ``display_vars()`` on + * every available lcore. The function checks that the variable is + * correctly set, or returns -1. + * + * - If at least one per-core variable was not correct, the test function + * returns -1. + */ + +static RTE_DEFINE_PER_LCORE(unsigned, test) = 0x12345678; + +static int +assign_vars(__attribute__((unused)) void *arg) +{ + if (RTE_PER_LCORE(test) != 0x12345678) + return -1; + RTE_PER_LCORE(test) = rte_lcore_id(); + return 0; +} + +static int +display_vars(__attribute__((unused)) void *arg) +{ + unsigned lcore_id = rte_lcore_id(); + unsigned var = RTE_PER_LCORE(test); + unsigned socket_id = rte_lcore_to_socket_id(lcore_id); + + printf("on socket %u, on core %u, variable is %u\n", socket_id, lcore_id, var); + if (lcore_id != var) + return -1; + + RTE_PER_LCORE(test) = 0x12345678; + return 0; +} + +static int +test_per_lcore_delay(__attribute__((unused)) void *arg) +{ + rte_delay_ms(100); + printf("wait 100ms on lcore %u\n", rte_lcore_id()); + + return 0; +} + +static int +test_per_lcore(void) +{ + unsigned lcore_id; + int ret; + + rte_eal_mp_remote_launch(assign_vars, NULL, SKIP_MASTER); + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) + return -1; + } + + rte_eal_mp_remote_launch(display_vars, NULL, SKIP_MASTER); + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) + return -1; + } + + /* test if it could do remote launch twice at the same time or not */ + ret = rte_eal_mp_remote_launch(test_per_lcore_delay, NULL, SKIP_MASTER); + if (ret < 0) { + printf("It fails to do remote launch but it should able to do\n"); + return -1; + } + /* it should not be able to launch a lcore which is running */ + ret = rte_eal_mp_remote_launch(test_per_lcore_delay, NULL, SKIP_MASTER); + if (ret == 0) { + printf("It does remote launch successfully but it should not at this time\n"); + return -1; + } + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) + return -1; + } + + return 0; +} + +REGISTER_TEST_COMMAND(per_lcore_autotest, test_per_lcore); diff --git a/test/test/test_pmd_perf.c b/test/test/test_pmd_perf.c new file mode 100644 index 0000000000..e055aa0726 --- /dev/null +++ b/test/test/test_pmd_perf.c @@ -0,0 +1,913 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "packet_burst_generator.h" +#include "test.h" + +#define NB_ETHPORTS_USED (1) +#define NB_SOCKETS (2) +#define MEMPOOL_CACHE_SIZE 250 +#define MAX_PKT_BURST (32) +#define RTE_TEST_RX_DESC_DEFAULT (128) +#define RTE_TEST_TX_DESC_DEFAULT (512) +#define RTE_PORT_ALL (~(uint8_t)0x0) + +/* how long test would take at full line rate */ +#define RTE_TEST_DURATION (2) + +/* + * RX and TX Prefetch, Host, and Write-back threshold values should be + * carefully set for optimal performance. Consult the network + * controller's datasheet and supporting DPDK documentation for guidance + * on how these parameters should be set. + */ +#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ +#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ +#define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */ + +/* + * These default values are optimized for use with the Intel(R) 82599 10 GbE + * Controller and the DPDK ixgbe PMD. Consider using other values for other + * network controllers and/or network drivers. + */ +#define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */ +#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ +#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ + +#define MAX_TRAFFIC_BURST 2048 + +#define NB_MBUF RTE_MAX( \ + (unsigned)(nb_ports*nb_rx_queue*nb_rxd + \ + nb_ports*nb_lcores*MAX_PKT_BURST + \ + nb_ports*nb_tx_queue*nb_txd + \ + nb_lcores*MEMPOOL_CACHE_SIZE + \ + nb_ports*MAX_TRAFFIC_BURST), \ + (unsigned)8192) + + +static struct rte_mempool *mbufpool[NB_SOCKETS]; +/* ethernet addresses of ports */ +static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; + +static struct rte_eth_conf port_conf = { + .rxmode = { + .mq_mode = ETH_MQ_RX_NONE, + .max_rx_pkt_len = ETHER_MAX_LEN, + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled */ + .hw_ip_checksum = 0, /**< IP checksum offload enabled */ + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ + .hw_vlan_strip = 0, /**< VLAN strip enabled. */ + .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ + .hw_strip_crc = 0, /**< CRC stripped by hardware */ + .enable_scatter = 0, /**< scatter rx disabled */ + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, + .lpbk_mode = 1, /* enable loopback */ +}; + +static struct rte_eth_rxconf rx_conf = { + .rx_thresh = { + .pthresh = RX_PTHRESH, + .hthresh = RX_HTHRESH, + .wthresh = RX_WTHRESH, + }, + .rx_free_thresh = 32, +}; + +static struct rte_eth_txconf tx_conf = { + .tx_thresh = { + .pthresh = TX_PTHRESH, + .hthresh = TX_HTHRESH, + .wthresh = TX_WTHRESH, + }, + .tx_free_thresh = 32, /* Use PMD default values */ + .tx_rs_thresh = 32, /* Use PMD default values */ + .txq_flags = (ETH_TXQ_FLAGS_NOMULTSEGS | + ETH_TXQ_FLAGS_NOVLANOFFL | + ETH_TXQ_FLAGS_NOXSUMSCTP | + ETH_TXQ_FLAGS_NOXSUMUDP | + ETH_TXQ_FLAGS_NOXSUMTCP) +}; + +enum { + LCORE_INVALID = 0, + LCORE_AVAIL, + LCORE_USED, +}; + +struct lcore_conf { + uint8_t status; + uint8_t socketid; + uint16_t nb_ports; + uint8_t portlist[RTE_MAX_ETHPORTS]; +} __rte_cache_aligned; + +struct lcore_conf lcore_conf[RTE_MAX_LCORE]; + +static uint64_t link_mbps; + +enum { + SC_CONTINUOUS = 0, + SC_BURST_POLL_FIRST, + SC_BURST_XMIT_FIRST, +}; + +static uint32_t sc_flag; + +/* Check the link status of all ports in up to 3s, and print them finally */ +static void +check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) +{ +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */ + uint8_t portid, count, all_ports_up, print_flag = 0; + struct rte_eth_link link; + + printf("Checking link statuses...\n"); + fflush(stdout); + for (count = 0; count <= MAX_CHECK_TIME; count++) { + all_ports_up = 1; + for (portid = 0; portid < port_num; portid++) { + if ((port_mask & (1 << portid)) == 0) + continue; + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(portid, &link); + /* print link status if flag set */ + if (print_flag == 1) { + if (link.link_status) { + printf("Port %d Link Up - speed %u " + "Mbps - %s\n", (uint8_t)portid, + (unsigned)link.link_speed, + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + ("full-duplex") : ("half-duplex\n")); + if (link_mbps == 0) + link_mbps = link.link_speed; + } else + printf("Port %d Link Down\n", + (uint8_t)portid); + continue; + } + /* clear all_ports_up flag if any link down */ + if (link.link_status == ETH_LINK_DOWN) { + all_ports_up = 0; + break; + } + } + /* after finally printing all link status, get out */ + if (print_flag == 1) + break; + + if (all_ports_up == 0) { + fflush(stdout); + rte_delay_ms(CHECK_INTERVAL); + } + + /* set the print_flag if all ports up or timeout */ + if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) + print_flag = 1; + } +} + +static void +print_ethaddr(const char *name, const struct ether_addr *eth_addr) +{ + char buf[ETHER_ADDR_FMT_SIZE]; + ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr); + printf("%s%s", name, buf); +} + +static int +init_traffic(struct rte_mempool *mp, + struct rte_mbuf **pkts_burst, uint32_t burst_size) +{ + struct ether_hdr pkt_eth_hdr; + struct ipv4_hdr pkt_ipv4_hdr; + struct udp_hdr pkt_udp_hdr; + uint32_t pktlen; + static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; + static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; + + + initialize_eth_header(&pkt_eth_hdr, + (struct ether_addr *)src_mac, + (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0); + + pktlen = initialize_ipv4_header(&pkt_ipv4_hdr, + IPV4_ADDR(10, 0, 0, 1), + IPV4_ADDR(10, 0, 0, 2), 26); + printf("IPv4 pktlen %u\n", pktlen); + + pktlen = initialize_udp_header(&pkt_udp_hdr, 0, 0, 18); + + printf("UDP pktlen %u\n", pktlen); + + return generate_packet_burst(mp, pkts_burst, &pkt_eth_hdr, + 0, &pkt_ipv4_hdr, 1, + &pkt_udp_hdr, burst_size, + PACKET_BURST_GEN_PKT_LEN, 1); +} + +static int +init_lcores(void) +{ + unsigned lcore_id; + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + lcore_conf[lcore_id].socketid = + rte_lcore_to_socket_id(lcore_id); + if (rte_lcore_is_enabled(lcore_id) == 0) { + lcore_conf[lcore_id].status = LCORE_INVALID; + continue; + } else + lcore_conf[lcore_id].status = LCORE_AVAIL; + } + return 0; +} + +static int +init_mbufpool(unsigned nb_mbuf) +{ + int socketid; + unsigned lcore_id; + char s[64]; + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (rte_lcore_is_enabled(lcore_id) == 0) + continue; + + socketid = rte_lcore_to_socket_id(lcore_id); + if (socketid >= NB_SOCKETS) { + rte_exit(EXIT_FAILURE, + "Socket %d of lcore %u is out of range %d\n", + socketid, lcore_id, NB_SOCKETS); + } + if (mbufpool[socketid] == NULL) { + snprintf(s, sizeof(s), "mbuf_pool_%d", socketid); + mbufpool[socketid] = + rte_pktmbuf_pool_create(s, nb_mbuf, + MEMPOOL_CACHE_SIZE, 0, + RTE_MBUF_DEFAULT_BUF_SIZE, socketid); + if (mbufpool[socketid] == NULL) + rte_exit(EXIT_FAILURE, + "Cannot init mbuf pool on socket %d\n", + socketid); + else + printf("Allocated mbuf pool on socket %d\n", + socketid); + } + } + return 0; +} + +static uint16_t +alloc_lcore(uint16_t socketid) +{ + unsigned lcore_id; + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (LCORE_AVAIL != lcore_conf[lcore_id].status || + lcore_conf[lcore_id].socketid != socketid || + lcore_id == rte_get_master_lcore()) + continue; + lcore_conf[lcore_id].status = LCORE_USED; + lcore_conf[lcore_id].nb_ports = 0; + return lcore_id; + } + + return (uint16_t)-1; +} + +volatile uint64_t stop; +uint64_t count; +uint64_t drop; +uint64_t idle; + +static void +reset_count(void) +{ + count = 0; + drop = 0; + idle = 0; +} + +static void +stats_display(uint8_t port_id) +{ + struct rte_eth_stats stats; + rte_eth_stats_get(port_id, &stats); + + printf(" RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes: " + "%-"PRIu64"\n", + stats.ipackets, stats.imissed, stats.ibytes); + printf(" RX-errors: %-10"PRIu64" RX-nombuf: %-10"PRIu64"\n", + stats.ierrors, stats.rx_nombuf); + printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes: " + "%-"PRIu64"\n", + stats.opackets, stats.oerrors, stats.obytes); +} + +static void +signal_handler(int signum) +{ + /* USR1 signal, stop testing */ + if (signum == SIGUSR1) { + printf("Force Stop!\n"); + stop = 1; + } + + /* USR2 signal, print stats */ + if (signum == SIGUSR2) + stats_display(0); +} + +struct rte_mbuf **tx_burst; + +uint64_t (*do_measure)(struct lcore_conf *conf, + struct rte_mbuf *pkts_burst[], + uint64_t total_pkts); + +static uint64_t +measure_rxtx(struct lcore_conf *conf, + struct rte_mbuf *pkts_burst[], + uint64_t total_pkts) +{ + unsigned i, portid, nb_rx, nb_tx; + uint64_t prev_tsc, cur_tsc; + + prev_tsc = rte_rdtsc(); + + while (likely(!stop)) { + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, + pkts_burst, MAX_PKT_BURST); + if (unlikely(nb_rx == 0)) { + idle++; + continue; + } + + count += nb_rx; + nb_tx = rte_eth_tx_burst(portid, 0, pkts_burst, nb_rx); + if (unlikely(nb_tx < nb_rx)) { + drop += (nb_rx - nb_tx); + do { + rte_pktmbuf_free(pkts_burst[nb_tx]); + } while (++nb_tx < nb_rx); + } + } + if (unlikely(count >= total_pkts)) + break; + } + + cur_tsc = rte_rdtsc(); + + return cur_tsc - prev_tsc; +} + +static uint64_t +measure_rxonly(struct lcore_conf *conf, + struct rte_mbuf *pkts_burst[], + uint64_t total_pkts) +{ + unsigned i, portid, nb_rx, nb_tx; + uint64_t diff_tsc, cur_tsc; + + diff_tsc = 0; + while (likely(!stop)) { + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + + cur_tsc = rte_rdtsc(); + nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, + pkts_burst, MAX_PKT_BURST); + if (unlikely(nb_rx == 0)) { + idle++; + continue; + } + diff_tsc += rte_rdtsc() - cur_tsc; + + count += nb_rx; + nb_tx = rte_eth_tx_burst(portid, 0, pkts_burst, nb_rx); + if (unlikely(nb_tx < nb_rx)) { + drop += (nb_rx - nb_tx); + do { + rte_pktmbuf_free(pkts_burst[nb_tx]); + } while (++nb_tx < nb_rx); + } + } + if (unlikely(count >= total_pkts)) + break; + } + + return diff_tsc; +} + +static uint64_t +measure_txonly(struct lcore_conf *conf, + struct rte_mbuf *pkts_burst[], + uint64_t total_pkts) +{ + unsigned i, portid, nb_rx, nb_tx; + uint64_t diff_tsc, cur_tsc; + + printf("do tx measure\n"); + diff_tsc = 0; + while (likely(!stop)) { + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, + pkts_burst, MAX_PKT_BURST); + if (unlikely(nb_rx == 0)) { + idle++; + continue; + } + + count += nb_rx; + + cur_tsc = rte_rdtsc(); + nb_tx = rte_eth_tx_burst(portid, 0, pkts_burst, nb_rx); + if (unlikely(nb_tx < nb_rx)) { + drop += (nb_rx - nb_tx); + do { + rte_pktmbuf_free(pkts_burst[nb_tx]); + } while (++nb_tx < nb_rx); + } + diff_tsc += rte_rdtsc() - cur_tsc; + } + if (unlikely(count >= total_pkts)) + break; + } + + return diff_tsc; +} + +/* main processing loop */ +static int +main_loop(__rte_unused void *args) +{ +#define PACKET_SIZE 64 +#define FRAME_GAP 12 +#define MAC_PREAMBLE 8 + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + unsigned lcore_id; + unsigned i, portid, nb_rx = 0, nb_tx = 0; + struct lcore_conf *conf; + int pkt_per_port; + uint64_t diff_tsc; + uint64_t packets_per_second, total_packets; + + lcore_id = rte_lcore_id(); + conf = &lcore_conf[lcore_id]; + if (conf->status != LCORE_USED) + return 0; + + pkt_per_port = MAX_TRAFFIC_BURST; + + int idx = 0; + for (i = 0; i < conf->nb_ports; i++) { + int num = pkt_per_port; + portid = conf->portlist[i]; + printf("inject %d packet to port %d\n", num, portid); + while (num) { + nb_tx = RTE_MIN(MAX_PKT_BURST, num); + nb_tx = rte_eth_tx_burst(portid, 0, + &tx_burst[idx], nb_tx); + num -= nb_tx; + idx += nb_tx; + } + } + printf("Total packets inject to prime ports = %u\n", idx); + + packets_per_second = (link_mbps * 1000 * 1000) / + ((PACKET_SIZE + FRAME_GAP + MAC_PREAMBLE) * CHAR_BIT); + printf("Each port will do %"PRIu64" packets per second\n", + packets_per_second); + + total_packets = RTE_TEST_DURATION * conf->nb_ports * packets_per_second; + printf("Test will stop after at least %"PRIu64" packets received\n", + + total_packets); + + diff_tsc = do_measure(conf, pkts_burst, total_packets); + + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + int nb_free = pkt_per_port; + do { /* dry out */ + nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, + pkts_burst, MAX_PKT_BURST); + nb_tx = 0; + while (nb_tx < nb_rx) + rte_pktmbuf_free(pkts_burst[nb_tx++]); + nb_free -= nb_rx; + } while (nb_free != 0); + printf("free %d mbuf left in port %u\n", pkt_per_port, portid); + } + + if (count == 0) + return -1; + + printf("%"PRIu64" packet, %"PRIu64" drop, %"PRIu64" idle\n", + count, drop, idle); + printf("Result: %"PRIu64" cycles per packet\n", diff_tsc / count); + + return 0; +} + +rte_atomic64_t start; + +static inline int +poll_burst(void *args) +{ +#define MAX_IDLE (10000) + unsigned lcore_id; + struct rte_mbuf **pkts_burst; + uint64_t diff_tsc, cur_tsc; + uint16_t next[RTE_MAX_ETHPORTS]; + struct lcore_conf *conf; + uint32_t pkt_per_port = *((uint32_t *)args); + unsigned i, portid, nb_rx = 0; + uint64_t total; + uint64_t timeout = MAX_IDLE; + + lcore_id = rte_lcore_id(); + conf = &lcore_conf[lcore_id]; + if (conf->status != LCORE_USED) + return 0; + + total = pkt_per_port * conf->nb_ports; + printf("start to receive total expect %"PRIu64"\n", total); + + pkts_burst = (struct rte_mbuf **) + rte_calloc_socket("poll_burst", + total, sizeof(void *), + RTE_CACHE_LINE_SIZE, conf->socketid); + if (!pkts_burst) + return -1; + + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + next[portid] = i * pkt_per_port; + } + + while (!rte_atomic64_read(&start)) + ; + + cur_tsc = rte_rdtsc(); + while (total) { + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, + &pkts_burst[next[portid]], + MAX_PKT_BURST); + if (unlikely(nb_rx == 0)) { + timeout--; + if (unlikely(timeout == 0)) + goto timeout; + continue; + } + next[portid] += nb_rx; + total -= nb_rx; + } + } +timeout: + diff_tsc = rte_rdtsc() - cur_tsc; + + printf("%"PRIu64" packets lost, IDLE %"PRIu64" times\n", + total, MAX_IDLE - timeout); + + /* clean up */ + total = pkt_per_port * conf->nb_ports - total; + for (i = 0; i < total; i++) + rte_pktmbuf_free(pkts_burst[i]); + + rte_free(pkts_burst); + + if (total > 0) + return diff_tsc / total; + else + return -1; +} + +static int +exec_burst(uint32_t flags, int lcore) +{ + unsigned i, portid, nb_tx = 0; + struct lcore_conf *conf; + uint32_t pkt_per_port; + int num, idx = 0; + int diff_tsc; + + conf = &lcore_conf[lcore]; + + pkt_per_port = MAX_TRAFFIC_BURST; + num = pkt_per_port; + + rte_atomic64_init(&start); + + /* start polling thread, but not actually poll yet */ + rte_eal_remote_launch(poll_burst, + (void *)&pkt_per_port, lcore); + + /* Only when polling first */ + if (flags == SC_BURST_POLL_FIRST) + rte_atomic64_set(&start, 1); + + /* start xmit */ + while (num) { + nb_tx = RTE_MIN(MAX_PKT_BURST, num); + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + rte_eth_tx_burst(portid, 0, + &tx_burst[idx], nb_tx); + idx += nb_tx; + } + num -= nb_tx; + } + + sleep(5); + + /* only when polling second */ + if (flags == SC_BURST_XMIT_FIRST) + rte_atomic64_set(&start, 1); + + /* wait for polling finished */ + diff_tsc = rte_eal_wait_lcore(lcore); + if (diff_tsc < 0) { + printf("exec_burst: Failed to measure cycles per packet\n"); + return -1; + } + + printf("Result: %d cycles per packet\n", diff_tsc); + + return 0; +} + +static int +test_pmd_perf(void) +{ + uint16_t nb_ports, num, nb_lcores, slave_id = (uint16_t)-1; + uint16_t nb_rxd = MAX_TRAFFIC_BURST; + uint16_t nb_txd = MAX_TRAFFIC_BURST; + uint16_t portid; + uint16_t nb_rx_queue = 1, nb_tx_queue = 1; + int socketid = -1; + int ret; + + printf("Start PMD RXTX cycles cost test.\n"); + + signal(SIGUSR1, signal_handler); + signal(SIGUSR2, signal_handler); + + nb_ports = rte_eth_dev_count(); + if (nb_ports < NB_ETHPORTS_USED) { + printf("At least %u port(s) used for perf. test\n", + NB_ETHPORTS_USED); + return -1; + } + + nb_lcores = rte_lcore_count(); + + memset(lcore_conf, 0, sizeof(lcore_conf)); + init_lcores(); + + init_mbufpool(NB_MBUF); + + if (sc_flag == SC_CONTINUOUS) { + nb_rxd = RTE_TEST_RX_DESC_DEFAULT; + nb_txd = RTE_TEST_TX_DESC_DEFAULT; + } + printf("CONFIG RXD=%d TXD=%d\n", nb_rxd, nb_txd); + + reset_count(); + num = 0; + for (portid = 0; portid < nb_ports; portid++) { + if (socketid == -1) { + socketid = rte_eth_dev_socket_id(portid); + slave_id = alloc_lcore(socketid); + if (slave_id == (uint16_t)-1) { + printf("No avail lcore to run test\n"); + return -1; + } + printf("Performance test runs on lcore %u socket %u\n", + slave_id, socketid); + } + + if (socketid != rte_eth_dev_socket_id(portid)) { + printf("Skip port %d\n", portid); + continue; + } + + /* port configure */ + ret = rte_eth_dev_configure(portid, nb_rx_queue, + nb_tx_queue, &port_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Cannot configure device: err=%d, port=%d\n", + ret, portid); + + rte_eth_macaddr_get(portid, &ports_eth_addr[portid]); + printf("Port %u ", portid); + print_ethaddr("Address:", &ports_eth_addr[portid]); + printf("\n"); + + /* tx queue setup */ + ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, + socketid, &tx_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "rte_eth_tx_queue_setup: err=%d, " + "port=%d\n", ret, portid); + + /* rx queue steup */ + ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, + socketid, &rx_conf, + mbufpool[socketid]); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d," + "port=%d\n", ret, portid); + + /* Start device */ + stop = 0; + ret = rte_eth_dev_start(portid); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "rte_eth_dev_start: err=%d, port=%d\n", + ret, portid); + + /* always eanble promiscuous */ + rte_eth_promiscuous_enable(portid); + + lcore_conf[slave_id].portlist[num++] = portid; + lcore_conf[slave_id].nb_ports++; + } + check_all_ports_link_status(nb_ports, RTE_PORT_ALL); + + if (tx_burst == NULL) { + tx_burst = (struct rte_mbuf **) + rte_calloc_socket("tx_buff", + MAX_TRAFFIC_BURST * nb_ports, + sizeof(void *), + RTE_CACHE_LINE_SIZE, socketid); + if (!tx_burst) + return -1; + } + + init_traffic(mbufpool[socketid], + tx_burst, MAX_TRAFFIC_BURST * nb_ports); + + printf("Generate %d packets @socket %d\n", + MAX_TRAFFIC_BURST * nb_ports, socketid); + + if (sc_flag == SC_CONTINUOUS) { + /* do both rxtx by default */ + if (NULL == do_measure) + do_measure = measure_rxtx; + + rte_eal_remote_launch(main_loop, NULL, slave_id); + + if (rte_eal_wait_lcore(slave_id) < 0) + return -1; + } else if (sc_flag == SC_BURST_POLL_FIRST || + sc_flag == SC_BURST_XMIT_FIRST) + if (exec_burst(sc_flag, slave_id) < 0) + return -1; + + /* port tear down */ + for (portid = 0; portid < nb_ports; portid++) { + if (socketid != rte_eth_dev_socket_id(portid)) + continue; + + rte_eth_dev_stop(portid); + } + + return 0; +} + +int +test_set_rxtx_conf(cmdline_fixed_string_t mode) +{ + printf("mode switch to %s\n", mode); + + if (!strcmp(mode, "vector")) { + /* vector rx, tx */ + tx_conf.txq_flags = 0xf01; + tx_conf.tx_rs_thresh = 32; + tx_conf.tx_free_thresh = 32; + port_conf.rxmode.hw_ip_checksum = 0; + port_conf.rxmode.enable_scatter = 0; + return 0; + } else if (!strcmp(mode, "scalar")) { + /* bulk alloc rx, full-featured tx */ + tx_conf.txq_flags = 0; + tx_conf.tx_rs_thresh = 32; + tx_conf.tx_free_thresh = 32; + port_conf.rxmode.hw_ip_checksum = 1; + port_conf.rxmode.enable_scatter = 0; + return 0; + } else if (!strcmp(mode, "hybrid")) { + /* bulk alloc rx, vector tx + * when vec macro not define, + * using the same rx/tx as scalar + */ + tx_conf.txq_flags = 0xf01; + tx_conf.tx_rs_thresh = 32; + tx_conf.tx_free_thresh = 32; + port_conf.rxmode.hw_ip_checksum = 1; + port_conf.rxmode.enable_scatter = 0; + return 0; + } else if (!strcmp(mode, "full")) { + /* full feature rx,tx pair */ + tx_conf.txq_flags = 0x0; /* must condition */ + tx_conf.tx_rs_thresh = 32; + tx_conf.tx_free_thresh = 32; + port_conf.rxmode.hw_ip_checksum = 0; + port_conf.rxmode.enable_scatter = 1; /* must condition */ + return 0; + } + + return -1; +} + +int +test_set_rxtx_anchor(cmdline_fixed_string_t type) +{ + printf("type switch to %s\n", type); + + if (!strcmp(type, "rxtx")) { + do_measure = measure_rxtx; + return 0; + } else if (!strcmp(type, "rxonly")) { + do_measure = measure_rxonly; + return 0; + } else if (!strcmp(type, "txonly")) { + do_measure = measure_txonly; + return 0; + } + + return -1; +} + +int +test_set_rxtx_sc(cmdline_fixed_string_t type) +{ + printf("stream control switch to %s\n", type); + + if (!strcmp(type, "continuous")) { + sc_flag = SC_CONTINUOUS; + return 0; + } else if (!strcmp(type, "poll_before_xmit")) { + sc_flag = SC_BURST_POLL_FIRST; + return 0; + } else if (!strcmp(type, "poll_after_xmit")) { + sc_flag = SC_BURST_XMIT_FIRST; + return 0; + } + + return -1; +} + +REGISTER_TEST_COMMAND(pmd_perf_autotest, test_pmd_perf); diff --git a/test/test/test_pmd_ring.c b/test/test/test_pmd_ring.c new file mode 100644 index 0000000000..2cdf60d103 --- /dev/null +++ b/test/test/test_pmd_ring.c @@ -0,0 +1,529 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 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 "test.h" + +#include + +#include +#include + +static struct rte_mempool *mp; +static int tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte; + +#define SOCKET0 0 +#define RING_SIZE 256 +#define NUM_RINGS 2 +#define NB_MBUF 512 + + +static int +test_ethdev_configure_port(int port) +{ + struct rte_eth_conf null_conf; + struct rte_eth_link link; + + memset(&null_conf, 0, sizeof(struct rte_eth_conf)); + + if (rte_eth_dev_configure(port, 1, 2, &null_conf) < 0) { + printf("Configure failed for port %d\n", port); + return -1; + } + + /* Test queue release */ + if (rte_eth_dev_configure(port, 1, 1, &null_conf) < 0) { + printf("Configure failed for port %d\n", port); + return -1; + } + + if (rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL) < 0) { + printf("TX queue setup failed port %d\n", port); + return -1; + } + + if (rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0, + NULL, mp) < 0) { + printf("RX queue setup failed port %d\n", port); + return -1; + } + + if (rte_eth_dev_start(port) < 0) { + printf("Error starting port %d\n", port); + return -1; + } + + rte_eth_link_get(port, &link); + + return 0; +} + +static int +test_send_basic_packets(void) +{ + struct rte_mbuf bufs[RING_SIZE]; + struct rte_mbuf *pbufs[RING_SIZE]; + int i; + + printf("Testing send and receive RING_SIZE/2 packets (tx_porta -> rx_portb)\n"); + + for (i = 0; i < RING_SIZE/2; i++) + pbufs[i] = &bufs[i]; + + if (rte_eth_tx_burst(tx_porta, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) { + printf("Failed to transmit packet burst port %d\n", tx_porta); + return -1; + } + + if (rte_eth_rx_burst(rx_portb, 0, pbufs, RING_SIZE) != RING_SIZE/2) { + printf("Failed to receive packet burst on port %d\n", rx_portb); + return -1; + } + + for (i = 0; i < RING_SIZE/2; i++) + if (pbufs[i] != &bufs[i]) { + printf("Error: received data does not match that transmitted\n"); + return -1; + } + + return 0; +} + +static int +test_send_basic_packets_port(int port) +{ + struct rte_mbuf bufs[RING_SIZE]; + struct rte_mbuf *pbufs[RING_SIZE]; + int i; + + printf("Testing send and receive RING_SIZE/2 packets (cmdl_port0 -> cmdl_port0)\n"); + + for (i = 0; i < RING_SIZE/2; i++) + pbufs[i] = &bufs[i]; + + if (rte_eth_tx_burst(port, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) { + printf("Failed to transmit packet burst port %d\n", port); + return -1; + } + + if (rte_eth_rx_burst(port, 0, pbufs, RING_SIZE) != RING_SIZE/2) { + printf("Failed to receive packet burst on port %d\n", port); + return -1; + } + + for (i = 0; i < RING_SIZE/2; i++) + if (pbufs[i] != &bufs[i]) { + printf("Error: received data does not match that transmitted\n"); + return -1; + } + + return 0; +} + + +static int +test_get_stats(int port) +{ + struct rte_eth_stats stats; + struct rte_mbuf buf, *pbuf = &buf; + + printf("Testing ring PMD stats_get port %d\n", port); + + /* check stats of RXTX port, should all be zero */ + + rte_eth_stats_get(port, &stats); + if (stats.ipackets != 0 || stats.opackets != 0 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not zero\n", port); + return -1; + } + + /* send and receive 1 packet and check for stats update */ + if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", port); + return -1; + } + + if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", port); + return -1; + } + + rte_eth_stats_get(port, &stats); + if (stats.ipackets != 1 || stats.opackets != 1 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", port); + return -1; + } + return 0; +} + +static int +test_stats_reset(int port) +{ + struct rte_eth_stats stats; + struct rte_mbuf buf, *pbuf = &buf; + + printf("Testing ring PMD stats_reset port %d\n", port); + + rte_eth_stats_reset(port); + + /* check stats of RXTX port, should all be zero */ + rte_eth_stats_get(port, &stats); + if (stats.ipackets != 0 || stats.opackets != 0 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not zero\n", port); + return -1; + } + + /* send and receive 1 packet and check for stats update */ + if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", port); + return -1; + } + + if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", port); + return -1; + } + + rte_eth_stats_get(port, &stats); + if (stats.ipackets != 1 || stats.opackets != 1 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", port); + return -1; + } + + rte_eth_stats_reset(port); + + /* check stats of RXTX port, should all be zero */ + rte_eth_stats_get(port, &stats); + if (stats.ipackets != 0 || stats.opackets != 0 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not zero\n", port); + return -1; + } + + return 0; +} + +static int +test_pmd_ring_pair_create_attach(int portd, int porte) +{ + struct rte_eth_stats stats, stats2; + struct rte_mbuf buf, *pbuf = &buf; + struct rte_eth_conf null_conf; + + if ((rte_eth_dev_configure(portd, 1, 1, &null_conf) < 0) + || (rte_eth_dev_configure(porte, 1, 1, &null_conf) < 0)) { + printf("Configure failed for port\n"); + return -1; + } + + if ((rte_eth_tx_queue_setup(portd, 0, RING_SIZE, SOCKET0, NULL) < 0) + || (rte_eth_tx_queue_setup(porte, 0, RING_SIZE, SOCKET0, NULL) < 0)) { + printf("TX queue setup failed\n"); + return -1; + } + + if ((rte_eth_rx_queue_setup(portd, 0, RING_SIZE, SOCKET0, NULL, mp) < 0) + || (rte_eth_rx_queue_setup(porte, 0, RING_SIZE, SOCKET0, NULL, mp) < 0)) { + printf("RX queue setup failed\n"); + return -1; + } + + if ((rte_eth_dev_start(portd) < 0) + || (rte_eth_dev_start(porte) < 0)) { + printf("Error starting port\n"); + return -1; + } + + rte_eth_stats_reset(portd); + /* check stats of port, should all be zero */ + rte_eth_stats_get(portd, &stats); + if (stats.ipackets != 0 || stats.opackets != 0 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not zero\n", portd); + return -1; + } + + rte_eth_stats_reset(porte); + /* check stats of port, should all be zero */ + rte_eth_stats_get(porte, &stats2); + if (stats2.ipackets != 0 || stats2.opackets != 0 || + stats2.ibytes != 0 || stats2.obytes != 0 || + stats2.ierrors != 0 || stats2.oerrors != 0) { + printf("Error: port %d stats are not zero\n", porte); + return -1; + } + + /* + * send and receive 1 packet (portd -> porte) + * and check for stats update + */ + printf("Testing send and receive 1 packet (portd -> porte)\n"); + if (rte_eth_tx_burst(portd, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", portd); + return -1; + } + + if (rte_eth_rx_burst(porte, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", porte); + return -1; + } + + rte_eth_stats_get(portd, &stats); + rte_eth_stats_get(porte, &stats2); + if (stats.ipackets != 0 || stats.opackets != 1 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", portd); + return -1; + } + + if (stats2.ipackets != 1 || stats2.opackets != 0 || + stats2.ibytes != 0 || stats2.obytes != 0 || + stats2.ierrors != 0 || stats2.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", porte); + return -1; + } + + /* + * send and receive 1 packet (porte -> portd) + * and check for stats update + */ + printf("Testing send and receive 1 packet (porte -> portd)\n"); + if (rte_eth_tx_burst(porte, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", porte); + return -1; + } + + if (rte_eth_rx_burst(portd, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", portd); + return -1; + } + + rte_eth_stats_get(portd, &stats); + rte_eth_stats_get(porte, &stats2); + if (stats.ipackets != 1 || stats.opackets != 1 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", portd); + return -1; + } + + if (stats2.ipackets != 1 || stats2.opackets != 1 || + stats2.ibytes != 0 || stats2.obytes != 0 || + stats2.ierrors != 0 || stats2.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", porte); + return -1; + } + + /* + * send and receive 1 packet (portd -> portd) + * and check for stats update + */ + printf("Testing send and receive 1 packet (portd -> portd)\n"); + if (rte_eth_tx_burst(portd, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", portd); + return -1; + } + + if (rte_eth_rx_burst(portd, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", porte); + return -1; + } + + rte_eth_stats_get(portd, &stats); + rte_eth_stats_get(porte, &stats2); + if (stats.ipackets != 2 || stats.opackets != 2 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", portd); + return -1; + } + + if (stats2.ipackets != 1 || stats2.opackets != 1 || + stats2.ibytes != 0 || stats2.obytes != 0 || + stats2.ierrors != 0 || stats2.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", porte); + return -1; + } + + /* + * send and receive 1 packet (porte -> porte) + * and check for stats update + */ + printf("Testing send and receive 1 packet (porte -> porte)\n"); + if (rte_eth_tx_burst(porte, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", porte); + return -1; + } + + if (rte_eth_rx_burst(porte, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", porte); + return -1; + } + + rte_eth_stats_get(portd, &stats); + rte_eth_stats_get(porte, &stats2); + if (stats.ipackets != 2 || stats.opackets != 2 || + stats.ibytes != 0 || stats.obytes != 0 || + stats.ierrors != 0 || stats.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", portd); + return -1; + } + + if (stats2.ipackets != 2 || stats2.opackets != 2 || + stats2.ibytes != 0 || stats2.obytes != 0 || + stats2.ierrors != 0 || stats2.oerrors != 0) { + printf("Error: port %d stats are not as expected\n", porte); + return -1; + } + + rte_eth_dev_stop(portd); + rte_eth_dev_stop(porte); + + return 0; +} + +static int +test_pmd_ring(void) +{ + struct rte_ring *rxtx[NUM_RINGS]; + int port, cmdl_port0 = -1; + uint8_t nb_ports; + + nb_ports = rte_eth_dev_count(); + printf("nb_ports=%d\n", (int)nb_ports); + + /* create the rings and eth_rings in the test code. + * This does not test the rte_pmd_ring_devinit function. + * + * Test with the command line option --vdev=net_ring0 to test rte_pmd_ring_devinit. + */ + rxtx[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); + if (rxtx[0] == NULL) { + printf("rte_ring_create R0 failed"); + return -1; + } + + rxtx[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); + if (rxtx[1] == NULL) { + printf("rte_ring_create R1 failed"); + return -1; + } + + tx_porta = rte_eth_from_rings("net_ringa", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); + rx_portb = rte_eth_from_rings("net_ringb", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); + rxtx_portc = rte_eth_from_rings("net_ringc", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); + rxtx_portd = rte_eth_from_rings("net_ringd", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); + rxtx_porte = rte_eth_from_rings("net_ringe", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); + + printf("tx_porta=%d rx_portb=%d rxtx_portc=%d rxtx_portd=%d rxtx_porte=%d\n", + tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte); + + if ((tx_porta == -1) || (rx_portb == -1) || (rxtx_portc == -1) + || (rxtx_portd == -1) || (rxtx_porte == -1)) { + printf("rte_eth_from rings failed\n"); + return -1; + } + + mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32, + 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + if (mp == NULL) + return -1; + + if ((tx_porta >= RTE_MAX_ETHPORTS) || (rx_portb >= RTE_MAX_ETHPORTS) + || (rxtx_portc >= RTE_MAX_ETHPORTS) + || (rxtx_portd >= RTE_MAX_ETHPORTS) + || (rxtx_porte >= RTE_MAX_ETHPORTS)) { + printf(" port exceed max eth ports\n"); + return -1; + } + + if (test_ethdev_configure_port(tx_porta) < 0) + return -1; + + if (test_ethdev_configure_port(rx_portb) < 0) + return -1; + + if (test_ethdev_configure_port(rxtx_portc) < 0) + return -1; + + if (test_send_basic_packets() < 0) + return -1; + + if (test_get_stats(rxtx_portc) < 0) + return -1; + + if (test_stats_reset(rxtx_portc) < 0) + return -1; + + rte_eth_dev_stop(tx_porta); + rte_eth_dev_stop(rx_portb); + rte_eth_dev_stop(rxtx_portc); + + if (test_pmd_ring_pair_create_attach(rxtx_portd, rxtx_porte) < 0) + return -1; + + /* find a port created with the --vdev=net_ring0 command line option */ + for (port = 0; port < nb_ports; port++) { + struct rte_eth_dev_info dev_info; + + rte_eth_dev_info_get(port, &dev_info); + if (!strcmp(dev_info.driver_name, "Rings PMD")) { + printf("found a command line ring port=%d\n", port); + cmdl_port0 = port; + break; + } + } + if (cmdl_port0 != -1) { + if (test_ethdev_configure_port(cmdl_port0) < 0) + return -1; + if (test_send_basic_packets_port(cmdl_port0) < 0) + return -1; + if (test_stats_reset(cmdl_port0) < 0) + return -1; + if (test_get_stats(cmdl_port0) < 0) + return -1; + rte_eth_dev_stop(cmdl_port0); + } + return 0; +} + +REGISTER_TEST_COMMAND(ring_pmd_autotest, test_pmd_ring); diff --git a/test/test/test_pmd_ring_perf.c b/test/test/test_pmd_ring_perf.c new file mode 100644 index 0000000000..af011f7db5 --- /dev/null +++ b/test/test/test_pmd_ring_perf.c @@ -0,0 +1,184 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 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 +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define RING_NAME "RING_PERF" +#define RING_SIZE 4096 +#define MAX_BURST 32 + +/* + * the sizes to enqueue and dequeue in testing + * (marked volatile so they won't be seen as compile-time constants) + */ +static const volatile unsigned bulk_sizes[] = { 1, 8, 32 }; + +/* The ring structure used for tests */ +static struct rte_ring *r; +static uint8_t ring_ethdev_port; + +/* Get cycle counts for dequeuing from an empty ring. Should be 2 or 3 cycles */ +static void +test_empty_dequeue(void) +{ + const unsigned iter_shift = 26; + const unsigned iterations = 1 << iter_shift; + unsigned i = 0; + void *burst[MAX_BURST]; + + const uint64_t sc_start = rte_rdtsc(); + for (i = 0; i < iterations; i++) + rte_ring_sc_dequeue_bulk(r, burst, bulk_sizes[0]); + const uint64_t sc_end = rte_rdtsc(); + + const uint64_t eth_start = rte_rdtsc(); + for (i = 0; i < iterations; i++) + rte_eth_rx_burst(ring_ethdev_port, 0, (void *)burst, + bulk_sizes[0]); + const uint64_t eth_end = rte_rdtsc(); + + printf("Ring empty dequeue : %.1F\n", + (double)(sc_end - sc_start) / iterations); + printf("Ethdev empty dequeue: %.1F\n", + (double)(eth_end - eth_start) / iterations); +} + +/* + * Test function that determines how long an enqueue + dequeue of a single item + * takes on a single lcore. Result is for comparison with the bulk enq+deq. + */ +static void +test_single_enqueue_dequeue(void) +{ + const unsigned iter_shift = 24; + const unsigned iterations = 1 << iter_shift; + unsigned i = 0; + void *burst = NULL; + struct rte_mbuf *mburst[1] = { NULL }; + + const uint64_t sc_start = rte_rdtsc_precise(); + rte_compiler_barrier(); + for (i = 0; i < iterations; i++) { + rte_ring_enqueue_bulk(r, &burst, 1); + rte_ring_dequeue_bulk(r, &burst, 1); + } + const uint64_t sc_end = rte_rdtsc_precise(); + rte_compiler_barrier(); + + const uint64_t eth_start = rte_rdtsc_precise(); + rte_compiler_barrier(); + for (i = 0; i < iterations; i++) { + rte_eth_tx_burst(ring_ethdev_port, 0, mburst, 1); + rte_eth_rx_burst(ring_ethdev_port, 0, mburst, 1); + } + const uint64_t eth_end = rte_rdtsc_precise(); + rte_compiler_barrier(); + + printf("Ring single enq/dequeue : %"PRIu64"\n", + (sc_end-sc_start) >> iter_shift); + printf("Ethdev single enq/dequeue: %"PRIu64"\n", + (eth_end-eth_start) >> iter_shift); +} + +/* Times enqueue and dequeue on a single lcore */ +static void +test_bulk_enqueue_dequeue(void) +{ + const unsigned iter_shift = 23; + const unsigned iterations = 1 << iter_shift; + unsigned sz, i = 0; + struct rte_mbuf *burst[MAX_BURST] = {0}; + + for (sz = 0; sz < sizeof(bulk_sizes)/sizeof(bulk_sizes[0]); sz++) { + const uint64_t sc_start = rte_rdtsc(); + for (i = 0; i < iterations; i++) { + rte_ring_sp_enqueue_bulk(r, (void *)burst, bulk_sizes[sz]); + rte_ring_sc_dequeue_bulk(r, (void *)burst, bulk_sizes[sz]); + } + const uint64_t sc_end = rte_rdtsc(); + + const uint64_t eth_start = rte_rdtsc_precise(); + rte_compiler_barrier(); + for (i = 0; i < iterations; i++) { + rte_eth_tx_burst(ring_ethdev_port, 0, burst, bulk_sizes[sz]); + rte_eth_rx_burst(ring_ethdev_port, 0, burst, bulk_sizes[sz]); + } + const uint64_t eth_end = rte_rdtsc_precise(); + rte_compiler_barrier(); + + double sc_avg = ((double)(sc_end-sc_start) / + (iterations * bulk_sizes[sz])); + double eth_avg = ((double)(eth_end-eth_start) / + (iterations * bulk_sizes[sz])); + + printf("ring bulk enq/deq (size: %u) : %.1F\n", bulk_sizes[sz], + sc_avg); + printf("ethdev bulk enq/deq (size:%u): %.1F\n", bulk_sizes[sz], + eth_avg); + + printf("\n"); + } +} + +static int +test_ring_pmd_perf(void) +{ + r = rte_ring_create(RING_NAME, RING_SIZE, rte_socket_id(), + RING_F_SP_ENQ|RING_F_SC_DEQ); + if (r == NULL && (r = rte_ring_lookup(RING_NAME)) == NULL) + return -1; + + ring_ethdev_port = rte_eth_from_ring(r); + + printf("\n### Testing const single element enq/deq ###\n"); + test_single_enqueue_dequeue(); + + printf("\n### Testing empty dequeue ###\n"); + test_empty_dequeue(); + + printf("\n### Testing using a single lcore ###\n"); + test_bulk_enqueue_dequeue(); + + return 0; +} + +REGISTER_TEST_COMMAND(ring_pmd_perf_autotest, test_ring_pmd_perf); diff --git a/test/test/test_power.c b/test/test/test_power.c new file mode 100644 index 0000000000..b2e1344c3d --- /dev/null +++ b/test/test/test_power.c @@ -0,0 +1,107 @@ +/*- + * 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 +#include +#include +#include +#include + +#include "test.h" + +#include + +static int +test_power(void) +{ + int ret = -1; + enum power_management_env env; + + /* Test setting an invalid environment */ + ret = rte_power_set_env(PM_ENV_NOT_SET); + if (ret == 0) { + printf("Unexpectedly succeeded on setting an invalid environment\n"); + return -1; + } + + /* Test that the environment has not been set */ + env = rte_power_get_env(); + if (env != PM_ENV_NOT_SET) { + printf("Unexpectedly got a valid environment configuration\n"); + return -1; + } + + /* verify that function pointers are NULL */ + if (rte_power_freqs != NULL) { + printf("rte_power_freqs should be NULL, environment has not been " + "initialised\n"); + goto fail_all; + } + if (rte_power_get_freq != NULL) { + printf("rte_power_get_freq should be NULL, environment has not been " + "initialised\n"); + goto fail_all; + } + if (rte_power_set_freq != NULL) { + printf("rte_power_set_freq should be NULL, environment has not been " + "initialised\n"); + goto fail_all; + } + if (rte_power_freq_up != NULL) { + printf("rte_power_freq_up should be NULL, environment has not been " + "initialised\n"); + goto fail_all; + } + if (rte_power_freq_down != NULL) { + printf("rte_power_freq_down should be NULL, environment has not been " + "initialised\n"); + goto fail_all; + } + if (rte_power_freq_max != NULL) { + printf("rte_power_freq_max should be NULL, environment has not been " + "initialised\n"); + goto fail_all; + } + if (rte_power_freq_min != NULL) { + printf("rte_power_freq_min should be NULL, environment has not been " + "initialised\n"); + goto fail_all; + } + rte_power_unset_env(); + return 0; +fail_all: + rte_power_unset_env(); + return -1; +} + +REGISTER_TEST_COMMAND(power_autotest, test_power); diff --git a/test/test/test_power_acpi_cpufreq.c b/test/test/test_power_acpi_cpufreq.c new file mode 100644 index 0000000000..64f5dd5679 --- /dev/null +++ b/test/test/test_power_acpi_cpufreq.c @@ -0,0 +1,540 @@ +/*- + * 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 +#include +#include +#include +#include + +#include "test.h" + +#include + +#define TEST_POWER_LCORE_ID 2U +#define TEST_POWER_LCORE_INVALID ((unsigned)RTE_MAX_LCORE) +#define TEST_POWER_FREQS_NUM_MAX ((unsigned)RTE_MAX_LCORE_FREQS) + +#define TEST_POWER_SYSFILE_CUR_FREQ \ + "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq" + +static uint32_t total_freq_num; +static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX]; + +static int +check_cur_freq(unsigned lcore_id, uint32_t idx) +{ +#define TEST_POWER_CONVERT_TO_DECIMAL 10 + FILE *f; + char fullpath[PATH_MAX]; + char buf[BUFSIZ]; + uint32_t cur_freq; + int ret = -1; + + if (snprintf(fullpath, sizeof(fullpath), + TEST_POWER_SYSFILE_CUR_FREQ, lcore_id) < 0) { + return 0; + } + f = fopen(fullpath, "r"); + if (f == NULL) { + return 0; + } + if (fgets(buf, sizeof(buf), f) == NULL) { + goto fail_get_cur_freq; + } + cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL); + ret = (freqs[idx] == cur_freq ? 0 : -1); + +fail_get_cur_freq: + fclose(f); + + return ret; +} + +/* Check rte_power_freqs() */ +static int +check_power_freqs(void) +{ + uint32_t ret; + + total_freq_num = 0; + memset(freqs, 0, sizeof(freqs)); + + /* test with an invalid lcore id */ + ret = rte_power_freqs(TEST_POWER_LCORE_INVALID, freqs, + TEST_POWER_FREQS_NUM_MAX); + if (ret > 0) { + printf("Unexpectedly get available freqs successfully on " + "lcore %u\n", TEST_POWER_LCORE_INVALID); + return -1; + } + + /* test with NULL buffer to save available freqs */ + ret = rte_power_freqs(TEST_POWER_LCORE_ID, NULL, + TEST_POWER_FREQS_NUM_MAX); + if (ret > 0) { + printf("Unexpectedly get available freqs successfully with " + "NULL buffer on lcore %u\n", TEST_POWER_LCORE_ID); + return -1; + } + + /* test of getting zero number of freqs */ + ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, 0); + if (ret > 0) { + printf("Unexpectedly get available freqs successfully with " + "zero buffer size on lcore %u\n", TEST_POWER_LCORE_ID); + return -1; + } + + /* test with all valid input parameters */ + ret = rte_power_freqs(TEST_POWER_LCORE_ID, freqs, + TEST_POWER_FREQS_NUM_MAX); + if (ret == 0 || ret > TEST_POWER_FREQS_NUM_MAX) { + printf("Fail to get available freqs on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Save the total number of available freqs */ + total_freq_num = ret; + + return 0; +} + +/* Check rte_power_get_freq() */ +static int +check_power_get_freq(void) +{ + int ret; + uint32_t count; + + /* test with an invalid lcore id */ + count = rte_power_get_freq(TEST_POWER_LCORE_INVALID); + if (count < TEST_POWER_FREQS_NUM_MAX) { + printf("Unexpectedly get freq index successfully on " + "lcore %u\n", TEST_POWER_LCORE_INVALID); + return -1; + } + + count = rte_power_get_freq(TEST_POWER_LCORE_ID); + if (count >= TEST_POWER_FREQS_NUM_MAX) { + printf("Fail to get the freq index on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Check the current frequency */ + ret = check_cur_freq(TEST_POWER_LCORE_ID, count); + if (ret < 0) + return -1; + + return 0; +} + +/* Check rte_power_set_freq() */ +static int +check_power_set_freq(void) +{ + int ret; + + /* test with an invalid lcore id */ + ret = rte_power_set_freq(TEST_POWER_LCORE_INVALID, 0); + if (ret >= 0) { + printf("Unexpectedly set freq index successfully on " + "lcore %u\n", TEST_POWER_LCORE_INVALID); + return -1; + } + + /* test with an invalid freq index */ + ret = rte_power_set_freq(TEST_POWER_LCORE_ID, + TEST_POWER_FREQS_NUM_MAX); + if (ret >= 0) { + printf("Unexpectedly set an invalid freq index (%u)" + "successfully on lcore %u\n", TEST_POWER_FREQS_NUM_MAX, + TEST_POWER_LCORE_ID); + return -1; + } + + /** + * test with an invalid freq index which is right one bigger than + * total number of freqs + */ + ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num); + if (ret >= 0) { + printf("Unexpectedly set an invalid freq index (%u)" + "successfully on lcore %u\n", total_freq_num, + TEST_POWER_LCORE_ID); + return -1; + } + ret = rte_power_set_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); + if (ret < 0) { + printf("Fail to set freq index on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Check the current frequency */ + ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); + if (ret < 0) + return -1; + + return 0; +} + +/* Check rte_power_freq_down() */ +static int +check_power_freq_down(void) +{ + int ret; + + /* test with an invalid lcore id */ + ret = rte_power_freq_down(TEST_POWER_LCORE_INVALID); + if (ret >= 0) { + printf("Unexpectedly scale down successfully the freq on " + "lcore %u\n", TEST_POWER_LCORE_INVALID); + return -1; + } + + /* Scale down to min and then scale down one step */ + ret = rte_power_freq_min(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale down the freq to min on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + ret = rte_power_freq_down(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale down the freq on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Check the current frequency */ + ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); + if (ret < 0) + return -1; + + /* Scale up to max and then scale down one step */ + ret = rte_power_freq_max(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale up the freq to max on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + ret = rte_power_freq_down(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale down the freq on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Check the current frequency */ + ret = check_cur_freq(TEST_POWER_LCORE_ID, 1); + if (ret < 0) + return -1; + + return 0; +} + +/* Check rte_power_freq_up() */ +static int +check_power_freq_up(void) +{ + int ret; + + /* test with an invalid lcore id */ + ret = rte_power_freq_up(TEST_POWER_LCORE_INVALID); + if (ret >= 0) { + printf("Unexpectedly scale up successfully the freq on %u\n", + TEST_POWER_LCORE_INVALID); + return -1; + } + + /* Scale down to min and then scale up one step */ + ret = rte_power_freq_min(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale down the freq to min on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + ret = rte_power_freq_up(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale up the freq on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Check the current frequency */ + ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2); + if (ret < 0) + return -1; + + /* Scale up to max and then scale up one step */ + ret = rte_power_freq_max(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale up the freq to max on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + ret = rte_power_freq_up(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale up the freq on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Check the current frequency */ + ret = check_cur_freq(TEST_POWER_LCORE_ID, 0); + if (ret < 0) + return -1; + + return 0; +} + +/* Check rte_power_freq_max() */ +static int +check_power_freq_max(void) +{ + int ret; + + /* test with an invalid lcore id */ + ret = rte_power_freq_max(TEST_POWER_LCORE_INVALID); + if (ret >= 0) { + printf("Unexpectedly scale up successfully the freq to max on " + "lcore %u\n", TEST_POWER_LCORE_INVALID); + return -1; + } + ret = rte_power_freq_max(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale up the freq to max on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Check the current frequency */ + ret = check_cur_freq(TEST_POWER_LCORE_ID, 0); + if (ret < 0) + return -1; + + return 0; +} + +/* Check rte_power_freq_min() */ +static int +check_power_freq_min(void) +{ + int ret; + + /* test with an invalid lcore id */ + ret = rte_power_freq_min(TEST_POWER_LCORE_INVALID); + if (ret >= 0) { + printf("Unexpectedly scale down successfully the freq to min " + "on lcore %u\n", TEST_POWER_LCORE_INVALID); + return -1; + } + ret = rte_power_freq_min(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Fail to scale down the freq to min on lcore %u\n", + TEST_POWER_LCORE_ID); + return -1; + } + + /* Check the current frequency */ + ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); + if (ret < 0) + return -1; + + return 0; +} + +static int +test_power_acpi_cpufreq(void) +{ + int ret = -1; + enum power_management_env env; + + ret = rte_power_set_env(PM_ENV_ACPI_CPUFREQ); + if (ret != 0) { + printf("Failed on setting environment to PM_ENV_ACPI_CPUFREQ, this " + "may occur if environment is not configured correctly or " + " operating in another valid Power management environment\n"); + return -1; + } + + /* Test environment configuration */ + env = rte_power_get_env(); + if (env != PM_ENV_ACPI_CPUFREQ) { + printf("Unexpectedly got an environment other than ACPI cpufreq\n"); + goto fail_all; + } + + /* verify that function pointers are not NULL */ + if (rte_power_freqs == NULL) { + printf("rte_power_freqs should not be NULL, environment has not been " + "initialised\n"); + goto fail_all; + } + if (rte_power_get_freq == NULL) { + printf("rte_power_get_freq should not be NULL, environment has not " + "been initialised\n"); + goto fail_all; + } + if (rte_power_set_freq == NULL) { + printf("rte_power_set_freq should not be NULL, environment has not " + "been initialised\n"); + goto fail_all; + } + if (rte_power_freq_up == NULL) { + printf("rte_power_freq_up should not be NULL, environment has not " + "been initialised\n"); + goto fail_all; + } + if (rte_power_freq_down == NULL) { + printf("rte_power_freq_down should not be NULL, environment has not " + "been initialised\n"); + goto fail_all; + } + if (rte_power_freq_max == NULL) { + printf("rte_power_freq_max should not be NULL, environment has not " + "been initialised\n"); + goto fail_all; + } + if (rte_power_freq_min == NULL) { + printf("rte_power_freq_min should not be NULL, environment has not " + "been initialised\n"); + goto fail_all; + } + + /* test of init power management for an invalid lcore */ + ret = rte_power_init(TEST_POWER_LCORE_INVALID); + if (ret == 0) { + printf("Unexpectedly initialise power management successfully " + "for lcore %u\n", TEST_POWER_LCORE_INVALID); + rte_power_unset_env(); + return -1; + } + + /* Test initialisation of a valid lcore */ + ret = rte_power_init(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Cannot initialise power management for lcore %u, this " + "may occur if environment is not configured " + "correctly(APCI cpufreq) or operating in another valid " + "Power management environment\n", TEST_POWER_LCORE_ID); + rte_power_unset_env(); + return -1; + } + + /** + * test of initialising power management for the lcore which has + * been initialised + */ + ret = rte_power_init(TEST_POWER_LCORE_ID); + if (ret == 0) { + printf("Unexpectedly init successfully power twice on " + "lcore %u\n", TEST_POWER_LCORE_ID); + goto fail_all; + } + + ret = check_power_freqs(); + if (ret < 0) + goto fail_all; + + if (total_freq_num < 2) { + rte_power_exit(TEST_POWER_LCORE_ID); + printf("Frequency can not be changed due to CPU itself\n"); + rte_power_unset_env(); + return 0; + } + + ret = check_power_get_freq(); + if (ret < 0) + goto fail_all; + + ret = check_power_set_freq(); + if (ret < 0) + goto fail_all; + + ret = check_power_freq_down(); + if (ret < 0) + goto fail_all; + + ret = check_power_freq_up(); + if (ret < 0) + goto fail_all; + + ret = check_power_freq_max(); + if (ret < 0) + goto fail_all; + + ret = check_power_freq_min(); + if (ret < 0) + goto fail_all; + + ret = rte_power_exit(TEST_POWER_LCORE_ID); + if (ret < 0) { + printf("Cannot exit power management for lcore %u\n", + TEST_POWER_LCORE_ID); + rte_power_unset_env(); + return -1; + } + + /** + * test of exiting power management for the lcore which has been exited + */ + ret = rte_power_exit(TEST_POWER_LCORE_ID); + if (ret == 0) { + printf("Unexpectedly exit successfully power management twice " + "on lcore %u\n", TEST_POWER_LCORE_ID); + rte_power_unset_env(); + return -1; + } + + /* test of exit power management for an invalid lcore */ + ret = rte_power_exit(TEST_POWER_LCORE_INVALID); + if (ret == 0) { + printf("Unpectedly exit power management successfully for " + "lcore %u\n", TEST_POWER_LCORE_INVALID); + rte_power_unset_env(); + return -1; + } + rte_power_unset_env(); + return 0; + +fail_all: + rte_power_exit(TEST_POWER_LCORE_ID); + rte_power_unset_env(); + return -1; +} + +REGISTER_TEST_COMMAND(power_acpi_cpufreq_autotest, test_power_acpi_cpufreq); diff --git a/test/test/test_power_kvm_vm.c b/test/test/test_power_kvm_vm.c new file mode 100644 index 0000000000..253a5f8b6f --- /dev/null +++ b/test/test/test_power_kvm_vm.c @@ -0,0 +1,303 @@ +/*- + * 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 +#include +#include +#include +#include + +#include "test.h" + +#include + +#define TEST_POWER_VM_LCORE_ID 0U +#define TEST_POWER_VM_LCORE_OUT_OF_BOUNDS (RTE_MAX_LCORE+1) +#define TEST_POWER_VM_LCORE_INVALID 1U + +static int +test_power_kvm_vm(void) +{ + int ret; + enum power_management_env env; + + ret = rte_power_set_env(PM_ENV_KVM_VM); + if (ret != 0) { + printf("Failed on setting environment to PM_ENV_KVM_VM\n"); + return -1; + } + + /* Test environment configuration */ + env = rte_power_get_env(); + if (env != PM_ENV_KVM_VM) { + printf("Unexpectedly got a Power Management environment other than " + "KVM VM\n"); + rte_power_unset_env(); + return -1; + } + + /* verify that function pointers are not NULL */ + if (rte_power_freqs == NULL) { + printf("rte_power_freqs should not be NULL, environment has not been " + "initialised\n"); + return -1; + } + if (rte_power_get_freq == NULL) { + printf("rte_power_get_freq should not be NULL, environment has not " + "been initialised\n"); + return -1; + } + if (rte_power_set_freq == NULL) { + printf("rte_power_set_freq should not be NULL, environment has not " + "been initialised\n"); + return -1; + } + if (rte_power_freq_up == NULL) { + printf("rte_power_freq_up should not be NULL, environment has not " + "been initialised\n"); + return -1; + } + if (rte_power_freq_down == NULL) { + printf("rte_power_freq_down should not be NULL, environment has not " + "been initialised\n"); + return -1; + } + if (rte_power_freq_max == NULL) { + printf("rte_power_freq_max should not be NULL, environment has not " + "been initialised\n"); + return -1; + } + if (rte_power_freq_min == NULL) { + printf("rte_power_freq_min should not be NULL, environment has not " + "been initialised\n"); + return -1; + } + /* Test initialisation of an out of bounds lcore */ + ret = rte_power_init(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + if (ret != -1) { + printf("rte_power_init unexpectedly succeeded on an invalid lcore %u\n", + TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + rte_power_unset_env(); + return -1; + } + + /* Test initialisation of a valid lcore */ + ret = rte_power_init(TEST_POWER_VM_LCORE_ID); + if (ret < 0) { + printf("Cannot initialise power management for lcore %u, this " + "may occur if environment is not configured " + "correctly(KVM VM) or operating in another valid " + "Power management environment\n", TEST_POWER_VM_LCORE_ID); + rte_power_unset_env(); + return -1; + } + + /* Test initialisation of previously initialised lcore */ + ret = rte_power_init(TEST_POWER_VM_LCORE_ID); + if (ret == 0) { + printf("rte_power_init unexpectedly succeeded on calling init twice on" + " lcore %u\n", TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test frequency up of invalid lcore */ + ret = rte_power_freq_up(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + if (ret == 1) { + printf("rte_power_freq_up unexpectedly succeeded on invalid lcore %u\n", + TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + goto fail_all; + } + + /* Test frequency down of invalid lcore */ + ret = rte_power_freq_down(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + if (ret == 1) { + printf("rte_power_freq_down unexpectedly succeeded on invalid lcore " + "%u\n", TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + goto fail_all; + } + + /* Test frequency min of invalid lcore */ + ret = rte_power_freq_min(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + if (ret == 1) { + printf("rte_power_freq_min unexpectedly succeeded on invalid lcore " + "%u\n", TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + goto fail_all; + } + + /* Test frequency max of invalid lcore */ + ret = rte_power_freq_max(TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + if (ret == 1) { + printf("rte_power_freq_max unexpectedly succeeded on invalid lcore " + "%u\n", TEST_POWER_VM_LCORE_OUT_OF_BOUNDS); + goto fail_all; + } + + /* Test frequency up of valid but uninitialised lcore */ + ret = rte_power_freq_up(TEST_POWER_VM_LCORE_INVALID); + if (ret == 1) { + printf("rte_power_freq_up unexpectedly succeeded on invalid lcore %u\n", + TEST_POWER_VM_LCORE_INVALID); + goto fail_all; + } + + /* Test frequency down of valid but uninitialised lcore */ + ret = rte_power_freq_down(TEST_POWER_VM_LCORE_INVALID); + if (ret == 1) { + printf("rte_power_freq_down unexpectedly succeeded on invalid lcore " + "%u\n", TEST_POWER_VM_LCORE_INVALID); + goto fail_all; + } + + /* Test frequency min of valid but uninitialised lcore */ + ret = rte_power_freq_min(TEST_POWER_VM_LCORE_INVALID); + if (ret == 1) { + printf("rte_power_freq_min unexpectedly succeeded on invalid lcore " + "%u\n", TEST_POWER_VM_LCORE_INVALID); + goto fail_all; + } + + /* Test frequency max of valid but uninitialised lcore */ + ret = rte_power_freq_max(TEST_POWER_VM_LCORE_INVALID); + if (ret == 1) { + printf("rte_power_freq_max unexpectedly succeeded on invalid lcore " + "%u\n", TEST_POWER_VM_LCORE_INVALID); + goto fail_all; + } + + /* Test frequency up of valid lcore */ + ret = rte_power_freq_up(TEST_POWER_VM_LCORE_ID); + if (ret != 1) { + printf("rte_power_freq_up unexpectedly failed on valid lcore %u\n", + TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test frequency down of valid lcore */ + ret = rte_power_freq_down(TEST_POWER_VM_LCORE_ID); + if (ret != 1) { + printf("rte_power_freq_down unexpectedly failed on valid lcore " + "%u\n", TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test frequency min of valid lcore */ + ret = rte_power_freq_min(TEST_POWER_VM_LCORE_ID); + if (ret != 1) { + printf("rte_power_freq_min unexpectedly failed on valid lcore " + "%u\n", TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test frequency max of valid lcore */ + ret = rte_power_freq_max(TEST_POWER_VM_LCORE_ID); + if (ret != 1) { + printf("rte_power_freq_max unexpectedly failed on valid lcore " + "%u\n", TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test unsupported rte_power_freqs */ + ret = rte_power_freqs(TEST_POWER_VM_LCORE_ID, NULL, 0); + if (ret != -ENOTSUP) { + printf("rte_power_freqs did not return the expected -ENOTSUP(%d) but " + "returned %d\n", -ENOTSUP, ret); + goto fail_all; + } + + /* Test unsupported rte_power_get_freq */ + ret = rte_power_get_freq(TEST_POWER_VM_LCORE_ID); + if (ret != -ENOTSUP) { + printf("rte_power_get_freq did not return the expected -ENOTSUP(%d) but" + " returned %d for lcore %u\n", + -ENOTSUP, ret, TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test unsupported rte_power_set_freq */ + ret = rte_power_set_freq(TEST_POWER_VM_LCORE_ID, 0); + if (ret != -ENOTSUP) { + printf("rte_power_set_freq did not return the expected -ENOTSUP(%d) but" + " returned %d for lcore %u\n", + -ENOTSUP, ret, TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test removing of an lcore */ + ret = rte_power_exit(TEST_POWER_VM_LCORE_ID); + if (ret != 0) { + printf("rte_power_exit unexpectedly failed on valid lcore %u," + "please ensure that the environment has been configured " + "correctly\n", TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test frequency up of previously removed lcore */ + ret = rte_power_freq_up(TEST_POWER_VM_LCORE_ID); + if (ret == 0) { + printf("rte_power_freq_up unexpectedly succeeded on a removed " + "lcore %u\n", TEST_POWER_VM_LCORE_ID); + return -1; + } + + /* Test frequency down of previously removed lcore */ + ret = rte_power_freq_down(TEST_POWER_VM_LCORE_ID); + if (ret == 0) { + printf("rte_power_freq_down unexpectedly succeeded on a removed " + "lcore %u\n", TEST_POWER_VM_LCORE_ID); + return -1; + } + + /* Test frequency min of previously removed lcore */ + ret = rte_power_freq_min(TEST_POWER_VM_LCORE_ID); + if (ret == 0) { + printf("rte_power_freq_min unexpectedly succeeded on a removed " + "lcore %u\n", TEST_POWER_VM_LCORE_ID); + return -1; + } + + /* Test frequency max of previously removed lcore */ + ret = rte_power_freq_max(TEST_POWER_VM_LCORE_ID); + if (ret == 0) { + printf("rte_power_freq_max unexpectedly succeeded on a removed " + "lcore %u\n", TEST_POWER_VM_LCORE_ID); + return -1; + } + rte_power_unset_env(); + return 0; +fail_all: + rte_power_exit(TEST_POWER_VM_LCORE_ID); + rte_power_unset_env(); + return -1; +} + +REGISTER_TEST_COMMAND(power_kvm_vm_autotest, test_power_kvm_vm); diff --git a/test/test/test_prefetch.c b/test/test/test_prefetch.c new file mode 100644 index 0000000000..80afaaf345 --- /dev/null +++ b/test/test/test_prefetch.c @@ -0,0 +1,61 @@ +/*- + * 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 +#include + +#include + +#include "test.h" + +/* + * Prefetch test + * ============= + * + * - Just test that the macro can be called and validate the compilation. + * The test always return success. + */ + +static int +test_prefetch(void) +{ + int a; + + rte_prefetch0(&a); + rte_prefetch1(&a); + rte_prefetch2(&a); + + return 0; +} + +REGISTER_TEST_COMMAND(prefetch_autotest, test_prefetch); diff --git a/test/test/test_red.c b/test/test/test_red.c new file mode 100644 index 0000000000..348075dc39 --- /dev/null +++ b/test/test/test_red.c @@ -0,0 +1,1885 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#include + +#ifdef __INTEL_COMPILER +#pragma warning(disable:2259) /* conversion may lose significant bits */ +#pragma warning(disable:181) /* Arg incompatible with format string */ +#endif + +#define TEST_HZ_PER_KHZ 1000 +#define TEST_NSEC_MARGIN 500 /**< nanosecond margin when calculating clk freq */ + +#define MAX_QEMPTY_TIME_MSEC 50000 +#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 */ + struct rte_red_config *rconfig; /**< RTE_RED configuration parameters */ + uint8_t num_cfg; /**< Number of RTE_RED configs to test */ + uint8_t *wq_log2; /**< Test wq_log2 value to use */ + uint32_t min_th; /**< Queue minimum threshold */ + uint32_t max_th; /**< Queue maximum threshold */ + uint8_t *maxp_inv; /**< Inverse mark probability */ +}; + +struct test_queue { /**< Test structure for RTE_RED Queues */ + struct rte_red *rdata; /**< RTE_RED runtime data */ + uint32_t num_queues; /**< Number of RTE_RED queues to test */ + uint32_t *qconfig; /**< Configuration of RTE_RED queues for test */ + uint32_t *q; /**< Queue size */ + uint32_t q_ramp_up; /**< Num of enqueues to ramp up the queue */ + uint32_t avg_ramp_up; /**< Average num of enqueues to ramp up the queue */ + uint32_t avg_tolerance; /**< Tolerance in queue average */ + double drop_tolerance; /**< Drop tolerance of packets not enqueued */ +}; + +struct test_var { /**< Test variables used for testing RTE_RED */ + uint32_t wait_usec; /**< Micro second wait interval */ + uint32_t num_iterations; /**< Number of test iterations */ + uint32_t num_ops; /**< Number of test operations */ + uint64_t clk_freq; /**< CPU clock frequency */ + uint32_t sleep_sec; /**< Seconds to sleep */ + uint32_t *dropped; /**< Test operations dropped */ + uint32_t *enqueued; /**< Test operations enqueued */ +}; + +struct test_config { /**< Master test structure for RTE_RED */ + const char *ifname; /**< Interface name */ + const char *msg; /**< Test message for display */ + const char *htxt; /**< Header txt display for result output */ + struct test_rte_red_config *tconfig; /**< Test structure for RTE_RED config */ + struct test_queue *tqueue; /**< Test structure for RTE_RED Queues */ + struct test_var *tvar; /**< Test variables used for testing RTE_RED */ + uint32_t *tlevel; /**< Queue levels */ +}; + +enum test_result { + FAIL = 0, + PASS +}; + +/**< Test structure to define tests to run */ +struct tests { + struct test_config *testcfg; + enum test_result (*testfn)(struct test_config *); +}; + +struct rdtsc_prof { + uint64_t clk_start; + uint64_t clk_min; /**< min clocks */ + uint64_t clk_max; /**< max clocks */ + uint64_t clk_avgc; /**< count to calc average */ + double clk_avg; /**< cumulative sum to calc average */ + const char *name; +}; + +static const uint64_t port_speed_bytes = (10ULL*1000ULL*1000ULL*1000ULL)/8ULL; +static double inv_cycles_per_byte = 0; +static double pkt_time_usec = 0; + +static void init_port_ts(uint64_t cpu_clock) +{ + double cycles_per_byte = (double)(cpu_clock) / (double)(port_speed_bytes); + inv_cycles_per_byte = 1.0 / cycles_per_byte; + pkt_time_usec = 1000000.0 / ((double)port_speed_bytes / (double)RTE_RED_S); +} + +static uint64_t get_port_ts(void) +{ + return (uint64_t)((double)rte_rdtsc() * inv_cycles_per_byte); +} + +static void rdtsc_prof_init(struct rdtsc_prof *p, const char *name) +{ + p->clk_min = (uint64_t)(-1LL); + p->clk_max = 0; + p->clk_avg = 0; + p->clk_avgc = 0; + p->name = name; +} + +static inline void rdtsc_prof_start(struct rdtsc_prof *p) +{ + p->clk_start = rte_rdtsc_precise(); +} + +static inline void rdtsc_prof_end(struct rdtsc_prof *p) +{ + uint64_t clk_start = rte_rdtsc() - p->clk_start; + + p->clk_avgc++; + p->clk_avg += (double) clk_start; + + if (clk_start > p->clk_max) + p->clk_max = clk_start; + if (clk_start < p->clk_min) + p->clk_min = clk_start; +} + +static void rdtsc_prof_print(struct rdtsc_prof *p) +{ + if (p->clk_avgc>0) { + printf("RDTSC stats for %s: n=%" PRIu64 ", min=%" PRIu64 ", max=%" PRIu64 ", avg=%.1f\n", + p->name, + p->clk_avgc, + p->clk_min, + p->clk_max, + (p->clk_avg / ((double) p->clk_avgc))); + } +} + +static uint32_t rte_red_get_avg_int(const struct rte_red_config *red_cfg, + struct rte_red *red) +{ + /** + * scale by 1/n and convert from fixed-point to integer + */ + return red->avg >> (RTE_RED_SCALING + red_cfg->wq_log2); +} + +static double rte_red_get_avg_float(const struct rte_red_config *red_cfg, + struct rte_red *red) +{ + /** + * scale by 1/n and convert from fixed-point to floating-point + */ + return ldexp((double)red->avg, -(RTE_RED_SCALING + red_cfg->wq_log2)); +} + +static void rte_red_set_avg_int(const struct rte_red_config *red_cfg, + struct rte_red *red, + uint32_t avg) +{ + /** + * scale by n and convert from integer to fixed-point + */ + red->avg = avg << (RTE_RED_SCALING + red_cfg->wq_log2); +} + +static double calc_exp_avg_on_empty(double avg, uint32_t n, uint32_t time_diff) +{ + return avg * pow((1.0 - 1.0 / (double)n), (double)time_diff / pkt_time_usec); +} + +static double calc_drop_rate(uint32_t enqueued, uint32_t dropped) +{ + return (double)dropped / ((double)enqueued + (double)dropped); +} + +/** + * calculate the drop probability + */ +static double calc_drop_prob(uint32_t min_th, uint32_t max_th, + uint32_t maxp_inv, uint32_t avg) +{ + double drop_prob = 0.0; + + if (avg < min_th) { + drop_prob = 0.0; + } else if (avg < max_th) { + drop_prob = (1.0 / (double)maxp_inv) + * ((double)(avg - min_th) + / (double)(max_th - min_th)); + } else { + drop_prob = 1.0; + } + return drop_prob; +} + +/** + * check if drop rate matches drop probability within tolerance + */ +static int check_drop_rate(double *diff, double drop_rate, double drop_prob, double tolerance) +{ + double abs_diff = 0.0; + int ret = 1; + + abs_diff = fabs(drop_rate - drop_prob); + if ((int)abs_diff == 0) { + *diff = 0.0; + } else { + *diff = (abs_diff / drop_prob) * 100.0; + if (*diff > tolerance) { + ret = 0; + } + } + return ret; +} + +/** + * check if average queue size is within tolerance + */ +static int check_avg(double *diff, double avg, double exp_avg, double tolerance) +{ + double abs_diff = 0.0; + int ret = 1; + + abs_diff = fabs(avg - exp_avg); + if ((int)abs_diff == 0) { + *diff = 0.0; + } else { + *diff = (abs_diff / exp_avg) * 100.0; + if (*diff > tolerance) { + ret = 0; + } + } + return ret; +} + +/** + * initialize the test rte_red config + */ +static enum test_result +test_rte_red_init(struct test_config *tcfg) +{ + unsigned i = 0; + + tcfg->tvar->clk_freq = rte_get_timer_hz(); + init_port_ts( tcfg->tvar->clk_freq ); + + for (i = 0; i < tcfg->tconfig->num_cfg; i++) { + if (rte_red_config_init(&tcfg->tconfig->rconfig[i], + (uint16_t)tcfg->tconfig->wq_log2[i], + (uint16_t)tcfg->tconfig->min_th, + (uint16_t)tcfg->tconfig->max_th, + (uint16_t)tcfg->tconfig->maxp_inv[i]) != 0) { + return FAIL; + } + } + + *tcfg->tqueue->q = 0; + *tcfg->tvar->dropped = 0; + *tcfg->tvar->enqueued = 0; + return PASS; +} + +/** + * enqueue until actual queue size reaches target level + */ +static int +increase_actual_qsize(struct rte_red_config *red_cfg, + struct rte_red *red, + uint32_t *q, + uint32_t level, + uint32_t attempts) +{ + uint32_t i = 0; + + for (i = 0; i < attempts; i++) { + int ret = 0; + + /** + * enqueue + */ + ret = rte_red_enqueue(red_cfg, red, *q, get_port_ts() ); + if (ret == 0) { + if (++(*q) >= level) + break; + } + } + /** + * check if target actual queue size has been reached + */ + if (*q != level) + return -1; + /** + * success + */ + return 0; +} + +/** + * enqueue until average queue size reaches target level + */ +static int +increase_average_qsize(struct rte_red_config *red_cfg, + struct rte_red *red, + uint32_t *q, + uint32_t level, + uint32_t num_ops) +{ + uint32_t avg = 0; + uint32_t i = 0; + + for (i = 0; i < num_ops; i++) { + /** + * enqueue + */ + rte_red_enqueue(red_cfg, red, *q, get_port_ts()); + } + /** + * check if target average queue size has been reached + */ + avg = rte_red_get_avg_int(red_cfg, red); + if (avg != level) + return -1; + /** + * success + */ + return 0; +} + +/** + * setup default values for the functional test structures + */ +static struct rte_red_config ft_wrconfig[1]; +static struct rte_red ft_rtdata[1]; +static uint8_t ft_wq_log2[] = {9}; +static uint8_t ft_maxp_inv[] = {10}; +static uint32_t ft_qconfig[] = {0, 0, 1, 1}; +static uint32_t ft_q[] ={0}; +static uint32_t ft_dropped[] ={0}; +static uint32_t ft_enqueued[] ={0}; + +static struct test_rte_red_config ft_tconfig = { + .rconfig = ft_wrconfig, + .num_cfg = RTE_DIM(ft_wrconfig), + .wq_log2 = ft_wq_log2, + .min_th = 32, + .max_th = 128, + .maxp_inv = ft_maxp_inv, +}; + +static struct test_queue ft_tqueue = { + .rdata = ft_rtdata, + .num_queues = RTE_DIM(ft_rtdata), + .qconfig = ft_qconfig, + .q = ft_q, + .q_ramp_up = 1000000, + .avg_ramp_up = 1000000, + .avg_tolerance = 5, /* 5 percent */ + .drop_tolerance = 50, /* 50 percent */ +}; + +static struct test_var ft_tvar = { + .wait_usec = 10000, + .num_iterations = 5, + .num_ops = 10000, + .clk_freq = 0, + .dropped = ft_dropped, + .enqueued = ft_enqueued, + .sleep_sec = (MAX_QEMPTY_TIME_MSEC / MSEC_PER_SEC) + 2, +}; + +/** + * functional test enqueue/dequeue packets + */ +static void enqueue_dequeue_func(struct rte_red_config *red_cfg, + struct rte_red *red, + uint32_t *q, + uint32_t num_ops, + uint32_t *enqueued, + uint32_t *dropped) +{ + uint32_t i = 0; + + for (i = 0; i < num_ops; i++) { + int ret = 0; + + /** + * enqueue + */ + ret = rte_red_enqueue(red_cfg, red, *q, get_port_ts()); + if (ret == 0) + (*enqueued)++; + else + (*dropped)++; + } +} + +/** + * Test F1: functional test 1 + */ +static uint32_t ft1_tlevels[] = {6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 126, 132, 138, 144}; + +static struct test_config func_test1_config = { + .ifname = "functional test 1 interface", + .msg = "functional test 1 : use one rte_red configuration,\n" + " increase average queue size to various levels,\n" + " compare drop rate to drop probability\n\n", + .htxt = " " + "avg queue size " + "enqueued " + "dropped " + "drop prob % " + "drop rate % " + "diff % " + "tolerance % " + "\n", + .tconfig = &ft_tconfig, + .tqueue = &ft_tqueue, + .tvar = &ft_tvar, + .tlevel = ft1_tlevels, +}; + +static enum test_result func_test1(struct test_config *tcfg) +{ + enum test_result result = PASS; + uint32_t i = 0; + + printf("%s", tcfg->msg); + + if (test_rte_red_init(tcfg) != PASS) { + result = FAIL; + goto out; + } + + printf("%s", tcfg->htxt); + + for (i = 0; i < RTE_DIM(ft1_tlevels); i++) { + const char *label = NULL; + uint32_t avg = 0; + double drop_rate = 0.0; + double drop_prob = 0.0; + double diff = 0.0; + + /** + * reset rte_red run-time data + */ + rte_red_rt_data_init(tcfg->tqueue->rdata); + *tcfg->tvar->enqueued = 0; + *tcfg->tvar->dropped = 0; + + if (increase_actual_qsize(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + tcfg->tlevel[i], + tcfg->tqueue->q_ramp_up) != 0) { + result = FAIL; + goto out; + } + + if (increase_average_qsize(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + tcfg->tlevel[i], + tcfg->tqueue->avg_ramp_up) != 0) { + result = FAIL; + goto out; + } + + enqueue_dequeue_func(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + tcfg->tvar->num_ops, + tcfg->tvar->enqueued, + tcfg->tvar->dropped); + + avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); + if (avg != tcfg->tlevel[i]) { + fprintf(stderr, "Fail: avg != level\n"); + result = FAIL; + } + + drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped); + drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th, + *tcfg->tconfig->maxp_inv, tcfg->tlevel[i]); + if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance)) + result = FAIL; + + if (tcfg->tlevel[i] == tcfg->tconfig->min_th) + label = "min thresh: "; + else if (tcfg->tlevel[i] == tcfg->tconfig->max_th) + label = "max thresh: "; + else + label = " "; + printf("%s%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n", + label, avg, *tcfg->tvar->enqueued, *tcfg->tvar->dropped, + drop_prob * 100.0, drop_rate * 100.0, diff, + (double)tcfg->tqueue->drop_tolerance); + } +out: + return result; +} + +/** + * Test F2: functional test 2 + */ +static uint32_t ft2_tlevel[] = {127}; +static uint8_t ft2_wq_log2[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9}; +static uint8_t ft2_maxp_inv[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; +static struct rte_red_config ft2_rconfig[10]; + +static struct test_rte_red_config ft2_tconfig = { + .rconfig = ft2_rconfig, + .num_cfg = RTE_DIM(ft2_rconfig), + .wq_log2 = ft2_wq_log2, + .min_th = 32, + .max_th = 128, + .maxp_inv = ft2_maxp_inv, +}; + +static struct test_config func_test2_config = { + .ifname = "functional test 2 interface", + .msg = "functional test 2 : use several RED configurations,\n" + " increase average queue size to just below maximum threshold,\n" + " compare drop rate to drop probability\n\n", + .htxt = "RED config " + "avg queue size " + "min threshold " + "max threshold " + "drop prob % " + "drop rate % " + "diff % " + "tolerance % " + "\n", + .tconfig = &ft2_tconfig, + .tqueue = &ft_tqueue, + .tvar = &ft_tvar, + .tlevel = ft2_tlevel, +}; + +static enum test_result func_test2(struct test_config *tcfg) +{ + enum test_result result = PASS; + double prev_drop_rate = 1.0; + uint32_t i = 0; + + printf("%s", tcfg->msg); + + if (test_rte_red_init(tcfg) != PASS) { + result = FAIL; + goto out; + } + rte_red_rt_data_init(tcfg->tqueue->rdata); + + if (increase_actual_qsize(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + *tcfg->tlevel, + tcfg->tqueue->q_ramp_up) != 0) { + result = FAIL; + goto out; + } + + if (increase_average_qsize(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + *tcfg->tlevel, + tcfg->tqueue->avg_ramp_up) != 0) { + result = FAIL; + goto out; + } + printf("%s", tcfg->htxt); + + for (i = 0; i < tcfg->tconfig->num_cfg; i++) { + uint32_t avg = 0; + double drop_rate = 0.0; + double drop_prob = 0.0; + double diff = 0.0; + + *tcfg->tvar->dropped = 0; + *tcfg->tvar->enqueued = 0; + + enqueue_dequeue_func(&tcfg->tconfig->rconfig[i], + tcfg->tqueue->rdata, + tcfg->tqueue->q, + tcfg->tvar->num_ops, + tcfg->tvar->enqueued, + tcfg->tvar->dropped); + + avg = rte_red_get_avg_int(&tcfg->tconfig->rconfig[i], tcfg->tqueue->rdata); + if (avg != *tcfg->tlevel) + result = FAIL; + + drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped); + drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th, + tcfg->tconfig->maxp_inv[i], *tcfg->tlevel); + if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance)) + result = FAIL; + /** + * drop rate should decrease as maxp_inv increases + */ + if (drop_rate > prev_drop_rate) + result = FAIL; + prev_drop_rate = drop_rate; + + printf("%-15u%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n", + i, avg, tcfg->tconfig->min_th, tcfg->tconfig->max_th, + drop_prob * 100.0, drop_rate * 100.0, diff, + (double)tcfg->tqueue->drop_tolerance); + } +out: + return result; +} + +/** + * Test F3: functional test 3 + */ +static uint32_t ft3_tlevel[] = {1022}; + +static struct test_rte_red_config ft3_tconfig = { + .rconfig = ft_wrconfig, + .num_cfg = RTE_DIM(ft_wrconfig), + .wq_log2 = ft_wq_log2, + .min_th = 32, + .max_th = 1023, + .maxp_inv = ft_maxp_inv, +}; + +static struct test_config func_test3_config = { + .ifname = "functional test 3 interface", + .msg = "functional test 3 : use one RED configuration,\n" + " increase average queue size to target level,\n" + " dequeue all packets until queue is empty,\n" + " confirm that average queue size is computed correctly while queue is empty\n\n", + .htxt = "q avg before " + "q avg after " + "expected " + "difference % " + "tolerance % " + "result " + "\n", + .tconfig = &ft3_tconfig, + .tqueue = &ft_tqueue, + .tvar = &ft_tvar, + .tlevel = ft3_tlevel, +}; + +static enum test_result func_test3(struct test_config *tcfg) +{ + enum test_result result = PASS; + uint32_t i = 0; + + printf("%s", tcfg->msg); + + if (test_rte_red_init(tcfg) != PASS) { + result = FAIL; + goto out; + } + + rte_red_rt_data_init(tcfg->tqueue->rdata); + + if (increase_actual_qsize(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + *tcfg->tlevel, + tcfg->tqueue->q_ramp_up) != 0) { + result = FAIL; + goto out; + } + + if (increase_average_qsize(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + *tcfg->tlevel, + tcfg->tqueue->avg_ramp_up) != 0) { + result = FAIL; + goto out; + } + + printf("%s", tcfg->htxt); + + for (i = 0; i < tcfg->tvar->num_iterations; i++) { + double avg_before = 0; + double avg_after = 0; + double exp_avg = 0; + double diff = 0.0; + + avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); + + /** + * empty the queue + */ + *tcfg->tqueue->q = 0; + rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts()); + + rte_delay_us(tcfg->tvar->wait_usec); + + /** + * enqueue one packet to recalculate average queue size + */ + if (rte_red_enqueue(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + *tcfg->tqueue->q, + get_port_ts()) == 0) { + (*tcfg->tqueue->q)++; + } else { + printf("%s:%d: packet enqueued on empty queue was dropped\n", __func__, __LINE__); + result = FAIL; + } + + exp_avg = calc_exp_avg_on_empty(avg_before, + (1 << *tcfg->tconfig->wq_log2), + tcfg->tvar->wait_usec); + avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata); + if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance)) + result = FAIL; + + printf("%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n", + avg_before, avg_after, exp_avg, diff, + (double)tcfg->tqueue->avg_tolerance, + diff <= (double)tcfg->tqueue->avg_tolerance ? "pass" : "fail"); + } +out: + return result; +} + +/** + * Test F4: functional test 4 + */ +static uint32_t ft4_tlevel[] = {1022}; +static uint8_t ft4_wq_log2[] = {11}; + +static struct test_rte_red_config ft4_tconfig = { + .rconfig = ft_wrconfig, + .num_cfg = RTE_DIM(ft_wrconfig), + .min_th = 32, + .max_th = 1023, + .wq_log2 = ft4_wq_log2, + .maxp_inv = ft_maxp_inv, +}; + +static struct test_queue ft4_tqueue = { + .rdata = ft_rtdata, + .num_queues = RTE_DIM(ft_rtdata), + .qconfig = ft_qconfig, + .q = ft_q, + .q_ramp_up = 1000000, + .avg_ramp_up = 1000000, + .avg_tolerance = 0, /* 0 percent */ + .drop_tolerance = 50, /* 50 percent */ +}; + +static struct test_config func_test4_config = { + .ifname = "functional test 4 interface", + .msg = "functional test 4 : use one RED configuration,\n" + " increase average queue size to target level,\n" + " dequeue all packets until queue is empty,\n" + " confirm that average queue size is computed correctly while\n" + " queue is empty for more than 50 sec,\n" + " (this test takes 52 sec to run)\n\n", + .htxt = "q avg before " + "q avg after " + "expected " + "difference % " + "tolerance % " + "result " + "\n", + .tconfig = &ft4_tconfig, + .tqueue = &ft4_tqueue, + .tvar = &ft_tvar, + .tlevel = ft4_tlevel, +}; + +static enum test_result func_test4(struct test_config *tcfg) +{ + enum test_result result = PASS; + uint64_t time_diff = 0; + uint64_t start = 0; + double avg_before = 0.0; + double avg_after = 0.0; + double exp_avg = 0.0; + double diff = 0.0; + + printf("%s", tcfg->msg); + + if (test_rte_red_init(tcfg) != PASS) { + result = FAIL; + goto out; + } + + rte_red_rt_data_init(tcfg->tqueue->rdata); + + if (increase_actual_qsize(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + *tcfg->tlevel, + tcfg->tqueue->q_ramp_up) != 0) { + result = FAIL; + goto out; + } + + if (increase_average_qsize(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + *tcfg->tlevel, + tcfg->tqueue->avg_ramp_up) != 0) { + result = FAIL; + goto out; + } + + printf("%s", tcfg->htxt); + + avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); + + /** + * empty the queue + */ + *tcfg->tqueue->q = 0; + rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts()); + + /** + * record empty time locally + */ + start = rte_rdtsc(); + + sleep(tcfg->tvar->sleep_sec); + + /** + * enqueue one packet to recalculate average queue size + */ + if (rte_red_enqueue(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + *tcfg->tqueue->q, + get_port_ts()) != 0) { + result = FAIL; + goto out; + } + (*tcfg->tqueue->q)++; + + /** + * calculate how long queue has been empty + */ + time_diff = ((rte_rdtsc() - start) / tcfg->tvar->clk_freq) + * MSEC_PER_SEC; + if (time_diff < MAX_QEMPTY_TIME_MSEC) { + /** + * this could happen if sleep was interrupted for some reason + */ + result = FAIL; + goto out; + } + + /** + * confirm that average queue size is now at expected level + */ + exp_avg = 0.0; + avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); + if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance)) + result = FAIL; + + printf("%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n", + avg_before, avg_after, exp_avg, + diff, (double)tcfg->tqueue->avg_tolerance, + diff <= (double)tcfg->tqueue->avg_tolerance ? "pass" : "fail"); +out: + return result; +} + +/** + * Test F5: functional test 5 + */ +static uint32_t ft5_tlevel[] = {127}; +static uint8_t ft5_wq_log2[] = {9, 8}; +static uint8_t ft5_maxp_inv[] = {10, 20}; +static struct rte_red_config ft5_config[2]; +static struct rte_red ft5_data[4]; +static uint32_t ft5_q[4]; +static uint32_t ft5_dropped[] = {0, 0, 0, 0}; +static uint32_t ft5_enqueued[] = {0, 0, 0, 0}; + +static struct test_rte_red_config ft5_tconfig = { + .rconfig = ft5_config, + .num_cfg = RTE_DIM(ft5_config), + .min_th = 32, + .max_th = 128, + .wq_log2 = ft5_wq_log2, + .maxp_inv = ft5_maxp_inv, +}; + +static struct test_queue ft5_tqueue = { + .rdata = ft5_data, + .num_queues = RTE_DIM(ft5_data), + .qconfig = ft_qconfig, + .q = ft5_q, + .q_ramp_up = 1000000, + .avg_ramp_up = 1000000, + .avg_tolerance = 5, /* 10 percent */ + .drop_tolerance = 50, /* 50 percent */ +}; + +struct test_var ft5_tvar = { + .wait_usec = 0, + .num_iterations = 15, + .num_ops = 10000, + .clk_freq = 0, + .dropped = ft5_dropped, + .enqueued = ft5_enqueued, + .sleep_sec = 0, +}; + +static struct test_config func_test5_config = { + .ifname = "functional test 5 interface", + .msg = "functional test 5 : use several queues (each with its own run-time data),\n" + " use several RED configurations (such that each configuration is shared by multiple queues),\n" + " increase average queue size to just below maximum threshold,\n" + " compare drop rate to drop probability,\n" + " (this is a larger scale version of functional test 2)\n\n", + .htxt = "queue " + "config " + "avg queue size " + "min threshold " + "max threshold " + "drop prob % " + "drop rate % " + "diff % " + "tolerance % " + "\n", + .tconfig = &ft5_tconfig, + .tqueue = &ft5_tqueue, + .tvar = &ft5_tvar, + .tlevel = ft5_tlevel, +}; + +static enum test_result func_test5(struct test_config *tcfg) +{ + enum test_result result = PASS; + uint32_t j = 0; + + printf("%s", tcfg->msg); + + if (test_rte_red_init(tcfg) != PASS) { + result = FAIL; + goto out; + } + + printf("%s", tcfg->htxt); + + for (j = 0; j < tcfg->tqueue->num_queues; j++) { + rte_red_rt_data_init(&tcfg->tqueue->rdata[j]); + tcfg->tqueue->q[j] = 0; + + if (increase_actual_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j], + &tcfg->tqueue->q[j], + *tcfg->tlevel, + tcfg->tqueue->q_ramp_up) != 0) { + result = FAIL; + goto out; + } + + if (increase_average_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j], + &tcfg->tqueue->q[j], + *tcfg->tlevel, + tcfg->tqueue->avg_ramp_up) != 0) { + result = FAIL; + goto out; + } + } + + for (j = 0; j < tcfg->tqueue->num_queues; j++) { + uint32_t avg = 0; + double drop_rate = 0.0; + double drop_prob = 0.0; + double diff = 0.0; + + tcfg->tvar->dropped[j] = 0; + tcfg->tvar->enqueued[j] = 0; + + enqueue_dequeue_func(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j], + &tcfg->tqueue->q[j], + tcfg->tvar->num_ops, + &tcfg->tvar->enqueued[j], + &tcfg->tvar->dropped[j]); + + avg = rte_red_get_avg_int(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j]); + if (avg != *tcfg->tlevel) + result = FAIL; + + drop_rate = calc_drop_rate(tcfg->tvar->enqueued[j],tcfg->tvar->dropped[j]); + drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th, + tcfg->tconfig->maxp_inv[tcfg->tqueue->qconfig[j]], + *tcfg->tlevel); + if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance)) + result = FAIL; + + printf("%-15u%-15u%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n", + j, tcfg->tqueue->qconfig[j], avg, + tcfg->tconfig->min_th, tcfg->tconfig->max_th, + drop_prob * 100.0, drop_rate * 100.0, + diff, (double)tcfg->tqueue->drop_tolerance); + } +out: + return result; +} + +/** + * Test F6: functional test 6 + */ +static uint32_t ft6_tlevel[] = {1022}; +static uint8_t ft6_wq_log2[] = {9, 8}; +static uint8_t ft6_maxp_inv[] = {10, 20}; +static struct rte_red_config ft6_config[2]; +static struct rte_red ft6_data[4]; +static uint32_t ft6_q[4]; + +static struct test_rte_red_config ft6_tconfig = { + .rconfig = ft6_config, + .num_cfg = RTE_DIM(ft6_config), + .min_th = 32, + .max_th = 1023, + .wq_log2 = ft6_wq_log2, + .maxp_inv = ft6_maxp_inv, +}; + +static struct test_queue ft6_tqueue = { + .rdata = ft6_data, + .num_queues = RTE_DIM(ft6_data), + .qconfig = ft_qconfig, + .q = ft6_q, + .q_ramp_up = 1000000, + .avg_ramp_up = 1000000, + .avg_tolerance = 5, /* 10 percent */ + .drop_tolerance = 50, /* 50 percent */ +}; + +static struct test_config func_test6_config = { + .ifname = "functional test 6 interface", + .msg = "functional test 6 : use several queues (each with its own run-time data),\n" + " use several RED configurations (such that each configuration is sharte_red by multiple queues),\n" + " increase average queue size to target level,\n" + " dequeue all packets until queue is empty,\n" + " confirm that average queue size is computed correctly while queue is empty\n" + " (this is a larger scale version of functional test 3)\n\n", + .htxt = "queue " + "config " + "q avg before " + "q avg after " + "expected " + "difference % " + "tolerance % " + "result ""\n", + .tconfig = &ft6_tconfig, + .tqueue = &ft6_tqueue, + .tvar = &ft_tvar, + .tlevel = ft6_tlevel, +}; + +static enum test_result func_test6(struct test_config *tcfg) +{ + enum test_result result = PASS; + uint32_t j = 0; + + printf("%s", tcfg->msg); + if (test_rte_red_init(tcfg) != PASS) { + result = FAIL; + goto out; + } + printf("%s", tcfg->htxt); + + for (j = 0; j < tcfg->tqueue->num_queues; j++) { + rte_red_rt_data_init(&tcfg->tqueue->rdata[j]); + tcfg->tqueue->q[j] = 0; + + if (increase_actual_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j], + &tcfg->tqueue->q[j], + *tcfg->tlevel, + tcfg->tqueue->q_ramp_up) != 0) { + result = FAIL; + goto out; + } + if (increase_average_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j], + &tcfg->tqueue->q[j], + *tcfg->tlevel, + tcfg->tqueue->avg_ramp_up) != 0) { + result = FAIL; + goto out; + } + } + for (j = 0; j < tcfg->tqueue->num_queues; j++) { + double avg_before = 0; + double avg_after = 0; + double exp_avg = 0; + double diff = 0.0; + + avg_before = rte_red_get_avg_float(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j]); + + /** + * empty the queue + */ + tcfg->tqueue->q[j] = 0; + rte_red_mark_queue_empty(&tcfg->tqueue->rdata[j], get_port_ts()); + rte_delay_us(tcfg->tvar->wait_usec); + + /** + * enqueue one packet to recalculate average queue size + */ + if (rte_red_enqueue(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j], + tcfg->tqueue->q[j], + get_port_ts()) == 0) { + tcfg->tqueue->q[j]++; + } else { + printf("%s:%d: packet enqueued on empty queue was dropped\n", __func__, __LINE__); + result = FAIL; + } + + exp_avg = calc_exp_avg_on_empty(avg_before, + (1 << tcfg->tconfig->wq_log2[tcfg->tqueue->qconfig[j]]), + tcfg->tvar->wait_usec); + avg_after = rte_red_get_avg_float(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]], + &tcfg->tqueue->rdata[j]); + if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance)) + result = FAIL; + + printf("%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n", + j, tcfg->tqueue->qconfig[j], avg_before, avg_after, + exp_avg, diff, (double)tcfg->tqueue->avg_tolerance, + diff <= tcfg->tqueue->avg_tolerance ? "pass" : "fail"); + } +out: + return result; +} + +/** + * setup default values for the performance test structures + */ +static struct rte_red_config pt_wrconfig[1]; +static struct rte_red pt_rtdata[1]; +static uint8_t pt_wq_log2[] = {9}; +static uint8_t pt_maxp_inv[] = {10}; +static uint32_t pt_qconfig[] = {0}; +static uint32_t pt_q[] = {0}; +static uint32_t pt_dropped[] = {0}; +static uint32_t pt_enqueued[] = {0}; + +static struct test_rte_red_config pt_tconfig = { + .rconfig = pt_wrconfig, + .num_cfg = RTE_DIM(pt_wrconfig), + .wq_log2 = pt_wq_log2, + .min_th = 32, + .max_th = 128, + .maxp_inv = pt_maxp_inv, +}; + +static struct test_queue pt_tqueue = { + .rdata = pt_rtdata, + .num_queues = RTE_DIM(pt_rtdata), + .qconfig = pt_qconfig, + .q = pt_q, + .q_ramp_up = 1000000, + .avg_ramp_up = 1000000, + .avg_tolerance = 5, /* 10 percent */ + .drop_tolerance = 50, /* 50 percent */ +}; + +/** + * enqueue/dequeue packets + */ +static void enqueue_dequeue_perf(struct rte_red_config *red_cfg, + struct rte_red *red, + uint32_t *q, + uint32_t num_ops, + uint32_t *enqueued, + uint32_t *dropped, + struct rdtsc_prof *prof) +{ + uint32_t i = 0; + + for (i = 0; i < num_ops; i++) { + uint64_t ts = 0; + int ret = 0; + /** + * enqueue + */ + ts = get_port_ts(); + rdtsc_prof_start(prof); + ret = rte_red_enqueue(red_cfg, red, *q, ts ); + rdtsc_prof_end(prof); + if (ret == 0) + (*enqueued)++; + else + (*dropped)++; + } +} + +/** + * Setup test structures for tests P1, P2, P3 + * performance tests 1, 2 and 3 + */ +static uint32_t pt1_tlevel[] = {16}; +static uint32_t pt2_tlevel[] = {80}; +static uint32_t pt3_tlevel[] = {144}; + +static struct test_var perf1_tvar = { + .wait_usec = 0, + .num_iterations = 15, + .num_ops = 50000000, + .clk_freq = 0, + .dropped = pt_dropped, + .enqueued = pt_enqueued, + .sleep_sec = 0 +}; + +static struct test_config perf1_test1_config = { + .ifname = "performance test 1 interface", + .msg = "performance test 1 : use one RED configuration,\n" + " set actual and average queue sizes to level below min threshold,\n" + " measure enqueue performance\n\n", + .tconfig = &pt_tconfig, + .tqueue = &pt_tqueue, + .tvar = &perf1_tvar, + .tlevel = pt1_tlevel, +}; + +static struct test_config perf1_test2_config = { + .ifname = "performance test 2 interface", + .msg = "performance test 2 : use one RED configuration,\n" + " set actual and average queue sizes to level in between min and max thresholds,\n" + " measure enqueue performance\n\n", + .tconfig = &pt_tconfig, + .tqueue = &pt_tqueue, + .tvar = &perf1_tvar, + .tlevel = pt2_tlevel, +}; + +static struct test_config perf1_test3_config = { + .ifname = "performance test 3 interface", + .msg = "performance test 3 : use one RED configuration,\n" + " set actual and average queue sizes to level above max threshold,\n" + " measure enqueue performance\n\n", + .tconfig = &pt_tconfig, + .tqueue = &pt_tqueue, + .tvar = &perf1_tvar, + .tlevel = pt3_tlevel, +}; + +/** + * Performance test function to measure enqueue performance. + * This runs performance tests 1, 2 and 3 + */ +static enum test_result perf1_test(struct test_config *tcfg) +{ + enum test_result result = PASS; + struct rdtsc_prof prof = {0, 0, 0, 0, 0.0, NULL}; + uint32_t total = 0; + + printf("%s", tcfg->msg); + + rdtsc_prof_init(&prof, "enqueue"); + + if (test_rte_red_init(tcfg) != PASS) { + result = FAIL; + goto out; + } + + /** + * set average queue size to target level + */ + *tcfg->tqueue->q = *tcfg->tlevel; + + /** + * initialize the rte_red run time data structure + */ + rte_red_rt_data_init(tcfg->tqueue->rdata); + + /** + * set the queue average + */ + rte_red_set_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, *tcfg->tlevel); + if (rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata) + != *tcfg->tlevel) { + result = FAIL; + goto out; + } + + enqueue_dequeue_perf(tcfg->tconfig->rconfig, + tcfg->tqueue->rdata, + tcfg->tqueue->q, + tcfg->tvar->num_ops, + tcfg->tvar->enqueued, + tcfg->tvar->dropped, + &prof); + + total = *tcfg->tvar->enqueued + *tcfg->tvar->dropped; + + printf("\ntotal: %u, enqueued: %u (%.2lf%%), dropped: %u (%.2lf%%)\n", total, + *tcfg->tvar->enqueued, ((double)(*tcfg->tvar->enqueued) / (double)total) * 100.0, + *tcfg->tvar->dropped, ((double)(*tcfg->tvar->dropped) / (double)total) * 100.0); + + rdtsc_prof_print(&prof); +out: + return result; +} + +/** + * Setup test structures for tests P4, P5, P6 + * performance tests 4, 5 and 6 + */ +static uint32_t pt4_tlevel[] = {16}; +static uint32_t pt5_tlevel[] = {80}; +static uint32_t pt6_tlevel[] = {144}; + +static struct test_var perf2_tvar = { + .wait_usec = 500, + .num_iterations = 10000, + .num_ops = 10000, + .dropped = pt_dropped, + .enqueued = pt_enqueued, + .sleep_sec = 0 +}; + +static struct test_config perf2_test4_config = { + .ifname = "performance test 4 interface", + .msg = "performance test 4 : use one RED configuration,\n" + " set actual and average queue sizes to level below min threshold,\n" + " dequeue all packets until queue is empty,\n" + " measure enqueue performance when queue is empty\n\n", + .htxt = "iteration " + "q avg before " + "q avg after " + "expected " + "difference % " + "tolerance % " + "result ""\n", + .tconfig = &pt_tconfig, + .tqueue = &pt_tqueue, + .tvar = &perf2_tvar, + .tlevel = pt4_tlevel, +}; + +static struct test_config perf2_test5_config = { + .ifname = "performance test 5 interface", + .msg = "performance test 5 : use one RED configuration,\n" + " set actual and average queue sizes to level in between min and max thresholds,\n" + " dequeue all packets until queue is empty,\n" + " measure enqueue performance when queue is empty\n\n", + .htxt = "iteration " + "q avg before " + "q avg after " + "expected " + "difference " + "tolerance " + "result ""\n", + .tconfig = &pt_tconfig, + .tqueue = &pt_tqueue, + .tvar = &perf2_tvar, + .tlevel = pt5_tlevel, +}; + +static struct test_config perf2_test6_config = { + .ifname = "performance test 6 interface", + .msg = "performance test 6 : use one RED configuration,\n" + " set actual and average queue sizes to level above max threshold,\n" + " dequeue all packets until queue is empty,\n" + " measure enqueue performance when queue is empty\n\n", + .htxt = "iteration " + "q avg before " + "q avg after " + "expected " + "difference % " + "tolerance % " + "result ""\n", + .tconfig = &pt_tconfig, + .tqueue = &pt_tqueue, + .tvar = &perf2_tvar, + .tlevel = pt6_tlevel, +}; + +/** + * Performance test function to measure enqueue performance when the + * queue is empty. This runs performance tests 4, 5 and 6 + */ +static enum test_result perf2_test(struct test_config *tcfg) +{ + enum test_result result = PASS; + struct rdtsc_prof prof = {0, 0, 0, 0, 0.0, NULL}; + uint32_t total = 0; + uint32_t i = 0; + + printf("%s", tcfg->msg); + + rdtsc_prof_init(&prof, "enqueue"); + + if (test_rte_red_init(tcfg) != PASS) { + result = FAIL; + goto out; + } + + printf("%s", tcfg->htxt); + + for (i = 0; i < tcfg->tvar->num_iterations; i++) { + uint32_t count = 0; + uint64_t ts = 0; + double avg_before = 0; + int ret = 0; + + /** + * set average queue size to target level + */ + *tcfg->tqueue->q = *tcfg->tlevel; + count = (*tcfg->tqueue->rdata).count; + + /** + * initialize the rte_red run time data structure + */ + rte_red_rt_data_init(tcfg->tqueue->rdata); + (*tcfg->tqueue->rdata).count = count; + + /** + * set the queue average + */ + rte_red_set_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, *tcfg->tlevel); + avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); + if ((avg_before < *tcfg->tlevel) || (avg_before > *tcfg->tlevel)) { + result = FAIL; + goto out; + } + + /** + * empty the queue + */ + *tcfg->tqueue->q = 0; + rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts()); + + /** + * wait for specified period of time + */ + rte_delay_us(tcfg->tvar->wait_usec); + + /** + * measure performance of enqueue operation while queue is empty + */ + ts = get_port_ts(); + rdtsc_prof_start(&prof); + ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, + *tcfg->tqueue->q, ts ); + rdtsc_prof_end(&prof); + + /** + * gather enqueued/dropped statistics + */ + if (ret == 0) + (*tcfg->tvar->enqueued)++; + else + (*tcfg->tvar->dropped)++; + + /** + * on first and last iteration, confirm that + * average queue size was computed correctly + */ + if ((i == 0) || (i == tcfg->tvar->num_iterations - 1)) { + double avg_after = 0; + double exp_avg = 0; + double diff = 0.0; + int ok = 0; + + avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); + exp_avg = calc_exp_avg_on_empty(avg_before, + (1 << *tcfg->tconfig->wq_log2), + tcfg->tvar->wait_usec); + if (check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance)) + ok = 1; + printf("%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n", + i, avg_before, avg_after, exp_avg, diff, + (double)tcfg->tqueue->avg_tolerance, ok ? "pass" : "fail"); + if (!ok) { + result = FAIL; + goto out; + } + } + } + total = *tcfg->tvar->enqueued + *tcfg->tvar->dropped; + printf("\ntotal: %u, enqueued: %u (%.2lf%%), dropped: %u (%.2lf%%)\n", total, + *tcfg->tvar->enqueued, ((double)(*tcfg->tvar->enqueued) / (double)total) * 100.0, + *tcfg->tvar->dropped, ((double)(*tcfg->tvar->dropped) / (double)total) * 100.0); + + rdtsc_prof_print(&prof); +out: + return result; +} + +/** + * setup default values for overflow test structures + */ +static uint32_t avg_max = 0; +static uint32_t avg_max_bits = 0; + +static struct rte_red_config ovfl_wrconfig[1]; +static struct rte_red ovfl_rtdata[1]; +static uint8_t ovfl_maxp_inv[] = {10}; +static uint32_t ovfl_qconfig[] = {0, 0, 1, 1}; +static uint32_t ovfl_q[] ={0}; +static uint32_t ovfl_dropped[] ={0}; +static uint32_t ovfl_enqueued[] ={0}; +static uint32_t ovfl_tlevel[] = {1023}; +static uint8_t ovfl_wq_log2[] = {12}; + +static struct test_rte_red_config ovfl_tconfig = { + .rconfig = ovfl_wrconfig, + .num_cfg = RTE_DIM(ovfl_wrconfig), + .wq_log2 = ovfl_wq_log2, + .min_th = 32, + .max_th = 1023, + .maxp_inv = ovfl_maxp_inv, +}; + +static struct test_queue ovfl_tqueue = { + .rdata = ovfl_rtdata, + .num_queues = RTE_DIM(ovfl_rtdata), + .qconfig = ovfl_qconfig, + .q = ovfl_q, + .q_ramp_up = 1000000, + .avg_ramp_up = 1000000, + .avg_tolerance = 5, /* 10 percent */ + .drop_tolerance = 50, /* 50 percent */ +}; + +static struct test_var ovfl_tvar = { + .wait_usec = 10000, + .num_iterations = 1, + .num_ops = 10000, + .clk_freq = 0, + .dropped = ovfl_dropped, + .enqueued = ovfl_enqueued, + .sleep_sec = 0 +}; + +static void ovfl_check_avg(uint32_t avg) +{ + if (avg > avg_max) { + double avg_log = 0; + uint32_t bits = 0; + avg_max = avg; + avg_log = log(((double)avg_max)); + avg_log = avg_log / log(2.0); + bits = (uint32_t)ceil(avg_log); + if (bits > avg_max_bits) + avg_max_bits = bits; + } +} + +static struct test_config ovfl_test1_config = { + .ifname = "queue avergage overflow test interface", + .msg = "overflow test 1 : use one RED configuration,\n" + " increase average queue size to target level,\n" + " check maximum number of bits requirte_red to represent avg_s\n\n", + .htxt = "avg queue size " + "wq_log2 " + "fraction bits " + "max queue avg " + "num bits " + "enqueued " + "dropped " + "drop prob % " + "drop rate % " + "\n", + .tconfig = &ovfl_tconfig, + .tqueue = &ovfl_tqueue, + .tvar = &ovfl_tvar, + .tlevel = ovfl_tlevel, +}; + +static enum test_result ovfl_test1(struct test_config *tcfg) +{ + enum test_result result = PASS; + uint32_t avg = 0; + uint32_t i = 0; + double drop_rate = 0.0; + double drop_prob = 0.0; + double diff = 0.0; + int ret = 0; + + printf("%s", tcfg->msg); + + if (test_rte_red_init(tcfg) != PASS) { + + result = FAIL; + goto out; + } + + /** + * reset rte_red run-time data + */ + rte_red_rt_data_init(tcfg->tqueue->rdata); + + /** + * increase actual queue size + */ + for (i = 0; i < tcfg->tqueue->q_ramp_up; i++) { + ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, + *tcfg->tqueue->q, get_port_ts()); + + if (ret == 0) { + if (++(*tcfg->tqueue->q) >= *tcfg->tlevel) + break; + } + } + + /** + * enqueue + */ + for (i = 0; i < tcfg->tqueue->avg_ramp_up; i++) { + ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, + *tcfg->tqueue->q, get_port_ts()); + ovfl_check_avg((*tcfg->tqueue->rdata).avg); + avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); + if (avg == *tcfg->tlevel) { + if (ret == 0) + (*tcfg->tvar->enqueued)++; + else + (*tcfg->tvar->dropped)++; + } + } + + /** + * check if target average queue size has been reached + */ + avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata); + if (avg != *tcfg->tlevel) { + result = FAIL; + goto out; + } + + /** + * check drop rate against drop probability + */ + drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped); + drop_prob = calc_drop_prob(tcfg->tconfig->min_th, + tcfg->tconfig->max_th, + *tcfg->tconfig->maxp_inv, + *tcfg->tlevel); + if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance)) + result = FAIL; + + printf("%s", tcfg->htxt); + + printf("%-16u%-9u%-15u0x%08x %-10u%-10u%-10u%-13.2lf%-13.2lf\n", + avg, *tcfg->tconfig->wq_log2, RTE_RED_SCALING, + avg_max, avg_max_bits, + *tcfg->tvar->enqueued, *tcfg->tvar->dropped, + drop_prob * 100.0, drop_rate * 100.0); +out: + return result; +} + +/** + * define the functional and performance tests to be executed + */ +struct tests func_tests[] = { + { &func_test1_config, func_test1 }, + { &func_test2_config, func_test2 }, + { &func_test3_config, func_test3 }, + { &func_test4_config, func_test4 }, + { &func_test5_config, func_test5 }, + { &func_test6_config, func_test6 }, + { &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 }, + { &perf1_test3_config, perf1_test }, + { &perf2_test4_config, perf2_test }, + { &perf2_test5_config, perf2_test }, + { &perf2_test6_config, perf2_test }, +}; + +/** + * function to execute the required_red tests + */ +static void run_tests(struct tests *test_type, uint32_t test_count, uint32_t *num_tests, uint32_t *num_pass) +{ + enum test_result result = PASS; + uint32_t i = 0; + + for (i = 0; i < test_count; i++) { + printf("\n--------------------------------------------------------------------------------\n"); + result = test_type[i].testfn(test_type[i].testcfg); + (*num_tests)++; + if (result == PASS) { + (*num_pass)++; + printf("--------------------------------------------------------------------------\n"); + } else { + printf("--------------------------------------------------------------------------\n"); + } + } + return; +} + +/** + * check if functions accept invalid parameters + * + * First, all functions will be called without initialized RED + * Then, all of them will be called with NULL/invalid parameters + * + * Some functions are not tested as they are performance-critical and thus + * don't do any parameter checking. + */ +static int +test_invalid_parameters(void) +{ + struct rte_red_config config; + + if (rte_red_rt_data_init(NULL) == 0) { + printf("rte_red_rt_data_init should have failed!\n"); + return -1; + } + + if (rte_red_config_init(NULL, 0, 0, 0, 0) == 0) { + printf("rte_red_config_init should have failed!\n"); + return -1; + } + + if (rte_red_rt_data_init(NULL) == 0) { + printf("rte_red_rt_data_init should have failed!\n"); + return -1; + } + + /* NULL config */ + if (rte_red_config_init(NULL, 0, 0, 0, 0) == 0) { + printf("%i: rte_red_config_init should have failed!\n", __LINE__); + return -1; + } + /* min_treshold == max_treshold */ + if (rte_red_config_init(&config, 0, 1, 1, 0) == 0) { + printf("%i: rte_red_config_init should have failed!\n", __LINE__); + return -1; + } + /* min_treshold > max_treshold */ + if (rte_red_config_init(&config, 0, 2, 1, 0) == 0) { + printf("%i: rte_red_config_init should have failed!\n", __LINE__); + return -1; + } + /* wq_log2 > RTE_RED_WQ_LOG2_MAX */ + if (rte_red_config_init(&config, + RTE_RED_WQ_LOG2_MAX + 1, 1, 2, 0) == 0) { + printf("%i: rte_red_config_init should have failed!\n", __LINE__); + return -1; + } + /* wq_log2 < RTE_RED_WQ_LOG2_MIN */ + if (rte_red_config_init(&config, + RTE_RED_WQ_LOG2_MIN - 1, 1, 2, 0) == 0) { + printf("%i: rte_red_config_init should have failed!\n", __LINE__); + return -1; + } + /* maxp_inv > RTE_RED_MAXP_INV_MAX */ + if (rte_red_config_init(&config, + RTE_RED_WQ_LOG2_MIN, 1, 2, RTE_RED_MAXP_INV_MAX + 1) == 0) { + printf("%i: rte_red_config_init should have failed!\n", __LINE__); + return -1; + } + /* maxp_inv < RTE_RED_MAXP_INV_MIN */ + if (rte_red_config_init(&config, + RTE_RED_WQ_LOG2_MIN, 1, 2, RTE_RED_MAXP_INV_MIN - 1) == 0) { + printf("%i: rte_red_config_init should have failed!\n", __LINE__); + return -1; + } + + 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; + + 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(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 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); +} + +REGISTER_TEST_COMMAND(red_autotest, test_red); +REGISTER_TEST_COMMAND(red_perf, test_red_perf); +REGISTER_TEST_COMMAND(red_all, test_red_all); diff --git a/test/test/test_reorder.c b/test/test/test_reorder.c new file mode 100644 index 0000000000..e8a0a2f234 --- /dev/null +++ b/test/test/test_reorder.c @@ -0,0 +1,386 @@ +/*- + * 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 "test.h" +#include "stdio.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define BURST 32 +#define REORDER_BUFFER_SIZE 16384 +#define NUM_MBUFS (2*REORDER_BUFFER_SIZE) +#define REORDER_BUFFER_SIZE_INVALID 2049 + +struct reorder_unittest_params { + struct rte_mempool *p; + struct rte_reorder_buffer *b; +}; + +static struct reorder_unittest_params default_params = { + .p = NULL, + .b = NULL +}; + +static struct reorder_unittest_params *test_params = &default_params; + +static int +test_reorder_create(void) +{ + struct rte_reorder_buffer *b = NULL; + + b = rte_reorder_create(NULL, rte_socket_id(), REORDER_BUFFER_SIZE); + TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), + "No error on create() with NULL name"); + + b = rte_reorder_create("PKT", rte_socket_id(), REORDER_BUFFER_SIZE_INVALID); + TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), + "No error on create() with invalid buffer size param."); + + b = rte_reorder_create("PKT_RO1", rte_socket_id(), REORDER_BUFFER_SIZE); + TEST_ASSERT_EQUAL(b, test_params->b, + "New reorder instance created with already existing name"); + + return 0; +} + +static int +test_reorder_init(void) +{ + struct rte_reorder_buffer *b = NULL; + unsigned int size; + /* + * The minimum memory area size that should be passed to library is, + * sizeof(struct rte_reorder_buffer) + (2 * size * sizeof(struct rte_mbuf *)); + * Otherwise error will be thrown + */ + + size = 100; + b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE); + TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), + "No error on init with NULL buffer."); + + b = rte_malloc(NULL, size, 0); + b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE); + TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), + "No error on init with invalid mem zone size."); + rte_free(b); + + size = 262336; + b = rte_malloc(NULL, size, 0); + b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE_INVALID); + TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), + "No error on init with invalid buffer size param."); + + b = rte_reorder_init(b, size, NULL, REORDER_BUFFER_SIZE); + TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), + "No error on init with invalid name."); + rte_free(b); + + return 0; +} + +static int +test_reorder_find_existing(void) +{ + struct rte_reorder_buffer *b = NULL; + + /* Try to find existing reorder buffer instance */ + b = rte_reorder_find_existing("PKT_RO1"); + TEST_ASSERT_EQUAL(b, test_params->b, + "existing reorder buffer instance not found"); + + /* Try to find non existing reorder buffer instance */ + b = rte_reorder_find_existing("ro_find_non_existing"); + TEST_ASSERT((b == NULL) && (rte_errno == ENOENT), + "non existing reorder buffer instance found"); + + return 0; +} + +static int +test_reorder_free(void) +{ + struct rte_reorder_buffer *b1 = NULL, *b2 = NULL; + const char *name = "test_free"; + + b1 = rte_reorder_create(name, rte_socket_id(), 8); + TEST_ASSERT_NOT_NULL(b1, "Failed to create reorder buffer."); + + b2 = rte_reorder_find_existing(name); + TEST_ASSERT_EQUAL(b1, b2, "Failed to find existing reorder buffer"); + + rte_reorder_free(b1); + + b2 = rte_reorder_find_existing(name); + TEST_ASSERT((b2 == NULL) && (rte_errno == ENOENT), + "Found previously freed reorder buffer"); + + return 0; +} + +static int +test_reorder_insert(void) +{ + struct rte_reorder_buffer *b = NULL; + struct rte_mempool *p = test_params->p; + const unsigned int size = 4; + const unsigned int num_bufs = 7; + struct rte_mbuf *bufs[num_bufs]; + int ret = 0; + unsigned i; + + /* This would create a reorder buffer instance consisting of: + * reorder_seq = 0 + * ready_buf: RB[size] = {NULL, NULL, NULL, NULL} + * order_buf: OB[size] = {NULL, NULL, NULL, NULL} + */ + b = rte_reorder_create("test_insert", rte_socket_id(), size); + TEST_ASSERT_NOT_NULL(b, "Failed to create reorder buffer"); + + ret = rte_mempool_get_bulk(p, (void *)bufs, num_bufs); + TEST_ASSERT_SUCCESS(ret, "Error getting mbuf from pool"); + + for (i = 0; i < num_bufs; i++) + bufs[i]->seqn = i; + + /* This should fill up order buffer: + * reorder_seq = 0 + * RB[] = {NULL, NULL, NULL, NULL} + * OB[] = {0, 1, 2, 3} + */ + for (i = 0; i < size; i++) { + ret = rte_reorder_insert(b, bufs[i]); + if (ret != 0) { + printf("%s:%d: Error inserting packet with seqn less than size\n", + __func__, __LINE__); + ret = -1; + goto exit; + } + } + + /* early packet - should move mbufs to ready buf and move sequence window + * reorder_seq = 4 + * RB[] = {0, 1, 2, 3} + * OB[] = {4, NULL, NULL, NULL} + */ + ret = rte_reorder_insert(b, bufs[4]); + if (ret != 0) { + printf("%s:%d: Error inserting early packet with seqn: size\n", + __func__, __LINE__); + ret = -1; + goto exit; + } + + /* early packet from current sequence window - full ready buffer */ + bufs[5]->seqn = 2 * size; + ret = rte_reorder_insert(b, bufs[5]); + if (!((ret == -1) && (rte_errno == ENOSPC))) { + printf("%s:%d: No error inserting early packet with full ready buffer\n", + __func__, __LINE__); + ret = -1; + goto exit; + } + + /* late packet */ + bufs[6]->seqn = 3 * size; + ret = rte_reorder_insert(b, bufs[6]); + if (!((ret == -1) && (rte_errno == ERANGE))) { + printf("%s:%d: No error inserting late packet with seqn:" + " 3 * size\n", __func__, __LINE__); + ret = -1; + goto exit; + } + + ret = 0; +exit: + rte_mempool_put_bulk(p, (void *)bufs, num_bufs); + rte_reorder_free(b); + return ret; +} + +static int +test_reorder_drain(void) +{ + struct rte_reorder_buffer *b = NULL; + struct rte_mempool *p = test_params->p; + const unsigned int size = 4; + const unsigned int num_bufs = 8; + struct rte_mbuf *bufs[num_bufs]; + struct rte_mbuf *robufs[num_bufs]; + int ret = 0; + unsigned i, cnt; + + /* This would create a reorder buffer instance consisting of: + * reorder_seq = 0 + * ready_buf: RB[size] = {NULL, NULL, NULL, NULL} + * order_buf: OB[size] = {NULL, NULL, NULL, NULL} + */ + b = rte_reorder_create("test_drain", rte_socket_id(), size); + TEST_ASSERT_NOT_NULL(b, "Failed to create reorder buffer"); + + ret = rte_mempool_get_bulk(p, (void *)bufs, num_bufs); + TEST_ASSERT_SUCCESS(ret, "Error getting mbuf from pool"); + + /* Check no drained packets if reorder is empty */ + cnt = rte_reorder_drain(b, robufs, 1); + if (cnt != 0) { + printf("%s:%d: drained packets from empty reorder buffer\n", + __func__, __LINE__); + ret = -1; + goto exit; + } + + for (i = 0; i < num_bufs; i++) + bufs[i]->seqn = i; + + /* Insert packet with seqn 1: + * reorder_seq = 0 + * RB[] = {NULL, NULL, NULL, NULL} + * OB[] = {1, NULL, NULL, NULL} + */ + rte_reorder_insert(b, bufs[1]); + + cnt = rte_reorder_drain(b, robufs, 1); + if (cnt != 1) { + printf("%s:%d:%d: number of expected packets not drained\n", + __func__, __LINE__, cnt); + ret = -1; + goto exit; + } + + /* Insert more packets + * RB[] = {NULL, NULL, NULL, NULL} + * OB[] = {NULL, 2, 3, NULL} + */ + rte_reorder_insert(b, bufs[2]); + rte_reorder_insert(b, bufs[3]); + + /* Insert more packets + * RB[] = {NULL, NULL, NULL, NULL} + * OB[] = {NULL, 2, 3, 4} + */ + rte_reorder_insert(b, bufs[4]); + + /* Insert more packets + * RB[] = {2, 3, 4, NULL} + * OB[] = {NULL, NULL, 7, NULL} + */ + rte_reorder_insert(b, bufs[7]); + + /* drained expected packets */ + cnt = rte_reorder_drain(b, robufs, 4); + if (cnt != 3) { + printf("%s:%d:%d: number of expected packets not drained\n", + __func__, __LINE__, cnt); + ret = -1; + goto exit; + } + + /* + * RB[] = {NULL, NULL, NULL, NULL} + * OB[] = {NULL, NULL, 7, NULL} + */ + cnt = rte_reorder_drain(b, robufs, 1); + if (cnt != 0) { + printf("%s:%d:%d: number of expected packets not drained\n", + __func__, __LINE__, cnt); + ret = -1; + goto exit; + } + ret = 0; +exit: + rte_mempool_put_bulk(p, (void *)bufs, num_bufs); + rte_reorder_free(b); + return ret; +} + +static int +test_setup(void) +{ + /* reorder buffer instance creation */ + if (test_params->b == NULL) { + test_params->b = rte_reorder_create("PKT_RO1", rte_socket_id(), + REORDER_BUFFER_SIZE); + if (test_params->b == NULL) { + printf("%s: Error creating reorder buffer instance b\n", + __func__); + return -1; + } + } else + rte_reorder_reset(test_params->b); + + /* mempool creation */ + if (test_params->p == NULL) { + test_params->p = rte_pktmbuf_pool_create("RO_MBUF_POOL", + NUM_MBUFS, BURST, 0, RTE_MBUF_DEFAULT_BUF_SIZE, + rte_socket_id()); + if (test_params->p == NULL) { + printf("%s: Error creating mempool\n", __func__); + return -1; + } + } + return 0; +} + +static struct unit_test_suite reorder_test_suite = { + + .setup = test_setup, + .suite_name = "Reorder Unit Test Suite", + .unit_test_cases = { + TEST_CASE(test_reorder_create), + TEST_CASE(test_reorder_init), + TEST_CASE(test_reorder_find_existing), + TEST_CASE(test_reorder_free), + TEST_CASE(test_reorder_insert), + TEST_CASE(test_reorder_drain), + TEST_CASES_END() + } +}; + +static int +test_reorder(void) +{ + return unit_test_suite_runner(&reorder_test_suite); +} + +REGISTER_TEST_COMMAND(reorder_autotest, test_reorder); diff --git a/test/test/test_resource.c b/test/test/test_resource.c new file mode 100644 index 0000000000..a3a82f13a5 --- /dev/null +++ b/test/test/test_resource.c @@ -0,0 +1,133 @@ +/*- + * 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 +#include + +#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; +} + +REGISTER_TEST_COMMAND(resource_autotest, test_resource); diff --git a/test/test/test_ring.c b/test/test/test_ring.c new file mode 100644 index 0000000000..ebcb896415 --- /dev/null +++ b/test/test/test_ring.c @@ -0,0 +1,1381 @@ +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * Ring + * ==== + * + * #. Basic tests: done on one core: + * + * - Using single producer/single consumer functions: + * + * - Enqueue one object, two objects, MAX_BULK objects + * - Dequeue one object, two objects, MAX_BULK objects + * - Check that dequeued pointers are correct + * + * - Using multi producers/multi consumers functions: + * + * - Enqueue one object, two objects, MAX_BULK objects + * - Dequeue one object, two objects, MAX_BULK objects + * - Check that dequeued pointers are correct + * + * - Test watermark and default bulk enqueue/dequeue: + * + * - Set watermark + * - Set default bulk value + * - Enqueue objects, check that -EDQUOT is returned when + * watermark is exceeded + * - Check that dequeued pointers are correct + * + * #. Check live watermark change + * + * - Start a loop on another lcore that will enqueue and dequeue + * objects in a ring. It will monitor the value of watermark. + * - At the same time, change the watermark on the master lcore. + * - The slave lcore will check that watermark changes from 16 to 32. + * + * #. Performance tests. + * + * Tests done in test_ring_perf.c + */ + +#define RING_SIZE 4096 +#define MAX_BULK 32 + +static rte_atomic32_t synchro; + +static struct rte_ring *r; + +#define TEST_RING_VERIFY(exp) \ + if (!(exp)) { \ + printf("error at %s:%d\tcondition " #exp " failed\n", \ + __func__, __LINE__); \ + rte_ring_dump(stdout, r); \ + return -1; \ + } + +#define TEST_RING_FULL_EMTPY_ITER 8 + +static int +check_live_watermark_change(__attribute__((unused)) void *dummy) +{ + uint64_t hz = rte_get_timer_hz(); + void *obj_table[MAX_BULK]; + unsigned watermark, watermark_old = 16; + uint64_t cur_time, end_time; + int64_t diff = 0; + int i, ret; + unsigned count = 4; + + /* init the object table */ + memset(obj_table, 0, sizeof(obj_table)); + end_time = rte_get_timer_cycles() + (hz / 4); + + /* check that bulk and watermark are 4 and 32 (respectively) */ + while (diff >= 0) { + + /* add in ring until we reach watermark */ + ret = 0; + for (i = 0; i < 16; i ++) { + if (ret != 0) + break; + ret = rte_ring_enqueue_bulk(r, obj_table, count); + } + + if (ret != -EDQUOT) { + printf("Cannot enqueue objects, or watermark not " + "reached (ret=%d)\n", ret); + return -1; + } + + /* read watermark, the only change allowed is from 16 to 32 */ + watermark = r->prod.watermark; + if (watermark != watermark_old && + (watermark_old != 16 || watermark != 32)) { + printf("Bad watermark change %u -> %u\n", watermark_old, + watermark); + return -1; + } + watermark_old = watermark; + + /* dequeue objects from ring */ + while (i--) { + ret = rte_ring_dequeue_bulk(r, obj_table, count); + if (ret != 0) { + printf("Cannot dequeue (ret=%d)\n", ret); + return -1; + } + } + + cur_time = rte_get_timer_cycles(); + diff = end_time - cur_time; + } + + if (watermark_old != 32 ) { + printf(" watermark was not updated (wm=%u)\n", + watermark_old); + return -1; + } + + return 0; +} + +static int +test_live_watermark_change(void) +{ + unsigned lcore_id = rte_lcore_id(); + unsigned lcore_id2 = rte_get_next_lcore(lcore_id, 0, 1); + + printf("Test watermark live modification\n"); + rte_ring_set_water_mark(r, 16); + + /* launch a thread that will enqueue and dequeue, checking + * watermark and quota */ + rte_eal_remote_launch(check_live_watermark_change, NULL, lcore_id2); + + rte_delay_ms(100); + rte_ring_set_water_mark(r, 32); + rte_delay_ms(100); + + if (rte_eal_wait_lcore(lcore_id2) < 0) + return -1; + + return 0; +} + +/* Test for catch on invalid watermark values */ +static int +test_set_watermark( void ){ + unsigned count; + int setwm; + + struct rte_ring *r = rte_ring_lookup("test_ring_basic_ex"); + if(r == NULL){ + printf( " ring lookup failed\n" ); + goto error; + } + count = r->prod.size*2; + setwm = rte_ring_set_water_mark(r, count); + if (setwm != -EINVAL){ + printf("Test failed to detect invalid watermark count value\n"); + goto error; + } + + count = 0; + rte_ring_set_water_mark(r, count); + if (r->prod.watermark != r->prod.size) { + printf("Test failed to detect invalid watermark count value\n"); + goto error; + } + return 0; + +error: + return -1; +} + +/* + * helper routine for test_ring_basic + */ +static int +test_ring_basic_full_empty(void * const src[], void *dst[]) +{ + unsigned i, rand; + const unsigned rsz = RING_SIZE - 1; + + printf("Basic full/empty test\n"); + + for (i = 0; TEST_RING_FULL_EMTPY_ITER != i; i++) { + + /* random shift in the ring */ + rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL); + printf("%s: iteration %u, random shift: %u;\n", + __func__, i, rand); + TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src, + rand)); + TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rand)); + + /* fill the ring */ + TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src, + rsz)); + TEST_RING_VERIFY(0 == rte_ring_free_count(r)); + TEST_RING_VERIFY(rsz == rte_ring_count(r)); + TEST_RING_VERIFY(rte_ring_full(r)); + TEST_RING_VERIFY(0 == rte_ring_empty(r)); + + /* empty the ring */ + TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rsz)); + TEST_RING_VERIFY(rsz == rte_ring_free_count(r)); + TEST_RING_VERIFY(0 == rte_ring_count(r)); + TEST_RING_VERIFY(0 == rte_ring_full(r)); + TEST_RING_VERIFY(rte_ring_empty(r)); + + /* check data */ + TEST_RING_VERIFY(0 == memcmp(src, dst, rsz)); + rte_ring_dump(stdout, r); + } + return 0; +} + +static int +test_ring_basic(void) +{ + void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL; + int ret; + unsigned i, num_elems; + + /* alloc dummy object pointers */ + src = malloc(RING_SIZE*2*sizeof(void *)); + if (src == NULL) + goto fail; + + for (i = 0; i < RING_SIZE*2 ; i++) { + src[i] = (void *)(unsigned long)i; + } + cur_src = src; + + /* alloc some room for copied objects */ + dst = malloc(RING_SIZE*2*sizeof(void *)); + if (dst == NULL) + goto fail; + + memset(dst, 0, RING_SIZE*2*sizeof(void *)); + cur_dst = dst; + + printf("enqueue 1 obj\n"); + ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1); + cur_src += 1; + if (ret != 0) + goto fail; + + printf("enqueue 2 objs\n"); + ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2); + cur_src += 2; + if (ret != 0) + goto fail; + + printf("enqueue MAX_BULK objs\n"); + ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK); + cur_src += MAX_BULK; + if (ret != 0) + goto fail; + + printf("dequeue 1 obj\n"); + ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1); + cur_dst += 1; + if (ret != 0) + goto fail; + + printf("dequeue 2 objs\n"); + ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2); + cur_dst += 2; + if (ret != 0) + goto fail; + + printf("dequeue MAX_BULK objs\n"); + ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK); + cur_dst += MAX_BULK; + if (ret != 0) + goto fail; + + /* check data */ + if (memcmp(src, dst, cur_dst - dst)) { + rte_hexdump(stdout, "src", src, cur_src - src); + rte_hexdump(stdout, "dst", dst, cur_dst - dst); + printf("data after dequeue is not the same\n"); + goto fail; + } + cur_src = src; + cur_dst = dst; + + printf("enqueue 1 obj\n"); + ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1); + cur_src += 1; + if (ret != 0) + goto fail; + + printf("enqueue 2 objs\n"); + ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2); + cur_src += 2; + if (ret != 0) + goto fail; + + printf("enqueue MAX_BULK objs\n"); + ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK); + cur_src += MAX_BULK; + if (ret != 0) + goto fail; + + printf("dequeue 1 obj\n"); + ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1); + cur_dst += 1; + if (ret != 0) + goto fail; + + printf("dequeue 2 objs\n"); + ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2); + cur_dst += 2; + if (ret != 0) + goto fail; + + printf("dequeue MAX_BULK objs\n"); + ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK); + cur_dst += MAX_BULK; + if (ret != 0) + goto fail; + + /* check data */ + if (memcmp(src, dst, cur_dst - dst)) { + rte_hexdump(stdout, "src", src, cur_src - src); + rte_hexdump(stdout, "dst", dst, cur_dst - dst); + printf("data after dequeue is not the same\n"); + goto fail; + } + cur_src = src; + cur_dst = dst; + + printf("fill and empty the ring\n"); + for (i = 0; istats[lcore_id]; + + printf("Test the ring stats.\n"); + + /* Reset the watermark in case it was set in another test. */ + rte_ring_set_water_mark(r, 0); + + /* Reset the ring stats. */ + memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id])); + + /* Allocate some dummy object pointers. */ + src = malloc(RING_SIZE*2*sizeof(void *)); + if (src == NULL) + goto fail; + + for (i = 0; i < RING_SIZE*2 ; i++) { + src[i] = (void *)(unsigned long)i; + } + + /* Allocate some memory for copied objects. */ + dst = malloc(RING_SIZE*2*sizeof(void *)); + if (dst == NULL) + goto fail; + + memset(dst, 0, RING_SIZE*2*sizeof(void *)); + + /* Set the head and tail pointers. */ + cur_src = src; + cur_dst = dst; + + /* Do Enqueue tests. */ + printf("Test the dequeue stats.\n"); + + /* Fill the ring up to RING_SIZE -1. */ + printf("Fill the ring.\n"); + for (i = 0; i< (RING_SIZE/MAX_BULK); i++) { + rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK); + cur_src += MAX_BULK; + } + + /* Adjust for final enqueue = MAX_BULK -1. */ + cur_src--; + + printf("Verify that the ring is full.\n"); + if (rte_ring_full(r) != 1) + goto fail; + + + printf("Verify the enqueue success stats.\n"); + /* Stats should match above enqueue operations to fill the ring. */ + if (ring_stats->enq_success_bulk != (RING_SIZE/MAX_BULK)) + goto fail; + + /* Current max objects is RING_SIZE -1. */ + if (ring_stats->enq_success_objs != RING_SIZE -1) + goto fail; + + /* Shouldn't have any failures yet. */ + if (ring_stats->enq_fail_bulk != 0) + goto fail; + if (ring_stats->enq_fail_objs != 0) + goto fail; + + + printf("Test stats for SP burst enqueue to a full ring.\n"); + num_items = 2; + ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items); + if ((ret & RTE_RING_SZ_MASK) != 0) + goto fail; + + failed_enqueue_ops += 1; + failed_enqueue_items += num_items; + + /* The enqueue should have failed. */ + if (ring_stats->enq_fail_bulk != failed_enqueue_ops) + goto fail; + if (ring_stats->enq_fail_objs != failed_enqueue_items) + goto fail; + + + printf("Test stats for SP bulk enqueue to a full ring.\n"); + num_items = 4; + ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items); + if (ret != -ENOBUFS) + goto fail; + + failed_enqueue_ops += 1; + failed_enqueue_items += num_items; + + /* The enqueue should have failed. */ + if (ring_stats->enq_fail_bulk != failed_enqueue_ops) + goto fail; + if (ring_stats->enq_fail_objs != failed_enqueue_items) + goto fail; + + + printf("Test stats for MP burst enqueue to a full ring.\n"); + num_items = 8; + ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items); + if ((ret & RTE_RING_SZ_MASK) != 0) + goto fail; + + failed_enqueue_ops += 1; + failed_enqueue_items += num_items; + + /* The enqueue should have failed. */ + if (ring_stats->enq_fail_bulk != failed_enqueue_ops) + goto fail; + if (ring_stats->enq_fail_objs != failed_enqueue_items) + goto fail; + + + printf("Test stats for MP bulk enqueue to a full ring.\n"); + num_items = 16; + ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items); + if (ret != -ENOBUFS) + goto fail; + + failed_enqueue_ops += 1; + failed_enqueue_items += num_items; + + /* The enqueue should have failed. */ + if (ring_stats->enq_fail_bulk != failed_enqueue_ops) + goto fail; + if (ring_stats->enq_fail_objs != failed_enqueue_items) + goto fail; + + + /* Do Dequeue tests. */ + printf("Test the dequeue stats.\n"); + + printf("Empty the ring.\n"); + for (i = 0; ideq_success_bulk != (RING_SIZE/MAX_BULK)) + goto fail; + + /* Objects dequeued is RING_SIZE -1. */ + if (ring_stats->deq_success_objs != RING_SIZE -1) + goto fail; + + /* Shouldn't have any dequeue failure stats yet. */ + if (ring_stats->deq_fail_bulk != 0) + goto fail; + + printf("Test stats for SC burst dequeue with an empty ring.\n"); + num_items = 2; + ret = rte_ring_sc_dequeue_burst(r, cur_dst, num_items); + if ((ret & RTE_RING_SZ_MASK) != 0) + goto fail; + + failed_dequeue_ops += 1; + failed_dequeue_items += num_items; + + /* The dequeue should have failed. */ + if (ring_stats->deq_fail_bulk != failed_dequeue_ops) + goto fail; + if (ring_stats->deq_fail_objs != failed_dequeue_items) + goto fail; + + + printf("Test stats for SC bulk dequeue with an empty ring.\n"); + num_items = 4; + ret = rte_ring_sc_dequeue_bulk(r, cur_dst, num_items); + if (ret != -ENOENT) + goto fail; + + failed_dequeue_ops += 1; + failed_dequeue_items += num_items; + + /* The dequeue should have failed. */ + if (ring_stats->deq_fail_bulk != failed_dequeue_ops) + goto fail; + if (ring_stats->deq_fail_objs != failed_dequeue_items) + goto fail; + + + printf("Test stats for MC burst dequeue with an empty ring.\n"); + num_items = 8; + ret = rte_ring_mc_dequeue_burst(r, cur_dst, num_items); + if ((ret & RTE_RING_SZ_MASK) != 0) + goto fail; + failed_dequeue_ops += 1; + failed_dequeue_items += num_items; + + /* The dequeue should have failed. */ + if (ring_stats->deq_fail_bulk != failed_dequeue_ops) + goto fail; + if (ring_stats->deq_fail_objs != failed_dequeue_items) + goto fail; + + + printf("Test stats for MC bulk dequeue with an empty ring.\n"); + num_items = 16; + ret = rte_ring_mc_dequeue_bulk(r, cur_dst, num_items); + if (ret != -ENOENT) + goto fail; + + failed_dequeue_ops += 1; + failed_dequeue_items += num_items; + + /* The dequeue should have failed. */ + if (ring_stats->deq_fail_bulk != failed_dequeue_ops) + goto fail; + if (ring_stats->deq_fail_objs != failed_dequeue_items) + goto fail; + + + printf("Test total enqueue/dequeue stats.\n"); + /* At this point the enqueue and dequeue stats should be the same. */ + if (ring_stats->enq_success_bulk != ring_stats->deq_success_bulk) + goto fail; + if (ring_stats->enq_success_objs != ring_stats->deq_success_objs) + goto fail; + if (ring_stats->enq_fail_bulk != ring_stats->deq_fail_bulk) + goto fail; + if (ring_stats->enq_fail_objs != ring_stats->deq_fail_objs) + goto fail; + + + /* Watermark Tests. */ + printf("Test the watermark/quota stats.\n"); + + printf("Verify the initial watermark stats.\n"); + /* Watermark stats should be 0 since there is no watermark. */ + if (ring_stats->enq_quota_bulk != 0) + goto fail; + if (ring_stats->enq_quota_objs != 0) + goto fail; + + /* Set a watermark. */ + rte_ring_set_water_mark(r, 16); + + /* Reset pointers. */ + cur_src = src; + cur_dst = dst; + + last_enqueue_ops = ring_stats->enq_success_bulk; + last_enqueue_items = ring_stats->enq_success_objs; + + + printf("Test stats for SP burst enqueue below watermark.\n"); + num_items = 8; + ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items); + if ((ret & RTE_RING_SZ_MASK) != num_items) + goto fail; + + /* Watermark stats should still be 0. */ + if (ring_stats->enq_quota_bulk != 0) + goto fail; + if (ring_stats->enq_quota_objs != 0) + goto fail; + + /* Success stats should have increased. */ + if (ring_stats->enq_success_bulk != last_enqueue_ops + 1) + goto fail; + if (ring_stats->enq_success_objs != last_enqueue_items + num_items) + goto fail; + + last_enqueue_ops = ring_stats->enq_success_bulk; + last_enqueue_items = ring_stats->enq_success_objs; + + + printf("Test stats for SP burst enqueue at watermark.\n"); + num_items = 8; + ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items); + if ((ret & RTE_RING_SZ_MASK) != num_items) + goto fail; + + /* Watermark stats should have changed. */ + if (ring_stats->enq_quota_bulk != 1) + goto fail; + if (ring_stats->enq_quota_objs != num_items) + goto fail; + + last_quota_ops = ring_stats->enq_quota_bulk; + last_quota_items = ring_stats->enq_quota_objs; + + + printf("Test stats for SP burst enqueue above watermark.\n"); + num_items = 1; + ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items); + if ((ret & RTE_RING_SZ_MASK) != num_items) + goto fail; + + /* Watermark stats should have changed. */ + if (ring_stats->enq_quota_bulk != last_quota_ops +1) + goto fail; + if (ring_stats->enq_quota_objs != last_quota_items + num_items) + goto fail; + + last_quota_ops = ring_stats->enq_quota_bulk; + last_quota_items = ring_stats->enq_quota_objs; + + + printf("Test stats for MP burst enqueue above watermark.\n"); + num_items = 2; + ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items); + if ((ret & RTE_RING_SZ_MASK) != num_items) + goto fail; + + /* Watermark stats should have changed. */ + if (ring_stats->enq_quota_bulk != last_quota_ops +1) + goto fail; + if (ring_stats->enq_quota_objs != last_quota_items + num_items) + goto fail; + + last_quota_ops = ring_stats->enq_quota_bulk; + last_quota_items = ring_stats->enq_quota_objs; + + + printf("Test stats for SP bulk enqueue above watermark.\n"); + num_items = 4; + ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items); + if (ret != -EDQUOT) + goto fail; + + /* Watermark stats should have changed. */ + if (ring_stats->enq_quota_bulk != last_quota_ops +1) + goto fail; + if (ring_stats->enq_quota_objs != last_quota_items + num_items) + goto fail; + + last_quota_ops = ring_stats->enq_quota_bulk; + last_quota_items = ring_stats->enq_quota_objs; + + + printf("Test stats for MP bulk enqueue above watermark.\n"); + num_items = 8; + ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items); + if (ret != -EDQUOT) + goto fail; + + /* Watermark stats should have changed. */ + if (ring_stats->enq_quota_bulk != last_quota_ops +1) + goto fail; + if (ring_stats->enq_quota_objs != last_quota_items + num_items) + goto fail; + + printf("Test watermark success stats.\n"); + /* Success stats should be same as last non-watermarked enqueue. */ + if (ring_stats->enq_success_bulk != last_enqueue_ops) + goto fail; + if (ring_stats->enq_success_objs != last_enqueue_items) + goto fail; + + + /* Cleanup. */ + + /* Empty the ring. */ + for (i = 0; istats[lcore_id], 0, sizeof(r->stats[lcore_id])); + + /* Free memory before test completed */ + free(src); + free(dst); + return 0; + +fail: + free(src); + free(dst); + return -1; +#endif +} + +/* + * it will always fail to create ring with a wrong ring size number in this function + */ +static int +test_ring_creation_with_wrong_size(void) +{ + struct rte_ring * rp = NULL; + + /* Test if ring size is not power of 2 */ + rp = rte_ring_create("test_bad_ring_size", RING_SIZE + 1, SOCKET_ID_ANY, 0); + if (NULL != rp) { + return -1; + } + + /* Test if ring size is exceeding the limit */ + rp = rte_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), SOCKET_ID_ANY, 0); + if (NULL != rp) { + return -1; + } + return 0; +} + +/* + * it tests if it would always fail to create ring with an used ring name + */ +static int +test_ring_creation_with_an_used_name(void) +{ + struct rte_ring * rp; + + rp = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0); + if (NULL != rp) + return -1; + + return 0; +} + +/* + * Test to if a non-power of 2 count causes the create + * function to fail correctly + */ +static int +test_create_count_odd(void) +{ + struct rte_ring *r = rte_ring_create("test_ring_count", + 4097, SOCKET_ID_ANY, 0 ); + if(r != NULL){ + return -1; + } + return 0; +} + +static int +test_lookup_null(void) +{ + struct rte_ring *rlp = rte_ring_lookup("ring_not_found"); + if (rlp ==NULL) + if (rte_errno != ENOENT){ + printf( "test failed to returnn error on null pointer\n"); + return -1; + } + return 0; +} + +/* + * it tests some more basic ring operations + */ +static int +test_ring_basic_ex(void) +{ + int ret = -1; + unsigned i; + struct rte_ring * rp; + void **obj = NULL; + + obj = rte_calloc("test_ring_basic_ex_malloc", RING_SIZE, sizeof(void *), 0); + if (obj == NULL) { + printf("test_ring_basic_ex fail to rte_malloc\n"); + goto fail_test; + } + + rp = rte_ring_create("test_ring_basic_ex", RING_SIZE, SOCKET_ID_ANY, + RING_F_SP_ENQ | RING_F_SC_DEQ); + if (rp == NULL) { + printf("test_ring_basic_ex fail to create ring\n"); + goto fail_test; + } + + if (rte_ring_lookup("test_ring_basic_ex") != rp) { + goto fail_test; + } + + if (rte_ring_empty(rp) != 1) { + printf("test_ring_basic_ex ring is not empty but it should be\n"); + goto fail_test; + } + + printf("%u ring entries are now free\n", rte_ring_free_count(rp)); + + for (i = 0; i < RING_SIZE; i ++) { + rte_ring_enqueue(rp, obj[i]); + } + + if (rte_ring_full(rp) != 1) { + printf("test_ring_basic_ex ring is not full but it should be\n"); + goto fail_test; + } + + for (i = 0; i < RING_SIZE; i ++) { + rte_ring_dequeue(rp, &obj[i]); + } + + if (rte_ring_empty(rp) != 1) { + printf("test_ring_basic_ex ring is not empty but it should be\n"); + goto fail_test; + } + + /* Covering the ring burst operation */ + ret = rte_ring_enqueue_burst(rp, obj, 2); + if ((ret & RTE_RING_SZ_MASK) != 2) { + printf("test_ring_basic_ex: rte_ring_enqueue_burst fails \n"); + goto fail_test; + } + + ret = rte_ring_dequeue_burst(rp, obj, 2); + if (ret != 2) { + printf("test_ring_basic_ex: rte_ring_dequeue_burst fails \n"); + goto fail_test; + } + + ret = 0; +fail_test: + if (obj != NULL) + rte_free(obj); + + return ret; +} + +static int +test_ring(void) +{ + /* some more basic operations */ + if (test_ring_basic_ex() < 0) + return -1; + + rte_atomic32_init(&synchro); + + if (r == NULL) + r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0); + if (r == NULL) + return -1; + + /* retrieve the ring from its name */ + if (rte_ring_lookup("test") != r) { + printf("Cannot lookup ring from its name\n"); + return -1; + } + + /* burst operations */ + if (test_ring_burst_basic() < 0) + return -1; + + /* basic operations */ + if (test_ring_basic() < 0) + return -1; + + /* ring stats */ + if (test_ring_stats() < 0) + return -1; + + /* basic operations */ + if (test_live_watermark_change() < 0) + return -1; + + if ( test_set_watermark() < 0){ + printf ("Test failed to detect invalid parameter\n"); + return -1; + } + else + printf ( "Test detected forced bad watermark values\n"); + + if ( test_create_count_odd() < 0){ + printf ("Test failed to detect odd count\n"); + return -1; + } + else + printf ( "Test detected odd count\n"); + + if ( test_lookup_null() < 0){ + printf ("Test failed to detect NULL ring lookup\n"); + return -1; + } + else + printf ( "Test detected NULL ring lookup \n"); + + /* test of creating ring with wrong size */ + if (test_ring_creation_with_wrong_size() < 0) + return -1; + + /* test of creation ring with an used name */ + if (test_ring_creation_with_an_used_name() < 0) + return -1; + + /* dump the ring status */ + rte_ring_list_dump(stdout); + + return 0; +} + +REGISTER_TEST_COMMAND(ring_autotest, test_ring); diff --git a/test/test/test_ring_perf.c b/test/test/test_ring_perf.c new file mode 100644 index 0000000000..320c20cd2c --- /dev/null +++ b/test/test/test_ring_perf.c @@ -0,0 +1,417 @@ +/*- + * 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 +#include +#include +#include +#include + +#include "test.h" + +/* + * Ring + * ==== + * + * Measures performance of various operations using rdtsc + * * Empty ring dequeue + * * Enqueue/dequeue of bursts in 1 threads + * * Enqueue/dequeue of bursts in 2 threads + */ + +#define RING_NAME "RING_PERF" +#define RING_SIZE 4096 +#define MAX_BURST 32 + +/* + * the sizes to enqueue and dequeue in testing + * (marked volatile so they won't be seen as compile-time constants) + */ +static const volatile unsigned bulk_sizes[] = { 8, 32 }; + +/* The ring structure used for tests */ +static struct rte_ring *r; + +struct lcore_pair { + unsigned c1, c2; +}; + +static volatile unsigned lcore_count = 0; + +/**** Functions to analyse our core mask to get cores for different tests ***/ + +static int +get_two_hyperthreads(struct lcore_pair *lcp) +{ + unsigned id1, id2; + unsigned c1, c2, s1, s2; + RTE_LCORE_FOREACH(id1) { + /* inner loop just re-reads all id's. We could skip the first few + * elements, but since number of cores is small there is little point + */ + RTE_LCORE_FOREACH(id2) { + if (id1 == id2) + continue; + c1 = lcore_config[id1].core_id; + c2 = lcore_config[id2].core_id; + s1 = lcore_config[id1].socket_id; + s2 = lcore_config[id2].socket_id; + if ((c1 == c2) && (s1 == s2)){ + lcp->c1 = id1; + lcp->c2 = id2; + return 0; + } + } + } + return 1; +} + +static int +get_two_cores(struct lcore_pair *lcp) +{ + unsigned id1, id2; + unsigned c1, c2, s1, s2; + RTE_LCORE_FOREACH(id1) { + RTE_LCORE_FOREACH(id2) { + if (id1 == id2) + continue; + c1 = lcore_config[id1].core_id; + c2 = lcore_config[id2].core_id; + s1 = lcore_config[id1].socket_id; + s2 = lcore_config[id2].socket_id; + if ((c1 != c2) && (s1 == s2)){ + lcp->c1 = id1; + lcp->c2 = id2; + return 0; + } + } + } + return 1; +} + +static int +get_two_sockets(struct lcore_pair *lcp) +{ + unsigned id1, id2; + unsigned s1, s2; + RTE_LCORE_FOREACH(id1) { + RTE_LCORE_FOREACH(id2) { + if (id1 == id2) + continue; + s1 = lcore_config[id1].socket_id; + s2 = lcore_config[id2].socket_id; + if (s1 != s2){ + lcp->c1 = id1; + lcp->c2 = id2; + return 0; + } + } + } + return 1; +} + +/* Get cycle counts for dequeuing from an empty ring. Should be 2 or 3 cycles */ +static void +test_empty_dequeue(void) +{ + const unsigned iter_shift = 26; + const unsigned iterations = 1<size; + unsigned i; + void *burst[MAX_BURST] = {0}; + + if ( __sync_add_and_fetch(&lcore_count, 1) != 2 ) + while(lcore_count != 2) + rte_pause(); + + const uint64_t sp_start = rte_rdtsc(); + for (i = 0; i < iterations; i++) + while (rte_ring_sp_enqueue_bulk(r, burst, size) != 0) + rte_pause(); + const uint64_t sp_end = rte_rdtsc(); + + const uint64_t mp_start = rte_rdtsc(); + for (i = 0; i < iterations; i++) + while (rte_ring_mp_enqueue_bulk(r, burst, size) != 0) + rte_pause(); + const uint64_t mp_end = rte_rdtsc(); + + params->spsc = ((double)(sp_end - sp_start))/(iterations*size); + params->mpmc = ((double)(mp_end - mp_start))/(iterations*size); + return 0; +} + +/* + * Function that uses rdtsc to measure timing for ring dequeue. Needs pair + * thread running enqueue_bulk function + */ +static int +dequeue_bulk(void *p) +{ + const unsigned iter_shift = 23; + const unsigned iterations = 1<size; + unsigned i; + void *burst[MAX_BURST] = {0}; + + if ( __sync_add_and_fetch(&lcore_count, 1) != 2 ) + while(lcore_count != 2) + rte_pause(); + + const uint64_t sc_start = rte_rdtsc(); + for (i = 0; i < iterations; i++) + while (rte_ring_sc_dequeue_bulk(r, burst, size) != 0) + rte_pause(); + const uint64_t sc_end = rte_rdtsc(); + + const uint64_t mc_start = rte_rdtsc(); + for (i = 0; i < iterations; i++) + while (rte_ring_mc_dequeue_bulk(r, burst, size) != 0) + rte_pause(); + const uint64_t mc_end = rte_rdtsc(); + + params->spsc = ((double)(sc_end - sc_start))/(iterations*size); + params->mpmc = ((double)(mc_end - mc_start))/(iterations*size); + return 0; +} + +/* + * Function that calls the enqueue and dequeue bulk functions on pairs of cores. + * used to measure ring perf between hyperthreads, cores and sockets. + */ +static void +run_on_core_pair(struct lcore_pair *cores, + lcore_function_t f1, lcore_function_t f2) +{ + struct thread_params param1 = {0}, param2 = {0}; + unsigned i; + for (i = 0; i < sizeof(bulk_sizes)/sizeof(bulk_sizes[0]); i++) { + lcore_count = 0; + param1.size = param2.size = bulk_sizes[i]; + if (cores->c1 == rte_get_master_lcore()) { + rte_eal_remote_launch(f2, ¶m2, cores->c2); + f1(¶m1); + rte_eal_wait_lcore(cores->c2); + } else { + rte_eal_remote_launch(f1, ¶m1, cores->c1); + rte_eal_remote_launch(f2, ¶m2, cores->c2); + rte_eal_wait_lcore(cores->c1); + rte_eal_wait_lcore(cores->c2); + } + printf("SP/SC bulk enq/dequeue (size: %u): %.2F\n", bulk_sizes[i], + param1.spsc + param2.spsc); + printf("MP/MC bulk enq/dequeue (size: %u): %.2F\n", bulk_sizes[i], + param1.mpmc + param2.mpmc); + } +} + +/* + * Test function that determines how long an enqueue + dequeue of a single item + * takes on a single lcore. Result is for comparison with the bulk enq+deq. + */ +static void +test_single_enqueue_dequeue(void) +{ + const unsigned iter_shift = 24; + const unsigned iterations = 1<> iter_shift); + printf("MP/MC single enq/dequeue: %"PRIu64"\n", + (mc_end-mc_start) >> iter_shift); +} + +/* + * Test that does both enqueue and dequeue on a core using the burst() API calls + * instead of the bulk() calls used in other tests. Results should be the same + * as for the bulk function called on a single lcore. + */ +static void +test_burst_enqueue_dequeue(void) +{ + const unsigned iter_shift = 23; + const unsigned iterations = 1<> iter_shift) / bulk_sizes[sz]; + uint64_t sc_avg = ((sc_end-sc_start) >> iter_shift) / bulk_sizes[sz]; + + printf("SP/SC burst enq/dequeue (size: %u): %"PRIu64"\n", bulk_sizes[sz], + sc_avg); + printf("MP/MC burst enq/dequeue (size: %u): %"PRIu64"\n", bulk_sizes[sz], + mc_avg); + } +} + +/* Times enqueue and dequeue on a single lcore */ +static void +test_bulk_enqueue_dequeue(void) +{ + const unsigned iter_shift = 23; + const unsigned iterations = 1< +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * rwlock test + * =========== + * + * - There is a global rwlock and a table of rwlocks (one per lcore). + * + * - The test function takes all of these locks and launches the + * ``test_rwlock_per_core()`` function on each core (except the master). + * + * - The function takes the global write lock, display something, + * then releases the global lock. + * - Then, it takes the per-lcore write lock, display something, and + * releases the per-core lock. + * - Finally, a read lock is taken during 100 ms, then released. + * + * - The main function unlocks the per-lcore locks sequentially and + * waits between each lock. This triggers the display of a message + * for each core, in the correct order. + * + * Then, it tries to take the global write lock and display the last + * message. The autotest script checks that the message order is correct. + */ + +static rte_rwlock_t sl; +static rte_rwlock_t sl_tab[RTE_MAX_LCORE]; + +static int +test_rwlock_per_core(__attribute__((unused)) void *arg) +{ + rte_rwlock_write_lock(&sl); + printf("Global write lock taken on core %u\n", rte_lcore_id()); + rte_rwlock_write_unlock(&sl); + + rte_rwlock_write_lock(&sl_tab[rte_lcore_id()]); + printf("Hello from core %u !\n", rte_lcore_id()); + rte_rwlock_write_unlock(&sl_tab[rte_lcore_id()]); + + rte_rwlock_read_lock(&sl); + printf("Global read lock taken on core %u\n", rte_lcore_id()); + rte_delay_ms(100); + printf("Release global read lock on core %u\n", rte_lcore_id()); + rte_rwlock_read_unlock(&sl); + + return 0; +} + +static int +test_rwlock(void) +{ + int i; + + rte_rwlock_init(&sl); + for (i=0; i +#include +#include +#include +#include + +#include "test.h" + +#include +#include +#include +#include +#include + + +#define SUBPORT 0 +#define PIPE 1 +#define TC 2 +#define QUEUE 3 + +static struct rte_sched_subport_params subport_param[] = { + { + .tb_rate = 1250000000, + .tb_size = 1000000, + + .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000}, + .tc_period = 10, + }, +}; + +static struct rte_sched_pipe_params pipe_profile[] = { + { /* Profile #0 */ + .tb_rate = 305175, + .tb_size = 1000000, + + .tc_rate = {305175, 305175, 305175, 305175}, + .tc_period = 40, + + .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + }, +}; + +static struct rte_sched_port_params port_param = { + .socket = 0, /* computed */ + .rate = 0, /* computed */ + .mtu = 1522, + .frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT, + .n_subports_per_port = 1, + .n_pipes_per_subport = 1024, + .qsize = {32, 32, 32, 32}, + .pipe_profiles = pipe_profile, + .n_pipe_profiles = 1, +}; + +#define NB_MBUF 32 +#define MBUF_DATA_SZ (2048 + RTE_PKTMBUF_HEADROOM) +#define MEMPOOL_CACHE_SZ 0 +#define SOCKET 0 + + +static struct rte_mempool * +create_mempool(void) +{ + struct rte_mempool * mp; + + mp = rte_mempool_lookup("test_sched"); + if (!mp) + mp = rte_pktmbuf_pool_create("test_sched", NB_MBUF, + MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, SOCKET); + + return mp; +} + +static void +prepare_pkt(struct rte_mbuf *mbuf) +{ + struct ether_hdr *eth_hdr; + struct vlan_hdr *vlan1, *vlan2; + struct ipv4_hdr *ip_hdr; + + /* Simulate a classifier */ + eth_hdr = rte_pktmbuf_mtod(mbuf, struct ether_hdr *); + vlan1 = (struct vlan_hdr *)(ð_hdr->ether_type ); + vlan2 = (struct vlan_hdr *)((uintptr_t)ð_hdr->ether_type + sizeof(struct vlan_hdr)); + eth_hdr = (struct ether_hdr *)((uintptr_t)ð_hdr->ether_type + 2 *sizeof(struct vlan_hdr)); + ip_hdr = (struct ipv4_hdr *)((uintptr_t)eth_hdr + sizeof(eth_hdr->ether_type)); + + vlan1->vlan_tci = rte_cpu_to_be_16(SUBPORT); + vlan2->vlan_tci = rte_cpu_to_be_16(PIPE); + eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4); + ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE); + + + rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW); + + /* 64 byte packet */ + mbuf->pkt_len = 60; + mbuf->data_len = 60; +} + + +/** + * test main entrance for library sched + */ +static int +test_sched(void) +{ + struct rte_mempool *mp = NULL; + struct rte_sched_port *port = NULL; + uint32_t pipe; + struct rte_mbuf *in_mbufs[10]; + struct rte_mbuf *out_mbufs[10]; + int i; + + int err; + + mp = create_mempool(); + TEST_ASSERT_NOT_NULL(mp, "Error creating mempool\n"); + + port_param.socket = 0; + port_param.rate = (uint64_t) 10000 * 1000 * 1000 / 8; + + port = rte_sched_port_config(&port_param); + TEST_ASSERT_NOT_NULL(port, "Error config sched port\n"); + + err = rte_sched_subport_config(port, SUBPORT, subport_param); + TEST_ASSERT_SUCCESS(err, "Error config sched, err=%d\n", err); + + for (pipe = 0; pipe < port_param.n_pipes_per_subport; pipe ++) { + err = rte_sched_pipe_config(port, SUBPORT, pipe, 0); + TEST_ASSERT_SUCCESS(err, "Error config sched pipe %u, err=%d\n", pipe, err); + } + + for (i = 0; i < 10; i++) { + in_mbufs[i] = rte_pktmbuf_alloc(mp); + TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n"); + prepare_pkt(in_mbufs[i]); + } + + + err = rte_sched_port_enqueue(port, in_mbufs, 10); + TEST_ASSERT_EQUAL(err, 10, "Wrong enqueue, err=%d\n", err); + + err = rte_sched_port_dequeue(port, out_mbufs, 10); + TEST_ASSERT_EQUAL(err, 10, "Wrong dequeue, err=%d\n", err); + + for (i = 0; i < 10; i++) { + enum rte_meter_color color; + uint32_t subport, traffic_class, queue; + + color = rte_sched_port_pkt_read_color(out_mbufs[i]); + TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n"); + + rte_sched_port_pkt_read_tree_path(out_mbufs[i], + &subport, &pipe, &traffic_class, &queue); + + TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n"); + TEST_ASSERT_EQUAL(pipe, PIPE, "Wrong pipe\n"); + TEST_ASSERT_EQUAL(traffic_class, TC, "Wrong traffic_class\n"); + TEST_ASSERT_EQUAL(queue, QUEUE, "Wrong queue\n"); + + } + + + struct rte_sched_subport_stats subport_stats; + uint32_t tc_ov; + rte_sched_subport_read_stats(port, SUBPORT, &subport_stats, &tc_ov); +#if 0 + TEST_ASSERT_EQUAL(subport_stats.n_pkts_tc[TC-1], 10, "Wrong subport stats\n"); +#endif + struct rte_sched_queue_stats queue_stats; + uint16_t qlen; + rte_sched_queue_read_stats(port, QUEUE, &queue_stats, &qlen); +#if 0 + TEST_ASSERT_EQUAL(queue_stats.n_pkts, 10, "Wrong queue stats\n"); +#endif + + rte_sched_port_free(port); + + return 0; +} + +REGISTER_TEST_COMMAND(sched_autotest, test_sched); diff --git a/test/test/test_spinlock.c b/test/test/test_spinlock.c new file mode 100644 index 0000000000..2d94eecc21 --- /dev/null +++ b/test/test/test_spinlock.c @@ -0,0 +1,336 @@ +/*- + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * Spinlock test + * ============= + * + * - There is a global spinlock and a table of spinlocks (one per lcore). + * + * - The test function takes all of these locks and launches the + * ``test_spinlock_per_core()`` function on each core (except the master). + * + * - The function takes the global lock, display something, then releases + * the global lock. + * - The function takes the per-lcore lock, display something, then releases + * the per-core lock. + * + * - The main function unlocks the per-lcore locks sequentially and + * waits between each lock. This triggers the display of a message + * for each core, in the correct order. The autotest script checks that + * this order is correct. + * + * - A load test is carried out, with all cores attempting to lock a single lock + * multiple times + */ + +static rte_spinlock_t sl, sl_try; +static rte_spinlock_t sl_tab[RTE_MAX_LCORE]; +static rte_spinlock_recursive_t slr; +static unsigned count = 0; + +static rte_atomic32_t synchro; + +static int +test_spinlock_per_core(__attribute__((unused)) void *arg) +{ + rte_spinlock_lock(&sl); + printf("Global lock taken on core %u\n", rte_lcore_id()); + rte_spinlock_unlock(&sl); + + rte_spinlock_lock(&sl_tab[rte_lcore_id()]); + printf("Hello from core %u !\n", rte_lcore_id()); + rte_spinlock_unlock(&sl_tab[rte_lcore_id()]); + + return 0; +} + +static int +test_spinlock_recursive_per_core(__attribute__((unused)) void *arg) +{ + unsigned id = rte_lcore_id(); + + rte_spinlock_recursive_lock(&slr); + printf("Global recursive lock taken on core %u - count = %d\n", + id, slr.count); + rte_spinlock_recursive_lock(&slr); + printf("Global recursive lock taken on core %u - count = %d\n", + id, slr.count); + rte_spinlock_recursive_lock(&slr); + printf("Global recursive lock taken on core %u - count = %d\n", + id, slr.count); + + printf("Hello from within recursive locks from core %u !\n", id); + + rte_spinlock_recursive_unlock(&slr); + printf("Global recursive lock released on core %u - count = %d\n", + id, slr.count); + rte_spinlock_recursive_unlock(&slr); + printf("Global recursive lock released on core %u - count = %d\n", + id, slr.count); + rte_spinlock_recursive_unlock(&slr); + printf("Global recursive lock released on core %u - count = %d\n", + id, slr.count); + + return 0; +} + +static rte_spinlock_t lk = RTE_SPINLOCK_INITIALIZER; +static uint64_t lock_count[RTE_MAX_LCORE] = {0}; + +#define TIME_MS 100 + +static int +load_loop_fn(void *func_param) +{ + uint64_t time_diff = 0, begin; + uint64_t hz = rte_get_timer_hz(); + uint64_t lcount = 0; + const int use_lock = *(int*)func_param; + const unsigned lcore = rte_lcore_id(); + + /* wait synchro for slaves */ + if (lcore != rte_get_master_lcore()) + while (rte_atomic32_read(&synchro) == 0); + + begin = rte_get_timer_cycles(); + while (time_diff < hz * TIME_MS / 1000) { + if (use_lock) + rte_spinlock_lock(&lk); + lcount++; + if (use_lock) + rte_spinlock_unlock(&lk); + /* delay to make lock duty cycle slighlty realistic */ + rte_delay_us(1); + time_diff = rte_get_timer_cycles() - begin; + } + lock_count[lcore] = lcount; + return 0; +} + +static int +test_spinlock_perf(void) +{ + unsigned int i; + uint64_t total = 0; + int lock = 0; + const unsigned lcore = rte_lcore_id(); + + printf("\nTest with no lock on single core...\n"); + load_loop_fn(&lock); + printf("Core [%u] count = %"PRIu64"\n", lcore, lock_count[lcore]); + memset(lock_count, 0, sizeof(lock_count)); + + printf("\nTest with lock on single core...\n"); + lock = 1; + load_loop_fn(&lock); + printf("Core [%u] count = %"PRIu64"\n", lcore, lock_count[lcore]); + memset(lock_count, 0, sizeof(lock_count)); + + printf("\nTest with lock on %u cores...\n", rte_lcore_count()); + + /* Clear synchro and start slaves */ + rte_atomic32_set(&synchro, 0); + rte_eal_mp_remote_launch(load_loop_fn, &lock, SKIP_MASTER); + + /* start synchro and launch test on master */ + rte_atomic32_set(&synchro, 1); + load_loop_fn(&lock); + + rte_eal_mp_wait_lcore(); + + RTE_LCORE_FOREACH(i) { + printf("Core [%u] count = %"PRIu64"\n", i, lock_count[i]); + total += lock_count[i]; + } + + printf("Total count = %"PRIu64"\n", total); + + return 0; +} + +/* + * Use rte_spinlock_trylock() to trylock a spinlock object, + * If it could not lock the object sucessfully, it would + * return immediately and the variable of "count" would be + * increased by one per times. the value of "count" could be + * checked as the result later. + */ +static int +test_spinlock_try(__attribute__((unused)) void *arg) +{ + if (rte_spinlock_trylock(&sl_try) == 0) { + rte_spinlock_lock(&sl); + count ++; + rte_spinlock_unlock(&sl); + } + + return 0; +} + + +/* + * Test rte_eal_get_lcore_state() in addition to spinlocks + * as we have "waiting" then "running" lcores. + */ +static int +test_spinlock(void) +{ + int ret = 0; + int i; + + /* slave cores should be waiting: print it */ + RTE_LCORE_FOREACH_SLAVE(i) { + printf("lcore %d state: %d\n", i, + (int) rte_eal_get_lcore_state(i)); + } + + rte_spinlock_init(&sl); + rte_spinlock_init(&sl_try); + rte_spinlock_recursive_init(&slr); + for (i=0; i +#include +#include +#include +#include + +#include + +#include "test.h" + +#define LOG(...) do {\ + fprintf(stderr, "%s() ln %d: ", __func__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ +} while(0) + +#define DATA_BYTE 'a' + +static int +test_rte_strsplit(void) +{ + int i; + do { + /* ======================================================= + * split a mac address correct number of splits requested + * =======================================================*/ + char test_string[] = "54:65:76:87:98:90"; + char *splits[6]; + + LOG("Source string: '%s', to split on ':'\n", test_string); + if (rte_strsplit(test_string, sizeof(test_string), + splits, 6, ':') != 6) { + LOG("Error splitting mac address\n"); + return -1; + } + for (i = 0; i < 6; i++) + LOG("Token %d = %s\n", i + 1, splits[i]); + } while (0); + + + do { + /* ======================================================= + * split on spaces smaller number of splits requested + * =======================================================*/ + char test_string[] = "54 65 76 87 98 90"; + char *splits[6]; + + LOG("Source string: '%s', to split on ' '\n", test_string); + if (rte_strsplit(test_string, sizeof(test_string), + splits, 3, ' ') != 3) { + LOG("Error splitting mac address for max 2 splits\n"); + return -1; + } + for (i = 0; i < 3; i++) + LOG("Token %d = %s\n", i + 1, splits[i]); + } while (0); + + do { + /* ======================================================= + * split on commas - more splits than commas requested + * =======================================================*/ + char test_string[] = "a,b,c,d"; + char *splits[6]; + + LOG("Source string: '%s', to split on ','\n", test_string); + if (rte_strsplit(test_string, sizeof(test_string), + splits, 6, ',') != 4) { + LOG("Error splitting %s on ','\n", test_string); + return -1; + } + for (i = 0; i < 4; i++) + LOG("Token %d = %s\n", i + 1, splits[i]); + } while(0); + + do { + /* ======================================================= + * Try splitting on non-existent character. + * =======================================================*/ + char test_string[] = "a,b,c,d"; + char *splits[6]; + + LOG("Source string: '%s', to split on ' '\n", test_string); + if (rte_strsplit(test_string, sizeof(test_string), + splits, 6, ' ') != 1) { + LOG("Error splitting %s on ' '\n", test_string); + return -1; + } + LOG("String not split\n"); + } while(0); + + do { + /* ======================================================= + * Invalid / edge case parameter checks + * =======================================================*/ + char test_string[] = "a,b,c,d"; + char *splits[6]; + + if (rte_strsplit(NULL, 0, splits, 6, ',') >= 0 + || errno != EINVAL){ + LOG("Error: rte_strsplit accepted NULL string parameter\n"); + return -1; + } + + if (rte_strsplit(test_string, sizeof(test_string), NULL, 0, ',') >= 0 + || errno != EINVAL){ + LOG("Error: rte_strsplit accepted NULL array parameter\n"); + return -1; + } + + errno = 0; + if (rte_strsplit(test_string, 0, splits, 6, ',') != 0 || errno != 0) { + LOG("Error: rte_strsplit did not accept 0 length string\n"); + return -1; + } + + if (rte_strsplit(test_string, sizeof(test_string), splits, 0, ',') != 0 + || errno != 0) { + LOG("Error: rte_strsplit did not accept 0 length array\n"); + return -1; + } + + LOG("Parameter test cases passed\n"); + } while(0); + + LOG("%s - PASSED\n", __func__); + return 0; +} + +static int +test_string_fns(void) +{ + if (test_rte_strsplit() < 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(string_autotest, test_string_fns); diff --git a/test/test/test_table.c b/test/test/test_table.c new file mode 100644 index 0000000000..1faa0a6d80 --- /dev/null +++ b/test/test/test_table.c @@ -0,0 +1,202 @@ +/*- + * 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 +#include +#include +#include +#include "test.h" +#include "test_table.h" +#include "test_table_pipeline.h" +#include "test_table_ports.h" +#include "test_table_tables.h" +#include "test_table_combined.h" +#include "test_table_acl.h" + +/* Global variables */ +struct rte_pipeline *p; +struct rte_ring *rings_rx[N_PORTS]; +struct rte_ring *rings_tx[N_PORTS]; +struct rte_mempool *pool = NULL; + +uint32_t port_in_id[N_PORTS]; +uint32_t port_out_id[N_PORTS]; +uint32_t port_out_id_type[3]; +uint32_t table_id[N_PORTS*2]; +uint64_t override_hit_mask = 0xFFFFFFFF; +uint64_t override_miss_mask = 0xFFFFFFFF; +uint64_t non_reserved_actions_hit = 0; +uint64_t non_reserved_actions_miss = 0; +uint8_t connect_miss_action_to_port_out = 0; +uint8_t connect_miss_action_to_table = 0; +uint32_t table_entry_default_action = RTE_PIPELINE_ACTION_DROP; +uint32_t table_entry_hit_action = RTE_PIPELINE_ACTION_PORT; +uint32_t table_entry_miss_action = RTE_PIPELINE_ACTION_DROP; +rte_pipeline_port_in_action_handler port_in_action = NULL; +rte_pipeline_port_out_action_handler port_out_action = NULL; +rte_pipeline_table_action_handler_hit action_handler_hit = NULL; +rte_pipeline_table_action_handler_miss action_handler_miss = NULL; + +/* Function prototypes */ +static void app_init_rings(void); +static void app_init_mbuf_pools(void); + +uint64_t pipeline_test_hash(void *key, + __attribute__((unused)) uint32_t key_size, + __attribute__((unused)) uint64_t seed) +{ + uint32_t *k32 = (uint32_t *) key; + uint32_t ip_dst = rte_be_to_cpu_32(k32[0]); + uint64_t signature = ip_dst; + + return signature; +} + +static void +app_init_mbuf_pools(void) +{ + /* Init the buffer pool */ + printf("Getting/Creating the mempool ...\n"); + pool = rte_mempool_lookup("mempool"); + if (!pool) { + pool = rte_pktmbuf_pool_create( + "mempool", + POOL_SIZE, + POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE, + 0); + if (pool == NULL) + rte_panic("Cannot create mbuf pool\n"); + } +} + +static void +app_init_rings(void) +{ + uint32_t i; + + for (i = 0; i < N_PORTS; i++) { + char name[32]; + + snprintf(name, sizeof(name), "app_ring_rx_%u", i); + rings_rx[i] = rte_ring_lookup(name); + if (rings_rx[i] == NULL) { + rings_rx[i] = rte_ring_create( + name, + RING_RX_SIZE, + 0, + RING_F_SP_ENQ | RING_F_SC_DEQ); + } + if (rings_rx[i] == NULL) + rte_panic("Cannot create RX ring %u\n", i); + } + + for (i = 0; i < N_PORTS; i++) { + char name[32]; + + snprintf(name, sizeof(name), "app_ring_tx_%u", i); + rings_tx[i] = rte_ring_lookup(name); + if (rings_tx[i] == NULL) { + rings_tx[i] = rte_ring_create( + name, + RING_TX_SIZE, + 0, + RING_F_SP_ENQ | RING_F_SC_DEQ); + } + if (rings_tx[i] == NULL) + rte_panic("Cannot create TX ring %u\n", i); + } + +} + +static int +test_table(void) +{ + int status, failures; + unsigned i; + + failures = 0; + + app_init_rings(); + app_init_mbuf_pools(); + + printf("\n\n\n\n************Pipeline tests************\n"); + + if (test_table_pipeline() < 0) + return -1; + + printf("\n\n\n\n************Port tests************\n"); + for (i = 0; i < n_port_tests; i++) { + status = port_tests[i](); + if (status < 0) { + printf("\nPort test number %d failed (%d).\n", i, + status); + failures++; + return -1; + } + } + + printf("\n\n\n\n************Table tests************\n"); + for (i = 0; i < n_table_tests; i++) { + status = table_tests[i](); + if (status < 0) { + printf("\nTable test number %d failed (%d).\n", i, + status); + failures++; + return -1; + } + } + + printf("\n\n\n\n************Table tests************\n"); + for (i = 0; i < n_table_tests_combined; i++) { + status = table_tests_combined[i](); + if (status < 0) { + printf("\nCombined table test number %d failed with " + "reason number %d.\n", i, status); + failures++; + return -1; + } + } + + if (failures) + return -1; + +#ifdef RTE_LIBRTE_ACL + printf("\n\n\n\n************ACL tests************\n"); + if (test_table_acl() < 0) + return -1; +#endif + + return 0; +} + +REGISTER_TEST_COMMAND(table_autotest, test_table); diff --git a/test/test/test_table.h b/test/test/test_table.h new file mode 100644 index 0000000000..84d1845a3d --- /dev/null +++ b/test/test/test_table.h @@ -0,0 +1,206 @@ +/*- + * 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 +#include +#include +#include +#include +#include + +#ifdef RTE_LIBRTE_ACL +#include +#endif + +#include +#include +#include + +#ifndef TEST_TABLE_H_ +#define TEST_TABLE_H_ + +#define RING_SIZE 4096 +#define MAX_BULK 32 +#define N 65536 +#define TIME_S 5 +#define TEST_RING_FULL_EMTPY_ITER 8 +#define N_PORTS 2 +#define N_PKTS 2 +#define N_PKTS_EXT 6 +#define RING_RX rings_rx[0] +#define RING_RX_2 rings_rx[1] +#define RING_TX rings_tx[0] +#define RING_TX_2 rings_tx[1] +#define PORT_RX_RING_SIZE 128 +#define PORT_TX_RING_SIZE 512 +#define RING_RX_SIZE 128 +#define RING_TX_SIZE 128 +#define POOL_BUFFER_SIZE RTE_MBUF_DEFAULT_BUF_SIZE +#define POOL_SIZE (32 * 1024) +#define POOL_CACHE_SIZE 256 +#define BURST_SIZE 8 +#define WORKER_TYPE 1 +#define MAX_DUMMY_PORTS 2 +#define MP_NAME "dummy_port_mempool" +#define MBUF_COUNT (8000 * MAX_DUMMY_PORTS) +#define MP_CACHE_SZ 256 +#define MP_SOCKET 0 +#define MP_FLAGS 0 + +/* Macros */ +#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset)) + +#define RING_ENQUEUE(ring, value) do { \ + struct rte_mbuf *m; \ + uint32_t *k32, *signature; \ + uint8_t *key; \ + \ + m = rte_pktmbuf_alloc(pool); \ + if (m == NULL) \ + return -1; \ + signature = RTE_MBUF_METADATA_UINT32_PTR(m, \ + APP_METADATA_OFFSET(0)); \ + key = RTE_MBUF_METADATA_UINT8_PTR(m, \ + APP_METADATA_OFFSET(32)); \ + k32 = (uint32_t *) key; \ + k32[0] = (value); \ + *signature = pipeline_test_hash(key, 0, 0); \ + rte_ring_enqueue((ring), m); \ +} while (0) + +#define RUN_PIPELINE(pipeline) do { \ + rte_pipeline_run((pipeline)); \ + rte_pipeline_flush((pipeline)); \ +} while (0) + +#define VERIFY(var, value) do { \ + if ((var) != -(value)) \ + return var; \ +} while (0) + +#define VERIFY_TRAFFIC(ring, sent, expected) do { \ + unsigned i, n = 0; \ + void *mbuf = NULL; \ + \ + for (i = 0; i < (sent); i++) { \ + if (!rte_ring_dequeue((ring), &mbuf)) { \ + if (mbuf == NULL) \ + continue; \ + n++; \ + rte_pktmbuf_free((struct rte_mbuf *)mbuf); \ + } \ + else \ + break; \ + } \ + printf("Expected %d, got %d\n", expected, n); \ + if (n != (expected)) { \ + return -21; \ + } \ +} while (0) + +/* Function definitions */ +uint64_t pipeline_test_hash( + void *key, + __attribute__((unused)) uint32_t key_size, + __attribute__((unused)) uint64_t seed); + +/* Extern variables */ +extern struct rte_pipeline *p; +extern struct rte_ring *rings_rx[N_PORTS]; +extern struct rte_ring *rings_tx[N_PORTS]; +extern struct rte_mempool *pool; +extern uint32_t port_in_id[N_PORTS]; +extern uint32_t port_out_id[N_PORTS]; +extern uint32_t port_out_id_type[3]; +extern uint32_t table_id[N_PORTS*2]; +extern uint64_t override_hit_mask; +extern uint64_t override_miss_mask; +extern uint64_t non_reserved_actions_hit; +extern uint64_t non_reserved_actions_miss; +extern uint8_t connect_miss_action_to_port_out; +extern uint8_t connect_miss_action_to_table; +extern uint32_t table_entry_default_action; +extern uint32_t table_entry_hit_action; +extern uint32_t table_entry_miss_action; +extern rte_pipeline_port_in_action_handler port_in_action; +extern rte_pipeline_port_out_action_handler port_out_action; +extern rte_pipeline_table_action_handler_hit action_handler_hit; +extern rte_pipeline_table_action_handler_miss action_handler_miss; + +/* Global data types */ +struct manage_ops { + uint32_t op_id; + void *op_data; + int expected_result; +}; + +/* Internal pipeline structures */ +struct rte_port_in { + struct rte_port_in_ops ops; + uint32_t burst_size; + uint32_t table_id; + void *h_port; +}; + +struct rte_port_out { + struct rte_port_out_ops ops; + void *h_port; +}; + +struct rte_table { + struct rte_table_ops ops; + rte_pipeline_table_action_handler_hit f_action; + uint32_t table_next_id; + uint32_t table_next_id_valid; + uint8_t actions_lookup_miss[RTE_CACHE_LINE_SIZE]; + uint32_t action_data_size; + void *h_table; +}; + +#define RTE_PIPELINE_MAX_NAME_SZ 124 + +struct rte_pipeline { + char name[RTE_PIPELINE_MAX_NAME_SZ]; + uint32_t socket_id; + struct rte_port_in ports_in[16]; + struct rte_port_out ports_out[16]; + struct rte_table tables[64]; + uint32_t num_ports_in; + uint32_t num_ports_out; + uint32_t num_tables; + struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX]; + struct rte_table_entry *actions[RTE_PORT_IN_BURST_SIZE_MAX]; + uint64_t mask_action[64]; + uint32_t mask_actions; +}; +#endif diff --git a/test/test/test_table_acl.c b/test/test/test_table_acl.c new file mode 100644 index 0000000000..b3bfda4ccc --- /dev/null +++ b/test/test/test_table_acl.c @@ -0,0 +1,760 @@ +/*- + * 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 +#include "test_table.h" +#include "test_table_acl.h" + +#define IPv4(a, b, c, d) ((uint32_t)(((a) & 0xff) << 24) | \ + (((b) & 0xff) << 16) | \ + (((c) & 0xff) << 8) | \ + ((d) & 0xff)) + +/* + * Rule and trace formats definitions. + **/ + +struct ipv4_5tuple { + uint8_t proto; + uint32_t ip_src; + uint32_t ip_dst; + uint16_t port_src; + uint16_t port_dst; +}; + +enum { + PROTO_FIELD_IPV4, + SRC_FIELD_IPV4, + DST_FIELD_IPV4, + SRCP_FIELD_IPV4, + DSTP_FIELD_IPV4, + NUM_FIELDS_IPV4 +}; + +struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint8_t), + .field_index = PROTO_FIELD_IPV4, + .input_index = PROTO_FIELD_IPV4, + .offset = offsetof(struct ipv4_5tuple, proto), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = SRC_FIELD_IPV4, + .input_index = SRC_FIELD_IPV4, + .offset = offsetof(struct ipv4_5tuple, ip_src), + }, + { + .type = RTE_ACL_FIELD_TYPE_MASK, + .size = sizeof(uint32_t), + .field_index = DST_FIELD_IPV4, + .input_index = DST_FIELD_IPV4, + .offset = offsetof(struct ipv4_5tuple, ip_dst), + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = SRCP_FIELD_IPV4, + .input_index = SRCP_FIELD_IPV4, + .offset = offsetof(struct ipv4_5tuple, port_src), + }, + { + .type = RTE_ACL_FIELD_TYPE_RANGE, + .size = sizeof(uint16_t), + .field_index = DSTP_FIELD_IPV4, + .input_index = SRCP_FIELD_IPV4, + .offset = offsetof(struct ipv4_5tuple, port_dst), + }, +}; + +struct rte_table_acl_rule_add_params table_acl_IPv4_rule; + +typedef int (*parse_5tuple)(char *text, + struct rte_table_acl_rule_add_params *rule); + +/* +* The order of the fields in the rule string after the initial '@' +*/ +enum { + CB_FLD_SRC_ADDR, + CB_FLD_DST_ADDR, + CB_FLD_SRC_PORT_RANGE, + CB_FLD_DST_PORT_RANGE, + CB_FLD_PROTO, + CB_FLD_NUM, +}; + + +#define GET_CB_FIELD(in, fd, base, lim, dlm) \ +do { \ + unsigned long val; \ + char *end; \ + \ + errno = 0; \ + val = strtoul((in), &end, (base)); \ + if (errno != 0 || end[0] != (dlm) || val > (lim)) \ + return -EINVAL; \ + (fd) = (typeof(fd)) val; \ + (in) = end + 1; \ +} while (0) + + + + +static int +parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len) +{ + uint8_t a, b, c, d, m; + + GET_CB_FIELD(in, a, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, b, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, c, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, d, 0, UINT8_MAX, '/'); + GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0); + + addr[0] = IPv4(a, b, c, d); + mask_len[0] = m; + + return 0; +} + +static int +parse_port_range(const char *in, uint16_t *port_low, uint16_t *port_high) +{ + uint16_t a, b; + + GET_CB_FIELD(in, a, 0, UINT16_MAX, ':'); + GET_CB_FIELD(in, b, 0, UINT16_MAX, 0); + + port_low[0] = a; + port_high[0] = b; + + return 0; +} + +static int +parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v) +{ + int i, rc; + char *s, *sp, *in[CB_FLD_NUM]; + static const char *dlm = " \t\n"; + + /* + ** Skip leading '@' + */ + if (strchr(str, '@') != str) + return -EINVAL; + + s = str + 1; + + /* + * Populate the 'in' array with the location of each + * field in the string we're parsing + */ + for (i = 0; i != DIM(in); i++) { + in[i] = strtok_r(s, dlm, &sp); + if (in[i] == NULL) + return -EINVAL; + s = NULL; + } + + /* Parse x.x.x.x/x */ + rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR], + &v->field_value[SRC_FIELD_IPV4].value.u32, + &v->field_value[SRC_FIELD_IPV4].mask_range.u32); + if (rc != 0) { + RTE_LOG(ERR, PIPELINE, "failed to read src address/mask: %s\n", + in[CB_FLD_SRC_ADDR]); + return rc; + } + + printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32, + v->field_value[SRC_FIELD_IPV4].mask_range.u32); + + /* Parse x.x.x.x/x */ + rc = parse_ipv4_net(in[CB_FLD_DST_ADDR], + &v->field_value[DST_FIELD_IPV4].value.u32, + &v->field_value[DST_FIELD_IPV4].mask_range.u32); + if (rc != 0) { + RTE_LOG(ERR, PIPELINE, "failed to read dest address/mask: %s\n", + in[CB_FLD_DST_ADDR]); + return rc; + } + + printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32, + v->field_value[DST_FIELD_IPV4].mask_range.u32); + /* Parse n:n */ + rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE], + &v->field_value[SRCP_FIELD_IPV4].value.u16, + &v->field_value[SRCP_FIELD_IPV4].mask_range.u16); + if (rc != 0) { + RTE_LOG(ERR, PIPELINE, "failed to read source port range: %s\n", + in[CB_FLD_SRC_PORT_RANGE]); + return rc; + } + + printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16, + v->field_value[SRCP_FIELD_IPV4].mask_range.u16); + /* Parse n:n */ + rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE], + &v->field_value[DSTP_FIELD_IPV4].value.u16, + &v->field_value[DSTP_FIELD_IPV4].mask_range.u16); + if (rc != 0) { + RTE_LOG(ERR, PIPELINE, "failed to read dest port range: %s\n", + in[CB_FLD_DST_PORT_RANGE]); + return rc; + } + + printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16, + v->field_value[DSTP_FIELD_IPV4].mask_range.u16); + /* parse 0/0xnn */ + GET_CB_FIELD(in[CB_FLD_PROTO], + v->field_value[PROTO_FIELD_IPV4].value.u8, + 0, UINT8_MAX, '/'); + GET_CB_FIELD(in[CB_FLD_PROTO], + v->field_value[PROTO_FIELD_IPV4].mask_range.u8, + 0, UINT8_MAX, 0); + + printf("V=%u, mask=%u\n", + (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8, + v->field_value[PROTO_FIELD_IPV4].mask_range.u8); + return 0; +} + +static int +parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v) +{ + int i, rc; + char *s, *sp, *in[CB_FLD_NUM]; + static const char *dlm = " \t\n"; + + /* + ** Skip leading '@' + */ + if (strchr(str, '@') != str) + return -EINVAL; + + s = str + 1; + + /* + * Populate the 'in' array with the location of each + * field in the string we're parsing + */ + for (i = 0; i != DIM(in); i++) { + in[i] = strtok_r(s, dlm, &sp); + if (in[i] == NULL) + return -EINVAL; + s = NULL; + } + + /* Parse x.x.x.x/x */ + rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR], + &v->field_value[SRC_FIELD_IPV4].value.u32, + &v->field_value[SRC_FIELD_IPV4].mask_range.u32); + if (rc != 0) { + RTE_LOG(ERR, PIPELINE, "failed to read src address/mask: %s\n", + in[CB_FLD_SRC_ADDR]); + return rc; + } + + printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32, + v->field_value[SRC_FIELD_IPV4].mask_range.u32); + + /* Parse x.x.x.x/x */ + rc = parse_ipv4_net(in[CB_FLD_DST_ADDR], + &v->field_value[DST_FIELD_IPV4].value.u32, + &v->field_value[DST_FIELD_IPV4].mask_range.u32); + if (rc != 0) { + RTE_LOG(ERR, PIPELINE, "failed to read dest address/mask: %s\n", + in[CB_FLD_DST_ADDR]); + return rc; + } + + printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32, + v->field_value[DST_FIELD_IPV4].mask_range.u32); + /* Parse n:n */ + rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE], + &v->field_value[SRCP_FIELD_IPV4].value.u16, + &v->field_value[SRCP_FIELD_IPV4].mask_range.u16); + if (rc != 0) { + RTE_LOG(ERR, PIPELINE, "failed to read source port range: %s\n", + in[CB_FLD_SRC_PORT_RANGE]); + return rc; + } + + printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16, + v->field_value[SRCP_FIELD_IPV4].mask_range.u16); + /* Parse n:n */ + rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE], + &v->field_value[DSTP_FIELD_IPV4].value.u16, + &v->field_value[DSTP_FIELD_IPV4].mask_range.u16); + if (rc != 0) { + RTE_LOG(ERR, PIPELINE, "failed to read dest port range: %s\n", + in[CB_FLD_DST_PORT_RANGE]); + return rc; + } + + printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16, + v->field_value[DSTP_FIELD_IPV4].mask_range.u16); + /* parse 0/0xnn */ + GET_CB_FIELD(in[CB_FLD_PROTO], + v->field_value[PROTO_FIELD_IPV4].value.u8, + 0, UINT8_MAX, '/'); + GET_CB_FIELD(in[CB_FLD_PROTO], + v->field_value[PROTO_FIELD_IPV4].mask_range.u8, + 0, UINT8_MAX, 0); + + printf("V=%u, mask=%u\n", + (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8, + v->field_value[PROTO_FIELD_IPV4].mask_range.u8); + return 0; +} + +/* + * The format for these rules DO NOT need the port ranges to be + * separated by ' : ', just ':'. It's a lot more readable and + * cleaner, IMO. + */ +char lines[][128] = { + "@0.0.0.0/0 0.0.0.0/0 0:65535 0:65535 2/0xff", /* Protocol check */ + "@192.168.3.1/32 0.0.0.0/0 0:65535 0:65535 0/0", /* Src IP checl */ + "@0.0.0.0/0 10.4.4.1/32 0:65535 0:65535 0/0", /* dst IP check */ + "@0.0.0.0/0 0.0.0.0/0 105:105 0:65535 0/0", /* src port check */ + "@0.0.0.0/0 0.0.0.0/0 0:65535 206:206 0/0", /* dst port check */ +}; + +char line[128]; + + +static int +setup_acl_pipeline(void) +{ + int ret; + int i; + struct rte_pipeline_params pipeline_params = { + .name = "PIPELINE", + .socket_id = 0, + }; + uint32_t n; + struct rte_table_acl_rule_add_params rule_params; + struct rte_pipeline_table_acl_rule_delete_params *delete_params; + parse_5tuple parser; + char acl_name[64]; + + /* Pipeline configuration */ + p = rte_pipeline_create(&pipeline_params); + if (p == NULL) { + RTE_LOG(INFO, PIPELINE, "%s: Failed to configure pipeline\n", + __func__); + goto fail; + } + + /* Input port configuration */ + for (i = 0; i < N_PORTS; i++) { + struct rte_port_ring_reader_params port_ring_params = { + .ring = rings_rx[i], + }; + + struct rte_pipeline_port_in_params port_params = { + .ops = &rte_port_ring_reader_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .burst_size = BURST_SIZE, + }; + + /* Put in action for some ports */ + if (i) + port_params.f_action = port_in_action; + + ret = rte_pipeline_port_in_create(p, &port_params, + &port_in_id[i]); + if (ret) { + rte_panic("Unable to configure input port %d, ret:%d\n", + i, ret); + goto fail; + } + } + + /* output Port configuration */ + for (i = 0; i < N_PORTS; i++) { + struct rte_port_ring_writer_params port_ring_params = { + .ring = rings_tx[i], + .tx_burst_sz = BURST_SIZE, + }; + + struct rte_pipeline_port_out_params port_params = { + .ops = &rte_port_ring_writer_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + }; + + + if (rte_pipeline_port_out_create(p, &port_params, + &port_out_id[i])) { + rte_panic("Unable to configure output port %d\n", i); + goto fail; + } + } + + /* Table configuration */ + for (i = 0; i < N_PORTS; i++) { + struct rte_pipeline_table_params table_params; + + /* Set up defaults for stub */ + table_params.ops = &rte_table_stub_ops; + table_params.arg_create = NULL; + table_params.f_action_hit = action_handler_hit; + table_params.f_action_miss = NULL; + table_params.action_data_size = 0; + + RTE_LOG(INFO, PIPELINE, "miss_action=%x\n", + table_entry_miss_action); + + printf("RTE_ACL_RULE_SZ(%zu) = %zu\n", DIM(ipv4_defs), + RTE_ACL_RULE_SZ(DIM(ipv4_defs))); + + struct rte_table_acl_params acl_params; + + acl_params.n_rules = 1 << 5; + acl_params.n_rule_fields = DIM(ipv4_defs); + snprintf(acl_name, sizeof(acl_name), "ACL%d", i); + acl_params.name = acl_name; + memcpy(acl_params.field_format, ipv4_defs, sizeof(ipv4_defs)); + + table_params.ops = &rte_table_acl_ops; + table_params.arg_create = &acl_params; + + if (rte_pipeline_table_create(p, &table_params, &table_id[i])) { + rte_panic("Unable to configure table %u\n", i); + goto fail; + } + + if (connect_miss_action_to_table) { + if (rte_pipeline_table_create(p, &table_params, + &table_id[i+2])) { + rte_panic("Unable to configure table %u\n", i); + goto fail; + } + } + } + + for (i = 0; i < N_PORTS; i++) { + if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], + table_id[i])) { + rte_panic("Unable to connect input port %u to " + "table %u\n", + port_in_id[i], table_id[i]); + goto fail; + } + } + + /* Add bulk entries to tables */ + for (i = 0; i < N_PORTS; i++) { + struct rte_table_acl_rule_add_params keys[5]; + struct rte_pipeline_table_entry entries[5]; + struct rte_table_acl_rule_add_params *key_array[5]; + struct rte_pipeline_table_entry *table_entries[5]; + int key_found[5]; + struct rte_pipeline_table_entry *table_entries_ptr[5]; + struct rte_pipeline_table_entry entries_ptr[5]; + + parser = parse_cb_ipv4_rule; + for (n = 0; n < 5; n++) { + memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params)); + key_array[n] = &keys[n]; + + snprintf(line, sizeof(line), "%s", lines[n]); + printf("PARSING [%s]\n", line); + + ret = parser(line, &keys[n]); + if (ret != 0) { + RTE_LOG(ERR, PIPELINE, + "line %u: parse_cb_ipv4vlan_rule" + " failed, error code: %d (%s)\n", + n, ret, strerror(-ret)); + return ret; + } + + keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1; + + entries[n].action = RTE_PIPELINE_ACTION_PORT; + entries[n].port_id = port_out_id[i^1]; + table_entries[n] = &entries[n]; + table_entries_ptr[n] = &entries_ptr[n]; + } + + ret = rte_pipeline_table_entry_add_bulk(p, table_id[i], + (void **)key_array, table_entries, 5, key_found, table_entries_ptr); + if (ret < 0) { + rte_panic("Add entry bulk to table %u failed (%d)\n", + table_id[i], ret); + goto fail; + } + } + + /* Delete bulk entries from tables */ + for (i = 0; i < N_PORTS; i++) { + struct rte_table_acl_rule_delete_params keys[5]; + struct rte_table_acl_rule_delete_params *key_array[5]; + struct rte_pipeline_table_entry *table_entries[5]; + int key_found[5]; + + for (n = 0; n < 5; n++) { + memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params)); + key_array[n] = &keys[n]; + + snprintf(line, sizeof(line), "%s", lines[n]); + printf("PARSING [%s]\n", line); + + ret = parse_cb_ipv4_rule_del(line, &keys[n]); + if (ret != 0) { + RTE_LOG(ERR, PIPELINE, + "line %u: parse_cb_ipv4vlan_rule" + " failed, error code: %d (%s)\n", + n, ret, strerror(-ret)); + return ret; + } + } + + ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i], + (void **)key_array, 5, key_found, table_entries); + if (ret < 0) { + rte_panic("Delete bulk entries from table %u failed (%d)\n", + table_id[i], ret); + goto fail; + } else + printf("Bulk deleted rules.\n"); + } + + /* Add entries to tables */ + for (i = 0; i < N_PORTS; i++) { + struct rte_pipeline_table_entry table_entry = { + .action = RTE_PIPELINE_ACTION_PORT, + {.port_id = port_out_id[i^1]}, + }; + int key_found; + struct rte_pipeline_table_entry *entry_ptr; + + memset(&rule_params, 0, sizeof(rule_params)); + parser = parse_cb_ipv4_rule; + + for (n = 1; n <= 5; n++) { + snprintf(line, sizeof(line), "%s", lines[n-1]); + printf("PARSING [%s]\n", line); + + ret = parser(line, &rule_params); + if (ret != 0) { + RTE_LOG(ERR, PIPELINE, + "line %u: parse_cb_ipv4vlan_rule" + " failed, error code: %d (%s)\n", + n, ret, strerror(-ret)); + return ret; + } + + rule_params.priority = RTE_ACL_MAX_PRIORITY - n; + + ret = rte_pipeline_table_entry_add(p, table_id[i], + &rule_params, + &table_entry, &key_found, &entry_ptr); + if (ret < 0) { + rte_panic("Add entry to table %u failed (%d)\n", + table_id[i], ret); + goto fail; + } + } + + /* delete a few rules */ + for (n = 2; n <= 3; n++) { + snprintf(line, sizeof(line), "%s", lines[n-1]); + printf("PARSING [%s]\n", line); + + ret = parser(line, &rule_params); + if (ret != 0) { + RTE_LOG(ERR, PIPELINE, "line %u: parse rule " + " failed, error code: %d (%s)\n", + n, ret, strerror(-ret)); + return ret; + } + + delete_params = (struct + rte_pipeline_table_acl_rule_delete_params *) + &(rule_params.field_value[0]); + ret = rte_pipeline_table_entry_delete(p, table_id[i], + delete_params, &key_found, NULL); + if (ret < 0) { + rte_panic("Add entry to table %u failed (%d)\n", + table_id[i], ret); + goto fail; + } else + printf("Deleted Rule.\n"); + } + + + /* Try to add duplicates */ + for (n = 1; n <= 5; n++) { + snprintf(line, sizeof(line), "%s", lines[n-1]); + printf("PARSING [%s]\n", line); + + ret = parser(line, &rule_params); + if (ret != 0) { + RTE_LOG(ERR, PIPELINE, "line %u: parse rule" + " failed, error code: %d (%s)\n", + n, ret, strerror(-ret)); + return ret; + } + + rule_params.priority = RTE_ACL_MAX_PRIORITY - n; + + ret = rte_pipeline_table_entry_add(p, table_id[i], + &rule_params, + &table_entry, &key_found, &entry_ptr); + if (ret < 0) { + rte_panic("Add entry to table %u failed (%d)\n", + table_id[i], ret); + goto fail; + } + } + } + + /* Enable input ports */ + for (i = 0; i < N_PORTS ; i++) + if (rte_pipeline_port_in_enable(p, port_in_id[i])) + rte_panic("Unable to enable input port %u\n", + port_in_id[i]); + + /* Check pipeline consistency */ + if (rte_pipeline_check(p) < 0) { + rte_panic("Pipeline consistency check failed\n"); + goto fail; + } + + return 0; +fail: + + return -1; +} + +static int +test_pipeline_single_filter(int expected_count) +{ + int i, j, ret, tx_count; + struct ipv4_5tuple five_tuple; + + /* Allocate a few mbufs and manually insert into the rings. */ + for (i = 0; i < N_PORTS; i++) { + for (j = 0; j < 8; j++) { + struct rte_mbuf *mbuf; + + mbuf = rte_pktmbuf_alloc(pool); + if (mbuf == NULL) + /* this will cause test failure after cleanup + * of already enqueued mbufs, as the mbuf + * counts won't match */ + break; + memset(rte_pktmbuf_mtod(mbuf, char *), 0x00, + sizeof(struct ipv4_5tuple)); + + five_tuple.proto = j; + five_tuple.ip_src = rte_bswap32(IPv4(192, 168, j, 1)); + five_tuple.ip_dst = rte_bswap32(IPv4(10, 4, j, 1)); + five_tuple.port_src = rte_bswap16(100 + j); + five_tuple.port_dst = rte_bswap16(200 + j); + + memcpy(rte_pktmbuf_mtod(mbuf, char *), &five_tuple, + sizeof(struct ipv4_5tuple)); + RTE_LOG(INFO, PIPELINE, "%s: Enqueue onto ring %d\n", + __func__, i); + rte_ring_enqueue(rings_rx[i], mbuf); + } + } + + /* Run pipeline once */ + for (i = 0; i< N_PORTS; i++) + rte_pipeline_run(p); + + rte_pipeline_flush(p); + + tx_count = 0; + + for (i = 0; i < N_PORTS; i++) { + void *objs[RING_TX_SIZE]; + struct rte_mbuf *mbuf; + + ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10); + if (ret <= 0) { + printf("Got no objects from ring %d - error code %d\n", + i, ret); + } else { + printf("Got %d object(s) from ring %d!\n", ret, i); + for (j = 0; j < ret; j++) { + mbuf = (struct rte_mbuf *)objs[j]; + rte_hexdump(stdout, "mbuf", + rte_pktmbuf_mtod(mbuf, char *), 64); + rte_pktmbuf_free(mbuf); + } + tx_count += ret; + } + } + + if (tx_count != expected_count) { + RTE_LOG(INFO, PIPELINE, + "%s: Unexpected packets for ACL test, " + "expected %d, got %d\n", + __func__, expected_count, tx_count); + goto fail; + } + + rte_pipeline_free(p); + + return 0; +fail: + return -1; + +} + +int +test_table_acl(void) +{ + + + override_hit_mask = 0xFF; /* All packets are a hit */ + + setup_acl_pipeline(); + if (test_pipeline_single_filter(10) < 0) + return -1; + + return 0; +} diff --git a/test/test/test_table_acl.h b/test/test/test_table_acl.h new file mode 100644 index 0000000000..a64c3e6cb0 --- /dev/null +++ b/test/test/test_table_acl.h @@ -0,0 +1,35 @@ +/*- + * 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. + */ + +/* Test prototypes */ +int test_table_acl(void); diff --git a/test/test/test_table_combined.c b/test/test/test_table_combined.c new file mode 100644 index 0000000000..a2d19a1a23 --- /dev/null +++ b/test/test/test_table_combined.c @@ -0,0 +1,881 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include "test_table_combined.h" +#include "test_table.h" +#include + +#define MAX_TEST_KEYS 128 +#define N_PACKETS 50 + +enum check_table_result { + CHECK_TABLE_OK, + CHECK_TABLE_PORT_CONFIG, + CHECK_TABLE_PORT_ENABLE, + CHECK_TABLE_TABLE_CONFIG, + CHECK_TABLE_ENTRY_ADD, + CHECK_TABLE_DEFAULT_ENTRY_ADD, + CHECK_TABLE_CONNECT, + CHECK_TABLE_MANAGE_ERROR, + CHECK_TABLE_CONSISTENCY, + CHECK_TABLE_NO_TRAFFIC, + CHECK_TABLE_INVALID_PARAMETER, +}; + +struct table_packets { + uint32_t hit_packet[MAX_TEST_KEYS]; + uint32_t miss_packet[MAX_TEST_KEYS]; + uint32_t n_hit_packets; + uint32_t n_miss_packets; +}; + +combined_table_test table_tests_combined[] = { + test_table_lpm_combined, + test_table_lpm_ipv6_combined, + test_table_hash8lru, + test_table_hash8ext, + test_table_hash16lru, + test_table_hash16ext, + test_table_hash32lru, + test_table_hash32ext, + test_table_hash_cuckoo_combined, +}; + +unsigned n_table_tests_combined = RTE_DIM(table_tests_combined); + +/* Generic port tester function */ +static int +test_table_type(struct rte_table_ops *table_ops, void *table_args, + void *key, struct table_packets *table_packets, + struct manage_ops *manage_ops, unsigned n_ops) +{ + uint32_t ring_in_id, table_id, ring_out_id, ring_out_2_id; + unsigned i; + + RTE_SET_USED(manage_ops); + RTE_SET_USED(n_ops); + /* Create pipeline */ + struct rte_pipeline_params pipeline_params = { + .name = "pipeline", + .socket_id = 0, + }; + + struct rte_pipeline *pipeline = rte_pipeline_create(&pipeline_params); + + /* Create input ring */ + struct rte_port_ring_reader_params ring_params_rx = { + .ring = RING_RX, + }; + + struct rte_port_ring_writer_params ring_params_tx = { + .ring = RING_RX, + .tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX, + }; + + struct rte_pipeline_port_in_params ring_in_params = { + .ops = &rte_port_ring_reader_ops, + .arg_create = (void *)&ring_params_rx, + .f_action = NULL, + .burst_size = RTE_PORT_IN_BURST_SIZE_MAX, + }; + + if (rte_pipeline_port_in_create(pipeline, &ring_in_params, + &ring_in_id) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_PORT_CONFIG; + } + + /* Create table */ + struct rte_pipeline_table_params table_params = { + .ops = table_ops, + .arg_create = table_args, + .f_action_hit = NULL, + .f_action_miss = NULL, + .arg_ah = NULL, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(pipeline, &table_params, + &table_id) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_TABLE_CONFIG; + } + + /* Create output ports */ + ring_params_tx.ring = RING_TX; + + struct rte_pipeline_port_out_params ring_out_params = { + .ops = &rte_port_ring_writer_ops, + .arg_create = (void *)&ring_params_tx, + .f_action = NULL, + }; + + if (rte_pipeline_port_out_create(pipeline, &ring_out_params, + &ring_out_id) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_PORT_CONFIG; + } + + ring_params_tx.ring = RING_TX_2; + + if (rte_pipeline_port_out_create(pipeline, &ring_out_params, + &ring_out_2_id) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_PORT_CONFIG; + } + + /* Add entry to the table */ + struct rte_pipeline_table_entry default_entry = { + .action = RTE_PIPELINE_ACTION_DROP, + {.table_id = ring_out_id}, + }; + + struct rte_pipeline_table_entry table_entry = { + .action = RTE_PIPELINE_ACTION_PORT, + {.table_id = ring_out_id}, + }; + + struct rte_pipeline_table_entry *default_entry_ptr, *entry_ptr; + + int key_found; + + if (rte_pipeline_table_default_entry_add(pipeline, table_id, + &default_entry, &default_entry_ptr) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_DEFAULT_ENTRY_ADD; + } + + if (rte_pipeline_table_entry_add(pipeline, table_id, + key ? key : &table_entry, &table_entry, &key_found, + &entry_ptr) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_ENTRY_ADD; + } + + /* Create connections and check consistency */ + if (rte_pipeline_port_in_connect_to_table(pipeline, ring_in_id, + table_id) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_CONNECT; + } + + if (rte_pipeline_port_in_enable(pipeline, ring_in_id) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_PORT_ENABLE; + } + + if (rte_pipeline_check(pipeline) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_CONSISTENCY; + } + + + + /* Flow test - All hits */ + if (table_packets->n_hit_packets) { + for (i = 0; i < table_packets->n_hit_packets; i++) + RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]); + + RUN_PIPELINE(pipeline); + + VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, + table_packets->n_hit_packets); + } + + /* Flow test - All misses */ + if (table_packets->n_miss_packets) { + for (i = 0; i < table_packets->n_miss_packets; i++) + RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]); + + RUN_PIPELINE(pipeline); + + VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0); + } + + /* Flow test - Half hits, half misses */ + if (table_packets->n_hit_packets && table_packets->n_miss_packets) { + for (i = 0; i < (table_packets->n_hit_packets) / 2; i++) + RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]); + + for (i = 0; i < (table_packets->n_miss_packets) / 2; i++) + RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]); + + RUN_PIPELINE(pipeline); + VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, + table_packets->n_hit_packets / 2); + } + + /* Flow test - Single packet */ + if (table_packets->n_hit_packets) { + RING_ENQUEUE(RING_RX, table_packets->hit_packet[0]); + RUN_PIPELINE(pipeline); + VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 1); + } + if (table_packets->n_miss_packets) { + RING_ENQUEUE(RING_RX, table_packets->miss_packet[0]); + RUN_PIPELINE(pipeline); + VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0); + } + + + /* Change table entry action */ + printf("Change entry action\n"); + table_entry.table_id = ring_out_2_id; + + if (rte_pipeline_table_default_entry_add(pipeline, table_id, + &default_entry, &default_entry_ptr) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_ENTRY_ADD; + } + + if (rte_pipeline_table_entry_add(pipeline, table_id, + key ? key : &table_entry, &table_entry, &key_found, + &entry_ptr) != 0) { + rte_pipeline_free(pipeline); + return -CHECK_TABLE_ENTRY_ADD; + } + + /* Check that traffic destination has changed */ + if (table_packets->n_hit_packets) { + for (i = 0; i < table_packets->n_hit_packets; i++) + RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]); + + RUN_PIPELINE(pipeline); + VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 0); + VERIFY_TRAFFIC(RING_TX_2, table_packets->n_hit_packets, + table_packets->n_hit_packets); + } + + printf("delete entry\n"); + /* Delete table entry */ + rte_pipeline_table_entry_delete(pipeline, table_id, + key ? key : &table_entry, &key_found, NULL); + + rte_pipeline_free(pipeline); + + return 0; +} + +/* Table tests */ +int +test_table_stub_combined(void) +{ + int status, i; + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < N_PACKETS; i++) + table_packets.hit_packet[i] = i; + + table_packets.n_hit_packets = N_PACKETS; + table_packets.n_miss_packets = 0; + + status = test_table_type(&rte_table_stub_ops, NULL, NULL, + &table_packets, NULL, 1); + VERIFY(status, CHECK_TABLE_OK); + + return 0; +} + +int +test_table_lpm_combined(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_lpm_params lpm_params = { + .name = "LPM", + .n_rules = 1 << 16, + .number_tbl8s = 1 << 8, + .flags = 0, + .entry_unique_size = 8, + .offset = APP_METADATA_OFFSET(0), + }; + + struct rte_table_lpm_key lpm_key = { + .ip = 0xadadadad, + .depth = 16, + }; + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + + for (i = 0; i < N_PACKETS; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < N_PACKETS; i++) + table_packets.miss_packet[i] = 0xfefefefe; + + table_packets.n_hit_packets = N_PACKETS; + table_packets.n_miss_packets = N_PACKETS; + + status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params, + (void *)&lpm_key, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + lpm_params.n_rules = 0; + + status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params, + (void *)&lpm_key, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + lpm_params.n_rules = 1 << 24; + lpm_key.depth = 0; + + status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params, + (void *)&lpm_key, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_ENTRY_ADD); + + lpm_key.depth = 33; + + status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params, + (void *)&lpm_key, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_ENTRY_ADD); + + return 0; +} + +int +test_table_lpm_ipv6_combined(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_lpm_ipv6_params lpm_ipv6_params = { + .name = "LPM", + .n_rules = 1 << 16, + .number_tbl8s = 1 << 13, + .entry_unique_size = 8, + .offset = APP_METADATA_OFFSET(32), + }; + + struct rte_table_lpm_ipv6_key lpm_ipv6_key = { + .depth = 16, + }; + memset(lpm_ipv6_key.ip, 0xad, 16); + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < N_PACKETS; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < N_PACKETS; i++) + table_packets.miss_packet[i] = 0xadadadab; + + table_packets.n_hit_packets = N_PACKETS; + table_packets.n_miss_packets = N_PACKETS; + + status = test_table_type(&rte_table_lpm_ipv6_ops, + (void *)&lpm_ipv6_params, + (void *)&lpm_ipv6_key, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + lpm_ipv6_params.n_rules = 0; + + status = test_table_type(&rte_table_lpm_ipv6_ops, + (void *)&lpm_ipv6_params, + (void *)&lpm_ipv6_key, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + lpm_ipv6_params.n_rules = 1 << 24; + lpm_ipv6_key.depth = 0; + + status = test_table_type(&rte_table_lpm_ipv6_ops, + (void *)&lpm_ipv6_params, + (void *)&lpm_ipv6_key, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_ENTRY_ADD); + + lpm_ipv6_key.depth = 129; + status = test_table_type(&rte_table_lpm_ipv6_ops, + (void *)&lpm_ipv6_params, + (void *)&lpm_ipv6_key, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_ENTRY_ADD); + + return 0; +} + +int +test_table_hash8lru(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_key8_lru_params key8lru_params = { + .n_entries = 1<<24, + .f_hash = pipeline_test_hash, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + }; + + uint8_t key8lru[8]; + uint32_t *k8lru = (uint32_t *) key8lru; + + memset(key8lru, 0, sizeof(key8lru)); + k8lru[0] = 0xadadadad; + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < 50; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < 50; i++) + table_packets.miss_packet[i] = 0xfefefefe; + + table_packets.n_hit_packets = 50; + table_packets.n_miss_packets = 50; + + status = test_table_type(&rte_table_hash_key8_lru_ops, + (void *)&key8lru_params, (void *)key8lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + key8lru_params.n_entries = 0; + + status = test_table_type(&rte_table_hash_key8_lru_ops, + (void *)&key8lru_params, (void *)key8lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key8lru_params.n_entries = 1<<16; + key8lru_params.f_hash = NULL; + + status = test_table_type(&rte_table_hash_key8_lru_ops, + (void *)&key8lru_params, (void *)key8lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + return 0; +} + +int +test_table_hash16lru(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_key16_lru_params key16lru_params = { + .n_entries = 1<<16, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + }; + + uint8_t key16lru[16]; + uint32_t *k16lru = (uint32_t *) key16lru; + + memset(key16lru, 0, sizeof(key16lru)); + k16lru[0] = 0xadadadad; + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < 50; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < 50; i++) + table_packets.miss_packet[i] = 0xfefefefe; + + table_packets.n_hit_packets = 50; + table_packets.n_miss_packets = 50; + + status = test_table_type(&rte_table_hash_key16_lru_ops, + (void *)&key16lru_params, (void *)key16lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + key16lru_params.n_entries = 0; + + status = test_table_type(&rte_table_hash_key16_lru_ops, + (void *)&key16lru_params, (void *)key16lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key16lru_params.n_entries = 1<<16; + key16lru_params.f_hash = NULL; + + status = test_table_type(&rte_table_hash_key16_lru_ops, + (void *)&key16lru_params, (void *)key16lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + return 0; +} + +int +test_table_hash32lru(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_key32_lru_params key32lru_params = { + .n_entries = 1<<16, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + }; + + uint8_t key32lru[32]; + uint32_t *k32lru = (uint32_t *) key32lru; + + memset(key32lru, 0, sizeof(key32lru)); + k32lru[0] = 0xadadadad; + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < 50; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < 50; i++) + table_packets.miss_packet[i] = 0xbdadadad; + + table_packets.n_hit_packets = 50; + table_packets.n_miss_packets = 50; + + status = test_table_type(&rte_table_hash_key32_lru_ops, + (void *)&key32lru_params, (void *)key32lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + key32lru_params.n_entries = 0; + + status = test_table_type(&rte_table_hash_key32_lru_ops, + (void *)&key32lru_params, (void *)key32lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key32lru_params.n_entries = 1<<16; + key32lru_params.f_hash = NULL; + + status = test_table_type(&rte_table_hash_key32_lru_ops, + (void *)&key32lru_params, (void *)key32lru, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + return 0; +} + +int +test_table_hash8ext(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_key8_ext_params key8ext_params = { + .n_entries = 1<<16, + .n_entries_ext = 1<<15, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + }; + + uint8_t key8ext[8]; + uint32_t *k8ext = (uint32_t *) key8ext; + + memset(key8ext, 0, sizeof(key8ext)); + k8ext[0] = 0xadadadad; + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < 50; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < 50; i++) + table_packets.miss_packet[i] = 0xbdadadad; + + table_packets.n_hit_packets = 50; + table_packets.n_miss_packets = 50; + + status = test_table_type(&rte_table_hash_key8_ext_ops, + (void *)&key8ext_params, (void *)key8ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + key8ext_params.n_entries = 0; + + status = test_table_type(&rte_table_hash_key8_ext_ops, + (void *)&key8ext_params, (void *)key8ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key8ext_params.n_entries = 1<<16; + key8ext_params.f_hash = NULL; + + status = test_table_type(&rte_table_hash_key8_ext_ops, + (void *)&key8ext_params, (void *)key8ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key8ext_params.f_hash = pipeline_test_hash; + key8ext_params.n_entries_ext = 0; + + status = test_table_type(&rte_table_hash_key8_ext_ops, + (void *)&key8ext_params, (void *)key8ext, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + return 0; +} + +int +test_table_hash16ext(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_key16_ext_params key16ext_params = { + .n_entries = 1<<16, + .n_entries_ext = 1<<15, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + }; + + uint8_t key16ext[16]; + uint32_t *k16ext = (uint32_t *) key16ext; + + memset(key16ext, 0, sizeof(key16ext)); + k16ext[0] = 0xadadadad; + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < 50; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < 50; i++) + table_packets.miss_packet[i] = 0xbdadadad; + + table_packets.n_hit_packets = 50; + table_packets.n_miss_packets = 50; + + status = test_table_type(&rte_table_hash_key16_ext_ops, + (void *)&key16ext_params, (void *)key16ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + key16ext_params.n_entries = 0; + + status = test_table_type(&rte_table_hash_key16_ext_ops, + (void *)&key16ext_params, (void *)key16ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key16ext_params.n_entries = 1<<16; + key16ext_params.f_hash = NULL; + + status = test_table_type(&rte_table_hash_key16_ext_ops, + (void *)&key16ext_params, (void *)key16ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key16ext_params.f_hash = pipeline_test_hash; + key16ext_params.n_entries_ext = 0; + + status = test_table_type(&rte_table_hash_key16_ext_ops, + (void *)&key16ext_params, (void *)key16ext, &table_packets, NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + return 0; +} + +int +test_table_hash32ext(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_key32_ext_params key32ext_params = { + .n_entries = 1<<16, + .n_entries_ext = 1<<15, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + }; + + uint8_t key32ext[32]; + uint32_t *k32ext = (uint32_t *) key32ext; + + memset(key32ext, 0, sizeof(key32ext)); + k32ext[0] = 0xadadadad; + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < 50; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < 50; i++) + table_packets.miss_packet[i] = 0xbdadadad; + + table_packets.n_hit_packets = 50; + table_packets.n_miss_packets = 50; + + status = test_table_type(&rte_table_hash_key32_ext_ops, + (void *)&key32ext_params, (void *)key32ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + key32ext_params.n_entries = 0; + + status = test_table_type(&rte_table_hash_key32_ext_ops, + (void *)&key32ext_params, (void *)key32ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key32ext_params.n_entries = 1<<16; + key32ext_params.f_hash = NULL; + + status = test_table_type(&rte_table_hash_key32_ext_ops, + (void *)&key32ext_params, (void *)key32ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + key32ext_params.f_hash = pipeline_test_hash; + key32ext_params.n_entries_ext = 0; + + status = test_table_type(&rte_table_hash_key32_ext_ops, + (void *)&key32ext_params, (void *)key32ext, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + return 0; +} + +int +test_table_hash_cuckoo_combined(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_cuckoo_params cuckoo_params = { + .key_size = 32, + .n_keys = 1<<16, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .name = "CUCKOO_HASH", + }; + + uint8_t key_cuckoo[32]; + uint32_t *kcuckoo = (uint32_t *) key_cuckoo; + + memset(key_cuckoo, 0, sizeof(key_cuckoo)); + kcuckoo[0] = 0xadadadad; + + struct table_packets table_packets; + + printf("--------------\n"); + printf("RUNNING TEST - %s\n", __func__); + printf("--------------\n"); + for (i = 0; i < 50; i++) + table_packets.hit_packet[i] = 0xadadadad; + + for (i = 0; i < 50; i++) + table_packets.miss_packet[i] = 0xbdadadad; + + table_packets.n_hit_packets = 50; + table_packets.n_miss_packets = 50; + + status = test_table_type(&rte_table_hash_cuckoo_dosig_ops, + (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_OK); + + /* Invalid parameters */ + cuckoo_params.key_size = 0; + + status = test_table_type(&rte_table_hash_cuckoo_dosig_ops, + (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + cuckoo_params.key_size = 32; + cuckoo_params.n_keys = 0; + + status = test_table_type(&rte_table_hash_cuckoo_dosig_ops, + (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + cuckoo_params.n_keys = 1<<16; + cuckoo_params.f_hash = NULL; + + status = test_table_type(&rte_table_hash_cuckoo_dosig_ops, + (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets, + NULL, 0); + VERIFY(status, CHECK_TABLE_TABLE_CONFIG); + + return 0; +} + diff --git a/test/test/test_table_combined.h b/test/test/test_table_combined.h new file mode 100644 index 0000000000..e1619f9258 --- /dev/null +++ b/test/test/test_table_combined.h @@ -0,0 +1,56 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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. + */ + +/* Test prototypes */ +int test_table_stub_combined(void); +int test_table_lpm_combined(void); +int test_table_lpm_ipv6_combined(void); +#ifdef RTE_LIBRTE_ACL +int test_table_acl(void); +#endif +int test_table_hash8unoptimized(void); +int test_table_hash8lru(void); +int test_table_hash8ext(void); +int test_table_hash16unoptimized(void); +int test_table_hash16lru(void); +int test_table_hash16ext(void); +int test_table_hash32unoptimized(void); +int test_table_hash32lru(void); +int test_table_hash32ext(void); +int test_table_hash_cuckoo_combined(void); + +/* Extern variables */ +typedef int (*combined_table_test)(void); + +extern combined_table_test table_tests_combined[]; +extern unsigned n_table_tests_combined; diff --git a/test/test/test_table_pipeline.c b/test/test/test_table_pipeline.c new file mode 100644 index 0000000000..36bfeda3d8 --- /dev/null +++ b/test/test/test_table_pipeline.c @@ -0,0 +1,600 @@ +/*- + * 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 +#include +#include +#include +#include +#include "test_table.h" +#include "test_table_pipeline.h" + +#if 0 + +static rte_pipeline_port_out_action_handler port_action_0x00 + (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg); +static rte_pipeline_port_out_action_handler port_action_0xFF + (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg); +static rte_pipeline_port_out_action_handler port_action_stub + (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg); + + +rte_pipeline_port_out_action_handler port_action_0x00(struct rte_mbuf **pkts, + uint32_t n, + uint64_t *pkts_mask, + void *arg) +{ + RTE_SET_USED(pkts); + RTE_SET_USED(n); + RTE_SET_USED(arg); + printf("Port Action 0x00\n"); + *pkts_mask = 0x00; + return 0; +} + +rte_pipeline_port_out_action_handler port_action_0xFF(struct rte_mbuf **pkts, + uint32_t n, + uint64_t *pkts_mask, + void *arg) +{ + RTE_SET_USED(pkts); + RTE_SET_USED(n); + RTE_SET_USED(arg); + printf("Port Action 0xFF\n"); + *pkts_mask = 0xFF; + return 0; +} + +rte_pipeline_port_out_action_handler port_action_stub(struct rte_mbuf **pkts, + uint32_t n, + uint64_t *pkts_mask, + void *arg) +{ + RTE_SET_USED(pkts); + RTE_SET_USED(n); + RTE_SET_USED(pkts_mask); + RTE_SET_USED(arg); + printf("Port Action stub\n"); + return 0; +} + +#endif + +rte_pipeline_table_action_handler_hit +table_action_0x00(struct rte_pipeline *p, struct rte_mbuf **pkts, + uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg); + +rte_pipeline_table_action_handler_hit +table_action_stub_hit(struct rte_pipeline *p, struct rte_mbuf **pkts, + uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg); + +rte_pipeline_table_action_handler_miss +table_action_stub_miss(struct rte_pipeline *p, struct rte_mbuf **pkts, + uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg); + +rte_pipeline_table_action_handler_hit +table_action_0x00(__attribute__((unused)) struct rte_pipeline *p, + __attribute__((unused)) struct rte_mbuf **pkts, + uint64_t pkts_mask, + __attribute__((unused)) struct rte_pipeline_table_entry **entry, + __attribute__((unused)) void *arg) +{ + printf("Table Action, setting pkts_mask to 0x00\n"); + pkts_mask = ~0x00; + rte_pipeline_ah_packet_drop(p, pkts_mask); + return 0; +} + +rte_pipeline_table_action_handler_hit +table_action_stub_hit(__attribute__((unused)) struct rte_pipeline *p, + __attribute__((unused)) struct rte_mbuf **pkts, + uint64_t pkts_mask, + __attribute__((unused)) struct rte_pipeline_table_entry **entry, + __attribute__((unused)) void *arg) +{ + printf("STUB Table Action Hit - doing nothing\n"); + printf("STUB Table Action Hit - setting mask to 0x%"PRIx64"\n", + override_hit_mask); + pkts_mask = (~override_hit_mask) & 0x3; + rte_pipeline_ah_packet_drop(p, pkts_mask); + return 0; +} + +rte_pipeline_table_action_handler_miss +table_action_stub_miss(struct rte_pipeline *p, + __attribute__((unused)) struct rte_mbuf **pkts, + uint64_t pkts_mask, + __attribute__((unused)) struct rte_pipeline_table_entry **entry, + __attribute__((unused)) void *arg) +{ + printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n", + override_miss_mask); + pkts_mask = (~override_miss_mask) & 0x3; + rte_pipeline_ah_packet_drop(p, pkts_mask); + return 0; +} + +enum e_test_type { + e_TEST_STUB = 0, + e_TEST_LPM, + e_TEST_LPM6, + e_TEST_HASH_LRU_8, + e_TEST_HASH_LRU_16, + e_TEST_HASH_LRU_32, + e_TEST_HASH_EXT_8, + e_TEST_HASH_EXT_16, + e_TEST_HASH_EXT_32 +}; + +char pipeline_test_names[][64] = { + "Stub", + "LPM", + "LPMv6", + "8-bit LRU Hash", + "16-bit LRU Hash", + "32-bit LRU Hash", + "16-bit Ext Hash", + "8-bit Ext Hash", + "32-bit Ext Hash", + "" +}; + + +static int +cleanup_pipeline(void) +{ + + rte_pipeline_free(p); + + return 0; +} + + +static int check_pipeline_invalid_params(void); + +static int +check_pipeline_invalid_params(void) +{ + struct rte_pipeline_params pipeline_params_1 = { + .name = NULL, + .socket_id = 0, + }; + struct rte_pipeline_params pipeline_params_2 = { + .name = "PIPELINE", + .socket_id = -1, + }; + struct rte_pipeline_params pipeline_params_3 = { + .name = "PIPELINE", + .socket_id = 127, + }; + + p = rte_pipeline_create(NULL); + if (p != NULL) { + RTE_LOG(INFO, PIPELINE, + "%s: configured pipeline with null params\n", + __func__); + goto fail; + } + p = rte_pipeline_create(&pipeline_params_1); + if (p != NULL) { + RTE_LOG(INFO, PIPELINE, "%s: Configure pipeline with NULL " + "name\n", __func__); + goto fail; + } + + p = rte_pipeline_create(&pipeline_params_2); + if (p != NULL) { + RTE_LOG(INFO, PIPELINE, "%s: Configure pipeline with invalid " + "socket\n", __func__); + goto fail; + } + + p = rte_pipeline_create(&pipeline_params_3); + if (p != NULL) { + RTE_LOG(INFO, PIPELINE, "%s: Configure pipeline with invalid " + "socket\n", __func__); + goto fail; + } + + /* Check pipeline consistency */ + if (!rte_pipeline_check(p)) { + rte_panic("Pipeline consistency reported as OK\n"); + goto fail; + } + + + return 0; +fail: + return -1; +} + + +static int +setup_pipeline(int test_type) +{ + int ret; + int i; + struct rte_pipeline_params pipeline_params = { + .name = "PIPELINE", + .socket_id = 0, + }; + + RTE_LOG(INFO, PIPELINE, "%s: **** Setting up %s test\n", + __func__, pipeline_test_names[test_type]); + + /* Pipeline configuration */ + p = rte_pipeline_create(&pipeline_params); + if (p == NULL) { + RTE_LOG(INFO, PIPELINE, "%s: Failed to configure pipeline\n", + __func__); + goto fail; + } + + ret = rte_pipeline_free(p); + if (ret != 0) { + RTE_LOG(INFO, PIPELINE, "%s: Failed to free pipeline\n", + __func__); + goto fail; + } + + /* Pipeline configuration */ + p = rte_pipeline_create(&pipeline_params); + if (p == NULL) { + RTE_LOG(INFO, PIPELINE, "%s: Failed to configure pipeline\n", + __func__); + goto fail; + } + + + /* Input port configuration */ + for (i = 0; i < N_PORTS; i++) { + struct rte_port_ring_reader_params port_ring_params = { + .ring = rings_rx[i], + }; + + struct rte_pipeline_port_in_params port_params = { + .ops = &rte_port_ring_reader_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .burst_size = BURST_SIZE, + }; + + /* Put in action for some ports */ + if (i) + port_params.f_action = NULL; + + ret = rte_pipeline_port_in_create(p, &port_params, + &port_in_id[i]); + if (ret) { + rte_panic("Unable to configure input port %d, ret:%d\n", + i, ret); + goto fail; + } + } + + /* output Port configuration */ + for (i = 0; i < N_PORTS; i++) { + struct rte_port_ring_writer_params port_ring_params = { + .ring = rings_tx[i], + .tx_burst_sz = BURST_SIZE, + }; + + struct rte_pipeline_port_out_params port_params = { + .ops = &rte_port_ring_writer_ops, + .arg_create = (void *) &port_ring_params, + .f_action = NULL, + .arg_ah = NULL, + }; + + if (i) + port_params.f_action = port_out_action; + + if (rte_pipeline_port_out_create(p, &port_params, + &port_out_id[i])) { + rte_panic("Unable to configure output port %d\n", i); + goto fail; + } + } + + /* Table configuration */ + for (i = 0; i < N_PORTS; i++) { + struct rte_pipeline_table_params table_params = { + .ops = &rte_table_stub_ops, + .arg_create = NULL, + .f_action_hit = action_handler_hit, + .f_action_miss = action_handler_miss, + .action_data_size = 0, + }; + + if (rte_pipeline_table_create(p, &table_params, &table_id[i])) { + rte_panic("Unable to configure table %u\n", i); + goto fail; + } + + if (connect_miss_action_to_table) + if (rte_pipeline_table_create(p, &table_params, + &table_id[i+2])) { + rte_panic("Unable to configure table %u\n", i); + goto fail; + } + } + + for (i = 0; i < N_PORTS; i++) + if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], + table_id[i])) { + rte_panic("Unable to connect input port %u to " + "table %u\n", port_in_id[i], table_id[i]); + goto fail; + } + + /* Add entries to tables */ + for (i = 0; i < N_PORTS; i++) { + struct rte_pipeline_table_entry default_entry = { + .action = (enum rte_pipeline_action) + table_entry_default_action, + {.port_id = port_out_id[i^1]}, + }; + struct rte_pipeline_table_entry *default_entry_ptr; + + if (connect_miss_action_to_table) { + printf("Setting first table to output to next table\n"); + default_entry.action = RTE_PIPELINE_ACTION_TABLE; + default_entry.table_id = table_id[i+2]; + } + + /* Add the default action for the table. */ + ret = rte_pipeline_table_default_entry_add(p, table_id[i], + &default_entry, &default_entry_ptr); + if (ret < 0) { + rte_panic("Unable to add default entry to table %u " + "code %d\n", table_id[i], ret); + goto fail; + } else + printf("Added default entry to table id %d with " + "action %x\n", + table_id[i], default_entry.action); + + if (connect_miss_action_to_table) { + /* We create a second table so the first can pass + traffic into it */ + struct rte_pipeline_table_entry default_entry = { + .action = RTE_PIPELINE_ACTION_PORT, + {.port_id = port_out_id[i^1]}, + }; + printf("Setting secont table to output to port\n"); + + /* Add the default action for the table. */ + ret = rte_pipeline_table_default_entry_add(p, + table_id[i+2], + &default_entry, &default_entry_ptr); + if (ret < 0) { + rte_panic("Unable to add default entry to " + "table %u code %d\n", + table_id[i], ret); + goto fail; + } else + printf("Added default entry to table id %d " + "with action %x\n", + table_id[i], default_entry.action); + } + } + + /* Enable input ports */ + for (i = 0; i < N_PORTS ; i++) + if (rte_pipeline_port_in_enable(p, port_in_id[i])) + rte_panic("Unable to enable input port %u\n", + port_in_id[i]); + + /* Check pipeline consistency */ + if (rte_pipeline_check(p) < 0) { + rte_panic("Pipeline consistency check failed\n"); + goto fail; + } else + printf("Pipeline Consistency OK!\n"); + + return 0; +fail: + + return -1; +} + +static int +test_pipeline_single_filter(int test_type, int expected_count) +{ + int i; + int j; + int ret; + int tx_count; + + RTE_LOG(INFO, PIPELINE, "%s: **** Running %s test\n", + __func__, pipeline_test_names[test_type]); + /* Run pipeline once */ + for (i = 0; i < N_PORTS; i++) + rte_pipeline_run(p); + + + ret = rte_pipeline_flush(NULL); + if (ret != -EINVAL) { + RTE_LOG(INFO, PIPELINE, + "%s: No pipeline flush error NULL pipeline (%d)\n", + __func__, ret); + goto fail; + } + + /* + * Allocate a few mbufs and manually insert into the rings. */ + for (i = 0; i < N_PORTS; i++) + for (j = 0; j < N_PORTS; j++) { + struct rte_mbuf *m; + uint8_t *key; + uint32_t *k32; + + m = rte_pktmbuf_alloc(pool); + if (m == NULL) { + rte_panic("Failed to alloc mbuf from pool\n"); + return -1; + } + key = RTE_MBUF_METADATA_UINT8_PTR(m, + APP_METADATA_OFFSET(32)); + + k32 = (uint32_t *) key; + k32[0] = 0xadadadad >> (j % 2); + + RTE_LOG(INFO, PIPELINE, "%s: Enqueue onto ring %d\n", + __func__, i); + rte_ring_enqueue(rings_rx[i], m); + } + + /* Run pipeline once */ + for (i = 0; i < N_PORTS; i++) + rte_pipeline_run(p); + + /* + * need to flush the pipeline, as there may be less hits than the burst + size and they will not have been flushed to the tx rings. */ + rte_pipeline_flush(p); + + /* + * Now we'll see what we got back on the tx rings. We should see whatever + * packets we had hits on that were destined for the output ports. + */ + tx_count = 0; + + for (i = 0; i < N_PORTS; i++) { + void *objs[RING_TX_SIZE]; + struct rte_mbuf *mbuf; + + ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10); + if (ret <= 0) + printf("Got no objects from ring %d - error code %d\n", + i, ret); + else { + printf("Got %d object(s) from ring %d!\n", ret, i); + for (j = 0; j < ret; j++) { + mbuf = (struct rte_mbuf *)objs[j]; + rte_hexdump(stdout, "Object:", + rte_pktmbuf_mtod(mbuf, char *), + mbuf->data_len); + rte_pktmbuf_free(mbuf); + } + tx_count += ret; + } + } + + if (tx_count != expected_count) { + RTE_LOG(INFO, PIPELINE, + "%s: Unexpected packets out for %s test, expected %d, " + "got %d\n", __func__, pipeline_test_names[test_type], + expected_count, tx_count); + goto fail; + } + + cleanup_pipeline(); + + return 0; +fail: + return -1; + +} + +int +test_table_pipeline(void) +{ + /* TEST - All packets dropped */ + action_handler_hit = NULL; + action_handler_miss = NULL; + table_entry_default_action = RTE_PIPELINE_ACTION_DROP; + setup_pipeline(e_TEST_STUB); + if (test_pipeline_single_filter(e_TEST_STUB, 0) < 0) + return -1; + + /* TEST - All packets passed through */ + table_entry_default_action = RTE_PIPELINE_ACTION_PORT; + setup_pipeline(e_TEST_STUB); + if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0) + return -1; + + /* TEST - one packet per port */ + action_handler_hit = NULL; + action_handler_miss = + (rte_pipeline_table_action_handler_miss) table_action_stub_miss; + table_entry_default_action = RTE_PIPELINE_ACTION_PORT; + override_miss_mask = 0x01; /* one packet per port */ + setup_pipeline(e_TEST_STUB); + if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0) + return -1; + + /* TEST - one packet per port */ + override_miss_mask = 0x02; /*all per port */ + setup_pipeline(e_TEST_STUB); + if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0) + return -1; + + /* TEST - all packets per port */ + override_miss_mask = 0x03; /*all per port */ + setup_pipeline(e_TEST_STUB); + if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0) + return -1; + + /* + * This test will set up two tables in the pipeline. the first table + * will forward to another table on miss, and the second table will + * forward to port. + */ + connect_miss_action_to_table = 1; + table_entry_default_action = RTE_PIPELINE_ACTION_TABLE; + action_handler_hit = NULL; /* not for stub, hitmask always zero */ + action_handler_miss = NULL; + setup_pipeline(e_TEST_STUB); + if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0) + return -1; + connect_miss_action_to_table = 0; + + printf("TEST - two tables, hitmask override to 0x01\n"); + connect_miss_action_to_table = 1; + action_handler_miss = + (rte_pipeline_table_action_handler_miss)table_action_stub_miss; + override_miss_mask = 0x01; + setup_pipeline(e_TEST_STUB); + if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0) + return -1; + connect_miss_action_to_table = 0; + + if (check_pipeline_invalid_params()) { + RTE_LOG(INFO, PIPELINE, "%s: Check pipeline invalid params " + "failed.\n", __func__); + return -1; + } + + return 0; +} diff --git a/test/test/test_table_pipeline.h b/test/test/test_table_pipeline.h new file mode 100644 index 0000000000..b3f20ba38e --- /dev/null +++ b/test/test/test_table_pipeline.h @@ -0,0 +1,35 @@ +/*- + * 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. + */ + +/* Test prototypes */ +int test_table_pipeline(void); diff --git a/test/test/test_table_ports.c b/test/test/test_table_ports.c new file mode 100644 index 0000000000..2532367789 --- /dev/null +++ b/test/test/test_table_ports.c @@ -0,0 +1,220 @@ +/*- + * 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 "test_table_ports.h" +#include "test_table.h" + +port_test port_tests[] = { + test_port_ring_reader, + test_port_ring_writer, +}; + +unsigned n_port_tests = RTE_DIM(port_tests); + +/* Port tests */ +int +test_port_ring_reader(void) +{ + int status, i; + struct rte_port_ring_reader_params port_ring_reader_params; + void *port; + + /* Invalid params */ + port = rte_port_ring_reader_ops.f_create(NULL, 0); + if (port != NULL) + return -1; + + status = rte_port_ring_reader_ops.f_free(port); + if (status >= 0) + return -2; + + /* Create and free */ + port_ring_reader_params.ring = RING_RX; + port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0); + if (port == NULL) + return -3; + + status = rte_port_ring_reader_ops.f_free(port); + if (status != 0) + return -4; + + /* -- Traffic RX -- */ + int expected_pkts, received_pkts; + struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX]; + void *mbuf[RTE_PORT_IN_BURST_SIZE_MAX]; + + port_ring_reader_params.ring = RING_RX; + port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0); + + /* Single packet */ + mbuf[0] = (void *)rte_pktmbuf_alloc(pool); + + expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring, + mbuf, 1); + received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf, 1); + + if (received_pkts < expected_pkts) + return -5; + + rte_pktmbuf_free(res_mbuf[0]); + + /* Multiple packets */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + mbuf[i] = rte_pktmbuf_alloc(pool); + + expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring, + (void * const *) mbuf, RTE_PORT_IN_BURST_SIZE_MAX); + received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf, + RTE_PORT_IN_BURST_SIZE_MAX); + + if (received_pkts < expected_pkts) + return -6; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(res_mbuf[i]); + + return 0; +} + +int +test_port_ring_writer(void) +{ + int status, i; + struct rte_port_ring_writer_params port_ring_writer_params; + void *port; + + /* Invalid params */ + port = rte_port_ring_writer_ops.f_create(NULL, 0); + if (port != NULL) + return -1; + + status = rte_port_ring_writer_ops.f_free(port); + if (status >= 0) + return -2; + + port_ring_writer_params.ring = NULL; + + port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0); + if (port != NULL) + return -3; + + port_ring_writer_params.ring = RING_TX; + port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX + 1; + + port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0); + if (port != NULL) + return -4; + + /* Create and free */ + port_ring_writer_params.ring = RING_TX; + port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX; + + port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0); + if (port == NULL) + return -5; + + status = rte_port_ring_writer_ops.f_free(port); + if (status != 0) + return -6; + + /* -- Traffic TX -- */ + int expected_pkts, received_pkts; + struct rte_mbuf *mbuf[RTE_PORT_IN_BURST_SIZE_MAX]; + struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX]; + + port_ring_writer_params.ring = RING_TX; + port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX; + port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0); + + /* Single packet */ + mbuf[0] = rte_pktmbuf_alloc(pool); + + rte_port_ring_writer_ops.f_tx(port, mbuf[0]); + rte_port_ring_writer_ops.f_flush(port); + expected_pkts = 1; + received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring, + (void **)res_mbuf, port_ring_writer_params.tx_burst_sz); + + if (received_pkts < expected_pkts) + return -7; + + rte_pktmbuf_free(res_mbuf[0]); + + /* Multiple packets */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) { + mbuf[i] = rte_pktmbuf_alloc(pool); + rte_port_ring_writer_ops.f_tx(port, mbuf[i]); + } + + expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX; + received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring, + (void **)res_mbuf, port_ring_writer_params.tx_burst_sz); + + if (received_pkts < expected_pkts) + return -8; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(res_mbuf[i]); + + /* TX Bulk */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + mbuf[i] = rte_pktmbuf_alloc(pool); + rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-1); + + expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX; + received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring, + (void **)res_mbuf, port_ring_writer_params.tx_burst_sz); + + if (received_pkts < expected_pkts) + return -8; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(res_mbuf[i]); + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + mbuf[i] = rte_pktmbuf_alloc(pool); + rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-3); + rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)2); + + expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX; + received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring, + (void **)res_mbuf, port_ring_writer_params.tx_burst_sz); + + if (received_pkts < expected_pkts) + return -9; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(res_mbuf[i]); + + return 0; +} diff --git a/test/test/test_table_ports.h b/test/test/test_table_ports.h new file mode 100644 index 0000000000..512b77fe4d --- /dev/null +++ b/test/test/test_table_ports.h @@ -0,0 +1,42 @@ +/*- + * 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. + */ + +/* Test prototypes */ +int test_port_ring_reader(void); +int test_port_ring_writer(void); + +/* Extern variables */ +typedef int (*port_test)(void); + +extern port_test port_tests[]; +extern unsigned n_port_tests; diff --git a/test/test/test_table_tables.c b/test/test/test_table_tables.c new file mode 100644 index 0000000000..d835eb9f5d --- /dev/null +++ b/test/test/test_table_tables.c @@ -0,0 +1,1109 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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 +#include +#include +#include +#include +#include "test_table_tables.h" +#include "test_table.h" + +table_test table_tests[] = { + test_table_stub, + test_table_array, + test_table_lpm, + test_table_lpm_ipv6, + test_table_hash_lru, + test_table_hash_ext, + test_table_hash_cuckoo, +}; + +#define PREPARE_PACKET(mbuf, value) do { \ + uint32_t *k32, *signature; \ + uint8_t *key; \ + mbuf = rte_pktmbuf_alloc(pool); \ + signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \ + APP_METADATA_OFFSET(0)); \ + key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \ + APP_METADATA_OFFSET(32)); \ + memset(key, 0, 32); \ + k32 = (uint32_t *) key; \ + k32[0] = (value); \ + *signature = pipeline_test_hash(key, 0, 0); \ +} while (0) + +unsigned n_table_tests = RTE_DIM(table_tests); + +/* Function prototypes */ +static int +test_table_hash_lru_generic(struct rte_table_ops *ops); +static int +test_table_hash_ext_generic(struct rte_table_ops *ops); + +struct rte_bucket_4_8 { + /* Cache line 0 */ + uint64_t signature; + uint64_t lru_list; + struct rte_bucket_4_8 *next; + uint64_t next_valid; + uint64_t key[4]; + /* Cache line 1 */ + uint8_t data[0]; +}; + +#if RTE_TABLE_HASH_LRU_STRATEGY == 3 +uint64_t shuffles = 0xfffffffdfffbfff9ULL; +#else +uint64_t shuffles = 0x0003000200010000ULL; +#endif + +static int test_lru_update(void) +{ + struct rte_bucket_4_8 b; + struct rte_bucket_4_8 *bucket; + uint32_t i; + uint64_t pos; + uint64_t iterations; + uint64_t j; + int poss; + + printf("---------------------------\n"); + printf("Testing lru_update macro...\n"); + printf("---------------------------\n"); + bucket = &b; + iterations = 10; +#if RTE_TABLE_HASH_LRU_STRATEGY == 3 + bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL; +#else + bucket->lru_list = 0x0000000100020003ULL; +#endif + poss = 0; + for (j = 0; j < iterations; j++) + for (i = 0; i < 9; i++) { + uint32_t idx = i >> 1; + lru_update(bucket, idx); + pos = lru_pos(bucket); + poss += pos; + printf("%s: %d lru_list=%016"PRIx64", upd=%d, " + "pos=%"PRIx64"\n", + __func__, i, bucket->lru_list, i>>1, pos); + } + + if (bucket->lru_list != shuffles) { + printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016" + PRIx64"\n", + __func__, i, bucket->lru_list, shuffles); + return -1; + } + printf("%s: output checksum of results =%d\n", + __func__, poss); +#if 0 + if (poss != 126) { + printf("%s: ERROR output checksum of results =%d expected %d\n", + __func__, poss, 126); + return -1; + } +#endif + + fflush(stdout); + + uint64_t sc_start = rte_rdtsc(); + iterations = 100000000; + poss = 0; + for (j = 0; j < iterations; j++) { + for (i = 0; i < 4; i++) { + lru_update(bucket, i); + pos |= bucket->lru_list; + } + } + uint64_t sc_end = rte_rdtsc(); + + printf("%s: output checksum of results =%llu\n", + __func__, (long long unsigned int)pos); + printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n", + __func__, sc_start, sc_end); + printf("\nlru_update: %lu cycles per loop iteration.\n\n", + (long unsigned int)((sc_end-sc_start)/(iterations*4))); + + return 0; +} + +/* Table tests */ +int +test_table_stub(void) +{ + int i; + uint64_t expected_mask = 0, result_mask; + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; + + /* Create */ + table = rte_table_stub_ops.f_create(NULL, 0, 1); + if (table == NULL) + return -1; + + /* Traffic flow */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + if (i % 2 == 0) + PREPARE_PACKET(mbufs[i], 0xadadadad); + else + PREPARE_PACKET(mbufs[i], 0xadadadab); + + expected_mask = 0; + rte_table_stub_ops.f_lookup(table, mbufs, -1, + &result_mask, (void **)entries); + if (result_mask != expected_mask) + return -2; + + /* Free resources */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(mbufs[i]); + + return 0; +} + +int +test_table_array(void) +{ + int status, i; + uint64_t result_mask; + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; + char entry1, entry2; + void *entry_ptr; + int key_found; + + /* Initialize params and create tables */ + struct rte_table_array_params array_params = { + .n_entries = 7, + .offset = APP_METADATA_OFFSET(1) + }; + + table = rte_table_array_ops.f_create(NULL, 0, 1); + if (table != NULL) + return -1; + + array_params.n_entries = 0; + + table = rte_table_array_ops.f_create(&array_params, 0, 1); + if (table != NULL) + return -2; + + array_params.n_entries = 7; + + table = rte_table_array_ops.f_create(&array_params, 0, 1); + if (table != NULL) + return -3; + + array_params.n_entries = 1 << 24; + array_params.offset = APP_METADATA_OFFSET(1); + + table = rte_table_array_ops.f_create(&array_params, 0, 1); + if (table == NULL) + return -4; + + array_params.offset = APP_METADATA_OFFSET(32); + + table = rte_table_array_ops.f_create(&array_params, 0, 1); + if (table == NULL) + return -5; + + /* Free */ + status = rte_table_array_ops.f_free(table); + if (status < 0) + return -6; + + status = rte_table_array_ops.f_free(NULL); + if (status == 0) + return -7; + + /* Add */ + struct rte_table_array_key array_key_1 = { + .pos = 10, + }; + struct rte_table_array_key array_key_2 = { + .pos = 20, + }; + entry1 = 'A'; + entry2 = 'B'; + + table = rte_table_array_ops.f_create(&array_params, 0, 1); + if (table == NULL) + return -8; + + status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1, + &key_found, &entry_ptr); + if (status == 0) + return -9; + + status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL, + &key_found, &entry_ptr); + if (status == 0) + return -10; + + status = rte_table_array_ops.f_add(table, (void *) &array_key_1, + &entry1, &key_found, &entry_ptr); + if (status != 0) + return -11; + + /* Traffic flow */ + status = rte_table_array_ops.f_add(table, (void *) &array_key_2, + &entry2, &key_found, &entry_ptr); + if (status != 0) + return -12; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + if (i % 2 == 0) + PREPARE_PACKET(mbufs[i], 10); + else + PREPARE_PACKET(mbufs[i], 20); + + rte_table_array_ops.f_lookup(table, mbufs, -1, + &result_mask, (void **)entries); + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + if (i % 2 == 0 && *entries[i] != 'A') + return -13; + else + if (i % 2 == 1 && *entries[i] != 'B') + return -13; + + /* Free resources */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(mbufs[i]); + + status = rte_table_array_ops.f_free(table); + + return 0; +} + +int +test_table_lpm(void) +{ + int status, i; + uint64_t expected_mask = 0, result_mask; + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; + char entry; + void *entry_ptr; + int key_found; + uint32_t entry_size = 1; + + /* Initialize params and create tables */ + struct rte_table_lpm_params lpm_params = { + .name = "LPM", + .n_rules = 1 << 24, + .number_tbl8s = 1 << 8, + .flags = 0, + .entry_unique_size = entry_size, + .offset = APP_METADATA_OFFSET(1) + }; + + table = rte_table_lpm_ops.f_create(NULL, 0, entry_size); + if (table != NULL) + return -1; + + lpm_params.name = NULL; + + table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -2; + + lpm_params.name = "LPM"; + lpm_params.n_rules = 0; + + table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -3; + + lpm_params.n_rules = 1 << 24; + lpm_params.offset = APP_METADATA_OFFSET(32); + lpm_params.entry_unique_size = 0; + + table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -4; + + lpm_params.entry_unique_size = entry_size + 1; + + table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -5; + + lpm_params.entry_unique_size = entry_size; + + table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); + if (table == NULL) + return -6; + + /* Free */ + status = rte_table_lpm_ops.f_free(table); + if (status < 0) + return -7; + + status = rte_table_lpm_ops.f_free(NULL); + if (status == 0) + return -8; + + /* Add */ + struct rte_table_lpm_key lpm_key; + lpm_key.ip = 0xadadadad; + + table = rte_table_lpm_ops.f_create(&lpm_params, 0, 1); + if (table == NULL) + return -9; + + status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found, + &entry_ptr); + if (status == 0) + return -10; + + status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found, + &entry_ptr); + if (status == 0) + return -11; + + status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found, + &entry_ptr); + if (status == 0) + return -12; + + lpm_key.depth = 0; + status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, + &entry_ptr); + if (status == 0) + return -13; + + lpm_key.depth = 33; + status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, + &entry_ptr); + if (status == 0) + return -14; + + lpm_key.depth = 16; + status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, + &entry_ptr); + if (status != 0) + return -15; + + /* Delete */ + status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL); + if (status == 0) + return -16; + + status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL); + if (status == 0) + return -17; + + lpm_key.depth = 0; + status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); + if (status == 0) + return -18; + + lpm_key.depth = 33; + status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); + if (status == 0) + return -19; + + lpm_key.depth = 16; + status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); + if (status != 0) + return -20; + + status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); + if (status != 0) + return -21; + + /* Traffic flow */ + entry = 'A'; + status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, + &entry_ptr); + if (status < 0) + return -22; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + if (i % 2 == 0) { + expected_mask |= (uint64_t)1 << i; + PREPARE_PACKET(mbufs[i], 0xadadadad); + } else + PREPARE_PACKET(mbufs[i], 0xadadadab); + + rte_table_lpm_ops.f_lookup(table, mbufs, -1, + &result_mask, (void **)entries); + if (result_mask != expected_mask) + return -23; + + /* Free resources */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(mbufs[i]); + + status = rte_table_lpm_ops.f_free(table); + + return 0; +} + +int +test_table_lpm_ipv6(void) +{ + int status, i; + uint64_t expected_mask = 0, result_mask; + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; + char entry; + void *entry_ptr; + int key_found; + uint32_t entry_size = 1; + + /* Initialize params and create tables */ + struct rte_table_lpm_ipv6_params lpm_params = { + .name = "LPM", + .n_rules = 1 << 24, + .number_tbl8s = 1 << 21, + .entry_unique_size = entry_size, + .offset = APP_METADATA_OFFSET(32) + }; + + table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size); + if (table != NULL) + return -1; + + lpm_params.name = NULL; + + table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -2; + + lpm_params.name = "LPM"; + lpm_params.n_rules = 0; + + table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -3; + + lpm_params.n_rules = 1 << 24; + lpm_params.number_tbl8s = 0; + table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -4; + + lpm_params.number_tbl8s = 1 << 21; + lpm_params.entry_unique_size = 0; + table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -5; + + lpm_params.entry_unique_size = entry_size + 1; + table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); + if (table != NULL) + return -6; + + lpm_params.entry_unique_size = entry_size; + lpm_params.offset = APP_METADATA_OFFSET(32); + + table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); + if (table == NULL) + return -7; + + /* Free */ + status = rte_table_lpm_ipv6_ops.f_free(table); + if (status < 0) + return -8; + + status = rte_table_lpm_ipv6_ops.f_free(NULL); + if (status == 0) + return -9; + + /* Add */ + struct rte_table_lpm_ipv6_key lpm_key; + + lpm_key.ip[0] = 0xad; + lpm_key.ip[1] = 0xad; + lpm_key.ip[2] = 0xad; + lpm_key.ip[3] = 0xad; + + table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); + if (table == NULL) + return -10; + + status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry, + &key_found, &entry_ptr); + if (status == 0) + return -11; + + status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found, + &entry_ptr); + if (status == 0) + return -12; + + status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found, + &entry_ptr); + if (status == 0) + return -13; + + lpm_key.depth = 0; + status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, + &key_found, &entry_ptr); + if (status == 0) + return -14; + + lpm_key.depth = 129; + status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, + &key_found, &entry_ptr); + if (status == 0) + return -15; + + lpm_key.depth = 16; + status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, + &key_found, &entry_ptr); + if (status != 0) + return -16; + + /* Delete */ + status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found, + NULL); + if (status == 0) + return -17; + + status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL); + if (status == 0) + return -18; + + lpm_key.depth = 0; + status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, + NULL); + if (status == 0) + return -19; + + lpm_key.depth = 129; + status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, + NULL); + if (status == 0) + return -20; + + lpm_key.depth = 16; + status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, + NULL); + if (status != 0) + return -21; + + status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, + NULL); + if (status != 0) + return -22; + + /* Traffic flow */ + entry = 'A'; + status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, + &key_found, &entry_ptr); + if (status < 0) + return -23; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + if (i % 2 == 0) { + expected_mask |= (uint64_t)1 << i; + PREPARE_PACKET(mbufs[i], 0xadadadad); + } else + PREPARE_PACKET(mbufs[i], 0xadadadab); + + rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1, + &result_mask, (void **)entries); + if (result_mask != expected_mask) + return -24; + + /* Free resources */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(mbufs[i]); + + status = rte_table_lpm_ipv6_ops.f_free(table); + + return 0; +} + +static int +test_table_hash_lru_generic(struct rte_table_ops *ops) +{ + int status, i; + uint64_t expected_mask = 0, result_mask; + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; + char entry; + void *entry_ptr; + int key_found; + + /* Initialize params and create tables */ + struct rte_table_hash_key8_lru_params hash_params = { + .n_entries = 1 << 10, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(1), + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + }; + + hash_params.n_entries = 0; + + table = ops->f_create(&hash_params, 0, 1); + if (table != NULL) + return -1; + + hash_params.n_entries = 1 << 10; + hash_params.signature_offset = APP_METADATA_OFFSET(1); + + table = ops->f_create(&hash_params, 0, 1); + if (table == NULL) + return -2; + + hash_params.signature_offset = APP_METADATA_OFFSET(0); + hash_params.key_offset = APP_METADATA_OFFSET(1); + + table = ops->f_create(&hash_params, 0, 1); + if (table == NULL) + return -3; + + hash_params.key_offset = APP_METADATA_OFFSET(32); + hash_params.f_hash = NULL; + + table = ops->f_create(&hash_params, 0, 1); + if (table != NULL) + return -4; + + hash_params.f_hash = pipeline_test_hash; + + table = ops->f_create(&hash_params, 0, 1); + if (table == NULL) + return -5; + + /* Free */ + status = ops->f_free(table); + if (status < 0) + return -6; + + status = ops->f_free(NULL); + if (status == 0) + return -7; + + /* Add */ + uint8_t key[32]; + uint32_t *k32 = (uint32_t *) &key; + + memset(key, 0, 32); + k32[0] = rte_be_to_cpu_32(0xadadadad); + + table = ops->f_create(&hash_params, 0, 1); + if (table == NULL) + return -8; + + entry = 'A'; + status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); + if (status != 0) + return -9; + + /* Delete */ + status = ops->f_delete(table, &key, &key_found, NULL); + if (status != 0) + return -10; + + status = ops->f_delete(table, &key, &key_found, NULL); + if (status != 0) + return -11; + + /* Traffic flow */ + entry = 'A'; + status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); + if (status < 0) + return -12; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + if (i % 2 == 0) { + expected_mask |= (uint64_t)1 << i; + PREPARE_PACKET(mbufs[i], 0xadadadad); + } else + PREPARE_PACKET(mbufs[i], 0xadadadab); + + ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries); + if (result_mask != expected_mask) + return -13; + + /* Free resources */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(mbufs[i]); + + status = ops->f_free(table); + + return 0; +} + +static int +test_table_hash_ext_generic(struct rte_table_ops *ops) +{ + int status, i; + uint64_t expected_mask = 0, result_mask; + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; + char entry; + int key_found; + void *entry_ptr; + + /* Initialize params and create tables */ + struct rte_table_hash_key8_ext_params hash_params = { + .n_entries = 1 << 10, + .n_entries_ext = 1 << 4, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(1), + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + }; + + hash_params.n_entries = 0; + + table = ops->f_create(&hash_params, 0, 1); + if (table != NULL) + return -1; + + hash_params.n_entries = 1 << 10; + hash_params.n_entries_ext = 0; + table = ops->f_create(&hash_params, 0, 1); + if (table != NULL) + return -2; + + hash_params.n_entries_ext = 1 << 4; + hash_params.signature_offset = APP_METADATA_OFFSET(1); + table = ops->f_create(&hash_params, 0, 1); + if (table == NULL) + return -2; + + hash_params.signature_offset = APP_METADATA_OFFSET(0); + hash_params.key_offset = APP_METADATA_OFFSET(1); + + table = ops->f_create(&hash_params, 0, 1); + if (table == NULL) + return -3; + + hash_params.key_offset = APP_METADATA_OFFSET(32); + hash_params.f_hash = NULL; + + table = ops->f_create(&hash_params, 0, 1); + if (table != NULL) + return -4; + + hash_params.f_hash = pipeline_test_hash; + + table = ops->f_create(&hash_params, 0, 1); + if (table == NULL) + return -5; + + /* Free */ + status = ops->f_free(table); + if (status < 0) + return -6; + + status = ops->f_free(NULL); + if (status == 0) + return -7; + + /* Add */ + uint8_t key[32]; + uint32_t *k32 = (uint32_t *) &key; + + memset(key, 0, 32); + k32[0] = rte_be_to_cpu_32(0xadadadad); + + table = ops->f_create(&hash_params, 0, 1); + if (table == NULL) + return -8; + + entry = 'A'; + status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); + if (status != 0) + return -9; + + /* Delete */ + status = ops->f_delete(table, &key, &key_found, NULL); + if (status != 0) + return -10; + + status = ops->f_delete(table, &key, &key_found, NULL); + if (status != 0) + return -11; + + /* Traffic flow */ + entry = 'A'; + status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); + if (status < 0) + return -12; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + if (i % 2 == 0) { + expected_mask |= (uint64_t)1 << i; + PREPARE_PACKET(mbufs[i], 0xadadadad); + } else + PREPARE_PACKET(mbufs[i], 0xadadadab); + + ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries); + if (result_mask != expected_mask) + return -13; + + /* Free resources */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(mbufs[i]); + + status = ops->f_free(table); + + return 0; +} + +int +test_table_hash_lru(void) +{ + int status; + + status = test_table_hash_lru_generic(&rte_table_hash_key8_lru_ops); + if (status < 0) + return status; + + status = test_table_hash_lru_generic( + &rte_table_hash_key8_lru_dosig_ops); + if (status < 0) + return status; + + status = test_table_hash_lru_generic(&rte_table_hash_key16_lru_ops); + if (status < 0) + return status; + + status = test_table_hash_lru_generic(&rte_table_hash_key32_lru_ops); + if (status < 0) + return status; + + status = test_lru_update(); + if (status < 0) + return status; + + return 0; +} + +int +test_table_hash_ext(void) +{ + int status; + + status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops); + if (status < 0) + return status; + + status = test_table_hash_ext_generic( + &rte_table_hash_key8_ext_dosig_ops); + if (status < 0) + return status; + + status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops); + if (status < 0) + return status; + + status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops); + if (status < 0) + return status; + + return 0; +} + + +int +test_table_hash_cuckoo(void) +{ + int status, i; + uint64_t expected_mask = 0, result_mask; + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; + char entry; + void *entry_ptr; + int key_found; + uint32_t entry_size = 1; + + /* Initialize params and create tables */ + struct rte_table_hash_cuckoo_params cuckoo_params = { + .key_size = 32, + .n_keys = 1 << 24, + .f_hash = pipeline_test_hash, + .seed = 0, + .signature_offset = APP_METADATA_OFFSET(0), + .key_offset = APP_METADATA_OFFSET(32), + .name = "CUCKOO", + }; + + table = rte_table_hash_cuckoo_dosig_ops.f_create(NULL, 0, entry_size); + if (table != NULL) + return -1; + + cuckoo_params.key_size = 0; + + table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, + 0, entry_size); + if (table != NULL) + return -2; + + cuckoo_params.key_size = 32; + cuckoo_params.n_keys = 0; + + table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, + 0, entry_size); + if (table != NULL) + return -3; + + cuckoo_params.n_keys = 1 << 24; + cuckoo_params.f_hash = NULL; + + table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, + 0, entry_size); + if (table != NULL) + return -4; + + cuckoo_params.f_hash = pipeline_test_hash; + cuckoo_params.name = NULL; + + table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, + 0, entry_size); + if (table != NULL) + return -5; + + cuckoo_params.name = "CUCKOO"; + + table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, + 0, entry_size); + if (table == NULL) + return -6; + + /* Free */ + status = rte_table_hash_cuckoo_dosig_ops.f_free(table); + if (status < 0) + return -7; + + status = rte_table_hash_cuckoo_dosig_ops.f_free(NULL); + if (status == 0) + return -8; + + /* Add */ + uint8_t key_cuckoo[32]; + uint32_t *kcuckoo = (uint32_t *) &key_cuckoo; + + memset(key_cuckoo, 0, 32); + kcuckoo[0] = rte_be_to_cpu_32(0xadadadad); + + table = rte_table_hash_cuckoo_dosig_ops.f_create(&cuckoo_params, 0, 1); + if (table == NULL) + return -9; + + entry = 'A'; + status = rte_table_hash_cuckoo_dosig_ops.f_add(NULL, &key_cuckoo, + &entry, &key_found, &entry_ptr); + if (status == 0) + return -10; + + status = rte_table_hash_cuckoo_dosig_ops.f_add(table, NULL, &entry, + &key_found, &entry_ptr); + if (status == 0) + return -11; + + status = rte_table_hash_cuckoo_dosig_ops.f_add(table, &key_cuckoo, + NULL, &key_found, &entry_ptr); + if (status == 0) + return -12; + + status = rte_table_hash_cuckoo_dosig_ops.f_add(table, &key_cuckoo, + &entry, &key_found, &entry_ptr); + if (status != 0) + return -13; + + status = rte_table_hash_cuckoo_dosig_ops.f_add(table, &key_cuckoo, + &entry, &key_found, &entry_ptr); + if (status != 0) + return -14; + + /* Delete */ + status = rte_table_hash_cuckoo_dosig_ops.f_delete(NULL, &key_cuckoo, + &key_found, NULL); + if (status == 0) + return -15; + + status = rte_table_hash_cuckoo_dosig_ops.f_delete(table, NULL, + &key_found, NULL); + if (status == 0) + return -16; + + status = rte_table_hash_cuckoo_dosig_ops.f_delete(table, &key_cuckoo, + &key_found, NULL); + if (status != 0) + return -17; + + status = rte_table_hash_cuckoo_dosig_ops.f_delete(table, &key_cuckoo, + &key_found, NULL); + if (status != -ENOENT) + return -18; + + /* Traffic flow */ + entry = 'A'; + status = rte_table_hash_cuckoo_dosig_ops.f_add(table, &key_cuckoo, + &entry, &key_found, + &entry_ptr); + if (status < 0) + return -19; + + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + if (i % 2 == 0) { + expected_mask |= (uint64_t)1 << i; + PREPARE_PACKET(mbufs[i], 0xadadadad); + } else + PREPARE_PACKET(mbufs[i], 0xadadadab); + + rte_table_hash_cuckoo_dosig_ops.f_lookup(table, mbufs, -1, + &result_mask, (void **)entries); + if (result_mask != expected_mask) + return -20; + + /* Free resources */ + for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) + rte_pktmbuf_free(mbufs[i]); + + status = rte_table_hash_cuckoo_dosig_ops.f_free(table); + + return 0; +} + diff --git a/test/test/test_table_tables.h b/test/test/test_table_tables.h new file mode 100644 index 0000000000..35311362bb --- /dev/null +++ b/test/test/test_table_tables.h @@ -0,0 +1,51 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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. + */ + +/* Test prototypes */ +int test_table_hash_cuckoo(void); +int test_table_lpm(void); +int test_table_lpm_ipv6(void); +int test_table_array(void); +#ifdef RTE_LIBRTE_ACL +int test_table_acl(void); +#endif +int test_table_hash_unoptimized(void); +int test_table_hash_lru(void); +int test_table_hash_ext(void); +int test_table_stub(void); + +/* Extern variables */ +typedef int (*table_test)(void); + +extern table_test table_tests[]; +extern unsigned n_table_tests; diff --git a/test/test/test_tailq.c b/test/test/test_tailq.c new file mode 100644 index 0000000000..33a3e8a9c8 --- /dev/null +++ b/test/test/test_tailq.c @@ -0,0 +1,157 @@ +/*- + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "test.h" + +#define do_return(...) do { \ + printf("Error at %s, line %d: ", __func__, __LINE__); \ + printf(__VA_ARGS__); \ + return 1; \ +} while (0) + +static struct rte_tailq_elem rte_dummy_tailq = { + .name = "dummy", +}; +EAL_REGISTER_TAILQ(rte_dummy_tailq) + +static struct rte_tailq_elem rte_dummy_dyn_tailq = { + .name = "dummy_dyn", +}; +static struct rte_tailq_elem rte_dummy_dyn2_tailq = { + .name = "dummy_dyn", +}; + +static struct rte_tailq_entry d_elem; +static struct rte_tailq_entry d_dyn_elem; + +static int +test_tailq_early(void) +{ + struct rte_tailq_entry_head *d_head; + + d_head = RTE_TAILQ_CAST(rte_dummy_tailq.head, rte_tailq_entry_head); + if (d_head == NULL) + do_return("Error %s has not been initialised\n", + rte_dummy_tailq.name); + + /* check we can add an item to it */ + TAILQ_INSERT_TAIL(d_head, &d_elem, next); + + return 0; +} + +static int +test_tailq_create(void) +{ + struct rte_tailq_entry_head *d_head; + + /* create a tailq and check its non-null (since we are post-eal init) */ + if ((rte_eal_tailq_register(&rte_dummy_dyn_tailq) < 0) || + (rte_dummy_dyn_tailq.head == NULL)) + do_return("Error allocating %s\n", rte_dummy_dyn_tailq.name); + + d_head = RTE_TAILQ_CAST(rte_dummy_dyn_tailq.head, rte_tailq_entry_head); + + /* check we can add an item to it */ + TAILQ_INSERT_TAIL(d_head, &d_dyn_elem, next); + + if (strcmp(rte_dummy_dyn2_tailq.name, rte_dummy_dyn_tailq.name)) + do_return("Error, something is wrong in the tailq test\n"); + + /* try allocating again, and check for failure */ + if (!rte_eal_tailq_register(&rte_dummy_dyn2_tailq)) + do_return("Error, registering the same tailq %s did not fail\n", + rte_dummy_dyn2_tailq.name); + + return 0; +} + +static int +test_tailq_lookup(void) +{ + /* run successful test - check result is found */ + struct rte_tailq_entry_head *d_head; + struct rte_tailq_entry *d_ptr; + + d_head = RTE_TAILQ_LOOKUP(rte_dummy_tailq.name, rte_tailq_entry_head); + /* rte_dummy_tailq has been registered by EAL_REGISTER_TAILQ */ + if (d_head == NULL || + d_head != RTE_TAILQ_CAST(rte_dummy_tailq.head, rte_tailq_entry_head)) + do_return("Error with tailq lookup\n"); + + TAILQ_FOREACH(d_ptr, d_head, next) + if (d_ptr != &d_elem) + do_return("Error with tailq returned from lookup - " + "expected element not found\n"); + + d_head = RTE_TAILQ_LOOKUP(rte_dummy_dyn_tailq.name, rte_tailq_entry_head); + /* rte_dummy_dyn_tailq has been registered by test_tailq_create */ + if (d_head == NULL || + d_head != RTE_TAILQ_CAST(rte_dummy_dyn_tailq.head, rte_tailq_entry_head)) + do_return("Error with tailq lookup\n"); + + TAILQ_FOREACH(d_ptr, d_head, next) + if (d_ptr != &d_dyn_elem) + do_return("Error with tailq returned from lookup - " + "expected element not found\n"); + + /* now try a bad/error lookup */ + d_head = RTE_TAILQ_LOOKUP("coucou", rte_tailq_entry_head); + if (d_head != NULL) + do_return("Error, lookup does not return NULL for bad tailq name\n"); + + return 0; +} + +static int +test_tailq(void) +{ + int ret = 0; + ret |= test_tailq_early(); + ret |= test_tailq_create(); + ret |= test_tailq_lookup(); + return ret; +} + +REGISTER_TEST_COMMAND(tailq_autotest, test_tailq); diff --git a/test/test/test_thash.c b/test/test/test_thash.c new file mode 100644 index 0000000000..61754a9475 --- /dev/null +++ b/test/test/test_thash.c @@ -0,0 +1,172 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 Vladimir Medvedkin + * 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 +#include +#include + +#include "test.h" + +#include + +struct test_thash_v4 { + uint32_t dst_ip; + uint32_t src_ip; + uint16_t dst_port; + uint16_t src_port; + uint32_t hash_l3; + uint32_t hash_l3l4; +}; + +struct test_thash_v6 { + uint8_t dst_ip[16]; + uint8_t src_ip[16]; + uint16_t dst_port; + uint16_t src_port; + uint32_t hash_l3; + uint32_t hash_l3l4; +}; + +/*From 82599 Datasheet 7.1.2.8.3 RSS Verification Suite*/ +struct test_thash_v4 v4_tbl[] = { +{IPv4(161, 142, 100, 80), IPv4(66, 9, 149, 187), + 1766, 2794, 0x323e8fc2, 0x51ccc178}, +{IPv4(65, 69, 140, 83), IPv4(199, 92, 111, 2), + 4739, 14230, 0xd718262a, 0xc626b0ea}, +{IPv4(12, 22, 207, 184), IPv4(24, 19, 198, 95), + 38024, 12898, 0xd2d0a5de, 0x5c2b394a}, +{IPv4(209, 142, 163, 6), IPv4(38, 27, 205, 30), + 2217, 48228, 0x82989176, 0xafc7327f}, +{IPv4(202, 188, 127, 2), IPv4(153, 39, 163, 191), + 1303, 44251, 0x5d1809c5, 0x10e828a2}, +}; + +struct test_thash_v6 v6_tbl[] = { +/*3ffe:2501:200:3::1*/ +{{0x3f, 0xfe, 0x25, 0x01, 0x02, 0x00, 0x00, 0x03, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,}, +/*3ffe:2501:200:1fff::7*/ +{0x3f, 0xfe, 0x25, 0x01, 0x02, 0x00, 0x1f, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,}, +1766, 2794, 0x2cc18cd5, 0x40207d3d}, +/*ff02::1*/ +{{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,}, +/*3ffe:501:8::260:97ff:fe40:efab*/ +{0x3f, 0xfe, 0x05, 0x01, 0x00, 0x08, 0x00, 0x00, +0x02, 0x60, 0x97, 0xff, 0xfe, 0x40, 0xef, 0xab,}, +4739, 14230, 0x0f0c461c, 0xdde51bbf}, +/*fe80::200:f8ff:fe21:67cf*/ +{{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x00, 0xf8, 0xff, 0xfe, 0x21, 0x67, 0xcf,}, +/*3ffe:1900:4545:3:200:f8ff:fe21:67cf*/ +{0x3f, 0xfe, 0x19, 0x00, 0x45, 0x45, 0x00, 0x03, +0x02, 0x00, 0xf8, 0xff, 0xfe, 0x21, 0x67, 0xcf,}, +38024, 44251, 0x4b61e985, 0x02d1feef}, +}; + +uint8_t default_rss_key[] = { +0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, +0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, +0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, +0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, +0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, +}; + +static int +test_thash(void) +{ + uint32_t i, j; + union rte_thash_tuple tuple; + uint32_t rss_l3, rss_l3l4; + uint8_t rss_key_be[RTE_DIM(default_rss_key)]; + struct ipv6_hdr ipv6_hdr; + + /* Convert RSS key*/ + rte_convert_rss_key((uint32_t *)&default_rss_key, + (uint32_t *)rss_key_be, RTE_DIM(default_rss_key)); + + + for (i = 0; i < RTE_DIM(v4_tbl); i++) { + tuple.v4.src_addr = v4_tbl[i].src_ip; + tuple.v4.dst_addr = v4_tbl[i].dst_ip; + tuple.v4.sport = v4_tbl[i].src_port; + tuple.v4.dport = v4_tbl[i].dst_port; + /*Calculate hash with original key*/ + rss_l3 = rte_softrss((uint32_t *)&tuple, + RTE_THASH_V4_L3_LEN, default_rss_key); + rss_l3l4 = rte_softrss((uint32_t *)&tuple, + RTE_THASH_V4_L4_LEN, default_rss_key); + if ((rss_l3 != v4_tbl[i].hash_l3) || + (rss_l3l4 != v4_tbl[i].hash_l3l4)) + return -1; + /*Calculate hash with converted key*/ + rss_l3 = rte_softrss_be((uint32_t *)&tuple, + RTE_THASH_V4_L3_LEN, rss_key_be); + rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, + RTE_THASH_V4_L4_LEN, rss_key_be); + if ((rss_l3 != v4_tbl[i].hash_l3) || + (rss_l3l4 != v4_tbl[i].hash_l3l4)) + return -1; + } + for (i = 0; i < RTE_DIM(v6_tbl); i++) { + /*Fill ipv6 hdr*/ + for (j = 0; j < RTE_DIM(ipv6_hdr.src_addr); j++) + ipv6_hdr.src_addr[j] = v6_tbl[i].src_ip[j]; + for (j = 0; j < RTE_DIM(ipv6_hdr.dst_addr); j++) + ipv6_hdr.dst_addr[j] = v6_tbl[i].dst_ip[j]; + /*Load and convert ipv6 address into tuple*/ + rte_thash_load_v6_addrs(&ipv6_hdr, &tuple); + tuple.v6.sport = v6_tbl[i].src_port; + tuple.v6.dport = v6_tbl[i].dst_port; + /*Calculate hash with original key*/ + rss_l3 = rte_softrss((uint32_t *)&tuple, + RTE_THASH_V6_L3_LEN, default_rss_key); + rss_l3l4 = rte_softrss((uint32_t *)&tuple, + RTE_THASH_V6_L4_LEN, default_rss_key); + if ((rss_l3 != v6_tbl[i].hash_l3) || + (rss_l3l4 != v6_tbl[i].hash_l3l4)) + return -1; + /*Calculate hash with converted key*/ + rss_l3 = rte_softrss_be((uint32_t *)&tuple, + RTE_THASH_V6_L3_LEN, rss_key_be); + rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, + RTE_THASH_V6_L4_LEN, rss_key_be); + if ((rss_l3 != v6_tbl[i].hash_l3) || + (rss_l3l4 != v6_tbl[i].hash_l3l4)) + return -1; + } + return 0; +} + +REGISTER_TEST_COMMAND(thash_autotest, test_thash); diff --git a/test/test/test_timer.c b/test/test/test_timer.c new file mode 100644 index 0000000000..2f6525a506 --- /dev/null +++ b/test/test/test_timer.c @@ -0,0 +1,629 @@ +/*- + * 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 "test.h" + +/* + * Timer + * ===== + * + * #. Stress test 1. + * + * The objective of the timer stress tests is to check that there are no + * race conditions in list and status management. This test launches, + * resets and stops the timer very often on many cores at the same + * time. + * + * - Only one timer is used for this test. + * - On each core, the rte_timer_manage() function is called from the main + * loop every 3 microseconds. + * - In the main loop, the timer may be reset (randomly, with a + * probability of 0.5 %) 100 microseconds later on a random core, or + * stopped (with a probability of 0.5 % also). + * - In callback, the timer is can be reset (randomly, with a + * probability of 0.5 %) 100 microseconds later on the same core or + * on another core (same probability), or stopped (same + * probability). + * + * # Stress test 2. + * + * The objective of this test is similar to the first in that it attempts + * to find if there are any race conditions in the timer library. However, + * it is less complex in terms of operations performed and duration, as it + * is designed to have a predictable outcome that can be tested. + * + * - A set of timers is initialized for use by the test + * - All cores then simultaneously are set to schedule all the timers at + * the same time, so conflicts should occur. + * - Then there is a delay while we wait for the timers to expire + * - Then the master lcore calls timer_manage() and we check that all + * timers have had their callbacks called exactly once - no more no less. + * - Then we repeat the process, except after setting up the timers, we have + * all cores randomly reschedule them. + * - Again we check that the expected number of callbacks has occurred when + * we call timer-manage. + * + * #. Basic test. + * + * This test performs basic functional checks of the timers. The test + * uses four different timers that are loaded and stopped under + * specific conditions in specific contexts. + * + * - Four timers are used for this test. + * - On each core, the rte_timer_manage() function is called from main loop + * every 3 microseconds. + * + * The autotest python script checks that the behavior is correct: + * + * - timer0 + * + * - At initialization, timer0 is loaded by the master core, on master core + * in "single" mode (time = 1 second). + * - In the first 19 callbacks, timer0 is reloaded on the same core, + * then, it is explicitly stopped at the 20th call. + * - At t=25s, timer0 is reloaded once by timer2. + * + * - timer1 + * + * - At initialization, timer1 is loaded by the master core, on the + * master core in "single" mode (time = 2 seconds). + * - In the first 9 callbacks, timer1 is reloaded on another + * core. After the 10th callback, timer1 is not reloaded anymore. + * + * - timer2 + * + * - At initialization, timer2 is loaded by the master core, on the + * master core in "periodical" mode (time = 1 second). + * - In the callback, when t=25s, it stops timer3 and reloads timer0 + * on the current core. + * + * - timer3 + * + * - At initialization, timer3 is loaded by the master core, on + * another core in "periodical" mode (time = 1 second). + * - It is stopped at t=25s by timer2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEST_DURATION_S 1 /* in seconds */ +#define NB_TIMER 4 + +#define RTE_LOGTYPE_TESTTIMER RTE_LOGTYPE_USER3 + +static volatile uint64_t end_time; +static volatile int test_failed; + +struct mytimerinfo { + struct rte_timer tim; + unsigned id; + unsigned count; +}; + +static struct mytimerinfo mytiminfo[NB_TIMER]; + +static void timer_basic_cb(struct rte_timer *tim, void *arg); + +static void +mytimer_reset(struct mytimerinfo *timinfo, uint64_t ticks, + enum rte_timer_type type, unsigned tim_lcore, + rte_timer_cb_t fct) +{ + rte_timer_reset_sync(&timinfo->tim, ticks, type, tim_lcore, + fct, timinfo); +} + +/* timer callback for stress tests */ +static void +timer_stress_cb(__attribute__((unused)) struct rte_timer *tim, + __attribute__((unused)) void *arg) +{ + long r; + unsigned lcore_id = rte_lcore_id(); + uint64_t hz = rte_get_timer_hz(); + + if (rte_timer_pending(tim)) + return; + + r = rte_rand(); + if ((r & 0xff) == 0) { + mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id, + timer_stress_cb); + } + else if ((r & 0xff) == 1) { + mytimer_reset(&mytiminfo[0], hz, SINGLE, + rte_get_next_lcore(lcore_id, 0, 1), + timer_stress_cb); + } + else if ((r & 0xff) == 2) { + rte_timer_stop(&mytiminfo[0].tim); + } +} + +static int +timer_stress_main_loop(__attribute__((unused)) void *arg) +{ + uint64_t hz = rte_get_timer_hz(); + unsigned lcore_id = rte_lcore_id(); + uint64_t cur_time; + int64_t diff = 0; + long r; + + while (diff >= 0) { + + /* call the timer handler on each core */ + rte_timer_manage(); + + /* simulate the processing of a packet + * (1 us = 2000 cycles at 2 Ghz) */ + rte_delay_us(1); + + /* randomly stop or reset timer */ + r = rte_rand(); + lcore_id = rte_get_next_lcore(lcore_id, 0, 1); + if ((r & 0xff) == 0) { + /* 100 us */ + mytimer_reset(&mytiminfo[0], hz/10000, SINGLE, lcore_id, + timer_stress_cb); + } + else if ((r & 0xff) == 1) { + rte_timer_stop_sync(&mytiminfo[0].tim); + } + cur_time = rte_get_timer_cycles(); + diff = end_time - cur_time; + } + + lcore_id = rte_lcore_id(); + RTE_LOG(INFO, TESTTIMER, "core %u finished\n", lcore_id); + + return 0; +} + +/* Need to synchronize slave lcores through multiple steps. */ +enum { SLAVE_WAITING = 1, SLAVE_RUN_SIGNAL, SLAVE_RUNNING, SLAVE_FINISHED }; +static rte_atomic16_t slave_state[RTE_MAX_LCORE]; + +static void +master_init_slaves(void) +{ + unsigned i; + + RTE_LCORE_FOREACH_SLAVE(i) { + rte_atomic16_set(&slave_state[i], SLAVE_WAITING); + } +} + +static void +master_start_slaves(void) +{ + unsigned i; + + RTE_LCORE_FOREACH_SLAVE(i) { + rte_atomic16_set(&slave_state[i], SLAVE_RUN_SIGNAL); + } + RTE_LCORE_FOREACH_SLAVE(i) { + while (rte_atomic16_read(&slave_state[i]) != SLAVE_RUNNING) + rte_pause(); + } +} + +static void +master_wait_for_slaves(void) +{ + unsigned i; + + RTE_LCORE_FOREACH_SLAVE(i) { + while (rte_atomic16_read(&slave_state[i]) != SLAVE_FINISHED) + rte_pause(); + } +} + +static void +slave_wait_to_start(void) +{ + unsigned lcore_id = rte_lcore_id(); + + while (rte_atomic16_read(&slave_state[lcore_id]) != SLAVE_RUN_SIGNAL) + rte_pause(); + rte_atomic16_set(&slave_state[lcore_id], SLAVE_RUNNING); +} + +static void +slave_finish(void) +{ + unsigned lcore_id = rte_lcore_id(); + + rte_atomic16_set(&slave_state[lcore_id], SLAVE_FINISHED); +} + + +static volatile int cb_count = 0; + +/* callback for second stress test. will only be called + * on master lcore */ +static void +timer_stress2_cb(struct rte_timer *tim __rte_unused, void *arg __rte_unused) +{ + cb_count++; +} + +#define NB_STRESS2_TIMERS 8192 + +static int +timer_stress2_main_loop(__attribute__((unused)) void *arg) +{ + static struct rte_timer *timers; + int i, ret; + 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; + static rte_atomic32_t collisions; + + if (lcore_id == master) { + cb_count = 0; + test_failed = 0; + rte_atomic32_set(&collisions, 0); + master_init_slaves(); + timers = rte_malloc(NULL, sizeof(*timers) * NB_STRESS2_TIMERS, 0); + if (timers == NULL) { + printf("Test Failed\n"); + printf("- Cannot allocate memory for timers\n" ); + test_failed = 1; + master_start_slaves(); + goto cleanup; + } + for (i = 0; i < NB_STRESS2_TIMERS; i++) + rte_timer_init(&timers[i]); + master_start_slaves(); + } else { + slave_wait_to_start(); + if (test_failed) + goto cleanup; + } + + /* have all cores schedule all timers on master lcore */ + for (i = 0; i < NB_STRESS2_TIMERS; i++) { + ret = rte_timer_reset(&timers[i], delay, SINGLE, master, + timer_stress2_cb, NULL); + /* there will be collisions when multiple cores simultaneously + * configure the same timers */ + if (ret != 0) + my_collisions++; + } + if (my_collisions != 0) + rte_atomic32_add(&collisions, my_collisions); + + /* wait long enough for timers to expire */ + rte_delay_ms(100); + + /* all cores rendezvous */ + if (lcore_id == master) { + master_wait_for_slaves(); + } else { + slave_finish(); + } + + /* now check that we get the right number of callbacks */ + if (lcore_id == master) { + my_collisions = rte_atomic32_read(&collisions); + if (my_collisions != 0) + printf("- %d timer reset collisions (OK)\n", my_collisions); + rte_timer_manage(); + if (cb_count != NB_STRESS2_TIMERS) { + printf("Test Failed\n"); + printf("- Stress test 2, part 1 failed\n"); + printf("- Expected %d callbacks, got %d\n", NB_STRESS2_TIMERS, + cb_count); + test_failed = 1; + master_start_slaves(); + goto cleanup; + } + cb_count = 0; + + /* proceed */ + master_start_slaves(); + } else { + /* proceed */ + slave_wait_to_start(); + if (test_failed) + goto cleanup; + } + + /* now test again, just stop and restart timers at random after init*/ + for (i = 0; i < NB_STRESS2_TIMERS; i++) + rte_timer_reset(&timers[i], delay, SINGLE, master, + timer_stress2_cb, NULL); + + /* pick random timer to reset, stopping them first half the time */ + for (i = 0; i < 100000; i++) { + int r = rand() % NB_STRESS2_TIMERS; + if (i % 2) + rte_timer_stop(&timers[r]); + rte_timer_reset(&timers[r], delay, SINGLE, master, + timer_stress2_cb, NULL); + } + + /* wait long enough for timers to expire */ + rte_delay_ms(100); + + /* now check that we get the right number of callbacks */ + if (lcore_id == master) { + master_wait_for_slaves(); + + rte_timer_manage(); + if (cb_count != NB_STRESS2_TIMERS) { + printf("Test Failed\n"); + printf("- Stress test 2, part 2 failed\n"); + printf("- Expected %d callbacks, got %d\n", NB_STRESS2_TIMERS, + cb_count); + test_failed = 1; + } else { + printf("Test OK\n"); + } + } + +cleanup: + if (lcore_id == master) { + master_wait_for_slaves(); + if (timers != NULL) { + rte_free(timers); + timers = NULL; + } + } else { + slave_finish(); + } + + return 0; +} + +/* timer callback for basic tests */ +static void +timer_basic_cb(struct rte_timer *tim, void *arg) +{ + struct mytimerinfo *timinfo = arg; + uint64_t hz = rte_get_timer_hz(); + unsigned lcore_id = rte_lcore_id(); + uint64_t cur_time = rte_get_timer_cycles(); + + if (rte_timer_pending(tim)) + return; + + timinfo->count ++; + + RTE_LOG(INFO, TESTTIMER, + "%"PRIu64": callback id=%u count=%u on core %u\n", + cur_time, timinfo->id, timinfo->count, lcore_id); + + /* reload timer 0 on same core */ + if (timinfo->id == 0 && timinfo->count < 20) { + mytimer_reset(timinfo, hz, SINGLE, lcore_id, timer_basic_cb); + return; + } + + /* reload timer 1 on next core */ + if (timinfo->id == 1 && timinfo->count < 10) { + mytimer_reset(timinfo, hz*2, SINGLE, + rte_get_next_lcore(lcore_id, 0, 1), + timer_basic_cb); + return; + } + + /* Explicitelly stop timer 0. Once stop() called, we can even + * erase the content of the structure: it is not referenced + * anymore by any code (in case of dynamic structure, it can + * be freed) */ + if (timinfo->id == 0 && timinfo->count == 20) { + + /* stop_sync() is not needed, because we know that the + * status of timer is only modified by this core */ + rte_timer_stop(tim); + memset(tim, 0xAA, sizeof(struct rte_timer)); + return; + } + + /* stop timer3, and restart a new timer0 (it was removed 5 + * seconds ago) for a single shot */ + if (timinfo->id == 2 && timinfo->count == 25) { + rte_timer_stop_sync(&mytiminfo[3].tim); + + /* need to reinit because structure was erased with 0xAA */ + rte_timer_init(&mytiminfo[0].tim); + mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id, + timer_basic_cb); + } +} + +static int +timer_basic_main_loop(__attribute__((unused)) void *arg) +{ + uint64_t hz = rte_get_timer_hz(); + unsigned lcore_id = rte_lcore_id(); + uint64_t cur_time; + int64_t diff = 0; + + /* launch all timers on core 0 */ + if (lcore_id == rte_get_master_lcore()) { + mytimer_reset(&mytiminfo[0], hz/4, SINGLE, lcore_id, + timer_basic_cb); + mytimer_reset(&mytiminfo[1], hz/2, SINGLE, lcore_id, + timer_basic_cb); + mytimer_reset(&mytiminfo[2], hz/4, PERIODICAL, lcore_id, + timer_basic_cb); + mytimer_reset(&mytiminfo[3], hz/4, PERIODICAL, + rte_get_next_lcore(lcore_id, 0, 1), + timer_basic_cb); + } + + while (diff >= 0) { + + /* call the timer handler on each core */ + rte_timer_manage(); + + /* simulate the processing of a packet + * (3 us = 6000 cycles at 2 Ghz) */ + rte_delay_us(3); + + cur_time = rte_get_timer_cycles(); + diff = end_time - cur_time; + } + RTE_LOG(INFO, TESTTIMER, "core %u finished\n", lcore_id); + + return 0; +} + +static int +timer_sanity_check(void) +{ +#ifdef RTE_LIBEAL_USE_HPET + if (eal_timer_source != EAL_TIMER_HPET) { + printf("Not using HPET, can't sanity check timer sources\n"); + return 0; + } + + const uint64_t t_hz = rte_get_tsc_hz(); + const uint64_t h_hz = rte_get_hpet_hz(); + printf("Hertz values: TSC = %"PRIu64", HPET = %"PRIu64"\n", t_hz, h_hz); + + const uint64_t tsc_start = rte_get_tsc_cycles(); + const uint64_t hpet_start = rte_get_hpet_cycles(); + rte_delay_ms(100); /* delay 1/10 second */ + const uint64_t tsc_end = rte_get_tsc_cycles(); + const uint64_t hpet_end = rte_get_hpet_cycles(); + printf("Measured cycles: TSC = %"PRIu64", HPET = %"PRIu64"\n", + tsc_end-tsc_start, hpet_end-hpet_start); + + const double tsc_time = (double)(tsc_end - tsc_start)/t_hz; + const double hpet_time = (double)(hpet_end - hpet_start)/h_hz; + /* get the percentage that the times differ by */ + const double time_diff = fabs(tsc_time - hpet_time)*100/tsc_time; + printf("Measured time: TSC = %.4f, HPET = %.4f\n", tsc_time, hpet_time); + + printf("Elapsed time measured by TSC and HPET differ by %f%%\n", + time_diff); + if (time_diff > 0.1) { + printf("Error times differ by >0.1%%"); + return -1; + } +#endif + return 0; +} + +static int +test_timer(void) +{ + unsigned i; + uint64_t cur_time; + uint64_t hz; + + /* sanity check our timer sources and timer config values */ + if (timer_sanity_check() < 0) { + printf("Timer sanity checks failed\n"); + return TEST_FAILED; + } + + if (rte_lcore_count() < 2) { + printf("not enough lcores for this test\n"); + return TEST_FAILED; + } + + /* init timer */ + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_ITERATIONS 1000000 + +int outstanding_count = 0; + +static void +timer_cb(struct rte_timer *t __rte_unused, void *param __rte_unused) +{ + outstanding_count--; +} + +#define DELAY_SECONDS 1 + +#ifdef RTE_EXEC_ENV_LINUXAPP +#define do_delay() usleep(10) +#else +#define do_delay() rte_pause() +#endif + +static int +test_timer_perf(void) +{ + unsigned iterations = 100; + unsigned i; + struct rte_timer *tms; + uint64_t start_tsc, end_tsc, delay_start; + unsigned lcore_id = rte_lcore_id(); + + tms = rte_malloc(NULL, sizeof(*tms) * MAX_ITERATIONS, 0); + + for (i = 0; i < MAX_ITERATIONS; i++) + rte_timer_init(&tms[i]); + + const uint64_t ticks = rte_get_timer_hz() * DELAY_SECONDS; + const uint64_t ticks_per_ms = rte_get_tsc_hz()/1000; + const uint64_t ticks_per_us = ticks_per_ms/1000; + + while (iterations <= MAX_ITERATIONS) { + + printf("Appending %u timers\n", iterations); + start_tsc = rte_rdtsc(); + for (i = 0; i < iterations; i++) + rte_timer_reset(&tms[i], ticks, SINGLE, lcore_id, + timer_cb, NULL); + end_tsc = rte_rdtsc(); + printf("Time for %u timers: %"PRIu64" (%"PRIu64"ms), ", iterations, + end_tsc-start_tsc, (end_tsc-start_tsc+ticks_per_ms/2)/(ticks_per_ms)); + printf("Time per timer: %"PRIu64" (%"PRIu64"us)\n", + (end_tsc-start_tsc)/iterations, + ((end_tsc-start_tsc)/iterations+ticks_per_us/2)/(ticks_per_us)); + outstanding_count = iterations; + delay_start = rte_get_timer_cycles(); + while (rte_get_timer_cycles() < delay_start + ticks) + do_delay(); + + start_tsc = rte_rdtsc(); + while (outstanding_count) + rte_timer_manage(); + end_tsc = rte_rdtsc(); + printf("Time for %u callbacks: %"PRIu64" (%"PRIu64"ms), ", iterations, + end_tsc-start_tsc, (end_tsc-start_tsc+ticks_per_ms/2)/(ticks_per_ms)); + printf("Time per callback: %"PRIu64" (%"PRIu64"us)\n", + (end_tsc-start_tsc)/iterations, + ((end_tsc-start_tsc)/iterations+ticks_per_us/2)/(ticks_per_us)); + + printf("Resetting %u timers\n", iterations); + start_tsc = rte_rdtsc(); + for (i = 0; i < iterations; i++) + rte_timer_reset(&tms[i], rte_rand() % ticks, SINGLE, lcore_id, + timer_cb, NULL); + end_tsc = rte_rdtsc(); + printf("Time for %u timers: %"PRIu64" (%"PRIu64"ms), ", iterations, + end_tsc-start_tsc, (end_tsc-start_tsc+ticks_per_ms/2)/(ticks_per_ms)); + printf("Time per timer: %"PRIu64" (%"PRIu64"us)\n", + (end_tsc-start_tsc)/iterations, + ((end_tsc-start_tsc)/iterations+ticks_per_us/2)/(ticks_per_us)); + outstanding_count = iterations; + + delay_start = rte_get_timer_cycles(); + while (rte_get_timer_cycles() < delay_start + ticks) + do_delay(); + + rte_timer_manage(); + if (outstanding_count != 0) { + printf("Error: outstanding callback count = %d\n", outstanding_count); + return -1; + } + + iterations *= 10; + printf("\n"); + } + + printf("All timers processed ok\n"); + + /* measure time to poll an empty timer list */ + start_tsc = rte_rdtsc(); + for (i = 0; i < iterations; i++) + rte_timer_manage(); + end_tsc = rte_rdtsc(); + printf("\nTime per rte_timer_manage with zero timers: %"PRIu64" cycles\n", + (end_tsc - start_tsc + iterations/2) / iterations); + + /* measure time to poll a timer list with timers, but without + * calling any callbacks */ + rte_timer_reset(&tms[0], ticks * 100, SINGLE, lcore_id, + timer_cb, NULL); + start_tsc = rte_rdtsc(); + for (i = 0; i < iterations; i++) + rte_timer_manage(); + end_tsc = rte_rdtsc(); + printf("Time per rte_timer_manage with zero callbacks: %"PRIu64" cycles\n", + (end_tsc - start_tsc + iterations/2) / iterations); + + return 0; +} + +REGISTER_TEST_COMMAND(timer_perf_autotest, test_timer_perf); diff --git a/test/test/test_timer_racecond.c b/test/test/test_timer_racecond.c new file mode 100644 index 0000000000..7824ec4bf6 --- /dev/null +++ b/test/test/test_timer_racecond.c @@ -0,0 +1,205 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 Akamai Technologies. + * 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 "test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef TEST_TIMER_RACECOND_VERBOSE + +#ifdef RTE_EXEC_ENV_LINUXAPP +#define usec_delay(us) usleep(us) +#else +#define usec_delay(us) rte_delay_us(us) +#endif + +#define BILLION (1UL << 30) + +#define TEST_DURATION_S 20 /* in seconds */ +#define N_TIMERS 50 + +static struct rte_timer timer[N_TIMERS]; +static unsigned timer_lcore_id[N_TIMERS]; + +static unsigned master; +static volatile unsigned stop_slaves; + +static int reload_timer(struct rte_timer *tim); + +static void +timer_cb(struct rte_timer *tim, void *arg __rte_unused) +{ + /* Simulate slow callback function, 100 us. */ + rte_delay_us(100); + +#ifdef TEST_TIMER_RACECOND_VERBOSE + if (tim == &timer[0]) + printf("------------------------------------------------\n"); + printf("timer_cb: core %u timer %lu\n", + rte_lcore_id(), tim - timer); +#endif + (void)reload_timer(tim); +} + +RTE_DEFINE_PER_LCORE(unsigned, n_reset_collisions); + +static int +reload_timer(struct rte_timer *tim) +{ + /* Make timer expire roughly when the TSC hits the next BILLION + * multiple. Add in timer's index to make them expire in nearly + * sorted order. This makes all timers somewhat synchronized, + * firing ~2-3 times per second, assuming 2-3 GHz TSCs. + */ + uint64_t ticks = BILLION - (rte_get_timer_cycles() % BILLION) + + (tim - timer); + int ret; + + ret = rte_timer_reset(tim, ticks, PERIODICAL, master, timer_cb, NULL); + if (ret != 0) { +#ifdef TEST_TIMER_RACECOND_VERBOSE + printf("- core %u failed to reset timer %lu (OK)\n", + rte_lcore_id(), tim - timer); +#endif + RTE_PER_LCORE(n_reset_collisions) += 1; + } + return ret; +} + +static int +slave_main_loop(__attribute__((unused)) void *arg) +{ + unsigned lcore_id = rte_lcore_id(); + unsigned i; + + RTE_PER_LCORE(n_reset_collisions) = 0; + + printf("Starting main loop on core %u\n", lcore_id); + + while (!stop_slaves) { + /* Wait until the timer manager is running. + * We know it's running when we see timer[0] NOT pending. + */ + if (rte_timer_pending(&timer[0])) { + rte_pause(); + continue; + } + + /* Now, go cause some havoc! + * Reload our timers. + */ + for (i = 0; i < N_TIMERS; i++) { + if (timer_lcore_id[i] == lcore_id) + (void)reload_timer(&timer[i]); + } + usec_delay(100*1000); /* sleep 100 ms */ + } + + if (RTE_PER_LCORE(n_reset_collisions) != 0) { + printf("- core %u, %u reset collisions (OK)\n", + lcore_id, RTE_PER_LCORE(n_reset_collisions)); + } + return 0; +} + +static int +test_timer_racecond(void) +{ + int ret; + uint64_t hz; + uint64_t cur_time; + uint64_t end_time; + int64_t diff = 0; + unsigned lcore_id; + unsigned i; + + master = lcore_id = rte_lcore_id(); + hz = rte_get_timer_hz(); + + /* init and start timers */ + for (i = 0; i < N_TIMERS; i++) { + rte_timer_init(&timer[i]); + ret = reload_timer(&timer[i]); + TEST_ASSERT(ret == 0, "reload_timer failed"); + + /* Distribute timers to slaves. + * Note that we assign timer[0] to the master. + */ + timer_lcore_id[i] = lcore_id; + lcore_id = rte_get_next_lcore(lcore_id, 1, 1); + } + + /* calculate the "end of test" time */ + cur_time = rte_get_timer_cycles(); + end_time = cur_time + (hz * TEST_DURATION_S); + + /* start slave cores */ + stop_slaves = 0; + printf("Start timer manage race condition test (%u seconds)\n", + TEST_DURATION_S); + rte_eal_mp_remote_launch(slave_main_loop, NULL, SKIP_MASTER); + + while (diff >= 0) { + /* run the timers */ + rte_timer_manage(); + + /* wait 100 ms */ + usec_delay(100*1000); + + cur_time = rte_get_timer_cycles(); + diff = end_time - cur_time; + } + + /* stop slave cores */ + printf("Stopping timer manage race condition test\n"); + stop_slaves = 1; + rte_eal_mp_wait_lcore(); + + /* stop timers */ + for (i = 0; i < N_TIMERS; i++) { + ret = rte_timer_stop(&timer[i]); + TEST_ASSERT(ret == 0, "rte_timer_stop failed"); + } + + return TEST_SUCCESS; +} + +REGISTER_TEST_COMMAND(timer_racecond_autotest, test_timer_racecond); diff --git a/test/test/test_version.c b/test/test/test_version.c new file mode 100644 index 0000000000..afc0d0b888 --- /dev/null +++ b/test/test/test_version.c @@ -0,0 +1,57 @@ +/*- + * 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 +#include +#include + +#include +#include + +#include "test.h" + + +static int +test_version(void) +{ + const char *version = rte_version(); + if (version == NULL) + return -1; + printf("Version string: '%s'\n", version); + if (*version == '\0' || + strncmp(version, RTE_VER_PREFIX, sizeof(RTE_VER_PREFIX)-1) != 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(version_autotest, test_version); diff --git a/test/test/test_xmmt_ops.h b/test/test/test_xmmt_ops.h new file mode 100644 index 0000000000..42174d2c92 --- /dev/null +++ b/test/test/test_xmmt_ops.h @@ -0,0 +1,83 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 Cavium Networks. 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 Cavium Networks 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_XMMT_OPS_H_ +#define _TEST_XMMT_OPS_H_ + +#include + +#if defined(RTE_ARCH_ARM) || defined(RTE_ARCH_ARM64) + +/* vect_* abstraction implementation using NEON */ + +/* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/ +#define vect_loadu_sil128(p) vld1q_s32((const int32_t *)p) + +/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */ +static inline xmm_t __attribute__((always_inline)) +vect_set_epi32(int i3, int i2, int i1, int i0) +{ + int32_t data[4] = {i0, i1, i2, i3}; + + return vld1q_s32(data); +} + +#elif defined(RTE_ARCH_X86) + +/* vect_* abstraction implementation using SSE */ + +/* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/ +#define vect_loadu_sil128(p) _mm_loadu_si128(p) + +/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */ +#define vect_set_epi32(i3, i2, i1, i0) _mm_set_epi32(i3, i2, i1, i0) + +#elif defined(RTE_ARCH_PPC_64) + +/* vect_* abstraction implementation using ALTIVEC */ + +/* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/ +#define vect_loadu_sil128(p) vec_ld(0, p) + +/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */ +static inline xmm_t __attribute__((always_inline)) +vect_set_epi32(int i3, int i2, int i1, int i0) +{ + xmm_t data = (xmm_t){i0, i1, i2, i3}; + + return data; +} + +#endif + +#endif /* _TEST_XMMT_OPS_H_ */ diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c new file mode 100644 index 0000000000..6e4dcd8f96 --- /dev/null +++ b/test/test/virtual_pmd.c @@ -0,0 +1,641 @@ +/*- + * 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 +#include +#include +#include +#include +#include + +#include "virtual_pmd.h" + +#define MAX_PKT_BURST 512 + +static const char *virtual_ethdev_driver_name = "Virtual PMD"; + +struct virtual_ethdev_private { + struct eth_dev_ops dev_ops; + struct rte_eth_stats eth_stats; + + struct rte_ring *rx_queue; + struct rte_ring *tx_queue; + + int tx_burst_fail_count; +}; + +struct virtual_ethdev_queue { + int port_id; + int queue_id; +}; + +static int +virtual_ethdev_start_success(struct rte_eth_dev *eth_dev __rte_unused) +{ + eth_dev->data->dev_started = 1; + + return 0; +} + +static int +virtual_ethdev_start_fail(struct rte_eth_dev *eth_dev __rte_unused) +{ + eth_dev->data->dev_started = 0; + + return -1; +} +static void virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused) +{ + void *pkt = NULL; + struct virtual_ethdev_private *prv = eth_dev->data->dev_private; + + eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; + eth_dev->data->dev_started = 0; + while (rte_ring_dequeue(prv->rx_queue, &pkt) != -ENOENT) + rte_pktmbuf_free(pkt); + + while (rte_ring_dequeue(prv->tx_queue, &pkt) != -ENOENT) + rte_pktmbuf_free(pkt); +} + +static void +virtual_ethdev_close(struct rte_eth_dev *dev __rte_unused) +{} + +static int +virtual_ethdev_configure_success(struct rte_eth_dev *dev __rte_unused) +{ + return 0; +} + +static int +virtual_ethdev_configure_fail(struct rte_eth_dev *dev __rte_unused) +{ + return -1; +} + +static void +virtual_ethdev_info_get(struct rte_eth_dev *dev __rte_unused, + struct rte_eth_dev_info *dev_info) +{ + dev_info->driver_name = virtual_ethdev_driver_name; + dev_info->max_mac_addrs = 1; + + dev_info->max_rx_pktlen = (uint32_t)2048; + + dev_info->max_rx_queues = (uint16_t)128; + dev_info->max_tx_queues = (uint16_t)512; + + dev_info->min_rx_bufsize = 0; +} + +static int +virtual_ethdev_rx_queue_setup_success(struct rte_eth_dev *dev, + uint16_t rx_queue_id, uint16_t nb_rx_desc __rte_unused, + unsigned int socket_id, + const struct rte_eth_rxconf *rx_conf __rte_unused, + struct rte_mempool *mb_pool __rte_unused) +{ + struct virtual_ethdev_queue *rx_q; + + rx_q = (struct virtual_ethdev_queue *)rte_zmalloc_socket(NULL, + sizeof(struct virtual_ethdev_queue), 0, socket_id); + + if (rx_q == NULL) + return -1; + + rx_q->port_id = dev->data->port_id; + rx_q->queue_id = rx_queue_id; + + dev->data->rx_queues[rx_queue_id] = rx_q; + + return 0; +} + +static int +virtual_ethdev_rx_queue_setup_fail(struct rte_eth_dev *dev __rte_unused, + uint16_t rx_queue_id __rte_unused, uint16_t nb_rx_desc __rte_unused, + unsigned int socket_id __rte_unused, + const struct rte_eth_rxconf *rx_conf __rte_unused, + struct rte_mempool *mb_pool __rte_unused) +{ + return -1; +} + +static int +virtual_ethdev_tx_queue_setup_success(struct rte_eth_dev *dev, + uint16_t tx_queue_id, uint16_t nb_tx_desc __rte_unused, + unsigned int socket_id, + const struct rte_eth_txconf *tx_conf __rte_unused) +{ + struct virtual_ethdev_queue *tx_q; + + tx_q = (struct virtual_ethdev_queue *)rte_zmalloc_socket(NULL, + sizeof(struct virtual_ethdev_queue), 0, socket_id); + + if (tx_q == NULL) + return -1; + + tx_q->port_id = dev->data->port_id; + tx_q->queue_id = tx_queue_id; + + dev->data->tx_queues[tx_queue_id] = tx_q; + + return 0; +} + +static int +virtual_ethdev_tx_queue_setup_fail(struct rte_eth_dev *dev __rte_unused, + uint16_t tx_queue_id __rte_unused, uint16_t nb_tx_desc __rte_unused, + unsigned int socket_id __rte_unused, + const struct rte_eth_txconf *tx_conf __rte_unused) +{ + return -1; +} + +static void +virtual_ethdev_rx_queue_release(void *q __rte_unused) +{ +} + +static void +virtual_ethdev_tx_queue_release(void *q __rte_unused) +{ +} + +static int +virtual_ethdev_link_update_success(struct rte_eth_dev *bonded_eth_dev, + int wait_to_complete __rte_unused) +{ + if (!bonded_eth_dev->data->dev_started) + bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; + + return 0; +} + +static int +virtual_ethdev_link_update_fail(struct rte_eth_dev *bonded_eth_dev __rte_unused, + int wait_to_complete __rte_unused) +{ + return -1; +} + +static void +virtual_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +{ + struct virtual_ethdev_private *dev_private = dev->data->dev_private; + + if (stats) + rte_memcpy(stats, &dev_private->eth_stats, sizeof(*stats)); +} + +static void +virtual_ethdev_stats_reset(struct rte_eth_dev *dev) +{ + struct virtual_ethdev_private *dev_private = dev->data->dev_private; + void *pkt = NULL; + + while (rte_ring_dequeue(dev_private->tx_queue, &pkt) == -ENOBUFS) + rte_pktmbuf_free(pkt); + + /* Reset internal statistics */ + memset(&dev_private->eth_stats, 0, sizeof(dev_private->eth_stats)); +} + +static void +virtual_ethdev_promiscuous_mode_enable(struct rte_eth_dev *dev __rte_unused) +{} + +static void +virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused) +{} + + +static const struct eth_dev_ops virtual_ethdev_default_dev_ops = { + .dev_configure = virtual_ethdev_configure_success, + .dev_start = virtual_ethdev_start_success, + .dev_stop = virtual_ethdev_stop, + .dev_close = virtual_ethdev_close, + .dev_infos_get = virtual_ethdev_info_get, + .rx_queue_setup = virtual_ethdev_rx_queue_setup_success, + .tx_queue_setup = virtual_ethdev_tx_queue_setup_success, + .rx_queue_release = virtual_ethdev_rx_queue_release, + .tx_queue_release = virtual_ethdev_tx_queue_release, + .link_update = virtual_ethdev_link_update_success, + .stats_get = virtual_ethdev_stats_get, + .stats_reset = virtual_ethdev_stats_reset, + .promiscuous_enable = virtual_ethdev_promiscuous_mode_enable, + .promiscuous_disable = virtual_ethdev_promiscuous_mode_disable +}; + + +void +virtual_ethdev_start_fn_set_success(uint8_t port_id, uint8_t success) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + struct virtual_ethdev_private *dev_private = dev->data->dev_private; + struct eth_dev_ops *dev_ops = &dev_private->dev_ops; + + if (success) + dev_ops->dev_start = virtual_ethdev_start_success; + else + dev_ops->dev_start = virtual_ethdev_start_fail; + +} + +void +virtual_ethdev_configure_fn_set_success(uint8_t port_id, uint8_t success) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + struct virtual_ethdev_private *dev_private = dev->data->dev_private; + struct eth_dev_ops *dev_ops = &dev_private->dev_ops; + + if (success) + dev_ops->dev_configure = virtual_ethdev_configure_success; + else + dev_ops->dev_configure = virtual_ethdev_configure_fail; +} + +void +virtual_ethdev_rx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + struct virtual_ethdev_private *dev_private = dev->data->dev_private; + struct eth_dev_ops *dev_ops = &dev_private->dev_ops; + + if (success) + dev_ops->rx_queue_setup = virtual_ethdev_rx_queue_setup_success; + else + dev_ops->rx_queue_setup = virtual_ethdev_rx_queue_setup_fail; +} + +void +virtual_ethdev_tx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + struct virtual_ethdev_private *dev_private = dev->data->dev_private; + struct eth_dev_ops *dev_ops = &dev_private->dev_ops; + + if (success) + dev_ops->tx_queue_setup = virtual_ethdev_tx_queue_setup_success; + else + dev_ops->tx_queue_setup = virtual_ethdev_tx_queue_setup_fail; +} + +void +virtual_ethdev_link_update_fn_set_success(uint8_t port_id, uint8_t success) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + struct virtual_ethdev_private *dev_private = dev->data->dev_private; + struct eth_dev_ops *dev_ops = &dev_private->dev_ops; + + if (success) + dev_ops->link_update = virtual_ethdev_link_update_success; + else + dev_ops->link_update = virtual_ethdev_link_update_fail; +} + + +static uint16_t +virtual_ethdev_rx_burst_success(void *queue __rte_unused, + struct rte_mbuf **bufs, + uint16_t nb_pkts) +{ + struct rte_eth_dev *vrtl_eth_dev; + struct virtual_ethdev_queue *pq_map; + struct virtual_ethdev_private *dev_private; + + int rx_count, i; + + pq_map = (struct virtual_ethdev_queue *)queue; + vrtl_eth_dev = &rte_eth_devices[pq_map->port_id]; + dev_private = vrtl_eth_dev->data->dev_private; + + rx_count = rte_ring_dequeue_burst(dev_private->rx_queue, (void **) bufs, + nb_pkts); + + /* increments ipackets count */ + dev_private->eth_stats.ipackets += rx_count; + + /* increments ibytes count */ + for (i = 0; i < rx_count; i++) + dev_private->eth_stats.ibytes += rte_pktmbuf_pkt_len(bufs[i]); + + return rx_count; +} + +static uint16_t +virtual_ethdev_rx_burst_fail(void *queue __rte_unused, + struct rte_mbuf **bufs __rte_unused, + uint16_t nb_pkts __rte_unused) +{ + return 0; +} + +static uint16_t +virtual_ethdev_tx_burst_success(void *queue, struct rte_mbuf **bufs, + uint16_t nb_pkts) +{ + struct virtual_ethdev_queue *tx_q = (struct virtual_ethdev_queue *)queue; + + struct rte_eth_dev *vrtl_eth_dev; + struct virtual_ethdev_private *dev_private; + + int i; + + vrtl_eth_dev = &rte_eth_devices[tx_q->port_id]; + dev_private = vrtl_eth_dev->data->dev_private; + + if (!vrtl_eth_dev->data->dev_link.link_status) + nb_pkts = 0; + else + nb_pkts = rte_ring_enqueue_burst(dev_private->tx_queue, (void **)bufs, + nb_pkts); + + /* increment opacket count */ + dev_private->eth_stats.opackets += nb_pkts; + + /* increment obytes count */ + for (i = 0; i < nb_pkts; i++) + dev_private->eth_stats.obytes += rte_pktmbuf_pkt_len(bufs[i]); + + return nb_pkts; +} + +static uint16_t +virtual_ethdev_tx_burst_fail(void *queue, struct rte_mbuf **bufs, + uint16_t nb_pkts) +{ + struct rte_eth_dev *vrtl_eth_dev = NULL; + struct virtual_ethdev_queue *tx_q = NULL; + struct virtual_ethdev_private *dev_private = NULL; + + int i; + + tx_q = (struct virtual_ethdev_queue *)queue; + vrtl_eth_dev = &rte_eth_devices[tx_q->port_id]; + dev_private = vrtl_eth_dev->data->dev_private; + + if (dev_private->tx_burst_fail_count < nb_pkts) { + int successfully_txd = nb_pkts - dev_private->tx_burst_fail_count; + + /* increment opacket count */ + dev_private->eth_stats.opackets += successfully_txd; + + /* free packets in burst */ + for (i = 0; i < successfully_txd; i++) { + /* free packets in burst */ + if (bufs[i] != NULL) + rte_pktmbuf_free(bufs[i]); + + bufs[i] = NULL; + } + + return successfully_txd; + } + + return 0; +} + + +void +virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success) +{ + struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; + + if (success) + vrtl_eth_dev->rx_pkt_burst = virtual_ethdev_rx_burst_success; + else + vrtl_eth_dev->rx_pkt_burst = virtual_ethdev_rx_burst_fail; +} + + +void +virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success) +{ + struct virtual_ethdev_private *dev_private = NULL; + struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; + + dev_private = vrtl_eth_dev->data->dev_private; + + if (success) + vrtl_eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_success; + else + vrtl_eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_fail; + + dev_private->tx_burst_fail_count = 0; +} + +void +virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id, + uint8_t packet_fail_count) +{ + struct virtual_ethdev_private *dev_private = NULL; + struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; + + + dev_private = vrtl_eth_dev->data->dev_private; + dev_private->tx_burst_fail_count = packet_fail_count; +} + +void +virtual_ethdev_set_link_status(uint8_t port_id, uint8_t link_status) +{ + struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; + + vrtl_eth_dev->data->dev_link.link_status = link_status; +} + +void +virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id, + uint8_t link_status) +{ + struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; + + vrtl_eth_dev->data->dev_link.link_status = link_status; + + _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL); +} + +int +virtual_ethdev_add_mbufs_to_rx_queue(uint8_t port_id, + struct rte_mbuf **pkt_burst, int burst_length) +{ + struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; + struct virtual_ethdev_private *dev_private = + vrtl_eth_dev->data->dev_private; + + return rte_ring_enqueue_burst(dev_private->rx_queue, (void **)pkt_burst, + burst_length); +} + +int +virtual_ethdev_get_mbufs_from_tx_queue(uint8_t port_id, + struct rte_mbuf **pkt_burst, int burst_length) +{ + struct virtual_ethdev_private *dev_private; + struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id]; + + dev_private = vrtl_eth_dev->data->dev_private; + return rte_ring_dequeue_burst(dev_private->tx_queue, (void **)pkt_burst, + burst_length); +} + +static uint8_t +get_number_of_sockets(void) +{ + int sockets = 0; + int i; + const struct rte_memseg *ms = rte_eal_get_physmem_layout(); + + for (i = 0; i < RTE_MAX_MEMSEG && ms[i].addr != NULL; i++) { + if (sockets < ms[i].socket_id) + sockets = ms[i].socket_id; + } + /* Number of sockets = maximum socket_id + 1 */ + return ++sockets; +} + +int +virtual_ethdev_create(const char *name, struct ether_addr *mac_addr, + uint8_t socket_id, uint8_t isr_support) +{ + struct rte_pci_device *pci_dev = NULL; + struct rte_eth_dev *eth_dev = NULL; + struct eth_driver *eth_drv = NULL; + struct rte_pci_driver *pci_drv = NULL; + struct rte_pci_id *id_table = NULL; + struct virtual_ethdev_private *dev_private = NULL; + char name_buf[RTE_RING_NAMESIZE]; + + + /* now do all data allocation - for eth_dev structure, dummy pci driver + * and internal (dev_private) data + */ + + if (socket_id >= get_number_of_sockets()) + goto err; + + pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, socket_id); + if (pci_dev == NULL) + goto err; + + eth_drv = rte_zmalloc_socket(name, sizeof(*eth_drv), 0, socket_id); + if (eth_drv == NULL) + goto err; + + pci_drv = rte_zmalloc_socket(name, sizeof(*pci_drv), 0, socket_id); + if (pci_drv == NULL) + goto err; + + id_table = rte_zmalloc_socket(name, sizeof(*id_table), 0, socket_id); + if (id_table == NULL) + goto err; + id_table->device_id = 0xBEEF; + + dev_private = rte_zmalloc_socket(name, sizeof(*dev_private), 0, socket_id); + if (dev_private == NULL) + goto err; + + snprintf(name_buf, sizeof(name_buf), "%s_rxQ", name); + dev_private->rx_queue = rte_ring_create(name_buf, MAX_PKT_BURST, socket_id, + 0); + if (dev_private->rx_queue == NULL) + goto err; + + snprintf(name_buf, sizeof(name_buf), "%s_txQ", name); + dev_private->tx_queue = rte_ring_create(name_buf, MAX_PKT_BURST, socket_id, + 0); + if (dev_private->tx_queue == NULL) + goto err; + + /* reserve an ethdev entry */ + eth_dev = rte_eth_dev_allocate(name); + if (eth_dev == NULL) + goto err; + + pci_dev->device.numa_node = socket_id; + pci_drv->driver.name = virtual_ethdev_driver_name; + pci_drv->id_table = id_table; + + if (isr_support) + pci_drv->drv_flags |= RTE_PCI_DRV_INTR_LSC; + else + pci_drv->drv_flags &= ~RTE_PCI_DRV_INTR_LSC; + + + eth_drv->pci_drv = (struct rte_pci_driver)(*pci_drv); + eth_dev->driver = eth_drv; + + eth_dev->data->nb_rx_queues = (uint16_t)1; + eth_dev->data->nb_tx_queues = (uint16_t)1; + + eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; + eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G; + eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX; + + eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0); + if (eth_dev->data->mac_addrs == NULL) + goto err; + + memcpy(eth_dev->data->mac_addrs, mac_addr, + sizeof(*eth_dev->data->mac_addrs)); + + eth_dev->data->dev_started = 0; + eth_dev->data->promiscuous = 0; + eth_dev->data->scattered_rx = 0; + eth_dev->data->all_multicast = 0; + + eth_dev->data->dev_private = dev_private; + + /* Copy default device operation functions */ + dev_private->dev_ops = virtual_ethdev_default_dev_ops; + eth_dev->dev_ops = &dev_private->dev_ops; + + pci_dev->device.driver = ð_drv->pci_drv.driver; + eth_dev->device = &pci_dev->device; + + eth_dev->rx_pkt_burst = virtual_ethdev_rx_burst_success; + eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_success; + + return eth_dev->data->port_id; + +err: + rte_free(pci_dev); + rte_free(pci_drv); + rte_free(eth_drv); + rte_free(id_table); + rte_free(dev_private); + + return -1; +} diff --git a/test/test/virtual_pmd.h b/test/test/virtual_pmd.h new file mode 100644 index 0000000000..de001884de --- /dev/null +++ b/test/test/virtual_pmd.h @@ -0,0 +1,104 @@ +/*- + * 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 __VIRTUAL_ETHDEV_H_ +#define __VIRTUAL_ETHDEV_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int +virtual_ethdev_init(void); + +int +virtual_ethdev_create(const char *name, struct ether_addr *mac_addr, + uint8_t socket_id, uint8_t isr_support); + +void +virtual_ethdev_set_link_status(uint8_t port_id, uint8_t link_status); + +void +virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id, + uint8_t link_status); + +int +virtual_ethdev_add_mbufs_to_rx_queue(uint8_t port_id, + struct rte_mbuf **pkts_burst, int burst_length); + +int +virtual_ethdev_get_mbufs_from_tx_queue(uint8_t port_id, + struct rte_mbuf **pkt_burst, int burst_length); + +/** Control methods for the dev_ops functions pointer to control the behavior + * of the Virtual PMD */ + +void +virtual_ethdev_start_fn_set_success(uint8_t port_id, uint8_t success); + +void +virtual_ethdev_stop_fn_set_success(uint8_t port_id, uint8_t success); + +void +virtual_ethdev_configure_fn_set_success(uint8_t port_id, uint8_t success); + +void +virtual_ethdev_rx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success); + +void +virtual_ethdev_tx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success); + +void +virtual_ethdev_link_update_fn_set_success(uint8_t port_id, uint8_t success); + +void +virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success); + +void +virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success); + +/* if a value greater than zero is set for packet_fail_count then virtual + * device tx burst function will fail that many packet from burst or all + * packets if packet_fail_count is greater than the number of packets in the + * burst */ +void +virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id, + uint8_t packet_fail_count); + +#ifdef __cplusplus +} +#endif + +#endif /* __VIRTUAL_ETHDEV_H_ */