From: Bruce Richardson Date: Tue, 26 Feb 2019 12:19:03 +0000 (+0000) Subject: test: move to app directory X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=a9de470cc7c0649221e156fc5f30a2dbdfe7c166;p=dpdk.git test: move to app directory Since all other apps have been moved to the "app" folder, the autotest app remains alone in the test folder. Rather than having an entire top-level folder for this, we can move it back to where it all started in early versions of DPDK - the "app/" folder. This move has a couple of advantages: * This reduces clutter at the top level of the project, due to one less folder. * It eliminates the separate build task necessary for building the autotests using make "make test-build" which means that developers are less likely to miss something in their own compilation tests * It re-aligns the final location of the test binary in the app folder when building with make with it's location in the source tree. For meson builds, the autotest app is different from the other apps in that it needs a series of different test cases defined for it for use by "meson test". Therefore, it does not get built as part of the main loop in the app folder, but gets built separately at the end. Signed-off-by: Bruce Richardson --- diff --git a/GNUmakefile b/GNUmakefile index ae80720e99..e8de422df8 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -13,6 +13,5 @@ export RTE_SDK # ROOTDIRS-y := buildtools lib kernel drivers app -ROOTDIRS- := test include $(RTE_SDK)/mk/rte.sdkroot.mk diff --git a/MAINTAINERS b/MAINTAINERS index e1c0f669be..15c53888c2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -142,27 +142,27 @@ F: lib/librte_eal/common/include/* F: lib/librte_eal/common/include/generic/ F: lib/librte_eal/rte_eal_version.map F: doc/guides/prog_guide/env_abstraction_layer.rst -F: test/test/test_alarm.c -F: test/test/test_atomic.c -F: test/test/test_barrier.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_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_per_lcore.c -F: test/test/test_prefetch.c -F: test/test/test_reciprocal_division* -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 +F: app/test/test_alarm.c +F: app/test/test_atomic.c +F: app/test/test_barrier.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_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_per_lcore.c +F: app/test/test_prefetch.c +F: app/test/test_reciprocal_division* +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 Memory Allocation M: Anatoly Burakov @@ -176,12 +176,12 @@ F: lib/librte_eal/common/eal_hugepages.h F: lib/librte_eal/linuxapp/eal/eal_mem* F: lib/librte_eal/bsdapp/eal/eal_mem* F: doc/guides/prog_guide/env_abstraction_layer.rst -F: test/test/test_external_mem.c -F: test/test/test_func_reentrancy.c -F: test/test/test_fbarray.c -F: test/test/test_malloc.c -F: test/test/test_memory.c -F: test/test/test_memzone.c +F: app/test/test_external_mem.c +F: app/test/test_func_reentrancy.c +F: app/test/test_fbarray.c +F: app/test/test_malloc.c +F: app/test/test_memory.c +F: app/test/test_memzone.c Keep alive M: Remy Horton @@ -194,7 +194,7 @@ Secondary process M: Anatoly Burakov K: RTE_PROC_ F: doc/guides/prog_guide/multi_proc_support.rst -F: test/test/test_mp_secondary.c +F: app/test/test_mp_secondary.c F: examples/multi_process/ F: doc/guides/sample_app_ug/multi_process.rst @@ -204,12 +204,12 @@ F: lib/librte_eal/common/include/rte_service.h F: lib/librte_eal/common/include/rte_service_component.h F: lib/librte_eal/common/rte_service.c F: doc/guides/prog_guide/service_cores.rst -F: test/test/test_service_cores.c +F: app/test/test_service_cores.c Bitmap M: Cristian Dumitrescu F: lib/librte_eal/common/include/rte_bitmap.h -F: test/test/test_bitmap.c +F: app/test/test_bitmap.c ARM v7 M: Jan Viktorin @@ -285,21 +285,21 @@ F: drivers/mempool/Makefile F: drivers/mempool/ring/ F: drivers/mempool/stack/ F: doc/guides/prog_guide/mempool_lib.rst -F: test/test/test_mempool* -F: test/test/test_func_reentrancy.c +F: app/test/test_mempool* +F: app/test/test_func_reentrancy.c Ring queue M: Olivier Matz F: lib/librte_ring/ F: doc/guides/prog_guide/ring_lib.rst -F: test/test/test_ring* -F: test/test/test_func_reentrancy.c +F: app/test/test_ring* +F: app/test/test_func_reentrancy.c Packet buffer M: Olivier Matz F: lib/librte_mbuf/ F: doc/guides/prog_guide/mbuf_lib.rst -F: test/test/test_mbuf.c +F: app/test/test_mbuf.c Ethernet API M: Thomas Monjalon @@ -342,7 +342,7 @@ M: Pablo de Lara M: Declan Doherty T: git://dpdk.org/next/dpdk-next-crypto F: lib/librte_cryptodev/ -F: test/test/test_cryptodev* +F: app/test/test_cryptodev* F: examples/l2fwd-crypto/ Security API @@ -359,7 +359,7 @@ M: Ashish Gupta T: git://dpdk.org/next/dpdk-next-crypto F: lib/librte_compressdev/ F: drivers/compress/ -F: test/test/test_compressdev* +F: app/test/test_compressdev* F: doc/guides/prog_guide/compressdev.rst F: doc/guides/compressdevs/features/default.ini @@ -368,34 +368,34 @@ M: Jerin Jacob T: git://dpdk.org/next/dpdk-next-eventdev F: lib/librte_eventdev/ F: drivers/event/skeleton/ -F: test/test/test_eventdev.c +F: app/test/test_eventdev.c Eventdev Ethdev Rx Adapter API - EXPERIMENTAL M: Nikhil Rao T: git://dpdk.org/next/dpdk-next-eventdev F: lib/librte_eventdev/*eth_rx_adapter* -F: test/test/test_event_eth_rx_adapter.c +F: app/test/test_event_eth_rx_adapter.c F: doc/guides/prog_guide/event_ethernet_rx_adapter.rst Eventdev Ethdev Tx Adapter API - EXPERIMENTAL M: Nikhil Rao T: git://dpdk.org/next/dpdk-next-eventdev F: lib/librte_eventdev/*eth_tx_adapter* -F: test/test/test_event_eth_tx_adapter.c +F: app/test/test_event_eth_tx_adapter.c F: doc/guides/prog_guide/event_ethernet_tx_adapter.rst Eventdev Timer Adapter API - EXPERIMENTAL M: Erik Gabriel Carrillo T: git://dpdk.org/next/dpdk-next-eventdev F: lib/librte_eventdev/*timer_adapter* -F: test/test/test_event_timer_adapter.c +F: app/test/test_event_timer_adapter.c F: doc/guides/prog_guide/event_timer_adapter.rst Eventdev Crypto Adapter API - EXPERIMENTAL M: Abhinandan Gujjar T: git://dpdk.org/next/dpdk-next-eventdev F: lib/librte_eventdev/*crypto_adapter* -F: test/test/test_event_crypto_adapter.c +F: app/test/test_event_crypto_adapter.c F: doc/guides/prog_guide/event_crypto_adapter.rst Raw device API - EXPERIMENTAL @@ -403,7 +403,7 @@ M: Shreyansh Jain M: Hemant Agrawal F: lib/librte_rawdev/ F: drivers/raw/skeleton_rawdev/ -F: test/test/test_rawdev.c +F: app/test/test_rawdev.c F: doc/guides/prog_guide/rawdev.rst @@ -451,7 +451,7 @@ Link bonding M: Chas Williams F: drivers/net/bonding/ F: doc/guides/prog_guide/link_bonding_poll_mode_drv_lib.rst -F: test/test/test_link_bonding* +F: app/test/test_link_bonding* F: examples/bond/ F: doc/guides/nics/features/bonding.ini @@ -460,7 +460,7 @@ M: Ferruh Yigit F: kernel/linux/kni/ F: lib/librte_kni/ F: doc/guides/prog_guide/kernel_nic_interface.rst -F: test/test/test_kni.c +F: app/test/test_kni.c F: examples/kni/ F: doc/guides/sample_app_ug/kernel_nic_interface.rst @@ -769,8 +769,8 @@ Ring PMD M: Bruce Richardson F: drivers/net/ring/ F: doc/guides/nics/pcap_ring.rst -F: test/test/test_pmd_ring.c -F: test/test/test_pmd_ring_perf.c +F: app/test/test_pmd_ring.c +F: app/test/test_pmd_ring_perf.c F: doc/guides/nics/features/ring.ini Null Networking PMD @@ -1014,7 +1014,7 @@ Packet CRC M: Jasvinder Singh F: lib/librte_net/rte_net_crc* F: lib/librte_net/net_crc_sse.h -F: test/test/test_crc.c +F: app/test/test_crc.c IP fragmentation & reassembly M: Konstantin Ananyev @@ -1040,13 +1040,13 @@ M: Konstantin Ananyev T: git://dpdk.org/next/dpdk-next-crypto F: lib/librte_ipsec/ M: Bernard Iremonger -F: test/test/test_ipsec.c +F: app/test/test_ipsec.c F: doc/guides/prog_guide/ipsec_lib.rst Flow Classify - EXPERIMENTAL M: Bernard Iremonger F: lib/librte_flow_classify/ -F: test/test/test_flow_classify* +F: app/test/test_flow_classify* F: doc/guides/prog_guide/flow_classify_lib.rst F: examples/flow_classify/ F: doc/guides/sample_app_ug/flow_classify.rst @@ -1055,7 +1055,7 @@ Distributor M: David Hunt F: lib/librte_distributor/ F: doc/guides/prog_guide/packet_distrib_lib.rst -F: test/test/test_distributor* +F: app/test/test_distributor* F: examples/distributor/ F: doc/guides/sample_app_ug/dist_app.rst @@ -1063,7 +1063,7 @@ Reorder M: Reshma Pattan F: lib/librte_reorder/ F: doc/guides/prog_guide/reorder_lib.rst -F: test/test/test_reorder* +F: app/test/test_reorder* F: examples/packet_ordering/ F: doc/guides/sample_app_ug/packet_ordering.rst @@ -1071,8 +1071,8 @@ Hierarchical scheduler M: Cristian Dumitrescu F: lib/librte_sched/ F: doc/guides/prog_guide/qos_framework.rst -F: test/test/test_red.c -F: test/test/test_sched.c +F: app/test/test_red.c +F: app/test/test_sched.c F: examples/qos_sched/ F: doc/guides/sample_app_ug/qos_scheduler.rst @@ -1080,7 +1080,7 @@ Packet capture M: Reshma Pattan F: lib/librte_pdump/ F: doc/guides/prog_guide/pdump_lib.rst -F: test/test/test_pdump.* +F: app/test/test_pdump.* F: app/pdump/ F: doc/guides/tools/pdump.rst @@ -1092,7 +1092,7 @@ F: lib/librte_pipeline/ F: lib/librte_port/ F: lib/librte_table/ F: doc/guides/prog_guide/packet_framework.rst -F: test/test/test_table* +F: app/test/test_table* F: app/test-pipeline/ F: doc/guides/sample_app_ug/test_pipeline.rst F: examples/ip_pipeline/ @@ -1107,7 +1107,7 @@ M: Konstantin Ananyev F: lib/librte_acl/ F: doc/guides/prog_guide/packet_classif_access_ctrl.rst F: app/test-acl/ -F: test/test/test_acl.* +F: app/test/test_acl.* F: examples/l3fwd-acl/ F: doc/guides/sample_app_ug/l3_forward_access_ctrl.rst @@ -1116,7 +1116,7 @@ M: Byron Marohn M: Pablo de Lara Guarch F: lib/librte_efd/ F: doc/guides/prog_guide/efd_lib.rst -F: test/test/test_efd* +F: app/test/test_efd* F: examples/server_node_efd/ F: doc/guides/sample_app_ug/server_node_efd.rst @@ -1127,30 +1127,30 @@ M: Bruce Richardson M: Pablo de Lara F: lib/librte_hash/ F: doc/guides/prog_guide/hash_lib.rst -F: test/test/test_*hash* -F: test/test/test_func_reentrancy.c +F: app/test/test_*hash* +F: app/test/test_func_reentrancy.c LPM M: Bruce Richardson M: Vladimir Medvedkin F: lib/librte_lpm/ F: doc/guides/prog_guide/lpm* -F: test/test/test_lpm* -F: test/test/test_func_reentrancy.c -F: test/test/test_xmmt_ops.h +F: app/test/test_lpm* +F: app/test/test_func_reentrancy.c +F: app/test/test_xmmt_ops.h Membership - EXPERIMENTAL M: Yipeng Wang M: Sameh Gobriel F: lib/librte_member/ F: doc/guides/prog_guide/member_lib.rst -F: test/test/test_member* +F: app/test/test_member* Traffic metering M: Cristian Dumitrescu F: lib/librte_meter/ F: doc/guides/sample_app_ug/qos_scheduler.rst -F: test/test/test_meter.c +F: app/test/test_meter.c F: examples/qos_meter/ F: doc/guides/sample_app_ug/qos_metering.rst @@ -1161,21 +1161,21 @@ Other libraries Configuration file M: Cristian Dumitrescu F: lib/librte_cfgfile/ -F: test/test/test_cfgfile.c -F: test/test/test_cfgfiles/ +F: app/test/test_cfgfile.c +F: app/test/test_cfgfiles/ Interactive command line M: Olivier Matz F: lib/librte_cmdline/ F: app/test-cmdline/ -F: test/test/test_cmdline* +F: app/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: test/test/test_kvargs.c +F: app/test/test_kvargs.c PCI M: Gaetan Rivet @@ -1185,7 +1185,7 @@ Power management M: David Hunt F: lib/librte_power/ F: doc/guides/prog_guide/power_man.rst -F: test/test/test_power* +F: app/test/test_power* F: examples/l3fwd-power/ F: doc/guides/sample_app_ug/l3_forward_power_man.rst F: examples/vm_power_manager/ @@ -1195,7 +1195,7 @@ Timers M: Robert Sanford F: lib/librte_timer/ F: doc/guides/prog_guide/timer_lib.rst -F: test/test/test_timer* +F: app/test/test_timer* F: examples/timer/ F: doc/guides/sample_app_ug/timer.rst @@ -1208,17 +1208,17 @@ F: doc/guides/sample_app_ug/l2_forward_job_stats.rst Metrics M: Remy Horton F: lib/librte_metrics/ -F: test/test/test_metrics.c +F: app/test/test_metrics.c Bit-rate statistics M: Remy Horton F: lib/librte_bitratestats/ -F: test/test/test_bitratestats.c +F: app/test/test_bitratestats.c Latency statistics M: Reshma Pattan F: lib/librte_latencystats/ -F: test/test/test_latencystats.c +F: app/test/test_latencystats.c Telemetry - EXPERIMENTAL M: Kevin Laatz @@ -1230,7 +1230,7 @@ BPF - EXPERIMENTAL M: Konstantin Ananyev F: lib/librte_bpf/ F: examples/bpf/ -F: test/test/test_bpf.c +F: app/test/test_bpf.c F: doc/guides/prog_guide/bpf_lib.rst @@ -1239,24 +1239,24 @@ Test Applications Unit tests framework 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 +F: app/test/Makefile +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 Sample packet helper functions for unit test M: Reshma Pattan -F: test/test/sample_packet_forward.c -F: test/test/sample_packet_forward.h +F: app/test/sample_packet_forward.c +F: app/test/sample_packet_forward.h Driver testing tool M: Wenzhuo Lu @@ -1280,7 +1280,7 @@ M: Jerin Jacob F: app/test-eventdev/ F: doc/guides/tools/testeventdev.rst F: doc/guides/tools/img/eventdev_* -F: test/test/test_event_ring.c +F: app/test/test_event_ring.c Procinfo tool M: Maryam Tahhan diff --git a/app/Makefile b/app/Makefile index eaf5016332..28acbceca9 100644 --- a/app/Makefile +++ b/app/Makefile @@ -3,6 +3,7 @@ include $(RTE_SDK)/mk/rte.vars.mk +DIRS-$(CONFIG_RTE_APP_TEST) += test DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd DIRS-$(CONFIG_RTE_PROC_INFO) += proc-info DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += pdump diff --git a/app/meson.build b/app/meson.build index 2360a3d45a..aa353f6572 100644 --- a/app/meson.build +++ b/app/meson.build @@ -65,3 +65,6 @@ foreach app:apps install: true) endif endforeach + +# special case the autotests +subdir('test') diff --git a/app/test/Makefile b/app/test/Makefile new file mode 100644 index 0000000000..89949c2bb9 --- /dev/null +++ b/app/test/Makefile @@ -0,0 +1,286 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2010-2017 Intel Corporation + +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) + +# how many workers to run tests with. FreeBSD doesn't support multiple primary +# processes, so make it 1, otherwise make it 4. ignored for non-parallel tests +n_processes = 1 if "bsdapp" in target else 4 + +runner = autotest_runner.AutotestRunner(cmdline, target, test_blacklist, + test_whitelist, n_processes) + +runner.parallel_tests = autotest_data.parallel_test_list[:] +runner.non_parallel_tests = autotest_data.non_parallel_test_list[:] + +num_fails = runner.run_all_tests() + +sys.exit(num_fails) diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py new file mode 100644 index 0000000000..5f87bb94dd --- /dev/null +++ b/app/test/autotest_data.py @@ -0,0 +1,706 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2010-2014 Intel Corporation + +# Test data for autotests + +from autotest_test_funcs import * + +# groups of tests that can be run in parallel +# the grouping has been found largely empirically +parallel_test_list = [ + { + "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, + }, + { + "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, + }, + { + "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, + }, + { + "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, + }, + { + "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, + }, + { + "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, + }, + { + "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, + }, + { + "Name": "Eventdev selftest octeontx", + "Command": "eventdev_selftest_octeontx", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Event ring autotest", + "Command": "event_ring_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Table autotest", + "Command": "table_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Flow classify autotest", + "Command": "flow_classify_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Event eth rx adapter autotest", + "Command": "event_eth_rx_adapter_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "User delay", + "Command": "user_delay_us", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Sleep delay", + "Command": "delay_us_sleep_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Rawdev autotest", + "Command": "rawdev_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Kvargs autotest", + "Command": "kvargs_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Devargs autotest", + "Command": "devargs_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Link bonding autotest", + "Command": "link_bonding_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Link bonding mode4 autotest", + "Command": "link_bonding_mode4_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Link bonding rssconf autotest", + "Command": "link_bonding_rssconf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Crc autotest", + "Command": "crc_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Distributor autotest", + "Command": "distributor_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Reorder autotest", + "Command": "reorder_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Barrier autotest", + "Command": "barrier_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Bitmap test", + "Command": "bitmap_test", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Hash multiwriter autotest", + "Command": "hash_multiwriter_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Service autotest", + "Command": "service_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Timer racecond autotest", + "Command": "timer_racecond_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Member autotest", + "Command": "member_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Efd_autotest", + "Command": "efd_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Thash autotest", + "Command": "thash_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Hash function autotest", + "Command": "hash_functions_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev sw mrvl autotest", + "Command": "cryptodev_sw_mrvl_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev dpaa2 sec autotest", + "Command": "cryptodev_dpaa2_sec_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev dpaa sec autotest", + "Command": "cryptodev_dpaa_sec_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev qat autotest", + "Command": "cryptodev_qat_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev aesni mb autotest", + "Command": "cryptodev_aesni_mb_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev openssl autotest", + "Command": "cryptodev_openssl_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev scheduler autotest", + "Command": "cryptodev_scheduler_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev aesni gcm autotest", + "Command": "cryptodev_aesni_gcm_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev null autotest", + "Command": "cryptodev_null_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev sw snow3g autotest", + "Command": "cryptodev_sw_snow3g_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev sw kasumi autotest", + "Command": "cryptodev_sw_kasumi_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Cryptodev_sw_zuc_autotest", + "Command": "cryptodev_sw_zuc_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Reciprocal division", + "Command": "reciprocal_division", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Red all", + "Command": "red_all", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Fbarray autotest", + "Command": "fbarray_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "External memory autotest", + "Command": "external_mem_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Metrics autotest", + "Command": "metrics_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Bitratestats autotest", + "Command": "bitratestats_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Latencystats autotest", + "Command": "latencystats_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Pdump autotest", + "Command": "pdump_autotest", + "Func": default_autotest, + "Report": None, + }, + # + #Please always keep all dump tests at the end and together! + # + { + "Name": "Dump physmem", + "Command": "dump_physmem", + "Func": dump_autotest, + "Report": None, + }, + { + "Name": "Dump memzone", + "Command": "dump_memzone", + "Func": dump_autotest, + "Report": None, + }, + { + "Name": "Dump struct sizes", + "Command": "dump_struct_sizes", + "Func": dump_autotest, + "Report": None, + }, + { + "Name": "Dump mempool", + "Command": "dump_mempool", + "Func": dump_autotest, + "Report": None, + }, + { + "Name": "Dump malloc stats", + "Command": "dump_malloc_stats", + "Func": dump_autotest, + "Report": None, + }, + { + "Name": "Dump devargs", + "Command": "dump_devargs", + "Func": dump_autotest, + "Report": None, + }, + { + "Name": "Dump log types", + "Command": "dump_log_types", + "Func": dump_autotest, + "Report": None, + }, + { + "Name": "Dump_ring", + "Command": "dump_ring", + "Func": dump_autotest, + "Report": None, + }, +] + +# tests that should not be run when any other tests are running +non_parallel_test_list = [ + { + "Name": "Eventdev common autotest", + "Command": "eventdev_common_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Eventdev selftest sw", + "Command": "eventdev_selftest_sw", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "KNI autotest", + "Command": "kni_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Mempool performance autotest", + "Command": "mempool_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Memcpy performance autotest", + "Command": "memcpy_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Hash performance autotest", + "Command": "hash_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Hash read-write concurrency autotest", + "Command": "hash_readwrite_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Hash read-write lock-free concurrency autotest", + "Command": "hash_readwrite_lf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Power autotest", + "Command": "power_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Power ACPI cpufreq autotest", + "Command": "power_acpi_cpufreq_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Power KVM VM autotest", + "Command": "power_kvm_vm_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Timer performance autotest", + "Command": "timer_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + + "Name": "Pmd perf autotest", + "Command": "pmd_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Ring pmd perf autotest", + "Command": "ring_pmd_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Distributor perf autotest", + "Command": "distributor_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Red_perf", + "Command": "red_perf", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Lpm6 perf autotest", + "Command": "lpm6_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Lpm perf autotest", + "Command": "lpm_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Efd perf autotest", + "Command": "efd_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Member perf autotest", + "Command": "member_perf_autotest", + "Func": default_autotest, + "Report": None, + }, + { + "Name": "Reciprocal division perf", + "Command": "reciprocal_division_perf", + "Func": default_autotest, + "Report": None, + }, + # + # Please always make sure that ring_perf is the last test! + # + { + "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 new file mode 100644 index 0000000000..36941a40a1 --- /dev/null +++ b/app/test/autotest_runner.py @@ -0,0 +1,433 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2010-2014 Intel Corporation + +# The main logic behind running autotests in parallel + +from __future__ import print_function +import StringIO +import csv +from multiprocessing import Pool, Queue +import pexpect +import re +import subprocess +import sys +import time +import glob +import os + +# 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 + + +# get all valid NUMA nodes +def get_numa_nodes(): + return [ + int( + re.match(r"node(\d+)", os.path.basename(node)) + .group(1) + ) + for node in glob.glob("/sys/devices/system/node/node*") + ] + + +# find first (or any, really) CPU on a particular node, will be used to spread +# processes around NUMA nodes to avoid exhausting memory on particular node +def first_cpu_on_node(node_nr): + cpu_path = glob.glob("/sys/devices/system/node/node%d/cpu*" % node_nr)[0] + cpu_name = os.path.basename(cpu_path) + m = re.match(r"cpu(\d+)", cpu_name) + return int(m.group(1)) + + +pool_child = None # per-process child + + +# we initialize each worker with a queue because we need per-pool unique +# command-line arguments, but we cannot do different arguments in an initializer +# because the API doesn't allow per-worker initializer arguments. so, instead, +# we will initialize with a shared queue, and dequeue command-line arguments +# from this queue +def pool_init(queue, result_queue): + global pool_child + + cmdline, prefix = queue.get() + start_time = time.time() + name = ("Start %s" % prefix) if prefix != "" else "Start" + + # use default prefix if no prefix was specified + prefix_cmdline = "--file-prefix=%s" % prefix if prefix != "" else "" + + # append prefix to cmdline + cmdline = "%s %s" % (cmdline, prefix_cmdline) + + # prepare logging of init + startuplog = StringIO.StringIO() + + # run test app + try: + + print("\n%s %s\n" % ("=" * 20, prefix), file=startuplog) + print("\ncmdline=%s" % cmdline, file=startuplog) + + pool_child = pexpect.spawn(cmdline, logfile=startuplog) + + # wait for target to boot + if not wait_prompt(pool_child): + pool_child.close() + + result = tuple((-1, + "Fail [No prompt]", + name, + time.time() - start_time, + startuplog.getvalue(), + None)) + pool_child = None + else: + result = tuple((0, + "Success", + name, + time.time() - start_time, + startuplog.getvalue(), + None)) + except: + result = tuple((-1, + "Fail [Can't run]", + name, + time.time() - start_time, + startuplog.getvalue(), + None)) + pool_child = None + + result_queue.put(result) + + +# run a test +# 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(target, test): + global pool_child + + if pool_child is None: + return -1, "Fail [No test process]", test["Name"], 0, "", None + + # 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() + pool_child.logfile = logfile + + # make a note when the test started + start_time = time.time() + + try: + # print test name to log buffer + print("\n%s %s\n" % ("-" * 20, test["Name"]), file=logfile) + + # run test function associated with the test + result = test["Func"](pool_child, test["Command"]) + + # make a note when the test was finished + end_time = time.time() + + log = logfile.getvalue() + + # append test data to the result tuple + result += (test["Name"], end_time - start_time, log) + + # call report function, if any defined, and supply it with + # target and complete log for test run + if test["Report"]: + report = test["Report"](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) + + # return test results + return result + + +# 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, n_processes): + self.cmdline = cmdline + self.target = target + self.binary = cmdline.split()[0] + self.blacklist = blacklist + self.whitelist = whitelist + self.skipped = [] + self.parallel_tests = [] + self.non_parallel_tests = [] + self.n_processes = n_processes + self.active_processes = 0 + + # 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, cpu_nr): + cmdline = ("taskset -c %i " % cpu_nr) + self.cmdline + + return cmdline + + def __process_result(self, result): + + # 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 + print(result + "[%02dm %02ds]" % (total_time / 60, total_time % 60)) + + # if test failed and it wasn't a "start" test + if test_result < 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 + self.csvwriter.writerow([test_name, test_result, result_str]) + + # this function checks individual test and decides if this test should be in + # the group by comparing it against whitelist/blacklist. it also checks if + # the test is compiled into the binary, and marks it as skipped if necessary + def __filter_test(self, test): + test_cmd = test["Command"] + test_id = test_cmd + + # 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: + return False + if self.whitelist and test_id not in self.whitelist: + return False + + # if test wasn't compiled in, remove it as well + + # parse the binary for available test commands + stripped = 'not stripped' not in \ + subprocess.check_output(['file', self.binary]) + if not stripped: + symbols = subprocess.check_output(['nm', + self.binary]).decode('utf-8') + avail_cmds = re.findall('test_register_(\w+)', symbols) + + if test_cmd not in avail_cmds: + # notify user + result = 0, "Skipped [Not compiled]", test_id, 0, "", None + self.skipped.append(tuple(result)) + return False + + return True + + def __run_test_group(self, test_group, worker_cmdlines): + group_queue = Queue() + init_result_queue = Queue() + for proc, cmdline in enumerate(worker_cmdlines): + prefix = "test%i" % proc if len(worker_cmdlines) > 1 else "" + group_queue.put(tuple((cmdline, prefix))) + + # create a pool of worker threads + # we will initialize child in the initializer, and we don't need to + # close the child because when the pool worker gets destroyed, child + # closes the process + pool = Pool(processes=len(worker_cmdlines), + initializer=pool_init, + initargs=(group_queue, init_result_queue)) + + results = [] + + # process all initialization results + for _ in range(len(worker_cmdlines)): + self.__process_result(init_result_queue.get()) + + # run all tests asynchronously + for test in test_group: + result = pool.apply_async(run_test, (self.target, test)) + results.append(result) + + # tell the pool to stop all processes once done + pool.close() + + # 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 async_result in results[:]: + # if the thread hasn't finished yet, continue + if not async_result.ready(): + continue + + res = async_result.get() + + self.__process_result(res) + + # remove result from results list once we're done with it + results.remove(async_result) + + # iterate over test groups and run tests associated with them + def run_all_tests(self): + # filter groups + self.parallel_tests = list( + filter(self.__filter_test, + self.parallel_tests) + ) + self.non_parallel_tests = list( + filter(self.__filter_test, + self.non_parallel_tests) + ) + + parallel_cmdlines = [] + # FreeBSD doesn't have NUMA support + numa_nodes = get_numa_nodes() + if len(numa_nodes) > 0: + for proc in range(self.n_processes): + # spread cpu affinity between NUMA nodes to have less chance of + # running out of memory while running multiple test apps in + # parallel. to do that, alternate between NUMA nodes in a round + # robin fashion, and pick an arbitrary CPU from that node to + # taskset our execution to + numa_node = numa_nodes[self.active_processes % len(numa_nodes)] + cpu_nr = first_cpu_on_node(numa_node) + parallel_cmdlines += [self.__get_cmdline(cpu_nr)] + # increase number of active processes so that the next cmdline + # gets a different NUMA node + self.active_processes += 1 + else: + parallel_cmdlines = [self.cmdline] * self.n_processes + + print("Running tests with %d workers" % self.n_processes) + + # create table header + print("") + print("Test name".ljust(30) + "Test result".ljust(29) + + "Test".center(9) + "Total".center(9)) + print("=" * 80) + + if len(self.skipped): + print("Skipped autotests:") + + # print out any skipped tests + for result in self.skipped: + # unpack result tuple + test_result, result_str, test_name, _, _, _ = result + self.csvwriter.writerow([test_name, test_result, result_str]) + + t = ("%s:" % test_name).ljust(30) + t += result_str.ljust(29) + t += "[00m 00s]" + + print(t) + + # make a note of tests start time + self.start = time.time() + + # whatever happens, try to save as much logs as possible + try: + if len(self.parallel_tests) > 0: + print("Parallel autotests:") + self.__run_test_group(self.parallel_tests, parallel_cmdlines) + + if len(self.non_parallel_tests) > 0: + print("Non-parallel autotests:") + self.__run_test_group(self.non_parallel_tests, [self.cmdline]) + + # 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 new file mode 100644 index 0000000000..65fe335397 --- /dev/null +++ b/app/test/autotest_test_funcs.py @@ -0,0 +1,276 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2010-2014 Intel Corporation + +# 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): + lines = 0 + error = '' + child.sendline(test_name) + while True: + regexp = "IOVA:0x[0-9a-f]*, len:([0-9]*), virt:0x[0-9a-f]*, " \ + "socket_id:[0-9]*" + index = child.expect([regexp, "Test OK", "Test Failed", + pexpect.TIMEOUT], timeout=10) + if index == 3: + return -1, "Fail [Timeout]" + elif index == 1: + break + elif index == 2: + return -1, "Fail" + else: + lines = lines + 1 + size = int(child.match.groups()[0], 10) + if size <= 0: + error = 'Bad size' + + if lines <= 0: + return -1, "Fail [No entries]" + if error != '': + return -1, "Fail [{}]".format(error) + 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]" + + return 0, "Success" diff --git a/app/test/commands.c b/app/test/commands.c new file mode 100644 index 0000000000..94fbc310ed --- /dev/null +++ b/app/test/commands.c @@ -0,0 +1,388 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation. + * Copyright(c) 2014 6WIND S.A. + */ + +#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 + +#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(); + } + + last_test_result = ret; + if (ret == 0) + printf("Test OK\n"); + else if (ret == TEST_SKIPPED) + printf("Test Skipped\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_devargs_dump(stdout); + else if (!strcmp(res->dump, "dump_log_types")) + rte_log_dump(stdout); + else if (!strcmp(res->dump, "dump_malloc_stats")) + rte_malloc_dump_stats(stdout, NULL); + else if (!strcmp(res->dump, "dump_malloc_heaps")) + rte_malloc_dump_heaps(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_malloc_stats#" + "dump_malloc_heaps#" + "dump_devargs#" + "dump_log_types"); + +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_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_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/meson.build b/app/test/meson.build new file mode 100644 index 0000000000..05e5ddeb09 --- /dev/null +++ b/app/test/meson.build @@ -0,0 +1,378 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2017 Intel Corporation + +test_sources = files('commands.c', + 'packet_burst_generator.c', + 'sample_packet_forward.c', + 'test.c', + 'test_acl.c', + 'test_alarm.c', + 'test_atomic.c', + 'test_barrier.c', + 'test_bitratestats.c', + 'test_bpf.c', + 'test_byteorder.c', + 'test_cmdline.c', + 'test_cmdline_cirbuf.c', + 'test_cmdline_etheraddr.c', + 'test_cmdline_ipaddr.c', + 'test_cmdline_lib.c', + 'test_cmdline_num.c', + 'test_cmdline_portlist.c', + 'test_cmdline_string.c', + 'test_common.c', + 'test_cpuflags.c', + 'test_crc.c', + 'test_cryptodev.c', + 'test_cryptodev_asym.c', + 'test_cryptodev_blockcipher.c', + 'test_cycles.c', + 'test_debug.c', + 'test_distributor.c', + 'test_distributor_perf.c', + 'test_eal_flags.c', + 'test_eal_fs.c', + 'test_efd.c', + 'test_efd_perf.c', + 'test_errno.c', + 'test_event_crypto_adapter.c', + 'test_event_eth_rx_adapter.c', + 'test_event_ring.c', + 'test_event_eth_tx_adapter.c', + 'test_event_timer_adapter.c', + 'test_eventdev.c', + 'test_external_mem.c', + 'test_fbarray.c', + 'test_func_reentrancy.c', + 'test_flow_classify.c', + 'test_hash.c', + 'test_hash_functions.c', + 'test_hash_multiwriter.c', + 'test_hash_readwrite.c', + 'test_hash_perf.c', + 'test_hash_readwrite_lf.c', + 'test_interrupts.c', + 'test_ipsec.c', + 'test_kni.c', + 'test_kvargs.c', + 'test_latencystats.c', + 'test_link_bonding.c', + 'test_link_bonding_mode4.c', + 'test_logs.c', + 'test_lpm.c', + 'test_lpm6.c', + 'test_lpm6_perf.c', + 'test_lpm_perf.c', + 'test_malloc.c', + 'test_mbuf.c', + 'test_member.c', + 'test_member_perf.c', + 'test_memcpy.c', + 'test_memcpy_perf.c', + 'test_memory.c', + 'test_mempool.c', + 'test_mempool_perf.c', + 'test_memzone.c', + 'test_meter.c', + 'test_metrics.c', + 'test_mp_secondary.c', + 'test_pdump.c', + 'test_per_lcore.c', + 'test_pmd_perf.c', + 'test_pmd_ring.c', + 'test_pmd_ring_perf.c', + 'test_power.c', + 'test_power_acpi_cpufreq.c', + 'test_power_kvm_vm.c', + 'test_prefetch.c', + 'test_reciprocal_division.c', + 'test_reciprocal_division_perf.c', + 'test_red.c', + 'test_reorder.c', + 'test_ring.c', + 'test_ring_perf.c', + 'test_rwlock.c', + 'test_sched.c', + 'test_service_cores.c', + 'test_spinlock.c', + 'test_string_fns.c', + 'test_table.c', + 'test_table_acl.c', + 'test_table_combined.c', + 'test_table_pipeline.c', + 'test_table_ports.c', + 'test_table_tables.c', + 'test_tailq.c', + 'test_thash.c', + 'test_timer.c', + 'test_timer_perf.c', + 'test_timer_racecond.c', + 'test_version.c', + 'virtual_pmd.c' +) + +test_deps = ['acl', + 'bitratestats', + 'bpf', + 'cfgfile', + 'cmdline', + 'cryptodev', + 'distributor', + 'efd', + 'ethdev', + 'eventdev', + 'flow_classify', + 'hash', + 'ipsec', + 'latencystats', + 'lpm', + 'member', + 'metrics', + 'pipeline', + 'port', + 'reorder', + 'ring', + 'timer' +] + +# All test cases in fast_parallel_test_names list are parallel +fast_parallel_test_names = [ + 'acl_autotest', + 'alarm_autotest', + 'atomic_autotest', + 'byteorder_autotest', + 'cmdline_autotest', + 'common_autotest', + 'cpuflags_autotest', + 'cycles_autotest', + 'debug_autotest', + 'eal_flags_autotest', + 'eal_fs_autotest', + 'errno_autotest', + 'event_ring_autotest', + 'func_reentrancy_autotest', + 'flow_classify_autotest', + 'hash_autotest', + 'interrupt_autotest', + 'logs_autotest', + 'lpm_autotest', + 'lpm6_autotest', + 'malloc_autotest', + 'mbuf_autotest', + 'memcpy_autotest', + 'memory_autotest', + 'mempool_autotest', + 'memzone_autotest', + 'meter_autotest', + 'multiprocess_autotest', + 'per_lcore_autotest', + 'prefetch_autotest', + 'red_autotest', + 'ring_autotest', + 'ring_pmd_autotest', + 'rwlock_autotest', + 'sched_autotest', + 'spinlock_autotest', + 'string_autotest', + 'table_autotest', + 'tailq_autotest', + 'timer_autotest', + 'user_delay_us', + 'version_autotest', +] + +# All test cases in fast_non_parallel_test_names list are non-parallel +fast_non_parallel_test_names = [ + 'bitratestats_autotest', + 'cryptodev_sw_armv8_autotest', + 'crc_autotest', + 'cryptodev_openssl_asym_autotest', + 'cryptodev_sw_mvsam_autotest', + 'delay_us_sleep_autotest', + 'devargs_autotest', + 'distributor_autotest', + 'eventdev_common_autotest', + 'eventdev_octeontx_autotest', + 'eventdev_sw_autotest', + 'fbarray_autotest', + 'hash_readwrite_autotest', + 'hash_readwrite_lf_autotest', + 'hash_scaling_autotest', + 'ipsec_autotest', + 'kni_autotest', + 'kvargs_autotest', + 'latencystats_autotest', + 'member_autotest', + 'metrics_autotest', + 'pdump_autotest', + 'power_acpi_cpufreq_autotest', + 'power_autotest', + 'power_kvm_vm_autotest', + 'reorder_autotest', + 'service_autotest', + 'thash_autotest', +] + +# All test cases in perf_test_names list are non-parallel +perf_test_names = [ + 'ring_perf_autotest', + 'mempool_perf_autotest', + 'memcpy_perf_autotest', + 'hash_perf_autotest', + 'timer_perf_autotest', + 'reciprocal_division', + 'reciprocal_division_perf', + 'lpm_perf_autotest', + 'red_all', + 'barrier_autotest', + 'hash_multiwriter_autotest', + 'timer_racecond_autotest', + 'efd_autotest', + 'hash_functions_autotest', + 'eventdev_selftest_sw', + 'member_perf_autotest', + 'efd_perf_autotest', + 'lpm6_perf_autotest', + 'red_perf', + 'distributor_perf_autotest', + 'ring_pmd_perf_autotest', + 'pmd_perf_autotest', +] + +# All test cases in driver_test_names list are non-parallel +driver_test_names = [ + 'link_bonding_autotest', + 'link_bonding_mode4_autotest', + 'link_bonding_rssconf_autotest', + 'cryptodev_sw_mrvl_autotest', + 'cryptodev_dpaa2_sec_autotest', + 'cryptodev_dpaa_sec_autotest', + 'cryptodev_qat_autotest', + 'cryptodev_aesni_mb_autotest', + 'cryptodev_openssl_autotest', + 'cryptodev_scheduler_autotest', + 'cryptodev_aesni_gcm_autotest', + 'cryptodev_null_autotest', + 'cryptodev_sw_snow3g_autotest', + 'cryptodev_sw_kasumi_autotest', + 'cryptodev_sw_zuc_autotest', +] + +# All test cases in dump_test_names list are non-parallel +dump_test_names = [ + 'dump_struct_sizes', + 'dump_mempool', + 'dump_malloc_stats', + 'dump_devargs', + 'dump_log_types', + 'dump_ring', + 'dump_physmem', + 'dump_memzone', +] + +if dpdk_conf.has('RTE_LIBRTE_PDUMP') + test_deps += 'pdump' +endif +if dpdk_conf.has('RTE_LIBRTE_I40E_PMD') + test_deps += 'pmd_i40e' +endif +if dpdk_conf.has('RTE_LIBRTE_IXGBE_PMD') + test_deps += 'pmd_ixgbe' +endif +if dpdk_conf.has('RTE_LIBRTE_BOND_PMD') + test_deps += 'pmd_bond' +endif +if dpdk_conf.has('RTE_LIBRTE_RING_PMD') + test_deps += 'pmd_ring' +endif +if dpdk_conf.has('RTE_LIBRTE_POWER') + test_deps += 'power' +endif +if dpdk_conf.has('RTE_LIBRTE_KNI') + test_deps += 'kni' +endif + +cflags = machine_args +if cc.has_argument('-Wno-format-truncation') + cflags += '-Wno-format-truncation' +endif + +# specify -D_GNU_SOURCE unconditionally +default_cflags += '-D_GNU_SOURCE' + +test_dep_objs = [] +if dpdk_conf.has('RTE_LIBRTE_COMPRESSDEV') + compress_test_dep = dependency('zlib', required: false) + if compress_test_dep.found() + test_dep_objs += compress_test_dep + test_sources += 'test_compressdev.c' + test_deps += 'compressdev' + fast_non_parallel_test_names += 'compressdev_autotest' + endif +endif + +foreach d:test_deps + def_lib = get_option('default_library') + test_dep_objs += get_variable(def_lib + '_rte_' + d) +endforeach +test_dep_objs += cc.find_library('execinfo', required: false) + +link_libs = [] +if get_option('default_library') == 'static' + link_libs = dpdk_drivers +endif + +if get_option('tests') + dpdk_test = executable('dpdk-test', + test_sources, + link_whole: link_libs, + dependencies: test_dep_objs, + c_args: [cflags, '-DALLOW_EXPERIMENTAL_API'], + install_rpath: driver_install_path, + install: false) + + # some perf tests (eg: memcpy perf autotest)take very long + # to complete, so timeout to 10 minutes + timeout_seconds = 600 + timeout_seconds_fast = 10 + + foreach arg : fast_parallel_test_names + test(arg, dpdk_test, + env : ['DPDK_TEST=' + arg], + args : ['-c f','-n 4', '--file-prefix=@0@'.format(arg)], + timeout : timeout_seconds_fast, + suite : 'fast-tests') + endforeach + + foreach arg : fast_non_parallel_test_names + test(arg, dpdk_test, + env : ['DPDK_TEST=' + arg], + timeout : timeout_seconds_fast, + is_parallel : false, + suite : 'fast-tests') + endforeach + + foreach arg : perf_test_names + test(arg, dpdk_test, + env : ['DPDK_TEST=' + arg], + timeout : timeout_seconds, + is_parallel : false, + suite : 'perf-tests') + endforeach + + foreach arg : driver_test_names + test(arg, dpdk_test, + env : ['DPDK_TEST=' + arg], + timeout : timeout_seconds, + is_parallel : false, + suite : 'driver-tests') + endforeach + + foreach arg : dump_test_names + test(arg, dpdk_test, + env : ['DPDK_TEST=' + arg], + timeout : timeout_seconds, + is_parallel : false, + suite : 'debug-tests') + endforeach +endif diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c new file mode 100644 index 0000000000..e894dc76f6 --- /dev/null +++ b/app/test/packet_burst_generator.c @@ -0,0 +1,447 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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_tcp_header(struct tcp_hdr *tcp_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 tcp_hdr)); + + memset(tcp_hdr, 0, sizeof(struct tcp_hdr)); + tcp_hdr->src_port = rte_cpu_to_be_16(src_port); + tcp_hdr->dst_port = rte_cpu_to_be_16(dst_port); + + return pkt_len; +} + +uint16_t +initialize_sctp_header(struct sctp_hdr *sctp_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)); + + sctp_hdr->src_port = rte_cpu_to_be_16(src_port); + sctp_hdr->dst_port = rte_cpu_to_be_16(dst_port); + sctp_hdr->tag = 0; + sctp_hdr->cksum = 0; /* No SCTP 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; +} + +uint16_t +initialize_ipv4_header_proto(struct ipv4_hdr *ip_hdr, uint32_t src_addr, + uint32_t dst_addr, uint16_t pkt_data_len, uint8_t proto) +{ + 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 = proto; + 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; +} + +int +generate_packet_burst_proto(struct rte_mempool *mp, + struct rte_mbuf **pkts_burst, + struct ether_hdr *eth_hdr, uint8_t vlan_enabled, void *ip_hdr, + uint8_t ipv4, uint8_t proto, void *proto_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); + switch (proto) { + case IPPROTO_UDP: + copy_buf_to_pkt(proto_hdr, + sizeof(struct udp_hdr), pkt, + eth_hdr_size + sizeof(struct ipv4_hdr)); + break; + case IPPROTO_TCP: + copy_buf_to_pkt(proto_hdr, + sizeof(struct tcp_hdr), pkt, + eth_hdr_size + sizeof(struct ipv4_hdr)); + break; + case IPPROTO_SCTP: + copy_buf_to_pkt(proto_hdr, + sizeof(struct sctp_hdr), pkt, + eth_hdr_size + sizeof(struct ipv4_hdr)); + break; + default: + break; + } + } else { + copy_buf_to_pkt(ip_hdr, sizeof(struct ipv6_hdr), pkt, + eth_hdr_size); + switch (proto) { + case IPPROTO_UDP: + copy_buf_to_pkt(proto_hdr, + sizeof(struct udp_hdr), pkt, + eth_hdr_size + sizeof(struct ipv6_hdr)); + break; + case IPPROTO_TCP: + copy_buf_to_pkt(proto_hdr, + sizeof(struct tcp_hdr), pkt, + eth_hdr_size + sizeof(struct ipv6_hdr)); + break; + case IPPROTO_SCTP: + copy_buf_to_pkt(proto_hdr, + sizeof(struct sctp_hdr), pkt, + eth_hdr_size + sizeof(struct ipv6_hdr)); + break; + default: + break; + } + } + + /* + * 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 new file mode 100644 index 0000000000..c20cea6e93 --- /dev/null +++ b/app/test/packet_burst_generator.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#ifndef PACKET_BURST_GENERATOR_H_ +#define PACKET_BURST_GENERATOR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#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_tcp_header(struct tcp_hdr *tcp_hdr, uint16_t src_port, + uint16_t dst_port, uint16_t pkt_data_len); + +uint16_t +initialize_sctp_header(struct sctp_hdr *sctp_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); + +uint16_t +initialize_ipv4_header_proto(struct ipv4_hdr *ip_hdr, uint32_t src_addr, + uint32_t dst_addr, uint16_t pkt_data_len, uint8_t proto); + +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 +generate_packet_burst_proto(struct rte_mempool *mp, + struct rte_mbuf **pkts_burst, + struct ether_hdr *eth_hdr, uint8_t vlan_enabled, void *ip_hdr, + uint8_t ipv4, uint8_t proto, void *proto_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 new file mode 100644 index 0000000000..7f62f644f0 --- /dev/null +++ b/app/test/process.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#ifndef _PROCESS_H_ +#define _PROCESS_H_ + +#include /* PATH_MAX */ +#include /* basename et al */ +#include /* NULL */ +#include /* readlink */ +#include + +#ifdef RTE_EXEC_ENV_BSDAPP +#define self "curproc" +#define exe "file" +#else +#define self "self" +#define exe "exe" +#endif + +#include +extern void *send_pkts(void *empty); +extern uint16_t flag_for_send_pkts; + +/* + * 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; + char *argv_cpy[numargs + 1]; + int i, fd, status; + char path[32]; + pthread_t thread; + + 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]); + argv_cpy[i] = NULL; + num = numargs; + + /* 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 */ + if ((strcmp(env_value, "run_pdump_server_tests") == 0)) + pthread_create(&thread, NULL, &send_pkts, NULL); + + while (wait(&status) != pid) + ; + if ((strcmp(env_value, "run_pdump_server_tests") == 0)) { + flag_for_send_pkts = 0; + pthread_join(thread, NULL); + } + return status; +} + +/* FreeBSD doesn't support file prefixes, so force compile failures for any + * tests attempting to use this function on FreeBSD. + */ +#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 prefix */ + snprintf(prefix, size, "%s", basename(dirname(buf))); + + return prefix; +} +#endif + +#endif /* _PROCESS_H_ */ diff --git a/app/test/resource.c b/app/test/resource.c new file mode 100644 index 0000000000..34465f1668 --- /dev/null +++ b/app/test/resource.c @@ -0,0 +1,276 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 RehiveTech. All rights reserved. + */ + +#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 new file mode 100644 index 0000000000..223fa22aec --- /dev/null +++ b/app/test/resource.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 RehiveTech. All rights reserved. + */ + +#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/sample_packet_forward.c b/app/test/sample_packet_forward.c new file mode 100644 index 0000000000..61384b3d9b --- /dev/null +++ b/app/test/sample_packet_forward.c @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include + +#include +#include +#include +#include +#include "rte_lcore.h" +#include "rte_mempool.h" +#include "rte_ring.h" + +#include "sample_packet_forward.h" + +/* Sample test to create virtual rings and tx,rx portid from rings */ +int +test_ring_setup(struct rte_ring **ring, uint16_t *portid) +{ + *ring = rte_ring_create("R0", RING_SIZE, rte_socket_id(), + RING_F_SP_ENQ | RING_F_SC_DEQ); + if (*ring == NULL) { + printf("%s() line %u: rte_ring_create R0 failed", + __func__, __LINE__); + return -1; + } + *portid = rte_eth_from_rings("net_ringa", ring, NUM_QUEUES, + ring, NUM_QUEUES, rte_socket_id()); + + return 0; +} + +/* Sample test to free the mempool */ +void +test_mp_free(struct rte_mempool *mp) +{ + rte_mempool_free(mp); +} + +/* Sample test to free the virtual rings */ +void +test_ring_free(struct rte_ring *rxtx) +{ + rte_ring_free(rxtx); +} + +/* Sample test to release the vdev */ +void +test_vdev_uninit(const char *vdev) +{ + rte_vdev_uninit(vdev); +} + +/* sample test to allocate the mempool */ +int +test_get_mempool(struct rte_mempool **mp, char *poolname) +{ + *mp = rte_pktmbuf_pool_create(poolname, NB_MBUF, 32, 0, + RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + if (*mp == NULL) + return -1; + return 0; +} + +/* sample test to allocate buffer for pkts */ +int +test_get_mbuf_from_pool(struct rte_mempool **mp, struct rte_mbuf **pbuf, + char *poolname) +{ + int ret = 0; + + ret = test_get_mempool(mp, poolname); + if (ret < 0) + return -1; + if (rte_pktmbuf_alloc_bulk(*mp, pbuf, NUM_PACKETS) != 0) { + printf("%s() line %u: rte_pktmbuf_alloc_bulk failed", __func__, + __LINE__); + return -1; + } + return 0; +} + +/* sample test to deallocate the allocated buffers and mempool */ +void +test_put_mbuf_to_pool(struct rte_mempool *mp, struct rte_mbuf **pbuf) +{ + int itr = 0; + + for (itr = 0; itr < NUM_PACKETS; itr++) + rte_pktmbuf_free(pbuf[itr]); + rte_mempool_free(mp); +} + +/* Sample test to forward packets using virtual portids */ +int +test_packet_forward(struct rte_mbuf **pbuf, uint16_t portid, uint16_t queue_id) +{ + /* send and receive packet and check for stats update */ + if (rte_eth_tx_burst(portid, queue_id, pbuf, NUM_PACKETS) + < NUM_PACKETS) { + printf("%s() line %u: Error sending packet to" + " port %d\n", __func__, __LINE__, portid); + return -1; + } + if (rte_eth_rx_burst(portid, queue_id, pbuf, NUM_PACKETS) + < NUM_PACKETS) { + printf("%s() line %u: Error receiving packet from" + " port %d\n", __func__, __LINE__, portid); + return -1; + } + return 0; +} diff --git a/app/test/sample_packet_forward.h b/app/test/sample_packet_forward.h new file mode 100644 index 0000000000..6789217de3 --- /dev/null +++ b/app/test/sample_packet_forward.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#ifndef _SAMPLE_PACKET_FORWARD_H_ +#define _SAMPLE_PACKET_FORWARD_H_ + +#include + +/* MACROS to support virtual ring creation */ +#define RING_SIZE 256 +#define NUM_QUEUES 1 +#define NB_MBUF 512 + +#define NUM_PACKETS 10 + +struct rte_mbuf; +struct rte_mempool; +struct rte_ring; + +/* Sample test to create virtual rings and tx,rx portid from rings */ +int test_ring_setup(struct rte_ring **ring, uint16_t *portid); + +/* Sample test to free the virtual rings */ +void test_ring_free(struct rte_ring *rxtx); + +/* Sample test to forward packet using virtual port id */ +int test_packet_forward(struct rte_mbuf **pbuf, uint16_t portid, + uint16_t queue_id); + +/* sample test to allocate buffer for pkts */ +int test_get_mbuf_from_pool(struct rte_mempool **mp, struct rte_mbuf **pbuf, + char *poolname); + +/* Sample test to create the mempool */ +int test_get_mempool(struct rte_mempool **mp, char *poolname); + +/* sample test to deallocate the allocated buffers and mempool */ +void test_put_mbuf_to_pool(struct rte_mempool *mp, struct rte_mbuf **pbuf); + +/* Sample test to free the mempool */ +void test_mp_free(struct rte_mempool *mp); + +/* Sample test to release the vdev */ +void test_vdev_uninit(const char *vdev); + +#endif /* _SAMPLE_PACKET_FORWARD_H_ */ diff --git a/app/test/test.c b/app/test/test.c new file mode 100644 index 0000000000..351c7f2759 --- /dev/null +++ b/app/test/test.c @@ -0,0 +1,288 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 +#ifdef RTE_LIBRTE_TIMER +#include +#endif + +#include "test.h" +#include "test_pdump.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 }, + { "run_pdump_server_tests", test_pdump }, + { "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 }, + { "test_misc_flags", no_action }, + { "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 last_test_result; + +#define MAX_EXTRA_ARGS 32 + +int +main(int argc, char **argv) +{ +#ifdef RTE_LIBRTE_CMDLINE + struct cmdline *cl; +#endif + char *extra_args; + int ret; + + extra_args = getenv("DPDK_TEST_PARAMS"); + if (extra_args != NULL && strlen(extra_args) > 0) { + char **all_argv; + char *eargv[MAX_EXTRA_ARGS]; + int all_argc; + int eargc; + int i; + + RTE_LOG(INFO, APP, "Using additional DPDK_TEST_PARAMS: '%s'\n", + extra_args); + eargc = rte_strsplit(extra_args, strlen(extra_args), + eargv, MAX_EXTRA_ARGS, ' '); + + /* merge argc/argv and the environment args */ + all_argc = argc + eargc; + all_argv = malloc(sizeof(*all_argv) * (all_argc + 1)); + if (all_argv == NULL) { + ret = -1; + goto out; + } + + for (i = 0; i < argc; i++) + all_argv[i] = argv[i]; + for (i = 0; i < eargc; i++) + all_argv[argc + i] = eargv[i]; + all_argv[all_argc] = NULL; + + /* call eal_init with combined args */ + ret = rte_eal_init(all_argc, all_argv); + free(all_argv); + } else + ret = rte_eal_init(argc, argv); + if (ret < 0) { + ret = -1; + goto out; + } + +#ifdef RTE_LIBRTE_TIMER + rte_timer_subsystem_init(); +#endif + + if (commands_init() < 0) { + ret = -1; + goto out; + } + + argv += ret; + + prgname = argv[0]; + + recursive_call = getenv(RECURSIVE_ENV_VAR); + if (recursive_call != NULL) { + ret = do_recursive_call(); + goto out; + } + +#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) { + ret = -1; + goto out; + } + + char *dpdk_test = getenv("DPDK_TEST"); + if (dpdk_test && strlen(dpdk_test)) { + char buf[1024]; + snprintf(buf, sizeof(buf), "%s\n", dpdk_test); + if (cmdline_in(cl, buf, strlen(buf)) < 0) { + printf("error on cmdline input\n"); + ret = -1; + goto out; + } + + cmdline_stdin_exit(cl); + ret = last_test_result; + goto out; + } + /* if no DPDK_TEST env variable, go interactive */ + cmdline_interact(cl); + cmdline_stdin_exit(cl); +#endif + ret = 0; + +out: + rte_eal_cleanup(); + return ret; +} + + +int +unit_test_suite_runner(struct unit_test_suite *suite) +{ + int test_success; + unsigned int total = 0, executed = 0, skipped = 0; + unsigned int succeeded = 0, failed = 0, unsupported = 0; + const char *status; + + if (suite->suite_name) { + printf(" + ------------------------------------------------------- +\n"); + printf(" + Test Suite : %s\n", suite->suite_name); + } + + if (suite->setup) + if (suite->setup() != 0) { + /* + * setup failed, so count all enabled tests and mark + * them as failed + */ + while (suite->unit_test_cases[total].testcase) { + if (!suite->unit_test_cases[total].enabled) + skipped++; + else + failed++; + total++; + } + 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 if (test_success == -ENOTSUP) + unsupported++; + else + failed++; + } else if (test_success == -ENOTSUP) { + unsupported++; + } 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) + status = "succeeded"; + else if (test_success == -ENOTSUP) + status = "unsupported"; + else + status = "failed"; + + printf(" + TestCase [%2d] : %s %s\n", total, + suite->unit_test_cases[total].name, status); + + 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 Unsupported: %2d\n", unsupported); + printf(" + Tests Passed : %2d\n", succeeded); + printf(" + Tests Failed : %2d\n", failed); + printf(" + ------------------------------------------------------- +\n"); + + last_test_result = failed; + + if (failed) + return -1; + + return 0; +} diff --git a/app/test/test.h b/app/test/test.h new file mode 100644 index 0000000000..7c24432303 --- /dev/null +++ b/app/test/test.h @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#ifndef _TEST_H_ +#define _TEST_H_ + +#include +#include + +#include +#include + +#define TEST_SUCCESS EXIT_SUCCESS +#define TEST_FAILED -1 +#define TEST_SKIPPED 77 + +/* 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 RTE_TEST_TRACE_FAILURE TEST_TRACE_FAILURE + +#include + +#define TEST_ASSERT RTE_TEST_ASSERT + +#define TEST_ASSERT_EQUAL RTE_TEST_ASSERT_EQUAL + +/* 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 RTE_TEST_ASSERT_NOT_EQUAL + +#define TEST_ASSERT_SUCCESS RTE_TEST_ASSERT_SUCCESS + +#define TEST_ASSERT_FAIL RTE_TEST_ASSERT_FAIL + +#define TEST_ASSERT_NULL RTE_TEST_ASSERT_NULL + +#define TEST_ASSERT_NOT_NULL RTE_TEST_ASSERT_NOT_NULL + +struct unit_test_case { + int (*setup)(void); + void (*teardown)(void); + int (*testcase)(void); + const char *name; + unsigned enabled; +}; + +#define TEST_CASE(fn) { NULL, NULL, fn, #fn, 1 } + +#define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, name, 1 } + +#define TEST_CASE_ST(setup, teardown, testcase) \ + { setup, teardown, testcase, #testcase, 1 } + + +#define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, #fn, 0 } + +#define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \ + { setup, teardown, testcase, #testcase, 0 } + +#define TEST_CASES_END() { NULL, NULL, NULL, NULL, 0 } + +static inline void +debug_hexdump(FILE *file, const char *title, const void *buf, size_t len) +{ + if (rte_log_get_global_level() == RTE_LOG_DEBUG) + rte_hexdump(file, title, buf, len); +} + +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); +extern int last_test_result; + +#define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE" + +#include +#include + +extern const char *prgname; + +int commands_init(void); + +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 new file mode 100644 index 0000000000..b1f75d1bc7 --- /dev/null +++ b/app/test/test_acl.c @@ -0,0 +1,1623 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..bbb0447a89 --- /dev/null +++ b/app/test/test_acl.h @@ -0,0 +1,669 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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, + .priority = 1}, + .src_addr = IPv4(10,0,0,0), + .src_mask_len = 24, + }, + { + .data = {.userdata = 2, .category_mask = 1, + .priority = 1}, + .dst_addr = IPv4(10,0,0,0), + .dst_mask_len = 24, + }, + /* test src and dst ports */ + { + .data = {.userdata = 3, .category_mask = 1, + .priority = 1}, + .dst_port_low = 100, + .dst_port_high = 100, + }, + { + .data = {.userdata = 4, .category_mask = 1, + .priority = 1}, + .src_port_low = 100, + .src_port_high = 100, + }, + /* test proto */ + { + .data = {.userdata = 5, .category_mask = 1, + .priority = 1}, + .proto = 0xf, + .proto_mask = 0xf + }, + { + .data = {.userdata = 6, .category_mask = 1, + .priority = 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 new file mode 100644 index 0000000000..d1284b379f --- /dev/null +++ b/app/test/test_alarm.c @@ -0,0 +1,234 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 */ +#define RTE_TEST_MAX_REPEAT 20 + +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; + int 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; + } + + while (flag != 2 && count++ < RTE_TEST_MAX_REPEAT) + 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; +#ifdef RTE_EXEC_ENV_BSDAPP + printf("The alarm API is not supported on FreeBSD\n"); + return 0; +#endif + /* 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++ < RTE_TEST_MAX_REPEAT) + 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 new file mode 100644 index 0000000000..43be30ec0b --- /dev/null +++ b/app/test/test_atomic.c @@ -0,0 +1,346 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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_barrier.c b/app/test/test_barrier.c new file mode 100644 index 0000000000..82b572c3eb --- /dev/null +++ b/app/test/test_barrier.c @@ -0,0 +1,286 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + + /* + * This is a simple functional test for rte_smp_mb() implementation. + * I.E. make sure that LOAD and STORE operations that precede the + * rte_smp_mb() call are globally visible across the lcores + * before the the LOAD and STORE operations that follows it. + * The test uses simple implementation of Peterson's lock algorithm + * (https://en.wikipedia.org/wiki/Peterson%27s_algorithm) + * for two execution units to make sure that rte_smp_mb() prevents + * store-load reordering to happen. + * Also when executed on a single lcore could be used as a approxiamate + * estimation of number of cycles particular implementation of rte_smp_mb() + * will take. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define ADD_MAX 8 +#define ITER_MAX 0x1000000 + +enum plock_use_type { + USE_MB, + USE_SMP_MB, + USE_NUM +}; + +struct plock { + volatile uint32_t flag[2]; + volatile uint32_t victim; + enum plock_use_type utype; +}; + +/* + * Lock plus protected by it two counters. + */ +struct plock_test { + struct plock lock; + uint32_t val; + uint32_t iter; +}; + +/* + * Each active lcore shares plock_test struct with it's left and right + * neighbours. + */ +struct lcore_plock_test { + struct plock_test *pt[2]; /* shared, lock-protected data */ + uint32_t sum[2]; /* local copy of the shared data */ + uint32_t iter; /* number of iterations to perfom */ + uint32_t lc; /* given lcore id */ +}; + +static inline void +store_load_barrier(uint32_t utype) +{ + if (utype == USE_MB) + rte_mb(); + else if (utype == USE_SMP_MB) + rte_smp_mb(); + else + RTE_VERIFY(0); +} + +/* + * Peterson lock implementation. + */ +static void +plock_lock(struct plock *l, uint32_t self) +{ + uint32_t other; + + other = self ^ 1; + + l->flag[self] = 1; + l->victim = self; + + store_load_barrier(l->utype); + + while (l->flag[other] == 1 && l->victim == self) + rte_pause(); +} + +static void +plock_unlock(struct plock *l, uint32_t self) +{ + rte_smp_wmb(); + l->flag[self] = 0; +} + +static void +plock_reset(struct plock *l, enum plock_use_type utype) +{ + memset(l, 0, sizeof(*l)); + l->utype = utype; +} + +/* + * grab the lock, update both counters, release the lock. + */ +static void +plock_add(struct plock_test *pt, uint32_t self, uint32_t n) +{ + plock_lock(&pt->lock, self); + pt->iter++; + pt->val += n; + plock_unlock(&pt->lock, self); +} + +static int +plock_test1_lcore(void *data) +{ + uint64_t tm; + uint32_t i, lc, ln, n; + struct lcore_plock_test *lpt; + + lpt = data; + lc = rte_lcore_id(); + + /* find lcore_plock_test struct for given lcore */ + for (ln = rte_lcore_count(); ln != 0 && lpt->lc != lc; lpt++, ln--) + ; + + if (ln == 0) { + printf("%s(%u) error at init\n", __func__, lc); + return -1; + } + + n = rte_rand() % ADD_MAX; + tm = rte_get_timer_cycles(); + + /* + * for each iteration: + * - update shared, locked protected data in a safe manner + * - update local copy of the shared data + */ + for (i = 0; i != lpt->iter; i++) { + + plock_add(lpt->pt[0], 0, n); + plock_add(lpt->pt[1], 1, n); + + lpt->sum[0] += n; + lpt->sum[1] += n; + + n = (n + 1) % ADD_MAX; + } + + tm = rte_get_timer_cycles() - tm; + + printf("%s(%u): %u iterations finished, in %" PRIu64 + " cycles, %#Lf cycles/iteration, " + "local sum={%u, %u}\n", + __func__, lc, i, tm, (long double)tm / i, + lpt->sum[0], lpt->sum[1]); + return 0; +} + +/* + * For N active lcores we allocate N+1 lcore_plock_test structures. + * Each active lcore shares one lcore_plock_test structure with its + * left lcore neighbor and one lcore_plock_test structure with its + * right lcore neighbor. + * During the test each lcore updates data in both shared structures and + * its local copies. Then at validation phase we check that our shared + * and local data are the same. + */ +static int +plock_test(uint32_t iter, enum plock_use_type utype) +{ + int32_t rc; + uint32_t i, lc, n; + uint32_t *sum; + struct plock_test *pt; + struct lcore_plock_test *lpt; + + /* init phase, allocate and initialize shared data */ + + n = rte_lcore_count(); + pt = calloc(n + 1, sizeof(*pt)); + lpt = calloc(n, sizeof(*lpt)); + sum = calloc(n + 1, sizeof(*sum)); + + printf("%s(iter=%u, utype=%u) started on %u lcores\n", + __func__, iter, utype, n); + + if (pt == NULL || lpt == NULL) { + printf("%s: failed to allocate memory for %u lcores\n", + __func__, n); + free(pt); + free(lpt); + free(sum); + return -ENOMEM; + } + + for (i = 0; i != n + 1; i++) + plock_reset(&pt[i].lock, utype); + + i = 0; + RTE_LCORE_FOREACH(lc) { + + lpt[i].lc = lc; + lpt[i].iter = iter; + lpt[i].pt[0] = pt + i; + lpt[i].pt[1] = pt + i + 1; + i++; + } + + lpt[i - 1].pt[1] = pt; + + for (i = 0; i != n; i++) + printf("lpt[%u]={lc=%u, pt={%p, %p},};\n", + i, lpt[i].lc, lpt[i].pt[0], lpt[i].pt[1]); + + + /* test phase - start and wait for completion on each active lcore */ + + rte_eal_mp_remote_launch(plock_test1_lcore, lpt, CALL_MASTER); + rte_eal_mp_wait_lcore(); + + /* validation phase - make sure that shared and local data match */ + + for (i = 0; i != n; i++) { + sum[i] += lpt[i].sum[0]; + sum[i + 1] += lpt[i].sum[1]; + } + + sum[0] += sum[i]; + + rc = 0; + for (i = 0; i != n; i++) { + printf("%s: sum[%u]=%u, pt[%u].val=%u, pt[%u].iter=%u;\n", + __func__, i, sum[i], i, pt[i].val, i, pt[i].iter); + + /* race condition occurred, lock doesn't work properly */ + if (sum[i] != pt[i].val || 2 * iter != pt[i].iter) { + printf("error: local and shared sums don't much\n"); + rc = -1; + } + } + + free(pt); + free(lpt); + free(sum); + + printf("%s(utype=%u) returns %d\n", __func__, utype, rc); + return rc; +} + +static int +test_barrier(void) +{ + int32_t i, ret, rc[USE_NUM]; + + for (i = 0; i != RTE_DIM(rc); i++) + rc[i] = plock_test(ITER_MAX, i); + + ret = 0; + for (i = 0; i != RTE_DIM(rc); i++) { + printf("%s for utype=%d %s\n", + __func__, i, rc[i] == 0 ? "passed" : "failed"); + ret |= rc[i]; + } + + return ret; +} + +REGISTER_TEST_COMMAND(barrier_autotest, test_barrier); diff --git a/app/test/test_bitmap.c b/app/test/test_bitmap.c new file mode 100644 index 0000000000..95c5184882 --- /dev/null +++ b/app/test/test_bitmap.c @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Cavium, Inc + */ + +#include +#include + +#include +#include +#include + +#include "test.h" + +#define MAX_BITS 1000 + +static int +test_bitmap_scan_operations(struct rte_bitmap *bmp) +{ + uint32_t pos = 0; + uint64_t slab1_magic = 0xBADC0FFEEBADF00D; + uint64_t slab2_magic = 0xFEEDDEADDEADF00D; + uint64_t out_slab = 0; + + rte_bitmap_reset(bmp); + + rte_bitmap_set_slab(bmp, pos, slab1_magic); + rte_bitmap_set_slab(bmp, pos + RTE_BITMAP_SLAB_BIT_SIZE, slab2_magic); + + if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { + printf("Failed to get slab from bitmap.\n"); + return TEST_FAILED; + } + + if (slab1_magic != out_slab) { + printf("Scan operation sanity failed.\n"); + return TEST_FAILED; + } + + if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { + printf("Failed to get slab from bitmap.\n"); + return TEST_FAILED; + } + + if (slab2_magic != out_slab) { + printf("Scan operation sanity failed.\n"); + return TEST_FAILED; + } + + /* Wrap around */ + if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { + printf("Failed to get slab from bitmap.\n"); + return TEST_FAILED; + } + + if (slab1_magic != out_slab) { + printf("Scan operation wrap around failed.\n"); + return TEST_FAILED; + } + + /* Scan reset check. */ + __rte_bitmap_scan_init(bmp); + + if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { + printf("Failed to get slab from bitmap.\n"); + return TEST_FAILED; + } + + if (slab1_magic != out_slab) { + printf("Scan reset operation failed.\n"); + return TEST_FAILED; + } + + return TEST_SUCCESS; +} + +static int +test_bitmap_slab_set_get(struct rte_bitmap *bmp) +{ + uint32_t pos = 0; + uint64_t slab_magic = 0xBADC0FFEEBADF00D; + uint64_t out_slab = 0; + + rte_bitmap_reset(bmp); + rte_bitmap_set_slab(bmp, pos, slab_magic); + + if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { + printf("Failed to get slab from bitmap.\n"); + return TEST_FAILED; + } + + + if (slab_magic != out_slab) { + printf("Invalid slab in bitmap.\n"); + return TEST_FAILED; + } + + + return TEST_SUCCESS; +} + +static int +test_bitmap_set_get_clear(struct rte_bitmap *bmp) +{ + uint64_t val; + int i; + + rte_bitmap_reset(bmp); + for (i = 0; i < MAX_BITS; i++) + rte_bitmap_set(bmp, i); + + for (i = 0; i < MAX_BITS; i++) { + if (!rte_bitmap_get(bmp, i)) { + printf("Failed to get set bit.\n"); + return TEST_FAILED; + } + } + + for (i = 0; i < MAX_BITS; i++) + rte_bitmap_clear(bmp, i); + + for (i = 0; i < MAX_BITS; i++) { + if (rte_bitmap_get(bmp, i)) { + printf("Failed to clear set bit.\n"); + return TEST_FAILED; + } + } + + rte_bitmap_reset(bmp); + + /* Alternate slab set test */ + for (i = 0; i < MAX_BITS; i++) { + if (i % RTE_BITMAP_SLAB_BIT_SIZE) + rte_bitmap_set(bmp, i); + } + + for (i = 0; i < MAX_BITS; i++) { + val = rte_bitmap_get(bmp, i); + if (((i % RTE_BITMAP_SLAB_BIT_SIZE) && !val) || + (!(i % RTE_BITMAP_SLAB_BIT_SIZE) && val)) { + printf("Failed to get set bit.\n"); + return TEST_FAILED; + } + } + + return TEST_SUCCESS; +} + +static int +test_bitmap(void) +{ + void *mem; + uint32_t bmp_size; + struct rte_bitmap *bmp; + + bmp_size = + rte_bitmap_get_memory_footprint(MAX_BITS); + + mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE); + if (mem == NULL) { + printf("Failed to allocate memory for bitmap\n"); + return TEST_FAILED; + } + + bmp = rte_bitmap_init(MAX_BITS, mem, bmp_size); + if (bmp == NULL) { + printf("Failed to init bitmap\n"); + return TEST_FAILED; + } + + if (test_bitmap_set_get_clear(bmp) < 0) + return TEST_FAILED; + + if (test_bitmap_slab_set_get(bmp) < 0) + return TEST_FAILED; + + if (test_bitmap_scan_operations(bmp) < 0) + return TEST_FAILED; + + rte_bitmap_free(bmp); + rte_free(mem); + + return TEST_SUCCESS; +} + +REGISTER_TEST_COMMAND(bitmap_test, test_bitmap); diff --git a/app/test/test_bitratestats.c b/app/test/test_bitratestats.c new file mode 100644 index 0000000000..32b1b0fc0e --- /dev/null +++ b/app/test/test_bitratestats.c @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sample_packet_forward.h" +#include "test.h" + +#define BIT_NUM_PACKETS 10 +#define QUEUE_ID 0 + +uint16_t portid; +struct rte_stats_bitrates *bitrate_data; +struct rte_ring *ring; + +/* To test whether rte_stats_bitrate_create is successful */ +static int +test_stats_bitrate_create(void) +{ + bitrate_data = rte_stats_bitrate_create(); + TEST_ASSERT(bitrate_data != NULL, "rte_stats_bitrate_create failed"); + + return TEST_SUCCESS; +} + +/* To test bit rate registration */ +static int +test_stats_bitrate_reg(void) +{ + int ret = 0; + + /* Test to register bit rate without metrics init */ + ret = rte_stats_bitrate_reg(bitrate_data); + TEST_ASSERT(ret < 0, "Test Failed: rte_stats_bitrate_reg succeeded " + "without metrics init, ret:%d", ret); + + /* Metrics initialization */ + rte_metrics_init(rte_socket_id()); + /* Test to register bit rate after metrics init */ + ret = rte_stats_bitrate_reg(bitrate_data); + TEST_ASSERT((ret >= 0), "Test Failed: rte_stats_bitrate_reg %d", ret); + + return TEST_SUCCESS; +} + +/* To test the bit rate registration with invalid pointer */ +static int +test_stats_bitrate_reg_invalidpointer(void) +{ + int ret = 0; + + ret = rte_stats_bitrate_reg(NULL); + TEST_ASSERT(ret < 0, "Test Failed: Expected failure < 0 but " + "got %d", ret); + + return TEST_SUCCESS; +} + +/* To test bit rate calculation with invalid bit rate data pointer */ +static int +test_stats_bitrate_calc_invalid_bitrate_data(void) +{ + int ret = 0; + + ret = rte_stats_bitrate_calc(NULL, portid); + TEST_ASSERT(ret < 0, "Test Failed: rte_stats_bitrate_calc " + "ret:%d", ret); + + return TEST_SUCCESS; +} + +/* To test the bit rate calculation with invalid portid + * (higher than max ports) + */ +static int +test_stats_bitrate_calc_invalid_portid_1(void) +{ + int ret = 0; + + ret = rte_stats_bitrate_calc(bitrate_data, 33); + TEST_ASSERT(ret == -EINVAL, "Test Failed: Expected -%d for higher " + "portid rte_stats_bitrate_calc ret:%d", EINVAL, ret); + + return TEST_SUCCESS; +} + +/* To test the bit rate calculation with invalid portid (lesser than 0) */ +static int +test_stats_bitrate_calc_invalid_portid_2(void) +{ + int ret = 0; + + ret = rte_stats_bitrate_calc(bitrate_data, -1); + TEST_ASSERT(ret == -EINVAL, "Test Failed: Expected -%d for invalid " + "portid rte_stats_bitrate_calc ret:%d", EINVAL, ret); + + return TEST_SUCCESS; +} + +/* To test the bit rate calculation with non-existing portid */ +static int +test_stats_bitrate_calc_non_existing_portid(void) +{ + int ret = 0; + + ret = rte_stats_bitrate_calc(bitrate_data, 31); + TEST_ASSERT(ret == -EINVAL, "Test Failed: Expected -%d for " + "non-existing portid rte_stats_bitrate_calc ret:%d", + EINVAL, ret); + + return TEST_SUCCESS; +} + +/* To test the bit rate calculation with valid bit rate data, valid portid */ +static int +test_stats_bitrate_calc(void) +{ + int ret = 0; + + ret = rte_stats_bitrate_calc(bitrate_data, portid); + TEST_ASSERT(ret >= 0, "Test Failed: Expected >=0 for valid portid " + "rte_stats_bitrate_calc ret:%d", ret); + + return TEST_SUCCESS; +} + +static int +test_bit_packet_forward(void) +{ + int ret; + struct rte_mbuf *pbuf[BIT_NUM_PACKETS] = { }; + struct rte_mempool *mp; + char poolname[] = "mbuf_pool"; + ret = test_get_mbuf_from_pool(&mp, pbuf, poolname); + if (ret < 0) { + printf("allocate mbuf pool Failed\n"); + return TEST_FAILED; + } + ret = test_packet_forward(pbuf, portid, QUEUE_ID); + if (ret < 0) + printf("send pkts Failed\n"); + test_put_mbuf_to_pool(mp, pbuf); + + return TEST_SUCCESS; +} + +static int +test_bit_ring_setup(void) +{ + test_ring_setup(&ring, &portid); + printf("port in ring setup : %d\n", portid); + + return TEST_SUCCESS; +} + +static void +test_bit_ring_free(void) +{ + test_ring_free(ring); + test_vdev_uninit("net_ring_net_ringa"); + rte_memzone_free(rte_memzone_lookup("RTE_METRICS")); +} + +static struct +unit_test_suite bitratestats_testsuite = { + .suite_name = "BitRate Stats Unit Test Suite", + .setup = test_bit_ring_setup, + .teardown = test_bit_ring_free, + .unit_test_cases = { + /* TEST CASE 1: Test to create bit rate data */ + TEST_CASE(test_stats_bitrate_create), + + /* TEST CASE 2: Test to register bit rate metrics + * without metrics init and after metrics init + */ + TEST_CASE(test_stats_bitrate_reg), + + /* TEST CASE 3: Test to register bit rate metrics + * with invalid bit rate data + */ + TEST_CASE(test_stats_bitrate_reg_invalidpointer), + + /* TEST CASE 4: Test to calculate bit rate data metrics + * with invalid bit rate data + */ + TEST_CASE(test_stats_bitrate_calc_invalid_bitrate_data), + + /* TEST CASE 5: Test to calculate bit rate data metrics + * with portid exceeding the max ports + */ + TEST_CASE(test_stats_bitrate_calc_invalid_portid_1), + + /* TEST CASE 6: Test to calculate bit rate data metrics + * with portid less than 0 + */ + TEST_CASE(test_stats_bitrate_calc_invalid_portid_2), + + /* TEST CASE 7: Test to calculate bit rate data metrics + * with non-existing portid + */ + TEST_CASE(test_stats_bitrate_calc_non_existing_portid), + + /* TEST CASE 8: Test to calculate bit rate data metrics + * with valid portid, valid bit rate data + */ + TEST_CASE_ST(test_bit_packet_forward, NULL, + test_stats_bitrate_calc), + TEST_CASES_END() + } +}; + +static int +test_bitratestats(void) +{ + return unit_test_suite_runner(&bitratestats_testsuite); +} +REGISTER_TEST_COMMAND(bitratestats_autotest, test_bitratestats); diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c new file mode 100644 index 0000000000..1d50401aa8 --- /dev/null +++ b/app/test/test_bpf.c @@ -0,0 +1,2034 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* + * Basic functional tests for librte_bpf. + * The main procedure - load eBPF program, execute it and + * compare restuls with expected values. + */ + +struct dummy_offset { + uint64_t u64; + uint32_t u32; + uint16_t u16; + uint8_t u8; +}; + +struct dummy_vect8 { + struct dummy_offset in[8]; + struct dummy_offset out[8]; +}; + +#define TEST_FILL_1 0xDEADBEEF + +#define TEST_MUL_1 21 +#define TEST_MUL_2 -100 + +#define TEST_SHIFT_1 15 +#define TEST_SHIFT_2 33 + +#define TEST_JCC_1 0 +#define TEST_JCC_2 -123 +#define TEST_JCC_3 5678 +#define TEST_JCC_4 TEST_FILL_1 + +#define TEST_IMM_1 UINT64_MAX +#define TEST_IMM_2 ((uint64_t)INT64_MIN) +#define TEST_IMM_3 ((uint64_t)INT64_MAX + INT32_MAX) +#define TEST_IMM_4 ((uint64_t)UINT32_MAX) +#define TEST_IMM_5 ((uint64_t)UINT32_MAX + 1) + +struct bpf_test { + const char *name; + size_t arg_sz; + struct rte_bpf_prm prm; + void (*prepare)(void *); + int (*check_result)(uint64_t, const void *); + uint32_t allow_fail; +}; + +/* + * Compare return value and result data with expected ones. + * Report a failure if they don't match. + */ +static int +cmp_res(const char *func, uint64_t exp_rc, uint64_t ret_rc, + const void *exp_res, const void *ret_res, size_t res_sz) +{ + int32_t ret; + + ret = 0; + if (exp_rc != ret_rc) { + printf("%s@%d: invalid return value, expected: 0x%" PRIx64 + ",result: 0x%" PRIx64 "\n", + func, __LINE__, exp_rc, ret_rc); + ret |= -1; + } + + if (memcmp(exp_res, ret_res, res_sz) != 0) { + printf("%s: invalid value\n", func); + rte_memdump(stdout, "expected", exp_res, res_sz); + rte_memdump(stdout, "result", ret_res, res_sz); + ret |= -1; + } + + return ret; +} + +/* store immediate test-cases */ +static const struct ebpf_insn test_store1_prog[] = { + { + .code = (BPF_ST | BPF_MEM | BPF_B), + .dst_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u8), + .imm = TEST_FILL_1, + }, + { + .code = (BPF_ST | BPF_MEM | BPF_H), + .dst_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u16), + .imm = TEST_FILL_1, + }, + { + .code = (BPF_ST | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u32), + .imm = TEST_FILL_1, + }, + { + .code = (BPF_ST | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u64), + .imm = TEST_FILL_1, + }, + /* return 1 */ + { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 1, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static void +test_store1_prepare(void *arg) +{ + struct dummy_offset *df; + + df = arg; + memset(df, 0, sizeof(*df)); +} + +static int +test_store1_check(uint64_t rc, const void *arg) +{ + const struct dummy_offset *dft; + struct dummy_offset dfe; + + dft = arg; + + memset(&dfe, 0, sizeof(dfe)); + dfe.u64 = (int32_t)TEST_FILL_1; + dfe.u32 = dfe.u64; + dfe.u16 = dfe.u64; + dfe.u8 = dfe.u64; + + return cmp_res(__func__, 1, rc, &dfe, dft, sizeof(dfe)); +} + +/* store register test-cases */ +static const struct ebpf_insn test_store2_prog[] = { + + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = TEST_FILL_1, + }, + { + .code = (BPF_STX | BPF_MEM | BPF_B), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_offset, u8), + }, + { + .code = (BPF_STX | BPF_MEM | BPF_H), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_offset, u16), + }, + { + .code = (BPF_STX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_offset, u64), + }, + /* return 1 */ + { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 1, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +/* load test-cases */ +static const struct ebpf_insn test_load1_prog[] = { + + { + .code = (BPF_LDX | BPF_MEM | BPF_B), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u8), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_H), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u16), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u64), + }, + /* return sum */ + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_4, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_3, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_2, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static void +test_load1_prepare(void *arg) +{ + struct dummy_offset *df; + + df = arg; + + memset(df, 0, sizeof(*df)); + df->u64 = (int32_t)TEST_FILL_1; + df->u32 = df->u64; + df->u16 = df->u64; + df->u8 = df->u64; +} + +static int +test_load1_check(uint64_t rc, const void *arg) +{ + uint64_t v; + const struct dummy_offset *dft; + + dft = arg; + v = dft->u64; + v += dft->u32; + v += dft->u16; + v += dft->u8; + + return cmp_res(__func__, v, rc, dft, dft, sizeof(*dft)); +} + +/* load immediate test-cases */ +static const struct ebpf_insn test_ldimm1_prog[] = { + + { + .code = (BPF_LD | BPF_IMM | EBPF_DW), + .dst_reg = EBPF_REG_0, + .imm = (uint32_t)TEST_IMM_1, + }, + { + .imm = TEST_IMM_1 >> 32, + }, + { + .code = (BPF_LD | BPF_IMM | EBPF_DW), + .dst_reg = EBPF_REG_3, + .imm = (uint32_t)TEST_IMM_2, + }, + { + .imm = TEST_IMM_2 >> 32, + }, + { + .code = (BPF_LD | BPF_IMM | EBPF_DW), + .dst_reg = EBPF_REG_5, + .imm = (uint32_t)TEST_IMM_3, + }, + { + .imm = TEST_IMM_3 >> 32, + }, + { + .code = (BPF_LD | BPF_IMM | EBPF_DW), + .dst_reg = EBPF_REG_7, + .imm = (uint32_t)TEST_IMM_4, + }, + { + .imm = TEST_IMM_4 >> 32, + }, + { + .code = (BPF_LD | BPF_IMM | EBPF_DW), + .dst_reg = EBPF_REG_9, + .imm = (uint32_t)TEST_IMM_5, + }, + { + .imm = TEST_IMM_5 >> 32, + }, + /* return sum */ + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_3, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_5, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_7, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_9, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static int +test_ldimm1_check(uint64_t rc, const void *arg) +{ + uint64_t v1, v2; + + v1 = TEST_IMM_1; + v2 = TEST_IMM_2; + v1 += v2; + v2 = TEST_IMM_3; + v1 += v2; + v2 = TEST_IMM_4; + v1 += v2; + v2 = TEST_IMM_5; + v1 += v2; + + return cmp_res(__func__, v1, rc, arg, arg, 0); +} + + +/* alu mul test-cases */ +static const struct ebpf_insn test_mul1_prog[] = { + + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[1].u64), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[2].u32), + }, + { + .code = (BPF_ALU | BPF_MUL | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = TEST_MUL_1, + }, + { + .code = (EBPF_ALU64 | BPF_MUL | BPF_K), + .dst_reg = EBPF_REG_3, + .imm = TEST_MUL_2, + }, + { + .code = (BPF_ALU | BPF_MUL | BPF_X), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_2, + }, + { + .code = (EBPF_ALU64 | BPF_MUL | BPF_X), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_3, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_vect8, out[0].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[1].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_vect8, out[2].u64), + }, + /* return 1 */ + { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 1, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static void +test_mul1_prepare(void *arg) +{ + struct dummy_vect8 *dv; + uint64_t v; + + dv = arg; + + v = rte_rand(); + + memset(dv, 0, sizeof(*dv)); + dv->in[0].u32 = v; + dv->in[1].u64 = v << 12 | v >> 6; + dv->in[2].u32 = -v; +} + +static int +test_mul1_check(uint64_t rc, const void *arg) +{ + uint64_t r2, r3, r4; + const struct dummy_vect8 *dvt; + struct dummy_vect8 dve; + + dvt = arg; + memset(&dve, 0, sizeof(dve)); + + r2 = dvt->in[0].u32; + r3 = dvt->in[1].u64; + r4 = dvt->in[2].u32; + + r2 = (uint32_t)r2 * TEST_MUL_1; + r3 *= TEST_MUL_2; + r4 = (uint32_t)(r4 * r2); + r4 *= r3; + + dve.out[0].u64 = r2; + dve.out[1].u64 = r3; + dve.out[2].u64 = r4; + + return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); +} + +/* alu shift test-cases */ +static const struct ebpf_insn test_shift1_prog[] = { + + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[1].u64), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[2].u32), + }, + { + .code = (BPF_ALU | BPF_LSH | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = TEST_SHIFT_1, + }, + { + .code = (EBPF_ALU64 | EBPF_ARSH | BPF_K), + .dst_reg = EBPF_REG_3, + .imm = TEST_SHIFT_2, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_vect8, out[0].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[1].u64), + }, + { + .code = (BPF_ALU | BPF_RSH | BPF_X), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_4, + }, + { + .code = (EBPF_ALU64 | BPF_LSH | BPF_X), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_4, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_vect8, out[2].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[3].u64), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[1].u64), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[2].u32), + }, + { + .code = (BPF_ALU | BPF_AND | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = sizeof(uint64_t) * CHAR_BIT - 1, + }, + { + .code = (EBPF_ALU64 | EBPF_ARSH | BPF_X), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_2, + }, + { + .code = (BPF_ALU | BPF_AND | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = sizeof(uint32_t) * CHAR_BIT - 1, + }, + { + .code = (BPF_ALU | BPF_LSH | BPF_X), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_2, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_vect8, out[4].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[5].u64), + }, + /* return 1 */ + { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 1, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static void +test_shift1_prepare(void *arg) +{ + struct dummy_vect8 *dv; + uint64_t v; + + dv = arg; + + v = rte_rand(); + + memset(dv, 0, sizeof(*dv)); + dv->in[0].u32 = v; + dv->in[1].u64 = v << 12 | v >> 6; + dv->in[2].u32 = (-v ^ 5); +} + +static int +test_shift1_check(uint64_t rc, const void *arg) +{ + uint64_t r2, r3, r4; + const struct dummy_vect8 *dvt; + struct dummy_vect8 dve; + + dvt = arg; + memset(&dve, 0, sizeof(dve)); + + r2 = dvt->in[0].u32; + r3 = dvt->in[1].u64; + r4 = dvt->in[2].u32; + + r2 = (uint32_t)r2 << TEST_SHIFT_1; + r3 = (int64_t)r3 >> TEST_SHIFT_2; + + dve.out[0].u64 = r2; + dve.out[1].u64 = r3; + + r2 = (uint32_t)r2 >> r4; + r3 <<= r4; + + dve.out[2].u64 = r2; + dve.out[3].u64 = r3; + + r2 = dvt->in[0].u32; + r3 = dvt->in[1].u64; + r4 = dvt->in[2].u32; + + r2 &= sizeof(uint64_t) * CHAR_BIT - 1; + r3 = (int64_t)r3 >> r2; + r2 &= sizeof(uint32_t) * CHAR_BIT - 1; + r4 = (uint32_t)r4 << r2; + + dve.out[4].u64 = r4; + dve.out[5].u64 = r3; + + return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); +} + +/* jmp test-cases */ +static const struct ebpf_insn test_jump1_prog[] = { + + [0] = { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0, + }, + [1] = { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u32), + }, + [2] = { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u64), + }, + [3] = { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[1].u32), + }, + [4] = { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_5, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[1].u64), + }, + [5] = { + .code = (BPF_JMP | BPF_JEQ | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = TEST_JCC_1, + .off = 8, + }, + [6] = { + .code = (BPF_JMP | EBPF_JSLE | BPF_K), + .dst_reg = EBPF_REG_3, + .imm = TEST_JCC_2, + .off = 9, + }, + [7] = { + .code = (BPF_JMP | BPF_JGT | BPF_K), + .dst_reg = EBPF_REG_4, + .imm = TEST_JCC_3, + .off = 10, + }, + [8] = { + .code = (BPF_JMP | BPF_JSET | BPF_K), + .dst_reg = EBPF_REG_5, + .imm = TEST_JCC_4, + .off = 11, + }, + [9] = { + .code = (BPF_JMP | EBPF_JNE | BPF_X), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_3, + .off = 12, + }, + [10] = { + .code = (BPF_JMP | EBPF_JSGT | BPF_X), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_4, + .off = 13, + }, + [11] = { + .code = (BPF_JMP | EBPF_JLE | BPF_X), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_5, + .off = 14, + }, + [12] = { + .code = (BPF_JMP | BPF_JSET | BPF_X), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_5, + .off = 15, + }, + [13] = { + .code = (BPF_JMP | EBPF_EXIT), + }, + [14] = { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x1, + }, + [15] = { + .code = (BPF_JMP | BPF_JA), + .off = -10, + }, + [16] = { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x2, + }, + [17] = { + .code = (BPF_JMP | BPF_JA), + .off = -11, + }, + [18] = { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x4, + }, + [19] = { + .code = (BPF_JMP | BPF_JA), + .off = -12, + }, + [20] = { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x8, + }, + [21] = { + .code = (BPF_JMP | BPF_JA), + .off = -13, + }, + [22] = { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x10, + }, + [23] = { + .code = (BPF_JMP | BPF_JA), + .off = -14, + }, + [24] = { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x20, + }, + [25] = { + .code = (BPF_JMP | BPF_JA), + .off = -15, + }, + [26] = { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x40, + }, + [27] = { + .code = (BPF_JMP | BPF_JA), + .off = -16, + }, + [28] = { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x80, + }, + [29] = { + .code = (BPF_JMP | BPF_JA), + .off = -17, + }, +}; + +static void +test_jump1_prepare(void *arg) +{ + struct dummy_vect8 *dv; + uint64_t v1, v2; + + dv = arg; + + v1 = rte_rand(); + v2 = rte_rand(); + + memset(dv, 0, sizeof(*dv)); + dv->in[0].u64 = v1; + dv->in[1].u64 = v2; + dv->in[0].u32 = (v1 << 12) + (v2 >> 6); + dv->in[1].u32 = (v2 << 12) - (v1 >> 6); +} + +static int +test_jump1_check(uint64_t rc, const void *arg) +{ + uint64_t r2, r3, r4, r5, rv; + const struct dummy_vect8 *dvt; + + dvt = arg; + + rv = 0; + r2 = dvt->in[0].u32; + r3 = dvt->in[0].u64; + r4 = dvt->in[1].u32; + r5 = dvt->in[1].u64; + + if (r2 == TEST_JCC_1) + rv |= 0x1; + if ((int64_t)r3 <= TEST_JCC_2) + rv |= 0x2; + if (r4 > TEST_JCC_3) + rv |= 0x4; + if (r5 & TEST_JCC_4) + rv |= 0x8; + if (r2 != r3) + rv |= 0x10; + if ((int64_t)r2 > (int64_t)r4) + rv |= 0x20; + if (r2 <= r5) + rv |= 0x40; + if (r3 & r5) + rv |= 0x80; + + return cmp_res(__func__, rv, rc, &rv, &rc, sizeof(rv)); +} + +/* alu (add, sub, and, or, xor, neg) test-cases */ +static const struct ebpf_insn test_alu1_prog[] = { + + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u64), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[1].u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_5, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[1].u64), + }, + { + .code = (BPF_ALU | BPF_AND | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = TEST_FILL_1, + }, + { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_3, + .imm = TEST_FILL_1, + }, + { + .code = (BPF_ALU | BPF_XOR | BPF_K), + .dst_reg = EBPF_REG_4, + .imm = TEST_FILL_1, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_K), + .dst_reg = EBPF_REG_5, + .imm = TEST_FILL_1, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_vect8, out[0].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[1].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_vect8, out[2].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_5, + .off = offsetof(struct dummy_vect8, out[3].u64), + }, + { + .code = (BPF_ALU | BPF_OR | BPF_X), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_3, + }, + { + .code = (EBPF_ALU64 | BPF_XOR | BPF_X), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_4, + }, + { + .code = (BPF_ALU | BPF_SUB | BPF_X), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_5, + }, + { + .code = (EBPF_ALU64 | BPF_AND | BPF_X), + .dst_reg = EBPF_REG_5, + .src_reg = EBPF_REG_2, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_vect8, out[4].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[5].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_vect8, out[6].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_5, + .off = offsetof(struct dummy_vect8, out[7].u64), + }, + /* return (-r2 + (-r3)) */ + { + .code = (BPF_ALU | BPF_NEG), + .dst_reg = EBPF_REG_2, + }, + { + .code = (EBPF_ALU64 | BPF_NEG), + .dst_reg = EBPF_REG_3, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_3, + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_2, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static int +test_alu1_check(uint64_t rc, const void *arg) +{ + uint64_t r2, r3, r4, r5, rv; + const struct dummy_vect8 *dvt; + struct dummy_vect8 dve; + + dvt = arg; + memset(&dve, 0, sizeof(dve)); + + r2 = dvt->in[0].u32; + r3 = dvt->in[0].u64; + r4 = dvt->in[1].u32; + r5 = dvt->in[1].u64; + + r2 = (uint32_t)r2 & TEST_FILL_1; + r3 |= (int32_t) TEST_FILL_1; + r4 = (uint32_t)r4 ^ TEST_FILL_1; + r5 += (int32_t)TEST_FILL_1; + + dve.out[0].u64 = r2; + dve.out[1].u64 = r3; + dve.out[2].u64 = r4; + dve.out[3].u64 = r5; + + r2 = (uint32_t)r2 | (uint32_t)r3; + r3 ^= r4; + r4 = (uint32_t)r4 - (uint32_t)r5; + r5 &= r2; + + dve.out[4].u64 = r2; + dve.out[5].u64 = r3; + dve.out[6].u64 = r4; + dve.out[7].u64 = r5; + + r2 = -(int32_t)r2; + rv = (uint32_t)r2; + r3 = -r3; + rv += r3; + + return cmp_res(__func__, rv, rc, dve.out, dvt->out, sizeof(dve.out)); +} + +/* endianness conversions (BE->LE/LE->BE) test-cases */ +static const struct ebpf_insn test_bele1_prog[] = { + + { + .code = (BPF_LDX | BPF_MEM | BPF_H), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u16), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u64), + }, + { + .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), + .dst_reg = EBPF_REG_2, + .imm = sizeof(uint16_t) * CHAR_BIT, + }, + { + .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), + .dst_reg = EBPF_REG_3, + .imm = sizeof(uint32_t) * CHAR_BIT, + }, + { + .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), + .dst_reg = EBPF_REG_4, + .imm = sizeof(uint64_t) * CHAR_BIT, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_vect8, out[0].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[1].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_vect8, out[2].u64), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_H), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u16), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u64), + }, + { + .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), + .dst_reg = EBPF_REG_2, + .imm = sizeof(uint16_t) * CHAR_BIT, + }, + { + .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), + .dst_reg = EBPF_REG_3, + .imm = sizeof(uint32_t) * CHAR_BIT, + }, + { + .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), + .dst_reg = EBPF_REG_4, + .imm = sizeof(uint64_t) * CHAR_BIT, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_vect8, out[3].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[4].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_vect8, out[5].u64), + }, + /* return 1 */ + { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 1, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static void +test_bele1_prepare(void *arg) +{ + struct dummy_vect8 *dv; + + dv = arg; + + memset(dv, 0, sizeof(*dv)); + dv->in[0].u64 = rte_rand(); + dv->in[0].u32 = dv->in[0].u64; + dv->in[0].u16 = dv->in[0].u64; +} + +static int +test_bele1_check(uint64_t rc, const void *arg) +{ + uint64_t r2, r3, r4; + const struct dummy_vect8 *dvt; + struct dummy_vect8 dve; + + dvt = arg; + memset(&dve, 0, sizeof(dve)); + + r2 = dvt->in[0].u16; + r3 = dvt->in[0].u32; + r4 = dvt->in[0].u64; + + r2 = rte_cpu_to_be_16(r2); + r3 = rte_cpu_to_be_32(r3); + r4 = rte_cpu_to_be_64(r4); + + dve.out[0].u64 = r2; + dve.out[1].u64 = r3; + dve.out[2].u64 = r4; + + r2 = dvt->in[0].u16; + r3 = dvt->in[0].u32; + r4 = dvt->in[0].u64; + + r2 = rte_cpu_to_le_16(r2); + r3 = rte_cpu_to_le_32(r3); + r4 = rte_cpu_to_le_64(r4); + + dve.out[3].u64 = r2; + dve.out[4].u64 = r3; + dve.out[5].u64 = r4; + + return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); +} + +/* atomic add test-cases */ +static const struct ebpf_insn test_xadd1_prog[] = { + + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = 1, + }, + { + .code = (BPF_STX | EBPF_XADD | BPF_W), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_STX | EBPF_XADD | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_offset, u64), + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_3, + .imm = -1, + }, + { + .code = (BPF_STX | EBPF_XADD | BPF_W), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_STX | EBPF_XADD | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_offset, u64), + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_4, + .imm = TEST_FILL_1, + }, + { + .code = (BPF_STX | EBPF_XADD | BPF_W), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_STX | EBPF_XADD | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_offset, u64), + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_5, + .imm = TEST_MUL_1, + }, + { + .code = (BPF_STX | EBPF_XADD | BPF_W), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_5, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_STX | EBPF_XADD | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_5, + .off = offsetof(struct dummy_offset, u64), + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_6, + .imm = TEST_MUL_2, + }, + { + .code = (BPF_STX | EBPF_XADD | BPF_W), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_6, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_STX | EBPF_XADD | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_6, + .off = offsetof(struct dummy_offset, u64), + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_7, + .imm = TEST_JCC_2, + }, + { + .code = (BPF_STX | EBPF_XADD | BPF_W), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_7, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_STX | EBPF_XADD | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_7, + .off = offsetof(struct dummy_offset, u64), + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_8, + .imm = TEST_JCC_3, + }, + { + .code = (BPF_STX | EBPF_XADD | BPF_W), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_8, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_STX | EBPF_XADD | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_8, + .off = offsetof(struct dummy_offset, u64), + }, + /* return 1 */ + { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 1, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static int +test_xadd1_check(uint64_t rc, const void *arg) +{ + uint64_t rv; + const struct dummy_offset *dft; + struct dummy_offset dfe; + + dft = arg; + memset(&dfe, 0, sizeof(dfe)); + + rv = 1; + rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); + rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); + + rv = -1; + rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); + rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); + + rv = (int32_t)TEST_FILL_1; + rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); + rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); + + rv = TEST_MUL_1; + rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); + rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); + + rv = TEST_MUL_2; + rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); + rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); + + rv = TEST_JCC_2; + rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); + rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); + + rv = TEST_JCC_3; + rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); + rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); + + return cmp_res(__func__, 1, rc, &dfe, dft, sizeof(dfe)); +} + +/* alu div test-cases */ +static const struct ebpf_insn test_div1_prog[] = { + + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[0].u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[1].u64), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[2].u32), + }, + { + .code = (BPF_ALU | BPF_DIV | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = TEST_MUL_1, + }, + { + .code = (EBPF_ALU64 | BPF_MOD | BPF_K), + .dst_reg = EBPF_REG_3, + .imm = TEST_MUL_2, + }, + { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = 1, + }, + { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_3, + .imm = 1, + }, + { + .code = (BPF_ALU | BPF_MOD | BPF_X), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_2, + }, + { + .code = (EBPF_ALU64 | BPF_DIV | BPF_X), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_3, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_2, + .off = offsetof(struct dummy_vect8, out[0].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_3, + .off = offsetof(struct dummy_vect8, out[1].u64), + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_4, + .off = offsetof(struct dummy_vect8, out[2].u64), + }, + /* check that we can handle division by zero gracefully. */ + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_vect8, in[3].u32), + }, + { + .code = (BPF_ALU | BPF_DIV | BPF_X), + .dst_reg = EBPF_REG_4, + .src_reg = EBPF_REG_2, + }, + /* return 1 */ + { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 1, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static int +test_div1_check(uint64_t rc, const void *arg) +{ + uint64_t r2, r3, r4; + const struct dummy_vect8 *dvt; + struct dummy_vect8 dve; + + dvt = arg; + memset(&dve, 0, sizeof(dve)); + + r2 = dvt->in[0].u32; + r3 = dvt->in[1].u64; + r4 = dvt->in[2].u32; + + r2 = (uint32_t)r2 / TEST_MUL_1; + r3 %= TEST_MUL_2; + r2 |= 1; + r3 |= 1; + r4 = (uint32_t)(r4 % r2); + r4 /= r3; + + dve.out[0].u64 = r2; + dve.out[1].u64 = r3; + dve.out[2].u64 = r4; + + /* + * in the test prog we attempted to divide by zero. + * so return value should return 0. + */ + return cmp_res(__func__, 0, rc, dve.out, dvt->out, sizeof(dve.out)); +} + +/* call test-cases */ +static const struct ebpf_insn test_call1_prog[] = { + + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u32), + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u64), + }, + { + .code = (BPF_STX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_10, + .src_reg = EBPF_REG_2, + .off = -4, + }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_10, + .src_reg = EBPF_REG_3, + .off = -16, + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_10, + }, + { + .code = (EBPF_ALU64 | BPF_SUB | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = 4, + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_10, + }, + { + .code = (EBPF_ALU64 | BPF_SUB | BPF_K), + .dst_reg = EBPF_REG_3, + .imm = 16, + }, + { + .code = (BPF_JMP | EBPF_CALL), + .imm = 0, + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_10, + .off = -4, + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_10, + .off = -16 + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_2, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static void +dummy_func1(const void *p, uint32_t *v32, uint64_t *v64) +{ + const struct dummy_offset *dv; + + dv = p; + + v32[0] += dv->u16; + v64[0] += dv->u8; +} + +static int +test_call1_check(uint64_t rc, const void *arg) +{ + uint32_t v32; + uint64_t v64; + const struct dummy_offset *dv; + + dv = arg; + + v32 = dv->u32; + v64 = dv->u64; + dummy_func1(arg, &v32, &v64); + v64 += v32; + + if (v64 != rc) { + printf("%s@%d: invalid return value " + "expected=0x%" PRIx64 ", actual=0x%" PRIx64 "\n", + __func__, __LINE__, v64, rc); + return -1; + } + return 0; + return cmp_res(__func__, v64, rc, dv, dv, sizeof(*dv)); +} + +static const struct rte_bpf_xsym test_call1_xsym[] = { + { + .name = RTE_STR(dummy_func1), + .type = RTE_BPF_XTYPE_FUNC, + .func = { + .val = (void *)dummy_func1, + .nb_args = 3, + .args = { + [0] = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + [1] = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(uint32_t), + }, + [2] = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(uint64_t), + }, + }, + }, + }, +}; + +static const struct ebpf_insn test_call2_prog[] = { + + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_10, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_K), + .dst_reg = EBPF_REG_1, + .imm = -(int32_t)sizeof(struct dummy_offset), + }, + { + .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_10, + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = -2 * (int32_t)sizeof(struct dummy_offset), + }, + { + .code = (BPF_JMP | EBPF_CALL), + .imm = 0, + }, + { + .code = (BPF_LDX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_10, + .off = -(int32_t)(sizeof(struct dummy_offset) - + offsetof(struct dummy_offset, u64)), + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_W), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_10, + .off = -(int32_t)(sizeof(struct dummy_offset) - + offsetof(struct dummy_offset, u32)), + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_1, + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_H), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_10, + .off = -(int32_t)(2 * sizeof(struct dummy_offset) - + offsetof(struct dummy_offset, u16)), + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_1, + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_B), + .dst_reg = EBPF_REG_1, + .src_reg = EBPF_REG_10, + .off = -(int32_t)(2 * sizeof(struct dummy_offset) - + offsetof(struct dummy_offset, u8)), + }, + { + .code = (EBPF_ALU64 | BPF_ADD | BPF_X), + .dst_reg = EBPF_REG_0, + .src_reg = EBPF_REG_1, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, + +}; + +static void +dummy_func2(struct dummy_offset *a, struct dummy_offset *b) +{ + uint64_t v; + + v = 0; + a->u64 = v++; + a->u32 = v++; + a->u16 = v++; + a->u8 = v++; + b->u64 = v++; + b->u32 = v++; + b->u16 = v++; + b->u8 = v++; +} + +static int +test_call2_check(uint64_t rc, const void *arg) +{ + uint64_t v; + struct dummy_offset a, b; + + RTE_SET_USED(arg); + + dummy_func2(&a, &b); + v = a.u64 + a.u32 + b.u16 + b.u8; + + if (v != rc) { + printf("%s@%d: invalid return value " + "expected=0x%" PRIx64 ", actual=0x%" PRIx64 "\n", + __func__, __LINE__, v, rc); + return -1; + } + return 0; +} + +static const struct rte_bpf_xsym test_call2_xsym[] = { + { + .name = RTE_STR(dummy_func2), + .type = RTE_BPF_XTYPE_FUNC, + .func = { + .val = (void *)dummy_func2, + .nb_args = 2, + .args = { + [0] = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + [1] = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + }, + }, + }, +}; + +static const struct bpf_test tests[] = { + { + .name = "test_store1", + .arg_sz = sizeof(struct dummy_offset), + .prm = { + .ins = test_store1_prog, + .nb_ins = RTE_DIM(test_store1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + }, + .prepare = test_store1_prepare, + .check_result = test_store1_check, + }, + { + .name = "test_store2", + .arg_sz = sizeof(struct dummy_offset), + .prm = { + .ins = test_store2_prog, + .nb_ins = RTE_DIM(test_store2_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + }, + .prepare = test_store1_prepare, + .check_result = test_store1_check, + }, + { + .name = "test_load1", + .arg_sz = sizeof(struct dummy_offset), + .prm = { + .ins = test_load1_prog, + .nb_ins = RTE_DIM(test_load1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + }, + .prepare = test_load1_prepare, + .check_result = test_load1_check, + }, + { + .name = "test_ldimm1", + .arg_sz = sizeof(struct dummy_offset), + .prm = { + .ins = test_ldimm1_prog, + .nb_ins = RTE_DIM(test_ldimm1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + }, + .prepare = test_store1_prepare, + .check_result = test_ldimm1_check, + }, + { + .name = "test_mul1", + .arg_sz = sizeof(struct dummy_vect8), + .prm = { + .ins = test_mul1_prog, + .nb_ins = RTE_DIM(test_mul1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_vect8), + }, + }, + .prepare = test_mul1_prepare, + .check_result = test_mul1_check, + }, + { + .name = "test_shift1", + .arg_sz = sizeof(struct dummy_vect8), + .prm = { + .ins = test_shift1_prog, + .nb_ins = RTE_DIM(test_shift1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_vect8), + }, + }, + .prepare = test_shift1_prepare, + .check_result = test_shift1_check, + }, + { + .name = "test_jump1", + .arg_sz = sizeof(struct dummy_vect8), + .prm = { + .ins = test_jump1_prog, + .nb_ins = RTE_DIM(test_jump1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_vect8), + }, + }, + .prepare = test_jump1_prepare, + .check_result = test_jump1_check, + }, + { + .name = "test_alu1", + .arg_sz = sizeof(struct dummy_vect8), + .prm = { + .ins = test_alu1_prog, + .nb_ins = RTE_DIM(test_alu1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_vect8), + }, + }, + .prepare = test_jump1_prepare, + .check_result = test_alu1_check, + }, + { + .name = "test_bele1", + .arg_sz = sizeof(struct dummy_vect8), + .prm = { + .ins = test_bele1_prog, + .nb_ins = RTE_DIM(test_bele1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_vect8), + }, + }, + .prepare = test_bele1_prepare, + .check_result = test_bele1_check, + }, + { + .name = "test_xadd1", + .arg_sz = sizeof(struct dummy_offset), + .prm = { + .ins = test_xadd1_prog, + .nb_ins = RTE_DIM(test_xadd1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + }, + .prepare = test_store1_prepare, + .check_result = test_xadd1_check, + }, + { + .name = "test_div1", + .arg_sz = sizeof(struct dummy_vect8), + .prm = { + .ins = test_div1_prog, + .nb_ins = RTE_DIM(test_div1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_vect8), + }, + }, + .prepare = test_mul1_prepare, + .check_result = test_div1_check, + }, + { + .name = "test_call1", + .arg_sz = sizeof(struct dummy_offset), + .prm = { + .ins = test_call1_prog, + .nb_ins = RTE_DIM(test_call1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + .xsym = test_call1_xsym, + .nb_xsym = RTE_DIM(test_call1_xsym), + }, + .prepare = test_load1_prepare, + .check_result = test_call1_check, + /* for now don't support function calls on 32 bit platform */ + .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), + }, + { + .name = "test_call2", + .arg_sz = sizeof(struct dummy_offset), + .prm = { + .ins = test_call2_prog, + .nb_ins = RTE_DIM(test_call2_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + .xsym = test_call2_xsym, + .nb_xsym = RTE_DIM(test_call2_xsym), + }, + .prepare = test_store1_prepare, + .check_result = test_call2_check, + /* for now don't support function calls on 32 bit platform */ + .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), + }, +}; + +static int +run_test(const struct bpf_test *tst) +{ + int32_t ret, rv; + int64_t rc; + struct rte_bpf *bpf; + struct rte_bpf_jit jit; + uint8_t tbuf[tst->arg_sz]; + + printf("%s(%s) start\n", __func__, tst->name); + + bpf = rte_bpf_load(&tst->prm); + if (bpf == NULL) { + printf("%s@%d: failed to load bpf code, error=%d(%s);\n", + __func__, __LINE__, rte_errno, strerror(rte_errno)); + return -1; + } + + tst->prepare(tbuf); + + rc = rte_bpf_exec(bpf, tbuf); + ret = tst->check_result(rc, tbuf); + if (ret != 0) { + printf("%s@%d: check_result(%s) failed, error: %d(%s);\n", + __func__, __LINE__, tst->name, ret, strerror(ret)); + } + + rte_bpf_get_jit(bpf, &jit); + if (jit.func == NULL) + return 0; + + tst->prepare(tbuf); + rc = jit.func(tbuf); + rv = tst->check_result(rc, tbuf); + ret |= rv; + if (rv != 0) { + printf("%s@%d: check_result(%s) failed, error: %d(%s);\n", + __func__, __LINE__, tst->name, rv, strerror(ret)); + } + + rte_bpf_destroy(bpf); + return ret; + +} + +static int +test_bpf(void) +{ + int32_t rc, rv; + uint32_t i; + + rc = 0; + for (i = 0; i != RTE_DIM(tests); i++) { + rv = run_test(tests + i); + if (tests[i].allow_fail == 0) + rc |= rv; + } + + return rc; +} + +REGISTER_TEST_COMMAND(bpf_autotest, test_bpf); diff --git a/app/test/test_byteorder.c b/app/test/test_byteorder.c new file mode 100644 index 0000000000..03c08d9abf --- /dev/null +++ b/app/test/test_byteorder.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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_cfgfile.c b/app/test/test_cfgfile.c new file mode 100644 index 0000000000..37435b395a --- /dev/null +++ b/app/test/test_cfgfile.c @@ -0,0 +1,362 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 Wind River Systems Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 "resource.h" + + +#define CFG_FILES_ETC "test_cfgfiles/etc" + +REGISTER_LINKED_RESOURCE(test_cfgfiles); + +static int +test_cfgfile_setup(void) +{ + const struct resource *r; + int ret; + + r = resource_find("test_cfgfiles"); + TEST_ASSERT_NOT_NULL(r, "missing resource test_cfgfiles"); + + ret = resource_untar(r); + TEST_ASSERT_SUCCESS(ret, "failed to untar %s", r->name); + + return 0; +} + +static int +test_cfgfile_cleanup(void) +{ + const struct resource *r; + int ret; + + r = resource_find("test_cfgfiles"); + TEST_ASSERT_NOT_NULL(r, "missing resource test_cfgfiles"); + + ret = resource_rm_by_tar(r); + TEST_ASSERT_SUCCESS(ret, "Failed to delete resource %s", r->name); + + return 0; +} + +static int +_test_cfgfile_sample(struct rte_cfgfile *cfgfile) +{ + const char *value; + int ret; + + ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); + TEST_ASSERT(ret == 2, "Unexpected number of sections: %d", ret); + + ret = rte_cfgfile_has_section(cfgfile, "section1"); + TEST_ASSERT(ret, "section1 section missing"); + + ret = rte_cfgfile_section_num_entries(cfgfile, "section1"); + TEST_ASSERT(ret == 1, "section1 unexpected number of entries: %d", ret); + + value = rte_cfgfile_get_entry(cfgfile, "section1", "key1"); + TEST_ASSERT(strcmp("value1", value) == 0, + "key1 unexpected value: %s", value); + + ret = rte_cfgfile_has_section(cfgfile, "section2"); + TEST_ASSERT(ret, "section2 section missing"); + + ret = rte_cfgfile_section_num_entries(cfgfile, "section2"); + TEST_ASSERT(ret == 2, "section2 unexpected number of entries: %d", ret); + + value = rte_cfgfile_get_entry(cfgfile, "section2", "key2"); + TEST_ASSERT(strcmp("value2", value) == 0, + "key2 unexpected value: %s", value); + + value = rte_cfgfile_get_entry(cfgfile, "section2", "key3"); + TEST_ASSERT(strcmp("value3", value) == 0, + "key3 unexpected value: %s", value); + + return 0; +} + +static int +test_cfgfile_sample1(void) +{ + struct rte_cfgfile *cfgfile; + int ret; + + cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/sample1.ini", 0); + TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file"); + + ret = _test_cfgfile_sample(cfgfile); + TEST_ASSERT_SUCCESS(ret, "Failed to validate sample file: %d", ret); + + ret = rte_cfgfile_close(cfgfile); + TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); + + return 0; +} + +static int +test_cfgfile_sample2(void) +{ + struct rte_cfgfile_parameters params; + struct rte_cfgfile *cfgfile; + int ret; + + /* override comment character */ + memset(¶ms, 0, sizeof(params)); + params.comment_character = '#'; + + cfgfile = rte_cfgfile_load_with_params(CFG_FILES_ETC "/sample2.ini", 0, + ¶ms); + TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse sample2.ini"); + + ret = _test_cfgfile_sample(cfgfile); + TEST_ASSERT_SUCCESS(ret, "Failed to validate sample file: %d", ret); + + ret = rte_cfgfile_close(cfgfile); + TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); + + return 0; +} + +static int +test_cfgfile_realloc_sections(void) +{ + struct rte_cfgfile *cfgfile; + int ret; + const char *value; + + cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/realloc_sections.ini", 0); + TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file"); + + ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); + TEST_ASSERT(ret == 9, "Unexpected number of sections: %d", ret); + + ret = rte_cfgfile_has_section(cfgfile, "section9"); + TEST_ASSERT(ret, "section9 missing"); + + ret = rte_cfgfile_section_num_entries(cfgfile, "section3"); + TEST_ASSERT(ret == 21, + "section3 unexpected number of entries: %d", ret); + + ret = rte_cfgfile_section_num_entries(cfgfile, "section9"); + TEST_ASSERT(ret == 8, "section9 unexpected number of entries: %d", ret); + + value = rte_cfgfile_get_entry(cfgfile, "section9", "key8"); + TEST_ASSERT(strcmp("value8_section9", value) == 0, + "key unexpected value: %s", value); + + ret = rte_cfgfile_save(cfgfile, "/tmp/cfgfile_save.ini"); + TEST_ASSERT_SUCCESS(ret, "Failed to save *.ini file"); + remove("/tmp/cfgfile_save.ini"); + + ret = rte_cfgfile_close(cfgfile); + TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); + + return 0; +} + +static int +test_cfgfile_invalid_section_header(void) +{ + struct rte_cfgfile *cfgfile; + + cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/invalid_section.ini", 0); + TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); + + return 0; +} + +static int +test_cfgfile_invalid_comment(void) +{ + struct rte_cfgfile_parameters params; + struct rte_cfgfile *cfgfile; + + /* override comment character with an invalid one */ + memset(¶ms, 0, sizeof(params)); + params.comment_character = '$'; + + cfgfile = rte_cfgfile_load_with_params(CFG_FILES_ETC "/sample2.ini", 0, + ¶ms); + TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); + + return 0; +} + +static int +test_cfgfile_invalid_key_value_pair(void) +{ + struct rte_cfgfile *cfgfile; + + cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty_key_value.ini", 0); + TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); + + return 0; +} + +static int +test_cfgfile_empty_key_value_pair(void) +{ + struct rte_cfgfile *cfgfile; + const char *value; + int ret; + + cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty_key_value.ini", + CFG_FLAG_EMPTY_VALUES); + TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse empty_key_value.ini"); + + ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); + TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret); + + ret = rte_cfgfile_has_section(cfgfile, "section1"); + TEST_ASSERT(ret, "section1 missing"); + + ret = rte_cfgfile_section_num_entries(cfgfile, "section1"); + TEST_ASSERT(ret == 1, "section1 unexpected number of entries: %d", ret); + + value = rte_cfgfile_get_entry(cfgfile, "section1", "key"); + TEST_ASSERT(strlen(value) == 0, "key unexpected value: %s", value); + + ret = rte_cfgfile_close(cfgfile); + TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); + + return 0; +} + +static int +test_cfgfile_missing_section(void) +{ + struct rte_cfgfile *cfgfile; + + cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/missing_section.ini", 0); + TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); + + return 0; +} + +static int +test_cfgfile_global_properties(void) +{ + struct rte_cfgfile *cfgfile; + const char *value; + int ret; + + cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/missing_section.ini", + CFG_FLAG_GLOBAL_SECTION); + TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file"); + + ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); + TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret); + + ret = rte_cfgfile_has_section(cfgfile, "GLOBAL"); + TEST_ASSERT(ret, "global section missing"); + + ret = rte_cfgfile_section_num_entries(cfgfile, "GLOBAL"); + TEST_ASSERT(ret == 1, "GLOBAL unexpected number of entries: %d", ret); + + value = rte_cfgfile_get_entry(cfgfile, "GLOBAL", "key"); + TEST_ASSERT(strcmp("value", value) == 0, + "key unexpected value: %s", value); + + ret = rte_cfgfile_close(cfgfile); + TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); + + return 0; +} + +static int +test_cfgfile_empty_file(void) +{ + struct rte_cfgfile *cfgfile; + int ret; + + cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty.ini", 0); + TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file"); + + ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); + TEST_ASSERT(ret == 0, "Unexpected number of sections: %d", ret); + + ret = rte_cfgfile_close(cfgfile); + TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); + + return 0; +} + +static int +test_cfgfile(void) +{ + if (test_cfgfile_setup()) + return -1; + + if (test_cfgfile_sample1()) + return -1; + + if (test_cfgfile_sample2()) + return -1; + + if (test_cfgfile_realloc_sections()) + return -1; + + if (test_cfgfile_invalid_section_header()) + return -1; + + if (test_cfgfile_invalid_comment()) + return -1; + + if (test_cfgfile_invalid_key_value_pair()) + return -1; + + if (test_cfgfile_empty_key_value_pair()) + return -1; + + if (test_cfgfile_missing_section()) + return -1; + + if (test_cfgfile_global_properties()) + return -1; + + if (test_cfgfile_empty_file()) + return -1; + + if (test_cfgfile_cleanup()) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(cfgfile_autotest, test_cfgfile); diff --git a/app/test/test_cfgfiles/etc/empty.ini b/app/test/test_cfgfiles/etc/empty.ini new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/test/test_cfgfiles/etc/empty_key_value.ini b/app/test/test_cfgfiles/etc/empty_key_value.ini new file mode 100644 index 0000000000..53284467b3 --- /dev/null +++ b/app/test/test_cfgfiles/etc/empty_key_value.ini @@ -0,0 +1,3 @@ +[section1] +; this is section 1 +key= diff --git a/app/test/test_cfgfiles/etc/invalid_section.ini b/app/test/test_cfgfiles/etc/invalid_section.ini new file mode 100644 index 0000000000..95d6803977 --- /dev/null +++ b/app/test/test_cfgfiles/etc/invalid_section.ini @@ -0,0 +1,3 @@ +[invalid +; this is section 1 +key1=value1 diff --git a/app/test/test_cfgfiles/etc/line_too_long.ini b/app/test/test_cfgfiles/etc/line_too_long.ini new file mode 100644 index 0000000000..1dce164838 --- /dev/null +++ b/app/test/test_cfgfiles/etc/line_too_long.ini @@ -0,0 +1,3 @@ +[section1] +; this is section 1 +012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 diff --git a/app/test/test_cfgfiles/etc/missing_section.ini b/app/test/test_cfgfiles/etc/missing_section.ini new file mode 100644 index 0000000000..c78e131b40 --- /dev/null +++ b/app/test/test_cfgfiles/etc/missing_section.ini @@ -0,0 +1,2 @@ +; no section +key=value diff --git a/app/test/test_cfgfiles/etc/realloc_sections.ini b/app/test/test_cfgfiles/etc/realloc_sections.ini new file mode 100644 index 0000000000..e653e40c6b --- /dev/null +++ b/app/test/test_cfgfiles/etc/realloc_sections.ini @@ -0,0 +1,128 @@ +[section1] +key1=value1_section1 +key2=value2_section1 +key3=value3_section1 +key4=value4_section1 +key5=value5_section1 +key6=value6_section1 +key7=value7_section1 +key8=value8_section1 +key9=value9_section1 +key10=value10_section1 +key11=value11_section1 +key12=value12_section1 +key13=value13_section1 +key14=value14_section1 +key15=value15_section1 +key16=value16_section1 +key17=value17_section1 +key18=value18_section1 +key19=value19_section1 +key20=value20_section1 +key21=value21_section1 + +[section2] +key1=value1_section2 +key2=value2_section2 +key3=value3_section2 +key4=value4_section2 +key5=value5_section2 +key6=value6_section2 +key7=value7_section2 +key8=value8_section2 +key9=value9_section2 +key10=value10_section2 +key11=value11_section2 +key12=value12_section2 +key13=value13_section2 +key14=value14_section2 +key15=value15_section2 +key16=value16_section2 +key17=value17_section2 +key18=value18_section2 +key19=value19_section2 +key20=value20_section2 +key21=value21_section2 + +[section3] +key1=value1_section3 +key2=value2_section3 +key3=value3_section3 +key4=value4_section3 +key5=value5_section3 +key6=value6_section3 +key7=value7_section3 +key8=value8_section3 +key9=value9_section3 +key10=value10_section3 +key11=value11_section3 +key12=value12_section3 +key13=value13_section3 +key14=value14_section3 +key15=value15_section3 +key16=value16_section3 +key17=value17_section3 +key18=value18_section3 +key19=value19_section3 +key20=value20_section3 +key21=value21_section3 + +[section4] +key1=value1_section4 +key2=value2_section4 +key3=value3_section4 +key4=value4_section4 +key5=value5_section4 +key6=value6_section4 +key7=value7_section4 +key8=value8_section4 + +[section5] +key1=value1_section5 +key2=value2_section5 +key3=value3_section5 +key4=value4_section5 +key5=value5_section5 +key6=value6_section5 +key7=value7_section5 +key8=value8_section5 + +[section6] +key1=value1_section6 +key2=value2_section6 +key3=value3_section6 +key4=value4_section6 +key5=value5_section6 +key6=value6_section6 +key7=value7_section6 +key8=value8_section6 + +[section7] +key1=value1_section7 +key2=value2_section7 +key3=value3_section7 +key4=value4_section7 +key5=value5_section7 +key6=value6_section7 +key7=value7_section7 +key8=value8_section7 + +[section8] +key1=value1_section8 +key2=value2_section8 +key3=value3_section8 +key4=value4_section8 +key5=value5_section8 +key6=value6_section8 +key7=value7_section8 +key8=value8_section8 + +[section9] +key1=value1_section9 +key2=value2_section9 +key3=value3_section9 +key4=value4_section9 +key5=value5_section9 +key6=value6_section9 +key7=value7_section9 +key8=value8_section9 diff --git a/app/test/test_cfgfiles/etc/sample1.ini b/app/test/test_cfgfiles/etc/sample1.ini new file mode 100644 index 0000000000..aef91c2416 --- /dev/null +++ b/app/test/test_cfgfiles/etc/sample1.ini @@ -0,0 +1,12 @@ +; this is a global comment + +[section1] +; this is section 1 +key1=value1 + +[section2] +; this is section 2 +;key1=value1 +key2=value2 +key3=value3 ; this is key3 +ignore-missing-separator diff --git a/app/test/test_cfgfiles/etc/sample2.ini b/app/test/test_cfgfiles/etc/sample2.ini new file mode 100644 index 0000000000..21075e9763 --- /dev/null +++ b/app/test/test_cfgfiles/etc/sample2.ini @@ -0,0 +1,12 @@ +# this is a global comment + +[section1] +# this is section 1 +key1=value1 + +[section2] +# this is section 2 +#key1=value1 +key2=value2 +key3=value3 # this is key3 +ignore-missing-separator diff --git a/app/test/test_cmdline.c b/app/test/test_cmdline.c new file mode 100644 index 0000000000..115bee966d --- /dev/null +++ b/app/test/test_cmdline.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..1854caf8fd --- /dev/null +++ b/app/test/test_cmdline.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..8ac326cb02 --- /dev/null +++ b/app/test/test_cmdline_cirbuf.c @@ -0,0 +1,1301 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include + +#include + +#include + +#include "test_cmdline.h" + +/* different length strings */ +#define CIRBUF_STR_HEAD " HEAD" +#define CIRBUF_STR_TAIL "TAIL" + +/* miscellaneous 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)); + + strlcpy(tmp2, CIRBUF_STR_HEAD, sizeof(tmp2)); + + /* + * 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 new file mode 100644 index 0000000000..6ceba4b29b --- /dev/null +++ b/app/test/test_cmdline_etheraddr.c @@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..8ee7f62886 --- /dev/null +++ b/app/test/test_cmdline_ipaddr.c @@ -0,0 +1,691 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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}, + {"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 new file mode 100644 index 0000000000..a856a97132 --- /dev/null +++ b/app/test/test_cmdline_lib.c @@ -0,0 +1,234 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..ea6b9f1e36 --- /dev/null +++ b/app/test/test_cmdline_num.c @@ -0,0 +1,594 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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; + break; + 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 new file mode 100644 index 0000000000..0dc6d00304 --- /dev/null +++ b/app/test/test_cmdline_portlist.c @@ -0,0 +1,221 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..0461a85bb9 --- /dev/null +++ b/app/test/test_cmdline_string.c @@ -0,0 +1,383 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..94d3674712 --- /dev/null +++ b/app/test/test_common.c @@ -0,0 +1,311 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#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_bsf(void) +{ + uint32_t shift, pos; + + /* safe versions should be able to handle 0 */ + if (rte_bsf32_safe(0, &pos) != 0) + FAIL("rte_bsf32_safe"); + if (rte_bsf64_safe(0, &pos) != 0) + FAIL("rte_bsf64_safe"); + + for (shift = 0; shift < 63; shift++) { + uint32_t val32; + uint64_t val64; + + val64 = 1ULL << shift; + if ((uint32_t)rte_bsf64(val64) != shift) + FAIL("rte_bsf64"); + if (rte_bsf64_safe(val64, &pos) != 1) + FAIL("rte_bsf64_safe"); + if (pos != shift) + FAIL("rte_bsf64_safe"); + + if (shift > 31) + continue; + + val32 = 1U << shift; + if ((uint32_t)rte_bsf32(val32) != shift) + FAIL("rte_bsf32"); + if (rte_bsf32_safe(val32, &pos) != 1) + FAIL("rte_bsf32_safe"); + if (pos != shift) + FAIL("rte_bsf32_safe"); + } + + return 0; +} + +static int +test_misc(void) +{ + char memdump[] = "memdump_test"; + + 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 FAIL_ALIGN64(x, j, q)\ + {printf(x "() test failed: %"PRIu64" %"PRIu64"\n", j, q);\ + 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; + uint64_t j, q; + + 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 (i = 1, p = 1; i <= MAX_NUM; i++) { + if (rte_align32prevpow2(i) != p) + FAIL_ALIGN("rte_align32prevpow2", i, p); + if (rte_is_power_of_2(i + 1)) + p = i + 1; + } + + for (j = 1, q = 1; j <= MAX_NUM ; j++) { + if (rte_align64pow2(j) != q) + FAIL_ALIGN64("rte_align64pow2", j, q); + if (j == q) + q <<= 1; + } + + for (j = 1, q = 1; j <= MAX_NUM ; j++) { + if (rte_align64prevpow2(j) != q) + FAIL_ALIGN64("rte_align64prevpow2", j, q); + if (rte_is_power_of_2(j + 1)) + q = j + 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"); + } + } + + for (p = 1; p <= MAX_NUM / 2; p++) { + for (i = 1; i <= MAX_NUM / 2; i++) { + val = RTE_ALIGN_MUL_CEIL(i, p); + if (val % p != 0 || val < i) + FAIL_ALIGN("RTE_ALIGN_MUL_CEIL", i, p); + val = RTE_ALIGN_MUL_FLOOR(i, p); + if (val % p != 0 || val > i) + FAIL_ALIGN("RTE_ALIGN_MUL_FLOOR", i, p); + } + } + + return 0; +} + +static int +test_log2(void) +{ + uint32_t i, base, compare; + const uint32_t max = 0x10000; + const uint32_t step = 1; + + for (i = 0; i < max; i = i + step) { + uint64_t i64; + + /* extend range for 64-bit */ + i64 = (uint64_t)i << 32; + base = (uint32_t)ceilf(log2(i64)); + compare = rte_log2_u64(i64); + if (base != compare) { + printf("Wrong rte_log2_u64(%" PRIx64 ") val %x, expected %x\n", + i64, compare, base); + return TEST_FAILED; + } + + base = (uint32_t)ceilf(log2((uint32_t)i)); + compare = rte_log2_u32((uint32_t)i); + if (base != compare) { + printf("Wrong rte_log2_u32(%x) val %x, expected %x\n", + i, compare, base); + return TEST_FAILED; + } + compare = rte_log2_u64((uint64_t)i); + if (base != compare) { + printf("Wrong rte_log2_u64(%x) val %x, expected %x\n", + i, compare, base); + return TEST_FAILED; + } + } + return 0; +} + +static int +test_fls(void) +{ + struct fls_test_vector { + uint32_t arg; + int rc; + }; + int expected, rc; + uint32_t i, arg; + + const struct fls_test_vector test[] = { + {0x0, 0}, + {0x1, 1}, + {0x4000, 15}, + {0x80000000, 32}, + }; + + for (i = 0; i < RTE_DIM(test); i++) { + uint64_t arg64; + + arg = test[i].arg; + rc = rte_fls_u32(arg); + expected = test[i].rc; + if (rc != expected) { + printf("Wrong rte_fls_u32(0x%x) rc=%d, expected=%d\n", + arg, rc, expected); + return TEST_FAILED; + } + /* 64-bit version */ + arg = test[i].arg; + rc = rte_fls_u64(arg); + expected = test[i].rc; + if (rc != expected) { + printf("Wrong rte_fls_u64(0x%x) rc=%d, expected=%d\n", + arg, rc, expected); + return TEST_FAILED; + } + /* 64-bit version shifted by 32 bits */ + arg64 = (uint64_t)test[i].arg << 32; + rc = rte_fls_u64(arg64); + /* don't shift zero */ + expected = test[i].rc == 0 ? 0 : test[i].rc + 32; + if (rc != expected) { + printf("Wrong rte_fls_u64(0x%" PRIx64 ") rc=%d, expected=%d\n", + arg64, rc, expected); + return TEST_FAILED; + } + } + + return 0; +} + +static int +test_common(void) +{ + int ret = 0; + ret |= test_align(); + ret |= test_macros(0); + ret |= test_misc(); + ret |= test_bsf(); + ret |= test_log2(); + ret |= test_fls(); + + return ret; +} + +REGISTER_TEST_COMMAND(common_autotest, test_common); diff --git a/app/test/test_compressdev.c b/app/test/test_compressdev.c new file mode 100644 index 0000000000..e8476edd29 --- /dev/null +++ b/app/test/test_compressdev.c @@ -0,0 +1,1940 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test_compressdev_test_buffer.h" +#include "test.h" + +#define DIV_CEIL(a, b) ((a) / (b) + ((a) % (b) != 0)) + +#define DEFAULT_WINDOW_SIZE 15 +#define DEFAULT_MEM_LEVEL 8 +#define MAX_DEQD_RETRIES 10 +#define DEQUEUE_WAIT_TIME 10000 + +/* + * 30% extra size for compressed data compared to original data, + * in case data size cannot be reduced and it is actually bigger + * due to the compress block headers + */ +#define COMPRESS_BUF_SIZE_RATIO 1.3 +#define NUM_LARGE_MBUFS 16 +#define SMALL_SEG_SIZE 256 +#define MAX_SEGS 16 +#define NUM_OPS 16 +#define NUM_MAX_XFORMS 16 +#define NUM_MAX_INFLIGHT_OPS 128 +#define CACHE_SIZE 0 + +#define ZLIB_CRC_CHECKSUM_WINDOW_BITS 31 +#define ZLIB_HEADER_SIZE 2 +#define ZLIB_TRAILER_SIZE 4 +#define GZIP_HEADER_SIZE 10 +#define GZIP_TRAILER_SIZE 8 + +#define OUT_OF_SPACE_BUF 1 + +const char * +huffman_type_strings[] = { + [RTE_COMP_HUFFMAN_DEFAULT] = "PMD default", + [RTE_COMP_HUFFMAN_FIXED] = "Fixed", + [RTE_COMP_HUFFMAN_DYNAMIC] = "Dynamic" +}; + +enum zlib_direction { + ZLIB_NONE, + ZLIB_COMPRESS, + ZLIB_DECOMPRESS, + ZLIB_ALL +}; + +enum varied_buff { + LB_BOTH = 0, /* both input and output are linear*/ + SGL_BOTH, /* both input and output are chained */ + SGL_TO_LB, /* input buffer is chained */ + LB_TO_SGL /* output buffer is chained */ +}; + +struct priv_op_data { + uint16_t orig_idx; +}; + +struct comp_testsuite_params { + struct rte_mempool *large_mbuf_pool; + struct rte_mempool *small_mbuf_pool; + struct rte_mempool *op_pool; + struct rte_comp_xform *def_comp_xform; + struct rte_comp_xform *def_decomp_xform; +}; + +struct interim_data_params { + const char * const *test_bufs; + unsigned int num_bufs; + uint16_t *buf_idx; + struct rte_comp_xform **compress_xforms; + struct rte_comp_xform **decompress_xforms; + unsigned int num_xforms; +}; + +struct test_data_params { + enum rte_comp_op_type state; + enum varied_buff buff_type; + enum zlib_direction zlib_dir; + unsigned int out_of_space; +}; + +static struct comp_testsuite_params testsuite_params = { 0 }; + +static void +testsuite_teardown(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + + if (rte_mempool_in_use_count(ts_params->large_mbuf_pool)) + RTE_LOG(ERR, USER1, "Large mbuf pool still has unfreed bufs\n"); + if (rte_mempool_in_use_count(ts_params->small_mbuf_pool)) + RTE_LOG(ERR, USER1, "Small mbuf pool still has unfreed bufs\n"); + if (rte_mempool_in_use_count(ts_params->op_pool)) + RTE_LOG(ERR, USER1, "op pool still has unfreed ops\n"); + + rte_mempool_free(ts_params->large_mbuf_pool); + rte_mempool_free(ts_params->small_mbuf_pool); + rte_mempool_free(ts_params->op_pool); + rte_free(ts_params->def_comp_xform); + rte_free(ts_params->def_decomp_xform); +} + +static int +testsuite_setup(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint32_t max_buf_size = 0; + unsigned int i; + + if (rte_compressdev_count() == 0) { + RTE_LOG(ERR, USER1, "Need at least one compress device\n"); + return TEST_FAILED; + } + + RTE_LOG(NOTICE, USER1, "Running tests on device %s\n", + rte_compressdev_name_get(0)); + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) + max_buf_size = RTE_MAX(max_buf_size, + strlen(compress_test_bufs[i]) + 1); + + /* + * Buffers to be used in compression and decompression. + * Since decompressed data might be larger than + * compressed data (due to block header), + * buffers should be big enough for both cases. + */ + max_buf_size *= COMPRESS_BUF_SIZE_RATIO; + ts_params->large_mbuf_pool = rte_pktmbuf_pool_create("large_mbuf_pool", + NUM_LARGE_MBUFS, + CACHE_SIZE, 0, + max_buf_size + RTE_PKTMBUF_HEADROOM, + rte_socket_id()); + if (ts_params->large_mbuf_pool == NULL) { + RTE_LOG(ERR, USER1, "Large mbuf pool could not be created\n"); + return TEST_FAILED; + } + + /* Create mempool with smaller buffers for SGL testing */ + ts_params->small_mbuf_pool = rte_pktmbuf_pool_create("small_mbuf_pool", + NUM_LARGE_MBUFS * MAX_SEGS, + CACHE_SIZE, 0, + SMALL_SEG_SIZE + RTE_PKTMBUF_HEADROOM, + rte_socket_id()); + if (ts_params->small_mbuf_pool == NULL) { + RTE_LOG(ERR, USER1, "Small mbuf pool could not be created\n"); + goto exit; + } + + ts_params->op_pool = rte_comp_op_pool_create("op_pool", NUM_OPS, + 0, sizeof(struct priv_op_data), + rte_socket_id()); + if (ts_params->op_pool == NULL) { + RTE_LOG(ERR, USER1, "Operation pool could not be created\n"); + goto exit; + } + + ts_params->def_comp_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + if (ts_params->def_comp_xform == NULL) { + RTE_LOG(ERR, USER1, + "Default compress xform could not be created\n"); + goto exit; + } + ts_params->def_decomp_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + if (ts_params->def_decomp_xform == NULL) { + RTE_LOG(ERR, USER1, + "Default decompress xform could not be created\n"); + goto exit; + } + + /* Initializes default values for compress/decompress xforms */ + ts_params->def_comp_xform->type = RTE_COMP_COMPRESS; + ts_params->def_comp_xform->compress.algo = RTE_COMP_ALGO_DEFLATE, + ts_params->def_comp_xform->compress.deflate.huffman = + RTE_COMP_HUFFMAN_DEFAULT; + ts_params->def_comp_xform->compress.level = RTE_COMP_LEVEL_PMD_DEFAULT; + ts_params->def_comp_xform->compress.chksum = RTE_COMP_CHECKSUM_NONE; + ts_params->def_comp_xform->compress.window_size = DEFAULT_WINDOW_SIZE; + + ts_params->def_decomp_xform->type = RTE_COMP_DECOMPRESS; + ts_params->def_decomp_xform->decompress.algo = RTE_COMP_ALGO_DEFLATE, + ts_params->def_decomp_xform->decompress.chksum = RTE_COMP_CHECKSUM_NONE; + ts_params->def_decomp_xform->decompress.window_size = DEFAULT_WINDOW_SIZE; + + return TEST_SUCCESS; + +exit: + testsuite_teardown(); + + return TEST_FAILED; +} + +static int +generic_ut_setup(void) +{ + /* Configure compressdev (one device, one queue pair) */ + struct rte_compressdev_config config = { + .socket_id = rte_socket_id(), + .nb_queue_pairs = 1, + .max_nb_priv_xforms = NUM_MAX_XFORMS, + .max_nb_streams = 0 + }; + + if (rte_compressdev_configure(0, &config) < 0) { + RTE_LOG(ERR, USER1, "Device configuration failed\n"); + return -1; + } + + if (rte_compressdev_queue_pair_setup(0, 0, NUM_MAX_INFLIGHT_OPS, + rte_socket_id()) < 0) { + RTE_LOG(ERR, USER1, "Queue pair setup failed\n"); + return -1; + } + + if (rte_compressdev_start(0) < 0) { + RTE_LOG(ERR, USER1, "Device could not be started\n"); + return -1; + } + + return 0; +} + +static void +generic_ut_teardown(void) +{ + rte_compressdev_stop(0); + if (rte_compressdev_close(0) < 0) + RTE_LOG(ERR, USER1, "Device could not be closed\n"); +} + +static int +test_compressdev_invalid_configuration(void) +{ + struct rte_compressdev_config invalid_config; + struct rte_compressdev_config valid_config = { + .socket_id = rte_socket_id(), + .nb_queue_pairs = 1, + .max_nb_priv_xforms = NUM_MAX_XFORMS, + .max_nb_streams = 0 + }; + struct rte_compressdev_info dev_info; + + /* Invalid configuration with 0 queue pairs */ + memcpy(&invalid_config, &valid_config, + sizeof(struct rte_compressdev_config)); + invalid_config.nb_queue_pairs = 0; + + TEST_ASSERT_FAIL(rte_compressdev_configure(0, &invalid_config), + "Device configuration was successful " + "with no queue pairs (invalid)\n"); + + /* + * Invalid configuration with too many queue pairs + * (if there is an actual maximum number of queue pairs) + */ + rte_compressdev_info_get(0, &dev_info); + if (dev_info.max_nb_queue_pairs != 0) { + memcpy(&invalid_config, &valid_config, + sizeof(struct rte_compressdev_config)); + invalid_config.nb_queue_pairs = dev_info.max_nb_queue_pairs + 1; + + TEST_ASSERT_FAIL(rte_compressdev_configure(0, &invalid_config), + "Device configuration was successful " + "with too many queue pairs (invalid)\n"); + } + + /* Invalid queue pair setup, with no number of queue pairs set */ + TEST_ASSERT_FAIL(rte_compressdev_queue_pair_setup(0, 0, + NUM_MAX_INFLIGHT_OPS, rte_socket_id()), + "Queue pair setup was successful " + "with no queue pairs set (invalid)\n"); + + return TEST_SUCCESS; +} + +static int +compare_buffers(const char *buffer1, uint32_t buffer1_len, + const char *buffer2, uint32_t buffer2_len) +{ + if (buffer1_len != buffer2_len) { + RTE_LOG(ERR, USER1, "Buffer lengths are different\n"); + return -1; + } + + if (memcmp(buffer1, buffer2, buffer1_len) != 0) { + RTE_LOG(ERR, USER1, "Buffers are different\n"); + return -1; + } + + return 0; +} + +/* + * Maps compressdev and Zlib flush flags + */ +static int +map_zlib_flush_flag(enum rte_comp_flush_flag flag) +{ + switch (flag) { + case RTE_COMP_FLUSH_NONE: + return Z_NO_FLUSH; + case RTE_COMP_FLUSH_SYNC: + return Z_SYNC_FLUSH; + case RTE_COMP_FLUSH_FULL: + return Z_FULL_FLUSH; + case RTE_COMP_FLUSH_FINAL: + return Z_FINISH; + /* + * There should be only the values above, + * so this should never happen + */ + default: + return -1; + } +} + +static int +compress_zlib(struct rte_comp_op *op, + const struct rte_comp_xform *xform, int mem_level) +{ + z_stream stream; + int zlib_flush; + int strategy, window_bits, comp_level; + int ret = TEST_FAILED; + uint8_t *single_src_buf = NULL; + uint8_t *single_dst_buf = NULL; + + /* initialize zlib stream */ + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + + if (xform->compress.deflate.huffman == RTE_COMP_HUFFMAN_FIXED) + strategy = Z_FIXED; + else + strategy = Z_DEFAULT_STRATEGY; + + /* + * Window bits is the base two logarithm of the window size (in bytes). + * When doing raw DEFLATE, this number will be negative. + */ + window_bits = -(xform->compress.window_size); + if (xform->compress.chksum == RTE_COMP_CHECKSUM_ADLER32) + window_bits *= -1; + else if (xform->compress.chksum == RTE_COMP_CHECKSUM_CRC32) + window_bits = ZLIB_CRC_CHECKSUM_WINDOW_BITS; + + comp_level = xform->compress.level; + + if (comp_level != RTE_COMP_LEVEL_NONE) + ret = deflateInit2(&stream, comp_level, Z_DEFLATED, + window_bits, mem_level, strategy); + else + ret = deflateInit(&stream, Z_NO_COMPRESSION); + + if (ret != Z_OK) { + printf("Zlib deflate could not be initialized\n"); + goto exit; + } + + /* Assuming stateless operation */ + /* SGL Input */ + if (op->m_src->nb_segs > 1) { + single_src_buf = rte_malloc(NULL, + rte_pktmbuf_pkt_len(op->m_src), 0); + if (single_src_buf == NULL) { + RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); + goto exit; + } + + if (rte_pktmbuf_read(op->m_src, op->src.offset, + rte_pktmbuf_pkt_len(op->m_src) - + op->src.offset, + single_src_buf) == NULL) { + RTE_LOG(ERR, USER1, + "Buffer could not be read entirely\n"); + goto exit; + } + + stream.avail_in = op->src.length; + stream.next_in = single_src_buf; + + } else { + stream.avail_in = op->src.length; + stream.next_in = rte_pktmbuf_mtod_offset(op->m_src, uint8_t *, + op->src.offset); + } + /* SGL output */ + if (op->m_dst->nb_segs > 1) { + + single_dst_buf = rte_malloc(NULL, + rte_pktmbuf_pkt_len(op->m_dst), 0); + if (single_dst_buf == NULL) { + RTE_LOG(ERR, USER1, + "Buffer could not be allocated\n"); + goto exit; + } + + stream.avail_out = op->m_dst->pkt_len; + stream.next_out = single_dst_buf; + + } else {/* linear output */ + stream.avail_out = op->m_dst->data_len; + stream.next_out = rte_pktmbuf_mtod_offset(op->m_dst, uint8_t *, + op->dst.offset); + } + + /* Stateless operation, all buffer will be compressed in one go */ + zlib_flush = map_zlib_flush_flag(op->flush_flag); + ret = deflate(&stream, zlib_flush); + + if (stream.avail_in != 0) { + RTE_LOG(ERR, USER1, "Buffer could not be read entirely\n"); + goto exit; + } + + if (ret != Z_STREAM_END) + goto exit; + + /* Copy data to destination SGL */ + if (op->m_dst->nb_segs > 1) { + uint32_t remaining_data = stream.total_out; + uint8_t *src_data = single_dst_buf; + struct rte_mbuf *dst_buf = op->m_dst; + + while (remaining_data > 0) { + uint8_t *dst_data = rte_pktmbuf_mtod_offset(dst_buf, + uint8_t *, op->dst.offset); + /* Last segment */ + if (remaining_data < dst_buf->data_len) { + memcpy(dst_data, src_data, remaining_data); + remaining_data = 0; + } else { + memcpy(dst_data, src_data, dst_buf->data_len); + remaining_data -= dst_buf->data_len; + src_data += dst_buf->data_len; + dst_buf = dst_buf->next; + } + } + } + + op->consumed = stream.total_in; + if (xform->compress.chksum == RTE_COMP_CHECKSUM_ADLER32) { + rte_pktmbuf_adj(op->m_dst, ZLIB_HEADER_SIZE); + rte_pktmbuf_trim(op->m_dst, ZLIB_TRAILER_SIZE); + op->produced = stream.total_out - (ZLIB_HEADER_SIZE + + ZLIB_TRAILER_SIZE); + } else if (xform->compress.chksum == RTE_COMP_CHECKSUM_CRC32) { + rte_pktmbuf_adj(op->m_dst, GZIP_HEADER_SIZE); + rte_pktmbuf_trim(op->m_dst, GZIP_TRAILER_SIZE); + op->produced = stream.total_out - (GZIP_HEADER_SIZE + + GZIP_TRAILER_SIZE); + } else + op->produced = stream.total_out; + + op->status = RTE_COMP_OP_STATUS_SUCCESS; + op->output_chksum = stream.adler; + + deflateReset(&stream); + + ret = 0; +exit: + deflateEnd(&stream); + rte_free(single_src_buf); + rte_free(single_dst_buf); + + return ret; +} + +static int +decompress_zlib(struct rte_comp_op *op, + const struct rte_comp_xform *xform) +{ + z_stream stream; + int window_bits; + int zlib_flush; + int ret = TEST_FAILED; + uint8_t *single_src_buf = NULL; + uint8_t *single_dst_buf = NULL; + + /* initialize zlib stream */ + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + + /* + * Window bits is the base two logarithm of the window size (in bytes). + * When doing raw DEFLATE, this number will be negative. + */ + window_bits = -(xform->decompress.window_size); + ret = inflateInit2(&stream, window_bits); + + if (ret != Z_OK) { + printf("Zlib deflate could not be initialized\n"); + goto exit; + } + + /* Assuming stateless operation */ + /* SGL */ + if (op->m_src->nb_segs > 1) { + single_src_buf = rte_malloc(NULL, + rte_pktmbuf_pkt_len(op->m_src), 0); + if (single_src_buf == NULL) { + RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); + goto exit; + } + single_dst_buf = rte_malloc(NULL, + rte_pktmbuf_pkt_len(op->m_dst), 0); + if (single_dst_buf == NULL) { + RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); + goto exit; + } + if (rte_pktmbuf_read(op->m_src, 0, + rte_pktmbuf_pkt_len(op->m_src), + single_src_buf) == NULL) { + RTE_LOG(ERR, USER1, + "Buffer could not be read entirely\n"); + goto exit; + } + + stream.avail_in = op->src.length; + stream.next_in = single_src_buf; + stream.avail_out = rte_pktmbuf_pkt_len(op->m_dst); + stream.next_out = single_dst_buf; + + } else { + stream.avail_in = op->src.length; + stream.next_in = rte_pktmbuf_mtod(op->m_src, uint8_t *); + stream.avail_out = op->m_dst->data_len; + stream.next_out = rte_pktmbuf_mtod(op->m_dst, uint8_t *); + } + + /* Stateless operation, all buffer will be compressed in one go */ + zlib_flush = map_zlib_flush_flag(op->flush_flag); + ret = inflate(&stream, zlib_flush); + + if (stream.avail_in != 0) { + RTE_LOG(ERR, USER1, "Buffer could not be read entirely\n"); + goto exit; + } + + if (ret != Z_STREAM_END) + goto exit; + + if (op->m_src->nb_segs > 1) { + uint32_t remaining_data = stream.total_out; + uint8_t *src_data = single_dst_buf; + struct rte_mbuf *dst_buf = op->m_dst; + + while (remaining_data > 0) { + uint8_t *dst_data = rte_pktmbuf_mtod(dst_buf, + uint8_t *); + /* Last segment */ + if (remaining_data < dst_buf->data_len) { + memcpy(dst_data, src_data, remaining_data); + remaining_data = 0; + } else { + memcpy(dst_data, src_data, dst_buf->data_len); + remaining_data -= dst_buf->data_len; + src_data += dst_buf->data_len; + dst_buf = dst_buf->next; + } + } + } + + op->consumed = stream.total_in; + op->produced = stream.total_out; + op->status = RTE_COMP_OP_STATUS_SUCCESS; + + inflateReset(&stream); + + ret = 0; +exit: + inflateEnd(&stream); + + return ret; +} + +static int +prepare_sgl_bufs(const char *test_buf, struct rte_mbuf *head_buf, + uint32_t total_data_size, + struct rte_mempool *small_mbuf_pool, + struct rte_mempool *large_mbuf_pool, + uint8_t limit_segs_in_sgl) +{ + uint32_t remaining_data = total_data_size; + uint16_t num_remaining_segs = DIV_CEIL(remaining_data, SMALL_SEG_SIZE); + struct rte_mempool *pool; + struct rte_mbuf *next_seg; + uint32_t data_size; + char *buf_ptr; + const char *data_ptr = test_buf; + uint16_t i; + int ret; + + if (limit_segs_in_sgl != 0 && num_remaining_segs > limit_segs_in_sgl) + num_remaining_segs = limit_segs_in_sgl - 1; + + /* + * Allocate data in the first segment (header) and + * copy data if test buffer is provided + */ + if (remaining_data < SMALL_SEG_SIZE) + data_size = remaining_data; + else + data_size = SMALL_SEG_SIZE; + buf_ptr = rte_pktmbuf_append(head_buf, data_size); + if (buf_ptr == NULL) { + RTE_LOG(ERR, USER1, + "Not enough space in the 1st buffer\n"); + return -1; + } + + if (data_ptr != NULL) { + /* Copy characters without NULL terminator */ + strncpy(buf_ptr, data_ptr, data_size); + data_ptr += data_size; + } + remaining_data -= data_size; + num_remaining_segs--; + + /* + * Allocate the rest of the segments, + * copy the rest of the data and chain the segments. + */ + for (i = 0; i < num_remaining_segs; i++) { + + if (i == (num_remaining_segs - 1)) { + /* last segment */ + if (remaining_data > SMALL_SEG_SIZE) + pool = large_mbuf_pool; + else + pool = small_mbuf_pool; + data_size = remaining_data; + } else { + data_size = SMALL_SEG_SIZE; + pool = small_mbuf_pool; + } + + next_seg = rte_pktmbuf_alloc(pool); + if (next_seg == NULL) { + RTE_LOG(ERR, USER1, + "New segment could not be allocated " + "from the mempool\n"); + return -1; + } + buf_ptr = rte_pktmbuf_append(next_seg, data_size); + if (buf_ptr == NULL) { + RTE_LOG(ERR, USER1, + "Not enough space in the buffer\n"); + rte_pktmbuf_free(next_seg); + return -1; + } + if (data_ptr != NULL) { + /* Copy characters without NULL terminator */ + strncpy(buf_ptr, data_ptr, data_size); + data_ptr += data_size; + } + remaining_data -= data_size; + + ret = rte_pktmbuf_chain(head_buf, next_seg); + if (ret != 0) { + rte_pktmbuf_free(next_seg); + RTE_LOG(ERR, USER1, + "Segment could not chained\n"); + return -1; + } + } + + return 0; +} + +/* + * Compresses and decompresses buffer with compressdev API and Zlib API + */ +static int +test_deflate_comp_decomp(const struct interim_data_params *int_data, + const struct test_data_params *test_data) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + const char * const *test_bufs = int_data->test_bufs; + unsigned int num_bufs = int_data->num_bufs; + uint16_t *buf_idx = int_data->buf_idx; + struct rte_comp_xform **compress_xforms = int_data->compress_xforms; + struct rte_comp_xform **decompress_xforms = int_data->decompress_xforms; + unsigned int num_xforms = int_data->num_xforms; + enum rte_comp_op_type state = test_data->state; + unsigned int buff_type = test_data->buff_type; + unsigned int out_of_space = test_data->out_of_space; + enum zlib_direction zlib_dir = test_data->zlib_dir; + int ret_status = -1; + int ret; + struct rte_mbuf *uncomp_bufs[num_bufs]; + struct rte_mbuf *comp_bufs[num_bufs]; + struct rte_comp_op *ops[num_bufs]; + struct rte_comp_op *ops_processed[num_bufs]; + void *priv_xforms[num_bufs]; + uint16_t num_enqd, num_deqd, num_total_deqd; + uint16_t num_priv_xforms = 0; + unsigned int deqd_retries = 0; + struct priv_op_data *priv_data; + char *buf_ptr; + unsigned int i; + struct rte_mempool *buf_pool; + uint32_t data_size; + /* Compressing with CompressDev */ + unsigned int oos_zlib_decompress = + (zlib_dir == ZLIB_NONE || zlib_dir == ZLIB_DECOMPRESS); + /* Decompressing with CompressDev */ + unsigned int oos_zlib_compress = + (zlib_dir == ZLIB_NONE || zlib_dir == ZLIB_COMPRESS); + const struct rte_compressdev_capabilities *capa = + rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + char *contig_buf = NULL; + uint64_t compress_checksum[num_bufs]; + + /* Initialize all arrays to NULL */ + memset(uncomp_bufs, 0, sizeof(struct rte_mbuf *) * num_bufs); + memset(comp_bufs, 0, sizeof(struct rte_mbuf *) * num_bufs); + memset(ops, 0, sizeof(struct rte_comp_op *) * num_bufs); + memset(ops_processed, 0, sizeof(struct rte_comp_op *) * num_bufs); + memset(priv_xforms, 0, sizeof(void *) * num_bufs); + + if (buff_type == SGL_BOTH) + buf_pool = ts_params->small_mbuf_pool; + else + buf_pool = ts_params->large_mbuf_pool; + + /* Prepare the source mbufs with the data */ + ret = rte_pktmbuf_alloc_bulk(buf_pool, + uncomp_bufs, num_bufs); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Source mbufs could not be allocated " + "from the mempool\n"); + goto exit; + } + + if (buff_type == SGL_BOTH || buff_type == SGL_TO_LB) { + for (i = 0; i < num_bufs; i++) { + data_size = strlen(test_bufs[i]) + 1; + if (prepare_sgl_bufs(test_bufs[i], uncomp_bufs[i], + data_size, + ts_params->small_mbuf_pool, + ts_params->large_mbuf_pool, + MAX_SEGS) < 0) + goto exit; + } + } else { + for (i = 0; i < num_bufs; i++) { + data_size = strlen(test_bufs[i]) + 1; + buf_ptr = rte_pktmbuf_append(uncomp_bufs[i], data_size); + snprintf(buf_ptr, data_size, "%s", test_bufs[i]); + } + } + + /* Prepare the destination mbufs */ + ret = rte_pktmbuf_alloc_bulk(buf_pool, comp_bufs, num_bufs); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Destination mbufs could not be allocated " + "from the mempool\n"); + goto exit; + } + + if (buff_type == SGL_BOTH || buff_type == LB_TO_SGL) { + for (i = 0; i < num_bufs; i++) { + if (out_of_space == 1 && oos_zlib_decompress) + data_size = OUT_OF_SPACE_BUF; + else + (data_size = strlen(test_bufs[i]) * + COMPRESS_BUF_SIZE_RATIO); + + if (prepare_sgl_bufs(NULL, comp_bufs[i], + data_size, + ts_params->small_mbuf_pool, + ts_params->large_mbuf_pool, + MAX_SEGS) < 0) + goto exit; + } + + } else { + for (i = 0; i < num_bufs; i++) { + if (out_of_space == 1 && oos_zlib_decompress) + data_size = OUT_OF_SPACE_BUF; + else + (data_size = strlen(test_bufs[i]) * + COMPRESS_BUF_SIZE_RATIO); + + rte_pktmbuf_append(comp_bufs[i], data_size); + } + } + + /* Build the compression operations */ + ret = rte_comp_op_bulk_alloc(ts_params->op_pool, ops, num_bufs); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Compress operations could not be allocated " + "from the mempool\n"); + goto exit; + } + + + for (i = 0; i < num_bufs; i++) { + ops[i]->m_src = uncomp_bufs[i]; + ops[i]->m_dst = comp_bufs[i]; + ops[i]->src.offset = 0; + ops[i]->src.length = rte_pktmbuf_pkt_len(uncomp_bufs[i]); + ops[i]->dst.offset = 0; + if (state == RTE_COMP_OP_STATELESS) { + ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL; + } else { + RTE_LOG(ERR, USER1, + "Stateful operations are not supported " + "in these tests yet\n"); + goto exit; + } + ops[i]->input_chksum = 0; + /* + * Store original operation index in private data, + * since ordering does not have to be maintained, + * when dequeueing from compressdev, so a comparison + * at the end of the test can be done. + */ + priv_data = (struct priv_op_data *) (ops[i] + 1); + priv_data->orig_idx = i; + } + + /* Compress data (either with Zlib API or compressdev API */ + if (zlib_dir == ZLIB_COMPRESS || zlib_dir == ZLIB_ALL) { + for (i = 0; i < num_bufs; i++) { + const struct rte_comp_xform *compress_xform = + compress_xforms[i % num_xforms]; + ret = compress_zlib(ops[i], compress_xform, + DEFAULT_MEM_LEVEL); + if (ret < 0) + goto exit; + + ops_processed[i] = ops[i]; + } + } else { + /* Create compress private xform data */ + for (i = 0; i < num_xforms; i++) { + ret = rte_compressdev_private_xform_create(0, + (const struct rte_comp_xform *)compress_xforms[i], + &priv_xforms[i]); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Compression private xform " + "could not be created\n"); + goto exit; + } + num_priv_xforms++; + } + + if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) { + /* Attach shareable private xform data to ops */ + for (i = 0; i < num_bufs; i++) + ops[i]->private_xform = priv_xforms[i % num_xforms]; + } else { + /* Create rest of the private xforms for the other ops */ + for (i = num_xforms; i < num_bufs; i++) { + ret = rte_compressdev_private_xform_create(0, + compress_xforms[i % num_xforms], + &priv_xforms[i]); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Compression private xform " + "could not be created\n"); + goto exit; + } + num_priv_xforms++; + } + + /* Attach non shareable private xform data to ops */ + for (i = 0; i < num_bufs; i++) + ops[i]->private_xform = priv_xforms[i]; + } + + /* Enqueue and dequeue all operations */ + num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs); + if (num_enqd < num_bufs) { + RTE_LOG(ERR, USER1, + "The operations could not be enqueued\n"); + goto exit; + } + + num_total_deqd = 0; + do { + /* + * If retrying a dequeue call, wait for 10 ms to allow + * enough time to the driver to process the operations + */ + if (deqd_retries != 0) { + /* + * Avoid infinite loop if not all the + * operations get out of the device + */ + if (deqd_retries == MAX_DEQD_RETRIES) { + RTE_LOG(ERR, USER1, + "Not all operations could be " + "dequeued\n"); + goto exit; + } + usleep(DEQUEUE_WAIT_TIME); + } + num_deqd = rte_compressdev_dequeue_burst(0, 0, + &ops_processed[num_total_deqd], num_bufs); + num_total_deqd += num_deqd; + deqd_retries++; + + } while (num_total_deqd < num_enqd); + + deqd_retries = 0; + + /* Free compress private xforms */ + for (i = 0; i < num_priv_xforms; i++) { + rte_compressdev_private_xform_free(0, priv_xforms[i]); + priv_xforms[i] = NULL; + } + num_priv_xforms = 0; + } + + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + uint16_t xform_idx = priv_data->orig_idx % num_xforms; + const struct rte_comp_compress_xform *compress_xform = + &compress_xforms[xform_idx]->compress; + enum rte_comp_huffman huffman_type = + compress_xform->deflate.huffman; + char engine[] = "zlib (directly, not PMD)"; + if (zlib_dir != ZLIB_COMPRESS || zlib_dir != ZLIB_ALL) + strlcpy(engine, "PMD", sizeof(engine)); + + RTE_LOG(DEBUG, USER1, "Buffer %u compressed by %s from %u to" + " %u bytes (level = %d, huffman = %s)\n", + buf_idx[priv_data->orig_idx], engine, + ops_processed[i]->consumed, ops_processed[i]->produced, + compress_xform->level, + huffman_type_strings[huffman_type]); + RTE_LOG(DEBUG, USER1, "Compression ratio = %.2f\n", + ops_processed[i]->consumed == 0 ? 0 : + (float)ops_processed[i]->produced / + ops_processed[i]->consumed * 100); + if (compress_xform->chksum != RTE_COMP_CHECKSUM_NONE) + compress_checksum[i] = ops_processed[i]->output_chksum; + ops[i] = NULL; + } + + /* + * Check operation status and free source mbufs (destination mbuf and + * compress operation information is needed for the decompression stage) + */ + for (i = 0; i < num_bufs; i++) { + if (out_of_space && oos_zlib_decompress) { + if (ops_processed[i]->status != + RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED) { + ret_status = -1; + + RTE_LOG(ERR, USER1, + "Operation without expected out of " + "space status error\n"); + goto exit; + } else + continue; + } + + if (ops_processed[i]->status != RTE_COMP_OP_STATUS_SUCCESS) { + RTE_LOG(ERR, USER1, + "Some operations were not successful\n"); + goto exit; + } + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + rte_pktmbuf_free(uncomp_bufs[priv_data->orig_idx]); + uncomp_bufs[priv_data->orig_idx] = NULL; + } + + if (out_of_space && oos_zlib_decompress) { + ret_status = 0; + goto exit; + } + + /* Allocate buffers for decompressed data */ + ret = rte_pktmbuf_alloc_bulk(buf_pool, uncomp_bufs, num_bufs); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Destination mbufs could not be allocated " + "from the mempool\n"); + goto exit; + } + + if (buff_type == SGL_BOTH || buff_type == LB_TO_SGL) { + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *) + (ops_processed[i] + 1); + if (out_of_space == 1 && oos_zlib_compress) + data_size = OUT_OF_SPACE_BUF; + else + data_size = + strlen(test_bufs[priv_data->orig_idx]) + 1; + + if (prepare_sgl_bufs(NULL, uncomp_bufs[i], + data_size, + ts_params->small_mbuf_pool, + ts_params->large_mbuf_pool, + MAX_SEGS) < 0) + goto exit; + } + + } else { + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *) + (ops_processed[i] + 1); + if (out_of_space == 1 && oos_zlib_compress) + data_size = OUT_OF_SPACE_BUF; + else + data_size = + strlen(test_bufs[priv_data->orig_idx]) + 1; + + rte_pktmbuf_append(uncomp_bufs[i], data_size); + } + } + + /* Build the decompression operations */ + ret = rte_comp_op_bulk_alloc(ts_params->op_pool, ops, num_bufs); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Decompress operations could not be allocated " + "from the mempool\n"); + goto exit; + } + + /* Source buffer is the compressed data from the previous operations */ + for (i = 0; i < num_bufs; i++) { + ops[i]->m_src = ops_processed[i]->m_dst; + ops[i]->m_dst = uncomp_bufs[i]; + ops[i]->src.offset = 0; + /* + * Set the length of the compressed data to the + * number of bytes that were produced in the previous stage + */ + ops[i]->src.length = ops_processed[i]->produced; + ops[i]->dst.offset = 0; + if (state == RTE_COMP_OP_STATELESS) { + ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL; + } else { + RTE_LOG(ERR, USER1, + "Stateful operations are not supported " + "in these tests yet\n"); + goto exit; + } + ops[i]->input_chksum = 0; + /* + * Copy private data from previous operations, + * to keep the pointer to the original buffer + */ + memcpy(ops[i] + 1, ops_processed[i] + 1, + sizeof(struct priv_op_data)); + } + + /* + * Free the previous compress operations, + * as they are not needed anymore + */ + rte_comp_op_bulk_free(ops_processed, num_bufs); + + /* Decompress data (either with Zlib API or compressdev API */ + if (zlib_dir == ZLIB_DECOMPRESS || zlib_dir == ZLIB_ALL) { + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops[i] + 1); + uint16_t xform_idx = priv_data->orig_idx % num_xforms; + const struct rte_comp_xform *decompress_xform = + decompress_xforms[xform_idx]; + + ret = decompress_zlib(ops[i], decompress_xform); + if (ret < 0) + goto exit; + + ops_processed[i] = ops[i]; + } + } else { + /* Create decompress private xform data */ + for (i = 0; i < num_xforms; i++) { + ret = rte_compressdev_private_xform_create(0, + (const struct rte_comp_xform *)decompress_xforms[i], + &priv_xforms[i]); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Decompression private xform " + "could not be created\n"); + goto exit; + } + num_priv_xforms++; + } + + if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) { + /* Attach shareable private xform data to ops */ + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops[i] + 1); + uint16_t xform_idx = priv_data->orig_idx % + num_xforms; + ops[i]->private_xform = priv_xforms[xform_idx]; + } + } else { + /* Create rest of the private xforms for the other ops */ + for (i = num_xforms; i < num_bufs; i++) { + ret = rte_compressdev_private_xform_create(0, + decompress_xforms[i % num_xforms], + &priv_xforms[i]); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Decompression private xform " + "could not be created\n"); + goto exit; + } + num_priv_xforms++; + } + + /* Attach non shareable private xform data to ops */ + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops[i] + 1); + uint16_t xform_idx = priv_data->orig_idx; + ops[i]->private_xform = priv_xforms[xform_idx]; + } + } + + /* Enqueue and dequeue all operations */ + num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs); + if (num_enqd < num_bufs) { + RTE_LOG(ERR, USER1, + "The operations could not be enqueued\n"); + goto exit; + } + + num_total_deqd = 0; + do { + /* + * If retrying a dequeue call, wait for 10 ms to allow + * enough time to the driver to process the operations + */ + if (deqd_retries != 0) { + /* + * Avoid infinite loop if not all the + * operations get out of the device + */ + if (deqd_retries == MAX_DEQD_RETRIES) { + RTE_LOG(ERR, USER1, + "Not all operations could be " + "dequeued\n"); + goto exit; + } + usleep(DEQUEUE_WAIT_TIME); + } + num_deqd = rte_compressdev_dequeue_burst(0, 0, + &ops_processed[num_total_deqd], num_bufs); + num_total_deqd += num_deqd; + deqd_retries++; + } while (num_total_deqd < num_enqd); + + deqd_retries = 0; + } + + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + char engine[] = "zlib, (directly, no PMD)"; + if (zlib_dir != ZLIB_DECOMPRESS || zlib_dir != ZLIB_ALL) + strlcpy(engine, "pmd", sizeof(engine)); + RTE_LOG(DEBUG, USER1, + "Buffer %u decompressed by %s from %u to %u bytes\n", + buf_idx[priv_data->orig_idx], engine, + ops_processed[i]->consumed, ops_processed[i]->produced); + ops[i] = NULL; + } + + /* + * Check operation status and free source mbuf (destination mbuf and + * compress operation information is still needed) + */ + for (i = 0; i < num_bufs; i++) { + if (out_of_space && oos_zlib_compress) { + if (ops_processed[i]->status != + RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED) { + ret_status = -1; + + RTE_LOG(ERR, USER1, + "Operation without expected out of " + "space status error\n"); + goto exit; + } else + continue; + } + + if (ops_processed[i]->status != RTE_COMP_OP_STATUS_SUCCESS) { + RTE_LOG(ERR, USER1, + "Some operations were not successful\n"); + goto exit; + } + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + rte_pktmbuf_free(comp_bufs[priv_data->orig_idx]); + comp_bufs[priv_data->orig_idx] = NULL; + } + + if (out_of_space && oos_zlib_compress) { + ret_status = 0; + goto exit; + } + + /* + * Compare the original stream with the decompressed stream + * (in size and the data) + */ + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + const char *buf1 = test_bufs[priv_data->orig_idx]; + const char *buf2; + contig_buf = rte_malloc(NULL, ops_processed[i]->produced, 0); + if (contig_buf == NULL) { + RTE_LOG(ERR, USER1, "Contiguous buffer could not " + "be allocated\n"); + goto exit; + } + + buf2 = rte_pktmbuf_read(ops_processed[i]->m_dst, 0, + ops_processed[i]->produced, contig_buf); + if (compare_buffers(buf1, strlen(buf1) + 1, + buf2, ops_processed[i]->produced) < 0) + goto exit; + + /* Test checksums */ + if (compress_xforms[0]->compress.chksum != + RTE_COMP_CHECKSUM_NONE) { + if (ops_processed[i]->output_chksum != + compress_checksum[i]) { + RTE_LOG(ERR, USER1, "The checksums differ\n" + "Compression Checksum: %" PRIu64 "\tDecompression " + "Checksum: %" PRIu64 "\n", compress_checksum[i], + ops_processed[i]->output_chksum); + goto exit; + } + } + + rte_free(contig_buf); + contig_buf = NULL; + } + + ret_status = 0; + +exit: + /* Free resources */ + for (i = 0; i < num_bufs; i++) { + rte_pktmbuf_free(uncomp_bufs[i]); + rte_pktmbuf_free(comp_bufs[i]); + rte_comp_op_free(ops[i]); + rte_comp_op_free(ops_processed[i]); + } + for (i = 0; i < num_priv_xforms; i++) { + if (priv_xforms[i] != NULL) + rte_compressdev_private_xform_free(0, priv_xforms[i]); + } + rte_free(contig_buf); + + return ret_status; +} + +static int +test_compressdev_deflate_stateless_fixed(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t i; + int ret; + const struct rte_compressdev_capabilities *capab; + + capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); + + if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_FIXED) == 0) + return -ENOTSUP; + + struct rte_comp_xform *compress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + + if (compress_xform == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(compress_xform, ts_params->def_comp_xform, + sizeof(struct rte_comp_xform)); + compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_FIXED; + + struct interim_data_params int_data = { + NULL, + 1, + NULL, + &compress_xform, + &ts_params->def_decomp_xform, + 1 + }; + + struct test_data_params test_data = { + RTE_COMP_OP_STATELESS, + LB_BOTH, + ZLIB_DECOMPRESS, + 0 + }; + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + int_data.test_bufs = &compress_test_bufs[i]; + int_data.buf_idx = &i; + + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + + /* Compress with Zlib, decompress with compressdev */ + test_data.zlib_dir = ZLIB_COMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + + ret = TEST_SUCCESS; + +exit: + rte_free(compress_xform); + return ret; +} + +static int +test_compressdev_deflate_stateless_dynamic(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t i; + int ret; + struct rte_comp_xform *compress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + + const struct rte_compressdev_capabilities *capab; + + capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); + + if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_DYNAMIC) == 0) + return -ENOTSUP; + + if (compress_xform == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(compress_xform, ts_params->def_comp_xform, + sizeof(struct rte_comp_xform)); + compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_DYNAMIC; + + struct interim_data_params int_data = { + NULL, + 1, + NULL, + &compress_xform, + &ts_params->def_decomp_xform, + 1 + }; + + struct test_data_params test_data = { + RTE_COMP_OP_STATELESS, + LB_BOTH, + ZLIB_DECOMPRESS, + 0 + }; + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + int_data.test_bufs = &compress_test_bufs[i]; + int_data.buf_idx = &i; + + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + + /* Compress with Zlib, decompress with compressdev */ + test_data.zlib_dir = ZLIB_COMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + + ret = TEST_SUCCESS; + +exit: + rte_free(compress_xform); + return ret; +} + +static int +test_compressdev_deflate_stateless_multi_op(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t num_bufs = RTE_DIM(compress_test_bufs); + uint16_t buf_idx[num_bufs]; + uint16_t i; + + for (i = 0; i < num_bufs; i++) + buf_idx[i] = i; + + struct interim_data_params int_data = { + compress_test_bufs, + num_bufs, + buf_idx, + &ts_params->def_comp_xform, + &ts_params->def_decomp_xform, + 1 + }; + + struct test_data_params test_data = { + RTE_COMP_OP_STATELESS, + LB_BOTH, + ZLIB_DECOMPRESS, + 0 + }; + + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) + return TEST_FAILED; + + /* Compress with Zlib, decompress with compressdev */ + test_data.zlib_dir = ZLIB_COMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) + return TEST_FAILED; + + return TEST_SUCCESS; +} + +static int +test_compressdev_deflate_stateless_multi_level(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + unsigned int level; + uint16_t i; + int ret; + struct rte_comp_xform *compress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + + if (compress_xform == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(compress_xform, ts_params->def_comp_xform, + sizeof(struct rte_comp_xform)); + + struct interim_data_params int_data = { + NULL, + 1, + NULL, + &compress_xform, + &ts_params->def_decomp_xform, + 1 + }; + + struct test_data_params test_data = { + RTE_COMP_OP_STATELESS, + LB_BOTH, + ZLIB_DECOMPRESS, + 0 + }; + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + int_data.test_bufs = &compress_test_bufs[i]; + int_data.buf_idx = &i; + + for (level = RTE_COMP_LEVEL_MIN; level <= RTE_COMP_LEVEL_MAX; + level++) { + compress_xform->compress.level = level; + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + } + + ret = TEST_SUCCESS; + +exit: + rte_free(compress_xform); + return ret; +} + +#define NUM_XFORMS 3 +static int +test_compressdev_deflate_stateless_multi_xform(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t num_bufs = NUM_XFORMS; + struct rte_comp_xform *compress_xforms[NUM_XFORMS] = {NULL}; + struct rte_comp_xform *decompress_xforms[NUM_XFORMS] = {NULL}; + const char *test_buffers[NUM_XFORMS]; + uint16_t i; + unsigned int level = RTE_COMP_LEVEL_MIN; + uint16_t buf_idx[num_bufs]; + + int ret; + + /* Create multiple xforms with various levels */ + for (i = 0; i < NUM_XFORMS; i++) { + compress_xforms[i] = rte_malloc(NULL, + sizeof(struct rte_comp_xform), 0); + if (compress_xforms[i] == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(compress_xforms[i], ts_params->def_comp_xform, + sizeof(struct rte_comp_xform)); + compress_xforms[i]->compress.level = level; + level++; + + decompress_xforms[i] = rte_malloc(NULL, + sizeof(struct rte_comp_xform), 0); + if (decompress_xforms[i] == NULL) { + RTE_LOG(ERR, USER1, + "Decompress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(decompress_xforms[i], ts_params->def_decomp_xform, + sizeof(struct rte_comp_xform)); + } + + for (i = 0; i < NUM_XFORMS; i++) { + buf_idx[i] = 0; + /* Use the same buffer in all sessions */ + test_buffers[i] = compress_test_bufs[0]; + } + + struct interim_data_params int_data = { + test_buffers, + num_bufs, + buf_idx, + compress_xforms, + decompress_xforms, + NUM_XFORMS + }; + + struct test_data_params test_data = { + RTE_COMP_OP_STATELESS, + LB_BOTH, + ZLIB_DECOMPRESS, + 0 + }; + + /* Compress with compressdev, decompress with Zlib */ + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + + ret = TEST_SUCCESS; +exit: + for (i = 0; i < NUM_XFORMS; i++) { + rte_free(compress_xforms[i]); + rte_free(decompress_xforms[i]); + } + + return ret; +} + +static int +test_compressdev_deflate_stateless_sgl(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t i; + const struct rte_compressdev_capabilities *capab; + + capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); + + if ((capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) == 0) + return -ENOTSUP; + + struct interim_data_params int_data = { + NULL, + 1, + NULL, + &ts_params->def_comp_xform, + &ts_params->def_decomp_xform, + 1 + }; + + struct test_data_params test_data = { + RTE_COMP_OP_STATELESS, + SGL_BOTH, + ZLIB_DECOMPRESS, + 0 + }; + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + int_data.test_bufs = &compress_test_bufs[i]; + int_data.buf_idx = &i; + + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) + return TEST_FAILED; + + /* Compress with Zlib, decompress with compressdev */ + test_data.zlib_dir = ZLIB_COMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) + return TEST_FAILED; + + if (capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_LB_OUT) { + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + test_data.buff_type = SGL_TO_LB; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) + return TEST_FAILED; + + /* Compress with Zlib, decompress with compressdev */ + test_data.zlib_dir = ZLIB_COMPRESS; + test_data.buff_type = SGL_TO_LB; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) + return TEST_FAILED; + } + + if (capab->comp_feature_flags & RTE_COMP_FF_OOP_LB_IN_SGL_OUT) { + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + test_data.buff_type = LB_TO_SGL; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) + return TEST_FAILED; + + /* Compress with Zlib, decompress with compressdev */ + test_data.zlib_dir = ZLIB_COMPRESS; + test_data.buff_type = LB_TO_SGL; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) + return TEST_FAILED; + } + + + } + + return TEST_SUCCESS; + +} + +static int +test_compressdev_deflate_stateless_checksum(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t i; + int ret; + const struct rte_compressdev_capabilities *capab; + + capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); + + /* Check if driver supports any checksum */ + if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_CHECKSUM) == 0 && + (capab->comp_feature_flags & + RTE_COMP_FF_ADLER32_CHECKSUM) == 0 && + (capab->comp_feature_flags & + RTE_COMP_FF_CRC32_ADLER32_CHECKSUM) == 0) + return -ENOTSUP; + + struct rte_comp_xform *compress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + if (compress_xform == NULL) { + RTE_LOG(ERR, USER1, "Compress xform could not be created\n"); + ret = TEST_FAILED; + return ret; + } + + memcpy(compress_xform, ts_params->def_comp_xform, + sizeof(struct rte_comp_xform)); + + struct rte_comp_xform *decompress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + if (decompress_xform == NULL) { + RTE_LOG(ERR, USER1, "Decompress xform could not be created\n"); + rte_free(compress_xform); + ret = TEST_FAILED; + return ret; + } + + memcpy(decompress_xform, ts_params->def_decomp_xform, + sizeof(struct rte_comp_xform)); + + struct interim_data_params int_data = { + NULL, + 1, + NULL, + &compress_xform, + &decompress_xform, + 1 + }; + + struct test_data_params test_data = { + RTE_COMP_OP_STATELESS, + LB_BOTH, + ZLIB_DECOMPRESS, + 0 + }; + + /* Check if driver supports crc32 checksum and test */ + if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_CHECKSUM)) { + compress_xform->compress.chksum = RTE_COMP_CHECKSUM_CRC32; + decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_CRC32; + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + /* Compress with compressdev, decompress with Zlib */ + int_data.test_bufs = &compress_test_bufs[i]; + int_data.buf_idx = &i; + + /* Generate zlib checksum and test against selected + * drivers decompression checksum + */ + test_data.zlib_dir = ZLIB_COMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + + /* Generate compression and decompression + * checksum of selected driver + */ + test_data.zlib_dir = ZLIB_NONE; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + } + + /* Check if driver supports adler32 checksum and test */ + if ((capab->comp_feature_flags & RTE_COMP_FF_ADLER32_CHECKSUM)) { + compress_xform->compress.chksum = RTE_COMP_CHECKSUM_ADLER32; + decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_ADLER32; + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + int_data.test_bufs = &compress_test_bufs[i]; + int_data.buf_idx = &i; + + /* Generate zlib checksum and test against selected + * drivers decompression checksum + */ + test_data.zlib_dir = ZLIB_COMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + /* Generate compression and decompression + * checksum of selected driver + */ + test_data.zlib_dir = ZLIB_NONE; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + } + + /* Check if driver supports combined crc and adler checksum and test */ + if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_ADLER32_CHECKSUM)) { + compress_xform->compress.chksum = + RTE_COMP_CHECKSUM_CRC32_ADLER32; + decompress_xform->decompress.chksum = + RTE_COMP_CHECKSUM_CRC32_ADLER32; + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + int_data.test_bufs = &compress_test_bufs[i]; + int_data.buf_idx = &i; + + /* Generate compression and decompression + * checksum of selected driver + */ + test_data.zlib_dir = ZLIB_NONE; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + } + + ret = TEST_SUCCESS; + +exit: + rte_free(compress_xform); + rte_free(decompress_xform); + return ret; +} + +static int +test_compressdev_out_of_space_buffer(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + int ret; + uint16_t i; + const struct rte_compressdev_capabilities *capab; + + RTE_LOG(INFO, USER1, "This is a negative test errors are expected\n"); + + capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); + + if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_FIXED) == 0) + return -ENOTSUP; + + struct rte_comp_xform *compress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + + if (compress_xform == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + struct interim_data_params int_data = { + &compress_test_bufs[0], + 1, + &i, + &ts_params->def_comp_xform, + &ts_params->def_decomp_xform, + 1 + }; + + struct test_data_params test_data = { + RTE_COMP_OP_STATELESS, + LB_BOTH, + ZLIB_DECOMPRESS, + 1 + }; + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + + /* Compress with Zlib, decompress with compressdev */ + test_data.zlib_dir = ZLIB_COMPRESS; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + + if (capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) { + /* Compress with compressdev, decompress with Zlib */ + test_data.zlib_dir = ZLIB_DECOMPRESS; + test_data.buff_type = SGL_BOTH; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + + /* Compress with Zlib, decompress with compressdev */ + test_data.zlib_dir = ZLIB_COMPRESS; + test_data.buff_type = SGL_BOTH; + if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + + ret = TEST_SUCCESS; + +exit: + rte_free(compress_xform); + return ret; +} + + +static struct unit_test_suite compressdev_testsuite = { + .suite_name = "compressdev unit test suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(NULL, NULL, + test_compressdev_invalid_configuration), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_fixed), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_dynamic), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_multi_op), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_multi_level), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_multi_xform), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_sgl), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_checksum), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_out_of_space_buffer), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_compressdev(void) +{ + return unit_test_suite_runner(&compressdev_testsuite); +} + +REGISTER_TEST_COMMAND(compressdev_autotest, test_compressdev); diff --git a/app/test/test_compressdev_test_buffer.h b/app/test/test_compressdev_test_buffer.h new file mode 100644 index 0000000000..c0492f89a2 --- /dev/null +++ b/app/test/test_compressdev_test_buffer.h @@ -0,0 +1,295 @@ +#ifndef TEST_COMPRESSDEV_TEST_BUFFERS_H_ +#define TEST_COMPRESSDEV_TEST_BUFFERS_H_ + +/* + * These test buffers are snippets obtained + * from the Canterbury and Calgary Corpus + * collection. + */ + +/* Snippet of Alice's Adventures in Wonderland */ +static const char test_buf_alice[] = + " Alice was beginning to get very tired of sitting by her sister\n" + "on the bank, and of having nothing to do: once or twice she had\n" + "peeped into the book her sister was reading, but it had no\n" + "pictures or conversations in it, `and what is the use of a book,'\n" + "thought Alice `without pictures or conversation?'\n\n" + " So she was considering in her own mind (as well as she could,\n" + "for the hot day made her feel very sleepy and stupid), whether\n" + "the pleasure of making a daisy-chain would be worth the trouble\n" + "of getting up and picking the daisies, when suddenly a White\n" + "Rabbit with pink eyes ran close by her.\n\n" + " There was nothing so VERY remarkable in that; nor did Alice\n" + "think it so VERY much out of the way to hear the Rabbit say to\n" + "itself, `Oh dear! Oh dear! I shall be late!' (when she thought\n" + "it over afterwards, it occurred to her that she ought to have\n" + "wondered at this, but at the time it all seemed quite natural);\n" + "but when the Rabbit actually TOOK A WATCH OUT OF ITS WAISTCOAT-\n" + "POCKET, and looked at it, and then hurried on, Alice started to\n" + "her feet, for it flashed across her mind that she had never\n" + "before seen a rabbit with either a waistcoat-pocket, or a watch to\n" + "take out of it, and burning with curiosity, she ran across the\n" + "field after it, and fortunately was just in time to see it pop\n" + "down a large rabbit-hole under the hedge.\n\n" + " In another moment down went Alice after it, never once\n" + "considering how in the world she was to get out again.\n\n" + " The rabbit-hole went straight on like a tunnel for some way,\n" + "and then dipped suddenly down, so suddenly that Alice had not a\n" + "moment to think about stopping herself before she found herself\n" + "falling down a very deep well.\n\n" + " Either the well was very deep, or she fell very slowly, for she\n" + "had plenty of time as she went down to look about her and to\n" + "wonder what was going to happen next. First, she tried to look\n" + "down and make out what she was coming to, but it was too dark to\n" + "see anything; then she looked at the sides of the well, and\n" + "noticed that they were filled with cupboards and book-shelves;\n" + "here and there she saw maps and pictures hung upon pegs. She\n" + "took down a jar from one of the shelves as she passed; it was\n" + "labelled `ORANGE MARMALADE', but to her great disappointment it\n" + "was empty: she did not like to drop the jar for fear of killing\n" + "somebody, so managed to put it into one of the cupboards as she\n" + "fell past it.\n\n" + " `Well!' thought Alice to herself, `after such a fall as this, I\n" + "shall think nothing of tumbling down stairs! How brave they'll\n" + "all think me at home! Why, I wouldn't say anything about it,\n" + "even if I fell off the top of the house!' (Which was very likely\n" + "true.)\n\n" + " Down, down, down. Would the fall NEVER come to an end! `I\n" + "wonder how many miles I've fallen by this time?' she said aloud.\n" + "`I must be getting somewhere near the centre of the earth. Let\n" + "me see: that would be four thousand miles down, I think--' (for,\n" + "you see, Alice had learnt several things of this sort in her\n" + "lessons in the schoolroom, and though this was not a VERY good\n" + "opportunity for showing off her knowledge, as there was no one to\n" + "listen to her, still it was good practice to say it over) `--yes,\n" + "that's about the right distance--but then I wonder what Latitude\n" + "or Longitude I've got to?' (Alice had no idea what Latitude was,\n" + "or Longitude either, but thought they were nice grand words to\n" + "say.)\n\n" + " Presently she began again. `I wonder if I shall fall right\n" + "THROUGH the earth! How funny it'll seem to come out among the\n" + "people that walk with their heads downward! The Antipathies, I\n" + "think--' (she was rather glad there WAS no one listening, this\n" + "time, as it didn't sound at all the right word) `--but I shall\n" + "have to ask them what the name of the country is, you know.\n" + "Please, Ma'am, is this New Zealand or Australia?' (and she tried\n" + "to curtsey as she spoke--fancy CURTSEYING as you're falling\n" + "through the air! Do you think you could manage it?) `And what\n" + "an ignorant little girl she'll think me for asking! No, it'll\n" + "never do to ask: perhaps I shall see it written up somewhere.'\n" + " Down, down, down. There was nothing else to do, so Alice soon\n" + "began talking again. `Dinah'll miss me very much to-night, I\n" + "should think!' (Dinah was the cat.) `I hope they'll remember\n" + "her saucer of milk at tea-time. Dinah my dear! I wish you were\n" + "down here with me! There are no mice in the air, I'm afraid, but\n" + "you might catch a bat, and that's very like a mouse, you know.\n" + "But do cats eat bats, I wonder?' And here Alice began to get\n" + "rather sleepy, and went on saying to herself, in a dreamy sort of\n" + "way, `Do cats eat bats? Do cats eat bats?' and sometimes, `Do\n" + "bats eat cats?' for, you see, as she couldn't answer either\n" + "question, it didn't much matter which way she put it. She felt\n" + "that she was dozing off, and had just begun to dream that she\n" + "was walking hand in hand with Dinah, and saying to her very\n" + "earnestly, `Now, Dinah, tell me the truth: did you ever eat a\n" + "bat?' when suddenly, thump! thump! down she came upon a heap of\n" + "sticks and dry leaves, and the fall was over.\n\n"; + +/* Snippet of Shakespeare play */ +static const char test_buf_shakespeare[] = + "CHARLES wrestler to Frederick.\n" + "\n" + "\n" + "OLIVER |\n" + " |\n" + "JAQUES (JAQUES DE BOYS:) | sons of Sir Rowland de Boys.\n" + " |\n" + "ORLANDO |\n" + "\n" + "\n" + "ADAM |\n" + " | servants to Oliver.\n" + "DENNIS |\n" + "\n" + "\n" + "TOUCHSTONE a clown.\n" + "\n" + "SIR OLIVER MARTEXT a vicar.\n" + "\n" + "\n" + "CORIN |\n" + " | shepherds.\n" + "SILVIUS |\n" + "\n" + "\n" + "WILLIAM a country fellow in love with Audrey.\n" + "\n" + " A person representing HYMEN. (HYMEN:)\n" + "\n" + "ROSALIND daughter to the banished duke.\n" + "\n" + "CELIA daughter to Frederick.\n" + "\n" + "PHEBE a shepherdess.\n" + "\n" + "AUDREY a country wench.\n" + "\n" + " Lords, pages, and attendants, &c.\n" + " (Forester:)\n" + " (A Lord:)\n" + " (First Lord:)\n" + " (Second Lord:)\n" + " (First Page:)\n" + " (Second Page:)\n" + "\n" + "\n" + "SCENE Oliver's house; Duke Frederick's court; and the\n" + " Forest of Arden.\n" + "\n" + "\n" + "\n" + "\n" + " AS YOU LIKE IT\n" + "\n" + "\n" + "ACT I\n" + "\n" + "\n" + "\n" + "SCENE I Orchard of Oliver's house.\n" + "\n" + "\n" + " [Enter ORLANDO and ADAM]\n" + "\n" + "ORLANDO As I remember, Adam, it was upon this fashion\n" + " bequeathed me by will but poor a thousand crowns,\n" + " and, as thou sayest, charged my brother, on his\n" + " blessing, to breed me well: and there begins my\n" + " sadness. My brother Jaques he keeps at school, and\n" + " report speaks goldenly of his profit: for my part,\n" + " he keeps me rustically at home, or, to speak more\n" + " properly, stays me here at home unkept; for call you\n" + " that keeping for a gentleman of my birth, that\n" + " differs not from the stalling of an ox? His horses\n" + " are bred better; for, besides that they are fair\n" + " with their feeding, they are taught their manage,\n" + " and to that end riders dearly hired: but I, his\n" + " brother, gain nothing under him but growth; for the\n" + " which his animals on his dunghills are as much\n" + " bound to him as I. Besides this nothing that he so\n" + " plentifully gives me, the something that nature gave\n" + " me his countenance seems to take from me: he lets\n" + " me feed with his hinds, bars me the place of a\n" + " brother, and, as much as in him lies, mines my\n" + " gentility with my education. This is it, Adam, that\n" + " grieves me; and the spirit of my father, which I\n" + " think is within me, begins to mutiny against this\n" + " servitude: I will no longer endure it, though yet I\n" + " know no wise remedy how to avoid it.\n" + "\n" + "ADAM Yonder comes my master, your brother.\n" + "\n" + "ORLANDO Go apart, Adam, and thou shalt hear how he will\n"; + +/* Snippet of source code in Pascal */ +static const char test_buf_pascal[] = + " Ptr = 1..DMem;\n" + " Loc = 1..IMem;\n" + " Loc0 = 0..IMem;\n" + " EdgeT = (hout,lin,hin,lout); {Warning this order is important in}\n" + " {predicates such as gtS,geS}\n" + " CardT = (finite,infinite);\n" + " ExpT = Minexp..Maxexp;\n" + " ManT = Mininf..Maxinf; \n" + " Pflag = (PNull,PSoln,PTrace,PPrint);\n" + " Sreal = record\n" + " edge:EdgeT;\n" + " cardinality:CardT;\n" + " exp:ExpT; {exponent}\n" + " mantissa:ManT;\n" + " end;\n" + " Int = record\n" + " hi:Sreal;\n" + " lo:Sreal;\n" + " end;\n" + " Instr = record\n" + " Code:OpType;\n" + " Pars: array[0..Par] of 0..DMem;\n" + " end;\n" + " DataMem= record\n" + " D :array [Ptr] of Int;\n" + " S :array [Loc] of State;\n" + " LastHalve:Loc;\n" + " RHalve :array [Loc] of real;\n" + " end;\n" + " DataFlags=record\n" + " PF :array [Ptr] of Pflag;\n" + " end;\n" + "var\n" + " Debug : (none,activity,post,trace,dump);\n" + " Cut : (once,all);\n" + " GlobalEnd,Verifiable:boolean;\n" + " HalveThreshold:real;\n" + " I : array [Loc] of Instr; {Memory holding instructions}\n" + " End : Loc; {last instruction in I}\n" + " ParN : array [OpType] of -1..Par; {number of parameters for each \n" + " opcode. -1 means no result}\n" + " ParIntersect : array [OpType] of boolean ;\n" + " DInit : DataMem; {initial memory which is cleared and \n" + " used in first call}\n" + " DF : DataFlags; {hold flags for variables, e.g. print/trace}\n" + " MaxDMem:0..DMem;\n" + " Shift : array[0..Digits] of 1..maxint;{array of constant multipliers}\n" + " {used for alignment etc.}\n" + " Dummy :Positive;\n" + " {constant intervals and Sreals}\n" + " PlusInfS,MinusInfS,PlusSmallS,MinusSmallS,ZeroS,\n" + " PlusFiniteS,MinusFiniteS:Sreal;\n" + " Zero,All,AllFinite:Int;\n" + "\n" + "procedure deblank;\n" + "var Ch:char;\n" + "begin\n" + " while (not eof) and (input^ in [' ',' ']) do read(Ch);\n" + "end;\n" + "\n" + "procedure InitialOptions;\n" + "\n" + "#include '/user/profs/cleary/bin/options.i';\n" + "\n" + " procedure Option;\n" + " begin\n" + " case Opt of\n" + " 'a','A':Debug:=activity;\n" + " 'd','D':Debug:=dump;\n" + " 'h','H':HalveThreshold:=StringNum/100;\n" + " 'n','N':Debug:=none;\n" + " 'p','P':Debug:=post;\n" + " 't','T':Debug:=trace;\n" + " 'v','V':Verifiable:=true;\n" + " end;\n" + " end;\n" + "\n" + "begin\n" + " Debug:=trace;\n" + " Verifiable:=false;\n" + " HalveThreshold:=67/100;\n" + " Options;\n" + " writeln(Debug);\n" + " writeln('Verifiable:',Verifiable);\n" + " writeln('Halve threshold',HalveThreshold);\n" + "end;{InitialOptions}\n" + "\n" + "procedure NormalizeUp(E,M:integer;var S:Sreal;var Closed:boolean);\n" + "begin\n" + "with S do\n" + "begin\n" + " if M=0 then S:=ZeroS else\n" + " if M>0 then\n"; + +static const char * const compress_test_bufs[] = { + test_buf_alice, + test_buf_shakespeare, + test_buf_pascal +}; + +#endif /* TEST_COMPRESSDEV_TEST_BUFFERS_H_ */ diff --git a/app/test/test_cpuflags.c b/app/test/test_cpuflags.c new file mode 100644 index 0000000000..06718631f0 --- /dev/null +++ b/app/test/test_cpuflags.c @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 AVX512F:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_AVX512F); + + 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_crc.c b/app/test/test_crc.c new file mode 100644 index 0000000000..f8a74e04ee --- /dev/null +++ b/app/test/test_crc.c @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Intel Corporation + */ + +#include "test.h" + +#include +#include +#include +#include + +#define CRC_VEC_LEN 32 +#define CRC32_VEC_LEN1 1512 +#define CRC32_VEC_LEN2 348 +#define CRC16_VEC_LEN1 12 +#define CRC16_VEC_LEN2 2 +#define LINE_LEN 75 + +/* CRC test vector */ +static const uint8_t crc_vec[CRC_VEC_LEN] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'A', 'B', 'C', 'D', + 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', +}; + +/* 32-bit CRC test vector */ +static const uint8_t crc32_vec1[12] = { + 0xBE, 0xD7, 0x23, 0x47, 0x6B, 0x8F, + 0xB3, 0x14, 0x5E, 0xFB, 0x35, 0x59, +}; + +/* 16-bit CRC test vector 1 */ +static const uint8_t crc16_vec1[CRC16_VEC_LEN1] = { + 0x0D, 0x01, 0x01, 0x23, 0x45, 0x67, + 0x89, 0x01, 0x23, 0x45, 0x00, 0x01, +}; + +/* 16-bit CRC test vector 2 */ +static const uint8_t crc16_vec2[CRC16_VEC_LEN2] = { + 0x03, 0x3f, +}; +/** CRC results */ +static const uint32_t crc32_vec_res = 0xb491aab4; +static const uint32_t crc32_vec1_res = 0xac54d294; +static const uint32_t crc32_vec2_res = 0xefaae02f; +static const uint32_t crc16_vec_res = 0x6bec; +static const uint16_t crc16_vec1_res = 0x8cdd; +static const uint16_t crc16_vec2_res = 0xec5b; + +static int +crc_calc(const uint8_t *vec, + uint32_t vec_len, + enum rte_net_crc_type type) +{ + /* compute CRC */ + uint32_t ret = rte_net_crc_calc(vec, vec_len, type); + + /* dump data on console */ + debug_hexdump(stdout, NULL, vec, vec_len); + + return ret; +} + +static int +test_crc_calc(void) +{ + uint32_t i; + enum rte_net_crc_type type; + uint8_t *test_data; + uint32_t result; + int error; + + /* 32-bit ethernet CRC: Test 1 */ + type = RTE_NET_CRC32_ETH; + + result = crc_calc(crc_vec, CRC_VEC_LEN, type); + if (result != crc32_vec_res) + return -1; + + /* 32-bit ethernet CRC: Test 2 */ + test_data = rte_zmalloc(NULL, CRC32_VEC_LEN1, 0); + + for (i = 0; i < CRC32_VEC_LEN1; i += 12) + rte_memcpy(&test_data[i], crc32_vec1, 12); + + result = crc_calc(test_data, CRC32_VEC_LEN1, type); + if (result != crc32_vec1_res) { + error = -2; + goto fail; + } + + /* 32-bit ethernet CRC: Test 3 */ + for (i = 0; i < CRC32_VEC_LEN2; i += 12) + rte_memcpy(&test_data[i], crc32_vec1, 12); + + result = crc_calc(test_data, CRC32_VEC_LEN2, type); + if (result != crc32_vec2_res) { + error = -3; + goto fail; + } + + /* 16-bit CCITT CRC: Test 4 */ + type = RTE_NET_CRC16_CCITT; + result = crc_calc(crc_vec, CRC_VEC_LEN, type); + if (result != crc16_vec_res) { + error = -4; + goto fail; + } + /* 16-bit CCITT CRC: Test 5 */ + result = crc_calc(crc16_vec1, CRC16_VEC_LEN1, type); + if (result != crc16_vec1_res) { + error = -5; + goto fail; + } + /* 16-bit CCITT CRC: Test 6 */ + result = crc_calc(crc16_vec2, CRC16_VEC_LEN2, type); + if (result != crc16_vec2_res) { + error = -6; + goto fail; + } + + rte_free(test_data); + return 0; + +fail: + rte_free(test_data); + return error; +} + +static int +test_crc(void) +{ + int ret; + /* set CRC scalar mode */ + rte_net_crc_set_alg(RTE_NET_CRC_SCALAR); + + ret = test_crc_calc(); + if (ret < 0) { + printf("test_crc (scalar): failed (%d)\n", ret); + return ret; + } + /* set CRC sse4.2 mode */ + rte_net_crc_set_alg(RTE_NET_CRC_SSE42); + + ret = test_crc_calc(); + if (ret < 0) { + printf("test_crc (x86_64_SSE4.2): failed (%d)\n", ret); + return ret; + } + + /* set CRC neon mode */ + rte_net_crc_set_alg(RTE_NET_CRC_NEON); + + ret = test_crc_calc(); + if (ret < 0) { + printf("test crc (arm64 neon pmull): failed (%d)\n", ret); + return ret; + } + + return 0; +} + +REGISTER_TEST_COMMAND(crc_autotest, test_crc); diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c new file mode 100644 index 0000000000..32f1893bce --- /dev/null +++ b/app/test/test_cryptodev.c @@ -0,0 +1,10846 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015-2017 Intel Corporation + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER +#include +#include +#endif + +#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_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_aead_test_vectors.h" +#include "test_cryptodev_hmac_test_vectors.h" + +#define VDEV_ARGS_SIZE 100 +#define MAX_NB_SESSIONS 4 + +static int gbl_driver_id; + +struct crypto_testsuite_params { + struct rte_mempool *mbuf_pool; + struct rte_mempool *large_mbuf_pool; + struct rte_mempool *op_mpool; + struct rte_mempool *session_mpool; + struct rte_mempool *session_priv_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_crypto_sym_xform aead_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) + + MAXIMUM_IV_LENGTH, + rte_socket_id()); + if (ts_params->op_mpool == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); + return TEST_FAILED; + } + + /* Create an AESNI MB device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance of" + " pmd : %s", + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + } + } + + /* Create an AESNI GCM device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD))); + if (nb_devs < 1) { + TEST_ASSERT_SUCCESS(rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD), NULL), + "Failed to create instance of" + " pmd : %s", + RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD)); + } + } + + /* Create a SNOW 3G device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD))); + if (nb_devs < 1) { + TEST_ASSERT_SUCCESS(rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD), NULL), + "Failed to create instance of" + " pmd : %s", + RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD)); + } + } + + /* Create a KASUMI device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_KASUMI_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_KASUMI_PMD))); + if (nb_devs < 1) { + TEST_ASSERT_SUCCESS(rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_KASUMI_PMD), NULL), + "Failed to create instance of" + " pmd : %s", + RTE_STR(CRYPTODEV_NAME_KASUMI_PMD)); + } + } + + /* Create a ZUC device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ZUC_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ZUC_PMD))); + if (nb_devs < 1) { + TEST_ASSERT_SUCCESS(rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_ZUC_PMD), NULL), + "Failed to create instance of" + " pmd : %s", + RTE_STR(CRYPTODEV_NAME_ZUC_PMD)); + } + } + + /* Create a NULL device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_NULL_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_NULL_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_NULL_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance of" + " pmd : %s", + RTE_STR(CRYPTODEV_NAME_NULL_PMD)); + } + } + + /* Create an OPENSSL device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance of pmd : %s", + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + } + } + + /* Create a ARMv8 device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance of pmd : %s", + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); + } + } + + /* Create a MVSAM device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance of pmd : %s", + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)); + } + } + + /* Create an CCP device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_CCP_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance of pmd : %s", + RTE_STR(CRYPTODEV_NAME_CCP_PMD)); + } + } + +#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER + char vdev_args[VDEV_ARGS_SIZE] = {""}; + char temp_str[VDEV_ARGS_SIZE] = {"mode=multi-core," + "ordering=enable,name=cryptodev_test_scheduler,corelist="}; + uint16_t slave_core_count = 0; + uint16_t socket_id = 0; + + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD))) { + + /* Identify the Slave Cores + * Use 2 slave cores for the device args + */ + RTE_LCORE_FOREACH_SLAVE(i) { + if (slave_core_count > 1) + break; + snprintf(vdev_args, sizeof(vdev_args), + "%s%d", temp_str, i); + strcpy(temp_str, vdev_args); + strcat(temp_str, ";"); + slave_core_count++; + socket_id = lcore_config[i].socket_id; + } + if (slave_core_count != 2) { + RTE_LOG(ERR, USER1, + "Cryptodev scheduler test require at least " + "two slave cores to run. " + "Please use the correct coremask.\n"); + return TEST_FAILED; + } + strcpy(temp_str, vdev_args); + snprintf(vdev_args, sizeof(vdev_args), "%s,socket_id=%d", + temp_str, socket_id); + RTE_LOG(DEBUG, USER1, "vdev_args: %s\n", vdev_args); + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD), + vdev_args); + 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 */ + + 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.driver_id == gbl_driver_id) + 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; + + unsigned int session_size = + rte_cryptodev_sym_get_private_session_size(dev_id); + + /* + * Create mempool with maximum number of sessions * 2, + * to include the session headers + */ + if (info.sym.max_nb_sessions != 0 && + info.sym.max_nb_sessions < MAX_NB_SESSIONS) { + RTE_LOG(ERR, USER1, "Device does not support " + "at least %u sessions\n", + MAX_NB_SESSIONS); + return TEST_FAILED; + } + + ts_params->session_mpool = rte_cryptodev_sym_session_pool_create( + "test_sess_mp", MAX_NB_SESSIONS, 0, 0, 0, + SOCKET_ID_ANY); + TEST_ASSERT_NOT_NULL(ts_params->session_mpool, + "session mempool allocation failed"); + + ts_params->session_priv_mpool = rte_mempool_create( + "test_sess_mp_priv", + MAX_NB_SESSIONS, + session_size, + 0, 0, NULL, NULL, NULL, + NULL, SOCKET_ID_ANY, + 0); + TEST_ASSERT_NOT_NULL(ts_params->session_priv_mpool, + "session mempool allocation failed"); + + + + 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; + ts_params->qp_conf.mp_session = ts_params->session_mpool; + ts_params->qp_conf.mp_session_private = ts_params->session_priv_mpool; + + 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)); + } + + /* Free session mempools */ + if (ts_params->session_priv_mpool != NULL) { + rte_mempool_free(ts_params->session_priv_mpool); + ts_params->session_priv_mpool = NULL; + } + + if (ts_params->session_mpool != NULL) { + rte_mempool_free(ts_params->session_mpool); + ts_params->session_mpool = NULL; + } +} + +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->qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT; + ts_params->qp_conf.mp_session = ts_params->session_mpool; + ts_params->qp_conf.mp_session_private = ts_params->session_priv_mpool; + + 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_clear(ts_params->valid_devs[0], + ut_params->sess); + rte_cryptodev_sym_session_free(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(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 = orig_nb_qps; + + 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 = orig_nb_qps + 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); + + 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*/ + qp_conf.mp_session = ts_params->session_mpool; + qp_conf.mp_session_private = ts_params->session_priv_mpool; + + 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 = ts_params->conf.nb_queue_pairs; /*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; + ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; + ut_params->cipher_xform.cipher.iv.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_GENERATE; + ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; + ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1; + ut_params->auth_xform.auth.key.data = hmac_sha1_key; + ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + /* Create crypto session*/ + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, &ut_params->cipher_xform, + ts_params->session_priv_mpool); + 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_iova_offset( + ut_params->ibuf, QUOTE_512_BYTES); + + sym_op->auth.data.offset = 0; + sym_op->auth.data.length = QUOTE_512_BYTES; + + /* Copy IV at the end of the crypto operation */ + rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), + aes_cbc_iv, CIPHER_IV_LENGTH_AES_CBC); + + /* Set crypto operation cipher parameters */ + sym_op->cipher.data.offset = 0; + 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(ut_params->op->sym->m_src, + uint8_t *); + + 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_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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; + ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; + ut_params->cipher_xform.cipher.iv.length = CIPHER_IV_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_iova_offset( + ut_params->ibuf, QUOTE_512_BYTES); + + sym_op->auth.data.offset = 0; + sym_op->auth.data.length = QUOTE_512_BYTES; + + /* Copy IV at the end of the crypto operation */ + rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), + iv, CIPHER_IV_LENGTH_AES_CBC); + + sym_op->cipher.data.offset = 0; + 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 *), + 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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_docsis_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), + BLKCIPHER_AES_DOCSIS_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_docsis_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)), + BLKCIPHER_AES_DOCSIS_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_DES_docsis_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)), + BLKCIPHER_DES_DOCSIS_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_QAT_SYM_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_ccp_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_PMD)), + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_ccp_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_virtio_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_caam_jr_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_caam_jr_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_caam_jr_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + + +static int +test_AES_chain_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), + BLKCIPHER_AUTHONLY_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_ccp_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)), + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_mrvl_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_mrvl_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_mrvl_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_mrvl_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_mrvl_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_octeontx_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->session_mpool, + ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_octeontx_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->session_mpool, + ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_octeontx_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->session_mpool, + ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_octeontx_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->session_mpool, + ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_octeontx_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->session_mpool, + ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), + BLKCIPHER_AUTHONLY_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 iv_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_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + memcpy(hash_key, key, key_len); + + debug_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.iv.offset = IV_OFFSET; + ut_params->auth_xform.auth.iv.length = iv_len; + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->auth_xform, + ts_params->session_priv_mpool); + 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 iv_len) +{ + uint8_t cipher_key[key_len]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + 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; + ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; + ut_params->cipher_xform.cipher.iv.length = iv_len; + + debug_hexdump(stdout, "key:", key, key_len); + + /* Create Crypto session */ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->cipher_xform, + ts_params->session_priv_mpool); + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + return 0; +} + +static int +create_wireless_algo_cipher_operation(const uint8_t *iv, uint8_t iv_len, + unsigned int cipher_len, + unsigned int cipher_offset) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + /* 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 */ + rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), + 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, uint8_t iv_len, + unsigned int cipher_len, + unsigned int cipher_offset) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + /* 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 */ + rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), + 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, uint8_t key_len, + uint8_t auth_iv_len, uint8_t auth_len, + uint8_t cipher_iv_len) + +{ + uint8_t cipher_auth_key[key_len]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + 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; + /* Auth IV will be after cipher IV */ + ut_params->auth_xform.auth.iv.offset = IV_OFFSET + cipher_iv_len; + ut_params->auth_xform.auth.iv.length = auth_iv_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; + ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; + ut_params->cipher_xform.cipher.iv.length = cipher_iv_len; + + debug_hexdump(stdout, "key:", key, key_len); + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->cipher_xform, + ts_params->session_priv_mpool); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + return 0; +} + +static int +create_wireless_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 struct wireless_test_data *tdata) +{ + const uint8_t key_len = tdata->key.len; + uint8_t cipher_auth_key[key_len]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + const uint8_t *key = tdata->key.data; + const uint8_t auth_len = tdata->digest.len; + uint8_t cipher_iv_len = tdata->cipher_iv.len; + uint8_t auth_iv_len = tdata->auth_iv.len; + + 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; + /* Auth IV will be after cipher IV */ + ut_params->auth_xform.auth.iv.offset = IV_OFFSET + cipher_iv_len; + ut_params->auth_xform.auth.iv.length = auth_iv_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; + ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; + ut_params->cipher_xform.cipher.iv.length = cipher_iv_len; + + + debug_hexdump(stdout, "key:", key, key_len); + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->cipher_xform, + ts_params->session_priv_mpool); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + return 0; +} + +static int +create_zuc_cipher_auth_encrypt_generate_session(uint8_t dev_id, + const struct wireless_test_data *tdata) +{ + return create_wireless_cipher_auth_session(dev_id, + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_AUTH_OP_GENERATE, RTE_CRYPTO_AUTH_ZUC_EIA3, + RTE_CRYPTO_CIPHER_ZUC_EEA3, tdata); +} + +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, + uint8_t auth_iv_len, uint8_t auth_len, + uint8_t cipher_iv_len) +{ + uint8_t auth_cipher_key[key_len]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + 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; + /* Auth IV will be after cipher IV */ + ut_params->auth_xform.auth.iv.offset = IV_OFFSET + cipher_iv_len; + ut_params->auth_xform.auth.iv.length = auth_iv_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; + ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; + ut_params->cipher_xform.cipher.iv.length = cipher_iv_len; + + debug_hexdump(stdout, "key:", key, key_len); + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->auth_xform, + ts_params->session_priv_mpool); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_wireless_algo_hash_operation(const uint8_t *auth_tag, + unsigned int auth_tag_len, + const uint8_t *iv, unsigned int iv_len, + unsigned int data_pad_len, + enum rte_crypto_auth_operation op, + unsigned int auth_len, unsigned int auth_offset) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + + struct crypto_unittest_params *ut_params = &unittest_params; + + /* 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 */ + rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), + iv, iv_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_iova_offset( + ut_params->ibuf, data_pad_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); + + debug_hexdump(stdout, "digest:", + sym_op->auth.digest.data, + auth_tag_len); + + sym_op->auth.data.length = auth_len; + sym_op->auth.data.offset = auth_offset; + + return 0; +} + +static int +create_wireless_cipher_hash_operation(const struct wireless_test_data *tdata, + enum rte_crypto_auth_operation op) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + const uint8_t *auth_tag = tdata->digest.data; + const unsigned int auth_tag_len = tdata->digest.len; + unsigned int plaintext_len = ceil_byte_length(tdata->plaintext.len); + unsigned int data_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); + + const uint8_t *cipher_iv = tdata->cipher_iv.data; + const uint8_t cipher_iv_len = tdata->cipher_iv.len; + const uint8_t *auth_iv = tdata->auth_iv.data; + const uint8_t auth_iv_len = tdata->auth_iv.len; + const unsigned int cipher_len = tdata->validCipherLenInBits.len; + const unsigned int auth_len = tdata->validAuthLenInBits.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_iova_offset( + ut_params->ibuf, data_pad_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); + + debug_hexdump(stdout, "digest:", + sym_op->auth.digest.data, + auth_tag_len); + + /* Copy cipher and auth IVs at the end of the crypto operation */ + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, + IV_OFFSET); + rte_memcpy(iv_ptr, cipher_iv, cipher_iv_len); + iv_ptr += cipher_iv_len; + rte_memcpy(iv_ptr, auth_iv, auth_iv_len); + + sym_op->cipher.data.length = cipher_len; + sym_op->cipher.data.offset = 0; + sym_op->auth.data.length = auth_len; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_zuc_cipher_hash_generate_operation( + const struct wireless_test_data *tdata) +{ + return create_wireless_cipher_hash_operation(tdata, + RTE_CRYPTO_AUTH_OP_GENERATE); +} + +static int +create_wireless_algo_cipher_hash_operation(const uint8_t *auth_tag, + const unsigned auth_tag_len, + const uint8_t *auth_iv, uint8_t auth_iv_len, + unsigned data_pad_len, + enum rte_crypto_auth_operation op, + const uint8_t *cipher_iv, uint8_t cipher_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; + + /* 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_iova_offset( + ut_params->ibuf, data_pad_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); + + debug_hexdump(stdout, "digest:", + sym_op->auth.digest.data, + auth_tag_len); + + /* Copy cipher and auth IVs at the end of the crypto operation */ + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, + IV_OFFSET); + rte_memcpy(iv_ptr, cipher_iv, cipher_iv_len); + iv_ptr += cipher_iv_len; + rte_memcpy(iv_ptr, auth_iv, auth_iv_len); + + sym_op->cipher.data.length = cipher_len; + sym_op->cipher.data.offset = cipher_offset; + sym_op->auth.data.length = auth_len; + sym_op->auth.data.offset = auth_offset; + + return 0; +} + +static int +create_wireless_algo_auth_cipher_operation(unsigned int auth_tag_len, + const uint8_t *cipher_iv, uint8_t cipher_iv_len, + const uint8_t *auth_iv, uint8_t auth_iv_len, + unsigned int data_pad_len, + unsigned int cipher_len, unsigned int cipher_offset, + unsigned int auth_len, unsigned int auth_offset) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + /* 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_iova_offset( + ut_params->ibuf, data_pad_len); + + memset(sym_op->auth.digest.data, 0, auth_tag_len); + + debug_hexdump(stdout, "digest:", + sym_op->auth.digest.data, + auth_tag_len); + + /* Copy cipher and auth IVs at the end of the crypto operation */ + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, + IV_OFFSET); + rte_memcpy(iv_ptr, cipher_iv, cipher_iv_len); + iv_ptr += cipher_iv_len; + rte_memcpy(iv_ptr, auth_iv, auth_iv_len); + + sym_op->cipher.data.length = cipher_len; + sym_op->cipher.data.offset = cipher_offset; + + sym_op->auth.data.length = auth_len; + sym_op->auth.data.offset = auth_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->auth_iv.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->auth_iv.data, tdata->auth_iv.len, + plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + tdata->validAuthLenInBits.len, + 0); + 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; + + /* 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->auth_iv.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->auth_iv.data, tdata->auth_iv.len, + plaintext_pad_len, + RTE_CRYPTO_AUTH_OP_VERIFY, + tdata->validAuthLenInBits.len, + 0); + 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; + + /* 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, + 0, 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, + NULL, 0, + plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + tdata->plaintext.len, + 0); + 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; + + /* 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, + 0, 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, + NULL, 0, + plaintext_pad_len, + RTE_CRYPTO_AUTH_OP_VERIFY, + tdata->plaintext.len, + 0); + 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; + + /* 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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create KASUMI operation */ + retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, + tdata->cipher_iv.len, + RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), + tdata->validCipherOffsetInBits.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_dst; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); + else + ciphertext = plaintext + (tdata->validCipherOffsetInBits.len >> 3); + + debug_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); + + const uint8_t *reference_ciphertext = tdata->ciphertext.data + + (tdata->validCipherOffsetInBits.len >> 3); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + reference_ciphertext, + 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); + + uint64_t feat_flags = dev_info.feature_flags; + + if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) { + printf("Device doesn't support in-place 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, + tdata->cipher_iv.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->cipher_iv.data, + tdata->cipher_iv.len, + RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), + tdata->validCipherOffsetInBits.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_dst; + + if (ut_params->obuf) + ciphertext = rte_pktmbuf_read(ut_params->obuf, 0, + plaintext_len, buffer); + else + ciphertext = rte_pktmbuf_read(ut_params->ibuf, + tdata->validCipherOffsetInBits.len >> 3, + plaintext_len, buffer); + + /* Validate obuf */ + debug_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); + + const uint8_t *reference_ciphertext = tdata->ciphertext.data + + (tdata->validCipherOffsetInBits.len >> 3); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + reference_ciphertext, + 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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create KASUMI operation */ + retval = create_wireless_algo_cipher_operation_oop(tdata->cipher_iv.data, + tdata->cipher_iv.len, + RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), + tdata->validCipherOffsetInBits.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_dst; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); + else + ciphertext = plaintext + (tdata->validCipherOffsetInBits.len >> 3); + + debug_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); + + const uint8_t *reference_ciphertext = tdata->ciphertext.data + + (tdata->validCipherOffsetInBits.len >> 3); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + reference_ciphertext, + 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); + + uint64_t feat_flags = dev_info.feature_flags; + if (!(feat_flags & RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT)) { + printf("Device doesn't support out-of-place scatter-gather " + "in both input and output mbufs. " + "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, + tdata->cipher_iv.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->cipher_iv.data, + tdata->cipher_iv.len, + RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), + tdata->validCipherOffsetInBits.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_dst; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_read(ut_params->obuf, 0, + plaintext_pad_len, buffer); + else + ciphertext = rte_pktmbuf_read(ut_params->ibuf, + tdata->validCipherOffsetInBits.len >> 3, + plaintext_pad_len, buffer); + + const uint8_t *reference_ciphertext = tdata->ciphertext.data + + (tdata->validCipherOffsetInBits.len >> 3); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + reference_ciphertext, + 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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "ciphertext:", ciphertext, ciphertext_len); + + /* Create KASUMI operation */ + retval = create_wireless_algo_cipher_operation_oop(tdata->cipher_iv.data, + tdata->cipher_iv.len, + RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), + tdata->validCipherOffsetInBits.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_dst; + if (ut_params->obuf) + plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); + else + plaintext = ciphertext + (tdata->validCipherOffsetInBits.len >> 3); + + debug_hexdump(stdout, "plaintext:", plaintext, ciphertext_len); + + const uint8_t *reference_plaintext = tdata->plaintext.data + + (tdata->validCipherOffsetInBits.len >> 3); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + plaintext, + reference_plaintext, + 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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "ciphertext:", ciphertext, ciphertext_len); + + /* Create KASUMI operation */ + retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, + tdata->cipher_iv.len, + tdata->ciphertext.len, + tdata->validCipherOffsetInBits.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_dst; + if (ut_params->obuf) + plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); + else + plaintext = ciphertext + (tdata->validCipherOffsetInBits.len >> 3); + + debug_hexdump(stdout, "plaintext:", plaintext, ciphertext_len); + + const uint8_t *reference_plaintext = tdata->plaintext.data + + (tdata->validCipherOffsetInBits.len >> 3); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + plaintext, + reference_plaintext, + 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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, + tdata->cipher_iv.len, + tdata->validCipherLenInBits.len, + 0); + 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 *); + else + ciphertext = plaintext; + + debug_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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_cipher_operation_oop(tdata->cipher_iv.data, + tdata->cipher_iv.len, + tdata->validCipherLenInBits.len, + 0); + 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 *); + else + ciphertext = plaintext; + + debug_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); + + uint64_t feat_flags = dev_info.feature_flags; + + if (!(feat_flags & RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT)) { + printf("Device doesn't support out-of-place scatter-gather " + "in both input and output mbufs. " + "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, + tdata->cipher_iv.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->cipher_iv.data, + tdata->cipher_iv.len, + tdata->validCipherLenInBits.len, + 0); + 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, 0, + plaintext_len, buffer); + else + ciphertext = rte_pktmbuf_read(ut_params->ibuf, 0, + plaintext_len, buffer); + + debug_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, + tdata->cipher_iv.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->cipher_iv.data, + tdata->cipher_iv.len, + tdata->validCipherLenInBits.len, + extra_offset); + 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 *); + else + ciphertext = plaintext; + +#ifdef RTE_APP_TEST_DEBUG + rte_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); +#endif + + expected_ciphertext_shifted = rte_malloc(NULL, plaintext_len, 8); + + 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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "ciphertext:", ciphertext, ciphertext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, + tdata->cipher_iv.len, + tdata->validCipherLenInBits.len, + 0); + 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 *); + else + plaintext = ciphertext; + + debug_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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "ciphertext:", ciphertext, ciphertext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_cipher_operation_oop(tdata->cipher_iv.data, + tdata->cipher_iv.len, + tdata->validCipherLenInBits.len, + 0); + 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 *); + else + plaintext = ciphertext; + + debug_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_zuc_cipher_auth(const struct wireless_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 int plaintext_pad_len; + unsigned int plaintext_len; + + struct rte_cryptodev_sym_capability_idx cap_idx; + + /* Check if device supports ZUC EEA3 */ + cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_ZUC_EEA3; + + if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], + &cap_idx) == NULL) + return -ENOTSUP; + + /* Check if device supports ZUC EIA3 */ + cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; + cap_idx.algo.auth = RTE_CRYPTO_AUTH_ZUC_EIA3; + + if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], + &cap_idx) == NULL) + return -ENOTSUP; + + /* Create ZUC session */ + retval = create_zuc_cipher_auth_encrypt_generate_session( + ts_params->valid_devs[0], + tdata); + 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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create ZUC operation */ + retval = create_zuc_cipher_hash_generate_operation(tdata); + 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 *); + else + ciphertext = plaintext; + + debug_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validDataLenInBits.len, + "ZUC Ciphertext data not as expected"); + + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len; + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ut_params->digest, + tdata->digest.data, + 4, + "ZUC Generated auth tag 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->auth_iv.len, tdata->digest.len, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_cipher_hash_operation(tdata->digest.data, + tdata->digest.len, tdata->auth_iv.data, + tdata->auth_iv.len, + plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + tdata->cipher_iv.data, tdata->cipher_iv.len, + tdata->validCipherLenInBits.len, + 0, + tdata->validAuthLenInBits.len, + 0 + ); + 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 *); + else + ciphertext = plaintext; + + debug_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; + + /* 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->auth_iv.len, tdata->digest.len, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create SNOW 3G operation */ + retval = create_wireless_algo_auth_cipher_operation( + tdata->digest.len, + tdata->cipher_iv.data, tdata->cipher_iv.len, + tdata->auth_iv.data, tdata->auth_iv.len, + plaintext_pad_len, + tdata->validCipherLenInBits.len, + 0, + tdata->validAuthLenInBits.len, + 0); + + 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 *); + else + ciphertext = plaintext; + + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len; + debug_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, + 0, tdata->digest.len, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create KASUMI operation */ + retval = create_wireless_algo_auth_cipher_operation(tdata->digest.len, + tdata->cipher_iv.data, tdata->cipher_iv.len, + NULL, 0, + plaintext_pad_len, + tdata->validCipherLenInBits.len, + tdata->validCipherOffsetInBits.len, + tdata->validAuthLenInBits.len, + 0 + ); + + 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"); + if (ut_params->op->sym->m_dst) + ut_params->obuf = ut_params->op->sym->m_dst; + else + ut_params->obuf = ut_params->op->sym->m_src; + + ciphertext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *, + tdata->validCipherOffsetInBits.len >> 3); + + const uint8_t *reference_ciphertext = tdata->ciphertext.data + + (tdata->validCipherOffsetInBits.len >> 3); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + reference_ciphertext, + tdata->validCipherLenInBits.len, + "KASUMI Ciphertext data not as expected"); + ut_params->digest = rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *) + + plaintext_pad_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, + 0, tdata->digest.len, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create KASUMI operation */ + retval = create_wireless_algo_cipher_hash_operation(tdata->digest.data, + tdata->digest.len, NULL, 0, + plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + tdata->cipher_iv.data, tdata->cipher_iv.len, + RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), + tdata->validCipherOffsetInBits.len, + tdata->validAuthLenInBits.len, + 0 + ); + 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"); + + if (ut_params->op->sym->m_dst) + ut_params->obuf = ut_params->op->sym->m_dst; + else + ut_params->obuf = ut_params->op->sym->m_src; + + ciphertext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *, + tdata->validCipherOffsetInBits.len >> 3); + + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len; + + const uint8_t *reference_ciphertext = tdata->ciphertext.data + + (tdata->validCipherOffsetInBits.len >> 3); + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + reference_ciphertext, + 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 wireless_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; + + struct rte_cryptodev_sym_capability_idx cap_idx; + + /* Check if device supports ZUC EEA3 */ + cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_ZUC_EEA3; + + if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], + &cap_idx) == NULL) + return -ENOTSUP; + + /* 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, + tdata->cipher_iv.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); + + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create ZUC operation */ + retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, + tdata->cipher_iv.len, + tdata->plaintext.len, + 0); + 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 *); + else + ciphertext = plaintext; + + debug_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 wireless_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; + + struct rte_cryptodev_sym_capability_idx cap_idx; + + /* Check if device supports ZUC EEA3 */ + cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_ZUC_EEA3; + + if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], + &cap_idx) == NULL) + return -ENOTSUP; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + uint64_t feat_flags = dev_info.feature_flags; + + if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) { + printf("Device doesn't support in-place 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, + tdata->cipher_iv.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->cipher_iv.data, + tdata->cipher_iv.len, tdata->plaintext.len, + 0); + 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, + 0, plaintext_len, ciphertext_buffer); + else + ciphertext = rte_pktmbuf_read(ut_params->ibuf, + 0, plaintext_len, ciphertext_buffer); + + /* Validate obuf */ + debug_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 wireless_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; + + struct rte_cryptodev_sym_capability_idx cap_idx; + + /* Check if device supports ZUC EIA3 */ + cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; + cap_idx.algo.auth = RTE_CRYPTO_AUTH_ZUC_EIA3; + + if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], + &cap_idx) == NULL) + return -ENOTSUP; + + /* Create ZUC session */ + retval = create_wireless_algo_hash_session(ts_params->valid_devs[0], + tdata->key.data, tdata->key.len, + tdata->auth_iv.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->auth_iv.data, tdata->auth_iv.len, + plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + tdata->validAuthLenInBits.len, + 0); + 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; + + /* 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_cipher_193b); +} + +static int +test_zuc_encryption_test_case_2(void) +{ + return test_zuc_encryption(&zuc_test_case_cipher_800b); +} + +static int +test_zuc_encryption_test_case_3(void) +{ + return test_zuc_encryption(&zuc_test_case_cipher_1570b); +} + +static int +test_zuc_encryption_test_case_4(void) +{ + return test_zuc_encryption(&zuc_test_case_cipher_2798b); +} + +static int +test_zuc_encryption_test_case_5(void) +{ + return test_zuc_encryption(&zuc_test_case_cipher_4019b); +} + +static int +test_zuc_encryption_test_case_6_sgl(void) +{ + return test_zuc_encryption_sgl(&zuc_test_case_cipher_193b); +} + +static int +test_zuc_hash_generate_test_case_1(void) +{ + return test_zuc_authentication(&zuc_test_case_auth_1b); +} + +static int +test_zuc_hash_generate_test_case_2(void) +{ + return test_zuc_authentication(&zuc_test_case_auth_90b); +} + +static int +test_zuc_hash_generate_test_case_3(void) +{ + return test_zuc_authentication(&zuc_test_case_auth_577b); +} + +static int +test_zuc_hash_generate_test_case_4(void) +{ + return test_zuc_authentication(&zuc_test_case_auth_2079b); +} + +static int +test_zuc_hash_generate_test_case_5(void) +{ + return test_zuc_authentication(&zuc_test_auth_5670b); +} + +static int +test_zuc_hash_generate_test_case_6(void) +{ + return test_zuc_authentication(&zuc_test_case_auth_128b); +} + +static int +test_zuc_hash_generate_test_case_7(void) +{ + return test_zuc_authentication(&zuc_test_case_auth_2080b); +} + +static int +test_zuc_hash_generate_test_case_8(void) +{ + return test_zuc_authentication(&zuc_test_case_auth_584b); +} + +static int +test_zuc_cipher_auth_test_case_1(void) +{ + return test_zuc_cipher_auth(&zuc_test_case_cipher_200b_auth_200b); +} + +static int +test_zuc_cipher_auth_test_case_2(void) +{ + return test_zuc_cipher_auth(&zuc_test_case_cipher_800b_auth_120b); +} + +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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)), + BLKCIPHER_DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_DES_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), + BLKCIPHER_DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_DES_docsis_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), + BLKCIPHER_DES_DOCSIS_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_DES_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), + BLKCIPHER_DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} +static int +test_3DES_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_DES_docsis_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), + BLKCIPHER_DES_DOCSIS_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_caam_jr_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_caam_jr_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_ccp_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_PMD)), + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_ccp_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_PMD)), + BLKCIPHER_3DES_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, + ts_params->valid_devs[0], + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +/* ***** AEAD algorithm Tests ***** */ + +static int +create_aead_session(uint8_t dev_id, enum rte_crypto_aead_algorithm algo, + enum rte_crypto_aead_operation op, + const uint8_t *key, const uint8_t key_len, + const uint16_t aad_len, const uint8_t auth_len, + uint8_t iv_len) +{ + uint8_t aead_key[key_len]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + memcpy(aead_key, key, key_len); + + /* Setup AEAD Parameters */ + ut_params->aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD; + ut_params->aead_xform.next = NULL; + ut_params->aead_xform.aead.algo = algo; + ut_params->aead_xform.aead.op = op; + ut_params->aead_xform.aead.key.data = aead_key; + ut_params->aead_xform.aead.key.length = key_len; + ut_params->aead_xform.aead.iv.offset = IV_OFFSET; + ut_params->aead_xform.aead.iv.length = iv_len; + ut_params->aead_xform.aead.digest_length = auth_len; + ut_params->aead_xform.aead.aad_length = aad_len; + + debug_hexdump(stdout, "key:", key, key_len); + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->aead_xform, + ts_params->session_priv_mpool); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_aead_xform(struct rte_crypto_op *op, + enum rte_crypto_aead_algorithm algo, + enum rte_crypto_aead_operation aead_op, + uint8_t *key, const uint8_t key_len, + const uint8_t aad_len, const uint8_t auth_len, + uint8_t iv_len) +{ + TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(op, 1), + "failed to allocate space for crypto transform"); + + struct rte_crypto_sym_op *sym_op = op->sym; + + /* Setup AEAD Parameters */ + sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; + sym_op->xform->next = NULL; + sym_op->xform->aead.algo = algo; + sym_op->xform->aead.op = aead_op; + sym_op->xform->aead.key.data = key; + sym_op->xform->aead.key.length = key_len; + sym_op->xform->aead.iv.offset = IV_OFFSET; + sym_op->xform->aead.iv.length = iv_len; + sym_op->xform->aead.digest_length = auth_len; + sym_op->xform->aead.aad_length = aad_len; + + debug_hexdump(stdout, "key:", key, key_len); + + return 0; +} + +static int +create_aead_operation(enum rte_crypto_aead_operation op, + const struct aead_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 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 */ + if (tdata->algo == RTE_CRYPTO_AEAD_AES_CCM) { + aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len + 18, 16); + sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + aad_pad_len); + TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, + "no room to append aad"); + + sym_op->aead.aad.phys_addr = + rte_pktmbuf_iova(ut_params->ibuf); + /* Copy AAD 18 bytes after the AAD pointer, according to the API */ + memcpy(sym_op->aead.aad.data + 18, tdata->aad.data, tdata->aad.len); + debug_hexdump(stdout, "aad:", sym_op->aead.aad.data, + tdata->aad.len); + + /* Append IV at the end of the crypto operation*/ + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, + uint8_t *, IV_OFFSET); + + /* Copy IV 1 byte after the IV pointer, according to the API */ + rte_memcpy(iv_ptr + 1, tdata->iv.data, tdata->iv.len); + debug_hexdump(stdout, "iv:", iv_ptr, + tdata->iv.len); + } else { + aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); + sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + aad_pad_len); + TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, + "no room to append aad"); + + sym_op->aead.aad.phys_addr = + rte_pktmbuf_iova(ut_params->ibuf); + memcpy(sym_op->aead.aad.data, tdata->aad.data, tdata->aad.len); + debug_hexdump(stdout, "aad:", sym_op->aead.aad.data, + tdata->aad.len); + + /* Append IV at the end of the crypto operation*/ + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, + uint8_t *, IV_OFFSET); + + rte_memcpy(iv_ptr, tdata->iv.data, tdata->iv.len); + debug_hexdump(stdout, "iv:", iv_ptr, + tdata->iv.len); + } + + /* Append plaintext/ciphertext */ + if (op == RTE_CRYPTO_AEAD_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); + debug_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); + TEST_ASSERT_NOT_NULL(ciphertext, + "no room to append ciphertext"); + + memset(ciphertext + aad_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); + debug_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); + TEST_ASSERT_NOT_NULL(plaintext, + "no room to append plaintext"); + + memset(plaintext + aad_pad_len, 0, + tdata->plaintext.len); + } + } + + /* Append digest data */ + if (op == RTE_CRYPTO_AEAD_OP_ENCRYPT) { + sym_op->aead.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->aead.digest.data, + "no room to append digest"); + memset(sym_op->aead.digest.data, 0, tdata->auth_tag.len); + sym_op->aead.digest.phys_addr = rte_pktmbuf_iova_offset( + ut_params->obuf ? ut_params->obuf : + ut_params->ibuf, + plaintext_pad_len + + aad_pad_len); + } else { + sym_op->aead.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, tdata->auth_tag.len); + TEST_ASSERT_NOT_NULL(sym_op->aead.digest.data, + "no room to append digest"); + sym_op->aead.digest.phys_addr = rte_pktmbuf_iova_offset( + ut_params->ibuf, + plaintext_pad_len + aad_pad_len); + + rte_memcpy(sym_op->aead.digest.data, tdata->auth_tag.data, + tdata->auth_tag.len); + debug_hexdump(stdout, "digest:", + sym_op->aead.digest.data, + tdata->auth_tag.len); + } + + sym_op->aead.data.length = tdata->plaintext.len; + sym_op->aead.data.offset = aad_pad_len; + + return 0; +} + +static int +test_authenticated_encryption(const struct aead_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 AEAD session */ + retval = create_aead_session(ts_params->valid_devs[0], + tdata->algo, + RTE_CRYPTO_AEAD_OP_ENCRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + tdata->iv.len); + 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 < 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 AEAD operation */ + retval = create_aead_operation(RTE_CRYPTO_AEAD_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; + } + + debug_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + debug_hexdump(stdout, "auth tag:", auth_tag, tdata->auth_tag.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ciphertext, + tdata->ciphertext.data, + tdata->ciphertext.len, + "Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + tdata->auth_tag.data, + tdata->auth_tag.len, + "Generated auth tag not as expected"); + + return 0; + +} + +static int +test_AES_GCM_authenticated_encryption_test_case_1(void) +{ + return test_authenticated_encryption(&gcm_test_case_1); +} + +static int +test_AES_GCM_authenticated_encryption_test_case_2(void) +{ + return test_authenticated_encryption(&gcm_test_case_2); +} + +static int +test_AES_GCM_authenticated_encryption_test_case_3(void) +{ + return test_authenticated_encryption(&gcm_test_case_3); +} + +static int +test_AES_GCM_authenticated_encryption_test_case_4(void) +{ + return test_authenticated_encryption(&gcm_test_case_4); +} + +static int +test_AES_GCM_authenticated_encryption_test_case_5(void) +{ + return test_authenticated_encryption(&gcm_test_case_5); +} + +static int +test_AES_GCM_authenticated_encryption_test_case_6(void) +{ + return test_authenticated_encryption(&gcm_test_case_6); +} + +static int +test_AES_GCM_authenticated_encryption_test_case_7(void) +{ + return test_authenticated_encryption(&gcm_test_case_7); +} + +static int +test_AES_GCM_auth_encryption_test_case_192_1(void) +{ + return test_authenticated_encryption(&gcm_test_case_192_1); +} + +static int +test_AES_GCM_auth_encryption_test_case_192_2(void) +{ + return test_authenticated_encryption(&gcm_test_case_192_2); +} + +static int +test_AES_GCM_auth_encryption_test_case_192_3(void) +{ + return test_authenticated_encryption(&gcm_test_case_192_3); +} + +static int +test_AES_GCM_auth_encryption_test_case_192_4(void) +{ + return test_authenticated_encryption(&gcm_test_case_192_4); +} + +static int +test_AES_GCM_auth_encryption_test_case_192_5(void) +{ + return test_authenticated_encryption(&gcm_test_case_192_5); +} + +static int +test_AES_GCM_auth_encryption_test_case_192_6(void) +{ + return test_authenticated_encryption(&gcm_test_case_192_6); +} + +static int +test_AES_GCM_auth_encryption_test_case_192_7(void) +{ + return test_authenticated_encryption(&gcm_test_case_192_7); +} + +static int +test_AES_GCM_auth_encryption_test_case_256_1(void) +{ + return test_authenticated_encryption(&gcm_test_case_256_1); +} + +static int +test_AES_GCM_auth_encryption_test_case_256_2(void) +{ + return test_authenticated_encryption(&gcm_test_case_256_2); +} + +static int +test_AES_GCM_auth_encryption_test_case_256_3(void) +{ + return test_authenticated_encryption(&gcm_test_case_256_3); +} + +static int +test_AES_GCM_auth_encryption_test_case_256_4(void) +{ + return test_authenticated_encryption(&gcm_test_case_256_4); +} + +static int +test_AES_GCM_auth_encryption_test_case_256_5(void) +{ + return test_authenticated_encryption(&gcm_test_case_256_5); +} + +static int +test_AES_GCM_auth_encryption_test_case_256_6(void) +{ + return test_authenticated_encryption(&gcm_test_case_256_6); +} + +static int +test_AES_GCM_auth_encryption_test_case_256_7(void) +{ + return test_authenticated_encryption(&gcm_test_case_256_7); +} + +static int +test_AES_GCM_auth_encryption_test_case_aad_1(void) +{ + return test_authenticated_encryption(&gcm_test_case_aad_1); +} + +static int +test_AES_GCM_auth_encryption_test_case_aad_2(void) +{ + return test_authenticated_encryption(&gcm_test_case_aad_2); +} + +static int +test_authenticated_decryption(const struct aead_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 AEAD session */ + retval = create_aead_session(ts_params->valid_devs[0], + tdata->algo, + RTE_CRYPTO_AEAD_OP_DECRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + tdata->iv.len); + 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 < 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 AEAD operation */ + retval = create_aead_operation(RTE_CRYPTO_AEAD_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); + + debug_hexdump(stdout, "plaintext:", plaintext, tdata->ciphertext.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + plaintext, + tdata->plaintext.data, + tdata->plaintext.len, + "Plaintext data not as expected"); + + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_SUCCESS, + "Authentication failed"); + return 0; +} + +static int +test_AES_GCM_authenticated_decryption_test_case_1(void) +{ + return test_authenticated_decryption(&gcm_test_case_1); +} + +static int +test_AES_GCM_authenticated_decryption_test_case_2(void) +{ + return test_authenticated_decryption(&gcm_test_case_2); +} + +static int +test_AES_GCM_authenticated_decryption_test_case_3(void) +{ + return test_authenticated_decryption(&gcm_test_case_3); +} + +static int +test_AES_GCM_authenticated_decryption_test_case_4(void) +{ + return test_authenticated_decryption(&gcm_test_case_4); +} + +static int +test_AES_GCM_authenticated_decryption_test_case_5(void) +{ + return test_authenticated_decryption(&gcm_test_case_5); +} + +static int +test_AES_GCM_authenticated_decryption_test_case_6(void) +{ + return test_authenticated_decryption(&gcm_test_case_6); +} + +static int +test_AES_GCM_authenticated_decryption_test_case_7(void) +{ + return test_authenticated_decryption(&gcm_test_case_7); +} + +static int +test_AES_GCM_auth_decryption_test_case_192_1(void) +{ + return test_authenticated_decryption(&gcm_test_case_192_1); +} + +static int +test_AES_GCM_auth_decryption_test_case_192_2(void) +{ + return test_authenticated_decryption(&gcm_test_case_192_2); +} + +static int +test_AES_GCM_auth_decryption_test_case_192_3(void) +{ + return test_authenticated_decryption(&gcm_test_case_192_3); +} + +static int +test_AES_GCM_auth_decryption_test_case_192_4(void) +{ + return test_authenticated_decryption(&gcm_test_case_192_4); +} + +static int +test_AES_GCM_auth_decryption_test_case_192_5(void) +{ + return test_authenticated_decryption(&gcm_test_case_192_5); +} + +static int +test_AES_GCM_auth_decryption_test_case_192_6(void) +{ + return test_authenticated_decryption(&gcm_test_case_192_6); +} + +static int +test_AES_GCM_auth_decryption_test_case_192_7(void) +{ + return test_authenticated_decryption(&gcm_test_case_192_7); +} + +static int +test_AES_GCM_auth_decryption_test_case_256_1(void) +{ + return test_authenticated_decryption(&gcm_test_case_256_1); +} + +static int +test_AES_GCM_auth_decryption_test_case_256_2(void) +{ + return test_authenticated_decryption(&gcm_test_case_256_2); +} + +static int +test_AES_GCM_auth_decryption_test_case_256_3(void) +{ + return test_authenticated_decryption(&gcm_test_case_256_3); +} + +static int +test_AES_GCM_auth_decryption_test_case_256_4(void) +{ + return test_authenticated_decryption(&gcm_test_case_256_4); +} + +static int +test_AES_GCM_auth_decryption_test_case_256_5(void) +{ + return test_authenticated_decryption(&gcm_test_case_256_5); +} + +static int +test_AES_GCM_auth_decryption_test_case_256_6(void) +{ + return test_authenticated_decryption(&gcm_test_case_256_6); +} + +static int +test_AES_GCM_auth_decryption_test_case_256_7(void) +{ + return test_authenticated_decryption(&gcm_test_case_256_7); +} + +static int +test_AES_GCM_auth_decryption_test_case_aad_1(void) +{ + return test_authenticated_decryption(&gcm_test_case_aad_1); +} + +static int +test_AES_GCM_auth_decryption_test_case_aad_2(void) +{ + return test_authenticated_decryption(&gcm_test_case_aad_2); +} + +static int +test_authenticated_encryption_oop(const struct aead_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 AEAD session */ + retval = create_aead_session(ts_params->valid_devs[0], + tdata->algo, + RTE_CRYPTO_AEAD_OP_ENCRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + tdata->iv.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)); + memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->obuf)); + + /* Create AEAD operation */ + retval = create_aead_operation(RTE_CRYPTO_AEAD_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; + + debug_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + debug_hexdump(stdout, "auth tag:", auth_tag, tdata->auth_tag.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ciphertext, + tdata->ciphertext.data, + tdata->ciphertext.len, + "Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + tdata->auth_tag.data, + tdata->auth_tag.len, + "Generated auth tag not as expected"); + + return 0; + +} + +static int +test_AES_GCM_authenticated_encryption_oop_test_case_1(void) +{ + return test_authenticated_encryption_oop(&gcm_test_case_5); +} + +static int +test_authenticated_decryption_oop(const struct aead_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 AEAD session */ + retval = create_aead_session(ts_params->valid_devs[0], + tdata->algo, + RTE_CRYPTO_AEAD_OP_DECRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + tdata->iv.len); + 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 AEAD operation */ + retval = create_aead_operation(RTE_CRYPTO_AEAD_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); + + debug_hexdump(stdout, "plaintext:", plaintext, tdata->ciphertext.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + plaintext, + tdata->plaintext.data, + tdata->plaintext.len, + "Plaintext data not as expected"); + + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_SUCCESS, + "Authentication failed"); + return 0; +} + +static int +test_AES_GCM_authenticated_decryption_oop_test_case_1(void) +{ + return test_authenticated_decryption_oop(&gcm_test_case_5); +} + +static int +test_authenticated_encryption_sessionless( + const struct aead_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 AEAD operation */ + retval = create_aead_operation(RTE_CRYPTO_AEAD_OP_ENCRYPT, tdata); + if (retval < 0) + return retval; + + /* Create GCM xform */ + memcpy(key, tdata->key.data, tdata->key.len); + retval = create_aead_xform(ut_params->op, + tdata->algo, + RTE_CRYPTO_AEAD_OP_ENCRYPT, + key, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + tdata->iv.len); + if (retval < 0) + return retval; + + ut_params->op->sym->m_src = ut_params->ibuf; + + TEST_ASSERT_EQUAL(ut_params->op->sess_type, + RTE_CRYPTO_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; + + debug_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + debug_hexdump(stdout, "auth tag:", auth_tag, tdata->auth_tag.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ciphertext, + tdata->ciphertext.data, + tdata->ciphertext.len, + "Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + auth_tag, + tdata->auth_tag.data, + tdata->auth_tag.len, + "Generated auth tag not as expected"); + + return 0; + +} + +static int +test_AES_GCM_authenticated_encryption_sessionless_test_case_1(void) +{ + return test_authenticated_encryption_sessionless( + &gcm_test_case_5); +} + +static int +test_authenticated_decryption_sessionless( + const struct aead_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 AEAD operation */ + retval = create_aead_operation(RTE_CRYPTO_AEAD_OP_DECRYPT, tdata); + if (retval < 0) + return retval; + + /* Create AEAD xform */ + memcpy(key, tdata->key.data, tdata->key.len); + retval = create_aead_xform(ut_params->op, + tdata->algo, + RTE_CRYPTO_AEAD_OP_DECRYPT, + key, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + tdata->iv.len); + if (retval < 0) + return retval; + + ut_params->op->sym->m_src = ut_params->ibuf; + + TEST_ASSERT_EQUAL(ut_params->op->sess_type, + RTE_CRYPTO_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); + + debug_hexdump(stdout, "plaintext:", plaintext, tdata->ciphertext.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + plaintext, + tdata->plaintext.data, + tdata->plaintext.len, + "Plaintext data not as expected"); + + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_SUCCESS, + "Authentication failed"); + return 0; +} + +static int +test_AES_GCM_authenticated_decryption_sessionless_test_case_1(void) +{ + return test_authenticated_decryption_sessionless( + &gcm_test_case_5); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_128_1(void) +{ + return test_authenticated_encryption(&ccm_test_case_128_1); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_128_2(void) +{ + return test_authenticated_encryption(&ccm_test_case_128_2); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_128_3(void) +{ + return test_authenticated_encryption(&ccm_test_case_128_3); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_128_1(void) +{ + return test_authenticated_decryption(&ccm_test_case_128_1); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_128_2(void) +{ + return test_authenticated_decryption(&ccm_test_case_128_2); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_128_3(void) +{ + return test_authenticated_decryption(&ccm_test_case_128_3); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_192_1(void) +{ + return test_authenticated_encryption(&ccm_test_case_192_1); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_192_2(void) +{ + return test_authenticated_encryption(&ccm_test_case_192_2); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_192_3(void) +{ + return test_authenticated_encryption(&ccm_test_case_192_3); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_192_1(void) +{ + return test_authenticated_decryption(&ccm_test_case_192_1); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_192_2(void) +{ + return test_authenticated_decryption(&ccm_test_case_192_2); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_192_3(void) +{ + return test_authenticated_decryption(&ccm_test_case_192_3); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_256_1(void) +{ + return test_authenticated_encryption(&ccm_test_case_256_1); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_256_2(void) +{ + return test_authenticated_encryption(&ccm_test_case_256_2); +} + +static int +test_AES_CCM_authenticated_encryption_test_case_256_3(void) +{ + return test_authenticated_encryption(&ccm_test_case_256_3); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_256_1(void) +{ + return test_authenticated_decryption(&ccm_test_case_256_1); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_256_2(void) +{ + return test_authenticated_decryption(&ccm_test_case_256_2); +} + +static int +test_AES_CCM_authenticated_decryption_test_case_256_3(void) +{ + return test_authenticated_decryption(&ccm_test_case_256_3); +} + +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.key.length = test_case->key.len; + ut_params->auth_xform.auth.key.data = key; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, &ut_params->auth_xform, + ts_params->session_priv_mpool); + + 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_iova_offset( + ut_params->ibuf, plaintext_pad_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 *) * + MAX_NB_SESSIONS) + 1, 0); + + /* Create multiple crypto sessions*/ + for (i = 0; i < MAX_NB_SESSIONS; i++) { + + sessions[i] = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + sessions[i], &ut_params->auth_xform, + ts_params->session_priv_mpool); + 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 */ + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + sessions[i], &ut_params->auth_xform, + ts_params->session_priv_mpool); + TEST_ASSERT_NULL(sessions[i], + "Session creation succeeded unexpectedly!"); + + for (i = 0; i < MAX_NB_SESSIONS; i++) { + rte_cryptodev_sym_session_clear(ts_params->valid_devs[0], + sessions[i]); + rte_cryptodev_sym_session_free(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 *) + * MAX_NB_SESSIONS) + 1, 0); + + for (i = 0; i < MB_SESSION_NUMBER; i++) { + sessions[i] = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_memcpy(&ut_paramz[i].ut_params, &unittest_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*/ + rte_cryptodev_sym_session_init( + ts_params->valid_devs[0], + sessions[i], + &ut_paramz[i].ut_params.auth_xform, + ts_params->session_priv_mpool); + + 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_clear(ts_params->valid_devs[0], + sessions[i]); + rte_cryptodev_sym_session_free(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; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + /* Create Crypto session*/ + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, + &ut_params->cipher_xform, + ts_params->session_priv_mpool); + 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; +} +uint8_t orig_data[] = {0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab}; +static int +test_null_auth_only_operation(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + uint8_t *digest; + + /* 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); + + /* create a pointer for digest, but don't expect anything to be written + * here in a NULL auth algo so no mbuf append done. + */ + digest = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, + QUOTE_512_BYTES); + /* prefill the memory pointed to by digest */ + memcpy(digest, orig_data, sizeof(orig_data)); + + /* 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; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + /* Create Crypto session*/ + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, &ut_params->auth_xform, + ts_params->session_priv_mpool); + 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; + sym_op->auth.digest.data = digest; + sym_op->auth.digest.phys_addr = rte_pktmbuf_iova_offset(ut_params->ibuf, + 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"); + /* Make sure memory pointed to by digest hasn't been overwritten */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + orig_data, + digest, + sizeof(orig_data), + "Memory at digest ptr overwritten unexpectedly"); + + 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; + uint8_t *digest; + + /* 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); + + /* create a pointer for digest, but don't expect anything to be written + * here in a NULL auth algo so no mbuf append done. + */ + digest = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, + QUOTE_512_BYTES); + /* prefill the memory pointed to by digest */ + memcpy(digest, orig_data, sizeof(orig_data)); + + /* 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; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + /* Create Crypto session*/ + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, &ut_params->cipher_xform, + ts_params->session_priv_mpool); + 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; + sym_op->auth.digest.data = digest; + sym_op->auth.digest.phys_addr = rte_pktmbuf_iova_offset(ut_params->ibuf, + 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"); + /* Make sure memory pointed to by digest hasn't been overwritten */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + orig_data, + digest, + sizeof(orig_data), + "Memory at digest ptr overwritten unexpectedly"); + + 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; + uint8_t *digest; + + /* Generate test mbuf data */ + ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, + catch_22_quote, QUOTE_512_BYTES, 0); + + /* create a pointer for digest, but don't expect anything to be written + * here in a NULL auth algo so no mbuf append done. + */ + digest = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, + QUOTE_512_BYTES); + /* prefill the memory pointed to by digest */ + memcpy(digest, orig_data, sizeof(orig_data)); + + /* 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; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + /* Create Crypto session*/ + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, &ut_params->cipher_xform, + ts_params->session_priv_mpool); + 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; + sym_op->auth.digest.data = digest; + sym_op->auth.digest.phys_addr = rte_pktmbuf_iova_offset(ut_params->ibuf, + 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"); + /* Make sure memory pointed to by digest hasn't been overwritten */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + orig_data, + digest, + sizeof(orig_data), + "Memory at digest ptr overwritten unexpectedly"); + + 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; + int ret; + + /* 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; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + /* Create Crypto session*/ + ret = rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, &ut_params->cipher_xform, + ts_params->session_priv_mpool); + TEST_ASSERT(ret < 0, + "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; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + /* Create Crypto session*/ + ret = rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, &ut_params->auth_xform, + ts_params->session_priv_mpool); + TEST_ASSERT(ret < 0, + "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; + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + /* Create Crypto session*/ + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + ut_params->sess, &ut_params->cipher_xform, + ts_params->session_priv_mpool); + 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; + + uint32_t plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); + + /* 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.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_iova_offset( + ut_params->ibuf, plaintext_pad_len); + + if (op == RTE_CRYPTO_AUTH_OP_VERIFY) { + rte_memcpy(sym_op->auth.digest.data, tdata->gmac_tag.data, + tdata->gmac_tag.len); + debug_hexdump(stdout, "digest:", + sym_op->auth.digest.data, + tdata->gmac_tag.len); + } + + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, + uint8_t *, IV_OFFSET); + + rte_memcpy(iv_ptr, tdata->iv.data, tdata->iv.len); + + debug_hexdump(stdout, "iv:", iv_ptr, tdata->iv.len); + + sym_op->cipher.data.length = 0; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.offset = 0; + sym_op->auth.data.length = tdata->plaintext.len; + + return 0; +} + +static int create_gmac_session(uint8_t dev_id, + const struct gmac_test_data *tdata, + enum rte_crypto_auth_operation auth_op) +{ + uint8_t auth_key[tdata->key.len]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + memcpy(auth_key, tdata->key.data, 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.key.length = tdata->key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.iv.offset = IV_OFFSET; + ut_params->auth_xform.auth.iv.length = tdata->iv.len; + + + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->auth_xform, + ts_params->session_priv_mpool); + + 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, *plaintext; + uint16_t plaintext_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], + tdata, RTE_CRYPTO_AUTH_OP_GENERATE); + + if (retval < 0) + return retval; + + if (tdata->plaintext.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)); + + plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.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->plaintext.len == GMAC_LARGE_PLAINTEXT_LENGTH) + generate_gmac_large_plaintext(tdata->plaintext.data); + + 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); + debug_hexdump(stdout, "plaintext:", plaintext, + tdata->plaintext.len); + + 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 *, plaintext_pad_len); + } else { + auth_tag = plaintext + plaintext_pad_len; + } + + debug_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; + uint32_t plaintext_pad_len; + uint8_t *plaintext; + + 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], + tdata, RTE_CRYPTO_AUTH_OP_VERIFY); + + if (retval < 0) + return retval; + + if (tdata->plaintext.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)); + + plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.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->plaintext.len == GMAC_LARGE_PLAINTEXT_LENGTH) + generate_gmac_large_plaintext(tdata->plaintext.data); + + 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); + debug_hexdump(stdout, "plaintext:", plaintext, + tdata->plaintext.len); + + 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, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B + }, + .len = 12 + }, + .auth_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) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + 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; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->auth_xform, + ts_params->session_priv_mpool); + + 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) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + 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.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; + + if (reference->auth_algo == RTE_CRYPTO_AUTH_AES_GMAC) { + ut_params->auth_xform.auth.iv.offset = IV_OFFSET; + ut_params->auth_xform.auth.iv.length = reference->iv.len; + } else { + ut_params->auth_xform.next = &ut_params->cipher_xform; + + /* 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; + ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; + ut_params->cipher_xform.cipher.iv.length = reference->iv.len; + } + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create( + ts_params->session_mpool); + + rte_cryptodev_sym_session_init(dev_id, ut_params->sess, + &ut_params->auth_xform, + ts_params->session_priv_mpool); + + 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_iova_offset( + ut_params->ibuf, reference->plaintext.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); + + debug_hexdump(stdout, "digest:", + sym_op->auth.digest.data, + reference->digest.len); + + 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; + + /* 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_iova_offset( + ut_params->ibuf, reference->ciphertext.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); + + debug_hexdump(stdout, "digest:", + sym_op->auth.digest.data, + reference->digest.len); + + rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), + reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = 0; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.length = reference->plaintext.len; + 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_iova_offset( + ut_params->ibuf, reference->ciphertext.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); + + debug_hexdump(stdout, "digest:", + sym_op->auth.digest.data, + reference->digest.len); + + rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), + reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = reference->ciphertext.len; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.length = reference->ciphertext.len; + sym_op->auth.data.offset = 0; + + 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); + + debug_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; + uint8_t *plaintext; + + /* 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)); + + 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); + + debug_hexdump(stdout, "plaintext:", plaintext, + reference->plaintext.len); + + /* Create operation */ + retval = create_auth_verify_GMAC_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(plaintext); + else + tag_corruption(plaintext, 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_aead_operation_SGL(enum rte_crypto_aead_operation op, + const struct aead_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; + unsigned int aad_len = tdata->aad.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; + + sym_op->aead.digest.data = digest_mem; + + TEST_ASSERT_NOT_NULL(sym_op->aead.digest.data, + "no room to append digest"); + + sym_op->aead.digest.phys_addr = digest_phys; + + if (op == RTE_CRYPTO_AEAD_OP_DECRYPT) { + rte_memcpy(sym_op->aead.digest.data, tdata->auth_tag.data, + auth_tag_len); + debug_hexdump(stdout, "digest:", + sym_op->aead.digest.data, + auth_tag_len); + } + + /* Append aad data */ + if (tdata->algo == RTE_CRYPTO_AEAD_AES_CCM) { + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, + uint8_t *, IV_OFFSET); + + /* Copy IV 1 byte after the IV pointer, according to the API */ + rte_memcpy(iv_ptr + 1, tdata->iv.data, iv_len); + + aad_len = RTE_ALIGN_CEIL(aad_len + 18, 16); + + sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, aad_len); + TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, + "no room to prepend aad"); + sym_op->aead.aad.phys_addr = rte_pktmbuf_iova( + ut_params->ibuf); + + memset(sym_op->aead.aad.data, 0, aad_len); + /* Copy AAD 18 bytes after the AAD pointer, according to the API */ + rte_memcpy(sym_op->aead.aad.data, tdata->aad.data, aad_len); + + debug_hexdump(stdout, "iv:", iv_ptr, iv_len); + debug_hexdump(stdout, "aad:", + sym_op->aead.aad.data, aad_len); + } else { + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, + uint8_t *, IV_OFFSET); + + rte_memcpy(iv_ptr, tdata->iv.data, iv_len); + + sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, aad_len); + TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, + "no room to prepend aad"); + sym_op->aead.aad.phys_addr = rte_pktmbuf_iova( + ut_params->ibuf); + + memset(sym_op->aead.aad.data, 0, aad_len); + rte_memcpy(sym_op->aead.aad.data, tdata->aad.data, aad_len); + + debug_hexdump(stdout, "iv:", iv_ptr, iv_len); + debug_hexdump(stdout, "aad:", + sym_op->aead.aad.data, aad_len); + } + + sym_op->aead.data.length = tdata->plaintext.len; + sym_op->aead.data.offset = aad_len; + + return 0; +} + +#define SGL_MAX_NO 16 + +static int +test_authenticated_encryption_SGL(const struct aead_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 = 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 AEAD session */ + retval = create_aead_session(ts_params->valid_devs[0], + tdata->algo, + RTE_CRYPTO_AEAD_OP_ENCRYPT, + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->auth_tag.len, + tdata->iv.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 = (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_iova_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_iova(buf) + to_trn; + if (oop && buf_last_oop) + digest_phys = rte_pktmbuf_iova(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_iova_offset(ut_params->ibuf, + tdata->plaintext.len); + } + + /* Create AEAD operation */ + retval = create_aead_operation_SGL(RTE_CRYPTO_AEAD_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, + "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], + "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, + "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_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_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_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_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, i, nb_devs_attached = 0; + int ret; + char vdev_name[32]; + + /* create 2 AESNI_MB if necessary */ + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD))); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + snprintf(vdev_name, sizeof(vdev_name), "%s_%u", + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), + i); + ret = rte_vdev_init(vdev_name, 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; + unsigned int session_size; + + rte_cryptodev_info_get(i, &info); + if (info.driver_id != rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD))) + continue; + + session_size = rte_cryptodev_sym_get_private_session_size(i); + /* + * Create the session mempool again, since now there are new devices + * to use the mempool. + */ + if (ts_params->session_mpool) { + rte_mempool_free(ts_params->session_mpool); + ts_params->session_mpool = NULL; + } + if (ts_params->session_priv_mpool) { + rte_mempool_free(ts_params->session_priv_mpool); + ts_params->session_priv_mpool = NULL; + } + + if (info.sym.max_nb_sessions != 0 && + info.sym.max_nb_sessions < MAX_NB_SESSIONS) { + RTE_LOG(ERR, USER1, + "Device does not support " + "at least %u sessions\n", + MAX_NB_SESSIONS); + return TEST_FAILED; + } + /* + * Create mempool with maximum number of sessions, + * to include the session headers + */ + if (ts_params->session_mpool == NULL) { + ts_params->session_mpool = + rte_cryptodev_sym_session_pool_create( + "test_sess_mp", + MAX_NB_SESSIONS, 0, 0, 0, + SOCKET_ID_ANY); + TEST_ASSERT_NOT_NULL(ts_params->session_mpool, + "session mempool allocation failed"); + } + + /* + * Create mempool with maximum number of sessions, + * to include device specific session private data + */ + if (ts_params->session_priv_mpool == NULL) { + ts_params->session_priv_mpool = rte_mempool_create( + "test_sess_mp_priv", + MAX_NB_SESSIONS, + session_size, + 0, 0, NULL, NULL, NULL, + NULL, SOCKET_ID_ANY, + 0); + + TEST_ASSERT_NOT_NULL(ts_params->session_priv_mpool, + "session mempool allocation failed"); + } + + ts_params->qp_conf.mp_session = ts_params->session_mpool; + ts_params->qp_conf.mp_session_private = + ts_params->session_priv_mpool; + + 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(enum rte_cryptodev_scheduler_mode scheduler_mode) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + uint8_t sched_id = ts_params->valid_devs[0]; + /* set mode */ + return rte_cryptodev_scheduler_mode_set(sched_id, + scheduler_mode); +} + +static int +test_scheduler_mode_roundrobin_op(void) +{ + TEST_ASSERT(test_scheduler_mode_op(CDEV_SCHED_MODE_ROUNDROBIN) == + 0, "Failed to set roundrobin mode"); + return 0; + +} + +static int +test_scheduler_mode_multicore_op(void) +{ + TEST_ASSERT(test_scheduler_mode_op(CDEV_SCHED_MODE_MULTICORE) == + 0, "Failed to set multicore mode"); + + return 0; +} + +static int +test_scheduler_mode_failover_op(void) +{ + TEST_ASSERT(test_scheduler_mode_op(CDEV_SCHED_MODE_FAILOVER) == + 0, "Failed to set failover mode"); + + return 0; +} + +static int +test_scheduler_mode_pkt_size_distr_op(void) +{ + TEST_ASSERT(test_scheduler_mode_op(CDEV_SCHED_MODE_PKT_SIZE_DISTR) == + 0, "Failed to set pktsize mode"); + + 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 = { + /* Multi Core */ + TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), + TEST_CASE_ST(NULL, NULL, test_scheduler_mode_multicore_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), + + /* Round Robin */ + TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), + TEST_CASE_ST(NULL, NULL, test_scheduler_mode_roundrobin_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), + + /* Fail over */ + TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), + TEST_CASE_ST(NULL, NULL, test_scheduler_mode_failover_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), + + /* PKT SIZE */ + TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), + TEST_CASE_ST(NULL, NULL, test_scheduler_mode_pkt_size_distr_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_AES_docsis_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_DES_docsis_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_stats), + + /** AES CCM Authenticated Encryption 128 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_3), + + /** AES CCM Authenticated Decryption 128 bits key*/ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_3), + + /** 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_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GCM Authenticated Encryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_7), + + /** AES GCM Authenticated Decryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_7), + + /** AES GCM Authenticated Encryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_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), + + /** 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), + + /** ZUC authenticate (EIA3) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_hash_generate_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_hash_generate_test_case_7), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_hash_generate_test_case_8), + + /** ZUC alg-chain (EEA3/EIA3) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_cipher_auth_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_zuc_cipher_auth_test_case_2), + + /** 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), + + /** KASUMI tests */ + 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_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_virtio_testsuite = { + .suite_name = "Crypto VIRTIO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_virtio_all), + + 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 = { +#if IMB_VERSION_NUM >= IMB_VERSION(0, 51, 0) + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GCM Authenticated Encryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_7), + + /** AES GCM Authenticated Decryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_7), + + /** AES GCM Authenticated Encryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_7), + + /** AES GCM Authenticated Decryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_7), + + /** AES GCM Authenticated Encryption big aad size */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_aad_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_aad_2), + + /** AES GCM Authenticated Decryption big aad size */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_aad_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_aad_2), + + /** Session-less tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_sessionless_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_sessionless_test_case_1), + + /** 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), +#endif /* IMB_VERSION_NUM >= IMB_VERSION(0, 51, 0) */ + + 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_AES_docsis_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_DES_cipheronly_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_DES_docsis_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_3), + + 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_DES_cipheronly_openssl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_DES_docsis_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_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_7), + + + /** AES GCM Authenticated Encryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_7), + + /** AES GCM Authenticated Decryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_7), + + /** AES GCM Authenticated Encryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_7), + + /** AES GCM Authenticated Decryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_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), + + /** AES CCM Authenticated Encryption 128 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_128_3), + + /** AES CCM Authenticated Decryption 128 bits key*/ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_128_3), + + /** AES CCM Authenticated Encryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_192_3), + + /** AES CCM Authenticated Decryption 192 bits key*/ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_192_3), + + /** AES CCM Authenticated Encryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_encryption_test_case_256_3), + + /** AES CCM Authenticated Decryption 256 bits key*/ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_CCM_authenticated_decryption_test_case_256_3), + + /** 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_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GCM Authenticated Encryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_7), + + /** AES GCM Authenticated Decryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_7), + + /** AES GCM Authenticated Encryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_7), + + /** AES GCM Authenticated Decryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_7), + + /** AES GCM Authenticated Encryption big aad size */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_aad_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_aad_2), + + /** AES GCM Authenticated Decryption big aad size */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_aad_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_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_AES_GCM_authenticated_encryption_oop_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_oop_test_case_1), + + /** Session-less tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_sessionless_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_sessionless_test_case_1), + + /** 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_caam_jr_testsuite = { + .suite_name = "Crypto CAAM JR 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_multi_session), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_chain_caam_jr_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_chain_caam_jr_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_caam_jr_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_caam_jr_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_caam_jr_all), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_dpaa_sec_testsuite = { + .suite_name = "Crypto DPAA_SEC 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_multi_session), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_chain_dpaa_sec_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_chain_dpaa_sec_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_dpaa_sec_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_dpaa_sec_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_dpaa_sec_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GCM Authenticated Encryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_7), + + /** AES GCM Authenticated Decryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_7), + + /** Out of place tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_oop_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_oop_test_case_1), + + /** Scatter-Gather */ + 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_400B_1seg), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_dpaa2_sec_testsuite = { + .suite_name = "Crypto DPAA2_SEC 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_multi_session), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_chain_dpaa2_sec_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_chain_dpaa2_sec_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_dpaa2_sec_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_dpaa2_sec_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_dpaa2_sec_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GCM Authenticated Encryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_192_7), + + /** AES GCM Authenticated Decryption 192 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_192_7), + + /** AES GCM Authenticated Encryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encryption_test_case_256_7), + + /** AES GCM Authenticated Decryption 256 bits key */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_decryption_test_case_256_7), + + /** Out of place tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_oop_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_oop_test_case_1), + + /** Scatter-Gather */ + 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_400B_1seg), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B), + + 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 struct unit_test_suite cryptodev_mrvl_testsuite = { + .suite_name = "Crypto Device Marvell Component 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_mrvl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_mrvl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_mrvl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_chain_mrvl_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_mrvl_all), + + /** 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, + 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_ccp_testsuite = { + .suite_name = "Crypto Device CCP 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_ccp_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_ccp_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_chain_ccp_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_ccp_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_ccp_all), + + /** 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, + 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_octeontx_testsuite = { + .suite_name = "Crypto Device OCTEONTX Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_chain_octeontx_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_octeontx_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_chain_octeontx_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_octeontx_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_octeontx_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_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), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1_oop_sgl), + + /** 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), + + /** 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), + + /** KASUMI encrypt only (UEA1) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_5), + 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_1_oop_sgl), + /** KASUMI decrypt only (UEA1) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_5), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_1_oop), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_1_oop), + + /** KASUMI hash only (UIA1) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_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), + + /** NULL tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_cipher_only_operation), + TEST_CASE_ST(ut_setup, ut_teardown, + test_null_auth_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), + + /** 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 int +test_cryptodev_qat(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "QAT PMD must be loaded. Check that both " + "CONFIG_RTE_LIBRTE_PMD_QAT and CONFIG_RTE_LIBRTE_PMD_QAT_SYM " + "are enabled in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_qat_testsuite); +} + +static int +test_cryptodev_virtio(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "VIRTIO PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO is enabled " + "in config file to run this testsuite.\n"); + return TEST_FAILED; + } + + return unit_test_suite_runner(&cryptodev_virtio_testsuite); +} + +static int +test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "AESNI MB PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_AESNI_MB is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_aesni_mb_testsuite); +} + +static int +test_cryptodev_openssl(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "OPENSSL PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_OPENSSL is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_openssl_testsuite); +} + +static int +test_cryptodev_aesni_gcm(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "AESNI GCM PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_AESNI_GCM is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_aesni_gcm_testsuite); +} + +static int +test_cryptodev_null(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_NULL_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "NULL PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_NULL is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_null_testsuite); +} + +static int +test_cryptodev_sw_snow3g(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "SNOW3G PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_SNOW3G is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_sw_snow3g_testsuite); +} + +static int +test_cryptodev_sw_kasumi(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_KASUMI_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "ZUC PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_KASUMI is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_sw_kasumi_testsuite); +} + +static int +test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ZUC_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "ZUC PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_ZUC is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_sw_zuc_testsuite); +} + +static int +test_cryptodev_armv8(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "ARMV8 PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_ARMV8 is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_armv8_testsuite); +} + +static int +test_cryptodev_mrvl(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "MVSAM PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_MVSAM_CRYPTO is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_mrvl_testsuite); +} + +#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER + +static int +test_cryptodev_scheduler(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "SCHEDULER PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_SCHEDULER is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + if (rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)) == -1) { + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_MB must be" + " enabled in config file to run this testsuite.\n"); + return TEST_SKIPPED; +} + return unit_test_suite_runner(&cryptodev_scheduler_testsuite); +} + +REGISTER_TEST_COMMAND(cryptodev_scheduler_autotest, test_cryptodev_scheduler); + +#endif + +static int +test_cryptodev_dpaa2_sec(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "DPAA2 SEC PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_dpaa2_sec_testsuite); +} + +static int +test_cryptodev_dpaa_sec(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "DPAA SEC PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_DPAA_SEC is enabled " + "in config file to run this testsuite.\n"); + return TEST_SKIPPED; + } + + return unit_test_suite_runner(&cryptodev_dpaa_sec_testsuite); +} + +static int +test_cryptodev_ccp(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "CCP PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_CCP is enabled " + "in config file to run this testsuite.\n"); + return TEST_FAILED; + } + + return unit_test_suite_runner(&cryptodev_ccp_testsuite); +} + +static int +test_cryptodev_octeontx(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)); + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "OCTEONTX PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_OCTEONTX_CRYPTO is " + "enabled in config file to run this " + "testsuite.\n"); + return TEST_FAILED; + } + return unit_test_suite_runner(&cryptodev_octeontx_testsuite); +} + +static int +test_cryptodev_caam_jr(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "CAAM_JR PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_CAAM_JR is enabled " + "in config file to run this testsuite.\n"); + return TEST_FAILED; + } + + return unit_test_suite_runner(&cryptodev_caam_jr_testsuite); +} + +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); +REGISTER_TEST_COMMAND(cryptodev_sw_mvsam_autotest, test_cryptodev_mrvl); +REGISTER_TEST_COMMAND(cryptodev_dpaa2_sec_autotest, test_cryptodev_dpaa2_sec); +REGISTER_TEST_COMMAND(cryptodev_dpaa_sec_autotest, test_cryptodev_dpaa_sec); +REGISTER_TEST_COMMAND(cryptodev_ccp_autotest, test_cryptodev_ccp); +REGISTER_TEST_COMMAND(cryptodev_virtio_autotest, test_cryptodev_virtio); +REGISTER_TEST_COMMAND(cryptodev_octeontx_autotest, test_cryptodev_octeontx); +REGISTER_TEST_COMMAND(cryptodev_caam_jr_autotest, test_cryptodev_caam_jr); diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h new file mode 100644 index 0000000000..a73a49e72f --- /dev/null +++ b/app/test/test_cryptodev.h @@ -0,0 +1,208 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015-2017 Intel Corporation + */ +#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) + +#define MAXIMUM_IV_LENGTH (16) + +#define IV_OFFSET (sizeof(struct rte_crypto_op) + \ + sizeof(struct rte_crypto_sym_op) + DEFAULT_NUM_XFORMS * \ + sizeof(struct rte_crypto_sym_xform)) + +#define CRYPTODEV_NAME_NULL_PMD crypto_null +#define CRYPTODEV_NAME_AESNI_MB_PMD crypto_aesni_mb +#define CRYPTODEV_NAME_AESNI_GCM_PMD crypto_aesni_gcm +#define CRYPTODEV_NAME_OPENSSL_PMD crypto_openssl +#define CRYPTODEV_NAME_QAT_SYM_PMD crypto_qat +#define CRYPTODEV_NAME_SNOW3G_PMD crypto_snow3g +#define CRYPTODEV_NAME_KASUMI_PMD crypto_kasumi +#define CRYPTODEV_NAME_ZUC_PMD crypto_zuc +#define CRYPTODEV_NAME_ARMV8_PMD crypto_armv8 +#define CRYPTODEV_NAME_DPAA_SEC_PMD crypto_dpaa_sec +#define CRYPTODEV_NAME_DPAA2_SEC_PMD crypto_dpaa2_sec +#define CRYPTODEV_NAME_SCHEDULER_PMD crypto_scheduler +#define CRYPTODEV_NAME_MVSAM_PMD crypto_mvsam +#define CRYPTODEV_NAME_CCP_PMD crypto_ccp +#define CRYPTODEV_NAME_VIRTIO_PMD crypto_virtio +#define CRYPTODEV_NAME_OCTEONTX_SYM_PMD crypto_octeontx +#define CRYPTODEV_NAME_CAAM_JR_PMD crypto_caam_jr + +/** + * 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 rte_iova_t +pktmbuf_iova_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_iova_offset: offset out of buffer\n"); + return 0; + } + return rte_pktmbuf_iova_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_aead_test_vectors.h b/app/test/test_cryptodev_aead_test_vectors.h new file mode 100644 index 0000000000..a4a3a25c9d --- /dev/null +++ b/app/test/test_cryptodev_aead_test_vectors.h @@ -0,0 +1,3775 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015-2017 Intel Corporation + */ + +#ifndef TEST_CRYPTODEV_AEAD_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_AEAD_TEST_VECTORS_H_ + +#define GMAC_LARGE_PLAINTEXT_LENGTH 65344 +#define MAX_AAD_LENGTH 65536 +#define GCM_LARGE_AAD_LENGTH 65296 + +static uint8_t gcm_aad_zero_text[MAX_AAD_LENGTH] = { 0 }; + +static uint8_t gcm_aad_text[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 }; + +static uint8_t ccm_aad_test_1[8] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 +}; + +static uint8_t ccm_aad_test_2[22] = { + 0x08, 0x40, 0x0F, 0xD2, 0xE1, 0x28, 0xA5, 0x7C, + 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xAB, 0xAE, + 0xA5, 0xB8, 0xFC, 0xBA, 0x00, 0x00 +}; + +struct aead_test_data { + enum rte_crypto_aead_algorithm algo; + + 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; + } plaintext; + + struct { + uint8_t data[16]; + unsigned len; + } gmac_tag; + +}; + +/** AES-GCM-128 Test Vectors */ +static const struct aead_test_data gcm_test_case_1 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +static const struct aead_test_data gcm_test_case_2 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +static const struct aead_test_data gcm_test_case_3 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +static const struct aead_test_data gcm_test_case_4 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } + +}; + +static const struct aead_test_data gcm_test_case_5 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } + +}; + +static const struct aead_test_data gcm_test_case_6 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +static const struct aead_test_data gcm_test_case_7 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 aead_test_data gcm_test_case_8 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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-GCM-192 Test Vectors */ +static const struct aead_test_data gcm_test_case_192_1 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + }, + .len = 24 + }, + .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 = { + 0xCD, 0x33, 0xB2, 0x8A, 0xC7, 0x73, 0xF7, 0x4B, + 0xA0, 0x0E, 0xD1, 0xF3, 0x12, 0x57, 0x24, 0x35 + }, + .len = 16 + } +}; + +static const struct aead_test_data gcm_test_case_192_2 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + }, + .len = 24 + }, + .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 = { + 0x98, 0xE7, 0x24, 0x7C, 0x07, 0xF0, 0xFE, 0x41, + 0x1C, 0x26, 0x7E, 0x43, 0x84, 0xB0, 0xF6, 0x00 + }, + .len = 16 + }, + .auth_tag = { + .data = { + 0x2F, 0xF5, 0x8D, 0x80, 0x03, 0x39, 0x27, 0xAB, + 0x8E, 0xF4, 0xD4, 0x58, 0x75, 0x14, 0xF0, 0xFB + + }, + .len = 16 + } +}; + +static const struct aead_test_data gcm_test_case_192_3 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .key = { + .data = { + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, + 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C + }, + .len = 24 + }, + .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 = { + 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, + 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, + 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, + 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, + 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, + 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, + 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, + 0xCC, 0xDA, 0x27, 0x10, 0xAC, 0xAD, 0xE2, 0x56 + }, + .len = 64 + }, + .auth_tag = { + .data = { + 0x99, 0x24, 0xA7, 0xC8, 0x58, 0x73, 0x36, 0xBF, + 0xB1, 0x18, 0x02, 0x4D, 0xB8, 0x67, 0x4A, 0x14 + }, + .len = 16 + } +}; + +static const struct aead_test_data gcm_test_case_192_4 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .key = { + .data = { + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, + 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C + }, + .len = 24 + }, + .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 = { + 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, + 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, + 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, + 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, + 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, + 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, + 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, + 0xCC, 0xDA, 0x27, 0x10 + }, + .len = 60 + }, + .auth_tag = { + .data = { + 0x57, 0x5F, 0x03, 0xA0, 0x8D, 0x8F, 0x40, 0x26, + 0xE5, 0x64, 0x1F, 0x5B, 0x5C, 0xC2, 0xFD, 0x4B + }, + .len = 16 + } +}; + +static const struct aead_test_data gcm_test_case_192_5 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .key = { + .data = { + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, + 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C + }, + .len = 24 + }, + .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 = { + 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, + 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, + 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, + 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, + 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, + 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, + 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, + 0xCC, 0xDA, 0x27, 0x10 + }, + .len = 60 + }, + .auth_tag = { + .data = { + 0xB6, 0x35, 0x56, 0xE7, 0xBA, 0x46, 0xA3, 0x38, + 0xED, 0xAD, 0x79, 0x9F, 0xB3, 0x5B, 0x34, 0xA8 + }, + .len = 16 + } +}; + +static const struct aead_test_data gcm_test_case_192_6 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .key = { + .data = { + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, + 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C + }, + .len = 24 + }, + .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 = { + 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, + 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, + 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, + 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, + 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, + 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, + 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, + 0xCC, 0xDA, 0x27, 0x10 + }, + .len = 60 + }, + .auth_tag = { + .data = { + 0xCA, 0x8A, 0x8A, 0x91, 0x5A, 0xF9, 0x76, 0xE3, + 0xFF, 0x2C, 0xE4, 0x7D, 0xE5, 0x62, 0x75, 0x18 + }, + .len = 16 + } +}; + +static const struct aead_test_data gcm_test_case_192_7 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .key = { + .data = { + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, + 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C + }, + .len = 24 + }, + .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 = { + 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, + 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, + 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, + 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, + 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, + 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, + 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, + 0xCC, 0xDA, 0x27, 0x10 + }, + .len = 60 + }, + .auth_tag = { + .data = { + 0xC2, 0xD8, 0x4C, 0x6B, 0xA8, 0x3B, 0xA5, 0x6B, + 0x18, 0x9F, 0xE6, 0xEF, 0x66, 0x24, 0xDD, 0xDA + }, + .len = 16 + } +}; + +/** AES-GCM-256 Test Vectors */ +static const struct aead_test_data gcm_test_case_256_1 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +static const struct aead_test_data gcm_test_case_256_2 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +static const struct aead_test_data gcm_test_case_256_3 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +static const struct aead_test_data gcm_test_case_256_4 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } + +}; + +static const struct aead_test_data gcm_test_case_256_5 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } + +}; + +static const struct aead_test_data gcm_test_case_256_6 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +static const struct aead_test_data gcm_test_case_256_7 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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-GCM-128 Test Vectors */ +static const struct aead_test_data gcm_test_case_aad_1 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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-GCM-256 Test Vectors */ +static const struct aead_test_data gcm_test_case_aad_2 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + }, + .plaintext = { + .data = gmac_plaintext, + .len = 160 + }, + .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 + }, + .plaintext = { + .data = gmac_plaintext, + .len = 80 + }, + .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 + }, + .plaintext = { + .data = gmac_plaintext, + .len = 65 + }, + .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 + }, + .plaintext = { + .data = gmac_plaintext, + .len = GMAC_LARGE_PLAINTEXT_LENGTH + }, + .gmac_tag = { + .data = { + 0x3f, 0x07, 0xcb, 0xb9, 0x86, 0x3a, 0xea, 0xc2, + 0x2f, 0x3a, 0x2a, 0x93, 0xd8, 0x09, 0x6b, 0xda + }, + .len = 16 + } +}; + +static const struct aead_test_data gcm_test_case_SGL_1 = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .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 + } +}; + +/** AES-CCM-128 Test Vectors */ +static const struct aead_test_data ccm_test_case_128_1 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F + }, + .len = 16 + }, + .iv = { + .data = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 + }, + .len = 7 + }, + .aad = { + .data = ccm_aad_test_1, + .len = 8 + }, + .plaintext = { + .data = { + 0x20, 0x21, 0x22, 0x23 + }, + .len = 4 + }, + .ciphertext = { + .data = { + 0x71, 0x62, 0x01, 0x5B + }, + .len = 4 + }, + .auth_tag = { + .data = { + 0x4D, 0xAC, 0x25, 0x5D + }, + .len = 4 + } +}; + +static const struct aead_test_data ccm_test_case_128_2 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, + 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, + 0x03, 0x97, 0x76, 0xE7, 0x0C + }, + .len = 13 + }, + .aad = { + .data = ccm_aad_test_2, + .len = 22 + }, + .plaintext = { + .data = { + 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, + 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, + 0x7E, 0x78, 0xA0, 0x50 + }, + .len = 20 + }, + .ciphertext = { + .data = { + 0xF3, 0xD0, 0xA2, 0xFE, 0x9A, 0x3D, 0xBF, 0x23, + 0x42, 0xA6, 0x43, 0xE4, 0x32, 0x46, 0xE8, 0x0C, + 0x3C, 0x04, 0xD0, 0x19 + }, + .len = 20 + }, + .auth_tag = { + .data = { + 0x78, 0x45, 0xCE, 0x0B, 0x16, 0xF9, 0x76, 0x23 + }, + .len = 8 + } +}; + +static const struct aead_test_data ccm_test_case_128_3 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, + 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, + 0x03, 0x97, 0x76, 0xE7, 0x0C + }, + .len = 13 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, + 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, + 0x7E, 0x78, 0xA0, 0x50 + }, + .len = 20 + }, + .ciphertext = { + .data = { + 0xF3, 0xD0, 0xA2, 0xFE, 0x9A, 0x3D, 0xBF, 0x23, + 0x42, 0xA6, 0x43, 0xE4, 0x32, 0x46, 0xE8, 0x0C, + 0x3C, 0x04, 0xD0, 0x19 + }, + .len = 20 + }, + .auth_tag = { + .data = { + 0x41, 0x83, 0x21, 0x89, 0xA3, 0xD3, 0x1B, 0x43 + }, + .len = 8 + } +}; + +/** AES-CCM-192 Test Vectors */ +static const struct aead_test_data ccm_test_case_192_1 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 + }, + .len = 24 + }, + .iv = { + .data = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 + }, + .len = 7 + }, + .aad = { + .data = ccm_aad_test_1, + .len = 8 + }, + .plaintext = { + .data = { + 0x20, 0x21, 0x22, 0x23 + }, + .len = 4 + }, + .ciphertext = { + .data = { + 0x18, 0xEE, 0x17, 0x30 + }, + .len = 4 + }, + .auth_tag = { + .data = { + 0xC8, 0xC3, 0x26, 0xD5 + }, + .len = 4 + } +}; + +static const struct aead_test_data ccm_test_case_192_2 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, + 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, + 0x03, 0x97, 0x76, 0xE7, 0x0C + }, + .len = 13 + }, + .aad = { + .data = ccm_aad_test_2, + .len = 22 + }, + .plaintext = { + .data = { + 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, + 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, + 0x7E, 0x78, 0xA0, 0x50 + }, + .len = 20 + }, + .ciphertext = { + .data = { + 0x41, 0xC6, 0x2D, 0xD5, 0x31, 0xF2, 0xD5, 0xC8, + 0xCC, 0x57, 0x01, 0x2E, 0x7E, 0x2B, 0xF1, 0x26, + 0x6A, 0xC7, 0xCB, 0xA5 + }, + .len = 20 + }, + .auth_tag = { + .data = { + 0x77, 0xA3, 0x41, 0xD5, 0x2A, 0xE3, 0x25, 0x37 + }, + .len = 8 + } +}; + +static const struct aead_test_data ccm_test_case_192_3 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, + 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, + 0x03, 0x97, 0x76, 0xE7, 0x0C + }, + .len = 13 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, + 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, + 0x7E, 0x78, 0xA0, 0x50 + }, + .len = 20 + }, + .ciphertext = { + .data = { + 0x41, 0xC6, 0x2D, 0xD5, 0x31, 0xF2, 0xD5, 0xC8, + 0xCC, 0x57, 0x01, 0x2E, 0x7E, 0x2B, 0xF1, 0x26, + 0x6A, 0xC7, 0xCB, 0xA5 + }, + .len = 20 + }, + .auth_tag = { + .data = { + 0x84, 0x72, 0x6E, 0xE7, 0x8E, 0x8E, 0x3A, 0xC6 + }, + .len = 8 + } +}; + +/** AES-CCM-256 Test Vectors */ +static const struct aead_test_data ccm_test_case_256_1 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F + }, + .len = 32 + }, + .iv = { + .data = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 + }, + .len = 7 + }, + .aad = { + .data = ccm_aad_test_1, + .len = 8 + }, + .plaintext = { + .data = { + 0x20, 0x21, 0x22, 0x23 + }, + .len = 4 + }, + .ciphertext = { + .data = { + 0x8A, 0xB1, 0xA8, 0x74 + }, + .len = 4 + }, + .auth_tag = { + .data = { + 0x95, 0xFC, 0x08, 0x20 + }, + .len = 4 + } +}; + +static const struct aead_test_data ccm_test_case_256_2 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, + 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F + }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, + 0x03, 0x97, 0x76, 0xE7, 0x0C + }, + .len = 13 + }, + .aad = { + .data = ccm_aad_test_2, + .len = 22 + }, + .plaintext = { + .data = { + 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, + 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, + 0x7E, 0x78, 0xA0, 0x50 + }, + .len = 20 + }, + .ciphertext = { + .data = { + 0x25, 0x82, 0x89, 0x09, 0x3E, 0x39, 0x1F, 0x16, + 0xD2, 0x82, 0x3D, 0xF6, 0xCE, 0x97, 0x72, 0x07, + 0xEC, 0x23, 0x17, 0x98 + }, + .len = 20 + }, + .auth_tag = { + .data = { + 0xAB, 0x02, 0xE9, 0xD1, 0x16, 0x69, 0xED, 0x0A + }, + .len = 8 + } +}; + +static const struct aead_test_data ccm_test_case_256_3 = { + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .key = { + .data = { + 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, + 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F + }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, + 0x03, 0x97, 0x76, 0xE7, 0x0C + }, + .len = 13 + }, + .aad = { + .data = gcm_aad_zero_text, + .len = 0 + }, + .plaintext = { + .data = { + 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, + 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, + 0x7E, 0x78, 0xA0, 0x50 + }, + .len = 20 + }, + .ciphertext = { + .data = { + 0x25, 0x82, 0x89, 0x09, 0x3E, 0x39, 0x1F, 0x16, + 0xD2, 0x82, 0x3D, 0xF6, 0xCE, 0x97, 0x72, 0x07, + 0xEC, 0x23, 0x17, 0x98 + }, + .len = 20 + }, + .auth_tag = { + .data = { + 0x15, 0x80, 0xC4, 0xC9, 0x3F, 0xAB, 0x2A, 0xFD + }, + .len = 8 + } +}; +#endif /* TEST_CRYPTODEV_AEAD_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h new file mode 100644 index 0000000000..6dd8e5f961 --- /dev/null +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -0,0 +1,1914 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#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 ciphertext64_aes128ctr_IV_12bytes[] = { + 0x28, 0x80, 0x28, 0xC7, 0x15, 0x99, 0xC5, 0xA8, + 0xDD, 0x53, 0xC2, 0x67, 0x1B, 0x86, 0xB8, 0x13, + 0xAB, 0x25, 0x39, 0x7A, 0xD2, 0x1F, 0x8B, 0x4B, + 0x94, 0x89, 0x2B, 0x65, 0xCF, 0x89, 0x1E, 0xDD, + 0xD4, 0x7C, 0xFD, 0x8D, 0x0E, 0xCD, 0x23, 0xA4, + 0xEB, 0x8C, 0x05, 0x58, 0x45, 0x4A, 0x63, 0x44, + 0x11, 0x42, 0x07, 0x17, 0xB4, 0xD2, 0xCC, 0x75, + 0xB7, 0x23, 0x99, 0xA9, 0xC5, 0x89, 0x7F, 0x66 +}; + +static const uint8_t plaintext_aes_docsis_bpi_cfb[] = { + 0x00, 0x01, 0x02, 0x88, 0xEE, 0x59, 0x7E +}; + +static const uint8_t ciphertext_aes_docsis_bpi_cfb[] = { + 0xFC, 0x68, 0xA3, 0x55, 0x60, 0x37, 0xDC +}; + +static const uint8_t plaintext_aes_docsis_bpi_cbc_cfb[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x91, + 0xD2, 0xD1, 0x9F +}; + +static const uint8_t ciphertext_aes_docsis_bpi_cbc_cfb[] = { + 0x9D, 0xD1, 0x67, 0x4B, 0xBA, 0x61, 0x10, 0x1B, + 0x56, 0x75, 0x64, 0x74, 0x36, 0x4F, 0x10, 0x1D, + 0x44, 0xD4, 0x73 +}; + +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 ciphertext64_aes192ctr_IV_12bytes[] = { + 0x67, 0x65, 0xa9, 0xee, 0xfd, 0x31, 0x62, 0xfc, + 0xad, 0xfd, 0xc7, 0x25, 0xb7, 0x25, 0x16, 0xbe, + 0x25, 0xce, 0xc0, 0x1d, 0xda, 0xa9, 0xd3, 0xda, + 0x1b, 0x7d, 0x68, 0x6a, 0x6f, 0x06, 0xea, 0x47, + 0xa0, 0xe0, 0x15, 0xf4, 0xbd, 0x1b, 0x70, 0x34, + 0xd4, 0x6d, 0x1c, 0x84, 0x17, 0x91, 0x46, 0x0c, + 0xe8, 0xbc, 0x7a, 0xfb, 0x9f, 0x2a, 0x8f, 0xb4, + 0xd4, 0xf3, 0x6e, 0x5b, 0x75, 0xa0, 0xce, 0x32 +}; + +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 ciphertext64_aes256ctr_IV_12bytes[] = { + 0x7B, 0x7A, 0x7D, 0x83, 0x85, 0xF8, 0x81, 0xF3, + 0x32, 0x33, 0xD9, 0xFB, 0x04, 0x73, 0xD4, 0x2F, + 0x70, 0xDE, 0x90, 0x3E, 0xD0, 0xA9, 0x93, 0x8A, + 0x91, 0xF3, 0xB5, 0x29, 0x4D, 0x2A, 0x74, 0xD0, + 0xDC, 0x4E, 0x5C, 0x9B, 0x97, 0x24, 0xD8, 0x02, + 0xFE, 0xAB, 0x38, 0xE8, 0x73, 0x51, 0x29, 0x7E, + 0xF1, 0xF9, 0x40, 0x78, 0xB1, 0x04, 0x7A, 0x78, + 0x61, 0x07, 0x47, 0xE6, 0x8C, 0x0F, 0xA8, 0x76 +}; + +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 + } +}; + +/* AES128-CTR-SHA1 test vector (12-byte IV) */ +static const struct blockcipher_test_data aes_test_data_1_IV_12_bytes = { + .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 + }, + .len = 12 + }, + .plaintext = { + .data = plaintext_aes128ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes128ctr_IV_12bytes, + .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 = { + 0x5C, 0x34, 0x6B, 0xE4, 0x9A, 0x7F, 0x4A, 0xC3, + 0x82, 0xBE, 0xA0, 0x12, 0xD1, 0xF0, 0x15, 0xFA, + 0xCF, 0xC8, 0x7F, 0x60 + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-192-CTR XCBC test vector (12-byte IV) */ +static const struct blockcipher_test_data aes_test_data_2_IV_12_bytes = { + .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 + }, + .len = 12 + }, + .plaintext = { + .data = plaintext_aes192ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes192ctr_IV_12bytes, + .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 = { + 0x0C, 0xA1, 0xA5, 0xAF, 0x3E, 0x41, 0xD2, 0xF4, + 0x4C, 0x4C, 0xAB, 0x13 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-256-CTR SHA1 test vector (12-byte IV) */ +static const struct blockcipher_test_data aes_test_data_3_IV_12_bytes = { + .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 + }, + .len = 12 + }, + .plaintext = { + .data = plaintext_aes256ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes256ctr_IV_12bytes, + .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 = { + 0x57, 0x9A, 0x52, 0x6E, 0x31, 0x17, 0x57, 0x49, + 0xE7, 0xA1, 0x88, 0x6C, 0x2E, 0x36, 0x67, 0x63, + 0x3F, 0x2D, 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 + } +}; + +/* AES-DOCSIS-BPI test vectors */ + +/* Multiple of AES block size */ +static const struct blockcipher_test_data aes_test_data_docsis_1 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI, + .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 + } +}; + +/* Less than AES block size */ +static const struct blockcipher_test_data aes_test_data_docsis_2 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI, + .cipher_key = { + .data = { + 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB, + 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB + }, + .len = 16 + }, + .iv = { + .data = { + 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A, + 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_docsis_bpi_cfb, + .len = 7 + }, + .ciphertext = { + .data = ciphertext_aes_docsis_bpi_cfb, + .len = 7 + } +}; + +/* Not multiple of AES block size */ +static const struct blockcipher_test_data aes_test_data_docsis_3 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI, + .cipher_key = { + .data = { + 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB, + 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB + }, + .len = 16 + }, + .iv = { + .data = { + 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A, + 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_docsis_bpi_cbc_cfb, + .len = 19 + }, + .ciphertext = { + .data = ciphertext_aes_docsis_bpi_cbc_cfb, + .len = 19 + } +}; + +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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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_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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify Scatter Gather", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, +}; + +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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "AES-192-CBC Decryption Scatter Gather", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "AES-256-CBC OOP Encryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO + }, + { + .test_descr = "AES-256-CBC OOP Decryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "AES-128-CTR Encryption (12-byte IV)", + .test_data = &aes_test_data_1_IV_12_bytes, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "AES-192-CTR Encryption (12-byte IV)", + .test_data = &aes_test_data_2_IV_12_bytes, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "AES-256-CTR Encryption (12-byte IV)", + .test_data = &aes_test_data_3_IV_12_bytes, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + } +}; + +static const struct blockcipher_test_case aes_docsis_test_cases[] = { + + { + .test_descr = "AES-DOCSIS-BPI Full Block Encryption", + .test_data = &aes_test_data_docsis_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI Runt Block Encryption", + .test_data = &aes_test_data_docsis_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI Uneven Encryption", + .test_data = &aes_test_data_docsis_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI Full Block Decryption", + .test_data = &aes_test_data_docsis_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI Runt Block Decryption", + .test_data = &aes_test_data_docsis_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI Uneven Decryption", + .test_data = &aes_test_data_docsis_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI OOP Full Block Encryption", + .test_data = &aes_test_data_docsis_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI OOP Runt Block Encryption", + .test_data = &aes_test_data_docsis_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI OOP Uneven Block Encryption", + .test_data = &aes_test_data_docsis_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI OOP Full Block Decryption", + .test_data = &aes_test_data_docsis_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI OOP Runt Block Decryption", + .test_data = &aes_test_data_docsis_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-DOCSIS-BPI OOP Uneven Block Decryption", + .test_data = &aes_test_data_docsis_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + } +}; +#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c new file mode 100644 index 0000000000..0f6fc5767d --- /dev/null +++ b/app/test/test_cryptodev_asym.c @@ -0,0 +1,1372 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Cavium Networks + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "test_cryptodev.h" +#include "test_cryptodev_dh_test_vectors.h" +#include "test_cryptodev_dsa_test_vectors.h" +#include "test_cryptodev_mod_test_vectors.h" +#include "test_cryptodev_rsa_test_vectors.h" +#include "test_cryptodev_asym_util.h" +#include "test.h" + +#define TEST_NUM_BUFS 10 +#define TEST_NUM_SESSIONS 4 + +static int gbl_driver_id; +struct crypto_testsuite_params { + struct rte_mempool *op_mpool; + struct rte_mempool *session_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_cryptodev_asym_session *sess; + struct rte_crypto_op *op; +}; + +static struct crypto_testsuite_params testsuite_params = { NULL }; + +static int +test_rsa_sign_verify(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + uint8_t output_buf[TEST_DATA_SIZE] = {0}; + uint8_t input_buf[TEST_DATA_SIZE] = {0}; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + + if (!sess) { + RTE_LOG(ERR, USER1, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, + "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + asym_op = op->asym; + /* Compute sign on the test vector */ + asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; + + memcpy(input_buf, &rsaplaintext.data, + rsaplaintext.len); + asym_op->rsa.message.data = input_buf; + asym_op->rsa.message.length = rsaplaintext.len; + asym_op->rsa.sign.data = output_buf; + asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1; + + debug_hexdump(stdout, "message", asym_op->rsa.message.data, + asym_op->rsa.message.length); + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + debug_hexdump(stdout, "signed message", asym_op->rsa.sign.data, + asym_op->rsa.sign.length); + asym_op = result_op->asym; + + /* Verify sign */ + asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; + asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2; + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + status = TEST_SUCCESS; + if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + +error_exit: + + if (sess) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + + if (op) + rte_crypto_op_free(op); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return status; +} + +static int +test_rsa_enc_dec(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + uint8_t input_buf[TEST_DATA_SIZE] = {0}; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + + if (!sess) { + RTE_LOG(ERR, USER1, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, + "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + asym_op = op->asym; + /*Compute encryption on the test vector */ + asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT; + + memcpy(input_buf, rsaplaintext.data, + rsaplaintext.len); + asym_op->rsa.message.data = input_buf; + asym_op->rsa.message.length = rsaplaintext.len; + asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2; + + debug_hexdump(stdout, "message", asym_op->rsa.message.data, + asym_op->rsa.message.length); + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + debug_hexdump(stdout, "encrypted message", asym_op->rsa.message.data, + asym_op->rsa.message.length); + /* Use the resulted output as decryption Input vector*/ + asym_op = result_op->asym; + asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_DECRYPT; + asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1; + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + status = TEST_SUCCESS; + int ret = 0; + ret = rsa_verify(&rsaplaintext, result_op); + if (ret) + status = TEST_FAILED; + +error_exit: + + if (sess) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + + if (op) + rte_crypto_op_free(op); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return status; +} + +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->op_mpool = rte_crypto_op_pool_create( + "CRYPTO_ASYM_OP_POOL", + RTE_CRYPTO_OP_TYPE_ASYMMETRIC, + TEST_NUM_BUFS, 0, + 0, + rte_socket_id()); + if (ts_params->op_mpool == NULL) { + RTE_LOG(ERR, USER1, "Can't create ASYM_CRYPTO_OP_POOL\n"); + return TEST_FAILED; + } + + /* Create an OPENSSL device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance of pmd : %s", + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + } + } + + 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.driver_id == gbl_driver_id) + 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); + + /* check if device support asymmetric, skip if not */ + if (!(info.feature_flags & + RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) { + RTE_LOG(ERR, USER1, "Device doesn't support asymmetric. " + "Test Skipped.\n"); + return TEST_FAILED; + } + + /* configure device with num qp */ + ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs; + ts_params->conf.socket_id = SOCKET_ID_ANY; + 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); + + /* configure qp */ + ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; + ts_params->qp_conf.mp_session = ts_params->session_mpool; + ts_params->qp_conf.mp_session_private = ts_params->session_mpool; + 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 ASYM", + qp_id, dev_id); + } + + /* setup asym session pool */ + unsigned int session_size = + rte_cryptodev_asym_get_private_session_size(dev_id); + /* + * Create mempool with TEST_NUM_SESSIONS * 2, + * to include the session headers + */ + ts_params->session_mpool = rte_mempool_create( + "test_asym_sess_mp", + TEST_NUM_SESSIONS * 2, + session_size, + 0, 0, NULL, NULL, NULL, + NULL, SOCKET_ID_ANY, + 0); + + TEST_ASSERT_NOT_NULL(ts_params->session_mpool, + "session mempool allocation failed"); + + return TEST_SUCCESS; +} + +static void +testsuite_teardown(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + + if (ts_params->op_mpool != NULL) { + RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n", + rte_mempool_avail_count(ts_params->op_mpool)); + } + + /* Free session mempools */ + if (ts_params->session_mpool != NULL) { + rte_mempool_free(ts_params->session_mpool); + ts_params->session_mpool = NULL; + } +} + +static int +ut_setup(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + + uint16_t qp_id; + + /* Reconfigure device to default parameters */ + ts_params->conf.socket_id = SOCKET_ID_ANY; + + 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 rte_cryptodev_stats stats; + + rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats); + + /* Stop the device */ + rte_cryptodev_stop(ts_params->valid_devs[0]); +} + +static inline void print_asym_capa( + const struct rte_cryptodev_asymmetric_xform_capability *capa) +{ + int i = 0; + + printf("\nxform type: %s\n===================\n", + rte_crypto_asym_xform_strings[capa->xform_type]); + printf("operation supported -"); + + for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) { + /* check supported operations */ + if (rte_cryptodev_asym_xform_capability_check_optype(capa, i)) + printf(" %s", + rte_crypto_asym_op_strings[i]); + } + switch (capa->xform_type) { + case RTE_CRYPTO_ASYM_XFORM_RSA: + case RTE_CRYPTO_ASYM_XFORM_MODINV: + case RTE_CRYPTO_ASYM_XFORM_MODEX: + case RTE_CRYPTO_ASYM_XFORM_DH: + case RTE_CRYPTO_ASYM_XFORM_DSA: + printf(" modlen: min %d max %d increment %d\n", + capa->modlen.min, + capa->modlen.max, + capa->modlen.increment); + break; + default: + break; + } +} + +static int +test_capability(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_cryptodev_info dev_info; + const struct rte_cryptodev_capabilities *dev_capa; + int i = 0; + struct rte_cryptodev_asym_capability_idx idx; + const struct rte_cryptodev_asymmetric_xform_capability *capa; + + rte_cryptodev_info_get(dev_id, &dev_info); + if (!(dev_info.feature_flags & + RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) { + RTE_LOG(INFO, USER1, + "Device doesn't support asymmetric. Test Skipped\n"); + return TEST_SUCCESS; + } + + /* print xform capability */ + for (i = 0; + dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED; + i++) { + dev_capa = &(dev_info.capabilities[i]); + if (dev_info.capabilities[i].op == + RTE_CRYPTO_OP_TYPE_ASYMMETRIC) { + idx.type = dev_capa->asym.xform_capa.xform_type; + + capa = rte_cryptodev_asym_capability_get(dev_id, + (const struct + rte_cryptodev_asym_capability_idx *) &idx); + print_asym_capa(capa); + } + } + return TEST_SUCCESS; +} + +static int +test_dh_gen_shared_sec(struct rte_crypto_asym_xform *xfrm) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + uint8_t output[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform xform = *xfrm; + uint8_t peer[] = "01234567890123456789012345678901234567890123456789"; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + + /* Setup a xform and op to generate private key only */ + xform.dh.type = RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE; + xform.next = NULL; + asym_op->dh.priv_key.data = dh_test_params.priv_key.data; + asym_op->dh.priv_key.length = dh_test_params.priv_key.length; + asym_op->dh.pub_key.data = (uint8_t *)peer; + asym_op->dh.pub_key.length = sizeof(peer); + asym_op->dh.shared_secret.data = output; + asym_op->dh.shared_secret.length = sizeof(output); + + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + debug_hexdump(stdout, "shared secret:", + asym_op->dh.shared_secret.data, + asym_op->dh.shared_secret.length); + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) + rte_crypto_op_free(op); + return status; +} + +static int +test_dh_gen_priv_key(struct rte_crypto_asym_xform *xfrm) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + uint8_t output[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform xform = *xfrm; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + + /* Setup a xform and op to generate private key only */ + xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE; + xform.next = NULL; + asym_op->dh.priv_key.data = output; + asym_op->dh.priv_key.length = sizeof(output); + + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + debug_hexdump(stdout, "private key:", + asym_op->dh.priv_key.data, + asym_op->dh.priv_key.length); + + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) + rte_crypto_op_free(op); + + return status; +} + + +static int +test_dh_gen_pub_key(struct rte_crypto_asym_xform *xfrm) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + uint8_t output[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform xform = *xfrm; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + /* Setup a xform chain to generate public key + * using test private key + * + */ + xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE; + xform.next = NULL; + + asym_op->dh.pub_key.data = output; + asym_op->dh.pub_key.length = sizeof(output); + /* load pre-defined private key */ + asym_op->dh.priv_key.data = rte_malloc(NULL, + dh_test_params.priv_key.length, + 0); + asym_op->dh.priv_key = dh_test_params.priv_key; + + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + debug_hexdump(stdout, "pub key:", + asym_op->dh.pub_key.data, asym_op->dh.pub_key.length); + + debug_hexdump(stdout, "priv key:", + asym_op->dh.priv_key.data, asym_op->dh.priv_key.length); + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) + rte_crypto_op_free(op); + + return status; +} + +static int +test_dh_gen_kp(struct rte_crypto_asym_xform *xfrm) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + uint8_t out_pub_key[TEST_DH_MOD_LEN]; + uint8_t out_prv_key[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform pub_key_xform; + struct rte_crypto_asym_xform xform = *xfrm; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + /* Setup a xform chain to generate + * private key first followed by + * public key + */xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE; + pub_key_xform.xform_type = RTE_CRYPTO_ASYM_XFORM_DH; + pub_key_xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE; + xform.next = &pub_key_xform; + + asym_op->dh.pub_key.data = out_pub_key; + asym_op->dh.pub_key.length = sizeof(out_pub_key); + asym_op->dh.priv_key.data = out_prv_key; + asym_op->dh.priv_key.length = sizeof(out_prv_key); + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + debug_hexdump(stdout, "priv key:", + out_prv_key, asym_op->dh.priv_key.length); + debug_hexdump(stdout, "pub key:", + out_pub_key, asym_op->dh.pub_key.length); + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) + rte_crypto_op_free(op); + + return status; +} + +static int +test_mod_inv(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + struct rte_cryptodev_asym_capability_idx cap_idx; + const struct rte_cryptodev_asymmetric_xform_capability *capability; + uint8_t input[TEST_DATA_SIZE] = {0}; + int ret = 0; + + if (rte_cryptodev_asym_get_xform_enum( + &modinv_xform.xform_type, "modinv") < 0) { + RTE_LOG(ERR, USER1, + "Invalid ASYNC algorithm specified\n"); + return -1; + } + + cap_idx.type = modinv_xform.xform_type; + capability = rte_cryptodev_asym_capability_get(dev_id, + &cap_idx); + + if (rte_cryptodev_asym_xform_capability_check_modlen( + capability, + modinv_xform.modinv.modulus.length)) { + RTE_LOG(ERR, USER1, + "Invalid MODULOUS length specified\n"); + return -1; + } + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (!sess) { + RTE_LOG(ERR, USER1, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (rte_cryptodev_asym_session_init(dev_id, sess, &modinv_xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* generate crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + asym_op = op->asym; + memcpy(input, base, sizeof(base)); + asym_op->modinv.base.data = input; + asym_op->modinv.base.length = sizeof(base); + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + ret = verify_modinv(mod_inv, result_op); + if (ret) { + RTE_LOG(ERR, USER1, + "operation verification failed\n"); + status = TEST_FAILED; + } + +error_exit: + if (sess) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + + if (op) + rte_crypto_op_free(op); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return status; +} + +static int +test_mod_exp(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + struct rte_cryptodev_asym_capability_idx cap_idx; + const struct rte_cryptodev_asymmetric_xform_capability *capability; + uint8_t input[TEST_DATA_SIZE] = {0}; + int ret = 0; + + if (rte_cryptodev_asym_get_xform_enum(&modex_xform.xform_type, + "modexp") + < 0) { + RTE_LOG(ERR, USER1, + "Invalid ASYNC algorithm specified\n"); + return -1; + } + + /* check for modlen capability */ + cap_idx.type = modex_xform.xform_type; + capability = rte_cryptodev_asym_capability_get(dev_id, &cap_idx); + + if (rte_cryptodev_asym_xform_capability_check_modlen( + capability, modex_xform.modex.modulus.length)) { + RTE_LOG(ERR, USER1, + "Invalid MODULOUS length specified\n"); + return -1; + } + + /* generate crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (!sess) { + RTE_LOG(ERR, USER1, + "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (rte_cryptodev_asym_session_init(dev_id, sess, &modex_xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + asym_op = op->asym; + memcpy(input, base, sizeof(base)); + asym_op->modex.base.data = input; + asym_op->modex.base.length = sizeof(base); + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + ret = verify_modexp(mod_exp, result_op); + if (ret) { + RTE_LOG(ERR, USER1, + "operation verification failed\n"); + status = TEST_FAILED; + } + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + + if (op != NULL) + rte_crypto_op_free(op); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return status; +} + +static int +test_dh_keygenration(void) +{ + int status; + + debug_hexdump(stdout, "p:", dh_xform.dh.p.data, dh_xform.dh.p.length); + debug_hexdump(stdout, "g:", dh_xform.dh.g.data, dh_xform.dh.g.length); + debug_hexdump(stdout, "priv_key:", dh_test_params.priv_key.data, + dh_test_params.priv_key.length); + + RTE_LOG(INFO, USER1, + "Test Public and Private key pair generation\n"); + + status = test_dh_gen_kp(&dh_xform); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + RTE_LOG(INFO, USER1, + "Test Public Key Generation using pre-defined priv key\n"); + + status = test_dh_gen_pub_key(&dh_xform); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + RTE_LOG(INFO, USER1, + "Test Private Key Generation only\n"); + + status = test_dh_gen_priv_key(&dh_xform); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + RTE_LOG(INFO, USER1, + "Test shared secret compute\n"); + + status = test_dh_gen_shared_sec(&dh_xform); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return status; +} + +static int +test_dsa_sign(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + uint8_t r[TEST_DH_MOD_LEN]; + uint8_t s[TEST_DH_MOD_LEN]; + uint8_t dgst[] = "35d81554afaad2cf18f3a1770d5fedc4ea5be344"; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + + debug_hexdump(stdout, "p: ", dsa_xform.dsa.p.data, + dsa_xform.dsa.p.length); + debug_hexdump(stdout, "q: ", dsa_xform.dsa.q.data, + dsa_xform.dsa.q.length); + debug_hexdump(stdout, "g: ", dsa_xform.dsa.g.data, + dsa_xform.dsa.g.length); + debug_hexdump(stdout, "priv_key: ", dsa_xform.dsa.x.data, + dsa_xform.dsa.x.length); + + if (rte_cryptodev_asym_session_init(dev_id, sess, &dsa_xform, + sess_mpool) < 0) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; + asym_op->dsa.message.data = dgst; + asym_op->dsa.message.length = sizeof(dgst); + asym_op->dsa.r.length = sizeof(r); + asym_op->dsa.r.data = r; + asym_op->dsa.s.length = sizeof(s); + asym_op->dsa.s.data = s; + + RTE_LOG(DEBUG, USER1, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + asym_op = result_op->asym; + + debug_hexdump(stdout, "r:", + asym_op->dsa.r.data, asym_op->dsa.r.length); + debug_hexdump(stdout, "s:", + asym_op->dsa.s.data, asym_op->dsa.s.length); + + /* Test PMD DSA sign verification using signer public key */ + asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; + + /* copy signer public key */ + asym_op->dsa.y.data = dsa_test_params.y.data; + asym_op->dsa.y.length = dsa_test_params.y.length; + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + RTE_LOG(ERR, USER1, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + } +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) + rte_crypto_op_free(op); + return status; +} + +static int +test_dsa(void) +{ + int status; + status = test_dsa_sign(); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + return status; +} + + +static struct unit_test_suite cryptodev_openssl_asym_testsuite = { + .suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_capability), + TEST_CASE_ST(ut_setup, ut_teardown, test_dsa), + TEST_CASE_ST(ut_setup, ut_teardown, test_dh_keygenration), + TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_enc_dec), + TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_sign_verify), + TEST_CASE_ST(ut_setup, ut_teardown, test_mod_inv), + TEST_CASE_ST(ut_setup, ut_teardown, test_mod_exp), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_cryptodev_openssl_asym(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "OPENSSL PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_OPENSSL is enabled " + "in config file to run this testsuite.\n"); + return TEST_FAILED; + } + + return unit_test_suite_runner(&cryptodev_openssl_asym_testsuite); +} + +REGISTER_TEST_COMMAND(cryptodev_openssl_asym_autotest, + test_cryptodev_openssl_asym); diff --git a/app/test/test_cryptodev_asym_util.h b/app/test/test_cryptodev_asym_util.h new file mode 100644 index 0000000000..dff0c2ada6 --- /dev/null +++ b/app/test/test_cryptodev_asym_util.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Cavium Networks + */ + +#ifndef TEST_CRYPTODEV_ASYM_TEST_UTIL_H__ +#define TEST_CRYPTODEV_ASYM_TEST_UTIL_H__ + +/* Below Apis compare resulted buffer to original test vector */ + +static inline int rsa_verify(struct rsa_test_data *rsa_param, + struct rte_crypto_op *result_op) +{ + if (memcmp(rsa_param->data, + result_op->asym->rsa.message.data, + result_op->asym->rsa.message.length)) + return -1; + return 0; +} + +static inline int verify_modinv(uint8_t *mod_inv, + struct rte_crypto_op *result_op) +{ + if (memcmp(mod_inv, result_op->asym->modinv.base.data, + result_op->asym->modinv.base.length)) + return -1; + return 0; +} + +static inline int verify_modexp(uint8_t *mod_exp, + struct rte_crypto_op *result_op) +{ + if (memcmp(mod_exp, result_op->asym->modex.base.data, + result_op->asym->modex.base.length)) + return -1; + return 0; +} + +#endif /* TEST_CRYPTODEV_ASYM_TEST_UTIL_H__ */ + + + + diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c new file mode 100644 index 0000000000..1f06891146 --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.c @@ -0,0 +1,752 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015-2017 Intel Corporation + */ + +#include +#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" + +static int +test_blockcipher_one_case(const struct blockcipher_test_case *t, + struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + struct rte_mempool *sess_mpool, + struct rte_mempool *sess_priv_mpool, + uint8_t dev_id, + int driver_id, + 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_info dev_info; + struct rte_cryptodev_sym_session *sess = NULL; + + 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 openssl_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + int ccp_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_PMD)); + int scheduler_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)); + int armv8_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); + int aesni_mb_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + int qat_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)); + int dpaa2_sec_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)); + int dpaa_sec_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)); + int caam_jr_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)); + int mrvl_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)); + int virtio_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)); + int octeontx_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)); + + int nb_segs = 1; + + rte_cryptodev_info_get(dev_id, &dev_info); + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) { + uint64_t feat_flags = dev_info.feature_flags; + uint64_t oop_flag = RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT; + + if (t->feature_mask && BLOCKCIPHER_TEST_FEATURE_OOP) { + if (!(feat_flags & oop_flag)) { + printf("Device doesn't support out-of-place " + "scatter-gather in input mbuf. " + "Test Skipped.\n"); + return 0; + } + } else { + if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) { + printf("Device doesn't support in-place " + "scatter-gather mbufs. " + "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); + + if (driver_id == dpaa2_sec_pmd || + driver_id == dpaa_sec_pmd || + driver_id == caam_jr_pmd || + driver_id == qat_pmd || + driver_id == openssl_pmd || + driver_id == armv8_pmd || + driver_id == mrvl_pmd || + driver_id == ccp_pmd || + driver_id == virtio_pmd || + driver_id == octeontx_pmd) { /* Fall through */ + digest_len = tdata->digest.len; + } else if (driver_id == aesni_mb_pmd || + driver_id == scheduler_pmd) { + digest_len = tdata->digest.truncated_len; + } else { + 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_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); + + 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; + cipher_xform->cipher.iv.offset = IV_OFFSET; + cipher_xform->cipher.iv.length = tdata->iv.len; + + sym_op->cipher.data.offset = 0; + sym_op->cipher.data.length = tdata->ciphertext.len; + rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET), + tdata->iv.data, + tdata->iv.len); + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { + uint32_t digest_offset = tdata->ciphertext.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_iova_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_iova_offset(sym_op->m_src, + digest_offset); + } + + sym_op->auth.data.offset = 0; + sym_op->auth.data.length = tdata->ciphertext.len; + } + + /* create session for sessioned op */ + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + sess = rte_cryptodev_sym_session_create(sess_mpool); + + rte_cryptodev_sym_session_init(dev_id, sess, init_xform, + sess_priv_mpool); + 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); + } + + debug_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) { + debug_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; + } + + debug_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) + debug_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) && + (op->status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED)) + 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: Operation 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, 0, 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 = 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, changed_len = 0; + uint32_t i; + uint32_t hdroom_used = 0, tlroom_used = 0; + uint32_t hdroom = 0; + + mbuf = sym_op->m_src; + /* + * Crypto PMDs specify the headroom & tailroom it would use + * when processing the crypto operation. PMD is free to modify + * this space, and so the verification check should skip that + * block. + */ + hdroom_used = dev_info.min_mbuf_headroom_req; + tlroom_used = dev_info.min_mbuf_tailroom_req; + + /* Get headroom */ + hdroom = rte_pktmbuf_headroom(mbuf); + + head_unchanged_len = mbuf->buf_len; + + for (i = 0; i < mbuf->buf_len; i++) { + + /* Skip headroom used by PMD */ + if (i == hdroom - hdroom_used) + i += hdroom_used; + + /* Skip tailroom used by PMD */ + if (i == (hdroom + mbuf->data_len)) + i += tlroom_used; + + 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 = hdroom + sym_op->auth.data.offset; + changed_len = sym_op->auth.data.length; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) + changed_len += digest_len; + } else { + /* cipher-only */ + head_unchanged_len = hdroom + + 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; + uint32_t hdroom_used = 0, tlroom_used = 0; + uint32_t hdroom = 0; + + /* + * Crypto PMDs specify the headroom & tailroom it would use + * when processing the crypto operation. PMD is free to modify + * this space, and so the verification check should skip that + * block. + */ + hdroom_used = dev_info.min_mbuf_headroom_req; + tlroom_used = dev_info.min_mbuf_tailroom_req; + + mbuf = sym_op->m_src; + + /* Get headroom */ + hdroom = rte_pktmbuf_headroom(mbuf); + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + head_unchanged_len = hdroom + + sym_op->cipher.data.offset; + changed_len = sym_op->cipher.data.length; + } else { + /* auth-only */ + head_unchanged_len = hdroom + + sym_op->auth.data.offset + + sym_op->auth.data.length; + changed_len = 0; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) + changed_len += digest_len; + + for (i = 0; i < mbuf->buf_len; i++) { + + /* Skip headroom used by PMD */ + if (i == hdroom - hdroom_used) + i += hdroom_used; + + if (i == head_unchanged_len) + i += changed_len; + + /* Skip tailroom used by PMD */ + if (i == (hdroom + mbuf->data_len)) + i += tlroom_used; + + 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_clear(dev_id, sess); + rte_cryptodev_sym_session_free(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, + struct rte_mempool *sess_mpool, + struct rte_mempool *sess_priv_mpool, + uint8_t dev_id, + int driver_id, + 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; + + int openssl_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + int ccp_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CCP_PMD)); + int dpaa2_sec_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)); + int dpaa_sec_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)); + int caam_jr_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)); + int scheduler_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)); + int armv8_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); + int aesni_mb_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); + int qat_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)); + int mrvl_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)); + int virtio_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)); + int octeontx_pmd = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)); + + 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_AES_DOCSIS_TYPE: + n_test_cases = sizeof(aes_docsis_test_cases) / + sizeof(aes_docsis_test_cases[0]); + tcs = aes_docsis_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_DES_DOCSIS_TYPE: + n_test_cases = sizeof(des_docsis_test_cases) / + sizeof(des_docsis_test_cases[0]); + tcs = des_docsis_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; + } + + if (driver_id == aesni_mb_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; + else if (driver_id == qat_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; + else if (driver_id == openssl_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL; + else if (driver_id == armv8_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8; + else if (driver_id == scheduler_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER; + else if (driver_id == dpaa2_sec_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC; + else if (driver_id == ccp_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_CCP; + else if (driver_id == dpaa_sec_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC; + else if (driver_id == caam_jr_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR; + else if (driver_id == mrvl_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MVSAM; + else if (driver_id == virtio_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO; + else if (driver_id == octeontx_pmd) + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX; + else + TEST_ASSERT(0, "Unrecognized cryptodev type"); + + 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, + sess_mpool, sess_priv_mpool, dev_id, driver_id, + 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 new file mode 100644 index 0000000000..5c22d5da6b --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#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_TARGET_PMD_DPAA2_SEC 0x0020 /* DPAA2_SEC flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC 0x0040 /* DPAA_SEC flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_MVSAM 0x0080 /* Marvell flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_CCP 0x0040 /* CCP flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO 0x0200 /* VIRTIO flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX 0x0100 /* OCTEON TX flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR 0x0400 /* CAAM_JR flag */ + +#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_AES_DOCSIS_TYPE, /* use aes_docsis_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[] */ + BLKCIPHER_DES_DOCSIS_TYPE /* use des_docsis_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, + struct rte_mempool *sess_mpool, + struct rte_mempool *sess_priv_mpool, + uint8_t dev_id, + int driver_id, + 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 new file mode 100644 index 0000000000..f1b8cbd453 --- /dev/null +++ b/app/test/test_cryptodev_des_test_vectors.h @@ -0,0 +1,1337 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 Intel Corporation + */ + +#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 +triple_des64cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_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_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 | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM + }, + { + .test_descr = "DES-CBC Decryption", + .test_data = &des_cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM + }, + +}; + +/* DES-DOCSIS-BPI test vectors */ + +static const uint8_t plaintext_des_docsis_bpi_cfb[] = { + 0x00, 0x01, 0x02, 0x88, 0xEE, 0x59, 0x7E +}; + +static const uint8_t ciphertext_des_docsis_bpi_cfb[] = { + 0x17, 0x86, 0xA8, 0x03, 0xA0, 0x85, 0x75 +}; + +static const uint8_t plaintext_des_docsis_bpi_cbc_cfb[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x91, + 0xD2, 0xD1, 0x9F +}; + +static const uint8_t ciphertext_des_docsis_bpi_cbc_cfb[] = { + 0x0D, 0xDA, 0x5A, 0xCB, 0xD0, 0x5E, 0x55, 0x67, + 0x51, 0x47, 0x46, 0x86, 0x8A, 0x71, 0xE5, 0x77, + 0xEF, 0xAC, 0x88 +}; + +/* Multiple of DES block size */ +static const struct blockcipher_test_data des_test_data_1 = { + .crypto_algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI, + .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 + }, +}; + +/* Less than DES block size */ +static const struct blockcipher_test_data des_test_data_2 = { + .crypto_algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI, + .cipher_key = { + .data = { + + 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB + }, + .len = 8 + }, + .iv = { + .data = { + 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des_docsis_bpi_cfb, + .len = 7 + }, + .ciphertext = { + .data = ciphertext_des_docsis_bpi_cfb, + .len = 7 + } +}; + +/* Not multiple of DES block size */ +static const struct blockcipher_test_data des_test_data_3 = { + .crypto_algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI, + .cipher_key = { + .data = { + 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB + }, + .len = 8 + }, + .iv = { + .data = { + 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des_docsis_bpi_cbc_cfb, + .len = 19 + }, + .ciphertext = { + .data = ciphertext_des_docsis_bpi_cbc_cfb, + .len = 19 + } +}; +static const struct blockcipher_test_case des_docsis_test_cases[] = { + { + .test_descr = "DES-DOCSIS-BPI Full Block Encryption", + .test_data = &des_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 + }, + { + .test_descr = "DES-DOCSIS-BPI Runt Block Encryption", + .test_data = &des_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 + }, + { + .test_descr = "DES-DOCSIS-BPI Uneven Encryption", + .test_data = &des_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 + }, + { + .test_descr = "DES-DOCSIS-BPI Full Block Decryption", + .test_data = &des_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 + }, + { + .test_descr = "DES-DOCSIS-BPI Runt Block Decryption", + .test_data = &des_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 + }, + { + .test_descr = "DES-DOCSIS-BPI Uneven Decryption", + .test_data = &des_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 + }, + { + .test_descr = "DES-DOCSIS-BPI OOP Full Block Encryption", + .test_data = &des_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "DES-DOCSIS-BPI OOP Runt Block Encryption", + .test_data = &des_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "DES-DOCSIS-BPI OOP Uneven Encryption", + .test_data = &des_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "DES-DOCSIS-BPI OOP Full Block Decryption", + .test_data = &des_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "DES-DOCSIS-BPI OOP Runt Block Decryption", + .test_data = &des_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "DES-DOCSIS-BPI OOP Uneven Decryption", + .test_data = &des_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + 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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_CCP + }, +}; + +static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { + { + .test_descr = "3DES-64-CBC Encryption", + .test_data = &triple_des64cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-64-CBC Decryption", + .test_data = &triple_des64cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MB + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MB + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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_dh_test_vectors.h b/app/test/test_cryptodev_dh_test_vectors.h new file mode 100644 index 0000000000..fe7510dcd3 --- /dev/null +++ b/app/test/test_cryptodev_dh_test_vectors.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Cavium Networks + */ + +#ifndef TEST_CRYPTODEV_DH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_DH_TEST_VECTORS_H_ + +#include "rte_crypto_asym.h" + +#define TEST_DATA_SIZE 4096 +#define TEST_DH_MOD_LEN 1024 + + +struct dh_test_param { + rte_crypto_param priv_key; +}; + +uint8_t dh_priv[] = { + 0x46, 0x3c, 0x7b, 0x43, 0xd1, 0xb8, 0xd4, 0x7a, + 0x56, 0x28, 0x85, 0x79, 0xcc, 0xd8, 0x90, 0x03, + 0x0c, 0x4b, 0xc6, 0xd3, 0x7f, 0xb3, 0x19, 0x84, + 0x8a, 0xc6, 0x0d, 0x24, 0x5e, 0xaa, 0x7e, 0x7a, + 0x73, 0x88, 0xa6, 0x47, 0x7c, 0x42, 0x78, 0x63, + 0x11, 0x12, 0xd3, 0xa0, 0xc5, 0xfe, 0xfd, 0xf2, + 0x9e, 0x17, 0x90, 0xe5, 0x6d, 0xcc, 0x20, 0x6f, + 0xe8, 0x82, 0x28, 0xbf, 0x5c, 0xe6, 0xd4, 0x86, + 0x5c, 0x35, 0x32, 0x97, 0xc2, 0x86, 0x1b, 0xc5, + 0x59, 0x1c, 0x0b, 0x1b, 0xec, 0x60, 0x3c, 0x1d, + 0x8d, 0x7f, 0xf0, 0xc7, 0x48, 0x3a, 0x51, 0x09, + 0xf2, 0x3e, 0x9e, 0x35, 0x74, 0x98, 0x4d, 0xad, + 0x39, 0xa7, 0xf2, 0xd2, 0xb4, 0x32, 0xd3, 0xc8, + 0xe9, 0x45, 0xbe, 0x56, 0xe7, 0x87, 0xe0, 0xa0, + 0x97, 0x6b, 0x5f, 0x99, 0x5e, 0x41, 0x59, 0x33, + 0x95, 0x64, 0x0d, 0xe9, 0x58, 0x5b, 0xa6, 0x38 +}; + +uint8_t dh_p[] = { + 0xef, 0xee, 0x8c, 0x8b, 0x3f, 0x85, 0x95, 0xcd, + 0x4d, 0x68, 0x5d, 0x4a, 0x5d, 0x1f, 0x2a, 0x2e, + 0xdd, 0xcf, 0xef, 0x1b, 0x3b, 0xe9, 0x7b, 0x0c, + 0x13, 0xee, 0x76, 0xd5, 0x93, 0xca, 0x8b, 0xc8, + 0x0b, 0x97, 0x00, 0xec, 0x1f, 0x34, 0xa2, 0xce, + 0x83, 0x8d, 0x80, 0xea, 0xfe, 0x11, 0xed, 0x28, + 0xdd, 0x32, 0x22, 0x77, 0x96, 0x4e, 0xc5, 0xed, + 0xc8, 0x7a, 0x52, 0x10, 0x22, 0xcc, 0xb2, 0x4d, + 0xd3, 0xda, 0x03, 0xf5, 0x1e, 0xa8, 0x79, 0x23, + 0x8b, 0xe1, 0x78, 0x47, 0x07, 0x5b, 0x26, 0xbb, + 0x53, 0x46, 0x0b, 0x18, 0x5c, 0x07, 0x4e, 0xb6, + 0x76, 0xc9, 0xa8, 0xd5, 0x30, 0xa3, 0xbe, 0x8d, + 0xae, 0xcd, 0x34, 0x68, 0x62, 0x5f, 0xb9, 0x5c, + 0x34, 0x90, 0xf0, 0xda, 0x47, 0x86, 0x36, 0x04, + 0x28, 0xbc, 0x7d, 0xae, 0x9d, 0x4e, 0x61, 0x28, + 0x70, 0xdb, 0xa6, 0x55, 0x04, 0x46, 0x27, 0xe3 +}; + +uint8_t dh_g[] = {0x02}; + +struct dh_test_param dh_test_params = { + .priv_key = { + .data = dh_priv, + .length = sizeof(dh_priv) + } +}; + +struct rte_crypto_asym_xform dh_xform = { + .next = NULL, + .xform_type = RTE_CRYPTO_ASYM_XFORM_DH, + .dh = { + .p = { + .data = dh_p, + .length = sizeof(dh_p) + }, + .g = { + .data = dh_g, + .length = sizeof(dh_g) + }, + } +}; + +#endif /* TEST_CRYPTODEV_DH_TEST_VECTORS_H__ */ diff --git a/app/test/test_cryptodev_dsa_test_vectors.h b/app/test/test_cryptodev_dsa_test_vectors.h new file mode 100644 index 0000000000..bbcb0d7297 --- /dev/null +++ b/app/test/test_cryptodev_dsa_test_vectors.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Cavium Networks + */ + +#ifndef TEST_CRYPTODEV_DSA_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_DSA_TEST_VECTORS_H_ + +#include "rte_crypto_asym.h" + +#define TEST_DATA_SIZE 4096 + + +struct dsa_test_param { + rte_crypto_param y; +}; + +static unsigned char dsa_x[] = { + 0xc5, 0x3e, 0xae, 0x6d, 0x45, 0x32, 0x31, 0x64, + 0xc7, 0xd0, 0x7a, 0xf5, 0x71, 0x57, 0x03, 0x74, + 0x4a, 0x63, 0xfc, 0x3a +}; + +uint8_t dsa_y[] = { + 0x31, 0x3f, 0xd9, 0xeb, 0xca, 0x91, 0x57, 0x4e, + 0x1c, 0x2e, 0xeb, 0xe1, 0x51, 0x7c, 0x57, 0xe0, + 0xc2, 0x1b, 0x02, 0x09, 0x87, 0x21, 0x40, 0xc5, + 0x32, 0x87, 0x61, 0xbb, 0xb2, 0x45, 0x0b, 0x33, + 0xf1, 0xb1, 0x8b, 0x40, 0x9c, 0xe9, 0xab, 0x7c, + 0x4c, 0xd8, 0xfd, 0xa3, 0x39, 0x1e, 0x8e, 0x34, + 0x86, 0x83, 0x57, 0xc1, 0x99, 0xe1, 0x6a, 0x6b, + 0x2e, 0xba, 0x06, 0xd6, 0x74, 0x9d, 0xef, 0x79, + 0x1d, 0x79, 0xe9, 0x5d, 0x3a, 0x4d, 0x09, 0xb2, + 0x4c, 0x39, 0x2a, 0xd8, 0x9d, 0xbf, 0x10, 0x09, + 0x95, 0xae, 0x19, 0xc0, 0x10, 0x62, 0x05, 0x6b, + 0xb1, 0x4b, 0xce, 0x00, 0x5e, 0x87, 0x31, 0xef, + 0xde, 0x17, 0x5f, 0x95, 0xb9, 0x75, 0x08, 0x9b, + 0xdc, 0xda, 0xea, 0x56, 0x2b, 0x32, 0x78, 0x6d, + 0x96, 0xf5, 0xa3, 0x1a, 0xed, 0xf7, 0x53, 0x64, + 0x00, 0x8a, 0xd4, 0xff, 0xfe, 0xbb, 0x97, 0x0b +}; + +static unsigned char dsa_p[] = { + 0xa8, 0xf9, 0xcd, 0x20, 0x1e, 0x5e, 0x35, 0xd8, + 0x92, 0xf8, 0x5f, 0x80, 0xe4, 0xdb, 0x25, 0x99, + 0xa5, 0x67, 0x6a, 0x3b, 0x1d, 0x4f, 0x19, 0x03, + 0x30, 0xed, 0x32, 0x56, 0xb2, 0x6d, 0x0e, 0x80, + 0xa0, 0xe4, 0x9a, 0x8f, 0xff, 0xaa, 0xad, 0x2a, + 0x24, 0xf4, 0x72, 0xd2, 0x57, 0x32, 0x41, 0xd4, + 0xd6, 0xd6, 0xc7, 0x48, 0x0c, 0x80, 0xb4, 0xc6, + 0x7b, 0xb4, 0x47, 0x9c, 0x15, 0xad, 0xa7, 0xea, + 0x84, 0x24, 0xd2, 0x50, 0x2f, 0xa0, 0x14, 0x72, + 0xe7, 0x60, 0x24, 0x17, 0x13, 0xda, 0xb0, 0x25, + 0xae, 0x1b, 0x02, 0xe1, 0x70, 0x3a, 0x14, 0x35, + 0xf6, 0x2d, 0xdf, 0x4e, 0xe4, 0xc1, 0xb6, 0x64, + 0x06, 0x6e, 0xb2, 0x2f, 0x2e, 0x3b, 0xf2, 0x8b, + 0xb7, 0x0a, 0x2a, 0x76, 0xe4, 0xfd, 0x5e, 0xbe, + 0x2d, 0x12, 0x29, 0x68, 0x1b, 0x5b, 0x06, 0x43, + 0x9a, 0xc9, 0xc7, 0xe9, 0xd8, 0xbd, 0xe2, 0x83 +}; + +static unsigned char dsa_q[] = { + 0xf8, 0x5f, 0x0f, 0x83, 0xac, 0x4d, 0xf7, 0xea, + 0x0c, 0xdf, 0x8f, 0x46, 0x9b, 0xfe, 0xea, 0xea, + 0x14, 0x15, 0x64, 0x95 +}; + +static unsigned char dsa_g[] = { + 0x2b, 0x31, 0x52, 0xff, 0x6c, 0x62, 0xf1, 0x46, + 0x22, 0xb8, 0xf4, 0x8e, 0x59, 0xf8, 0xaf, 0x46, + 0x88, 0x3b, 0x38, 0xe7, 0x9b, 0x8c, 0x74, 0xde, + 0xea, 0xe9, 0xdf, 0x13, 0x1f, 0x8b, 0x85, 0x6e, + 0x3a, 0xd6, 0xc8, 0x45, 0x5d, 0xab, 0x87, 0xcc, + 0x0d, 0xa8, 0xac, 0x97, 0x34, 0x17, 0xce, 0x4f, + 0x78, 0x78, 0x55, 0x7d, 0x6c, 0xdf, 0x40, 0xb3, + 0x5b, 0x4a, 0x0c, 0xa3, 0xeb, 0x31, 0x0c, 0x6a, + 0x95, 0xd6, 0x8c, 0xe2, 0x84, 0xad, 0x4e, 0x25, + 0xea, 0x28, 0x59, 0x16, 0x11, 0xee, 0x08, 0xb8, + 0x44, 0x4b, 0xd6, 0x4b, 0x25, 0xf3, 0xf7, 0xc5, + 0x72, 0x41, 0x0d, 0xdf, 0xb3, 0x9c, 0xc7, 0x28, + 0xb9, 0xc9, 0x36, 0xf8, 0x5f, 0x41, 0x91, 0x29, + 0x86, 0x99, 0x29, 0xcd, 0xb9, 0x09, 0xa6, 0xa3, + 0xa9, 0x9b, 0xbe, 0x08, 0x92, 0x16, 0x36, 0x81, + 0x71, 0xbd, 0x0b, 0xa8, 0x1d, 0xe4, 0xfe, 0x33 +}; + +struct dsa_test_param dsa_test_params = { + .y = { + .data = dsa_y, + .length = sizeof(dsa_y) + } +}; + +struct rte_crypto_asym_xform dsa_xform = { + .next = NULL, + .xform_type = RTE_CRYPTO_ASYM_XFORM_DSA, + .dsa = { + .p = { + .data = dsa_p, + .length = sizeof(dsa_p) + }, + .q = { + .data = dsa_q, + .length = sizeof(dsa_q) + }, + .g = { + .data = dsa_g, + .length = sizeof(dsa_g) + }, + .x = { + .data = dsa_x, + .length = sizeof(dsa_x) + } + + } +}; + +#endif /* TEST_CRYPTODEV_DSA_TEST_VECTORS_H__ */ diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h new file mode 100644 index 0000000000..d3a26609c9 --- /dev/null +++ b/app/test/test_cryptodev_hash_test_vectors.h @@ -0,0 +1,747 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#ifndef TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ + +#ifdef RTE_LIBRTE_PMD_AESNI_MB +#include +#endif + +#if !defined(IMB_VERSION_NUM) +#define IMB_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) +#define IMB_VERSION_NUM IMB_VERSION(0, 49, 0) +#endif + +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, + .truncated_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, + .truncated_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, + .truncated_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, + .truncated_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, + .truncated_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_data +cmac_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_AES_CMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }, + .len = 16 + }, + .digest = { + .data = { + 0x4C, 0x77, 0x87, 0xA0, 0x78, 0x8E, 0xEA, 0x96, + 0xC1, 0xEB, 0x1E, 0x4E, 0x95, 0x8F, 0xED, 0x27 + }, + .len = 16, + .truncated_len = 16 + } +}; + +static const struct blockcipher_test_data +cmac_test_vector_12 = { + .auth_algo = RTE_CRYPTO_AUTH_AES_CMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }, + .len = 16 + }, + .digest = { + .data = { + 0x4C, 0x77, 0x87, 0xA0, 0x78, 0x8E, 0xEA, 0x96, + 0xC1, 0xEB, 0x1E, 0x4E, 0x95, 0x8F, 0xED, 0x27 + }, + .len = 12, + .truncated_len = 12 + } +}; + +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 | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "MD5 Digest Verify", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA1 Digest", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA1 Digest Verify", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "HMAC-SHA1 Digest Scatter Gather", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "HMAC-SHA1 Digest Verify Scatter Gather", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA224 Digest", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA224 Digest Verify", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA256 Digest", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA256 Digest Verify", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA384 Digest", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA384 Digest Verify", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA512 Digest", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "SHA512 Digest Verify", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | +#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) + BLOCKCIPHER_TEST_TARGET_PMD_MB | +#endif + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .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 | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | + BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | + BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_CCP | + BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX + }, + { + .test_descr = "CMAC Digest 12B", + .test_data = &cmac_test_vector_12, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "CMAC Digest Verify 12B", + .test_data = &cmac_test_vector_12, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "CMAC Digest 16B", + .test_data = &cmac_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "CMAC Digest Verify 16B", + .test_data = &cmac_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + } +}; + +#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 new file mode 100644 index 0000000000..77153a5c10 --- /dev/null +++ b/app/test/test_cryptodev_hmac_test_vectors.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..5033d1830b --- /dev/null +++ b/app/test/test_cryptodev_kasumi_hash_test_vectors.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#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), FRESH (4 bytes), message + * and DIRECTION (1 bit), plus 1 0*, with enough 0s, + * so total length is multiple of 8 or 64 bits + */ + struct { + uint8_t data[2056]; + unsigned len; /* length must be in Bits */ + } plaintext; + + 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 + }, + .plaintext = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + 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 = 256 + }, + .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 + }, + .plaintext = { + .data = { + 0x3E, 0xDC, 0x87, 0xE2, 0xA4, 0xF2, 0xD8, 0xE2, + 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 = 320 + }, + .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 + }, + .plaintext = { + .data = { + 0x36, 0xAF, 0x61, 0x44, 0x98, 0x38, 0xF0, 0x3A, + 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 = 448 + }, + .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 + }, + .plaintext = { + .data = { + 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, + 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 = 512 + }, + .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 + }, + .plaintext = { + .data = { + 0x29, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0x77, 0x37, + 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 = 1088 + }, + .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 + }, + .plaintext = { + .data = { + 0x36, 0xAF, 0x61, 0x44, 0x4F, 0x30, 0x2A, 0xD2, + 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 = 840 + }, + .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 + }, + .plaintext = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, + 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 + }, + .len = 192 + }, + .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 new file mode 100644 index 0000000000..58a696a339 --- /dev/null +++ b/app/test/test_cryptodev_kasumi_test_vectors.h @@ -0,0 +1,359 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#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; + } cipher_iv; + + /* + * Data may include COUNT (4 bytes), FRESH (4 bytes), + * DIRECTION (1 bit), plus 1 0*, with enough 0s, + * so total length is multiple of 8 or 64 bits + */ + struct { + uint8_t data[1024]; + 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 int len; + } validCipherOffsetInBits; + + /* Actual length of data to be hashed */ + struct { + unsigned len; + } validAuthLenInBits; + + 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 + }, + .cipher_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 + }, + .validCipherOffsetInBits = { + .len = 0 + } +}; + +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 + }, + .cipher_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 + }, + .validCipherOffsetInBits = { + .len = 0 + } +}; + +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 + }, + .cipher_iv = { + .data = { + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, + 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 + }, + .len = 192 + }, + .ciphertext = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, + 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25, 0xC0 + }, + .len = 192 + }, + .validDataLenInBits = { + .len = 192 + }, + .validCipherLenInBits = { + .len = 120 + }, + .validAuthLenInBits = { + .len = 192 + }, + .validCipherOffsetInBits = { + .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 + }, + .cipher_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 + }, + .validCipherOffsetInBits = { + .len = 0 + } +}; + +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 + }, + .cipher_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 + }, + .validCipherOffsetInBits = { + .len = 0 + } +}; + +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 + }, + .cipher_iv = { + .data = { + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, + 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 + }, + .len = 192 + }, + .ciphertext = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, + 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25, 0xC0 + }, + .len = 192 + }, + .validDataLenInBits = { + .len = 192 + }, + .validCipherLenInBits = { + .len = 120 + }, + .validCipherOffsetInBits = { + .len = 64 + }, + .validAuthLenInBits = { + .len = 192 + }, + .digest = { + .data = {0x0F, 0xD2, 0xAA, 0xB5}, + .len = 4 + } +}; +#endif /* TEST_CRYPTODEV_KASUMI_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_mod_test_vectors.h b/app/test/test_cryptodev_mod_test_vectors.h new file mode 100644 index 0000000000..a25c676ac1 --- /dev/null +++ b/app/test/test_cryptodev_mod_test_vectors.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Cavium Networks + */ + +#ifndef TEST_CRYPTODEV_MOD_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_MOD_TEST_VECTORS_H_ + +/* modular operation test data */ +uint8_t base[] = { + 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, + 0xAE, 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, + 0xA8, 0xEB, 0x7E, 0x78, 0xA0, 0x50 +}; + +uint8_t mod_p[] = { + 0x00, 0xb3, 0xa1, 0xaf, 0xb7, 0x13, 0x08, 0x00, + 0x0a, 0x35, 0xdc, 0x2b, 0x20, 0x8d, 0xa1, 0xb5, + 0xce, 0x47, 0x8a, 0xc3, 0x80, 0xf4, 0x7d, 0x4a, + 0xa2, 0x62, 0xfd, 0x61, 0x7f, 0xb5, 0xa8, 0xde, + 0x0a, 0x17, 0x97, 0xa0, 0xbf, 0xdf, 0x56, 0x5a, + 0x3d, 0x51, 0x56, 0x4f, 0x70, 0x70, 0x3f, 0x63, + 0x6a, 0x44, 0x5b, 0xad, 0x84, 0x0d, 0x3f, 0x27, + 0x6e, 0x3b, 0x34, 0x91, 0x60, 0x14, 0xb9, 0xaa, + 0x72, 0xfd, 0xa3, 0x64, 0xd2, 0x03, 0xa7, 0x53, + 0x87, 0x9e, 0x88, 0x0b, 0xc1, 0x14, 0x93, 0x1a, + 0x62, 0xff, 0xb1, 0x5d, 0x74, 0xcd, 0x59, 0x63, + 0x18, 0x11, 0x3d, 0x4f, 0xba, 0x75, 0xd4, 0x33, + 0x4e, 0x23, 0x6b, 0x7b, 0x57, 0x44, 0xe1, 0xd3, + 0x03, 0x13, 0xa6, 0xf0, 0x8b, 0x60, 0xb0, 0x9e, + 0xee, 0x75, 0x08, 0x9d, 0x71, 0x63, 0x13, 0xcb, + 0xa6, 0x81, 0x92, 0x14, 0x03, 0x22, 0x2d, 0xde, + 0x55 +}; + +uint8_t mod_e[] = {0x01, 0x00, 0x01}; + +/* Precomputed modular exponentiation for verification */ +uint8_t mod_exp[] = { + 0x2C, 0x60, 0x75, 0x45, 0x98, 0x9D, 0xE0, 0x72, + 0xA0, 0x9D, 0x3A, 0x9E, 0x03, 0x38, 0x73, 0x3C, + 0x31, 0x83, 0x04, 0xFE, 0x75, 0x43, 0xE6, 0x17, + 0x5C, 0x01, 0x29, 0x51, 0x69, 0x33, 0x62, 0x2D, + 0x78, 0xBE, 0xAE, 0xC4, 0xBC, 0xDE, 0x7E, 0x2C, + 0x77, 0x84, 0xF2, 0xC5, 0x14, 0xB5, 0x2F, 0xF7, + 0xC5, 0x94, 0xEF, 0x86, 0x75, 0x75, 0xB5, 0x11, + 0xE5, 0x0E, 0x0A, 0x29, 0x76, 0xE2, 0xEA, 0x32, + 0x0E, 0x43, 0x77, 0x7E, 0x2C, 0x27, 0xAC, 0x3B, + 0x86, 0xA5, 0xDB, 0xC9, 0x48, 0x40, 0xE8, 0x99, + 0x9A, 0x0A, 0x3D, 0xD6, 0x74, 0xFA, 0x2E, 0x2E, + 0x5B, 0xAF, 0x8C, 0x99, 0x44, 0x2A, 0x67, 0x38, + 0x27, 0x41, 0x59, 0x9D, 0xB8, 0x51, 0xC9, 0xF7, + 0x43, 0x61, 0x31, 0x6E, 0xF1, 0x25, 0x38, 0x7F, + 0xAE, 0xC6, 0xD0, 0xBB, 0x29, 0x76, 0x3F, 0x46, + 0x2E, 0x1B, 0xE4, 0x67, 0x71, 0xE3, 0x87, 0x5A +}; + +/* Precomputed modular inverse for verification */ +uint8_t mod_inv[] = { + 0x52, 0xb1, 0xa3, 0x8c, 0xc5, 0x8a, 0xb9, 0x1f, + 0xb6, 0x82, 0xf5, 0x6a, 0x9a, 0xde, 0x8d, 0x2e, + 0x62, 0x4b, 0xac, 0x49, 0x21, 0x1d, 0x30, 0x4d, + 0x32, 0xac, 0x1f, 0x40, 0x6d, 0x52, 0xc7, 0x9b, + 0x6c, 0x0a, 0x82, 0x3a, 0x2c, 0xaf, 0x6b, 0x6d, + 0x17, 0xbe, 0x43, 0xed, 0x97, 0x78, 0xeb, 0x4c, + 0x92, 0x6f, 0xcf, 0xed, 0xb1, 0x09, 0xcb, 0x27, + 0xc2, 0xde, 0x62, 0xfd, 0x21, 0xe6, 0xbd, 0x4f, + 0xfe, 0x7a, 0x1b, 0x50, 0xfe, 0x10, 0x4a, 0xb0, + 0xb7, 0xcf, 0xdb, 0x7d, 0xca, 0xc2, 0xf0, 0x1c, + 0x39, 0x48, 0x6a, 0xb5, 0x4d, 0x8c, 0xfe, 0x63, + 0x91, 0x9c, 0x21, 0xc3, 0x0e, 0x76, 0xad, 0x44, + 0x8d, 0x54, 0x33, 0x99, 0xe1, 0x80, 0x19, 0xba, + 0xb5, 0xac, 0x7d, 0x9c, 0xce, 0x91, 0x2a, 0xd9, + 0x2c, 0xe1, 0x16, 0xd6, 0xd7, 0xcf, 0x9d, 0x05, + 0x9a, 0x66, 0x9a, 0x3a, 0xc1, 0xb8, 0x4b, 0xc3 +}; + +struct rte_crypto_asym_xform modex_xform = { + .next = NULL, + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX, + .modex = { + .modulus = { + .data = mod_p, + .length = sizeof(mod_p) + }, + .exponent = { + .data = mod_e, + .length = sizeof(mod_e) + } + } +}; + +struct rte_crypto_asym_xform modinv_xform = { + .next = NULL, + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV, + .modinv = { + .modulus = { + .data = mod_p, + .length = sizeof(mod_p) + } + } +}; + +#endif /* TEST_CRYPTODEV_MOD_TEST_VECTORS_H__ */ diff --git a/app/test/test_cryptodev_rsa_test_vectors.h b/app/test/test_cryptodev_rsa_test_vectors.h new file mode 100644 index 0000000000..3f8c41a673 --- /dev/null +++ b/app/test/test_cryptodev_rsa_test_vectors.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Cavium Networks + */ + +#ifndef TEST_CRYPTODEV_RSA_TEST_VECTORS_H__ +#define TEST_CRYPTODEV_RSA_TEST_VECTORS_H__ + +#include "rte_crypto_asym.h" + +#define TEST_DATA_SIZE 4096 + +struct rsa_test_data { + uint8_t data[TEST_DATA_SIZE]; + unsigned int len; +}; + +struct rsa_test_data rsaplaintext = { + .data = { + 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae, + 0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb, + 0x7e, 0x78, 0xa0, 0x50 + }, + .len = 20 +}; + +uint8_t rsa_n[] = { + 0xb3, 0xa1, 0xaf, 0xb7, 0x13, 0x08, 0x00, + 0x0a, 0x35, 0xdc, 0x2b, 0x20, 0x8d, 0xa1, 0xb5, + 0xce, 0x47, 0x8a, 0xc3, 0x80, 0xf4, 0x7d, 0x4a, + 0xa2, 0x62, 0xfd, 0x61, 0x7f, 0xb5, 0xa8, 0xde, + 0x0a, 0x17, 0x97, 0xa0, 0xbf, 0xdf, 0x56, 0x5a, + 0x3d, 0x51, 0x56, 0x4f, 0x70, 0x70, 0x3f, 0x63, + 0x6a, 0x44, 0x5b, 0xad, 0x84, 0x0d, 0x3f, 0x27, + 0x6e, 0x3b, 0x34, 0x91, 0x60, 0x14, 0xb9, 0xaa, + 0x72, 0xfd, 0xa3, 0x64, 0xd2, 0x03, 0xa7, 0x53, + 0x87, 0x9e, 0x88, 0x0b, 0xc1, 0x14, 0x93, 0x1a, + 0x62, 0xff, 0xb1, 0x5d, 0x74, 0xcd, 0x59, 0x63, + 0x18, 0x11, 0x3d, 0x4f, 0xba, 0x75, 0xd4, 0x33, + 0x4e, 0x23, 0x6b, 0x7b, 0x57, 0x44, 0xe1, 0xd3, + 0x03, 0x13, 0xa6, 0xf0, 0x8b, 0x60, 0xb0, 0x9e, + 0xee, 0x75, 0x08, 0x9d, 0x71, 0x63, 0x13, 0xcb, + 0xa6, 0x81, 0x92, 0x14, 0x03, 0x22, 0x2d, 0xde, + 0x55 +}; + +uint8_t rsa_d[] = { + 0x24, 0xd7, 0xea, 0xf4, 0x7f, 0xe0, 0xca, 0x31, + 0x4d, 0xee, 0xc4, 0xa1, 0xbe, 0xab, 0x06, 0x61, + 0x32, 0xe7, 0x51, 0x46, 0x27, 0xdf, 0x72, 0xe9, + 0x6f, 0xa8, 0x4c, 0xd1, 0x26, 0xef, 0x65, 0xeb, + 0x67, 0xff, 0x5f, 0xa7, 0x3b, 0x25, 0xb9, 0x08, + 0x8e, 0xa0, 0x47, 0x56, 0xe6, 0x8e, 0xf9, 0xd3, + 0x18, 0x06, 0x3d, 0xc6, 0xb1, 0xf8, 0xdc, 0x1b, + 0x8d, 0xe5, 0x30, 0x54, 0x26, 0xac, 0x16, 0x3b, + 0x7b, 0xad, 0x46, 0x9e, 0x21, 0x6a, 0x57, 0xe6, + 0x81, 0x56, 0x1d, 0x2a, 0xc4, 0x39, 0x63, 0x67, + 0x81, 0x2c, 0xca, 0xcc, 0xf8, 0x42, 0x04, 0xbe, + 0xcf, 0x8f, 0x6c, 0x5b, 0x81, 0x46, 0xb9, 0xc7, + 0x62, 0x90, 0x87, 0x35, 0x03, 0x9b, 0x89, 0xcb, + 0x37, 0xbd, 0xf1, 0x1b, 0x99, 0xa1, 0x9a, 0x78, + 0xd5, 0x4c, 0xdd, 0x3f, 0x41, 0x0c, 0xb7, 0x1a, + 0xd9, 0x7b, 0x87, 0x5f, 0xbe, 0xb1, 0x83, 0x41 +}; + +uint8_t rsa_e[] = {0x01, 0x00, 0x01}; + +/** rsa xform using exponent key */ +struct rte_crypto_asym_xform rsa_xform = { + .next = NULL, + .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA, + .rsa = { + .n = { + .data = rsa_n, + .length = sizeof(rsa_n) + }, + .e = { + .data = rsa_e, + .length = sizeof(rsa_e) + }, + .key_type = RTE_RSA_KEY_TYPE_EXP, + .d = { + .data = rsa_d, + .length = sizeof(rsa_d) + } + } +}; + +#endif /* TEST_CRYPTODEV_RSA_TEST_VECTORS_H__ */ diff --git a/app/test/test_cryptodev_snow3g_hash_test_vectors.h b/app/test/test_cryptodev_snow3g_hash_test_vectors.h new file mode 100644 index 0000000000..e9fb2147be --- /dev/null +++ b/app/test/test_cryptodev_snow3g_hash_test_vectors.h @@ -0,0 +1,498 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#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; + } auth_iv; + + struct { + uint8_t data[2056]; + unsigned len; /* length must be in Bits */ + } plaintext; + + struct { + unsigned len; + } validAuthLenInBits; + + 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 + }, + .auth_iv = { + .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 + }, + .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 + }, + .auth_iv = { + .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 + }, + .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 + }, + .auth_iv = { + .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 + }, + .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 + }, + .auth_iv = { + .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 + }, + .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 + }, + .auth_iv = { + .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 + }, + .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 + }, + .auth_iv = { + .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 + }, + .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 new file mode 100644 index 0000000000..cb9dc4b350 --- /dev/null +++ b/app/test/test_cryptodev_snow3g_test_vectors.h @@ -0,0 +1,383 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015-2017 Intel Corporation + */ + +#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; + } cipher_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; + } validAuthLenInBits; + + struct { + uint8_t data[64]; + unsigned len; + } auth_iv; + + 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 + }, + .cipher_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 + }, + .auth_iv = { + .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 + }, + .cipher_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 + }, + .auth_iv = { + .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 + }, + .cipher_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 + }, + .auth_iv = { + .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 + } +}; + +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 + }, + .cipher_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 + } +}; + +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 + }, + .cipher_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 + }, +}; +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 + }, + .cipher_iv = { + .data = { + 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, + 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD + }, + .len = 16 + }, + .auth_iv = { + .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 + }, + .validAuthLenInBits = { + .len = 384 + }, +}; + +#endif /* TEST_CRYPTODEV_SNOW3G_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_zuc_test_vectors.h b/app/test/test_cryptodev_zuc_test_vectors.h new file mode 100644 index 0000000000..9ff821a18d --- /dev/null +++ b/app/test/test_cryptodev_zuc_test_vectors.h @@ -0,0 +1,1043 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#ifndef TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ + +struct wireless_test_data { + struct { + uint8_t data[64]; + unsigned len; + } key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned len; + } cipher_iv; + + struct { + uint8_t data[2048]; + unsigned len; /* length must be in Bits */ + } plaintext; + + struct { + uint8_t data[2048]; + unsigned len; /* length must be in Bits */ + } ciphertext; + + struct { + unsigned len; + } validDataLenInBits; + + struct { + unsigned len; + } validCipherLenInBits; + + struct { + unsigned len; + } validAuthLenInBits; + + struct { + uint8_t data[64]; + unsigned len; + } auth_iv; + + struct { + uint8_t data[64]; + unsigned len; + } digest; +}; +static struct wireless_test_data zuc_test_case_cipher_193b = { + .key = { + .data = { + 0x17, 0x3D, 0x14, 0xBA, 0x50, 0x03, 0x73, 0x1D, + 0x7A, 0x60, 0x04, 0x94, 0x70, 0xF0, 0x0A, 0x29 + }, + .len = 16 + }, + .cipher_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 + } +}; + +static struct wireless_test_data zuc_test_case_cipher_800b = { + .key = { + .data = { + 0xE5, 0xBD, 0x3E, 0xA0, 0xEB, 0x55, 0xAD, 0xE8, + 0x66, 0xC6, 0xAC, 0x58, 0xBD, 0x54, 0x30, 0x2A + }, + .len = 16 + }, + .cipher_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 + } +}; + +static struct wireless_test_data zuc_test_case_cipher_1570b = { + .key = { + .data = { + 0xD4, 0x55, 0x2A, 0x8F, 0xD6, 0xE6, 0x1C, 0xC8, + 0x1A, 0x20, 0x09, 0x14, 0x1A, 0x29, 0xC1, 0x0B + }, + .len = 16 + }, + .cipher_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 + } +}; + +static struct wireless_test_data zuc_test_case_cipher_2798b = { + .key = { + .data = { + 0xDB, 0x84, 0xB4, 0xFB, 0xCC, 0xDA, 0x56, 0x3B, + 0x66, 0x22, 0x7B, 0xFE, 0x45, 0x6F, 0x0F, 0x77 + }, + .len = 16 + }, + .cipher_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 + } +}; + +static struct wireless_test_data zuc_test_case_cipher_4019b = { + .key = { + .data = { + 0xE1, 0x3F, 0xED, 0x21, 0xB4, 0x6E, 0x4E, 0x7E, + 0xC3, 0x12, 0x53, 0xB2, 0xBB, 0x17, 0xB3, 0xE0 + }, + .len = 16 + }, + .cipher_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 + } +}; + +static struct wireless_test_data zuc_test_case_cipher_200b_auth_200b = { + .key = { + .data = { + 0x17, 0x3D, 0x14, 0xBA, 0x50, 0x03, 0x73, 0x1D, + 0x7A, 0x60, 0x04, 0x94, 0x70, 0xF0, 0x0A, 0x29 + }, + .len = 16 + }, + .cipher_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, + 0x10 + }, + .len = 200 + }, + .validDataLenInBits = { + .len = 200 + }, + .validCipherLenInBits = { + .len = 200 + }, + .auth_iv = { + .data = { + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .digest = { + .data = {0x01, 0xFE, 0x5E, 0x38}, + .len = 4 + }, + .validAuthLenInBits = { + .len = 200 + } +}; + +static struct wireless_test_data zuc_test_case_cipher_800b_auth_120b = { + .key = { + .data = { + 0xE5, 0xBD, 0x3E, 0xA0, 0xEB, 0x55, 0xAD, 0xE8, + 0x66, 0xC6, 0xAC, 0x58, 0xBD, 0x54, 0x30, 0x2A + }, + .len = 16 + }, + .cipher_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 + }, + .auth_iv = { + .data = { + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .digest = { + .data = {0x9D, 0x42, 0x1C, 0xEA}, + .len = 4 + }, + .validAuthLenInBits = { + .len = 120 + } +}; + +struct wireless_test_data zuc_test_case_auth_1b = { + .key = { + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .auth_iv = { + .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 + }, + .digest = { + .data = {0xC8, 0xA9, 0x59, 0x5E}, + .len = 4 + } +}; + +struct wireless_test_data zuc_test_case_auth_90b = { + .key = { + .data = { + 0x47, 0x05, 0x41, 0x25, 0x56, 0x1E, 0xB2, 0xDD, + 0xA9, 0x40, 0x59, 0xDA, 0x05, 0x09, 0x78, 0x50 + }, + .len = 16 + }, + .auth_iv = { + .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 + }, + .digest = { + .data = {0x67, 0x19, 0xA0, 0x88}, + .len = 4 + } +}; + +struct wireless_test_data zuc_test_case_auth_577b = { + .key = { + .data = { + 0xC9, 0xE6, 0xCE, 0xC4, 0x60, 0x7C, 0x72, 0xDB, + 0x00, 0x0A, 0xEF, 0xA8, 0x83, 0x85, 0xAB, 0x0A + }, + .len = 16 + }, + .auth_iv = { + .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 + }, + .digest = { + .data = {0xFA, 0xE8, 0xFF, 0x0B}, + .len = 4 + } +}; + +struct wireless_test_data zuc_test_case_auth_2079b = { + .key = { + .data = { + 0xC8, 0xA4, 0x82, 0x62, 0xD0, 0xC2, 0xE2, 0xBA, + 0xC4, 0xB9, 0x6E, 0xF7, 0x7E, 0x80, 0xCA, 0x59 + }, + .len = 16 + }, + .auth_iv = { + .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 + }, + .digest = { + .data = {0x00, 0x4A, 0xC4, 0xD6}, + .len = 4 + } +}; + +struct wireless_test_data zuc_test_auth_5670b = { + .key = { + .data = { + 0x6B, 0x8B, 0x08, 0xEE, 0x79, 0xE0, 0xB5, 0x98, + 0x2D, 0x6D, 0x12, 0x8E, 0xA9, 0xF2, 0x20, 0xCB + }, + .len = 16 + }, + .auth_iv = { + .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 + }, + .digest = { + .data = {0x0C, 0xA1, 0x27, 0x92}, + .len = 4 + } +}; + +static struct wireless_test_data zuc_test_case_auth_128b = { + .key = { + .data = { 0x0 }, + .len = 16 + }, + .auth_iv = { + .data = { 0x0 }, + .len = 16 + }, + .plaintext = { + .data = { 0x0 }, + .len = 8 + }, + .validAuthLenInBits = { + .len = 8 + }, + .digest = { + .data = { 0x39, 0x0a, 0x91, 0xb7 }, + .len = 4 + } +}; + +static struct wireless_test_data zuc_test_case_auth_2080b = { + .key = { + .data = { + 0xC8, 0xA4, 0x82, 0x62, 0xD0, 0xC2, 0xE2, 0xBA, + 0xC4, 0xB9, 0x6E, 0xF7, 0x7E, 0x80, 0xCA, 0x59 + }, + .len = 16 + }, + .auth_iv = { + .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 = 2080 + }, + .digest = { + .data = {0x03, 0x95, 0x32, 0xe1}, + .len = 4 + } +}; + +static struct wireless_test_data zuc_test_case_auth_584b = { + .key = { + .data = { + 0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb, + 0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 0xab, 0x0a + }, + .len = 16 + }, + .auth_iv = { + .data = { + 0xa9, 0x40, 0x59, 0xda, 0x50, 0x0, 0x0, 0x0, + 0x29, 0x40, 0x59, 0xda, 0x50, 0x0, 0x80, 0x0 + }, + .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, 0x00, 0x00, 0x00 + }, + .len = 584 + }, + .validAuthLenInBits = { + .len = 584 + }, + .digest = { + .data = {0x24, 0xa8, 0x42, 0xb3}, + .len = 4 + } +}; + +#endif /* TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ */ diff --git a/app/test/test_cycles.c b/app/test/test_cycles.c new file mode 100644 index 0000000000..c78e6a5b12 --- /dev/null +++ b/app/test/test_cycles.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 +check_wait_one_second(void) +{ + uint64_t cycles, prev_cycles; + uint64_t hz = rte_get_timer_hz(); + uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */ + + /* 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; +} + +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; + } + + return check_wait_one_second(); +} + +REGISTER_TEST_COMMAND(cycles_autotest, test_cycles); + +/* + * One second precision test with rte_delay_us_sleep. + */ + +static int +test_delay_us_sleep(void) +{ + rte_delay_us_callback_register(rte_delay_us_sleep); + return check_wait_one_second(); +} + +REGISTER_TEST_COMMAND(delay_us_sleep_autotest, test_delay_us_sleep); + +/* + * 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 new file mode 100644 index 0000000000..faf2cf5573 --- /dev/null +++ b/app/test/test_debug.c @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#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; + + /* manually cleanup EAL memory, as the fork() below would otherwise + * cause the same hugepages to be free()-ed multiple times. + */ + rte_service_finalize(); + + 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_distributor.c b/app/test/test_distributor.c new file mode 100644 index 0000000000..98919ec0cc --- /dev/null +++ b/app/test/test_distributor.c @@ -0,0 +1,697 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2017 Intel Corporation + */ + +#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 + +struct worker_params { + char name[64]; + struct rte_distributor *dist; +}; + +struct worker_params worker_params; + +/* 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 *buf[8] __rte_cache_aligned; + struct worker_params *wp = arg; + struct rte_distributor *db = wp->dist; + unsigned int count = 0, num = 0; + unsigned int id = __sync_fetch_and_add(&worker_idx, 1); + int i; + + for (i = 0; i < 8; i++) + buf[i] = NULL; + num = rte_distributor_get_pkt(db, id, buf, buf, num); + while (!quit) { + worker_stats[id].handled_packets += num; + count += num; + num = rte_distributor_get_pkt(db, id, + buf, buf, num); + } + worker_stats[id].handled_packets += num; + count += num; + rte_distributor_return_pkt(db, id, buf, num); + 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 through 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 worker_params *wp, struct rte_mempool *p) +{ + struct rte_distributor *db = wp->dist; + struct rte_mbuf *bufs[BURST]; + struct rte_mbuf *returns[BURST*2]; + unsigned int i, count; + unsigned int retries; + + 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(db, bufs, BURST); + count = 0; + do { + + rte_distributor_flush(db); + count += rte_distributor_returned_pkts(db, + returns, BURST*2); + } while (count < BURST); + + 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"); + + /* 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(db, bufs, BURST); + count = 0; + do { + rte_distributor_flush(db); + count += rte_distributor_returned_pkts(db, + returns, BURST*2); + } while (count < BURST); + 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"); + } + + /* 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+1; + + rte_distributor_process(db, bufs, BURST); + count = 0; + do { + rte_distributor_flush(db); + count += rte_distributor_returned_pkts(db, + returns, BURST*2); + } while (count < BURST); + 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(db); + rte_distributor_clear_returns(db); + + 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; + + printf("=== testing big burst (%s) ===\n", wp->name); + for (i = 0; i < BIG_BATCH/BURST; i++) { + rte_distributor_process(db, + &many_bufs[i*BURST], BURST); + count = rte_distributor_returned_pkts(db, + &return_bufs[num_returned], + BIG_BATCH - num_returned); + num_returned += count; + } + rte_distributor_flush(db); + count = rte_distributor_returned_pkts(db, + &return_bufs[num_returned], + BIG_BATCH - num_returned); + num_returned += count; + retries = 0; + do { + rte_distributor_flush(db); + count = rte_distributor_returned_pkts(db, + &return_bufs[num_returned], + BIG_BATCH - num_returned); + num_returned += count; + retries++; + } while ((num_returned < BIG_BATCH) && (retries < 100)); + + if (num_returned != BIG_BATCH) { + printf("line %d: Missing packets, expected %d\n", + __LINE__, num_returned); + 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 *buf[8] __rte_cache_aligned; + struct worker_params *wp = arg; + struct rte_distributor *d = wp->dist; + unsigned int count = 0; + unsigned int i; + unsigned int num = 0; + unsigned int id = __sync_fetch_and_add(&worker_idx, 1); + + for (i = 0; i < 8; i++) + buf[i] = NULL; + num = rte_distributor_get_pkt(d, id, buf, buf, num); + while (!quit) { + worker_stats[id].handled_packets += num; + count += num; + for (i = 0; i < num; i++) + rte_pktmbuf_free(buf[i]); + num = rte_distributor_get_pkt(d, + id, buf, buf, num); + } + worker_stats[id].handled_packets += num; + count += num; + rte_distributor_return_pkt(d, id, buf, num); + 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 worker_params *wp, struct rte_mempool *p) +{ + struct rte_distributor *d = wp->dist; + unsigned i; + struct rte_mbuf *bufs[BURST]; + + printf("=== Sanity test with mbuf alloc/free (%s) ===\n", wp->name); + + 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); + + rte_delay_us(10000); + + if (total_packet_count() < (1<dist; + unsigned int count = 0; + unsigned int num = 0; + unsigned int total = 0; + unsigned int i; + unsigned int returned = 0; + const unsigned int id = __sync_fetch_and_add(&worker_idx, 1); + + num = rte_distributor_get_pkt(d, id, buf, buf, num); + + /* wait for quit single globally, or for worker zero, wait + * for zero_quit */ + while (!quit && !(id == 0 && zero_quit)) { + worker_stats[id].handled_packets += num; + count += num; + for (i = 0; i < num; i++) + rte_pktmbuf_free(buf[i]); + num = rte_distributor_get_pkt(d, + id, buf, buf, num); + total += num; + } + worker_stats[id].handled_packets += num; + count += num; + returned = rte_distributor_return_pkt(d, id, buf, num); + + if (id == 0) { + /* for worker zero, allow it to restart to pick up last packet + * when all workers are shutting down. + */ + while (zero_quit) + usleep(100); + + num = rte_distributor_get_pkt(d, + id, buf, buf, num); + + while (!quit) { + worker_stats[id].handled_packets++, count++; + rte_pktmbuf_free(pkt); + num = rte_distributor_get_pkt(d, id, buf, buf, num); + } + returned = rte_distributor_return_pkt(d, + id, buf, num); + printf("Num returned = %d\n", returned); + } + 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_worker_shutdown(struct worker_params *wp, + struct rte_mempool *p) +{ + struct rte_distributor *d = wp->dist; + struct rte_mbuf *bufs[BURST]; + unsigned i; + + printf("=== Sanity test of 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 same value so all + * pkts go to the one worker thread + */ + for (i = 0; i < BURST; i++) + bufs[i]->hash.usr = 1; + + rte_distributor_process(d, bufs, BURST); + rte_distributor_flush(d); + + /* 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 = 1; + + /* get worker zero to quit */ + zero_quit = 1; + rte_distributor_process(d, bufs, BURST); + + /* flush the distributor */ + rte_distributor_flush(d); + rte_delay_us(10000); + + for (i = 0; i < rte_lcore_count() - 1; i++) + printf("Worker %u handled %u packets\n", i, + worker_stats[i].handled_packets); + + 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; + } + + 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 worker_params *wp, + struct rte_mempool *p) +{ + struct rte_distributor *d = wp->dist; + struct rte_mbuf *bufs[BURST]; + unsigned i; + + printf("=== Test flush fn with worker shutdown (%s) ===\n", wp->name); + + 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); + + rte_delay_us(10000); + + zero_quit = 0; + for (i = 0; i < rte_lcore_count() - 1; i++) + printf("Worker %u handled %u packets\n", i, + worker_stats[i].handled_packets); + + 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; + } + + printf("Flush test with worker shutdown passed\n\n"); + return 0; +} + +static +int test_error_distributor_create_name(void) +{ + struct rte_distributor *d = NULL; + struct rte_distributor *db = NULL; + char *name = NULL; + + d = rte_distributor_create(name, rte_socket_id(), + rte_lcore_count() - 1, + RTE_DIST_ALG_SINGLE); + if (d != NULL || rte_errno != EINVAL) { + printf("ERROR: No error on create() with NULL name param\n"); + return -1; + } + + db = rte_distributor_create(name, rte_socket_id(), + rte_lcore_count() - 1, + RTE_DIST_ALG_BURST); + if (db != NULL || rte_errno != EINVAL) { + printf("ERROR: No error on create() with NULL param\n"); + return -1; + } + + return 0; +} + + +static +int test_error_distributor_create_numworkers(void) +{ + struct rte_distributor *ds = NULL; + struct rte_distributor *db = NULL; + + ds = rte_distributor_create("test_numworkers", rte_socket_id(), + RTE_MAX_LCORE + 10, + RTE_DIST_ALG_SINGLE); + if (ds != NULL || rte_errno != EINVAL) { + printf("ERROR: No error on create() with num_workers > MAX\n"); + return -1; + } + + db = rte_distributor_create("test_numworkers", rte_socket_id(), + RTE_MAX_LCORE + 10, + RTE_DIST_ALG_BURST); + if (db != NULL || rte_errno != EINVAL) { + printf("ERROR: No error on create() num_workers > MAX\n"); + return -1; + } + + return 0; +} + + +/* Useful function which ensures that all worker functions terminate */ +static void +quit_workers(struct worker_params *wp, struct rte_mempool *p) +{ + struct rte_distributor *d = wp->dist; + 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 *ds; + static struct rte_distributor *db; + static struct rte_distributor *dist[2]; + static struct rte_mempool *p; + int i; + + if (rte_lcore_count() < 2) { + printf("ERROR: not enough cores to test distributor\n"); + return -1; + } + + if (db == NULL) { + db = rte_distributor_create("Test_dist_burst", rte_socket_id(), + rte_lcore_count() - 1, + RTE_DIST_ALG_BURST); + if (db == NULL) { + printf("Error creating burst distributor\n"); + return -1; + } + } else { + rte_distributor_flush(db); + rte_distributor_clear_returns(db); + } + + if (ds == NULL) { + ds = rte_distributor_create("Test_dist_single", + rte_socket_id(), + rte_lcore_count() - 1, + RTE_DIST_ALG_SINGLE); + if (ds == NULL) { + printf("Error creating single distributor\n"); + return -1; + } + } else { + rte_distributor_flush(ds); + rte_distributor_clear_returns(ds); + } + + 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; + } + } + + dist[0] = ds; + dist[1] = db; + + for (i = 0; i < 2; i++) { + + worker_params.dist = dist[i]; + if (i) + sprintf(worker_params.name, "burst"); + else + sprintf(worker_params.name, "single"); + + rte_eal_mp_remote_launch(handle_work, + &worker_params, SKIP_MASTER); + if (sanity_test(&worker_params, p) < 0) + goto err; + quit_workers(&worker_params, p); + + rte_eal_mp_remote_launch(handle_work_with_free_mbufs, + &worker_params, SKIP_MASTER); + if (sanity_test_with_mbuf_alloc(&worker_params, p) < 0) + goto err; + quit_workers(&worker_params, p); + + if (rte_lcore_count() > 2) { + rte_eal_mp_remote_launch(handle_work_for_shutdown_test, + &worker_params, + SKIP_MASTER); + if (sanity_test_with_worker_shutdown(&worker_params, + p) < 0) + goto err; + quit_workers(&worker_params, p); + + rte_eal_mp_remote_launch(handle_work_for_shutdown_test, + &worker_params, + SKIP_MASTER); + if (test_flush_with_worker_shutdown(&worker_params, + p) < 0) + goto err; + quit_workers(&worker_params, p); + + } else { + printf("Too few cores to run worker shutdown test\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(&worker_params, 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 new file mode 100644 index 0000000000..edf1998ab0 --- /dev/null +++ b/app/test/test_distributor_perf.c @@ -0,0 +1,268 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include "test.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ITER_POWER_CL 25 /* log 2 of how many iterations for Cache Line test */ +#define ITER_POWER 21 /* log 2 of how many iterations we do when timing. */ +#define BURST 64 +#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 int +flip_bit(volatile uint64_t *arg) +{ + uint64_t old_val = 0; + while (old_val != 2) { + while (!*arg) + rte_pause(); + old_val = *arg; + *arg = 0; + } + return 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_CL); 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_CL); +} + +/* + * 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_distributor *d = arg; + unsigned int count = 0; + unsigned int num = 0; + int i; + unsigned int id = __sync_fetch_and_add(&worker_idx, 1); + struct rte_mbuf *buf[8] __rte_cache_aligned; + + for (i = 0; i < 8; i++) + buf[i] = NULL; + + num = rte_distributor_get_pkt(d, id, buf, buf, num); + while (!quit) { + worker_stats[id].handled_packets += num; + count += num; + num = rte_distributor_get_pkt(d, id, buf, buf, num); + } + worker_stats[id].handled_packets += num; + count += num; + rte_distributor_return_pkt(d, id, buf, num); + 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 int 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 int num_workers = rte_lcore_count() - 1; + unsigned int 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 *ds; + static struct rte_distributor *db; + 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 (ds == NULL) { + ds = rte_distributor_create("Test_perf", rte_socket_id(), + rte_lcore_count() - 1, + RTE_DIST_ALG_SINGLE); + if (ds == NULL) { + printf("Error creating distributor\n"); + return -1; + } + } else { + rte_distributor_clear_returns(ds); + } + + if (db == NULL) { + db = rte_distributor_create("Test_burst", rte_socket_id(), + rte_lcore_count() - 1, + RTE_DIST_ALG_BURST); + if (db == NULL) { + printf("Error creating burst distributor\n"); + return -1; + } + } else { + rte_distributor_clear_returns(db); + } + + 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; + } + } + + printf("=== Performance test of distributor (single mode) ===\n"); + rte_eal_mp_remote_launch(handle_work, ds, SKIP_MASTER); + if (perf_test(ds, p) < 0) + return -1; + quit_workers(ds, p); + + printf("=== Performance test of distributor (burst mode) ===\n"); + rte_eal_mp_remote_launch(handle_work, db, SKIP_MASTER); + if (perf_test(db, p) < 0) + return -1; + quit_workers(db, 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 new file mode 100644 index 0000000000..81e345b879 --- /dev/null +++ b/app/test/test_eal_flags.c @@ -0,0 +1,1393 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation. + * Copyright(c) 2014 6WIND S.A. + */ + +#include + +#include "test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "process.h" + +#define DEFAULT_MEM_SIZE "18" +#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 * 20) +#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 + +/* + * 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, no_huge, "-n", "1", + "-c", "1", vdev, "eth_dummy"}; + + /* Test with valid vdev option */ + const char *vdevval1[] = {prgname, prefix, no_huge, "-n", "1", + "-c", "1", vdev, "net_ring0"}; + + const char *vdevval2[] = {prgname, prefix, no_huge, "-n", "1", + "-c", "1", vdev, "net_ring0,args=test"}; + + const char *vdevval3[] = {prgname, prefix, no_huge, "-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" }; + /* core number is negative value */ + const char * const argv11[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "-5" }; + const char * const argv12[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "-5-7" }; + /* core number is maximum value */ + const char * const argv13[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", RTE_STR(RTE_MAX_LCORE) }; + const char * const argv14[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "1-"RTE_STR(RTE_MAX_LCORE) }; + /* sanity check test - valid corelist value */ + const char * const argv15[] = { prgname, prefix, mp_flag, + "-n", "3", "-l", "1-2,3" }; + + /* --lcores flag but no lcores value */ + const char * const argv16[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores" }; + const char * const argv17[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", " " }; + /* bad lcores value */ + const char * const argv18[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "1-3-5" }; + const char * const argv19[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "0-1,,2" }; + const char * const argv20[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "0-,1" }; + const char * const argv21[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(0-,2-4)" }; + const char * const argv22[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(-1,2)" }; + const char * const argv23[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(2-4)@(2-4-6)" }; + const char * const argv24[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(a,2)" }; + const char * const argv25[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "1-3@(1,3)" }; + const char * const argv26[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "3@((1,3)" }; + const char * const argv27[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "(4-7)=(1,3)" }; + const char * const argv28[] = { prgname, prefix, mp_flag, + "-n", "3", "--lcores", "[4-7]@(1,3)" }; + /* sanity check of tests - valid lcores value */ + const char * const argv29[] = { 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 + || launch_proc(argv11) == 0 + || launch_proc(argv12) == 0 + || launch_proc(argv13) == 0 + || launch_proc(argv14) == 0) { + printf("Error - " + "process ran without error with invalid -l flag\n"); + return -1; + } + if (launch_proc(argv15) != 0) { + printf("Error - " + "process did not run ok with valid corelist value\n"); + return -1; + } + + /* start --lcores tests */ + if (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(argv22) == 0 || launch_proc(argv23) == 0 || + launch_proc(argv24) == 0 || launch_proc(argv25) == 0 || + launch_proc(argv26) == 0 || launch_proc(argv27) == 0 || + launch_proc(argv28) == 0) { + printf("Error - " + "process ran without error with invalid --lcore flag\n"); + return -1; + } + + if (launch_proc(argv29) != 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] = ""; + +#ifdef RTE_EXEC_ENV_BSDAPP + return 0; +#else + char 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 + + /* 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; +} + +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 further 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, also use no-huge to ensure this test runs on BSD */ + const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, + no_shconf, nosh_prefix, no_huge}; + + /* 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"}; + + /* run all tests also applicable to FreeBSD first */ + + 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(argv6) != 0) { + printf("Error - process did not run ok with --no-shconf flag\n"); + return -1; + } + +#ifdef RTE_EXEC_ENV_BSDAPP + /* no more tests to be done on FreeBSD */ + return 0; +#endif + + 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(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; +} + +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 in default and legacy + * mem mode + * 5. check if memtest1 hugefiles are created in case of legacy mem + * mode, and deleted in case of default mem mode + * 6. run a primary process with memtest2 prefix in default and legacy + * mem modes + * 7. check that memtest2 hugefiles are present in the hugedir after a + * run in legacy mode, and not present at all after run in default + * mem mode + */ + char prefix[PATH_MAX] = ""; + +#ifdef RTE_EXEC_ENV_BSDAPP + return 0; +#else + if (get_current_prefix(prefix, sizeof(prefix)) == NULL) { + printf("Error - unable to get current prefix!\n"); + return -1; + } +#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 and default mem mode */ + const char *argv1[] = {prgname, "-c", "1", "-n", "2", "-m", + DEFAULT_MEM_SIZE, "--file-prefix=" memtest1 }; + + /* primary process with memtest1 and legacy mem mode */ + const char *argv2[] = {prgname, "-c", "1", "-n", "2", "-m", + DEFAULT_MEM_SIZE, "--file-prefix=" memtest1, + "--legacy-mem" }; + + /* primary process with memtest2 and legacy mem mode */ + const char *argv3[] = {prgname, "-c", "1", "-n", "2", "-m", + DEFAULT_MEM_SIZE, "--file-prefix=" memtest2, + "--legacy-mem" }; + + /* primary process with memtest2 and default mem mode */ + const char *argv4[] = {prgname, "-c", "1", "-n", "2", "-m", + DEFAULT_MEM_SIZE, "--file-prefix=" memtest2 }; + + /* 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; + } + + /* we're running this process in default memory mode, which means it + * should clean up after itself on exit and leave no hugepages behind. + */ + if (launch_proc(argv1) != 0) { + printf("Error - failed to run with --file-prefix=%s\n", + memtest1); + return -1; + } + + /* check if memtest1_map0 is present */ + if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { + printf("Error - hugepage files for %s were not deleted!\n", + memtest1); + return -1; + } + + /* now, we're running a process under the same prefix, but with legacy + * mem mode - this should leave behind hugepage files. + */ + if (launch_proc(argv2) != 0) { + printf("Error - failed to run with --file-prefix=%s\n", + memtest1); + 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(argv3) != 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; + } + + /* this process will run in default mem mode, so it should not leave any + * hugepage files behind. + */ + if (launch_proc(argv4) != 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) != 0) { + printf("Error - hugepage files for %s were not deleted!\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}; + + /* valid (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 = RTE_MIN(get_number_of_sockets(), + RTE_MAX_NUMA_NODES); +#endif + + if (num_sockets <= 0) { + 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); + strlcpy(invalid_socket_mem, buf, sizeof(invalid_socket_mem)); + + if (num_sockets + 1 - i > 1) { + snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem); + strlcpy(invalid_socket_mem, buf, + sizeof(invalid_socket_mem)); + } + } + + /* 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); + strlcpy(valid_socket_mem, buf, sizeof(valid_socket_mem)); + + if (num_sockets - i > 1) { + snprintf(buf, sizeof(buf), "%s,", valid_socket_mem); + strlcpy(valid_socket_mem, buf, + sizeof(valid_socket_mem)); + } + } + + /* 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; + } + if (launch_proc(argv2) != 0) { + printf("Error - process failed with valid (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; + } + + ret = test_misc_flags(); + 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 new file mode 100644 index 0000000000..7ca2164102 --- /dev/null +++ b/app/test/test_eal_fs.c @@ -0,0 +1,177 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..ced091aab6 --- /dev/null +++ b/app/test/test_efd.c @@ -0,0 +1,471 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#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, + (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 new file mode 100644 index 0000000000..1dcb992c6e --- /dev/null +++ b/app/test/test_efd_perf.c @@ -0,0 +1,385 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016-2017 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..920a2cf890 --- /dev/null +++ b/app/test/test_errno.c @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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_event_crypto_adapter.c b/app/test/test_event_crypto_adapter.c new file mode 100644 index 0000000000..f750ce3d8c --- /dev/null +++ b/app/test/test_event_crypto_adapter.c @@ -0,0 +1,941 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation. + * All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define PKT_TRACE 0 +#define NUM 1 +#define DEFAULT_NUM_XFORMS (2) +#define NUM_MBUFS (8191) +#define MBUF_CACHE_SIZE (256) +#define MAXIMUM_IV_LENGTH (16) +#define DEFAULT_NUM_OPS_INFLIGHT (128) +#define MAX_NB_SESSIONS 4 +#define TEST_APP_PORT_ID 0 +#define TEST_APP_EV_QUEUE_ID 0 +#define TEST_APP_EV_PRIORITY 0 +#define TEST_APP_EV_FLOWID 0xAABB +#define TEST_CRYPTO_EV_QUEUE_ID 1 +#define TEST_ADAPTER_ID 0 +#define TEST_CDEV_ID 0 +#define TEST_CDEV_QP_ID 0 +#define PACKET_LENGTH 64 +#define NB_TEST_PORTS 1 +#define NB_TEST_QUEUES 2 +#define NUM_CORES 1 +#define CRYPTODEV_NAME_NULL_PMD crypto_null + +#define MBUF_SIZE (sizeof(struct rte_mbuf) + \ + RTE_PKTMBUF_HEADROOM + PACKET_LENGTH) +#define IV_OFFSET (sizeof(struct rte_crypto_op) + \ + sizeof(struct rte_crypto_sym_op) + \ + DEFAULT_NUM_XFORMS * \ + sizeof(struct rte_crypto_sym_xform)) + +/* Handle log statements in same manner as test macros */ +#define LOG_DBG(...) RTE_LOG(DEBUG, EAL, __VA_ARGS__) + +static const uint8_t text_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 +}; + +struct event_crypto_adapter_test_params { + struct rte_mempool *mbuf_pool; + struct rte_mempool *op_mpool; + struct rte_mempool *session_mpool; + struct rte_mempool *session_priv_mpool; + struct rte_cryptodev_config *config; + uint8_t crypto_event_port_id; +}; + +struct rte_event response_info = { + .queue_id = TEST_APP_EV_QUEUE_ID, + .sched_type = RTE_SCHED_TYPE_ATOMIC, + .flow_id = TEST_APP_EV_FLOWID, + .priority = TEST_APP_EV_PRIORITY +}; + +struct rte_event_crypto_request request_info = { + .cdev_id = TEST_CDEV_ID, + .queue_pair_id = TEST_CDEV_QP_ID +}; + +static struct event_crypto_adapter_test_params params; +static uint8_t crypto_adapter_setup_done; +static uint32_t slcore_id; +static int evdev; + +static struct rte_mbuf * +alloc_fill_mbuf(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 int +send_recv_ev(struct rte_event *ev) +{ + struct rte_crypto_op *op; + struct rte_event recv_ev; + int ret; + + ret = rte_event_enqueue_burst(evdev, TEST_APP_PORT_ID, ev, NUM); + TEST_ASSERT_EQUAL(ret, NUM, + "Failed to send event to crypto adapter\n"); + + while (rte_event_dequeue_burst(evdev, + TEST_APP_PORT_ID, &recv_ev, NUM, 0) == 0) + rte_pause(); + + op = recv_ev.event_ptr; +#if PKT_TRACE + struct rte_mbuf *m = op->sym->m_src; + rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m)); +#endif + rte_pktmbuf_free(op->sym->m_src); + rte_crypto_op_free(op); + + return TEST_SUCCESS; +} + +static int +test_crypto_adapter_stats(void) +{ + struct rte_event_crypto_adapter_stats stats; + + rte_event_crypto_adapter_stats_get(TEST_ADAPTER_ID, &stats); + printf(" +------------------------------------------------------+\n"); + printf(" + Crypto adapter stats for instance %u:\n", TEST_ADAPTER_ID); + printf(" + Event port poll count %" PRIx64 "\n", + stats.event_poll_count); + printf(" + Event dequeue count %" PRIx64 "\n", + stats.event_deq_count); + printf(" + Cryptodev enqueue count %" PRIx64 "\n", + stats.crypto_enq_count); + printf(" + Cryptodev enqueue failed count %" PRIx64 "\n", + stats.crypto_enq_fail); + printf(" + Cryptodev dequeue count %" PRIx64 "\n", + stats.crypto_deq_count); + printf(" + Event enqueue count %" PRIx64 "\n", + stats.event_enq_count); + printf(" + Event enqueue retry count %" PRIx64 "\n", + stats.event_enq_retry_count); + printf(" + Event enqueue fail count %" PRIx64 "\n", + stats.event_enq_fail_count); + printf(" +------------------------------------------------------+\n"); + + rte_event_crypto_adapter_stats_reset(TEST_ADAPTER_ID); + return TEST_SUCCESS; +} + +static int +test_op_forward_mode(uint8_t session_less) +{ + struct rte_crypto_sym_xform cipher_xform; + struct rte_cryptodev_sym_session *sess; + union rte_event_crypto_metadata m_data; + struct rte_crypto_sym_op *sym_op; + struct rte_crypto_op *op; + struct rte_mbuf *m; + struct rte_event ev; + uint32_t cap; + int ret; + + memset(&m_data, 0, sizeof(m_data)); + + m = alloc_fill_mbuf(params.mbuf_pool, text_64B, PACKET_LENGTH, 0); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate mbuf!\n"); +#if PKT_TRACE + rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m)); +#endif + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.next = NULL; + + cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_NULL; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + op = rte_crypto_op_alloc(params.op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, + "Failed to allocate symmetric crypto operation struct\n"); + + sym_op = op->sym; + + if (!session_less) { + sess = rte_cryptodev_sym_session_create( + params.session_mpool); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed\n"); + + /* Create Crypto session*/ + rte_cryptodev_sym_session_init(TEST_CDEV_ID, sess, + &cipher_xform, params.session_priv_mpool); + + ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, + evdev, &cap); + TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); + + if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA) { + /* Fill in private user data information */ + rte_memcpy(&m_data.response_info, &response_info, + sizeof(response_info)); + rte_memcpy(&m_data.request_info, &request_info, + sizeof(request_info)); + rte_cryptodev_sym_session_set_user_data(sess, + &m_data, sizeof(m_data)); + } + + rte_crypto_op_attach_sym_session(op, sess); + } else { + struct rte_crypto_sym_xform *first_xform; + + rte_crypto_op_sym_xforms_alloc(op, NUM); + op->sess_type = RTE_CRYPTO_OP_SESSIONLESS; + first_xform = &cipher_xform; + sym_op->xform = first_xform; + uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH + + (sizeof(struct rte_crypto_sym_xform) * 2); + op->private_data_offset = len; + /* Fill in private data information */ + rte_memcpy(&m_data.response_info, &response_info, + sizeof(response_info)); + rte_memcpy(&m_data.request_info, &request_info, + sizeof(request_info)); + rte_memcpy((uint8_t *)op + len, &m_data, sizeof(m_data)); + } + + sym_op->m_src = m; + sym_op->cipher.data.offset = 0; + sym_op->cipher.data.length = PACKET_LENGTH; + + /* Fill in event info and update event_ptr with rte_crypto_op */ + memset(&ev, 0, sizeof(ev)); + ev.queue_id = TEST_CRYPTO_EV_QUEUE_ID; + ev.sched_type = RTE_SCHED_TYPE_ATOMIC; + ev.flow_id = 0xAABB; + ev.event_ptr = op; + + ret = send_recv_ev(&ev); + TEST_ASSERT_SUCCESS(ret, "Failed to send/receive event to " + "crypto adapter\n"); + + test_crypto_adapter_stats(); + + return TEST_SUCCESS; +} + +static int +map_adapter_service_core(void) +{ + uint32_t adapter_service_id; + int ret; + + if (rte_event_crypto_adapter_service_id_get(TEST_ADAPTER_ID, + &adapter_service_id) == 0) { + uint32_t core_list[NUM_CORES]; + + ret = rte_service_lcore_list(core_list, NUM_CORES); + TEST_ASSERT(ret >= 0, "Failed to get service core list!"); + + if (core_list[0] != slcore_id) { + TEST_ASSERT_SUCCESS(rte_service_lcore_add(slcore_id), + "Failed to add service core"); + TEST_ASSERT_SUCCESS(rte_service_lcore_start(slcore_id), + "Failed to start service core"); + } + + TEST_ASSERT_SUCCESS(rte_service_map_lcore_set( + adapter_service_id, slcore_id, 1), + "Failed to map adapter service"); + } + + return TEST_SUCCESS; +} + +static int +test_sessionless_with_op_forward_mode(void) +{ + uint32_t cap; + int ret; + + ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); + TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); + + if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD)) + map_adapter_service_core(); + + TEST_ASSERT_SUCCESS(rte_event_crypto_adapter_start(TEST_ADAPTER_ID), + "Failed to start event crypto adapter"); + + ret = test_op_forward_mode(1); + TEST_ASSERT_SUCCESS(ret, "Sessionless - FORWARD mode test failed\n"); + return TEST_SUCCESS; +} + +static int +test_session_with_op_forward_mode(void) +{ + uint32_t cap; + int ret; + + ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); + TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); + + if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD)) + map_adapter_service_core(); + + TEST_ASSERT_SUCCESS(rte_event_crypto_adapter_start(TEST_ADAPTER_ID + ), "Failed to start event crypto adapter"); + + ret = test_op_forward_mode(0); + TEST_ASSERT_SUCCESS(ret, "Session based - FORWARD mode test failed\n"); + return TEST_SUCCESS; +} + +static int +send_op_recv_ev(struct rte_crypto_op *op) +{ + struct rte_crypto_op *recv_op; + struct rte_event ev; + int ret; + + ret = rte_cryptodev_enqueue_burst(TEST_CDEV_ID, TEST_CDEV_QP_ID, + &op, NUM); + TEST_ASSERT_EQUAL(ret, NUM, "Failed to enqueue to cryptodev\n"); + memset(&ev, 0, sizeof(ev)); + + while (rte_event_dequeue_burst(evdev, + TEST_APP_PORT_ID, &ev, NUM, 0) == 0) + rte_pause(); + + recv_op = ev.event_ptr; +#if PKT_TRACE + struct rte_mbuf *m = recv_op->sym->m_src; + rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m)); +#endif + rte_pktmbuf_free(recv_op->sym->m_src); + rte_crypto_op_free(recv_op); + + return TEST_SUCCESS; +} + +static int +test_op_new_mode(uint8_t session_less) +{ + struct rte_crypto_sym_xform cipher_xform; + struct rte_cryptodev_sym_session *sess; + union rte_event_crypto_metadata m_data; + struct rte_crypto_sym_op *sym_op; + struct rte_crypto_op *op; + struct rte_mbuf *m; + uint32_t cap; + int ret; + + memset(&m_data, 0, sizeof(m_data)); + + m = alloc_fill_mbuf(params.mbuf_pool, text_64B, PACKET_LENGTH, 0); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate mbuf!\n"); +#if PKT_TRACE + rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m)); +#endif + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.next = NULL; + + cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_NULL; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + op = rte_crypto_op_alloc(params.op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, "Failed to allocate crypto_op!\n"); + + sym_op = op->sym; + + if (!session_less) { + sess = rte_cryptodev_sym_session_create( + params.session_mpool); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed\n"); + + ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, + evdev, &cap); + TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); + + if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA) { + /* Fill in private user data information */ + rte_memcpy(&m_data.response_info, &response_info, + sizeof(m_data)); + rte_cryptodev_sym_session_set_user_data(sess, + &m_data, sizeof(m_data)); + } + rte_cryptodev_sym_session_init(TEST_CDEV_ID, sess, + &cipher_xform, params.session_priv_mpool); + rte_crypto_op_attach_sym_session(op, sess); + } else { + struct rte_crypto_sym_xform *first_xform; + + rte_crypto_op_sym_xforms_alloc(op, NUM); + op->sess_type = RTE_CRYPTO_OP_SESSIONLESS; + first_xform = &cipher_xform; + sym_op->xform = first_xform; + uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH + + (sizeof(struct rte_crypto_sym_xform) * 2); + op->private_data_offset = len; + /* Fill in private data information */ + rte_memcpy(&m_data.response_info, &response_info, + sizeof(m_data)); + rte_memcpy((uint8_t *)op + len, &m_data, sizeof(m_data)); + } + + sym_op->m_src = m; + sym_op->cipher.data.offset = 0; + sym_op->cipher.data.length = PACKET_LENGTH; + + ret = send_op_recv_ev(op); + TEST_ASSERT_SUCCESS(ret, "Failed to enqueue op to cryptodev\n"); + + test_crypto_adapter_stats(); + + return TEST_SUCCESS; +} + +static int +test_sessionless_with_op_new_mode(void) +{ + uint32_t cap; + int ret; + + ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); + TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); + + if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) || + !(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_NEW)) + map_adapter_service_core(); + + /* start the event crypto adapter */ + TEST_ASSERT_SUCCESS(rte_event_crypto_adapter_start(TEST_ADAPTER_ID), + "Failed to start event crypto adapter"); + + ret = test_op_new_mode(1); + TEST_ASSERT_SUCCESS(ret, "Sessionless - NEW mode test failed\n"); + return TEST_SUCCESS; +} + +static int +test_session_with_op_new_mode(void) +{ + uint32_t cap; + int ret; + + ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); + TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); + + if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) || + !(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_NEW)) + map_adapter_service_core(); + + TEST_ASSERT_SUCCESS(rte_event_crypto_adapter_start(TEST_ADAPTER_ID), + "Failed to start event crypto adapter"); + + ret = test_op_new_mode(0); + TEST_ASSERT_SUCCESS(ret, "Session based - NEW mode test failed\n"); + return TEST_SUCCESS; +} + +static int +configure_cryptodev(void) +{ + struct rte_cryptodev_qp_conf qp_conf; + struct rte_cryptodev_config conf; + struct rte_cryptodev_info info; + unsigned int session_size; + uint8_t nb_devs; + int ret; + + params.mbuf_pool = rte_pktmbuf_pool_create( + "CRYPTO_ADAPTER_MBUFPOOL", + NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, + rte_socket_id()); + if (params.mbuf_pool == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n"); + return TEST_FAILED; + } + + params.op_mpool = rte_crypto_op_pool_create( + "EVENT_CRYPTO_SYM_OP_POOL", + RTE_CRYPTO_OP_TYPE_SYMMETRIC, + NUM_MBUFS, MBUF_CACHE_SIZE, + DEFAULT_NUM_XFORMS * + sizeof(struct rte_crypto_sym_xform) + + MAXIMUM_IV_LENGTH, + rte_socket_id()); + if (params.op_mpool == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); + return TEST_FAILED; + } + + /* Create a NULL crypto device */ + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_NULL_PMD))); + if (!nb_devs) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_NULL_PMD), NULL); + + TEST_ASSERT(ret == 0, "Failed to create pmd:%s instance\n", + RTE_STR(CRYPTODEV_NAME_NULL_PMD)); + } + + nb_devs = rte_cryptodev_count(); + if (!nb_devs) { + RTE_LOG(ERR, USER1, "No crypto devices found!\n"); + return TEST_FAILED; + } + + /* + * Create mempool with maximum number of sessions * 2, + * to include the session headers & private data + */ + session_size = rte_cryptodev_sym_get_private_session_size(TEST_CDEV_ID); + session_size += sizeof(union rte_event_crypto_metadata); + + params.session_mpool = rte_cryptodev_sym_session_pool_create( + "CRYPTO_ADAPTER_SESSION_MP", + MAX_NB_SESSIONS, 0, 0, 0, SOCKET_ID_ANY); + TEST_ASSERT_NOT_NULL(params.session_mpool, + "session mempool allocation failed\n"); + + params.session_priv_mpool = rte_mempool_create( + "CRYPTO_ADAPTER_SESSION_MP_PRIV", + MAX_NB_SESSIONS, + session_size, + 0, 0, NULL, NULL, NULL, + NULL, SOCKET_ID_ANY, + 0); + TEST_ASSERT_NOT_NULL(params.session_priv_mpool, + "session mempool allocation failed\n"); + + rte_cryptodev_info_get(TEST_CDEV_ID, &info); + conf.nb_queue_pairs = info.max_nb_queue_pairs; + conf.socket_id = SOCKET_ID_ANY; + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(TEST_CDEV_ID, &conf), + "Failed to configure cryptodev %u with %u qps\n", + TEST_CDEV_ID, conf.nb_queue_pairs); + + qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; + qp_conf.mp_session = params.session_mpool; + qp_conf.mp_session_private = params.session_priv_mpool; + + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + TEST_CDEV_ID, TEST_CDEV_QP_ID, &qp_conf, + rte_cryptodev_socket_id(TEST_CDEV_ID)), + "Failed to setup queue pair %u on cryptodev %u\n", + TEST_CDEV_QP_ID, TEST_CDEV_ID); + + return TEST_SUCCESS; +} + +static inline void +evdev_set_conf_values(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + memset(dev_conf, 0, sizeof(struct rte_event_dev_config)); + dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns; + dev_conf->nb_event_ports = NB_TEST_PORTS; + dev_conf->nb_event_queues = NB_TEST_QUEUES; + dev_conf->nb_event_queue_flows = info->max_event_queue_flows; + dev_conf->nb_event_port_dequeue_depth = + info->max_event_port_dequeue_depth; + dev_conf->nb_event_port_enqueue_depth = + info->max_event_port_enqueue_depth; + dev_conf->nb_event_port_enqueue_depth = + info->max_event_port_enqueue_depth; + dev_conf->nb_events_limit = + info->max_num_events; +} + +static int +configure_eventdev(void) +{ + struct rte_event_queue_conf queue_conf; + struct rte_event_dev_config devconf; + struct rte_event_dev_info info; + uint32_t queue_count; + uint32_t port_count; + int ret; + uint8_t qid; + + if (!rte_event_dev_count()) { + /* If there is no hardware eventdev, or no software vdev was + * specified on the command line, create an instance of + * event_sw. + */ + LOG_DBG("Failed to find a valid event device... " + "testing with event_sw device\n"); + TEST_ASSERT_SUCCESS(rte_vdev_init("event_sw0", NULL), + "Error creating eventdev"); + evdev = rte_event_dev_get_dev_id("event_sw0"); + } + + ret = rte_event_dev_info_get(evdev, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info\n"); + + evdev_set_conf_values(&devconf, &info); + + ret = rte_event_dev_configure(evdev, &devconf); + TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev\n"); + + /* Set up event queue */ + ret = rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT, + &queue_count); + TEST_ASSERT_SUCCESS(ret, "Queue count get failed\n"); + TEST_ASSERT_EQUAL(queue_count, 2, "Unexpected queue count\n"); + + qid = TEST_APP_EV_QUEUE_ID; + ret = rte_event_queue_setup(evdev, qid, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%d\n", qid); + + queue_conf.nb_atomic_flows = info.max_event_queue_flows; + queue_conf.nb_atomic_order_sequences = 32; + queue_conf.schedule_type = RTE_SCHED_TYPE_ATOMIC; + queue_conf.priority = RTE_EVENT_DEV_PRIORITY_HIGHEST; + queue_conf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK; + + qid = TEST_CRYPTO_EV_QUEUE_ID; + ret = rte_event_queue_setup(evdev, qid, &queue_conf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%u\n", qid); + + /* Set up event port */ + ret = rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT, + &port_count); + TEST_ASSERT_SUCCESS(ret, "Port count get failed\n"); + TEST_ASSERT_EQUAL(port_count, 1, "Unexpected port count\n"); + + ret = rte_event_port_setup(evdev, TEST_APP_PORT_ID, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port=%d\n", + TEST_APP_PORT_ID); + + qid = TEST_APP_EV_QUEUE_ID; + ret = rte_event_port_link(evdev, TEST_APP_PORT_ID, &qid, NULL, 1); + TEST_ASSERT(ret >= 0, "Failed to link queue port=%d\n", + TEST_APP_PORT_ID); + + return TEST_SUCCESS; +} + +static void +test_crypto_adapter_free(void) +{ + rte_event_crypto_adapter_free(TEST_ADAPTER_ID); +} + +static int +test_crypto_adapter_create(void) +{ + struct rte_event_port_conf conf = { + .dequeue_depth = 8, + .enqueue_depth = 8, + .new_event_threshold = 1200, + }; + int ret; + + /* Create adapter with default port creation callback */ + ret = rte_event_crypto_adapter_create(TEST_ADAPTER_ID, + TEST_CDEV_ID, + &conf, 0); + TEST_ASSERT_SUCCESS(ret, "Failed to create event crypto adapter\n"); + + return TEST_SUCCESS; +} + +static int +test_crypto_adapter_qp_add_del(void) +{ + uint32_t cap; + int ret; + + ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); + TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); + + if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND) { + ret = rte_event_crypto_adapter_queue_pair_add(TEST_ADAPTER_ID, + TEST_CDEV_ID, TEST_CDEV_QP_ID, &response_info); + } else + ret = rte_event_crypto_adapter_queue_pair_add(TEST_ADAPTER_ID, + TEST_CDEV_ID, TEST_CDEV_QP_ID, NULL); + + TEST_ASSERT_SUCCESS(ret, "Failed to create add queue pair\n"); + + ret = rte_event_crypto_adapter_queue_pair_del(TEST_ADAPTER_ID, + TEST_CDEV_ID, TEST_CDEV_QP_ID); + TEST_ASSERT_SUCCESS(ret, "Failed to delete add queue pair\n"); + + return TEST_SUCCESS; +} + +static int +configure_event_crypto_adapter(enum rte_event_crypto_adapter_mode mode) +{ + struct rte_event_port_conf conf = { + .dequeue_depth = 8, + .enqueue_depth = 8, + .new_event_threshold = 1200, + }; + + uint32_t cap; + int ret; + + /* Create adapter with default port creation callback */ + ret = rte_event_crypto_adapter_create(TEST_ADAPTER_ID, + TEST_CDEV_ID, + &conf, mode); + TEST_ASSERT_SUCCESS(ret, "Failed to create event crypto adapter\n"); + + ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); + TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); + + if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND) { + ret = rte_event_crypto_adapter_queue_pair_add(TEST_ADAPTER_ID, + TEST_CDEV_ID, TEST_CDEV_QP_ID, &response_info); + } else + ret = rte_event_crypto_adapter_queue_pair_add(TEST_ADAPTER_ID, + TEST_CDEV_ID, TEST_CDEV_QP_ID, NULL); + + TEST_ASSERT_SUCCESS(ret, "Failed to add queue pair\n"); + + ret = rte_event_crypto_adapter_event_port_get(TEST_ADAPTER_ID, + ¶ms.crypto_event_port_id); + TEST_ASSERT_SUCCESS(ret, "Failed to get event port\n"); + + return TEST_SUCCESS; +} + +static void +test_crypto_adapter_stop(void) +{ + uint32_t evdev_service_id, adapter_service_id; + + /* retrieve service ids & stop services */ + if (rte_event_crypto_adapter_service_id_get(TEST_ADAPTER_ID, + &adapter_service_id) == 0) { + rte_service_runstate_set(adapter_service_id, 0); + rte_service_lcore_stop(slcore_id); + rte_service_lcore_del(slcore_id); + rte_event_crypto_adapter_stop(TEST_ADAPTER_ID); + } + + if (rte_event_dev_service_id_get(evdev, &evdev_service_id) == 0) { + rte_service_runstate_set(evdev_service_id, 0); + rte_service_lcore_stop(slcore_id); + rte_service_lcore_del(slcore_id); + rte_event_dev_stop(evdev); + } +} + +static int +test_crypto_adapter_conf(enum rte_event_crypto_adapter_mode mode) +{ + uint32_t evdev_service_id; + uint8_t qid; + int ret; + + if (!crypto_adapter_setup_done) { + ret = configure_event_crypto_adapter(mode); + if (!ret) { + qid = TEST_CRYPTO_EV_QUEUE_ID; + ret = rte_event_port_link(evdev, + params.crypto_event_port_id, &qid, NULL, 1); + TEST_ASSERT(ret >= 0, "Failed to link queue %d " + "port=%u\n", qid, + params.crypto_event_port_id); + } + crypto_adapter_setup_done = 1; + } + + /* retrieve service ids */ + if (rte_event_dev_service_id_get(evdev, &evdev_service_id) == 0) { + /* add a service core and start it */ + TEST_ASSERT_SUCCESS(rte_service_lcore_add(slcore_id), + "Failed to add service core"); + TEST_ASSERT_SUCCESS(rte_service_lcore_start(slcore_id), + "Failed to start service core"); + + /* map services to it */ + TEST_ASSERT_SUCCESS(rte_service_map_lcore_set(evdev_service_id, + slcore_id, 1), "Failed to map evdev service"); + + /* set services to running */ + TEST_ASSERT_SUCCESS(rte_service_runstate_set(evdev_service_id, + 1), "Failed to start evdev service"); + } + + /* start the eventdev */ + TEST_ASSERT_SUCCESS(rte_event_dev_start(evdev), + "Failed to start event device"); + + return TEST_SUCCESS; +} + +static int +test_crypto_adapter_conf_op_forward_mode(void) +{ + enum rte_event_crypto_adapter_mode mode; + + mode = RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD; + test_crypto_adapter_conf(mode); + + return TEST_SUCCESS; +} + +static int +test_crypto_adapter_conf_op_new_mode(void) +{ + enum rte_event_crypto_adapter_mode mode; + + mode = RTE_EVENT_CRYPTO_ADAPTER_OP_NEW; + test_crypto_adapter_conf(mode); + return TEST_SUCCESS; +} + + +static int +testsuite_setup(void) +{ + int ret; + + slcore_id = rte_get_next_lcore(-1, 1, 0); + TEST_ASSERT_NOT_EQUAL(slcore_id, RTE_MAX_LCORE, "At least 2 lcores " + "are required to run this autotest\n"); + + /* Setup and start event device. */ + ret = configure_eventdev(); + TEST_ASSERT_SUCCESS(ret, "Failed to setup eventdev\n"); + + /* Setup and start crypto device. */ + ret = configure_cryptodev(); + TEST_ASSERT_SUCCESS(ret, "cryptodev initialization failed\n"); + + return TEST_SUCCESS; +} + +static void +crypto_teardown(void) +{ + /* Free mbuf mempool */ + if (params.mbuf_pool != NULL) { + RTE_LOG(DEBUG, USER1, "CRYPTO_ADAPTER_MBUFPOOL count %u\n", + rte_mempool_avail_count(params.mbuf_pool)); + rte_mempool_free(params.mbuf_pool); + params.mbuf_pool = NULL; + } + + /* Free session mempool */ + if (params.session_mpool != NULL) { + RTE_LOG(DEBUG, USER1, "CRYPTO_ADAPTER_SESSION_MP count %u\n", + rte_mempool_avail_count(params.session_mpool)); + rte_mempool_free(params.session_mpool); + params.session_mpool = NULL; + } + if (params.session_priv_mpool != NULL) { + rte_mempool_free(params.session_priv_mpool); + params.session_priv_mpool = NULL; + } + + /* Free ops mempool */ + if (params.op_mpool != NULL) { + RTE_LOG(DEBUG, USER1, "EVENT_CRYPTO_SYM_OP_POOL count %u\n", + rte_mempool_avail_count(params.op_mpool)); + rte_mempool_free(params.op_mpool); + params.op_mpool = NULL; + } +} + +static void +eventdev_teardown(void) +{ + rte_event_dev_stop(evdev); +} + +static void +testsuite_teardown(void) +{ + crypto_teardown(); + eventdev_teardown(); +} + +static struct unit_test_suite functional_testsuite = { + .suite_name = "Event crypto adapter test suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + + TEST_CASE_ST(NULL, test_crypto_adapter_free, + test_crypto_adapter_create), + + TEST_CASE_ST(test_crypto_adapter_create, + test_crypto_adapter_free, + test_crypto_adapter_qp_add_del), + + TEST_CASE_ST(test_crypto_adapter_create, + test_crypto_adapter_free, + test_crypto_adapter_stats), + + TEST_CASE_ST(test_crypto_adapter_conf_op_forward_mode, + test_crypto_adapter_stop, + test_session_with_op_forward_mode), + + TEST_CASE_ST(test_crypto_adapter_conf_op_forward_mode, + test_crypto_adapter_stop, + test_sessionless_with_op_forward_mode), + + TEST_CASE_ST(test_crypto_adapter_conf_op_new_mode, + test_crypto_adapter_stop, + test_session_with_op_new_mode), + + TEST_CASE_ST(test_crypto_adapter_conf_op_new_mode, + test_crypto_adapter_stop, + test_sessionless_with_op_new_mode), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_event_crypto_adapter(void) +{ + return unit_test_suite_runner(&functional_testsuite); +} + +REGISTER_TEST_COMMAND(event_crypto_adapter_autotest, + test_event_crypto_adapter); diff --git a/app/test/test_event_eth_rx_adapter.c b/app/test/test_event_eth_rx_adapter.c new file mode 100644 index 0000000000..1d3be82b5a --- /dev/null +++ b/app/test/test_event_eth_rx_adapter.c @@ -0,0 +1,714 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Intel Corporation + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "test.h" + +#define MAX_NUM_RX_QUEUE 64 +#define NB_MBUFS (8192 * num_ports * MAX_NUM_RX_QUEUE) +#define MBUF_CACHE_SIZE 512 +#define MBUF_PRIV_SIZE 0 +#define TEST_INST_ID 0 +#define TEST_DEV_ID 0 +#define TEST_ETHDEV_ID 0 + +struct event_eth_rx_adapter_test_params { + struct rte_mempool *mp; + uint16_t rx_rings, tx_rings; + uint32_t caps; + int rx_intr_port_inited; + uint16_t rx_intr_port; +}; + +static struct event_eth_rx_adapter_test_params default_params; + +static inline int +port_init_common(uint16_t port, const struct rte_eth_conf *port_conf, + struct rte_mempool *mp) +{ + const uint16_t rx_ring_size = 512, tx_ring_size = 512; + int retval; + uint16_t q; + struct rte_eth_dev_info dev_info; + + if (!rte_eth_dev_is_valid_port(port)) + return -1; + + retval = rte_eth_dev_configure(port, 0, 0, port_conf); + + rte_eth_dev_info_get(port, &dev_info); + + default_params.rx_rings = RTE_MIN(dev_info.max_rx_queues, + MAX_NUM_RX_QUEUE); + default_params.tx_rings = 1; + + /* Configure the Ethernet device. */ + retval = rte_eth_dev_configure(port, default_params.rx_rings, + default_params.tx_rings, port_conf); + if (retval != 0) + return retval; + + for (q = 0; q < default_params.rx_rings; q++) { + retval = rte_eth_rx_queue_setup(port, q, rx_ring_size, + rte_eth_dev_socket_id(port), NULL, mp); + if (retval < 0) + return retval; + } + + /* Allocate and set up 1 TX queue per Ethernet port. */ + for (q = 0; q < default_params.tx_rings; q++) { + retval = rte_eth_tx_queue_setup(port, q, tx_ring_size, + rte_eth_dev_socket_id(port), NULL); + if (retval < 0) + return retval; + } + + /* Start the Ethernet port. */ + retval = rte_eth_dev_start(port); + if (retval < 0) + return retval; + + /* Display the port MAC address. */ + struct ether_addr addr; + rte_eth_macaddr_get(port, &addr); + printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 + " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", + (unsigned int)port, + addr.addr_bytes[0], addr.addr_bytes[1], + addr.addr_bytes[2], addr.addr_bytes[3], + addr.addr_bytes[4], addr.addr_bytes[5]); + + /* Enable RX in promiscuous mode for the Ethernet device. */ + rte_eth_promiscuous_enable(port); + + return 0; +} + +static inline int +port_init_rx_intr(uint16_t port, struct rte_mempool *mp) +{ + static const struct rte_eth_conf port_conf_default = { + .rxmode = { + .mq_mode = ETH_MQ_RX_NONE, + }, + .intr_conf = { + .rxq = 1, + }, + }; + + return port_init_common(port, &port_conf_default, mp); +} + +static inline int +port_init(uint16_t port, struct rte_mempool *mp) +{ + static const struct rte_eth_conf port_conf_default = { + .rxmode = { + .mq_mode = ETH_MQ_RX_NONE, + }, + }; + + return port_init_common(port, &port_conf_default, mp); +} + +static int +init_port_rx_intr(int num_ports) +{ + int retval; + uint16_t portid; + int err; + + default_params.mp = rte_pktmbuf_pool_create("packet_pool", + NB_MBUFS, + MBUF_CACHE_SIZE, + MBUF_PRIV_SIZE, + RTE_MBUF_DEFAULT_BUF_SIZE, + rte_socket_id()); + if (!default_params.mp) + return -ENOMEM; + + RTE_ETH_FOREACH_DEV(portid) { + retval = port_init_rx_intr(portid, default_params.mp); + if (retval) + continue; + err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, portid, + &default_params.caps); + if (err) + continue; + if (!(default_params.caps & + RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT)) { + default_params.rx_intr_port_inited = 1; + default_params.rx_intr_port = portid; + return 0; + } + rte_eth_dev_stop(portid); + } + return 0; +} + +static int +init_ports(int num_ports) +{ + uint16_t portid; + int retval; + + struct rte_mempool *ptr = rte_mempool_lookup("packet_pool"); + + if (ptr == NULL) + default_params.mp = rte_pktmbuf_pool_create("packet_pool", + NB_MBUFS, + MBUF_CACHE_SIZE, + MBUF_PRIV_SIZE, + RTE_MBUF_DEFAULT_BUF_SIZE, + rte_socket_id()); + else + default_params.mp = ptr; + + if (!default_params.mp) + return -ENOMEM; + + RTE_ETH_FOREACH_DEV(portid) { + retval = port_init(portid, default_params.mp); + if (retval) + return retval; + } + + return 0; +} + +static int +testsuite_setup(void) +{ + int err; + uint8_t count; + struct rte_event_dev_info dev_info; + + count = rte_event_dev_count(); + if (!count) { + printf("Failed to find a valid event device," + " testing with event_skeleton device\n"); + rte_vdev_init("event_skeleton", NULL); + } + + struct rte_event_dev_config config = { + .nb_event_queues = 1, + .nb_event_ports = 1, + }; + + err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); + config.nb_event_queue_flows = dev_info.max_event_queue_flows; + config.nb_event_port_dequeue_depth = + dev_info.max_event_port_dequeue_depth; + config.nb_event_port_enqueue_depth = + dev_info.max_event_port_enqueue_depth; + config.nb_events_limit = + dev_info.max_num_events; + err = rte_event_dev_configure(TEST_DEV_ID, &config); + TEST_ASSERT(err == 0, "Event device initialization failed err %d\n", + err); + + /* + * eth devices like octeontx use event device to receive packets + * so rte_eth_dev_start invokes rte_event_dev_start internally, so + * call init_ports after rte_event_dev_configure + */ + err = init_ports(rte_eth_dev_count_total()); + TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err); + + err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID, + &default_params.caps); + TEST_ASSERT(err == 0, "Failed to get adapter cap err %d\n", + err); + + return err; +} + +static int +testsuite_setup_rx_intr(void) +{ + int err; + uint8_t count; + struct rte_event_dev_info dev_info; + + count = rte_event_dev_count(); + if (!count) { + printf("Failed to find a valid event device," + " testing with event_skeleton device\n"); + rte_vdev_init("event_skeleton", NULL); + } + + struct rte_event_dev_config config = { + .nb_event_queues = 1, + .nb_event_ports = 1, + }; + + err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); + config.nb_event_queue_flows = dev_info.max_event_queue_flows; + config.nb_event_port_dequeue_depth = + dev_info.max_event_port_dequeue_depth; + config.nb_event_port_enqueue_depth = + dev_info.max_event_port_enqueue_depth; + config.nb_events_limit = + dev_info.max_num_events; + + err = rte_event_dev_configure(TEST_DEV_ID, &config); + TEST_ASSERT(err == 0, "Event device initialization failed err %d\n", + err); + + /* + * eth devices like octeontx use event device to receive packets + * so rte_eth_dev_start invokes rte_event_dev_start internally, so + * call init_ports after rte_event_dev_configure + */ + err = init_port_rx_intr(rte_eth_dev_count_total()); + TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err); + + if (!default_params.rx_intr_port_inited) + return 0; + + err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, + default_params.rx_intr_port, + &default_params.caps); + TEST_ASSERT(err == 0, "Failed to get adapter cap err %d\n", err); + + return err; +} + +static void +testsuite_teardown(void) +{ + uint32_t i; + RTE_ETH_FOREACH_DEV(i) + rte_eth_dev_stop(i); + + rte_mempool_free(default_params.mp); +} + +static void +testsuite_teardown_rx_intr(void) +{ + if (!default_params.rx_intr_port_inited) + return; + + rte_eth_dev_stop(default_params.rx_intr_port); + rte_mempool_free(default_params.mp); +} + +static int +adapter_create(void) +{ + int err; + struct rte_event_dev_info dev_info; + struct rte_event_port_conf rx_p_conf; + + memset(&rx_p_conf, 0, sizeof(rx_p_conf)); + + err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + rx_p_conf.new_event_threshold = dev_info.max_num_events; + rx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; + rx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; + err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID, + &rx_p_conf); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + return err; +} + +static void +adapter_free(void) +{ + rte_event_eth_rx_adapter_free(TEST_INST_ID); +} + +static int +adapter_create_free(void) +{ + int err; + + struct rte_event_port_conf rx_p_conf = { + .dequeue_depth = 8, + .enqueue_depth = 8, + .new_event_threshold = 1200, + }; + + err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID, + NULL); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID, + &rx_p_conf); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_create(TEST_INST_ID, + TEST_DEV_ID, &rx_p_conf); + TEST_ASSERT(err == -EEXIST, "Expected -EEXIST %d got %d", -EEXIST, err); + + err = rte_event_eth_rx_adapter_free(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_free(TEST_INST_ID); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err); + + err = rte_event_eth_rx_adapter_free(1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err); + + return TEST_SUCCESS; +} + +static int +adapter_queue_add_del(void) +{ + int err; + struct rte_event ev; + uint32_t cap; + + struct rte_event_eth_rx_adapter_queue_conf queue_config; + + err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID, + &cap); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + ev.queue_id = 0; + ev.sched_type = RTE_SCHED_TYPE_ATOMIC; + ev.priority = 0; + + queue_config.rx_queue_flags = 0; + if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) { + ev.flow_id = 1; + queue_config.rx_queue_flags = + RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID; + } + queue_config.ev = ev; + queue_config.servicing_weight = 1; + + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + rte_eth_dev_count_total(), + -1, &queue_config); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) { + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, 0, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, 0); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, + -1, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } else { + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, + 0, + &queue_config); + TEST_ASSERT(err == -EINVAL, "Expected EINVAL got %d", err); + + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, -1, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, 0); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } + + err = rte_event_eth_rx_adapter_queue_add(1, TEST_ETHDEV_ID, -1, + &queue_config); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_rx_adapter_queue_del(1, TEST_ETHDEV_ID, -1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + return TEST_SUCCESS; +} + +static int +adapter_multi_eth_add_del(void) +{ + int err; + struct rte_event ev; + + uint16_t port_index, drv_id = 0; + char driver_name[50]; + + struct rte_event_eth_rx_adapter_queue_conf queue_config; + + ev.queue_id = 0; + ev.sched_type = RTE_SCHED_TYPE_ATOMIC; + ev.priority = 0; + + queue_config.rx_queue_flags = 0; + queue_config.ev = ev; + queue_config.servicing_weight = 1; + + /* stop eth devices for existing */ + port_index = 0; + for (; port_index < rte_eth_dev_count_total(); port_index += 1) + rte_eth_dev_stop(port_index); + + /* add the max port for rx_adapter */ + port_index = rte_eth_dev_count_total(); + for (; port_index < RTE_MAX_ETHPORTS; port_index += 1) { + sprintf(driver_name, "%s%u", "net_null", drv_id); + err = rte_vdev_init(driver_name, NULL); + TEST_ASSERT(err == 0, "Failed driver %s got %d", + driver_name, err); + drv_id += 1; + } + + err = init_ports(rte_eth_dev_count_total()); + TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err); + + /* eth_rx_adapter_queue_add for n ports */ + port_index = 0; + for (; port_index < rte_eth_dev_count_total(); port_index += 1) { + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + port_index, -1, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } + + /* eth_rx_adapter_queue_del n ports */ + port_index = 0; + for (; port_index < rte_eth_dev_count_total(); port_index += 1) { + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + port_index, -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } + + return TEST_SUCCESS; +} + +static int +adapter_intr_queue_add_del(void) +{ + int err; + struct rte_event ev; + uint32_t cap; + uint16_t eth_port; + struct rte_event_eth_rx_adapter_queue_conf queue_config; + + if (!default_params.rx_intr_port_inited) + return 0; + + eth_port = default_params.rx_intr_port; + err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, eth_port, &cap); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + ev.queue_id = 0; + ev.sched_type = RTE_SCHED_TYPE_ATOMIC; + ev.priority = 0; + + queue_config.rx_queue_flags = 0; + queue_config.ev = ev; + + /* weight = 0 => interrupt mode */ + queue_config.servicing_weight = 0; + + if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) { + /* add queue 0 */ + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, 0, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } + + /* add all queues */ + queue_config.servicing_weight = 0; + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, + -1, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) { + /* del queue 0 */ + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, + 0); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } + + /* del remaining queues */ + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + /* add all queues */ + queue_config.servicing_weight = 0; + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, + -1, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + /* intr -> poll mode queue */ + queue_config.servicing_weight = 1; + + if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) { + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, + 0, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } + + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, + -1, + &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + /* del queues */ + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + return TEST_SUCCESS; +} + +static int +adapter_start_stop(void) +{ + int err; + struct rte_event ev; + + ev.queue_id = 0; + ev.sched_type = RTE_SCHED_TYPE_ATOMIC; + ev.priority = 0; + + struct rte_event_eth_rx_adapter_queue_conf queue_config; + + queue_config.rx_queue_flags = 0; + if (default_params.caps & + RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) { + ev.flow_id = 1; + queue_config.rx_queue_flags = + RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID; + } + + queue_config.ev = ev; + queue_config.servicing_weight = 1; + + err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, TEST_ETHDEV_ID, + -1, &queue_config); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_start(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_stop(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_start(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_stop(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_start(1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_rx_adapter_stop(1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + return TEST_SUCCESS; +} + +static int +adapter_stats(void) +{ + int err; + struct rte_event_eth_rx_adapter_stats stats; + + err = rte_event_eth_rx_adapter_stats_get(TEST_INST_ID, NULL); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_rx_adapter_stats_get(TEST_INST_ID, &stats); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_rx_adapter_stats_get(1, &stats); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + return TEST_SUCCESS; +} + +static struct unit_test_suite event_eth_rx_tests = { + .suite_name = "rx event eth adapter test suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(NULL, NULL, adapter_create_free), + TEST_CASE_ST(adapter_create, adapter_free, + adapter_queue_add_del), + TEST_CASE_ST(adapter_create, adapter_free, + adapter_multi_eth_add_del), + TEST_CASE_ST(adapter_create, adapter_free, adapter_start_stop), + TEST_CASE_ST(adapter_create, adapter_free, adapter_stats), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite event_eth_rx_intr_tests = { + .suite_name = "rx event eth adapter test suite", + .setup = testsuite_setup_rx_intr, + .teardown = testsuite_teardown_rx_intr, + .unit_test_cases = { + TEST_CASE_ST(adapter_create, adapter_free, + adapter_intr_queue_add_del), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_event_eth_rx_adapter_common(void) +{ + return unit_test_suite_runner(&event_eth_rx_tests); +} + +static int +test_event_eth_rx_intr_adapter_common(void) +{ + return unit_test_suite_runner(&event_eth_rx_intr_tests); +} + +REGISTER_TEST_COMMAND(event_eth_rx_adapter_autotest, + test_event_eth_rx_adapter_common); +REGISTER_TEST_COMMAND(event_eth_rx_intr_adapter_autotest, + test_event_eth_rx_intr_adapter_common); diff --git a/app/test/test_event_eth_tx_adapter.c b/app/test/test_event_eth_tx_adapter.c new file mode 100644 index 0000000000..c26c5152c2 --- /dev/null +++ b/app/test/test_event_eth_tx_adapter.c @@ -0,0 +1,699 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define MAX_NUM_QUEUE RTE_PMD_RING_MAX_RX_RINGS +#define TEST_INST_ID 0 +#define TEST_DEV_ID 0 +#define SOCKET0 0 +#define RING_SIZE 256 +#define ETH_NAME_LEN 32 +#define NUM_ETH_PAIR 1 +#define NUM_ETH_DEV (2 * NUM_ETH_PAIR) +#define NB_MBUF 512 +#define PAIR_PORT_INDEX(p) ((p) + NUM_ETH_PAIR) +#define PORT(p) default_params.port[(p)] +#define TEST_ETHDEV_ID PORT(0) +#define TEST_ETHDEV_PAIR_ID PORT(PAIR_PORT_INDEX(0)) + +#define EDEV_RETRY 0xffff + +struct event_eth_tx_adapter_test_params { + struct rte_mempool *mp; + uint16_t rx_rings, tx_rings; + struct rte_ring *r[NUM_ETH_DEV][MAX_NUM_QUEUE]; + int port[NUM_ETH_DEV]; +}; + +static int event_dev_delete; +static struct event_eth_tx_adapter_test_params default_params; +static uint64_t eid = ~0ULL; +static uint32_t tid; + +static inline int +port_init_common(uint8_t port, const struct rte_eth_conf *port_conf, + struct rte_mempool *mp) +{ + const uint16_t rx_ring_size = RING_SIZE, tx_ring_size = RING_SIZE; + int retval; + uint16_t q; + + if (!rte_eth_dev_is_valid_port(port)) + return -1; + + default_params.rx_rings = MAX_NUM_QUEUE; + default_params.tx_rings = MAX_NUM_QUEUE; + + /* Configure the Ethernet device. */ + retval = rte_eth_dev_configure(port, default_params.rx_rings, + default_params.tx_rings, port_conf); + if (retval != 0) + return retval; + + for (q = 0; q < default_params.rx_rings; q++) { + retval = rte_eth_rx_queue_setup(port, q, rx_ring_size, + rte_eth_dev_socket_id(port), NULL, mp); + if (retval < 0) + return retval; + } + + for (q = 0; q < default_params.tx_rings; q++) { + retval = rte_eth_tx_queue_setup(port, q, tx_ring_size, + rte_eth_dev_socket_id(port), NULL); + if (retval < 0) + return retval; + } + + /* Start the Ethernet port. */ + retval = rte_eth_dev_start(port); + if (retval < 0) + return retval; + + /* Display the port MAC address. */ + struct ether_addr addr; + rte_eth_macaddr_get(port, &addr); + printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 + " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", + (unsigned int)port, + addr.addr_bytes[0], addr.addr_bytes[1], + addr.addr_bytes[2], addr.addr_bytes[3], + addr.addr_bytes[4], addr.addr_bytes[5]); + + /* Enable RX in promiscuous mode for the Ethernet device. */ + rte_eth_promiscuous_enable(port); + + return 0; +} + +static inline int +port_init(uint8_t port, struct rte_mempool *mp) +{ + struct rte_eth_conf conf = { 0 }; + return port_init_common(port, &conf, mp); +} + +#define RING_NAME_LEN 20 +#define DEV_NAME_LEN 20 + +static int +init_ports(void) +{ + char ring_name[ETH_NAME_LEN]; + unsigned int i, j; + struct rte_ring * const *c1; + struct rte_ring * const *c2; + int err; + + if (!default_params.mp) + default_params.mp = rte_pktmbuf_pool_create("mbuf_pool", + NB_MBUF, 32, + 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + + if (!default_params.mp) + return -ENOMEM; + + for (i = 0; i < NUM_ETH_DEV; i++) { + for (j = 0; j < MAX_NUM_QUEUE; j++) { + snprintf(ring_name, sizeof(ring_name), "R%u%u", i, j); + default_params.r[i][j] = rte_ring_create(ring_name, + RING_SIZE, + SOCKET0, + RING_F_SP_ENQ | RING_F_SC_DEQ); + TEST_ASSERT((default_params.r[i][j] != NULL), + "Failed to allocate ring"); + } + } + + /* + * To create two pseudo-Ethernet ports where the traffic is + * switched between them, that is, traffic sent to port 1 is + * read back from port 2 and vice-versa + */ + for (i = 0; i < NUM_ETH_PAIR; i++) { + char dev_name[DEV_NAME_LEN]; + int p; + + c1 = default_params.r[i]; + c2 = default_params.r[PAIR_PORT_INDEX(i)]; + + snprintf(dev_name, DEV_NAME_LEN, "%u-%u", i, i + NUM_ETH_PAIR); + p = rte_eth_from_rings(dev_name, c1, MAX_NUM_QUEUE, + c2, MAX_NUM_QUEUE, SOCKET0); + TEST_ASSERT(p >= 0, "Port creation failed %s", dev_name); + err = port_init(p, default_params.mp); + TEST_ASSERT(err == 0, "Port init failed %s", dev_name); + default_params.port[i] = p; + + snprintf(dev_name, DEV_NAME_LEN, "%u-%u", i + NUM_ETH_PAIR, i); + p = rte_eth_from_rings(dev_name, c2, MAX_NUM_QUEUE, + c1, MAX_NUM_QUEUE, SOCKET0); + TEST_ASSERT(p > 0, "Port creation failed %s", dev_name); + err = port_init(p, default_params.mp); + TEST_ASSERT(err == 0, "Port init failed %s", dev_name); + default_params.port[PAIR_PORT_INDEX(i)] = p; + } + + return 0; +} + +static void +deinit_ports(void) +{ + uint16_t i, j; + char name[ETH_NAME_LEN]; + + for (i = 0; i < RTE_DIM(default_params.port); i++) { + rte_eth_dev_stop(default_params.port[i]); + rte_eth_dev_get_name_by_port(default_params.port[i], name); + rte_vdev_uninit(name); + for (j = 0; j < RTE_DIM(default_params.r[i]); j++) + rte_ring_free(default_params.r[i][j]); + } +} + +static int +testsuite_setup(void) +{ + const char *vdev_name = "event_sw0"; + + int err = init_ports(); + TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err); + + if (rte_event_dev_count() == 0) { + printf("Failed to find a valid event device," + " testing with event_sw0 device\n"); + err = rte_vdev_init(vdev_name, NULL); + TEST_ASSERT(err == 0, "vdev %s creation failed %d\n", + vdev_name, err); + event_dev_delete = 1; + } + return err; +} + +#define DEVICE_ID_SIZE 64 + +static void +testsuite_teardown(void) +{ + deinit_ports(); + rte_mempool_free(default_params.mp); + default_params.mp = NULL; + if (event_dev_delete) + rte_vdev_uninit("event_sw0"); +} + +static int +tx_adapter_create(void) +{ + int err; + struct rte_event_dev_info dev_info; + struct rte_event_port_conf tx_p_conf; + uint8_t priority; + uint8_t queue_id; + + struct rte_event_dev_config config = { + .nb_event_queues = 1, + .nb_event_ports = 1, + }; + + struct rte_event_queue_conf wkr_q_conf = { + .schedule_type = RTE_SCHED_TYPE_ORDERED, + .priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .nb_atomic_flows = 1024, + .nb_atomic_order_sequences = 1024, + }; + + memset(&tx_p_conf, 0, sizeof(tx_p_conf)); + err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); + config.nb_event_queue_flows = dev_info.max_event_queue_flows; + config.nb_event_port_dequeue_depth = + dev_info.max_event_port_dequeue_depth; + config.nb_event_port_enqueue_depth = + dev_info.max_event_port_enqueue_depth; + config.nb_events_limit = + dev_info.max_num_events; + + err = rte_event_dev_configure(TEST_DEV_ID, &config); + TEST_ASSERT(err == 0, "Event device initialization failed err %d\n", + err); + + queue_id = 0; + err = rte_event_queue_setup(TEST_DEV_ID, 0, &wkr_q_conf); + TEST_ASSERT(err == 0, "Event queue setup failed %d\n", err); + + err = rte_event_port_setup(TEST_DEV_ID, 0, NULL); + TEST_ASSERT(err == 0, "Event port setup failed %d\n", err); + + priority = RTE_EVENT_DEV_PRIORITY_LOWEST; + err = rte_event_port_link(TEST_DEV_ID, 0, &queue_id, &priority, 1); + TEST_ASSERT(err == 1, "Error linking port %s\n", + rte_strerror(rte_errno)); + err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + tx_p_conf.new_event_threshold = dev_info.max_num_events; + tx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; + tx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; + err = rte_event_eth_tx_adapter_create(TEST_INST_ID, TEST_DEV_ID, + &tx_p_conf); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + return err; +} + +static void +tx_adapter_free(void) +{ + rte_event_eth_tx_adapter_free(TEST_INST_ID); +} + +static int +tx_adapter_create_free(void) +{ + int err; + struct rte_event_dev_info dev_info; + struct rte_event_port_conf tx_p_conf; + + err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + tx_p_conf.new_event_threshold = dev_info.max_num_events; + tx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; + tx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; + + err = rte_event_eth_tx_adapter_create(TEST_INST_ID, TEST_DEV_ID, + NULL); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_tx_adapter_create(TEST_INST_ID, TEST_DEV_ID, + &tx_p_conf); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_create(TEST_INST_ID, + TEST_DEV_ID, &tx_p_conf); + TEST_ASSERT(err == -EEXIST, "Expected -EEXIST %d got %d", -EEXIST, err); + + err = rte_event_eth_tx_adapter_free(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_free(TEST_INST_ID); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err); + + err = rte_event_eth_tx_adapter_free(1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err); + + return TEST_SUCCESS; +} + +static int +tx_adapter_queue_add_del(void) +{ + int err; + uint32_t cap; + + err = rte_event_eth_tx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID, + &cap); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + + err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, + rte_eth_dev_count_total(), + -1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, + 0); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, + TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, + 0); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, + TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_queue_add(1, TEST_ETHDEV_ID, -1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_tx_adapter_queue_del(1, TEST_ETHDEV_ID, -1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + return TEST_SUCCESS; +} + +static int +tx_adapter_start_stop(void) +{ + int err; + + err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_start(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_stop(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_start(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_stop(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_start(1); + + err = rte_event_eth_tx_adapter_stop(1); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + return TEST_SUCCESS; +} + + +static int +tx_adapter_single(uint16_t port, uint16_t tx_queue_id, + struct rte_mbuf *m, uint8_t qid, + uint8_t sched_type) +{ + struct rte_event event; + struct rte_mbuf *r; + int ret; + unsigned int l; + + event.queue_id = qid; + event.op = RTE_EVENT_OP_NEW; + event.event_type = RTE_EVENT_TYPE_CPU; + event.sched_type = sched_type; + event.mbuf = m; + + m->port = port; + rte_event_eth_tx_adapter_txq_set(m, tx_queue_id); + + l = 0; + while (rte_event_enqueue_burst(TEST_DEV_ID, 0, &event, 1) != 1) { + l++; + if (l > EDEV_RETRY) + break; + } + + TEST_ASSERT(l < EDEV_RETRY, "Unable to enqueue to eventdev"); + l = 0; + while (l++ < EDEV_RETRY) { + + if (eid != ~0ULL) { + ret = rte_service_run_iter_on_app_lcore(eid, 0); + TEST_ASSERT(ret == 0, "failed to run service %d", ret); + } + + ret = rte_service_run_iter_on_app_lcore(tid, 0); + TEST_ASSERT(ret == 0, "failed to run service %d", ret); + + if (rte_eth_rx_burst(TEST_ETHDEV_PAIR_ID, tx_queue_id, + &r, 1)) { + TEST_ASSERT_EQUAL(r, m, "mbuf comparison failed" + " expected %p received %p", m, r); + return 0; + } + } + + TEST_ASSERT(0, "Failed to receive packet"); + return -1; +} + +static int +tx_adapter_service(void) +{ + struct rte_event_eth_tx_adapter_stats stats; + uint32_t i; + int err; + uint8_t ev_port, ev_qid; + struct rte_mbuf bufs[RING_SIZE]; + struct rte_mbuf *pbufs[RING_SIZE]; + struct rte_event_dev_info dev_info; + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qconf; + uint32_t qcnt, pcnt; + uint16_t q; + int internal_port; + uint32_t cap; + + memset(&dev_conf, 0, sizeof(dev_conf)); + err = rte_event_eth_tx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID, + &cap); + TEST_ASSERT(err == 0, "Failed to get adapter cap err %d\n", err); + + internal_port = !!(cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT); + if (internal_port) + return TEST_SUCCESS; + + err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_event_port_get(TEST_INST_ID, + &ev_port); + TEST_ASSERT_SUCCESS(err, "Failed to get event port %d", err); + + err = rte_event_dev_attr_get(TEST_DEV_ID, RTE_EVENT_DEV_ATTR_PORT_COUNT, + &pcnt); + TEST_ASSERT_SUCCESS(err, "Port count get failed"); + + err = rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &qcnt); + TEST_ASSERT_SUCCESS(err, "Queue count get failed"); + + err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); + TEST_ASSERT_SUCCESS(err, "Dev info failed"); + + dev_conf.nb_event_queue_flows = dev_info.max_event_queue_flows; + dev_conf.nb_event_port_dequeue_depth = + dev_info.max_event_port_dequeue_depth; + dev_conf.nb_event_port_enqueue_depth = + dev_info.max_event_port_enqueue_depth; + dev_conf.nb_events_limit = + dev_info.max_num_events; + dev_conf.nb_event_queues = qcnt + 1; + dev_conf.nb_event_ports = pcnt; + err = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT(err == 0, "Event device initialization failed err %d\n", + err); + + ev_qid = qcnt; + qconf.nb_atomic_flows = dev_info.max_event_queue_flows; + qconf.nb_atomic_order_sequences = 32; + qconf.schedule_type = RTE_SCHED_TYPE_ATOMIC; + qconf.priority = RTE_EVENT_DEV_PRIORITY_HIGHEST; + qconf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK; + err = rte_event_queue_setup(TEST_DEV_ID, ev_qid, &qconf); + TEST_ASSERT_SUCCESS(err, "Failed to setup queue %u", ev_qid); + + /* + * Setup ports again so that the newly added queue is visible + * to them + */ + for (i = 0; i < pcnt; i++) { + + int n_links; + uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; + uint8_t priorities[RTE_EVENT_MAX_QUEUES_PER_DEV]; + + if (i == ev_port) + continue; + + n_links = rte_event_port_links_get(TEST_DEV_ID, i, queues, + priorities); + TEST_ASSERT(n_links > 0, "Failed to get port links %d\n", + n_links); + err = rte_event_port_setup(TEST_DEV_ID, i, NULL); + TEST_ASSERT(err == 0, "Failed to setup port err %d\n", err); + err = rte_event_port_link(TEST_DEV_ID, i, queues, priorities, + n_links); + TEST_ASSERT(n_links == err, "Failed to link all queues" + " err %s\n", rte_strerror(rte_errno)); + } + + err = rte_event_port_link(TEST_DEV_ID, ev_port, &ev_qid, NULL, 1); + TEST_ASSERT(err == 1, "Failed to link queue port %u", + ev_port); + + err = rte_event_eth_tx_adapter_start(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + if (!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED)) { + err = rte_event_dev_service_id_get(0, (uint32_t *)&eid); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_service_runstate_set(eid, 1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_service_set_runstate_mapped_check(eid, 0); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } + + err = rte_event_eth_tx_adapter_service_id_get(TEST_INST_ID, &tid); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_service_runstate_set(tid, 1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_service_set_runstate_mapped_check(tid, 0); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + for (q = 0; q < MAX_NUM_QUEUE; q++) { + for (i = 0; i < RING_SIZE; i++) + pbufs[i] = &bufs[i]; + for (i = 0; i < RING_SIZE; i++) { + pbufs[i] = &bufs[i]; + err = tx_adapter_single(TEST_ETHDEV_ID, q, pbufs[i], + ev_qid, + RTE_SCHED_TYPE_ORDERED); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + } + for (i = 0; i < RING_SIZE; i++) { + TEST_ASSERT_EQUAL(pbufs[i], &bufs[i], + "Error: received data does not match" + " that transmitted"); + } + } + + err = rte_event_eth_tx_adapter_stats_get(TEST_INST_ID, NULL); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_tx_adapter_stats_get(TEST_INST_ID, &stats); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + TEST_ASSERT_EQUAL(stats.tx_packets, MAX_NUM_QUEUE * RING_SIZE, + "stats.tx_packets expected %u got %"PRIu64, + MAX_NUM_QUEUE * RING_SIZE, + stats.tx_packets); + + err = rte_event_eth_tx_adapter_stats_reset(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_stats_get(TEST_INST_ID, &stats); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + TEST_ASSERT_EQUAL(stats.tx_packets, 0, + "stats.tx_packets expected %u got %"PRIu64, + 0, + stats.tx_packets); + + err = rte_event_eth_tx_adapter_stats_get(1, &stats); + TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); + + err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, TEST_ETHDEV_ID, + -1); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + err = rte_event_eth_tx_adapter_free(TEST_INST_ID); + TEST_ASSERT(err == 0, "Expected 0 got %d", err); + + rte_event_dev_stop(TEST_DEV_ID); + + return TEST_SUCCESS; +} + +static int +tx_adapter_dynamic_device(void) +{ + uint16_t port_id = rte_eth_dev_count_avail(); + const char *null_dev[2] = { "eth_null0", "eth_null1" }; + struct rte_eth_conf dev_conf; + int ret; + size_t i; + + memset(&dev_conf, 0, sizeof(dev_conf)); + for (i = 0; i < RTE_DIM(null_dev); i++) { + ret = rte_vdev_init(null_dev[i], NULL); + TEST_ASSERT_SUCCESS(ret, "%s Port creation failed %d", + null_dev[i], ret); + + if (i == 0) { + ret = tx_adapter_create(); + TEST_ASSERT_SUCCESS(ret, "Adapter create failed %d", + ret); + } + + ret = rte_eth_dev_configure(port_id + i, MAX_NUM_QUEUE, + MAX_NUM_QUEUE, &dev_conf); + TEST_ASSERT_SUCCESS(ret, "Failed to configure device %d", ret); + + ret = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, + port_id + i, 0); + TEST_ASSERT_SUCCESS(ret, "Failed to add queues %d", ret); + + } + + for (i = 0; i < RTE_DIM(null_dev); i++) { + ret = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, + port_id + i, -1); + TEST_ASSERT_SUCCESS(ret, "Failed to delete queues %d", ret); + } + + tx_adapter_free(); + + for (i = 0; i < RTE_DIM(null_dev); i++) + rte_vdev_uninit(null_dev[i]); + + return TEST_SUCCESS; +} + +static struct unit_test_suite event_eth_tx_tests = { + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .suite_name = "tx event eth adapter test suite", + .unit_test_cases = { + TEST_CASE_ST(NULL, NULL, tx_adapter_create_free), + TEST_CASE_ST(tx_adapter_create, tx_adapter_free, + tx_adapter_queue_add_del), + TEST_CASE_ST(tx_adapter_create, tx_adapter_free, + tx_adapter_start_stop), + TEST_CASE_ST(tx_adapter_create, tx_adapter_free, + tx_adapter_service), + TEST_CASE_ST(NULL, NULL, tx_adapter_dynamic_device), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_event_eth_tx_adapter_common(void) +{ + return unit_test_suite_runner(&event_eth_tx_tests); +} + +REGISTER_TEST_COMMAND(event_eth_tx_adapter_autotest, + test_event_eth_tx_adapter_common); diff --git a/app/test/test_event_ring.c b/app/test/test_event_ring.c new file mode 100644 index 0000000000..70eb9845e1 --- /dev/null +++ b/app/test/test_event_ring.c @@ -0,0 +1,247 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include + +#include + +#include "test.h" + +/* + * Event Ring + * =========== + * + * Test some basic ops for the event rings. + * Does not fully test everything, since most code is reused from rte_ring + * library and tested as part of the normal ring autotests. + */ + +#define RING_SIZE 4096 +#define MAX_BULK 32 + +static struct rte_event_ring *r; + +/* + * ensure failure to create ring with a bad ring size + */ +static int +test_event_ring_creation_with_wrong_size(void) +{ + struct rte_event_ring *rp = NULL; + + /* Test if ring size is not power of 2 */ + rp = rte_event_ring_create("test_bad_ring_size", RING_SIZE + 1, + SOCKET_ID_ANY, 0); + if (rp != NULL) + return -1; + + /* Test if ring size is exceeding the limit */ + rp = rte_event_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), + SOCKET_ID_ANY, 0); + if (rp != NULL) + return -1; + return 0; +} + +/* + * Test to check if a non-power-of-2 count causes the create + * function to fail correctly + */ +static int +test_create_count_odd(void) +{ + struct rte_event_ring *r = rte_event_ring_create("test_event_ring_count", + 4097, SOCKET_ID_ANY, 0); + if (r != NULL) + return -1; + return 0; +} + +static int +test_lookup_null(void) +{ + struct rte_event_ring *rlp = rte_event_ring_lookup("ring_not_found"); + if (rlp == NULL && rte_errno != ENOENT) { + printf("test failed to return error on null pointer\n"); + return -1; + } + return 0; +} + +static int +test_basic_event_enqueue_dequeue(void) +{ + struct rte_event_ring *sr = NULL; + struct rte_event evs[16]; + uint16_t ret, free_count, used_count; + + memset(evs, 0, sizeof(evs)); + sr = rte_event_ring_create("spsc_ring", 32, rte_socket_id(), + RING_F_SP_ENQ | RING_F_SC_DEQ); + if (sr == NULL) { + printf("Failed to create sp/sc ring\n"); + return -1; + } + if (rte_event_ring_get_capacity(sr) != 31) { + printf("Error, invalid capacity\n"); + goto error; + } + + /* test sp/sc ring */ + if (rte_event_ring_count(sr) != 0) { + printf("Error, ring not empty as expected\n"); + goto error; + } + if (rte_event_ring_free_count(sr) != rte_event_ring_get_capacity(sr)) { + printf("Error, ring free count not as expected\n"); + goto error; + } + + ret = rte_event_ring_enqueue_burst(sr, evs, RTE_DIM(evs), &free_count); + if (ret != RTE_DIM(evs) || + free_count != rte_event_ring_get_capacity(sr) - ret) { + printf("Error, status after enqueue is unexpected\n"); + goto error; + } + + ret = rte_event_ring_enqueue_burst(sr, evs, RTE_DIM(evs), &free_count); + if (ret != RTE_DIM(evs) - 1 || + free_count != 0) { + printf("Error, status after enqueue is unexpected\n"); + goto error; + } + + ret = rte_event_ring_dequeue_burst(sr, evs, RTE_DIM(evs), &used_count); + if (ret != RTE_DIM(evs) || + used_count != rte_event_ring_get_capacity(sr) - ret) { + printf("Error, status after enqueue is unexpected\n"); + goto error; + } + ret = rte_event_ring_dequeue_burst(sr, evs, RTE_DIM(evs), &used_count); + if (ret != RTE_DIM(evs) - 1 || + used_count != 0) { + printf("Error, status after enqueue is unexpected\n"); + goto error; + } + + rte_event_ring_free(sr); + return 0; +error: + rte_event_ring_free(sr); + return -1; +} + +static int +test_event_ring_with_exact_size(void) +{ + struct rte_event_ring *std_ring, *exact_sz_ring; + struct rte_event ev = { .mbuf = NULL }; + struct rte_event ev_array[16]; + static const unsigned int ring_sz = RTE_DIM(ev_array); + unsigned int i; + + std_ring = rte_event_ring_create("std", ring_sz, rte_socket_id(), + RING_F_SP_ENQ | RING_F_SC_DEQ); + if (std_ring == NULL) { + printf("%s: error, can't create std ring\n", __func__); + return -1; + } + exact_sz_ring = rte_event_ring_create("exact sz", + ring_sz, rte_socket_id(), + RING_F_SP_ENQ | RING_F_SC_DEQ | RING_F_EXACT_SZ); + if (exact_sz_ring == NULL) { + printf("%s: error, can't create exact size ring\n", __func__); + return -1; + } + + /* + * Check that the exact size ring is bigger than the standard ring + */ + if (rte_event_ring_get_size(std_ring) >= + rte_event_ring_get_size(exact_sz_ring)) { + printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n", + __func__, + rte_event_ring_get_size(std_ring), + rte_event_ring_get_size(exact_sz_ring)); + return -1; + } + /* + * check that the exact_sz_ring can hold one more element than the + * standard ring. (16 vs 15 elements) + */ + for (i = 0; i < ring_sz - 1; i++) { + rte_event_ring_enqueue_burst(std_ring, &ev, 1, NULL); + rte_event_ring_enqueue_burst(exact_sz_ring, &ev, 1, NULL); + } + if (rte_event_ring_enqueue_burst(std_ring, &ev, 1, NULL) != 0) { + printf("%s: error, unexpected successful enqueue\n", __func__); + return -1; + } + if (rte_event_ring_enqueue_burst(exact_sz_ring, &ev, 1, NULL) != 1) { + printf("%s: error, enqueue failed\n", __func__); + return -1; + } + + /* check that dequeue returns the expected number of elements */ + if (rte_event_ring_dequeue_burst(exact_sz_ring, ev_array, + RTE_DIM(ev_array), NULL) != ring_sz) { + printf("%s: error, failed to dequeue expected nb of elements\n", + __func__); + return -1; + } + + /* check that the capacity function returns expected value */ + if (rte_event_ring_get_capacity(exact_sz_ring) != ring_sz) { + printf("%s: error, incorrect ring capacity reported\n", + __func__); + return -1; + } + + rte_event_ring_free(std_ring); + rte_event_ring_free(exact_sz_ring); + return 0; +} + +static int +test_event_ring(void) +{ + if (r == NULL) + r = rte_event_ring_create("ev_test", RING_SIZE, + SOCKET_ID_ANY, 0); + if (r == NULL) + return -1; + + /* retrieve the ring from its name */ + if (rte_event_ring_lookup("ev_test") != r) { + printf("Cannot lookup ring from its name\n"); + return -1; + } + + /* basic operations */ + if (test_create_count_odd() < 0) { + printf("Test failed to detect odd count\n"); + return -1; + } + printf("Test detected odd count\n"); + + if (test_lookup_null() < 0) { + printf("Test failed to detect NULL ring lookup\n"); + return -1; + } + printf("Test detected NULL ring lookup\n"); + + /* test of creating ring with wrong size */ + if (test_event_ring_creation_with_wrong_size() < 0) + return -1; + + if (test_basic_event_enqueue_dequeue() < 0) + return -1; + + if (test_event_ring_with_exact_size() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(event_ring_autotest, test_event_ring); diff --git a/app/test/test_event_timer_adapter.c b/app/test/test_event_timer_adapter.c new file mode 100644 index 0000000000..a45b7d1957 --- /dev/null +++ b/app/test/test_event_timer_adapter.c @@ -0,0 +1,1830 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Cavium, Inc + * Copyright(c) 2017-2018 Intel Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* 4K timers corresponds to sw evdev max inflight events */ +#define MAX_TIMERS (4 * 1024) +#define BKT_TCK_NSEC + +#define NSECPERSEC 1E9 +#define BATCH_SIZE 16 +/* Both the app lcore and adapter ports are linked to this queue */ +#define TEST_QUEUE_ID 0 +/* Port the application dequeues from */ +#define TEST_PORT_ID 0 +#define TEST_ADAPTER_ID 0 + +/* Handle log statements in same manner as test macros */ +#define LOG_DBG(...) RTE_LOG(DEBUG, EAL, __VA_ARGS__) + +static int evdev; +static struct rte_event_timer_adapter *timdev; +static struct rte_mempool *eventdev_test_mempool; +static struct rte_ring *timer_producer_ring; +static uint64_t global_bkt_tck_ns; +static volatile uint8_t arm_done; + +static bool using_services; +static uint32_t test_lcore1; +static uint32_t test_lcore2; +static uint32_t test_lcore3; +static uint32_t sw_evdev_slcore; +static uint32_t sw_adptr_slcore; + +static inline void +devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + memset(dev_conf, 0, sizeof(struct rte_event_dev_config)); + dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns; + dev_conf->nb_event_ports = 1; + dev_conf->nb_event_queues = 1; + dev_conf->nb_event_queue_flows = info->max_event_queue_flows; + dev_conf->nb_event_port_dequeue_depth = + info->max_event_port_dequeue_depth; + dev_conf->nb_event_port_enqueue_depth = + info->max_event_port_enqueue_depth; + dev_conf->nb_event_port_enqueue_depth = + info->max_event_port_enqueue_depth; + dev_conf->nb_events_limit = + info->max_num_events; +} + +static inline int +eventdev_setup(void) +{ + int ret; + struct rte_event_dev_config dev_conf; + struct rte_event_dev_info info; + uint32_t service_id; + + ret = rte_event_dev_info_get(evdev, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + TEST_ASSERT(info.max_num_events >= (int32_t)MAX_TIMERS, + "ERROR max_num_events=%d < max_events=%d", + info.max_num_events, MAX_TIMERS); + + devconf_set_default_sane_values(&dev_conf, &info); + ret = rte_event_dev_configure(evdev, &dev_conf); + TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); + + ret = rte_event_queue_setup(evdev, 0, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%d", 0); + + /* Configure event port */ + ret = rte_event_port_setup(evdev, 0, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port=%d", 0); + ret = rte_event_port_link(evdev, 0, NULL, NULL, 0); + TEST_ASSERT(ret >= 0, "Failed to link all queues port=%d", 0); + + /* If this is a software event device, map and start its service */ + if (rte_event_dev_service_id_get(evdev, &service_id) == 0) { + TEST_ASSERT_SUCCESS(rte_service_lcore_add(sw_evdev_slcore), + "Failed to add service core"); + TEST_ASSERT_SUCCESS(rte_service_lcore_start( + sw_evdev_slcore), + "Failed to start service core"); + TEST_ASSERT_SUCCESS(rte_service_map_lcore_set( + service_id, sw_evdev_slcore, 1), + "Failed to map evdev service"); + TEST_ASSERT_SUCCESS(rte_service_runstate_set( + service_id, 1), + "Failed to start evdev service"); + } + + ret = rte_event_dev_start(evdev); + TEST_ASSERT_SUCCESS(ret, "Failed to start device"); + + return TEST_SUCCESS; +} + +static int +testsuite_setup(void) +{ + /* Some of the multithreaded tests require 3 other lcores to run */ + unsigned int required_lcore_count = 4; + uint32_t service_id; + + /* To make it easier to map services later if needed, just reset + * service core state. + */ + (void) rte_service_lcore_reset_all(); + + if (!rte_event_dev_count()) { + /* If there is no hardware eventdev, or no software vdev was + * specified on the command line, create an instance of + * event_sw. + */ + LOG_DBG("Failed to find a valid event device... testing with" + " event_sw device\n"); + TEST_ASSERT_SUCCESS(rte_vdev_init("event_sw0", NULL), + "Error creating eventdev"); + evdev = rte_event_dev_get_dev_id("event_sw0"); + } + + if (rte_event_dev_service_id_get(evdev, &service_id) == 0) { + /* A software event device will use a software event timer + * adapter as well. 2 more cores required to convert to + * service cores. + */ + required_lcore_count += 2; + using_services = true; + } + + if (rte_lcore_count() < required_lcore_count) { + printf("%d lcores needed to run tests", required_lcore_count); + return TEST_FAILED; + } + + /* Assign lcores for various tasks */ + test_lcore1 = rte_get_next_lcore(-1, 1, 0); + test_lcore2 = rte_get_next_lcore(test_lcore1, 1, 0); + test_lcore3 = rte_get_next_lcore(test_lcore2, 1, 0); + if (using_services) { + sw_evdev_slcore = rte_get_next_lcore(test_lcore3, 1, 0); + sw_adptr_slcore = rte_get_next_lcore(sw_evdev_slcore, 1, 0); + } + + return eventdev_setup(); +} + +static void +testsuite_teardown(void) +{ + rte_event_dev_stop(evdev); + rte_event_dev_close(evdev); +} + +static int +setup_adapter_service(struct rte_event_timer_adapter *adptr) +{ + uint32_t adapter_service_id; + int ret; + + /* retrieve service ids */ + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_service_id_get(adptr, + &adapter_service_id), "Failed to get event timer " + "adapter service id"); + /* add a service core and start it */ + ret = rte_service_lcore_add(sw_adptr_slcore); + TEST_ASSERT(ret == 0 || ret == -EALREADY, + "Failed to add service core"); + ret = rte_service_lcore_start(sw_adptr_slcore); + TEST_ASSERT(ret == 0 || ret == -EALREADY, + "Failed to start service core"); + + /* map services to it */ + TEST_ASSERT_SUCCESS(rte_service_map_lcore_set(adapter_service_id, + sw_adptr_slcore, 1), + "Failed to map adapter service"); + + /* set services to running */ + TEST_ASSERT_SUCCESS(rte_service_runstate_set(adapter_service_id, 1), + "Failed to start event timer adapter service"); + + return TEST_SUCCESS; +} + +static int +test_port_conf_cb(uint16_t id, uint8_t event_dev_id, uint8_t *event_port_id, + void *conf_arg) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_dev_info info; + struct rte_event_port_conf *port_conf, def_port_conf = {0}; + uint32_t started; + static int port_allocated; + static uint8_t port_id; + int ret; + + if (port_allocated) { + *event_port_id = port_id; + return 0; + } + + RTE_SET_USED(id); + + ret = rte_event_dev_attr_get(event_dev_id, RTE_EVENT_DEV_ATTR_STARTED, + &started); + if (ret < 0) + return ret; + + if (started) + rte_event_dev_stop(event_dev_id); + + ret = rte_event_dev_info_get(evdev, &info); + if (ret < 0) + return ret; + + devconf_set_default_sane_values(&dev_conf, &info); + + port_id = dev_conf.nb_event_ports; + dev_conf.nb_event_ports++; + + ret = rte_event_dev_configure(event_dev_id, &dev_conf); + if (ret < 0) { + if (started) + rte_event_dev_start(event_dev_id); + return ret; + } + + if (conf_arg != NULL) + port_conf = conf_arg; + else { + port_conf = &def_port_conf; + ret = rte_event_port_default_conf_get(event_dev_id, port_id, + port_conf); + if (ret < 0) + return ret; + } + + ret = rte_event_port_setup(event_dev_id, port_id, port_conf); + if (ret < 0) + return ret; + + *event_port_id = port_id; + + if (started) + rte_event_dev_start(event_dev_id); + + /* Reuse this port number next time this is called */ + port_allocated = 1; + + return 0; +} + +static int +_timdev_setup(uint64_t max_tmo_ns, uint64_t bkt_tck_ns) +{ + struct rte_event_timer_adapter_conf config = { + .event_dev_id = evdev, + .timer_adapter_id = TEST_ADAPTER_ID, + .timer_tick_ns = bkt_tck_ns, + .max_tmo_ns = max_tmo_ns, + .nb_timers = MAX_TIMERS * 10, + }; + uint32_t caps = 0; + const char *pool_name = "timdev_test_pool"; + + global_bkt_tck_ns = bkt_tck_ns; + + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_caps_get(evdev, &caps), + "failed to get adapter capabilities"); + if (!(caps & RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) { + timdev = rte_event_timer_adapter_create_ext(&config, + test_port_conf_cb, + NULL); + setup_adapter_service(timdev); + using_services = true; + } else + timdev = rte_event_timer_adapter_create(&config); + + TEST_ASSERT_NOT_NULL(timdev, + "failed to create event timer ring"); + + TEST_ASSERT_EQUAL(rte_event_timer_adapter_start(timdev), 0, + "failed to Start event timer adapter"); + + /* Create event timer mempool */ + eventdev_test_mempool = rte_mempool_create(pool_name, + MAX_TIMERS * 2, + sizeof(struct rte_event_timer), /* element size*/ + 0, /* cache size*/ + 0, NULL, NULL, NULL, NULL, + rte_socket_id(), 0); + if (!eventdev_test_mempool) { + printf("ERROR creating mempool\n"); + return TEST_FAILED; + } + + return TEST_SUCCESS; +} + +static int +timdev_setup_usec(void) +{ + return using_services ? + /* Max timeout is 10,000us and bucket interval is 100us */ + _timdev_setup(1E7, 1E5) : + /* Max timeout is 100us and bucket interval is 1us */ + _timdev_setup(1E5, 1E3); +} + +static int +timdev_setup_usec_multicore(void) +{ + return using_services ? + /* Max timeout is 10,000us and bucket interval is 100us */ + _timdev_setup(1E7, 1E5) : + /* Max timeout is 100us and bucket interval is 1us */ + _timdev_setup(1E5, 1E3); +} + +static int +timdev_setup_msec(void) +{ + /* Max timeout is 2 mins, and bucket interval is 100 ms */ + return _timdev_setup(180 * NSECPERSEC, NSECPERSEC / 10); +} + +static int +timdev_setup_sec(void) +{ + /* Max timeout is 100sec and bucket interval is 1sec */ + return _timdev_setup(1E11, 1E9); +} + +static int +timdev_setup_sec_multicore(void) +{ + /* Max timeout is 100sec and bucket interval is 1sec */ + return _timdev_setup(1E11, 1E9); +} + +static void +timdev_teardown(void) +{ + rte_event_timer_adapter_stop(timdev); + rte_event_timer_adapter_free(timdev); + + rte_mempool_free(eventdev_test_mempool); +} + +static inline int +test_timer_state(void) +{ + struct rte_event_timer *ev_tim; + struct rte_event ev; + const struct rte_event_timer tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = 0, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + }; + + rte_mempool_get(eventdev_test_mempool, (void **)&ev_tim); + *ev_tim = tim; + ev_tim->ev.event_ptr = ev_tim; + ev_tim->timeout_ticks = 120; + + TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 0, + "Armed timer exceeding max_timeout."); + TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_ERROR_TOOLATE, + "Improper timer state set expected %d returned %d", + RTE_EVENT_TIMER_ERROR_TOOLATE, ev_tim->state); + + ev_tim->state = RTE_EVENT_TIMER_NOT_ARMED; + ev_tim->timeout_ticks = 10; + + TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 1, + "Failed to arm timer with proper timeout."); + TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_ARMED, + "Improper timer state set expected %d returned %d", + RTE_EVENT_TIMER_ARMED, ev_tim->state); + + if (!using_services) + rte_delay_us(20); + else + rte_delay_us(1000 + 200); + TEST_ASSERT_EQUAL(rte_event_dequeue_burst(evdev, 0, &ev, 1, 0), 1, + "Armed timer failed to trigger."); + + ev_tim->state = RTE_EVENT_TIMER_NOT_ARMED; + ev_tim->timeout_ticks = 90; + TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 1, + "Failed to arm timer with proper timeout."); + TEST_ASSERT_EQUAL(rte_event_timer_cancel_burst(timdev, &ev_tim, 1), + 1, "Failed to cancel armed timer"); + TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_CANCELED, + "Improper timer state set expected %d returned %d", + RTE_EVENT_TIMER_CANCELED, ev_tim->state); + + rte_mempool_put(eventdev_test_mempool, (void *)ev_tim); + + return TEST_SUCCESS; +} + +static inline int +_arm_timers(uint64_t timeout_tcks, uint64_t timers) +{ + uint64_t i; + struct rte_event_timer *ev_tim; + const struct rte_event_timer tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = 0, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = timeout_tcks, + }; + + for (i = 0; i < timers; i++) { + + TEST_ASSERT_SUCCESS(rte_mempool_get(eventdev_test_mempool, + (void **)&ev_tim), + "mempool alloc failed"); + *ev_tim = tim; + ev_tim->ev.event_ptr = ev_tim; + + TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, + 1), 1, "Failed to arm timer %d", + rte_errno); + } + + return TEST_SUCCESS; +} + +static inline int +_wait_timer_triggers(uint64_t wait_sec, uint64_t arm_count, + uint64_t cancel_count) +{ + uint8_t valid_event; + uint64_t events = 0; + uint64_t wait_start, max_wait; + struct rte_event ev; + + max_wait = rte_get_timer_hz() * wait_sec; + wait_start = rte_get_timer_cycles(); + while (1) { + if (rte_get_timer_cycles() - wait_start > max_wait) { + if (events + cancel_count != arm_count) + TEST_ASSERT_SUCCESS(max_wait, + "Max time limit for timers exceeded."); + break; + } + + valid_event = rte_event_dequeue_burst(evdev, 0, &ev, 1, 0); + if (!valid_event) + continue; + + rte_mempool_put(eventdev_test_mempool, ev.event_ptr); + events++; + } + + return TEST_SUCCESS; +} + +static inline int +test_timer_arm(void) +{ + TEST_ASSERT_SUCCESS(_arm_timers(20, MAX_TIMERS), + "Failed to arm timers"); + TEST_ASSERT_SUCCESS(_wait_timer_triggers(10, MAX_TIMERS, 0), + "Timer triggered count doesn't match arm count"); + return TEST_SUCCESS; +} + +static int +_arm_wrapper(void *arg) +{ + RTE_SET_USED(arg); + + TEST_ASSERT_SUCCESS(_arm_timers(20, MAX_TIMERS), + "Failed to arm timers"); + + return TEST_SUCCESS; +} + +static inline int +test_timer_arm_multicore(void) +{ + + uint32_t lcore_1 = rte_get_next_lcore(-1, 1, 0); + uint32_t lcore_2 = rte_get_next_lcore(lcore_1, 1, 0); + + rte_eal_remote_launch(_arm_wrapper, NULL, lcore_1); + rte_eal_remote_launch(_arm_wrapper, NULL, lcore_2); + + rte_eal_mp_wait_lcore(); + TEST_ASSERT_SUCCESS(_wait_timer_triggers(10, MAX_TIMERS * 2, 0), + "Timer triggered count doesn't match arm count"); + + return TEST_SUCCESS; +} + +#define MAX_BURST 16 +static inline int +_arm_timers_burst(uint64_t timeout_tcks, uint64_t timers) +{ + uint64_t i; + int j; + struct rte_event_timer *ev_tim[MAX_BURST]; + const struct rte_event_timer tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = 0, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = timeout_tcks, + }; + + for (i = 0; i < timers / MAX_BURST; i++) { + TEST_ASSERT_SUCCESS(rte_mempool_get_bulk( + eventdev_test_mempool, + (void **)ev_tim, MAX_BURST), + "mempool alloc failed"); + + for (j = 0; j < MAX_BURST; j++) { + *ev_tim[j] = tim; + ev_tim[j]->ev.event_ptr = ev_tim[j]; + } + + TEST_ASSERT_EQUAL(rte_event_timer_arm_tmo_tick_burst(timdev, + ev_tim, tim.timeout_ticks, MAX_BURST), + MAX_BURST, "Failed to arm timer %d", rte_errno); + } + + return TEST_SUCCESS; +} + +static inline int +test_timer_arm_burst(void) +{ + TEST_ASSERT_SUCCESS(_arm_timers_burst(20, MAX_TIMERS), + "Failed to arm timers"); + TEST_ASSERT_SUCCESS(_wait_timer_triggers(10, MAX_TIMERS, 0), + "Timer triggered count doesn't match arm count"); + + return TEST_SUCCESS; +} + +static int +_arm_wrapper_burst(void *arg) +{ + RTE_SET_USED(arg); + + TEST_ASSERT_SUCCESS(_arm_timers_burst(20, MAX_TIMERS), + "Failed to arm timers"); + + return TEST_SUCCESS; +} + +static inline int +test_timer_arm_burst_multicore(void) +{ + rte_eal_remote_launch(_arm_wrapper_burst, NULL, test_lcore1); + rte_eal_remote_launch(_arm_wrapper_burst, NULL, test_lcore2); + + rte_eal_mp_wait_lcore(); + TEST_ASSERT_SUCCESS(_wait_timer_triggers(10, MAX_TIMERS * 2, 0), + "Timer triggered count doesn't match arm count"); + + return TEST_SUCCESS; +} + +static inline int +test_timer_cancel(void) +{ + uint64_t i; + struct rte_event_timer *ev_tim; + const struct rte_event_timer tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = 0, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 20, + }; + + for (i = 0; i < MAX_TIMERS; i++) { + TEST_ASSERT_SUCCESS(rte_mempool_get(eventdev_test_mempool, + (void **)&ev_tim), + "mempool alloc failed"); + *ev_tim = tim; + ev_tim->ev.event_ptr = ev_tim; + + TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, + 1), 1, "Failed to arm timer %d", + rte_errno); + + rte_delay_us(100 + (i % 5000)); + + TEST_ASSERT_EQUAL(rte_event_timer_cancel_burst(timdev, + &ev_tim, 1), 1, + "Failed to cancel event timer %d", rte_errno); + rte_mempool_put(eventdev_test_mempool, ev_tim); + } + + + TEST_ASSERT_SUCCESS(_wait_timer_triggers(30, MAX_TIMERS, + MAX_TIMERS), + "Timer triggered count doesn't match arm, cancel count"); + + return TEST_SUCCESS; +} + +static int +_cancel_producer(uint64_t timeout_tcks, uint64_t timers) +{ + uint64_t i; + struct rte_event_timer *ev_tim; + const struct rte_event_timer tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = 0, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = timeout_tcks, + }; + + for (i = 0; i < timers; i++) { + TEST_ASSERT_SUCCESS(rte_mempool_get(eventdev_test_mempool, + (void **)&ev_tim), + "mempool alloc failed"); + + *ev_tim = tim; + ev_tim->ev.event_ptr = ev_tim; + + TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, + 1), 1, "Failed to arm timer %d", + rte_errno); + + TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_ARMED, + "Failed to arm event timer"); + + while (rte_ring_enqueue(timer_producer_ring, ev_tim) != 0) + ; + } + + return TEST_SUCCESS; +} + +static int +_cancel_producer_burst(uint64_t timeout_tcks, uint64_t timers) +{ + + uint64_t i; + int j, ret; + struct rte_event_timer *ev_tim[MAX_BURST]; + const struct rte_event_timer tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = 0, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = timeout_tcks, + }; + int arm_count = 0; + + for (i = 0; i < timers / MAX_BURST; i++) { + TEST_ASSERT_SUCCESS(rte_mempool_get_bulk( + eventdev_test_mempool, + (void **)ev_tim, MAX_BURST), + "mempool alloc failed"); + + for (j = 0; j < MAX_BURST; j++) { + *ev_tim[j] = tim; + ev_tim[j]->ev.event_ptr = ev_tim[j]; + } + + TEST_ASSERT_EQUAL(rte_event_timer_arm_tmo_tick_burst(timdev, + ev_tim, tim.timeout_ticks, MAX_BURST), + MAX_BURST, "Failed to arm timer %d", rte_errno); + + for (j = 0; j < MAX_BURST; j++) + TEST_ASSERT_EQUAL(ev_tim[j]->state, + RTE_EVENT_TIMER_ARMED, + "Event timer not armed, state = %d", + ev_tim[j]->state); + + ret = rte_ring_enqueue_bulk(timer_producer_ring, + (void **)ev_tim, MAX_BURST, NULL); + TEST_ASSERT_EQUAL(ret, MAX_BURST, + "Failed to enqueue event timers to ring"); + arm_count += ret; + } + + TEST_ASSERT_EQUAL(arm_count, MAX_TIMERS, + "Failed to arm expected number of event timers"); + + return TEST_SUCCESS; +} + +static int +_cancel_producer_wrapper(void *args) +{ + RTE_SET_USED(args); + + return _cancel_producer(20, MAX_TIMERS); +} + +static int +_cancel_producer_burst_wrapper(void *args) +{ + RTE_SET_USED(args); + + return _cancel_producer_burst(100, MAX_TIMERS); +} + +static int +_cancel_thread(void *args) +{ + RTE_SET_USED(args); + struct rte_event_timer *ev_tim = NULL; + uint64_t cancel_count = 0; + uint16_t ret; + + while (!arm_done || rte_ring_count(timer_producer_ring) > 0) { + if (rte_ring_dequeue(timer_producer_ring, (void **)&ev_tim)) + continue; + + ret = rte_event_timer_cancel_burst(timdev, &ev_tim, 1); + TEST_ASSERT_EQUAL(ret, 1, "Failed to cancel timer"); + rte_mempool_put(eventdev_test_mempool, (void *)ev_tim); + cancel_count++; + } + + return TEST_SUCCESS; +} + +static int +_cancel_burst_thread(void *args) +{ + RTE_SET_USED(args); + + int ret, i, n; + struct rte_event_timer *ev_tim[MAX_BURST]; + uint64_t cancel_count = 0; + uint64_t dequeue_count = 0; + + while (!arm_done || rte_ring_count(timer_producer_ring) > 0) { + n = rte_ring_dequeue_burst(timer_producer_ring, + (void **)ev_tim, MAX_BURST, NULL); + if (!n) + continue; + + dequeue_count += n; + + for (i = 0; i < n; i++) + TEST_ASSERT_EQUAL(ev_tim[i]->state, + RTE_EVENT_TIMER_ARMED, + "Event timer not armed, state = %d", + ev_tim[i]->state); + + ret = rte_event_timer_cancel_burst(timdev, ev_tim, n); + TEST_ASSERT_EQUAL(n, ret, "Failed to cancel complete burst of " + "event timers"); + rte_mempool_put_bulk(eventdev_test_mempool, (void **)ev_tim, + RTE_MIN(ret, MAX_BURST)); + + cancel_count += ret; + } + + TEST_ASSERT_EQUAL(cancel_count, MAX_TIMERS, + "Failed to cancel expected number of timers: " + "expected = %d, cancel_count = %"PRIu64", " + "dequeue_count = %"PRIu64"\n", MAX_TIMERS, + cancel_count, dequeue_count); + + return TEST_SUCCESS; +} + +static inline int +test_timer_cancel_multicore(void) +{ + arm_done = 0; + timer_producer_ring = rte_ring_create("timer_cancel_queue", + MAX_TIMERS * 2, rte_socket_id(), 0); + TEST_ASSERT_NOT_NULL(timer_producer_ring, + "Unable to reserve memory for ring"); + + rte_eal_remote_launch(_cancel_thread, NULL, test_lcore3); + rte_eal_remote_launch(_cancel_producer_wrapper, NULL, test_lcore1); + rte_eal_remote_launch(_cancel_producer_wrapper, NULL, test_lcore2); + + rte_eal_wait_lcore(test_lcore1); + rte_eal_wait_lcore(test_lcore2); + arm_done = 1; + rte_eal_wait_lcore(test_lcore3); + rte_ring_free(timer_producer_ring); + + TEST_ASSERT_SUCCESS(_wait_timer_triggers(30, MAX_TIMERS * 2, + MAX_TIMERS * 2), + "Timer triggered count doesn't match arm count"); + + return TEST_SUCCESS; +} + +static inline int +test_timer_cancel_burst_multicore(void) +{ + arm_done = 0; + timer_producer_ring = rte_ring_create("timer_cancel_queue", + MAX_TIMERS * 2, rte_socket_id(), 0); + TEST_ASSERT_NOT_NULL(timer_producer_ring, + "Unable to reserve memory for ring"); + + rte_eal_remote_launch(_cancel_burst_thread, NULL, test_lcore2); + rte_eal_remote_launch(_cancel_producer_burst_wrapper, NULL, + test_lcore1); + + rte_eal_wait_lcore(test_lcore1); + arm_done = 1; + rte_eal_wait_lcore(test_lcore2); + rte_ring_free(timer_producer_ring); + + TEST_ASSERT_SUCCESS(_wait_timer_triggers(30, MAX_TIMERS, + MAX_TIMERS), + "Timer triggered count doesn't match arm count"); + + return TEST_SUCCESS; +} + +static inline int +test_timer_cancel_random(void) +{ + uint64_t i; + uint64_t events_canceled = 0; + struct rte_event_timer *ev_tim; + const struct rte_event_timer tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = 0, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 20, + }; + + for (i = 0; i < MAX_TIMERS; i++) { + + TEST_ASSERT_SUCCESS(rte_mempool_get(eventdev_test_mempool, + (void **)&ev_tim), + "mempool alloc failed"); + *ev_tim = tim; + ev_tim->ev.event_ptr = ev_tim; + + TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, + 1), 1, "Failed to arm timer %d", + rte_errno); + + if (rte_rand() & 1) { + rte_delay_us(100 + (i % 5000)); + TEST_ASSERT_EQUAL(rte_event_timer_cancel_burst( + timdev, + &ev_tim, 1), 1, + "Failed to cancel event timer %d", rte_errno); + rte_mempool_put(eventdev_test_mempool, ev_tim); + events_canceled++; + } + } + + TEST_ASSERT_SUCCESS(_wait_timer_triggers(30, MAX_TIMERS, + events_canceled), + "Timer triggered count doesn't match arm, cancel count"); + + return TEST_SUCCESS; +} + +/* Check that the adapter can be created correctly */ +static int +adapter_create(void) +{ + int adapter_id = 0; + struct rte_event_timer_adapter *adapter, *adapter2; + + struct rte_event_timer_adapter_conf conf = { + .event_dev_id = evdev + 1, // invalid event dev id + .timer_adapter_id = adapter_id, + .clk_src = RTE_EVENT_TIMER_ADAPTER_CPU_CLK, + .timer_tick_ns = NSECPERSEC / 10, + .max_tmo_ns = 180 * NSECPERSEC, + .nb_timers = MAX_TIMERS, + .flags = 0, + }; + uint32_t caps = 0; + + /* Test invalid conf */ + adapter = rte_event_timer_adapter_create(&conf); + TEST_ASSERT_NULL(adapter, "Created adapter with invalid " + "event device id"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Incorrect errno value for " + "invalid event device id"); + + /* Test valid conf */ + conf.event_dev_id = evdev; + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_caps_get(evdev, &caps), + "failed to get adapter capabilities"); + if (!(caps & RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) + adapter = rte_event_timer_adapter_create_ext(&conf, + test_port_conf_cb, + NULL); + else + adapter = rte_event_timer_adapter_create(&conf); + TEST_ASSERT_NOT_NULL(adapter, "Failed to create adapter with valid " + "configuration"); + + /* Test existing id */ + adapter2 = rte_event_timer_adapter_create(&conf); + TEST_ASSERT_NULL(adapter2, "Created adapter with in-use id"); + TEST_ASSERT(rte_errno == EEXIST, "Incorrect errno value for existing " + "id"); + + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(adapter), + "Failed to free adapter"); + + rte_mempool_free(eventdev_test_mempool); + + return TEST_SUCCESS; +} + + +/* Test that adapter can be freed correctly. */ +static int +adapter_free(void) +{ + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stop(timdev), + "Failed to stop adapter"); + + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(timdev), + "Failed to free valid adapter"); + + /* Test free of already freed adapter */ + TEST_ASSERT_FAIL(rte_event_timer_adapter_free(timdev), + "Freed adapter that was already freed"); + + /* Test free of null adapter */ + timdev = NULL; + TEST_ASSERT_FAIL(rte_event_timer_adapter_free(timdev), + "Freed null adapter"); + + rte_mempool_free(eventdev_test_mempool); + + return TEST_SUCCESS; +} + +/* Test that adapter info can be retrieved and is correct. */ +static int +adapter_get_info(void) +{ + struct rte_event_timer_adapter_info info; + + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_get_info(timdev, &info), + "Failed to get adapter info"); + + if (using_services) + TEST_ASSERT_EQUAL(info.event_dev_port_id, 1, + "Expected port id = 1, got port id = %d", + info.event_dev_port_id); + + return TEST_SUCCESS; +} + +/* Test adapter lookup via adapter ID. */ +static int +adapter_lookup(void) +{ + struct rte_event_timer_adapter *adapter; + + adapter = rte_event_timer_adapter_lookup(TEST_ADAPTER_ID); + TEST_ASSERT_NOT_NULL(adapter, "Failed to lookup adapter"); + + return TEST_SUCCESS; +} + +static int +adapter_start(void) +{ + TEST_ASSERT_SUCCESS(_timdev_setup(180 * NSECPERSEC, + NSECPERSEC / 10), + "Failed to start adapter"); + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_start(timdev), + "Failed to repeatedly start adapter"); + + return TEST_SUCCESS; +} + +/* Test that adapter stops correctly. */ +static int +adapter_stop(void) +{ + struct rte_event_timer_adapter *l_adapter = NULL; + + /* Test adapter stop */ + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stop(timdev), + "Failed to stop event adapter"); + + TEST_ASSERT_FAIL(rte_event_timer_adapter_stop(l_adapter), + "Erroneously stopped null event adapter"); + + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(timdev), + "Failed to free adapter"); + + rte_mempool_free(eventdev_test_mempool); + + return TEST_SUCCESS; +} + +/* Test increment and reset of ev_enq_count stat */ +static int +stat_inc_reset_ev_enq(void) +{ + int ret, i, n; + int num_evtims = MAX_TIMERS; + struct rte_event_timer *evtims[num_evtims]; + struct rte_event evs[BATCH_SIZE]; + struct rte_event_timer_adapter_stats stats; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 5, // expire in .5 sec + }; + + ret = rte_mempool_get_bulk(eventdev_test_mempool, (void **)evtims, + num_evtims); + TEST_ASSERT_EQUAL(ret, 0, "Failed to get array of timer objs: ret = %d", + ret); + + for (i = 0; i < num_evtims; i++) { + *evtims[i] = init_tim; + evtims[i]->ev.event_ptr = evtims[i]; + } + + ret = rte_event_timer_adapter_stats_get(timdev, &stats); + TEST_ASSERT_EQUAL(ret, 0, "Failed to get stats"); + TEST_ASSERT_EQUAL((int)stats.ev_enq_count, 0, "Stats not clear at " + "startup"); + + /* Test with the max value for the adapter */ + ret = rte_event_timer_arm_burst(timdev, evtims, num_evtims); + TEST_ASSERT_EQUAL(ret, num_evtims, + "Failed to arm all event timers: attempted = %d, " + "succeeded = %d, rte_errno = %s", + num_evtims, ret, rte_strerror(rte_errno)); + + rte_delay_ms(1000); + +#define MAX_TRIES num_evtims + int sum = 0; + int tries = 0; + bool done = false; + while (!done) { + sum += rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, + RTE_DIM(evs), 10); + if (sum >= num_evtims || ++tries >= MAX_TRIES) + done = true; + + rte_delay_ms(10); + } + + TEST_ASSERT_EQUAL(sum, num_evtims, "Expected %d timer expiry events, " + "got %d", num_evtims, sum); + + TEST_ASSERT(tries < MAX_TRIES, "Exceeded max tries"); + + rte_delay_ms(100); + + /* Make sure the eventdev is still empty */ + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), + 10); + + TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected number of timer expiry " + "events from event device"); + + /* Check stats again */ + ret = rte_event_timer_adapter_stats_get(timdev, &stats); + TEST_ASSERT_EQUAL(ret, 0, "Failed to get stats"); + TEST_ASSERT_EQUAL((int)stats.ev_enq_count, num_evtims, + "Expected enqueue stat = %d; got %d", num_evtims, + (int)stats.ev_enq_count); + + /* Reset and check again */ + ret = rte_event_timer_adapter_stats_reset(timdev); + TEST_ASSERT_EQUAL(ret, 0, "Failed to reset stats"); + + ret = rte_event_timer_adapter_stats_get(timdev, &stats); + TEST_ASSERT_EQUAL(ret, 0, "Failed to get stats"); + TEST_ASSERT_EQUAL((int)stats.ev_enq_count, 0, + "Expected enqueue stat = %d; got %d", 0, + (int)stats.ev_enq_count); + + rte_mempool_put_bulk(eventdev_test_mempool, (void **)evtims, + num_evtims); + + return TEST_SUCCESS; +} + +/* Test various cases in arming timers */ +static int +event_timer_arm(void) +{ + uint16_t n; + int ret; + struct rte_event_timer_adapter *adapter = timdev; + struct rte_event_timer *evtim = NULL; + struct rte_event evs[BATCH_SIZE]; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 5, // expire in .5 sec + }; + + rte_mempool_get(eventdev_test_mempool, (void **)&evtim); + if (evtim == NULL) { + /* Failed to get an event timer object */ + return TEST_FAILED; + } + + /* Set up a timer */ + *evtim = init_tim; + evtim->ev.event_ptr = evtim; + + /* Test single timer arm succeeds */ + ret = rte_event_timer_arm_burst(adapter, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", + rte_strerror(rte_errno)); + TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, "Event timer " + "in incorrect state"); + + /* Test arm of armed timer fails */ + ret = rte_event_timer_arm_burst(adapter, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 0, "expected return value from " + "rte_event_timer_arm_burst: 0, got: %d", ret); + TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value " + "after arming already armed timer"); + + /* Let timer expire */ + rte_delay_ms(1000); + + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); + TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry " + "events from event device"); + + rte_mempool_put(eventdev_test_mempool, evtim); + + return TEST_SUCCESS; +} + +/* This test checks that repeated references to the same event timer in the + * arm request work as expected; only the first one through should succeed. + */ +static int +event_timer_arm_double(void) +{ + uint16_t n; + int ret; + struct rte_event_timer_adapter *adapter = timdev; + struct rte_event_timer *evtim = NULL; + struct rte_event evs[BATCH_SIZE]; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 5, // expire in .5 sec + }; + + rte_mempool_get(eventdev_test_mempool, (void **)&evtim); + if (evtim == NULL) { + /* Failed to get an event timer object */ + return TEST_FAILED; + } + + /* Set up a timer */ + *evtim = init_tim; + evtim->ev.event_ptr = evtim; + + struct rte_event_timer *evtim_arr[] = {evtim, evtim}; + ret = rte_event_timer_arm_burst(adapter, evtim_arr, RTE_DIM(evtim_arr)); + TEST_ASSERT_EQUAL(ret, 1, "Unexpected return value from " + "rte_event_timer_arm_burst"); + TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value " + "after double-arm"); + + /* Let timer expire */ + rte_delay_ms(600); + + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); + TEST_ASSERT_EQUAL(n, 1, "Dequeued incorrect number of expiry events - " + "expected: 1, actual: %d", n); + + rte_mempool_put(eventdev_test_mempool, evtim); + + return TEST_SUCCESS; +} + +/* Test the timer expiry event is generated at the expected time. */ +static int +event_timer_arm_expiry(void) +{ + uint16_t n; + int ret; + struct rte_event_timer_adapter *adapter = timdev; + struct rte_event_timer *evtim = NULL; + struct rte_event_timer *evtim2 = NULL; + struct rte_event evs[BATCH_SIZE]; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + }; + + rte_mempool_get(eventdev_test_mempool, (void **)&evtim); + if (evtim == NULL) { + /* Failed to get an event timer object */ + return TEST_FAILED; + } + + /* Set up an event timer */ + *evtim = init_tim; + evtim->timeout_ticks = 30, // expire in 3 secs + evtim->ev.event_ptr = evtim; + + ret = rte_event_timer_arm_burst(adapter, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s", + rte_strerror(rte_errno)); + TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, "Event " + "timer in incorrect state"); + + rte_delay_ms(2999); + + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); + TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event"); + + /* Delay 100 ms to account for the adapter tick window - should let us + * dequeue one event + */ + rte_delay_ms(100); + + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); + TEST_ASSERT_EQUAL(n, 1, "Dequeued incorrect number (%d) of timer " + "expiry events", n); + TEST_ASSERT_EQUAL(evs[0].event_type, RTE_EVENT_TYPE_TIMER, + "Dequeued unexpected type of event"); + + /* Check that we recover the original event timer and then free it */ + evtim2 = evs[0].event_ptr; + TEST_ASSERT_EQUAL(evtim, evtim2, + "Failed to recover pointer to original event timer"); + rte_mempool_put(eventdev_test_mempool, evtim2); + + return TEST_SUCCESS; +} + +/* Check that rearming a timer works as expected. */ +static int +event_timer_arm_rearm(void) +{ + uint16_t n; + int ret; + struct rte_event_timer *evtim = NULL; + struct rte_event_timer *evtim2 = NULL; + struct rte_event evs[BATCH_SIZE]; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + }; + + rte_mempool_get(eventdev_test_mempool, (void **)&evtim); + if (evtim == NULL) { + /* Failed to get an event timer object */ + return TEST_FAILED; + } + + /* Set up a timer */ + *evtim = init_tim; + evtim->timeout_ticks = 1; // expire in 0.1 sec + evtim->ev.event_ptr = evtim; + + /* Arm it */ + ret = rte_event_timer_arm_burst(timdev, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", + rte_strerror(rte_errno)); + + /* Add 100ms to account for the adapter tick window */ + rte_delay_ms(100 + 100); + + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); + TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry " + "events from event device"); + + /* Recover the timer through the event that was dequeued. */ + evtim2 = evs[0].event_ptr; + TEST_ASSERT_EQUAL(evtim, evtim2, + "Failed to recover pointer to original event timer"); + + /* Need to reset state in case implementation can't do it */ + evtim2->state = RTE_EVENT_TIMER_NOT_ARMED; + + /* Rearm it */ + ret = rte_event_timer_arm_burst(timdev, &evtim2, 1); + TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", + rte_strerror(rte_errno)); + + /* Add 100ms to account for the adapter tick window */ + rte_delay_ms(100 + 100); + + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); + TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry " + "events from event device"); + + /* Free it */ + evtim2 = evs[0].event_ptr; + TEST_ASSERT_EQUAL(evtim, evtim2, + "Failed to recover pointer to original event timer"); + rte_mempool_put(eventdev_test_mempool, evtim2); + + return TEST_SUCCESS; +} + +/* Check that the adapter handles the max specified number of timers as + * expected. + */ +static int +event_timer_arm_max(void) +{ + int ret, i, n; + int num_evtims = MAX_TIMERS; + struct rte_event_timer *evtims[num_evtims]; + struct rte_event evs[BATCH_SIZE]; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 5, // expire in .5 sec + }; + + ret = rte_mempool_get_bulk(eventdev_test_mempool, (void **)evtims, + num_evtims); + TEST_ASSERT_EQUAL(ret, 0, "Failed to get array of timer objs: ret = %d", + ret); + + for (i = 0; i < num_evtims; i++) { + *evtims[i] = init_tim; + evtims[i]->ev.event_ptr = evtims[i]; + } + + /* Test with the max value for the adapter */ + ret = rte_event_timer_arm_burst(timdev, evtims, num_evtims); + TEST_ASSERT_EQUAL(ret, num_evtims, + "Failed to arm all event timers: attempted = %d, " + "succeeded = %d, rte_errno = %s", + num_evtims, ret, rte_strerror(rte_errno)); + + rte_delay_ms(1000); + +#define MAX_TRIES num_evtims + int sum = 0; + int tries = 0; + bool done = false; + while (!done) { + sum += rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, + RTE_DIM(evs), 10); + if (sum >= num_evtims || ++tries >= MAX_TRIES) + done = true; + + rte_delay_ms(10); + } + + TEST_ASSERT_EQUAL(sum, num_evtims, "Expected %d timer expiry events, " + "got %d", num_evtims, sum); + + TEST_ASSERT(tries < MAX_TRIES, "Exceeded max tries"); + + rte_delay_ms(100); + + /* Make sure the eventdev is still empty */ + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), + 10); + + TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected number of timer expiry " + "events from event device"); + + rte_mempool_put_bulk(eventdev_test_mempool, (void **)evtims, + num_evtims); + + return TEST_SUCCESS; +} + +/* Check that creating an event timer with incorrect event sched type fails. */ +static int +event_timer_arm_invalid_sched_type(void) +{ + int ret; + struct rte_event_timer *evtim = NULL; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 5, // expire in .5 sec + }; + + if (!using_services) + return -ENOTSUP; + + rte_mempool_get(eventdev_test_mempool, (void **)&evtim); + if (evtim == NULL) { + /* Failed to get an event timer object */ + return TEST_FAILED; + } + + *evtim = init_tim; + evtim->ev.event_ptr = evtim; + evtim->ev.sched_type = RTE_SCHED_TYPE_PARALLEL; // bad sched type + + ret = rte_event_timer_arm_burst(timdev, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 0, "Expected to fail timer arm with invalid " + "sched type, but didn't"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after" + " arm fail with invalid queue"); + + rte_mempool_put(eventdev_test_mempool, &evtim); + + return TEST_SUCCESS; +} + +/* Check that creating an event timer with a timeout value that is too small or + * too big fails. + */ +static int +event_timer_arm_invalid_timeout(void) +{ + int ret; + struct rte_event_timer *evtim = NULL; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 5, // expire in .5 sec + }; + + rte_mempool_get(eventdev_test_mempool, (void **)&evtim); + if (evtim == NULL) { + /* Failed to get an event timer object */ + return TEST_FAILED; + } + + *evtim = init_tim; + evtim->ev.event_ptr = evtim; + evtim->timeout_ticks = 0; // timeout too small + + ret = rte_event_timer_arm_burst(timdev, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 0, "Expected to fail timer arm with invalid " + "timeout, but didn't"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after" + " arm fail with invalid timeout"); + TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ERROR_TOOEARLY, + "Unexpected event timer state"); + + *evtim = init_tim; + evtim->ev.event_ptr = evtim; + evtim->timeout_ticks = 1801; // timeout too big + + ret = rte_event_timer_arm_burst(timdev, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 0, "Expected to fail timer arm with invalid " + "timeout, but didn't"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after" + " arm fail with invalid timeout"); + TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ERROR_TOOLATE, + "Unexpected event timer state"); + + rte_mempool_put(eventdev_test_mempool, evtim); + + return TEST_SUCCESS; +} + +static int +event_timer_cancel(void) +{ + uint16_t n; + int ret; + struct rte_event_timer_adapter *adapter = timdev; + struct rte_event_timer *evtim = NULL; + struct rte_event evs[BATCH_SIZE]; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + }; + + rte_mempool_get(eventdev_test_mempool, (void **)&evtim); + if (evtim == NULL) { + /* Failed to get an event timer object */ + return TEST_FAILED; + } + + /* Check that cancelling an uninited timer fails */ + ret = rte_event_timer_cancel_burst(adapter, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 0, "Succeeded unexpectedly in canceling " + "uninited timer"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after " + "cancelling uninited timer"); + + /* Set up a timer */ + *evtim = init_tim; + evtim->ev.event_ptr = evtim; + evtim->timeout_ticks = 30; // expire in 3 sec + + /* Check that cancelling an inited but unarmed timer fails */ + ret = rte_event_timer_cancel_burst(adapter, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 0, "Succeeded unexpectedly in canceling " + "unarmed timer"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after " + "cancelling unarmed timer"); + + ret = rte_event_timer_arm_burst(adapter, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", + rte_strerror(rte_errno)); + TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, + "evtim in incorrect state"); + + /* Delay 1 sec */ + rte_delay_ms(1000); + + ret = rte_event_timer_cancel_burst(adapter, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 1, "Failed to cancel event_timer: %s\n", + rte_strerror(rte_errno)); + TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_CANCELED, + "evtim in incorrect state"); + + rte_delay_ms(3000); + + /* Make sure that no expiry event was generated */ + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); + TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event\n"); + + rte_mempool_put(eventdev_test_mempool, evtim); + + return TEST_SUCCESS; +} + +static int +event_timer_cancel_double(void) +{ + uint16_t n; + int ret; + struct rte_event_timer_adapter *adapter = timdev; + struct rte_event_timer *evtim = NULL; + struct rte_event evs[BATCH_SIZE]; + const struct rte_event_timer init_tim = { + .ev.op = RTE_EVENT_OP_NEW, + .ev.queue_id = TEST_QUEUE_ID, + .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, + .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, + .ev.event_type = RTE_EVENT_TYPE_TIMER, + .state = RTE_EVENT_TIMER_NOT_ARMED, + .timeout_ticks = 5, // expire in .5 sec + }; + + rte_mempool_get(eventdev_test_mempool, (void **)&evtim); + if (evtim == NULL) { + /* Failed to get an event timer object */ + return TEST_FAILED; + } + + /* Set up a timer */ + *evtim = init_tim; + evtim->ev.event_ptr = evtim; + evtim->timeout_ticks = 30; // expire in 3 sec + + ret = rte_event_timer_arm_burst(adapter, &evtim, 1); + TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", + rte_strerror(rte_errno)); + TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, + "timer in unexpected state"); + + /* Now, test that referencing the same timer twice in the same call + * fails + */ + struct rte_event_timer *evtim_arr[] = {evtim, evtim}; + ret = rte_event_timer_cancel_burst(adapter, evtim_arr, + RTE_DIM(evtim_arr)); + + /* Two requests to cancel same timer, only one should succeed */ + TEST_ASSERT_EQUAL(ret, 1, "Succeeded unexpectedly in canceling timer " + "twice"); + + TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value " + "after double-cancel: rte_errno = %d", rte_errno); + + rte_delay_ms(3000); + + /* Still make sure that no expiry event was generated */ + n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); + TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event\n"); + + rte_mempool_put(eventdev_test_mempool, evtim); + + return TEST_SUCCESS; +} + +/* Check that event timer adapter tick resolution works as expected by testing + * the number of adapter ticks that occur within a particular time interval. + */ +static int +adapter_tick_resolution(void) +{ + struct rte_event_timer_adapter_stats stats; + uint64_t adapter_tick_count; + + /* Only run this test in the software driver case */ + if (!using_services) + return -ENOTSUP; + + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stats_reset(timdev), + "Failed to reset stats"); + + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stats_get(timdev, + &stats), "Failed to get adapter stats"); + TEST_ASSERT_EQUAL(stats.adapter_tick_count, 0, "Adapter tick count " + "not zeroed out"); + + /* Delay 1 second; should let at least 10 ticks occur with the default + * adapter configuration used by this test. + */ + rte_delay_ms(1000); + + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stats_get(timdev, + &stats), "Failed to get adapter stats"); + + adapter_tick_count = stats.adapter_tick_count; + TEST_ASSERT(adapter_tick_count >= 10 && adapter_tick_count <= 12, + "Expected 10-12 adapter ticks, got %"PRIu64"\n", + adapter_tick_count); + + return TEST_SUCCESS; +} + +static int +adapter_create_max(void) +{ + int i; + uint32_t svc_start_count, svc_end_count; + struct rte_event_timer_adapter *adapters[ + RTE_EVENT_TIMER_ADAPTER_NUM_MAX + 1]; + + struct rte_event_timer_adapter_conf conf = { + .event_dev_id = evdev, + // timer_adapter_id set in loop + .clk_src = RTE_EVENT_TIMER_ADAPTER_CPU_CLK, + .timer_tick_ns = NSECPERSEC / 10, + .max_tmo_ns = 180 * NSECPERSEC, + .nb_timers = MAX_TIMERS, + .flags = 0, + }; + + if (!using_services) + return -ENOTSUP; + + svc_start_count = rte_service_get_count(); + + /* This test expects that there are sufficient service IDs available + * to be allocated. I.e., RTE_EVENT_TIMER_ADAPTER_NUM_MAX may need to + * be less than RTE_SERVICE_NUM_MAX if anything else uses a service + * (the SW event device, for example). + */ + for (i = 0; i < RTE_EVENT_TIMER_ADAPTER_NUM_MAX; i++) { + conf.timer_adapter_id = i; + adapters[i] = rte_event_timer_adapter_create_ext(&conf, + test_port_conf_cb, NULL); + TEST_ASSERT_NOT_NULL(adapters[i], "Failed to create adapter " + "%d", i); + } + + conf.timer_adapter_id = i; + adapters[i] = rte_event_timer_adapter_create(&conf); + TEST_ASSERT_NULL(adapters[i], "Created too many adapters"); + + /* Check that at least RTE_EVENT_TIMER_ADAPTER_NUM_MAX services + * have been created + */ + svc_end_count = rte_service_get_count(); + TEST_ASSERT_EQUAL(svc_end_count - svc_start_count, + RTE_EVENT_TIMER_ADAPTER_NUM_MAX, + "Failed to create expected number of services"); + + for (i = 0; i < RTE_EVENT_TIMER_ADAPTER_NUM_MAX; i++) + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(adapters[i]), + "Failed to free adapter %d", i); + + /* Check that service count is back to where it was at start */ + svc_end_count = rte_service_get_count(); + TEST_ASSERT_EQUAL(svc_start_count, svc_end_count, "Failed to release " + "correct number of services"); + + return TEST_SUCCESS; +} + +static struct unit_test_suite event_timer_adptr_functional_testsuite = { + .suite_name = "event timer functional test suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(timdev_setup_usec, timdev_teardown, + test_timer_state), + TEST_CASE_ST(timdev_setup_usec, timdev_teardown, + test_timer_arm), + TEST_CASE_ST(timdev_setup_usec, timdev_teardown, + test_timer_arm_burst), + TEST_CASE_ST(timdev_setup_sec, timdev_teardown, + test_timer_cancel), + TEST_CASE_ST(timdev_setup_sec, timdev_teardown, + test_timer_cancel_random), + TEST_CASE_ST(timdev_setup_usec_multicore, timdev_teardown, + test_timer_arm_multicore), + TEST_CASE_ST(timdev_setup_usec_multicore, timdev_teardown, + test_timer_arm_burst_multicore), + TEST_CASE_ST(timdev_setup_sec_multicore, timdev_teardown, + test_timer_cancel_multicore), + TEST_CASE_ST(timdev_setup_sec_multicore, timdev_teardown, + test_timer_cancel_burst_multicore), + TEST_CASE(adapter_create), + TEST_CASE_ST(timdev_setup_msec, NULL, adapter_free), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + adapter_get_info), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + adapter_lookup), + TEST_CASE_ST(NULL, timdev_teardown, + adapter_start), + TEST_CASE_ST(timdev_setup_msec, NULL, + adapter_stop), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + stat_inc_reset_ev_enq), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_arm), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_arm_double), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_arm_expiry), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_arm_rearm), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_arm_max), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_arm_invalid_sched_type), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_arm_invalid_timeout), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_cancel), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + event_timer_cancel_double), + TEST_CASE_ST(timdev_setup_msec, timdev_teardown, + adapter_tick_resolution), + TEST_CASE(adapter_create_max), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_event_timer_adapter_func(void) +{ + return unit_test_suite_runner(&event_timer_adptr_functional_testsuite); +} + +REGISTER_TEST_COMMAND(event_timer_adapter_test, test_event_timer_adapter_func); diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c new file mode 100644 index 0000000000..00d73275c8 --- /dev/null +++ b/app/test/test_eventdev.c @@ -0,0 +1,1018 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 Cavium, Inc + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define TEST_DEV_ID 0 + +static int +testsuite_setup(void) +{ + RTE_BUILD_BUG_ON(sizeof(struct rte_event) != 16); + uint8_t count; + count = rte_event_dev_count(); + if (!count) { + printf("Failed to find a valid event device," + " testing with event_skeleton device\n"); + return rte_vdev_init("event_skeleton", NULL); + } + return TEST_SUCCESS; +} + +static void +testsuite_teardown(void) +{ +} + +static int +test_eventdev_count(void) +{ + uint8_t count; + count = rte_event_dev_count(); + TEST_ASSERT(count > 0, "Invalid eventdev count %" PRIu8, count); + return TEST_SUCCESS; +} + +static int +test_eventdev_get_dev_id(void) +{ + int ret; + ret = rte_event_dev_get_dev_id("not_a_valid_eventdev_driver"); + TEST_ASSERT_FAIL(ret, "Expected <0 for invalid dev name ret=%d", ret); + return TEST_SUCCESS; +} + +static int +test_eventdev_socket_id(void) +{ + int socket_id; + socket_id = rte_event_dev_socket_id(TEST_DEV_ID); + TEST_ASSERT(socket_id != -EINVAL, "Failed to get socket_id %d", + socket_id); + socket_id = rte_event_dev_socket_id(RTE_EVENT_MAX_DEVS); + TEST_ASSERT(socket_id == -EINVAL, "Expected -EINVAL %d", socket_id); + + return TEST_SUCCESS; +} + +static int +test_eventdev_info_get(void) +{ + int ret; + struct rte_event_dev_info info; + ret = rte_event_dev_info_get(TEST_DEV_ID, NULL); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + TEST_ASSERT(info.max_event_ports > 0, + "Not enough event ports %d", info.max_event_ports); + TEST_ASSERT(info.max_event_queues > 0, + "Not enough event queues %d", info.max_event_queues); + return TEST_SUCCESS; +} + +static inline void +devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + memset(dev_conf, 0, sizeof(struct rte_event_dev_config)); + dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns; + dev_conf->nb_event_ports = info->max_event_ports; + dev_conf->nb_event_queues = info->max_event_queues; + dev_conf->nb_event_queue_flows = info->max_event_queue_flows; + dev_conf->nb_event_port_dequeue_depth = + info->max_event_port_dequeue_depth; + dev_conf->nb_event_port_enqueue_depth = + info->max_event_port_enqueue_depth; + dev_conf->nb_event_port_enqueue_depth = + info->max_event_port_enqueue_depth; + dev_conf->nb_events_limit = + info->max_num_events; +} + +static int +test_ethdev_config_run(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info, + void (*fn)(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info)) +{ + devconf_set_default_sane_values(dev_conf, info); + fn(dev_conf, info); + return rte_event_dev_configure(TEST_DEV_ID, dev_conf); +} + +static void +max_dequeue_limit(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + dev_conf->dequeue_timeout_ns = info->max_dequeue_timeout_ns + 1; +} + +static void +max_events_limit(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + dev_conf->nb_events_limit = info->max_num_events + 1; +} + +static void +max_event_ports(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + dev_conf->nb_event_ports = info->max_event_ports + 1; +} + +static void +max_event_queues(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + dev_conf->nb_event_queues = info->max_event_queues + 1; +} + +static void +max_event_queue_flows(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + dev_conf->nb_event_queue_flows = info->max_event_queue_flows + 1; +} + +static void +max_event_port_dequeue_depth(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + dev_conf->nb_event_port_dequeue_depth = + info->max_event_port_dequeue_depth + 1; +} + +static void +max_event_port_enqueue_depth(struct rte_event_dev_config *dev_conf, + struct rte_event_dev_info *info) +{ + dev_conf->nb_event_port_enqueue_depth = + info->max_event_port_enqueue_depth + 1; +} + + +static int +test_eventdev_configure(void) +{ + int ret; + struct rte_event_dev_config dev_conf; + struct rte_event_dev_info info; + ret = rte_event_dev_configure(TEST_DEV_ID, NULL); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + /* Check limits */ + TEST_ASSERT_EQUAL(-EINVAL, + test_ethdev_config_run(&dev_conf, &info, max_dequeue_limit), + "Config negative test failed"); + TEST_ASSERT_EQUAL(-EINVAL, + test_ethdev_config_run(&dev_conf, &info, max_events_limit), + "Config negative test failed"); + TEST_ASSERT_EQUAL(-EINVAL, + test_ethdev_config_run(&dev_conf, &info, max_event_ports), + "Config negative test failed"); + TEST_ASSERT_EQUAL(-EINVAL, + test_ethdev_config_run(&dev_conf, &info, max_event_queues), + "Config negative test failed"); + TEST_ASSERT_EQUAL(-EINVAL, + test_ethdev_config_run(&dev_conf, &info, max_event_queue_flows), + "Config negative test failed"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE) { + TEST_ASSERT_EQUAL(-EINVAL, + test_ethdev_config_run(&dev_conf, &info, + max_event_port_dequeue_depth), + "Config negative test failed"); + TEST_ASSERT_EQUAL(-EINVAL, + test_ethdev_config_run(&dev_conf, &info, + max_event_port_enqueue_depth), + "Config negative test failed"); + } + + /* Positive case */ + devconf_set_default_sane_values(&dev_conf, &info); + ret = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); + + /* re-configure */ + devconf_set_default_sane_values(&dev_conf, &info); + dev_conf.nb_event_ports = RTE_MAX(info.max_event_ports/2, 1); + dev_conf.nb_event_queues = RTE_MAX(info.max_event_queues/2, 1); + ret = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(ret, "Failed to re configure eventdev"); + + /* re-configure back to max_event_queues and max_event_ports */ + devconf_set_default_sane_values(&dev_conf, &info); + ret = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(ret, "Failed to re-configure eventdev"); + + return TEST_SUCCESS; + +} + +static int +eventdev_configure_setup(void) +{ + int ret; + struct rte_event_dev_config dev_conf; + struct rte_event_dev_info info; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + devconf_set_default_sane_values(&dev_conf, &info); + ret = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); + + return TEST_SUCCESS; +} + +static int +test_eventdev_queue_default_conf_get(void) +{ + int i, ret; + struct rte_event_queue_conf qconf; + + ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, NULL); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + + for (i = 0; i < (int)queue_count; i++) { + ret = rte_event_queue_default_conf_get(TEST_DEV_ID, i, + &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get queue%d info", i); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_queue_setup(void) +{ + int i, ret; + struct rte_event_dev_info info; + struct rte_event_queue_conf qconf; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + /* Negative cases */ + ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get queue0 info"); + qconf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_ALL_TYPES; + qconf.nb_atomic_flows = info.max_event_queue_flows + 1; + ret = rte_event_queue_setup(TEST_DEV_ID, 0, &qconf); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + qconf.nb_atomic_flows = info.max_event_queue_flows; + qconf.schedule_type = RTE_SCHED_TYPE_ORDERED; + qconf.nb_atomic_order_sequences = info.max_event_queue_flows + 1; + ret = rte_event_queue_setup(TEST_DEV_ID, 0, &qconf); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + ret = rte_event_queue_setup(TEST_DEV_ID, info.max_event_queues, + &qconf); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Positive case */ + ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get queue0 info"); + ret = rte_event_queue_setup(TEST_DEV_ID, 0, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue0"); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + + for (i = 0; i < (int)queue_count; i++) { + ret = rte_event_queue_setup(TEST_DEV_ID, i, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_queue_count(void) +{ + int ret; + struct rte_event_dev_info info; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + TEST_ASSERT_EQUAL(queue_count, info.max_event_queues, + "Wrong queue count"); + + return TEST_SUCCESS; +} + +static int +test_eventdev_queue_attr_priority(void) +{ + int i, ret; + struct rte_event_dev_info info; + struct rte_event_queue_conf qconf; + uint8_t priority; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + + for (i = 0; i < (int)queue_count; i++) { + ret = rte_event_queue_default_conf_get(TEST_DEV_ID, i, + &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get queue%d def conf", i); + qconf.priority = i % RTE_EVENT_DEV_PRIORITY_LOWEST; + ret = rte_event_queue_setup(TEST_DEV_ID, i, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); + } + + for (i = 0; i < (int)queue_count; i++) { + uint32_t tmp; + TEST_ASSERT_SUCCESS(rte_event_queue_attr_get(TEST_DEV_ID, i, + RTE_EVENT_QUEUE_ATTR_PRIORITY, &tmp), + "Queue priority get failed"); + priority = tmp; + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_QUEUE_QOS) + TEST_ASSERT_EQUAL(priority, + i % RTE_EVENT_DEV_PRIORITY_LOWEST, + "Wrong priority value for queue%d", i); + else + TEST_ASSERT_EQUAL(priority, + RTE_EVENT_DEV_PRIORITY_NORMAL, + "Wrong priority value for queue%d", i); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_queue_attr_nb_atomic_flows(void) +{ + int i, ret; + struct rte_event_dev_info info; + struct rte_event_queue_conf qconf; + uint32_t nb_atomic_flows; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + + ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get queue 0's def conf"); + + if (qconf.nb_atomic_flows == 0) + /* Assume PMD doesn't support atomic flows, return early */ + return -ENOTSUP; + + qconf.schedule_type = RTE_SCHED_TYPE_ATOMIC; + + for (i = 0; i < (int)queue_count; i++) { + ret = rte_event_queue_setup(TEST_DEV_ID, i, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); + } + + for (i = 0; i < (int)queue_count; i++) { + TEST_ASSERT_SUCCESS(rte_event_queue_attr_get(TEST_DEV_ID, i, + RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_FLOWS, + &nb_atomic_flows), + "Queue nb_atomic_flows get failed"); + + TEST_ASSERT_EQUAL(nb_atomic_flows, qconf.nb_atomic_flows, + "Wrong atomic flows value for queue%d", i); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_queue_attr_nb_atomic_order_sequences(void) +{ + int i, ret; + struct rte_event_dev_info info; + struct rte_event_queue_conf qconf; + uint32_t nb_atomic_order_sequences; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + + ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get queue 0's def conf"); + + if (qconf.nb_atomic_order_sequences == 0) + /* Assume PMD doesn't support reordering */ + return -ENOTSUP; + + qconf.schedule_type = RTE_SCHED_TYPE_ORDERED; + + for (i = 0; i < (int)queue_count; i++) { + ret = rte_event_queue_setup(TEST_DEV_ID, i, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); + } + + for (i = 0; i < (int)queue_count; i++) { + TEST_ASSERT_SUCCESS(rte_event_queue_attr_get(TEST_DEV_ID, i, + RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_ORDER_SEQUENCES, + &nb_atomic_order_sequences), + "Queue nb_atomic_order_sequencess get failed"); + + TEST_ASSERT_EQUAL(nb_atomic_order_sequences, + qconf.nb_atomic_order_sequences, + "Wrong atomic order sequences value for queue%d", + i); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_queue_attr_event_queue_cfg(void) +{ + int i, ret; + struct rte_event_dev_info info; + struct rte_event_queue_conf qconf; + uint32_t event_queue_cfg; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + + ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get queue0 def conf"); + + qconf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK; + + for (i = 0; i < (int)queue_count; i++) { + ret = rte_event_queue_setup(TEST_DEV_ID, i, &qconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); + } + + for (i = 0; i < (int)queue_count; i++) { + TEST_ASSERT_SUCCESS(rte_event_queue_attr_get(TEST_DEV_ID, i, + RTE_EVENT_QUEUE_ATTR_EVENT_QUEUE_CFG, + &event_queue_cfg), + "Queue event_queue_cfg get failed"); + + TEST_ASSERT_EQUAL(event_queue_cfg, qconf.event_queue_cfg, + "Wrong event_queue_cfg value for queue%d", + i); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_port_default_conf_get(void) +{ + int i, ret; + struct rte_event_port_conf pconf; + + ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, NULL); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + uint32_t port_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_PORT_COUNT, + &port_count), "Port count get failed"); + + ret = rte_event_port_default_conf_get(TEST_DEV_ID, + port_count + 1, NULL); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + for (i = 0; i < (int)port_count; i++) { + ret = rte_event_port_default_conf_get(TEST_DEV_ID, i, + &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get port%d info", i); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_port_setup(void) +{ + int i, ret; + struct rte_event_dev_info info; + struct rte_event_port_conf pconf; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + /* Negative cases */ + ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); + pconf.new_event_threshold = info.max_num_events + 1; + ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + pconf.new_event_threshold = info.max_num_events; + pconf.dequeue_depth = info.max_event_port_dequeue_depth + 1; + ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + pconf.dequeue_depth = info.max_event_port_dequeue_depth; + pconf.enqueue_depth = info.max_event_port_enqueue_depth + 1; + ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + if (!(info.event_dev_cap & + RTE_EVENT_DEV_CAP_IMPLICIT_RELEASE_DISABLE)) { + pconf.enqueue_depth = info.max_event_port_enqueue_depth; + pconf.disable_implicit_release = 1; + ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + pconf.disable_implicit_release = 0; + } + + ret = rte_event_port_setup(TEST_DEV_ID, info.max_event_ports, + &pconf); + TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Positive case */ + ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); + ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port0"); + + uint32_t port_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_PORT_COUNT, + &port_count), "Port count get failed"); + + for (i = 0; i < (int)port_count; i++) { + ret = rte_event_port_setup(TEST_DEV_ID, i, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port%d", i); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_port_attr_dequeue_depth(void) +{ + int ret; + struct rte_event_dev_info info; + struct rte_event_port_conf pconf; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); + ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port0"); + + uint32_t value; + TEST_ASSERT_EQUAL(rte_event_port_attr_get(TEST_DEV_ID, 0, + RTE_EVENT_PORT_ATTR_DEQ_DEPTH, &value), + 0, "Call to get port dequeue depth failed"); + TEST_ASSERT_EQUAL(value, pconf.dequeue_depth, + "Wrong port dequeue depth"); + + return TEST_SUCCESS; +} + +static int +test_eventdev_port_attr_enqueue_depth(void) +{ + int ret; + struct rte_event_dev_info info; + struct rte_event_port_conf pconf; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); + ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port0"); + + uint32_t value; + TEST_ASSERT_EQUAL(rte_event_port_attr_get(TEST_DEV_ID, 0, + RTE_EVENT_PORT_ATTR_ENQ_DEPTH, &value), + 0, "Call to get port enqueue depth failed"); + TEST_ASSERT_EQUAL(value, pconf.enqueue_depth, + "Wrong port enqueue depth"); + + return TEST_SUCCESS; +} + +static int +test_eventdev_port_attr_new_event_threshold(void) +{ + int ret; + struct rte_event_dev_info info; + struct rte_event_port_conf pconf; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); + ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port0"); + + uint32_t value; + TEST_ASSERT_EQUAL(rte_event_port_attr_get(TEST_DEV_ID, 0, + RTE_EVENT_PORT_ATTR_NEW_EVENT_THRESHOLD, &value), + 0, "Call to get port new event threshold failed"); + TEST_ASSERT_EQUAL((int32_t) value, pconf.new_event_threshold, + "Wrong port new event threshold"); + + return TEST_SUCCESS; +} + +static int +test_eventdev_port_count(void) +{ + int ret; + struct rte_event_dev_info info; + + ret = rte_event_dev_info_get(TEST_DEV_ID, &info); + TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); + + uint32_t port_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_PORT_COUNT, + &port_count), "Port count get failed"); + TEST_ASSERT_EQUAL(port_count, info.max_event_ports, "Wrong port count"); + + return TEST_SUCCESS; +} + +static int +test_eventdev_timeout_ticks(void) +{ + int ret; + uint64_t timeout_ticks; + + ret = rte_event_dequeue_timeout_ticks(TEST_DEV_ID, 100, &timeout_ticks); + if (ret != -ENOTSUP) + TEST_ASSERT_SUCCESS(ret, "Fail to get timeout_ticks"); + + return ret; +} + + +static int +test_eventdev_start_stop(void) +{ + int i, ret; + + ret = eventdev_configure_setup(); + TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + for (i = 0; i < (int)queue_count; i++) { + ret = rte_event_queue_setup(TEST_DEV_ID, i, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); + } + + uint32_t port_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_PORT_COUNT, + &port_count), "Port count get failed"); + + for (i = 0; i < (int)port_count; i++) { + ret = rte_event_port_setup(TEST_DEV_ID, i, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port%d", i); + } + + ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(ret == (int)queue_count, "Failed to link port, device %d", + TEST_DEV_ID); + + ret = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(ret, "Failed to start device%d", TEST_DEV_ID); + + rte_event_dev_stop(TEST_DEV_ID); + return TEST_SUCCESS; +} + + +static int +eventdev_setup_device(void) +{ + int i, ret; + + ret = eventdev_configure_setup(); + TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + for (i = 0; i < (int)queue_count; i++) { + ret = rte_event_queue_setup(TEST_DEV_ID, i, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); + } + + uint32_t port_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_PORT_COUNT, + &port_count), "Port count get failed"); + + for (i = 0; i < (int)port_count; i++) { + ret = rte_event_port_setup(TEST_DEV_ID, i, NULL); + TEST_ASSERT_SUCCESS(ret, "Failed to setup port%d", i); + } + + ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(ret == (int)queue_count, "Failed to link port, device %d", + TEST_DEV_ID); + + ret = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(ret, "Failed to start device%d", TEST_DEV_ID); + + return TEST_SUCCESS; +} + +static void +eventdev_stop_device(void) +{ + rte_event_dev_stop(TEST_DEV_ID); +} + +static int +test_eventdev_link(void) +{ + int ret, nb_queues, i; + uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; + uint8_t priorities[RTE_EVENT_MAX_QUEUES_PER_DEV]; + + ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(ret >= 0, "Failed to link with NULL device%d", + TEST_DEV_ID); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + nb_queues = queue_count; + for (i = 0; i < nb_queues; i++) { + queues[i] = i; + priorities[i] = RTE_EVENT_DEV_PRIORITY_NORMAL; + } + + ret = rte_event_port_link(TEST_DEV_ID, 0, queues, + priorities, nb_queues); + TEST_ASSERT(ret == nb_queues, "Failed to link(device%d) ret=%d", + TEST_DEV_ID, ret); + return TEST_SUCCESS; +} + +static int +test_eventdev_unlink(void) +{ + int ret, nb_queues, i; + uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; + + ret = rte_event_port_unlink(TEST_DEV_ID, 0, NULL, 0); + TEST_ASSERT(ret >= 0, "Failed to unlink with NULL device%d", + TEST_DEV_ID); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + nb_queues = queue_count; + for (i = 0; i < nb_queues; i++) + queues[i] = i; + + ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(ret >= 0, "Failed to link with NULL device%d", + TEST_DEV_ID); + + ret = rte_event_port_unlink(TEST_DEV_ID, 0, queues, nb_queues); + TEST_ASSERT(ret == nb_queues, "Failed to unlink(device%d) ret=%d", + TEST_DEV_ID, ret); + return TEST_SUCCESS; +} + +static int +test_eventdev_link_get(void) +{ + int ret, i; + uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; + uint8_t priorities[RTE_EVENT_MAX_QUEUES_PER_DEV]; + + /* link all queues */ + ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(ret >= 0, "Failed to link with NULL device%d", + TEST_DEV_ID); + + uint32_t queue_count; + TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, + RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), + "Queue count get failed"); + const int nb_queues = queue_count; + for (i = 0; i < nb_queues; i++) + queues[i] = i; + + ret = rte_event_port_unlink(TEST_DEV_ID, 0, queues, nb_queues); + TEST_ASSERT(ret == nb_queues, "Failed to unlink(device%d) ret=%d", + TEST_DEV_ID, ret); + + ret = rte_event_port_links_get(TEST_DEV_ID, 0, queues, priorities); + TEST_ASSERT(ret == 0, "(%d)Wrong link get=%d", TEST_DEV_ID, ret); + + /* link all queues and get the links */ + for (i = 0; i < nb_queues; i++) { + queues[i] = i; + priorities[i] = RTE_EVENT_DEV_PRIORITY_NORMAL; + } + ret = rte_event_port_link(TEST_DEV_ID, 0, queues, priorities, + nb_queues); + TEST_ASSERT(ret == nb_queues, "Failed to link(device%d) ret=%d", + TEST_DEV_ID, ret); + ret = rte_event_port_links_get(TEST_DEV_ID, 0, queues, priorities); + TEST_ASSERT(ret == nb_queues, "(%d)Wrong link get ret=%d expected=%d", + TEST_DEV_ID, ret, nb_queues); + /* unlink all*/ + ret = rte_event_port_unlink(TEST_DEV_ID, 0, NULL, 0); + TEST_ASSERT(ret == nb_queues, "Failed to unlink(device%d) ret=%d", + TEST_DEV_ID, ret); + /* link just one queue */ + queues[0] = 0; + priorities[0] = RTE_EVENT_DEV_PRIORITY_NORMAL; + + ret = rte_event_port_link(TEST_DEV_ID, 0, queues, priorities, 1); + TEST_ASSERT(ret == 1, "Failed to link(device%d) ret=%d", + TEST_DEV_ID, ret); + ret = rte_event_port_links_get(TEST_DEV_ID, 0, queues, priorities); + TEST_ASSERT(ret == 1, "(%d)Wrong link get ret=%d expected=%d", + TEST_DEV_ID, ret, 1); + /* unlink the queue */ + ret = rte_event_port_unlink(TEST_DEV_ID, 0, NULL, 0); + TEST_ASSERT(ret == 1, "Failed to unlink(device%d) ret=%d", + TEST_DEV_ID, ret); + + /* 4links and 2 unlinks */ + if (nb_queues >= 4) { + for (i = 0; i < 4; i++) { + queues[i] = i; + priorities[i] = 0x40; + } + ret = rte_event_port_link(TEST_DEV_ID, 0, queues, priorities, + 4); + TEST_ASSERT(ret == 4, "Failed to link(device%d) ret=%d", + TEST_DEV_ID, ret); + + for (i = 0; i < 2; i++) + queues[i] = i; + + ret = rte_event_port_unlink(TEST_DEV_ID, 0, queues, 2); + TEST_ASSERT(ret == 2, "Failed to unlink(device%d) ret=%d", + TEST_DEV_ID, ret); + ret = rte_event_port_links_get(TEST_DEV_ID, 0, + queues, priorities); + TEST_ASSERT(ret == 2, "(%d)Wrong link get ret=%d expected=%d", + TEST_DEV_ID, ret, 2); + TEST_ASSERT(queues[0] == 2, "ret=%d expected=%d", ret, 2); + TEST_ASSERT(priorities[0] == 0x40, "ret=%d expected=%d", + ret, 0x40); + TEST_ASSERT(queues[1] == 3, "ret=%d expected=%d", ret, 3); + TEST_ASSERT(priorities[1] == 0x40, "ret=%d expected=%d", + ret, 0x40); + } + + return TEST_SUCCESS; +} + +static int +test_eventdev_close(void) +{ + rte_event_dev_stop(TEST_DEV_ID); + return rte_event_dev_close(TEST_DEV_ID); +} + +static struct unit_test_suite eventdev_common_testsuite = { + .suite_name = "eventdev common code unit test suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(NULL, NULL, + test_eventdev_count), + TEST_CASE_ST(NULL, NULL, + test_eventdev_get_dev_id), + TEST_CASE_ST(NULL, NULL, + test_eventdev_socket_id), + TEST_CASE_ST(NULL, NULL, + test_eventdev_info_get), + TEST_CASE_ST(NULL, NULL, + test_eventdev_configure), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_queue_default_conf_get), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_queue_setup), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_queue_count), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_queue_attr_priority), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_queue_attr_nb_atomic_flows), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_queue_attr_nb_atomic_order_sequences), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_queue_attr_event_queue_cfg), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_port_default_conf_get), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_port_setup), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_port_attr_dequeue_depth), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_port_attr_enqueue_depth), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_port_attr_new_event_threshold), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_port_count), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_timeout_ticks), + TEST_CASE_ST(NULL, NULL, + test_eventdev_start_stop), + TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, + test_eventdev_link), + TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, + test_eventdev_unlink), + TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, + test_eventdev_link_get), + TEST_CASE_ST(eventdev_setup_device, NULL, + test_eventdev_close), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_eventdev_common(void) +{ + return unit_test_suite_runner(&eventdev_common_testsuite); +} + +static int +test_eventdev_selftest_impl(const char *pmd, const char *opts) +{ + rte_vdev_init(pmd, opts); + return rte_event_dev_selftest(rte_event_dev_get_dev_id(pmd)); +} + +static int +test_eventdev_selftest_sw(void) +{ + return test_eventdev_selftest_impl("event_sw", ""); +} + +static int +test_eventdev_selftest_octeontx(void) +{ + return test_eventdev_selftest_impl("event_octeontx", ""); +} + +REGISTER_TEST_COMMAND(eventdev_common_autotest, test_eventdev_common); +REGISTER_TEST_COMMAND(eventdev_selftest_sw, test_eventdev_selftest_sw); +REGISTER_TEST_COMMAND(eventdev_selftest_octeontx, + test_eventdev_selftest_octeontx); diff --git a/app/test/test_external_mem.c b/app/test/test_external_mem.c new file mode 100644 index 0000000000..97bde1cfbc --- /dev/null +++ b/app/test/test_external_mem.c @@ -0,0 +1,577 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define EXTERNAL_MEM_SZ (RTE_PGSIZE_4K << 10) /* 4M of data */ + +static int +check_mem(void *addr, rte_iova_t *iova, size_t pgsz, int n_pages) +{ + int i; + + /* check that we can get this memory from EAL now */ + for (i = 0; i < n_pages; i++) { + const struct rte_memseg_list *msl; + const struct rte_memseg *ms; + void *cur = RTE_PTR_ADD(addr, pgsz * i); + rte_iova_t expected_iova; + + msl = rte_mem_virt2memseg_list(cur); + if (!msl->external) { + printf("%s():%i: Memseg list is not marked as external\n", + __func__, __LINE__); + return -1; + } + + ms = rte_mem_virt2memseg(cur, msl); + if (ms == NULL) { + printf("%s():%i: Failed to retrieve memseg for external mem\n", + __func__, __LINE__); + return -1; + } + if (ms->addr != cur) { + printf("%s():%i: VA mismatch\n", __func__, __LINE__); + return -1; + } + expected_iova = (iova == NULL) ? RTE_BAD_IOVA : iova[i]; + if (ms->iova != expected_iova) { + printf("%s():%i: IOVA mismatch\n", __func__, __LINE__); + return -1; + } + } + return 0; +} + +static int +test_malloc_invalid_param(void *addr, size_t len, size_t pgsz, rte_iova_t *iova, + int n_pages) +{ + static const char * const names[] = { + NULL, /* NULL name */ + "", /* empty name */ + "this heap name is definitely way too long to be valid" + }; + const char *valid_name = "valid heap name"; + unsigned int i; + + /* check invalid name handling */ + for (i = 0; i < RTE_DIM(names); i++) { + const char *name = names[i]; + + /* these calls may fail for other reasons, so check errno */ + if (rte_malloc_heap_create(name) >= 0 || rte_errno != EINVAL) { + printf("%s():%i: Created heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_destroy(name) >= 0 || rte_errno != EINVAL) { + printf("%s():%i: Destroyed heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_get_socket(name) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Found socket for heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_memory_add(name, addr, len, + NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) { + printf("%s():%i: Added memory to heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_memory_remove(name, addr, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Removed memory from heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_memory_attach(name, addr, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Attached memory to heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_memory_detach(name, addr, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Detached memory from heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + } + + /* do same as above, but with a valid heap name */ + + /* skip create call */ + if (rte_malloc_heap_destroy(valid_name) >= 0 || rte_errno != ENOENT) { + printf("%s():%i: Destroyed heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_get_socket(valid_name) >= 0 || + rte_errno != ENOENT) { + printf("%s():%i: Found socket for heap with invalid name\n", + __func__, __LINE__); + goto fail; + } + + /* these calls may fail for other reasons, so check errno */ + if (rte_malloc_heap_memory_add(valid_name, addr, len, + NULL, 0, pgsz) >= 0 || rte_errno != ENOENT) { + printf("%s():%i: Added memory to non-existent heap\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_memory_remove(valid_name, addr, len) >= 0 || + rte_errno != ENOENT) { + printf("%s():%i: Removed memory from non-existent heap\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_memory_attach(valid_name, addr, len) >= 0 || + rte_errno != ENOENT) { + printf("%s():%i: Attached memory to non-existent heap\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_memory_detach(valid_name, addr, len) >= 0 || + rte_errno != ENOENT) { + printf("%s():%i: Detached memory from non-existent heap\n", + __func__, __LINE__); + goto fail; + } + + /* create a valid heap but test other invalid parameters */ + if (rte_malloc_heap_create(valid_name) != 0) { + printf("%s():%i: Failed to create valid heap\n", + __func__, __LINE__); + goto fail; + } + + /* zero length */ + if (rte_malloc_heap_memory_add(valid_name, addr, 0, + NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) { + printf("%s():%i: Added memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_memory_remove(valid_name, addr, 0) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Removed memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_memory_attach(valid_name, addr, 0) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Attached memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_memory_detach(valid_name, addr, 0) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Detached memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + + /* zero address */ + if (rte_malloc_heap_memory_add(valid_name, NULL, len, + NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) { + printf("%s():%i: Added memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_memory_remove(valid_name, NULL, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Removed memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + + if (rte_malloc_heap_memory_attach(valid_name, NULL, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Attached memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_memory_detach(valid_name, NULL, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Detached memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + + /* the following tests are only valid if IOVA table is not NULL */ + if (iova != NULL) { + /* wrong page count */ + if (rte_malloc_heap_memory_add(valid_name, addr, len, + iova, 0, pgsz) >= 0 || rte_errno != EINVAL) { + printf("%s():%i: Added memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_memory_add(valid_name, addr, len, + iova, n_pages - 1, pgsz) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Added memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_memory_add(valid_name, addr, len, + iova, n_pages + 1, pgsz) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Added memory with invalid parameters\n", + __func__, __LINE__); + goto fail; + } + } + + /* tests passed, destroy heap */ + if (rte_malloc_heap_destroy(valid_name) != 0) { + printf("%s():%i: Failed to destroy valid heap\n", + __func__, __LINE__); + goto fail; + } + return 0; +fail: + rte_malloc_heap_destroy(valid_name); + return -1; +} + +static int +test_malloc_basic(void *addr, size_t len, size_t pgsz, rte_iova_t *iova, + int n_pages) +{ + const char *heap_name = "heap"; + void *ptr = NULL; + int socket_id; + const struct rte_memzone *mz = NULL, *contig_mz = NULL; + + /* create heap */ + if (rte_malloc_heap_create(heap_name) != 0) { + printf("%s():%i: Failed to create malloc heap\n", + __func__, __LINE__); + goto fail; + } + + /* get socket ID corresponding to this heap */ + socket_id = rte_malloc_heap_get_socket(heap_name); + if (socket_id < 0) { + printf("%s():%i: cannot find socket for external heap\n", + __func__, __LINE__); + goto fail; + } + + /* heap is empty, so any allocation should fail */ + ptr = rte_malloc_socket("EXTMEM", 64, 0, socket_id); + if (ptr != NULL) { + printf("%s():%i: Allocated from empty heap\n", __func__, + __LINE__); + goto fail; + } + + /* add memory to heap */ + if (rte_malloc_heap_memory_add(heap_name, addr, len, + iova, n_pages, pgsz) != 0) { + printf("%s():%i: Failed to add memory to heap\n", + __func__, __LINE__); + goto fail; + } + + /* check if memory is accessible from EAL */ + if (check_mem(addr, iova, pgsz, n_pages) < 0) + goto fail; + + /* allocate - this now should succeed */ + ptr = rte_malloc_socket("EXTMEM", 64, 0, socket_id); + if (ptr == NULL) { + printf("%s():%i: Failed to allocate from external heap\n", + __func__, __LINE__); + goto fail; + } + + /* check if address is in expected range */ + if (ptr < addr || ptr >= RTE_PTR_ADD(addr, len)) { + printf("%s():%i: Allocated from unexpected address space\n", + __func__, __LINE__); + goto fail; + } + + /* we've allocated something - removing memory should fail */ + if (rte_malloc_heap_memory_remove(heap_name, addr, len) >= 0 || + rte_errno != EBUSY) { + printf("%s():%i: Removing memory succeeded when memory is not free\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_destroy(heap_name) >= 0 || rte_errno != EBUSY) { + printf("%s():%i: Destroying heap succeeded when memory is not free\n", + __func__, __LINE__); + goto fail; + } + + /* try allocating a memzone */ + mz = rte_memzone_reserve("heap_test", pgsz * 2, socket_id, 0); + if (mz == NULL) { + printf("%s():%i: Failed to reserve memzone\n", + __func__, __LINE__); + goto fail; + } + /* try allocating an IOVA-contiguous memzone - this should succeed + * if we've set up a contiguous IOVA table, and fail if we haven't. + */ + contig_mz = rte_memzone_reserve("heap_test_contig", pgsz * 2, socket_id, + RTE_MEMZONE_IOVA_CONTIG); + if ((iova == NULL) != (contig_mz == NULL)) { + printf("%s():%i: Failed to reserve memzone\n", + __func__, __LINE__); + goto fail; + } + + rte_malloc_dump_stats(stdout, NULL); + rte_malloc_dump_heaps(stdout); + + /* free memory - removing it should now succeed */ + rte_free(ptr); + ptr = NULL; + + rte_memzone_free(mz); + mz = NULL; + rte_memzone_free(contig_mz); + contig_mz = NULL; + + if (rte_malloc_heap_memory_remove(heap_name, addr, len) != 0) { + printf("%s():%i: Removing memory from heap failed\n", + __func__, __LINE__); + goto fail; + } + if (rte_malloc_heap_destroy(heap_name) != 0) { + printf("%s():%i: Destroying heap failed\n", + __func__, __LINE__); + goto fail; + } + + return 0; +fail: + rte_memzone_free(contig_mz); + rte_memzone_free(mz); + rte_free(ptr); + /* even if something failed, attempt to clean up */ + rte_malloc_heap_memory_remove(heap_name, addr, len); + rte_malloc_heap_destroy(heap_name); + + return -1; +} + +static int +test_extmem_invalid_param(void *addr, size_t len, size_t pgsz, rte_iova_t *iova, + int n_pages) +{ + /* these calls may fail for other reasons, so check errno */ + if (rte_extmem_unregister(addr, len) >= 0 || + rte_errno != ENOENT) { + printf("%s():%i: Unregistered non-existent memory\n", + __func__, __LINE__); + return -1; + } + + if (rte_extmem_attach(addr, len) >= 0 || + rte_errno != ENOENT) { + printf("%s():%i: Attached to non-existent memory\n", + __func__, __LINE__); + return -1; + } + if (rte_extmem_attach(addr, len) >= 0 || + rte_errno != ENOENT) { + printf("%s():%i: Detached from non-existent memory\n", + __func__, __LINE__); + return -1; + } + + /* zero length */ + if (rte_extmem_register(addr, 0, NULL, 0, pgsz) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Registered memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + + if (rte_extmem_unregister(addr, 0) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Unregistered memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + + if (rte_extmem_attach(addr, 0) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Attached memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + if (rte_extmem_attach(addr, 0) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Detached memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + + /* zero address */ + if (rte_extmem_register(NULL, len, NULL, 0, pgsz) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Registered memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + + if (rte_extmem_unregister(NULL, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Unregistered memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + + if (rte_extmem_attach(NULL, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Attached memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + if (rte_extmem_attach(NULL, len) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Detached memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + + /* the following tests are only valid if IOVA table is not NULL */ + if (iova != NULL) { + /* wrong page count */ + if (rte_extmem_register(addr, len, + iova, 0, pgsz) >= 0 || rte_errno != EINVAL) { + printf("%s():%i: Registered memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + if (rte_extmem_register(addr, len, + iova, n_pages - 1, pgsz) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Registered memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + if (rte_extmem_register(addr, len, + iova, n_pages + 1, pgsz) >= 0 || + rte_errno != EINVAL) { + printf("%s():%i: Registered memory with invalid parameters\n", + __func__, __LINE__); + return -1; + } + } + + return 0; +} + +static int +test_extmem_basic(void *addr, size_t len, size_t pgsz, rte_iova_t *iova, + int n_pages) +{ + /* register memory */ + if (rte_extmem_register(addr, len, iova, n_pages, pgsz) != 0) { + printf("%s():%i: Failed to register memory\n", + __func__, __LINE__); + goto fail; + } + + /* check if memory is accessible from EAL */ + if (check_mem(addr, iova, pgsz, n_pages) < 0) + goto fail; + + if (rte_extmem_unregister(addr, len) != 0) { + printf("%s():%i: Removing memory from heap failed\n", + __func__, __LINE__); + goto fail; + } + + return 0; +fail: + /* even if something failed, attempt to clean up */ + rte_extmem_unregister(addr, len); + + return -1; +} + +/* we need to test attach/detach in secondary processes. */ +static int +test_external_mem(void) +{ + size_t len = EXTERNAL_MEM_SZ; + size_t pgsz = RTE_PGSIZE_4K; + rte_iova_t iova[len / pgsz]; + void *addr; + int ret, n_pages; + int i; + + /* create external memory area */ + n_pages = RTE_DIM(iova); + addr = mmap(NULL, len, PROT_WRITE | PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (addr == MAP_FAILED) { + printf("%s():%i: Failed to create dummy memory area\n", + __func__, __LINE__); + return -1; + } + for (i = 0; i < n_pages; i++) { + /* arbitrary IOVA */ + rte_iova_t tmp = 0x100000000 + i * pgsz; + iova[i] = tmp; + } + + /* test external heap memory */ + ret = test_malloc_invalid_param(addr, len, pgsz, iova, n_pages); + ret |= test_malloc_basic(addr, len, pgsz, iova, n_pages); + /* when iova table is NULL, everything should still work */ + ret |= test_malloc_invalid_param(addr, len, pgsz, NULL, n_pages); + ret |= test_malloc_basic(addr, len, pgsz, NULL, n_pages); + + /* test non-heap memory */ + ret |= test_extmem_invalid_param(addr, len, pgsz, iova, n_pages); + ret |= test_extmem_basic(addr, len, pgsz, iova, n_pages); + /* when iova table is NULL, everything should still work */ + ret |= test_extmem_invalid_param(addr, len, pgsz, NULL, n_pages); + ret |= test_extmem_basic(addr, len, pgsz, NULL, n_pages); + + munmap(addr, len); + + return ret; +} + +REGISTER_TEST_COMMAND(external_mem_autotest, test_external_mem); diff --git a/app/test/test_fbarray.c b/app/test/test_fbarray.c new file mode 100644 index 0000000000..8c44e2c7e1 --- /dev/null +++ b/app/test/test_fbarray.c @@ -0,0 +1,576 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "test.h" + +struct fbarray_testsuite_params { + struct rte_fbarray arr; + int start; + int end; +}; + +static struct fbarray_testsuite_params param; + +#define FBARRAY_TEST_ARR_NAME "fbarray_autotest" +#define FBARRAY_TEST_LEN 256 +#define FBARRAY_TEST_ELT_SZ (sizeof(int)) + +static int autotest_setup(void) +{ + return rte_fbarray_init(¶m.arr, FBARRAY_TEST_ARR_NAME, + FBARRAY_TEST_LEN, FBARRAY_TEST_ELT_SZ); +} + +static void autotest_teardown(void) +{ + rte_fbarray_destroy(¶m.arr); +} + +static int init_array(void) +{ + int i; + for (i = param.start; i <= param.end; i++) { + if (rte_fbarray_set_used(¶m.arr, i)) + return -1; + } + return 0; +} + +static void reset_array(void) +{ + int i; + for (i = 0; i < FBARRAY_TEST_LEN; i++) + rte_fbarray_set_free(¶m.arr, i); +} + +static int first_msk_test_setup(void) +{ + /* put all within first mask */ + param.start = 3; + param.end = 10; + return init_array(); +} + +static int cross_msk_test_setup(void) +{ + /* put all within second and third mask */ + param.start = 70; + param.end = 160; + return init_array(); +} + +static int multi_msk_test_setup(void) +{ + /* put all within first and last mask */ + param.start = 3; + param.end = FBARRAY_TEST_LEN - 20; + return init_array(); +} + +static int last_msk_test_setup(void) +{ + /* put all within last mask */ + param.start = FBARRAY_TEST_LEN - 20; + param.end = FBARRAY_TEST_LEN - 1; + return init_array(); +} + +static int full_msk_test_setup(void) +{ + /* fill entire mask */ + param.start = 0; + param.end = FBARRAY_TEST_LEN - 1; + return init_array(); +} + +static int empty_msk_test_setup(void) +{ + /* do not fill anything in */ + reset_array(); + return 0; +} + +static int test_invalid(void) +{ + struct rte_fbarray dummy; + + /* invalid parameters */ + TEST_ASSERT_FAIL(rte_fbarray_attach(NULL), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT_FAIL(rte_fbarray_detach(NULL), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT_FAIL(rte_fbarray_destroy(NULL), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno valuey\n"); + TEST_ASSERT_FAIL(rte_fbarray_init(NULL, "fail", 16, 16), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, NULL, 16, 16), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", 0, 16), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", 16, 0), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + /* len must not be greater than INT_MAX */ + TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", INT_MAX + 1U, 16), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT_NULL(rte_fbarray_get(NULL, 0), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_idx(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_set_free(NULL, 0), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_set_used(NULL, 0), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_contig_free(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_contig_used(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_rev_contig_free(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_rev_contig_used(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_free(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_used(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_free(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_used(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_n_free(NULL, 0, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_n_used(NULL, 0, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_n_free(NULL, 0, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_n_used(NULL, 0, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_is_used(NULL, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT_SUCCESS(rte_fbarray_init(&dummy, "success", + FBARRAY_TEST_LEN, 8), + "Failed to initialize valid fbarray\n"); + + /* test API for handling invalid parameters with a valid fbarray */ + TEST_ASSERT_NULL(rte_fbarray_get(&dummy, FBARRAY_TEST_LEN), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_idx(&dummy, NULL) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_set_free(&dummy, FBARRAY_TEST_LEN), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_set_used(&dummy, FBARRAY_TEST_LEN), + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_contig_free(&dummy, FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_contig_used(&dummy, FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_rev_contig_free(&dummy, + FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_rev_contig_used(&dummy, + FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_next_free(&dummy, FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_next_used(&dummy, FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_prev_free(&dummy, FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_prev_used(&dummy, FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, + FBARRAY_TEST_LEN, 1) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 0, + FBARRAY_TEST_LEN + 1) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 0, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, + FBARRAY_TEST_LEN, 1) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 0, + FBARRAY_TEST_LEN + 1) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 0, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, + FBARRAY_TEST_LEN, 1) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 0, + FBARRAY_TEST_LEN + 1) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 0, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, + FBARRAY_TEST_LEN, 1) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 0, + FBARRAY_TEST_LEN + 1) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 0, 0) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT(rte_fbarray_is_used(&dummy, FBARRAY_TEST_LEN) < 0, + "Call succeeded with invalid parameters\n"); + TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); + + TEST_ASSERT_SUCCESS(rte_fbarray_destroy(&dummy), + "Failed to destroy valid fbarray\n"); + + return TEST_SUCCESS; +} + +static int check_free(void) +{ + const int idx = 0; + const int last_idx = FBARRAY_TEST_LEN - 1; + + /* ensure we can find a free spot */ + TEST_ASSERT_EQUAL(rte_fbarray_find_next_free(¶m.arr, idx), idx, + "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(¶m.arr, idx, 1), idx, + "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(¶m.arr, idx), + FBARRAY_TEST_LEN, + "Free space not found where expected\n"); + + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(¶m.arr, idx), idx, + "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(¶m.arr, idx, 1), idx, + "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, idx), 1, + "Free space not found where expected\n"); + + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(¶m.arr, last_idx), + last_idx, "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(¶m.arr, last_idx, 1), + last_idx, "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, + last_idx), FBARRAY_TEST_LEN, + "Free space not found where expected\n"); + + /* ensure we can't find any used spots */ + TEST_ASSERT(rte_fbarray_find_next_used(¶m.arr, idx) < 0, + "Used space found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_n_used(¶m.arr, idx, 1) < 0, + "Used space found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx), 0, + "Used space found where none was expected\n"); + + TEST_ASSERT(rte_fbarray_find_prev_used(¶m.arr, last_idx) < 0, + "Used space found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1) < 0, + "Used space found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, + last_idx), 0, + "Used space found where none was expected\n"); + + return 0; +} + +static int check_used_one(void) +{ + const int idx = 0; + const int last_idx = FBARRAY_TEST_LEN - 1; + + /* check that we can find used spots now */ + TEST_ASSERT_EQUAL(rte_fbarray_find_next_used(¶m.arr, idx), idx, + "Used space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(¶m.arr, idx, 1), idx, + "Used space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx), 1, + "Used space not found where expected\n"); + + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(¶m.arr, last_idx), idx, + "Used space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1), + idx, "Used space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, idx), 1, + "Used space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, + last_idx), idx, + "Used space not found where expected\n"); + + /* check if further indices are still free */ + TEST_ASSERT(rte_fbarray_find_next_used(¶m.arr, idx + 1) < 0, + "Used space not found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); + TEST_ASSERT(rte_fbarray_find_next_n_used(¶m.arr, idx + 1, 1) < 0, + "Used space not found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx + 1), 0, + "Used space not found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(¶m.arr, idx + 1), + FBARRAY_TEST_LEN - 1, + "Used space not found where none was expected\n"); + + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(¶m.arr, last_idx), 0, + "Used space not found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1), + 0, "Used space not found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, + last_idx), 0, + "Used space not found where none was expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, + last_idx), FBARRAY_TEST_LEN - 1, + "Used space not found where none was expected\n"); + + return 0; +} + +static int test_basic(void) +{ + const int idx = 0; + int i; + + /* check array count */ + TEST_ASSERT_EQUAL(param.arr.count, 0, "Wrong element count\n"); + + /* ensure we can find a free spot */ + if (check_free()) + return TEST_FAILED; + + /* check if used */ + TEST_ASSERT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, + "Used space found where not expected\n"); + + /* mark as used */ + TEST_ASSERT_SUCCESS(rte_fbarray_set_used(¶m.arr, idx), + "Failed to set as used\n"); + + /* check if used again */ + TEST_ASSERT_NOT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, + "Used space not found where expected\n"); + + if (check_used_one()) + return TEST_FAILED; + + /* check array count */ + TEST_ASSERT_EQUAL(param.arr.count, 1, "Wrong element count\n"); + + /* check if getting pointers works for every element */ + for (i = 0; i < FBARRAY_TEST_LEN; i++) { + void *td = rte_fbarray_get(¶m.arr, i); + TEST_ASSERT_NOT_NULL(td, "Invalid pointer returned\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_idx(¶m.arr, td), i, + "Wrong index returned\n"); + } + + /* mark as free */ + TEST_ASSERT_SUCCESS(rte_fbarray_set_free(¶m.arr, idx), + "Failed to set as free\n"); + + /* check array count */ + TEST_ASSERT_EQUAL(param.arr.count, 0, "Wrong element count\n"); + + /* check if used */ + TEST_ASSERT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, + "Used space found where not expected\n"); + + if (check_free()) + return TEST_FAILED; + + reset_array(); + + return TEST_SUCCESS; +} + +static int ensure_correct(struct rte_fbarray *arr, int first, int last, + bool used) +{ + int i, len = last - first + 1; + for (i = 0; i < len; i++) { + int cur = first + i; + int cur_len = len - i; + + if (used) { + TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(arr, + cur), cur_len, + "Used space length is wrong\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(arr, + last), len, + "Used space length is wrong\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(arr, + cur), i + 1, + "Used space length is wrong\n"); + + TEST_ASSERT_EQUAL(rte_fbarray_find_next_used(arr, cur), + cur, + "Used space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(arr, + cur, 1), cur, + "Used space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(arr, cur, + cur_len), cur, + "Used space not found where expected\n"); + + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(arr, cur), + cur, + "Used space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(arr, + last, cur_len), cur, + "Used space not found where expected\n"); + } else { + TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr, + cur), cur_len, + "Free space length is wrong\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, + last), len, + "Free space length is wrong\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, + cur), i + 1, + "Free space length is wrong\n"); + + TEST_ASSERT_EQUAL(rte_fbarray_find_next_free(arr, cur), + cur, + "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(arr, cur, + 1), cur, + "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(arr, cur, + cur_len), cur, + "Free space not found where expected\n"); + + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(arr, cur), + cur, + "Free space not found where expected\n"); + TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(arr, + last, cur_len), cur, + "Free space not found where expected\n"); + } + } + return 0; +} + +static int test_find(void) +{ + TEST_ASSERT_EQUAL((int)param.arr.count, param.end - param.start + 1, + "Wrong element count\n"); + /* ensure space is free before start */ + if (ensure_correct(¶m.arr, 0, param.start - 1, false)) + return TEST_FAILED; + /* ensure space is occupied where it's supposed to be */ + if (ensure_correct(¶m.arr, param.start, param.end, true)) + return TEST_FAILED; + /* ensure space after end is free as well */ + if (ensure_correct(¶m.arr, param.end + 1, FBARRAY_TEST_LEN - 1, + false)) + return TEST_FAILED; + return TEST_SUCCESS; +} + +static int test_empty(void) +{ + TEST_ASSERT_EQUAL((int)param.arr.count, 0, "Wrong element count\n"); + /* ensure space is free */ + if (ensure_correct(¶m.arr, 0, FBARRAY_TEST_LEN - 1, false)) + return TEST_FAILED; + return TEST_SUCCESS; +} + + +static struct unit_test_suite fbarray_test_suite = { + .suite_name = "fbarray autotest", + .setup = autotest_setup, + .teardown = autotest_teardown, + .unit_test_cases = { + TEST_CASE(test_invalid), + TEST_CASE(test_basic), + TEST_CASE_ST(first_msk_test_setup, reset_array, test_find), + TEST_CASE_ST(cross_msk_test_setup, reset_array, test_find), + TEST_CASE_ST(multi_msk_test_setup, reset_array, test_find), + TEST_CASE_ST(last_msk_test_setup, reset_array, test_find), + TEST_CASE_ST(full_msk_test_setup, reset_array, test_find), + TEST_CASE_ST(empty_msk_test_setup, reset_array, test_empty), + TEST_CASES_END() + } +}; + +static int +test_fbarray(void) +{ + return unit_test_suite_runner(&fbarray_test_suite); +} + +REGISTER_TEST_COMMAND(fbarray_autotest, test_fbarray); diff --git a/app/test/test_flow_classify.c b/app/test/test_flow_classify.c new file mode 100644 index 0000000000..5f5beeee75 --- /dev/null +++ b/app/test/test_flow_classify.c @@ -0,0 +1,902 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Intel Corporation + */ + +#include +#include + +#include "test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "packet_burst_generator.h" +#include "test_flow_classify.h" + + +#define FLOW_CLASSIFY_MAX_RULE_NUM 100 +#define MAX_PKT_BURST 32 +#define NB_SOCKETS 1 +#define MEMPOOL_CACHE_SIZE 256 +#define MBUF_SIZE 512 +#define NB_MBUF 512 + +/* test UDP, TCP and SCTP packets */ +static struct rte_mempool *mbufpool[NB_SOCKETS]; +static struct rte_mbuf *bufs[MAX_PKT_BURST]; + +static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { + /* first input field - always one byte long. */ + { + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint8_t), + .field_index = PROTO_FIELD_IPV4, + .input_index = PROTO_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, next_proto_id), + }, + /* next input field (IPv4 source address) - 4 consecutive bytes. */ + { + /* rte_flow uses a bit mask for IPv4 addresses */ + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint32_t), + .field_index = SRC_FIELD_IPV4, + .input_index = SRC_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, src_addr), + }, + /* next input field (IPv4 destination address) - 4 consecutive bytes. */ + { + /* rte_flow uses a bit mask for IPv4 addresses */ + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint32_t), + .field_index = DST_FIELD_IPV4, + .input_index = DST_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + offsetof(struct ipv4_hdr, dst_addr), + }, + /* + * Next 2 fields (src & dst ports) form 4 consecutive bytes. + * They share the same input index. + */ + { + /* rte_flow uses a bit mask for protocol ports */ + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint16_t), + .field_index = SRCP_FIELD_IPV4, + .input_index = SRCP_DESTP_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + sizeof(struct ipv4_hdr) + + offsetof(struct tcp_hdr, src_port), + }, + { + /* rte_flow uses a bit mask for protocol ports */ + .type = RTE_ACL_FIELD_TYPE_BITMASK, + .size = sizeof(uint16_t), + .field_index = DSTP_FIELD_IPV4, + .input_index = SRCP_DESTP_INPUT_IPV4, + .offset = sizeof(struct ether_hdr) + + sizeof(struct ipv4_hdr) + + offsetof(struct tcp_hdr, dst_port), + }, +}; + +/* parameters for rte_flow_classify_validate and rte_flow_classify_create */ + +/* test UDP pattern: + * "eth / ipv4 src spec 2.2.2.3 src mask 255.255.255.00 dst spec 2.2.2.7 + * dst mask 255.255.255.00 / udp src is 32 dst is 33 / end" + */ +static struct rte_flow_item_ipv4 ipv4_udp_spec_1 = { + { 0, 0, 0, 0, 0, 0, IPPROTO_UDP, 0, IPv4(2, 2, 2, 3), IPv4(2, 2, 2, 7)} +}; +static const struct rte_flow_item_ipv4 ipv4_mask_24 = { + .hdr = { + .next_proto_id = 0xff, + .src_addr = 0xffffff00, + .dst_addr = 0xffffff00, + }, +}; +static struct rte_flow_item_udp udp_spec_1 = { + { 32, 33, 0, 0 } +}; + +static struct rte_flow_item eth_item = { RTE_FLOW_ITEM_TYPE_ETH, + 0, 0, 0 }; +static struct rte_flow_item eth_item_bad = { -1, 0, 0, 0 }; + +static struct rte_flow_item ipv4_udp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, + &ipv4_udp_spec_1, 0, &ipv4_mask_24}; +static struct rte_flow_item ipv4_udp_item_bad = { RTE_FLOW_ITEM_TYPE_IPV4, + NULL, 0, NULL}; + +static struct rte_flow_item udp_item_1 = { RTE_FLOW_ITEM_TYPE_UDP, + &udp_spec_1, 0, &rte_flow_item_udp_mask}; +static struct rte_flow_item udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP, + NULL, 0, NULL}; + +static struct rte_flow_item end_item = { RTE_FLOW_ITEM_TYPE_END, + 0, 0, 0 }; +static struct rte_flow_item end_item_bad = { -1, 0, 0, 0 }; + +/* test TCP pattern: + * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8 + * dst mask 255.255.255.00 / tcp src is 16 dst is 17 / end" + */ +static struct rte_flow_item_ipv4 ipv4_tcp_spec_1 = { + { 0, 0, 0, 0, 0, 0, IPPROTO_TCP, 0, IPv4(1, 2, 3, 4), IPv4(5, 6, 7, 8)} +}; + +static struct rte_flow_item_tcp tcp_spec_1 = { + { 16, 17, 0, 0, 0, 0, 0, 0, 0} +}; + +static struct rte_flow_item ipv4_tcp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, + &ipv4_tcp_spec_1, 0, &ipv4_mask_24}; + +static struct rte_flow_item tcp_item_1 = { RTE_FLOW_ITEM_TYPE_TCP, + &tcp_spec_1, 0, &rte_flow_item_tcp_mask}; + +/* test SCTP pattern: + * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8 + * dst mask 255.255.255.00 / sctp src is 16 dst is 17/ end" + */ +static struct rte_flow_item_ipv4 ipv4_sctp_spec_1 = { + { 0, 0, 0, 0, 0, 0, IPPROTO_SCTP, 0, IPv4(11, 12, 13, 14), + IPv4(15, 16, 17, 18)} +}; + +static struct rte_flow_item_sctp sctp_spec_1 = { + { 10, 11, 0, 0} +}; + +static struct rte_flow_item ipv4_sctp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, + &ipv4_sctp_spec_1, 0, &ipv4_mask_24}; + +static struct rte_flow_item sctp_item_1 = { RTE_FLOW_ITEM_TYPE_SCTP, + &sctp_spec_1, 0, &rte_flow_item_sctp_mask}; + + +/* test actions: + * "actions count / end" + */ +static struct rte_flow_query_count count = { + .reset = 1, + .hits_set = 1, + .bytes_set = 1, + .hits = 0, + .bytes = 0, +}; +static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT, + &count}; +static struct rte_flow_action count_action_bad = { -1, 0}; + +static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0}; +static struct rte_flow_action end_action_bad = { -1, 0}; + +static struct rte_flow_action actions[2]; + +/* test attributes */ +static struct rte_flow_attr attr; + +/* test error */ +static struct rte_flow_error error; + +/* test pattern */ +static struct rte_flow_item pattern[4]; + +/* flow classify data for UDP burst */ +static struct rte_flow_classify_ipv4_5tuple_stats udp_ntuple_stats; +static struct rte_flow_classify_stats udp_classify_stats = { + .stats = (void *)&udp_ntuple_stats +}; + +/* flow classify data for TCP burst */ +static struct rte_flow_classify_ipv4_5tuple_stats tcp_ntuple_stats; +static struct rte_flow_classify_stats tcp_classify_stats = { + .stats = (void *)&tcp_ntuple_stats +}; + +/* flow classify data for SCTP burst */ +static struct rte_flow_classify_ipv4_5tuple_stats sctp_ntuple_stats; +static struct rte_flow_classify_stats sctp_classify_stats = { + .stats = (void *)&sctp_ntuple_stats +}; + +struct flow_classifier_acl *cls; + +struct flow_classifier_acl { + struct rte_flow_classifier *cls; +} __rte_cache_aligned; + +/* + * test functions by passing invalid or + * non-workable parameters. + */ +static int +test_invalid_parameters(void) +{ + struct rte_flow_classify_rule *rule; + int ret; + + ret = rte_flow_classify_validate(NULL, NULL, NULL, NULL, NULL); + if (!ret) { + printf("Line %i: rte_flow_classify_validate", + __LINE__); + printf(" with NULL param should have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL, + NULL, NULL); + if (rule) { + printf("Line %i: flow_classifier_table_entry_add", __LINE__); + printf(" with NULL param should have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(NULL, NULL); + if (!ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf(" with NULL param should have failed!\n"); + return -1; + } + + ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL); + if (!ret) { + printf("Line %i: flow_classifier_query", __LINE__); + printf(" with NULL param should have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL, + NULL, &error); + if (rule) { + printf("Line %i: flow_classify_table_entry_add ", __LINE__); + printf("with NULL param should have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(NULL, NULL); + if (!ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf("with NULL param should have failed!\n"); + return -1; + } + + ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL); + if (!ret) { + printf("Line %i: flow_classifier_query", __LINE__); + printf(" with NULL param should have failed!\n"); + return -1; + } + return 0; +} + +static int +test_valid_parameters(void) +{ + struct rte_flow_classify_rule *rule; + int ret; + int key_found; + + /* + * set up parameters for rte_flow_classify_validate, + * rte_flow_classify_table_entry_add and + * rte_flow_classify_table_entry_delete + */ + + attr.ingress = 1; + attr.priority = 1; + pattern[0] = eth_item; + pattern[1] = ipv4_udp_item_1; + pattern[2] = udp_item_1; + pattern[3] = end_item; + actions[0] = count_action; + actions[1] = end_action; + + ret = rte_flow_classify_validate(cls->cls, &attr, pattern, + actions, &error); + if (ret) { + printf("Line %i: rte_flow_classify_validate", + __LINE__); + printf(" should not have failed!\n"); + return -1; + } + rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, + actions, &key_found, &error); + + if (!rule) { + printf("Line %i: flow_classify_table_entry_add", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(cls->cls, rule); + if (ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf(" should not have failed!\n"); + return -1; + } + return 0; +} + +static int +test_invalid_patterns(void) +{ + struct rte_flow_classify_rule *rule; + int ret; + int key_found; + + /* + * set up parameters for rte_flow_classify_validate, + * rte_flow_classify_table_entry_add and + * rte_flow_classify_table_entry_delete + */ + + attr.ingress = 1; + attr.priority = 1; + pattern[0] = eth_item_bad; + pattern[1] = ipv4_udp_item_1; + pattern[2] = udp_item_1; + pattern[3] = end_item; + actions[0] = count_action; + actions[1] = end_action; + + pattern[0] = eth_item; + pattern[1] = ipv4_udp_item_bad; + + ret = rte_flow_classify_validate(cls->cls, &attr, pattern, + actions, &error); + if (!ret) { + printf("Line %i: rte_flow_classify_validate", __LINE__); + printf(" should have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, + actions, &key_found, &error); + if (rule) { + printf("Line %i: flow_classify_table_entry_add", __LINE__); + printf(" should have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(cls->cls, rule); + if (!ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf(" should have failed!\n"); + return -1; + } + + pattern[1] = ipv4_udp_item_1; + pattern[2] = udp_item_bad; + pattern[3] = end_item_bad; + + ret = rte_flow_classify_validate(cls->cls, &attr, pattern, + actions, &error); + if (!ret) { + printf("Line %i: rte_flow_classify_validate", __LINE__); + printf(" should have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, + actions, &key_found, &error); + if (rule) { + printf("Line %i: flow_classify_table_entry_add", __LINE__); + printf(" should have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(cls->cls, rule); + if (!ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf(" should have failed!\n"); + return -1; + } + return 0; +} + +static int +test_invalid_actions(void) +{ + struct rte_flow_classify_rule *rule; + int ret; + int key_found; + + /* + * set up parameters for rte_flow_classify_validate, + * rte_flow_classify_table_entry_add and + * rte_flow_classify_table_entry_delete + */ + + attr.ingress = 1; + attr.priority = 1; + pattern[0] = eth_item; + pattern[1] = ipv4_udp_item_1; + pattern[2] = udp_item_1; + pattern[3] = end_item; + actions[0] = count_action_bad; + actions[1] = end_action; + + ret = rte_flow_classify_validate(cls->cls, &attr, pattern, + actions, &error); + if (!ret) { + printf("Line %i: rte_flow_classify_validate", __LINE__); + printf(" should have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, + actions, &key_found, &error); + if (rule) { + printf("Line %i: flow_classify_table_entry_add", __LINE__); + printf(" should have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(cls->cls, rule); + if (!ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf(" should have failed!\n"); + return -1; + } + + actions[0] = count_action; + actions[1] = end_action_bad; + + ret = rte_flow_classify_validate(cls->cls, &attr, pattern, + actions, &error); + if (!ret) { + printf("Line %i: rte_flow_classify_validate", __LINE__); + printf(" should have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, + actions, &key_found, &error); + if (rule) { + printf("Line %i: flow_classify_table_entry_add", __LINE__); + printf(" should have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(cls->cls, rule); + if (!ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf("should have failed!\n"); + return -1; + } + return 0; +} + +static int +init_ipv4_udp_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 src_addr = IPV4_ADDR(2, 2, 2, 3); + uint32_t dst_addr = IPV4_ADDR(2, 2, 2, 7); + uint16_t src_port = 32; + uint16_t dst_port = 33; + uint16_t pktlen; + + static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; + static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; + + printf("Set up IPv4 UDP traffic\n"); + initialize_eth_header(&pkt_eth_hdr, + (struct ether_addr *)src_mac, + (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0); + pktlen = (uint16_t)(sizeof(struct ether_hdr)); + printf("ETH pktlen %u\n", pktlen); + + pktlen = initialize_ipv4_header(&pkt_ipv4_hdr, src_addr, dst_addr, + pktlen); + printf("ETH + IPv4 pktlen %u\n", pktlen); + + pktlen = initialize_udp_header(&pkt_udp_hdr, src_port, dst_port, + pktlen); + printf("ETH + IPv4 + UDP pktlen %u\n\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_ipv4_tcp_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 tcp_hdr pkt_tcp_hdr; + uint32_t src_addr = IPV4_ADDR(1, 2, 3, 4); + uint32_t dst_addr = IPV4_ADDR(5, 6, 7, 8); + uint16_t src_port = 16; + uint16_t dst_port = 17; + uint16_t pktlen; + + static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; + static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; + + printf("Set up IPv4 TCP traffic\n"); + initialize_eth_header(&pkt_eth_hdr, + (struct ether_addr *)src_mac, + (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0); + pktlen = (uint16_t)(sizeof(struct ether_hdr)); + printf("ETH pktlen %u\n", pktlen); + + pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr, + dst_addr, pktlen, IPPROTO_TCP); + printf("ETH + IPv4 pktlen %u\n", pktlen); + + pktlen = initialize_tcp_header(&pkt_tcp_hdr, src_port, dst_port, + pktlen); + printf("ETH + IPv4 + TCP pktlen %u\n\n", pktlen); + + return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr, + 0, &pkt_ipv4_hdr, 1, IPPROTO_TCP, + &pkt_tcp_hdr, burst_size, + PACKET_BURST_GEN_PKT_LEN, 1); +} + +static int +init_ipv4_sctp_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 sctp_hdr pkt_sctp_hdr; + uint32_t src_addr = IPV4_ADDR(11, 12, 13, 14); + uint32_t dst_addr = IPV4_ADDR(15, 16, 17, 18); + uint16_t src_port = 10; + uint16_t dst_port = 11; + uint16_t pktlen; + + static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; + static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; + + printf("Set up IPv4 SCTP traffic\n"); + initialize_eth_header(&pkt_eth_hdr, + (struct ether_addr *)src_mac, + (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0); + pktlen = (uint16_t)(sizeof(struct ether_hdr)); + printf("ETH pktlen %u\n", pktlen); + + pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr, + dst_addr, pktlen, IPPROTO_SCTP); + printf("ETH + IPv4 pktlen %u\n", pktlen); + + pktlen = initialize_sctp_header(&pkt_sctp_hdr, src_port, dst_port, + pktlen); + printf("ETH + IPv4 + SCTP pktlen %u\n\n", pktlen); + + return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr, + 0, &pkt_ipv4_hdr, 1, IPPROTO_SCTP, + &pkt_sctp_hdr, burst_size, + PACKET_BURST_GEN_PKT_LEN, 1); +} + +static int +init_mbufpool(void) +{ + int socketid; + int ret = 0; + unsigned int 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) { + printf( + "Socket %d of lcore %u is out of range %d\n", + socketid, lcore_id, NB_SOCKETS); + ret = -1; + break; + } + 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, MBUF_SIZE, + socketid); + if (mbufpool[socketid]) { + printf("Allocated mbuf pool on socket %d\n", + socketid); + } else { + printf("Cannot init mbuf pool on socket %d\n", + socketid); + ret = -ENOMEM; + break; + } + } + } + return ret; +} + +static int +test_query_udp(void) +{ + struct rte_flow_error error; + struct rte_flow_classify_rule *rule; + int ret; + int i; + int key_found; + + ret = init_ipv4_udp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); + if (ret != MAX_PKT_BURST) { + printf("Line %i: init_udp_ipv4_traffic has failed!\n", + __LINE__); + return -1; + } + + for (i = 0; i < MAX_PKT_BURST; i++) + bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; + + /* + * set up parameters for rte_flow_classify_validate, + * rte_flow_classify_table_entry_add and + * rte_flow_classify_table_entry_delete + */ + + attr.ingress = 1; + attr.priority = 1; + pattern[0] = eth_item; + pattern[1] = ipv4_udp_item_1; + pattern[2] = udp_item_1; + pattern[3] = end_item; + actions[0] = count_action; + actions[1] = end_action; + + ret = rte_flow_classify_validate(cls->cls, &attr, pattern, + actions, &error); + if (ret) { + printf("Line %i: rte_flow_classify_validate", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, + actions, &key_found, &error); + if (!rule) { + printf("Line %i: flow_classify_table_entry_add", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, + rule, &udp_classify_stats); + if (ret) { + printf("Line %i: flow_classifier_query", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(cls->cls, rule); + if (ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf(" should not have failed!\n"); + return -1; + } + return 0; +} + +static int +test_query_tcp(void) +{ + struct rte_flow_classify_rule *rule; + int ret; + int i; + int key_found; + + ret = init_ipv4_tcp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); + if (ret != MAX_PKT_BURST) { + printf("Line %i: init_ipv4_tcp_traffic has failed!\n", + __LINE__); + return -1; + } + + for (i = 0; i < MAX_PKT_BURST; i++) + bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; + + /* + * set up parameters for rte_flow_classify_validate, + * rte_flow_classify_table_entry_add and + * rte_flow_classify_table_entry_delete + */ + + attr.ingress = 1; + attr.priority = 1; + pattern[0] = eth_item; + pattern[1] = ipv4_tcp_item_1; + pattern[2] = tcp_item_1; + pattern[3] = end_item; + actions[0] = count_action; + actions[1] = end_action; + + ret = rte_flow_classify_validate(cls->cls, &attr, pattern, + actions, &error); + if (ret) { + printf("Line %i: flow_classifier_query", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, + actions, &key_found, &error); + if (!rule) { + printf("Line %i: flow_classify_table_entry_add", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, + rule, &tcp_classify_stats); + if (ret) { + printf("Line %i: flow_classifier_query", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(cls->cls, rule); + if (ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf(" should not have failed!\n"); + return -1; + } + return 0; +} + +static int +test_query_sctp(void) +{ + struct rte_flow_classify_rule *rule; + int ret; + int i; + int key_found; + + ret = init_ipv4_sctp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); + if (ret != MAX_PKT_BURST) { + printf("Line %i: init_ipv4_tcp_traffic has failed!\n", + __LINE__); + return -1; + } + + for (i = 0; i < MAX_PKT_BURST; i++) + bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; + + /* + * set up parameters rte_flow_classify_validate, + * rte_flow_classify_table_entry_add and + * rte_flow_classify_table_entry_delete + */ + + attr.ingress = 1; + attr.priority = 1; + pattern[0] = eth_item; + pattern[1] = ipv4_sctp_item_1; + pattern[2] = sctp_item_1; + pattern[3] = end_item; + actions[0] = count_action; + actions[1] = end_action; + + ret = rte_flow_classify_validate(cls->cls, &attr, pattern, + actions, &error); + if (ret) { + printf("Line %i: flow_classifier_query", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, + actions, &key_found, &error); + if (!rule) { + printf("Line %i: flow_classify_table_entry_add", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, + rule, &sctp_classify_stats); + if (ret) { + printf("Line %i: flow_classifier_query", __LINE__); + printf(" should not have failed!\n"); + return -1; + } + + ret = rte_flow_classify_table_entry_delete(cls->cls, rule); + if (ret) { + printf("Line %i: rte_flow_classify_table_entry_delete", + __LINE__); + printf(" should not have failed!\n"); + return -1; + } + return 0; +} + +static int +test_flow_classify(void) +{ + struct rte_table_acl_params table_acl_params; + struct rte_flow_classify_table_params cls_table_params; + struct rte_flow_classifier_params cls_params; + int ret; + uint32_t size; + + /* Memory allocation */ + size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct flow_classifier_acl)); + cls = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE); + + cls_params.name = "flow_classifier"; + cls_params.socket_id = 0; + cls->cls = rte_flow_classifier_create(&cls_params); + + /* initialise ACL table params */ + table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs); + table_acl_params.name = "table_acl_ipv4_5tuple"; + table_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM; + memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs)); + + /* initialise table create params */ + cls_table_params.ops = &rte_table_acl_ops; + cls_table_params.arg_create = &table_acl_params; + cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE; + + ret = rte_flow_classify_table_create(cls->cls, &cls_table_params); + if (ret) { + printf("Line %i: f_create has failed!\n", __LINE__); + rte_flow_classifier_free(cls->cls); + rte_free(cls); + return TEST_FAILED; + } + printf("Created table_acl for for IPv4 five tuple packets\n"); + + ret = init_mbufpool(); + if (ret) { + printf("Line %i: init_mbufpool has failed!\n", __LINE__); + return TEST_FAILED; + } + + if (test_invalid_parameters() < 0) + return TEST_FAILED; + if (test_valid_parameters() < 0) + return TEST_FAILED; + if (test_invalid_patterns() < 0) + return TEST_FAILED; + if (test_invalid_actions() < 0) + return TEST_FAILED; + if (test_query_udp() < 0) + return TEST_FAILED; + if (test_query_tcp() < 0) + return TEST_FAILED; + if (test_query_sctp() < 0) + return TEST_FAILED; + + return TEST_SUCCESS; +} + +REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify); diff --git a/app/test/test_flow_classify.h b/app/test/test_flow_classify.h new file mode 100644 index 0000000000..6bd10ec972 --- /dev/null +++ b/app/test/test_flow_classify.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Intel Corporation + */ + +#ifndef TEST_FLOW_CLASSIFY_H_ +#define TEST_FLOW_CLASSIFY_H_ + +/* ACL field definitions for IPv4 5 tuple rule */ + +enum { + PROTO_FIELD_IPV4, + SRC_FIELD_IPV4, + DST_FIELD_IPV4, + SRCP_FIELD_IPV4, + DSTP_FIELD_IPV4, + NUM_FIELDS_IPV4 +}; + +enum { + PROTO_INPUT_IPV4, + SRC_INPUT_IPV4, + DST_INPUT_IPV4, + SRCP_DESTP_INPUT_IPV4 +}; + +#endif /* TEST_FLOW_CLASSIFY_H_ */ diff --git a/app/test/test_func_reentrancy.c b/app/test/test_func_reentrancy.c new file mode 100644 index 0000000000..e27d1e020f --- /dev/null +++ b/app/test/test_func_reentrancy.c @@ -0,0 +1,498 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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_MULTI (16) +#define MAX_ITER_ONCE (4) +#define MAX_LPM_ITER_TIMES (6) + +#define MEMPOOL_ELT_SIZE (sizeof(uint32_t)) +#define MEMPOOL_SIZE (4) + +#define MAX_LCORES (RTE_MAX_MEMZONE / (MAX_ITER_MULTI * 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 void +ring_clean(unsigned int lcore_id) +{ + struct rte_ring *rp; + char ring_name[MAX_STRING_SIZE]; + int i; + + for (i = 0; i < MAX_ITER_MULTI; i++) { + snprintf(ring_name, sizeof(ring_name), + "fr_test_%d_%d", lcore_id, i); + rp = rte_ring_lookup(ring_name); + if (rp != NULL) + rte_ring_free(rp); + } +} + +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_ONCE; 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_MULTI; 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 successful */ + 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 void +mempool_clean(unsigned int lcore_id) +{ + struct rte_mempool *mp; + char mempool_name[MAX_STRING_SIZE]; + int i; + + /* verify all ring created successful */ + for (i = 0; i < MAX_ITER_MULTI; i++) { + snprintf(mempool_name, sizeof(mempool_name), "fr_test_%d_%d", + lcore_id, i); + mp = rte_mempool_lookup(mempool_name); + if (mp != NULL) + rte_mempool_free(mp); + } +} + +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_ONCE; 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_MULTI; 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 successful */ + 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_MULTI; 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_ONCE; 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_MULTI; 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 */ + 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_MULTI; 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_ONCE; 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_MULTI; 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 */ + 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 int 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_ONCE; 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 */ + 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, ring_clean, "ring create/lookup" }, + { mempool_create_lookup, NULL, mempool_clean, + "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 new file mode 100644 index 0000000000..fe607fadf2 --- /dev/null +++ b/app/test/test_hash.c @@ -0,0 +1,1778 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2015 Intel Corporation + */ + +#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; +} + +#define UNIT_TEST_HASH_VERBOSE 0 +/* + * Print out result of unit test hash operation. + */ +static void print_key_info(const char *msg, const struct flow_key *key, + int32_t pos) +{ + if (UNIT_TEST_HASH_VERBOSE) { + 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(" @ pos %d\n", pos); + } +} + +/* 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) + * + * Repeat the test case when 'free on delete' is disabled. + * - add + * - lookup (hit) + * - delete + * - lookup (miss) + * - free + */ +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, delPos1; + + ut_params.extra_flag = RTE_HASH_EXTRA_FLAGS_NO_FREE_ON_DEL; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + ut_params.extra_flag = 0; + + 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); + delPos1 = 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); + + pos1 = rte_hash_free_key_with_position(handle, delPos1); + print_key_info("Free", &keys[0], delPos1); + RETURN_IF_ERROR(pos1 != 0, + "failed to free key (pos1=%d)", delPos1); + + 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 a single key with 'disable free on del' set: + * - delete: miss + * - add + * - lookup: hit + * - add: update + * - lookup: hit (updated data) + * - delete: hit + * - delete: miss + * - lookup: miss + * - free: hit + * - lookup: miss + */ +static int test_add_update_delete_free(void) +{ + struct rte_hash *handle; + int pos0, expectedPos0, delPos0, result; + + ut_params.name = "test2"; + ut_params.extra_flag = RTE_HASH_EXTRA_FLAGS_NO_FREE_ON_DEL; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + ut_params.extra_flag = 0; + + 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); + + delPos0 = rte_hash_del_key(handle, &keys[0]); + print_key_info("Del", &keys[0], delPos0); + RETURN_IF_ERROR(delPos0 != expectedPos0, + "failed to delete key (pos0=%d)", delPos0); + + 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); + + result = rte_hash_free_key_with_position(handle, delPos0); + print_key_info("Free", &keys[0], delPos0); + RETURN_IF_ERROR(result != 0, + "failed to free key (pos1=%d)", delPos0); + + 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 + * + * Repeat the test case when 'free on delete' is disabled. + * - create table + * - add key + * - get the key with its position: hit + * - delete key + * - try to get the deleted key: hit + * - free 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, delPos, 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); + + ut_params.name = "hash_get_key_w_pos"; + ut_params.extra_flag = RTE_HASH_EXTRA_FLAGS_NO_FREE_ON_DEL; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + ut_params.extra_flag = 0; + + 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"); + + delPos = rte_hash_del_key(handle, &keys[0]); + print_key_info("Del", &keys[0], delPos); + RETURN_IF_ERROR(delPos != expectedPos, + "failed to delete key (pos0=%d)", delPos); + + result = rte_hash_get_key_with_position(handle, delPos, &key); + RETURN_IF_ERROR(result != -ENOENT, "non valid key retrieved"); + + result = rte_hash_free_key_with_position(handle, delPos); + print_key_info("Free", &keys[0], delPos); + RETURN_IF_ERROR(result != 0, + "failed to free key (pos1=%d)", delPos); + + result = rte_hash_get_key_with_position(handle, delPos, &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; +} + +/* + * Similar to the test above (full bucket test), but for extendable buckets. + */ +static int test_extendable_bucket(void) +{ + struct rte_hash_parameters params_pseudo_hash = { + .name = "test5", + .entries = 64, + .key_len = sizeof(struct flow_key), /* 13 */ + .hash_func = pseudo_hash, + .hash_func_init_val = 0, + .socket_id = 0, + .extra_flag = RTE_HASH_EXTRA_FLAGS_EXT_TABLE + }; + struct rte_hash *handle; + int pos[64]; + int expected_pos[64]; + unsigned int i; + struct flow_key rand_keys[64]; + + for (i = 0; i < 64; i++) { + rand_keys[i].port_dst = i; + rand_keys[i].port_src = i+1; + } + + handle = rte_hash_create(¶ms_pseudo_hash); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + /* Fill bucket */ + for (i = 0; i < 64; i++) { + pos[i] = rte_hash_add_key(handle, &rand_keys[i]); + print_key_info("Add", &rand_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 < 64; i++) { + pos[i] = rte_hash_lookup(handle, &rand_keys[i]); + print_key_info("Lkp", &rand_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 < 64; i++) { + pos[i] = rte_hash_add_key(handle, &rand_keys[i]); + print_key_info("Add", &rand_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 < 64; i++) { + pos[i] = rte_hash_lookup(handle, &rand_keys[i]); + print_key_info("Lkp", &rand_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[35] = rte_hash_del_key(handle, &rand_keys[35]); + print_key_info("Del", &rand_keys[35], pos[35]); + RETURN_IF_ERROR(pos[35] != expected_pos[35], + "failed to delete key (pos[1]=%d)", pos[35]); + pos[20] = rte_hash_lookup(handle, &rand_keys[20]); + print_key_info("Lkp", &rand_keys[20], pos[20]); + RETURN_IF_ERROR(pos[20] != expected_pos[20], + "failed lookup after deleting key from same bucket " + "(pos[20]=%d)", pos[20]); + + /* Go back to previous state */ + pos[35] = rte_hash_add_key(handle, &rand_keys[35]); + print_key_info("Add", &rand_keys[35], pos[35]); + expected_pos[35] = pos[35]; + RETURN_IF_ERROR(pos[35] < 0, "failed to add key (pos[1]=%d)", pos[35]); + + /* Delete */ + for (i = 0; i < 64; i++) { + pos[i] = rte_hash_del_key(handle, &rand_keys[i]); + print_key_info("Del", &rand_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 < 64; i++) { + pos[i] = rte_hash_lookup(handle, &rand_keys[i]); + print_key_info("Lkp", &rand_keys[i], pos[i]); + RETURN_IF_ERROR(pos[i] != -ENOENT, + "fail: found non-existent key (pos[%u]=%d)", i, pos[i]); + } + + /* Add again */ + for (i = 0; i < 64; i++) { + pos[i] = rte_hash_add_key(handle, &rand_keys[i]); + print_key_info("Add", &rand_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]; + } + + 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 successfully 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 successfully 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 successfully 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 successfully 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 successfully 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(uint32_t ext_table) +{ + struct rte_hash *handle; + uint8_t simple_key[MAX_KEYSIZE]; + unsigned i, j; + unsigned added_keys, average_keys_added = 0; + int ret; + unsigned int cnt; + + printf("\n# Running test to determine average utilization" + "\n before adding elements begins to fail\n"); + if (ext_table) + printf("ext table is enabled\n"); + else + printf("ext table is disabled\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; + if (ext_table) + ut_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE; + else + ut_params.extra_flag &= ~RTE_HASH_EXTRA_FLAGS_EXT_TABLE; + + 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 < 0) + break; + } + + if (ret != -ENOSPC) { + printf("Unexpected error when adding keys\n"); + rte_hash_free(handle); + return -1; + } + + cnt = rte_hash_count(handle); + if (cnt != added_keys) { + printf("rte_hash_count returned wrong value %u, %u," + "%u\n", j, added_keys, cnt); + rte_hash_free(handle); + return -1; + } + if (ext_table) { + if (cnt != ut_params.entries) { + printf("rte_hash_count returned wrong value " + "%u, %u, %u\n", j, added_keys, cnt); + 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(uint32_t ext_table) +{ + 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; + if (ext_table) + ut_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE; + else + ut_params.extra_flag &= ~RTE_HASH_EXTRA_FLAGS_EXT_TABLE; + + 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) { + if (ext_table) { + printf("Insertion failed for ext table\n"); + goto err; + } + 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_add_update_delete_free() < 0) + return -1; + if (test_five_keys() < 0) + return -1; + if (test_full_bucket() < 0) + return -1; + if (test_extendable_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; + + /* ext table disabled */ + if (test_average_table_utilization(0) < 0) + return -1; + if (test_hash_iteration(0) < 0) + return -1; + + /* ext table enabled */ + if (test_average_table_utilization(1) < 0) + return -1; + if (test_hash_iteration(1) < 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 new file mode 100644 index 0000000000..c1fc9492d5 --- /dev/null +++ b/app/test/test_hash_functions.c @@ -0,0 +1,293 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2015 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..50018db56c --- /dev/null +++ b/app/test/test_hash_multiwriter.c @@ -0,0 +1,294 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 Intel Corporation + */ + +#include +#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 = 5*1024*1024; +const uint32_t nb_total_tsx_insertion = 4.5*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(void *arg) +{ + uint64_t i, offset; + uint16_t pos_core; + uint32_t lcore_id = rte_lcore_id(); + uint64_t begin, cycles; + uint16_t *enabled_core_ids = (uint16_t *)arg; + + for (pos_core = 0; pos_core < rte_lcore_count(); pos_core++) { + if (enabled_core_ids[pos_core] == lcore_id) + break; + } + + /* + * Calculate offset for entries based on the position of the + * logical core, from the master core (not counting not enabled cores) + */ + offset = pos_core * 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 - 1); + + 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; + uint16_t enabled_core_ids[RTE_MAX_LCORE]; + uint16_t core_id; + + uint32_t *keys; + uint32_t *found; + + struct rte_hash_parameters hash_params = { + .entries = nb_entries, + .key_len = sizeof(uint32_t), + .hash_func = rte_jhash, + .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; + uint32_t count; + + 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; + } + + for (i = 0; i < nb_entries; i++) + keys[i] = i; + + tbl_multiwriter_test_params.keys = keys; + + found = rte_zmalloc(NULL, sizeof(uint32_t) * nb_entries, 0); + if (found == NULL) { + printf("RTE_ZMALLOC failed\n"); + goto err2; + } + + tbl_multiwriter_test_params.found = found; + + rte_atomic64_init(&gcycles); + rte_atomic64_clear(&gcycles); + + rte_atomic64_init(&ginsertions); + rte_atomic64_clear(&ginsertions); + + /* Get list of enabled cores */ + i = 0; + for (core_id = 0; core_id < RTE_MAX_LCORE; core_id++) { + if (i == rte_lcore_count()) + break; + + if (rte_lcore_is_enabled(core_id)) { + enabled_core_ids[i] = core_id; + i++; + } + } + + if (i != rte_lcore_count()) { + printf("Number of enabled cores in list is different from " + "number given by rte_lcore_count()\n"); + goto err3; + } + + /* Fire all threads. */ + rte_eal_mp_remote_launch(test_hash_multiwriter_worker, + enabled_core_ids, CALL_MASTER); + rte_eal_mp_wait_lcore(); + + count = rte_hash_count(handle); + if (count != rounded_nb_total_tsx_insertion) { + printf("rte_hash_count returned wrong value %u, %d\n", + rounded_nb_total_tsx_insertion, count); + goto err3; + } + + 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 new file mode 100644 index 0000000000..5252111803 --- /dev/null +++ b/app/test/test_hash_perf.c @@ -0,0 +1,699 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2015 Intel Corporation + */ + +#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) +#define ADD_PERCENT 0.75 /* 75% table utilization */ +#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ +/* BUCKET_SIZE should be same as RTE_HASH_BUCKET_ENTRIES in rte_hash library */ +#define BUCKET_SIZE 8 +#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 int with_data, unsigned int table_index, + unsigned int with_locks, unsigned int ext) +{ + 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]); + + + if (with_locks) + ut_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT + | RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY; + else + ut_params.extra_flag = 0; + + if (ext) + ut_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE; + + 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 int table_index, unsigned int ext) +{ + unsigned i; + uint32_t swap_idx; + uint8_t temp_key[MAX_KEYSIZE]; + hash_sig_t temp_signature; + int32_t temp_position; + unsigned int keys_to_add; + + if (!ext) + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + else + keys_to_add = KEYS_TO_ADD; + + 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 int with_pushes, unsigned int table_index, + unsigned int ext) +{ + unsigned i, j; + unsigned bucket_idx, incr, success = 1; + uint8_t k = 0; + int32_t ret; + const uint32_t bucket_bitmask = NUM_BUCKETS - 1; + unsigned int keys_to_add; + + if (!ext) + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + else + keys_to_add = KEYS_TO_ADD; + /* 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 int with_hash, unsigned int with_data, + unsigned int table_index, unsigned int ext) +{ + unsigned i; + const uint64_t start_tsc = rte_rdtsc(); + void *data; + int32_t ret; + unsigned int keys_to_add; + if (!ext) + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + else + keys_to_add = KEYS_TO_ADD; + + 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("H+D: Failed to add key number %u\n", i); + 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("H: Failed to add key number %u\n", i); + 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("D: Failed to add key number %u\n", i); + 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", i); + 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 int with_hash, unsigned int with_data, + unsigned int table_index, unsigned int ext) +{ + unsigned i, j; + const uint64_t start_tsc = rte_rdtsc(); + void *ret_data; + void *expected_data; + int32_t ret; + unsigned int keys_to_add, num_lookups; + + if (!ext) { + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + num_lookups = NUM_LOOKUPS * ADD_PERCENT; + } else { + keys_to_add = KEYS_TO_ADD; + num_lookups = NUM_LOOKUPS; + } + 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 int with_data, unsigned int table_index, + unsigned int ext) +{ + 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; + unsigned int keys_to_add, num_lookups; + + if (!ext) { + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + num_lookups = NUM_LOOKUPS * ADD_PERCENT; + } else { + keys_to_add = KEYS_TO_ADD; + num_lookups = NUM_LOOKUPS; + } + + 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 int with_hash, unsigned int with_data, + unsigned int table_index, unsigned int ext) +{ + unsigned i; + const uint64_t start_tsc = rte_rdtsc(); + int32_t ret; + unsigned int keys_to_add; + if (!ext) + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + else + keys_to_add = KEYS_TO_ADD; + + 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 delete key number %u\n", i); + 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 int with_pushes, unsigned int with_locks, + unsigned int ext) +{ + 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, with_locks, ext) < 0) + return -1; + + if (get_input_keys(with_pushes, i, ext) < 0) + return -1; + for (with_hash = 0; with_hash <= 1; with_hash++) { + if (timed_adds(with_hash, with_data, i, ext) < 0) + return -1; + + for (j = 0; j < NUM_SHUFFLES; j++) + shuffle_input_keys(i, ext); + + if (timed_lookups(with_hash, with_data, i, ext) < 0) + return -1; + + if (timed_lookups_multi(with_data, i, ext) < 0) + return -1; + + if (timed_deletes(with_hash, with_data, i, ext) < 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 int with_pushes, with_locks; + for (with_locks = 0; with_locks <= 1; with_locks++) { + if (with_locks) + printf("\nWith locks in the code\n"); + else + printf("\nWithout locks in the code\n"); + 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, with_locks, 0) < 0) + return -1; + } + } + + printf("\n EXTENDABLE BUCKETS PERFORMANCE\n"); + + if (run_all_tbl_perf_tests(1, 0, 1) < 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_readwrite.c b/app/test/test_hash_readwrite.c new file mode 100644 index 0000000000..480ae97d85 --- /dev/null +++ b/app/test/test_hash_readwrite.c @@ -0,0 +1,709 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define RTE_RWTEST_FAIL 0 + +#define TOTAL_ENTRY (5*1024*1024) +#define TOTAL_INSERT (4.5*1024*1024) +#define TOTAL_INSERT_EXT (5*1024*1024) + +#define NUM_TEST 3 +unsigned int core_cnt[NUM_TEST] = {2, 4, 8}; + +unsigned int slave_core_ids[RTE_MAX_LCORE]; +struct perf { + uint32_t single_read; + uint32_t single_write; + uint32_t read_only[NUM_TEST]; + uint32_t write_only[NUM_TEST]; + uint32_t read_write_r[NUM_TEST]; + uint32_t read_write_w[NUM_TEST]; +}; + +static struct perf htm_results, non_htm_results; + +struct { + uint32_t *keys; + uint8_t *found; + uint32_t num_insert; + uint32_t rounded_tot_insert; + struct rte_hash *h; +} tbl_rw_test_param; + +static rte_atomic64_t gcycles; +static rte_atomic64_t ginsertions; + +static rte_atomic64_t gread_cycles; +static rte_atomic64_t gwrite_cycles; + +static rte_atomic64_t greads; +static rte_atomic64_t gwrites; + +static int +test_hash_readwrite_worker(__attribute__((unused)) void *arg) +{ + uint64_t i, offset; + uint32_t lcore_id = rte_lcore_id(); + uint64_t begin, cycles; + int *ret; + + ret = rte_malloc(NULL, sizeof(int) * + tbl_rw_test_param.num_insert, 0); + for (i = 0; i < rte_lcore_count(); i++) { + if (slave_core_ids[i] == lcore_id) + break; + } + offset = tbl_rw_test_param.num_insert * i; + + printf("Core #%d inserting and reading %d: %'"PRId64" - %'"PRId64"\n", + lcore_id, tbl_rw_test_param.num_insert, + offset, offset + tbl_rw_test_param.num_insert - 1); + + begin = rte_rdtsc_precise(); + + for (i = offset; i < offset + tbl_rw_test_param.num_insert; i++) { + + if (rte_hash_lookup(tbl_rw_test_param.h, + tbl_rw_test_param.keys + i) > 0) + break; + + ret[i - offset] = rte_hash_add_key(tbl_rw_test_param.h, + tbl_rw_test_param.keys + i); + if (ret[i - offset] < 0) + break; + + /* lookup a random key */ + uint32_t rand = rte_rand() % (i + 1 - offset); + + if (rte_hash_lookup(tbl_rw_test_param.h, + tbl_rw_test_param.keys + rand) != ret[rand]) + break; + + + if (rte_hash_del_key(tbl_rw_test_param.h, + tbl_rw_test_param.keys + rand) != ret[rand]) + break; + + ret[rand] = rte_hash_add_key(tbl_rw_test_param.h, + tbl_rw_test_param.keys + rand); + if (ret[rand] < 0) + break; + + if (rte_hash_lookup(tbl_rw_test_param.h, + tbl_rw_test_param.keys + rand) != ret[rand]) + break; + } + + cycles = rte_rdtsc_precise() - begin; + rte_atomic64_add(&gcycles, cycles); + rte_atomic64_add(&ginsertions, i - offset); + + for (; i < offset + tbl_rw_test_param.num_insert; i++) + tbl_rw_test_param.keys[i] = RTE_RWTEST_FAIL; + + rte_free(ret); + return 0; +} + +static int +init_params(int use_ext, int use_htm, int use_jhash) +{ + unsigned int i; + + uint32_t *keys = NULL; + uint8_t *found = NULL; + struct rte_hash *handle; + + struct rte_hash_parameters hash_params = { + .entries = TOTAL_ENTRY, + .key_len = sizeof(uint32_t), + .hash_func_init_val = 0, + .socket_id = rte_socket_id(), + }; + if (use_jhash) + hash_params.hash_func = rte_jhash; + else + hash_params.hash_func = rte_hash_crc; + + if (use_htm) + hash_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT | + RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | + RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; + else + hash_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | + RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; + + if (use_ext) + hash_params.extra_flag |= + RTE_HASH_EXTRA_FLAGS_EXT_TABLE; + else + hash_params.extra_flag &= + ~RTE_HASH_EXTRA_FLAGS_EXT_TABLE; + + hash_params.name = "tests"; + + handle = rte_hash_create(&hash_params); + if (handle == NULL) { + printf("hash creation failed"); + return -1; + } + + tbl_rw_test_param.h = handle; + keys = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_ENTRY, 0); + + if (keys == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + found = rte_zmalloc(NULL, sizeof(uint8_t) * TOTAL_ENTRY, 0); + if (found == NULL) { + printf("RTE_ZMALLOC failed\n"); + goto err; + } + + tbl_rw_test_param.keys = keys; + tbl_rw_test_param.found = found; + + for (i = 0; i < TOTAL_ENTRY; i++) + keys[i] = i; + + return 0; + +err: + rte_free(keys); + rte_hash_free(handle); + + return -1; +} + +static int +test_hash_readwrite_functional(int use_ext, int use_htm) +{ + unsigned int i; + const void *next_key; + void *next_data; + uint32_t iter = 0; + + uint32_t duplicated_keys = 0; + uint32_t lost_keys = 0; + int use_jhash = 1; + int slave_cnt = rte_lcore_count() - 1; + uint32_t tot_insert = 0; + + rte_atomic64_init(&gcycles); + rte_atomic64_clear(&gcycles); + + rte_atomic64_init(&ginsertions); + rte_atomic64_clear(&ginsertions); + + if (init_params(use_ext, use_htm, use_jhash) != 0) + goto err; + + if (use_ext) + tot_insert = TOTAL_INSERT_EXT; + else + tot_insert = TOTAL_INSERT; + + tbl_rw_test_param.num_insert = + tot_insert / slave_cnt; + + tbl_rw_test_param.rounded_tot_insert = + tbl_rw_test_param.num_insert + * slave_cnt; + + printf("++++++++Start function tests:+++++++++\n"); + + /* Fire all threads. */ + rte_eal_mp_remote_launch(test_hash_readwrite_worker, + NULL, SKIP_MASTER); + rte_eal_mp_wait_lcore(); + + while (rte_hash_iterate(tbl_rw_test_param.h, &next_key, + &next_data, &iter) >= 0) { + /* Search for the key in the list of keys added .*/ + i = *(const uint32_t *)next_key; + tbl_rw_test_param.found[i]++; + } + + for (i = 0; i < tbl_rw_test_param.rounded_tot_insert; i++) { + if (tbl_rw_test_param.keys[i] != RTE_RWTEST_FAIL) { + if (tbl_rw_test_param.found[i] > 1) { + duplicated_keys++; + break; + } + if (tbl_rw_test_param.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 err_free; + } + + if (lost_keys > 0) { + printf("%d key lost\n", lost_keys); + goto err_free; + } + + printf("No key corrupted during read-write test.\n"); + + unsigned long long int cycles_per_insertion = + rte_atomic64_read(&gcycles) / + rte_atomic64_read(&ginsertions); + + printf("cycles per insertion and lookup: %llu\n", cycles_per_insertion); + + rte_free(tbl_rw_test_param.found); + rte_free(tbl_rw_test_param.keys); + rte_hash_free(tbl_rw_test_param.h); + printf("+++++++++Complete function tests+++++++++\n"); + return 0; + +err_free: + rte_free(tbl_rw_test_param.found); + rte_free(tbl_rw_test_param.keys); + rte_hash_free(tbl_rw_test_param.h); +err: + return -1; +} + +static int +test_rw_reader(void *arg) +{ + uint64_t i; + uint64_t begin, cycles; + uint64_t read_cnt = (uint64_t)((uintptr_t)arg); + + begin = rte_rdtsc_precise(); + for (i = 0; i < read_cnt; i++) { + void *data; + rte_hash_lookup_data(tbl_rw_test_param.h, + tbl_rw_test_param.keys + i, + &data); + if (i != (uint64_t)(uintptr_t)data) { + printf("lookup find wrong value %"PRIu64"," + "%"PRIu64"\n", i, + (uint64_t)(uintptr_t)data); + break; + } + } + + cycles = rte_rdtsc_precise() - begin; + rte_atomic64_add(&gread_cycles, cycles); + rte_atomic64_add(&greads, i); + return 0; +} + +static int +test_rw_writer(void *arg) +{ + uint64_t i; + uint32_t lcore_id = rte_lcore_id(); + uint64_t begin, cycles; + int ret; + uint64_t start_coreid = (uint64_t)(uintptr_t)arg; + uint64_t offset; + + for (i = 0; i < rte_lcore_count(); i++) { + if (slave_core_ids[i] == lcore_id) + break; + } + + offset = TOTAL_INSERT / 2 + (i - (start_coreid)) * + tbl_rw_test_param.num_insert; + begin = rte_rdtsc_precise(); + for (i = offset; i < offset + tbl_rw_test_param.num_insert; i++) { + ret = rte_hash_add_key_data(tbl_rw_test_param.h, + tbl_rw_test_param.keys + i, + (void *)((uintptr_t)i)); + if (ret < 0) { + printf("writer failed %"PRIu64"\n", i); + break; + } + } + + cycles = rte_rdtsc_precise() - begin; + rte_atomic64_add(&gwrite_cycles, cycles); + rte_atomic64_add(&gwrites, tbl_rw_test_param.num_insert); + return 0; +} + +static int +test_hash_readwrite_perf(struct perf *perf_results, int use_htm, + int reader_faster) +{ + unsigned int n; + int ret; + int start_coreid; + uint64_t i, read_cnt; + + const void *next_key; + void *next_data; + uint32_t iter; + int use_jhash = 0; + + uint32_t duplicated_keys = 0; + uint32_t lost_keys = 0; + + uint64_t start = 0, end = 0; + + rte_atomic64_init(&greads); + rte_atomic64_init(&gwrites); + rte_atomic64_clear(&gwrites); + rte_atomic64_clear(&greads); + + rte_atomic64_init(&gread_cycles); + rte_atomic64_clear(&gread_cycles); + rte_atomic64_init(&gwrite_cycles); + rte_atomic64_clear(&gwrite_cycles); + + if (init_params(0, use_htm, use_jhash) != 0) + goto err; + + /* + * Do a readers finish faster or writers finish faster test. + * When readers finish faster, we timing the readers, and when writers + * finish faster, we timing the writers. + * Divided by 10 or 2 is just experimental values to vary the workload + * of readers. + */ + if (reader_faster) { + printf("++++++Start perf test: reader++++++++\n"); + read_cnt = TOTAL_INSERT / 10; + } else { + printf("++++++Start perf test: writer++++++++\n"); + read_cnt = TOTAL_INSERT / 2; + } + + /* We first test single thread performance */ + start = rte_rdtsc_precise(); + /* Insert half of the keys */ + for (i = 0; i < TOTAL_INSERT / 2; i++) { + ret = rte_hash_add_key_data(tbl_rw_test_param.h, + tbl_rw_test_param.keys + i, + (void *)((uintptr_t)i)); + if (ret < 0) { + printf("Failed to insert half of keys\n"); + goto err_free; + } + } + end = rte_rdtsc_precise() - start; + perf_results->single_write = end / i; + + start = rte_rdtsc_precise(); + + for (i = 0; i < read_cnt; i++) { + void *data; + rte_hash_lookup_data(tbl_rw_test_param.h, + tbl_rw_test_param.keys + i, + &data); + if (i != (uint64_t)(uintptr_t)data) { + printf("lookup find wrong value" + " %"PRIu64",%"PRIu64"\n", i, + (uint64_t)(uintptr_t)data); + break; + } + } + end = rte_rdtsc_precise() - start; + perf_results->single_read = end / i; + + for (n = 0; n < NUM_TEST; n++) { + unsigned int tot_slave_lcore = rte_lcore_count() - 1; + if (tot_slave_lcore < core_cnt[n] * 2) + goto finish; + + rte_atomic64_clear(&greads); + rte_atomic64_clear(&gread_cycles); + rte_atomic64_clear(&gwrites); + rte_atomic64_clear(&gwrite_cycles); + + rte_hash_reset(tbl_rw_test_param.h); + + tbl_rw_test_param.num_insert = TOTAL_INSERT / 2 / core_cnt[n]; + tbl_rw_test_param.rounded_tot_insert = TOTAL_INSERT / 2 + + tbl_rw_test_param.num_insert * + core_cnt[n]; + + for (i = 0; i < TOTAL_INSERT / 2; i++) { + ret = rte_hash_add_key_data(tbl_rw_test_param.h, + tbl_rw_test_param.keys + i, + (void *)((uintptr_t)i)); + if (ret < 0) { + printf("Failed to insert half of keys\n"); + goto err_free; + } + } + + /* Then test multiple thread case but only all reads or + * all writes + */ + + /* Test only reader cases */ + for (i = 0; i < core_cnt[n]; i++) + rte_eal_remote_launch(test_rw_reader, + (void *)(uintptr_t)read_cnt, + slave_core_ids[i]); + + rte_eal_mp_wait_lcore(); + + start_coreid = i; + /* Test only writer cases */ + for (; i < core_cnt[n] * 2; i++) + rte_eal_remote_launch(test_rw_writer, + (void *)((uintptr_t)start_coreid), + slave_core_ids[i]); + + rte_eal_mp_wait_lcore(); + + if (reader_faster) { + unsigned long long int cycles_per_insertion = + rte_atomic64_read(&gread_cycles) / + rte_atomic64_read(&greads); + perf_results->read_only[n] = cycles_per_insertion; + printf("Reader only: cycles per lookup: %llu\n", + cycles_per_insertion); + } + + else { + unsigned long long int cycles_per_insertion = + rte_atomic64_read(&gwrite_cycles) / + rte_atomic64_read(&gwrites); + perf_results->write_only[n] = cycles_per_insertion; + printf("Writer only: cycles per writes: %llu\n", + cycles_per_insertion); + } + + rte_atomic64_clear(&greads); + rte_atomic64_clear(&gread_cycles); + rte_atomic64_clear(&gwrites); + rte_atomic64_clear(&gwrite_cycles); + + rte_hash_reset(tbl_rw_test_param.h); + + for (i = 0; i < TOTAL_INSERT / 2; i++) { + ret = rte_hash_add_key_data(tbl_rw_test_param.h, + tbl_rw_test_param.keys + i, + (void *)((uintptr_t)i)); + if (ret < 0) { + printf("Failed to insert half of keys\n"); + goto err_free; + } + } + + start_coreid = core_cnt[n]; + + if (reader_faster) { + for (i = core_cnt[n]; i < core_cnt[n] * 2; i++) + rte_eal_remote_launch(test_rw_writer, + (void *)((uintptr_t)start_coreid), + slave_core_ids[i]); + for (i = 0; i < core_cnt[n]; i++) + rte_eal_remote_launch(test_rw_reader, + (void *)(uintptr_t)read_cnt, + slave_core_ids[i]); + } else { + for (i = 0; i < core_cnt[n]; i++) + rte_eal_remote_launch(test_rw_reader, + (void *)(uintptr_t)read_cnt, + slave_core_ids[i]); + for (; i < core_cnt[n] * 2; i++) + rte_eal_remote_launch(test_rw_writer, + (void *)((uintptr_t)start_coreid), + slave_core_ids[i]); + } + + rte_eal_mp_wait_lcore(); + + iter = 0; + memset(tbl_rw_test_param.found, 0, TOTAL_ENTRY); + while (rte_hash_iterate(tbl_rw_test_param.h, + &next_key, &next_data, &iter) >= 0) { + /* Search for the key in the list of keys added .*/ + i = *(const uint32_t *)next_key; + tbl_rw_test_param.found[i]++; + } + + for (i = 0; i < tbl_rw_test_param.rounded_tot_insert; i++) { + if (tbl_rw_test_param.keys[i] != RTE_RWTEST_FAIL) { + if (tbl_rw_test_param.found[i] > 1) { + duplicated_keys++; + break; + } + if (tbl_rw_test_param.found[i] == 0) { + lost_keys++; + printf("key %"PRIu64" is lost\n", i); + break; + } + } + } + + if (duplicated_keys > 0) { + printf("%d key duplicated\n", duplicated_keys); + goto err_free; + } + + if (lost_keys > 0) { + printf("%d key lost\n", lost_keys); + goto err_free; + } + + printf("No key corrupted during read-write test.\n"); + + if (reader_faster) { + unsigned long long int cycles_per_insertion = + rte_atomic64_read(&gread_cycles) / + rte_atomic64_read(&greads); + perf_results->read_write_r[n] = cycles_per_insertion; + printf("Read-write cycles per lookup: %llu\n", + cycles_per_insertion); + } + + else { + unsigned long long int cycles_per_insertion = + rte_atomic64_read(&gwrite_cycles) / + rte_atomic64_read(&gwrites); + perf_results->read_write_w[n] = cycles_per_insertion; + printf("Read-write cycles per writes: %llu\n", + cycles_per_insertion); + } + } + +finish: + rte_free(tbl_rw_test_param.found); + rte_free(tbl_rw_test_param.keys); + rte_hash_free(tbl_rw_test_param.h); + return 0; + +err_free: + rte_free(tbl_rw_test_param.found); + rte_free(tbl_rw_test_param.keys); + rte_hash_free(tbl_rw_test_param.h); + +err: + return -1; +} + +static int +test_hash_readwrite_main(void) +{ + /* + * Variables used to choose different tests. + * use_htm indicates if hardware transactional memory should be used. + * reader_faster indicates if the reader threads should finish earlier + * than writer threads. This is to timing either reader threads or + * writer threads for performance numbers. + */ + int use_htm, use_ext, reader_faster; + unsigned int i = 0, core_id = 0; + + if (rte_lcore_count() <= 2) { + printf("More than two lcores are required " + "to do read write test\n"); + return -1; + } + + RTE_LCORE_FOREACH_SLAVE(core_id) { + slave_core_ids[i] = core_id; + i++; + } + + setlocale(LC_NUMERIC, ""); + + if (rte_tm_supported()) { + printf("Hardware transactional memory (lock elision) " + "is supported\n"); + + printf("Test read-write with Hardware transactional memory\n"); + + use_htm = 1; + use_ext = 0; + + if (test_hash_readwrite_functional(use_ext, use_htm) < 0) + return -1; + + use_ext = 1; + if (test_hash_readwrite_functional(use_ext, use_htm) < 0) + return -1; + + reader_faster = 1; + if (test_hash_readwrite_perf(&htm_results, use_htm, + reader_faster) < 0) + return -1; + + reader_faster = 0; + if (test_hash_readwrite_perf(&htm_results, use_htm, + reader_faster) < 0) + return -1; + } else { + printf("Hardware transactional memory (lock elision) " + "is NOT supported\n"); + } + + printf("Test read-write without Hardware transactional memory\n"); + use_htm = 0; + use_ext = 0; + if (test_hash_readwrite_functional(use_ext, use_htm) < 0) + return -1; + + use_ext = 1; + if (test_hash_readwrite_functional(use_ext, use_htm) < 0) + return -1; + + reader_faster = 1; + if (test_hash_readwrite_perf(&non_htm_results, use_htm, + reader_faster) < 0) + return -1; + reader_faster = 0; + if (test_hash_readwrite_perf(&non_htm_results, use_htm, + reader_faster) < 0) + return -1; + + printf("================\n"); + printf("Results summary:\n"); + printf("================\n"); + + printf("single read: %u\n", htm_results.single_read); + printf("single write: %u\n", htm_results.single_write); + for (i = 0; i < NUM_TEST; i++) { + printf("+++ core_cnt: %u +++\n", core_cnt[i]); + printf("HTM:\n"); + printf(" read only: %u\n", htm_results.read_only[i]); + printf(" write only: %u\n", htm_results.write_only[i]); + printf(" read-write read: %u\n", htm_results.read_write_r[i]); + printf(" read-write write: %u\n", htm_results.read_write_w[i]); + + printf("non HTM:\n"); + printf(" read only: %u\n", non_htm_results.read_only[i]); + printf(" write only: %u\n", non_htm_results.write_only[i]); + printf(" read-write read: %u\n", + non_htm_results.read_write_r[i]); + printf(" read-write write: %u\n", + non_htm_results.read_write_w[i]); + } + + return 0; +} + +REGISTER_TEST_COMMAND(hash_readwrite_autotest, test_hash_readwrite_main); diff --git a/app/test/test_hash_readwrite_lf.c b/app/test/test_hash_readwrite_lf.c new file mode 100644 index 0000000000..cbfd932269 --- /dev/null +++ b/app/test/test_hash_readwrite_lf.c @@ -0,0 +1,1220 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Arm Limited + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#ifndef RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF +#define RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF 0 +#endif + +#define BULK_LOOKUP_SIZE 32 + +#define RUN_WITH_HTM_DISABLED 0 + +#if (RUN_WITH_HTM_DISABLED) + +#define TOTAL_ENTRY (5*1024) +#define TOTAL_INSERT (5*1024) + +#else + +#define TOTAL_ENTRY (4*1024*1024) +#define TOTAL_INSERT (4*1024*1024) + +#endif + +#define READ_FAIL 1 +#define READ_PASS_NO_KEY_SHIFTS 2 +#define READ_PASS_SHIFT_PATH 4 +#define READ_PASS_NON_SHIFT_PATH 8 +#define BULK_LOOKUP 16 +#define NUM_TEST 3 +unsigned int rwc_core_cnt[NUM_TEST] = {1, 2, 4}; + +struct rwc_perf { + uint32_t w_no_ks_r_hit[2][NUM_TEST]; + uint32_t w_no_ks_r_miss[2][NUM_TEST]; + uint32_t w_ks_r_hit_nsp[2][NUM_TEST]; + uint32_t w_ks_r_hit_sp[2][NUM_TEST]; + uint32_t w_ks_r_miss[2][NUM_TEST]; + uint32_t multi_rw[NUM_TEST - 1][2][NUM_TEST]; +}; + +static struct rwc_perf rwc_lf_results, rwc_non_lf_results; + +struct { + uint32_t *keys; + uint32_t *keys_no_ks; + uint32_t *keys_ks; + uint32_t *keys_absent; + uint32_t *keys_shift_path; + uint32_t *keys_non_shift_path; + uint32_t count_keys_no_ks; + uint32_t count_keys_ks; + uint32_t count_keys_absent; + uint32_t count_keys_shift_path; + uint32_t count_keys_non_shift_path; + uint32_t single_insert; + struct rte_hash *h; +} tbl_rwc_test_param; + +static rte_atomic64_t gread_cycles; +static rte_atomic64_t greads; + +static volatile uint8_t writer_done; +static volatile uint8_t multi_writer_done[4]; + +uint16_t enabled_core_ids[RTE_MAX_LCORE]; + +uint8_t *scanned_bkts; + +static inline int +get_enabled_cores_list(void) +{ + uint32_t i = 0; + uint16_t core_id; + uint32_t max_cores = rte_lcore_count(); + for (core_id = 0; core_id < RTE_MAX_LCORE && i < max_cores; core_id++) { + if (rte_lcore_is_enabled(core_id)) { + enabled_core_ids[i] = core_id; + i++; + } + } + + if (i != max_cores) { + printf("Number of enabled cores in list is different from " + "number given by rte_lcore_count()\n"); + return -1; + } + return 0; +} + +static inline int +check_bucket(uint32_t bkt_idx, uint32_t key) +{ + uint32_t iter; + uint32_t prev_iter; + uint32_t diff; + uint32_t count = 0; + const void *next_key; + void *next_data; + + /* Temporary bucket to hold the keys */ + uint32_t keys_in_bkt[8]; + + iter = bkt_idx * 8; + prev_iter = iter; + while (rte_hash_iterate(tbl_rwc_test_param.h, + &next_key, &next_data, &iter) >= 0) { + + /* Check for duplicate entries */ + if (*(const uint32_t *)next_key == key) + return 1; + + /* Identify if there is any free entry in the bucket */ + diff = iter - prev_iter; + if (diff > 1) + break; + + prev_iter = iter; + keys_in_bkt[count] = *(const uint32_t *)next_key; + count++; + + /* All entries in the bucket are occupied */ + if (count == 8) { + + /* + * Check if bucket was not scanned before, to avoid + * duplicate keys. + */ + if (scanned_bkts[bkt_idx] == 0) { + /* + * Since this bucket (pointed to by bkt_idx) is + * full, it is likely that key(s) in this + * bucket will be on the shift path, when + * collision occurs. Thus, add it to + * keys_shift_path. + */ + memcpy(tbl_rwc_test_param.keys_shift_path + + tbl_rwc_test_param.count_keys_shift_path + , keys_in_bkt, 32); + tbl_rwc_test_param.count_keys_shift_path += 8; + scanned_bkts[bkt_idx] = 1; + } + return -1; + } + } + return 0; +} + +static int +generate_keys(void) +{ + uint32_t *keys = NULL; + uint32_t *keys_no_ks = NULL; + uint32_t *keys_ks = NULL; + uint32_t *keys_absent = NULL; + uint32_t *keys_non_shift_path = NULL; + uint32_t *found = NULL; + uint32_t count_keys_no_ks = 0; + uint32_t count_keys_ks = 0; + uint32_t i; + + /* + * keys will consist of a) keys whose addition to the hash table + * will result in shifting of the existing keys to their alternate + * locations b) keys whose addition to the hash table will not result + * in shifting of the existing keys. + */ + keys = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); + if (keys == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + /* + * keys_no_ks (no key-shifts): Subset of 'keys' - consists of keys that + * will NOT result in shifting of the existing keys to their alternate + * locations. Roughly around 900K keys. + */ + keys_no_ks = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); + if (keys_no_ks == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + /* + * keys_ks (key-shifts): Subset of 'keys' - consists of keys that will + * result in shifting of the existing keys to their alternate locations. + * Roughly around 146K keys. There might be repeating keys. More code is + * required to filter out these keys which will complicate the test case + */ + keys_ks = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); + if (keys_ks == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + /* Used to identify keys not inserted in the hash table */ + found = rte_zmalloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); + if (found == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + /* + * This consist of keys not inserted to the hash table. + * Used to test perf of lookup on keys that do not exist in the table. + */ + keys_absent = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); + if (keys_absent == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + /* + * This consist of keys which are likely to be on the shift + * path (i.e. being moved to alternate location), when collision occurs + * on addition of a key to an already full primary bucket. + * Used to test perf of lookup on keys that are on the shift path. + */ + tbl_rwc_test_param.keys_shift_path = rte_malloc(NULL, sizeof(uint32_t) * + TOTAL_INSERT, 0); + if (tbl_rwc_test_param.keys_shift_path == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + /* + * This consist of keys which are never on the shift + * path (i.e. being moved to alternate location), when collision occurs + * on addition of a key to an already full primary bucket. + * Used to test perf of lookup on keys that are not on the shift path. + */ + keys_non_shift_path = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, + 0); + if (keys_non_shift_path == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + + hash_sig_t sig; + uint32_t prim_bucket_idx; + int ret; + uint32_t num_buckets; + uint32_t bucket_bitmask; + num_buckets = rte_align32pow2(TOTAL_ENTRY) / 8; + bucket_bitmask = num_buckets - 1; + + /* + * Used to mark bkts in which at least one key was shifted to its + * alternate location + */ + scanned_bkts = rte_malloc(NULL, sizeof(uint8_t) * num_buckets, 0); + if (scanned_bkts == NULL) { + printf("RTE_MALLOC failed\n"); + goto err; + } + + tbl_rwc_test_param.keys = keys; + tbl_rwc_test_param.keys_no_ks = keys_no_ks; + tbl_rwc_test_param.keys_ks = keys_ks; + tbl_rwc_test_param.keys_absent = keys_absent; + tbl_rwc_test_param.keys_non_shift_path = keys_non_shift_path; + /* Generate keys by adding previous two keys, neglect overflow */ + printf("Generating keys...\n"); + keys[0] = 0; + keys[1] = 1; + for (i = 2; i < TOTAL_INSERT; i++) + keys[i] = keys[i-1] + keys[i-2]; + + /* Segregate keys into keys_no_ks and keys_ks */ + for (i = 0; i < TOTAL_INSERT; i++) { + /* Check if primary bucket has space.*/ + sig = rte_hash_hash(tbl_rwc_test_param.h, + tbl_rwc_test_param.keys+i); + prim_bucket_idx = sig & bucket_bitmask; + ret = check_bucket(prim_bucket_idx, keys[i]); + if (ret < 0) { + /* + * Primary bucket is full, this key will result in + * shifting of the keys to their alternate locations. + */ + keys_ks[count_keys_ks] = keys[i]; + count_keys_ks++; + } else if (ret == 0) { + /* + * Primary bucket has space, this key will not result in + * shifting of the keys. Hence, add key to the table. + */ + ret = rte_hash_add_key_data(tbl_rwc_test_param.h, + keys+i, + (void *)((uintptr_t)i)); + if (ret < 0) { + printf("writer failed %"PRIu32"\n", i); + break; + } + keys_no_ks[count_keys_no_ks] = keys[i]; + count_keys_no_ks++; + } + } + + for (i = 0; i < count_keys_no_ks; i++) { + /* + * Identify keys in keys_no_ks with value less than + * 4M (HTM enabled) OR 5K (HTM disabled) + */ + if (keys_no_ks[i] < TOTAL_INSERT) + found[keys_no_ks[i]]++; + } + + for (i = 0; i < count_keys_ks; i++) { + /* + * Identify keys in keys_ks with value less than + * 4M (HTM enabled) OR 5K (HTM disabled) + */ + if (keys_ks[i] < TOTAL_INSERT) + found[keys_ks[i]]++; + } + + uint32_t count_keys_absent = 0; + for (i = 0; i < TOTAL_INSERT; i++) { + /* + * Identify missing keys between 0 and + * 4M (HTM enabled) OR 5K (HTM disabled) + */ + if (found[i] == 0) + keys_absent[count_keys_absent++] = i; + } + + /* Find keys that will not be on the shift path */ + uint32_t iter; + const void *next_key; + void *next_data; + uint32_t count = 0; + for (i = 0; i < num_buckets; i++) { + /* Check bucket for no keys shifted to alternate locations */ + if (scanned_bkts[i] == 0) { + iter = i * 8; + while (rte_hash_iterate(tbl_rwc_test_param.h, + &next_key, &next_data, &iter) >= 0) { + + /* Check if key belongs to the current bucket */ + if (i >= (iter-1)/8) + keys_non_shift_path[count++] + = *(const uint32_t *)next_key; + else + break; + } + } + } + + tbl_rwc_test_param.count_keys_no_ks = count_keys_no_ks; + tbl_rwc_test_param.count_keys_ks = count_keys_ks; + tbl_rwc_test_param.count_keys_absent = count_keys_absent; + tbl_rwc_test_param.count_keys_non_shift_path = count; + + printf("\nCount of keys NOT causing shifting of existing keys to " + "alternate location: %d\n", tbl_rwc_test_param.count_keys_no_ks); + printf("\nCount of keys causing shifting of existing keys to alternate " + "locations: %d\n\n", tbl_rwc_test_param.count_keys_ks); + printf("Count of absent keys that will never be added to the hash " + "table: %d\n\n", tbl_rwc_test_param.count_keys_absent); + printf("Count of keys likely to be on the shift path: %d\n\n", + tbl_rwc_test_param.count_keys_shift_path); + printf("Count of keys not likely to be on the shift path: %d\n\n", + tbl_rwc_test_param.count_keys_non_shift_path); + + rte_free(found); + rte_hash_free(tbl_rwc_test_param.h); + return 0; + +err: + rte_free(keys); + rte_free(keys_no_ks); + rte_free(keys_ks); + rte_free(keys_absent); + rte_free(found); + rte_free(tbl_rwc_test_param.keys_shift_path); + rte_free(scanned_bkts); + return -1; +} + +static int +init_params(int rwc_lf, int use_jhash, int htm) +{ + struct rte_hash *handle; + + struct rte_hash_parameters hash_params = { + .entries = TOTAL_ENTRY, + .key_len = sizeof(uint32_t), + .hash_func_init_val = 0, + .socket_id = rte_socket_id(), + }; + + if (use_jhash) + hash_params.hash_func = rte_jhash; + else + hash_params.hash_func = rte_hash_crc; + + if (rwc_lf) + hash_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF | + RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; + else if (htm) + hash_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT | + RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | + RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; + else + hash_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | + RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; + + hash_params.name = "tests"; + + handle = rte_hash_create(&hash_params); + if (handle == NULL) { + printf("hash creation failed"); + return -1; + } + + tbl_rwc_test_param.h = handle; + return 0; +} + +static int +test_rwc_reader(__attribute__((unused)) void *arg) +{ + uint32_t i, j; + int ret; + uint64_t begin, cycles; + uint32_t loop_cnt = 0; + uint8_t read_type = (uint8_t)((uintptr_t)arg); + uint32_t read_cnt; + uint32_t *keys; + uint32_t extra_keys; + int32_t *pos; + void *temp_a[BULK_LOOKUP_SIZE]; + + /* Used to identify keys not inserted in the hash table */ + pos = rte_zmalloc(NULL, sizeof(uint32_t) * BULK_LOOKUP_SIZE, 0); + if (pos == NULL) { + printf("RTE_MALLOC failed\n"); + return -1; + } + + if (read_type & READ_FAIL) { + keys = tbl_rwc_test_param.keys_absent; + read_cnt = tbl_rwc_test_param.count_keys_absent; + } else if (read_type & READ_PASS_NO_KEY_SHIFTS) { + keys = tbl_rwc_test_param.keys_no_ks; + read_cnt = tbl_rwc_test_param.count_keys_no_ks; + } else if (read_type & READ_PASS_SHIFT_PATH) { + keys = tbl_rwc_test_param.keys_shift_path; + read_cnt = tbl_rwc_test_param.count_keys_shift_path; + } else { + keys = tbl_rwc_test_param.keys_non_shift_path; + read_cnt = tbl_rwc_test_param.count_keys_non_shift_path; + } + + extra_keys = read_cnt & (BULK_LOOKUP_SIZE - 1); + + begin = rte_rdtsc_precise(); + do { + if (read_type & BULK_LOOKUP) { + for (i = 0; i < (read_cnt - extra_keys); + i += BULK_LOOKUP_SIZE) { + /* Array of pointer to the list of keys */ + for (j = 0; j < BULK_LOOKUP_SIZE; j++) + temp_a[j] = keys + i + j; + + rte_hash_lookup_bulk(tbl_rwc_test_param.h, + (const void **) + ((uintptr_t)temp_a), + BULK_LOOKUP_SIZE, pos); + /* Validate lookup result */ + for (j = 0; j < BULK_LOOKUP_SIZE; j++) + if ((read_type & READ_FAIL && + pos[j] != -ENOENT) || + (!(read_type & READ_FAIL) && + pos[j] == -ENOENT)) { + printf("lookup failed!" + "%"PRIu32"\n", + keys[i + j]); + return -1; + } + } + for (j = 0; j < extra_keys; j++) + temp_a[j] = keys + i + j; + + rte_hash_lookup_bulk(tbl_rwc_test_param.h, + (const void **) + ((uintptr_t)temp_a), + extra_keys, pos); + for (j = 0; j < extra_keys; j++) + if ((read_type & READ_FAIL && + pos[j] != -ENOENT) || + (!(read_type & READ_FAIL) && + pos[j] == -ENOENT)) { + printf("lookup failed! %"PRIu32"\n", + keys[i + j]); + return -1; + } + } else { + for (i = 0; i < read_cnt; i++) { + ret = rte_hash_lookup + (tbl_rwc_test_param.h, keys + i); + if (((read_type & READ_FAIL) && + (ret != -ENOENT)) || + (!(read_type & READ_FAIL) && + ret == -ENOENT)) { + printf("lookup failed! %"PRIu32"\n", + keys[i]); + return -1; + } + } + } + loop_cnt++; + } while (!writer_done); + + cycles = rte_rdtsc_precise() - begin; + rte_atomic64_add(&gread_cycles, cycles); + rte_atomic64_add(&greads, read_cnt*loop_cnt); + return 0; +} + +static int +write_keys(uint8_t key_shift) +{ + uint32_t i; + int ret; + uint32_t key_cnt; + uint32_t *keys; + if (key_shift) { + key_cnt = tbl_rwc_test_param.count_keys_ks; + keys = tbl_rwc_test_param.keys_ks; + } else { + key_cnt = tbl_rwc_test_param.count_keys_no_ks; + keys = tbl_rwc_test_param.keys_no_ks; + } + for (i = 0; i < key_cnt; i++) { + ret = rte_hash_add_key(tbl_rwc_test_param.h, keys + i); + if (!key_shift && ret < 0) { + printf("writer failed %"PRIu32"\n", i); + return -1; + } + } + return 0; +} + +static int +test_rwc_multi_writer(__attribute__((unused)) void *arg) +{ + uint32_t i, offset; + uint32_t pos_core = (uint32_t)((uintptr_t)arg); + offset = pos_core * tbl_rwc_test_param.single_insert; + for (i = offset; i < offset + tbl_rwc_test_param.single_insert; i++) + rte_hash_add_key(tbl_rwc_test_param.h, + tbl_rwc_test_param.keys_ks + i); + multi_writer_done[pos_core] = 1; + return 0; +} + +/* + * Test lookup perf: + * Reader(s) lookup keys present in the table. + */ +static int +test_hash_add_no_ks_lookup_hit(struct rwc_perf *rwc_perf_results, int rwc_lf, + int htm) +{ + unsigned int n, m; + uint64_t i; + int use_jhash = 0; + uint8_t key_shift = 0; + uint8_t read_type = READ_PASS_NO_KEY_SHIFTS; + + rte_atomic64_init(&greads); + rte_atomic64_init(&gread_cycles); + + if (init_params(rwc_lf, use_jhash, htm) != 0) + goto err; + printf("\nTest: Hash add - no key-shifts, read - hit\n"); + for (m = 0; m < 2; m++) { + if (m == 1) { + printf("\n** With bulk-lookup **\n"); + read_type |= BULK_LOOKUP; + } + for (n = 0; n < NUM_TEST; n++) { + unsigned int tot_lcore = rte_lcore_count(); + if (tot_lcore < rwc_core_cnt[n] + 1) + goto finish; + + printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); + + rte_atomic64_clear(&greads); + rte_atomic64_clear(&gread_cycles); + + rte_hash_reset(tbl_rwc_test_param.h); + writer_done = 0; + if (write_keys(key_shift) < 0) + goto err; + writer_done = 1; + for (i = 1; i <= rwc_core_cnt[n]; i++) + rte_eal_remote_launch(test_rwc_reader, + (void *)(uintptr_t)read_type, + enabled_core_ids[i]); + rte_eal_mp_wait_lcore(); + + for (i = 1; i <= rwc_core_cnt[n]; i++) + if (lcore_config[i].ret < 0) + goto err; + + unsigned long long cycles_per_lookup = + rte_atomic64_read(&gread_cycles) / + rte_atomic64_read(&greads); + rwc_perf_results->w_no_ks_r_hit[m][n] + = cycles_per_lookup; + printf("Cycles per lookup: %llu\n", cycles_per_lookup); + } + } + +finish: + rte_hash_free(tbl_rwc_test_param.h); + return 0; + +err: + rte_hash_free(tbl_rwc_test_param.h); + return -1; +} + +/* + * Test lookup perf: + * Reader(s) lookup keys absent in the table while + * 'Main' thread adds with no key-shifts. + */ +static int +test_hash_add_no_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf, + int htm) +{ + unsigned int n, m; + uint64_t i; + int use_jhash = 0; + uint8_t key_shift = 0; + uint8_t read_type = READ_FAIL; + int ret; + + rte_atomic64_init(&greads); + rte_atomic64_init(&gread_cycles); + + if (init_params(rwc_lf, use_jhash, htm) != 0) + goto err; + printf("\nTest: Hash add - no key-shifts, Hash lookup - miss\n"); + for (m = 0; m < 2; m++) { + if (m == 1) { + printf("\n** With bulk-lookup **\n"); + read_type |= BULK_LOOKUP; + } + for (n = 0; n < NUM_TEST; n++) { + unsigned int tot_lcore = rte_lcore_count(); + if (tot_lcore < rwc_core_cnt[n] + 1) + goto finish; + + printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); + + rte_atomic64_clear(&greads); + rte_atomic64_clear(&gread_cycles); + + rte_hash_reset(tbl_rwc_test_param.h); + writer_done = 0; + + for (i = 1; i <= rwc_core_cnt[n]; i++) + rte_eal_remote_launch(test_rwc_reader, + (void *)(uintptr_t)read_type, + enabled_core_ids[i]); + ret = write_keys(key_shift); + writer_done = 1; + rte_eal_mp_wait_lcore(); + + if (ret < 0) + goto err; + for (i = 1; i <= rwc_core_cnt[n]; i++) + if (lcore_config[i].ret < 0) + goto err; + + unsigned long long cycles_per_lookup = + rte_atomic64_read(&gread_cycles) / + rte_atomic64_read(&greads); + rwc_perf_results->w_no_ks_r_miss[m][n] + = cycles_per_lookup; + printf("Cycles per lookup: %llu\n", cycles_per_lookup); + } + } + +finish: + rte_hash_free(tbl_rwc_test_param.h); + return 0; + +err: + rte_hash_free(tbl_rwc_test_param.h); + return -1; +} + +/* + * Test lookup perf: + * Reader(s) lookup keys present in the table and not likely to be on the + * shift path while 'Main' thread adds keys causing key-shifts. + */ +static int +test_hash_add_ks_lookup_hit_non_sp(struct rwc_perf *rwc_perf_results, + int rwc_lf, int htm) +{ + unsigned int n, m; + uint64_t i; + int use_jhash = 0; + int ret; + uint8_t key_shift; + uint8_t read_type = READ_PASS_NON_SHIFT_PATH; + + rte_atomic64_init(&greads); + rte_atomic64_init(&gread_cycles); + + if (init_params(rwc_lf, use_jhash, htm) != 0) + goto err; + printf("\nTest: Hash add - key shift, Hash lookup - hit" + " (non-shift-path)\n"); + for (m = 0; m < 2; m++) { + if (m == 1) { + printf("\n** With bulk-lookup **\n"); + read_type |= BULK_LOOKUP; + } + for (n = 0; n < NUM_TEST; n++) { + unsigned int tot_lcore = rte_lcore_count(); + if (tot_lcore < rwc_core_cnt[n] + 1) + goto finish; + + printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); + + rte_atomic64_clear(&greads); + rte_atomic64_clear(&gread_cycles); + + rte_hash_reset(tbl_rwc_test_param.h); + writer_done = 0; + key_shift = 0; + if (write_keys(key_shift) < 0) + goto err; + for (i = 1; i <= rwc_core_cnt[n]; i++) + rte_eal_remote_launch(test_rwc_reader, + (void *)(uintptr_t)read_type, + enabled_core_ids[i]); + key_shift = 1; + ret = write_keys(key_shift); + writer_done = 1; + rte_eal_mp_wait_lcore(); + + if (ret < 0) + goto err; + for (i = 1; i <= rwc_core_cnt[n]; i++) + if (lcore_config[i].ret < 0) + goto err; + + unsigned long long cycles_per_lookup = + rte_atomic64_read(&gread_cycles) / + rte_atomic64_read(&greads); + rwc_perf_results->w_ks_r_hit_nsp[m][n] + = cycles_per_lookup; + printf("Cycles per lookup: %llu\n", cycles_per_lookup); + } + } + +finish: + rte_hash_free(tbl_rwc_test_param.h); + return 0; + +err: + rte_hash_free(tbl_rwc_test_param.h); + return -1; +} + +/* + * Test lookup perf: + * Reader(s) lookup keys present in the table and likely on the shift-path while + * 'Main' thread adds keys causing key-shifts. + */ +static int +test_hash_add_ks_lookup_hit_sp(struct rwc_perf *rwc_perf_results, int rwc_lf, + int htm) +{ + unsigned int n, m; + uint64_t i; + int use_jhash = 0; + int ret; + uint8_t key_shift; + uint8_t read_type = READ_PASS_SHIFT_PATH; + + rte_atomic64_init(&greads); + rte_atomic64_init(&gread_cycles); + + if (init_params(rwc_lf, use_jhash, htm) != 0) + goto err; + printf("\nTest: Hash add - key shift, Hash lookup - hit (shift-path)" + "\n"); + + for (m = 0; m < 2; m++) { + if (m == 1) { + printf("\n** With bulk-lookup **\n"); + read_type |= BULK_LOOKUP; + } + for (n = 0; n < NUM_TEST; n++) { + unsigned int tot_lcore = rte_lcore_count(); + if (tot_lcore < rwc_core_cnt[n]) + goto finish; + + printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); + rte_atomic64_clear(&greads); + rte_atomic64_clear(&gread_cycles); + + rte_hash_reset(tbl_rwc_test_param.h); + writer_done = 0; + key_shift = 0; + if (write_keys(key_shift) < 0) + goto err; + for (i = 1; i <= rwc_core_cnt[n]; i++) + rte_eal_remote_launch(test_rwc_reader, + (void *)(uintptr_t)read_type, + enabled_core_ids[i]); + key_shift = 1; + ret = write_keys(key_shift); + writer_done = 1; + rte_eal_mp_wait_lcore(); + + if (ret < 0) + goto err; + for (i = 1; i <= rwc_core_cnt[n]; i++) + if (lcore_config[i].ret < 0) + goto err; + + unsigned long long cycles_per_lookup = + rte_atomic64_read(&gread_cycles) / + rte_atomic64_read(&greads); + rwc_perf_results->w_ks_r_hit_sp[m][n] + = cycles_per_lookup; + printf("Cycles per lookup: %llu\n", cycles_per_lookup); + } + } + +finish: + rte_hash_free(tbl_rwc_test_param.h); + return 0; + +err: + rte_hash_free(tbl_rwc_test_param.h); + return -1; +} + +/* + * Test lookup perf: + * Reader(s) lookup keys absent in the table while + * 'Main' thread adds keys causing key-shifts. + */ +static int +test_hash_add_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf, int + htm) +{ + unsigned int n, m; + uint64_t i; + int use_jhash = 0; + int ret; + uint8_t key_shift; + uint8_t read_type = READ_FAIL; + + rte_atomic64_init(&greads); + rte_atomic64_init(&gread_cycles); + + if (init_params(rwc_lf, use_jhash, htm) != 0) + goto err; + printf("\nTest: Hash add - key shift, Hash lookup - miss\n"); + for (m = 0; m < 2; m++) { + if (m == 1) { + printf("\n** With bulk-lookup **\n"); + read_type |= BULK_LOOKUP; + } + for (n = 0; n < NUM_TEST; n++) { + unsigned int tot_lcore = rte_lcore_count(); + if (tot_lcore < rwc_core_cnt[n] + 1) + goto finish; + + printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); + + rte_atomic64_clear(&greads); + rte_atomic64_clear(&gread_cycles); + + rte_hash_reset(tbl_rwc_test_param.h); + writer_done = 0; + key_shift = 0; + if (write_keys(key_shift) < 0) + goto err; + for (i = 1; i <= rwc_core_cnt[n]; i++) + rte_eal_remote_launch(test_rwc_reader, + (void *)(uintptr_t)read_type, + enabled_core_ids[i]); + key_shift = 1; + ret = write_keys(key_shift); + writer_done = 1; + rte_eal_mp_wait_lcore(); + + if (ret < 0) + goto err; + for (i = 1; i <= rwc_core_cnt[n]; i++) + if (lcore_config[i].ret < 0) + goto err; + + unsigned long long cycles_per_lookup = + rte_atomic64_read(&gread_cycles) / + rte_atomic64_read(&greads); + rwc_perf_results->w_ks_r_miss[m][n] = cycles_per_lookup; + printf("Cycles per lookup: %llu\n", cycles_per_lookup); + } + } + +finish: + rte_hash_free(tbl_rwc_test_param.h); + return 0; + +err: + rte_hash_free(tbl_rwc_test_param.h); + return -1; +} + +/* + * Test lookup perf for multi-writer: + * Reader(s) lookup keys present in the table and likely on the shift-path while + * Writers add keys causing key-shiftsi. + * Writers are running in parallel, on different data plane cores. + */ +static int +test_hash_multi_add_lookup(struct rwc_perf *rwc_perf_results, int rwc_lf, + int htm) +{ + unsigned int n, m, k; + uint64_t i; + int use_jhash = 0; + uint8_t key_shift; + uint8_t read_type = READ_PASS_SHIFT_PATH; + + rte_atomic64_init(&greads); + rte_atomic64_init(&gread_cycles); + + if (init_params(rwc_lf, use_jhash, htm) != 0) + goto err; + printf("\nTest: Multi-add-lookup\n"); + uint8_t pos_core; + for (m = 1; m < NUM_TEST; m++) { + /* Calculate keys added by each writer */ + tbl_rwc_test_param.single_insert = + tbl_rwc_test_param.count_keys_ks / rwc_core_cnt[m]; + for (k = 0; k < 2; k++) { + if (k == 1) { + printf("\n** With bulk-lookup **\n"); + read_type |= BULK_LOOKUP; + } + for (n = 0; n < NUM_TEST; n++) { + unsigned int tot_lcore = rte_lcore_count(); + if (tot_lcore < (rwc_core_cnt[n] + + rwc_core_cnt[m] + 1)) + goto finish; + + printf("\nNumber of writers: %u", + rwc_core_cnt[m]); + printf("\nNumber of readers: %u\n", + rwc_core_cnt[n]); + + rte_atomic64_clear(&greads); + rte_atomic64_clear(&gread_cycles); + + rte_hash_reset(tbl_rwc_test_param.h); + writer_done = 0; + for (i = 0; i < 4; i++) + multi_writer_done[i] = 0; + key_shift = 0; + if (write_keys(key_shift) < 0) + goto err; + + /* Launch reader(s) */ + for (i = 1; i <= rwc_core_cnt[n]; i++) + rte_eal_remote_launch(test_rwc_reader, + (void *)(uintptr_t)read_type, + enabled_core_ids[i]); + key_shift = 1; + pos_core = 0; + + /* Launch writers */ + for (; i <= rwc_core_cnt[m] + + rwc_core_cnt[n]; i++) { + rte_eal_remote_launch + (test_rwc_multi_writer, + (void *)(uintptr_t)pos_core, + enabled_core_ids[i]); + pos_core++; + } + + /* Wait for writers to complete */ + for (i = 0; i < rwc_core_cnt[m]; i++) + while + (multi_writer_done[i] == 0); + writer_done = 1; + + rte_eal_mp_wait_lcore(); + + for (i = 1; i <= rwc_core_cnt[n]; i++) + if (lcore_config[i].ret < 0) + goto err; + + unsigned long long cycles_per_lookup = + rte_atomic64_read(&gread_cycles) + / rte_atomic64_read(&greads); + rwc_perf_results->multi_rw[m][k][n] + = cycles_per_lookup; + printf("Cycles per lookup: %llu\n", + cycles_per_lookup); + } + } + } + +finish: + rte_hash_free(tbl_rwc_test_param.h); + return 0; + +err: + rte_hash_free(tbl_rwc_test_param.h); + return -1; +} + +static int +test_hash_readwrite_lf_main(void) +{ + /* + * Variables used to choose different tests. + * rwc_lf indicates if read-write concurrency lock-free support is + * enabled. + * htm indicates if Hardware transactional memory support is enabled. + */ + int rwc_lf = 0; + int htm; + int use_jhash = 0; + if (rte_lcore_count() == 1) { + printf("More than one lcore is required " + "to do read write lock-free concurrency test\n"); + return -1; + } + + setlocale(LC_NUMERIC, ""); + + if (rte_tm_supported()) + htm = 1; + else + htm = 0; + + if (init_params(rwc_lf, use_jhash, htm) != 0) + return -1; + if (generate_keys() != 0) + return -1; + if (get_enabled_cores_list() != 0) + return -1; + + if (RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF) { + rwc_lf = 1; + printf("Test lookup with read-write concurrency lock free support" + " enabled\n"); + if (test_hash_add_no_ks_lookup_hit(&rwc_lf_results, rwc_lf, + htm) < 0) + return -1; + if (test_hash_add_no_ks_lookup_miss(&rwc_lf_results, rwc_lf, + htm) < 0) + return -1; + if (test_hash_add_ks_lookup_hit_non_sp(&rwc_lf_results, rwc_lf, + htm) < 0) + return -1; + if (test_hash_add_ks_lookup_hit_sp(&rwc_lf_results, rwc_lf, + htm) < 0) + return -1; + if (test_hash_add_ks_lookup_miss(&rwc_lf_results, rwc_lf, htm) + < 0) + return -1; + if (test_hash_multi_add_lookup(&rwc_lf_results, rwc_lf, htm) + < 0) + return -1; + } + printf("\nTest lookup with read-write concurrency lock free support" + " disabled\n"); + rwc_lf = 0; + if (!htm) { + printf("With HTM Disabled\n"); + if (!RUN_WITH_HTM_DISABLED) { + printf("Enable RUN_WITH_HTM_DISABLED to test with" + " lock-free disabled"); + goto results; + } + } else + printf("With HTM Enabled\n"); + if (test_hash_add_no_ks_lookup_hit(&rwc_non_lf_results, rwc_lf, htm) + < 0) + return -1; + if (test_hash_add_no_ks_lookup_miss(&rwc_non_lf_results, rwc_lf, htm) + < 0) + return -1; + if (test_hash_add_ks_lookup_hit_non_sp(&rwc_non_lf_results, rwc_lf, + htm) < 0) + return -1; + if (test_hash_add_ks_lookup_hit_sp(&rwc_non_lf_results, rwc_lf, htm) + < 0) + return -1; + if (test_hash_add_ks_lookup_miss(&rwc_non_lf_results, rwc_lf, htm) < 0) + return -1; + if (test_hash_multi_add_lookup(&rwc_non_lf_results, rwc_lf, htm) < 0) + return -1; +results: + printf("\n\t\t\t\t\t\t********** Results summary **********\n\n"); + int i, j, k; + for (j = 0; j < 2; j++) { + if (j == 1) + printf("\n\t\t\t\t\t#######********** Bulk Lookup " + "**********#######\n\n"); + printf("_______\t\t_______\t\t_________\t___\t\t_________\t\t" + "\t\t\t\t_________________\n"); + printf("Writers\t\tReaders\t\tLock-free\tHTM\t\tTest-case\t\t\t" + "\t\t\tCycles per lookup\n"); + printf("_______\t\t_______\t\t_________\t___\t\t_________\t\t\t" + "\t\t\t_________________\n"); + for (i = 0; i < NUM_TEST; i++) { + printf("%u\t\t%u\t\t", 1, rwc_core_cnt[i]); + printf("Enabled\t\t"); + printf("N/A\t\t"); + printf("Hash add - no key-shifts, lookup - hit\t\t\t\t" + "%u\n\t\t\t\t\t\t\t\t", + rwc_lf_results.w_no_ks_r_hit[j][i]); + printf("Hash add - no key-shifts, lookup - miss\t\t\t\t" + "%u\n\t\t\t\t\t\t\t\t", + rwc_lf_results.w_no_ks_r_miss[j][i]); + printf("Hash add - key-shifts, lookup - hit" + "(non-shift-path)\t\t%u\n\t\t\t\t\t\t\t\t", + rwc_lf_results.w_ks_r_hit_nsp[j][i]); + printf("Hash add - key-shifts, lookup - hit " + "(shift-path)\t\t%u\n\t\t\t\t\t\t\t\t", + rwc_lf_results.w_ks_r_hit_sp[j][i]); + printf("Hash add - key-shifts, Hash lookup miss\t\t\t\t" + "%u\n\n\t\t\t\t", + rwc_lf_results.w_ks_r_miss[j][i]); + + printf("Disabled\t"); + if (htm) + printf("Enabled\t\t"); + else + printf("Disabled\t"); + printf("Hash add - no key-shifts, lookup - hit\t\t\t\t" + "%u\n\t\t\t\t\t\t\t\t", + rwc_non_lf_results.w_no_ks_r_hit[j][i]); + printf("Hash add - no key-shifts, lookup - miss\t\t\t\t" + "%u\n\t\t\t\t\t\t\t\t", + rwc_non_lf_results.w_no_ks_r_miss[j][i]); + printf("Hash add - key-shifts, lookup - hit " + "(non-shift-path)\t\t%u\n\t\t\t\t\t\t\t\t", + rwc_non_lf_results.w_ks_r_hit_nsp[j][i]); + printf("Hash add - key-shifts, lookup - hit " + "(shift-path)\t\t%u\n\t\t\t\t\t\t\t\t", + rwc_non_lf_results.w_ks_r_hit_sp[j][i]); + printf("Hash add - key-shifts, Hash lookup miss\t\t\t\t" + "%u\n", rwc_non_lf_results.w_ks_r_miss[j][i]); + + printf("_______\t\t_______\t\t_________\t___\t\t" + "_________\t\t\t\t\t\t_________________\n"); + } + + for (i = 1; i < NUM_TEST; i++) { + for (k = 0; k < NUM_TEST; k++) { + printf("%u", rwc_core_cnt[i]); + printf("\t\t%u\t\t", rwc_core_cnt[k]); + printf("Enabled\t\t"); + printf("N/A\t\t"); + printf("Multi-add-lookup\t\t\t\t\t\t%u\n\n\t\t" + "\t\t", + rwc_lf_results.multi_rw[i][j][k]); + printf("Disabled\t"); + if (htm) + printf("Enabled\t\t"); + else + printf("Disabled\t"); + printf("Multi-add-lookup\t\t\t\t\t\t%u\n", + rwc_non_lf_results.multi_rw[i][j][k]); + + printf("_______\t\t_______\t\t_________\t___" + "\t\t_________\t\t\t\t\t\t" + "_________________\n"); + } + } + } + rte_free(tbl_rwc_test_param.keys); + rte_free(tbl_rwc_test_param.keys_no_ks); + rte_free(tbl_rwc_test_param.keys_ks); + rte_free(tbl_rwc_test_param.keys_absent); + rte_free(tbl_rwc_test_param.keys_shift_path); + rte_free(scanned_bkts); + return 0; +} + +REGISTER_TEST_COMMAND(hash_readwrite_lf_autotest, test_hash_readwrite_lf_main); diff --git a/app/test/test_interrupts.c b/app/test/test_interrupts.c new file mode 100644 index 0000000000..4e82e9a22d --- /dev/null +++ b/app/test/test_interrupts.c @@ -0,0 +1,558 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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_VALID_DEV_EVENT, + 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_VALID_DEV_EVENT].fd = pfds.readfd; + intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT].type = + RTE_INTR_HANDLE_DEV_EVENT; + + 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(void *arg) +{ + struct rte_intr_handle *intr_handle = 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(void *arg) +{ + struct rte_intr_handle *intr_handle = 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 specific valid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT]; + 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 specific valid intr_handle */ + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT]; + 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, &test_intr_handle) < 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, &test_intr_handle) < 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 occurred 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 occurred during checking valid UIO interrupt " + "full path\n"); + goto out; + } + + printf("Check valid device event interrupt full path\n"); + if (test_interrupt_full_path_check( + TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT) < 0) { + printf("failure occurred during checking valid device event " + "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 occurred 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, &test_intr_handle) == 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, &test_intr_handle) == 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, &test_intr_handle) > 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, &test_intr_handle) < 0) { + printf("it fails to register test_interrupt_callback\n"); + goto out; + } + if (rte_intr_callback_register(&test_intr_handle, + test_interrupt_callback_1, &test_intr_handle) < 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, &test_intr_handle) <= 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); + + test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT]; + 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_ipsec.c b/app/test/test_ipsec.c new file mode 100644 index 0000000000..80a2d255fb --- /dev/null +++ b/app/test/test_ipsec.c @@ -0,0 +1,2499 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" +#include "test_cryptodev.h" + +#define VDEV_ARGS_SIZE 100 +#define MAX_NB_SESSIONS 100 +#define MAX_NB_SAS 2 +#define REPLAY_WIN_0 0 +#define REPLAY_WIN_32 32 +#define REPLAY_WIN_64 64 +#define REPLAY_WIN_128 128 +#define REPLAY_WIN_256 256 +#define DATA_64_BYTES 64 +#define DATA_80_BYTES 80 +#define DATA_100_BYTES 100 +#define ESN_ENABLED 1 +#define ESN_DISABLED 0 +#define INBOUND_SPI 7 +#define OUTBOUND_SPI 17 +#define BURST_SIZE 32 +#define REORDER_PKTS 1 + +struct user_params { + enum rte_crypto_sym_xform_type auth; + enum rte_crypto_sym_xform_type cipher; + enum rte_crypto_sym_xform_type aead; + + char auth_algo[128]; + char cipher_algo[128]; + char aead_algo[128]; +}; + +struct ipsec_testsuite_params { + struct rte_mempool *mbuf_pool; + struct rte_mempool *cop_mpool; + struct rte_cryptodev_config conf; + struct rte_cryptodev_qp_conf qp_conf; + + uint8_t valid_dev; + uint8_t valid_dev_found; +}; + +struct ipsec_unitest_params { + struct rte_crypto_sym_xform cipher_xform; + struct rte_crypto_sym_xform auth_xform; + struct rte_crypto_sym_xform aead_xform; + struct rte_crypto_sym_xform *crypto_xforms; + + struct rte_security_ipsec_xform ipsec_xform; + + struct rte_ipsec_sa_prm sa_prm; + struct rte_ipsec_session ss[MAX_NB_SAS]; + + struct rte_crypto_op *cop[BURST_SIZE]; + + struct rte_mbuf *obuf[BURST_SIZE], *ibuf[BURST_SIZE], + *testbuf[BURST_SIZE]; + + uint8_t *digest; + uint16_t pkt_index; +}; + +struct ipsec_test_cfg { + uint32_t replay_win_sz; + uint32_t esn; + uint64_t flags; + size_t pkt_sz; + uint16_t num_pkts; + uint32_t reorder_pkts; +}; + +static const struct ipsec_test_cfg test_cfg[] = { + + {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_64_BYTES, 1, 0}, + {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_80_BYTES, BURST_SIZE, + REORDER_PKTS}, + {REPLAY_WIN_32, ESN_ENABLED, 0, DATA_100_BYTES, 1, 0}, + {REPLAY_WIN_32, ESN_ENABLED, 0, DATA_100_BYTES, BURST_SIZE, + REORDER_PKTS}, + {REPLAY_WIN_64, ESN_ENABLED, 0, DATA_64_BYTES, 1, 0}, + {REPLAY_WIN_128, ESN_ENABLED, RTE_IPSEC_SAFLAG_SQN_ATOM, + DATA_80_BYTES, 1, 0}, + {REPLAY_WIN_256, ESN_DISABLED, 0, DATA_100_BYTES, 1, 0}, +}; + +static const int num_cfg = RTE_DIM(test_cfg); +static struct ipsec_testsuite_params testsuite_params = { NULL }; +static struct ipsec_unitest_params unittest_params; +static struct user_params uparams; + +static uint8_t global_key[128] = { 0 }; + +struct supported_cipher_algo { + const char *keyword; + enum rte_crypto_cipher_algorithm algo; + uint16_t iv_len; + uint16_t block_size; + uint16_t key_len; +}; + +struct supported_auth_algo { + const char *keyword; + enum rte_crypto_auth_algorithm algo; + uint16_t digest_len; + uint16_t key_len; + uint8_t key_not_req; +}; + +const struct supported_cipher_algo cipher_algos[] = { + { + .keyword = "null", + .algo = RTE_CRYPTO_CIPHER_NULL, + .iv_len = 0, + .block_size = 4, + .key_len = 0 + }, +}; + +const struct supported_auth_algo auth_algos[] = { + { + .keyword = "null", + .algo = RTE_CRYPTO_AUTH_NULL, + .digest_len = 0, + .key_len = 0, + .key_not_req = 1 + }, +}; + +static int +dummy_sec_create(void *device, struct rte_security_session_conf *conf, + struct rte_security_session *sess, struct rte_mempool *mp) +{ + RTE_SET_USED(device); + RTE_SET_USED(conf); + RTE_SET_USED(mp); + + sess->sess_private_data = NULL; + return 0; +} + +static int +dummy_sec_destroy(void *device, struct rte_security_session *sess) +{ + RTE_SET_USED(device); + RTE_SET_USED(sess); + return 0; +} + +static const struct rte_security_ops dummy_sec_ops = { + .session_create = dummy_sec_create, + .session_destroy = dummy_sec_destroy, +}; + +static struct rte_security_ctx dummy_sec_ctx = { + .ops = &dummy_sec_ops, +}; + +static const struct supported_cipher_algo * +find_match_cipher_algo(const char *cipher_keyword) +{ + size_t i; + + for (i = 0; i < RTE_DIM(cipher_algos); i++) { + const struct supported_cipher_algo *algo = + &cipher_algos[i]; + + if (strcmp(cipher_keyword, algo->keyword) == 0) + return algo; + } + + return NULL; +} + +static const struct supported_auth_algo * +find_match_auth_algo(const char *auth_keyword) +{ + size_t i; + + for (i = 0; i < RTE_DIM(auth_algos); i++) { + const struct supported_auth_algo *algo = + &auth_algos[i]; + + if (strcmp(auth_keyword, algo->keyword) == 0) + return algo; + } + + return NULL; +} + +static void +fill_crypto_xform(struct ipsec_unitest_params *ut_params, + const struct supported_auth_algo *auth_algo, + const struct supported_cipher_algo *cipher_algo) +{ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.algo = auth_algo->algo; + ut_params->auth_xform.auth.key.data = global_key; + ut_params->auth_xform.auth.key.length = auth_algo->key_len; + ut_params->auth_xform.auth.digest_length = auth_algo->digest_len; + ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + + ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + ut_params->cipher_xform.cipher.algo = cipher_algo->algo; + ut_params->cipher_xform.cipher.key.data = global_key; + ut_params->cipher_xform.cipher.key.length = cipher_algo->key_len; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; + ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; + ut_params->cipher_xform.cipher.iv.length = cipher_algo->iv_len; + + if (ut_params->ipsec_xform.direction == + RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { + ut_params->crypto_xforms = &ut_params->auth_xform; + ut_params->auth_xform.next = &ut_params->cipher_xform; + ut_params->cipher_xform.next = NULL; + } else { + ut_params->crypto_xforms = &ut_params->cipher_xform; + ut_params->cipher_xform.next = &ut_params->auth_xform; + ut_params->auth_xform.next = NULL; + } +} + +static int +check_cryptodev_capablity(const struct ipsec_unitest_params *ut, + uint8_t dev_id) +{ + struct rte_cryptodev_sym_capability_idx cap_idx; + const struct rte_cryptodev_symmetric_capability *cap; + int rc = -1; + + cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; + cap_idx.algo.auth = ut->auth_xform.auth.algo; + cap = rte_cryptodev_sym_capability_get(dev_id, &cap_idx); + + if (cap != NULL) { + rc = rte_cryptodev_sym_capability_check_auth(cap, + ut->auth_xform.auth.key.length, + ut->auth_xform.auth.digest_length, 0); + if (rc == 0) { + cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cap_idx.algo.cipher = ut->cipher_xform.cipher.algo; + cap = rte_cryptodev_sym_capability_get( + dev_id, &cap_idx); + if (cap != NULL) + rc = rte_cryptodev_sym_capability_check_cipher( + cap, + ut->cipher_xform.cipher.key.length, + ut->cipher_xform.cipher.iv.length); + } + } + + return rc; +} + +static int +testsuite_setup(void) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + const struct supported_auth_algo *auth_algo; + const struct supported_cipher_algo *cipher_algo; + struct rte_cryptodev_info info; + uint32_t i, nb_devs, dev_id; + size_t sess_sz; + int rc; + + memset(ts_params, 0, sizeof(*ts_params)); + + uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH; + uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER; + strcpy(uparams.auth_algo, "null"); + strcpy(uparams.cipher_algo, "null"); + + auth_algo = find_match_auth_algo(uparams.auth_algo); + cipher_algo = find_match_cipher_algo(uparams.cipher_algo); + fill_crypto_xform(ut_params, auth_algo, cipher_algo); + + nb_devs = rte_cryptodev_count(); + if (nb_devs < 1) { + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); + return TEST_FAILED; + } + + /* Find first valid crypto device */ + for (i = 0; i < nb_devs; i++) { + rc = check_cryptodev_capablity(ut_params, i); + if (rc == 0) { + ts_params->valid_dev = i; + ts_params->valid_dev_found = 1; + break; + } + } + + if (ts_params->valid_dev_found == 0) + return TEST_FAILED; + + 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->cop_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) + + MAXIMUM_IV_LENGTH, + rte_socket_id()); + if (ts_params->cop_mpool == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); + return TEST_FAILED; + } + + /* Set up all the qps on the first of the valid devices found */ + dev_id = ts_params->valid_dev; + + 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; + + sess_sz = rte_cryptodev_sym_get_private_session_size(dev_id); + sess_sz = RTE_MAX(sess_sz, sizeof(struct rte_security_session)); + + /* + * Create mempools for sessions + */ + if (info.sym.max_nb_sessions != 0 && + info.sym.max_nb_sessions < MAX_NB_SESSIONS) { + RTE_LOG(ERR, USER1, "Device does not support " + "at least %u sessions\n", + MAX_NB_SESSIONS); + return TEST_FAILED; + } + + ts_params->qp_conf.mp_session_private = rte_mempool_create( + "test_priv_sess_mp", + MAX_NB_SESSIONS, + sess_sz, + 0, 0, NULL, NULL, NULL, + NULL, SOCKET_ID_ANY, + 0); + + TEST_ASSERT_NOT_NULL(ts_params->qp_conf.mp_session_private, + "private session mempool allocation failed"); + + ts_params->qp_conf.mp_session = + rte_cryptodev_sym_session_pool_create("test_sess_mp", + MAX_NB_SESSIONS, 0, 0, 0, SOCKET_ID_ANY); + + TEST_ASSERT_NOT_NULL(ts_params->qp_conf.mp_session, + "session mempool allocation failed"); + + 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; + + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + dev_id, 0, &ts_params->qp_conf, + rte_cryptodev_socket_id(dev_id)), + "Failed to setup queue pair %u on cryptodev %u", + 0, dev_id); + + return TEST_SUCCESS; +} + +static void +testsuite_teardown(void) +{ + struct ipsec_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)); + rte_mempool_free(ts_params->mbuf_pool); + ts_params->mbuf_pool = NULL; + } + + if (ts_params->cop_mpool != NULL) { + RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n", + rte_mempool_avail_count(ts_params->cop_mpool)); + rte_mempool_free(ts_params->cop_mpool); + ts_params->cop_mpool = NULL; + } + + /* Free session mempools */ + if (ts_params->qp_conf.mp_session != NULL) { + rte_mempool_free(ts_params->qp_conf.mp_session); + ts_params->qp_conf.mp_session = NULL; + } + + if (ts_params->qp_conf.mp_session_private != NULL) { + rte_mempool_free(ts_params->qp_conf.mp_session_private); + ts_params->qp_conf.mp_session_private = NULL; + } +} + +static int +ut_setup(void) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + + /* 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; + + /* Start the device */ + TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_dev), + "Failed to start cryptodev %u", + ts_params->valid_dev); + + return TEST_SUCCESS; +} + +static void +ut_teardown(void) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + int i; + + for (i = 0; i < BURST_SIZE; i++) { + /* free crypto operation structure */ + if (ut_params->cop[i]) + rte_crypto_op_free(ut_params->cop[i]); + + /* + * 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[i]) { + rte_pktmbuf_free(ut_params->obuf[i]); + if (ut_params->ibuf[i] == ut_params->obuf[i]) + ut_params->ibuf[i] = 0; + ut_params->obuf[i] = 0; + } + if (ut_params->ibuf[i]) { + rte_pktmbuf_free(ut_params->ibuf[i]); + ut_params->ibuf[i] = 0; + } + + if (ut_params->testbuf[i]) { + rte_pktmbuf_free(ut_params->testbuf[i]); + ut_params->testbuf[i] = 0; + } + } + + if (ts_params->mbuf_pool != NULL) + RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", + rte_mempool_avail_count(ts_params->mbuf_pool)); + + /* Stop the device */ + rte_cryptodev_stop(ts_params->valid_dev); +} + +#define IPSEC_MAX_PAD_SIZE UINT8_MAX + +static const uint8_t esp_pad_bytes[IPSEC_MAX_PAD_SIZE] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, +}; + +/* ***** data for tests ***** */ + +const char null_plain_data[] = + "Network Security People Have A Strange Sense Of Humor unlike Other " + "People who have a normal sense of humour"; + +const char null_encrypted_data[] = + "Network Security People Have A Strange Sense Of Humor unlike Other " + "People who have a normal sense of humour"; + +struct ipv4_hdr ipv4_outer = { + .version_ihl = IPVERSION << 4 | + sizeof(ipv4_outer) / IPV4_IHL_MULTIPLIER, + .time_to_live = IPDEFTTL, + .next_proto_id = IPPROTO_ESP, + .src_addr = IPv4(192, 168, 1, 100), + .dst_addr = IPv4(192, 168, 2, 100), +}; + +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); + + if (m) { + memset(m->buf_addr, 0, m->buf_len); + 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; +} + +static struct rte_mbuf * +setup_test_string_tunneled(struct rte_mempool *mpool, const char *string, + size_t len, uint32_t spi, uint32_t seq) +{ + struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); + uint32_t hdrlen = sizeof(struct ipv4_hdr) + sizeof(struct esp_hdr); + uint32_t taillen = sizeof(struct esp_tail); + uint32_t t_len = len + hdrlen + taillen; + uint32_t padlen; + + struct esp_hdr esph = { + .spi = rte_cpu_to_be_32(spi), + .seq = rte_cpu_to_be_32(seq) + }; + + padlen = RTE_ALIGN(t_len, 4) - t_len; + t_len += padlen; + + struct esp_tail espt = { + .pad_len = padlen, + .next_proto = IPPROTO_IPIP, + }; + + if (m == NULL) + return NULL; + + memset(m->buf_addr, 0, m->buf_len); + char *dst = rte_pktmbuf_append(m, t_len); + + if (!dst) { + rte_pktmbuf_free(m); + return NULL; + } + /* copy outer IP and ESP header */ + ipv4_outer.total_length = rte_cpu_to_be_16(t_len); + ipv4_outer.packet_id = rte_cpu_to_be_16(seq); + rte_memcpy(dst, &ipv4_outer, sizeof(ipv4_outer)); + dst += sizeof(ipv4_outer); + m->l3_len = sizeof(ipv4_outer); + rte_memcpy(dst, &esph, sizeof(esph)); + dst += sizeof(esph); + + if (string != NULL) { + /* copy payload */ + rte_memcpy(dst, string, len); + dst += len; + /* copy pad bytes */ + rte_memcpy(dst, esp_pad_bytes, padlen); + dst += padlen; + /* copy ESP tail header */ + rte_memcpy(dst, &espt, sizeof(espt)); + } else + memset(dst, 0, t_len); + + return m; +} + +static int +create_dummy_sec_session(struct ipsec_unitest_params *ut, + struct rte_cryptodev_qp_conf *qp, uint32_t j) +{ + static struct rte_security_session_conf conf; + + ut->ss[j].security.ses = rte_security_session_create(&dummy_sec_ctx, + &conf, qp->mp_session_private); + + if (ut->ss[j].security.ses == NULL) + return -ENOMEM; + + ut->ss[j].security.ctx = &dummy_sec_ctx; + ut->ss[j].security.ol_flags = 0; + return 0; +} + +static int +create_crypto_session(struct ipsec_unitest_params *ut, + struct rte_cryptodev_qp_conf *qp, uint8_t dev_id, uint32_t j) +{ + int32_t rc; + struct rte_cryptodev_sym_session *s; + + s = rte_cryptodev_sym_session_create(qp->mp_session); + if (s == NULL) + return -ENOMEM; + + /* initiliaze SA crypto session for device */ + rc = rte_cryptodev_sym_session_init(dev_id, s, + ut->crypto_xforms, qp->mp_session_private); + if (rc == 0) { + ut->ss[j].crypto.ses = s; + return 0; + } else { + /* failure, do cleanup */ + rte_cryptodev_sym_session_clear(dev_id, s); + rte_cryptodev_sym_session_free(s); + return rc; + } +} + +static int +create_session(struct ipsec_unitest_params *ut, + struct rte_cryptodev_qp_conf *qp, uint8_t crypto_dev, uint32_t j) +{ + if (ut->ss[j].type == RTE_SECURITY_ACTION_TYPE_NONE) + return create_crypto_session(ut, qp, crypto_dev, j); + else + return create_dummy_sec_session(ut, qp, j); +} + +static int +fill_ipsec_param(uint32_t replay_win_sz, uint64_t flags) +{ + struct ipsec_unitest_params *ut_params = &unittest_params; + struct rte_ipsec_sa_prm *prm = &ut_params->sa_prm; + const struct supported_auth_algo *auth_algo; + const struct supported_cipher_algo *cipher_algo; + + memset(prm, 0, sizeof(*prm)); + + prm->userdata = 1; + prm->flags = flags; + prm->replay_win_sz = replay_win_sz; + + /* setup ipsec xform */ + prm->ipsec_xform = ut_params->ipsec_xform; + prm->ipsec_xform.salt = (uint32_t)rte_rand(); + + /* setup tunnel related fields */ + prm->tun.hdr_len = sizeof(ipv4_outer); + prm->tun.next_proto = IPPROTO_IPIP; + prm->tun.hdr = &ipv4_outer; + + /* setup crypto section */ + if (uparams.aead != 0) { + /* TODO: will need to fill out with other test cases */ + } else { + if (uparams.auth == 0 && uparams.cipher == 0) + return TEST_FAILED; + + auth_algo = find_match_auth_algo(uparams.auth_algo); + cipher_algo = find_match_cipher_algo(uparams.cipher_algo); + + fill_crypto_xform(ut_params, auth_algo, cipher_algo); + } + + prm->crypto_xform = ut_params->crypto_xforms; + return TEST_SUCCESS; +} + +static int +create_sa(enum rte_security_session_action_type action_type, + uint32_t replay_win_sz, uint64_t flags, uint32_t j) +{ + struct ipsec_testsuite_params *ts = &testsuite_params; + struct ipsec_unitest_params *ut = &unittest_params; + size_t sz; + int rc; + + memset(&ut->ss[j], 0, sizeof(ut->ss[j])); + + rc = fill_ipsec_param(replay_win_sz, flags); + if (rc != 0) + return TEST_FAILED; + + /* create rte_ipsec_sa*/ + sz = rte_ipsec_sa_size(&ut->sa_prm); + TEST_ASSERT(sz > 0, "rte_ipsec_sa_size() failed\n"); + + ut->ss[j].sa = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE); + TEST_ASSERT_NOT_NULL(ut->ss[j].sa, + "failed to allocate memory for rte_ipsec_sa\n"); + + ut->ss[j].type = action_type; + rc = create_session(ut, &ts->qp_conf, ts->valid_dev, j); + if (rc != 0) + return TEST_FAILED; + + rc = rte_ipsec_sa_init(ut->ss[j].sa, &ut->sa_prm, sz); + rc = (rc > 0 && (uint32_t)rc <= sz) ? 0 : -EINVAL; + if (rc == 0) + rc = rte_ipsec_session_prepare(&ut->ss[j]); + + return rc; +} + +static int +crypto_ipsec(uint16_t num_pkts) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint32_t k, ng; + struct rte_ipsec_group grp[1]; + + /* call crypto prepare */ + k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[0], ut_params->ibuf, + ut_params->cop, num_pkts); + if (k != num_pkts) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n"); + return TEST_FAILED; + } + k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0, + ut_params->cop, num_pkts); + if (k != num_pkts) { + RTE_LOG(ERR, USER1, "rte_cryptodev_enqueue_burst fail\n"); + return TEST_FAILED; + } + + k = rte_cryptodev_dequeue_burst(ts_params->valid_dev, 0, + ut_params->cop, num_pkts); + if (k != num_pkts) { + RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n"); + return TEST_FAILED; + } + + ng = rte_ipsec_pkt_crypto_group( + (const struct rte_crypto_op **)(uintptr_t)ut_params->cop, + ut_params->obuf, grp, num_pkts); + if (ng != 1 || + grp[0].m[0] != ut_params->obuf[0] || + grp[0].cnt != num_pkts || + grp[0].id.ptr != &ut_params->ss[0]) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail\n"); + return TEST_FAILED; + } + + /* call crypto process */ + k = rte_ipsec_pkt_process(grp[0].id.ptr, grp[0].m, grp[0].cnt); + if (k != num_pkts) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n"); + return TEST_FAILED; + } + + return TEST_SUCCESS; +} + +static int +lksd_proto_ipsec(uint16_t num_pkts) +{ + struct ipsec_unitest_params *ut_params = &unittest_params; + uint32_t i, k, ng; + struct rte_ipsec_group grp[1]; + + /* call crypto prepare */ + k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[0], ut_params->ibuf, + ut_params->cop, num_pkts); + if (k != num_pkts) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n"); + return TEST_FAILED; + } + + /* check crypto ops */ + for (i = 0; i != num_pkts; i++) { + TEST_ASSERT_EQUAL(ut_params->cop[i]->type, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, + "%s: invalid crypto op type for %u-th packet\n", + __func__, i); + TEST_ASSERT_EQUAL(ut_params->cop[i]->status, + RTE_CRYPTO_OP_STATUS_NOT_PROCESSED, + "%s: invalid crypto op status for %u-th packet\n", + __func__, i); + TEST_ASSERT_EQUAL(ut_params->cop[i]->sess_type, + RTE_CRYPTO_OP_SECURITY_SESSION, + "%s: invalid crypto op sess_type for %u-th packet\n", + __func__, i); + TEST_ASSERT_EQUAL(ut_params->cop[i]->sym->m_src, + ut_params->ibuf[i], + "%s: invalid crypto op m_src for %u-th packet\n", + __func__, i); + } + + /* update crypto ops, pretend all finished ok */ + for (i = 0; i != num_pkts; i++) + ut_params->cop[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + + ng = rte_ipsec_pkt_crypto_group( + (const struct rte_crypto_op **)(uintptr_t)ut_params->cop, + ut_params->obuf, grp, num_pkts); + if (ng != 1 || + grp[0].m[0] != ut_params->obuf[0] || + grp[0].cnt != num_pkts || + grp[0].id.ptr != &ut_params->ss[0]) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail\n"); + return TEST_FAILED; + } + + /* call crypto process */ + k = rte_ipsec_pkt_process(grp[0].id.ptr, grp[0].m, grp[0].cnt); + if (k != num_pkts) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n"); + return TEST_FAILED; + } + + return TEST_SUCCESS; +} + +static int +crypto_ipsec_2sa(void) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + struct rte_ipsec_group grp[BURST_SIZE]; + + uint32_t k, ng, i, r; + + for (i = 0; i < BURST_SIZE; i++) { + r = i % 2; + /* call crypto prepare */ + k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[r], + ut_params->ibuf + i, ut_params->cop + i, 1); + if (k != 1) { + RTE_LOG(ERR, USER1, + "rte_ipsec_pkt_crypto_prepare fail\n"); + return TEST_FAILED; + } + k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0, + ut_params->cop + i, 1); + if (k != 1) { + RTE_LOG(ERR, USER1, + "rte_cryptodev_enqueue_burst fail\n"); + return TEST_FAILED; + } + } + + k = rte_cryptodev_dequeue_burst(ts_params->valid_dev, 0, + ut_params->cop, BURST_SIZE); + if (k != BURST_SIZE) { + RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n"); + return TEST_FAILED; + } + + ng = rte_ipsec_pkt_crypto_group( + (const struct rte_crypto_op **)(uintptr_t)ut_params->cop, + ut_params->obuf, grp, BURST_SIZE); + if (ng != BURST_SIZE) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail ng=%d\n", + ng); + return TEST_FAILED; + } + + /* call crypto process */ + for (i = 0; i < ng; i++) { + k = rte_ipsec_pkt_process(grp[i].id.ptr, grp[i].m, grp[i].cnt); + if (k != grp[i].cnt) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n"); + return TEST_FAILED; + } + } + return TEST_SUCCESS; +} + +#define PKT_4 4 +#define PKT_12 12 +#define PKT_21 21 + +static uint32_t +crypto_ipsec_4grp(uint32_t pkt_num) +{ + uint32_t sa_ind; + + /* group packets in 4 different size groups groups, 2 per SA */ + if (pkt_num < PKT_4) + sa_ind = 0; + else if (pkt_num < PKT_12) + sa_ind = 1; + else if (pkt_num < PKT_21) + sa_ind = 0; + else + sa_ind = 1; + + return sa_ind; +} + +static uint32_t +crypto_ipsec_4grp_check_mbufs(uint32_t grp_ind, struct rte_ipsec_group *grp) +{ + struct ipsec_unitest_params *ut_params = &unittest_params; + uint32_t i, j; + uint32_t rc = 0; + + if (grp_ind == 0) { + for (i = 0, j = 0; i < PKT_4; i++, j++) + if (grp[grp_ind].m[i] != ut_params->obuf[j]) { + rc = TEST_FAILED; + break; + } + } else if (grp_ind == 1) { + for (i = 0, j = PKT_4; i < (PKT_12 - PKT_4); i++, j++) { + if (grp[grp_ind].m[i] != ut_params->obuf[j]) { + rc = TEST_FAILED; + break; + } + } + } else if (grp_ind == 2) { + for (i = 0, j = PKT_12; i < (PKT_21 - PKT_12); i++, j++) + if (grp[grp_ind].m[i] != ut_params->obuf[j]) { + rc = TEST_FAILED; + break; + } + } else if (grp_ind == 3) { + for (i = 0, j = PKT_21; i < (BURST_SIZE - PKT_21); i++, j++) + if (grp[grp_ind].m[i] != ut_params->obuf[j]) { + rc = TEST_FAILED; + break; + } + } else + rc = TEST_FAILED; + + return rc; +} + +static uint32_t +crypto_ipsec_4grp_check_cnt(uint32_t grp_ind, struct rte_ipsec_group *grp) +{ + uint32_t rc = 0; + + if (grp_ind == 0) { + if (grp[grp_ind].cnt != PKT_4) + rc = TEST_FAILED; + } else if (grp_ind == 1) { + if (grp[grp_ind].cnt != PKT_12 - PKT_4) + rc = TEST_FAILED; + } else if (grp_ind == 2) { + if (grp[grp_ind].cnt != PKT_21 - PKT_12) + rc = TEST_FAILED; + } else if (grp_ind == 3) { + if (grp[grp_ind].cnt != BURST_SIZE - PKT_21) + rc = TEST_FAILED; + } else + rc = TEST_FAILED; + + return rc; +} + +static int +crypto_ipsec_2sa_4grp(void) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + struct rte_ipsec_group grp[BURST_SIZE]; + uint32_t k, ng, i, j; + uint32_t rc = 0; + + for (i = 0; i < BURST_SIZE; i++) { + j = crypto_ipsec_4grp(i); + + /* call crypto prepare */ + k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[j], + ut_params->ibuf + i, ut_params->cop + i, 1); + if (k != 1) { + RTE_LOG(ERR, USER1, + "rte_ipsec_pkt_crypto_prepare fail\n"); + return TEST_FAILED; + } + k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0, + ut_params->cop + i, 1); + if (k != 1) { + RTE_LOG(ERR, USER1, + "rte_cryptodev_enqueue_burst fail\n"); + return TEST_FAILED; + } + } + + k = rte_cryptodev_dequeue_burst(ts_params->valid_dev, 0, + ut_params->cop, BURST_SIZE); + if (k != BURST_SIZE) { + RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n"); + return TEST_FAILED; + } + + ng = rte_ipsec_pkt_crypto_group( + (const struct rte_crypto_op **)(uintptr_t)ut_params->cop, + ut_params->obuf, grp, BURST_SIZE); + if (ng != 4) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail ng=%d\n", + ng); + return TEST_FAILED; + } + + /* call crypto process */ + for (i = 0; i < ng; i++) { + k = rte_ipsec_pkt_process(grp[i].id.ptr, grp[i].m, grp[i].cnt); + if (k != grp[i].cnt) { + RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n"); + return TEST_FAILED; + } + rc = crypto_ipsec_4grp_check_cnt(i, grp); + if (rc != 0) { + RTE_LOG(ERR, USER1, + "crypto_ipsec_4grp_check_cnt fail\n"); + return TEST_FAILED; + } + rc = crypto_ipsec_4grp_check_mbufs(i, grp); + if (rc != 0) { + RTE_LOG(ERR, USER1, + "crypto_ipsec_4grp_check_mbufs fail\n"); + return TEST_FAILED; + } + } + return TEST_SUCCESS; +} + +static void +test_ipsec_reorder_inb_pkt_burst(uint16_t num_pkts) +{ + struct ipsec_unitest_params *ut_params = &unittest_params; + struct rte_mbuf *ibuf_tmp[BURST_SIZE]; + uint16_t j; + + /* reorder packets and create gaps in sequence numbers */ + static const uint32_t reorder[BURST_SIZE] = { + 24, 25, 26, 27, 28, 29, 30, 31, + 16, 17, 18, 19, 20, 21, 22, 23, + 8, 9, 10, 11, 12, 13, 14, 15, + 0, 1, 2, 3, 4, 5, 6, 7, + }; + + if (num_pkts != BURST_SIZE) + return; + + for (j = 0; j != BURST_SIZE; j++) + ibuf_tmp[j] = ut_params->ibuf[reorder[j]]; + + memcpy(ut_params->ibuf, ibuf_tmp, sizeof(ut_params->ibuf)); +} + +static int +test_ipsec_crypto_op_alloc(uint16_t num_pkts) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + int rc = 0; + uint16_t j; + + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->cop[j] = rte_crypto_op_alloc(ts_params->cop_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + if (ut_params->cop[j] == NULL) { + RTE_LOG(ERR, USER1, + "Failed to allocate symmetric crypto op\n"); + rc = TEST_FAILED; + } + } + + return rc; +} + +static void +test_ipsec_dump_buffers(struct ipsec_unitest_params *ut_params, int i) +{ + uint16_t j = ut_params->pkt_index; + + printf("\ntest config: num %d\n", i); + printf(" replay_win_sz %u\n", test_cfg[i].replay_win_sz); + printf(" esn %u\n", test_cfg[i].esn); + printf(" flags 0x%" PRIx64 "\n", test_cfg[i].flags); + printf(" pkt_sz %zu\n", test_cfg[i].pkt_sz); + printf(" num_pkts %u\n\n", test_cfg[i].num_pkts); + + if (ut_params->ibuf[j]) { + printf("ibuf[%u] data:\n", j); + rte_pktmbuf_dump(stdout, ut_params->ibuf[j], + ut_params->ibuf[j]->data_len); + } + if (ut_params->obuf[j]) { + printf("obuf[%u] data:\n", j); + rte_pktmbuf_dump(stdout, ut_params->obuf[j], + ut_params->obuf[j]->data_len); + } + if (ut_params->testbuf[j]) { + printf("testbuf[%u] data:\n", j); + rte_pktmbuf_dump(stdout, ut_params->testbuf[j], + ut_params->testbuf[j]->data_len); + } +} + +static void +destroy_sa(uint32_t j) +{ + struct ipsec_unitest_params *ut = &unittest_params; + + rte_ipsec_sa_fini(ut->ss[j].sa); + rte_free(ut->ss[j].sa); + rte_cryptodev_sym_session_free(ut->ss[j].crypto.ses); + memset(&ut->ss[j], 0, sizeof(ut->ss[j])); +} + +static int +crypto_inb_burst_null_null_check(struct ipsec_unitest_params *ut_params, int i, + uint16_t num_pkts) +{ + uint16_t j; + + for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) { + ut_params->pkt_index = j; + + /* compare the data buffers */ + TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data, + rte_pktmbuf_mtod(ut_params->obuf[j], void *), + test_cfg[i].pkt_sz, + "input and output data does not match\n"); + TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, + ut_params->obuf[j]->pkt_len, + "data_len is not equal to pkt_len"); + TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, + test_cfg[i].pkt_sz, + "data_len is not equal to input data"); + } + + return 0; +} + +static int +test_ipsec_crypto_inb_burst_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j; + int rc; + + /* create rte_ipsec_sa */ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate test mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + /* packet with sequence number 0 is invalid */ + ut_params->ibuf[j] = setup_test_string_tunneled( + ts_params->mbuf_pool, null_encrypted_data, + test_cfg[i].pkt_sz, INBOUND_SPI, j + 1); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + } + + if (rc == 0) { + if (test_cfg[i].reorder_pkts) + test_ipsec_reorder_inb_pkt_burst(num_pkts); + rc = test_ipsec_crypto_op_alloc(num_pkts); + } + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(num_pkts); + if (rc == 0) + rc = crypto_inb_burst_null_null_check( + ut_params, i, num_pkts); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + return rc; +} + +static int +test_ipsec_crypto_inb_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_crypto_inb_burst_null_null(i); + } + + return rc; +} + +static int +crypto_outb_burst_null_null_check(struct ipsec_unitest_params *ut_params, + uint16_t num_pkts) +{ + void *obuf_data; + void *testbuf_data; + uint16_t j; + + for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) { + ut_params->pkt_index = j; + + testbuf_data = rte_pktmbuf_mtod(ut_params->testbuf[j], void *); + obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *); + /* compare the buffer data */ + TEST_ASSERT_BUFFERS_ARE_EQUAL(testbuf_data, obuf_data, + ut_params->obuf[j]->pkt_len, + "test and output data does not match\n"); + TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, + ut_params->testbuf[j]->data_len, + "obuf data_len is not equal to testbuf data_len"); + TEST_ASSERT_EQUAL(ut_params->obuf[j]->pkt_len, + ut_params->testbuf[j]->pkt_len, + "obuf pkt_len is not equal to testbuf pkt_len"); + } + + return 0; +} + +static int +test_ipsec_crypto_outb_burst_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j; + int32_t rc; + + /* create rte_ipsec_sa*/ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate input mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + else { + /* Generate test mbuf data */ + /* packet with sequence number 0 is invalid */ + ut_params->testbuf[j] = setup_test_string_tunneled( + ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, + OUTBOUND_SPI, j + 1); + if (ut_params->testbuf[j] == NULL) + rc = TEST_FAILED; + } + } + + if (rc == 0) + rc = test_ipsec_crypto_op_alloc(num_pkts); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(num_pkts); + if (rc == 0) + rc = crypto_outb_burst_null_null_check(ut_params, + num_pkts); + else + RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", + i); + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + return rc; +} + +static int +test_ipsec_crypto_outb_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = OUTBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_crypto_outb_burst_null_null(i); + } + + return rc; +} + +static int +inline_inb_burst_null_null_check(struct ipsec_unitest_params *ut_params, int i, + uint16_t num_pkts) +{ + void *ibuf_data; + void *obuf_data; + uint16_t j; + + for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) { + ut_params->pkt_index = j; + + /* compare the buffer data */ + ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf[j], void *); + obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *); + + TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data, + ut_params->ibuf[j]->data_len, + "input and output data does not match\n"); + TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len, + ut_params->obuf[j]->data_len, + "ibuf data_len is not equal to obuf data_len"); + TEST_ASSERT_EQUAL(ut_params->ibuf[j]->pkt_len, + ut_params->obuf[j]->pkt_len, + "ibuf pkt_len is not equal to obuf pkt_len"); + TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len, + test_cfg[i].pkt_sz, + "data_len is not equal input data"); + } + return 0; +} + +static int +test_ipsec_inline_crypto_inb_burst_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j; + int32_t rc; + uint32_t n; + + /* create rte_ipsec_sa*/ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate inbound mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->ibuf[j] = setup_test_string_tunneled( + ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, + INBOUND_SPI, j + 1); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + else { + /* Generate test mbuf data */ + ut_params->obuf[j] = setup_test_string( + ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, 0); + if (ut_params->obuf[j] == NULL) + rc = TEST_FAILED; + } + } + + if (rc == 0) { + n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf, + num_pkts); + if (n == num_pkts) + rc = inline_inb_burst_null_null_check(ut_params, i, + num_pkts); + else { + RTE_LOG(ERR, USER1, + "rte_ipsec_pkt_process failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + return rc; +} + +static int +test_ipsec_inline_crypto_inb_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_inline_crypto_inb_burst_null_null(i); + } + + return rc; +} + +static int +test_ipsec_inline_proto_inb_burst_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j; + int32_t rc; + uint32_t n; + + /* create rte_ipsec_sa*/ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate inbound mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->ibuf[j] = setup_test_string( + ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + else { + /* Generate test mbuf data */ + ut_params->obuf[j] = setup_test_string( + ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, 0); + if (ut_params->obuf[j] == NULL) + rc = TEST_FAILED; + } + } + + if (rc == 0) { + n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf, + num_pkts); + if (n == num_pkts) + rc = inline_inb_burst_null_null_check(ut_params, i, + num_pkts); + else { + RTE_LOG(ERR, USER1, + "rte_ipsec_pkt_process failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + return rc; +} + +static int +test_ipsec_inline_proto_inb_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_inline_proto_inb_burst_null_null(i); + } + + return rc; +} + +static int +inline_outb_burst_null_null_check(struct ipsec_unitest_params *ut_params, + uint16_t num_pkts) +{ + void *obuf_data; + void *ibuf_data; + uint16_t j; + + for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) { + ut_params->pkt_index = j; + + /* compare the buffer data */ + ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf[j], void *); + obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *); + TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data, + ut_params->ibuf[j]->data_len, + "input and output data does not match\n"); + TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len, + ut_params->obuf[j]->data_len, + "ibuf data_len is not equal to obuf data_len"); + TEST_ASSERT_EQUAL(ut_params->ibuf[j]->pkt_len, + ut_params->obuf[j]->pkt_len, + "ibuf pkt_len is not equal to obuf pkt_len"); + + /* check mbuf ol_flags */ + TEST_ASSERT(ut_params->ibuf[j]->ol_flags & PKT_TX_SEC_OFFLOAD, + "ibuf PKT_TX_SEC_OFFLOAD is not set"); + } + return 0; +} + +static int +test_ipsec_inline_crypto_outb_burst_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j; + int32_t rc; + uint32_t n; + + /* create rte_ipsec_sa */ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate test mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + + if (rc == 0) { + /* Generate test tunneled mbuf data for comparison */ + ut_params->obuf[j] = setup_test_string_tunneled( + ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, + OUTBOUND_SPI, j + 1); + if (ut_params->obuf[j] == NULL) + rc = TEST_FAILED; + } + } + + if (rc == 0) { + n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf, + num_pkts); + if (n == num_pkts) + rc = inline_outb_burst_null_null_check(ut_params, + num_pkts); + else { + RTE_LOG(ERR, USER1, + "rte_ipsec_pkt_process failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + return rc; +} + +static int +test_ipsec_inline_crypto_outb_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = OUTBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_inline_crypto_outb_burst_null_null(i); + } + + return rc; +} + +static int +test_ipsec_inline_proto_outb_burst_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j; + int32_t rc; + uint32_t n; + + /* create rte_ipsec_sa */ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate test mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + + if (rc == 0) { + /* Generate test tunneled mbuf data for comparison */ + ut_params->obuf[j] = setup_test_string( + ts_params->mbuf_pool, + null_plain_data, test_cfg[i].pkt_sz, 0); + if (ut_params->obuf[j] == NULL) + rc = TEST_FAILED; + } + } + + if (rc == 0) { + n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf, + num_pkts); + if (n == num_pkts) + rc = inline_outb_burst_null_null_check(ut_params, + num_pkts); + else { + RTE_LOG(ERR, USER1, + "rte_ipsec_pkt_process failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + return rc; +} + +static int +test_ipsec_inline_proto_outb_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = OUTBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_inline_proto_outb_burst_null_null(i); + } + + return rc; +} + +static int +test_ipsec_lksd_proto_inb_burst_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j; + int rc; + + /* create rte_ipsec_sa */ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate test mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + /* packet with sequence number 0 is invalid */ + ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, + null_encrypted_data, test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + } + + if (rc == 0) { + if (test_cfg[i].reorder_pkts) + test_ipsec_reorder_inb_pkt_burst(num_pkts); + rc = test_ipsec_crypto_op_alloc(num_pkts); + } + + if (rc == 0) { + /* call ipsec library api */ + rc = lksd_proto_ipsec(num_pkts); + if (rc == 0) + rc = crypto_inb_burst_null_null_check(ut_params, i, + num_pkts); + else { + RTE_LOG(ERR, USER1, "%s failed, cfg %d\n", + __func__, i); + rc = TEST_FAILED; + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + return rc; +} + +static int +test_ipsec_lksd_proto_inb_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_lksd_proto_inb_burst_null_null(i); + } + + return rc; +} + +static int +test_ipsec_lksd_proto_outb_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_lksd_proto_inb_burst_null_null(i); + } + + return rc; +} + +static int +replay_inb_null_null_check(struct ipsec_unitest_params *ut_params, int i, + int num_pkts) +{ + uint16_t j; + + for (j = 0; j < num_pkts; j++) { + /* compare the buffer data */ + TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data, + rte_pktmbuf_mtod(ut_params->obuf[j], void *), + test_cfg[i].pkt_sz, + "input and output data does not match\n"); + + TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, + ut_params->obuf[j]->pkt_len, + "data_len is not equal to pkt_len"); + } + + return 0; +} + +static int +test_ipsec_replay_inb_inside_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + int rc; + + /* create rte_ipsec_sa*/ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate inbound mbuf data */ + ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool, + null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + else + rc = test_ipsec_crypto_op_alloc(1); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(1); + if (rc == 0) + rc = replay_inb_null_null_check(ut_params, i, 1); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) { + /* generate packet with seq number inside the replay window */ + if (ut_params->ibuf[0]) { + rte_pktmbuf_free(ut_params->ibuf[0]); + ut_params->ibuf[0] = 0; + } + + ut_params->ibuf[0] = setup_test_string_tunneled( + ts_params->mbuf_pool, null_encrypted_data, + test_cfg[i].pkt_sz, INBOUND_SPI, + test_cfg[i].replay_win_sz); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + else + rc = test_ipsec_crypto_op_alloc(1); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(1); + if (rc == 0) + rc = replay_inb_null_null_check( + ut_params, i, 1); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed\n"); + rc = TEST_FAILED; + } + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + + return rc; +} + +static int +test_ipsec_replay_inb_inside_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_replay_inb_inside_null_null(i); + } + + return rc; +} + +static int +test_ipsec_replay_inb_outside_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + int rc; + + /* create rte_ipsec_sa */ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate test mbuf data */ + ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool, + null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, + test_cfg[i].replay_win_sz + 2); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + else + rc = test_ipsec_crypto_op_alloc(1); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(1); + if (rc == 0) + rc = replay_inb_null_null_check(ut_params, i, 1); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) { + /* generate packet with seq number outside the replay window */ + if (ut_params->ibuf[0]) { + rte_pktmbuf_free(ut_params->ibuf[0]); + ut_params->ibuf[0] = 0; + } + ut_params->ibuf[0] = setup_test_string_tunneled( + ts_params->mbuf_pool, null_encrypted_data, + test_cfg[i].pkt_sz, INBOUND_SPI, 1); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + else + rc = test_ipsec_crypto_op_alloc(1); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(1); + if (rc == 0) { + if (test_cfg[i].esn == 0) { + RTE_LOG(ERR, USER1, + "packet is not outside the replay window, cfg %d pkt0_seq %u pkt1_seq %u\n", + i, + test_cfg[i].replay_win_sz + 2, + 1); + rc = TEST_FAILED; + } + } else { + RTE_LOG(ERR, USER1, + "packet is outside the replay window, cfg %d pkt0_seq %u pkt1_seq %u\n", + i, test_cfg[i].replay_win_sz + 2, 1); + rc = 0; + } + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + + return rc; +} + +static int +test_ipsec_replay_inb_outside_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_replay_inb_outside_null_null(i); + } + + return rc; +} + +static int +test_ipsec_replay_inb_repeat_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + int rc; + + /* create rte_ipsec_sa */ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", i); + return TEST_FAILED; + } + + /* Generate test mbuf data */ + ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool, + null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + else + rc = test_ipsec_crypto_op_alloc(1); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(1); + if (rc == 0) + rc = replay_inb_null_null_check(ut_params, i, 1); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) { + /* + * generate packet with repeat seq number in the replay + * window + */ + if (ut_params->ibuf[0]) { + rte_pktmbuf_free(ut_params->ibuf[0]); + ut_params->ibuf[0] = 0; + } + + ut_params->ibuf[0] = setup_test_string_tunneled( + ts_params->mbuf_pool, null_encrypted_data, + test_cfg[i].pkt_sz, INBOUND_SPI, 1); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + else + rc = test_ipsec_crypto_op_alloc(1); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(1); + if (rc == 0) { + RTE_LOG(ERR, USER1, + "packet is not repeated in the replay window, cfg %d seq %u\n", + i, 1); + rc = TEST_FAILED; + } else { + RTE_LOG(ERR, USER1, + "packet is repeated in the replay window, cfg %d seq %u\n", + i, 1); + rc = 0; + } + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + + return rc; +} + +static int +test_ipsec_replay_inb_repeat_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_replay_inb_repeat_null_null(i); + } + + return rc; +} + +static int +test_ipsec_replay_inb_inside_burst_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + int rc; + int j; + + /* create rte_ipsec_sa*/ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* Generate inbound mbuf data */ + ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool, + null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + else + rc = test_ipsec_crypto_op_alloc(1); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(1); + if (rc == 0) + rc = replay_inb_null_null_check(ut_params, i, 1); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) { + /* + * generate packet(s) with seq number(s) inside the + * replay window + */ + if (ut_params->ibuf[0]) { + rte_pktmbuf_free(ut_params->ibuf[0]); + ut_params->ibuf[0] = 0; + } + + for (j = 0; j < num_pkts && rc == 0; j++) { + /* packet with sequence number 1 already processed */ + ut_params->ibuf[j] = setup_test_string_tunneled( + ts_params->mbuf_pool, null_encrypted_data, + test_cfg[i].pkt_sz, INBOUND_SPI, j + 2); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + } + + if (rc == 0) { + if (test_cfg[i].reorder_pkts) + test_ipsec_reorder_inb_pkt_burst(num_pkts); + rc = test_ipsec_crypto_op_alloc(num_pkts); + } + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec(num_pkts); + if (rc == 0) + rc = replay_inb_null_null_check( + ut_params, i, num_pkts); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed\n"); + rc = TEST_FAILED; + } + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + + return rc; +} + +static int +test_ipsec_replay_inb_inside_burst_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_replay_inb_inside_burst_null_null(i); + } + + return rc; +} + + +static int +crypto_inb_burst_2sa_null_null_check(struct ipsec_unitest_params *ut_params, + int i) +{ + uint16_t j; + + for (j = 0; j < BURST_SIZE; j++) { + ut_params->pkt_index = j; + + /* compare the data buffers */ + TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data, + rte_pktmbuf_mtod(ut_params->obuf[j], void *), + test_cfg[i].pkt_sz, + "input and output data does not match\n"); + TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, + ut_params->obuf[j]->pkt_len, + "data_len is not equal to pkt_len"); + TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, + test_cfg[i].pkt_sz, + "data_len is not equal to input data"); + } + + return 0; +} + +static int +test_ipsec_crypto_inb_burst_2sa_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j, r; + int rc = 0; + + if (num_pkts != BURST_SIZE) + return rc; + + /* create rte_ipsec_sa */ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* create second rte_ipsec_sa */ + ut_params->ipsec_xform.spi = INBOUND_SPI + 1; + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 1); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + destroy_sa(0); + return TEST_FAILED; + } + + /* Generate test mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + r = j % 2; + /* packet with sequence number 0 is invalid */ + ut_params->ibuf[j] = setup_test_string_tunneled( + ts_params->mbuf_pool, null_encrypted_data, + test_cfg[i].pkt_sz, INBOUND_SPI + r, j + 1); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + } + + if (rc == 0) + rc = test_ipsec_crypto_op_alloc(num_pkts); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec_2sa(); + if (rc == 0) + rc = crypto_inb_burst_2sa_null_null_check( + ut_params, i); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + destroy_sa(1); + return rc; +} + +static int +test_ipsec_crypto_inb_burst_2sa_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_crypto_inb_burst_2sa_null_null(i); + } + + return rc; +} + +static int +test_ipsec_crypto_inb_burst_2sa_4grp_null_null(int i) +{ + struct ipsec_testsuite_params *ts_params = &testsuite_params; + struct ipsec_unitest_params *ut_params = &unittest_params; + uint16_t num_pkts = test_cfg[i].num_pkts; + uint16_t j, k; + int rc = 0; + + if (num_pkts != BURST_SIZE) + return rc; + + /* create rte_ipsec_sa */ + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + return TEST_FAILED; + } + + /* create second rte_ipsec_sa */ + ut_params->ipsec_xform.spi = INBOUND_SPI + 1; + rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, + test_cfg[i].replay_win_sz, test_cfg[i].flags, 1); + if (rc != 0) { + RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", + i); + destroy_sa(0); + return TEST_FAILED; + } + + /* Generate test mbuf data */ + for (j = 0; j < num_pkts && rc == 0; j++) { + k = crypto_ipsec_4grp(j); + + /* packet with sequence number 0 is invalid */ + ut_params->ibuf[j] = setup_test_string_tunneled( + ts_params->mbuf_pool, null_encrypted_data, + test_cfg[i].pkt_sz, INBOUND_SPI + k, j + 1); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + } + + if (rc == 0) + rc = test_ipsec_crypto_op_alloc(num_pkts); + + if (rc == 0) { + /* call ipsec library api */ + rc = crypto_ipsec_2sa_4grp(); + if (rc == 0) + rc = crypto_inb_burst_2sa_null_null_check( + ut_params, i); + else { + RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", + i); + rc = TEST_FAILED; + } + } + + if (rc == TEST_FAILED) + test_ipsec_dump_buffers(ut_params, i); + + destroy_sa(0); + destroy_sa(1); + return rc; +} + +static int +test_ipsec_crypto_inb_burst_2sa_4grp_null_null_wrapper(void) +{ + int i; + int rc = 0; + struct ipsec_unitest_params *ut_params = &unittest_params; + + ut_params->ipsec_xform.spi = INBOUND_SPI; + ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + for (i = 0; i < num_cfg && rc == 0; i++) { + ut_params->ipsec_xform.options.esn = test_cfg[i].esn; + rc = test_ipsec_crypto_inb_burst_2sa_4grp_null_null(i); + } + + return rc; +} + +static struct unit_test_suite ipsec_testsuite = { + .suite_name = "IPsec NULL Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_crypto_inb_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_crypto_outb_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_inline_crypto_inb_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_inline_crypto_outb_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_inline_proto_inb_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_inline_proto_outb_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_lksd_proto_inb_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_lksd_proto_outb_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_replay_inb_inside_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_replay_inb_outside_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_replay_inb_repeat_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_replay_inb_inside_burst_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_crypto_inb_burst_2sa_null_null_wrapper), + TEST_CASE_ST(ut_setup, ut_teardown, + test_ipsec_crypto_inb_burst_2sa_4grp_null_null_wrapper), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_ipsec(void) +{ + return unit_test_suite_runner(&ipsec_testsuite); +} + +REGISTER_TEST_COMMAND(ipsec_autotest, test_ipsec); diff --git a/app/test/test_kni.c b/app/test/test_kni.c new file mode 100644 index 0000000000..c92c09054f --- /dev/null +++ b/app/test/test_kni.c @@ -0,0 +1,739 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#if !defined(RTE_EXEC_ENV_LINUXAPP) || !defined(RTE_LIBRTE_KNI) + +static int +test_kni(void) +{ + printf("KNI not supported, skipping test\n"); + return TEST_SKIPPED; +} + +#else + +#include +#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 1024 +#define NB_TXD 1024 +#define KNI_TIMEOUT_MS 5000 /* ms */ + +#define IFCONFIG "/sbin/ifconfig " +#define TEST_KNI_PORT "test_kni_port" +#define KNI_MODULE_PATH "/sys/module/rte_kni" +#define KNI_MODULE_PARAM_LO KNI_MODULE_PATH"/parameters/lo_mode" +#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 = { + .txmode = { + .mq_mode = ETH_DCB_NONE, + }, +}; + +static struct rte_kni_ops kni_ops = { + .change_mtu = NULL, + .config_network_if = NULL, + .config_mac_address = NULL, + .config_promiscusity = 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(uint16_t port_id, unsigned int 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; +} + +static int +test_kni_link_change(void) +{ + int ret; + int pid; + + pid = fork(); + if (pid < 0) { + printf("Error: Failed to fork a process\n"); + return -1; + } + + if (pid == 0) { + printf("Starting KNI Link status change tests.\n"); + if (system(IFCONFIG TEST_KNI_PORT" up") == -1) { + ret = -1; + goto error; + } + + ret = rte_kni_update_link(test_kni_ctx, 1); + if (ret < 0) { + printf("Failed to change link state to Up ret=%d.\n", + ret); + goto error; + } + rte_delay_ms(1000); + printf("KNI: Set LINKUP, previous state=%d\n", ret); + + ret = rte_kni_update_link(test_kni_ctx, 0); + if (ret != 1) { + printf( + "Failed! Previous link state should be 1, returned %d.\n", + ret); + goto error; + } + rte_delay_ms(1000); + printf("KNI: Set LINKDOWN, previous state=%d\n", ret); + + ret = rte_kni_update_link(test_kni_ctx, 1); + if (ret != 0) { + printf( + "Failed! Previous link state should be 0, returned %d.\n", + ret); + goto error; + } + printf("KNI: Set LINKUP, previous state=%d\n", ret); + + ret = 0; + rte_delay_ms(1000); + +error: + if (system(IFCONFIG TEST_KNI_PORT" down") == -1) + ret = -1; + + printf("KNI: Link status change tests: %s.\n", + (ret == 0) ? "Passed" : "Failed"); + exit(ret); + } else { + int p_ret, status; + + while (1) { + p_ret = waitpid(pid, &status, WNOHANG); + if (p_ret != 0) { + if (WIFEXITED(status)) + return WEXITSTATUS(status); + return -1; + } + rte_delay_ms(10); + rte_kni_handle_request(test_kni_ctx); + } + } +} +/** + * 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, + .config_mac_address = NULL, + .config_promiscusity = 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(uint16_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; + const struct rte_pci_device *pci_dev; + const struct rte_bus *bus = NULL; + + 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); + if (info.device) + bus = rte_bus_find_by_device(info.device); + if (bus && !strcmp(bus->name, "pci")) { + pci_dev = RTE_DEV_TO_PCI(info.device); + conf.addr = pci_dev->addr; + conf.id = 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 = 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; + } + + ret = test_kni_link_change(); + if (ret != 0) + 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 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; + uint16_t 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; + const struct rte_pci_device *pci_dev; + const struct rte_bus *bus; + FILE *fd; + DIR *dir; + char buf[16]; + + dir = opendir(KNI_MODULE_PATH); + if (!dir) { + if (errno == ENOENT) { + printf("Cannot run UT due to missing rte_kni module\n"); + return TEST_SKIPPED; + } + printf("opendir: %s", strerror(errno)); + return -1; + } + closedir(dir); + + /* 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; + } + + /* 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 */ + fd = fopen(KNI_MODULE_PARAM_LO, "r"); + if (fd == NULL) { + printf("fopen: %s", strerror(errno)); + return -1; + } + memset(&buf, 0, sizeof(buf)); + if (fgets(buf, sizeof(buf), fd)) { + if (!strncmp(buf, "lo_mode_fifo", strlen("lo_mode_fifo")) || + !strncmp(buf, "lo_mode_fifo_skb", + strlen("lo_mode_fifo_skb"))) { + ret = test_kni_processing(port_id, mp); + if (ret < 0) { + fclose(fd); + goto fail; + } + } else + printf("test_kni_processing skipped because of missing rte_kni module lo_mode argument\n"); + } + fclose(fd); + + /* 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); + if (info.device) + bus = rte_bus_find_by_device(info.device); + else + bus = NULL; + if (bus && !strcmp(bus->name, "pci")) { + pci_dev = RTE_DEV_TO_PCI(info.device); + conf.addr = pci_dev->addr; + conf.id = pci_dev->id; + } + conf.group_id = 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); + if (info.device) + bus = rte_bus_find_by_device(info.device); + else + bus = NULL; + if (bus && !strcmp(bus->name, "pci")) { + pci_dev = RTE_DEV_TO_PCI(info.device); + conf.addr = pci_dev->addr; + conf.id = pci_dev->id; + } + conf.group_id = 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; +} + +#endif + +REGISTER_TEST_COMMAND(kni_autotest, test_kni); diff --git a/app/test/test_kvargs.c b/app/test/test_kvargs.c new file mode 100644 index 0000000000..a42056f361 --- /dev/null +++ b/app/test/test_kvargs.c @@ -0,0 +1,227 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2014 6WIND S.A. + */ + +#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); + + /* third test using list as value */ + args = "foo=[0,1],check=value2"; + valid_keys = valid_keys_list; + kvlist = rte_kvargs_parse(args, valid_keys); + if (kvlist == NULL) { + printf("rte_kvargs_parse() error"); + goto fail; + } + if (strcmp(kvlist->pairs[0].value, "[0,1]") != 0) { + printf("wrong value %s", kvlist->pairs[0].value); + goto fail; + } + count = kvlist->count; + if (count != 2) { + printf("invalid count value %d\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 */ + "foo=[1,2", /* no closing bracket in value */ + ",=", /* 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_latencystats.c b/app/test/test_latencystats.c new file mode 100644 index 0000000000..039c508cd1 --- /dev/null +++ b/app/test/test_latencystats.c @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include +#include + +#include +#include "rte_lcore.h" +#include "rte_metrics.h" + +#include "sample_packet_forward.h" +#include "test.h" + +#define NUM_STATS 4 +#define LATENCY_NUM_PACKETS 10 +#define QUEUE_ID 0 + +uint16_t portid; +struct rte_ring *ring; + +struct rte_metric_name lat_stats_strings[] = { + {"min_latency_ns"}, + {"avg_latency_ns"}, + {"max_latency_ns"}, + {"jitter_ns"}, +}; + +/* Test case for latency init with metrics init */ +static int test_latency_init(void) +{ + int ret = 0; + + /* Metrics Initialization */ + rte_metrics_init(rte_socket_id()); + + ret = rte_latencystats_init(1, NULL); + TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_init failed"); + + return TEST_SUCCESS; +} + +/* Test case to update the latency stats */ +static int test_latency_update(void) +{ + int ret = 0; + + ret = rte_latencystats_update(); + TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_update failed"); + + return TEST_SUCCESS; +} + +/* Test case to uninit latency stats */ +static int test_latency_uninit(void) +{ + int ret = 0; + + ret = rte_latencystats_uninit(); + TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_uninit failed"); + + return TEST_SUCCESS; +} + +/* Test case to get names of latency stats */ +static int test_latencystats_get_names(void) +{ + int ret = 0, i = 0; + int size = 0; + struct rte_metric_name names[NUM_STATS]; + struct rte_metric_name wrongnames[NUM_STATS - 2]; + + size_t m_size = sizeof(struct rte_metric_name); + for (i = 0; i < NUM_STATS; i++) + memset(&names[i], 0, m_size); + for (i = 0; i < NUM_STATS - 2; i++) + memset(&wrongnames[i], 0, m_size); + + /* Success Test: Valid names and size */ + size = NUM_STATS; + ret = rte_latencystats_get_names(names, size); + for (i = 0; i <= NUM_STATS; i++) { + if (strcmp(lat_stats_strings[i].name, names[i].name) == 0) + printf(" %s\n", names[i].name); + else + printf("Failed: Names are not matched\n"); + } + TEST_ASSERT((ret == NUM_STATS), "Test Failed to get metrics names"); + + /* Failure Test: Invalid names and valid size */ + ret = rte_latencystats_get_names(NULL, size); + TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the metrics count," + "Actual: %d Expected: %d", ret, NUM_STATS); + + /* Failure Test: Valid names and invalid size */ + size = 0; + ret = rte_latencystats_get_names(names, size); + TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the metrics count," + "Actual: %d Expected: %d", ret, NUM_STATS); + + /* Failure Test: Invalid names (array size lesser than size) */ + size = NUM_STATS + 1; + ret = rte_latencystats_get_names(wrongnames, size); + TEST_ASSERT((ret == NUM_STATS), "Test Failed to get metrics names"); + return TEST_SUCCESS; +} + +/* Test case to get latency stats values */ +static int test_latencystats_get(void) +{ + int ret = 0, i = 0; + int size = 0; + struct rte_metric_value values[NUM_STATS]; + struct rte_metric_value wrongvalues[NUM_STATS - 2]; + + size_t v_size = sizeof(struct rte_metric_value); + for (i = 0; i < NUM_STATS; i++) + memset(&values[i], 0, v_size); + for (i = 0; i < NUM_STATS - 2; i++) + memset(&wrongvalues[i], 0, v_size); + + /* Success Test: Valid values and valid size */ + size = NUM_STATS; + ret = rte_latencystats_get(values, size); + TEST_ASSERT((ret == NUM_STATS), "Test Failed to get latency metrics" + " values"); + + /* Failure Test: Invalid values and valid size */ + ret = rte_latencystats_get(NULL, size); + TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the stats count," + "Actual: %d Expected: %d", ret, NUM_STATS); + + /* Failure Test: Valid values and invalid size */ + size = 0; + ret = rte_latencystats_get(values, size); + TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the stats count," + "Actual: %d Expected: %d", ret, NUM_STATS); + + /* Failure Test: Invalid values(array size lesser than size) + * and invalid size + */ + size = NUM_STATS + 2; + ret = rte_latencystats_get(wrongvalues, size); + TEST_ASSERT(ret == NUM_STATS, "Test Failed to get latency metrics" + " values"); + + return TEST_SUCCESS; +} + +static int test_latency_ring_setup(void) +{ + test_ring_setup(&ring, &portid); + + return TEST_SUCCESS; +} + +static void test_latency_ring_free(void) +{ + test_ring_free(ring); + test_vdev_uninit("net_ring_net_ringa"); +} + +static int test_latency_packet_forward(void) +{ + int ret; + struct rte_mbuf *pbuf[LATENCY_NUM_PACKETS] = { }; + struct rte_mempool *mp; + char poolname[] = "mbuf_pool"; + + ret = test_get_mbuf_from_pool(&mp, pbuf, poolname); + if (ret < 0) { + printf("allocate mbuf pool Failed\n"); + return TEST_FAILED; + } + ret = test_packet_forward(pbuf, portid, QUEUE_ID); + if (ret < 0) + printf("send pkts Failed\n"); + test_put_mbuf_to_pool(mp, pbuf); + + return TEST_SUCCESS; +} + +static struct +unit_test_suite latencystats_testsuite = { + .suite_name = "Latency Stats Unit Test Suite", + .setup = test_latency_ring_setup, + .teardown = test_latency_ring_free, + .unit_test_cases = { + + /* Test Case 1: To check latency init with + * metrics init + */ + TEST_CASE_ST(NULL, NULL, test_latency_init), + + /* Test Case 2: Do packet forwarding for metrics + * calculation and check the latency metrics values + * are updated + */ + TEST_CASE_ST(test_latency_packet_forward, NULL, + test_latency_update), + /* Test Case 3: To check whether latency stats names + * are retrieved + */ + TEST_CASE_ST(NULL, NULL, test_latencystats_get_names), + + /* Test Case 4: To check whether latency stats + * values are retrieved + */ + TEST_CASE_ST(NULL, NULL, test_latencystats_get), + + /* Test Case 5: To check uninit of latency test */ + TEST_CASE_ST(NULL, NULL, test_latency_uninit), + + TEST_CASES_END() + } +}; + +static int test_latencystats(void) +{ + return unit_test_suite_runner(&latencystats_testsuite); +} + +REGISTER_TEST_COMMAND(latencystats_autotest, test_latencystats); diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c new file mode 100644 index 0000000000..0fe1d78eb0 --- /dev/null +++ b/app/test/test_link_bonding.c @@ -0,0 +1,4906 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include "unistd.h" +#include +#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 1024 +#define RX_FREE_THRESH 32 +#define RX_PTHRESH 8 +#define RX_HTHRESH 8 +#define RX_WTHRESH 0 + +#define TX_RING_SIZE 1024 +#define TX_FREE_THRESH 32 +#define TX_PTHRESH 32 +#define TX_HTHRESH 0 +#define TX_WTHRESH 0 +#define TX_RSBIT_THRESH 32 + +#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 ("net_bonding_ut") + +#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 { + int16_t bonded_port_id; + int16_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS]; + uint16_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; + +static struct rte_eth_conf default_pmd_conf = { + .rxmode = { + .mq_mode = ETH_MQ_RX_NONE, + .split_hdr_size = 0, + .max_rx_pkt_len = ETHER_MAX_LEN, + }, + .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, +}; + +static void free_virtualpmd_tx_queue(void); + + + +static int +configure_ethdev(uint16_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; + + uint16_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; + + uint16_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; + uint16_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; + uint16_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; + uint16_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; + uint16_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; + uint16_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 */ + free_virtualpmd_tx_queue(); + 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; + + uint16_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("net_bonding_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, + uint16_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 int +test_bonding_lsc_event_callback(uint16_t port_id __rte_unused, + enum rte_eth_event_type type __rte_unused, + void *param __rte_unused, + void *ret_param __rte_unused) +{ + pthread_mutex_lock(&mutex); + test_lsc_interrupt_count++; + + pthread_cond_signal(&cvar); + pthread_mutex_unlock(&mutex); + + return 0; +} + +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; + uint16_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, uint16_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 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."); + + /* 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 initialise 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 (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; + uint16_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]); + } + + /* 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; + + uint16_t slaves[RTE_MAX_ETHPORTS]; + + int i, 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]); + + /* 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, 0, 1); +} + +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 initialise 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 initialise 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 initialise 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 initialise 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; + + uint16_t slaves[RTE_MAX_ETHPORTS]; + + int i, 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 initialise 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); + + /* 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 initialise 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 initialise 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 initialise 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 initialise 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 initialise 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; + + uint16_t slaves[RTE_MAX_ETHPORTS]; + + int i, 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 initialise 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); + + /* 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 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_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; + + uint16_t slaves[RTE_MAX_ETHPORTS]; + + int i, 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); + + /* 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 new file mode 100644 index 0000000000..e539f078dd --- /dev/null +++ b/app/test/test_link_bonding_mode4.c @@ -0,0 +1,1645 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 1024 +#define TX_RING_SIZE 1024 + +#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 ("net_bonding_m4_bond_dev") + +#define SLAVE_DEV_NAME_FMT ("net_virt_%d") +#define SLAVE_RX_QUEUE_FMT ("net_virt_%d_rx") +#define SLAVE_TX_QUEUE_FMT ("net_virt_%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; + uint16_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, + }, + .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, NULL); +} + +/* + * 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, NULL); +} + +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(uint16_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(uint16_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(uint16_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; + uint16_t slaves[RTE_MAX_ETHPORTS]; + uint16_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(); + uint16_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_avail() - 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 +test_mode4_agg_mode_selection(void) +{ + int retval; + /* Test and verify for Stable mode */ + retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + + retval = rte_eth_bond_8023ad_agg_selection_set( + test_params.bonded_port_id, AGG_STABLE); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bond aggregation mode"); + retval = bond_handshake(); + TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); + + + retval = rte_eth_bond_8023ad_agg_selection_get( + test_params.bonded_port_id); + TEST_ASSERT_EQUAL(retval, AGG_STABLE, + "Wrong agg mode received from bonding device"); + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); + + + /* test and verify for Bandwidth mode */ + retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + + retval = rte_eth_bond_8023ad_agg_selection_set( + test_params.bonded_port_id, + AGG_BANDWIDTH); + TEST_ASSERT_SUCCESS(retval, + "Failed to initialize bond aggregation mode"); + retval = bond_handshake(); + TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); + + retval = rte_eth_bond_8023ad_agg_selection_get( + test_params.bonded_port_id); + TEST_ASSERT_EQUAL(retval, AGG_BANDWIDTH, + "Wrong agg mode received from bonding device"); + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); + + /* test and verify selection for count mode */ + retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + + retval = rte_eth_bond_8023ad_agg_selection_set( + test_params.bonded_port_id, AGG_COUNT); + TEST_ASSERT_SUCCESS(retval, + "Failed to initialize bond aggregation mode"); + retval = bond_handshake(); + TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); + + retval = rte_eth_bond_8023ad_agg_selection_get( + test_params.bonded_port_id); + TEST_ASSERT_EQUAL(retval, AGG_COUNT, + "Wrong agg mode received from bonding device"); + + 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 different 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 aggregate 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 suppose 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; + uint16_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_agg_mode_selection_wrapper(void){ + return test_mode4_executor(&test_mode4_agg_mode_selection); +} + +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_agg_mode_selection", + test_mode4_agg_mode_selection_wrapper), + 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 new file mode 100644 index 0000000000..d82de2cef5 --- /dev/null +++ b/app/test/test_link_bonding_rssconf.c @@ -0,0 +1,639 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015 Intel Corporation + */ + +#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 ("net_bonding_rss") + +#define SLAVE_DEV_NAME_FMT ("net_null%d") +#define SLAVE_RXTX_QUEUE_FMT ("rssconf_slave%d_q%d") + +#define NUM_MBUFS 8191 +#define MBUF_SIZE (1600 + 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 { + uint16_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, + }, + .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, + }, + .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(uint16_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(uint16_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; + struct ether_addr mac_addr = { .addr_bytes = {0} }; + + if (test_params.mbuf_pool == NULL) { + + test_params.mbuf_pool = rte_pktmbuf_pool_create( + "RSS_MBUF_POOL", NUM_MBUFS * SLAVE_COUNT, + MBUF_CACHE_SIZE, 0, MBUF_SIZE, rte_socket_id()); + + TEST_ASSERT(test_params.mbuf_pool != NULL, + "rte_pktmbuf_pool_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_avail(); + snprintf(name, sizeof(name), SLAVE_DEV_NAME_FMT, port_id); + + retval = rte_vdev_init(name, "size=64,copy=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); + + /* assign a non-zero MAC */ + mac_addr.addr_bytes[5] = 0x10 + port->port_id; + rte_eth_dev_default_mac_addr_set(port->port_id, &mac_addr); + + 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 new file mode 100644 index 0000000000..425ae03cb9 --- /dev/null +++ b/app/test/test_logs.c @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* for legacy log test */ +#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_legacy_logs(void) +{ + printf("== static log types\n"); + + /* set logtype level low to so we can test global level */ + rte_log_set_level(RTE_LOGTYPE_TESTAPP1, RTE_LOG_DEBUG); + rte_log_set_level(RTE_LOGTYPE_TESTAPP2, RTE_LOG_DEBUG); + + /* log in error level */ + rte_log_set_global_level(RTE_LOG_ERR); + RTE_LOG(ERR, TESTAPP1, "error message\n"); + RTE_LOG(CRIT, TESTAPP1, "critical message\n"); + + /* log in critical level */ + rte_log_set_global_level(RTE_LOG_CRIT); + RTE_LOG(ERR, TESTAPP2, "error message (not displayed)\n"); + RTE_LOG(CRIT, TESTAPP2, "critical message\n"); + + /* bump up single log type level above global to test it */ + rte_log_set_level(RTE_LOGTYPE_TESTAPP2, RTE_LOG_EMERG); + + /* log in error level */ + rte_log_set_global_level(RTE_LOG_ERR); + RTE_LOG(ERR, TESTAPP1, "error message\n"); + RTE_LOG(ERR, TESTAPP2, "error message (not displayed)\n"); + + return 0; +} + +static int +test_logs(void) +{ + int logtype1, logtype2; + int ret; + + printf("== dynamic log types\n"); + + logtype1 = rte_log_register("logtype1"); + if (logtype1 < 0) { + printf("Cannot register logtype1\n"); + return -1; + } + logtype2 = rte_log_register("logtype2"); + if (logtype2 < 0) { + printf("Cannot register logtype2\n"); + return -1; + } + + /* set logtype level low to so we can test global level */ + rte_log_set_level(logtype1, RTE_LOG_DEBUG); + rte_log_set_level(logtype2, RTE_LOG_DEBUG); + + /* log in error level */ + rte_log_set_global_level(RTE_LOG_ERR); + rte_log(RTE_LOG_ERR, logtype1, "error message\n"); + rte_log(RTE_LOG_CRIT, logtype1, "critical message\n"); + + /* log in critical level */ + rte_log_set_global_level(RTE_LOG_CRIT); + rte_log(RTE_LOG_ERR, logtype2, "error message (not displayed)\n"); + rte_log(RTE_LOG_CRIT, logtype2, "critical message\n"); + + /* bump up single log type level above global to test it */ + rte_log_set_level(logtype2, RTE_LOG_EMERG); + + /* log in error level */ + rte_log_set_global_level(RTE_LOG_ERR); + rte_log(RTE_LOG_ERR, logtype1, "error message\n"); + rte_log(RTE_LOG_ERR, logtype2, "error message (not displayed)\n"); + + ret = test_legacy_logs(); + if (ret < 0) + return ret; + + return 0; +} + +REGISTER_TEST_COMMAND(logs_autotest, test_logs); diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c new file mode 100644 index 0000000000..5d697dd0f6 --- /dev/null +++ b/app/test/test_lpm.c @@ -0,0 +1,1290 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..670aadb40e --- /dev/null +++ b/app/test/test_lpm6.c @@ -0,0 +1,1796 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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); +static int32_t test28(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, + test28, +}; + +#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}; + uint32_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]; + int32_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; + uint32_t 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; + uint32_t 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; + uint32_t 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; + uint32_t 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; + uint32_t 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; + uint32_t 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; + uint32_t 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; + uint32_t 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; + uint32_t 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 = (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; + uint32_t 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; + uint32_t 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; + uint32_t 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; + uint32_t next_hop_add; + int32_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]; + uint32_t next_hop_add; + int32_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; + uint32_t 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; + uint32_t 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; + uint32_t next_hop_ip_10_32 = 100; + uint32_t next_hop_ip_10_24 = 105; + uint32_t next_hop_ip_20_25 = 111; + uint32_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); + 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_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); + 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_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); + 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_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; + uint32_t 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; +} + +/* + * Call add, lookup and delete for a single rule with maximum 21bit next_hop + * size. + * Check that next_hop returned from lookup is equal to provisioned value. + * Delete the rule and check that the same test returs a miss. + */ +int32_t +test28(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; + uint32_t next_hop_add = 0x001FFFFF, 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); + 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 new file mode 100644 index 0000000000..565138a317 --- /dev/null +++ b/app/test/test_lpm6_data.h @@ -0,0 +1,1159 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2016 Intel Corporation + */ +#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 new file mode 100644 index 0000000000..0b43ad824a --- /dev/null +++ b/app/test/test_lpm6_perf.c @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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; + uint32_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]; + int32_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 new file mode 100644 index 0000000000..3b98ce0c84 --- /dev/null +++ b/app/test/test_lpm_perf.c @@ -0,0 +1,484 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..6b6c6fec11 --- /dev/null +++ b/app/test/test_malloc.c @@ -0,0 +1,941 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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; + int overhead = 0; + + /* Dynamically calculate the overhead by allocating one cacheline and + * then comparing what was allocated from the heap. + */ + rte_malloc_get_socket_stats(socket, &pre_stats); + + void *dummy = rte_malloc_socket(NULL, RTE_CACHE_LINE_SIZE, 0, socket); + if (dummy == NULL) + return -1; + + rte_malloc_get_socket_stats(socket, &post_stats); + + /* after subtracting cache line, remainder is overhead */ + overhead = post_stats.heap_allocsz_bytes - pre_stats.heap_allocsz_bytes; + overhead -= RTE_CACHE_LINE_SIZE; + + rte_free(dummy); + + /* Now start the real tests */ + 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; + } + strlcpy(ptr1, hello_str, size1); + 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_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_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; +} + +static int +check_socket_mem(const struct rte_memseg_list *msl, void *arg) +{ + int32_t *socket = arg; + + if (msl->external) + return 0; + + return *socket == msl->socket_id; +} + +/* Check if memory is available on a specific socket */ +static int +is_mem_on_socket(int32_t socket) +{ + return rte_memseg_list_walk(check_socket_mem, &socket); +} + + +/* + * 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_mem_virt2memseg(addr, NULL); + return ms == NULL ? -1 : ms->socket_id; + +} + +/* 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 new file mode 100644 index 0000000000..9e82a20be1 --- /dev/null +++ b/app/test/test_mbuf.c @@ -0,0 +1,1137 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 + +#ifdef RTE_MBUF_REFCNT_ATOMIC + +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(struct rte_mempool *pktmbuf_pool) +{ + 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(struct rte_mempool *pktmbuf_pool) +{ + 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(struct rte_mempool *pktmbuf_pool, + struct rte_mempool *pktmbuf_pool2) +{ + 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(struct rte_mempool *pktmbuf_pool) +{ + 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 efficiency, recommended to run with RTE_LIBRTE_MBUF_DEBUG defined. + */ + +#ifdef RTE_MBUF_REFCNT_ATOMIC + +static int +test_refcnt_slave(void *arg) +{ + unsigned lcore, free; + void *mp = 0; + struct rte_ring *refcnt_mbuf_ring = arg; + + 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(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 int lcore, unsigned int iter, + struct rte_mempool *refcnt_pool, + struct rte_ring *refcnt_mbuf_ring) +{ + 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(struct rte_mempool *refcnt_pool, + struct rte_ring *refcnt_mbuf_ring) +{ + 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_pool, refcnt_mbuf_ring); + + 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; + int ret = -1; + struct rte_mempool *refcnt_pool = NULL; + struct rte_ring *refcnt_mbuf_ring = NULL; + + 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 */ + + refcnt_pool = rte_pktmbuf_pool_create(MAKE_STRING(refcnt_pool), + REFCNT_MBUF_NUM, 0, 0, 0, + SOCKET_ID_ANY); + if (refcnt_pool == NULL) { + printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n", + __func__); + return -1; + } + + refcnt_mbuf_ring = rte_ring_create("refcnt_mbuf_ring", + rte_align32pow2(REFCNT_RING_SIZE), SOCKET_ID_ANY, + RING_F_SP_ENQ); + if (refcnt_mbuf_ring == NULL) { + printf("%s: cannot allocate " MAKE_STRING(refcnt_mbuf_ring) + "\n", __func__); + goto err; + } + + refcnt_stop_slaves = 0; + memset(refcnt_lcore, 0, sizeof (refcnt_lcore)); + + rte_eal_mp_remote_launch(test_refcnt_slave, refcnt_mbuf_ring, + SKIP_MASTER); + + test_refcnt_master(refcnt_pool, refcnt_mbuf_ring); + + 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); + + ret = 0; + +err: + rte_mempool_free(refcnt_pool); + rte_ring_free(refcnt_mbuf_ring); + return ret; +#else + return 0; +#endif +} + +#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(struct rte_mempool *pktmbuf_pool) +{ + 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_iova = 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(struct rte_mempool *pktmbuf_pool, 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(struct rte_mempool *pktmbuf_pool) +{ + 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(pktmbuf_pool, 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) +{ + int ret = -1; + struct rte_mempool *pktmbuf_pool = NULL; + struct rte_mempool *pktmbuf_pool2 = NULL; + + + RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != RTE_CACHE_LINE_MIN_SIZE * 2); + + /* create pktmbuf pool if it does not exist */ + 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"); + goto err; + } + + /* create a specific pktmbuf pool with a priv_size != 0 and no data + * room size */ + 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"); + goto err; + } + + /* test multiple mbuf alloc */ + if (test_pktmbuf_pool(pktmbuf_pool) < 0) { + printf("test_mbuf_pool() failed\n"); + goto err; + } + + /* do it another time to check that all mbufs were freed */ + if (test_pktmbuf_pool(pktmbuf_pool) < 0) { + printf("test_mbuf_pool() failed (2)\n"); + goto err; + } + + /* test that the pointer to the data on a packet mbuf is set properly */ + if (test_pktmbuf_pool_ptr(pktmbuf_pool) < 0) { + printf("test_pktmbuf_pool_ptr() failed\n"); + goto err; + } + + /* test data manipulation in mbuf */ + if (test_one_pktmbuf(pktmbuf_pool) < 0) { + printf("test_one_mbuf() failed\n"); + goto err; + } + + + /* + * do it another time, to check that allocation reinitialize + * the mbuf correctly + */ + if (test_one_pktmbuf(pktmbuf_pool) < 0) { + printf("test_one_mbuf() failed (2)\n"); + goto err; + } + + if (test_pktmbuf_with_non_ascii_data(pktmbuf_pool) < 0) { + printf("test_pktmbuf_with_non_ascii_data() failed\n"); + goto err; + } + + /* test free pktmbuf segment one by one */ + if (test_pktmbuf_free_segment(pktmbuf_pool) < 0) { + printf("test_pktmbuf_free_segment() failed.\n"); + goto err; + } + + if (testclone_testupdate_testdetach(pktmbuf_pool) < 0) { + printf("testclone_and_testupdate() failed \n"); + goto err; + } + + if (test_attach_from_different_pool(pktmbuf_pool, pktmbuf_pool2) < 0) { + printf("test_attach_from_different_pool() failed\n"); + goto err; + } + + if (test_refcnt_mbuf()<0){ + printf("test_refcnt_mbuf() failed \n"); + goto err; + } + + if (test_failing_mbuf_sanity_check(pktmbuf_pool) < 0) { + printf("test_failing_mbuf_sanity_check() failed\n"); + goto err; + } + + if (test_mbuf_linearize_check(pktmbuf_pool) < 0) { + printf("test_mbuf_linearize_check() failed\n"); + goto err; + } + ret = 0; + +err: + rte_mempool_free(pktmbuf_pool); + rte_mempool_free(pktmbuf_pool2); + return ret; +} + +REGISTER_TEST_COMMAND(mbuf_autotest, test_mbuf); diff --git a/app/test/test_member.c b/app/test/test_member.c new file mode 100644 index 0000000000..e2a3932f2e --- /dev/null +++ b/app/test/test_member.c @@ -0,0 +1,715 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Intel Corporation + */ + +/* This test is for membership library's simple feature test */ + +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +struct rte_member_setsum *setsum_ht; +struct rte_member_setsum *setsum_cache; +struct rte_member_setsum *setsum_vbf; + +/* 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)); + +/* Set ID Macros for multimatch test usage */ +#define M_MATCH_S 1 /* Not start with 0 since by default 0 means no match */ +#define M_MATCH_E 15 +#define M_MATCH_STEP 2 +#define M_MATCH_CNT \ + (1 + (M_MATCH_E - M_MATCH_S) / M_MATCH_STEP) + + +#define NUM_SAMPLES 5 +#define MAX_MATCH 32 + +/* Keys used by unit test functions */ +static struct flow_key keys[NUM_SAMPLES] = { + { + .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, + } +}; + +uint32_t test_set[NUM_SAMPLES] = {1, 2, 3, 4, 5}; + +#define ITERATIONS 3 +#define KEY_SIZE 4 + +#define MAX_ENTRIES (1 << 16) +uint8_t generated_keys[MAX_ENTRIES][KEY_SIZE]; + +static struct rte_member_parameters params = { + .num_keys = MAX_ENTRIES, /* Total hash table entries. */ + .key_len = KEY_SIZE, /* Length of hash key. */ + + /* num_set and false_positive_rate only relevant to vBF */ + .num_set = 16, + .false_positive_rate = 0.03, + .prim_hash_seed = 1, + .sec_hash_seed = 11, + .socket_id = 0 /* NUMA Socket ID for memory. */ +}; + +/* + * Sequence of operations for find existing setsummary + * + * - create setsum + * - find existing setsum: hit + * - find non-existing setsum: miss + * + */ +static int +test_member_find_existing(void) +{ + struct rte_member_setsum *tmp_setsum = NULL, *result = NULL; + struct rte_member_parameters tmp_params = { + .name = "member_find_existing", + .num_keys = MAX_ENTRIES, /* Total hash table entries. */ + .key_len = KEY_SIZE, /* Length of hash key. */ + .type = RTE_MEMBER_TYPE_HT, + .num_set = 32, + .false_positive_rate = 0.03, + .prim_hash_seed = 1, + .sec_hash_seed = 11, + .socket_id = 0 /* NUMA Socket ID for memory. */ + }; + + /* Create */ + tmp_setsum = rte_member_create(&tmp_params); + TEST_ASSERT(tmp_setsum != NULL, "setsum creation failed"); + + /* Try to find existing hash table */ + result = rte_member_find_existing("member_find_existing"); + TEST_ASSERT(result == tmp_setsum, "could not find existing setsum"); + + /* Try to find non-existing hash table */ + result = rte_member_find_existing("member_find_non_existing"); + TEST_ASSERT(result == NULL, "found setsum that shouldn't exist"); + + /* Cleanup. */ + rte_member_free(tmp_setsum); + + return 0; +} + +/* + * Test for bad creating parameters + */ +static int +test_member_create_bad_param(void) +{ + struct rte_member_setsum *bad_setsum = NULL; + struct rte_member_parameters bad_params = { + .num_keys = MAX_ENTRIES, /* Total hash table entries. */ + .key_len = KEY_SIZE, /* Length of hash key. */ + .type = RTE_MEMBER_TYPE_HT, + .num_set = 32, + .false_positive_rate = 0.03, + .prim_hash_seed = 1, + .sec_hash_seed = 11, + .socket_id = 0 /* NUMA Socket ID for memory. */ + }; + + printf("Expected error section begin...\n"); + bad_params.name = "bad_param1"; + bad_params.num_set = 0; + bad_params.type = RTE_MEMBER_TYPE_VBF; + /* Test with 0 set for vBF should fail */ + bad_setsum = rte_member_create(&bad_params); + if (bad_setsum != NULL) { + rte_member_free(bad_setsum); + printf("Impossible creating setsum successfully with invalid " + "number of set for vBF\n"); + return -1; + } + + bad_params.name = "bad_param2"; + bad_params.false_positive_rate = 0; + bad_params.num_set = 32; + /* Test with 0 false positive for vBF should fail */ + bad_setsum = rte_member_create(&bad_params); + if (bad_setsum != NULL) { + rte_member_free(bad_setsum); + printf("Impossible creating setsum successfully with invalid " + "false positive rate for vBF\n"); + return -1; + } + + bad_params.name = "bad_param3"; + bad_params.false_positive_rate = 0.03; + bad_params.num_keys = 0; + /* Test with 0 key per BF for vBF should fail */ + bad_setsum = rte_member_create(&bad_params); + if (bad_setsum != NULL) { + rte_member_free(bad_setsum); + printf("Impossible creating setsum successfully with invalid " + "num_keys for vBF\n"); + return -1; + } + + bad_params.name = "bad_param4"; + bad_params.type = RTE_MEMBER_TYPE_HT; + bad_params.num_keys = RTE_MEMBER_BUCKET_ENTRIES / 2; + /* Test with less than 1 bucket for HTSS should fail */ + bad_setsum = rte_member_create(&bad_params); + if (bad_setsum != NULL) { + rte_member_free(bad_setsum); + printf("Impossible creating setsum successfully with too few " + "number of keys(entries) for HT\n"); + return -1; + } + + bad_params.name = "bad_param5"; + bad_params.num_keys = RTE_MEMBER_ENTRIES_MAX + 1; + /* Test with more than maximum entries for HTSS should fail */ + bad_setsum = rte_member_create(&bad_params); + if (bad_setsum != NULL) { + rte_member_free(bad_setsum); + printf("Impossible creating setsum successfully with to many " + "number of keys(entries) for HT\n"); + return -1; + } + + bad_params.name = "bad_param5"; + /* Test with same name should fail */ + bad_setsum = rte_member_create(&bad_params); + if (bad_setsum != NULL) { + rte_member_free(bad_setsum); + printf("Impossible creating setsum successfully with existed " + "name\n"); + return -1; + } + printf("Expected error section end...\n"); + rte_member_free(bad_setsum); + return 0; +} + +/* Create test setsummaries. */ +static int test_member_create(void) +{ + params.key_len = sizeof(struct flow_key); + + params.name = "test_member_ht"; + params.is_cache = 0; + params.type = RTE_MEMBER_TYPE_HT; + setsum_ht = rte_member_create(¶ms); + + params.name = "test_member_cache"; + params.is_cache = 1; + setsum_cache = rte_member_create(¶ms); + + params.name = "test_member_vbf"; + params.type = RTE_MEMBER_TYPE_VBF; + setsum_vbf = rte_member_create(¶ms); + + if (setsum_ht == NULL || setsum_cache == NULL || setsum_vbf == NULL) { + printf("Creation of setsums fail\n"); + return -1; + } + printf("Creation of setsums success\n"); + return 0; +} + +static int test_member_insert(void) +{ + int ret_ht, ret_cache, ret_vbf, i; + + for (i = 0; i < NUM_SAMPLES; i++) { + ret_ht = rte_member_add(setsum_ht, &keys[i], test_set[i]); + ret_cache = rte_member_add(setsum_cache, &keys[i], + test_set[i]); + ret_vbf = rte_member_add(setsum_vbf, &keys[i], test_set[i]); + TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0, + "insert error"); + } + printf("insert key success\n"); + return 0; +} + +static int test_member_lookup(void) +{ + int ret_ht, ret_cache, ret_vbf, i; + uint16_t set_ht, set_cache, set_vbf; + member_set_t set_ids_ht[NUM_SAMPLES] = {0}; + member_set_t set_ids_cache[NUM_SAMPLES] = {0}; + member_set_t set_ids_vbf[NUM_SAMPLES] = {0}; + + uint32_t num_key_ht = NUM_SAMPLES; + uint32_t num_key_cache = NUM_SAMPLES; + uint32_t num_key_vbf = NUM_SAMPLES; + + const void *key_array[NUM_SAMPLES]; + + /* Single lookup test */ + for (i = 0; i < NUM_SAMPLES; i++) { + ret_ht = rte_member_lookup(setsum_ht, &keys[i], &set_ht); + ret_cache = rte_member_lookup(setsum_cache, &keys[i], + &set_cache); + ret_vbf = rte_member_lookup(setsum_vbf, &keys[i], &set_vbf); + TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0, + "single lookup function error"); + + TEST_ASSERT(set_ht == test_set[i] && + set_cache == test_set[i] && + set_vbf == test_set[i], + "single lookup set value error"); + } + printf("lookup single key success\n"); + + /* Bulk lookup test */ + for (i = 0; i < NUM_SAMPLES; i++) + key_array[i] = &keys[i]; + + ret_ht = rte_member_lookup_bulk(setsum_ht, key_array, + num_key_ht, set_ids_ht); + + ret_cache = rte_member_lookup_bulk(setsum_cache, key_array, + num_key_cache, set_ids_cache); + + ret_vbf = rte_member_lookup_bulk(setsum_vbf, key_array, + num_key_vbf, set_ids_vbf); + + TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0, + "bulk lookup function error"); + + for (i = 0; i < NUM_SAMPLES; i++) { + TEST_ASSERT((set_ids_ht[i] == test_set[i]) && + (set_ids_cache[i] == test_set[i]) && + (set_ids_vbf[i] == test_set[i]), + "bulk lookup result error"); + } + + return 0; +} + +static int test_member_delete(void) +{ + int ret_ht, ret_cache, ret_vbf, i; + uint16_t set_ht, set_cache, set_vbf; + const void *key_array[NUM_SAMPLES]; + member_set_t set_ids_ht[NUM_SAMPLES] = {0}; + member_set_t set_ids_cache[NUM_SAMPLES] = {0}; + member_set_t set_ids_vbf[NUM_SAMPLES] = {0}; + uint32_t num_key_ht = NUM_SAMPLES; + uint32_t num_key_cache = NUM_SAMPLES; + uint32_t num_key_vbf = NUM_SAMPLES; + + /* Delete part of all inserted keys */ + for (i = 0; i < NUM_SAMPLES / 2; i++) { + ret_ht = rte_member_delete(setsum_ht, &keys[i], test_set[i]); + ret_cache = rte_member_delete(setsum_cache, &keys[i], + test_set[i]); + ret_vbf = rte_member_delete(setsum_vbf, &keys[i], test_set[i]); + /* VBF does not support delete yet, so return error code */ + TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0, + "key deletion function error"); + TEST_ASSERT(ret_vbf < 0, + "vbf does not support deletion, error"); + } + + for (i = 0; i < NUM_SAMPLES; i++) + key_array[i] = &keys[i]; + + ret_ht = rte_member_lookup_bulk(setsum_ht, key_array, + num_key_ht, set_ids_ht); + + ret_cache = rte_member_lookup_bulk(setsum_cache, key_array, + num_key_cache, set_ids_cache); + + ret_vbf = rte_member_lookup_bulk(setsum_vbf, key_array, + num_key_vbf, set_ids_vbf); + + TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0, + "bulk lookup function error"); + + for (i = 0; i < NUM_SAMPLES / 2; i++) { + TEST_ASSERT((set_ids_ht[i] == RTE_MEMBER_NO_MATCH) && + (set_ids_cache[i] == RTE_MEMBER_NO_MATCH), + "bulk lookup result error"); + } + + for (i = NUM_SAMPLES / 2; i < NUM_SAMPLES; i++) { + TEST_ASSERT((set_ids_ht[i] == test_set[i]) && + (set_ids_cache[i] == test_set[i]) && + (set_ids_vbf[i] == test_set[i]), + "bulk lookup result error"); + } + + /* Delete the left of inserted keys */ + for (i = NUM_SAMPLES / 2; i < NUM_SAMPLES; i++) { + ret_ht = rte_member_delete(setsum_ht, &keys[i], test_set[i]); + ret_cache = rte_member_delete(setsum_cache, &keys[i], + test_set[i]); + ret_vbf = rte_member_delete(setsum_vbf, &keys[i], test_set[i]); + /* VBF does not support delete yet, so return error code */ + TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0, + "key deletion function error"); + TEST_ASSERT(ret_vbf < 0, + "vbf does not support deletion, error"); + } + + for (i = 0; i < NUM_SAMPLES; i++) { + ret_ht = rte_member_lookup(setsum_ht, &keys[i], &set_ht); + ret_cache = rte_member_lookup(setsum_cache, &keys[i], + &set_cache); + ret_vbf = rte_member_lookup(setsum_vbf, &keys[i], &set_vbf); + TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0, + "key lookup function error"); + TEST_ASSERT(set_ht == RTE_MEMBER_NO_MATCH && + ret_cache == RTE_MEMBER_NO_MATCH, + "key deletion failed"); + } + /* Reset vbf for other following tests */ + rte_member_reset(setsum_vbf); + + printf("delete success\n"); + return 0; +} + +static int test_member_multimatch(void) +{ + int ret_ht, ret_vbf, ret_cache; + member_set_t set_ids_ht[MAX_MATCH] = {0}; + member_set_t set_ids_vbf[MAX_MATCH] = {0}; + member_set_t set_ids_cache[MAX_MATCH] = {0}; + + member_set_t set_ids_ht_m[NUM_SAMPLES][MAX_MATCH] = {{0} }; + member_set_t set_ids_vbf_m[NUM_SAMPLES][MAX_MATCH] = {{0} }; + member_set_t set_ids_cache_m[NUM_SAMPLES][MAX_MATCH] = {{0} }; + + uint32_t match_count_ht[NUM_SAMPLES]; + uint32_t match_count_vbf[NUM_SAMPLES]; + uint32_t match_count_cache[NUM_SAMPLES]; + + uint32_t num_key_ht = NUM_SAMPLES; + uint32_t num_key_vbf = NUM_SAMPLES; + uint32_t num_key_cache = NUM_SAMPLES; + + const void *key_array[NUM_SAMPLES]; + + uint32_t i, j; + + /* Same key at most inserted 2*entry_per_bucket times for HT mode */ + for (i = M_MATCH_S; i <= M_MATCH_E; i += M_MATCH_STEP) { + for (j = 0; j < NUM_SAMPLES; j++) { + ret_ht = rte_member_add(setsum_ht, &keys[j], i); + ret_vbf = rte_member_add(setsum_vbf, &keys[j], i); + ret_cache = rte_member_add(setsum_cache, &keys[j], i); + + TEST_ASSERT(ret_ht >= 0 && ret_vbf >= 0 && + ret_cache >= 0, + "insert function error"); + } + } + + /* Single multimatch test */ + for (i = 0; i < NUM_SAMPLES; i++) { + ret_vbf = rte_member_lookup_multi(setsum_vbf, &keys[i], + MAX_MATCH, set_ids_vbf); + ret_ht = rte_member_lookup_multi(setsum_ht, &keys[i], + MAX_MATCH, set_ids_ht); + ret_cache = rte_member_lookup_multi(setsum_cache, &keys[i], + MAX_MATCH, set_ids_cache); + /* + * For cache mode, keys overwrite when signature same. + * the mutimatch should work like single match. + */ + TEST_ASSERT(ret_ht == M_MATCH_CNT && ret_vbf == M_MATCH_CNT && + ret_cache == 1, + "single lookup_multi error"); + TEST_ASSERT(set_ids_cache[0] == M_MATCH_E, + "single lookup_multi cache error"); + + for (j = 1; j <= M_MATCH_CNT; j++) { + TEST_ASSERT(set_ids_ht[j-1] == j * M_MATCH_STEP - 1 && + set_ids_vbf[j-1] == + j * M_MATCH_STEP - 1, + "single multimatch lookup error"); + } + } + printf("lookup single key for multimatch success\n"); + + /* Bulk multimatch test */ + for (i = 0; i < NUM_SAMPLES; i++) + key_array[i] = &keys[i]; + ret_vbf = rte_member_lookup_multi_bulk(setsum_vbf, + &key_array[0], num_key_ht, MAX_MATCH, match_count_vbf, + (member_set_t *)set_ids_vbf_m); + + ret_ht = rte_member_lookup_multi_bulk(setsum_ht, + &key_array[0], num_key_vbf, MAX_MATCH, match_count_ht, + (member_set_t *)set_ids_ht_m); + + ret_cache = rte_member_lookup_multi_bulk(setsum_cache, + &key_array[0], num_key_cache, MAX_MATCH, + match_count_cache, (member_set_t *)set_ids_cache_m); + + + for (j = 0; j < NUM_SAMPLES; j++) { + TEST_ASSERT(match_count_ht[j] == M_MATCH_CNT, + "bulk multimatch lookup HT match count error"); + TEST_ASSERT(match_count_vbf[j] == M_MATCH_CNT, + "bulk multimatch lookup vBF match count error"); + TEST_ASSERT(match_count_cache[j] == 1, + "bulk multimatch lookup CACHE match count error"); + TEST_ASSERT(set_ids_cache_m[j][0] == M_MATCH_E, + "bulk multimatch lookup CACHE set value error"); + + for (i = 1; i <= M_MATCH_CNT; i++) { + TEST_ASSERT(set_ids_ht_m[j][i-1] == + i * M_MATCH_STEP - 1, + "bulk multimatch lookup HT set value error"); + TEST_ASSERT(set_ids_vbf_m[j][i-1] == + i * M_MATCH_STEP - 1, + "bulk multimatch lookup vBF set value error"); + } + } + + printf("lookup for bulk multimatch success\n"); + + return 0; +} + +static int key_compare(const void *key1, const void *key2) +{ + return memcmp(key1, key2, KEY_SIZE); +} + +static void +setup_keys_and_data(void) +{ + unsigned int i, j; + int num_duplicates; + + /* Reset all arrays */ + for (i = 0; i < KEY_SIZE; i++) + generated_keys[0][i] = 0; + + /* Generate a list of keys, some of which may be duplicates */ + for (i = 0; i < MAX_ENTRIES; i++) { + for (j = 0; j < KEY_SIZE; j++) + generated_keys[i][j] = rte_rand() & 0xFF; + } + + /* Remove duplicates from the keys array */ + do { + num_duplicates = 0; + /* Sort the list of keys to make it easier to find duplicates */ + qsort(generated_keys, MAX_ENTRIES, KEY_SIZE, key_compare); + + /* Sift through the list of keys and look for duplicates */ + int num_duplicates = 0; + for (i = 0; i < MAX_ENTRIES - 1; i++) { + if (memcmp(generated_keys[i], generated_keys[i + 1], + KEY_SIZE) == 0) { + /* This key already exists, try again */ + num_duplicates++; + for (j = 0; j < KEY_SIZE; j++) + generated_keys[i][j] = + rte_rand() & 0xFF; + } + } + } while (num_duplicates != 0); +} + +static inline int +add_generated_keys(struct rte_member_setsum *setsum, unsigned int *added_keys) +{ + int ret = 0; + + for (*added_keys = 0; ret >= 0 && *added_keys < MAX_ENTRIES; + (*added_keys)++) { + uint16_t set = (rte_rand() & 0xf) + 1; + ret = rte_member_add(setsum, &generated_keys[*added_keys], set); + } + return ret; +} + +static inline int +add_generated_keys_cache(struct rte_member_setsum *setsum, + unsigned int *added_keys) +{ + int ret = 0; + + for (*added_keys = 0; ret == 0 && *added_keys < MAX_ENTRIES; + (*added_keys)++) { + uint16_t set = (rte_rand() & 0xf) + 1; + ret = rte_member_add(setsum, &generated_keys[*added_keys], set); + } + return ret; +} + +static int +test_member_loadfactor(void) +{ + unsigned int j; + unsigned int added_keys, average_keys_added = 0; + int ret; + + setup_keys_and_data(); + + rte_member_free(setsum_ht); + rte_member_free(setsum_cache); + rte_member_free(setsum_vbf); + + params.key_len = KEY_SIZE; + params.name = "test_member_ht"; + params.is_cache = 0; + params.type = RTE_MEMBER_TYPE_HT; + setsum_ht = rte_member_create(¶ms); + + params.name = "test_member_cache"; + params.is_cache = 1; + setsum_cache = rte_member_create(¶ms); + + + if (setsum_ht == NULL || setsum_cache == NULL) { + printf("Creation of setsums fail\n"); + return -1; + } + /* Test HT non-cache mode */ + for (j = 0; j < ITERATIONS; j++) { + /* Add random entries until key cannot be added */ + ret = add_generated_keys(setsum_ht, &added_keys); + if (ret != -ENOSPC) { + printf("Unexpected error when adding keys\n"); + return -1; + } + average_keys_added += added_keys; + + /* Reset the table */ + rte_member_reset(setsum_ht); + + /* Print a dot to show progress on operations */ + printf("."); + fflush(stdout); + } + + average_keys_added /= ITERATIONS; + + printf("\nKeys inserted when no space(non-cache) = %.2f%% (%u/%u)\n", + ((double) average_keys_added / params.num_keys * 100), + average_keys_added, params.num_keys); + + /* Test cache mode */ + added_keys = average_keys_added = 0; + for (j = 0; j < ITERATIONS; j++) { + /* Add random entries until key cannot be added */ + ret = add_generated_keys_cache(setsum_cache, &added_keys); + if (ret != 1) { + printf("Unexpected error when adding keys\n"); + return -1; + } + average_keys_added += added_keys; + + /* Reset the table */ + rte_member_reset(setsum_cache); + + /* Print a dot to show progress on operations */ + printf("."); + fflush(stdout); + } + + average_keys_added /= ITERATIONS; + + printf("\nKeys inserted when eviction happens(cache)= %.2f%% (%u/%u)\n", + ((double) average_keys_added / params.num_keys * 100), + average_keys_added, params.num_keys); + return 0; +} + +static void +perform_free(void) +{ + rte_member_free(setsum_ht); + rte_member_free(setsum_cache); + rte_member_free(setsum_vbf); +} + +static int +test_member(void) +{ + if (test_member_create_bad_param() < 0) + return -1; + + if (test_member_find_existing() < 0) + return -1; + + if (test_member_create() < 0) { + perform_free(); + return -1; + } + if (test_member_insert() < 0) { + perform_free(); + return -1; + } + if (test_member_lookup() < 0) { + perform_free(); + return -1; + } + if (test_member_delete() < 0) { + perform_free(); + return -1; + } + if (test_member_multimatch() < 0) { + perform_free(); + return -1; + } + if (test_member_loadfactor() < 0) { + rte_member_free(setsum_ht); + rte_member_free(setsum_cache); + return -1; + } + + perform_free(); + return 0; +} + +REGISTER_TEST_COMMAND(member_autotest, test_member); diff --git a/app/test/test_member_perf.c b/app/test/test_member_perf.c new file mode 100644 index 0000000000..564a2b3c1e --- /dev/null +++ b/app/test/test_member_perf.c @@ -0,0 +1,625 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Intel Corporation + */ + +#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 * 75 / 100) /* 75% table utilization */ +#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ +#define VBF_SET_CNT 16 +#define BURST_SIZE 64 +#define VBF_FALSE_RATE 0.03 + +static unsigned int test_socket_id; + +enum sstype { + HT = 0, + CACHE, + VBF, + NUM_TYPE +}; + +enum operations { + ADD = 0, + LOOKUP, + LOOKUP_BULK, + LOOKUP_MULTI, + LOOKUP_MULTI_BULK, + DELETE, + LOOKUP_MISS, + NUM_OPERATIONS +}; + +struct member_perf_params { + struct rte_member_setsum *setsum[NUM_TYPE]; + 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_TYPE][NUM_KEYSIZES][NUM_OPERATIONS]; +uint64_t false_data[NUM_TYPE][NUM_KEYSIZES]; +uint64_t false_data_bulk[NUM_TYPE][NUM_KEYSIZES]; +uint64_t false_data_multi[NUM_TYPE][NUM_KEYSIZES]; +uint64_t false_data_multi_bulk[NUM_TYPE][NUM_KEYSIZES]; + +uint64_t false_hit[NUM_TYPE][NUM_KEYSIZES]; + +member_set_t data[NUM_TYPE][/* Array to store the 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 member_perf_params *params) +{ + member_set_t temp_data; + unsigned int i, j; + 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]); + memcpy(keys[i], keys[swap_idx], + hashtest_key_lens[params->cycle]); + memcpy(keys[swap_idx], temp_key, + hashtest_key_lens[params->cycle]); + for (j = 0; j < NUM_TYPE; j++) { + temp_data = data[j][i]; + data[j][i] = data[j][swap_idx]; + data[j][swap_idx] = temp_data; + } + } +} + +static int key_compare(const void *key1, const void *key2) +{ + return memcmp(key1, key2, MAX_KEYSIZE); +} + +struct rte_member_parameters member_params = { + .num_keys = MAX_ENTRIES, /* Total hash table entries. */ + .key_len = 4, /* Length of hash key. */ + + /* num_set and false_positive_rate only relevant to vBF */ + .num_set = VBF_SET_CNT, + .false_positive_rate = 0.03, + .prim_hash_seed = 0, + .sec_hash_seed = 1, + .socket_id = 0, /* NUMA Socket ID for memory. */ + }; + +static int +setup_keys_and_data(struct member_perf_params *params, unsigned int cycle, + int miss) +{ + 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[HT][i] = data[CACHE][i] = (rte_rand() & 0x7FFE) + 1; + data[VBF][i] = rte_rand() % VBF_SET_CNT + 1; + } + + /* 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); + + /* For testing miss lookup, we insert half and lookup the other half */ + unsigned int entry_cnt, bf_key_cnt; + if (!miss) { + entry_cnt = MAX_ENTRIES; + bf_key_cnt = KEYS_TO_ADD; + } else { + entry_cnt = MAX_ENTRIES / 2; + bf_key_cnt = KEYS_TO_ADD / 2; + } + member_params.false_positive_rate = VBF_FALSE_RATE; + member_params.key_len = params->key_size; + member_params.socket_id = test_socket_id; + member_params.num_keys = entry_cnt; + member_params.name = "test_member_ht"; + member_params.is_cache = 0; + member_params.type = RTE_MEMBER_TYPE_HT; + params->setsum[HT] = rte_member_create(&member_params); + if (params->setsum[HT] == NULL) + fprintf(stderr, "ht create fail\n"); + + member_params.name = "test_member_cache"; + member_params.is_cache = 1; + params->setsum[CACHE] = rte_member_create(&member_params); + if (params->setsum[CACHE] == NULL) + fprintf(stderr, "CACHE create fail\n"); + + member_params.name = "test_member_vbf"; + member_params.type = RTE_MEMBER_TYPE_VBF; + member_params.num_keys = bf_key_cnt; + params->setsum[VBF] = rte_member_create(&member_params); + if (params->setsum[VBF] == NULL) + fprintf(stderr, "VBF create fail\n"); + for (i = 0; i < NUM_TYPE; i++) { + if (params->setsum[i] == NULL) + return -1; + } + + return 0; +} + +static int +timed_adds(struct member_perf_params *params, int type) +{ + const uint64_t start_tsc = rte_rdtsc(); + unsigned int i, a; + int32_t ret; + + for (i = 0; i < KEYS_TO_ADD; i++) { + ret = rte_member_add(params->setsum[type], &keys[i], + data[type][i]); + if (ret < 0) { + printf("Error %d in rte_member_add - key=0x", ret); + for (a = 0; a < params->key_size; a++) + printf("%02x", keys[i][a]); + printf(" value=%d, type: %d\n", data[type][i], type); + + return -1; + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[type][params->cycle][ADD] = time_taken / KEYS_TO_ADD; + return 0; +} + +static int +timed_lookups(struct member_perf_params *params, int type) +{ + unsigned int i, j; + + false_data[type][params->cycle] = 0; + + const uint64_t start_tsc = rte_rdtsc(); + member_set_t result; + int ret; + + for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) { + for (j = 0; j < KEYS_TO_ADD; j++) { + ret = rte_member_lookup(params->setsum[type], &keys[j], + &result); + if (ret < 0) { + printf("lookup wrong internally"); + return -1; + } + if (type == HT && result == RTE_MEMBER_NO_MATCH) { + printf("HT mode shouldn't have false negative"); + return -1; + } + if (result != data[type][j]) + false_data[type][params->cycle]++; + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[type][params->cycle][LOOKUP] = time_taken / NUM_LOOKUPS; + + return 0; +} + +static int +timed_lookups_bulk(struct member_perf_params *params, int type) +{ + unsigned int i, j, k; + member_set_t result[BURST_SIZE] = {0}; + const void *keys_burst[BURST_SIZE]; + int ret; + + false_data_bulk[type][params->cycle] = 0; + + 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]; + + ret = rte_member_lookup_bulk(params->setsum[type], + keys_burst, + BURST_SIZE, + result); + if (ret <= 0) { + printf("lookup bulk has wrong return value\n"); + return -1; + } + for (k = 0; k < BURST_SIZE; k++) { + uint32_t data_idx = j * BURST_SIZE + k; + if (type == HT && result[k] == + RTE_MEMBER_NO_MATCH) { + printf("HT mode shouldn't have " + "false negative"); + return -1; + } + if (result[k] != data[type][data_idx]) + false_data_bulk[type][params->cycle]++; + } + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[type][params->cycle][LOOKUP_BULK] = time_taken / NUM_LOOKUPS; + + return 0; +} + +static int +timed_lookups_multimatch(struct member_perf_params *params, int type) +{ + unsigned int i, j; + member_set_t result[RTE_MEMBER_BUCKET_ENTRIES] = {0}; + int ret; + false_data_multi[type][params->cycle] = 0; + + const uint64_t start_tsc = rte_rdtsc(); + + for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) { + for (j = 0; j < KEYS_TO_ADD; j++) { + ret = rte_member_lookup_multi(params->setsum[type], + &keys[j], RTE_MEMBER_BUCKET_ENTRIES, result); + if (type != CACHE && ret <= 0) { + printf("lookup multi has wrong return value %d," + "type %d\n", ret, type); + } + if (type == HT && ret == 0) { + printf("HT mode shouldn't have false negative"); + return -1; + } + /* + * For performance test purpose, we do not iterate all + * results here. We assume most likely each key can only + * find one match which is result[0]. + */ + if (result[0] != data[type][j]) + false_data_multi[type][params->cycle]++; + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[type][params->cycle][LOOKUP_MULTI] = time_taken / NUM_LOOKUPS; + + return 0; +} + +static int +timed_lookups_multimatch_bulk(struct member_perf_params *params, int type) +{ + unsigned int i, j, k; + member_set_t result[BURST_SIZE][RTE_MEMBER_BUCKET_ENTRIES] = {{0} }; + const void *keys_burst[BURST_SIZE]; + uint32_t match_count[BURST_SIZE]; + int ret; + + false_data_multi_bulk[type][params->cycle] = 0; + + 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]; + + ret = rte_member_lookup_multi_bulk( + params->setsum[type], + keys_burst, BURST_SIZE, + RTE_MEMBER_BUCKET_ENTRIES, match_count, + (member_set_t *)result); + if (ret < 0) { + printf("lookup multimatch bulk has wrong return" + " value\n"); + return -1; + } + for (k = 0; k < BURST_SIZE; k++) { + if (type != CACHE && match_count[k] == 0) { + printf("lookup multimatch bulk get " + "wrong match count\n"); + return -1; + } + if (type == HT && match_count[k] == 0) { + printf("HT mode shouldn't have " + "false negative"); + return -1; + } + uint32_t data_idx = j * BURST_SIZE + k; + if (result[k][0] != data[type][data_idx]) + false_data_multi_bulk[type][params->cycle]++; + } + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[type][params->cycle][LOOKUP_MULTI_BULK] = time_taken / + NUM_LOOKUPS; + + return 0; +} + +static int +timed_deletes(struct member_perf_params *params, int type) +{ + unsigned int i; + int32_t ret; + + if (type == VBF) + return 0; + const uint64_t start_tsc = rte_rdtsc(); + for (i = 0; i < KEYS_TO_ADD; i++) { + ret = rte_member_delete(params->setsum[type], &keys[i], + data[type][i]); + if (type != CACHE && ret < 0) { + printf("delete error\n"); + return -1; + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[type][params->cycle][DELETE] = time_taken / KEYS_TO_ADD; + + return 0; +} + +static int +timed_miss_lookup(struct member_perf_params *params, int type) +{ + unsigned int i, j; + int ret; + + false_hit[type][params->cycle] = 0; + + for (i = 0; i < KEYS_TO_ADD / 2; i++) { + ret = rte_member_add(params->setsum[type], &keys[i], + data[type][i]); + if (ret < 0) { + unsigned int a; + printf("Error %d in rte_member_add - key=0x", ret); + for (a = 0; a < params->key_size; a++) + printf("%02x", keys[i][a]); + printf(" value=%d, type: %d\n", data[type][i], type); + + return -1; + } + } + + const uint64_t start_tsc = rte_rdtsc(); + member_set_t result; + + for (i = 0; i < 2 * NUM_LOOKUPS / KEYS_TO_ADD; i++) { + for (j = KEYS_TO_ADD / 2; j < KEYS_TO_ADD; j++) { + ret = rte_member_lookup(params->setsum[type], &keys[j], + &result); + if (ret < 0) { + printf("lookup wrong internally"); + return -1; + } + if (result != RTE_MEMBER_NO_MATCH) + false_hit[type][params->cycle]++; + } + } + + const uint64_t end_tsc = rte_rdtsc(); + const uint64_t time_taken = end_tsc - start_tsc; + + cycles[type][params->cycle][LOOKUP_MISS] = time_taken / NUM_LOOKUPS; + + return 0; +} + +static void +perform_frees(struct member_perf_params *params) +{ + int i; + for (i = 0; i < NUM_TYPE; i++) { + if (params->setsum[i] != NULL) { + rte_member_free(params->setsum[i]); + params->setsum[i] = NULL; + } + } +} + +static int +exit_with_fail(const char *testname, struct member_perf_params *params, + unsigned int i, unsigned int j) +{ + printf("<<<<>>>>\n", + testname, hashtest_key_lens[params->cycle], i, j); + perform_frees(params); + return -1; +} + +static int +run_all_tbl_perf_tests(void) +{ + unsigned int i, j, k; + struct member_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) < 0) { + printf("Could not create keys/data/table\n"); + return -1; + } + for (j = 0; j < NUM_TYPE; j++) { + + if (timed_adds(¶ms, j) < 0) + return exit_with_fail("timed_adds", ¶ms, + i, j); + + for (k = 0; k < NUM_SHUFFLES; k++) + shuffle_input_keys(¶ms); + + if (timed_lookups(¶ms, j) < 0) + return exit_with_fail("timed_lookups", ¶ms, + i, j); + + if (timed_lookups_bulk(¶ms, j) < 0) + return exit_with_fail("timed_lookups_bulk", + ¶ms, i, j); + + if (timed_lookups_multimatch(¶ms, j) < 0) + return exit_with_fail("timed_lookups_multi", + ¶ms, i, j); + + if (timed_lookups_multimatch_bulk(¶ms, j) < 0) + return exit_with_fail("timed_lookups_multi_bulk", + ¶ms, i, j); + + if (timed_deletes(¶ms, j) < 0) + return exit_with_fail("timed_deletes", ¶ms, + i, j); + + /* Print a dot to show progress on operations */ + } + printf("."); + fflush(stdout); + + perform_frees(¶ms); + } + + /* Test false positive rate using un-inserted keys */ + for (i = 0; i < NUM_KEYSIZES; i++) { + if (setup_keys_and_data(¶ms, i, 1) < 0) { + printf("Could not create keys/data/table\n"); + return -1; + } + for (j = 0; j < NUM_TYPE; j++) { + if (timed_miss_lookup(¶ms, j) < 0) + return exit_with_fail("timed_miss_lookup", + ¶ms, i, j); + } + perform_frees(¶ms); + } + + printf("\nResults (in CPU cycles/operation)\n"); + printf("-----------------------------------\n"); + printf("\n%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s\n", + "Keysize", "type", "Add", "Lookup", "Lookup_bulk", + "lookup_multi", "lookup_multi_bulk", "Delete", + "miss_lookup"); + for (i = 0; i < NUM_KEYSIZES; i++) { + for (j = 0; j < NUM_TYPE; j++) { + printf("%-18d", hashtest_key_lens[i]); + printf("%-18d", j); + for (k = 0; k < NUM_OPERATIONS; k++) + printf("%-18"PRIu64, cycles[j][i][k]); + printf("\n"); + } + } + + printf("\nFalse results rate (and false positive rate)\n"); + printf("-----------------------------------\n"); + printf("\n%-18s%-18s%-18s%-18s%-18s%-18s%-18s\n", + "Keysize", "type", "fr_single", "fr_bulk", "fr_multi", + "fr_multi_bulk", "false_positive_rate"); + /* Key size not influence False rate so just print out one key size */ + for (i = 0; i < 1; i++) { + for (j = 0; j < NUM_TYPE; j++) { + printf("%-18d", hashtest_key_lens[i]); + printf("%-18d", j); + printf("%-18f", (float)false_data[j][i] / NUM_LOOKUPS); + printf("%-18f", (float)false_data_bulk[j][i] / + NUM_LOOKUPS); + printf("%-18f", (float)false_data_multi[j][i] / + NUM_LOOKUPS); + printf("%-18f", (float)false_data_multi_bulk[j][i] / + NUM_LOOKUPS); + printf("%-18f", (float)false_hit[j][i] / + NUM_LOOKUPS); + printf("\n"); + } + } + return 0; +} + +static int +test_member_perf(void) +{ + + if (run_all_tbl_perf_tests() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(member_perf_autotest, test_member_perf); diff --git a/app/test/test_memcpy.c b/app/test/test_memcpy.c new file mode 100644 index 0000000000..2c69ad9647 --- /dev/null +++ b/app/test/test_memcpy.c @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..6f436f3ef3 --- /dev/null +++ b/app/test/test_memcpy_perf.c @@ -0,0 +1,352 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#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("%3.0f -", (double)total_time / TEST_ITERATIONS); \ + printf("%3.0f", (double)total_time2 / TEST_ITERATIONS); \ + printf("(%6.2f%%) ", ((double)total_time - total_time2)*100/total_time2); \ +} 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; + struct timeval tv_begin, tv_end; + double time_aligned, time_unaligned; + double time_aligned_const, time_unaligned_const; + + 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 */ + gettimeofday(&tv_begin, NULL); + perf_test_variable_aligned(); + gettimeofday(&tv_end, NULL); + time_aligned = (double)(tv_end.tv_sec - tv_begin.tv_sec) + + ((double)tv_end.tv_usec - tv_begin.tv_usec)/1000000; + printf("\n------- ----------------- ----------------- ----------------- -----------------"); + /* Do aligned tests where size is a compile-time constant */ + gettimeofday(&tv_begin, NULL); + perf_test_constant_aligned(); + gettimeofday(&tv_end, NULL); + time_aligned_const = (double)(tv_end.tv_sec - tv_begin.tv_sec) + + ((double)tv_end.tv_usec - tv_begin.tv_usec)/1000000; + printf("\n================================== Unaligned =================================="); + /* Do unaligned tests where size is a variable */ + gettimeofday(&tv_begin, NULL); + perf_test_variable_unaligned(); + gettimeofday(&tv_end, NULL); + time_unaligned = (double)(tv_end.tv_sec - tv_begin.tv_sec) + + ((double)tv_end.tv_usec - tv_begin.tv_usec)/1000000; + printf("\n------- ----------------- ----------------- ----------------- -----------------"); + /* Do unaligned tests where size is a compile-time constant */ + gettimeofday(&tv_begin, NULL); + perf_test_constant_unaligned(); + gettimeofday(&tv_end, NULL); + time_unaligned_const = (double)(tv_end.tv_sec - tv_begin.tv_sec) + + ((double)tv_end.tv_usec - tv_begin.tv_usec)/1000000; + printf("\n======= ================= ================= ================= =================\n\n"); + + printf("Test Execution Time (seconds):\n"); + printf("Aligned variable copy size = %8.3f\n", time_aligned); + printf("Aligned constant copy size = %8.3f\n", time_aligned_const); + printf("Unaligned variable copy size = %8.3f\n", time_unaligned); + printf("Unaligned constant copy size = %8.3f\n", time_unaligned_const); + 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 new file mode 100644 index 0000000000..3da803e4e1 --- /dev/null +++ b/app/test/test_memory.c @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include + +#include +#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 +check_mem(const struct rte_memseg_list *msl __rte_unused, + const struct rte_memseg *ms, void *arg __rte_unused) +{ + volatile uint8_t *mem = (volatile uint8_t *) ms->addr; + size_t i, max = ms->len; + + for (i = 0; i < max; i++, mem++) + *mem; + return 0; +} + +static int +check_seg_fds(const struct rte_memseg_list *msl, const struct rte_memseg *ms, + void *arg __rte_unused) +{ + size_t offset; + int ret; + + /* skip external segments */ + if (msl->external) + return 0; + + /* try segment fd first. we're in a callback, so thread-unsafe */ + ret = rte_memseg_get_fd_thread_unsafe(ms); + if (ret < 0) { + /* ENOTSUP means segment is valid, but there is not support for + * segment fd API (e.g. on FreeBSD). + */ + if (errno == ENOTSUP) + return 1; + /* all other errors are treated as failures */ + return -1; + } + + /* we're able to get memseg fd - try getting its offset */ + ret = rte_memseg_get_fd_offset_thread_unsafe(ms, &offset); + if (ret < 0) { + if (errno == ENOTSUP) + return 1; + return -1; + } + return 0; +} + +static int +test_memory(void) +{ + uint64_t s; + int ret; + + /* + * 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) */ + rte_memseg_walk(check_mem, NULL); + + /* check segment fd support */ + ret = rte_memseg_walk(check_seg_fds, NULL); + if (ret == 1) { + printf("Segment fd API is unsupported\n"); + } else if (ret == -1) { + printf("Error getting segment fd's\n"); + return -1; + } + + return 0; +} + +REGISTER_TEST_COMMAND(memory_autotest, test_memory); diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c new file mode 100644 index 0000000000..eebb1f24d3 --- /dev/null +++ b/app/test/test_mempool.c @@ -0,0 +1,594 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 + * ======= + * + * 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) + 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_virt2iova() not supported on bsd */ + printf("get physical address of an object\n"); + if (rte_mempool_virt2iova(obj) != rte_mem_virt2iova(obj)) + GOTO_ERR(ret, out); +#endif + + printf("put the object back\n"); + rte_mempool_generic_put(mp, &obj, 1, cache); + rte_mempool_dump(stdout, mp); + + printf("get 2 objects\n"); + if (rte_mempool_generic_get(mp, &obj, 1, cache) < 0) + GOTO_ERR(ret, out); + if (rte_mempool_generic_get(mp, &obj2, 1, cache) < 0) { + rte_mempool_generic_put(mp, &obj, 1, cache); + GOTO_ERR(ret, out); + } + rte_mempool_dump(stdout, mp); + + printf("put the objects back\n"); + rte_mempool_generic_put(mp, &obj, 1, cache); + rte_mempool_generic_put(mp, &obj2, 1, cache); + 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) + 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); + } + + 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"); + ret = -1; + goto err; + } + lcore_next = rte_get_next_lcore(lcore_id, 0, 1); + if (lcore_next >= RTE_MAX_LCORE) { + ret = -1; + goto err; + } + if (rte_eal_lcore_role(lcore_next) != ROLE_RTE) { + ret = -1; + goto 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; + +err: + rte_mempool_free(mp_spsc); + mp_spsc = NULL; + + 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; +} + +static void +walk_cb(struct rte_mempool *mp, void *userdata __rte_unused) +{ + printf("\t%s\n", mp->name); +} + +static int +test_mempool(void) +{ + int ret = -1; + struct rte_mempool *mp_cache = NULL; + struct rte_mempool *mp_nocache = NULL; + struct rte_mempool *mp_stack = NULL; + struct rte_mempool *default_pool = NULL; + const char *default_pool_ops = rte_mbuf_best_mempool_ops(); + + 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); + + /* Create a mempool based on Default handler */ + printf("Testing %s mempool handler\n", default_pool_ops); + default_pool = rte_mempool_create_empty("default_pool", + MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, + RTE_MEMPOOL_CACHE_MAX_SIZE, 0, + SOCKET_ID_ANY, 0); + + if (default_pool == NULL) { + printf("cannot allocate default mempool\n"); + goto err; + } + if (rte_mempool_set_ops_byname(default_pool, + default_pool_ops, NULL) < 0) { + printf("cannot set %s handler\n", default_pool_ops); + goto err; + } + if (rte_mempool_populate_default(default_pool) < 0) { + printf("cannot populate %s mempool\n", default_pool_ops); + goto err; + } + rte_mempool_obj_iter(default_pool, 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; + + /* test the stack handler */ + if (test_mempool_basic(mp_stack, 1) < 0) + goto err; + + if (test_mempool_basic(default_pool, 1) < 0) + goto err; + + rte_mempool_list_dump(stdout); + + ret = 0; + +err: + rte_mempool_free(mp_nocache); + rte_mempool_free(mp_cache); + rte_mempool_free(mp_stack); + rte_mempool_free(default_pool); + + return ret; +} + +REGISTER_TEST_COMMAND(mempool_autotest, test_mempool); diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c new file mode 100644 index 0000000000..4c877834e7 --- /dev/null +++ b/app/test/test_mempool_perf.c @@ -0,0 +1,399 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 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(void *arg) +{ + void *obj_table[MAX_KEEP]; + unsigned i, idx; + struct rte_mempool *mp = arg; + 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); + 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); + 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(struct rte_mempool *mp, unsigned int 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, + mp, lcore_id); + } + + /* start synchro and launch test on master */ + rte_atomic32_set(&synchro, 1); + + ret = per_lcore_mempool_test(mp); + + 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(struct rte_mempool *mp, unsigned int 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(mp, cores); + + if (ret < 0) + return -1; + } + } + } + return 0; +} + +static int +test_mempool_perf(void) +{ + struct rte_mempool *mp_cache = NULL; + struct rte_mempool *mp_nocache = NULL; + struct rte_mempool *default_pool = NULL; + const char *default_pool_ops; + int ret = -1; + + rte_atomic32_init(&synchro); + + /* create a mempool (without cache) */ + 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) + goto err; + + /* create a mempool (with cache) */ + 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) + goto err; + + default_pool_ops = rte_mbuf_best_mempool_ops(); + /* Create a mempool based on Default handler */ + default_pool = rte_mempool_create_empty("default_pool", + MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, + 0, 0, + SOCKET_ID_ANY, 0); + + if (default_pool == NULL) { + printf("cannot allocate %s mempool\n", default_pool_ops); + goto err; + } + + if (rte_mempool_set_ops_byname(default_pool, default_pool_ops, NULL) + < 0) { + printf("cannot set %s handler\n", default_pool_ops); + goto err; + } + + if (rte_mempool_populate_default(default_pool) < 0) { + printf("cannot populate %s mempool\n", default_pool_ops); + goto err; + } + + rte_mempool_obj_iter(default_pool, my_obj_init, NULL); + + /* performance test with 1, 2 and max cores */ + printf("start performance test (without cache)\n"); + + if (do_one_mempool_test(mp_nocache, 1) < 0) + goto err; + + if (do_one_mempool_test(mp_nocache, 2) < 0) + goto err; + + if (do_one_mempool_test(mp_nocache, rte_lcore_count()) < 0) + goto err; + + /* performance test with 1, 2 and max cores */ + printf("start performance test for %s (without cache)\n", + default_pool_ops); + + if (do_one_mempool_test(default_pool, 1) < 0) + goto err; + + if (do_one_mempool_test(default_pool, 2) < 0) + goto err; + + if (do_one_mempool_test(default_pool, rte_lcore_count()) < 0) + goto err; + + /* performance test with 1, 2 and max cores */ + printf("start performance test (with cache)\n"); + + if (do_one_mempool_test(mp_cache, 1) < 0) + goto err; + + if (do_one_mempool_test(mp_cache, 2) < 0) + goto err; + + if (do_one_mempool_test(mp_cache, rte_lcore_count()) < 0) + goto err; + + /* performance test with 1, 2 and max cores */ + printf("start performance test (with user-owned cache)\n"); + use_external_cache = 1; + + if (do_one_mempool_test(mp_nocache, 1) < 0) + goto err; + + if (do_one_mempool_test(mp_nocache, 2) < 0) + goto err; + + if (do_one_mempool_test(mp_nocache, rte_lcore_count()) < 0) + goto err; + + rte_mempool_list_dump(stdout); + + ret = 0; + +err: + rte_mempool_free(mp_cache); + rte_mempool_free(mp_nocache); + rte_mempool_free(default_pool); + return ret; +} + +REGISTER_TEST_COMMAND(mempool_perf_autotest, test_mempool_perf); diff --git a/app/test/test_memzone.c b/app/test/test_memzone.c new file mode 100644 index 0000000000..9fe465e621 --- /dev/null +++ b/app/test/test_memzone.c @@ -0,0 +1,1116 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#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 + */ + +#define TEST_MEMZONE_NAME(suffix) "MZ_TEST_" suffix + +/* Test if memory overlaps: return 1 if true, or 0 if false. */ +static int +is_memory_overlap(rte_iova_t ptr1, size_t len1, rte_iova_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(TEST_MEMZONE_NAME("invalid_alignment")); + if (mz != NULL) { + printf("Zone with invalid alignment has been reserved\n"); + return -1; + } + + mz = rte_memzone_reserve_aligned(TEST_MEMZONE_NAME("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( + TEST_MEMZONE_NAME("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( + TEST_MEMZONE_NAME("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; +} + +struct walk_arg { + int hugepage_2MB_avail; + int hugepage_1GB_avail; + int hugepage_16MB_avail; + int hugepage_16GB_avail; +}; +static int +find_available_pagesz(const struct rte_memseg_list *msl, void *arg) +{ + struct walk_arg *wa = arg; + + if (msl->external) + return 0; + + if (msl->page_sz == RTE_PGSIZE_2M) + wa->hugepage_2MB_avail = 1; + if (msl->page_sz == RTE_PGSIZE_1G) + wa->hugepage_1GB_avail = 1; + if (msl->page_sz == RTE_PGSIZE_16M) + wa->hugepage_16MB_avail = 1; + if (msl->page_sz == RTE_PGSIZE_16G) + wa->hugepage_16GB_avail = 1; + + return 0; +} + +static int +test_memzone_reserve_flags(void) +{ + const struct rte_memzone *mz; + struct walk_arg wa; + int hugepage_2MB_avail, hugepage_1GB_avail; + int hugepage_16MB_avail, hugepage_16GB_avail; + const size_t size = 100; + + memset(&wa, 0, sizeof(wa)); + + rte_memseg_list_walk(find_available_pagesz, &wa); + + hugepage_2MB_avail = wa.hugepage_2MB_avail; + hugepage_1GB_avail = wa.hugepage_1GB_avail; + hugepage_16MB_avail = wa.hugepage_16MB_avail; + hugepage_16GB_avail = wa.hugepage_16GB_avail; + + /* 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(TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + + mz = rte_memzone_reserve(TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\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( + TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + + mz = rte_memzone_reserve( + TEST_MEMZONE_NAME("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(TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + + mz = rte_memzone_reserve(TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\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( + TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + mz = rte_memzone_reserve( + TEST_MEMZONE_NAME("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( + TEST_MEMZONE_NAME("flag_zone_2M_HINT"), + size, SOCKET_ID_ANY, + RTE_MEMZONE_2MB|RTE_MEMZONE_1GB); + if (mz == NULL) { + printf("BOTH SIZES SET\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_1G && + mz->hugepage_sz != RTE_PGSIZE_2M) { + printf("Wrong size when both sizes set\n"); + return -1; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\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(TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + + mz = rte_memzone_reserve( + TEST_MEMZONE_NAME("flag_zone_16M_HINT"), size, + SOCKET_ID_ANY, + RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY); + 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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\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( + TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + + mz = rte_memzone_reserve( + TEST_MEMZONE_NAME("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(TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + + mz = rte_memzone_reserve( + TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\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( + TEST_MEMZONE_NAME("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; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + mz = rte_memzone_reserve( + TEST_MEMZONE_NAME("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( + TEST_MEMZONE_NAME("flag_zone_16M_HINT"), + size, SOCKET_ID_ANY, + RTE_MEMZONE_16MB|RTE_MEMZONE_16GB); + if (mz == NULL) { + printf("BOTH SIZES SET\n"); + return -1; + } + if (mz->hugepage_sz != RTE_PGSIZE_16G && + mz->hugepage_sz != RTE_PGSIZE_16M) { + printf("Wrong size when both sizes set\n"); + return -1; + } + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + } + } + return 0; +} + + +/* Find the heap with the greatest free block size */ +static size_t +find_max_block_free_size(unsigned int align, unsigned int socket_id) +{ + struct rte_malloc_socket_stats stats; + size_t len, overhead; + + rte_malloc_get_socket_stats(socket_id, &stats); + + len = stats.greatest_free_size; + overhead = MALLOC_ELEM_OVERHEAD; + + if (len == 0) + return 0; + + align = RTE_CACHE_LINE_ROUNDUP(align); + overhead += align; + + if (len < overhead) + return 0; + + return len - overhead; +} + +static int +test_memzone_reserve_max(void) +{ + unsigned int i; + + for (i = 0; i < rte_socket_count(); i++) { + const struct rte_memzone *mz; + size_t maxlen; + int socket; + + socket = rte_socket_id_by_idx(i); + maxlen = find_max_block_free_size(0, socket); + + if (maxlen == 0) { + printf("There is no space left!\n"); + return 0; + } + + mz = rte_memzone_reserve(TEST_MEMZONE_NAME("max_zone"), 0, + socket, 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; + } + + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + } + + return 0; +} + +static int +test_memzone_reserve_max_aligned(void) +{ + unsigned int i; + + for (i = 0; i < rte_socket_count(); i++) { + const struct rte_memzone *mz; + size_t maxlen, minlen = 0; + int socket; + + socket = rte_socket_id_by_idx(i); + + /* random alignment */ + rte_srand((unsigned int)rte_rdtsc()); + const unsigned int align = 1 << ((rte_rand() % 8) + 5); /* from 128 up to 4k alignment */ + + /* memzone size may be between size and size - align */ + minlen = find_max_block_free_size(align, socket); + maxlen = find_max_block_free_size(0, socket); + + if (minlen == 0 || maxlen == 0) { + printf("There is no space left for biggest %u-aligned memzone!\n", + align); + return 0; + } + + mz = rte_memzone_reserve_aligned( + TEST_MEMZONE_NAME("max_zone_aligned"), + 0, socket, 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->addr != RTE_PTR_ALIGN(mz->addr, align)) { + printf("Memzone reserve with 0 size and alignment %u did not return aligned block\n", + align); + rte_dump_physmem_layout(stdout); + rte_memzone_dump(stdout); + return -1; + } + + if (mz->len < minlen || mz->len > maxlen) { + printf("Memzone reserve with 0 size and alignment %u did not return" + " bigest block\n", align); + printf("Expected size = %zu-%zu, actual size = %zu\n", + minlen, maxlen, mz->len); + rte_dump_physmem_layout(stdout); + rte_memzone_dump(stdout); + return -1; + } + + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + 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( + TEST_MEMZONE_NAME("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( + TEST_MEMZONE_NAME("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( + TEST_MEMZONE_NAME("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( + TEST_MEMZONE_NAME("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( + TEST_MEMZONE_NAME("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->iova & 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->iova & 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->iova & 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->iova & 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->iova & 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->iova, memzone_aligned_32->len, + memzone_aligned_128->iova, memzone_aligned_128->len)) + return -1; + if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len, + memzone_aligned_256->iova, memzone_aligned_256->len)) + return -1; + if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len, + memzone_aligned_512->iova, memzone_aligned_512->len)) + return -1; + if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len, + memzone_aligned_1024->iova, memzone_aligned_1024->len)) + return -1; + if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len, + memzone_aligned_256->iova, memzone_aligned_256->len)) + return -1; + if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len, + memzone_aligned_512->iova, memzone_aligned_512->len)) + return -1; + if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len, + memzone_aligned_1024->iova, memzone_aligned_1024->len)) + return -1; + if (is_memory_overlap(memzone_aligned_256->iova, memzone_aligned_256->len, + memzone_aligned_512->iova, memzone_aligned_512->len)) + return -1; + if (is_memory_overlap(memzone_aligned_256->iova, memzone_aligned_256->len, + memzone_aligned_1024->iova, memzone_aligned_1024->len)) + return -1; + if (is_memory_overlap(memzone_aligned_512->iova, memzone_aligned_512->len, + memzone_aligned_1024->iova, memzone_aligned_1024->len)) + return -1; + + /* free all used zones */ + if (rte_memzone_free(memzone_aligned_32)) { + printf("Fail memzone free\n"); + return -1; + } + if (rte_memzone_free(memzone_aligned_128)) { + printf("Fail memzone free\n"); + return -1; + } + if (rte_memzone_free(memzone_aligned_256)) { + printf("Fail memzone free\n"); + return -1; + } + if (rte_memzone_free(memzone_aligned_512)) { + printf("Fail memzone free\n"); + return -1; + } + if (rte_memzone_free(memzone_aligned_1024)) { + printf("Fail memzone free\n"); + 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; + rte_iova_t bmask; + + bmask = ~((rte_iova_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->iova & ((rte_iova_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->iova & bmask) != + ((mz->iova + mz->len - 1) & bmask)) { + printf("%s(%s): invalid memzone boundary %u crossed\n", + __func__, mz->name, bound); + return -1; + } + + if (rte_memzone_free(mz)) { + printf("Fail memzone free\n"); + return -1; + } + + return 0; +} + +static int +test_memzone_bounded(void) +{ + const struct rte_memzone *memzone_err; + int rc; + + /* should fail as boundary is not power of two */ + memzone_err = rte_memzone_reserve_bounded( + TEST_MEMZONE_NAME("bounded_error_31"), 100, + SOCKET_ID_ANY, 0, 32, UINT32_MAX); + if (memzone_err != 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 */ + memzone_err = rte_memzone_reserve_bounded( + TEST_MEMZONE_NAME("bounded_error_32"), 100, + SOCKET_ID_ANY, 0, 32, 32); + if (memzone_err != NULL) { + printf("%s(%s)created a memzone with invalid boundary " + "conditions\n", __func__, memzone_err->name); + return -1; + } + + rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_128"), 100, 128, + 128); + if (rc != 0) + return rc; + + rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_256"), 100, 256, + 128); + if (rc != 0) + return rc; + + rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_1K"), 100, 64, + 1024); + if (rc != 0) + return rc; + + rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_1K_MAX"), 0, 64, + 1024); + if (rc != 0) + return rc; + + return 0; +} + +static int +test_memzone_free(void) +{ + const struct rte_memzone *mz[RTE_MAX_MEMZONE + 1]; + int i; + char name[20]; + + mz[0] = rte_memzone_reserve(TEST_MEMZONE_NAME("tempzone0"), 2000, + SOCKET_ID_ANY, 0); + mz[1] = rte_memzone_reserve(TEST_MEMZONE_NAME("tempzone1"), 4000, + SOCKET_ID_ANY, 0); + + if (mz[0] > mz[1]) + return -1; + if (!rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone0"))) + return -1; + if (!rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone1"))) + return -1; + + if (rte_memzone_free(mz[0])) { + printf("Fail memzone free - tempzone0\n"); + return -1; + } + if (rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone0"))) { + printf("Found previously free memzone - tempzone0\n"); + return -1; + } + mz[2] = rte_memzone_reserve(TEST_MEMZONE_NAME("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(TEST_MEMZONE_NAME("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(TEST_MEMZONE_NAME("tempzone1"))) { + printf("Found previously free memzone - tempzone1\n"); + return -1; + } + + i = 0; + do { + snprintf(name, sizeof(name), TEST_MEMZONE_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(TEST_MEMZONE_NAME("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_basic(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; + int memzone_cnt_after, memzone_cnt_expected; + int memzone_cnt_before = + rte_eal_get_configuration()->mem_config->memzones.count; + + memzone1 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone1"), 100, + SOCKET_ID_ANY, 0); + + memzone2 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone2"), 1000, + 0, 0); + + memzone3 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone3"), 1000, + 1, 0); + + memzone4 = rte_memzone_reserve(TEST_MEMZONE_NAME("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; + + /* check how many memzones we are expecting */ + memzone_cnt_expected = memzone_cnt_before + + (memzone1 != NULL) + (memzone2 != NULL) + + (memzone3 != NULL) + (memzone4 != NULL); + + memzone_cnt_after = + rte_eal_get_configuration()->mem_config->memzones.count; + + if (memzone_cnt_after != memzone_cnt_expected) + return -1; + + + rte_memzone_dump(stdout); + + /* check cache-line alignments */ + printf("check alignments and lengths\n"); + + if ((memzone1->iova & RTE_CACHE_LINE_MASK) != 0) + return -1; + if ((memzone2->iova & RTE_CACHE_LINE_MASK) != 0) + return -1; + if (memzone3 != NULL && (memzone3->iova & 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->iova, memzone1->len, + memzone2->iova, memzone2->len)) + return -1; + if (memzone3 != NULL && + is_memory_overlap(memzone1->iova, memzone1->len, + memzone3->iova, memzone3->len)) + return -1; + if (memzone3 != NULL && + is_memory_overlap(memzone2->iova, memzone2->len, + memzone3->iova, 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(TEST_MEMZONE_NAME("testzone1")); + if (mz != memzone1) + return -1; + + printf("test duplcate zone name\n"); + mz = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone1"), 100, + SOCKET_ID_ANY, 0); + if (mz != NULL) + return -1; + + if (rte_memzone_free(memzone1)) { + printf("Fail memzone free - memzone1\n"); + return -1; + } + if (rte_memzone_free(memzone2)) { + printf("Fail memzone free - memzone2\n"); + return -1; + } + if (memzone3 && rte_memzone_free(memzone3)) { + printf("Fail memzone free - memzone3\n"); + return -1; + } + if (rte_memzone_free(memzone4)) { + printf("Fail memzone free - memzone4\n"); + return -1; + } + + memzone_cnt_after = + rte_eal_get_configuration()->mem_config->memzones.count; + if (memzone_cnt_after != memzone_cnt_before) + return -1; + + return 0; +} + +static int test_memzones_left; +static int memzone_walk_cnt; +static void memzone_walk_clb(const struct rte_memzone *mz, + void *arg __rte_unused) +{ + memzone_walk_cnt++; + if (!strncmp(TEST_MEMZONE_NAME(""), mz->name, RTE_MEMZONE_NAMESIZE)) + test_memzones_left++; +} + +static int +test_memzone(void) +{ + /* take note of how many memzones were allocated before running */ + int memzone_cnt = + rte_eal_get_configuration()->mem_config->memzones.count; + + printf("test basic memzone API\n"); + if (test_memzone_basic() < 0) + 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; + + printf("check memzone cleanup\n"); + memzone_walk_cnt = 0; + test_memzones_left = 0; + rte_memzone_walk(memzone_walk_clb, NULL); + if (memzone_walk_cnt != memzone_cnt || test_memzones_left > 0) { + printf("there are some memzones left after test\n"); + rte_memzone_dump(stdout); + 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 new file mode 100644 index 0000000000..f935faa539 --- /dev/null +++ b/app/test/test_meter.c @@ -0,0 +1,716 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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_EIR_DF 69000000 +#define TM_TEST_TRTCM_CBS_DF 2048 +#define TM_TEST_TRTCM_PBS_DF 4096 +#define TM_TEST_TRTCM_EBS_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,}; + +static struct rte_meter_trtcm_rfc4115_params rfc4115params = + {.cir = TM_TEST_TRTCM_CIR_DF, + .eir = TM_TEST_TRTCM_EIR_DF, + .cbs = TM_TEST_TRTCM_CBS_DF, + .ebs = TM_TEST_TRTCM_EBS_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_profile sp; + struct rte_meter_srtcm_params sparams1; + + /* invalid parameter test */ + if (rte_meter_srtcm_profile_config(NULL, NULL) == 0) + melog(SRTCM_CFG_MSG); + if (rte_meter_srtcm_profile_config(&sp, NULL) == 0) + melog(SRTCM_CFG_MSG); + if (rte_meter_srtcm_profile_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_profile_config(&sp, &sparams1) == 0) + melog(SRTCM_CFG_MSG); + + /* cir should never be 0 */ + sparams1 = sparams; + sparams1.cir = 0; + if (rte_meter_srtcm_profile_config(&sp, &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_profile_config(&sp, &sparams1) != 0) + melog(SRTCM_CFG_MSG); + + sparams1 = sparams; + sparams1.cbs = 0; + if (rte_meter_srtcm_profile_config(&sp, &sparams1) != 0) + melog(SRTCM_CFG_MSG); + + /* usual parameter, should be successful */ + if (rte_meter_srtcm_profile_config(&sp, &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_profile tp; + struct rte_meter_trtcm_params tparams1; +#define TRTCM_CFG_MSG "trtcm_config" + + /* invalid parameter test */ + if (rte_meter_trtcm_profile_config(NULL, NULL) == 0) + melog(TRTCM_CFG_MSG); + if (rte_meter_trtcm_profile_config(&tp, NULL) == 0) + melog(TRTCM_CFG_MSG); + if (rte_meter_trtcm_profile_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_profile_config(&tp, &tparams1) == 0) + melog(TRTCM_CFG_MSG); + + tparams1 = tparams; + tparams1.cbs = 0; + if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0) + melog(TRTCM_CFG_MSG); + + tparams1 = tparams; + tparams1.pbs = 0; + if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0) + melog(TRTCM_CFG_MSG); + + tparams1 = tparams; + tparams1.pir = 0; + if (rte_meter_trtcm_profile_config(&tp, &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_profile_config(&tp, &tparams1) == 0) + melog(TRTCM_CFG_MSG" pir < cir test"); + + /* usual parameter, should be successful */ + if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) + melog(TRTCM_CFG_MSG); + + return 0; +} + +/** + * functional test for rte_meter_trtcm_rfc4115_config + */ +static inline int +tm_test_trtcm_rfc4115_config(void) +{ + struct rte_meter_trtcm_rfc4115_profile tp; + struct rte_meter_trtcm_rfc4115_params rfc4115params1; +#define TRTCM_RFC4115_CFG_MSG "trtcm_rfc4115_config" + + /* invalid parameter test */ + if (rte_meter_trtcm_rfc4115_profile_config(NULL, NULL) == 0) + melog(TRTCM_RFC4115_CFG_MSG); + if (rte_meter_trtcm_rfc4115_profile_config(&tp, NULL) == 0) + melog(TRTCM_RFC4115_CFG_MSG); + if (rte_meter_trtcm_rfc4115_profile_config(NULL, &rfc4115params) == 0) + melog(TRTCM_RFC4115_CFG_MSG); + + /* + * cbs and pbs should be none-zero if cir and eir are none-zero + * respectively + */ + rfc4115params1 = rfc4115params; + rfc4115params1.cbs = 0; + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params1) == 0) + melog(TRTCM_RFC4115_CFG_MSG); + + rfc4115params1 = rfc4115params; + rfc4115params1.ebs = 0; + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params1) == 0) + melog(TRTCM_RFC4115_CFG_MSG); + + /* usual parameter, should be successful */ + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_RFC4115_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_profile sp; + struct rte_meter_srtcm sm; + uint64_t time; + uint64_t hz = rte_get_tsc_hz(); + + /* Test green */ + if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + if (rte_meter_srtcm_config(&sm, &sp) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_srtcm_color_blind_check( + &sm, &sp, time, TM_TEST_SRTCM_CBS_DF - 1) + != e_RTE_METER_GREEN) + melog(SRTCM_BLIND_CHECK_MSG" GREEN"); + + /* Test yellow */ + if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + if (rte_meter_srtcm_config(&sm, &sp) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_srtcm_color_blind_check( + &sm, &sp, time, TM_TEST_SRTCM_CBS_DF + 1) + != e_RTE_METER_YELLOW) + melog(SRTCM_BLIND_CHECK_MSG" YELLOW"); + + if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + if (rte_meter_srtcm_config(&sm, &sp) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_srtcm_color_blind_check( + &sm, &sp, time, (uint32_t)sp.ebs - 1) != e_RTE_METER_YELLOW) + melog(SRTCM_BLIND_CHECK_MSG" YELLOW"); + + /* Test red */ + if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + if (rte_meter_srtcm_config(&sm, &sp) != 0) + melog(SRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_srtcm_color_blind_check( + &sm, &sp, 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_profile tp; + struct rte_meter_trtcm tm; + uint64_t hz = rte_get_tsc_hz(); + + /* Test green */ + if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + if (rte_meter_trtcm_config(&tm, &tp) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_color_blind_check( + &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1) + != e_RTE_METER_GREEN) + melog(TRTCM_BLIND_CHECK_MSG" GREEN"); + + /* Test yellow */ + if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + if (rte_meter_trtcm_config(&tm, &tp) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_color_blind_check( + &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1) + != e_RTE_METER_YELLOW) + melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); + + if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + if (rte_meter_trtcm_config(&tm, &tp) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_color_blind_check( + &tm, &tp, time, TM_TEST_TRTCM_PBS_DF - 1) + != e_RTE_METER_YELLOW) + melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); + + /* Test red */ + if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + if (rte_meter_trtcm_config(&tm, &tp) != 0) + melog(TRTCM_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_color_blind_check( + &tm, &tp, time, TM_TEST_TRTCM_PBS_DF + 1) + != e_RTE_METER_RED) + melog(TRTCM_BLIND_CHECK_MSG" RED"); + + return 0; +} + +/** + * functional test for rte_meter_trtcm_rfc4115_color_blind_check + */ +static inline int +tm_test_trtcm_rfc4115_color_blind_check(void) +{ +#define TRTCM_RFC4115_BLIND_CHECK_MSG "trtcm_rfc4115_blind_check" + + uint64_t time; + struct rte_meter_trtcm_rfc4115_profile tp; + struct rte_meter_trtcm_rfc4115 tm; + uint64_t hz = rte_get_tsc_hz(); + + /* Test green */ + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG); + if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_rfc4115_color_blind_check( + &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1) + != e_RTE_METER_GREEN) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG" GREEN"); + + /* Test yellow */ + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG); + if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_rfc4115_color_blind_check( + &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1) + != e_RTE_METER_YELLOW) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG" YELLOW"); + + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG); + if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_rfc4115_color_blind_check( + &tm, &tp, time, TM_TEST_TRTCM_EBS_DF - 1) + != e_RTE_METER_YELLOW) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG" YELLOW"); + + /* Test red */ + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG); + if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) + melog(TRTCM_RFC4115_BLIND_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_rfc4115_color_blind_check( + &tm, &tp, time, TM_TEST_TRTCM_EBS_DF + 1) + != e_RTE_METER_RED) + melog(TRTCM_RFC4115_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_profile sp; + struct rte_meter_srtcm sm; + uint64_t time; + uint64_t hz = rte_get_tsc_hz(); + + if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + if (rte_meter_srtcm_config(&sm, &sp) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_srtcm_color_aware_check( + &sm, &sp, 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_profile_config(&sp, &sparams) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + if (rte_meter_srtcm_config(&sm, &sp) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_srtcm_color_aware_check( + &sm, &sp, 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_profile_config(&sp, &sparams) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + if (rte_meter_srtcm_config(&sm, &sp) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_srtcm_color_aware_check( + &sm, &sp, 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_profile_config(&sp, &sparams) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + if (rte_meter_srtcm_config(&sm, &sp) != 0) + melog(SRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_srtcm_color_aware_check( + &sm, &sp, 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_profile tp; + struct rte_meter_trtcm tm; + uint64_t time; + uint64_t hz = rte_get_tsc_hz(); + + if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + if (rte_meter_trtcm_config(&tm, &tp) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_color_aware_check( + &tm, &tp, 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_profile_config(&tp, &tparams) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + if (rte_meter_trtcm_config(&tm, &tp) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_color_aware_check( + &tm, &tp, 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_profile_config(&tp, &tparams) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + if (rte_meter_trtcm_config(&tm, &tp) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_color_aware_check( + &tm, &tp, 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_profile_config(&tp, &tparams) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + if (rte_meter_trtcm_config(&tm, &tp) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_color_aware_check( + &tm, &tp, 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; +} + +/** + * @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_rfc4115_aware_check +(enum rte_meter_color in[4], enum rte_meter_color out[4]) +{ +#define TRTCM_RFC4115_AWARE_CHECK_MSG "trtcm_rfc4115_aware_check" + struct rte_meter_trtcm_rfc4115_profile tp; + struct rte_meter_trtcm_rfc4115 tm; + uint64_t time; + uint64_t hz = rte_get_tsc_hz(); + + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_AWARE_CHECK_MSG); + if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_rfc4115_color_aware_check( + &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0]) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG" %u:%u", in[0], out[0]); + + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG); + if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_rfc4115_color_aware_check( + &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1]) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG" %u:%u", in[1], out[1]); + + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG); + if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_rfc4115_color_aware_check( + &tm, &tp, time, TM_TEST_TRTCM_EBS_DF - 1, in[2]) != out[2]) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG" %u:%u", in[2], out[2]); + + if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG); + if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG); + time = rte_get_tsc_cycles() + hz; + if (rte_meter_trtcm_rfc4115_color_aware_check( + &tm, &tp, time, TM_TEST_TRTCM_EBS_DF + 1, in[3]) != out[3]) + melog(TRTCM_RFC4115_AWARE_CHECK_MSG" %u:%u", in[3], out[3]); + + return 0; +} + +/** + * functional test for rte_meter_trtcm_rfc4115_color_aware_check + */ +static inline int +tm_test_trtcm_rfc4115_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_rfc4115_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_rfc4115_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_rfc4115_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_trtcm_rfc4115_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_trtcm_rfc4115_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; + + if (tm_test_trtcm_rfc4115_color_aware_check() != 0) + return -1; + + return 0; + +} + +REGISTER_TEST_COMMAND(meter_autotest, test_meter); diff --git a/app/test/test_metrics.c b/app/test/test_metrics.c new file mode 100644 index 0000000000..3c2f36b8a4 --- /dev/null +++ b/app/test/test_metrics.c @@ -0,0 +1,313 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include +#include +#include + +#include +#include + +#include "test.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define REG_METRIC_COUNT 6 +#define METRIC_LESSER_COUNT 3 +#define KEY 1 +#define VALUE 1 + +/* Initializes metric module. This function must be called + * from a primary process before metrics are used + */ +static int +test_metrics_init(void) +{ + rte_metrics_init(rte_socket_id()); + return TEST_SUCCESS; +} + + /* Test Case to check failures when memzone init is not done */ +static int +test_metrics_without_init(void) +{ + int err = 0; + const uint64_t value[REG_METRIC_COUNT] = {0}; + const char * const mnames[] = { + "mean_bits_in", "mean_bits_out", + "peak_bits_in", "peak_bits_out", + }; + + /* Failure Test: Checking for memzone initialization */ + err = rte_metrics_reg_name("peak_bits_in"); + TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); + + err = rte_metrics_reg_names(&mnames[0], 1); + TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); + + err = rte_metrics_update_value(RTE_METRICS_GLOBAL, KEY, VALUE); + TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); + + err = rte_metrics_update_values(RTE_METRICS_GLOBAL, KEY, &value[0], 4); + TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); + + err = rte_metrics_get_names(NULL, 0); + TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); + + err = rte_metrics_get_values(RTE_METRICS_GLOBAL, NULL, 0); + TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); + + return TEST_SUCCESS; +} + +/* Test Case to validate registering a single metric */ +static int +test_metrics_reg_name_with_validname(void) +{ + int err = 0; + + /* Test to register the new metric name */ + err = rte_metrics_reg_name("peak_bits_out"); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Test to register the same metric name */ + err = rte_metrics_reg_name("peak_bits_out"); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Test case to validate registering a invalid metric */ + err = rte_metrics_reg_name(NULL); + TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); + + return TEST_SUCCESS; +} + +/* Test case to validate registering a list of valid metric names */ +static int +test_metrics_reg_names(void) +{ + int err = 0; + const char * const mnames[] = { + "mean_bits_in", "mean_bits_out", + "peak_bits_in", "peak_bits_out", + }; + + /* Success Test: valid array and count size */ + err = rte_metrics_reg_names(&mnames[0], ARRAY_SIZE(mnames)); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + return TEST_SUCCESS; +} + +/* Test case to validate update a metric */ +static int +test_metrics_update_value(void) +{ + int err = 0; + + /* Successful Test: Valid port_id, key and value */ + err = rte_metrics_update_value(RTE_METRICS_GLOBAL, KEY, VALUE); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Successful Test: Valid port_id otherthan RTE_METRICS_GLOBAL, key + * and value + */ + err = rte_metrics_update_value(9, KEY, VALUE); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Failed Test: Invalid port_id with lower value */ + err = rte_metrics_update_value(-2, KEY, VALUE); + TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); + + /* Failed Test: Invalid port_id with higher value */ + err = rte_metrics_update_value(39, KEY, VALUE); + TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); + + /* Failed Test: valid port id, value with invalid key */ + err = rte_metrics_update_value(RTE_METRICS_GLOBAL, KEY+12, VALUE); + TEST_ASSERT(err < 0, "%s, %d", __func__, __LINE__); + + return TEST_SUCCESS; +} + +/* Test case to validate update a list of metrics */ +static int +test_metrics_update_values(void) +{ + int err = 0; + const uint64_t value[REG_METRIC_COUNT] = {1, 2, 3, 4, 5, 6}; + + /* Successful Test: update metrics with first set */ + err = rte_metrics_update_values(RTE_METRICS_GLOBAL, 0, + &value[0], 1); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Successful Test: update metrics with second set */ + err = rte_metrics_update_values(RTE_METRICS_GLOBAL, 1, + &value[1], 1); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Successful Test: update metrics with third set */ + err = rte_metrics_update_values(RTE_METRICS_GLOBAL, 2, + &value[2], 4); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Failed Test: Invalid count size */ + err = rte_metrics_update_values(RTE_METRICS_GLOBAL, + KEY, &value[0], ARRAY_SIZE(value)); + TEST_ASSERT(err < 0, "%s, %d", __func__, __LINE__); + + /* Failed Test: Invalid port_id(lower value) and valid data */ + err = rte_metrics_update_values(-2, KEY, &value[0], ARRAY_SIZE(value)); + TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); + + /* Failed Test: Invalid port_id(higher value) and valid data */ + err = rte_metrics_update_values(39, 1, &value[0], ARRAY_SIZE(value)); + TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); + + /* Failed Test: Invalid array */ + err = rte_metrics_update_values(RTE_METRICS_GLOBAL, + KEY, NULL, ARRAY_SIZE(value)); + TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); + + return TEST_SUCCESS; +} + +/* Test to validate get metric name-key lookup table */ +static int +test_metrics_get_names(void) +{ + int err = 0; + struct rte_metric_name metrics[METRIC_LESSER_COUNT]; + struct rte_metric_name success_metrics[REG_METRIC_COUNT]; + + /* Successful Test: Invalid array list */ + err = rte_metrics_get_names(NULL, 0); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Successful Test: Valid array list, Correct Count Stats same + * as memzone stats + */ + err = rte_metrics_get_names(success_metrics, REG_METRIC_COUNT); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Successful Test: Valid array list, Increase Count Stats than + * memzone stats + */ + err = rte_metrics_get_names(success_metrics, REG_METRIC_COUNT+5); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Successful Test, Not update results: + * Invalid array list, Lesser Count Stats than allocated stats + */ + err = rte_metrics_get_names(metrics, METRIC_LESSER_COUNT); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + return TEST_SUCCESS; +} + +/* Test to validate get list of metric values */ +static int +test_metrics_get_values(void) +{ + int i = 0; + int err = 0; + struct rte_metric_value getvalues[REG_METRIC_COUNT]; + + size_t m_size = sizeof(struct rte_metric_value); + for (i = 0; i < REG_METRIC_COUNT; i++) + memset(&getvalues[i], 0, m_size); + + /* Successful Test, Not update results: valid arguments + * count lessthan the memzone stats + */ + err = rte_metrics_get_values(RTE_METRICS_GLOBAL, getvalues, + METRIC_LESSER_COUNT); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Successful Test, update results: valid arguments */ + err = rte_metrics_get_values(RTE_METRICS_GLOBAL, getvalues, + REG_METRIC_COUNT); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Successful Test : valid arguments count greaterthan the + * memzone stats + */ + err = rte_metrics_get_values(RTE_METRICS_GLOBAL, getvalues, + REG_METRIC_COUNT+2); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + /* Failure Test: Invalid port_id(lower value) with correct values + * and Capacity + */ + err = rte_metrics_get_values(-2, getvalues, REG_METRIC_COUNT); + TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); + + /* Failure Test: Invalid port_id(higher value) with correct values + * and Capacity + */ + err = rte_metrics_get_values(33, getvalues, REG_METRIC_COUNT); + TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); + + /* Successful Test: valid port_id with incorrect values and valid + * capacity + */ + err = rte_metrics_get_values(RTE_METRICS_GLOBAL, NULL, + REG_METRIC_COUNT); + TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); + + return TEST_SUCCESS; +} + +static struct unit_test_suite metrics_testsuite = { + .suite_name = "Metrics Unit Test Suite", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + /* Test Case 1: Test to check all metric APIs without + * metrics init + */ + TEST_CASE(test_metrics_without_init), + + /* TEST CASE 2: Test to register valid metrics*/ + TEST_CASE_ST(test_metrics_init, NULL, + test_metrics_reg_name_with_validname), + + /* TEST CASE 3: Test to register list of metrics with valid + * names and valid count size, invalid names and invalid + * count size + */ + TEST_CASE(test_metrics_reg_names), + + /* TEST CASE 4: Test to register a update value with valid port + * id and invalid port id + */ + TEST_CASE(test_metrics_update_value), + + /* TEST CASE 5: Test to register update list of values with + * valid port id, key, value, count size and invalid port id, + * key, value, count size + */ + TEST_CASE(test_metrics_update_values), + + /* TEST CASE 6: Test to get metric names-key with valid + * array list, count size and invalid array list, count size + */ + TEST_CASE(test_metrics_get_names), + + /* TEST CASE 7: Test to get list of metric values with valid + * port id, array list, count size and invalid port id, + * arraylist, count size + */ + TEST_CASE(test_metrics_get_values), + TEST_CASES_END() + } +}; + +static int +test_metrics(void) +{ + return unit_test_suite_runner(&metrics_testsuite); +} + +REGISTER_TEST_COMMAND(metrics_autotest, test_metrics); diff --git a/app/test/test_mp_secondary.c b/app/test/test_mp_secondary.c new file mode 100644 index 0000000000..b597dfcdf1 --- /dev/null +++ b/app/test/test_mp_secondary.c @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 + +#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__) + +/* + * 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 + + 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) { + 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_pdump.c b/app/test/test_pdump.c new file mode 100644 index 0000000000..4a894c0e1b --- /dev/null +++ b/app/test/test_pdump.c @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ +#include +#include +#include +#include + +#include +#include +#include "rte_eal.h" +#include "rte_lcore.h" +#include "rte_mempool.h" +#include "rte_ring.h" + +#include "sample_packet_forward.h" +#include "test.h" +#include "process.h" +#include "test_pdump.h" + +#define launch_p(ARGV) process_dup(ARGV, \ + sizeof(ARGV)/(sizeof(ARGV[0])), __func__) + +struct rte_ring *ring_server; +uint16_t portid; +uint16_t flag_for_send_pkts = 1; + +int +test_pdump_init(void) +{ + int ret = 0; + + ret = rte_pdump_init(); + if (ret < 0) { + printf("rte_pdump_init failed\n"); + return -1; + } + ret = test_ring_setup(&ring_server, &portid); + if (ret < 0) { + printf("test_ring_setup failed\n"); + return -1; + } + printf("pdump_init success\n"); + return ret; +} + +int +run_pdump_client_tests(void) +{ + int flags = RTE_PDUMP_FLAG_TX, ret = 0, itr; + char deviceid[] = "net_ring_net_ringa"; + struct rte_ring *ring_client; + struct rte_mempool *mp = NULL; + struct rte_eth_dev *eth_dev = NULL; + char poolname[] = "mbuf_pool_client"; + + ret = test_get_mempool(&mp, poolname); + if (ret < 0) + return -1; + mp->flags = 0x0000; + ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(), + RING_F_SP_ENQ | RING_F_SC_DEQ); + if (ring_client == NULL) { + printf("rte_ring_create SR0 failed"); + return -1; + } + + eth_dev = rte_eth_dev_attach_secondary(deviceid); + if (!eth_dev) { + printf("Failed to probe %s", deviceid); + return -1; + } + rte_eth_dev_probing_finish(eth_dev); + + ring_client->prod.single = 0; + ring_client->cons.single = 0; + + printf("\n***** flags = RTE_PDUMP_FLAG_TX *****\n"); + + for (itr = 0; itr < NUM_ITR; itr++) { + ret = rte_pdump_enable(portid, QUEUE_ID, flags, ring_client, + mp, NULL); + if (ret < 0) { + printf("rte_pdump_enable failed\n"); + return -1; + } + printf("pdump_enable success\n"); + + ret = rte_pdump_disable(portid, QUEUE_ID, flags); + if (ret < 0) { + printf("rte_pdump_disable failed\n"); + return -1; + } + printf("pdump_disable success\n"); + + ret = rte_pdump_enable_by_deviceid(deviceid, QUEUE_ID, flags, + ring_client, mp, NULL); + if (ret < 0) { + printf("rte_pdump_enable_by_deviceid failed\n"); + return -1; + } + printf("pdump_enable_by_deviceid success\n"); + + ret = rte_pdump_disable_by_deviceid(deviceid, QUEUE_ID, flags); + if (ret < 0) { + printf("rte_pdump_disable_by_deviceid failed\n"); + return -1; + } + printf("pdump_disable_by_deviceid success\n"); + + if (itr == 0) { + flags = RTE_PDUMP_FLAG_RX; + printf("\n***** flags = RTE_PDUMP_FLAG_RX *****\n"); + } else if (itr == 1) { + flags = RTE_PDUMP_FLAG_RXTX; + printf("\n***** flags = RTE_PDUMP_FLAG_RXTX *****\n"); + } + } + if (ring_client != NULL) + test_ring_free(ring_client); + if (mp != NULL) + test_mp_free(mp); + + return ret; +} + +int +test_pdump_uninit(void) +{ + int ret = 0; + + ret = rte_pdump_uninit(); + if (ret < 0) { + printf("rte_pdump_uninit failed\n"); + return -1; + } + if (ring_server != NULL) + test_ring_free(ring_server); + printf("pdump_uninit success\n"); + test_vdev_uninit("net_ring_net_ringa"); + return ret; +} + +void * +send_pkts(void *empty) +{ + int ret = 0; + struct rte_mbuf *pbuf[NUM_PACKETS] = { }; + struct rte_mempool *mp; + char poolname[] = "mbuf_pool_server"; + + ret = test_get_mbuf_from_pool(&mp, pbuf, poolname); + if (ret < 0) + printf("get_mbuf_from_pool failed\n"); + do { + ret = test_packet_forward(pbuf, portid, QUEUE_ID); + if (ret < 0) + printf("send pkts Failed\n"); + } while (flag_for_send_pkts); + test_put_mbuf_to_pool(mp, pbuf); + return empty; +} + +/* + * 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 + */ + +int +run_pdump_server_tests(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 *const argv1[] = { + prgname, "-c", coremask, "--proc-type=secondary", + prefix + }; + + snprintf(coremask, sizeof(coremask), "%x", + (1 << rte_get_master_lcore())); + + ret = test_pdump_init(); + ret |= launch_p(argv1); + ret |= test_pdump_uninit(); + return ret; +} + +int +test_pdump(void) +{ + int ret = 0; + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + printf("IN PRIMARY PROCESS\n"); + ret = run_pdump_server_tests(); + if (ret < 0) + return TEST_FAILED; + } else if (rte_eal_process_type() == RTE_PROC_SECONDARY) { + printf("IN SECONDARY PROCESS\n"); + sleep(5); + ret = run_pdump_client_tests(); + if (ret < 0) + return TEST_FAILED; + } + return TEST_SUCCESS; +} + +REGISTER_TEST_COMMAND(pdump_autotest, test_pdump); diff --git a/app/test/test_pdump.h b/app/test/test_pdump.h new file mode 100644 index 0000000000..abef9a85ec --- /dev/null +++ b/app/test/test_pdump.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#ifndef _TEST_PDUMP_H_ +#define _TEST_PDUMP_H_ + +#define QUEUE_ID 0 +#define NUM_ITR 3 + +/* sample test to send packets to the pdump client recursively */ +void *send_pkts(void *port); + +/* Sample test to create setup for the pdump server tests */ +int test_pdump_init(void); + +/* Sample test to teardown the pdump server setup */ +int test_pdump_uninit(void); + +/* Sample test to run the pdump client tests */ +int run_pdump_client_tests(void); + +/* Sample test to run the pdump server tests */ +int run_pdump_server_tests(void); + +/* Sample test to run the pdump client and server tests based on + * the process type + */ +int test_pdump(void); + +#endif /* _TEST_PDUMP_H_ */ diff --git a/app/test/test_per_lcore.c b/app/test/test_per_lcore.c new file mode 100644 index 0000000000..19b55f2642 --- /dev/null +++ b/app/test/test_per_lcore.c @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..ed8524a176 --- /dev/null +++ b/app/test/test_pmd_perf.c @@ -0,0 +1,870 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + + +#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 (1024) +#define RTE_TEST_TX_DESC_DEFAULT (1024) +#define RTE_PORT_ALL (~(uint16_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, + }, + .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 */ +}; + +enum { + LCORE_INVALID = 0, + LCORE_AVAIL, + LCORE_USED, +}; + +struct lcore_conf { + uint8_t status; + uint8_t socketid; + uint16_t nb_ports; + uint16_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(uint16_t port_num, uint32_t port_mask) +{ +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */ + uint16_t portid; + uint8_t 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", + portid, 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", 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; +} + +static volatile uint64_t stop; +static uint64_t count; +static uint64_t drop; +static uint64_t idle; + +static void +reset_count(void) +{ + count = 0; + drop = 0; + idle = 0; +} + +static void +stats_display(uint16_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(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(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(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 = 0; + uint64_t timeout = 10000; + do { /* dry out */ + nb_rx = rte_eth_rx_burst(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; + + if (unlikely(nb_rx == 0)) + timeout--; + } while (nb_free != pkt_per_port && timeout != 0); + printf("free %d (expected %d) mbuf left in port %u\n", nb_free, + 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; +} + +static 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; + int num[RTE_MAX_ETHPORTS]; + + 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; + num[portid] = 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(portid, 0, + &pkts_burst[next[portid]], + RTE_MIN(MAX_PKT_BURST, num[portid])); + if (unlikely(nb_rx == 0)) { + timeout--; + if (unlikely(timeout == 0)) + goto timeout; + continue; + } + next[portid] += nb_rx; + num[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 * conf->nb_ports; + + 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]; + nb_tx = 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_avail(); + 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; + RTE_ETH_FOREACH_DEV(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 */ + RTE_ETH_FOREACH_DEV(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.tx_rs_thresh = 32; + tx_conf.tx_free_thresh = 32; + return 0; + } else if (!strcmp(mode, "scalar")) { + /* bulk alloc rx, full-featured tx */ + tx_conf.tx_rs_thresh = 32; + tx_conf.tx_free_thresh = 32; + port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CHECKSUM; + 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.tx_rs_thresh = 32; + tx_conf.tx_free_thresh = 32; + port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CHECKSUM; + return 0; + } else if (!strcmp(mode, "full")) { + /* full feature rx,tx pair */ + tx_conf.tx_rs_thresh = 32; + tx_conf.tx_free_thresh = 32; + port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_SCATTER; + 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 new file mode 100644 index 0000000000..6414bbd189 --- /dev/null +++ b/app/test/test_pmd_ring.c @@ -0,0 +1,566 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2015 Intel Corporation + */ +#include "test.h" +#include + +#include + +#include +#include +#include + +#define SOCKET0 0 +#define RING_SIZE 256 +#define NUM_RINGS 2 +#define NB_MBUF 512 + +static struct rte_mempool *mp; +struct rte_ring *rxtx[NUM_RINGS]; +static int tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte; + +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 TEST_FAILED; + } + + 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 TEST_FAILED; + } + + for (i = 0; i < RING_SIZE/2; i++) + if (pbufs[i] != &bufs[i]) { + printf("Error: received data does not match that transmitted\n"); + return TEST_FAILED; + } + + return TEST_SUCCESS; +} + +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(void) +{ + struct rte_eth_stats stats, stats2; + struct rte_mbuf buf, *pbuf = &buf; + struct rte_eth_conf null_conf; + + memset(&null_conf, 0, sizeof(struct rte_eth_conf)); + + if ((rte_eth_dev_configure(rxtx_portd, 1, 1, &null_conf) < 0) + || (rte_eth_dev_configure(rxtx_porte, 1, 1, + &null_conf) < 0)) { + printf("Configure failed for port\n"); + return TEST_FAILED; + } + + if ((rte_eth_tx_queue_setup(rxtx_portd, 0, RING_SIZE, + SOCKET0, NULL) < 0) + || (rte_eth_tx_queue_setup(rxtx_porte, 0, RING_SIZE, + SOCKET0, NULL) < 0)) { + printf("TX queue setup failed\n"); + return TEST_FAILED; + } + + if ((rte_eth_rx_queue_setup(rxtx_portd, 0, RING_SIZE, + SOCKET0, NULL, mp) < 0) + || (rte_eth_rx_queue_setup(rxtx_porte, 0, RING_SIZE, + SOCKET0, NULL, mp) < 0)) { + printf("RX queue setup failed\n"); + return TEST_FAILED; + } + + if ((rte_eth_dev_start(rxtx_portd) < 0) + || (rte_eth_dev_start(rxtx_porte) < 0)) { + printf("Error starting port\n"); + return TEST_FAILED; + } + + rte_eth_stats_reset(rxtx_portd); + /* check stats of port, should all be zero */ + rte_eth_stats_get(rxtx_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", rxtx_portd); + return TEST_FAILED; + } + + rte_eth_stats_reset(rxtx_porte); + /* check stats of port, should all be zero */ + rte_eth_stats_get(rxtx_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", rxtx_porte); + return TEST_FAILED; + } + + /* + * send and receive 1 packet (rxtx_portd -> rxtx_porte) + * and check for stats update + */ + printf("Testing send and receive 1 packet (rxtx_portd -> rxtx_porte)\n"); + if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", rxtx_portd); + return TEST_FAILED; + } + + if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", rxtx_porte); + return TEST_FAILED; + } + + rte_eth_stats_get(rxtx_portd, &stats); + rte_eth_stats_get(rxtx_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", + rxtx_portd); + return TEST_FAILED; + } + + 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", + rxtx_porte); + return TEST_FAILED; + } + + /* + * send and receive 1 packet (rxtx_porte -> rxtx_portd) + * and check for stats update + */ + printf("Testing send and receive 1 packet " + "(rxtx_porte -> rxtx_portd)\n"); + if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", rxtx_porte); + return TEST_FAILED; + } + + if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", rxtx_portd); + return TEST_FAILED; + } + + rte_eth_stats_get(rxtx_portd, &stats); + rte_eth_stats_get(rxtx_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", + rxtx_portd); + return TEST_FAILED; + } + + 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", + rxtx_porte); + return TEST_FAILED; + } + + /* + * send and receive 1 packet (rxtx_portd -> rxtx_portd) + * and check for stats update + */ + printf("Testing send and receive 1 packet " + "(rxtx_portd -> rxtx_portd)\n"); + if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", rxtx_portd); + return TEST_FAILED; + } + + if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", rxtx_porte); + return TEST_FAILED; + } + + rte_eth_stats_get(rxtx_portd, &stats); + rte_eth_stats_get(rxtx_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", + rxtx_portd); + return TEST_FAILED; + } + + 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", + rxtx_porte); + return TEST_FAILED; + } + + /* + * send and receive 1 packet (rxtx_porte -> rxtx_porte) + * and check for stats update + */ + printf("Testing send and receive 1 packet " + "(rxtx_porte -> rxtx_porte)\n"); + if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { + printf("Error sending packet to port %d\n", rxtx_porte); + return TEST_FAILED; + } + + if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { + printf("Error receiving packet from port %d\n", rxtx_porte); + return TEST_FAILED; + } + + rte_eth_stats_get(rxtx_portd, &stats); + rte_eth_stats_get(rxtx_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", + rxtx_portd); + return TEST_FAILED; + } + + 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", + rxtx_porte); + return TEST_FAILED; + } + + rte_eth_dev_stop(rxtx_portd); + rte_eth_dev_stop(rxtx_porte); + + return TEST_SUCCESS; +} + +static void +test_cleanup_resources(void) +{ + int itr; + for (itr = 0; itr < NUM_RINGS; itr++) + rte_ring_free(rxtx[itr]); + + rte_eth_dev_stop(tx_porta); + rte_eth_dev_stop(rx_portb); + rte_eth_dev_stop(rxtx_portc); + + rte_mempool_free(mp); + rte_vdev_uninit("net_ring_net_ringa"); + rte_vdev_uninit("net_ring_net_ringb"); + rte_vdev_uninit("net_ring_net_ringc"); + rte_vdev_uninit("net_ring_net_ringd"); + rte_vdev_uninit("net_ring_net_ringe"); +} + +static int +test_pmd_ringcreate_setup(void) +{ + uint8_t nb_ports; + + nb_ports = rte_eth_dev_count_avail(); + 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; + } + return 0; +} + +static int +test_command_line_ring_port(void) +{ + int port, cmdl_port0 = -1; + /* find a port created with the --vdev=net_ring0 command line option */ + RTE_ETH_FOREACH_DEV(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) { + TEST_ASSERT((test_ethdev_configure_port(cmdl_port0) < 0), + "test ethdev configure port cmdl_port0 is failed"); + TEST_ASSERT((test_send_basic_packets_port(cmdl_port0) < 0), + "test send basic packets port cmdl_port0 is failed"); + TEST_ASSERT((test_stats_reset(cmdl_port0) < 0), + "test stats reset cmdl_port0 is failed"); + TEST_ASSERT((test_get_stats(cmdl_port0) < 0), + "test get stats cmdl_port0 is failed"); + rte_eth_dev_stop(cmdl_port0); + } + return TEST_SUCCESS; +} + +static int +test_ethdev_configure_ports(void) +{ + TEST_ASSERT((test_ethdev_configure_port(tx_porta) == 0), + "test ethdev configure ports tx_porta is failed"); + TEST_ASSERT((test_ethdev_configure_port(rx_portb) == 0), + "test ethdev configure ports rx_portb is failed"); + TEST_ASSERT((test_ethdev_configure_port(rxtx_portc) == 0), + "test ethdev configure ports rxtx_portc is failed"); + + return TEST_SUCCESS; +} + +static int +test_get_stats_for_port(void) +{ + TEST_ASSERT(test_get_stats(rxtx_portc) == 0, "test get stats failed"); + return TEST_SUCCESS; +} + +static int +test_stats_reset_for_port(void) +{ + TEST_ASSERT(test_stats_reset(rxtx_portc) == 0, "test stats reset failed"); + return TEST_SUCCESS; +} + +static struct +unit_test_suite test_pmd_ring_suite = { + .setup = test_pmd_ringcreate_setup, + .teardown = test_cleanup_resources, + .suite_name = "Test Pmd Ring Unit Test Suite", + .unit_test_cases = { + TEST_CASE(test_ethdev_configure_ports), + TEST_CASE(test_send_basic_packets), + TEST_CASE(test_get_stats_for_port), + TEST_CASE(test_stats_reset_for_port), + TEST_CASE(test_pmd_ring_pair_create_attach), + TEST_CASE(test_command_line_ring_port), + TEST_CASES_END() + } +}; + +static int +test_pmd_ring(void) +{ + return unit_test_suite_runner(&test_pmd_ring_suite); +} + +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 new file mode 100644 index 0000000000..6318da18f2 --- /dev/null +++ b/app/test/test_pmd_ring_perf.c @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015 Intel Corporation + */ + + +#include +#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 uint16_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], NULL); + 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, NULL); + rte_ring_dequeue_bulk(r, &burst, 1, NULL); + } + 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], NULL); + rte_ring_sc_dequeue_bulk(r, (void *)burst, + bulk_sizes[sz], NULL); + } + 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) +{ + char name[RTE_ETH_NAME_MAX_LEN]; + + 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(); + + /* release port and ring resources */ + rte_eth_dev_stop(ring_ethdev_port); + rte_eth_dev_get_name_by_port(ring_ethdev_port, name); + rte_vdev_uninit(name); + rte_ring_free(r); + 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 new file mode 100644 index 0000000000..a0ee219830 --- /dev/null +++ b/app/test/test_power.c @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#include +#include + +#include "test.h" + +#ifndef RTE_LIBRTE_POWER + +static int +test_power(void) +{ + printf("Power management library not supported, skipping test\n"); + return TEST_SKIPPED; +} + +#else + +#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; +} +#endif + +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 new file mode 100644 index 0000000000..61b1da05ae --- /dev/null +++ b/app/test/test_power_acpi_cpufreq.c @@ -0,0 +1,572 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#ifndef RTE_LIBRTE_POWER + +static int +test_power_acpi_cpufreq(void) +{ + printf("Power management library not supported, skipping test\n"); + return TEST_SKIPPED; +} + +static int +test_power_acpi_caps(void) +{ + printf("Power management library not supported, skipping test\n"); + return TEST_SKIPPED; +} + +#else +#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/cpuinfo_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; + + /* 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 TEST_SKIPPED; + } + + /* Test environment configuration */ + env = rte_power_get_env(); + if ((env != PM_ENV_ACPI_CPUFREQ) && (env != PM_ENV_PSTATE_CPUFREQ)) { + printf("Unexpectedly got an environment other than ACPI/PSTATE\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; + } + + 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 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 TEST_SKIPPED; + } + + /** + * 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; +} + +static int +test_power_acpi_caps(void) +{ + struct rte_power_core_capabilities caps; + int ret; + + 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; + } + + ret = rte_power_get_capabilities(TEST_POWER_LCORE_ID, &caps); + if (ret) { + printf("POWER: Error getting capabilities\n"); + return -1; + } + + printf("POWER: Capabilities %"PRIx64"\n", caps.capabilities); + + rte_power_unset_env(); + return 0; +} + +#endif + +REGISTER_TEST_COMMAND(power_acpi_cpufreq_autotest, test_power_acpi_cpufreq); +REGISTER_TEST_COMMAND(power_acpi_caps_autotest, test_power_acpi_caps); diff --git a/app/test/test_power_kvm_vm.c b/app/test/test_power_kvm_vm.c new file mode 100644 index 0000000000..785cd048df --- /dev/null +++ b/app/test/test_power_kvm_vm.c @@ -0,0 +1,302 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#include +#include +#include +#include +#include + +#include "test.h" + +#ifndef RTE_LIBRTE_POWER + +static int +test_power_kvm_vm(void) +{ + printf("Power management library not supported, skipping test\n"); + return TEST_SKIPPED; +} + +#else +#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 TEST_SKIPPED; + } + + /* 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 KVM_VM Enable Turbo of valid core */ + ret = rte_power_freq_enable_turbo(TEST_POWER_VM_LCORE_ID); + if (ret == -1) { + printf("rte_power_freq_enable_turbo failed on valid lcore" + "%u\n", TEST_POWER_VM_LCORE_ID); + goto fail_all; + } + + /* Test KVM_VM Disable Turbo of valid core */ + ret = rte_power_freq_disable_turbo(TEST_POWER_VM_LCORE_ID); + if (ret == -1) { + printf("rte_power_freq_disable_turbo failed on valid lcore" + "%u\n", TEST_POWER_VM_LCORE_ID); + 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; +} +#endif + +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 new file mode 100644 index 0000000000..41f219af78 --- /dev/null +++ b/app/test/test_prefetch.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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_rawdev.c b/app/test/test_rawdev.c new file mode 100644 index 0000000000..043a38a13f --- /dev/null +++ b/app/test/test_rawdev.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 NXP + */ +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +static int +test_rawdev_selftest_impl(const char *pmd, const char *opts) +{ + rte_vdev_init(pmd, opts); + return rte_rawdev_selftest(rte_rawdev_get_dev_id(pmd)); +} + +static int +test_rawdev_selftest_skeleton(void) +{ + return test_rawdev_selftest_impl("rawdev_skeleton", ""); +} + +REGISTER_TEST_COMMAND(rawdev_autotest, test_rawdev_selftest_skeleton); diff --git a/app/test/test_reciprocal_division.c b/app/test/test_reciprocal_division.c new file mode 100644 index 0000000000..8ea9b1d24d --- /dev/null +++ b/app/test/test_reciprocal_division.c @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Cavium, Inc + */ + +#include "test.h" + +#include +#include +#include + +#include +#include +#include +#include + +#define MAX_ITERATIONS (1ULL << 32) +#define DIVIDE_ITER (100) + +static int +test_reciprocal(void) +{ + int result = 0; + uint32_t divisor_u32 = 0; + uint32_t dividend_u32; + uint32_t nresult_u32; + uint32_t rresult_u32; + uint64_t i, j; + uint64_t divisor_u64 = 0; + uint64_t dividend_u64; + uint64_t nresult_u64; + uint64_t rresult_u64; + struct rte_reciprocal reci_u32 = {0}; + struct rte_reciprocal_u64 reci_u64 = {0}; + + rte_srand(rte_rdtsc()); + printf("Validating unsigned 32bit division.\n"); + for (i = 0; i < MAX_ITERATIONS; i++) { + /* Change divisor every DIVIDE_ITER iterations. */ + if (i % DIVIDE_ITER == 0) { + divisor_u32 = rte_rand(); + reci_u32 = rte_reciprocal_value(divisor_u32); + } + + dividend_u32 = rte_rand(); + nresult_u32 = dividend_u32 / divisor_u32; + rresult_u32 = rte_reciprocal_divide(dividend_u32, + reci_u32); + if (nresult_u32 != rresult_u32) { + printf("Division failed, %"PRIu32"/%"PRIu32" = " + "expected %"PRIu32" result %"PRIu32"\n", + dividend_u32, divisor_u32, + nresult_u32, rresult_u32); + result = 1; + break; + } + } + + printf("Validating unsigned 64bit division.\n"); + for (i = 0; i < MAX_ITERATIONS; i++) { + /* Change divisor every DIVIDE_ITER iterations. */ + if (i % DIVIDE_ITER == 0) { + divisor_u64 = rte_rand(); + reci_u64 = rte_reciprocal_value_u64(divisor_u64); + } + + dividend_u64 = rte_rand(); + nresult_u64 = dividend_u64 / divisor_u64; + rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, + &reci_u64); + if (nresult_u64 != rresult_u64) { + printf("Division failed, %"PRIu64"/%"PRIu64" = " + "expected %"PRIu64" result %"PRIu64"\n", + dividend_u64, divisor_u64, + nresult_u64, rresult_u64); + result = 1; + break; + } + } + + printf("Validating unsigned 64bit division with 32bit divisor.\n"); + for (i = 0; i < MAX_ITERATIONS; i++) { + /* Change divisor every DIVIDE_ITER iterations. */ + if (i % DIVIDE_ITER == 0) { + divisor_u64 = rte_rand() >> 32; + reci_u64 = rte_reciprocal_value_u64(divisor_u64); + } + + dividend_u64 = rte_rand(); + + nresult_u64 = dividend_u64 / divisor_u64; + rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, + &reci_u64); + + if (nresult_u64 != rresult_u64) { + printf("Division failed, %"PRIu64"/%"PRIu64" = " + "expected %"PRIu64" result %"PRIu64"\n", + dividend_u64, divisor_u64, + nresult_u64, rresult_u64); + result = 1; + break; + } + } + + printf("Validating division by power of 2.\n"); + for (i = 0; i < 32; i++) { + divisor_u64 = 1ull << i; + reci_u64 = rte_reciprocal_value_u64(divisor_u64); + reci_u32 = rte_reciprocal_value((uint32_t)divisor_u64); + + for (j = 0; j < MAX_ITERATIONS >> 4; j++) { + dividend_u64 = rte_rand(); + + nresult_u64 = dividend_u64 / divisor_u64; + rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, + &reci_u64); + + if (nresult_u64 != rresult_u64) { + printf( + "Division 64 failed, %"PRIu64"/%"PRIu64" = " + "expected %"PRIu64" result %"PRIu64"\n", + dividend_u64, divisor_u64, + nresult_u64, rresult_u64); + result = 1; + } + + nresult_u32 = (dividend_u64 >> 32) / divisor_u64; + rresult_u32 = rte_reciprocal_divide( + (dividend_u64 >> 32), reci_u32); + + if (nresult_u32 != rresult_u32) { + printf( + "Division 32 failed, %"PRIu64"/%"PRIu64" = " + "expected %"PRIu64" result %"PRIu64"\n", + dividend_u64 >> 32, divisor_u64, + nresult_u64, rresult_u64); + result = 1; + break; + } + } + } + + for (; i < 64; i++) { + divisor_u64 = 1ull << i; + reci_u64 = rte_reciprocal_value_u64(divisor_u64); + + for (j = 0; j < MAX_ITERATIONS >> 4; j++) { + dividend_u64 = rte_rand(); + + nresult_u64 = dividend_u64 / divisor_u64; + rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, + &reci_u64); + + if (nresult_u64 != rresult_u64) { + printf("Division failed, %"PRIu64"/%"PRIu64" = " + "expected %"PRIu64" result %"PRIu64"\n", + dividend_u64, divisor_u64, + nresult_u64, rresult_u64); + result = 1; + break; + } + } + } + + return result; +} + +REGISTER_TEST_COMMAND(reciprocal_division, test_reciprocal); diff --git a/app/test/test_reciprocal_division_perf.c b/app/test/test_reciprocal_division_perf.c new file mode 100644 index 0000000000..a7be8aa71a --- /dev/null +++ b/app/test/test_reciprocal_division_perf.c @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Cavium, Inc + */ + +#include "test.h" + +#include +#include +#include + +#include +#include +#include +#include + +#define MAX_ITERATIONS (1ULL << 32) +#define DIVIDE_ITER (1ULL << 28) + +static int +test_reciprocal_division_perf(void) +{ + int result = 0; + uint32_t divisor_u32 = 0; + uint32_t dividend_u32; + uint64_t divisor_u64 = 0; + uint64_t dividend_u64; + volatile uint32_t nresult_u32; + volatile uint32_t rresult_u32; + volatile uint64_t nresult_u64; + volatile uint64_t rresult_u64; + uint64_t start_cyc; + uint64_t split_cyc; + uint64_t end_cyc; + uint64_t tot_cyc_n = 0; + uint64_t tot_cyc_r = 0; + uint64_t i; + struct rte_reciprocal reci_u32 = {0}; + struct rte_reciprocal_u64 reci_u64 = {0}; + + rte_srand(rte_rdtsc()); + + printf("Validating unsigned 32bit division.\n"); + for (i = 0; i < MAX_ITERATIONS; i++) { + /* Change divisor every DIVIDE_ITER iterations. */ + if (i % DIVIDE_ITER == 0) { + divisor_u32 = rte_rand(); + reci_u32 = rte_reciprocal_value(divisor_u32); + } + + dividend_u32 = rte_rand(); + + start_cyc = rte_rdtsc(); + nresult_u32 = dividend_u32 / divisor_u32; + split_cyc = rte_rdtsc(); + rresult_u32 = rte_reciprocal_divide(dividend_u32, + reci_u32); + end_cyc = rte_rdtsc(); + + tot_cyc_n += split_cyc - start_cyc; + tot_cyc_r += end_cyc - split_cyc; + if (nresult_u32 != rresult_u32) { + printf("Division failed, expected %"PRIu32" " + "result %"PRIu32"", + nresult_u32, rresult_u32); + result = 1; + break; + } + } + printf("32bit Division results:\n"); + printf("Total number of cycles normal division : %"PRIu64"\n", + tot_cyc_n); + printf("Total number of cycles reciprocal division : %"PRIu64"\n", + tot_cyc_r); + printf("Cycles per division(normal) : %3.2f\n", + ((double)tot_cyc_n)/i); + printf("Cycles per division(reciprocal) : %3.2f\n\n", + ((double)tot_cyc_r)/i); + + tot_cyc_n = 0; + tot_cyc_r = 0; + + printf("Validating unsigned 64bit division.\n"); + for (i = 0; i < MAX_ITERATIONS; i++) { + /* Change divisor every DIVIDE_ITER iterations. */ + if (i % DIVIDE_ITER == 0) { + divisor_u64 = rte_rand(); + reci_u64 = rte_reciprocal_value_u64(divisor_u64); + } + + dividend_u64 = rte_rand(); + + start_cyc = rte_rdtsc(); + nresult_u64 = dividend_u64 / divisor_u64; + split_cyc = rte_rdtsc(); + rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, + &reci_u64); + end_cyc = rte_rdtsc(); + + tot_cyc_n += split_cyc - start_cyc; + tot_cyc_r += end_cyc - split_cyc; + if (nresult_u64 != rresult_u64) { + printf("Division failed, expected %"PRIu64" " + "result %"PRIu64"", + nresult_u64, rresult_u64); + result = 1; + break; + } + } + printf("64bit Division results:\n"); + printf("Total number of cycles normal division : %"PRIu64"\n", + tot_cyc_n); + printf("Total number of cycles reciprocal division : %"PRIu64"\n", + tot_cyc_r); + printf("Cycles per division(normal) : %3.2f\n", + ((double)tot_cyc_n)/i); + printf("Cycles per division(reciprocal) : %3.2f\n\n", + ((double)tot_cyc_r)/i); + + tot_cyc_n = 0; + tot_cyc_r = 0; + + printf("Validating unsigned 64bit division with 32bit divisor.\n"); + for (i = 0; i < MAX_ITERATIONS; i++) { + /* Change divisor every DIVIDE_ITER iterations. */ + if (i % DIVIDE_ITER == 0) { + divisor_u64 = rte_rand() >> 32; + reci_u64 = rte_reciprocal_value_u64(divisor_u64); + } + + dividend_u64 = rte_rand(); + + start_cyc = rte_rdtsc(); + nresult_u64 = dividend_u64 / divisor_u64; + split_cyc = rte_rdtsc(); + rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, + &reci_u64); + end_cyc = rte_rdtsc(); + + tot_cyc_n += split_cyc - start_cyc; + tot_cyc_r += end_cyc - split_cyc; + if (nresult_u64 != rresult_u64) { + printf("Division failed, expected %"PRIu64" " + "result %"PRIu64"", + nresult_u64, rresult_u64); + result = 1; + break; + } + } + + printf("64bit Division results:\n"); + printf("Total number of cycles normal division : %"PRIu64"\n", + tot_cyc_n); + printf("Total number of cycles reciprocal division : %"PRIu64"\n", + tot_cyc_r); + printf("Cycles per division(normal) : %3.2f\n", + ((double)tot_cyc_n)/i); + printf("Cycles per division(reciprocal) : %3.2f\n\n", + ((double)tot_cyc_r)/i); + + tot_cyc_n = 0; + tot_cyc_r = 0; + + printf("Validating division by power of 2.\n"); + for (i = 0; i < 64; i++) { + divisor_u64 = 1ull << i; + reci_u64 = rte_reciprocal_value_u64(divisor_u64); + + dividend_u64 = rte_rand(); + + start_cyc = rte_rdtsc(); + nresult_u64 = dividend_u64 / divisor_u64; + split_cyc = rte_rdtsc(); + rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, + &reci_u64); + end_cyc = rte_rdtsc(); + + tot_cyc_n += split_cyc - start_cyc; + tot_cyc_r += end_cyc - split_cyc; + if (nresult_u64 != rresult_u64) { + printf("Division 64 failed, %"PRIu64"/%"PRIu64" = " + "expected %"PRIu64" result %"PRIu64"\n", + dividend_u64, divisor_u64, + nresult_u64, rresult_u64); + result = 1; + break; + } + } + printf("64bit Division results:\n"); + printf("Total number of cycles normal division : %"PRIu64"\n", + tot_cyc_n); + printf("Total number of cycles reciprocal division : %"PRIu64"\n", + tot_cyc_r); + printf("Cycles per division(normal) : %3.2f\n", + ((double)tot_cyc_n)/i); + printf("Cycles per division(reciprocal) : %3.2f\n", + ((double)tot_cyc_r)/i); + + return result; +} + +REGISTER_TEST_COMMAND(reciprocal_division_perf, test_reciprocal_division_perf); diff --git a/app/test/test_red.c b/app/test/test_red.c new file mode 100644 index 0000000000..e973f3131e --- /dev/null +++ b/app/test/test_red.c @@ -0,0 +1,1856 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..58fa9c71b5 --- /dev/null +++ b/app/test/test_reorder.c @@ -0,0 +1,393 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#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"); + + for (i = 0; i < num_bufs; i++) { + bufs[i] = rte_pktmbuf_alloc(p); + TEST_ASSERT_NOT_NULL(bufs[i], "Packet allocation failed\n"); + 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; + } + bufs[i] = NULL; + } + + /* 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; + } + bufs[4] = NULL; + + /* 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; + } + bufs[5] = NULL; + + /* 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; + } + bufs[6] = NULL; + + ret = 0; +exit: + rte_reorder_free(b); + for (i = 0; i < num_bufs; i++) { + if (bufs[i] != NULL) + rte_pktmbuf_free(bufs[i]); + } + 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; + + /* initialize all robufs to NULL */ + for (i = 0; i < num_bufs; i++) + robufs[i] = NULL; + + /* 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"); + + /* 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] = rte_pktmbuf_alloc(p); + TEST_ASSERT_NOT_NULL(bufs[i], "Packet allocation failed\n"); + 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]); + bufs[1] = NULL; + + 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; + } + if (robufs[0] != NULL) + rte_pktmbuf_free(robufs[0]); + + /* 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]); + bufs[2] = NULL; + bufs[3] = NULL; + + /* Insert more packets + * RB[] = {NULL, NULL, NULL, NULL} + * OB[] = {NULL, 2, 3, 4} + */ + rte_reorder_insert(b, bufs[4]); + bufs[4] = NULL; + + /* Insert more packets + * RB[] = {2, 3, 4, NULL} + * OB[] = {NULL, NULL, 7, NULL} + */ + rte_reorder_insert(b, bufs[7]); + bufs[7] = NULL; + + /* 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; + } + for (i = 0; i < 3; i++) { + if (robufs[i] != NULL) + rte_pktmbuf_free(robufs[i]); + } + + /* + * 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_reorder_free(b); + for (i = 0; i < num_bufs; i++) { + if (bufs[i] != NULL) + rte_pktmbuf_free(bufs[i]); + if (robufs[i] != NULL) + rte_pktmbuf_free(robufs[i]); + } + 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 void +test_teardown(void) +{ + rte_reorder_free(test_params->b); + test_params->b = NULL; + rte_mempool_free(test_params->p); + test_params->p = NULL; +} + + +static struct unit_test_suite reorder_test_suite = { + + .setup = test_setup, + .teardown = test_teardown, + .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 new file mode 100644 index 0000000000..8f41e3babd --- /dev/null +++ b/app/test/test_resource.c @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 RehiveTech. All rights reserved. + */ + +#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 new file mode 100644 index 0000000000..aaf1e70ad8 --- /dev/null +++ b/app/test/test_ring.c @@ -0,0 +1,876 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 + * + * #. Performance tests. + * + * Tests done in test_ring_perf.c + */ + +#define RING_SIZE 4096 +#define MAX_BULK 32 + +static rte_atomic32_t synchro; + +#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 + +/* + * helper routine for test_ring_basic + */ +static int +test_ring_basic_full_empty(struct rte_ring *r, 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(rte_ring_enqueue_bulk(r, src, rand, + NULL) != 0); + TEST_RING_VERIFY(rte_ring_dequeue_bulk(r, dst, rand, + NULL) == rand); + + /* fill the ring */ + TEST_RING_VERIFY(rte_ring_enqueue_bulk(r, src, rsz, NULL) != 0); + 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(rte_ring_dequeue_bulk(r, dst, rsz, + NULL) == 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(struct rte_ring *r) +{ + 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, NULL); + cur_src += 1; + if (ret == 0) + goto fail; + + printf("enqueue 2 objs\n"); + ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2, NULL); + 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, NULL); + cur_src += MAX_BULK; + if (ret == 0) + goto fail; + + printf("dequeue 1 obj\n"); + ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1, NULL); + cur_dst += 1; + if (ret == 0) + goto fail; + + printf("dequeue 2 objs\n"); + ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2, NULL); + 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, NULL); + 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, NULL); + cur_src += 1; + if (ret == 0) + goto fail; + + printf("enqueue 2 objs\n"); + ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2, NULL); + 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, NULL); + cur_src += MAX_BULK; + if (ret == 0) + goto fail; + + printf("dequeue 1 obj\n"); + ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1, NULL); + cur_dst += 1; + if (ret == 0) + goto fail; + + printf("dequeue 2 objs\n"); + ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2, NULL); + 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, NULL); + 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; i= rte_ring_get_size(exact_sz_ring)) { + printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n", + __func__, + rte_ring_get_size(std_ring), + rte_ring_get_size(exact_sz_ring)); + goto end; + } + /* + * check that the exact_sz_ring can hold one more element than the + * standard ring. (16 vs 15 elements) + */ + for (i = 0; i < ring_sz - 1; i++) { + rte_ring_enqueue(std_ring, NULL); + rte_ring_enqueue(exact_sz_ring, NULL); + } + if (rte_ring_enqueue(std_ring, NULL) != -ENOBUFS) { + printf("%s: error, unexpected successful enqueue\n", __func__); + goto end; + } + if (rte_ring_enqueue(exact_sz_ring, NULL) == -ENOBUFS) { + printf("%s: error, enqueue failed\n", __func__); + goto end; + } + + /* check that dequeue returns the expected number of elements */ + if (rte_ring_dequeue_burst(exact_sz_ring, ptr_array, + RTE_DIM(ptr_array), NULL) != ring_sz) { + printf("%s: error, failed to dequeue expected nb of elements\n", + __func__); + goto end; + } + + /* check that the capacity function returns expected value */ + if (rte_ring_get_capacity(exact_sz_ring) != ring_sz) { + printf("%s: error, incorrect ring capacity reported\n", + __func__); + goto end; + } + + ret = 0; /* all ok if we get here */ +end: + rte_ring_free(std_ring); + rte_ring_free(exact_sz_ring); + return ret; +} + +static int +test_ring(void) +{ + struct rte_ring *r = NULL; + + /* some more basic operations */ + if (test_ring_basic_ex() < 0) + goto test_fail; + + rte_atomic32_init(&synchro); + + r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0); + if (r == NULL) + goto test_fail; + + /* retrieve the ring from its name */ + if (rte_ring_lookup("test") != r) { + printf("Cannot lookup ring from its name\n"); + goto test_fail; + } + + /* burst operations */ + if (test_ring_burst_basic(r) < 0) + goto test_fail; + + /* basic operations */ + if (test_ring_basic(r) < 0) + goto test_fail; + + /* basic operations */ + if ( test_create_count_odd() < 0){ + printf("Test failed to detect odd count\n"); + goto test_fail; + } else + printf("Test detected odd count\n"); + + if ( test_lookup_null() < 0){ + printf("Test failed to detect NULL ring lookup\n"); + goto test_fail; + } else + printf("Test detected NULL ring lookup\n"); + + /* test of creating ring with wrong size */ + if (test_ring_creation_with_wrong_size() < 0) + goto test_fail; + + /* test of creation ring with an used name */ + if (test_ring_creation_with_an_used_name() < 0) + goto test_fail; + + if (test_ring_with_exact_size() < 0) + goto test_fail; + + /* dump the ring status */ + rte_ring_list_dump(stdout); + + rte_ring_free(r); + + return 0; + +test_fail: + rte_ring_free(r); + + return -1; +} + +REGISTER_TEST_COMMAND(ring_autotest, test_ring); diff --git a/app/test/test_ring_perf.c b/app/test/test_ring_perf.c new file mode 100644 index 0000000000..ebb3939f51 --- /dev/null +++ b/app/test/test_ring_perf.c @@ -0,0 +1,401 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + + +#include +#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 }; + +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(struct rte_ring *r) +{ + const unsigned iter_shift = 26; + const unsigned iterations = 1<r; + const unsigned size = params->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, NULL) == 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, NULL) == 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<r; + const unsigned size = params->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, NULL) == 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, NULL) == 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, struct rte_ring *r, + 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]; + param1.r = param2.r = r; + 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(struct rte_ring *r) +{ + 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(struct rte_ring *r) +{ + 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(struct rte_ring *r) +{ + 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 + * =========== + * Provides UT for rte_rwlock API. + * Main concern is on functional testing, but also provides some + * performance measurements. + * Obviously for proper testing need to be executed with more than one lcore. + */ + +#define ITER_NUM 0x80 + +#define TEST_SEC 5 + +static rte_rwlock_t sl; +static rte_rwlock_t sl_tab[RTE_MAX_LCORE]; + +enum { + LC_TYPE_RDLOCK, + LC_TYPE_WRLOCK, +}; + +static struct { + rte_rwlock_t lock; + uint64_t tick; + volatile union { + uint8_t u8[RTE_CACHE_LINE_SIZE]; + uint64_t u64[RTE_CACHE_LINE_SIZE / sizeof(uint64_t)]; + } data; +} __rte_cache_aligned try_rwlock_data; + +struct try_rwlock_lcore { + int32_t rc; + int32_t type; + struct { + uint64_t tick; + uint64_t fail; + uint64_t success; + } stat; +} __rte_cache_aligned; + +static struct try_rwlock_lcore try_lcore_data[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; +} + +/* + * - 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 int +rwlock_test1(void) +{ + int i; + + rte_rwlock_init(&sl); + for (i=0; itype = LC_TYPE_RDLOCK; + + ftm = try_rwlock_data.tick; + stm = rte_get_timer_cycles(); + + do { + for (i = 0; i != ITER_NUM; i++) { + rc = try_read(lc); + if (rc == 0) + lcd->stat.success++; + else if (rc == -EBUSY) + lcd->stat.fail++; + else + break; + rc = 0; + } + tm = rte_get_timer_cycles() - stm; + } while (tm < ftm && rc == 0); + + lcd->rc = rc; + lcd->stat.tick = tm; + return rc; +} + +static int +try_write_lcore(__rte_unused void *data) +{ + int32_t rc; + uint32_t i, lc; + uint64_t ftm, stm, tm; + struct try_rwlock_lcore *lcd; + + lc = rte_lcore_id(); + lcd = try_lcore_data + lc; + lcd->type = LC_TYPE_WRLOCK; + + ftm = try_rwlock_data.tick; + stm = rte_get_timer_cycles(); + + do { + for (i = 0; i != ITER_NUM; i++) { + rc = try_write(lc); + if (rc == 0) + lcd->stat.success++; + else if (rc == -EBUSY) + lcd->stat.fail++; + else + break; + rc = 0; + } + tm = rte_get_timer_cycles() - stm; + } while (tm < ftm && rc == 0); + + lcd->rc = rc; + lcd->stat.tick = tm; + return rc; +} + +static void +print_try_lcore_stats(const struct try_rwlock_lcore *tlc, uint32_t lc) +{ + uint64_t f, s; + + f = RTE_MAX(tlc->stat.fail, 1ULL); + s = RTE_MAX(tlc->stat.success, 1ULL); + + printf("try_lcore_data[%u]={\n" + "\trc=%d,\n" + "\ttype=%s,\n" + "\tfail=%" PRIu64 ",\n" + "\tsuccess=%" PRIu64 ",\n" + "\tcycles=%" PRIu64 ",\n" + "\tcycles/op=%#Lf,\n" + "\tcycles/success=%#Lf,\n" + "\tsuccess/fail=%#Lf,\n" + "};\n", + lc, + tlc->rc, + tlc->type == LC_TYPE_RDLOCK ? "RDLOCK" : "WRLOCK", + tlc->stat.fail, + tlc->stat.success, + tlc->stat.tick, + (long double)tlc->stat.tick / + (tlc->stat.fail + tlc->stat.success), + (long double)tlc->stat.tick / s, + (long double)tlc->stat.success / f); +} + +static void +collect_try_lcore_stats(struct try_rwlock_lcore *tlc, + const struct try_rwlock_lcore *lc) +{ + tlc->stat.tick += lc->stat.tick; + tlc->stat.fail += lc->stat.fail; + tlc->stat.success += lc->stat.success; +} + +/* + * Process collected results: + * - check status + * - collect and print statistics + */ +static int +process_try_lcore_stats(void) +{ + int32_t rc; + uint32_t lc, rd, wr; + struct try_rwlock_lcore rlc, wlc; + + memset(&rlc, 0, sizeof(rlc)); + memset(&wlc, 0, sizeof(wlc)); + + rlc.type = LC_TYPE_RDLOCK; + wlc.type = LC_TYPE_WRLOCK; + rd = 0; + wr = 0; + + rc = 0; + RTE_LCORE_FOREACH(lc) { + rc |= try_lcore_data[lc].rc; + if (try_lcore_data[lc].type == LC_TYPE_RDLOCK) { + collect_try_lcore_stats(&rlc, try_lcore_data + lc); + rd++; + } else { + collect_try_lcore_stats(&wlc, try_lcore_data + lc); + wr++; + } + } + + if (rc == 0) { + RTE_LCORE_FOREACH(lc) + print_try_lcore_stats(try_lcore_data + lc, lc); + + if (rd != 0) { + printf("aggregated stats for %u RDLOCK cores:\n", rd); + print_try_lcore_stats(&rlc, rd); + } + + if (wr != 0) { + printf("aggregated stats for %u WRLOCK cores:\n", wr); + print_try_lcore_stats(&wlc, wr); + } + } + + return rc; +} + +static void +try_test_reset(void) +{ + memset(&try_lcore_data, 0, sizeof(try_lcore_data)); + memset(&try_rwlock_data, 0, sizeof(try_rwlock_data)); + try_rwlock_data.tick = TEST_SEC * rte_get_tsc_hz(); +} + +/* all lcores grab RDLOCK */ +static int +try_rwlock_test_rda(void) +{ + try_test_reset(); + + /* start read test on all avaialble lcores */ + rte_eal_mp_remote_launch(try_read_lcore, NULL, CALL_MASTER); + rte_eal_mp_wait_lcore(); + + return process_try_lcore_stats(); +} + +/* all slave lcores grab RDLOCK, master one grabs WRLOCK */ +static int +try_rwlock_test_rds_wrm(void) +{ + try_test_reset(); + + rte_eal_mp_remote_launch(try_read_lcore, NULL, SKIP_MASTER); + try_write_lcore(NULL); + rte_eal_mp_wait_lcore(); + + return process_try_lcore_stats(); +} + +/* master and even slave lcores grab RDLOCK, odd lcores grab WRLOCK */ +static int +try_rwlock_test_rde_wro(void) +{ + uint32_t lc, mlc; + + try_test_reset(); + + mlc = rte_get_master_lcore(); + + RTE_LCORE_FOREACH(lc) { + if (lc != mlc) { + if ((lc & 1) == 0) + rte_eal_remote_launch(try_read_lcore, + NULL, lc); + else + rte_eal_remote_launch(try_write_lcore, + NULL, lc); + } + } + try_read_lcore(NULL); + rte_eal_mp_wait_lcore(); + + return process_try_lcore_stats(); +} + +static int +test_rwlock(void) +{ + uint32_t i; + int32_t rc, ret; + + static const struct { + const char *name; + int (*ftst)(void); + } test[] = { + { + .name = "rwlock_test1", + .ftst = rwlock_test1, + }, + { + .name = "try_rwlock_test_rda", + .ftst = try_rwlock_test_rda, + }, + { + .name = "try_rwlock_test_rds_wrm", + .ftst = try_rwlock_test_rds_wrm, + }, + { + .name = "try_rwlock_test_rde_wro", + .ftst = try_rwlock_test_rde_wro, + }, + }; + + ret = 0; + for (i = 0; i != RTE_DIM(test); i++) { + printf("starting test %s;\n", test[i].name); + rc = test[i].ftst(); + printf("test %s completed with status %d\n", test[i].name, rc); + ret |= rc; + } + + return ret; +} + +REGISTER_TEST_COMMAND(rwlock_autotest, test_rwlock); diff --git a/app/test/test_sched.c b/app/test/test_sched.c new file mode 100644 index 0000000000..40e411cabe --- /dev/null +++ b/app/test/test_sched.c @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#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_sched_port *port, 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(port, 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(port, 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(port, 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_service_cores.c b/app/test/test_service_cores.c new file mode 100644 index 0000000000..ec31882d99 --- /dev/null +++ b/app/test/test_service_cores.c @@ -0,0 +1,919 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "test.h" + +/* used as the service core ID */ +static uint32_t slcore_id; +/* used as timestamp to detect if a service core is running */ +static uint64_t service_tick; +/* used as a flag to check if a function was run */ +static uint32_t service_remote_launch_flag; + +#define SERVICE_DELAY 1 + +#define DUMMY_SERVICE_NAME "dummy_service" +#define MT_SAFE_SERVICE_NAME "mt_safe_service" + +static int +testsuite_setup(void) +{ + slcore_id = rte_get_next_lcore(/* start core */ -1, + /* skip master */ 1, + /* wrap */ 0); + + return TEST_SUCCESS; +} + +static void +testsuite_teardown(void) +{ + /* release service cores? */ +} + +static int32_t dummy_cb(void *args) +{ + RTE_SET_USED(args); + service_tick++; + rte_delay_ms(SERVICE_DELAY); + return 0; +} + +static int32_t dummy_mt_unsafe_cb(void *args) +{ + /* before running test, the initialization has set pass_test to 1. + * If the cmpset in service-cores is working correctly, the code here + * should never fail to take the lock. If the lock *is* taken, fail the + * test, because two threads are concurrently in a non-MT safe callback. + */ + uint32_t *test_params = args; + uint32_t *atomic_lock = &test_params[0]; + uint32_t *pass_test = &test_params[1]; + int lock_taken = rte_atomic32_cmpset(atomic_lock, 0, 1); + if (lock_taken) { + /* delay with the lock held */ + rte_delay_ms(250); + rte_atomic32_clear((rte_atomic32_t *)atomic_lock); + } else { + /* 2nd thread will fail to take lock, so set pass flag */ + *pass_test = 0; + } + + return 0; +} + + +static int32_t dummy_mt_safe_cb(void *args) +{ + /* Atomic checks to ensure MT safe services allow > 1 thread to + * concurrently run the callback. The concept is as follows; + * 1) if lock is available, take the lock then delay + * 2) if first lock is taken, and a thread arrives in the CB, we know + * that 2 threads are running the callback at the same time: MT safe + */ + uint32_t *test_params = args; + uint32_t *atomic_lock = &test_params[0]; + uint32_t *pass_test = &test_params[1]; + int lock_taken = rte_atomic32_cmpset(atomic_lock, 0, 1); + if (lock_taken) { + /* delay with the lock held */ + rte_delay_ms(250); + rte_atomic32_clear((rte_atomic32_t *)atomic_lock); + } else { + /* 2nd thread will fail to take lock, so set pass flag */ + *pass_test = 1; + } + + return 0; +} + +/* unregister all services */ +static int +unregister_all(void) +{ + uint32_t i; + + TEST_ASSERT_EQUAL(-EINVAL, rte_service_component_unregister(1000), + "Unregistered invalid service id"); + + uint32_t c = rte_service_get_count(); + for (i = 0; i < c; i++) { + TEST_ASSERT_EQUAL(0, rte_service_component_unregister(i), + "Error unregistering a valid service"); + } + + rte_service_lcore_reset_all(); + + return TEST_SUCCESS; +} + +/* register a single dummy service */ +static int +dummy_register(void) +{ + /* make sure there are no remains from previous tests */ + unregister_all(); + + struct rte_service_spec service; + memset(&service, 0, sizeof(struct rte_service_spec)); + + TEST_ASSERT_EQUAL(-EINVAL, + rte_service_component_register(&service, NULL), + "Invalid callback"); + service.callback = dummy_cb; + + TEST_ASSERT_EQUAL(-EINVAL, + rte_service_component_register(&service, NULL), + "Invalid name"); + snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); + + uint32_t id; + TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), + "Failed to register valid service"); + + rte_service_component_runstate_set(id, 1); + + return TEST_SUCCESS; +} + +/* verify get_by_name() service lookup */ +static int +service_get_by_name(void) +{ + unregister_all(); + + uint32_t sid; + TEST_ASSERT_EQUAL(-ENODEV, + rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid), + "get by name with invalid name should return -ENODEV"); + TEST_ASSERT_EQUAL(-EINVAL, + rte_service_get_by_name(DUMMY_SERVICE_NAME, 0x0), + "get by name with NULL ptr should return -ENODEV"); + + /* register service */ + struct rte_service_spec service; + memset(&service, 0, sizeof(struct rte_service_spec)); + TEST_ASSERT_EQUAL(-EINVAL, + rte_service_component_register(&service, NULL), + "Invalid callback"); + service.callback = dummy_cb; + TEST_ASSERT_EQUAL(-EINVAL, + rte_service_component_register(&service, NULL), + "Invalid name"); + snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); + TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL), + "Failed to register valid service"); + + /* we unregistered all service, now registering 1, should be id 0 */ + uint32_t service_id_as_expected = 0; + TEST_ASSERT_EQUAL(0, rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid), + "Service get_by_name should return 0 on valid inputs"); + TEST_ASSERT_EQUAL(service_id_as_expected, sid, + "Service get_by_name should equal expected id"); + + unregister_all(); + + /* ensure after unregister, get_by_name returns NULL */ + TEST_ASSERT_EQUAL(-ENODEV, + rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid), + "get by name should return -ENODEV after unregister"); + + return TEST_SUCCESS; +} + +/* verify probe of capabilities */ +static int +service_probe_capability(void) +{ + unregister_all(); + + struct rte_service_spec service; + memset(&service, 0, sizeof(struct rte_service_spec)); + service.callback = dummy_cb; + snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); + service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; + TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL), + "Register of MT SAFE service failed"); + + /* verify flag is enabled */ + const uint32_t sid = 0; + int32_t mt = rte_service_probe_capability(sid, RTE_SERVICE_CAP_MT_SAFE); + TEST_ASSERT_EQUAL(1, mt, "MT SAFE capability flag not set."); + + + unregister_all(); + + memset(&service, 0, sizeof(struct rte_service_spec)); + service.callback = dummy_cb; + snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); + TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL), + "Register of non-MT safe service failed"); + + /* verify flag is enabled */ + mt = rte_service_probe_capability(sid, RTE_SERVICE_CAP_MT_SAFE); + TEST_ASSERT_EQUAL(0, mt, "MT SAFE cap flag set on non MT SAFE service"); + + return unregister_all(); +} + +/* verify the service name */ +static int +service_name(void) +{ + const char *name = rte_service_get_name(0); + int equal = strcmp(name, DUMMY_SERVICE_NAME); + TEST_ASSERT_EQUAL(0, equal, "Error: Service name not correct"); + + return unregister_all(); +} + +/* verify service attr get */ +static int +service_attr_get(void) +{ + /* ensure all services unregistered so cycle counts are zero */ + unregister_all(); + + struct rte_service_spec service; + memset(&service, 0, sizeof(struct rte_service_spec)); + service.callback = dummy_cb; + snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); + service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; + uint32_t id; + TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), + "Register of service failed"); + rte_service_component_runstate_set(id, 1); + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(id, 1), + "Error: Service start returned non-zero"); + rte_service_set_stats_enable(id, 1); + + uint32_t attr_id = UINT32_MAX; + uint32_t attr_value = 0xdead; + /* check error return values */ + TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(id, attr_id, + &attr_value), + "Invalid attr_id didn't return -EINVAL"); + + attr_id = RTE_SERVICE_ATTR_CYCLES; + TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(UINT32_MAX, attr_id, + &attr_value), + "Invalid service id didn't return -EINVAL"); + + TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(id, attr_id, NULL), + "Invalid attr_value pointer id didn't return -EINVAL"); + + /* check correct (zero) return value and correct value (zero) */ + TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value), + "Valid attr_get() call didn't return success"); + TEST_ASSERT_EQUAL(0, attr_value, + "attr_get() call didn't set correct cycles (zero)"); + /* check correct call count */ + const int attr_calls = RTE_SERVICE_ATTR_CALL_COUNT; + TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value), + "Valid attr_get() call didn't return success"); + TEST_ASSERT_EQUAL(0, attr_value, + "attr_get() call didn't get call count (zero)"); + + /* Call service to increment cycle count */ + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), + "Service core add did not return zero"); + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(id, slcore_id, 1), + "Enabling valid service and core failed"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id), + "Starting service core failed"); + + /* wait for the service lcore to run */ + rte_delay_ms(200); + + TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value), + "Valid attr_get() call didn't return success"); + int cycles_gt_zero = attr_value > 0; + TEST_ASSERT_EQUAL(1, cycles_gt_zero, + "attr_get() failed to get cycles (expected > zero)"); + + rte_service_lcore_stop(slcore_id); + + TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value), + "Valid attr_get() call didn't return success"); + TEST_ASSERT_EQUAL(1, (attr_value > 0), + "attr_get() call didn't get call count (zero)"); + + TEST_ASSERT_EQUAL(0, rte_service_attr_reset_all(id), + "Valid attr_reset_all() return success"); + + TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value), + "Valid attr_get() call didn't return success"); + TEST_ASSERT_EQUAL(0, attr_value, + "attr_get() call didn't set correct cycles (zero)"); + /* ensure call count > zero */ + TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value), + "Valid attr_get() call didn't return success"); + TEST_ASSERT_EQUAL(0, (attr_value > 0), + "attr_get() call didn't get call count (zero)"); + + return unregister_all(); +} + +/* verify service lcore attr get */ +static int +service_lcore_attr_get(void) +{ + /* ensure all services unregistered so cycle counts are zero */ + unregister_all(); + + struct rte_service_spec service; + memset(&service, 0, sizeof(struct rte_service_spec)); + service.callback = dummy_cb; + snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); + service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; + uint32_t id; + TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), + "Register of service failed"); + rte_service_component_runstate_set(id, 1); + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(id, 1), + "Error: Service start returned non-zero"); + rte_service_set_stats_enable(id, 1); + + uint64_t lcore_attr_value = 0xdead; + uint32_t lcore_attr_id = UINT32_MAX; + + /* check error return values */ + TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_attr_get(UINT32_MAX, + lcore_attr_id, &lcore_attr_value), + "Invalid lcore_id didn't return -EINVAL"); + TEST_ASSERT_EQUAL(-ENOTSUP, rte_service_lcore_attr_get(rte_lcore_id(), + lcore_attr_id, &lcore_attr_value), + "Non-service core didn't return -ENOTSUP"); + + /* Start service core to increment loop count */ + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), + "Service core add did not return zero"); + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(id, slcore_id, 1), + "Enabling valid service and core failed"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id), + "Starting service core failed"); + + /* wait for the service lcore to run */ + rte_delay_ms(200); + + lcore_attr_id = RTE_SERVICE_LCORE_ATTR_LOOPS; + TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_get(slcore_id, + lcore_attr_id, &lcore_attr_value), + "Valid lcore_attr_get() call didn't return success"); + int loops_gt_zero = lcore_attr_value > 0; + TEST_ASSERT_EQUAL(1, loops_gt_zero, + "lcore_attr_get() failed to get loops " + "(expected > zero)"); + + lcore_attr_id++; // invalid lcore attr id + TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_attr_get(slcore_id, + lcore_attr_id, &lcore_attr_value), + "Invalid lcore attr didn't return -EINVAL"); + + rte_service_lcore_stop(slcore_id); + + TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_reset_all(slcore_id), + "Valid lcore_attr_reset_all() didn't return success"); + + lcore_attr_id = RTE_SERVICE_LCORE_ATTR_LOOPS; + TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_get(slcore_id, + lcore_attr_id, &lcore_attr_value), + "Valid lcore_attr_get() call didn't return success"); + TEST_ASSERT_EQUAL(0, lcore_attr_value, + "lcore_attr_get() didn't get correct loop count " + "(zero)"); + + return unregister_all(); +} + +/* verify service dump */ +static int +service_dump(void) +{ + const uint32_t sid = 0; + rte_service_set_stats_enable(sid, 1); + rte_service_dump(stdout, 0); + rte_service_set_stats_enable(sid, 0); + rte_service_dump(stdout, 0); + return unregister_all(); +} + +/* start and stop a service */ +static int +service_start_stop(void) +{ + const uint32_t sid = 0; + + /* runstate_get() returns if service is running and slcore is mapped */ + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), + "Service core add did not return zero"); + int ret = rte_service_map_lcore_set(sid, slcore_id, 1); + TEST_ASSERT_EQUAL(0, ret, + "Enabling service core, expected 0 got %d", ret); + + TEST_ASSERT_EQUAL(0, rte_service_runstate_get(sid), + "Error: Service should be stopped"); + + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), + "Error: Service stopped returned non-zero"); + + TEST_ASSERT_EQUAL(0, rte_service_runstate_get(sid), + "Error: Service is running - should be stopped"); + + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1), + "Error: Service start returned non-zero"); + + TEST_ASSERT_EQUAL(1, rte_service_runstate_get(sid), + "Error: Service is not running"); + + return unregister_all(); +} + + +static int +service_remote_launch_func(void *arg) +{ + RTE_SET_USED(arg); + service_remote_launch_flag = 1; + return 0; +} + +/* enable and disable a lcore for a service */ +static int +service_lcore_en_dis_able(void) +{ + const uint32_t sid = 0; + + /* expected failure cases */ + TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, 100000, 1), + "Enable on invalid core did not fail"); + TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, 100000, 0), + "Disable on invalid core did not fail"); + + /* add service core to allow enabling */ + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), + "Add service core failed when not in use before"); + + /* valid enable */ + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1), + "Enabling valid service and core failed"); + TEST_ASSERT_EQUAL(1, rte_service_map_lcore_get(sid, slcore_id), + "Enabled core returned not-enabled"); + + /* valid disable */ + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 0), + "Disabling valid service and lcore failed"); + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_get(sid, slcore_id), + "Disabled core returned enabled"); + + /* call remote_launch to verify that app can launch ex-service lcore */ + service_remote_launch_flag = 0; + rte_eal_wait_lcore(slcore_id); + int ret = rte_eal_remote_launch(service_remote_launch_func, NULL, + slcore_id); + TEST_ASSERT_EQUAL(0, ret, "Ex-service core remote launch failed."); + rte_eal_mp_wait_lcore(); + TEST_ASSERT_EQUAL(1, service_remote_launch_flag, + "Ex-service core function call had no effect."); + + return unregister_all(); +} + +static int +service_lcore_running_check(void) +{ + uint64_t tick = service_tick; + rte_delay_ms(SERVICE_DELAY * 100); + /* if (tick != service_tick) we know the lcore as polled the service */ + return tick != service_tick; +} + +static int +service_lcore_add_del(void) +{ + /* check initial count */ + TEST_ASSERT_EQUAL(0, rte_service_lcore_count(), + "Service lcore count has value before adding a lcore"); + + /* check service lcore add */ + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), + "Add service core failed when not in use before"); + TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_add(slcore_id), + "Add service core failed to refuse in-use lcore"); + + /* check count */ + TEST_ASSERT_EQUAL(1, rte_service_lcore_count(), + "Service core count not equal to one"); + + /* retrieve core list, checking lcore ids */ + const uint32_t size = 4; + uint32_t service_core_ids[size]; + int32_t n = rte_service_lcore_list(service_core_ids, size); + TEST_ASSERT_EQUAL(1, n, "Service core list return should equal 1"); + TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0], + "Service core list lcore must equal slcore_id"); + + /* recheck count, add more cores, and check count */ + TEST_ASSERT_EQUAL(1, rte_service_lcore_count(), + "Service core count not equal to one"); + uint32_t slcore_1 = rte_get_next_lcore(/* start core */ -1, + /* skip master */ 1, + /* wrap */ 0); + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_1), + "Service core add did not return zero"); + uint32_t slcore_2 = rte_get_next_lcore(/* start core */ slcore_1, + /* skip master */ 1, + /* wrap */ 0); + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_2), + "Service core add did not return zero"); + + uint32_t count = rte_service_lcore_count(); + const uint32_t cores_at_this_point = 3; + TEST_ASSERT_EQUAL(cores_at_this_point, count, + "Service core count %d, expected %d", count, + cores_at_this_point); + + /* check longer service core list */ + n = rte_service_lcore_list(service_core_ids, size); + TEST_ASSERT_EQUAL(3, n, "Service core list return should equal 3"); + TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0], + "Service core list[0] lcore must equal 1"); + TEST_ASSERT_EQUAL(slcore_1, service_core_ids[1], + "Service core list[1] lcore must equal 2"); + TEST_ASSERT_EQUAL(slcore_2, service_core_ids[2], + "Service core list[2] lcore must equal 3"); + + /* recheck count, remove lcores, check remaining lcore_id is correct */ + TEST_ASSERT_EQUAL(3, rte_service_lcore_count(), + "Service core count not equal to three"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_1), + "Service core add did not return zero"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_2), + "Service core add did not return zero"); + TEST_ASSERT_EQUAL(1, rte_service_lcore_count(), + "Service core count not equal to one"); + n = rte_service_lcore_list(service_core_ids, size); + TEST_ASSERT_EQUAL(1, n, "Service core list return should equal one"); + TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0], + "Service core list[0] lcore must equal %d", + slcore_id); + + return unregister_all(); +} + +static int +service_threaded_test(int mt_safe) +{ + unregister_all(); + + /* add next 2 cores */ + uint32_t slcore_1 = rte_get_next_lcore(/* start core */ -1, + /* skip master */ 1, + /* wrap */ 0); + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_1), + "mt safe lcore add fail"); + uint32_t slcore_2 = rte_get_next_lcore(/* start core */ slcore_1, + /* skip master */ 1, + /* wrap */ 0); + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_2), + "mt safe lcore add fail"); + + /* Use atomic locks to verify that two threads are in the same function + * at the same time. These are passed to the unit tests through the + * callback userdata parameter + */ + uint32_t test_params[2]; + memset(test_params, 0, sizeof(uint32_t) * 2); + + /* register MT safe service. */ + struct rte_service_spec service; + memset(&service, 0, sizeof(struct rte_service_spec)); + service.callback_userdata = test_params; + snprintf(service.name, sizeof(service.name), MT_SAFE_SERVICE_NAME); + + if (mt_safe) { + service.callback = dummy_mt_safe_cb; + service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; + } else + service.callback = dummy_mt_unsafe_cb; + + uint32_t id; + TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), + "Register of MT SAFE service failed"); + + const uint32_t sid = 0; + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1), + "Starting valid service failed"); + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_1, 1), + "Failed to enable lcore 1 on mt safe service"); + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_2, 1), + "Failed to enable lcore 2 on mt safe service"); + rte_service_lcore_start(slcore_1); + rte_service_lcore_start(slcore_2); + + /* wait for the worker threads to run */ + rte_delay_ms(500); + rte_service_lcore_stop(slcore_1); + rte_service_lcore_stop(slcore_2); + + TEST_ASSERT_EQUAL(0, test_params[1], + "Service run with component runstate = 0"); + + /* enable backend runstate: the service should run after this */ + rte_service_component_runstate_set(id, 1); + + /* initialize to pass, see callback comment for details */ + if (!mt_safe) + test_params[1] = 1; + + /* wait for lcores before start() */ + rte_eal_wait_lcore(slcore_1); + rte_eal_wait_lcore(slcore_2); + + rte_service_lcore_start(slcore_1); + rte_service_lcore_start(slcore_2); + + /* wait for the worker threads to run */ + rte_delay_ms(500); + rte_service_lcore_stop(slcore_1); + rte_service_lcore_stop(slcore_2); + + TEST_ASSERT_EQUAL(1, test_params[1], + "MT Safe service not run by two cores concurrently"); + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), + "Failed to stop MT Safe service"); + + rte_eal_wait_lcore(slcore_1); + rte_eal_wait_lcore(slcore_2); + unregister_all(); + + /* return the value of the callback pass_test variable to caller */ + return test_params[1]; +} + +/* tests an MT SAFE service with two cores. The callback function ensures that + * two threads access the callback concurrently. + */ +static int +service_mt_safe_poll(void) +{ + int mt_safe = 1; + TEST_ASSERT_EQUAL(1, service_threaded_test(mt_safe), + "Error: MT Safe service not run by two cores concurrently"); + return TEST_SUCCESS; +} + +/* tests a NON mt safe service with two cores, the callback is serialized + * using the atomic cmpset. + */ +static int +service_mt_unsafe_poll(void) +{ + int mt_safe = 0; + TEST_ASSERT_EQUAL(1, service_threaded_test(mt_safe), + "Error: NON MT Safe service run by two cores concurrently"); + return TEST_SUCCESS; +} + +static int32_t +delay_as_a_mt_safe_service(void *args) +{ + RTE_SET_USED(args); + uint32_t *params = args; + + /* retrieve done flag and atomic lock to inc/dec */ + uint32_t *done = ¶ms[0]; + rte_atomic32_t *lock = (rte_atomic32_t *)¶ms[1]; + + while (!*done) { + rte_atomic32_inc(lock); + rte_delay_us(500); + if (rte_atomic32_read(lock) > 1) + /* pass: second core has simultaneously incremented */ + *done = 1; + rte_atomic32_dec(lock); + } + + return 0; +} + +static int32_t +delay_as_a_service(void *args) +{ + uint32_t *done = (uint32_t *)args; + while (!*done) + rte_delay_ms(5); + return 0; +} + +static int +service_run_on_app_core_func(void *arg) +{ + uint32_t *delay_service_id = (uint32_t *)arg; + return rte_service_run_iter_on_app_lcore(*delay_service_id, 1); +} + +static int +service_app_lcore_poll_impl(const int mt_safe) +{ + uint32_t params[2] = {0}; + + struct rte_service_spec service; + memset(&service, 0, sizeof(struct rte_service_spec)); + snprintf(service.name, sizeof(service.name), MT_SAFE_SERVICE_NAME); + if (mt_safe) { + service.callback = delay_as_a_mt_safe_service; + service.callback_userdata = params; + service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; + } else { + service.callback = delay_as_a_service; + service.callback_userdata = ¶ms; + } + + uint32_t id; + TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), + "Register of app lcore delay service failed"); + + rte_service_component_runstate_set(id, 1); + rte_service_runstate_set(id, 1); + + uint32_t app_core2 = rte_get_next_lcore(slcore_id, 1, 1); + rte_eal_wait_lcore(app_core2); + int app_core2_ret = rte_eal_remote_launch(service_run_on_app_core_func, + &id, app_core2); + + rte_delay_ms(100); + + int app_core1_ret = service_run_on_app_core_func(&id); + + /* flag done, then wait for the spawned 2nd core to return */ + params[0] = 1; + rte_eal_mp_wait_lcore(); + + /* core two gets launched first - and should hold the service lock */ + TEST_ASSERT_EQUAL(0, app_core2_ret, + "App core2 : run service didn't return zero"); + + if (mt_safe) { + /* mt safe should have both cores return 0 for success */ + TEST_ASSERT_EQUAL(0, app_core1_ret, + "MT Safe: App core1 didn't return 0"); + } else { + /* core one attempts to run later - should be blocked */ + TEST_ASSERT_EQUAL(-EBUSY, app_core1_ret, + "MT Unsafe: App core1 didn't return -EBUSY"); + } + + unregister_all(); + + return TEST_SUCCESS; +} + +static int +service_app_lcore_mt_safe(void) +{ + const int mt_safe = 1; + return service_app_lcore_poll_impl(mt_safe); +} + +static int +service_app_lcore_mt_unsafe(void) +{ + const int mt_safe = 0; + return service_app_lcore_poll_impl(mt_safe); +} + +/* start and stop a service core - ensuring it goes back to sleep */ +static int +service_lcore_start_stop(void) +{ + /* start service core and service, create mapping so tick() runs */ + const uint32_t sid = 0; + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1), + "Starting valid service failed"); + TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, slcore_id, 1), + "Enabling valid service on non-service core must fail"); + + /* core start */ + TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_start(slcore_id), + "Service core start without add should return EINVAL"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), + "Service core add did not return zero"); + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1), + "Enabling valid service on valid core failed"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id), + "Service core start after add failed"); + TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_start(slcore_id), + "Service core expected as running but was stopped"); + + /* ensures core really is running the service function */ + TEST_ASSERT_EQUAL(1, service_lcore_running_check(), + "Service core expected to poll service but it didn't"); + + /* core stop */ + TEST_ASSERT_EQUAL(-EBUSY, rte_service_lcore_stop(slcore_id), + "Service core running a service should return -EBUSY"); + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), + "Stopping valid service failed"); + TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_stop(100000), + "Invalid Service core stop should return -EINVAL"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_stop(slcore_id), + "Service core stop expected to return 0"); + TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_stop(slcore_id), + "Already stopped service core should return -EALREADY"); + + /* ensure service is not longer running */ + TEST_ASSERT_EQUAL(0, service_lcore_running_check(), + "Service core expected to poll service but it didn't"); + + TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_id), + "Service core del did not return zero"); + + return unregister_all(); +} + +/* stop a service and wait for it to become inactive */ +static int +service_may_be_active(void) +{ + const uint32_t sid = 0; + int i; + + /* expected failure cases */ + TEST_ASSERT_EQUAL(-EINVAL, rte_service_may_be_active(10000), + "Invalid service may be active check did not fail"); + + /* start the service */ + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1), + "Starting valid service failed"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), + "Add service core failed when not in use before"); + TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1), + "Enabling valid service on valid core failed"); + TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id), + "Service core start after add failed"); + + /* ensures core really is running the service function */ + TEST_ASSERT_EQUAL(1, service_lcore_running_check(), + "Service core expected to poll service but it didn't"); + + /* stop the service */ + TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), + "Error: Service stop returned non-zero"); + + /* give the service 100ms to stop running */ + for (i = 0; i < 100; i++) { + if (!rte_service_may_be_active(sid)) + break; + rte_delay_ms(SERVICE_DELAY); + } + + TEST_ASSERT_EQUAL(0, rte_service_may_be_active(sid), + "Error: Service not stopped after 100ms"); + + return unregister_all(); +} + +static struct unit_test_suite service_tests = { + .suite_name = "service core test suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(dummy_register, NULL, unregister_all), + TEST_CASE_ST(dummy_register, NULL, service_name), + TEST_CASE_ST(dummy_register, NULL, service_get_by_name), + TEST_CASE_ST(dummy_register, NULL, service_dump), + TEST_CASE_ST(dummy_register, NULL, service_attr_get), + TEST_CASE_ST(dummy_register, NULL, service_lcore_attr_get), + TEST_CASE_ST(dummy_register, NULL, service_probe_capability), + TEST_CASE_ST(dummy_register, NULL, service_start_stop), + TEST_CASE_ST(dummy_register, NULL, service_lcore_add_del), + TEST_CASE_ST(dummy_register, NULL, service_lcore_start_stop), + TEST_CASE_ST(dummy_register, NULL, service_lcore_en_dis_able), + TEST_CASE_ST(dummy_register, NULL, service_mt_unsafe_poll), + TEST_CASE_ST(dummy_register, NULL, service_mt_safe_poll), + TEST_CASE_ST(dummy_register, NULL, service_app_lcore_mt_safe), + TEST_CASE_ST(dummy_register, NULL, service_app_lcore_mt_unsafe), + TEST_CASE_ST(dummy_register, NULL, service_may_be_active), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_service_common(void) +{ + return unit_test_suite_runner(&service_tests); +} + +REGISTER_TEST_COMMAND(service_autotest, test_service_common); diff --git a/app/test/test_spinlock.c b/app/test/test_spinlock.c new file mode 100644 index 0000000000..73bff128e6 --- /dev/null +++ b/app/test/test_spinlock.c @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 successfully, 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_rte_strlcat(void) +{ + /* only run actual unit tests if we have system-provided strlcat */ +#if defined(__BSD_VISIBLE) || defined(RTE_USE_LIBBSD) +#define BUF_LEN 32 + const char dst[BUF_LEN] = "Test string"; + const char src[] = " appended"; + char bsd_dst[BUF_LEN]; + char rte_dst[BUF_LEN]; + size_t i, bsd_ret, rte_ret; + + LOG("dst = '%s', strlen(dst) = %zu\n", dst, strlen(dst)); + LOG("src = '%s', strlen(src) = %zu\n", src, strlen(src)); + LOG("---\n"); + + for (i = 0; i < BUF_LEN; i++) { + /* initialize destination buffers */ + memcpy(bsd_dst, dst, BUF_LEN); + memcpy(rte_dst, dst, BUF_LEN); + /* compare implementations */ + bsd_ret = strlcat(bsd_dst, src, i); + rte_ret = rte_strlcat(rte_dst, src, i); + if (bsd_ret != rte_ret) { + LOG("Incorrect retval for buf length = %zu\n", i); + LOG("BSD: '%zu', rte: '%zu'\n", bsd_ret, rte_ret); + return -1; + } + if (memcmp(bsd_dst, rte_dst, BUF_LEN) != 0) { + LOG("Resulting buffers don't match\n"); + LOG("BSD: '%s', rte: '%s'\n", bsd_dst, rte_dst); + return -1; + } + LOG("buffer size = %zu: dst = '%s', ret = %zu\n", + i, rte_dst, rte_ret); + } + LOG("Checked %zu combinations\n", i); +#undef BUF_LEN +#endif /* defined(__BSD_VISIBLE) || defined(RTE_USE_LIBBSD) */ + + return 0; +} + +static int +test_string_fns(void) +{ + if (test_rte_strsplit() < 0) + return -1; + if (test_rte_strlcat() < 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 new file mode 100644 index 0000000000..a4b0ed65f9 --- /dev/null +++ b/app/test/test_table.c @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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)) void *key_mask, + __attribute__((unused)) uint32_t key_size, + __attribute__((unused)) uint64_t seed) +{ + uint32_t *k32 = key; + uint32_t ip_dst = rte_be_to_cpu_32(k32[0]); + uint64_t signature = ip_dst; + + return signature; +} + +uint32_t pipeline_test_hash_cuckoo(const void *key, + __attribute__((unused)) uint32_t key_size, + __attribute__((unused)) uint32_t seed) +{ + const uint32_t *k32 = key; + uint32_t ip_dst = rte_be_to_cpu_32(k32[0]); + uint32_t signature = ip_dst; + + return signature; +} + +static void +app_free_resources(void) { + int i; + for (i = 0; i < N_PORTS; i++) + rte_ring_free(rings_rx[i]); + rte_mempool_free(pool); +} + +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, ret; + unsigned i; + + ret = TEST_SUCCESS; + + app_init_rings(); + app_init_mbuf_pools(); + + printf("\n\n\n\n************Pipeline tests************\n"); + + if (test_table_pipeline() < 0) { + ret = TEST_FAILED; + goto end; + } + + 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); + ret = TEST_FAILED; + goto end; + } + } + + 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); + ret = TEST_FAILED; + goto end; + } + } + + 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); + ret = TEST_FAILED; + goto end; + } + } + +#ifdef RTE_LIBRTE_ACL + printf("\n\n\n\n************ACL tests************\n"); + if (test_table_acl() < 0) { + ret = TEST_FAILED; + goto end; + } +#endif + +end: + app_free_resources(); + + return ret; +} + +REGISTER_TEST_COMMAND(table_autotest, test_table); diff --git a/app/test/test_table.h b/app/test/test_table.h new file mode 100644 index 0000000000..a66342cb65 --- /dev/null +++ b/app/test/test_table.h @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#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, NULL, 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)) void *key_mask, + __attribute__((unused)) uint32_t key_size, + __attribute__((unused)) uint64_t seed); + +uint32_t pipeline_test_hash_cuckoo( + const void *key, + __attribute__((unused)) uint32_t key_size, + __attribute__((unused)) uint32_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 new file mode 100644 index 0000000000..33e2f6ee64 --- /dev/null +++ b/app/test/test_table_acl.c @@ -0,0 +1,733 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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]; + + memset(table_entries, 0, sizeof(table_entries)); + + 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, NULL); + 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 = 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 new file mode 100644 index 0000000000..a6ae7d2838 --- /dev/null +++ b/app/test/test_table_acl.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +/* Test prototypes */ +int test_table_acl(void); diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c new file mode 100644 index 0000000000..73ad0155d6 --- /dev/null +++ b/app/test/test_table_combined.c @@ -0,0 +1,843 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2016 Intel Corporation + */ + +#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_params key8lru_params = { + .name = "TABLE", + .key_size = 8, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 16, + .n_buckets = 1 << 16, + .f_hash = pipeline_test_hash, + .seed = 0, + }; + + 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_keys = 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_keys = 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_params key16lru_params = { + .name = "TABLE", + .key_size = 16, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 16, + .n_buckets = 1 << 16, + .f_hash = pipeline_test_hash, + .seed = 0, + }; + + 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_keys = 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_keys = 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_params key32lru_params = { + .name = "TABLE", + .key_size = 32, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 16, + .n_buckets = 1 << 16, + .f_hash = pipeline_test_hash, + .seed = 0, + }; + + 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_keys = 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_keys = 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_params key8ext_params = { + .name = "TABLE", + .key_size = 8, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 16, + .n_buckets = 1 << 16, + .f_hash = pipeline_test_hash, + .seed = 0, + }; + + 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_keys = 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_keys = 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); + + return 0; +} + +int +test_table_hash16ext(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_params key16ext_params = { + .name = "TABLE", + .key_size = 16, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 16, + .n_buckets = 1 << 16, + .f_hash = pipeline_test_hash, + .seed = 0, + }; + + 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_keys = 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_keys = 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); + + return 0; +} + +int +test_table_hash32ext(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_params key32ext_params = { + .name = "TABLE", + .key_size = 32, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 16, + .n_buckets = 1 << 16, + .f_hash = pipeline_test_hash, + .seed = 0, + }; + + 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_keys = 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_keys = 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); + + return 0; +} + +int +test_table_hash_cuckoo_combined(void) +{ + int status, i; + + /* Traffic flow */ + struct rte_table_hash_cuckoo_params cuckoo_params = { + .name = "TABLE", + .key_size = 32, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 16, + .n_buckets = 1 << 16, + .f_hash = pipeline_test_hash_cuckoo, + .seed = 0, + }; + + 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_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_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_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_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 new file mode 100644 index 0000000000..d05866240f --- /dev/null +++ b/app/test/test_table_combined.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2016 Intel Corporation + */ + +/* 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 new file mode 100644 index 0000000000..441338ac01 --- /dev/null +++ b/app/test/test_table_pipeline.c @@ -0,0 +1,569 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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); + +static int +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; +} + +static int +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, NULL); + 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 = 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 = 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 = 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 new file mode 100644 index 0000000000..d66d09d6f1 --- /dev/null +++ b/app/test/test_table_pipeline.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +/* Test prototypes */ +int test_table_pipeline(void); diff --git a/app/test/test_table_ports.c b/app/test/test_table_ports.c new file mode 100644 index 0000000000..d921b2e207 --- /dev/null +++ b/app/test/test_table_ports.c @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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, NULL); + 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, NULL); + 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, NULL); + + 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, NULL); + + 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, NULL); + + 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, NULL); + + 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 new file mode 100644 index 0000000000..dfa6119319 --- /dev/null +++ b/app/test/test_table_ports.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +/* 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 new file mode 100644 index 0000000000..20df2e9225 --- /dev/null +++ b/app/test/test_table_tables.c @@ -0,0 +1,1054 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2016 Intel Corporation + */ + +#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, NULL, 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, uint32_t key_size); +static int +test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size); + +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, uint32_t key_size) +{ + 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_params hash_params = { + .name = "TABLE", + .key_size = key_size, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 10, + .n_buckets = 1 << 10, + .f_hash = pipeline_test_hash, + .seed = 0, + }; + + hash_params.n_keys = 0; + + table = ops->f_create(&hash_params, 0, 1); + if (table != NULL) + return -1; + + hash_params.n_keys = 1 << 10; + 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, uint32_t key_size) +{ + 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_params hash_params = { + .name = "TABLE", + .key_size = key_size, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 10, + .n_buckets = 1 << 10, + .f_hash = pipeline_test_hash, + .seed = 0, + }; + + hash_params.n_keys = 0; + + table = ops->f_create(&hash_params, 0, 1); + if (table != NULL) + return -1; + + hash_params.n_keys = 1 << 10; + 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, + 8); + if (status < 0) + return status; + + status = test_table_hash_lru_generic( + &rte_table_hash_key16_lru_ops, + 16); + if (status < 0) + return status; + + status = test_table_hash_lru_generic( + &rte_table_hash_key32_lru_ops, + 32); + 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, 8); + if (status < 0) + return status; + + status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops, 16); + if (status < 0) + return status; + + status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops, 32); + 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 = { + .name = "TABLE", + .key_size = 32, + .key_offset = APP_METADATA_OFFSET(32), + .key_mask = NULL, + .n_keys = 1 << 16, + .n_buckets = 1 << 16, + .f_hash = pipeline_test_hash_cuckoo, + .seed = 0, + }; + + table = rte_table_hash_cuckoo_ops.f_create(NULL, 0, entry_size); + if (table != NULL) + return -1; + + cuckoo_params.key_size = 0; + + table = rte_table_hash_cuckoo_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_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_ops.f_create(&cuckoo_params, + 0, entry_size); + if (table != NULL) + return -4; + + cuckoo_params.f_hash = pipeline_test_hash_cuckoo; + cuckoo_params.name = NULL; + + table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, + 0, entry_size); + if (table != NULL) + return -5; + + cuckoo_params.name = "CUCKOO"; + + table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, + 0, entry_size); + if (table == NULL) + return -6; + + /* Free */ + status = rte_table_hash_cuckoo_ops.f_free(table); + if (status < 0) + return -7; + + status = rte_table_hash_cuckoo_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_ops.f_create(&cuckoo_params, 0, 1); + if (table == NULL) + return -9; + + entry = 'A'; + status = rte_table_hash_cuckoo_ops.f_add(NULL, &key_cuckoo, + &entry, &key_found, &entry_ptr); + if (status == 0) + return -10; + + status = rte_table_hash_cuckoo_ops.f_add(table, NULL, &entry, + &key_found, &entry_ptr); + if (status == 0) + return -11; + + status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, + NULL, &key_found, &entry_ptr); + if (status == 0) + return -12; + + status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, + &entry, &key_found, &entry_ptr); + if (status != 0) + return -13; + + status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, + &entry, &key_found, &entry_ptr); + if (status != 0) + return -14; + + /* Delete */ + status = rte_table_hash_cuckoo_ops.f_delete(NULL, &key_cuckoo, + &key_found, NULL); + if (status == 0) + return -15; + + status = rte_table_hash_cuckoo_ops.f_delete(table, NULL, + &key_found, NULL); + if (status == 0) + return -16; + + status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo, + &key_found, NULL); + if (status != 0) + return -17; + + status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo, + &key_found, NULL); + if (status != -ENOENT) + return -18; + + /* Traffic flow */ + entry = 'A'; + status = rte_table_hash_cuckoo_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_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_ops.f_free(table); + + return 0; +} + diff --git a/app/test/test_table_tables.h b/app/test/test_table_tables.h new file mode 100644 index 0000000000..7570e99639 --- /dev/null +++ b/app/test/test_table_tables.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2016 Intel Corporation + */ + +/* 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 new file mode 100644 index 0000000000..a4ecea2d8d --- /dev/null +++ b/app/test/test_tailq.c @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..61754a9475 --- /dev/null +++ b/app/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/app/test/test_timer.c b/app/test/test_timer.c new file mode 100644 index 0000000000..e2aab53085 --- /dev/null +++ b/app/test/test_timer.c @@ -0,0 +1,600 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 +#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); + + rte_free(tms); + 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 new file mode 100644 index 0000000000..d29048eaf1 --- /dev/null +++ b/app/test/test_timer_racecond.c @@ -0,0 +1,206 @@ +/*- + * 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 +#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 4 /* 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 new file mode 100644 index 0000000000..1e1ff18656 --- /dev/null +++ b/app/test/test_version.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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 new file mode 100644 index 0000000000..8bcf0b2617 --- /dev/null +++ b/app/test/test_xmmt_ops.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015 Cavium, Inc + */ + +#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 __rte_always_inline xmm_t +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 __rte_always_inline xmm_t +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 new file mode 100644 index 0000000000..f8ddc2db82 --- /dev/null +++ b/app/test/virtual_pmd.c @@ -0,0 +1,604 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#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 int +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)); + + return 0; +} + +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 int +virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev, + __rte_unused struct ether_addr *addr) +{ + return 0; +} + +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, + .mac_addr_set = virtual_ethdev_mac_address_set, + .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(uint16_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(uint16_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(uint16_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(uint16_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(uint16_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, NULL); + + /* 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 = 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, NULL); + + /* 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 = 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(uint16_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(uint16_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(uint16_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(uint16_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(uint16_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(uint16_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, NULL); +} + +int +virtual_ethdev_get_mbufs_from_tx_queue(uint16_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, NULL); +} + + +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 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 + */ + + pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, socket_id); + if (pci_dev == 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_dev->device.name = eth_dev->data->name; + 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_dev->device = &pci_dev->device; + eth_dev->device->driver = &pci_drv->driver; + + 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 = &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; + + rte_eth_dev_probing_finish(eth_dev); + + return eth_dev->data->port_id; + +err: + rte_free(pci_dev); + rte_free(pci_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 new file mode 100644 index 0000000000..5ca02bb503 --- /dev/null +++ b/app/test/virtual_pmd.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#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(uint16_t port_id, uint8_t link_status); + +void +virtual_ethdev_simulate_link_status_interrupt(uint16_t port_id, + uint8_t link_status); + +int +virtual_ethdev_add_mbufs_to_rx_queue(uint16_t port_id, + struct rte_mbuf **pkts_burst, int burst_length); + +int +virtual_ethdev_get_mbufs_from_tx_queue(uint16_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(uint16_t port_id, uint8_t success); + +void +virtual_ethdev_stop_fn_set_success(uint16_t port_id, uint8_t success); + +void +virtual_ethdev_configure_fn_set_success(uint16_t port_id, uint8_t success); + +void +virtual_ethdev_rx_queue_setup_fn_set_success(uint16_t port_id, + uint8_t success); + +void +virtual_ethdev_tx_queue_setup_fn_set_success(uint16_t port_id, + uint8_t success); + +void +virtual_ethdev_link_update_fn_set_success(uint16_t port_id, uint8_t success); + +void +virtual_ethdev_rx_burst_fn_set_success(uint16_t port_id, uint8_t success); + +void +virtual_ethdev_tx_burst_fn_set_success(uint16_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(uint16_t port_id, + uint8_t packet_fail_count); + +#ifdef __cplusplus +} +#endif + +#endif /* __VIRTUAL_ETHDEV_H_ */ diff --git a/devtools/test-build.sh b/devtools/test-build.sh index d37b121ca8..19ff759ed0 100755 --- a/devtools/test-build.sh +++ b/devtools/test-build.sh @@ -229,9 +229,6 @@ for conf in $configs ; do make -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \ EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose O=$dir ! $short || break - echo "================== Build tests for $dir" - make test-build -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \ - EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose O=$dir echo "================== Build examples for $dir" export RTE_SDK=$(pwd) export RTE_TARGET=$dir diff --git a/doc/guides/compressdevs/octeontx.rst b/doc/guides/compressdevs/octeontx.rst index 05dbd681b6..c57d03a8e8 100644 --- a/doc/guides/compressdevs/octeontx.rst +++ b/doc/guides/compressdevs/octeontx.rst @@ -99,7 +99,7 @@ probed. To use the PMD in an application, user must: cd to the top-level DPDK directory export RTE_TARGET=arm64-thunderx-linuxapp-gcc export RTE_SDK=`pwd` - cd to test/test + cd to app/test type the command "make" to compile run the tests with "./test" type the command "compressdev_autotest" to test diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst index b079aa381c..9207bfa554 100644 --- a/doc/guides/cryptodevs/qat.rst +++ b/doc/guides/cryptodevs/qat.rst @@ -530,7 +530,7 @@ Testing QAT crypto PMD can be tested by running the test application:: make defconfig - make test-build -j + make -j cd ./build/app ./test -l1 -n1 -w RTE>>cryptodev_qat_autotest @@ -539,7 +539,7 @@ QAT compression PMD can be tested by running the test application:: make defconfig sed -i 's,\(CONFIG_RTE_COMPRESSDEV_TEST\)=n,\1=y,' build/.config - make test-build -j + make -j cd ./build/app ./test -l1 -n1 -w RTE>>compressdev_autotest diff --git a/doc/guides/cryptodevs/virtio.rst b/doc/guides/cryptodevs/virtio.rst index f3aa7c6545..cfc6d57d77 100644 --- a/doc/guides/cryptodevs/virtio.rst +++ b/doc/guides/cryptodevs/virtio.rst @@ -93,7 +93,7 @@ The unit test cases can be tested as below: cd to the top-level DPDK directory export RTE_TARGET=x86_64-native-linuxapp-gcc export RTE_SDK=`pwd` - cd to test/test + cd to app/test type the command "make" to compile run the tests with "./test" type the command "cryptodev_virtio_autotest" to test diff --git a/doc/guides/mempool/octeontx.rst b/doc/guides/mempool/octeontx.rst index e05aeb94c7..3ade61fc2c 100644 --- a/doc/guides/mempool/octeontx.rst +++ b/doc/guides/mempool/octeontx.rst @@ -56,7 +56,7 @@ following ``make`` command: .. code-block:: console cd - make config T=arm64-thunderx-linuxapp-gcc test-build + make config T=arm64-thunderx-linuxapp-gcc Initialization diff --git a/doc/guides/prog_guide/compressdev.rst b/doc/guides/prog_guide/compressdev.rst index 87e2649067..ad97037533 100644 --- a/doc/guides/prog_guide/compressdev.rst +++ b/doc/guides/prog_guide/compressdev.rst @@ -615,7 +615,7 @@ Sample code ----------- There are unit test applications that show how to use the compressdev library inside -test/test/test_compressdev.c +app/test/test_compressdev.c Compression Device API ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/meson.build b/meson.build index a6a034eb39..2bbd42bc86 100644 --- a/meson.build +++ b/meson.build @@ -43,7 +43,6 @@ subdir('drivers') # build binaries and installable tools subdir('usertools') subdir('app') -subdir('test') # build docs subdir('doc') diff --git a/mk/rte.sdkbuild.mk b/mk/rte.sdkbuild.mk index 5dc43e429f..b512de1ecd 100644 --- a/mk/rte.sdkbuild.mk +++ b/mk/rte.sdkbuild.mk @@ -40,9 +40,6 @@ clean: $(CLEANDIRS) $(Q)$(MAKE) -f $(RTE_SDK)/GNUmakefile gcovclean @echo Clean complete -.PHONY: test-build -test-build: test - .SECONDEXPANSION: .PHONY: $(ROOTDIRS-y) $(ROOTDIRS-) $(ROOTDIRS-y) $(ROOTDIRS-): diff --git a/mk/rte.sdkroot.mk b/mk/rte.sdkroot.mk index 18c88017ed..d91583a631 100644 --- a/mk/rte.sdkroot.mk +++ b/mk/rte.sdkroot.mk @@ -57,8 +57,8 @@ export BUILDDIR export ROOTDIRS-y ROOTDIRS- ROOTDIRS-n -.PHONY: default -default: all +.PHONY: default test-build +default test-build: all .PHONY: config defconfig showconfigs showversion showversionum config defconfig showconfigs showversion showversionum: @@ -72,8 +72,6 @@ cscope gtags tags etags: test test-fast test-perf coverage test-drivers test-dump: $(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdktest.mk $@ -test: test-build - .PHONY: install install: $(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdkinstall.mk pre_install diff --git a/mk/rte.sdktest.mk b/mk/rte.sdktest.mk index 2955928098..803018ba3a 100644 --- a/mk/rte.sdktest.mk +++ b/mk/rte.sdktest.mk @@ -49,12 +49,12 @@ test test-fast test-perf test-drivers test-dump: @mkdir -p $(AUTOTEST_DIR) ; \ cd $(AUTOTEST_DIR) ; \ if [ -f $(RTE_OUTPUT)/app/test ]; then \ - python $(RTE_SDK)/test/test/autotest.py \ + python $(RTE_SDK)/app/test/autotest.py \ $(RTE_OUTPUT)/app/test \ $(RTE_TARGET) \ $(BLACKLIST) $(WHITELIST); \ else \ - echo "No test found, please do a 'make test-build' first, or specify O=" ; \ + echo "No test found, please do a 'make' first, or specify O=" ; \ fi # this is a special target to ease the pain of running coverage tests @@ -66,11 +66,11 @@ coverage: python $(RTE_SDK)/test/cmdline_test/cmdline_test.py \ $(RTE_OUTPUT)/app/cmdline_test; \ ulimit -S -n 100 ; \ - python $(RTE_SDK)/test/test/autotest.py \ + python $(RTE_SDK)/app/test/autotest.py \ $(RTE_OUTPUT)/app/test \ $(RTE_TARGET) \ $(BLACKLIST) $(WHITELIST) ; \ $(RTE_OUTPUT)/app/dpdk-procinfo --file-prefix=ring_perf -- -m; \ else \ - echo "No test found, please do a 'make test-build' first, or specify O=" ;\ + echo "No test found, please do a 'make' first, or specify O=" ;\ fi diff --git a/test/Makefile b/test/Makefile deleted file mode 100644 index e9ae64b593..0000000000 --- a/test/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2017 Intel Corporation - -include $(RTE_SDK)/mk/rte.vars.mk - -DIRS-$(CONFIG_RTE_APP_TEST) += test - -include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/test/meson.build b/test/meson.build deleted file mode 100644 index 3ad11b34f1..0000000000 --- a/test/meson.build +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2017 Intel Corporation - -subdir('test') diff --git a/test/test/Makefile b/test/test/Makefile deleted file mode 100644 index 89949c2bb9..0000000000 --- a/test/test/Makefile +++ /dev/null @@ -1,286 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2017 Intel Corporation - -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) - -# how many workers to run tests with. FreeBSD doesn't support multiple primary -# processes, so make it 1, otherwise make it 4. ignored for non-parallel tests -n_processes = 1 if "bsdapp" in target else 4 - -runner = autotest_runner.AutotestRunner(cmdline, target, test_blacklist, - test_whitelist, n_processes) - -runner.parallel_tests = autotest_data.parallel_test_list[:] -runner.non_parallel_tests = autotest_data.non_parallel_test_list[:] - -num_fails = runner.run_all_tests() - -sys.exit(num_fails) diff --git a/test/test/autotest_data.py b/test/test/autotest_data.py deleted file mode 100644 index 5f87bb94dd..0000000000 --- a/test/test/autotest_data.py +++ /dev/null @@ -1,706 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2014 Intel Corporation - -# Test data for autotests - -from autotest_test_funcs import * - -# groups of tests that can be run in parallel -# the grouping has been found largely empirically -parallel_test_list = [ - { - "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, - }, - { - "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, - }, - { - "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, - }, - { - "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, - }, - { - "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, - }, - { - "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, - }, - { - "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, - }, - { - "Name": "Eventdev selftest octeontx", - "Command": "eventdev_selftest_octeontx", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Event ring autotest", - "Command": "event_ring_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Table autotest", - "Command": "table_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Flow classify autotest", - "Command": "flow_classify_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Event eth rx adapter autotest", - "Command": "event_eth_rx_adapter_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "User delay", - "Command": "user_delay_us", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Sleep delay", - "Command": "delay_us_sleep_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Rawdev autotest", - "Command": "rawdev_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Kvargs autotest", - "Command": "kvargs_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Devargs autotest", - "Command": "devargs_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Link bonding autotest", - "Command": "link_bonding_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Link bonding mode4 autotest", - "Command": "link_bonding_mode4_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Link bonding rssconf autotest", - "Command": "link_bonding_rssconf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Crc autotest", - "Command": "crc_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Distributor autotest", - "Command": "distributor_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Reorder autotest", - "Command": "reorder_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Barrier autotest", - "Command": "barrier_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Bitmap test", - "Command": "bitmap_test", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Hash multiwriter autotest", - "Command": "hash_multiwriter_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Service autotest", - "Command": "service_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Timer racecond autotest", - "Command": "timer_racecond_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Member autotest", - "Command": "member_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Efd_autotest", - "Command": "efd_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Thash autotest", - "Command": "thash_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Hash function autotest", - "Command": "hash_functions_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev sw mrvl autotest", - "Command": "cryptodev_sw_mrvl_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev dpaa2 sec autotest", - "Command": "cryptodev_dpaa2_sec_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev dpaa sec autotest", - "Command": "cryptodev_dpaa_sec_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev qat autotest", - "Command": "cryptodev_qat_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev aesni mb autotest", - "Command": "cryptodev_aesni_mb_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev openssl autotest", - "Command": "cryptodev_openssl_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev scheduler autotest", - "Command": "cryptodev_scheduler_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev aesni gcm autotest", - "Command": "cryptodev_aesni_gcm_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev null autotest", - "Command": "cryptodev_null_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev sw snow3g autotest", - "Command": "cryptodev_sw_snow3g_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev sw kasumi autotest", - "Command": "cryptodev_sw_kasumi_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Cryptodev_sw_zuc_autotest", - "Command": "cryptodev_sw_zuc_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Reciprocal division", - "Command": "reciprocal_division", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Red all", - "Command": "red_all", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Fbarray autotest", - "Command": "fbarray_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "External memory autotest", - "Command": "external_mem_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Metrics autotest", - "Command": "metrics_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Bitratestats autotest", - "Command": "bitratestats_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Latencystats autotest", - "Command": "latencystats_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Pdump autotest", - "Command": "pdump_autotest", - "Func": default_autotest, - "Report": None, - }, - # - #Please always keep all dump tests at the end and together! - # - { - "Name": "Dump physmem", - "Command": "dump_physmem", - "Func": dump_autotest, - "Report": None, - }, - { - "Name": "Dump memzone", - "Command": "dump_memzone", - "Func": dump_autotest, - "Report": None, - }, - { - "Name": "Dump struct sizes", - "Command": "dump_struct_sizes", - "Func": dump_autotest, - "Report": None, - }, - { - "Name": "Dump mempool", - "Command": "dump_mempool", - "Func": dump_autotest, - "Report": None, - }, - { - "Name": "Dump malloc stats", - "Command": "dump_malloc_stats", - "Func": dump_autotest, - "Report": None, - }, - { - "Name": "Dump devargs", - "Command": "dump_devargs", - "Func": dump_autotest, - "Report": None, - }, - { - "Name": "Dump log types", - "Command": "dump_log_types", - "Func": dump_autotest, - "Report": None, - }, - { - "Name": "Dump_ring", - "Command": "dump_ring", - "Func": dump_autotest, - "Report": None, - }, -] - -# tests that should not be run when any other tests are running -non_parallel_test_list = [ - { - "Name": "Eventdev common autotest", - "Command": "eventdev_common_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Eventdev selftest sw", - "Command": "eventdev_selftest_sw", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "KNI autotest", - "Command": "kni_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Mempool performance autotest", - "Command": "mempool_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Memcpy performance autotest", - "Command": "memcpy_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Hash performance autotest", - "Command": "hash_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Hash read-write concurrency autotest", - "Command": "hash_readwrite_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Hash read-write lock-free concurrency autotest", - "Command": "hash_readwrite_lf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Power autotest", - "Command": "power_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Power ACPI cpufreq autotest", - "Command": "power_acpi_cpufreq_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Power KVM VM autotest", - "Command": "power_kvm_vm_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Timer performance autotest", - "Command": "timer_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - - "Name": "Pmd perf autotest", - "Command": "pmd_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Ring pmd perf autotest", - "Command": "ring_pmd_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Distributor perf autotest", - "Command": "distributor_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Red_perf", - "Command": "red_perf", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Lpm6 perf autotest", - "Command": "lpm6_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Lpm perf autotest", - "Command": "lpm_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Efd perf autotest", - "Command": "efd_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Member perf autotest", - "Command": "member_perf_autotest", - "Func": default_autotest, - "Report": None, - }, - { - "Name": "Reciprocal division perf", - "Command": "reciprocal_division_perf", - "Func": default_autotest, - "Report": None, - }, - # - # Please always make sure that ring_perf is the last test! - # - { - "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 deleted file mode 100644 index 36941a40a1..0000000000 --- a/test/test/autotest_runner.py +++ /dev/null @@ -1,433 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2014 Intel Corporation - -# The main logic behind running autotests in parallel - -from __future__ import print_function -import StringIO -import csv -from multiprocessing import Pool, Queue -import pexpect -import re -import subprocess -import sys -import time -import glob -import os - -# 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 - - -# get all valid NUMA nodes -def get_numa_nodes(): - return [ - int( - re.match(r"node(\d+)", os.path.basename(node)) - .group(1) - ) - for node in glob.glob("/sys/devices/system/node/node*") - ] - - -# find first (or any, really) CPU on a particular node, will be used to spread -# processes around NUMA nodes to avoid exhausting memory on particular node -def first_cpu_on_node(node_nr): - cpu_path = glob.glob("/sys/devices/system/node/node%d/cpu*" % node_nr)[0] - cpu_name = os.path.basename(cpu_path) - m = re.match(r"cpu(\d+)", cpu_name) - return int(m.group(1)) - - -pool_child = None # per-process child - - -# we initialize each worker with a queue because we need per-pool unique -# command-line arguments, but we cannot do different arguments in an initializer -# because the API doesn't allow per-worker initializer arguments. so, instead, -# we will initialize with a shared queue, and dequeue command-line arguments -# from this queue -def pool_init(queue, result_queue): - global pool_child - - cmdline, prefix = queue.get() - start_time = time.time() - name = ("Start %s" % prefix) if prefix != "" else "Start" - - # use default prefix if no prefix was specified - prefix_cmdline = "--file-prefix=%s" % prefix if prefix != "" else "" - - # append prefix to cmdline - cmdline = "%s %s" % (cmdline, prefix_cmdline) - - # prepare logging of init - startuplog = StringIO.StringIO() - - # run test app - try: - - print("\n%s %s\n" % ("=" * 20, prefix), file=startuplog) - print("\ncmdline=%s" % cmdline, file=startuplog) - - pool_child = pexpect.spawn(cmdline, logfile=startuplog) - - # wait for target to boot - if not wait_prompt(pool_child): - pool_child.close() - - result = tuple((-1, - "Fail [No prompt]", - name, - time.time() - start_time, - startuplog.getvalue(), - None)) - pool_child = None - else: - result = tuple((0, - "Success", - name, - time.time() - start_time, - startuplog.getvalue(), - None)) - except: - result = tuple((-1, - "Fail [Can't run]", - name, - time.time() - start_time, - startuplog.getvalue(), - None)) - pool_child = None - - result_queue.put(result) - - -# run a test -# 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(target, test): - global pool_child - - if pool_child is None: - return -1, "Fail [No test process]", test["Name"], 0, "", None - - # 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() - pool_child.logfile = logfile - - # make a note when the test started - start_time = time.time() - - try: - # print test name to log buffer - print("\n%s %s\n" % ("-" * 20, test["Name"]), file=logfile) - - # run test function associated with the test - result = test["Func"](pool_child, test["Command"]) - - # make a note when the test was finished - end_time = time.time() - - log = logfile.getvalue() - - # append test data to the result tuple - result += (test["Name"], end_time - start_time, log) - - # call report function, if any defined, and supply it with - # target and complete log for test run - if test["Report"]: - report = test["Report"](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) - - # return test results - return result - - -# 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, n_processes): - self.cmdline = cmdline - self.target = target - self.binary = cmdline.split()[0] - self.blacklist = blacklist - self.whitelist = whitelist - self.skipped = [] - self.parallel_tests = [] - self.non_parallel_tests = [] - self.n_processes = n_processes - self.active_processes = 0 - - # 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, cpu_nr): - cmdline = ("taskset -c %i " % cpu_nr) + self.cmdline - - return cmdline - - def __process_result(self, result): - - # 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 - print(result + "[%02dm %02ds]" % (total_time / 60, total_time % 60)) - - # if test failed and it wasn't a "start" test - if test_result < 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 - self.csvwriter.writerow([test_name, test_result, result_str]) - - # this function checks individual test and decides if this test should be in - # the group by comparing it against whitelist/blacklist. it also checks if - # the test is compiled into the binary, and marks it as skipped if necessary - def __filter_test(self, test): - test_cmd = test["Command"] - test_id = test_cmd - - # 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: - return False - if self.whitelist and test_id not in self.whitelist: - return False - - # if test wasn't compiled in, remove it as well - - # parse the binary for available test commands - stripped = 'not stripped' not in \ - subprocess.check_output(['file', self.binary]) - if not stripped: - symbols = subprocess.check_output(['nm', - self.binary]).decode('utf-8') - avail_cmds = re.findall('test_register_(\w+)', symbols) - - if test_cmd not in avail_cmds: - # notify user - result = 0, "Skipped [Not compiled]", test_id, 0, "", None - self.skipped.append(tuple(result)) - return False - - return True - - def __run_test_group(self, test_group, worker_cmdlines): - group_queue = Queue() - init_result_queue = Queue() - for proc, cmdline in enumerate(worker_cmdlines): - prefix = "test%i" % proc if len(worker_cmdlines) > 1 else "" - group_queue.put(tuple((cmdline, prefix))) - - # create a pool of worker threads - # we will initialize child in the initializer, and we don't need to - # close the child because when the pool worker gets destroyed, child - # closes the process - pool = Pool(processes=len(worker_cmdlines), - initializer=pool_init, - initargs=(group_queue, init_result_queue)) - - results = [] - - # process all initialization results - for _ in range(len(worker_cmdlines)): - self.__process_result(init_result_queue.get()) - - # run all tests asynchronously - for test in test_group: - result = pool.apply_async(run_test, (self.target, test)) - results.append(result) - - # tell the pool to stop all processes once done - pool.close() - - # 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 async_result in results[:]: - # if the thread hasn't finished yet, continue - if not async_result.ready(): - continue - - res = async_result.get() - - self.__process_result(res) - - # remove result from results list once we're done with it - results.remove(async_result) - - # iterate over test groups and run tests associated with them - def run_all_tests(self): - # filter groups - self.parallel_tests = list( - filter(self.__filter_test, - self.parallel_tests) - ) - self.non_parallel_tests = list( - filter(self.__filter_test, - self.non_parallel_tests) - ) - - parallel_cmdlines = [] - # FreeBSD doesn't have NUMA support - numa_nodes = get_numa_nodes() - if len(numa_nodes) > 0: - for proc in range(self.n_processes): - # spread cpu affinity between NUMA nodes to have less chance of - # running out of memory while running multiple test apps in - # parallel. to do that, alternate between NUMA nodes in a round - # robin fashion, and pick an arbitrary CPU from that node to - # taskset our execution to - numa_node = numa_nodes[self.active_processes % len(numa_nodes)] - cpu_nr = first_cpu_on_node(numa_node) - parallel_cmdlines += [self.__get_cmdline(cpu_nr)] - # increase number of active processes so that the next cmdline - # gets a different NUMA node - self.active_processes += 1 - else: - parallel_cmdlines = [self.cmdline] * self.n_processes - - print("Running tests with %d workers" % self.n_processes) - - # create table header - print("") - print("Test name".ljust(30) + "Test result".ljust(29) + - "Test".center(9) + "Total".center(9)) - print("=" * 80) - - if len(self.skipped): - print("Skipped autotests:") - - # print out any skipped tests - for result in self.skipped: - # unpack result tuple - test_result, result_str, test_name, _, _, _ = result - self.csvwriter.writerow([test_name, test_result, result_str]) - - t = ("%s:" % test_name).ljust(30) - t += result_str.ljust(29) - t += "[00m 00s]" - - print(t) - - # make a note of tests start time - self.start = time.time() - - # whatever happens, try to save as much logs as possible - try: - if len(self.parallel_tests) > 0: - print("Parallel autotests:") - self.__run_test_group(self.parallel_tests, parallel_cmdlines) - - if len(self.non_parallel_tests) > 0: - print("Non-parallel autotests:") - self.__run_test_group(self.non_parallel_tests, [self.cmdline]) - - # 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 deleted file mode 100644 index 65fe335397..0000000000 --- a/test/test/autotest_test_funcs.py +++ /dev/null @@ -1,276 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2014 Intel Corporation - -# 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): - lines = 0 - error = '' - child.sendline(test_name) - while True: - regexp = "IOVA:0x[0-9a-f]*, len:([0-9]*), virt:0x[0-9a-f]*, " \ - "socket_id:[0-9]*" - index = child.expect([regexp, "Test OK", "Test Failed", - pexpect.TIMEOUT], timeout=10) - if index == 3: - return -1, "Fail [Timeout]" - elif index == 1: - break - elif index == 2: - return -1, "Fail" - else: - lines = lines + 1 - size = int(child.match.groups()[0], 10) - if size <= 0: - error = 'Bad size' - - if lines <= 0: - return -1, "Fail [No entries]" - if error != '': - return -1, "Fail [{}]".format(error) - 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]" - - return 0, "Success" diff --git a/test/test/commands.c b/test/test/commands.c deleted file mode 100644 index 94fbc310ed..0000000000 --- a/test/test/commands.c +++ /dev/null @@ -1,388 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation. - * Copyright(c) 2014 6WIND S.A. - */ - -#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 - -#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(); - } - - last_test_result = ret; - if (ret == 0) - printf("Test OK\n"); - else if (ret == TEST_SKIPPED) - printf("Test Skipped\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_devargs_dump(stdout); - else if (!strcmp(res->dump, "dump_log_types")) - rte_log_dump(stdout); - else if (!strcmp(res->dump, "dump_malloc_stats")) - rte_malloc_dump_stats(stdout, NULL); - else if (!strcmp(res->dump, "dump_malloc_heaps")) - rte_malloc_dump_heaps(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_malloc_stats#" - "dump_malloc_heaps#" - "dump_devargs#" - "dump_log_types"); - -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_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_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/meson.build b/test/test/meson.build deleted file mode 100644 index 05e5ddeb09..0000000000 --- a/test/test/meson.build +++ /dev/null @@ -1,378 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2017 Intel Corporation - -test_sources = files('commands.c', - 'packet_burst_generator.c', - 'sample_packet_forward.c', - 'test.c', - 'test_acl.c', - 'test_alarm.c', - 'test_atomic.c', - 'test_barrier.c', - 'test_bitratestats.c', - 'test_bpf.c', - 'test_byteorder.c', - 'test_cmdline.c', - 'test_cmdline_cirbuf.c', - 'test_cmdline_etheraddr.c', - 'test_cmdline_ipaddr.c', - 'test_cmdline_lib.c', - 'test_cmdline_num.c', - 'test_cmdline_portlist.c', - 'test_cmdline_string.c', - 'test_common.c', - 'test_cpuflags.c', - 'test_crc.c', - 'test_cryptodev.c', - 'test_cryptodev_asym.c', - 'test_cryptodev_blockcipher.c', - 'test_cycles.c', - 'test_debug.c', - 'test_distributor.c', - 'test_distributor_perf.c', - 'test_eal_flags.c', - 'test_eal_fs.c', - 'test_efd.c', - 'test_efd_perf.c', - 'test_errno.c', - 'test_event_crypto_adapter.c', - 'test_event_eth_rx_adapter.c', - 'test_event_ring.c', - 'test_event_eth_tx_adapter.c', - 'test_event_timer_adapter.c', - 'test_eventdev.c', - 'test_external_mem.c', - 'test_fbarray.c', - 'test_func_reentrancy.c', - 'test_flow_classify.c', - 'test_hash.c', - 'test_hash_functions.c', - 'test_hash_multiwriter.c', - 'test_hash_readwrite.c', - 'test_hash_perf.c', - 'test_hash_readwrite_lf.c', - 'test_interrupts.c', - 'test_ipsec.c', - 'test_kni.c', - 'test_kvargs.c', - 'test_latencystats.c', - 'test_link_bonding.c', - 'test_link_bonding_mode4.c', - 'test_logs.c', - 'test_lpm.c', - 'test_lpm6.c', - 'test_lpm6_perf.c', - 'test_lpm_perf.c', - 'test_malloc.c', - 'test_mbuf.c', - 'test_member.c', - 'test_member_perf.c', - 'test_memcpy.c', - 'test_memcpy_perf.c', - 'test_memory.c', - 'test_mempool.c', - 'test_mempool_perf.c', - 'test_memzone.c', - 'test_meter.c', - 'test_metrics.c', - 'test_mp_secondary.c', - 'test_pdump.c', - 'test_per_lcore.c', - 'test_pmd_perf.c', - 'test_pmd_ring.c', - 'test_pmd_ring_perf.c', - 'test_power.c', - 'test_power_acpi_cpufreq.c', - 'test_power_kvm_vm.c', - 'test_prefetch.c', - 'test_reciprocal_division.c', - 'test_reciprocal_division_perf.c', - 'test_red.c', - 'test_reorder.c', - 'test_ring.c', - 'test_ring_perf.c', - 'test_rwlock.c', - 'test_sched.c', - 'test_service_cores.c', - 'test_spinlock.c', - 'test_string_fns.c', - 'test_table.c', - 'test_table_acl.c', - 'test_table_combined.c', - 'test_table_pipeline.c', - 'test_table_ports.c', - 'test_table_tables.c', - 'test_tailq.c', - 'test_thash.c', - 'test_timer.c', - 'test_timer_perf.c', - 'test_timer_racecond.c', - 'test_version.c', - 'virtual_pmd.c' -) - -test_deps = ['acl', - 'bitratestats', - 'bpf', - 'cfgfile', - 'cmdline', - 'cryptodev', - 'distributor', - 'efd', - 'ethdev', - 'eventdev', - 'flow_classify', - 'hash', - 'ipsec', - 'latencystats', - 'lpm', - 'member', - 'metrics', - 'pipeline', - 'port', - 'reorder', - 'ring', - 'timer' -] - -# All test cases in fast_parallel_test_names list are parallel -fast_parallel_test_names = [ - 'acl_autotest', - 'alarm_autotest', - 'atomic_autotest', - 'byteorder_autotest', - 'cmdline_autotest', - 'common_autotest', - 'cpuflags_autotest', - 'cycles_autotest', - 'debug_autotest', - 'eal_flags_autotest', - 'eal_fs_autotest', - 'errno_autotest', - 'event_ring_autotest', - 'func_reentrancy_autotest', - 'flow_classify_autotest', - 'hash_autotest', - 'interrupt_autotest', - 'logs_autotest', - 'lpm_autotest', - 'lpm6_autotest', - 'malloc_autotest', - 'mbuf_autotest', - 'memcpy_autotest', - 'memory_autotest', - 'mempool_autotest', - 'memzone_autotest', - 'meter_autotest', - 'multiprocess_autotest', - 'per_lcore_autotest', - 'prefetch_autotest', - 'red_autotest', - 'ring_autotest', - 'ring_pmd_autotest', - 'rwlock_autotest', - 'sched_autotest', - 'spinlock_autotest', - 'string_autotest', - 'table_autotest', - 'tailq_autotest', - 'timer_autotest', - 'user_delay_us', - 'version_autotest', -] - -# All test cases in fast_non_parallel_test_names list are non-parallel -fast_non_parallel_test_names = [ - 'bitratestats_autotest', - 'cryptodev_sw_armv8_autotest', - 'crc_autotest', - 'cryptodev_openssl_asym_autotest', - 'cryptodev_sw_mvsam_autotest', - 'delay_us_sleep_autotest', - 'devargs_autotest', - 'distributor_autotest', - 'eventdev_common_autotest', - 'eventdev_octeontx_autotest', - 'eventdev_sw_autotest', - 'fbarray_autotest', - 'hash_readwrite_autotest', - 'hash_readwrite_lf_autotest', - 'hash_scaling_autotest', - 'ipsec_autotest', - 'kni_autotest', - 'kvargs_autotest', - 'latencystats_autotest', - 'member_autotest', - 'metrics_autotest', - 'pdump_autotest', - 'power_acpi_cpufreq_autotest', - 'power_autotest', - 'power_kvm_vm_autotest', - 'reorder_autotest', - 'service_autotest', - 'thash_autotest', -] - -# All test cases in perf_test_names list are non-parallel -perf_test_names = [ - 'ring_perf_autotest', - 'mempool_perf_autotest', - 'memcpy_perf_autotest', - 'hash_perf_autotest', - 'timer_perf_autotest', - 'reciprocal_division', - 'reciprocal_division_perf', - 'lpm_perf_autotest', - 'red_all', - 'barrier_autotest', - 'hash_multiwriter_autotest', - 'timer_racecond_autotest', - 'efd_autotest', - 'hash_functions_autotest', - 'eventdev_selftest_sw', - 'member_perf_autotest', - 'efd_perf_autotest', - 'lpm6_perf_autotest', - 'red_perf', - 'distributor_perf_autotest', - 'ring_pmd_perf_autotest', - 'pmd_perf_autotest', -] - -# All test cases in driver_test_names list are non-parallel -driver_test_names = [ - 'link_bonding_autotest', - 'link_bonding_mode4_autotest', - 'link_bonding_rssconf_autotest', - 'cryptodev_sw_mrvl_autotest', - 'cryptodev_dpaa2_sec_autotest', - 'cryptodev_dpaa_sec_autotest', - 'cryptodev_qat_autotest', - 'cryptodev_aesni_mb_autotest', - 'cryptodev_openssl_autotest', - 'cryptodev_scheduler_autotest', - 'cryptodev_aesni_gcm_autotest', - 'cryptodev_null_autotest', - 'cryptodev_sw_snow3g_autotest', - 'cryptodev_sw_kasumi_autotest', - 'cryptodev_sw_zuc_autotest', -] - -# All test cases in dump_test_names list are non-parallel -dump_test_names = [ - 'dump_struct_sizes', - 'dump_mempool', - 'dump_malloc_stats', - 'dump_devargs', - 'dump_log_types', - 'dump_ring', - 'dump_physmem', - 'dump_memzone', -] - -if dpdk_conf.has('RTE_LIBRTE_PDUMP') - test_deps += 'pdump' -endif -if dpdk_conf.has('RTE_LIBRTE_I40E_PMD') - test_deps += 'pmd_i40e' -endif -if dpdk_conf.has('RTE_LIBRTE_IXGBE_PMD') - test_deps += 'pmd_ixgbe' -endif -if dpdk_conf.has('RTE_LIBRTE_BOND_PMD') - test_deps += 'pmd_bond' -endif -if dpdk_conf.has('RTE_LIBRTE_RING_PMD') - test_deps += 'pmd_ring' -endif -if dpdk_conf.has('RTE_LIBRTE_POWER') - test_deps += 'power' -endif -if dpdk_conf.has('RTE_LIBRTE_KNI') - test_deps += 'kni' -endif - -cflags = machine_args -if cc.has_argument('-Wno-format-truncation') - cflags += '-Wno-format-truncation' -endif - -# specify -D_GNU_SOURCE unconditionally -default_cflags += '-D_GNU_SOURCE' - -test_dep_objs = [] -if dpdk_conf.has('RTE_LIBRTE_COMPRESSDEV') - compress_test_dep = dependency('zlib', required: false) - if compress_test_dep.found() - test_dep_objs += compress_test_dep - test_sources += 'test_compressdev.c' - test_deps += 'compressdev' - fast_non_parallel_test_names += 'compressdev_autotest' - endif -endif - -foreach d:test_deps - def_lib = get_option('default_library') - test_dep_objs += get_variable(def_lib + '_rte_' + d) -endforeach -test_dep_objs += cc.find_library('execinfo', required: false) - -link_libs = [] -if get_option('default_library') == 'static' - link_libs = dpdk_drivers -endif - -if get_option('tests') - dpdk_test = executable('dpdk-test', - test_sources, - link_whole: link_libs, - dependencies: test_dep_objs, - c_args: [cflags, '-DALLOW_EXPERIMENTAL_API'], - install_rpath: driver_install_path, - install: false) - - # some perf tests (eg: memcpy perf autotest)take very long - # to complete, so timeout to 10 minutes - timeout_seconds = 600 - timeout_seconds_fast = 10 - - foreach arg : fast_parallel_test_names - test(arg, dpdk_test, - env : ['DPDK_TEST=' + arg], - args : ['-c f','-n 4', '--file-prefix=@0@'.format(arg)], - timeout : timeout_seconds_fast, - suite : 'fast-tests') - endforeach - - foreach arg : fast_non_parallel_test_names - test(arg, dpdk_test, - env : ['DPDK_TEST=' + arg], - timeout : timeout_seconds_fast, - is_parallel : false, - suite : 'fast-tests') - endforeach - - foreach arg : perf_test_names - test(arg, dpdk_test, - env : ['DPDK_TEST=' + arg], - timeout : timeout_seconds, - is_parallel : false, - suite : 'perf-tests') - endforeach - - foreach arg : driver_test_names - test(arg, dpdk_test, - env : ['DPDK_TEST=' + arg], - timeout : timeout_seconds, - is_parallel : false, - suite : 'driver-tests') - endforeach - - foreach arg : dump_test_names - test(arg, dpdk_test, - env : ['DPDK_TEST=' + arg], - timeout : timeout_seconds, - is_parallel : false, - suite : 'debug-tests') - endforeach -endif diff --git a/test/test/packet_burst_generator.c b/test/test/packet_burst_generator.c deleted file mode 100644 index e894dc76f6..0000000000 --- a/test/test/packet_burst_generator.c +++ /dev/null @@ -1,447 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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_tcp_header(struct tcp_hdr *tcp_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 tcp_hdr)); - - memset(tcp_hdr, 0, sizeof(struct tcp_hdr)); - tcp_hdr->src_port = rte_cpu_to_be_16(src_port); - tcp_hdr->dst_port = rte_cpu_to_be_16(dst_port); - - return pkt_len; -} - -uint16_t -initialize_sctp_header(struct sctp_hdr *sctp_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)); - - sctp_hdr->src_port = rte_cpu_to_be_16(src_port); - sctp_hdr->dst_port = rte_cpu_to_be_16(dst_port); - sctp_hdr->tag = 0; - sctp_hdr->cksum = 0; /* No SCTP 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; -} - -uint16_t -initialize_ipv4_header_proto(struct ipv4_hdr *ip_hdr, uint32_t src_addr, - uint32_t dst_addr, uint16_t pkt_data_len, uint8_t proto) -{ - 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 = proto; - 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; -} - -int -generate_packet_burst_proto(struct rte_mempool *mp, - struct rte_mbuf **pkts_burst, - struct ether_hdr *eth_hdr, uint8_t vlan_enabled, void *ip_hdr, - uint8_t ipv4, uint8_t proto, void *proto_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); - switch (proto) { - case IPPROTO_UDP: - copy_buf_to_pkt(proto_hdr, - sizeof(struct udp_hdr), pkt, - eth_hdr_size + sizeof(struct ipv4_hdr)); - break; - case IPPROTO_TCP: - copy_buf_to_pkt(proto_hdr, - sizeof(struct tcp_hdr), pkt, - eth_hdr_size + sizeof(struct ipv4_hdr)); - break; - case IPPROTO_SCTP: - copy_buf_to_pkt(proto_hdr, - sizeof(struct sctp_hdr), pkt, - eth_hdr_size + sizeof(struct ipv4_hdr)); - break; - default: - break; - } - } else { - copy_buf_to_pkt(ip_hdr, sizeof(struct ipv6_hdr), pkt, - eth_hdr_size); - switch (proto) { - case IPPROTO_UDP: - copy_buf_to_pkt(proto_hdr, - sizeof(struct udp_hdr), pkt, - eth_hdr_size + sizeof(struct ipv6_hdr)); - break; - case IPPROTO_TCP: - copy_buf_to_pkt(proto_hdr, - sizeof(struct tcp_hdr), pkt, - eth_hdr_size + sizeof(struct ipv6_hdr)); - break; - case IPPROTO_SCTP: - copy_buf_to_pkt(proto_hdr, - sizeof(struct sctp_hdr), pkt, - eth_hdr_size + sizeof(struct ipv6_hdr)); - break; - default: - break; - } - } - - /* - * 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 deleted file mode 100644 index c20cea6e93..0000000000 --- a/test/test/packet_burst_generator.h +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef PACKET_BURST_GENERATOR_H_ -#define PACKET_BURST_GENERATOR_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#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_tcp_header(struct tcp_hdr *tcp_hdr, uint16_t src_port, - uint16_t dst_port, uint16_t pkt_data_len); - -uint16_t -initialize_sctp_header(struct sctp_hdr *sctp_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); - -uint16_t -initialize_ipv4_header_proto(struct ipv4_hdr *ip_hdr, uint32_t src_addr, - uint32_t dst_addr, uint16_t pkt_data_len, uint8_t proto); - -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 -generate_packet_burst_proto(struct rte_mempool *mp, - struct rte_mbuf **pkts_burst, - struct ether_hdr *eth_hdr, uint8_t vlan_enabled, void *ip_hdr, - uint8_t ipv4, uint8_t proto, void *proto_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 deleted file mode 100644 index 7f62f644f0..0000000000 --- a/test/test/process.h +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef _PROCESS_H_ -#define _PROCESS_H_ - -#include /* PATH_MAX */ -#include /* basename et al */ -#include /* NULL */ -#include /* readlink */ -#include - -#ifdef RTE_EXEC_ENV_BSDAPP -#define self "curproc" -#define exe "file" -#else -#define self "self" -#define exe "exe" -#endif - -#include -extern void *send_pkts(void *empty); -extern uint16_t flag_for_send_pkts; - -/* - * 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; - char *argv_cpy[numargs + 1]; - int i, fd, status; - char path[32]; - pthread_t thread; - - 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]); - argv_cpy[i] = NULL; - num = numargs; - - /* 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 */ - if ((strcmp(env_value, "run_pdump_server_tests") == 0)) - pthread_create(&thread, NULL, &send_pkts, NULL); - - while (wait(&status) != pid) - ; - if ((strcmp(env_value, "run_pdump_server_tests") == 0)) { - flag_for_send_pkts = 0; - pthread_join(thread, NULL); - } - return status; -} - -/* FreeBSD doesn't support file prefixes, so force compile failures for any - * tests attempting to use this function on FreeBSD. - */ -#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 prefix */ - snprintf(prefix, size, "%s", basename(dirname(buf))); - - return prefix; -} -#endif - -#endif /* _PROCESS_H_ */ diff --git a/test/test/resource.c b/test/test/resource.c deleted file mode 100644 index 34465f1668..0000000000 --- a/test/test/resource.c +++ /dev/null @@ -1,276 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016 RehiveTech. All rights reserved. - */ - -#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 deleted file mode 100644 index 223fa22aec..0000000000 --- a/test/test/resource.h +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016 RehiveTech. All rights reserved. - */ - -#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/sample_packet_forward.c b/test/test/sample_packet_forward.c deleted file mode 100644 index 61384b3d9b..0000000000 --- a/test/test/sample_packet_forward.c +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include -#include - -#include -#include -#include -#include -#include "rte_lcore.h" -#include "rte_mempool.h" -#include "rte_ring.h" - -#include "sample_packet_forward.h" - -/* Sample test to create virtual rings and tx,rx portid from rings */ -int -test_ring_setup(struct rte_ring **ring, uint16_t *portid) -{ - *ring = rte_ring_create("R0", RING_SIZE, rte_socket_id(), - RING_F_SP_ENQ | RING_F_SC_DEQ); - if (*ring == NULL) { - printf("%s() line %u: rte_ring_create R0 failed", - __func__, __LINE__); - return -1; - } - *portid = rte_eth_from_rings("net_ringa", ring, NUM_QUEUES, - ring, NUM_QUEUES, rte_socket_id()); - - return 0; -} - -/* Sample test to free the mempool */ -void -test_mp_free(struct rte_mempool *mp) -{ - rte_mempool_free(mp); -} - -/* Sample test to free the virtual rings */ -void -test_ring_free(struct rte_ring *rxtx) -{ - rte_ring_free(rxtx); -} - -/* Sample test to release the vdev */ -void -test_vdev_uninit(const char *vdev) -{ - rte_vdev_uninit(vdev); -} - -/* sample test to allocate the mempool */ -int -test_get_mempool(struct rte_mempool **mp, char *poolname) -{ - *mp = rte_pktmbuf_pool_create(poolname, NB_MBUF, 32, 0, - RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - if (*mp == NULL) - return -1; - return 0; -} - -/* sample test to allocate buffer for pkts */ -int -test_get_mbuf_from_pool(struct rte_mempool **mp, struct rte_mbuf **pbuf, - char *poolname) -{ - int ret = 0; - - ret = test_get_mempool(mp, poolname); - if (ret < 0) - return -1; - if (rte_pktmbuf_alloc_bulk(*mp, pbuf, NUM_PACKETS) != 0) { - printf("%s() line %u: rte_pktmbuf_alloc_bulk failed", __func__, - __LINE__); - return -1; - } - return 0; -} - -/* sample test to deallocate the allocated buffers and mempool */ -void -test_put_mbuf_to_pool(struct rte_mempool *mp, struct rte_mbuf **pbuf) -{ - int itr = 0; - - for (itr = 0; itr < NUM_PACKETS; itr++) - rte_pktmbuf_free(pbuf[itr]); - rte_mempool_free(mp); -} - -/* Sample test to forward packets using virtual portids */ -int -test_packet_forward(struct rte_mbuf **pbuf, uint16_t portid, uint16_t queue_id) -{ - /* send and receive packet and check for stats update */ - if (rte_eth_tx_burst(portid, queue_id, pbuf, NUM_PACKETS) - < NUM_PACKETS) { - printf("%s() line %u: Error sending packet to" - " port %d\n", __func__, __LINE__, portid); - return -1; - } - if (rte_eth_rx_burst(portid, queue_id, pbuf, NUM_PACKETS) - < NUM_PACKETS) { - printf("%s() line %u: Error receiving packet from" - " port %d\n", __func__, __LINE__, portid); - return -1; - } - return 0; -} diff --git a/test/test/sample_packet_forward.h b/test/test/sample_packet_forward.h deleted file mode 100644 index 6789217de3..0000000000 --- a/test/test/sample_packet_forward.h +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#ifndef _SAMPLE_PACKET_FORWARD_H_ -#define _SAMPLE_PACKET_FORWARD_H_ - -#include - -/* MACROS to support virtual ring creation */ -#define RING_SIZE 256 -#define NUM_QUEUES 1 -#define NB_MBUF 512 - -#define NUM_PACKETS 10 - -struct rte_mbuf; -struct rte_mempool; -struct rte_ring; - -/* Sample test to create virtual rings and tx,rx portid from rings */ -int test_ring_setup(struct rte_ring **ring, uint16_t *portid); - -/* Sample test to free the virtual rings */ -void test_ring_free(struct rte_ring *rxtx); - -/* Sample test to forward packet using virtual port id */ -int test_packet_forward(struct rte_mbuf **pbuf, uint16_t portid, - uint16_t queue_id); - -/* sample test to allocate buffer for pkts */ -int test_get_mbuf_from_pool(struct rte_mempool **mp, struct rte_mbuf **pbuf, - char *poolname); - -/* Sample test to create the mempool */ -int test_get_mempool(struct rte_mempool **mp, char *poolname); - -/* sample test to deallocate the allocated buffers and mempool */ -void test_put_mbuf_to_pool(struct rte_mempool *mp, struct rte_mbuf **pbuf); - -/* Sample test to free the mempool */ -void test_mp_free(struct rte_mempool *mp); - -/* Sample test to release the vdev */ -void test_vdev_uninit(const char *vdev); - -#endif /* _SAMPLE_PACKET_FORWARD_H_ */ diff --git a/test/test/test.c b/test/test/test.c deleted file mode 100644 index 351c7f2759..0000000000 --- a/test/test/test.c +++ /dev/null @@ -1,288 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 -#ifdef RTE_LIBRTE_TIMER -#include -#endif - -#include "test.h" -#include "test_pdump.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 }, - { "run_pdump_server_tests", test_pdump }, - { "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 }, - { "test_misc_flags", no_action }, - { "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 last_test_result; - -#define MAX_EXTRA_ARGS 32 - -int -main(int argc, char **argv) -{ -#ifdef RTE_LIBRTE_CMDLINE - struct cmdline *cl; -#endif - char *extra_args; - int ret; - - extra_args = getenv("DPDK_TEST_PARAMS"); - if (extra_args != NULL && strlen(extra_args) > 0) { - char **all_argv; - char *eargv[MAX_EXTRA_ARGS]; - int all_argc; - int eargc; - int i; - - RTE_LOG(INFO, APP, "Using additional DPDK_TEST_PARAMS: '%s'\n", - extra_args); - eargc = rte_strsplit(extra_args, strlen(extra_args), - eargv, MAX_EXTRA_ARGS, ' '); - - /* merge argc/argv and the environment args */ - all_argc = argc + eargc; - all_argv = malloc(sizeof(*all_argv) * (all_argc + 1)); - if (all_argv == NULL) { - ret = -1; - goto out; - } - - for (i = 0; i < argc; i++) - all_argv[i] = argv[i]; - for (i = 0; i < eargc; i++) - all_argv[argc + i] = eargv[i]; - all_argv[all_argc] = NULL; - - /* call eal_init with combined args */ - ret = rte_eal_init(all_argc, all_argv); - free(all_argv); - } else - ret = rte_eal_init(argc, argv); - if (ret < 0) { - ret = -1; - goto out; - } - -#ifdef RTE_LIBRTE_TIMER - rte_timer_subsystem_init(); -#endif - - if (commands_init() < 0) { - ret = -1; - goto out; - } - - argv += ret; - - prgname = argv[0]; - - recursive_call = getenv(RECURSIVE_ENV_VAR); - if (recursive_call != NULL) { - ret = do_recursive_call(); - goto out; - } - -#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) { - ret = -1; - goto out; - } - - char *dpdk_test = getenv("DPDK_TEST"); - if (dpdk_test && strlen(dpdk_test)) { - char buf[1024]; - snprintf(buf, sizeof(buf), "%s\n", dpdk_test); - if (cmdline_in(cl, buf, strlen(buf)) < 0) { - printf("error on cmdline input\n"); - ret = -1; - goto out; - } - - cmdline_stdin_exit(cl); - ret = last_test_result; - goto out; - } - /* if no DPDK_TEST env variable, go interactive */ - cmdline_interact(cl); - cmdline_stdin_exit(cl); -#endif - ret = 0; - -out: - rte_eal_cleanup(); - return ret; -} - - -int -unit_test_suite_runner(struct unit_test_suite *suite) -{ - int test_success; - unsigned int total = 0, executed = 0, skipped = 0; - unsigned int succeeded = 0, failed = 0, unsupported = 0; - const char *status; - - if (suite->suite_name) { - printf(" + ------------------------------------------------------- +\n"); - printf(" + Test Suite : %s\n", suite->suite_name); - } - - if (suite->setup) - if (suite->setup() != 0) { - /* - * setup failed, so count all enabled tests and mark - * them as failed - */ - while (suite->unit_test_cases[total].testcase) { - if (!suite->unit_test_cases[total].enabled) - skipped++; - else - failed++; - total++; - } - 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 if (test_success == -ENOTSUP) - unsupported++; - else - failed++; - } else if (test_success == -ENOTSUP) { - unsupported++; - } 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) - status = "succeeded"; - else if (test_success == -ENOTSUP) - status = "unsupported"; - else - status = "failed"; - - printf(" + TestCase [%2d] : %s %s\n", total, - suite->unit_test_cases[total].name, status); - - 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 Unsupported: %2d\n", unsupported); - printf(" + Tests Passed : %2d\n", succeeded); - printf(" + Tests Failed : %2d\n", failed); - printf(" + ------------------------------------------------------- +\n"); - - last_test_result = failed; - - if (failed) - return -1; - - return 0; -} diff --git a/test/test/test.h b/test/test/test.h deleted file mode 100644 index 7c24432303..0000000000 --- a/test/test/test.h +++ /dev/null @@ -1,186 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef _TEST_H_ -#define _TEST_H_ - -#include -#include - -#include -#include - -#define TEST_SUCCESS EXIT_SUCCESS -#define TEST_FAILED -1 -#define TEST_SKIPPED 77 - -/* 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 RTE_TEST_TRACE_FAILURE TEST_TRACE_FAILURE - -#include - -#define TEST_ASSERT RTE_TEST_ASSERT - -#define TEST_ASSERT_EQUAL RTE_TEST_ASSERT_EQUAL - -/* 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 RTE_TEST_ASSERT_NOT_EQUAL - -#define TEST_ASSERT_SUCCESS RTE_TEST_ASSERT_SUCCESS - -#define TEST_ASSERT_FAIL RTE_TEST_ASSERT_FAIL - -#define TEST_ASSERT_NULL RTE_TEST_ASSERT_NULL - -#define TEST_ASSERT_NOT_NULL RTE_TEST_ASSERT_NOT_NULL - -struct unit_test_case { - int (*setup)(void); - void (*teardown)(void); - int (*testcase)(void); - const char *name; - unsigned enabled; -}; - -#define TEST_CASE(fn) { NULL, NULL, fn, #fn, 1 } - -#define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, name, 1 } - -#define TEST_CASE_ST(setup, teardown, testcase) \ - { setup, teardown, testcase, #testcase, 1 } - - -#define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, #fn, 0 } - -#define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \ - { setup, teardown, testcase, #testcase, 0 } - -#define TEST_CASES_END() { NULL, NULL, NULL, NULL, 0 } - -static inline void -debug_hexdump(FILE *file, const char *title, const void *buf, size_t len) -{ - if (rte_log_get_global_level() == RTE_LOG_DEBUG) - rte_hexdump(file, title, buf, len); -} - -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); -extern int last_test_result; - -#define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE" - -#include -#include - -extern const char *prgname; - -int commands_init(void); - -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 deleted file mode 100644 index b1f75d1bc7..0000000000 --- a/test/test/test_acl.c +++ /dev/null @@ -1,1623 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index bbb0447a89..0000000000 --- a/test/test/test_acl.h +++ /dev/null @@ -1,669 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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, - .priority = 1}, - .src_addr = IPv4(10,0,0,0), - .src_mask_len = 24, - }, - { - .data = {.userdata = 2, .category_mask = 1, - .priority = 1}, - .dst_addr = IPv4(10,0,0,0), - .dst_mask_len = 24, - }, - /* test src and dst ports */ - { - .data = {.userdata = 3, .category_mask = 1, - .priority = 1}, - .dst_port_low = 100, - .dst_port_high = 100, - }, - { - .data = {.userdata = 4, .category_mask = 1, - .priority = 1}, - .src_port_low = 100, - .src_port_high = 100, - }, - /* test proto */ - { - .data = {.userdata = 5, .category_mask = 1, - .priority = 1}, - .proto = 0xf, - .proto_mask = 0xf - }, - { - .data = {.userdata = 6, .category_mask = 1, - .priority = 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 deleted file mode 100644 index d1284b379f..0000000000 --- a/test/test/test_alarm.c +++ /dev/null @@ -1,234 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 */ -#define RTE_TEST_MAX_REPEAT 20 - -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; - int 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; - } - - while (flag != 2 && count++ < RTE_TEST_MAX_REPEAT) - 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; -#ifdef RTE_EXEC_ENV_BSDAPP - printf("The alarm API is not supported on FreeBSD\n"); - return 0; -#endif - /* 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++ < RTE_TEST_MAX_REPEAT) - 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 deleted file mode 100644 index 43be30ec0b..0000000000 --- a/test/test/test_atomic.c +++ /dev/null @@ -1,346 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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_barrier.c b/test/test/test_barrier.c deleted file mode 100644 index 82b572c3eb..0000000000 --- a/test/test/test_barrier.c +++ /dev/null @@ -1,286 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2018 Intel Corporation - */ - - /* - * This is a simple functional test for rte_smp_mb() implementation. - * I.E. make sure that LOAD and STORE operations that precede the - * rte_smp_mb() call are globally visible across the lcores - * before the the LOAD and STORE operations that follows it. - * The test uses simple implementation of Peterson's lock algorithm - * (https://en.wikipedia.org/wiki/Peterson%27s_algorithm) - * for two execution units to make sure that rte_smp_mb() prevents - * store-load reordering to happen. - * Also when executed on a single lcore could be used as a approxiamate - * estimation of number of cycles particular implementation of rte_smp_mb() - * will take. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define ADD_MAX 8 -#define ITER_MAX 0x1000000 - -enum plock_use_type { - USE_MB, - USE_SMP_MB, - USE_NUM -}; - -struct plock { - volatile uint32_t flag[2]; - volatile uint32_t victim; - enum plock_use_type utype; -}; - -/* - * Lock plus protected by it two counters. - */ -struct plock_test { - struct plock lock; - uint32_t val; - uint32_t iter; -}; - -/* - * Each active lcore shares plock_test struct with it's left and right - * neighbours. - */ -struct lcore_plock_test { - struct plock_test *pt[2]; /* shared, lock-protected data */ - uint32_t sum[2]; /* local copy of the shared data */ - uint32_t iter; /* number of iterations to perfom */ - uint32_t lc; /* given lcore id */ -}; - -static inline void -store_load_barrier(uint32_t utype) -{ - if (utype == USE_MB) - rte_mb(); - else if (utype == USE_SMP_MB) - rte_smp_mb(); - else - RTE_VERIFY(0); -} - -/* - * Peterson lock implementation. - */ -static void -plock_lock(struct plock *l, uint32_t self) -{ - uint32_t other; - - other = self ^ 1; - - l->flag[self] = 1; - l->victim = self; - - store_load_barrier(l->utype); - - while (l->flag[other] == 1 && l->victim == self) - rte_pause(); -} - -static void -plock_unlock(struct plock *l, uint32_t self) -{ - rte_smp_wmb(); - l->flag[self] = 0; -} - -static void -plock_reset(struct plock *l, enum plock_use_type utype) -{ - memset(l, 0, sizeof(*l)); - l->utype = utype; -} - -/* - * grab the lock, update both counters, release the lock. - */ -static void -plock_add(struct plock_test *pt, uint32_t self, uint32_t n) -{ - plock_lock(&pt->lock, self); - pt->iter++; - pt->val += n; - plock_unlock(&pt->lock, self); -} - -static int -plock_test1_lcore(void *data) -{ - uint64_t tm; - uint32_t i, lc, ln, n; - struct lcore_plock_test *lpt; - - lpt = data; - lc = rte_lcore_id(); - - /* find lcore_plock_test struct for given lcore */ - for (ln = rte_lcore_count(); ln != 0 && lpt->lc != lc; lpt++, ln--) - ; - - if (ln == 0) { - printf("%s(%u) error at init\n", __func__, lc); - return -1; - } - - n = rte_rand() % ADD_MAX; - tm = rte_get_timer_cycles(); - - /* - * for each iteration: - * - update shared, locked protected data in a safe manner - * - update local copy of the shared data - */ - for (i = 0; i != lpt->iter; i++) { - - plock_add(lpt->pt[0], 0, n); - plock_add(lpt->pt[1], 1, n); - - lpt->sum[0] += n; - lpt->sum[1] += n; - - n = (n + 1) % ADD_MAX; - } - - tm = rte_get_timer_cycles() - tm; - - printf("%s(%u): %u iterations finished, in %" PRIu64 - " cycles, %#Lf cycles/iteration, " - "local sum={%u, %u}\n", - __func__, lc, i, tm, (long double)tm / i, - lpt->sum[0], lpt->sum[1]); - return 0; -} - -/* - * For N active lcores we allocate N+1 lcore_plock_test structures. - * Each active lcore shares one lcore_plock_test structure with its - * left lcore neighbor and one lcore_plock_test structure with its - * right lcore neighbor. - * During the test each lcore updates data in both shared structures and - * its local copies. Then at validation phase we check that our shared - * and local data are the same. - */ -static int -plock_test(uint32_t iter, enum plock_use_type utype) -{ - int32_t rc; - uint32_t i, lc, n; - uint32_t *sum; - struct plock_test *pt; - struct lcore_plock_test *lpt; - - /* init phase, allocate and initialize shared data */ - - n = rte_lcore_count(); - pt = calloc(n + 1, sizeof(*pt)); - lpt = calloc(n, sizeof(*lpt)); - sum = calloc(n + 1, sizeof(*sum)); - - printf("%s(iter=%u, utype=%u) started on %u lcores\n", - __func__, iter, utype, n); - - if (pt == NULL || lpt == NULL) { - printf("%s: failed to allocate memory for %u lcores\n", - __func__, n); - free(pt); - free(lpt); - free(sum); - return -ENOMEM; - } - - for (i = 0; i != n + 1; i++) - plock_reset(&pt[i].lock, utype); - - i = 0; - RTE_LCORE_FOREACH(lc) { - - lpt[i].lc = lc; - lpt[i].iter = iter; - lpt[i].pt[0] = pt + i; - lpt[i].pt[1] = pt + i + 1; - i++; - } - - lpt[i - 1].pt[1] = pt; - - for (i = 0; i != n; i++) - printf("lpt[%u]={lc=%u, pt={%p, %p},};\n", - i, lpt[i].lc, lpt[i].pt[0], lpt[i].pt[1]); - - - /* test phase - start and wait for completion on each active lcore */ - - rte_eal_mp_remote_launch(plock_test1_lcore, lpt, CALL_MASTER); - rte_eal_mp_wait_lcore(); - - /* validation phase - make sure that shared and local data match */ - - for (i = 0; i != n; i++) { - sum[i] += lpt[i].sum[0]; - sum[i + 1] += lpt[i].sum[1]; - } - - sum[0] += sum[i]; - - rc = 0; - for (i = 0; i != n; i++) { - printf("%s: sum[%u]=%u, pt[%u].val=%u, pt[%u].iter=%u;\n", - __func__, i, sum[i], i, pt[i].val, i, pt[i].iter); - - /* race condition occurred, lock doesn't work properly */ - if (sum[i] != pt[i].val || 2 * iter != pt[i].iter) { - printf("error: local and shared sums don't much\n"); - rc = -1; - } - } - - free(pt); - free(lpt); - free(sum); - - printf("%s(utype=%u) returns %d\n", __func__, utype, rc); - return rc; -} - -static int -test_barrier(void) -{ - int32_t i, ret, rc[USE_NUM]; - - for (i = 0; i != RTE_DIM(rc); i++) - rc[i] = plock_test(ITER_MAX, i); - - ret = 0; - for (i = 0; i != RTE_DIM(rc); i++) { - printf("%s for utype=%d %s\n", - __func__, i, rc[i] == 0 ? "passed" : "failed"); - ret |= rc[i]; - } - - return ret; -} - -REGISTER_TEST_COMMAND(barrier_autotest, test_barrier); diff --git a/test/test/test_bitmap.c b/test/test/test_bitmap.c deleted file mode 100644 index 95c5184882..0000000000 --- a/test/test/test_bitmap.c +++ /dev/null @@ -1,185 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Cavium, Inc - */ - -#include -#include - -#include -#include -#include - -#include "test.h" - -#define MAX_BITS 1000 - -static int -test_bitmap_scan_operations(struct rte_bitmap *bmp) -{ - uint32_t pos = 0; - uint64_t slab1_magic = 0xBADC0FFEEBADF00D; - uint64_t slab2_magic = 0xFEEDDEADDEADF00D; - uint64_t out_slab = 0; - - rte_bitmap_reset(bmp); - - rte_bitmap_set_slab(bmp, pos, slab1_magic); - rte_bitmap_set_slab(bmp, pos + RTE_BITMAP_SLAB_BIT_SIZE, slab2_magic); - - if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { - printf("Failed to get slab from bitmap.\n"); - return TEST_FAILED; - } - - if (slab1_magic != out_slab) { - printf("Scan operation sanity failed.\n"); - return TEST_FAILED; - } - - if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { - printf("Failed to get slab from bitmap.\n"); - return TEST_FAILED; - } - - if (slab2_magic != out_slab) { - printf("Scan operation sanity failed.\n"); - return TEST_FAILED; - } - - /* Wrap around */ - if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { - printf("Failed to get slab from bitmap.\n"); - return TEST_FAILED; - } - - if (slab1_magic != out_slab) { - printf("Scan operation wrap around failed.\n"); - return TEST_FAILED; - } - - /* Scan reset check. */ - __rte_bitmap_scan_init(bmp); - - if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { - printf("Failed to get slab from bitmap.\n"); - return TEST_FAILED; - } - - if (slab1_magic != out_slab) { - printf("Scan reset operation failed.\n"); - return TEST_FAILED; - } - - return TEST_SUCCESS; -} - -static int -test_bitmap_slab_set_get(struct rte_bitmap *bmp) -{ - uint32_t pos = 0; - uint64_t slab_magic = 0xBADC0FFEEBADF00D; - uint64_t out_slab = 0; - - rte_bitmap_reset(bmp); - rte_bitmap_set_slab(bmp, pos, slab_magic); - - if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { - printf("Failed to get slab from bitmap.\n"); - return TEST_FAILED; - } - - - if (slab_magic != out_slab) { - printf("Invalid slab in bitmap.\n"); - return TEST_FAILED; - } - - - return TEST_SUCCESS; -} - -static int -test_bitmap_set_get_clear(struct rte_bitmap *bmp) -{ - uint64_t val; - int i; - - rte_bitmap_reset(bmp); - for (i = 0; i < MAX_BITS; i++) - rte_bitmap_set(bmp, i); - - for (i = 0; i < MAX_BITS; i++) { - if (!rte_bitmap_get(bmp, i)) { - printf("Failed to get set bit.\n"); - return TEST_FAILED; - } - } - - for (i = 0; i < MAX_BITS; i++) - rte_bitmap_clear(bmp, i); - - for (i = 0; i < MAX_BITS; i++) { - if (rte_bitmap_get(bmp, i)) { - printf("Failed to clear set bit.\n"); - return TEST_FAILED; - } - } - - rte_bitmap_reset(bmp); - - /* Alternate slab set test */ - for (i = 0; i < MAX_BITS; i++) { - if (i % RTE_BITMAP_SLAB_BIT_SIZE) - rte_bitmap_set(bmp, i); - } - - for (i = 0; i < MAX_BITS; i++) { - val = rte_bitmap_get(bmp, i); - if (((i % RTE_BITMAP_SLAB_BIT_SIZE) && !val) || - (!(i % RTE_BITMAP_SLAB_BIT_SIZE) && val)) { - printf("Failed to get set bit.\n"); - return TEST_FAILED; - } - } - - return TEST_SUCCESS; -} - -static int -test_bitmap(void) -{ - void *mem; - uint32_t bmp_size; - struct rte_bitmap *bmp; - - bmp_size = - rte_bitmap_get_memory_footprint(MAX_BITS); - - mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE); - if (mem == NULL) { - printf("Failed to allocate memory for bitmap\n"); - return TEST_FAILED; - } - - bmp = rte_bitmap_init(MAX_BITS, mem, bmp_size); - if (bmp == NULL) { - printf("Failed to init bitmap\n"); - return TEST_FAILED; - } - - if (test_bitmap_set_get_clear(bmp) < 0) - return TEST_FAILED; - - if (test_bitmap_slab_set_get(bmp) < 0) - return TEST_FAILED; - - if (test_bitmap_scan_operations(bmp) < 0) - return TEST_FAILED; - - rte_bitmap_free(bmp); - rte_free(mem); - - return TEST_SUCCESS; -} - -REGISTER_TEST_COMMAND(bitmap_test, test_bitmap); diff --git a/test/test/test_bitratestats.c b/test/test/test_bitratestats.c deleted file mode 100644 index 32b1b0fc0e..0000000000 --- a/test/test/test_bitratestats.c +++ /dev/null @@ -1,226 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "sample_packet_forward.h" -#include "test.h" - -#define BIT_NUM_PACKETS 10 -#define QUEUE_ID 0 - -uint16_t portid; -struct rte_stats_bitrates *bitrate_data; -struct rte_ring *ring; - -/* To test whether rte_stats_bitrate_create is successful */ -static int -test_stats_bitrate_create(void) -{ - bitrate_data = rte_stats_bitrate_create(); - TEST_ASSERT(bitrate_data != NULL, "rte_stats_bitrate_create failed"); - - return TEST_SUCCESS; -} - -/* To test bit rate registration */ -static int -test_stats_bitrate_reg(void) -{ - int ret = 0; - - /* Test to register bit rate without metrics init */ - ret = rte_stats_bitrate_reg(bitrate_data); - TEST_ASSERT(ret < 0, "Test Failed: rte_stats_bitrate_reg succeeded " - "without metrics init, ret:%d", ret); - - /* Metrics initialization */ - rte_metrics_init(rte_socket_id()); - /* Test to register bit rate after metrics init */ - ret = rte_stats_bitrate_reg(bitrate_data); - TEST_ASSERT((ret >= 0), "Test Failed: rte_stats_bitrate_reg %d", ret); - - return TEST_SUCCESS; -} - -/* To test the bit rate registration with invalid pointer */ -static int -test_stats_bitrate_reg_invalidpointer(void) -{ - int ret = 0; - - ret = rte_stats_bitrate_reg(NULL); - TEST_ASSERT(ret < 0, "Test Failed: Expected failure < 0 but " - "got %d", ret); - - return TEST_SUCCESS; -} - -/* To test bit rate calculation with invalid bit rate data pointer */ -static int -test_stats_bitrate_calc_invalid_bitrate_data(void) -{ - int ret = 0; - - ret = rte_stats_bitrate_calc(NULL, portid); - TEST_ASSERT(ret < 0, "Test Failed: rte_stats_bitrate_calc " - "ret:%d", ret); - - return TEST_SUCCESS; -} - -/* To test the bit rate calculation with invalid portid - * (higher than max ports) - */ -static int -test_stats_bitrate_calc_invalid_portid_1(void) -{ - int ret = 0; - - ret = rte_stats_bitrate_calc(bitrate_data, 33); - TEST_ASSERT(ret == -EINVAL, "Test Failed: Expected -%d for higher " - "portid rte_stats_bitrate_calc ret:%d", EINVAL, ret); - - return TEST_SUCCESS; -} - -/* To test the bit rate calculation with invalid portid (lesser than 0) */ -static int -test_stats_bitrate_calc_invalid_portid_2(void) -{ - int ret = 0; - - ret = rte_stats_bitrate_calc(bitrate_data, -1); - TEST_ASSERT(ret == -EINVAL, "Test Failed: Expected -%d for invalid " - "portid rte_stats_bitrate_calc ret:%d", EINVAL, ret); - - return TEST_SUCCESS; -} - -/* To test the bit rate calculation with non-existing portid */ -static int -test_stats_bitrate_calc_non_existing_portid(void) -{ - int ret = 0; - - ret = rte_stats_bitrate_calc(bitrate_data, 31); - TEST_ASSERT(ret == -EINVAL, "Test Failed: Expected -%d for " - "non-existing portid rte_stats_bitrate_calc ret:%d", - EINVAL, ret); - - return TEST_SUCCESS; -} - -/* To test the bit rate calculation with valid bit rate data, valid portid */ -static int -test_stats_bitrate_calc(void) -{ - int ret = 0; - - ret = rte_stats_bitrate_calc(bitrate_data, portid); - TEST_ASSERT(ret >= 0, "Test Failed: Expected >=0 for valid portid " - "rte_stats_bitrate_calc ret:%d", ret); - - return TEST_SUCCESS; -} - -static int -test_bit_packet_forward(void) -{ - int ret; - struct rte_mbuf *pbuf[BIT_NUM_PACKETS] = { }; - struct rte_mempool *mp; - char poolname[] = "mbuf_pool"; - ret = test_get_mbuf_from_pool(&mp, pbuf, poolname); - if (ret < 0) { - printf("allocate mbuf pool Failed\n"); - return TEST_FAILED; - } - ret = test_packet_forward(pbuf, portid, QUEUE_ID); - if (ret < 0) - printf("send pkts Failed\n"); - test_put_mbuf_to_pool(mp, pbuf); - - return TEST_SUCCESS; -} - -static int -test_bit_ring_setup(void) -{ - test_ring_setup(&ring, &portid); - printf("port in ring setup : %d\n", portid); - - return TEST_SUCCESS; -} - -static void -test_bit_ring_free(void) -{ - test_ring_free(ring); - test_vdev_uninit("net_ring_net_ringa"); - rte_memzone_free(rte_memzone_lookup("RTE_METRICS")); -} - -static struct -unit_test_suite bitratestats_testsuite = { - .suite_name = "BitRate Stats Unit Test Suite", - .setup = test_bit_ring_setup, - .teardown = test_bit_ring_free, - .unit_test_cases = { - /* TEST CASE 1: Test to create bit rate data */ - TEST_CASE(test_stats_bitrate_create), - - /* TEST CASE 2: Test to register bit rate metrics - * without metrics init and after metrics init - */ - TEST_CASE(test_stats_bitrate_reg), - - /* TEST CASE 3: Test to register bit rate metrics - * with invalid bit rate data - */ - TEST_CASE(test_stats_bitrate_reg_invalidpointer), - - /* TEST CASE 4: Test to calculate bit rate data metrics - * with invalid bit rate data - */ - TEST_CASE(test_stats_bitrate_calc_invalid_bitrate_data), - - /* TEST CASE 5: Test to calculate bit rate data metrics - * with portid exceeding the max ports - */ - TEST_CASE(test_stats_bitrate_calc_invalid_portid_1), - - /* TEST CASE 6: Test to calculate bit rate data metrics - * with portid less than 0 - */ - TEST_CASE(test_stats_bitrate_calc_invalid_portid_2), - - /* TEST CASE 7: Test to calculate bit rate data metrics - * with non-existing portid - */ - TEST_CASE(test_stats_bitrate_calc_non_existing_portid), - - /* TEST CASE 8: Test to calculate bit rate data metrics - * with valid portid, valid bit rate data - */ - TEST_CASE_ST(test_bit_packet_forward, NULL, - test_stats_bitrate_calc), - TEST_CASES_END() - } -}; - -static int -test_bitratestats(void) -{ - return unit_test_suite_runner(&bitratestats_testsuite); -} -REGISTER_TEST_COMMAND(bitratestats_autotest, test_bitratestats); diff --git a/test/test/test_bpf.c b/test/test/test_bpf.c deleted file mode 100644 index 1d50401aa8..0000000000 --- a/test/test/test_bpf.c +++ /dev/null @@ -1,2034 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* - * Basic functional tests for librte_bpf. - * The main procedure - load eBPF program, execute it and - * compare restuls with expected values. - */ - -struct dummy_offset { - uint64_t u64; - uint32_t u32; - uint16_t u16; - uint8_t u8; -}; - -struct dummy_vect8 { - struct dummy_offset in[8]; - struct dummy_offset out[8]; -}; - -#define TEST_FILL_1 0xDEADBEEF - -#define TEST_MUL_1 21 -#define TEST_MUL_2 -100 - -#define TEST_SHIFT_1 15 -#define TEST_SHIFT_2 33 - -#define TEST_JCC_1 0 -#define TEST_JCC_2 -123 -#define TEST_JCC_3 5678 -#define TEST_JCC_4 TEST_FILL_1 - -#define TEST_IMM_1 UINT64_MAX -#define TEST_IMM_2 ((uint64_t)INT64_MIN) -#define TEST_IMM_3 ((uint64_t)INT64_MAX + INT32_MAX) -#define TEST_IMM_4 ((uint64_t)UINT32_MAX) -#define TEST_IMM_5 ((uint64_t)UINT32_MAX + 1) - -struct bpf_test { - const char *name; - size_t arg_sz; - struct rte_bpf_prm prm; - void (*prepare)(void *); - int (*check_result)(uint64_t, const void *); - uint32_t allow_fail; -}; - -/* - * Compare return value and result data with expected ones. - * Report a failure if they don't match. - */ -static int -cmp_res(const char *func, uint64_t exp_rc, uint64_t ret_rc, - const void *exp_res, const void *ret_res, size_t res_sz) -{ - int32_t ret; - - ret = 0; - if (exp_rc != ret_rc) { - printf("%s@%d: invalid return value, expected: 0x%" PRIx64 - ",result: 0x%" PRIx64 "\n", - func, __LINE__, exp_rc, ret_rc); - ret |= -1; - } - - if (memcmp(exp_res, ret_res, res_sz) != 0) { - printf("%s: invalid value\n", func); - rte_memdump(stdout, "expected", exp_res, res_sz); - rte_memdump(stdout, "result", ret_res, res_sz); - ret |= -1; - } - - return ret; -} - -/* store immediate test-cases */ -static const struct ebpf_insn test_store1_prog[] = { - { - .code = (BPF_ST | BPF_MEM | BPF_B), - .dst_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u8), - .imm = TEST_FILL_1, - }, - { - .code = (BPF_ST | BPF_MEM | BPF_H), - .dst_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u16), - .imm = TEST_FILL_1, - }, - { - .code = (BPF_ST | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u32), - .imm = TEST_FILL_1, - }, - { - .code = (BPF_ST | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u64), - .imm = TEST_FILL_1, - }, - /* return 1 */ - { - .code = (BPF_ALU | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 1, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static void -test_store1_prepare(void *arg) -{ - struct dummy_offset *df; - - df = arg; - memset(df, 0, sizeof(*df)); -} - -static int -test_store1_check(uint64_t rc, const void *arg) -{ - const struct dummy_offset *dft; - struct dummy_offset dfe; - - dft = arg; - - memset(&dfe, 0, sizeof(dfe)); - dfe.u64 = (int32_t)TEST_FILL_1; - dfe.u32 = dfe.u64; - dfe.u16 = dfe.u64; - dfe.u8 = dfe.u64; - - return cmp_res(__func__, 1, rc, &dfe, dft, sizeof(dfe)); -} - -/* store register test-cases */ -static const struct ebpf_insn test_store2_prog[] = { - - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = TEST_FILL_1, - }, - { - .code = (BPF_STX | BPF_MEM | BPF_B), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_offset, u8), - }, - { - .code = (BPF_STX | BPF_MEM | BPF_H), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_offset, u16), - }, - { - .code = (BPF_STX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_offset, u64), - }, - /* return 1 */ - { - .code = (BPF_ALU | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 1, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -/* load test-cases */ -static const struct ebpf_insn test_load1_prog[] = { - - { - .code = (BPF_LDX | BPF_MEM | BPF_B), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u8), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_H), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u16), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u64), - }, - /* return sum */ - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_4, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_3, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_2, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static void -test_load1_prepare(void *arg) -{ - struct dummy_offset *df; - - df = arg; - - memset(df, 0, sizeof(*df)); - df->u64 = (int32_t)TEST_FILL_1; - df->u32 = df->u64; - df->u16 = df->u64; - df->u8 = df->u64; -} - -static int -test_load1_check(uint64_t rc, const void *arg) -{ - uint64_t v; - const struct dummy_offset *dft; - - dft = arg; - v = dft->u64; - v += dft->u32; - v += dft->u16; - v += dft->u8; - - return cmp_res(__func__, v, rc, dft, dft, sizeof(*dft)); -} - -/* load immediate test-cases */ -static const struct ebpf_insn test_ldimm1_prog[] = { - - { - .code = (BPF_LD | BPF_IMM | EBPF_DW), - .dst_reg = EBPF_REG_0, - .imm = (uint32_t)TEST_IMM_1, - }, - { - .imm = TEST_IMM_1 >> 32, - }, - { - .code = (BPF_LD | BPF_IMM | EBPF_DW), - .dst_reg = EBPF_REG_3, - .imm = (uint32_t)TEST_IMM_2, - }, - { - .imm = TEST_IMM_2 >> 32, - }, - { - .code = (BPF_LD | BPF_IMM | EBPF_DW), - .dst_reg = EBPF_REG_5, - .imm = (uint32_t)TEST_IMM_3, - }, - { - .imm = TEST_IMM_3 >> 32, - }, - { - .code = (BPF_LD | BPF_IMM | EBPF_DW), - .dst_reg = EBPF_REG_7, - .imm = (uint32_t)TEST_IMM_4, - }, - { - .imm = TEST_IMM_4 >> 32, - }, - { - .code = (BPF_LD | BPF_IMM | EBPF_DW), - .dst_reg = EBPF_REG_9, - .imm = (uint32_t)TEST_IMM_5, - }, - { - .imm = TEST_IMM_5 >> 32, - }, - /* return sum */ - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_3, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_5, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_7, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_9, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static int -test_ldimm1_check(uint64_t rc, const void *arg) -{ - uint64_t v1, v2; - - v1 = TEST_IMM_1; - v2 = TEST_IMM_2; - v1 += v2; - v2 = TEST_IMM_3; - v1 += v2; - v2 = TEST_IMM_4; - v1 += v2; - v2 = TEST_IMM_5; - v1 += v2; - - return cmp_res(__func__, v1, rc, arg, arg, 0); -} - - -/* alu mul test-cases */ -static const struct ebpf_insn test_mul1_prog[] = { - - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[1].u64), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[2].u32), - }, - { - .code = (BPF_ALU | BPF_MUL | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = TEST_MUL_1, - }, - { - .code = (EBPF_ALU64 | BPF_MUL | BPF_K), - .dst_reg = EBPF_REG_3, - .imm = TEST_MUL_2, - }, - { - .code = (BPF_ALU | BPF_MUL | BPF_X), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_2, - }, - { - .code = (EBPF_ALU64 | BPF_MUL | BPF_X), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_3, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_vect8, out[0].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[1].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_vect8, out[2].u64), - }, - /* return 1 */ - { - .code = (BPF_ALU | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 1, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static void -test_mul1_prepare(void *arg) -{ - struct dummy_vect8 *dv; - uint64_t v; - - dv = arg; - - v = rte_rand(); - - memset(dv, 0, sizeof(*dv)); - dv->in[0].u32 = v; - dv->in[1].u64 = v << 12 | v >> 6; - dv->in[2].u32 = -v; -} - -static int -test_mul1_check(uint64_t rc, const void *arg) -{ - uint64_t r2, r3, r4; - const struct dummy_vect8 *dvt; - struct dummy_vect8 dve; - - dvt = arg; - memset(&dve, 0, sizeof(dve)); - - r2 = dvt->in[0].u32; - r3 = dvt->in[1].u64; - r4 = dvt->in[2].u32; - - r2 = (uint32_t)r2 * TEST_MUL_1; - r3 *= TEST_MUL_2; - r4 = (uint32_t)(r4 * r2); - r4 *= r3; - - dve.out[0].u64 = r2; - dve.out[1].u64 = r3; - dve.out[2].u64 = r4; - - return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); -} - -/* alu shift test-cases */ -static const struct ebpf_insn test_shift1_prog[] = { - - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[1].u64), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[2].u32), - }, - { - .code = (BPF_ALU | BPF_LSH | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = TEST_SHIFT_1, - }, - { - .code = (EBPF_ALU64 | EBPF_ARSH | BPF_K), - .dst_reg = EBPF_REG_3, - .imm = TEST_SHIFT_2, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_vect8, out[0].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[1].u64), - }, - { - .code = (BPF_ALU | BPF_RSH | BPF_X), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_4, - }, - { - .code = (EBPF_ALU64 | BPF_LSH | BPF_X), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_4, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_vect8, out[2].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[3].u64), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[1].u64), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[2].u32), - }, - { - .code = (BPF_ALU | BPF_AND | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = sizeof(uint64_t) * CHAR_BIT - 1, - }, - { - .code = (EBPF_ALU64 | EBPF_ARSH | BPF_X), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_2, - }, - { - .code = (BPF_ALU | BPF_AND | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = sizeof(uint32_t) * CHAR_BIT - 1, - }, - { - .code = (BPF_ALU | BPF_LSH | BPF_X), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_2, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_vect8, out[4].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[5].u64), - }, - /* return 1 */ - { - .code = (BPF_ALU | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 1, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static void -test_shift1_prepare(void *arg) -{ - struct dummy_vect8 *dv; - uint64_t v; - - dv = arg; - - v = rte_rand(); - - memset(dv, 0, sizeof(*dv)); - dv->in[0].u32 = v; - dv->in[1].u64 = v << 12 | v >> 6; - dv->in[2].u32 = (-v ^ 5); -} - -static int -test_shift1_check(uint64_t rc, const void *arg) -{ - uint64_t r2, r3, r4; - const struct dummy_vect8 *dvt; - struct dummy_vect8 dve; - - dvt = arg; - memset(&dve, 0, sizeof(dve)); - - r2 = dvt->in[0].u32; - r3 = dvt->in[1].u64; - r4 = dvt->in[2].u32; - - r2 = (uint32_t)r2 << TEST_SHIFT_1; - r3 = (int64_t)r3 >> TEST_SHIFT_2; - - dve.out[0].u64 = r2; - dve.out[1].u64 = r3; - - r2 = (uint32_t)r2 >> r4; - r3 <<= r4; - - dve.out[2].u64 = r2; - dve.out[3].u64 = r3; - - r2 = dvt->in[0].u32; - r3 = dvt->in[1].u64; - r4 = dvt->in[2].u32; - - r2 &= sizeof(uint64_t) * CHAR_BIT - 1; - r3 = (int64_t)r3 >> r2; - r2 &= sizeof(uint32_t) * CHAR_BIT - 1; - r4 = (uint32_t)r4 << r2; - - dve.out[4].u64 = r4; - dve.out[5].u64 = r3; - - return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); -} - -/* jmp test-cases */ -static const struct ebpf_insn test_jump1_prog[] = { - - [0] = { - .code = (BPF_ALU | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0, - }, - [1] = { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u32), - }, - [2] = { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u64), - }, - [3] = { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[1].u32), - }, - [4] = { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_5, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[1].u64), - }, - [5] = { - .code = (BPF_JMP | BPF_JEQ | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = TEST_JCC_1, - .off = 8, - }, - [6] = { - .code = (BPF_JMP | EBPF_JSLE | BPF_K), - .dst_reg = EBPF_REG_3, - .imm = TEST_JCC_2, - .off = 9, - }, - [7] = { - .code = (BPF_JMP | BPF_JGT | BPF_K), - .dst_reg = EBPF_REG_4, - .imm = TEST_JCC_3, - .off = 10, - }, - [8] = { - .code = (BPF_JMP | BPF_JSET | BPF_K), - .dst_reg = EBPF_REG_5, - .imm = TEST_JCC_4, - .off = 11, - }, - [9] = { - .code = (BPF_JMP | EBPF_JNE | BPF_X), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_3, - .off = 12, - }, - [10] = { - .code = (BPF_JMP | EBPF_JSGT | BPF_X), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_4, - .off = 13, - }, - [11] = { - .code = (BPF_JMP | EBPF_JLE | BPF_X), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_5, - .off = 14, - }, - [12] = { - .code = (BPF_JMP | BPF_JSET | BPF_X), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_5, - .off = 15, - }, - [13] = { - .code = (BPF_JMP | EBPF_EXIT), - }, - [14] = { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0x1, - }, - [15] = { - .code = (BPF_JMP | BPF_JA), - .off = -10, - }, - [16] = { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0x2, - }, - [17] = { - .code = (BPF_JMP | BPF_JA), - .off = -11, - }, - [18] = { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0x4, - }, - [19] = { - .code = (BPF_JMP | BPF_JA), - .off = -12, - }, - [20] = { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0x8, - }, - [21] = { - .code = (BPF_JMP | BPF_JA), - .off = -13, - }, - [22] = { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0x10, - }, - [23] = { - .code = (BPF_JMP | BPF_JA), - .off = -14, - }, - [24] = { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0x20, - }, - [25] = { - .code = (BPF_JMP | BPF_JA), - .off = -15, - }, - [26] = { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0x40, - }, - [27] = { - .code = (BPF_JMP | BPF_JA), - .off = -16, - }, - [28] = { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 0x80, - }, - [29] = { - .code = (BPF_JMP | BPF_JA), - .off = -17, - }, -}; - -static void -test_jump1_prepare(void *arg) -{ - struct dummy_vect8 *dv; - uint64_t v1, v2; - - dv = arg; - - v1 = rte_rand(); - v2 = rte_rand(); - - memset(dv, 0, sizeof(*dv)); - dv->in[0].u64 = v1; - dv->in[1].u64 = v2; - dv->in[0].u32 = (v1 << 12) + (v2 >> 6); - dv->in[1].u32 = (v2 << 12) - (v1 >> 6); -} - -static int -test_jump1_check(uint64_t rc, const void *arg) -{ - uint64_t r2, r3, r4, r5, rv; - const struct dummy_vect8 *dvt; - - dvt = arg; - - rv = 0; - r2 = dvt->in[0].u32; - r3 = dvt->in[0].u64; - r4 = dvt->in[1].u32; - r5 = dvt->in[1].u64; - - if (r2 == TEST_JCC_1) - rv |= 0x1; - if ((int64_t)r3 <= TEST_JCC_2) - rv |= 0x2; - if (r4 > TEST_JCC_3) - rv |= 0x4; - if (r5 & TEST_JCC_4) - rv |= 0x8; - if (r2 != r3) - rv |= 0x10; - if ((int64_t)r2 > (int64_t)r4) - rv |= 0x20; - if (r2 <= r5) - rv |= 0x40; - if (r3 & r5) - rv |= 0x80; - - return cmp_res(__func__, rv, rc, &rv, &rc, sizeof(rv)); -} - -/* alu (add, sub, and, or, xor, neg) test-cases */ -static const struct ebpf_insn test_alu1_prog[] = { - - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u64), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[1].u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_5, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[1].u64), - }, - { - .code = (BPF_ALU | BPF_AND | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = TEST_FILL_1, - }, - { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_3, - .imm = TEST_FILL_1, - }, - { - .code = (BPF_ALU | BPF_XOR | BPF_K), - .dst_reg = EBPF_REG_4, - .imm = TEST_FILL_1, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_K), - .dst_reg = EBPF_REG_5, - .imm = TEST_FILL_1, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_vect8, out[0].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[1].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_vect8, out[2].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_5, - .off = offsetof(struct dummy_vect8, out[3].u64), - }, - { - .code = (BPF_ALU | BPF_OR | BPF_X), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_3, - }, - { - .code = (EBPF_ALU64 | BPF_XOR | BPF_X), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_4, - }, - { - .code = (BPF_ALU | BPF_SUB | BPF_X), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_5, - }, - { - .code = (EBPF_ALU64 | BPF_AND | BPF_X), - .dst_reg = EBPF_REG_5, - .src_reg = EBPF_REG_2, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_vect8, out[4].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[5].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_vect8, out[6].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_5, - .off = offsetof(struct dummy_vect8, out[7].u64), - }, - /* return (-r2 + (-r3)) */ - { - .code = (BPF_ALU | BPF_NEG), - .dst_reg = EBPF_REG_2, - }, - { - .code = (EBPF_ALU64 | BPF_NEG), - .dst_reg = EBPF_REG_3, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_3, - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_2, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static int -test_alu1_check(uint64_t rc, const void *arg) -{ - uint64_t r2, r3, r4, r5, rv; - const struct dummy_vect8 *dvt; - struct dummy_vect8 dve; - - dvt = arg; - memset(&dve, 0, sizeof(dve)); - - r2 = dvt->in[0].u32; - r3 = dvt->in[0].u64; - r4 = dvt->in[1].u32; - r5 = dvt->in[1].u64; - - r2 = (uint32_t)r2 & TEST_FILL_1; - r3 |= (int32_t) TEST_FILL_1; - r4 = (uint32_t)r4 ^ TEST_FILL_1; - r5 += (int32_t)TEST_FILL_1; - - dve.out[0].u64 = r2; - dve.out[1].u64 = r3; - dve.out[2].u64 = r4; - dve.out[3].u64 = r5; - - r2 = (uint32_t)r2 | (uint32_t)r3; - r3 ^= r4; - r4 = (uint32_t)r4 - (uint32_t)r5; - r5 &= r2; - - dve.out[4].u64 = r2; - dve.out[5].u64 = r3; - dve.out[6].u64 = r4; - dve.out[7].u64 = r5; - - r2 = -(int32_t)r2; - rv = (uint32_t)r2; - r3 = -r3; - rv += r3; - - return cmp_res(__func__, rv, rc, dve.out, dvt->out, sizeof(dve.out)); -} - -/* endianness conversions (BE->LE/LE->BE) test-cases */ -static const struct ebpf_insn test_bele1_prog[] = { - - { - .code = (BPF_LDX | BPF_MEM | BPF_H), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u16), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u64), - }, - { - .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), - .dst_reg = EBPF_REG_2, - .imm = sizeof(uint16_t) * CHAR_BIT, - }, - { - .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), - .dst_reg = EBPF_REG_3, - .imm = sizeof(uint32_t) * CHAR_BIT, - }, - { - .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), - .dst_reg = EBPF_REG_4, - .imm = sizeof(uint64_t) * CHAR_BIT, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_vect8, out[0].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[1].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_vect8, out[2].u64), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_H), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u16), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u64), - }, - { - .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), - .dst_reg = EBPF_REG_2, - .imm = sizeof(uint16_t) * CHAR_BIT, - }, - { - .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), - .dst_reg = EBPF_REG_3, - .imm = sizeof(uint32_t) * CHAR_BIT, - }, - { - .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), - .dst_reg = EBPF_REG_4, - .imm = sizeof(uint64_t) * CHAR_BIT, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_vect8, out[3].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[4].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_vect8, out[5].u64), - }, - /* return 1 */ - { - .code = (BPF_ALU | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 1, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static void -test_bele1_prepare(void *arg) -{ - struct dummy_vect8 *dv; - - dv = arg; - - memset(dv, 0, sizeof(*dv)); - dv->in[0].u64 = rte_rand(); - dv->in[0].u32 = dv->in[0].u64; - dv->in[0].u16 = dv->in[0].u64; -} - -static int -test_bele1_check(uint64_t rc, const void *arg) -{ - uint64_t r2, r3, r4; - const struct dummy_vect8 *dvt; - struct dummy_vect8 dve; - - dvt = arg; - memset(&dve, 0, sizeof(dve)); - - r2 = dvt->in[0].u16; - r3 = dvt->in[0].u32; - r4 = dvt->in[0].u64; - - r2 = rte_cpu_to_be_16(r2); - r3 = rte_cpu_to_be_32(r3); - r4 = rte_cpu_to_be_64(r4); - - dve.out[0].u64 = r2; - dve.out[1].u64 = r3; - dve.out[2].u64 = r4; - - r2 = dvt->in[0].u16; - r3 = dvt->in[0].u32; - r4 = dvt->in[0].u64; - - r2 = rte_cpu_to_le_16(r2); - r3 = rte_cpu_to_le_32(r3); - r4 = rte_cpu_to_le_64(r4); - - dve.out[3].u64 = r2; - dve.out[4].u64 = r3; - dve.out[5].u64 = r4; - - return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); -} - -/* atomic add test-cases */ -static const struct ebpf_insn test_xadd1_prog[] = { - - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = 1, - }, - { - .code = (BPF_STX | EBPF_XADD | BPF_W), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_STX | EBPF_XADD | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_offset, u64), - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_3, - .imm = -1, - }, - { - .code = (BPF_STX | EBPF_XADD | BPF_W), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_STX | EBPF_XADD | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_offset, u64), - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_4, - .imm = TEST_FILL_1, - }, - { - .code = (BPF_STX | EBPF_XADD | BPF_W), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_STX | EBPF_XADD | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_offset, u64), - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_5, - .imm = TEST_MUL_1, - }, - { - .code = (BPF_STX | EBPF_XADD | BPF_W), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_5, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_STX | EBPF_XADD | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_5, - .off = offsetof(struct dummy_offset, u64), - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_6, - .imm = TEST_MUL_2, - }, - { - .code = (BPF_STX | EBPF_XADD | BPF_W), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_6, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_STX | EBPF_XADD | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_6, - .off = offsetof(struct dummy_offset, u64), - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_7, - .imm = TEST_JCC_2, - }, - { - .code = (BPF_STX | EBPF_XADD | BPF_W), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_7, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_STX | EBPF_XADD | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_7, - .off = offsetof(struct dummy_offset, u64), - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_8, - .imm = TEST_JCC_3, - }, - { - .code = (BPF_STX | EBPF_XADD | BPF_W), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_8, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_STX | EBPF_XADD | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_8, - .off = offsetof(struct dummy_offset, u64), - }, - /* return 1 */ - { - .code = (BPF_ALU | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 1, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static int -test_xadd1_check(uint64_t rc, const void *arg) -{ - uint64_t rv; - const struct dummy_offset *dft; - struct dummy_offset dfe; - - dft = arg; - memset(&dfe, 0, sizeof(dfe)); - - rv = 1; - rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); - rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); - - rv = -1; - rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); - rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); - - rv = (int32_t)TEST_FILL_1; - rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); - rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); - - rv = TEST_MUL_1; - rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); - rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); - - rv = TEST_MUL_2; - rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); - rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); - - rv = TEST_JCC_2; - rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); - rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); - - rv = TEST_JCC_3; - rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv); - rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv); - - return cmp_res(__func__, 1, rc, &dfe, dft, sizeof(dfe)); -} - -/* alu div test-cases */ -static const struct ebpf_insn test_div1_prog[] = { - - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[0].u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[1].u64), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[2].u32), - }, - { - .code = (BPF_ALU | BPF_DIV | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = TEST_MUL_1, - }, - { - .code = (EBPF_ALU64 | BPF_MOD | BPF_K), - .dst_reg = EBPF_REG_3, - .imm = TEST_MUL_2, - }, - { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = 1, - }, - { - .code = (EBPF_ALU64 | BPF_OR | BPF_K), - .dst_reg = EBPF_REG_3, - .imm = 1, - }, - { - .code = (BPF_ALU | BPF_MOD | BPF_X), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_2, - }, - { - .code = (EBPF_ALU64 | BPF_DIV | BPF_X), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_3, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_2, - .off = offsetof(struct dummy_vect8, out[0].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_3, - .off = offsetof(struct dummy_vect8, out[1].u64), - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_4, - .off = offsetof(struct dummy_vect8, out[2].u64), - }, - /* check that we can handle division by zero gracefully. */ - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_vect8, in[3].u32), - }, - { - .code = (BPF_ALU | BPF_DIV | BPF_X), - .dst_reg = EBPF_REG_4, - .src_reg = EBPF_REG_2, - }, - /* return 1 */ - { - .code = (BPF_ALU | EBPF_MOV | BPF_K), - .dst_reg = EBPF_REG_0, - .imm = 1, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static int -test_div1_check(uint64_t rc, const void *arg) -{ - uint64_t r2, r3, r4; - const struct dummy_vect8 *dvt; - struct dummy_vect8 dve; - - dvt = arg; - memset(&dve, 0, sizeof(dve)); - - r2 = dvt->in[0].u32; - r3 = dvt->in[1].u64; - r4 = dvt->in[2].u32; - - r2 = (uint32_t)r2 / TEST_MUL_1; - r3 %= TEST_MUL_2; - r2 |= 1; - r3 |= 1; - r4 = (uint32_t)(r4 % r2); - r4 /= r3; - - dve.out[0].u64 = r2; - dve.out[1].u64 = r3; - dve.out[2].u64 = r4; - - /* - * in the test prog we attempted to divide by zero. - * so return value should return 0. - */ - return cmp_res(__func__, 0, rc, dve.out, dvt->out, sizeof(dve.out)); -} - -/* call test-cases */ -static const struct ebpf_insn test_call1_prog[] = { - - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u32), - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_1, - .off = offsetof(struct dummy_offset, u64), - }, - { - .code = (BPF_STX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_10, - .src_reg = EBPF_REG_2, - .off = -4, - }, - { - .code = (BPF_STX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_10, - .src_reg = EBPF_REG_3, - .off = -16, - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_10, - }, - { - .code = (EBPF_ALU64 | BPF_SUB | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = 4, - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), - .dst_reg = EBPF_REG_3, - .src_reg = EBPF_REG_10, - }, - { - .code = (EBPF_ALU64 | BPF_SUB | BPF_K), - .dst_reg = EBPF_REG_3, - .imm = 16, - }, - { - .code = (BPF_JMP | EBPF_CALL), - .imm = 0, - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_10, - .off = -4, - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_10, - .off = -16 - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_2, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, -}; - -static void -dummy_func1(const void *p, uint32_t *v32, uint64_t *v64) -{ - const struct dummy_offset *dv; - - dv = p; - - v32[0] += dv->u16; - v64[0] += dv->u8; -} - -static int -test_call1_check(uint64_t rc, const void *arg) -{ - uint32_t v32; - uint64_t v64; - const struct dummy_offset *dv; - - dv = arg; - - v32 = dv->u32; - v64 = dv->u64; - dummy_func1(arg, &v32, &v64); - v64 += v32; - - if (v64 != rc) { - printf("%s@%d: invalid return value " - "expected=0x%" PRIx64 ", actual=0x%" PRIx64 "\n", - __func__, __LINE__, v64, rc); - return -1; - } - return 0; - return cmp_res(__func__, v64, rc, dv, dv, sizeof(*dv)); -} - -static const struct rte_bpf_xsym test_call1_xsym[] = { - { - .name = RTE_STR(dummy_func1), - .type = RTE_BPF_XTYPE_FUNC, - .func = { - .val = (void *)dummy_func1, - .nb_args = 3, - .args = { - [0] = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - [1] = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(uint32_t), - }, - [2] = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(uint64_t), - }, - }, - }, - }, -}; - -static const struct ebpf_insn test_call2_prog[] = { - - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_10, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_K), - .dst_reg = EBPF_REG_1, - .imm = -(int32_t)sizeof(struct dummy_offset), - }, - { - .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), - .dst_reg = EBPF_REG_2, - .src_reg = EBPF_REG_10, - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_K), - .dst_reg = EBPF_REG_2, - .imm = -2 * (int32_t)sizeof(struct dummy_offset), - }, - { - .code = (BPF_JMP | EBPF_CALL), - .imm = 0, - }, - { - .code = (BPF_LDX | BPF_MEM | EBPF_DW), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_10, - .off = -(int32_t)(sizeof(struct dummy_offset) - - offsetof(struct dummy_offset, u64)), - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_W), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_10, - .off = -(int32_t)(sizeof(struct dummy_offset) - - offsetof(struct dummy_offset, u32)), - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_1, - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_H), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_10, - .off = -(int32_t)(2 * sizeof(struct dummy_offset) - - offsetof(struct dummy_offset, u16)), - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_1, - }, - { - .code = (BPF_LDX | BPF_MEM | BPF_B), - .dst_reg = EBPF_REG_1, - .src_reg = EBPF_REG_10, - .off = -(int32_t)(2 * sizeof(struct dummy_offset) - - offsetof(struct dummy_offset, u8)), - }, - { - .code = (EBPF_ALU64 | BPF_ADD | BPF_X), - .dst_reg = EBPF_REG_0, - .src_reg = EBPF_REG_1, - }, - { - .code = (BPF_JMP | EBPF_EXIT), - }, - -}; - -static void -dummy_func2(struct dummy_offset *a, struct dummy_offset *b) -{ - uint64_t v; - - v = 0; - a->u64 = v++; - a->u32 = v++; - a->u16 = v++; - a->u8 = v++; - b->u64 = v++; - b->u32 = v++; - b->u16 = v++; - b->u8 = v++; -} - -static int -test_call2_check(uint64_t rc, const void *arg) -{ - uint64_t v; - struct dummy_offset a, b; - - RTE_SET_USED(arg); - - dummy_func2(&a, &b); - v = a.u64 + a.u32 + b.u16 + b.u8; - - if (v != rc) { - printf("%s@%d: invalid return value " - "expected=0x%" PRIx64 ", actual=0x%" PRIx64 "\n", - __func__, __LINE__, v, rc); - return -1; - } - return 0; -} - -static const struct rte_bpf_xsym test_call2_xsym[] = { - { - .name = RTE_STR(dummy_func2), - .type = RTE_BPF_XTYPE_FUNC, - .func = { - .val = (void *)dummy_func2, - .nb_args = 2, - .args = { - [0] = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - [1] = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - }, - }, - }, -}; - -static const struct bpf_test tests[] = { - { - .name = "test_store1", - .arg_sz = sizeof(struct dummy_offset), - .prm = { - .ins = test_store1_prog, - .nb_ins = RTE_DIM(test_store1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - }, - .prepare = test_store1_prepare, - .check_result = test_store1_check, - }, - { - .name = "test_store2", - .arg_sz = sizeof(struct dummy_offset), - .prm = { - .ins = test_store2_prog, - .nb_ins = RTE_DIM(test_store2_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - }, - .prepare = test_store1_prepare, - .check_result = test_store1_check, - }, - { - .name = "test_load1", - .arg_sz = sizeof(struct dummy_offset), - .prm = { - .ins = test_load1_prog, - .nb_ins = RTE_DIM(test_load1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - }, - .prepare = test_load1_prepare, - .check_result = test_load1_check, - }, - { - .name = "test_ldimm1", - .arg_sz = sizeof(struct dummy_offset), - .prm = { - .ins = test_ldimm1_prog, - .nb_ins = RTE_DIM(test_ldimm1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - }, - .prepare = test_store1_prepare, - .check_result = test_ldimm1_check, - }, - { - .name = "test_mul1", - .arg_sz = sizeof(struct dummy_vect8), - .prm = { - .ins = test_mul1_prog, - .nb_ins = RTE_DIM(test_mul1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_vect8), - }, - }, - .prepare = test_mul1_prepare, - .check_result = test_mul1_check, - }, - { - .name = "test_shift1", - .arg_sz = sizeof(struct dummy_vect8), - .prm = { - .ins = test_shift1_prog, - .nb_ins = RTE_DIM(test_shift1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_vect8), - }, - }, - .prepare = test_shift1_prepare, - .check_result = test_shift1_check, - }, - { - .name = "test_jump1", - .arg_sz = sizeof(struct dummy_vect8), - .prm = { - .ins = test_jump1_prog, - .nb_ins = RTE_DIM(test_jump1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_vect8), - }, - }, - .prepare = test_jump1_prepare, - .check_result = test_jump1_check, - }, - { - .name = "test_alu1", - .arg_sz = sizeof(struct dummy_vect8), - .prm = { - .ins = test_alu1_prog, - .nb_ins = RTE_DIM(test_alu1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_vect8), - }, - }, - .prepare = test_jump1_prepare, - .check_result = test_alu1_check, - }, - { - .name = "test_bele1", - .arg_sz = sizeof(struct dummy_vect8), - .prm = { - .ins = test_bele1_prog, - .nb_ins = RTE_DIM(test_bele1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_vect8), - }, - }, - .prepare = test_bele1_prepare, - .check_result = test_bele1_check, - }, - { - .name = "test_xadd1", - .arg_sz = sizeof(struct dummy_offset), - .prm = { - .ins = test_xadd1_prog, - .nb_ins = RTE_DIM(test_xadd1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - }, - .prepare = test_store1_prepare, - .check_result = test_xadd1_check, - }, - { - .name = "test_div1", - .arg_sz = sizeof(struct dummy_vect8), - .prm = { - .ins = test_div1_prog, - .nb_ins = RTE_DIM(test_div1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_vect8), - }, - }, - .prepare = test_mul1_prepare, - .check_result = test_div1_check, - }, - { - .name = "test_call1", - .arg_sz = sizeof(struct dummy_offset), - .prm = { - .ins = test_call1_prog, - .nb_ins = RTE_DIM(test_call1_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - .xsym = test_call1_xsym, - .nb_xsym = RTE_DIM(test_call1_xsym), - }, - .prepare = test_load1_prepare, - .check_result = test_call1_check, - /* for now don't support function calls on 32 bit platform */ - .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), - }, - { - .name = "test_call2", - .arg_sz = sizeof(struct dummy_offset), - .prm = { - .ins = test_call2_prog, - .nb_ins = RTE_DIM(test_call2_prog), - .prog_arg = { - .type = RTE_BPF_ARG_PTR, - .size = sizeof(struct dummy_offset), - }, - .xsym = test_call2_xsym, - .nb_xsym = RTE_DIM(test_call2_xsym), - }, - .prepare = test_store1_prepare, - .check_result = test_call2_check, - /* for now don't support function calls on 32 bit platform */ - .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), - }, -}; - -static int -run_test(const struct bpf_test *tst) -{ - int32_t ret, rv; - int64_t rc; - struct rte_bpf *bpf; - struct rte_bpf_jit jit; - uint8_t tbuf[tst->arg_sz]; - - printf("%s(%s) start\n", __func__, tst->name); - - bpf = rte_bpf_load(&tst->prm); - if (bpf == NULL) { - printf("%s@%d: failed to load bpf code, error=%d(%s);\n", - __func__, __LINE__, rte_errno, strerror(rte_errno)); - return -1; - } - - tst->prepare(tbuf); - - rc = rte_bpf_exec(bpf, tbuf); - ret = tst->check_result(rc, tbuf); - if (ret != 0) { - printf("%s@%d: check_result(%s) failed, error: %d(%s);\n", - __func__, __LINE__, tst->name, ret, strerror(ret)); - } - - rte_bpf_get_jit(bpf, &jit); - if (jit.func == NULL) - return 0; - - tst->prepare(tbuf); - rc = jit.func(tbuf); - rv = tst->check_result(rc, tbuf); - ret |= rv; - if (rv != 0) { - printf("%s@%d: check_result(%s) failed, error: %d(%s);\n", - __func__, __LINE__, tst->name, rv, strerror(ret)); - } - - rte_bpf_destroy(bpf); - return ret; - -} - -static int -test_bpf(void) -{ - int32_t rc, rv; - uint32_t i; - - rc = 0; - for (i = 0; i != RTE_DIM(tests); i++) { - rv = run_test(tests + i); - if (tests[i].allow_fail == 0) - rc |= rv; - } - - return rc; -} - -REGISTER_TEST_COMMAND(bpf_autotest, test_bpf); diff --git a/test/test/test_byteorder.c b/test/test/test_byteorder.c deleted file mode 100644 index 03c08d9abf..0000000000 --- a/test/test/test_byteorder.c +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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_cfgfile.c b/test/test/test_cfgfile.c deleted file mode 100644 index 37435b395a..0000000000 --- a/test/test/test_cfgfile.c +++ /dev/null @@ -1,362 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2017 Wind River Systems Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (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 "resource.h" - - -#define CFG_FILES_ETC "test_cfgfiles/etc" - -REGISTER_LINKED_RESOURCE(test_cfgfiles); - -static int -test_cfgfile_setup(void) -{ - const struct resource *r; - int ret; - - r = resource_find("test_cfgfiles"); - TEST_ASSERT_NOT_NULL(r, "missing resource test_cfgfiles"); - - ret = resource_untar(r); - TEST_ASSERT_SUCCESS(ret, "failed to untar %s", r->name); - - return 0; -} - -static int -test_cfgfile_cleanup(void) -{ - const struct resource *r; - int ret; - - r = resource_find("test_cfgfiles"); - TEST_ASSERT_NOT_NULL(r, "missing resource test_cfgfiles"); - - ret = resource_rm_by_tar(r); - TEST_ASSERT_SUCCESS(ret, "Failed to delete resource %s", r->name); - - return 0; -} - -static int -_test_cfgfile_sample(struct rte_cfgfile *cfgfile) -{ - const char *value; - int ret; - - ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); - TEST_ASSERT(ret == 2, "Unexpected number of sections: %d", ret); - - ret = rte_cfgfile_has_section(cfgfile, "section1"); - TEST_ASSERT(ret, "section1 section missing"); - - ret = rte_cfgfile_section_num_entries(cfgfile, "section1"); - TEST_ASSERT(ret == 1, "section1 unexpected number of entries: %d", ret); - - value = rte_cfgfile_get_entry(cfgfile, "section1", "key1"); - TEST_ASSERT(strcmp("value1", value) == 0, - "key1 unexpected value: %s", value); - - ret = rte_cfgfile_has_section(cfgfile, "section2"); - TEST_ASSERT(ret, "section2 section missing"); - - ret = rte_cfgfile_section_num_entries(cfgfile, "section2"); - TEST_ASSERT(ret == 2, "section2 unexpected number of entries: %d", ret); - - value = rte_cfgfile_get_entry(cfgfile, "section2", "key2"); - TEST_ASSERT(strcmp("value2", value) == 0, - "key2 unexpected value: %s", value); - - value = rte_cfgfile_get_entry(cfgfile, "section2", "key3"); - TEST_ASSERT(strcmp("value3", value) == 0, - "key3 unexpected value: %s", value); - - return 0; -} - -static int -test_cfgfile_sample1(void) -{ - struct rte_cfgfile *cfgfile; - int ret; - - cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/sample1.ini", 0); - TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file"); - - ret = _test_cfgfile_sample(cfgfile); - TEST_ASSERT_SUCCESS(ret, "Failed to validate sample file: %d", ret); - - ret = rte_cfgfile_close(cfgfile); - TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); - - return 0; -} - -static int -test_cfgfile_sample2(void) -{ - struct rte_cfgfile_parameters params; - struct rte_cfgfile *cfgfile; - int ret; - - /* override comment character */ - memset(¶ms, 0, sizeof(params)); - params.comment_character = '#'; - - cfgfile = rte_cfgfile_load_with_params(CFG_FILES_ETC "/sample2.ini", 0, - ¶ms); - TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse sample2.ini"); - - ret = _test_cfgfile_sample(cfgfile); - TEST_ASSERT_SUCCESS(ret, "Failed to validate sample file: %d", ret); - - ret = rte_cfgfile_close(cfgfile); - TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); - - return 0; -} - -static int -test_cfgfile_realloc_sections(void) -{ - struct rte_cfgfile *cfgfile; - int ret; - const char *value; - - cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/realloc_sections.ini", 0); - TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file"); - - ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); - TEST_ASSERT(ret == 9, "Unexpected number of sections: %d", ret); - - ret = rte_cfgfile_has_section(cfgfile, "section9"); - TEST_ASSERT(ret, "section9 missing"); - - ret = rte_cfgfile_section_num_entries(cfgfile, "section3"); - TEST_ASSERT(ret == 21, - "section3 unexpected number of entries: %d", ret); - - ret = rte_cfgfile_section_num_entries(cfgfile, "section9"); - TEST_ASSERT(ret == 8, "section9 unexpected number of entries: %d", ret); - - value = rte_cfgfile_get_entry(cfgfile, "section9", "key8"); - TEST_ASSERT(strcmp("value8_section9", value) == 0, - "key unexpected value: %s", value); - - ret = rte_cfgfile_save(cfgfile, "/tmp/cfgfile_save.ini"); - TEST_ASSERT_SUCCESS(ret, "Failed to save *.ini file"); - remove("/tmp/cfgfile_save.ini"); - - ret = rte_cfgfile_close(cfgfile); - TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); - - return 0; -} - -static int -test_cfgfile_invalid_section_header(void) -{ - struct rte_cfgfile *cfgfile; - - cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/invalid_section.ini", 0); - TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); - - return 0; -} - -static int -test_cfgfile_invalid_comment(void) -{ - struct rte_cfgfile_parameters params; - struct rte_cfgfile *cfgfile; - - /* override comment character with an invalid one */ - memset(¶ms, 0, sizeof(params)); - params.comment_character = '$'; - - cfgfile = rte_cfgfile_load_with_params(CFG_FILES_ETC "/sample2.ini", 0, - ¶ms); - TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); - - return 0; -} - -static int -test_cfgfile_invalid_key_value_pair(void) -{ - struct rte_cfgfile *cfgfile; - - cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty_key_value.ini", 0); - TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); - - return 0; -} - -static int -test_cfgfile_empty_key_value_pair(void) -{ - struct rte_cfgfile *cfgfile; - const char *value; - int ret; - - cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty_key_value.ini", - CFG_FLAG_EMPTY_VALUES); - TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse empty_key_value.ini"); - - ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); - TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret); - - ret = rte_cfgfile_has_section(cfgfile, "section1"); - TEST_ASSERT(ret, "section1 missing"); - - ret = rte_cfgfile_section_num_entries(cfgfile, "section1"); - TEST_ASSERT(ret == 1, "section1 unexpected number of entries: %d", ret); - - value = rte_cfgfile_get_entry(cfgfile, "section1", "key"); - TEST_ASSERT(strlen(value) == 0, "key unexpected value: %s", value); - - ret = rte_cfgfile_close(cfgfile); - TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); - - return 0; -} - -static int -test_cfgfile_missing_section(void) -{ - struct rte_cfgfile *cfgfile; - - cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/missing_section.ini", 0); - TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); - - return 0; -} - -static int -test_cfgfile_global_properties(void) -{ - struct rte_cfgfile *cfgfile; - const char *value; - int ret; - - cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/missing_section.ini", - CFG_FLAG_GLOBAL_SECTION); - TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file"); - - ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); - TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret); - - ret = rte_cfgfile_has_section(cfgfile, "GLOBAL"); - TEST_ASSERT(ret, "global section missing"); - - ret = rte_cfgfile_section_num_entries(cfgfile, "GLOBAL"); - TEST_ASSERT(ret == 1, "GLOBAL unexpected number of entries: %d", ret); - - value = rte_cfgfile_get_entry(cfgfile, "GLOBAL", "key"); - TEST_ASSERT(strcmp("value", value) == 0, - "key unexpected value: %s", value); - - ret = rte_cfgfile_close(cfgfile); - TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); - - return 0; -} - -static int -test_cfgfile_empty_file(void) -{ - struct rte_cfgfile *cfgfile; - int ret; - - cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty.ini", 0); - TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file"); - - ret = rte_cfgfile_num_sections(cfgfile, NULL, 0); - TEST_ASSERT(ret == 0, "Unexpected number of sections: %d", ret); - - ret = rte_cfgfile_close(cfgfile); - TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); - - return 0; -} - -static int -test_cfgfile(void) -{ - if (test_cfgfile_setup()) - return -1; - - if (test_cfgfile_sample1()) - return -1; - - if (test_cfgfile_sample2()) - return -1; - - if (test_cfgfile_realloc_sections()) - return -1; - - if (test_cfgfile_invalid_section_header()) - return -1; - - if (test_cfgfile_invalid_comment()) - return -1; - - if (test_cfgfile_invalid_key_value_pair()) - return -1; - - if (test_cfgfile_empty_key_value_pair()) - return -1; - - if (test_cfgfile_missing_section()) - return -1; - - if (test_cfgfile_global_properties()) - return -1; - - if (test_cfgfile_empty_file()) - return -1; - - if (test_cfgfile_cleanup()) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(cfgfile_autotest, test_cfgfile); diff --git a/test/test/test_cfgfiles/etc/empty.ini b/test/test/test_cfgfiles/etc/empty.ini deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/test/test_cfgfiles/etc/empty_key_value.ini b/test/test/test_cfgfiles/etc/empty_key_value.ini deleted file mode 100644 index 53284467b3..0000000000 --- a/test/test/test_cfgfiles/etc/empty_key_value.ini +++ /dev/null @@ -1,3 +0,0 @@ -[section1] -; this is section 1 -key= diff --git a/test/test/test_cfgfiles/etc/invalid_section.ini b/test/test/test_cfgfiles/etc/invalid_section.ini deleted file mode 100644 index 95d6803977..0000000000 --- a/test/test/test_cfgfiles/etc/invalid_section.ini +++ /dev/null @@ -1,3 +0,0 @@ -[invalid -; this is section 1 -key1=value1 diff --git a/test/test/test_cfgfiles/etc/line_too_long.ini b/test/test/test_cfgfiles/etc/line_too_long.ini deleted file mode 100644 index 1dce164838..0000000000 --- a/test/test/test_cfgfiles/etc/line_too_long.ini +++ /dev/null @@ -1,3 +0,0 @@ -[section1] -; this is section 1 -012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 diff --git a/test/test/test_cfgfiles/etc/missing_section.ini b/test/test/test_cfgfiles/etc/missing_section.ini deleted file mode 100644 index c78e131b40..0000000000 --- a/test/test/test_cfgfiles/etc/missing_section.ini +++ /dev/null @@ -1,2 +0,0 @@ -; no section -key=value diff --git a/test/test/test_cfgfiles/etc/realloc_sections.ini b/test/test/test_cfgfiles/etc/realloc_sections.ini deleted file mode 100644 index e653e40c6b..0000000000 --- a/test/test/test_cfgfiles/etc/realloc_sections.ini +++ /dev/null @@ -1,128 +0,0 @@ -[section1] -key1=value1_section1 -key2=value2_section1 -key3=value3_section1 -key4=value4_section1 -key5=value5_section1 -key6=value6_section1 -key7=value7_section1 -key8=value8_section1 -key9=value9_section1 -key10=value10_section1 -key11=value11_section1 -key12=value12_section1 -key13=value13_section1 -key14=value14_section1 -key15=value15_section1 -key16=value16_section1 -key17=value17_section1 -key18=value18_section1 -key19=value19_section1 -key20=value20_section1 -key21=value21_section1 - -[section2] -key1=value1_section2 -key2=value2_section2 -key3=value3_section2 -key4=value4_section2 -key5=value5_section2 -key6=value6_section2 -key7=value7_section2 -key8=value8_section2 -key9=value9_section2 -key10=value10_section2 -key11=value11_section2 -key12=value12_section2 -key13=value13_section2 -key14=value14_section2 -key15=value15_section2 -key16=value16_section2 -key17=value17_section2 -key18=value18_section2 -key19=value19_section2 -key20=value20_section2 -key21=value21_section2 - -[section3] -key1=value1_section3 -key2=value2_section3 -key3=value3_section3 -key4=value4_section3 -key5=value5_section3 -key6=value6_section3 -key7=value7_section3 -key8=value8_section3 -key9=value9_section3 -key10=value10_section3 -key11=value11_section3 -key12=value12_section3 -key13=value13_section3 -key14=value14_section3 -key15=value15_section3 -key16=value16_section3 -key17=value17_section3 -key18=value18_section3 -key19=value19_section3 -key20=value20_section3 -key21=value21_section3 - -[section4] -key1=value1_section4 -key2=value2_section4 -key3=value3_section4 -key4=value4_section4 -key5=value5_section4 -key6=value6_section4 -key7=value7_section4 -key8=value8_section4 - -[section5] -key1=value1_section5 -key2=value2_section5 -key3=value3_section5 -key4=value4_section5 -key5=value5_section5 -key6=value6_section5 -key7=value7_section5 -key8=value8_section5 - -[section6] -key1=value1_section6 -key2=value2_section6 -key3=value3_section6 -key4=value4_section6 -key5=value5_section6 -key6=value6_section6 -key7=value7_section6 -key8=value8_section6 - -[section7] -key1=value1_section7 -key2=value2_section7 -key3=value3_section7 -key4=value4_section7 -key5=value5_section7 -key6=value6_section7 -key7=value7_section7 -key8=value8_section7 - -[section8] -key1=value1_section8 -key2=value2_section8 -key3=value3_section8 -key4=value4_section8 -key5=value5_section8 -key6=value6_section8 -key7=value7_section8 -key8=value8_section8 - -[section9] -key1=value1_section9 -key2=value2_section9 -key3=value3_section9 -key4=value4_section9 -key5=value5_section9 -key6=value6_section9 -key7=value7_section9 -key8=value8_section9 diff --git a/test/test/test_cfgfiles/etc/sample1.ini b/test/test/test_cfgfiles/etc/sample1.ini deleted file mode 100644 index aef91c2416..0000000000 --- a/test/test/test_cfgfiles/etc/sample1.ini +++ /dev/null @@ -1,12 +0,0 @@ -; this is a global comment - -[section1] -; this is section 1 -key1=value1 - -[section2] -; this is section 2 -;key1=value1 -key2=value2 -key3=value3 ; this is key3 -ignore-missing-separator diff --git a/test/test/test_cfgfiles/etc/sample2.ini b/test/test/test_cfgfiles/etc/sample2.ini deleted file mode 100644 index 21075e9763..0000000000 --- a/test/test/test_cfgfiles/etc/sample2.ini +++ /dev/null @@ -1,12 +0,0 @@ -# this is a global comment - -[section1] -# this is section 1 -key1=value1 - -[section2] -# this is section 2 -#key1=value1 -key2=value2 -key3=value3 # this is key3 -ignore-missing-separator diff --git a/test/test/test_cmdline.c b/test/test/test_cmdline.c deleted file mode 100644 index 115bee966d..0000000000 --- a/test/test/test_cmdline.c +++ /dev/null @@ -1,63 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 1854caf8fd..0000000000 --- a/test/test/test_cmdline.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 8ac326cb02..0000000000 --- a/test/test/test_cmdline_cirbuf.c +++ /dev/null @@ -1,1301 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include - -#include - -#include - -#include "test_cmdline.h" - -/* different length strings */ -#define CIRBUF_STR_HEAD " HEAD" -#define CIRBUF_STR_TAIL "TAIL" - -/* miscellaneous 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)); - - strlcpy(tmp2, CIRBUF_STR_HEAD, sizeof(tmp2)); - - /* - * 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 deleted file mode 100644 index 6ceba4b29b..0000000000 --- a/test/test/test_cmdline_etheraddr.c +++ /dev/null @@ -1,218 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 8ee7f62886..0000000000 --- a/test/test/test_cmdline_ipaddr.c +++ /dev/null @@ -1,691 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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}, - {"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 deleted file mode 100644 index a856a97132..0000000000 --- a/test/test/test_cmdline_lib.c +++ /dev/null @@ -1,234 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index ea6b9f1e36..0000000000 --- a/test/test/test_cmdline_num.c +++ /dev/null @@ -1,594 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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; - break; - 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 deleted file mode 100644 index 0dc6d00304..0000000000 --- a/test/test/test_cmdline_portlist.c +++ /dev/null @@ -1,221 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 0461a85bb9..0000000000 --- a/test/test/test_cmdline_string.c +++ /dev/null @@ -1,383 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 94d3674712..0000000000 --- a/test/test/test_common.c +++ /dev/null @@ -1,311 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include -#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_bsf(void) -{ - uint32_t shift, pos; - - /* safe versions should be able to handle 0 */ - if (rte_bsf32_safe(0, &pos) != 0) - FAIL("rte_bsf32_safe"); - if (rte_bsf64_safe(0, &pos) != 0) - FAIL("rte_bsf64_safe"); - - for (shift = 0; shift < 63; shift++) { - uint32_t val32; - uint64_t val64; - - val64 = 1ULL << shift; - if ((uint32_t)rte_bsf64(val64) != shift) - FAIL("rte_bsf64"); - if (rte_bsf64_safe(val64, &pos) != 1) - FAIL("rte_bsf64_safe"); - if (pos != shift) - FAIL("rte_bsf64_safe"); - - if (shift > 31) - continue; - - val32 = 1U << shift; - if ((uint32_t)rte_bsf32(val32) != shift) - FAIL("rte_bsf32"); - if (rte_bsf32_safe(val32, &pos) != 1) - FAIL("rte_bsf32_safe"); - if (pos != shift) - FAIL("rte_bsf32_safe"); - } - - return 0; -} - -static int -test_misc(void) -{ - char memdump[] = "memdump_test"; - - 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 FAIL_ALIGN64(x, j, q)\ - {printf(x "() test failed: %"PRIu64" %"PRIu64"\n", j, q);\ - 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; - uint64_t j, q; - - 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 (i = 1, p = 1; i <= MAX_NUM; i++) { - if (rte_align32prevpow2(i) != p) - FAIL_ALIGN("rte_align32prevpow2", i, p); - if (rte_is_power_of_2(i + 1)) - p = i + 1; - } - - for (j = 1, q = 1; j <= MAX_NUM ; j++) { - if (rte_align64pow2(j) != q) - FAIL_ALIGN64("rte_align64pow2", j, q); - if (j == q) - q <<= 1; - } - - for (j = 1, q = 1; j <= MAX_NUM ; j++) { - if (rte_align64prevpow2(j) != q) - FAIL_ALIGN64("rte_align64prevpow2", j, q); - if (rte_is_power_of_2(j + 1)) - q = j + 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"); - } - } - - for (p = 1; p <= MAX_NUM / 2; p++) { - for (i = 1; i <= MAX_NUM / 2; i++) { - val = RTE_ALIGN_MUL_CEIL(i, p); - if (val % p != 0 || val < i) - FAIL_ALIGN("RTE_ALIGN_MUL_CEIL", i, p); - val = RTE_ALIGN_MUL_FLOOR(i, p); - if (val % p != 0 || val > i) - FAIL_ALIGN("RTE_ALIGN_MUL_FLOOR", i, p); - } - } - - return 0; -} - -static int -test_log2(void) -{ - uint32_t i, base, compare; - const uint32_t max = 0x10000; - const uint32_t step = 1; - - for (i = 0; i < max; i = i + step) { - uint64_t i64; - - /* extend range for 64-bit */ - i64 = (uint64_t)i << 32; - base = (uint32_t)ceilf(log2(i64)); - compare = rte_log2_u64(i64); - if (base != compare) { - printf("Wrong rte_log2_u64(%" PRIx64 ") val %x, expected %x\n", - i64, compare, base); - return TEST_FAILED; - } - - base = (uint32_t)ceilf(log2((uint32_t)i)); - compare = rte_log2_u32((uint32_t)i); - if (base != compare) { - printf("Wrong rte_log2_u32(%x) val %x, expected %x\n", - i, compare, base); - return TEST_FAILED; - } - compare = rte_log2_u64((uint64_t)i); - if (base != compare) { - printf("Wrong rte_log2_u64(%x) val %x, expected %x\n", - i, compare, base); - return TEST_FAILED; - } - } - return 0; -} - -static int -test_fls(void) -{ - struct fls_test_vector { - uint32_t arg; - int rc; - }; - int expected, rc; - uint32_t i, arg; - - const struct fls_test_vector test[] = { - {0x0, 0}, - {0x1, 1}, - {0x4000, 15}, - {0x80000000, 32}, - }; - - for (i = 0; i < RTE_DIM(test); i++) { - uint64_t arg64; - - arg = test[i].arg; - rc = rte_fls_u32(arg); - expected = test[i].rc; - if (rc != expected) { - printf("Wrong rte_fls_u32(0x%x) rc=%d, expected=%d\n", - arg, rc, expected); - return TEST_FAILED; - } - /* 64-bit version */ - arg = test[i].arg; - rc = rte_fls_u64(arg); - expected = test[i].rc; - if (rc != expected) { - printf("Wrong rte_fls_u64(0x%x) rc=%d, expected=%d\n", - arg, rc, expected); - return TEST_FAILED; - } - /* 64-bit version shifted by 32 bits */ - arg64 = (uint64_t)test[i].arg << 32; - rc = rte_fls_u64(arg64); - /* don't shift zero */ - expected = test[i].rc == 0 ? 0 : test[i].rc + 32; - if (rc != expected) { - printf("Wrong rte_fls_u64(0x%" PRIx64 ") rc=%d, expected=%d\n", - arg64, rc, expected); - return TEST_FAILED; - } - } - - return 0; -} - -static int -test_common(void) -{ - int ret = 0; - ret |= test_align(); - ret |= test_macros(0); - ret |= test_misc(); - ret |= test_bsf(); - ret |= test_log2(); - ret |= test_fls(); - - return ret; -} - -REGISTER_TEST_COMMAND(common_autotest, test_common); diff --git a/test/test/test_compressdev.c b/test/test/test_compressdev.c deleted file mode 100644 index e8476edd29..0000000000 --- a/test/test/test_compressdev.c +++ /dev/null @@ -1,1940 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "test_compressdev_test_buffer.h" -#include "test.h" - -#define DIV_CEIL(a, b) ((a) / (b) + ((a) % (b) != 0)) - -#define DEFAULT_WINDOW_SIZE 15 -#define DEFAULT_MEM_LEVEL 8 -#define MAX_DEQD_RETRIES 10 -#define DEQUEUE_WAIT_TIME 10000 - -/* - * 30% extra size for compressed data compared to original data, - * in case data size cannot be reduced and it is actually bigger - * due to the compress block headers - */ -#define COMPRESS_BUF_SIZE_RATIO 1.3 -#define NUM_LARGE_MBUFS 16 -#define SMALL_SEG_SIZE 256 -#define MAX_SEGS 16 -#define NUM_OPS 16 -#define NUM_MAX_XFORMS 16 -#define NUM_MAX_INFLIGHT_OPS 128 -#define CACHE_SIZE 0 - -#define ZLIB_CRC_CHECKSUM_WINDOW_BITS 31 -#define ZLIB_HEADER_SIZE 2 -#define ZLIB_TRAILER_SIZE 4 -#define GZIP_HEADER_SIZE 10 -#define GZIP_TRAILER_SIZE 8 - -#define OUT_OF_SPACE_BUF 1 - -const char * -huffman_type_strings[] = { - [RTE_COMP_HUFFMAN_DEFAULT] = "PMD default", - [RTE_COMP_HUFFMAN_FIXED] = "Fixed", - [RTE_COMP_HUFFMAN_DYNAMIC] = "Dynamic" -}; - -enum zlib_direction { - ZLIB_NONE, - ZLIB_COMPRESS, - ZLIB_DECOMPRESS, - ZLIB_ALL -}; - -enum varied_buff { - LB_BOTH = 0, /* both input and output are linear*/ - SGL_BOTH, /* both input and output are chained */ - SGL_TO_LB, /* input buffer is chained */ - LB_TO_SGL /* output buffer is chained */ -}; - -struct priv_op_data { - uint16_t orig_idx; -}; - -struct comp_testsuite_params { - struct rte_mempool *large_mbuf_pool; - struct rte_mempool *small_mbuf_pool; - struct rte_mempool *op_pool; - struct rte_comp_xform *def_comp_xform; - struct rte_comp_xform *def_decomp_xform; -}; - -struct interim_data_params { - const char * const *test_bufs; - unsigned int num_bufs; - uint16_t *buf_idx; - struct rte_comp_xform **compress_xforms; - struct rte_comp_xform **decompress_xforms; - unsigned int num_xforms; -}; - -struct test_data_params { - enum rte_comp_op_type state; - enum varied_buff buff_type; - enum zlib_direction zlib_dir; - unsigned int out_of_space; -}; - -static struct comp_testsuite_params testsuite_params = { 0 }; - -static void -testsuite_teardown(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - - if (rte_mempool_in_use_count(ts_params->large_mbuf_pool)) - RTE_LOG(ERR, USER1, "Large mbuf pool still has unfreed bufs\n"); - if (rte_mempool_in_use_count(ts_params->small_mbuf_pool)) - RTE_LOG(ERR, USER1, "Small mbuf pool still has unfreed bufs\n"); - if (rte_mempool_in_use_count(ts_params->op_pool)) - RTE_LOG(ERR, USER1, "op pool still has unfreed ops\n"); - - rte_mempool_free(ts_params->large_mbuf_pool); - rte_mempool_free(ts_params->small_mbuf_pool); - rte_mempool_free(ts_params->op_pool); - rte_free(ts_params->def_comp_xform); - rte_free(ts_params->def_decomp_xform); -} - -static int -testsuite_setup(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - uint32_t max_buf_size = 0; - unsigned int i; - - if (rte_compressdev_count() == 0) { - RTE_LOG(ERR, USER1, "Need at least one compress device\n"); - return TEST_FAILED; - } - - RTE_LOG(NOTICE, USER1, "Running tests on device %s\n", - rte_compressdev_name_get(0)); - - for (i = 0; i < RTE_DIM(compress_test_bufs); i++) - max_buf_size = RTE_MAX(max_buf_size, - strlen(compress_test_bufs[i]) + 1); - - /* - * Buffers to be used in compression and decompression. - * Since decompressed data might be larger than - * compressed data (due to block header), - * buffers should be big enough for both cases. - */ - max_buf_size *= COMPRESS_BUF_SIZE_RATIO; - ts_params->large_mbuf_pool = rte_pktmbuf_pool_create("large_mbuf_pool", - NUM_LARGE_MBUFS, - CACHE_SIZE, 0, - max_buf_size + RTE_PKTMBUF_HEADROOM, - rte_socket_id()); - if (ts_params->large_mbuf_pool == NULL) { - RTE_LOG(ERR, USER1, "Large mbuf pool could not be created\n"); - return TEST_FAILED; - } - - /* Create mempool with smaller buffers for SGL testing */ - ts_params->small_mbuf_pool = rte_pktmbuf_pool_create("small_mbuf_pool", - NUM_LARGE_MBUFS * MAX_SEGS, - CACHE_SIZE, 0, - SMALL_SEG_SIZE + RTE_PKTMBUF_HEADROOM, - rte_socket_id()); - if (ts_params->small_mbuf_pool == NULL) { - RTE_LOG(ERR, USER1, "Small mbuf pool could not be created\n"); - goto exit; - } - - ts_params->op_pool = rte_comp_op_pool_create("op_pool", NUM_OPS, - 0, sizeof(struct priv_op_data), - rte_socket_id()); - if (ts_params->op_pool == NULL) { - RTE_LOG(ERR, USER1, "Operation pool could not be created\n"); - goto exit; - } - - ts_params->def_comp_xform = - rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - if (ts_params->def_comp_xform == NULL) { - RTE_LOG(ERR, USER1, - "Default compress xform could not be created\n"); - goto exit; - } - ts_params->def_decomp_xform = - rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - if (ts_params->def_decomp_xform == NULL) { - RTE_LOG(ERR, USER1, - "Default decompress xform could not be created\n"); - goto exit; - } - - /* Initializes default values for compress/decompress xforms */ - ts_params->def_comp_xform->type = RTE_COMP_COMPRESS; - ts_params->def_comp_xform->compress.algo = RTE_COMP_ALGO_DEFLATE, - ts_params->def_comp_xform->compress.deflate.huffman = - RTE_COMP_HUFFMAN_DEFAULT; - ts_params->def_comp_xform->compress.level = RTE_COMP_LEVEL_PMD_DEFAULT; - ts_params->def_comp_xform->compress.chksum = RTE_COMP_CHECKSUM_NONE; - ts_params->def_comp_xform->compress.window_size = DEFAULT_WINDOW_SIZE; - - ts_params->def_decomp_xform->type = RTE_COMP_DECOMPRESS; - ts_params->def_decomp_xform->decompress.algo = RTE_COMP_ALGO_DEFLATE, - ts_params->def_decomp_xform->decompress.chksum = RTE_COMP_CHECKSUM_NONE; - ts_params->def_decomp_xform->decompress.window_size = DEFAULT_WINDOW_SIZE; - - return TEST_SUCCESS; - -exit: - testsuite_teardown(); - - return TEST_FAILED; -} - -static int -generic_ut_setup(void) -{ - /* Configure compressdev (one device, one queue pair) */ - struct rte_compressdev_config config = { - .socket_id = rte_socket_id(), - .nb_queue_pairs = 1, - .max_nb_priv_xforms = NUM_MAX_XFORMS, - .max_nb_streams = 0 - }; - - if (rte_compressdev_configure(0, &config) < 0) { - RTE_LOG(ERR, USER1, "Device configuration failed\n"); - return -1; - } - - if (rte_compressdev_queue_pair_setup(0, 0, NUM_MAX_INFLIGHT_OPS, - rte_socket_id()) < 0) { - RTE_LOG(ERR, USER1, "Queue pair setup failed\n"); - return -1; - } - - if (rte_compressdev_start(0) < 0) { - RTE_LOG(ERR, USER1, "Device could not be started\n"); - return -1; - } - - return 0; -} - -static void -generic_ut_teardown(void) -{ - rte_compressdev_stop(0); - if (rte_compressdev_close(0) < 0) - RTE_LOG(ERR, USER1, "Device could not be closed\n"); -} - -static int -test_compressdev_invalid_configuration(void) -{ - struct rte_compressdev_config invalid_config; - struct rte_compressdev_config valid_config = { - .socket_id = rte_socket_id(), - .nb_queue_pairs = 1, - .max_nb_priv_xforms = NUM_MAX_XFORMS, - .max_nb_streams = 0 - }; - struct rte_compressdev_info dev_info; - - /* Invalid configuration with 0 queue pairs */ - memcpy(&invalid_config, &valid_config, - sizeof(struct rte_compressdev_config)); - invalid_config.nb_queue_pairs = 0; - - TEST_ASSERT_FAIL(rte_compressdev_configure(0, &invalid_config), - "Device configuration was successful " - "with no queue pairs (invalid)\n"); - - /* - * Invalid configuration with too many queue pairs - * (if there is an actual maximum number of queue pairs) - */ - rte_compressdev_info_get(0, &dev_info); - if (dev_info.max_nb_queue_pairs != 0) { - memcpy(&invalid_config, &valid_config, - sizeof(struct rte_compressdev_config)); - invalid_config.nb_queue_pairs = dev_info.max_nb_queue_pairs + 1; - - TEST_ASSERT_FAIL(rte_compressdev_configure(0, &invalid_config), - "Device configuration was successful " - "with too many queue pairs (invalid)\n"); - } - - /* Invalid queue pair setup, with no number of queue pairs set */ - TEST_ASSERT_FAIL(rte_compressdev_queue_pair_setup(0, 0, - NUM_MAX_INFLIGHT_OPS, rte_socket_id()), - "Queue pair setup was successful " - "with no queue pairs set (invalid)\n"); - - return TEST_SUCCESS; -} - -static int -compare_buffers(const char *buffer1, uint32_t buffer1_len, - const char *buffer2, uint32_t buffer2_len) -{ - if (buffer1_len != buffer2_len) { - RTE_LOG(ERR, USER1, "Buffer lengths are different\n"); - return -1; - } - - if (memcmp(buffer1, buffer2, buffer1_len) != 0) { - RTE_LOG(ERR, USER1, "Buffers are different\n"); - return -1; - } - - return 0; -} - -/* - * Maps compressdev and Zlib flush flags - */ -static int -map_zlib_flush_flag(enum rte_comp_flush_flag flag) -{ - switch (flag) { - case RTE_COMP_FLUSH_NONE: - return Z_NO_FLUSH; - case RTE_COMP_FLUSH_SYNC: - return Z_SYNC_FLUSH; - case RTE_COMP_FLUSH_FULL: - return Z_FULL_FLUSH; - case RTE_COMP_FLUSH_FINAL: - return Z_FINISH; - /* - * There should be only the values above, - * so this should never happen - */ - default: - return -1; - } -} - -static int -compress_zlib(struct rte_comp_op *op, - const struct rte_comp_xform *xform, int mem_level) -{ - z_stream stream; - int zlib_flush; - int strategy, window_bits, comp_level; - int ret = TEST_FAILED; - uint8_t *single_src_buf = NULL; - uint8_t *single_dst_buf = NULL; - - /* initialize zlib stream */ - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - if (xform->compress.deflate.huffman == RTE_COMP_HUFFMAN_FIXED) - strategy = Z_FIXED; - else - strategy = Z_DEFAULT_STRATEGY; - - /* - * Window bits is the base two logarithm of the window size (in bytes). - * When doing raw DEFLATE, this number will be negative. - */ - window_bits = -(xform->compress.window_size); - if (xform->compress.chksum == RTE_COMP_CHECKSUM_ADLER32) - window_bits *= -1; - else if (xform->compress.chksum == RTE_COMP_CHECKSUM_CRC32) - window_bits = ZLIB_CRC_CHECKSUM_WINDOW_BITS; - - comp_level = xform->compress.level; - - if (comp_level != RTE_COMP_LEVEL_NONE) - ret = deflateInit2(&stream, comp_level, Z_DEFLATED, - window_bits, mem_level, strategy); - else - ret = deflateInit(&stream, Z_NO_COMPRESSION); - - if (ret != Z_OK) { - printf("Zlib deflate could not be initialized\n"); - goto exit; - } - - /* Assuming stateless operation */ - /* SGL Input */ - if (op->m_src->nb_segs > 1) { - single_src_buf = rte_malloc(NULL, - rte_pktmbuf_pkt_len(op->m_src), 0); - if (single_src_buf == NULL) { - RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); - goto exit; - } - - if (rte_pktmbuf_read(op->m_src, op->src.offset, - rte_pktmbuf_pkt_len(op->m_src) - - op->src.offset, - single_src_buf) == NULL) { - RTE_LOG(ERR, USER1, - "Buffer could not be read entirely\n"); - goto exit; - } - - stream.avail_in = op->src.length; - stream.next_in = single_src_buf; - - } else { - stream.avail_in = op->src.length; - stream.next_in = rte_pktmbuf_mtod_offset(op->m_src, uint8_t *, - op->src.offset); - } - /* SGL output */ - if (op->m_dst->nb_segs > 1) { - - single_dst_buf = rte_malloc(NULL, - rte_pktmbuf_pkt_len(op->m_dst), 0); - if (single_dst_buf == NULL) { - RTE_LOG(ERR, USER1, - "Buffer could not be allocated\n"); - goto exit; - } - - stream.avail_out = op->m_dst->pkt_len; - stream.next_out = single_dst_buf; - - } else {/* linear output */ - stream.avail_out = op->m_dst->data_len; - stream.next_out = rte_pktmbuf_mtod_offset(op->m_dst, uint8_t *, - op->dst.offset); - } - - /* Stateless operation, all buffer will be compressed in one go */ - zlib_flush = map_zlib_flush_flag(op->flush_flag); - ret = deflate(&stream, zlib_flush); - - if (stream.avail_in != 0) { - RTE_LOG(ERR, USER1, "Buffer could not be read entirely\n"); - goto exit; - } - - if (ret != Z_STREAM_END) - goto exit; - - /* Copy data to destination SGL */ - if (op->m_dst->nb_segs > 1) { - uint32_t remaining_data = stream.total_out; - uint8_t *src_data = single_dst_buf; - struct rte_mbuf *dst_buf = op->m_dst; - - while (remaining_data > 0) { - uint8_t *dst_data = rte_pktmbuf_mtod_offset(dst_buf, - uint8_t *, op->dst.offset); - /* Last segment */ - if (remaining_data < dst_buf->data_len) { - memcpy(dst_data, src_data, remaining_data); - remaining_data = 0; - } else { - memcpy(dst_data, src_data, dst_buf->data_len); - remaining_data -= dst_buf->data_len; - src_data += dst_buf->data_len; - dst_buf = dst_buf->next; - } - } - } - - op->consumed = stream.total_in; - if (xform->compress.chksum == RTE_COMP_CHECKSUM_ADLER32) { - rte_pktmbuf_adj(op->m_dst, ZLIB_HEADER_SIZE); - rte_pktmbuf_trim(op->m_dst, ZLIB_TRAILER_SIZE); - op->produced = stream.total_out - (ZLIB_HEADER_SIZE + - ZLIB_TRAILER_SIZE); - } else if (xform->compress.chksum == RTE_COMP_CHECKSUM_CRC32) { - rte_pktmbuf_adj(op->m_dst, GZIP_HEADER_SIZE); - rte_pktmbuf_trim(op->m_dst, GZIP_TRAILER_SIZE); - op->produced = stream.total_out - (GZIP_HEADER_SIZE + - GZIP_TRAILER_SIZE); - } else - op->produced = stream.total_out; - - op->status = RTE_COMP_OP_STATUS_SUCCESS; - op->output_chksum = stream.adler; - - deflateReset(&stream); - - ret = 0; -exit: - deflateEnd(&stream); - rte_free(single_src_buf); - rte_free(single_dst_buf); - - return ret; -} - -static int -decompress_zlib(struct rte_comp_op *op, - const struct rte_comp_xform *xform) -{ - z_stream stream; - int window_bits; - int zlib_flush; - int ret = TEST_FAILED; - uint8_t *single_src_buf = NULL; - uint8_t *single_dst_buf = NULL; - - /* initialize zlib stream */ - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - /* - * Window bits is the base two logarithm of the window size (in bytes). - * When doing raw DEFLATE, this number will be negative. - */ - window_bits = -(xform->decompress.window_size); - ret = inflateInit2(&stream, window_bits); - - if (ret != Z_OK) { - printf("Zlib deflate could not be initialized\n"); - goto exit; - } - - /* Assuming stateless operation */ - /* SGL */ - if (op->m_src->nb_segs > 1) { - single_src_buf = rte_malloc(NULL, - rte_pktmbuf_pkt_len(op->m_src), 0); - if (single_src_buf == NULL) { - RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); - goto exit; - } - single_dst_buf = rte_malloc(NULL, - rte_pktmbuf_pkt_len(op->m_dst), 0); - if (single_dst_buf == NULL) { - RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); - goto exit; - } - if (rte_pktmbuf_read(op->m_src, 0, - rte_pktmbuf_pkt_len(op->m_src), - single_src_buf) == NULL) { - RTE_LOG(ERR, USER1, - "Buffer could not be read entirely\n"); - goto exit; - } - - stream.avail_in = op->src.length; - stream.next_in = single_src_buf; - stream.avail_out = rte_pktmbuf_pkt_len(op->m_dst); - stream.next_out = single_dst_buf; - - } else { - stream.avail_in = op->src.length; - stream.next_in = rte_pktmbuf_mtod(op->m_src, uint8_t *); - stream.avail_out = op->m_dst->data_len; - stream.next_out = rte_pktmbuf_mtod(op->m_dst, uint8_t *); - } - - /* Stateless operation, all buffer will be compressed in one go */ - zlib_flush = map_zlib_flush_flag(op->flush_flag); - ret = inflate(&stream, zlib_flush); - - if (stream.avail_in != 0) { - RTE_LOG(ERR, USER1, "Buffer could not be read entirely\n"); - goto exit; - } - - if (ret != Z_STREAM_END) - goto exit; - - if (op->m_src->nb_segs > 1) { - uint32_t remaining_data = stream.total_out; - uint8_t *src_data = single_dst_buf; - struct rte_mbuf *dst_buf = op->m_dst; - - while (remaining_data > 0) { - uint8_t *dst_data = rte_pktmbuf_mtod(dst_buf, - uint8_t *); - /* Last segment */ - if (remaining_data < dst_buf->data_len) { - memcpy(dst_data, src_data, remaining_data); - remaining_data = 0; - } else { - memcpy(dst_data, src_data, dst_buf->data_len); - remaining_data -= dst_buf->data_len; - src_data += dst_buf->data_len; - dst_buf = dst_buf->next; - } - } - } - - op->consumed = stream.total_in; - op->produced = stream.total_out; - op->status = RTE_COMP_OP_STATUS_SUCCESS; - - inflateReset(&stream); - - ret = 0; -exit: - inflateEnd(&stream); - - return ret; -} - -static int -prepare_sgl_bufs(const char *test_buf, struct rte_mbuf *head_buf, - uint32_t total_data_size, - struct rte_mempool *small_mbuf_pool, - struct rte_mempool *large_mbuf_pool, - uint8_t limit_segs_in_sgl) -{ - uint32_t remaining_data = total_data_size; - uint16_t num_remaining_segs = DIV_CEIL(remaining_data, SMALL_SEG_SIZE); - struct rte_mempool *pool; - struct rte_mbuf *next_seg; - uint32_t data_size; - char *buf_ptr; - const char *data_ptr = test_buf; - uint16_t i; - int ret; - - if (limit_segs_in_sgl != 0 && num_remaining_segs > limit_segs_in_sgl) - num_remaining_segs = limit_segs_in_sgl - 1; - - /* - * Allocate data in the first segment (header) and - * copy data if test buffer is provided - */ - if (remaining_data < SMALL_SEG_SIZE) - data_size = remaining_data; - else - data_size = SMALL_SEG_SIZE; - buf_ptr = rte_pktmbuf_append(head_buf, data_size); - if (buf_ptr == NULL) { - RTE_LOG(ERR, USER1, - "Not enough space in the 1st buffer\n"); - return -1; - } - - if (data_ptr != NULL) { - /* Copy characters without NULL terminator */ - strncpy(buf_ptr, data_ptr, data_size); - data_ptr += data_size; - } - remaining_data -= data_size; - num_remaining_segs--; - - /* - * Allocate the rest of the segments, - * copy the rest of the data and chain the segments. - */ - for (i = 0; i < num_remaining_segs; i++) { - - if (i == (num_remaining_segs - 1)) { - /* last segment */ - if (remaining_data > SMALL_SEG_SIZE) - pool = large_mbuf_pool; - else - pool = small_mbuf_pool; - data_size = remaining_data; - } else { - data_size = SMALL_SEG_SIZE; - pool = small_mbuf_pool; - } - - next_seg = rte_pktmbuf_alloc(pool); - if (next_seg == NULL) { - RTE_LOG(ERR, USER1, - "New segment could not be allocated " - "from the mempool\n"); - return -1; - } - buf_ptr = rte_pktmbuf_append(next_seg, data_size); - if (buf_ptr == NULL) { - RTE_LOG(ERR, USER1, - "Not enough space in the buffer\n"); - rte_pktmbuf_free(next_seg); - return -1; - } - if (data_ptr != NULL) { - /* Copy characters without NULL terminator */ - strncpy(buf_ptr, data_ptr, data_size); - data_ptr += data_size; - } - remaining_data -= data_size; - - ret = rte_pktmbuf_chain(head_buf, next_seg); - if (ret != 0) { - rte_pktmbuf_free(next_seg); - RTE_LOG(ERR, USER1, - "Segment could not chained\n"); - return -1; - } - } - - return 0; -} - -/* - * Compresses and decompresses buffer with compressdev API and Zlib API - */ -static int -test_deflate_comp_decomp(const struct interim_data_params *int_data, - const struct test_data_params *test_data) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - const char * const *test_bufs = int_data->test_bufs; - unsigned int num_bufs = int_data->num_bufs; - uint16_t *buf_idx = int_data->buf_idx; - struct rte_comp_xform **compress_xforms = int_data->compress_xforms; - struct rte_comp_xform **decompress_xforms = int_data->decompress_xforms; - unsigned int num_xforms = int_data->num_xforms; - enum rte_comp_op_type state = test_data->state; - unsigned int buff_type = test_data->buff_type; - unsigned int out_of_space = test_data->out_of_space; - enum zlib_direction zlib_dir = test_data->zlib_dir; - int ret_status = -1; - int ret; - struct rte_mbuf *uncomp_bufs[num_bufs]; - struct rte_mbuf *comp_bufs[num_bufs]; - struct rte_comp_op *ops[num_bufs]; - struct rte_comp_op *ops_processed[num_bufs]; - void *priv_xforms[num_bufs]; - uint16_t num_enqd, num_deqd, num_total_deqd; - uint16_t num_priv_xforms = 0; - unsigned int deqd_retries = 0; - struct priv_op_data *priv_data; - char *buf_ptr; - unsigned int i; - struct rte_mempool *buf_pool; - uint32_t data_size; - /* Compressing with CompressDev */ - unsigned int oos_zlib_decompress = - (zlib_dir == ZLIB_NONE || zlib_dir == ZLIB_DECOMPRESS); - /* Decompressing with CompressDev */ - unsigned int oos_zlib_compress = - (zlib_dir == ZLIB_NONE || zlib_dir == ZLIB_COMPRESS); - const struct rte_compressdev_capabilities *capa = - rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); - char *contig_buf = NULL; - uint64_t compress_checksum[num_bufs]; - - /* Initialize all arrays to NULL */ - memset(uncomp_bufs, 0, sizeof(struct rte_mbuf *) * num_bufs); - memset(comp_bufs, 0, sizeof(struct rte_mbuf *) * num_bufs); - memset(ops, 0, sizeof(struct rte_comp_op *) * num_bufs); - memset(ops_processed, 0, sizeof(struct rte_comp_op *) * num_bufs); - memset(priv_xforms, 0, sizeof(void *) * num_bufs); - - if (buff_type == SGL_BOTH) - buf_pool = ts_params->small_mbuf_pool; - else - buf_pool = ts_params->large_mbuf_pool; - - /* Prepare the source mbufs with the data */ - ret = rte_pktmbuf_alloc_bulk(buf_pool, - uncomp_bufs, num_bufs); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Source mbufs could not be allocated " - "from the mempool\n"); - goto exit; - } - - if (buff_type == SGL_BOTH || buff_type == SGL_TO_LB) { - for (i = 0; i < num_bufs; i++) { - data_size = strlen(test_bufs[i]) + 1; - if (prepare_sgl_bufs(test_bufs[i], uncomp_bufs[i], - data_size, - ts_params->small_mbuf_pool, - ts_params->large_mbuf_pool, - MAX_SEGS) < 0) - goto exit; - } - } else { - for (i = 0; i < num_bufs; i++) { - data_size = strlen(test_bufs[i]) + 1; - buf_ptr = rte_pktmbuf_append(uncomp_bufs[i], data_size); - snprintf(buf_ptr, data_size, "%s", test_bufs[i]); - } - } - - /* Prepare the destination mbufs */ - ret = rte_pktmbuf_alloc_bulk(buf_pool, comp_bufs, num_bufs); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Destination mbufs could not be allocated " - "from the mempool\n"); - goto exit; - } - - if (buff_type == SGL_BOTH || buff_type == LB_TO_SGL) { - for (i = 0; i < num_bufs; i++) { - if (out_of_space == 1 && oos_zlib_decompress) - data_size = OUT_OF_SPACE_BUF; - else - (data_size = strlen(test_bufs[i]) * - COMPRESS_BUF_SIZE_RATIO); - - if (prepare_sgl_bufs(NULL, comp_bufs[i], - data_size, - ts_params->small_mbuf_pool, - ts_params->large_mbuf_pool, - MAX_SEGS) < 0) - goto exit; - } - - } else { - for (i = 0; i < num_bufs; i++) { - if (out_of_space == 1 && oos_zlib_decompress) - data_size = OUT_OF_SPACE_BUF; - else - (data_size = strlen(test_bufs[i]) * - COMPRESS_BUF_SIZE_RATIO); - - rte_pktmbuf_append(comp_bufs[i], data_size); - } - } - - /* Build the compression operations */ - ret = rte_comp_op_bulk_alloc(ts_params->op_pool, ops, num_bufs); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Compress operations could not be allocated " - "from the mempool\n"); - goto exit; - } - - - for (i = 0; i < num_bufs; i++) { - ops[i]->m_src = uncomp_bufs[i]; - ops[i]->m_dst = comp_bufs[i]; - ops[i]->src.offset = 0; - ops[i]->src.length = rte_pktmbuf_pkt_len(uncomp_bufs[i]); - ops[i]->dst.offset = 0; - if (state == RTE_COMP_OP_STATELESS) { - ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL; - } else { - RTE_LOG(ERR, USER1, - "Stateful operations are not supported " - "in these tests yet\n"); - goto exit; - } - ops[i]->input_chksum = 0; - /* - * Store original operation index in private data, - * since ordering does not have to be maintained, - * when dequeueing from compressdev, so a comparison - * at the end of the test can be done. - */ - priv_data = (struct priv_op_data *) (ops[i] + 1); - priv_data->orig_idx = i; - } - - /* Compress data (either with Zlib API or compressdev API */ - if (zlib_dir == ZLIB_COMPRESS || zlib_dir == ZLIB_ALL) { - for (i = 0; i < num_bufs; i++) { - const struct rte_comp_xform *compress_xform = - compress_xforms[i % num_xforms]; - ret = compress_zlib(ops[i], compress_xform, - DEFAULT_MEM_LEVEL); - if (ret < 0) - goto exit; - - ops_processed[i] = ops[i]; - } - } else { - /* Create compress private xform data */ - for (i = 0; i < num_xforms; i++) { - ret = rte_compressdev_private_xform_create(0, - (const struct rte_comp_xform *)compress_xforms[i], - &priv_xforms[i]); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Compression private xform " - "could not be created\n"); - goto exit; - } - num_priv_xforms++; - } - - if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) { - /* Attach shareable private xform data to ops */ - for (i = 0; i < num_bufs; i++) - ops[i]->private_xform = priv_xforms[i % num_xforms]; - } else { - /* Create rest of the private xforms for the other ops */ - for (i = num_xforms; i < num_bufs; i++) { - ret = rte_compressdev_private_xform_create(0, - compress_xforms[i % num_xforms], - &priv_xforms[i]); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Compression private xform " - "could not be created\n"); - goto exit; - } - num_priv_xforms++; - } - - /* Attach non shareable private xform data to ops */ - for (i = 0; i < num_bufs; i++) - ops[i]->private_xform = priv_xforms[i]; - } - - /* Enqueue and dequeue all operations */ - num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs); - if (num_enqd < num_bufs) { - RTE_LOG(ERR, USER1, - "The operations could not be enqueued\n"); - goto exit; - } - - num_total_deqd = 0; - do { - /* - * If retrying a dequeue call, wait for 10 ms to allow - * enough time to the driver to process the operations - */ - if (deqd_retries != 0) { - /* - * Avoid infinite loop if not all the - * operations get out of the device - */ - if (deqd_retries == MAX_DEQD_RETRIES) { - RTE_LOG(ERR, USER1, - "Not all operations could be " - "dequeued\n"); - goto exit; - } - usleep(DEQUEUE_WAIT_TIME); - } - num_deqd = rte_compressdev_dequeue_burst(0, 0, - &ops_processed[num_total_deqd], num_bufs); - num_total_deqd += num_deqd; - deqd_retries++; - - } while (num_total_deqd < num_enqd); - - deqd_retries = 0; - - /* Free compress private xforms */ - for (i = 0; i < num_priv_xforms; i++) { - rte_compressdev_private_xform_free(0, priv_xforms[i]); - priv_xforms[i] = NULL; - } - num_priv_xforms = 0; - } - - for (i = 0; i < num_bufs; i++) { - priv_data = (struct priv_op_data *)(ops_processed[i] + 1); - uint16_t xform_idx = priv_data->orig_idx % num_xforms; - const struct rte_comp_compress_xform *compress_xform = - &compress_xforms[xform_idx]->compress; - enum rte_comp_huffman huffman_type = - compress_xform->deflate.huffman; - char engine[] = "zlib (directly, not PMD)"; - if (zlib_dir != ZLIB_COMPRESS || zlib_dir != ZLIB_ALL) - strlcpy(engine, "PMD", sizeof(engine)); - - RTE_LOG(DEBUG, USER1, "Buffer %u compressed by %s from %u to" - " %u bytes (level = %d, huffman = %s)\n", - buf_idx[priv_data->orig_idx], engine, - ops_processed[i]->consumed, ops_processed[i]->produced, - compress_xform->level, - huffman_type_strings[huffman_type]); - RTE_LOG(DEBUG, USER1, "Compression ratio = %.2f\n", - ops_processed[i]->consumed == 0 ? 0 : - (float)ops_processed[i]->produced / - ops_processed[i]->consumed * 100); - if (compress_xform->chksum != RTE_COMP_CHECKSUM_NONE) - compress_checksum[i] = ops_processed[i]->output_chksum; - ops[i] = NULL; - } - - /* - * Check operation status and free source mbufs (destination mbuf and - * compress operation information is needed for the decompression stage) - */ - for (i = 0; i < num_bufs; i++) { - if (out_of_space && oos_zlib_decompress) { - if (ops_processed[i]->status != - RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED) { - ret_status = -1; - - RTE_LOG(ERR, USER1, - "Operation without expected out of " - "space status error\n"); - goto exit; - } else - continue; - } - - if (ops_processed[i]->status != RTE_COMP_OP_STATUS_SUCCESS) { - RTE_LOG(ERR, USER1, - "Some operations were not successful\n"); - goto exit; - } - priv_data = (struct priv_op_data *)(ops_processed[i] + 1); - rte_pktmbuf_free(uncomp_bufs[priv_data->orig_idx]); - uncomp_bufs[priv_data->orig_idx] = NULL; - } - - if (out_of_space && oos_zlib_decompress) { - ret_status = 0; - goto exit; - } - - /* Allocate buffers for decompressed data */ - ret = rte_pktmbuf_alloc_bulk(buf_pool, uncomp_bufs, num_bufs); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Destination mbufs could not be allocated " - "from the mempool\n"); - goto exit; - } - - if (buff_type == SGL_BOTH || buff_type == LB_TO_SGL) { - for (i = 0; i < num_bufs; i++) { - priv_data = (struct priv_op_data *) - (ops_processed[i] + 1); - if (out_of_space == 1 && oos_zlib_compress) - data_size = OUT_OF_SPACE_BUF; - else - data_size = - strlen(test_bufs[priv_data->orig_idx]) + 1; - - if (prepare_sgl_bufs(NULL, uncomp_bufs[i], - data_size, - ts_params->small_mbuf_pool, - ts_params->large_mbuf_pool, - MAX_SEGS) < 0) - goto exit; - } - - } else { - for (i = 0; i < num_bufs; i++) { - priv_data = (struct priv_op_data *) - (ops_processed[i] + 1); - if (out_of_space == 1 && oos_zlib_compress) - data_size = OUT_OF_SPACE_BUF; - else - data_size = - strlen(test_bufs[priv_data->orig_idx]) + 1; - - rte_pktmbuf_append(uncomp_bufs[i], data_size); - } - } - - /* Build the decompression operations */ - ret = rte_comp_op_bulk_alloc(ts_params->op_pool, ops, num_bufs); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Decompress operations could not be allocated " - "from the mempool\n"); - goto exit; - } - - /* Source buffer is the compressed data from the previous operations */ - for (i = 0; i < num_bufs; i++) { - ops[i]->m_src = ops_processed[i]->m_dst; - ops[i]->m_dst = uncomp_bufs[i]; - ops[i]->src.offset = 0; - /* - * Set the length of the compressed data to the - * number of bytes that were produced in the previous stage - */ - ops[i]->src.length = ops_processed[i]->produced; - ops[i]->dst.offset = 0; - if (state == RTE_COMP_OP_STATELESS) { - ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL; - } else { - RTE_LOG(ERR, USER1, - "Stateful operations are not supported " - "in these tests yet\n"); - goto exit; - } - ops[i]->input_chksum = 0; - /* - * Copy private data from previous operations, - * to keep the pointer to the original buffer - */ - memcpy(ops[i] + 1, ops_processed[i] + 1, - sizeof(struct priv_op_data)); - } - - /* - * Free the previous compress operations, - * as they are not needed anymore - */ - rte_comp_op_bulk_free(ops_processed, num_bufs); - - /* Decompress data (either with Zlib API or compressdev API */ - if (zlib_dir == ZLIB_DECOMPRESS || zlib_dir == ZLIB_ALL) { - for (i = 0; i < num_bufs; i++) { - priv_data = (struct priv_op_data *)(ops[i] + 1); - uint16_t xform_idx = priv_data->orig_idx % num_xforms; - const struct rte_comp_xform *decompress_xform = - decompress_xforms[xform_idx]; - - ret = decompress_zlib(ops[i], decompress_xform); - if (ret < 0) - goto exit; - - ops_processed[i] = ops[i]; - } - } else { - /* Create decompress private xform data */ - for (i = 0; i < num_xforms; i++) { - ret = rte_compressdev_private_xform_create(0, - (const struct rte_comp_xform *)decompress_xforms[i], - &priv_xforms[i]); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Decompression private xform " - "could not be created\n"); - goto exit; - } - num_priv_xforms++; - } - - if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) { - /* Attach shareable private xform data to ops */ - for (i = 0; i < num_bufs; i++) { - priv_data = (struct priv_op_data *)(ops[i] + 1); - uint16_t xform_idx = priv_data->orig_idx % - num_xforms; - ops[i]->private_xform = priv_xforms[xform_idx]; - } - } else { - /* Create rest of the private xforms for the other ops */ - for (i = num_xforms; i < num_bufs; i++) { - ret = rte_compressdev_private_xform_create(0, - decompress_xforms[i % num_xforms], - &priv_xforms[i]); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Decompression private xform " - "could not be created\n"); - goto exit; - } - num_priv_xforms++; - } - - /* Attach non shareable private xform data to ops */ - for (i = 0; i < num_bufs; i++) { - priv_data = (struct priv_op_data *)(ops[i] + 1); - uint16_t xform_idx = priv_data->orig_idx; - ops[i]->private_xform = priv_xforms[xform_idx]; - } - } - - /* Enqueue and dequeue all operations */ - num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs); - if (num_enqd < num_bufs) { - RTE_LOG(ERR, USER1, - "The operations could not be enqueued\n"); - goto exit; - } - - num_total_deqd = 0; - do { - /* - * If retrying a dequeue call, wait for 10 ms to allow - * enough time to the driver to process the operations - */ - if (deqd_retries != 0) { - /* - * Avoid infinite loop if not all the - * operations get out of the device - */ - if (deqd_retries == MAX_DEQD_RETRIES) { - RTE_LOG(ERR, USER1, - "Not all operations could be " - "dequeued\n"); - goto exit; - } - usleep(DEQUEUE_WAIT_TIME); - } - num_deqd = rte_compressdev_dequeue_burst(0, 0, - &ops_processed[num_total_deqd], num_bufs); - num_total_deqd += num_deqd; - deqd_retries++; - } while (num_total_deqd < num_enqd); - - deqd_retries = 0; - } - - for (i = 0; i < num_bufs; i++) { - priv_data = (struct priv_op_data *)(ops_processed[i] + 1); - char engine[] = "zlib, (directly, no PMD)"; - if (zlib_dir != ZLIB_DECOMPRESS || zlib_dir != ZLIB_ALL) - strlcpy(engine, "pmd", sizeof(engine)); - RTE_LOG(DEBUG, USER1, - "Buffer %u decompressed by %s from %u to %u bytes\n", - buf_idx[priv_data->orig_idx], engine, - ops_processed[i]->consumed, ops_processed[i]->produced); - ops[i] = NULL; - } - - /* - * Check operation status and free source mbuf (destination mbuf and - * compress operation information is still needed) - */ - for (i = 0; i < num_bufs; i++) { - if (out_of_space && oos_zlib_compress) { - if (ops_processed[i]->status != - RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED) { - ret_status = -1; - - RTE_LOG(ERR, USER1, - "Operation without expected out of " - "space status error\n"); - goto exit; - } else - continue; - } - - if (ops_processed[i]->status != RTE_COMP_OP_STATUS_SUCCESS) { - RTE_LOG(ERR, USER1, - "Some operations were not successful\n"); - goto exit; - } - priv_data = (struct priv_op_data *)(ops_processed[i] + 1); - rte_pktmbuf_free(comp_bufs[priv_data->orig_idx]); - comp_bufs[priv_data->orig_idx] = NULL; - } - - if (out_of_space && oos_zlib_compress) { - ret_status = 0; - goto exit; - } - - /* - * Compare the original stream with the decompressed stream - * (in size and the data) - */ - for (i = 0; i < num_bufs; i++) { - priv_data = (struct priv_op_data *)(ops_processed[i] + 1); - const char *buf1 = test_bufs[priv_data->orig_idx]; - const char *buf2; - contig_buf = rte_malloc(NULL, ops_processed[i]->produced, 0); - if (contig_buf == NULL) { - RTE_LOG(ERR, USER1, "Contiguous buffer could not " - "be allocated\n"); - goto exit; - } - - buf2 = rte_pktmbuf_read(ops_processed[i]->m_dst, 0, - ops_processed[i]->produced, contig_buf); - if (compare_buffers(buf1, strlen(buf1) + 1, - buf2, ops_processed[i]->produced) < 0) - goto exit; - - /* Test checksums */ - if (compress_xforms[0]->compress.chksum != - RTE_COMP_CHECKSUM_NONE) { - if (ops_processed[i]->output_chksum != - compress_checksum[i]) { - RTE_LOG(ERR, USER1, "The checksums differ\n" - "Compression Checksum: %" PRIu64 "\tDecompression " - "Checksum: %" PRIu64 "\n", compress_checksum[i], - ops_processed[i]->output_chksum); - goto exit; - } - } - - rte_free(contig_buf); - contig_buf = NULL; - } - - ret_status = 0; - -exit: - /* Free resources */ - for (i = 0; i < num_bufs; i++) { - rte_pktmbuf_free(uncomp_bufs[i]); - rte_pktmbuf_free(comp_bufs[i]); - rte_comp_op_free(ops[i]); - rte_comp_op_free(ops_processed[i]); - } - for (i = 0; i < num_priv_xforms; i++) { - if (priv_xforms[i] != NULL) - rte_compressdev_private_xform_free(0, priv_xforms[i]); - } - rte_free(contig_buf); - - return ret_status; -} - -static int -test_compressdev_deflate_stateless_fixed(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - uint16_t i; - int ret; - const struct rte_compressdev_capabilities *capab; - - capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); - TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); - - if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_FIXED) == 0) - return -ENOTSUP; - - struct rte_comp_xform *compress_xform = - rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - - if (compress_xform == NULL) { - RTE_LOG(ERR, USER1, - "Compress xform could not be created\n"); - ret = TEST_FAILED; - goto exit; - } - - memcpy(compress_xform, ts_params->def_comp_xform, - sizeof(struct rte_comp_xform)); - compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_FIXED; - - struct interim_data_params int_data = { - NULL, - 1, - NULL, - &compress_xform, - &ts_params->def_decomp_xform, - 1 - }; - - struct test_data_params test_data = { - RTE_COMP_OP_STATELESS, - LB_BOTH, - ZLIB_DECOMPRESS, - 0 - }; - - for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { - int_data.test_bufs = &compress_test_bufs[i]; - int_data.buf_idx = &i; - - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - - /* Compress with Zlib, decompress with compressdev */ - test_data.zlib_dir = ZLIB_COMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - } - - ret = TEST_SUCCESS; - -exit: - rte_free(compress_xform); - return ret; -} - -static int -test_compressdev_deflate_stateless_dynamic(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - uint16_t i; - int ret; - struct rte_comp_xform *compress_xform = - rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - - const struct rte_compressdev_capabilities *capab; - - capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); - TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); - - if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_DYNAMIC) == 0) - return -ENOTSUP; - - if (compress_xform == NULL) { - RTE_LOG(ERR, USER1, - "Compress xform could not be created\n"); - ret = TEST_FAILED; - goto exit; - } - - memcpy(compress_xform, ts_params->def_comp_xform, - sizeof(struct rte_comp_xform)); - compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_DYNAMIC; - - struct interim_data_params int_data = { - NULL, - 1, - NULL, - &compress_xform, - &ts_params->def_decomp_xform, - 1 - }; - - struct test_data_params test_data = { - RTE_COMP_OP_STATELESS, - LB_BOTH, - ZLIB_DECOMPRESS, - 0 - }; - - for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { - int_data.test_bufs = &compress_test_bufs[i]; - int_data.buf_idx = &i; - - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - - /* Compress with Zlib, decompress with compressdev */ - test_data.zlib_dir = ZLIB_COMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - } - - ret = TEST_SUCCESS; - -exit: - rte_free(compress_xform); - return ret; -} - -static int -test_compressdev_deflate_stateless_multi_op(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - uint16_t num_bufs = RTE_DIM(compress_test_bufs); - uint16_t buf_idx[num_bufs]; - uint16_t i; - - for (i = 0; i < num_bufs; i++) - buf_idx[i] = i; - - struct interim_data_params int_data = { - compress_test_bufs, - num_bufs, - buf_idx, - &ts_params->def_comp_xform, - &ts_params->def_decomp_xform, - 1 - }; - - struct test_data_params test_data = { - RTE_COMP_OP_STATELESS, - LB_BOTH, - ZLIB_DECOMPRESS, - 0 - }; - - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) - return TEST_FAILED; - - /* Compress with Zlib, decompress with compressdev */ - test_data.zlib_dir = ZLIB_COMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) - return TEST_FAILED; - - return TEST_SUCCESS; -} - -static int -test_compressdev_deflate_stateless_multi_level(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - unsigned int level; - uint16_t i; - int ret; - struct rte_comp_xform *compress_xform = - rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - - if (compress_xform == NULL) { - RTE_LOG(ERR, USER1, - "Compress xform could not be created\n"); - ret = TEST_FAILED; - goto exit; - } - - memcpy(compress_xform, ts_params->def_comp_xform, - sizeof(struct rte_comp_xform)); - - struct interim_data_params int_data = { - NULL, - 1, - NULL, - &compress_xform, - &ts_params->def_decomp_xform, - 1 - }; - - struct test_data_params test_data = { - RTE_COMP_OP_STATELESS, - LB_BOTH, - ZLIB_DECOMPRESS, - 0 - }; - - for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { - int_data.test_bufs = &compress_test_bufs[i]; - int_data.buf_idx = &i; - - for (level = RTE_COMP_LEVEL_MIN; level <= RTE_COMP_LEVEL_MAX; - level++) { - compress_xform->compress.level = level; - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - } - } - - ret = TEST_SUCCESS; - -exit: - rte_free(compress_xform); - return ret; -} - -#define NUM_XFORMS 3 -static int -test_compressdev_deflate_stateless_multi_xform(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - uint16_t num_bufs = NUM_XFORMS; - struct rte_comp_xform *compress_xforms[NUM_XFORMS] = {NULL}; - struct rte_comp_xform *decompress_xforms[NUM_XFORMS] = {NULL}; - const char *test_buffers[NUM_XFORMS]; - uint16_t i; - unsigned int level = RTE_COMP_LEVEL_MIN; - uint16_t buf_idx[num_bufs]; - - int ret; - - /* Create multiple xforms with various levels */ - for (i = 0; i < NUM_XFORMS; i++) { - compress_xforms[i] = rte_malloc(NULL, - sizeof(struct rte_comp_xform), 0); - if (compress_xforms[i] == NULL) { - RTE_LOG(ERR, USER1, - "Compress xform could not be created\n"); - ret = TEST_FAILED; - goto exit; - } - - memcpy(compress_xforms[i], ts_params->def_comp_xform, - sizeof(struct rte_comp_xform)); - compress_xforms[i]->compress.level = level; - level++; - - decompress_xforms[i] = rte_malloc(NULL, - sizeof(struct rte_comp_xform), 0); - if (decompress_xforms[i] == NULL) { - RTE_LOG(ERR, USER1, - "Decompress xform could not be created\n"); - ret = TEST_FAILED; - goto exit; - } - - memcpy(decompress_xforms[i], ts_params->def_decomp_xform, - sizeof(struct rte_comp_xform)); - } - - for (i = 0; i < NUM_XFORMS; i++) { - buf_idx[i] = 0; - /* Use the same buffer in all sessions */ - test_buffers[i] = compress_test_bufs[0]; - } - - struct interim_data_params int_data = { - test_buffers, - num_bufs, - buf_idx, - compress_xforms, - decompress_xforms, - NUM_XFORMS - }; - - struct test_data_params test_data = { - RTE_COMP_OP_STATELESS, - LB_BOTH, - ZLIB_DECOMPRESS, - 0 - }; - - /* Compress with compressdev, decompress with Zlib */ - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - - ret = TEST_SUCCESS; -exit: - for (i = 0; i < NUM_XFORMS; i++) { - rte_free(compress_xforms[i]); - rte_free(decompress_xforms[i]); - } - - return ret; -} - -static int -test_compressdev_deflate_stateless_sgl(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - uint16_t i; - const struct rte_compressdev_capabilities *capab; - - capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); - TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); - - if ((capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) == 0) - return -ENOTSUP; - - struct interim_data_params int_data = { - NULL, - 1, - NULL, - &ts_params->def_comp_xform, - &ts_params->def_decomp_xform, - 1 - }; - - struct test_data_params test_data = { - RTE_COMP_OP_STATELESS, - SGL_BOTH, - ZLIB_DECOMPRESS, - 0 - }; - - for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { - int_data.test_bufs = &compress_test_bufs[i]; - int_data.buf_idx = &i; - - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) - return TEST_FAILED; - - /* Compress with Zlib, decompress with compressdev */ - test_data.zlib_dir = ZLIB_COMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) - return TEST_FAILED; - - if (capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_LB_OUT) { - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - test_data.buff_type = SGL_TO_LB; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) - return TEST_FAILED; - - /* Compress with Zlib, decompress with compressdev */ - test_data.zlib_dir = ZLIB_COMPRESS; - test_data.buff_type = SGL_TO_LB; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) - return TEST_FAILED; - } - - if (capab->comp_feature_flags & RTE_COMP_FF_OOP_LB_IN_SGL_OUT) { - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - test_data.buff_type = LB_TO_SGL; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) - return TEST_FAILED; - - /* Compress with Zlib, decompress with compressdev */ - test_data.zlib_dir = ZLIB_COMPRESS; - test_data.buff_type = LB_TO_SGL; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) - return TEST_FAILED; - } - - - } - - return TEST_SUCCESS; - -} - -static int -test_compressdev_deflate_stateless_checksum(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - uint16_t i; - int ret; - const struct rte_compressdev_capabilities *capab; - - capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); - TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); - - /* Check if driver supports any checksum */ - if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_CHECKSUM) == 0 && - (capab->comp_feature_flags & - RTE_COMP_FF_ADLER32_CHECKSUM) == 0 && - (capab->comp_feature_flags & - RTE_COMP_FF_CRC32_ADLER32_CHECKSUM) == 0) - return -ENOTSUP; - - struct rte_comp_xform *compress_xform = - rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - if (compress_xform == NULL) { - RTE_LOG(ERR, USER1, "Compress xform could not be created\n"); - ret = TEST_FAILED; - return ret; - } - - memcpy(compress_xform, ts_params->def_comp_xform, - sizeof(struct rte_comp_xform)); - - struct rte_comp_xform *decompress_xform = - rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - if (decompress_xform == NULL) { - RTE_LOG(ERR, USER1, "Decompress xform could not be created\n"); - rte_free(compress_xform); - ret = TEST_FAILED; - return ret; - } - - memcpy(decompress_xform, ts_params->def_decomp_xform, - sizeof(struct rte_comp_xform)); - - struct interim_data_params int_data = { - NULL, - 1, - NULL, - &compress_xform, - &decompress_xform, - 1 - }; - - struct test_data_params test_data = { - RTE_COMP_OP_STATELESS, - LB_BOTH, - ZLIB_DECOMPRESS, - 0 - }; - - /* Check if driver supports crc32 checksum and test */ - if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_CHECKSUM)) { - compress_xform->compress.chksum = RTE_COMP_CHECKSUM_CRC32; - decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_CRC32; - - for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { - /* Compress with compressdev, decompress with Zlib */ - int_data.test_bufs = &compress_test_bufs[i]; - int_data.buf_idx = &i; - - /* Generate zlib checksum and test against selected - * drivers decompression checksum - */ - test_data.zlib_dir = ZLIB_COMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - - /* Generate compression and decompression - * checksum of selected driver - */ - test_data.zlib_dir = ZLIB_NONE; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - } - } - - /* Check if driver supports adler32 checksum and test */ - if ((capab->comp_feature_flags & RTE_COMP_FF_ADLER32_CHECKSUM)) { - compress_xform->compress.chksum = RTE_COMP_CHECKSUM_ADLER32; - decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_ADLER32; - - for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { - int_data.test_bufs = &compress_test_bufs[i]; - int_data.buf_idx = &i; - - /* Generate zlib checksum and test against selected - * drivers decompression checksum - */ - test_data.zlib_dir = ZLIB_COMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - /* Generate compression and decompression - * checksum of selected driver - */ - test_data.zlib_dir = ZLIB_NONE; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - } - } - - /* Check if driver supports combined crc and adler checksum and test */ - if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_ADLER32_CHECKSUM)) { - compress_xform->compress.chksum = - RTE_COMP_CHECKSUM_CRC32_ADLER32; - decompress_xform->decompress.chksum = - RTE_COMP_CHECKSUM_CRC32_ADLER32; - - for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { - int_data.test_bufs = &compress_test_bufs[i]; - int_data.buf_idx = &i; - - /* Generate compression and decompression - * checksum of selected driver - */ - test_data.zlib_dir = ZLIB_NONE; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - } - } - - ret = TEST_SUCCESS; - -exit: - rte_free(compress_xform); - rte_free(decompress_xform); - return ret; -} - -static int -test_compressdev_out_of_space_buffer(void) -{ - struct comp_testsuite_params *ts_params = &testsuite_params; - int ret; - uint16_t i; - const struct rte_compressdev_capabilities *capab; - - RTE_LOG(INFO, USER1, "This is a negative test errors are expected\n"); - - capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); - TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); - - if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_FIXED) == 0) - return -ENOTSUP; - - struct rte_comp_xform *compress_xform = - rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - - if (compress_xform == NULL) { - RTE_LOG(ERR, USER1, - "Compress xform could not be created\n"); - ret = TEST_FAILED; - goto exit; - } - - struct interim_data_params int_data = { - &compress_test_bufs[0], - 1, - &i, - &ts_params->def_comp_xform, - &ts_params->def_decomp_xform, - 1 - }; - - struct test_data_params test_data = { - RTE_COMP_OP_STATELESS, - LB_BOTH, - ZLIB_DECOMPRESS, - 1 - }; - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - - /* Compress with Zlib, decompress with compressdev */ - test_data.zlib_dir = ZLIB_COMPRESS; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - - if (capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) { - /* Compress with compressdev, decompress with Zlib */ - test_data.zlib_dir = ZLIB_DECOMPRESS; - test_data.buff_type = SGL_BOTH; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - - /* Compress with Zlib, decompress with compressdev */ - test_data.zlib_dir = ZLIB_COMPRESS; - test_data.buff_type = SGL_BOTH; - if (test_deflate_comp_decomp(&int_data, &test_data) < 0) { - ret = TEST_FAILED; - goto exit; - } - } - - ret = TEST_SUCCESS; - -exit: - rte_free(compress_xform); - return ret; -} - - -static struct unit_test_suite compressdev_testsuite = { - .suite_name = "compressdev unit test suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(NULL, NULL, - test_compressdev_invalid_configuration), - TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, - test_compressdev_deflate_stateless_fixed), - TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, - test_compressdev_deflate_stateless_dynamic), - TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, - test_compressdev_deflate_stateless_multi_op), - TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, - test_compressdev_deflate_stateless_multi_level), - TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, - test_compressdev_deflate_stateless_multi_xform), - TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, - test_compressdev_deflate_stateless_sgl), - TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, - test_compressdev_deflate_stateless_checksum), - TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, - test_compressdev_out_of_space_buffer), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_compressdev(void) -{ - return unit_test_suite_runner(&compressdev_testsuite); -} - -REGISTER_TEST_COMMAND(compressdev_autotest, test_compressdev); diff --git a/test/test/test_compressdev_test_buffer.h b/test/test/test_compressdev_test_buffer.h deleted file mode 100644 index c0492f89a2..0000000000 --- a/test/test/test_compressdev_test_buffer.h +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef TEST_COMPRESSDEV_TEST_BUFFERS_H_ -#define TEST_COMPRESSDEV_TEST_BUFFERS_H_ - -/* - * These test buffers are snippets obtained - * from the Canterbury and Calgary Corpus - * collection. - */ - -/* Snippet of Alice's Adventures in Wonderland */ -static const char test_buf_alice[] = - " Alice was beginning to get very tired of sitting by her sister\n" - "on the bank, and of having nothing to do: once or twice she had\n" - "peeped into the book her sister was reading, but it had no\n" - "pictures or conversations in it, `and what is the use of a book,'\n" - "thought Alice `without pictures or conversation?'\n\n" - " So she was considering in her own mind (as well as she could,\n" - "for the hot day made her feel very sleepy and stupid), whether\n" - "the pleasure of making a daisy-chain would be worth the trouble\n" - "of getting up and picking the daisies, when suddenly a White\n" - "Rabbit with pink eyes ran close by her.\n\n" - " There was nothing so VERY remarkable in that; nor did Alice\n" - "think it so VERY much out of the way to hear the Rabbit say to\n" - "itself, `Oh dear! Oh dear! I shall be late!' (when she thought\n" - "it over afterwards, it occurred to her that she ought to have\n" - "wondered at this, but at the time it all seemed quite natural);\n" - "but when the Rabbit actually TOOK A WATCH OUT OF ITS WAISTCOAT-\n" - "POCKET, and looked at it, and then hurried on, Alice started to\n" - "her feet, for it flashed across her mind that she had never\n" - "before seen a rabbit with either a waistcoat-pocket, or a watch to\n" - "take out of it, and burning with curiosity, she ran across the\n" - "field after it, and fortunately was just in time to see it pop\n" - "down a large rabbit-hole under the hedge.\n\n" - " In another moment down went Alice after it, never once\n" - "considering how in the world she was to get out again.\n\n" - " The rabbit-hole went straight on like a tunnel for some way,\n" - "and then dipped suddenly down, so suddenly that Alice had not a\n" - "moment to think about stopping herself before she found herself\n" - "falling down a very deep well.\n\n" - " Either the well was very deep, or she fell very slowly, for she\n" - "had plenty of time as she went down to look about her and to\n" - "wonder what was going to happen next. First, she tried to look\n" - "down and make out what she was coming to, but it was too dark to\n" - "see anything; then she looked at the sides of the well, and\n" - "noticed that they were filled with cupboards and book-shelves;\n" - "here and there she saw maps and pictures hung upon pegs. She\n" - "took down a jar from one of the shelves as she passed; it was\n" - "labelled `ORANGE MARMALADE', but to her great disappointment it\n" - "was empty: she did not like to drop the jar for fear of killing\n" - "somebody, so managed to put it into one of the cupboards as she\n" - "fell past it.\n\n" - " `Well!' thought Alice to herself, `after such a fall as this, I\n" - "shall think nothing of tumbling down stairs! How brave they'll\n" - "all think me at home! Why, I wouldn't say anything about it,\n" - "even if I fell off the top of the house!' (Which was very likely\n" - "true.)\n\n" - " Down, down, down. Would the fall NEVER come to an end! `I\n" - "wonder how many miles I've fallen by this time?' she said aloud.\n" - "`I must be getting somewhere near the centre of the earth. Let\n" - "me see: that would be four thousand miles down, I think--' (for,\n" - "you see, Alice had learnt several things of this sort in her\n" - "lessons in the schoolroom, and though this was not a VERY good\n" - "opportunity for showing off her knowledge, as there was no one to\n" - "listen to her, still it was good practice to say it over) `--yes,\n" - "that's about the right distance--but then I wonder what Latitude\n" - "or Longitude I've got to?' (Alice had no idea what Latitude was,\n" - "or Longitude either, but thought they were nice grand words to\n" - "say.)\n\n" - " Presently she began again. `I wonder if I shall fall right\n" - "THROUGH the earth! How funny it'll seem to come out among the\n" - "people that walk with their heads downward! The Antipathies, I\n" - "think--' (she was rather glad there WAS no one listening, this\n" - "time, as it didn't sound at all the right word) `--but I shall\n" - "have to ask them what the name of the country is, you know.\n" - "Please, Ma'am, is this New Zealand or Australia?' (and she tried\n" - "to curtsey as she spoke--fancy CURTSEYING as you're falling\n" - "through the air! Do you think you could manage it?) `And what\n" - "an ignorant little girl she'll think me for asking! No, it'll\n" - "never do to ask: perhaps I shall see it written up somewhere.'\n" - " Down, down, down. There was nothing else to do, so Alice soon\n" - "began talking again. `Dinah'll miss me very much to-night, I\n" - "should think!' (Dinah was the cat.) `I hope they'll remember\n" - "her saucer of milk at tea-time. Dinah my dear! I wish you were\n" - "down here with me! There are no mice in the air, I'm afraid, but\n" - "you might catch a bat, and that's very like a mouse, you know.\n" - "But do cats eat bats, I wonder?' And here Alice began to get\n" - "rather sleepy, and went on saying to herself, in a dreamy sort of\n" - "way, `Do cats eat bats? Do cats eat bats?' and sometimes, `Do\n" - "bats eat cats?' for, you see, as she couldn't answer either\n" - "question, it didn't much matter which way she put it. She felt\n" - "that she was dozing off, and had just begun to dream that she\n" - "was walking hand in hand with Dinah, and saying to her very\n" - "earnestly, `Now, Dinah, tell me the truth: did you ever eat a\n" - "bat?' when suddenly, thump! thump! down she came upon a heap of\n" - "sticks and dry leaves, and the fall was over.\n\n"; - -/* Snippet of Shakespeare play */ -static const char test_buf_shakespeare[] = - "CHARLES wrestler to Frederick.\n" - "\n" - "\n" - "OLIVER |\n" - " |\n" - "JAQUES (JAQUES DE BOYS:) | sons of Sir Rowland de Boys.\n" - " |\n" - "ORLANDO |\n" - "\n" - "\n" - "ADAM |\n" - " | servants to Oliver.\n" - "DENNIS |\n" - "\n" - "\n" - "TOUCHSTONE a clown.\n" - "\n" - "SIR OLIVER MARTEXT a vicar.\n" - "\n" - "\n" - "CORIN |\n" - " | shepherds.\n" - "SILVIUS |\n" - "\n" - "\n" - "WILLIAM a country fellow in love with Audrey.\n" - "\n" - " A person representing HYMEN. (HYMEN:)\n" - "\n" - "ROSALIND daughter to the banished duke.\n" - "\n" - "CELIA daughter to Frederick.\n" - "\n" - "PHEBE a shepherdess.\n" - "\n" - "AUDREY a country wench.\n" - "\n" - " Lords, pages, and attendants, &c.\n" - " (Forester:)\n" - " (A Lord:)\n" - " (First Lord:)\n" - " (Second Lord:)\n" - " (First Page:)\n" - " (Second Page:)\n" - "\n" - "\n" - "SCENE Oliver's house; Duke Frederick's court; and the\n" - " Forest of Arden.\n" - "\n" - "\n" - "\n" - "\n" - " AS YOU LIKE IT\n" - "\n" - "\n" - "ACT I\n" - "\n" - "\n" - "\n" - "SCENE I Orchard of Oliver's house.\n" - "\n" - "\n" - " [Enter ORLANDO and ADAM]\n" - "\n" - "ORLANDO As I remember, Adam, it was upon this fashion\n" - " bequeathed me by will but poor a thousand crowns,\n" - " and, as thou sayest, charged my brother, on his\n" - " blessing, to breed me well: and there begins my\n" - " sadness. My brother Jaques he keeps at school, and\n" - " report speaks goldenly of his profit: for my part,\n" - " he keeps me rustically at home, or, to speak more\n" - " properly, stays me here at home unkept; for call you\n" - " that keeping for a gentleman of my birth, that\n" - " differs not from the stalling of an ox? His horses\n" - " are bred better; for, besides that they are fair\n" - " with their feeding, they are taught their manage,\n" - " and to that end riders dearly hired: but I, his\n" - " brother, gain nothing under him but growth; for the\n" - " which his animals on his dunghills are as much\n" - " bound to him as I. Besides this nothing that he so\n" - " plentifully gives me, the something that nature gave\n" - " me his countenance seems to take from me: he lets\n" - " me feed with his hinds, bars me the place of a\n" - " brother, and, as much as in him lies, mines my\n" - " gentility with my education. This is it, Adam, that\n" - " grieves me; and the spirit of my father, which I\n" - " think is within me, begins to mutiny against this\n" - " servitude: I will no longer endure it, though yet I\n" - " know no wise remedy how to avoid it.\n" - "\n" - "ADAM Yonder comes my master, your brother.\n" - "\n" - "ORLANDO Go apart, Adam, and thou shalt hear how he will\n"; - -/* Snippet of source code in Pascal */ -static const char test_buf_pascal[] = - " Ptr = 1..DMem;\n" - " Loc = 1..IMem;\n" - " Loc0 = 0..IMem;\n" - " EdgeT = (hout,lin,hin,lout); {Warning this order is important in}\n" - " {predicates such as gtS,geS}\n" - " CardT = (finite,infinite);\n" - " ExpT = Minexp..Maxexp;\n" - " ManT = Mininf..Maxinf; \n" - " Pflag = (PNull,PSoln,PTrace,PPrint);\n" - " Sreal = record\n" - " edge:EdgeT;\n" - " cardinality:CardT;\n" - " exp:ExpT; {exponent}\n" - " mantissa:ManT;\n" - " end;\n" - " Int = record\n" - " hi:Sreal;\n" - " lo:Sreal;\n" - " end;\n" - " Instr = record\n" - " Code:OpType;\n" - " Pars: array[0..Par] of 0..DMem;\n" - " end;\n" - " DataMem= record\n" - " D :array [Ptr] of Int;\n" - " S :array [Loc] of State;\n" - " LastHalve:Loc;\n" - " RHalve :array [Loc] of real;\n" - " end;\n" - " DataFlags=record\n" - " PF :array [Ptr] of Pflag;\n" - " end;\n" - "var\n" - " Debug : (none,activity,post,trace,dump);\n" - " Cut : (once,all);\n" - " GlobalEnd,Verifiable:boolean;\n" - " HalveThreshold:real;\n" - " I : array [Loc] of Instr; {Memory holding instructions}\n" - " End : Loc; {last instruction in I}\n" - " ParN : array [OpType] of -1..Par; {number of parameters for each \n" - " opcode. -1 means no result}\n" - " ParIntersect : array [OpType] of boolean ;\n" - " DInit : DataMem; {initial memory which is cleared and \n" - " used in first call}\n" - " DF : DataFlags; {hold flags for variables, e.g. print/trace}\n" - " MaxDMem:0..DMem;\n" - " Shift : array[0..Digits] of 1..maxint;{array of constant multipliers}\n" - " {used for alignment etc.}\n" - " Dummy :Positive;\n" - " {constant intervals and Sreals}\n" - " PlusInfS,MinusInfS,PlusSmallS,MinusSmallS,ZeroS,\n" - " PlusFiniteS,MinusFiniteS:Sreal;\n" - " Zero,All,AllFinite:Int;\n" - "\n" - "procedure deblank;\n" - "var Ch:char;\n" - "begin\n" - " while (not eof) and (input^ in [' ',' ']) do read(Ch);\n" - "end;\n" - "\n" - "procedure InitialOptions;\n" - "\n" - "#include '/user/profs/cleary/bin/options.i';\n" - "\n" - " procedure Option;\n" - " begin\n" - " case Opt of\n" - " 'a','A':Debug:=activity;\n" - " 'd','D':Debug:=dump;\n" - " 'h','H':HalveThreshold:=StringNum/100;\n" - " 'n','N':Debug:=none;\n" - " 'p','P':Debug:=post;\n" - " 't','T':Debug:=trace;\n" - " 'v','V':Verifiable:=true;\n" - " end;\n" - " end;\n" - "\n" - "begin\n" - " Debug:=trace;\n" - " Verifiable:=false;\n" - " HalveThreshold:=67/100;\n" - " Options;\n" - " writeln(Debug);\n" - " writeln('Verifiable:',Verifiable);\n" - " writeln('Halve threshold',HalveThreshold);\n" - "end;{InitialOptions}\n" - "\n" - "procedure NormalizeUp(E,M:integer;var S:Sreal;var Closed:boolean);\n" - "begin\n" - "with S do\n" - "begin\n" - " if M=0 then S:=ZeroS else\n" - " if M>0 then\n"; - -static const char * const compress_test_bufs[] = { - test_buf_alice, - test_buf_shakespeare, - test_buf_pascal -}; - -#endif /* TEST_COMPRESSDEV_TEST_BUFFERS_H_ */ diff --git a/test/test/test_cpuflags.c b/test/test/test_cpuflags.c deleted file mode 100644 index 06718631f0..0000000000 --- a/test/test/test_cpuflags.c +++ /dev/null @@ -1,176 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 AVX512F:\t"); - CHECK_FOR_FLAG(RTE_CPUFLAG_AVX512F); - - 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_crc.c b/test/test/test_crc.c deleted file mode 100644 index f8a74e04ee..0000000000 --- a/test/test/test_crc.c +++ /dev/null @@ -1,164 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#include "test.h" - -#include -#include -#include -#include - -#define CRC_VEC_LEN 32 -#define CRC32_VEC_LEN1 1512 -#define CRC32_VEC_LEN2 348 -#define CRC16_VEC_LEN1 12 -#define CRC16_VEC_LEN2 2 -#define LINE_LEN 75 - -/* CRC test vector */ -static const uint8_t crc_vec[CRC_VEC_LEN] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'A', 'B', 'C', 'D', - 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', -}; - -/* 32-bit CRC test vector */ -static const uint8_t crc32_vec1[12] = { - 0xBE, 0xD7, 0x23, 0x47, 0x6B, 0x8F, - 0xB3, 0x14, 0x5E, 0xFB, 0x35, 0x59, -}; - -/* 16-bit CRC test vector 1 */ -static const uint8_t crc16_vec1[CRC16_VEC_LEN1] = { - 0x0D, 0x01, 0x01, 0x23, 0x45, 0x67, - 0x89, 0x01, 0x23, 0x45, 0x00, 0x01, -}; - -/* 16-bit CRC test vector 2 */ -static const uint8_t crc16_vec2[CRC16_VEC_LEN2] = { - 0x03, 0x3f, -}; -/** CRC results */ -static const uint32_t crc32_vec_res = 0xb491aab4; -static const uint32_t crc32_vec1_res = 0xac54d294; -static const uint32_t crc32_vec2_res = 0xefaae02f; -static const uint32_t crc16_vec_res = 0x6bec; -static const uint16_t crc16_vec1_res = 0x8cdd; -static const uint16_t crc16_vec2_res = 0xec5b; - -static int -crc_calc(const uint8_t *vec, - uint32_t vec_len, - enum rte_net_crc_type type) -{ - /* compute CRC */ - uint32_t ret = rte_net_crc_calc(vec, vec_len, type); - - /* dump data on console */ - debug_hexdump(stdout, NULL, vec, vec_len); - - return ret; -} - -static int -test_crc_calc(void) -{ - uint32_t i; - enum rte_net_crc_type type; - uint8_t *test_data; - uint32_t result; - int error; - - /* 32-bit ethernet CRC: Test 1 */ - type = RTE_NET_CRC32_ETH; - - result = crc_calc(crc_vec, CRC_VEC_LEN, type); - if (result != crc32_vec_res) - return -1; - - /* 32-bit ethernet CRC: Test 2 */ - test_data = rte_zmalloc(NULL, CRC32_VEC_LEN1, 0); - - for (i = 0; i < CRC32_VEC_LEN1; i += 12) - rte_memcpy(&test_data[i], crc32_vec1, 12); - - result = crc_calc(test_data, CRC32_VEC_LEN1, type); - if (result != crc32_vec1_res) { - error = -2; - goto fail; - } - - /* 32-bit ethernet CRC: Test 3 */ - for (i = 0; i < CRC32_VEC_LEN2; i += 12) - rte_memcpy(&test_data[i], crc32_vec1, 12); - - result = crc_calc(test_data, CRC32_VEC_LEN2, type); - if (result != crc32_vec2_res) { - error = -3; - goto fail; - } - - /* 16-bit CCITT CRC: Test 4 */ - type = RTE_NET_CRC16_CCITT; - result = crc_calc(crc_vec, CRC_VEC_LEN, type); - if (result != crc16_vec_res) { - error = -4; - goto fail; - } - /* 16-bit CCITT CRC: Test 5 */ - result = crc_calc(crc16_vec1, CRC16_VEC_LEN1, type); - if (result != crc16_vec1_res) { - error = -5; - goto fail; - } - /* 16-bit CCITT CRC: Test 6 */ - result = crc_calc(crc16_vec2, CRC16_VEC_LEN2, type); - if (result != crc16_vec2_res) { - error = -6; - goto fail; - } - - rte_free(test_data); - return 0; - -fail: - rte_free(test_data); - return error; -} - -static int -test_crc(void) -{ - int ret; - /* set CRC scalar mode */ - rte_net_crc_set_alg(RTE_NET_CRC_SCALAR); - - ret = test_crc_calc(); - if (ret < 0) { - printf("test_crc (scalar): failed (%d)\n", ret); - return ret; - } - /* set CRC sse4.2 mode */ - rte_net_crc_set_alg(RTE_NET_CRC_SSE42); - - ret = test_crc_calc(); - if (ret < 0) { - printf("test_crc (x86_64_SSE4.2): failed (%d)\n", ret); - return ret; - } - - /* set CRC neon mode */ - rte_net_crc_set_alg(RTE_NET_CRC_NEON); - - ret = test_crc_calc(); - if (ret < 0) { - printf("test crc (arm64 neon pmull): failed (%d)\n", ret); - return ret; - } - - return 0; -} - -REGISTER_TEST_COMMAND(crc_autotest, test_crc); diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c deleted file mode 100644 index 32f1893bce..0000000000 --- a/test/test/test_cryptodev.c +++ /dev/null @@ -1,10846 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015-2017 Intel Corporation - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER -#include -#include -#endif - -#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_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_aead_test_vectors.h" -#include "test_cryptodev_hmac_test_vectors.h" - -#define VDEV_ARGS_SIZE 100 -#define MAX_NB_SESSIONS 4 - -static int gbl_driver_id; - -struct crypto_testsuite_params { - struct rte_mempool *mbuf_pool; - struct rte_mempool *large_mbuf_pool; - struct rte_mempool *op_mpool; - struct rte_mempool *session_mpool; - struct rte_mempool *session_priv_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_crypto_sym_xform aead_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) + - MAXIMUM_IV_LENGTH, - rte_socket_id()); - if (ts_params->op_mpool == NULL) { - RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); - return TEST_FAILED; - } - - /* Create an AESNI MB device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD))); - if (nb_devs < 1) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), NULL); - - TEST_ASSERT(ret == 0, - "Failed to create instance of" - " pmd : %s", - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - } - } - - /* Create an AESNI GCM device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD))); - if (nb_devs < 1) { - TEST_ASSERT_SUCCESS(rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD), NULL), - "Failed to create instance of" - " pmd : %s", - RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD)); - } - } - - /* Create a SNOW 3G device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD))); - if (nb_devs < 1) { - TEST_ASSERT_SUCCESS(rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD), NULL), - "Failed to create instance of" - " pmd : %s", - RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD)); - } - } - - /* Create a KASUMI device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_KASUMI_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_KASUMI_PMD))); - if (nb_devs < 1) { - TEST_ASSERT_SUCCESS(rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_KASUMI_PMD), NULL), - "Failed to create instance of" - " pmd : %s", - RTE_STR(CRYPTODEV_NAME_KASUMI_PMD)); - } - } - - /* Create a ZUC device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ZUC_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ZUC_PMD))); - if (nb_devs < 1) { - TEST_ASSERT_SUCCESS(rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_ZUC_PMD), NULL), - "Failed to create instance of" - " pmd : %s", - RTE_STR(CRYPTODEV_NAME_ZUC_PMD)); - } - } - - /* Create a NULL device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_NULL_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_NULL_PMD))); - if (nb_devs < 1) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_NULL_PMD), NULL); - - TEST_ASSERT(ret == 0, - "Failed to create instance of" - " pmd : %s", - RTE_STR(CRYPTODEV_NAME_NULL_PMD)); - } - } - - /* Create an OPENSSL device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))); - if (nb_devs < 1) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance of pmd : %s", - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); - } - } - - /* Create a ARMv8 device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD))); - if (nb_devs < 1) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance of pmd : %s", - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); - } - } - - /* Create a MVSAM device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD))); - if (nb_devs < 1) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance of pmd : %s", - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)); - } - } - - /* Create an CCP device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_PMD))); - if (nb_devs < 1) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_CCP_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance of pmd : %s", - RTE_STR(CRYPTODEV_NAME_CCP_PMD)); - } - } - -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER - char vdev_args[VDEV_ARGS_SIZE] = {""}; - char temp_str[VDEV_ARGS_SIZE] = {"mode=multi-core," - "ordering=enable,name=cryptodev_test_scheduler,corelist="}; - uint16_t slave_core_count = 0; - uint16_t socket_id = 0; - - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD))) { - - /* Identify the Slave Cores - * Use 2 slave cores for the device args - */ - RTE_LCORE_FOREACH_SLAVE(i) { - if (slave_core_count > 1) - break; - snprintf(vdev_args, sizeof(vdev_args), - "%s%d", temp_str, i); - strcpy(temp_str, vdev_args); - strcat(temp_str, ";"); - slave_core_count++; - socket_id = lcore_config[i].socket_id; - } - if (slave_core_count != 2) { - RTE_LOG(ERR, USER1, - "Cryptodev scheduler test require at least " - "two slave cores to run. " - "Please use the correct coremask.\n"); - return TEST_FAILED; - } - strcpy(temp_str, vdev_args); - snprintf(vdev_args, sizeof(vdev_args), "%s,socket_id=%d", - temp_str, socket_id); - RTE_LOG(DEBUG, USER1, "vdev_args: %s\n", vdev_args); - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD))); - if (nb_devs < 1) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD), - vdev_args); - 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 */ - - 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.driver_id == gbl_driver_id) - 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; - - unsigned int session_size = - rte_cryptodev_sym_get_private_session_size(dev_id); - - /* - * Create mempool with maximum number of sessions * 2, - * to include the session headers - */ - if (info.sym.max_nb_sessions != 0 && - info.sym.max_nb_sessions < MAX_NB_SESSIONS) { - RTE_LOG(ERR, USER1, "Device does not support " - "at least %u sessions\n", - MAX_NB_SESSIONS); - return TEST_FAILED; - } - - ts_params->session_mpool = rte_cryptodev_sym_session_pool_create( - "test_sess_mp", MAX_NB_SESSIONS, 0, 0, 0, - SOCKET_ID_ANY); - TEST_ASSERT_NOT_NULL(ts_params->session_mpool, - "session mempool allocation failed"); - - ts_params->session_priv_mpool = rte_mempool_create( - "test_sess_mp_priv", - MAX_NB_SESSIONS, - session_size, - 0, 0, NULL, NULL, NULL, - NULL, SOCKET_ID_ANY, - 0); - TEST_ASSERT_NOT_NULL(ts_params->session_priv_mpool, - "session mempool allocation failed"); - - - - 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; - ts_params->qp_conf.mp_session = ts_params->session_mpool; - ts_params->qp_conf.mp_session_private = ts_params->session_priv_mpool; - - 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)); - } - - /* Free session mempools */ - if (ts_params->session_priv_mpool != NULL) { - rte_mempool_free(ts_params->session_priv_mpool); - ts_params->session_priv_mpool = NULL; - } - - if (ts_params->session_mpool != NULL) { - rte_mempool_free(ts_params->session_mpool); - ts_params->session_mpool = NULL; - } -} - -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->qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT; - ts_params->qp_conf.mp_session = ts_params->session_mpool; - ts_params->qp_conf.mp_session_private = ts_params->session_priv_mpool; - - 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_clear(ts_params->valid_devs[0], - ut_params->sess); - rte_cryptodev_sym_session_free(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(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 = orig_nb_qps; - - 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 = orig_nb_qps + 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); - - 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*/ - qp_conf.mp_session = ts_params->session_mpool; - qp_conf.mp_session_private = ts_params->session_priv_mpool; - - 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 = ts_params->conf.nb_queue_pairs; /*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; - ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; - ut_params->cipher_xform.cipher.iv.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_GENERATE; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1; - ut_params->auth_xform.auth.key.data = hmac_sha1_key; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - /* Create crypto session*/ - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, &ut_params->cipher_xform, - ts_params->session_priv_mpool); - 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_iova_offset( - ut_params->ibuf, QUOTE_512_BYTES); - - sym_op->auth.data.offset = 0; - sym_op->auth.data.length = QUOTE_512_BYTES; - - /* Copy IV at the end of the crypto operation */ - rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), - aes_cbc_iv, CIPHER_IV_LENGTH_AES_CBC); - - /* Set crypto operation cipher parameters */ - sym_op->cipher.data.offset = 0; - 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(ut_params->op->sym->m_src, - uint8_t *); - - 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_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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; - ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; - ut_params->cipher_xform.cipher.iv.length = CIPHER_IV_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_iova_offset( - ut_params->ibuf, QUOTE_512_BYTES); - - sym_op->auth.data.offset = 0; - sym_op->auth.data.length = QUOTE_512_BYTES; - - /* Copy IV at the end of the crypto operation */ - rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), - iv, CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = 0; - 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 *), - 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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_docsis_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), - BLKCIPHER_AES_DOCSIS_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_docsis_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)), - BLKCIPHER_AES_DOCSIS_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_DES_docsis_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)), - BLKCIPHER_DES_DOCSIS_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), - BLKCIPHER_AUTHONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_QAT_SYM_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_ccp_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_PMD)), - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_ccp_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_virtio_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_caam_jr_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_caam_jr_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_caam_jr_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), - BLKCIPHER_AUTHONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - - -static int -test_AES_chain_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), - BLKCIPHER_AUTHONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), - BLKCIPHER_AUTHONLY_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), - BLKCIPHER_AUTHONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_ccp_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)), - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_mrvl_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_mrvl_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_mrvl_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), - BLKCIPHER_AUTHONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_chain_mrvl_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), - BLKCIPHER_3DES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_cipheronly_mrvl_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)), - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_chain_octeontx_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->session_mpool, - ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), - BLKCIPHER_AES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_AES_cipheronly_octeontx_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->session_mpool, - ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), - BLKCIPHER_AES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_chain_octeontx_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->session_mpool, - ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), - BLKCIPHER_3DES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_cipheronly_octeontx_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->session_mpool, - ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_authonly_octeontx_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->session_mpool, - ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)), - BLKCIPHER_AUTHONLY_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 iv_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_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - memcpy(hash_key, key, key_len); - - debug_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.iv.offset = IV_OFFSET; - ut_params->auth_xform.auth.iv.length = iv_len; - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->auth_xform, - ts_params->session_priv_mpool); - 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 iv_len) -{ - uint8_t cipher_key[key_len]; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - 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; - ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; - ut_params->cipher_xform.cipher.iv.length = iv_len; - - debug_hexdump(stdout, "key:", key, key_len); - - /* Create Crypto session */ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->cipher_xform, - ts_params->session_priv_mpool); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - return 0; -} - -static int -create_wireless_algo_cipher_operation(const uint8_t *iv, uint8_t iv_len, - unsigned int cipher_len, - unsigned int cipher_offset) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* 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 */ - rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), - 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, uint8_t iv_len, - unsigned int cipher_len, - unsigned int cipher_offset) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* 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 */ - rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), - 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, uint8_t key_len, - uint8_t auth_iv_len, uint8_t auth_len, - uint8_t cipher_iv_len) - -{ - uint8_t cipher_auth_key[key_len]; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - 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; - /* Auth IV will be after cipher IV */ - ut_params->auth_xform.auth.iv.offset = IV_OFFSET + cipher_iv_len; - ut_params->auth_xform.auth.iv.length = auth_iv_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; - ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; - ut_params->cipher_xform.cipher.iv.length = cipher_iv_len; - - debug_hexdump(stdout, "key:", key, key_len); - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->cipher_xform, - ts_params->session_priv_mpool); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - return 0; -} - -static int -create_wireless_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 struct wireless_test_data *tdata) -{ - const uint8_t key_len = tdata->key.len; - uint8_t cipher_auth_key[key_len]; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - const uint8_t *key = tdata->key.data; - const uint8_t auth_len = tdata->digest.len; - uint8_t cipher_iv_len = tdata->cipher_iv.len; - uint8_t auth_iv_len = tdata->auth_iv.len; - - 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; - /* Auth IV will be after cipher IV */ - ut_params->auth_xform.auth.iv.offset = IV_OFFSET + cipher_iv_len; - ut_params->auth_xform.auth.iv.length = auth_iv_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; - ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; - ut_params->cipher_xform.cipher.iv.length = cipher_iv_len; - - - debug_hexdump(stdout, "key:", key, key_len); - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->cipher_xform, - ts_params->session_priv_mpool); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - return 0; -} - -static int -create_zuc_cipher_auth_encrypt_generate_session(uint8_t dev_id, - const struct wireless_test_data *tdata) -{ - return create_wireless_cipher_auth_session(dev_id, - RTE_CRYPTO_CIPHER_OP_ENCRYPT, - RTE_CRYPTO_AUTH_OP_GENERATE, RTE_CRYPTO_AUTH_ZUC_EIA3, - RTE_CRYPTO_CIPHER_ZUC_EEA3, tdata); -} - -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, - uint8_t auth_iv_len, uint8_t auth_len, - uint8_t cipher_iv_len) -{ - uint8_t auth_cipher_key[key_len]; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - 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; - /* Auth IV will be after cipher IV */ - ut_params->auth_xform.auth.iv.offset = IV_OFFSET + cipher_iv_len; - ut_params->auth_xform.auth.iv.length = auth_iv_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; - ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; - ut_params->cipher_xform.cipher.iv.length = cipher_iv_len; - - debug_hexdump(stdout, "key:", key, key_len); - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->auth_xform, - ts_params->session_priv_mpool); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - return 0; -} - -static int -create_wireless_algo_hash_operation(const uint8_t *auth_tag, - unsigned int auth_tag_len, - const uint8_t *iv, unsigned int iv_len, - unsigned int data_pad_len, - enum rte_crypto_auth_operation op, - unsigned int auth_len, unsigned int auth_offset) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - - struct crypto_unittest_params *ut_params = &unittest_params; - - /* 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 */ - rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), - iv, iv_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_iova_offset( - ut_params->ibuf, data_pad_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); - - debug_hexdump(stdout, "digest:", - sym_op->auth.digest.data, - auth_tag_len); - - sym_op->auth.data.length = auth_len; - sym_op->auth.data.offset = auth_offset; - - return 0; -} - -static int -create_wireless_cipher_hash_operation(const struct wireless_test_data *tdata, - enum rte_crypto_auth_operation op) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - const uint8_t *auth_tag = tdata->digest.data; - const unsigned int auth_tag_len = tdata->digest.len; - unsigned int plaintext_len = ceil_byte_length(tdata->plaintext.len); - unsigned int data_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); - - const uint8_t *cipher_iv = tdata->cipher_iv.data; - const uint8_t cipher_iv_len = tdata->cipher_iv.len; - const uint8_t *auth_iv = tdata->auth_iv.data; - const uint8_t auth_iv_len = tdata->auth_iv.len; - const unsigned int cipher_len = tdata->validCipherLenInBits.len; - const unsigned int auth_len = tdata->validAuthLenInBits.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_iova_offset( - ut_params->ibuf, data_pad_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); - - debug_hexdump(stdout, "digest:", - sym_op->auth.digest.data, - auth_tag_len); - - /* Copy cipher and auth IVs at the end of the crypto operation */ - uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, - IV_OFFSET); - rte_memcpy(iv_ptr, cipher_iv, cipher_iv_len); - iv_ptr += cipher_iv_len; - rte_memcpy(iv_ptr, auth_iv, auth_iv_len); - - sym_op->cipher.data.length = cipher_len; - sym_op->cipher.data.offset = 0; - sym_op->auth.data.length = auth_len; - sym_op->auth.data.offset = 0; - - return 0; -} - -static int -create_zuc_cipher_hash_generate_operation( - const struct wireless_test_data *tdata) -{ - return create_wireless_cipher_hash_operation(tdata, - RTE_CRYPTO_AUTH_OP_GENERATE); -} - -static int -create_wireless_algo_cipher_hash_operation(const uint8_t *auth_tag, - const unsigned auth_tag_len, - const uint8_t *auth_iv, uint8_t auth_iv_len, - unsigned data_pad_len, - enum rte_crypto_auth_operation op, - const uint8_t *cipher_iv, uint8_t cipher_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; - - /* 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_iova_offset( - ut_params->ibuf, data_pad_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); - - debug_hexdump(stdout, "digest:", - sym_op->auth.digest.data, - auth_tag_len); - - /* Copy cipher and auth IVs at the end of the crypto operation */ - uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, - IV_OFFSET); - rte_memcpy(iv_ptr, cipher_iv, cipher_iv_len); - iv_ptr += cipher_iv_len; - rte_memcpy(iv_ptr, auth_iv, auth_iv_len); - - sym_op->cipher.data.length = cipher_len; - sym_op->cipher.data.offset = cipher_offset; - sym_op->auth.data.length = auth_len; - sym_op->auth.data.offset = auth_offset; - - return 0; -} - -static int -create_wireless_algo_auth_cipher_operation(unsigned int auth_tag_len, - const uint8_t *cipher_iv, uint8_t cipher_iv_len, - const uint8_t *auth_iv, uint8_t auth_iv_len, - unsigned int data_pad_len, - unsigned int cipher_len, unsigned int cipher_offset, - unsigned int auth_len, unsigned int auth_offset) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* 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_iova_offset( - ut_params->ibuf, data_pad_len); - - memset(sym_op->auth.digest.data, 0, auth_tag_len); - - debug_hexdump(stdout, "digest:", - sym_op->auth.digest.data, - auth_tag_len); - - /* Copy cipher and auth IVs at the end of the crypto operation */ - uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, - IV_OFFSET); - rte_memcpy(iv_ptr, cipher_iv, cipher_iv_len); - iv_ptr += cipher_iv_len; - rte_memcpy(iv_ptr, auth_iv, auth_iv_len); - - sym_op->cipher.data.length = cipher_len; - sym_op->cipher.data.offset = cipher_offset; - - sym_op->auth.data.length = auth_len; - sym_op->auth.data.offset = auth_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->auth_iv.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->auth_iv.data, tdata->auth_iv.len, - plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, - tdata->validAuthLenInBits.len, - 0); - 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; - - /* 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->auth_iv.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->auth_iv.data, tdata->auth_iv.len, - plaintext_pad_len, - RTE_CRYPTO_AUTH_OP_VERIFY, - tdata->validAuthLenInBits.len, - 0); - 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; - - /* 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, - 0, 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, - NULL, 0, - plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, - tdata->plaintext.len, - 0); - 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; - - /* 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, - 0, 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, - NULL, 0, - plaintext_pad_len, - RTE_CRYPTO_AUTH_OP_VERIFY, - tdata->plaintext.len, - 0); - 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; - - /* 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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create KASUMI operation */ - retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, - tdata->cipher_iv.len, - RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), - tdata->validCipherOffsetInBits.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_dst; - if (ut_params->obuf) - ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); - else - ciphertext = plaintext + (tdata->validCipherOffsetInBits.len >> 3); - - debug_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); - - const uint8_t *reference_ciphertext = tdata->ciphertext.data + - (tdata->validCipherOffsetInBits.len >> 3); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - reference_ciphertext, - 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); - - uint64_t feat_flags = dev_info.feature_flags; - - if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) { - printf("Device doesn't support in-place 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, - tdata->cipher_iv.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->cipher_iv.data, - tdata->cipher_iv.len, - RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), - tdata->validCipherOffsetInBits.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_dst; - - if (ut_params->obuf) - ciphertext = rte_pktmbuf_read(ut_params->obuf, 0, - plaintext_len, buffer); - else - ciphertext = rte_pktmbuf_read(ut_params->ibuf, - tdata->validCipherOffsetInBits.len >> 3, - plaintext_len, buffer); - - /* Validate obuf */ - debug_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); - - const uint8_t *reference_ciphertext = tdata->ciphertext.data + - (tdata->validCipherOffsetInBits.len >> 3); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - reference_ciphertext, - 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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create KASUMI operation */ - retval = create_wireless_algo_cipher_operation_oop(tdata->cipher_iv.data, - tdata->cipher_iv.len, - RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), - tdata->validCipherOffsetInBits.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_dst; - if (ut_params->obuf) - ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); - else - ciphertext = plaintext + (tdata->validCipherOffsetInBits.len >> 3); - - debug_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); - - const uint8_t *reference_ciphertext = tdata->ciphertext.data + - (tdata->validCipherOffsetInBits.len >> 3); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - reference_ciphertext, - 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); - - uint64_t feat_flags = dev_info.feature_flags; - if (!(feat_flags & RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT)) { - printf("Device doesn't support out-of-place scatter-gather " - "in both input and output mbufs. " - "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, - tdata->cipher_iv.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->cipher_iv.data, - tdata->cipher_iv.len, - RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), - tdata->validCipherOffsetInBits.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_dst; - if (ut_params->obuf) - ciphertext = rte_pktmbuf_read(ut_params->obuf, 0, - plaintext_pad_len, buffer); - else - ciphertext = rte_pktmbuf_read(ut_params->ibuf, - tdata->validCipherOffsetInBits.len >> 3, - plaintext_pad_len, buffer); - - const uint8_t *reference_ciphertext = tdata->ciphertext.data + - (tdata->validCipherOffsetInBits.len >> 3); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - reference_ciphertext, - 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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "ciphertext:", ciphertext, ciphertext_len); - - /* Create KASUMI operation */ - retval = create_wireless_algo_cipher_operation_oop(tdata->cipher_iv.data, - tdata->cipher_iv.len, - RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), - tdata->validCipherOffsetInBits.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_dst; - if (ut_params->obuf) - plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); - else - plaintext = ciphertext + (tdata->validCipherOffsetInBits.len >> 3); - - debug_hexdump(stdout, "plaintext:", plaintext, ciphertext_len); - - const uint8_t *reference_plaintext = tdata->plaintext.data + - (tdata->validCipherOffsetInBits.len >> 3); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - plaintext, - reference_plaintext, - 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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "ciphertext:", ciphertext, ciphertext_len); - - /* Create KASUMI operation */ - retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, - tdata->cipher_iv.len, - tdata->ciphertext.len, - tdata->validCipherOffsetInBits.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_dst; - if (ut_params->obuf) - plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); - else - plaintext = ciphertext + (tdata->validCipherOffsetInBits.len >> 3); - - debug_hexdump(stdout, "plaintext:", plaintext, ciphertext_len); - - const uint8_t *reference_plaintext = tdata->plaintext.data + - (tdata->validCipherOffsetInBits.len >> 3); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - plaintext, - reference_plaintext, - 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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, - tdata->cipher_iv.len, - tdata->validCipherLenInBits.len, - 0); - 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 *); - else - ciphertext = plaintext; - - debug_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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_cipher_operation_oop(tdata->cipher_iv.data, - tdata->cipher_iv.len, - tdata->validCipherLenInBits.len, - 0); - 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 *); - else - ciphertext = plaintext; - - debug_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); - - uint64_t feat_flags = dev_info.feature_flags; - - if (!(feat_flags & RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT)) { - printf("Device doesn't support out-of-place scatter-gather " - "in both input and output mbufs. " - "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, - tdata->cipher_iv.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->cipher_iv.data, - tdata->cipher_iv.len, - tdata->validCipherLenInBits.len, - 0); - 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, 0, - plaintext_len, buffer); - else - ciphertext = rte_pktmbuf_read(ut_params->ibuf, 0, - plaintext_len, buffer); - - debug_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, - tdata->cipher_iv.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->cipher_iv.data, - tdata->cipher_iv.len, - tdata->validCipherLenInBits.len, - extra_offset); - 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 *); - else - ciphertext = plaintext; - -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); -#endif - - expected_ciphertext_shifted = rte_malloc(NULL, plaintext_len, 8); - - 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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "ciphertext:", ciphertext, ciphertext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, - tdata->cipher_iv.len, - tdata->validCipherLenInBits.len, - 0); - 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 *); - else - plaintext = ciphertext; - - debug_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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "ciphertext:", ciphertext, ciphertext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_cipher_operation_oop(tdata->cipher_iv.data, - tdata->cipher_iv.len, - tdata->validCipherLenInBits.len, - 0); - 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 *); - else - plaintext = ciphertext; - - debug_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_zuc_cipher_auth(const struct wireless_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 int plaintext_pad_len; - unsigned int plaintext_len; - - struct rte_cryptodev_sym_capability_idx cap_idx; - - /* Check if device supports ZUC EEA3 */ - cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_ZUC_EEA3; - - if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], - &cap_idx) == NULL) - return -ENOTSUP; - - /* Check if device supports ZUC EIA3 */ - cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; - cap_idx.algo.auth = RTE_CRYPTO_AUTH_ZUC_EIA3; - - if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], - &cap_idx) == NULL) - return -ENOTSUP; - - /* Create ZUC session */ - retval = create_zuc_cipher_auth_encrypt_generate_session( - ts_params->valid_devs[0], - tdata); - 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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create ZUC operation */ - retval = create_zuc_cipher_hash_generate_operation(tdata); - 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 *); - else - ciphertext = plaintext; - - debug_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - tdata->ciphertext.data, - tdata->validDataLenInBits.len, - "ZUC Ciphertext data not as expected"); - - ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + plaintext_pad_len; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ut_params->digest, - tdata->digest.data, - 4, - "ZUC Generated auth tag 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->auth_iv.len, tdata->digest.len, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_cipher_hash_operation(tdata->digest.data, - tdata->digest.len, tdata->auth_iv.data, - tdata->auth_iv.len, - plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, - tdata->cipher_iv.data, tdata->cipher_iv.len, - tdata->validCipherLenInBits.len, - 0, - tdata->validAuthLenInBits.len, - 0 - ); - 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 *); - else - ciphertext = plaintext; - - debug_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; - - /* 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->auth_iv.len, tdata->digest.len, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create SNOW 3G operation */ - retval = create_wireless_algo_auth_cipher_operation( - tdata->digest.len, - tdata->cipher_iv.data, tdata->cipher_iv.len, - tdata->auth_iv.data, tdata->auth_iv.len, - plaintext_pad_len, - tdata->validCipherLenInBits.len, - 0, - tdata->validAuthLenInBits.len, - 0); - - 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 *); - else - ciphertext = plaintext; - - ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + plaintext_pad_len; - debug_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, - 0, tdata->digest.len, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create KASUMI operation */ - retval = create_wireless_algo_auth_cipher_operation(tdata->digest.len, - tdata->cipher_iv.data, tdata->cipher_iv.len, - NULL, 0, - plaintext_pad_len, - tdata->validCipherLenInBits.len, - tdata->validCipherOffsetInBits.len, - tdata->validAuthLenInBits.len, - 0 - ); - - 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"); - if (ut_params->op->sym->m_dst) - ut_params->obuf = ut_params->op->sym->m_dst; - else - ut_params->obuf = ut_params->op->sym->m_src; - - ciphertext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *, - tdata->validCipherOffsetInBits.len >> 3); - - const uint8_t *reference_ciphertext = tdata->ciphertext.data + - (tdata->validCipherOffsetInBits.len >> 3); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - reference_ciphertext, - tdata->validCipherLenInBits.len, - "KASUMI Ciphertext data not as expected"); - ut_params->digest = rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *) - + plaintext_pad_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, - 0, tdata->digest.len, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create KASUMI operation */ - retval = create_wireless_algo_cipher_hash_operation(tdata->digest.data, - tdata->digest.len, NULL, 0, - plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, - tdata->cipher_iv.data, tdata->cipher_iv.len, - RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), - tdata->validCipherOffsetInBits.len, - tdata->validAuthLenInBits.len, - 0 - ); - 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"); - - if (ut_params->op->sym->m_dst) - ut_params->obuf = ut_params->op->sym->m_dst; - else - ut_params->obuf = ut_params->op->sym->m_src; - - ciphertext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *, - tdata->validCipherOffsetInBits.len >> 3); - - ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) - + plaintext_pad_len; - - const uint8_t *reference_ciphertext = tdata->ciphertext.data + - (tdata->validCipherOffsetInBits.len >> 3); - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( - ciphertext, - reference_ciphertext, - 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 wireless_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; - - struct rte_cryptodev_sym_capability_idx cap_idx; - - /* Check if device supports ZUC EEA3 */ - cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_ZUC_EEA3; - - if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], - &cap_idx) == NULL) - return -ENOTSUP; - - /* 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, - tdata->cipher_iv.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); - - debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); - - /* Create ZUC operation */ - retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, - tdata->cipher_iv.len, - tdata->plaintext.len, - 0); - 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 *); - else - ciphertext = plaintext; - - debug_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 wireless_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; - - struct rte_cryptodev_sym_capability_idx cap_idx; - - /* Check if device supports ZUC EEA3 */ - cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_ZUC_EEA3; - - if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], - &cap_idx) == NULL) - return -ENOTSUP; - - rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); - - uint64_t feat_flags = dev_info.feature_flags; - - if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) { - printf("Device doesn't support in-place 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, - tdata->cipher_iv.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->cipher_iv.data, - tdata->cipher_iv.len, tdata->plaintext.len, - 0); - 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, - 0, plaintext_len, ciphertext_buffer); - else - ciphertext = rte_pktmbuf_read(ut_params->ibuf, - 0, plaintext_len, ciphertext_buffer); - - /* Validate obuf */ - debug_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 wireless_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; - - struct rte_cryptodev_sym_capability_idx cap_idx; - - /* Check if device supports ZUC EIA3 */ - cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; - cap_idx.algo.auth = RTE_CRYPTO_AUTH_ZUC_EIA3; - - if (rte_cryptodev_sym_capability_get(ts_params->valid_devs[0], - &cap_idx) == NULL) - return -ENOTSUP; - - /* Create ZUC session */ - retval = create_wireless_algo_hash_session(ts_params->valid_devs[0], - tdata->key.data, tdata->key.len, - tdata->auth_iv.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->auth_iv.data, tdata->auth_iv.len, - plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, - tdata->validAuthLenInBits.len, - 0); - 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; - - /* 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_cipher_193b); -} - -static int -test_zuc_encryption_test_case_2(void) -{ - return test_zuc_encryption(&zuc_test_case_cipher_800b); -} - -static int -test_zuc_encryption_test_case_3(void) -{ - return test_zuc_encryption(&zuc_test_case_cipher_1570b); -} - -static int -test_zuc_encryption_test_case_4(void) -{ - return test_zuc_encryption(&zuc_test_case_cipher_2798b); -} - -static int -test_zuc_encryption_test_case_5(void) -{ - return test_zuc_encryption(&zuc_test_case_cipher_4019b); -} - -static int -test_zuc_encryption_test_case_6_sgl(void) -{ - return test_zuc_encryption_sgl(&zuc_test_case_cipher_193b); -} - -static int -test_zuc_hash_generate_test_case_1(void) -{ - return test_zuc_authentication(&zuc_test_case_auth_1b); -} - -static int -test_zuc_hash_generate_test_case_2(void) -{ - return test_zuc_authentication(&zuc_test_case_auth_90b); -} - -static int -test_zuc_hash_generate_test_case_3(void) -{ - return test_zuc_authentication(&zuc_test_case_auth_577b); -} - -static int -test_zuc_hash_generate_test_case_4(void) -{ - return test_zuc_authentication(&zuc_test_case_auth_2079b); -} - -static int -test_zuc_hash_generate_test_case_5(void) -{ - return test_zuc_authentication(&zuc_test_auth_5670b); -} - -static int -test_zuc_hash_generate_test_case_6(void) -{ - return test_zuc_authentication(&zuc_test_case_auth_128b); -} - -static int -test_zuc_hash_generate_test_case_7(void) -{ - return test_zuc_authentication(&zuc_test_case_auth_2080b); -} - -static int -test_zuc_hash_generate_test_case_8(void) -{ - return test_zuc_authentication(&zuc_test_case_auth_584b); -} - -static int -test_zuc_cipher_auth_test_case_1(void) -{ - return test_zuc_cipher_auth(&zuc_test_case_cipher_200b_auth_200b); -} - -static int -test_zuc_cipher_auth_test_case_2(void) -{ - return test_zuc_cipher_auth(&zuc_test_case_cipher_800b_auth_120b); -} - -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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)), - BLKCIPHER_DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_DES_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), - BLKCIPHER_DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_DES_docsis_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), - BLKCIPHER_DES_DOCSIS_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_DES_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), - BLKCIPHER_DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} -static int -test_3DES_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_DES_docsis_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)), - BLKCIPHER_DES_DOCSIS_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_chain_caam_jr_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), - BLKCIPHER_3DES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_cipheronly_caam_jr_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)), - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_chain_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), - BLKCIPHER_3DES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_cipheronly_dpaa_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)), - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_chain_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), - BLKCIPHER_3DES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_cipheronly_dpaa2_sec_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)), - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_chain_ccp_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_PMD)), - BLKCIPHER_3DES_CHAIN_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -static int -test_3DES_cipheronly_ccp_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_PMD)), - BLKCIPHER_3DES_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_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->session_mpool, ts_params->session_priv_mpool, - ts_params->valid_devs[0], - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)), - BLKCIPHER_3DES_CIPHERONLY_TYPE); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return TEST_SUCCESS; -} - -/* ***** AEAD algorithm Tests ***** */ - -static int -create_aead_session(uint8_t dev_id, enum rte_crypto_aead_algorithm algo, - enum rte_crypto_aead_operation op, - const uint8_t *key, const uint8_t key_len, - const uint16_t aad_len, const uint8_t auth_len, - uint8_t iv_len) -{ - uint8_t aead_key[key_len]; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - memcpy(aead_key, key, key_len); - - /* Setup AEAD Parameters */ - ut_params->aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD; - ut_params->aead_xform.next = NULL; - ut_params->aead_xform.aead.algo = algo; - ut_params->aead_xform.aead.op = op; - ut_params->aead_xform.aead.key.data = aead_key; - ut_params->aead_xform.aead.key.length = key_len; - ut_params->aead_xform.aead.iv.offset = IV_OFFSET; - ut_params->aead_xform.aead.iv.length = iv_len; - ut_params->aead_xform.aead.digest_length = auth_len; - ut_params->aead_xform.aead.aad_length = aad_len; - - debug_hexdump(stdout, "key:", key, key_len); - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->aead_xform, - ts_params->session_priv_mpool); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - return 0; -} - -static int -create_aead_xform(struct rte_crypto_op *op, - enum rte_crypto_aead_algorithm algo, - enum rte_crypto_aead_operation aead_op, - uint8_t *key, const uint8_t key_len, - const uint8_t aad_len, const uint8_t auth_len, - uint8_t iv_len) -{ - TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(op, 1), - "failed to allocate space for crypto transform"); - - struct rte_crypto_sym_op *sym_op = op->sym; - - /* Setup AEAD Parameters */ - sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; - sym_op->xform->next = NULL; - sym_op->xform->aead.algo = algo; - sym_op->xform->aead.op = aead_op; - sym_op->xform->aead.key.data = key; - sym_op->xform->aead.key.length = key_len; - sym_op->xform->aead.iv.offset = IV_OFFSET; - sym_op->xform->aead.iv.length = iv_len; - sym_op->xform->aead.digest_length = auth_len; - sym_op->xform->aead.aad_length = aad_len; - - debug_hexdump(stdout, "key:", key, key_len); - - return 0; -} - -static int -create_aead_operation(enum rte_crypto_aead_operation op, - const struct aead_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 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 */ - if (tdata->algo == RTE_CRYPTO_AEAD_AES_CCM) { - aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len + 18, 16); - sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - aad_pad_len); - TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, - "no room to append aad"); - - sym_op->aead.aad.phys_addr = - rte_pktmbuf_iova(ut_params->ibuf); - /* Copy AAD 18 bytes after the AAD pointer, according to the API */ - memcpy(sym_op->aead.aad.data + 18, tdata->aad.data, tdata->aad.len); - debug_hexdump(stdout, "aad:", sym_op->aead.aad.data, - tdata->aad.len); - - /* Append IV at the end of the crypto operation*/ - uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, - uint8_t *, IV_OFFSET); - - /* Copy IV 1 byte after the IV pointer, according to the API */ - rte_memcpy(iv_ptr + 1, tdata->iv.data, tdata->iv.len); - debug_hexdump(stdout, "iv:", iv_ptr, - tdata->iv.len); - } else { - aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); - sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - aad_pad_len); - TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, - "no room to append aad"); - - sym_op->aead.aad.phys_addr = - rte_pktmbuf_iova(ut_params->ibuf); - memcpy(sym_op->aead.aad.data, tdata->aad.data, tdata->aad.len); - debug_hexdump(stdout, "aad:", sym_op->aead.aad.data, - tdata->aad.len); - - /* Append IV at the end of the crypto operation*/ - uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, - uint8_t *, IV_OFFSET); - - rte_memcpy(iv_ptr, tdata->iv.data, tdata->iv.len); - debug_hexdump(stdout, "iv:", iv_ptr, - tdata->iv.len); - } - - /* Append plaintext/ciphertext */ - if (op == RTE_CRYPTO_AEAD_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); - debug_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); - TEST_ASSERT_NOT_NULL(ciphertext, - "no room to append ciphertext"); - - memset(ciphertext + aad_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); - debug_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); - TEST_ASSERT_NOT_NULL(plaintext, - "no room to append plaintext"); - - memset(plaintext + aad_pad_len, 0, - tdata->plaintext.len); - } - } - - /* Append digest data */ - if (op == RTE_CRYPTO_AEAD_OP_ENCRYPT) { - sym_op->aead.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->aead.digest.data, - "no room to append digest"); - memset(sym_op->aead.digest.data, 0, tdata->auth_tag.len); - sym_op->aead.digest.phys_addr = rte_pktmbuf_iova_offset( - ut_params->obuf ? ut_params->obuf : - ut_params->ibuf, - plaintext_pad_len + - aad_pad_len); - } else { - sym_op->aead.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, tdata->auth_tag.len); - TEST_ASSERT_NOT_NULL(sym_op->aead.digest.data, - "no room to append digest"); - sym_op->aead.digest.phys_addr = rte_pktmbuf_iova_offset( - ut_params->ibuf, - plaintext_pad_len + aad_pad_len); - - rte_memcpy(sym_op->aead.digest.data, tdata->auth_tag.data, - tdata->auth_tag.len); - debug_hexdump(stdout, "digest:", - sym_op->aead.digest.data, - tdata->auth_tag.len); - } - - sym_op->aead.data.length = tdata->plaintext.len; - sym_op->aead.data.offset = aad_pad_len; - - return 0; -} - -static int -test_authenticated_encryption(const struct aead_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 AEAD session */ - retval = create_aead_session(ts_params->valid_devs[0], - tdata->algo, - RTE_CRYPTO_AEAD_OP_ENCRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - tdata->iv.len); - 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 < 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 AEAD operation */ - retval = create_aead_operation(RTE_CRYPTO_AEAD_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; - } - - debug_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); - debug_hexdump(stdout, "auth tag:", auth_tag, tdata->auth_tag.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ciphertext, - tdata->ciphertext.data, - tdata->ciphertext.len, - "Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - tdata->auth_tag.data, - tdata->auth_tag.len, - "Generated auth tag not as expected"); - - return 0; - -} - -static int -test_AES_GCM_authenticated_encryption_test_case_1(void) -{ - return test_authenticated_encryption(&gcm_test_case_1); -} - -static int -test_AES_GCM_authenticated_encryption_test_case_2(void) -{ - return test_authenticated_encryption(&gcm_test_case_2); -} - -static int -test_AES_GCM_authenticated_encryption_test_case_3(void) -{ - return test_authenticated_encryption(&gcm_test_case_3); -} - -static int -test_AES_GCM_authenticated_encryption_test_case_4(void) -{ - return test_authenticated_encryption(&gcm_test_case_4); -} - -static int -test_AES_GCM_authenticated_encryption_test_case_5(void) -{ - return test_authenticated_encryption(&gcm_test_case_5); -} - -static int -test_AES_GCM_authenticated_encryption_test_case_6(void) -{ - return test_authenticated_encryption(&gcm_test_case_6); -} - -static int -test_AES_GCM_authenticated_encryption_test_case_7(void) -{ - return test_authenticated_encryption(&gcm_test_case_7); -} - -static int -test_AES_GCM_auth_encryption_test_case_192_1(void) -{ - return test_authenticated_encryption(&gcm_test_case_192_1); -} - -static int -test_AES_GCM_auth_encryption_test_case_192_2(void) -{ - return test_authenticated_encryption(&gcm_test_case_192_2); -} - -static int -test_AES_GCM_auth_encryption_test_case_192_3(void) -{ - return test_authenticated_encryption(&gcm_test_case_192_3); -} - -static int -test_AES_GCM_auth_encryption_test_case_192_4(void) -{ - return test_authenticated_encryption(&gcm_test_case_192_4); -} - -static int -test_AES_GCM_auth_encryption_test_case_192_5(void) -{ - return test_authenticated_encryption(&gcm_test_case_192_5); -} - -static int -test_AES_GCM_auth_encryption_test_case_192_6(void) -{ - return test_authenticated_encryption(&gcm_test_case_192_6); -} - -static int -test_AES_GCM_auth_encryption_test_case_192_7(void) -{ - return test_authenticated_encryption(&gcm_test_case_192_7); -} - -static int -test_AES_GCM_auth_encryption_test_case_256_1(void) -{ - return test_authenticated_encryption(&gcm_test_case_256_1); -} - -static int -test_AES_GCM_auth_encryption_test_case_256_2(void) -{ - return test_authenticated_encryption(&gcm_test_case_256_2); -} - -static int -test_AES_GCM_auth_encryption_test_case_256_3(void) -{ - return test_authenticated_encryption(&gcm_test_case_256_3); -} - -static int -test_AES_GCM_auth_encryption_test_case_256_4(void) -{ - return test_authenticated_encryption(&gcm_test_case_256_4); -} - -static int -test_AES_GCM_auth_encryption_test_case_256_5(void) -{ - return test_authenticated_encryption(&gcm_test_case_256_5); -} - -static int -test_AES_GCM_auth_encryption_test_case_256_6(void) -{ - return test_authenticated_encryption(&gcm_test_case_256_6); -} - -static int -test_AES_GCM_auth_encryption_test_case_256_7(void) -{ - return test_authenticated_encryption(&gcm_test_case_256_7); -} - -static int -test_AES_GCM_auth_encryption_test_case_aad_1(void) -{ - return test_authenticated_encryption(&gcm_test_case_aad_1); -} - -static int -test_AES_GCM_auth_encryption_test_case_aad_2(void) -{ - return test_authenticated_encryption(&gcm_test_case_aad_2); -} - -static int -test_authenticated_decryption(const struct aead_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 AEAD session */ - retval = create_aead_session(ts_params->valid_devs[0], - tdata->algo, - RTE_CRYPTO_AEAD_OP_DECRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - tdata->iv.len); - 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 < 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 AEAD operation */ - retval = create_aead_operation(RTE_CRYPTO_AEAD_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); - - debug_hexdump(stdout, "plaintext:", plaintext, tdata->ciphertext.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - plaintext, - tdata->plaintext.data, - tdata->plaintext.len, - "Plaintext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_SUCCESS, - "Authentication failed"); - return 0; -} - -static int -test_AES_GCM_authenticated_decryption_test_case_1(void) -{ - return test_authenticated_decryption(&gcm_test_case_1); -} - -static int -test_AES_GCM_authenticated_decryption_test_case_2(void) -{ - return test_authenticated_decryption(&gcm_test_case_2); -} - -static int -test_AES_GCM_authenticated_decryption_test_case_3(void) -{ - return test_authenticated_decryption(&gcm_test_case_3); -} - -static int -test_AES_GCM_authenticated_decryption_test_case_4(void) -{ - return test_authenticated_decryption(&gcm_test_case_4); -} - -static int -test_AES_GCM_authenticated_decryption_test_case_5(void) -{ - return test_authenticated_decryption(&gcm_test_case_5); -} - -static int -test_AES_GCM_authenticated_decryption_test_case_6(void) -{ - return test_authenticated_decryption(&gcm_test_case_6); -} - -static int -test_AES_GCM_authenticated_decryption_test_case_7(void) -{ - return test_authenticated_decryption(&gcm_test_case_7); -} - -static int -test_AES_GCM_auth_decryption_test_case_192_1(void) -{ - return test_authenticated_decryption(&gcm_test_case_192_1); -} - -static int -test_AES_GCM_auth_decryption_test_case_192_2(void) -{ - return test_authenticated_decryption(&gcm_test_case_192_2); -} - -static int -test_AES_GCM_auth_decryption_test_case_192_3(void) -{ - return test_authenticated_decryption(&gcm_test_case_192_3); -} - -static int -test_AES_GCM_auth_decryption_test_case_192_4(void) -{ - return test_authenticated_decryption(&gcm_test_case_192_4); -} - -static int -test_AES_GCM_auth_decryption_test_case_192_5(void) -{ - return test_authenticated_decryption(&gcm_test_case_192_5); -} - -static int -test_AES_GCM_auth_decryption_test_case_192_6(void) -{ - return test_authenticated_decryption(&gcm_test_case_192_6); -} - -static int -test_AES_GCM_auth_decryption_test_case_192_7(void) -{ - return test_authenticated_decryption(&gcm_test_case_192_7); -} - -static int -test_AES_GCM_auth_decryption_test_case_256_1(void) -{ - return test_authenticated_decryption(&gcm_test_case_256_1); -} - -static int -test_AES_GCM_auth_decryption_test_case_256_2(void) -{ - return test_authenticated_decryption(&gcm_test_case_256_2); -} - -static int -test_AES_GCM_auth_decryption_test_case_256_3(void) -{ - return test_authenticated_decryption(&gcm_test_case_256_3); -} - -static int -test_AES_GCM_auth_decryption_test_case_256_4(void) -{ - return test_authenticated_decryption(&gcm_test_case_256_4); -} - -static int -test_AES_GCM_auth_decryption_test_case_256_5(void) -{ - return test_authenticated_decryption(&gcm_test_case_256_5); -} - -static int -test_AES_GCM_auth_decryption_test_case_256_6(void) -{ - return test_authenticated_decryption(&gcm_test_case_256_6); -} - -static int -test_AES_GCM_auth_decryption_test_case_256_7(void) -{ - return test_authenticated_decryption(&gcm_test_case_256_7); -} - -static int -test_AES_GCM_auth_decryption_test_case_aad_1(void) -{ - return test_authenticated_decryption(&gcm_test_case_aad_1); -} - -static int -test_AES_GCM_auth_decryption_test_case_aad_2(void) -{ - return test_authenticated_decryption(&gcm_test_case_aad_2); -} - -static int -test_authenticated_encryption_oop(const struct aead_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 AEAD session */ - retval = create_aead_session(ts_params->valid_devs[0], - tdata->algo, - RTE_CRYPTO_AEAD_OP_ENCRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - tdata->iv.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)); - memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, - rte_pktmbuf_tailroom(ut_params->obuf)); - - /* Create AEAD operation */ - retval = create_aead_operation(RTE_CRYPTO_AEAD_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; - - debug_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); - debug_hexdump(stdout, "auth tag:", auth_tag, tdata->auth_tag.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ciphertext, - tdata->ciphertext.data, - tdata->ciphertext.len, - "Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - tdata->auth_tag.data, - tdata->auth_tag.len, - "Generated auth tag not as expected"); - - return 0; - -} - -static int -test_AES_GCM_authenticated_encryption_oop_test_case_1(void) -{ - return test_authenticated_encryption_oop(&gcm_test_case_5); -} - -static int -test_authenticated_decryption_oop(const struct aead_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 AEAD session */ - retval = create_aead_session(ts_params->valid_devs[0], - tdata->algo, - RTE_CRYPTO_AEAD_OP_DECRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - tdata->iv.len); - 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 AEAD operation */ - retval = create_aead_operation(RTE_CRYPTO_AEAD_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); - - debug_hexdump(stdout, "plaintext:", plaintext, tdata->ciphertext.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - plaintext, - tdata->plaintext.data, - tdata->plaintext.len, - "Plaintext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_SUCCESS, - "Authentication failed"); - return 0; -} - -static int -test_AES_GCM_authenticated_decryption_oop_test_case_1(void) -{ - return test_authenticated_decryption_oop(&gcm_test_case_5); -} - -static int -test_authenticated_encryption_sessionless( - const struct aead_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 AEAD operation */ - retval = create_aead_operation(RTE_CRYPTO_AEAD_OP_ENCRYPT, tdata); - if (retval < 0) - return retval; - - /* Create GCM xform */ - memcpy(key, tdata->key.data, tdata->key.len); - retval = create_aead_xform(ut_params->op, - tdata->algo, - RTE_CRYPTO_AEAD_OP_ENCRYPT, - key, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - tdata->iv.len); - if (retval < 0) - return retval; - - ut_params->op->sym->m_src = ut_params->ibuf; - - TEST_ASSERT_EQUAL(ut_params->op->sess_type, - RTE_CRYPTO_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; - - debug_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); - debug_hexdump(stdout, "auth tag:", auth_tag, tdata->auth_tag.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - ciphertext, - tdata->ciphertext.data, - tdata->ciphertext.len, - "Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - auth_tag, - tdata->auth_tag.data, - tdata->auth_tag.len, - "Generated auth tag not as expected"); - - return 0; - -} - -static int -test_AES_GCM_authenticated_encryption_sessionless_test_case_1(void) -{ - return test_authenticated_encryption_sessionless( - &gcm_test_case_5); -} - -static int -test_authenticated_decryption_sessionless( - const struct aead_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 AEAD operation */ - retval = create_aead_operation(RTE_CRYPTO_AEAD_OP_DECRYPT, tdata); - if (retval < 0) - return retval; - - /* Create AEAD xform */ - memcpy(key, tdata->key.data, tdata->key.len); - retval = create_aead_xform(ut_params->op, - tdata->algo, - RTE_CRYPTO_AEAD_OP_DECRYPT, - key, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - tdata->iv.len); - if (retval < 0) - return retval; - - ut_params->op->sym->m_src = ut_params->ibuf; - - TEST_ASSERT_EQUAL(ut_params->op->sess_type, - RTE_CRYPTO_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); - - debug_hexdump(stdout, "plaintext:", plaintext, tdata->ciphertext.len); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - plaintext, - tdata->plaintext.data, - tdata->plaintext.len, - "Plaintext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, - RTE_CRYPTO_OP_STATUS_SUCCESS, - "Authentication failed"); - return 0; -} - -static int -test_AES_GCM_authenticated_decryption_sessionless_test_case_1(void) -{ - return test_authenticated_decryption_sessionless( - &gcm_test_case_5); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_128_1(void) -{ - return test_authenticated_encryption(&ccm_test_case_128_1); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_128_2(void) -{ - return test_authenticated_encryption(&ccm_test_case_128_2); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_128_3(void) -{ - return test_authenticated_encryption(&ccm_test_case_128_3); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_128_1(void) -{ - return test_authenticated_decryption(&ccm_test_case_128_1); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_128_2(void) -{ - return test_authenticated_decryption(&ccm_test_case_128_2); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_128_3(void) -{ - return test_authenticated_decryption(&ccm_test_case_128_3); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_192_1(void) -{ - return test_authenticated_encryption(&ccm_test_case_192_1); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_192_2(void) -{ - return test_authenticated_encryption(&ccm_test_case_192_2); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_192_3(void) -{ - return test_authenticated_encryption(&ccm_test_case_192_3); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_192_1(void) -{ - return test_authenticated_decryption(&ccm_test_case_192_1); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_192_2(void) -{ - return test_authenticated_decryption(&ccm_test_case_192_2); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_192_3(void) -{ - return test_authenticated_decryption(&ccm_test_case_192_3); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_256_1(void) -{ - return test_authenticated_encryption(&ccm_test_case_256_1); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_256_2(void) -{ - return test_authenticated_encryption(&ccm_test_case_256_2); -} - -static int -test_AES_CCM_authenticated_encryption_test_case_256_3(void) -{ - return test_authenticated_encryption(&ccm_test_case_256_3); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_256_1(void) -{ - return test_authenticated_decryption(&ccm_test_case_256_1); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_256_2(void) -{ - return test_authenticated_decryption(&ccm_test_case_256_2); -} - -static int -test_AES_CCM_authenticated_decryption_test_case_256_3(void) -{ - return test_authenticated_decryption(&ccm_test_case_256_3); -} - -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.key.length = test_case->key.len; - ut_params->auth_xform.auth.key.data = key; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, &ut_params->auth_xform, - ts_params->session_priv_mpool); - - 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_iova_offset( - ut_params->ibuf, plaintext_pad_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 *) * - MAX_NB_SESSIONS) + 1, 0); - - /* Create multiple crypto sessions*/ - for (i = 0; i < MAX_NB_SESSIONS; i++) { - - sessions[i] = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - sessions[i], &ut_params->auth_xform, - ts_params->session_priv_mpool); - 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 */ - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - sessions[i], &ut_params->auth_xform, - ts_params->session_priv_mpool); - TEST_ASSERT_NULL(sessions[i], - "Session creation succeeded unexpectedly!"); - - for (i = 0; i < MAX_NB_SESSIONS; i++) { - rte_cryptodev_sym_session_clear(ts_params->valid_devs[0], - sessions[i]); - rte_cryptodev_sym_session_free(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 *) - * MAX_NB_SESSIONS) + 1, 0); - - for (i = 0; i < MB_SESSION_NUMBER; i++) { - sessions[i] = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_memcpy(&ut_paramz[i].ut_params, &unittest_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*/ - rte_cryptodev_sym_session_init( - ts_params->valid_devs[0], - sessions[i], - &ut_paramz[i].ut_params.auth_xform, - ts_params->session_priv_mpool); - - 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_clear(ts_params->valid_devs[0], - sessions[i]); - rte_cryptodev_sym_session_free(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; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - /* Create Crypto session*/ - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, - &ut_params->cipher_xform, - ts_params->session_priv_mpool); - 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; -} -uint8_t orig_data[] = {0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab}; -static int -test_null_auth_only_operation(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - uint8_t *digest; - - /* 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); - - /* create a pointer for digest, but don't expect anything to be written - * here in a NULL auth algo so no mbuf append done. - */ - digest = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, - QUOTE_512_BYTES); - /* prefill the memory pointed to by digest */ - memcpy(digest, orig_data, sizeof(orig_data)); - - /* 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; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - /* Create Crypto session*/ - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, &ut_params->auth_xform, - ts_params->session_priv_mpool); - 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; - sym_op->auth.digest.data = digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_iova_offset(ut_params->ibuf, - 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"); - /* Make sure memory pointed to by digest hasn't been overwritten */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - orig_data, - digest, - sizeof(orig_data), - "Memory at digest ptr overwritten unexpectedly"); - - 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; - uint8_t *digest; - - /* 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); - - /* create a pointer for digest, but don't expect anything to be written - * here in a NULL auth algo so no mbuf append done. - */ - digest = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, - QUOTE_512_BYTES); - /* prefill the memory pointed to by digest */ - memcpy(digest, orig_data, sizeof(orig_data)); - - /* 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; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - /* Create Crypto session*/ - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, &ut_params->cipher_xform, - ts_params->session_priv_mpool); - 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; - sym_op->auth.digest.data = digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_iova_offset(ut_params->ibuf, - 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"); - /* Make sure memory pointed to by digest hasn't been overwritten */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - orig_data, - digest, - sizeof(orig_data), - "Memory at digest ptr overwritten unexpectedly"); - - 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; - uint8_t *digest; - - /* Generate test mbuf data */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - catch_22_quote, QUOTE_512_BYTES, 0); - - /* create a pointer for digest, but don't expect anything to be written - * here in a NULL auth algo so no mbuf append done. - */ - digest = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *, - QUOTE_512_BYTES); - /* prefill the memory pointed to by digest */ - memcpy(digest, orig_data, sizeof(orig_data)); - - /* 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; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - /* Create Crypto session*/ - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, &ut_params->cipher_xform, - ts_params->session_priv_mpool); - 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; - sym_op->auth.digest.data = digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_iova_offset(ut_params->ibuf, - 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"); - /* Make sure memory pointed to by digest hasn't been overwritten */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - orig_data, - digest, - sizeof(orig_data), - "Memory at digest ptr overwritten unexpectedly"); - - 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; - int ret; - - /* 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; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - /* Create Crypto session*/ - ret = rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, &ut_params->cipher_xform, - ts_params->session_priv_mpool); - TEST_ASSERT(ret < 0, - "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; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - /* Create Crypto session*/ - ret = rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, &ut_params->auth_xform, - ts_params->session_priv_mpool); - TEST_ASSERT(ret < 0, - "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; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - /* Create Crypto session*/ - rte_cryptodev_sym_session_init(ts_params->valid_devs[0], - ut_params->sess, &ut_params->cipher_xform, - ts_params->session_priv_mpool); - 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; - - uint32_t plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16); - - /* 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.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_iova_offset( - ut_params->ibuf, plaintext_pad_len); - - if (op == RTE_CRYPTO_AUTH_OP_VERIFY) { - rte_memcpy(sym_op->auth.digest.data, tdata->gmac_tag.data, - tdata->gmac_tag.len); - debug_hexdump(stdout, "digest:", - sym_op->auth.digest.data, - tdata->gmac_tag.len); - } - - uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, - uint8_t *, IV_OFFSET); - - rte_memcpy(iv_ptr, tdata->iv.data, tdata->iv.len); - - debug_hexdump(stdout, "iv:", iv_ptr, tdata->iv.len); - - sym_op->cipher.data.length = 0; - sym_op->cipher.data.offset = 0; - - sym_op->auth.data.offset = 0; - sym_op->auth.data.length = tdata->plaintext.len; - - return 0; -} - -static int create_gmac_session(uint8_t dev_id, - const struct gmac_test_data *tdata, - enum rte_crypto_auth_operation auth_op) -{ - uint8_t auth_key[tdata->key.len]; - - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - memcpy(auth_key, tdata->key.data, 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.key.length = tdata->key.len; - ut_params->auth_xform.auth.key.data = auth_key; - ut_params->auth_xform.auth.iv.offset = IV_OFFSET; - ut_params->auth_xform.auth.iv.length = tdata->iv.len; - - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->auth_xform, - ts_params->session_priv_mpool); - - 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, *plaintext; - uint16_t plaintext_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], - tdata, RTE_CRYPTO_AUTH_OP_GENERATE); - - if (retval < 0) - return retval; - - if (tdata->plaintext.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)); - - plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.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->plaintext.len == GMAC_LARGE_PLAINTEXT_LENGTH) - generate_gmac_large_plaintext(tdata->plaintext.data); - - 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); - debug_hexdump(stdout, "plaintext:", plaintext, - tdata->plaintext.len); - - 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 *, plaintext_pad_len); - } else { - auth_tag = plaintext + plaintext_pad_len; - } - - debug_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; - uint32_t plaintext_pad_len; - uint8_t *plaintext; - - 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], - tdata, RTE_CRYPTO_AUTH_OP_VERIFY); - - if (retval < 0) - return retval; - - if (tdata->plaintext.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)); - - plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.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->plaintext.len == GMAC_LARGE_PLAINTEXT_LENGTH) - generate_gmac_large_plaintext(tdata->plaintext.data); - - 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); - debug_hexdump(stdout, "plaintext:", plaintext, - tdata->plaintext.len); - - 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, - .plaintext = { - .data = plaintext_hash, - .len = 512 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B - }, - .len = 12 - }, - .auth_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) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - 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; - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->auth_xform, - ts_params->session_priv_mpool); - - 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) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - 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.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; - - if (reference->auth_algo == RTE_CRYPTO_AUTH_AES_GMAC) { - ut_params->auth_xform.auth.iv.offset = IV_OFFSET; - ut_params->auth_xform.auth.iv.length = reference->iv.len; - } else { - ut_params->auth_xform.next = &ut_params->cipher_xform; - - /* 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; - ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; - ut_params->cipher_xform.cipher.iv.length = reference->iv.len; - } - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->session_mpool); - - rte_cryptodev_sym_session_init(dev_id, ut_params->sess, - &ut_params->auth_xform, - ts_params->session_priv_mpool); - - 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_iova_offset( - ut_params->ibuf, reference->plaintext.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); - - debug_hexdump(stdout, "digest:", - sym_op->auth.digest.data, - reference->digest.len); - - 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; - - /* 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_iova_offset( - ut_params->ibuf, reference->ciphertext.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); - - debug_hexdump(stdout, "digest:", - sym_op->auth.digest.data, - reference->digest.len); - - rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), - reference->iv.data, reference->iv.len); - - sym_op->cipher.data.length = 0; - sym_op->cipher.data.offset = 0; - - sym_op->auth.data.length = reference->plaintext.len; - 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_iova_offset( - ut_params->ibuf, reference->ciphertext.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); - - debug_hexdump(stdout, "digest:", - sym_op->auth.digest.data, - reference->digest.len); - - rte_memcpy(rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET), - reference->iv.data, reference->iv.len); - - sym_op->cipher.data.length = reference->ciphertext.len; - sym_op->cipher.data.offset = 0; - - sym_op->auth.data.length = reference->ciphertext.len; - sym_op->auth.data.offset = 0; - - 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); - - debug_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; - uint8_t *plaintext; - - /* 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)); - - 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); - - debug_hexdump(stdout, "plaintext:", plaintext, - reference->plaintext.len); - - /* Create operation */ - retval = create_auth_verify_GMAC_operation(ts_params, - ut_params, - reference); - - if (retval < 0) - return retval; - - if (data_corrupted) - data_corruption(plaintext); - else - tag_corruption(plaintext, 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_aead_operation_SGL(enum rte_crypto_aead_operation op, - const struct aead_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; - unsigned int aad_len = tdata->aad.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; - - sym_op->aead.digest.data = digest_mem; - - TEST_ASSERT_NOT_NULL(sym_op->aead.digest.data, - "no room to append digest"); - - sym_op->aead.digest.phys_addr = digest_phys; - - if (op == RTE_CRYPTO_AEAD_OP_DECRYPT) { - rte_memcpy(sym_op->aead.digest.data, tdata->auth_tag.data, - auth_tag_len); - debug_hexdump(stdout, "digest:", - sym_op->aead.digest.data, - auth_tag_len); - } - - /* Append aad data */ - if (tdata->algo == RTE_CRYPTO_AEAD_AES_CCM) { - uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, - uint8_t *, IV_OFFSET); - - /* Copy IV 1 byte after the IV pointer, according to the API */ - rte_memcpy(iv_ptr + 1, tdata->iv.data, iv_len); - - aad_len = RTE_ALIGN_CEIL(aad_len + 18, 16); - - sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_prepend( - ut_params->ibuf, aad_len); - TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, - "no room to prepend aad"); - sym_op->aead.aad.phys_addr = rte_pktmbuf_iova( - ut_params->ibuf); - - memset(sym_op->aead.aad.data, 0, aad_len); - /* Copy AAD 18 bytes after the AAD pointer, according to the API */ - rte_memcpy(sym_op->aead.aad.data, tdata->aad.data, aad_len); - - debug_hexdump(stdout, "iv:", iv_ptr, iv_len); - debug_hexdump(stdout, "aad:", - sym_op->aead.aad.data, aad_len); - } else { - uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op, - uint8_t *, IV_OFFSET); - - rte_memcpy(iv_ptr, tdata->iv.data, iv_len); - - sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_prepend( - ut_params->ibuf, aad_len); - TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, - "no room to prepend aad"); - sym_op->aead.aad.phys_addr = rte_pktmbuf_iova( - ut_params->ibuf); - - memset(sym_op->aead.aad.data, 0, aad_len); - rte_memcpy(sym_op->aead.aad.data, tdata->aad.data, aad_len); - - debug_hexdump(stdout, "iv:", iv_ptr, iv_len); - debug_hexdump(stdout, "aad:", - sym_op->aead.aad.data, aad_len); - } - - sym_op->aead.data.length = tdata->plaintext.len; - sym_op->aead.data.offset = aad_len; - - return 0; -} - -#define SGL_MAX_NO 16 - -static int -test_authenticated_encryption_SGL(const struct aead_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 = 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 AEAD session */ - retval = create_aead_session(ts_params->valid_devs[0], - tdata->algo, - RTE_CRYPTO_AEAD_OP_ENCRYPT, - tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - tdata->iv.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 = (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_iova_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_iova(buf) + to_trn; - if (oop && buf_last_oop) - digest_phys = rte_pktmbuf_iova(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_iova_offset(ut_params->ibuf, - tdata->plaintext.len); - } - - /* Create AEAD operation */ - retval = create_aead_operation_SGL(RTE_CRYPTO_AEAD_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, - "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], - "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, - "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_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_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_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_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, i, nb_devs_attached = 0; - int ret; - char vdev_name[32]; - - /* create 2 AESNI_MB if necessary */ - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD))); - if (nb_devs < 2) { - for (i = nb_devs; i < 2; i++) { - snprintf(vdev_name, sizeof(vdev_name), "%s_%u", - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD), - i); - ret = rte_vdev_init(vdev_name, 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; - unsigned int session_size; - - rte_cryptodev_info_get(i, &info); - if (info.driver_id != rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD))) - continue; - - session_size = rte_cryptodev_sym_get_private_session_size(i); - /* - * Create the session mempool again, since now there are new devices - * to use the mempool. - */ - if (ts_params->session_mpool) { - rte_mempool_free(ts_params->session_mpool); - ts_params->session_mpool = NULL; - } - if (ts_params->session_priv_mpool) { - rte_mempool_free(ts_params->session_priv_mpool); - ts_params->session_priv_mpool = NULL; - } - - if (info.sym.max_nb_sessions != 0 && - info.sym.max_nb_sessions < MAX_NB_SESSIONS) { - RTE_LOG(ERR, USER1, - "Device does not support " - "at least %u sessions\n", - MAX_NB_SESSIONS); - return TEST_FAILED; - } - /* - * Create mempool with maximum number of sessions, - * to include the session headers - */ - if (ts_params->session_mpool == NULL) { - ts_params->session_mpool = - rte_cryptodev_sym_session_pool_create( - "test_sess_mp", - MAX_NB_SESSIONS, 0, 0, 0, - SOCKET_ID_ANY); - TEST_ASSERT_NOT_NULL(ts_params->session_mpool, - "session mempool allocation failed"); - } - - /* - * Create mempool with maximum number of sessions, - * to include device specific session private data - */ - if (ts_params->session_priv_mpool == NULL) { - ts_params->session_priv_mpool = rte_mempool_create( - "test_sess_mp_priv", - MAX_NB_SESSIONS, - session_size, - 0, 0, NULL, NULL, NULL, - NULL, SOCKET_ID_ANY, - 0); - - TEST_ASSERT_NOT_NULL(ts_params->session_priv_mpool, - "session mempool allocation failed"); - } - - ts_params->qp_conf.mp_session = ts_params->session_mpool; - ts_params->qp_conf.mp_session_private = - ts_params->session_priv_mpool; - - 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(enum rte_cryptodev_scheduler_mode scheduler_mode) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - uint8_t sched_id = ts_params->valid_devs[0]; - /* set mode */ - return rte_cryptodev_scheduler_mode_set(sched_id, - scheduler_mode); -} - -static int -test_scheduler_mode_roundrobin_op(void) -{ - TEST_ASSERT(test_scheduler_mode_op(CDEV_SCHED_MODE_ROUNDROBIN) == - 0, "Failed to set roundrobin mode"); - return 0; - -} - -static int -test_scheduler_mode_multicore_op(void) -{ - TEST_ASSERT(test_scheduler_mode_op(CDEV_SCHED_MODE_MULTICORE) == - 0, "Failed to set multicore mode"); - - return 0; -} - -static int -test_scheduler_mode_failover_op(void) -{ - TEST_ASSERT(test_scheduler_mode_op(CDEV_SCHED_MODE_FAILOVER) == - 0, "Failed to set failover mode"); - - return 0; -} - -static int -test_scheduler_mode_pkt_size_distr_op(void) -{ - TEST_ASSERT(test_scheduler_mode_op(CDEV_SCHED_MODE_PKT_SIZE_DISTR) == - 0, "Failed to set pktsize mode"); - - 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 = { - /* Multi Core */ - TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), - TEST_CASE_ST(NULL, NULL, test_scheduler_mode_multicore_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), - - /* Round Robin */ - TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), - TEST_CASE_ST(NULL, NULL, test_scheduler_mode_roundrobin_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), - - /* Fail over */ - TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), - TEST_CASE_ST(NULL, NULL, test_scheduler_mode_failover_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), - - /* PKT SIZE */ - TEST_CASE_ST(NULL, NULL, test_scheduler_attach_slave_op), - TEST_CASE_ST(NULL, NULL, test_scheduler_mode_pkt_size_distr_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_AES_docsis_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_DES_docsis_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_stats), - - /** AES CCM Authenticated Encryption 128 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_3), - - /** AES CCM Authenticated Decryption 128 bits key*/ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_3), - - /** 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_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_7), - - /** AES GCM Authenticated Encryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_7), - - /** AES GCM Authenticated Decryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_7), - - /** AES GCM Authenticated Encryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_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), - - /** 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), - - /** ZUC authenticate (EIA3) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_hash_generate_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_hash_generate_test_case_7), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_hash_generate_test_case_8), - - /** ZUC alg-chain (EEA3/EIA3) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_cipher_auth_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_zuc_cipher_auth_test_case_2), - - /** 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), - - /** KASUMI tests */ - 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_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_virtio_testsuite = { - .suite_name = "Crypto VIRTIO Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_virtio_all), - - 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 = { -#if IMB_VERSION_NUM >= IMB_VERSION(0, 51, 0) - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_7), - - /** AES GCM Authenticated Encryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_7), - - /** AES GCM Authenticated Decryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_7), - - /** AES GCM Authenticated Encryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_7), - - /** AES GCM Authenticated Decryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_7), - - /** AES GCM Authenticated Encryption big aad size */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_aad_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_aad_2), - - /** AES GCM Authenticated Decryption big aad size */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_aad_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_aad_2), - - /** Session-less tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_sessionless_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_sessionless_test_case_1), - - /** 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), -#endif /* IMB_VERSION_NUM >= IMB_VERSION(0, 51, 0) */ - - 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_AES_docsis_mb_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_mb_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_DES_cipheronly_mb_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_DES_docsis_mb_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_mb_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_3), - - 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_DES_cipheronly_openssl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_DES_docsis_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_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_7), - - - /** AES GCM Authenticated Encryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_7), - - /** AES GCM Authenticated Decryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_7), - - /** AES GCM Authenticated Encryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_7), - - /** AES GCM Authenticated Decryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_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), - - /** AES CCM Authenticated Encryption 128 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_128_3), - - /** AES CCM Authenticated Decryption 128 bits key*/ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_128_3), - - /** AES CCM Authenticated Encryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_192_3), - - /** AES CCM Authenticated Decryption 192 bits key*/ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_192_3), - - /** AES CCM Authenticated Encryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_encryption_test_case_256_3), - - /** AES CCM Authenticated Decryption 256 bits key*/ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CCM_authenticated_decryption_test_case_256_3), - - /** 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_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_7), - - /** AES GCM Authenticated Encryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_7), - - /** AES GCM Authenticated Decryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_7), - - /** AES GCM Authenticated Encryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_7), - - /** AES GCM Authenticated Decryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_7), - - /** AES GCM Authenticated Encryption big aad size */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_aad_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_aad_2), - - /** AES GCM Authenticated Decryption big aad size */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_aad_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_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_AES_GCM_authenticated_encryption_oop_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_oop_test_case_1), - - /** Session-less tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_sessionless_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_sessionless_test_case_1), - - /** 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_caam_jr_testsuite = { - .suite_name = "Crypto CAAM JR 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_multi_session), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_chain_caam_jr_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_chain_caam_jr_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_caam_jr_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_caam_jr_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_authonly_caam_jr_all), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_dpaa_sec_testsuite = { - .suite_name = "Crypto DPAA_SEC 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_multi_session), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_chain_dpaa_sec_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_chain_dpaa_sec_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_dpaa_sec_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_dpaa_sec_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_authonly_dpaa_sec_all), - - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_7), - - /** AES GCM Authenticated Encryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_7), - - /** AES GCM Authenticated Decryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_7), - - /** Out of place tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_oop_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_oop_test_case_1), - - /** Scatter-Gather */ - 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_400B_1seg), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite cryptodev_dpaa2_sec_testsuite = { - .suite_name = "Crypto DPAA2_SEC 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_multi_session), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_chain_dpaa2_sec_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_chain_dpaa2_sec_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_dpaa2_sec_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_dpaa2_sec_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_authonly_dpaa2_sec_all), - - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_7), - - /** AES GCM Authenticated Encryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_192_7), - - /** AES GCM Authenticated Decryption 192 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_192_7), - - /** AES GCM Authenticated Encryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encryption_test_case_256_7), - - /** AES GCM Authenticated Decryption 256 bits key */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_decryption_test_case_256_7), - - /** Out of place tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_oop_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_oop_test_case_1), - - /** Scatter-Gather */ - 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_400B_1seg), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B), - - 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 struct unit_test_suite cryptodev_mrvl_testsuite = { - .suite_name = "Crypto Device Marvell Component 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_mrvl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_mrvl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_authonly_mrvl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_chain_mrvl_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_mrvl_all), - - /** 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, - 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_ccp_testsuite = { - .suite_name = "Crypto Device CCP 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_ccp_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_ccp_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_chain_ccp_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_ccp_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_authonly_ccp_all), - - /** 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, - 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_octeontx_testsuite = { - .suite_name = "Crypto Device OCTEONTX Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_chain_octeontx_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_cipheronly_octeontx_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_chain_octeontx_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_3DES_cipheronly_octeontx_all), - TEST_CASE_ST(ut_setup, ut_teardown, - test_authonly_octeontx_all), - - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_encryption_test_case_7), - - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_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), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_1_oop_sgl), - - /** 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), - - /** 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), - - /** KASUMI encrypt only (UEA1) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_encryption_test_case_5), - 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_1_oop_sgl), - /** KASUMI decrypt only (UEA1) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_decryption_test_case_5), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_encryption_test_case_1_oop), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_decryption_test_case_1_oop), - - /** KASUMI hash only (UIA1) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_hash_generate_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_hash_generate_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_hash_generate_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_hash_generate_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_hash_generate_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_kasumi_hash_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), - - /** NULL tests */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_cipher_only_operation), - TEST_CASE_ST(ut_setup, ut_teardown, - test_null_auth_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), - - /** 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 int -test_cryptodev_qat(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "QAT PMD must be loaded. Check that both " - "CONFIG_RTE_LIBRTE_PMD_QAT and CONFIG_RTE_LIBRTE_PMD_QAT_SYM " - "are enabled in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_qat_testsuite); -} - -static int -test_cryptodev_virtio(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "VIRTIO PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO is enabled " - "in config file to run this testsuite.\n"); - return TEST_FAILED; - } - - return unit_test_suite_runner(&cryptodev_virtio_testsuite); -} - -static int -test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "AESNI MB PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_AESNI_MB is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_aesni_mb_testsuite); -} - -static int -test_cryptodev_openssl(void) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "OPENSSL PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_OPENSSL is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_openssl_testsuite); -} - -static int -test_cryptodev_aesni_gcm(void) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_GCM_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "AESNI GCM PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_AESNI_GCM is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_aesni_gcm_testsuite); -} - -static int -test_cryptodev_null(void) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_NULL_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "NULL PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_NULL is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_null_testsuite); -} - -static int -test_cryptodev_sw_snow3g(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_SNOW3G_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "SNOW3G PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_SNOW3G is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_sw_snow3g_testsuite); -} - -static int -test_cryptodev_sw_kasumi(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_KASUMI_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "ZUC PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_KASUMI is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_sw_kasumi_testsuite); -} - -static int -test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ZUC_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "ZUC PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_ZUC is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_sw_zuc_testsuite); -} - -static int -test_cryptodev_armv8(void) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "ARMV8 PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_ARMV8 is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_armv8_testsuite); -} - -static int -test_cryptodev_mrvl(void) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "MVSAM PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_MVSAM_CRYPTO is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_mrvl_testsuite); -} - -#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER - -static int -test_cryptodev_scheduler(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "SCHEDULER PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_SCHEDULER is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - if (rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)) == -1) { - RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_AESNI_MB must be" - " enabled in config file to run this testsuite.\n"); - return TEST_SKIPPED; -} - return unit_test_suite_runner(&cryptodev_scheduler_testsuite); -} - -REGISTER_TEST_COMMAND(cryptodev_scheduler_autotest, test_cryptodev_scheduler); - -#endif - -static int -test_cryptodev_dpaa2_sec(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "DPAA2 SEC PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_dpaa2_sec_testsuite); -} - -static int -test_cryptodev_dpaa_sec(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "DPAA SEC PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_DPAA_SEC is enabled " - "in config file to run this testsuite.\n"); - return TEST_SKIPPED; - } - - return unit_test_suite_runner(&cryptodev_dpaa_sec_testsuite); -} - -static int -test_cryptodev_ccp(void) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "CCP PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_CCP is enabled " - "in config file to run this testsuite.\n"); - return TEST_FAILED; - } - - return unit_test_suite_runner(&cryptodev_ccp_testsuite); -} - -static int -test_cryptodev_octeontx(void) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)); - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "OCTEONTX PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_OCTEONTX_CRYPTO is " - "enabled in config file to run this " - "testsuite.\n"); - return TEST_FAILED; - } - return unit_test_suite_runner(&cryptodev_octeontx_testsuite); -} - -static int -test_cryptodev_caam_jr(void /*argv __rte_unused, int argc __rte_unused*/) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "CAAM_JR PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_CAAM_JR is enabled " - "in config file to run this testsuite.\n"); - return TEST_FAILED; - } - - return unit_test_suite_runner(&cryptodev_caam_jr_testsuite); -} - -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); -REGISTER_TEST_COMMAND(cryptodev_sw_mvsam_autotest, test_cryptodev_mrvl); -REGISTER_TEST_COMMAND(cryptodev_dpaa2_sec_autotest, test_cryptodev_dpaa2_sec); -REGISTER_TEST_COMMAND(cryptodev_dpaa_sec_autotest, test_cryptodev_dpaa_sec); -REGISTER_TEST_COMMAND(cryptodev_ccp_autotest, test_cryptodev_ccp); -REGISTER_TEST_COMMAND(cryptodev_virtio_autotest, test_cryptodev_virtio); -REGISTER_TEST_COMMAND(cryptodev_octeontx_autotest, test_cryptodev_octeontx); -REGISTER_TEST_COMMAND(cryptodev_caam_jr_autotest, test_cryptodev_caam_jr); diff --git a/test/test/test_cryptodev.h b/test/test/test_cryptodev.h deleted file mode 100644 index a73a49e72f..0000000000 --- a/test/test/test_cryptodev.h +++ /dev/null @@ -1,208 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015-2017 Intel Corporation - */ -#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) - -#define MAXIMUM_IV_LENGTH (16) - -#define IV_OFFSET (sizeof(struct rte_crypto_op) + \ - sizeof(struct rte_crypto_sym_op) + DEFAULT_NUM_XFORMS * \ - sizeof(struct rte_crypto_sym_xform)) - -#define CRYPTODEV_NAME_NULL_PMD crypto_null -#define CRYPTODEV_NAME_AESNI_MB_PMD crypto_aesni_mb -#define CRYPTODEV_NAME_AESNI_GCM_PMD crypto_aesni_gcm -#define CRYPTODEV_NAME_OPENSSL_PMD crypto_openssl -#define CRYPTODEV_NAME_QAT_SYM_PMD crypto_qat -#define CRYPTODEV_NAME_SNOW3G_PMD crypto_snow3g -#define CRYPTODEV_NAME_KASUMI_PMD crypto_kasumi -#define CRYPTODEV_NAME_ZUC_PMD crypto_zuc -#define CRYPTODEV_NAME_ARMV8_PMD crypto_armv8 -#define CRYPTODEV_NAME_DPAA_SEC_PMD crypto_dpaa_sec -#define CRYPTODEV_NAME_DPAA2_SEC_PMD crypto_dpaa2_sec -#define CRYPTODEV_NAME_SCHEDULER_PMD crypto_scheduler -#define CRYPTODEV_NAME_MVSAM_PMD crypto_mvsam -#define CRYPTODEV_NAME_CCP_PMD crypto_ccp -#define CRYPTODEV_NAME_VIRTIO_PMD crypto_virtio -#define CRYPTODEV_NAME_OCTEONTX_SYM_PMD crypto_octeontx -#define CRYPTODEV_NAME_CAAM_JR_PMD crypto_caam_jr - -/** - * 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 rte_iova_t -pktmbuf_iova_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_iova_offset: offset out of buffer\n"); - return 0; - } - return rte_pktmbuf_iova_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_aead_test_vectors.h b/test/test/test_cryptodev_aead_test_vectors.h deleted file mode 100644 index a4a3a25c9d..0000000000 --- a/test/test/test_cryptodev_aead_test_vectors.h +++ /dev/null @@ -1,3775 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015-2017 Intel Corporation - */ - -#ifndef TEST_CRYPTODEV_AEAD_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_AEAD_TEST_VECTORS_H_ - -#define GMAC_LARGE_PLAINTEXT_LENGTH 65344 -#define MAX_AAD_LENGTH 65536 -#define GCM_LARGE_AAD_LENGTH 65296 - -static uint8_t gcm_aad_zero_text[MAX_AAD_LENGTH] = { 0 }; - -static uint8_t gcm_aad_text[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 }; - -static uint8_t ccm_aad_test_1[8] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 -}; - -static uint8_t ccm_aad_test_2[22] = { - 0x08, 0x40, 0x0F, 0xD2, 0xE1, 0x28, 0xA5, 0x7C, - 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xAB, 0xAE, - 0xA5, 0xB8, 0xFC, 0xBA, 0x00, 0x00 -}; - -struct aead_test_data { - enum rte_crypto_aead_algorithm algo; - - 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; - } plaintext; - - struct { - uint8_t data[16]; - unsigned len; - } gmac_tag; - -}; - -/** AES-GCM-128 Test Vectors */ -static const struct aead_test_data gcm_test_case_1 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -static const struct aead_test_data gcm_test_case_2 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -static const struct aead_test_data gcm_test_case_3 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -static const struct aead_test_data gcm_test_case_4 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } - -}; - -static const struct aead_test_data gcm_test_case_5 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } - -}; - -static const struct aead_test_data gcm_test_case_6 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -static const struct aead_test_data gcm_test_case_7 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 aead_test_data gcm_test_case_8 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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-GCM-192 Test Vectors */ -static const struct aead_test_data gcm_test_case_192_1 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - }, - .len = 24 - }, - .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 = { - 0xCD, 0x33, 0xB2, 0x8A, 0xC7, 0x73, 0xF7, 0x4B, - 0xA0, 0x0E, 0xD1, 0xF3, 0x12, 0x57, 0x24, 0x35 - }, - .len = 16 - } -}; - -static const struct aead_test_data gcm_test_case_192_2 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - }, - .len = 24 - }, - .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 = { - 0x98, 0xE7, 0x24, 0x7C, 0x07, 0xF0, 0xFE, 0x41, - 0x1C, 0x26, 0x7E, 0x43, 0x84, 0xB0, 0xF6, 0x00 - }, - .len = 16 - }, - .auth_tag = { - .data = { - 0x2F, 0xF5, 0x8D, 0x80, 0x03, 0x39, 0x27, 0xAB, - 0x8E, 0xF4, 0xD4, 0x58, 0x75, 0x14, 0xF0, 0xFB - - }, - .len = 16 - } -}; - -static const struct aead_test_data gcm_test_case_192_3 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .key = { - .data = { - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, - 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C - }, - .len = 24 - }, - .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 = { - 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, - 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, - 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, - 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, - 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, - 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, - 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, - 0xCC, 0xDA, 0x27, 0x10, 0xAC, 0xAD, 0xE2, 0x56 - }, - .len = 64 - }, - .auth_tag = { - .data = { - 0x99, 0x24, 0xA7, 0xC8, 0x58, 0x73, 0x36, 0xBF, - 0xB1, 0x18, 0x02, 0x4D, 0xB8, 0x67, 0x4A, 0x14 - }, - .len = 16 - } -}; - -static const struct aead_test_data gcm_test_case_192_4 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .key = { - .data = { - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, - 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C - }, - .len = 24 - }, - .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 = { - 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, - 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, - 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, - 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, - 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, - 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, - 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, - 0xCC, 0xDA, 0x27, 0x10 - }, - .len = 60 - }, - .auth_tag = { - .data = { - 0x57, 0x5F, 0x03, 0xA0, 0x8D, 0x8F, 0x40, 0x26, - 0xE5, 0x64, 0x1F, 0x5B, 0x5C, 0xC2, 0xFD, 0x4B - }, - .len = 16 - } -}; - -static const struct aead_test_data gcm_test_case_192_5 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .key = { - .data = { - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, - 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C - }, - .len = 24 - }, - .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 = { - 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, - 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, - 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, - 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, - 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, - 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, - 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, - 0xCC, 0xDA, 0x27, 0x10 - }, - .len = 60 - }, - .auth_tag = { - .data = { - 0xB6, 0x35, 0x56, 0xE7, 0xBA, 0x46, 0xA3, 0x38, - 0xED, 0xAD, 0x79, 0x9F, 0xB3, 0x5B, 0x34, 0xA8 - }, - .len = 16 - } -}; - -static const struct aead_test_data gcm_test_case_192_6 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .key = { - .data = { - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, - 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C - }, - .len = 24 - }, - .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 = { - 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, - 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, - 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, - 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, - 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, - 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, - 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, - 0xCC, 0xDA, 0x27, 0x10 - }, - .len = 60 - }, - .auth_tag = { - .data = { - 0xCA, 0x8A, 0x8A, 0x91, 0x5A, 0xF9, 0x76, 0xE3, - 0xFF, 0x2C, 0xE4, 0x7D, 0xE5, 0x62, 0x75, 0x18 - }, - .len = 16 - } -}; - -static const struct aead_test_data gcm_test_case_192_7 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .key = { - .data = { - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, - 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C - }, - .len = 24 - }, - .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 = { - 0x39, 0x80, 0xCA, 0x0B, 0x3C, 0x00, 0xE8, 0x41, - 0xEB, 0x06, 0xFA, 0xC4, 0x87, 0x2A, 0x27, 0x57, - 0x85, 0x9E, 0x1C, 0xEA, 0xA6, 0xEF, 0xD9, 0x84, - 0x62, 0x85, 0x93, 0xB4, 0x0C, 0xA1, 0xE1, 0x9C, - 0x7D, 0x77, 0x3D, 0x00, 0xC1, 0x44, 0xC5, 0x25, - 0xAC, 0x61, 0x9D, 0x18, 0xC8, 0x4A, 0x3F, 0x47, - 0x18, 0xE2, 0x44, 0x8B, 0x2F, 0xE3, 0x24, 0xD9, - 0xCC, 0xDA, 0x27, 0x10 - }, - .len = 60 - }, - .auth_tag = { - .data = { - 0xC2, 0xD8, 0x4C, 0x6B, 0xA8, 0x3B, 0xA5, 0x6B, - 0x18, 0x9F, 0xE6, 0xEF, 0x66, 0x24, 0xDD, 0xDA - }, - .len = 16 - } -}; - -/** AES-GCM-256 Test Vectors */ -static const struct aead_test_data gcm_test_case_256_1 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -static const struct aead_test_data gcm_test_case_256_2 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -static const struct aead_test_data gcm_test_case_256_3 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -static const struct aead_test_data gcm_test_case_256_4 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } - -}; - -static const struct aead_test_data gcm_test_case_256_5 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } - -}; - -static const struct aead_test_data gcm_test_case_256_6 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -static const struct aead_test_data gcm_test_case_256_7 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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-GCM-128 Test Vectors */ -static const struct aead_test_data gcm_test_case_aad_1 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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-GCM-256 Test Vectors */ -static const struct aead_test_data gcm_test_case_aad_2 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - }, - .plaintext = { - .data = gmac_plaintext, - .len = 160 - }, - .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 - }, - .plaintext = { - .data = gmac_plaintext, - .len = 80 - }, - .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 - }, - .plaintext = { - .data = gmac_plaintext, - .len = 65 - }, - .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 - }, - .plaintext = { - .data = gmac_plaintext, - .len = GMAC_LARGE_PLAINTEXT_LENGTH - }, - .gmac_tag = { - .data = { - 0x3f, 0x07, 0xcb, 0xb9, 0x86, 0x3a, 0xea, 0xc2, - 0x2f, 0x3a, 0x2a, 0x93, 0xd8, 0x09, 0x6b, 0xda - }, - .len = 16 - } -}; - -static const struct aead_test_data gcm_test_case_SGL_1 = { - .algo = RTE_CRYPTO_AEAD_AES_GCM, - .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 - } -}; - -/** AES-CCM-128 Test Vectors */ -static const struct aead_test_data ccm_test_case_128_1 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F - }, - .len = 16 - }, - .iv = { - .data = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 - }, - .len = 7 - }, - .aad = { - .data = ccm_aad_test_1, - .len = 8 - }, - .plaintext = { - .data = { - 0x20, 0x21, 0x22, 0x23 - }, - .len = 4 - }, - .ciphertext = { - .data = { - 0x71, 0x62, 0x01, 0x5B - }, - .len = 4 - }, - .auth_tag = { - .data = { - 0x4D, 0xAC, 0x25, 0x5D - }, - .len = 4 - } -}; - -static const struct aead_test_data ccm_test_case_128_2 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, - 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, - 0x03, 0x97, 0x76, 0xE7, 0x0C - }, - .len = 13 - }, - .aad = { - .data = ccm_aad_test_2, - .len = 22 - }, - .plaintext = { - .data = { - 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, - 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, - 0x7E, 0x78, 0xA0, 0x50 - }, - .len = 20 - }, - .ciphertext = { - .data = { - 0xF3, 0xD0, 0xA2, 0xFE, 0x9A, 0x3D, 0xBF, 0x23, - 0x42, 0xA6, 0x43, 0xE4, 0x32, 0x46, 0xE8, 0x0C, - 0x3C, 0x04, 0xD0, 0x19 - }, - .len = 20 - }, - .auth_tag = { - .data = { - 0x78, 0x45, 0xCE, 0x0B, 0x16, 0xF9, 0x76, 0x23 - }, - .len = 8 - } -}; - -static const struct aead_test_data ccm_test_case_128_3 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, - 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, - 0x03, 0x97, 0x76, 0xE7, 0x0C - }, - .len = 13 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, - 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, - 0x7E, 0x78, 0xA0, 0x50 - }, - .len = 20 - }, - .ciphertext = { - .data = { - 0xF3, 0xD0, 0xA2, 0xFE, 0x9A, 0x3D, 0xBF, 0x23, - 0x42, 0xA6, 0x43, 0xE4, 0x32, 0x46, 0xE8, 0x0C, - 0x3C, 0x04, 0xD0, 0x19 - }, - .len = 20 - }, - .auth_tag = { - .data = { - 0x41, 0x83, 0x21, 0x89, 0xA3, 0xD3, 0x1B, 0x43 - }, - .len = 8 - } -}; - -/** AES-CCM-192 Test Vectors */ -static const struct aead_test_data ccm_test_case_192_1 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 - }, - .len = 24 - }, - .iv = { - .data = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 - }, - .len = 7 - }, - .aad = { - .data = ccm_aad_test_1, - .len = 8 - }, - .plaintext = { - .data = { - 0x20, 0x21, 0x22, 0x23 - }, - .len = 4 - }, - .ciphertext = { - .data = { - 0x18, 0xEE, 0x17, 0x30 - }, - .len = 4 - }, - .auth_tag = { - .data = { - 0xC8, 0xC3, 0x26, 0xD5 - }, - .len = 4 - } -}; - -static const struct aead_test_data ccm_test_case_192_2 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, - 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, - 0x03, 0x97, 0x76, 0xE7, 0x0C - }, - .len = 13 - }, - .aad = { - .data = ccm_aad_test_2, - .len = 22 - }, - .plaintext = { - .data = { - 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, - 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, - 0x7E, 0x78, 0xA0, 0x50 - }, - .len = 20 - }, - .ciphertext = { - .data = { - 0x41, 0xC6, 0x2D, 0xD5, 0x31, 0xF2, 0xD5, 0xC8, - 0xCC, 0x57, 0x01, 0x2E, 0x7E, 0x2B, 0xF1, 0x26, - 0x6A, 0xC7, 0xCB, 0xA5 - }, - .len = 20 - }, - .auth_tag = { - .data = { - 0x77, 0xA3, 0x41, 0xD5, 0x2A, 0xE3, 0x25, 0x37 - }, - .len = 8 - } -}; - -static const struct aead_test_data ccm_test_case_192_3 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, - 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 - }, - .len = 24 - }, - .iv = { - .data = { - 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, - 0x03, 0x97, 0x76, 0xE7, 0x0C - }, - .len = 13 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, - 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, - 0x7E, 0x78, 0xA0, 0x50 - }, - .len = 20 - }, - .ciphertext = { - .data = { - 0x41, 0xC6, 0x2D, 0xD5, 0x31, 0xF2, 0xD5, 0xC8, - 0xCC, 0x57, 0x01, 0x2E, 0x7E, 0x2B, 0xF1, 0x26, - 0x6A, 0xC7, 0xCB, 0xA5 - }, - .len = 20 - }, - .auth_tag = { - .data = { - 0x84, 0x72, 0x6E, 0xE7, 0x8E, 0x8E, 0x3A, 0xC6 - }, - .len = 8 - } -}; - -/** AES-CCM-256 Test Vectors */ -static const struct aead_test_data ccm_test_case_256_1 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F - }, - .len = 32 - }, - .iv = { - .data = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 - }, - .len = 7 - }, - .aad = { - .data = ccm_aad_test_1, - .len = 8 - }, - .plaintext = { - .data = { - 0x20, 0x21, 0x22, 0x23 - }, - .len = 4 - }, - .ciphertext = { - .data = { - 0x8A, 0xB1, 0xA8, 0x74 - }, - .len = 4 - }, - .auth_tag = { - .data = { - 0x95, 0xFC, 0x08, 0x20 - }, - .len = 4 - } -}; - -static const struct aead_test_data ccm_test_case_256_2 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, - 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F - }, - .len = 32 - }, - .iv = { - .data = { - 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, - 0x03, 0x97, 0x76, 0xE7, 0x0C - }, - .len = 13 - }, - .aad = { - .data = ccm_aad_test_2, - .len = 22 - }, - .plaintext = { - .data = { - 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, - 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, - 0x7E, 0x78, 0xA0, 0x50 - }, - .len = 20 - }, - .ciphertext = { - .data = { - 0x25, 0x82, 0x89, 0x09, 0x3E, 0x39, 0x1F, 0x16, - 0xD2, 0x82, 0x3D, 0xF6, 0xCE, 0x97, 0x72, 0x07, - 0xEC, 0x23, 0x17, 0x98 - }, - .len = 20 - }, - .auth_tag = { - .data = { - 0xAB, 0x02, 0xE9, 0xD1, 0x16, 0x69, 0xED, 0x0A - }, - .len = 8 - } -}; - -static const struct aead_test_data ccm_test_case_256_3 = { - .algo = RTE_CRYPTO_AEAD_AES_CCM, - .key = { - .data = { - 0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85, - 0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F - }, - .len = 32 - }, - .iv = { - .data = { - 0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5, - 0x03, 0x97, 0x76, 0xE7, 0x0C - }, - .len = 13 - }, - .aad = { - .data = gcm_aad_zero_text, - .len = 0 - }, - .plaintext = { - .data = { - 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, - 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, - 0x7E, 0x78, 0xA0, 0x50 - }, - .len = 20 - }, - .ciphertext = { - .data = { - 0x25, 0x82, 0x89, 0x09, 0x3E, 0x39, 0x1F, 0x16, - 0xD2, 0x82, 0x3D, 0xF6, 0xCE, 0x97, 0x72, 0x07, - 0xEC, 0x23, 0x17, 0x98 - }, - .len = 20 - }, - .auth_tag = { - .data = { - 0x15, 0x80, 0xC4, 0xC9, 0x3F, 0xAB, 0x2A, 0xFD - }, - .len = 8 - } -}; -#endif /* TEST_CRYPTODEV_AEAD_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_aes_test_vectors.h b/test/test/test_cryptodev_aes_test_vectors.h deleted file mode 100644 index 6dd8e5f961..0000000000 --- a/test/test/test_cryptodev_aes_test_vectors.h +++ /dev/null @@ -1,1914 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#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 ciphertext64_aes128ctr_IV_12bytes[] = { - 0x28, 0x80, 0x28, 0xC7, 0x15, 0x99, 0xC5, 0xA8, - 0xDD, 0x53, 0xC2, 0x67, 0x1B, 0x86, 0xB8, 0x13, - 0xAB, 0x25, 0x39, 0x7A, 0xD2, 0x1F, 0x8B, 0x4B, - 0x94, 0x89, 0x2B, 0x65, 0xCF, 0x89, 0x1E, 0xDD, - 0xD4, 0x7C, 0xFD, 0x8D, 0x0E, 0xCD, 0x23, 0xA4, - 0xEB, 0x8C, 0x05, 0x58, 0x45, 0x4A, 0x63, 0x44, - 0x11, 0x42, 0x07, 0x17, 0xB4, 0xD2, 0xCC, 0x75, - 0xB7, 0x23, 0x99, 0xA9, 0xC5, 0x89, 0x7F, 0x66 -}; - -static const uint8_t plaintext_aes_docsis_bpi_cfb[] = { - 0x00, 0x01, 0x02, 0x88, 0xEE, 0x59, 0x7E -}; - -static const uint8_t ciphertext_aes_docsis_bpi_cfb[] = { - 0xFC, 0x68, 0xA3, 0x55, 0x60, 0x37, 0xDC -}; - -static const uint8_t plaintext_aes_docsis_bpi_cbc_cfb[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x91, - 0xD2, 0xD1, 0x9F -}; - -static const uint8_t ciphertext_aes_docsis_bpi_cbc_cfb[] = { - 0x9D, 0xD1, 0x67, 0x4B, 0xBA, 0x61, 0x10, 0x1B, - 0x56, 0x75, 0x64, 0x74, 0x36, 0x4F, 0x10, 0x1D, - 0x44, 0xD4, 0x73 -}; - -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 ciphertext64_aes192ctr_IV_12bytes[] = { - 0x67, 0x65, 0xa9, 0xee, 0xfd, 0x31, 0x62, 0xfc, - 0xad, 0xfd, 0xc7, 0x25, 0xb7, 0x25, 0x16, 0xbe, - 0x25, 0xce, 0xc0, 0x1d, 0xda, 0xa9, 0xd3, 0xda, - 0x1b, 0x7d, 0x68, 0x6a, 0x6f, 0x06, 0xea, 0x47, - 0xa0, 0xe0, 0x15, 0xf4, 0xbd, 0x1b, 0x70, 0x34, - 0xd4, 0x6d, 0x1c, 0x84, 0x17, 0x91, 0x46, 0x0c, - 0xe8, 0xbc, 0x7a, 0xfb, 0x9f, 0x2a, 0x8f, 0xb4, - 0xd4, 0xf3, 0x6e, 0x5b, 0x75, 0xa0, 0xce, 0x32 -}; - -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 ciphertext64_aes256ctr_IV_12bytes[] = { - 0x7B, 0x7A, 0x7D, 0x83, 0x85, 0xF8, 0x81, 0xF3, - 0x32, 0x33, 0xD9, 0xFB, 0x04, 0x73, 0xD4, 0x2F, - 0x70, 0xDE, 0x90, 0x3E, 0xD0, 0xA9, 0x93, 0x8A, - 0x91, 0xF3, 0xB5, 0x29, 0x4D, 0x2A, 0x74, 0xD0, - 0xDC, 0x4E, 0x5C, 0x9B, 0x97, 0x24, 0xD8, 0x02, - 0xFE, 0xAB, 0x38, 0xE8, 0x73, 0x51, 0x29, 0x7E, - 0xF1, 0xF9, 0x40, 0x78, 0xB1, 0x04, 0x7A, 0x78, - 0x61, 0x07, 0x47, 0xE6, 0x8C, 0x0F, 0xA8, 0x76 -}; - -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 - } -}; - -/* AES128-CTR-SHA1 test vector (12-byte IV) */ -static const struct blockcipher_test_data aes_test_data_1_IV_12_bytes = { - .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 - }, - .len = 12 - }, - .plaintext = { - .data = plaintext_aes128ctr, - .len = 64 - }, - .ciphertext = { - .data = ciphertext64_aes128ctr_IV_12bytes, - .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 = { - 0x5C, 0x34, 0x6B, 0xE4, 0x9A, 0x7F, 0x4A, 0xC3, - 0x82, 0xBE, 0xA0, 0x12, 0xD1, 0xF0, 0x15, 0xFA, - 0xCF, 0xC8, 0x7F, 0x60 - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-192-CTR XCBC test vector (12-byte IV) */ -static const struct blockcipher_test_data aes_test_data_2_IV_12_bytes = { - .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 - }, - .len = 12 - }, - .plaintext = { - .data = plaintext_aes192ctr, - .len = 64 - }, - .ciphertext = { - .data = ciphertext64_aes192ctr_IV_12bytes, - .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 = { - 0x0C, 0xA1, 0xA5, 0xAF, 0x3E, 0x41, 0xD2, 0xF4, - 0x4C, 0x4C, 0xAB, 0x13 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-256-CTR SHA1 test vector (12-byte IV) */ -static const struct blockcipher_test_data aes_test_data_3_IV_12_bytes = { - .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 - }, - .len = 12 - }, - .plaintext = { - .data = plaintext_aes256ctr, - .len = 64 - }, - .ciphertext = { - .data = ciphertext64_aes256ctr_IV_12bytes, - .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 = { - 0x57, 0x9A, 0x52, 0x6E, 0x31, 0x17, 0x57, 0x49, - 0xE7, 0xA1, 0x88, 0x6C, 0x2E, 0x36, 0x67, 0x63, - 0x3F, 0x2D, 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 - } -}; - -/* AES-DOCSIS-BPI test vectors */ - -/* Multiple of AES block size */ -static const struct blockcipher_test_data aes_test_data_docsis_1 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI, - .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 - } -}; - -/* Less than AES block size */ -static const struct blockcipher_test_data aes_test_data_docsis_2 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI, - .cipher_key = { - .data = { - 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB, - 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB - }, - .len = 16 - }, - .iv = { - .data = { - 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A, - 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A - }, - .len = 16 - }, - .plaintext = { - .data = plaintext_aes_docsis_bpi_cfb, - .len = 7 - }, - .ciphertext = { - .data = ciphertext_aes_docsis_bpi_cfb, - .len = 7 - } -}; - -/* Not multiple of AES block size */ -static const struct blockcipher_test_data aes_test_data_docsis_3 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI, - .cipher_key = { - .data = { - 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB, - 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB - }, - .len = 16 - }, - .iv = { - .data = { - 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A, - 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A - }, - .len = 16 - }, - .plaintext = { - .data = plaintext_aes_docsis_bpi_cbc_cfb, - .len = 19 - }, - .ciphertext = { - .data = ciphertext_aes_docsis_bpi_cbc_cfb, - .len = 19 - } -}; - -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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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_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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify Scatter Gather", - .test_data = &aes_test_data_4, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, -}; - -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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "AES-192-CBC Decryption Scatter Gather", - .test_data = &aes_test_data_10, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "AES-256-CBC OOP Encryption", - .test_data = &aes_test_data_11, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO - }, - { - .test_descr = "AES-256-CBC OOP Decryption", - .test_data = &aes_test_data_11, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "AES-128-CTR Encryption (12-byte IV)", - .test_data = &aes_test_data_1_IV_12_bytes, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "AES-192-CTR Encryption (12-byte IV)", - .test_data = &aes_test_data_2_IV_12_bytes, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "AES-256-CTR Encryption (12-byte IV)", - .test_data = &aes_test_data_3_IV_12_bytes, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - } -}; - -static const struct blockcipher_test_case aes_docsis_test_cases[] = { - - { - .test_descr = "AES-DOCSIS-BPI Full Block Encryption", - .test_data = &aes_test_data_docsis_1, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI Runt Block Encryption", - .test_data = &aes_test_data_docsis_2, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI Uneven Encryption", - .test_data = &aes_test_data_docsis_3, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI Full Block Decryption", - .test_data = &aes_test_data_docsis_1, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI Runt Block Decryption", - .test_data = &aes_test_data_docsis_2, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI Uneven Decryption", - .test_data = &aes_test_data_docsis_3, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI OOP Full Block Encryption", - .test_data = &aes_test_data_docsis_1, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI OOP Runt Block Encryption", - .test_data = &aes_test_data_docsis_2, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI OOP Uneven Block Encryption", - .test_data = &aes_test_data_docsis_3, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI OOP Full Block Decryption", - .test_data = &aes_test_data_docsis_1, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI OOP Runt Block Decryption", - .test_data = &aes_test_data_docsis_2, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-DOCSIS-BPI OOP Uneven Block Decryption", - .test_data = &aes_test_data_docsis_3, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT - } -}; -#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_asym.c b/test/test/test_cryptodev_asym.c deleted file mode 100644 index 0f6fc5767d..0000000000 --- a/test/test/test_cryptodev_asym.c +++ /dev/null @@ -1,1372 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Cavium Networks - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "test_cryptodev.h" -#include "test_cryptodev_dh_test_vectors.h" -#include "test_cryptodev_dsa_test_vectors.h" -#include "test_cryptodev_mod_test_vectors.h" -#include "test_cryptodev_rsa_test_vectors.h" -#include "test_cryptodev_asym_util.h" -#include "test.h" - -#define TEST_NUM_BUFS 10 -#define TEST_NUM_SESSIONS 4 - -static int gbl_driver_id; -struct crypto_testsuite_params { - struct rte_mempool *op_mpool; - struct rte_mempool *session_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_cryptodev_asym_session *sess; - struct rte_crypto_op *op; -}; - -static struct crypto_testsuite_params testsuite_params = { NULL }; - -static int -test_rsa_sign_verify(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - uint8_t output_buf[TEST_DATA_SIZE] = {0}; - uint8_t input_buf[TEST_DATA_SIZE] = {0}; - - sess = rte_cryptodev_asym_session_create(sess_mpool); - - if (!sess) { - RTE_LOG(ERR, USER1, "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - /* set up crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, - "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - asym_op = op->asym; - /* Compute sign on the test vector */ - asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; - - memcpy(input_buf, &rsaplaintext.data, - rsaplaintext.len); - asym_op->rsa.message.data = input_buf; - asym_op->rsa.message.length = rsaplaintext.len; - asym_op->rsa.sign.data = output_buf; - asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1; - - debug_hexdump(stdout, "message", asym_op->rsa.message.data, - asym_op->rsa.message.length); - - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - debug_hexdump(stdout, "signed message", asym_op->rsa.sign.data, - asym_op->rsa.sign.length); - asym_op = result_op->asym; - - /* Verify sign */ - asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; - asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2; - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - status = TEST_SUCCESS; - if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - -error_exit: - - if (sess) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - - if (op) - rte_crypto_op_free(op); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return status; -} - -static int -test_rsa_enc_dec(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - uint8_t input_buf[TEST_DATA_SIZE] = {0}; - - sess = rte_cryptodev_asym_session_create(sess_mpool); - - if (!sess) { - RTE_LOG(ERR, USER1, "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - /* set up crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, - "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - asym_op = op->asym; - /*Compute encryption on the test vector */ - asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT; - - memcpy(input_buf, rsaplaintext.data, - rsaplaintext.len); - asym_op->rsa.message.data = input_buf; - asym_op->rsa.message.length = rsaplaintext.len; - asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2; - - debug_hexdump(stdout, "message", asym_op->rsa.message.data, - asym_op->rsa.message.length); - - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - debug_hexdump(stdout, "encrypted message", asym_op->rsa.message.data, - asym_op->rsa.message.length); - /* Use the resulted output as decryption Input vector*/ - asym_op = result_op->asym; - asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_DECRYPT; - asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1; - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - status = TEST_SUCCESS; - int ret = 0; - ret = rsa_verify(&rsaplaintext, result_op); - if (ret) - status = TEST_FAILED; - -error_exit: - - if (sess) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - - if (op) - rte_crypto_op_free(op); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return status; -} - -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->op_mpool = rte_crypto_op_pool_create( - "CRYPTO_ASYM_OP_POOL", - RTE_CRYPTO_OP_TYPE_ASYMMETRIC, - TEST_NUM_BUFS, 0, - 0, - rte_socket_id()); - if (ts_params->op_mpool == NULL) { - RTE_LOG(ERR, USER1, "Can't create ASYM_CRYPTO_OP_POOL\n"); - return TEST_FAILED; - } - - /* Create an OPENSSL device if required */ - if (gbl_driver_id == rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))) { - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))); - if (nb_devs < 1) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), - NULL); - - TEST_ASSERT(ret == 0, "Failed to create " - "instance of pmd : %s", - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); - } - } - - 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.driver_id == gbl_driver_id) - 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); - - /* check if device support asymmetric, skip if not */ - if (!(info.feature_flags & - RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) { - RTE_LOG(ERR, USER1, "Device doesn't support asymmetric. " - "Test Skipped.\n"); - return TEST_FAILED; - } - - /* configure device with num qp */ - ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs; - ts_params->conf.socket_id = SOCKET_ID_ANY; - 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); - - /* configure qp */ - ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; - ts_params->qp_conf.mp_session = ts_params->session_mpool; - ts_params->qp_conf.mp_session_private = ts_params->session_mpool; - 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 ASYM", - qp_id, dev_id); - } - - /* setup asym session pool */ - unsigned int session_size = - rte_cryptodev_asym_get_private_session_size(dev_id); - /* - * Create mempool with TEST_NUM_SESSIONS * 2, - * to include the session headers - */ - ts_params->session_mpool = rte_mempool_create( - "test_asym_sess_mp", - TEST_NUM_SESSIONS * 2, - session_size, - 0, 0, NULL, NULL, NULL, - NULL, SOCKET_ID_ANY, - 0); - - TEST_ASSERT_NOT_NULL(ts_params->session_mpool, - "session mempool allocation failed"); - - return TEST_SUCCESS; -} - -static void -testsuite_teardown(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - - if (ts_params->op_mpool != NULL) { - RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n", - rte_mempool_avail_count(ts_params->op_mpool)); - } - - /* Free session mempools */ - if (ts_params->session_mpool != NULL) { - rte_mempool_free(ts_params->session_mpool); - ts_params->session_mpool = NULL; - } -} - -static int -ut_setup(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - - uint16_t qp_id; - - /* Reconfigure device to default parameters */ - ts_params->conf.socket_id = SOCKET_ID_ANY; - - 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 rte_cryptodev_stats stats; - - rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats); - - /* Stop the device */ - rte_cryptodev_stop(ts_params->valid_devs[0]); -} - -static inline void print_asym_capa( - const struct rte_cryptodev_asymmetric_xform_capability *capa) -{ - int i = 0; - - printf("\nxform type: %s\n===================\n", - rte_crypto_asym_xform_strings[capa->xform_type]); - printf("operation supported -"); - - for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) { - /* check supported operations */ - if (rte_cryptodev_asym_xform_capability_check_optype(capa, i)) - printf(" %s", - rte_crypto_asym_op_strings[i]); - } - switch (capa->xform_type) { - case RTE_CRYPTO_ASYM_XFORM_RSA: - case RTE_CRYPTO_ASYM_XFORM_MODINV: - case RTE_CRYPTO_ASYM_XFORM_MODEX: - case RTE_CRYPTO_ASYM_XFORM_DH: - case RTE_CRYPTO_ASYM_XFORM_DSA: - printf(" modlen: min %d max %d increment %d\n", - capa->modlen.min, - capa->modlen.max, - capa->modlen.increment); - break; - default: - break; - } -} - -static int -test_capability(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_cryptodev_info dev_info; - const struct rte_cryptodev_capabilities *dev_capa; - int i = 0; - struct rte_cryptodev_asym_capability_idx idx; - const struct rte_cryptodev_asymmetric_xform_capability *capa; - - rte_cryptodev_info_get(dev_id, &dev_info); - if (!(dev_info.feature_flags & - RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) { - RTE_LOG(INFO, USER1, - "Device doesn't support asymmetric. Test Skipped\n"); - return TEST_SUCCESS; - } - - /* print xform capability */ - for (i = 0; - dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED; - i++) { - dev_capa = &(dev_info.capabilities[i]); - if (dev_info.capabilities[i].op == - RTE_CRYPTO_OP_TYPE_ASYMMETRIC) { - idx.type = dev_capa->asym.xform_capa.xform_type; - - capa = rte_cryptodev_asym_capability_get(dev_id, - (const struct - rte_cryptodev_asym_capability_idx *) &idx); - print_asym_capa(capa); - } - } - return TEST_SUCCESS; -} - -static int -test_dh_gen_shared_sec(struct rte_crypto_asym_xform *xfrm) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - uint8_t output[TEST_DH_MOD_LEN]; - struct rte_crypto_asym_xform xform = *xfrm; - uint8_t peer[] = "01234567890123456789012345678901234567890123456789"; - - sess = rte_cryptodev_asym_session_create(sess_mpool); - if (sess == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - /* set up crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - asym_op = op->asym; - - /* Setup a xform and op to generate private key only */ - xform.dh.type = RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE; - xform.next = NULL; - asym_op->dh.priv_key.data = dh_test_params.priv_key.data; - asym_op->dh.priv_key.length = dh_test_params.priv_key.length; - asym_op->dh.pub_key.data = (uint8_t *)peer; - asym_op->dh.pub_key.length = sizeof(peer); - asym_op->dh.shared_secret.data = output; - asym_op->dh.shared_secret.length = sizeof(output); - - if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - debug_hexdump(stdout, "shared secret:", - asym_op->dh.shared_secret.data, - asym_op->dh.shared_secret.length); - -error_exit: - if (sess != NULL) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - if (op != NULL) - rte_crypto_op_free(op); - return status; -} - -static int -test_dh_gen_priv_key(struct rte_crypto_asym_xform *xfrm) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - uint8_t output[TEST_DH_MOD_LEN]; - struct rte_crypto_asym_xform xform = *xfrm; - - sess = rte_cryptodev_asym_session_create(sess_mpool); - if (sess == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - /* set up crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - asym_op = op->asym; - - /* Setup a xform and op to generate private key only */ - xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE; - xform.next = NULL; - asym_op->dh.priv_key.data = output; - asym_op->dh.priv_key.length = sizeof(output); - - if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - debug_hexdump(stdout, "private key:", - asym_op->dh.priv_key.data, - asym_op->dh.priv_key.length); - - -error_exit: - if (sess != NULL) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - if (op != NULL) - rte_crypto_op_free(op); - - return status; -} - - -static int -test_dh_gen_pub_key(struct rte_crypto_asym_xform *xfrm) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - uint8_t output[TEST_DH_MOD_LEN]; - struct rte_crypto_asym_xform xform = *xfrm; - - sess = rte_cryptodev_asym_session_create(sess_mpool); - if (sess == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - /* set up crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - asym_op = op->asym; - /* Setup a xform chain to generate public key - * using test private key - * - */ - xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE; - xform.next = NULL; - - asym_op->dh.pub_key.data = output; - asym_op->dh.pub_key.length = sizeof(output); - /* load pre-defined private key */ - asym_op->dh.priv_key.data = rte_malloc(NULL, - dh_test_params.priv_key.length, - 0); - asym_op->dh.priv_key = dh_test_params.priv_key; - - if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - debug_hexdump(stdout, "pub key:", - asym_op->dh.pub_key.data, asym_op->dh.pub_key.length); - - debug_hexdump(stdout, "priv key:", - asym_op->dh.priv_key.data, asym_op->dh.priv_key.length); - -error_exit: - if (sess != NULL) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - if (op != NULL) - rte_crypto_op_free(op); - - return status; -} - -static int -test_dh_gen_kp(struct rte_crypto_asym_xform *xfrm) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - uint8_t out_pub_key[TEST_DH_MOD_LEN]; - uint8_t out_prv_key[TEST_DH_MOD_LEN]; - struct rte_crypto_asym_xform pub_key_xform; - struct rte_crypto_asym_xform xform = *xfrm; - - sess = rte_cryptodev_asym_session_create(sess_mpool); - if (sess == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - /* set up crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - asym_op = op->asym; - /* Setup a xform chain to generate - * private key first followed by - * public key - */xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE; - pub_key_xform.xform_type = RTE_CRYPTO_ASYM_XFORM_DH; - pub_key_xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE; - xform.next = &pub_key_xform; - - asym_op->dh.pub_key.data = out_pub_key; - asym_op->dh.pub_key.length = sizeof(out_pub_key); - asym_op->dh.priv_key.data = out_prv_key; - asym_op->dh.priv_key.length = sizeof(out_prv_key); - if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - debug_hexdump(stdout, "priv key:", - out_prv_key, asym_op->dh.priv_key.length); - debug_hexdump(stdout, "pub key:", - out_pub_key, asym_op->dh.pub_key.length); - -error_exit: - if (sess != NULL) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - if (op != NULL) - rte_crypto_op_free(op); - - return status; -} - -static int -test_mod_inv(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - struct rte_cryptodev_asym_capability_idx cap_idx; - const struct rte_cryptodev_asymmetric_xform_capability *capability; - uint8_t input[TEST_DATA_SIZE] = {0}; - int ret = 0; - - if (rte_cryptodev_asym_get_xform_enum( - &modinv_xform.xform_type, "modinv") < 0) { - RTE_LOG(ERR, USER1, - "Invalid ASYNC algorithm specified\n"); - return -1; - } - - cap_idx.type = modinv_xform.xform_type; - capability = rte_cryptodev_asym_capability_get(dev_id, - &cap_idx); - - if (rte_cryptodev_asym_xform_capability_check_modlen( - capability, - modinv_xform.modinv.modulus.length)) { - RTE_LOG(ERR, USER1, - "Invalid MODULOUS length specified\n"); - return -1; - } - - sess = rte_cryptodev_asym_session_create(sess_mpool); - if (!sess) { - RTE_LOG(ERR, USER1, "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (rte_cryptodev_asym_session_init(dev_id, sess, &modinv_xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - /* generate crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - asym_op = op->asym; - memcpy(input, base, sizeof(base)); - asym_op->modinv.base.data = input; - asym_op->modinv.base.length = sizeof(base); - - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - ret = verify_modinv(mod_inv, result_op); - if (ret) { - RTE_LOG(ERR, USER1, - "operation verification failed\n"); - status = TEST_FAILED; - } - -error_exit: - if (sess) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - - if (op) - rte_crypto_op_free(op); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return status; -} - -static int -test_mod_exp(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - struct rte_cryptodev_asym_capability_idx cap_idx; - const struct rte_cryptodev_asymmetric_xform_capability *capability; - uint8_t input[TEST_DATA_SIZE] = {0}; - int ret = 0; - - if (rte_cryptodev_asym_get_xform_enum(&modex_xform.xform_type, - "modexp") - < 0) { - RTE_LOG(ERR, USER1, - "Invalid ASYNC algorithm specified\n"); - return -1; - } - - /* check for modlen capability */ - cap_idx.type = modex_xform.xform_type; - capability = rte_cryptodev_asym_capability_get(dev_id, &cap_idx); - - if (rte_cryptodev_asym_xform_capability_check_modlen( - capability, modex_xform.modex.modulus.length)) { - RTE_LOG(ERR, USER1, - "Invalid MODULOUS length specified\n"); - return -1; - } - - /* generate crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - sess = rte_cryptodev_asym_session_create(sess_mpool); - if (!sess) { - RTE_LOG(ERR, USER1, - "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (rte_cryptodev_asym_session_init(dev_id, sess, &modex_xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - asym_op = op->asym; - memcpy(input, base, sizeof(base)); - asym_op->modex.base.data = input; - asym_op->modex.base.length = sizeof(base); - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - ret = verify_modexp(mod_exp, result_op); - if (ret) { - RTE_LOG(ERR, USER1, - "operation verification failed\n"); - status = TEST_FAILED; - } - -error_exit: - if (sess != NULL) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - - if (op != NULL) - rte_crypto_op_free(op); - - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return status; -} - -static int -test_dh_keygenration(void) -{ - int status; - - debug_hexdump(stdout, "p:", dh_xform.dh.p.data, dh_xform.dh.p.length); - debug_hexdump(stdout, "g:", dh_xform.dh.g.data, dh_xform.dh.g.length); - debug_hexdump(stdout, "priv_key:", dh_test_params.priv_key.data, - dh_test_params.priv_key.length); - - RTE_LOG(INFO, USER1, - "Test Public and Private key pair generation\n"); - - status = test_dh_gen_kp(&dh_xform); - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - RTE_LOG(INFO, USER1, - "Test Public Key Generation using pre-defined priv key\n"); - - status = test_dh_gen_pub_key(&dh_xform); - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - RTE_LOG(INFO, USER1, - "Test Private Key Generation only\n"); - - status = test_dh_gen_priv_key(&dh_xform); - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - RTE_LOG(INFO, USER1, - "Test shared secret compute\n"); - - status = test_dh_gen_shared_sec(&dh_xform); - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - - return status; -} - -static int -test_dsa_sign(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct rte_mempool *op_mpool = ts_params->op_mpool; - struct rte_mempool *sess_mpool = ts_params->session_mpool; - uint8_t dev_id = ts_params->valid_devs[0]; - struct rte_crypto_asym_op *asym_op = NULL; - struct rte_crypto_op *op = NULL, *result_op = NULL; - struct rte_cryptodev_asym_session *sess = NULL; - int status = TEST_SUCCESS; - uint8_t r[TEST_DH_MOD_LEN]; - uint8_t s[TEST_DH_MOD_LEN]; - uint8_t dgst[] = "35d81554afaad2cf18f3a1770d5fedc4ea5be344"; - - sess = rte_cryptodev_asym_session_create(sess_mpool); - if (sess == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - /* set up crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); - if (!op) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to allocate asymmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - asym_op = op->asym; - - debug_hexdump(stdout, "p: ", dsa_xform.dsa.p.data, - dsa_xform.dsa.p.length); - debug_hexdump(stdout, "q: ", dsa_xform.dsa.q.data, - dsa_xform.dsa.q.length); - debug_hexdump(stdout, "g: ", dsa_xform.dsa.g.data, - dsa_xform.dsa.g.length); - debug_hexdump(stdout, "priv_key: ", dsa_xform.dsa.x.data, - dsa_xform.dsa.x.length); - - if (rte_cryptodev_asym_session_init(dev_id, sess, &dsa_xform, - sess_mpool) < 0) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "unabled to config sym session"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach asymmetric crypto session to crypto operations */ - rte_crypto_op_attach_asym_session(op, sess); - asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; - asym_op->dsa.message.data = dgst; - asym_op->dsa.message.length = sizeof(dgst); - asym_op->dsa.r.length = sizeof(r); - asym_op->dsa.r.data = r; - asym_op->dsa.s.length = sizeof(s); - asym_op->dsa.s.data = s; - - RTE_LOG(DEBUG, USER1, "Process ASYM operation"); - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - asym_op = result_op->asym; - - debug_hexdump(stdout, "r:", - asym_op->dsa.r.data, asym_op->dsa.r.length); - debug_hexdump(stdout, "s:", - asym_op->dsa.s.data, asym_op->dsa.s.length); - - /* Test PMD DSA sign verification using signer public key */ - asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; - - /* copy signer public key */ - asym_op->dsa.y.data = dsa_test_params.y.data; - asym_op->dsa.y.length = dsa_test_params.y.length; - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Error sending packet for operation"); - status = TEST_FAILED; - goto error_exit; - } - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) - rte_pause(); - - if (result_op == NULL) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { - RTE_LOG(ERR, USER1, - "line %u FAILED: %s", - __LINE__, "Failed to process asym crypto op"); - status = TEST_FAILED; - } -error_exit: - if (sess != NULL) { - rte_cryptodev_asym_session_clear(dev_id, sess); - rte_cryptodev_asym_session_free(sess); - } - if (op != NULL) - rte_crypto_op_free(op); - return status; -} - -static int -test_dsa(void) -{ - int status; - status = test_dsa_sign(); - TEST_ASSERT_EQUAL(status, 0, "Test failed"); - return status; -} - - -static struct unit_test_suite cryptodev_openssl_asym_testsuite = { - .suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, test_capability), - TEST_CASE_ST(ut_setup, ut_teardown, test_dsa), - TEST_CASE_ST(ut_setup, ut_teardown, test_dh_keygenration), - TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_enc_dec), - TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_sign_verify), - TEST_CASE_ST(ut_setup, ut_teardown, test_mod_inv), - TEST_CASE_ST(ut_setup, ut_teardown, test_mod_exp), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_cryptodev_openssl_asym(void) -{ - gbl_driver_id = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); - - if (gbl_driver_id == -1) { - RTE_LOG(ERR, USER1, "OPENSSL PMD must be loaded. Check if " - "CONFIG_RTE_LIBRTE_PMD_OPENSSL is enabled " - "in config file to run this testsuite.\n"); - return TEST_FAILED; - } - - return unit_test_suite_runner(&cryptodev_openssl_asym_testsuite); -} - -REGISTER_TEST_COMMAND(cryptodev_openssl_asym_autotest, - test_cryptodev_openssl_asym); diff --git a/test/test/test_cryptodev_asym_util.h b/test/test/test_cryptodev_asym_util.h deleted file mode 100644 index dff0c2ada6..0000000000 --- a/test/test/test_cryptodev_asym_util.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Cavium Networks - */ - -#ifndef TEST_CRYPTODEV_ASYM_TEST_UTIL_H__ -#define TEST_CRYPTODEV_ASYM_TEST_UTIL_H__ - -/* Below Apis compare resulted buffer to original test vector */ - -static inline int rsa_verify(struct rsa_test_data *rsa_param, - struct rte_crypto_op *result_op) -{ - if (memcmp(rsa_param->data, - result_op->asym->rsa.message.data, - result_op->asym->rsa.message.length)) - return -1; - return 0; -} - -static inline int verify_modinv(uint8_t *mod_inv, - struct rte_crypto_op *result_op) -{ - if (memcmp(mod_inv, result_op->asym->modinv.base.data, - result_op->asym->modinv.base.length)) - return -1; - return 0; -} - -static inline int verify_modexp(uint8_t *mod_exp, - struct rte_crypto_op *result_op) -{ - if (memcmp(mod_exp, result_op->asym->modex.base.data, - result_op->asym->modex.base.length)) - return -1; - return 0; -} - -#endif /* TEST_CRYPTODEV_ASYM_TEST_UTIL_H__ */ - - - - diff --git a/test/test/test_cryptodev_blockcipher.c b/test/test/test_cryptodev_blockcipher.c deleted file mode 100644 index 1f06891146..0000000000 --- a/test/test/test_cryptodev_blockcipher.c +++ /dev/null @@ -1,752 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015-2017 Intel Corporation - */ - -#include -#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" - -static int -test_blockcipher_one_case(const struct blockcipher_test_case *t, - struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - struct rte_mempool *sess_mpool, - struct rte_mempool *sess_priv_mpool, - uint8_t dev_id, - int driver_id, - 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_info dev_info; - struct rte_cryptodev_sym_session *sess = NULL; - - 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 openssl_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); - int ccp_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_PMD)); - int scheduler_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)); - int armv8_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); - int aesni_mb_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - int qat_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)); - int dpaa2_sec_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)); - int dpaa_sec_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)); - int caam_jr_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)); - int mrvl_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)); - int virtio_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)); - int octeontx_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)); - - int nb_segs = 1; - - rte_cryptodev_info_get(dev_id, &dev_info); - - if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) { - uint64_t feat_flags = dev_info.feature_flags; - uint64_t oop_flag = RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT; - - if (t->feature_mask && BLOCKCIPHER_TEST_FEATURE_OOP) { - if (!(feat_flags & oop_flag)) { - printf("Device doesn't support out-of-place " - "scatter-gather in input mbuf. " - "Test Skipped.\n"); - return 0; - } - } else { - if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) { - printf("Device doesn't support in-place " - "scatter-gather mbufs. " - "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); - - if (driver_id == dpaa2_sec_pmd || - driver_id == dpaa_sec_pmd || - driver_id == caam_jr_pmd || - driver_id == qat_pmd || - driver_id == openssl_pmd || - driver_id == armv8_pmd || - driver_id == mrvl_pmd || - driver_id == ccp_pmd || - driver_id == virtio_pmd || - driver_id == octeontx_pmd) { /* Fall through */ - digest_len = tdata->digest.len; - } else if (driver_id == aesni_mb_pmd || - driver_id == scheduler_pmd) { - digest_len = tdata->digest.truncated_len; - } else { - 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_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); - - 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; - cipher_xform->cipher.iv.offset = IV_OFFSET; - cipher_xform->cipher.iv.length = tdata->iv.len; - - sym_op->cipher.data.offset = 0; - sym_op->cipher.data.length = tdata->ciphertext.len; - rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET), - tdata->iv.data, - tdata->iv.len); - } - - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { - uint32_t digest_offset = tdata->ciphertext.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_iova_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_iova_offset(sym_op->m_src, - digest_offset); - } - - sym_op->auth.data.offset = 0; - sym_op->auth.data.length = tdata->ciphertext.len; - } - - /* create session for sessioned op */ - if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { - sess = rte_cryptodev_sym_session_create(sess_mpool); - - rte_cryptodev_sym_session_init(dev_id, sess, init_xform, - sess_priv_mpool); - 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); - } - - debug_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) { - debug_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; - } - - debug_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) - debug_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) && - (op->status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED)) - 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: Operation 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, 0, 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 = 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, changed_len = 0; - uint32_t i; - uint32_t hdroom_used = 0, tlroom_used = 0; - uint32_t hdroom = 0; - - mbuf = sym_op->m_src; - /* - * Crypto PMDs specify the headroom & tailroom it would use - * when processing the crypto operation. PMD is free to modify - * this space, and so the verification check should skip that - * block. - */ - hdroom_used = dev_info.min_mbuf_headroom_req; - tlroom_used = dev_info.min_mbuf_tailroom_req; - - /* Get headroom */ - hdroom = rte_pktmbuf_headroom(mbuf); - - head_unchanged_len = mbuf->buf_len; - - for (i = 0; i < mbuf->buf_len; i++) { - - /* Skip headroom used by PMD */ - if (i == hdroom - hdroom_used) - i += hdroom_used; - - /* Skip tailroom used by PMD */ - if (i == (hdroom + mbuf->data_len)) - i += tlroom_used; - - 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 = hdroom + sym_op->auth.data.offset; - changed_len = sym_op->auth.data.length; - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) - changed_len += digest_len; - } else { - /* cipher-only */ - head_unchanged_len = hdroom + - 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; - uint32_t hdroom_used = 0, tlroom_used = 0; - uint32_t hdroom = 0; - - /* - * Crypto PMDs specify the headroom & tailroom it would use - * when processing the crypto operation. PMD is free to modify - * this space, and so the verification check should skip that - * block. - */ - hdroom_used = dev_info.min_mbuf_headroom_req; - tlroom_used = dev_info.min_mbuf_tailroom_req; - - mbuf = sym_op->m_src; - - /* Get headroom */ - hdroom = rte_pktmbuf_headroom(mbuf); - - if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { - head_unchanged_len = hdroom + - sym_op->cipher.data.offset; - changed_len = sym_op->cipher.data.length; - } else { - /* auth-only */ - head_unchanged_len = hdroom + - sym_op->auth.data.offset + - sym_op->auth.data.length; - changed_len = 0; - } - - if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) - changed_len += digest_len; - - for (i = 0; i < mbuf->buf_len; i++) { - - /* Skip headroom used by PMD */ - if (i == hdroom - hdroom_used) - i += hdroom_used; - - if (i == head_unchanged_len) - i += changed_len; - - /* Skip tailroom used by PMD */ - if (i == (hdroom + mbuf->data_len)) - i += tlroom_used; - - 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_clear(dev_id, sess); - rte_cryptodev_sym_session_free(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, - struct rte_mempool *sess_mpool, - struct rte_mempool *sess_priv_mpool, - uint8_t dev_id, - int driver_id, - 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; - - int openssl_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); - int ccp_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CCP_PMD)); - int dpaa2_sec_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)); - int dpaa_sec_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)); - int caam_jr_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)); - int scheduler_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)); - int armv8_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)); - int aesni_mb_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)); - int qat_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)); - int mrvl_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)); - int virtio_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)); - int octeontx_pmd = rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)); - - 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_AES_DOCSIS_TYPE: - n_test_cases = sizeof(aes_docsis_test_cases) / - sizeof(aes_docsis_test_cases[0]); - tcs = aes_docsis_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_DES_DOCSIS_TYPE: - n_test_cases = sizeof(des_docsis_test_cases) / - sizeof(des_docsis_test_cases[0]); - tcs = des_docsis_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; - } - - if (driver_id == aesni_mb_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; - else if (driver_id == qat_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; - else if (driver_id == openssl_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL; - else if (driver_id == armv8_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8; - else if (driver_id == scheduler_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER; - else if (driver_id == dpaa2_sec_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC; - else if (driver_id == ccp_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_CCP; - else if (driver_id == dpaa_sec_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC; - else if (driver_id == caam_jr_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR; - else if (driver_id == mrvl_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MVSAM; - else if (driver_id == virtio_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO; - else if (driver_id == octeontx_pmd) - target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX; - else - TEST_ASSERT(0, "Unrecognized cryptodev type"); - - 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, - sess_mpool, sess_priv_mpool, dev_id, driver_id, - 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 deleted file mode 100644 index 5c22d5da6b..0000000000 --- a/test/test/test_cryptodev_blockcipher.h +++ /dev/null @@ -1,112 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#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_TARGET_PMD_DPAA2_SEC 0x0020 /* DPAA2_SEC flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC 0x0040 /* DPAA_SEC flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_MVSAM 0x0080 /* Marvell flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_CCP 0x0040 /* CCP flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO 0x0200 /* VIRTIO flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX 0x0100 /* OCTEON TX flag */ -#define BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR 0x0400 /* CAAM_JR flag */ - -#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_AES_DOCSIS_TYPE, /* use aes_docsis_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[] */ - BLKCIPHER_DES_DOCSIS_TYPE /* use des_docsis_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, - struct rte_mempool *sess_mpool, - struct rte_mempool *sess_priv_mpool, - uint8_t dev_id, - int driver_id, - 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 deleted file mode 100644 index f1b8cbd453..0000000000 --- a/test/test/test_cryptodev_des_test_vectors.h +++ /dev/null @@ -1,1337 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016 Intel Corporation - */ - -#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 -triple_des64cbc_test_vector = { - .crypto_algo = RTE_CRYPTO_CIPHER_3DES_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_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 | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM - }, - { - .test_descr = "DES-CBC Decryption", - .test_data = &des_cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM - }, - -}; - -/* DES-DOCSIS-BPI test vectors */ - -static const uint8_t plaintext_des_docsis_bpi_cfb[] = { - 0x00, 0x01, 0x02, 0x88, 0xEE, 0x59, 0x7E -}; - -static const uint8_t ciphertext_des_docsis_bpi_cfb[] = { - 0x17, 0x86, 0xA8, 0x03, 0xA0, 0x85, 0x75 -}; - -static const uint8_t plaintext_des_docsis_bpi_cbc_cfb[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x91, - 0xD2, 0xD1, 0x9F -}; - -static const uint8_t ciphertext_des_docsis_bpi_cbc_cfb[] = { - 0x0D, 0xDA, 0x5A, 0xCB, 0xD0, 0x5E, 0x55, 0x67, - 0x51, 0x47, 0x46, 0x86, 0x8A, 0x71, 0xE5, 0x77, - 0xEF, 0xAC, 0x88 -}; - -/* Multiple of DES block size */ -static const struct blockcipher_test_data des_test_data_1 = { - .crypto_algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI, - .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 - }, -}; - -/* Less than DES block size */ -static const struct blockcipher_test_data des_test_data_2 = { - .crypto_algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI, - .cipher_key = { - .data = { - - 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB - }, - .len = 8 - }, - .iv = { - .data = { - 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des_docsis_bpi_cfb, - .len = 7 - }, - .ciphertext = { - .data = ciphertext_des_docsis_bpi_cfb, - .len = 7 - } -}; - -/* Not multiple of DES block size */ -static const struct blockcipher_test_data des_test_data_3 = { - .crypto_algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI, - .cipher_key = { - .data = { - 0xE6, 0x60, 0x0F, 0xD8, 0x85, 0x2E, 0xF5, 0xAB - }, - .len = 8 - }, - .iv = { - .data = { - 0x81, 0x0E, 0x52, 0x8E, 0x1C, 0x5F, 0xDA, 0x1A - }, - .len = 8 - }, - .plaintext = { - .data = plaintext_des_docsis_bpi_cbc_cfb, - .len = 19 - }, - .ciphertext = { - .data = ciphertext_des_docsis_bpi_cbc_cfb, - .len = 19 - } -}; -static const struct blockcipher_test_case des_docsis_test_cases[] = { - { - .test_descr = "DES-DOCSIS-BPI Full Block Encryption", - .test_data = &des_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 - }, - { - .test_descr = "DES-DOCSIS-BPI Runt Block Encryption", - .test_data = &des_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 - }, - { - .test_descr = "DES-DOCSIS-BPI Uneven Encryption", - .test_data = &des_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 - }, - { - .test_descr = "DES-DOCSIS-BPI Full Block Decryption", - .test_data = &des_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 - }, - { - .test_descr = "DES-DOCSIS-BPI Runt Block Decryption", - .test_data = &des_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 - }, - { - .test_descr = "DES-DOCSIS-BPI Uneven Decryption", - .test_data = &des_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 - }, - { - .test_descr = "DES-DOCSIS-BPI OOP Full Block Encryption", - .test_data = &des_test_data_1, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "DES-DOCSIS-BPI OOP Runt Block Encryption", - .test_data = &des_test_data_2, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "DES-DOCSIS-BPI OOP Uneven Encryption", - .test_data = &des_test_data_3, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "DES-DOCSIS-BPI OOP Full Block Decryption", - .test_data = &des_test_data_1, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "DES-DOCSIS-BPI OOP Runt Block Decryption", - .test_data = &des_test_data_2, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "DES-DOCSIS-BPI OOP Uneven Decryption", - .test_data = &des_test_data_3, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - 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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_CCP - }, -}; - -static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { - { - .test_descr = "3DES-64-CBC Encryption", - .test_data = &triple_des64cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "3DES-64-CBC Decryption", - .test_data = &triple_des64cbc_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MB - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MB - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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_dh_test_vectors.h b/test/test/test_cryptodev_dh_test_vectors.h deleted file mode 100644 index fe7510dcd3..0000000000 --- a/test/test/test_cryptodev_dh_test_vectors.h +++ /dev/null @@ -1,80 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Cavium Networks - */ - -#ifndef TEST_CRYPTODEV_DH_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_DH_TEST_VECTORS_H_ - -#include "rte_crypto_asym.h" - -#define TEST_DATA_SIZE 4096 -#define TEST_DH_MOD_LEN 1024 - - -struct dh_test_param { - rte_crypto_param priv_key; -}; - -uint8_t dh_priv[] = { - 0x46, 0x3c, 0x7b, 0x43, 0xd1, 0xb8, 0xd4, 0x7a, - 0x56, 0x28, 0x85, 0x79, 0xcc, 0xd8, 0x90, 0x03, - 0x0c, 0x4b, 0xc6, 0xd3, 0x7f, 0xb3, 0x19, 0x84, - 0x8a, 0xc6, 0x0d, 0x24, 0x5e, 0xaa, 0x7e, 0x7a, - 0x73, 0x88, 0xa6, 0x47, 0x7c, 0x42, 0x78, 0x63, - 0x11, 0x12, 0xd3, 0xa0, 0xc5, 0xfe, 0xfd, 0xf2, - 0x9e, 0x17, 0x90, 0xe5, 0x6d, 0xcc, 0x20, 0x6f, - 0xe8, 0x82, 0x28, 0xbf, 0x5c, 0xe6, 0xd4, 0x86, - 0x5c, 0x35, 0x32, 0x97, 0xc2, 0x86, 0x1b, 0xc5, - 0x59, 0x1c, 0x0b, 0x1b, 0xec, 0x60, 0x3c, 0x1d, - 0x8d, 0x7f, 0xf0, 0xc7, 0x48, 0x3a, 0x51, 0x09, - 0xf2, 0x3e, 0x9e, 0x35, 0x74, 0x98, 0x4d, 0xad, - 0x39, 0xa7, 0xf2, 0xd2, 0xb4, 0x32, 0xd3, 0xc8, - 0xe9, 0x45, 0xbe, 0x56, 0xe7, 0x87, 0xe0, 0xa0, - 0x97, 0x6b, 0x5f, 0x99, 0x5e, 0x41, 0x59, 0x33, - 0x95, 0x64, 0x0d, 0xe9, 0x58, 0x5b, 0xa6, 0x38 -}; - -uint8_t dh_p[] = { - 0xef, 0xee, 0x8c, 0x8b, 0x3f, 0x85, 0x95, 0xcd, - 0x4d, 0x68, 0x5d, 0x4a, 0x5d, 0x1f, 0x2a, 0x2e, - 0xdd, 0xcf, 0xef, 0x1b, 0x3b, 0xe9, 0x7b, 0x0c, - 0x13, 0xee, 0x76, 0xd5, 0x93, 0xca, 0x8b, 0xc8, - 0x0b, 0x97, 0x00, 0xec, 0x1f, 0x34, 0xa2, 0xce, - 0x83, 0x8d, 0x80, 0xea, 0xfe, 0x11, 0xed, 0x28, - 0xdd, 0x32, 0x22, 0x77, 0x96, 0x4e, 0xc5, 0xed, - 0xc8, 0x7a, 0x52, 0x10, 0x22, 0xcc, 0xb2, 0x4d, - 0xd3, 0xda, 0x03, 0xf5, 0x1e, 0xa8, 0x79, 0x23, - 0x8b, 0xe1, 0x78, 0x47, 0x07, 0x5b, 0x26, 0xbb, - 0x53, 0x46, 0x0b, 0x18, 0x5c, 0x07, 0x4e, 0xb6, - 0x76, 0xc9, 0xa8, 0xd5, 0x30, 0xa3, 0xbe, 0x8d, - 0xae, 0xcd, 0x34, 0x68, 0x62, 0x5f, 0xb9, 0x5c, - 0x34, 0x90, 0xf0, 0xda, 0x47, 0x86, 0x36, 0x04, - 0x28, 0xbc, 0x7d, 0xae, 0x9d, 0x4e, 0x61, 0x28, - 0x70, 0xdb, 0xa6, 0x55, 0x04, 0x46, 0x27, 0xe3 -}; - -uint8_t dh_g[] = {0x02}; - -struct dh_test_param dh_test_params = { - .priv_key = { - .data = dh_priv, - .length = sizeof(dh_priv) - } -}; - -struct rte_crypto_asym_xform dh_xform = { - .next = NULL, - .xform_type = RTE_CRYPTO_ASYM_XFORM_DH, - .dh = { - .p = { - .data = dh_p, - .length = sizeof(dh_p) - }, - .g = { - .data = dh_g, - .length = sizeof(dh_g) - }, - } -}; - -#endif /* TEST_CRYPTODEV_DH_TEST_VECTORS_H__ */ diff --git a/test/test/test_cryptodev_dsa_test_vectors.h b/test/test/test_cryptodev_dsa_test_vectors.h deleted file mode 100644 index bbcb0d7297..0000000000 --- a/test/test/test_cryptodev_dsa_test_vectors.h +++ /dev/null @@ -1,117 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Cavium Networks - */ - -#ifndef TEST_CRYPTODEV_DSA_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_DSA_TEST_VECTORS_H_ - -#include "rte_crypto_asym.h" - -#define TEST_DATA_SIZE 4096 - - -struct dsa_test_param { - rte_crypto_param y; -}; - -static unsigned char dsa_x[] = { - 0xc5, 0x3e, 0xae, 0x6d, 0x45, 0x32, 0x31, 0x64, - 0xc7, 0xd0, 0x7a, 0xf5, 0x71, 0x57, 0x03, 0x74, - 0x4a, 0x63, 0xfc, 0x3a -}; - -uint8_t dsa_y[] = { - 0x31, 0x3f, 0xd9, 0xeb, 0xca, 0x91, 0x57, 0x4e, - 0x1c, 0x2e, 0xeb, 0xe1, 0x51, 0x7c, 0x57, 0xe0, - 0xc2, 0x1b, 0x02, 0x09, 0x87, 0x21, 0x40, 0xc5, - 0x32, 0x87, 0x61, 0xbb, 0xb2, 0x45, 0x0b, 0x33, - 0xf1, 0xb1, 0x8b, 0x40, 0x9c, 0xe9, 0xab, 0x7c, - 0x4c, 0xd8, 0xfd, 0xa3, 0x39, 0x1e, 0x8e, 0x34, - 0x86, 0x83, 0x57, 0xc1, 0x99, 0xe1, 0x6a, 0x6b, - 0x2e, 0xba, 0x06, 0xd6, 0x74, 0x9d, 0xef, 0x79, - 0x1d, 0x79, 0xe9, 0x5d, 0x3a, 0x4d, 0x09, 0xb2, - 0x4c, 0x39, 0x2a, 0xd8, 0x9d, 0xbf, 0x10, 0x09, - 0x95, 0xae, 0x19, 0xc0, 0x10, 0x62, 0x05, 0x6b, - 0xb1, 0x4b, 0xce, 0x00, 0x5e, 0x87, 0x31, 0xef, - 0xde, 0x17, 0x5f, 0x95, 0xb9, 0x75, 0x08, 0x9b, - 0xdc, 0xda, 0xea, 0x56, 0x2b, 0x32, 0x78, 0x6d, - 0x96, 0xf5, 0xa3, 0x1a, 0xed, 0xf7, 0x53, 0x64, - 0x00, 0x8a, 0xd4, 0xff, 0xfe, 0xbb, 0x97, 0x0b -}; - -static unsigned char dsa_p[] = { - 0xa8, 0xf9, 0xcd, 0x20, 0x1e, 0x5e, 0x35, 0xd8, - 0x92, 0xf8, 0x5f, 0x80, 0xe4, 0xdb, 0x25, 0x99, - 0xa5, 0x67, 0x6a, 0x3b, 0x1d, 0x4f, 0x19, 0x03, - 0x30, 0xed, 0x32, 0x56, 0xb2, 0x6d, 0x0e, 0x80, - 0xa0, 0xe4, 0x9a, 0x8f, 0xff, 0xaa, 0xad, 0x2a, - 0x24, 0xf4, 0x72, 0xd2, 0x57, 0x32, 0x41, 0xd4, - 0xd6, 0xd6, 0xc7, 0x48, 0x0c, 0x80, 0xb4, 0xc6, - 0x7b, 0xb4, 0x47, 0x9c, 0x15, 0xad, 0xa7, 0xea, - 0x84, 0x24, 0xd2, 0x50, 0x2f, 0xa0, 0x14, 0x72, - 0xe7, 0x60, 0x24, 0x17, 0x13, 0xda, 0xb0, 0x25, - 0xae, 0x1b, 0x02, 0xe1, 0x70, 0x3a, 0x14, 0x35, - 0xf6, 0x2d, 0xdf, 0x4e, 0xe4, 0xc1, 0xb6, 0x64, - 0x06, 0x6e, 0xb2, 0x2f, 0x2e, 0x3b, 0xf2, 0x8b, - 0xb7, 0x0a, 0x2a, 0x76, 0xe4, 0xfd, 0x5e, 0xbe, - 0x2d, 0x12, 0x29, 0x68, 0x1b, 0x5b, 0x06, 0x43, - 0x9a, 0xc9, 0xc7, 0xe9, 0xd8, 0xbd, 0xe2, 0x83 -}; - -static unsigned char dsa_q[] = { - 0xf8, 0x5f, 0x0f, 0x83, 0xac, 0x4d, 0xf7, 0xea, - 0x0c, 0xdf, 0x8f, 0x46, 0x9b, 0xfe, 0xea, 0xea, - 0x14, 0x15, 0x64, 0x95 -}; - -static unsigned char dsa_g[] = { - 0x2b, 0x31, 0x52, 0xff, 0x6c, 0x62, 0xf1, 0x46, - 0x22, 0xb8, 0xf4, 0x8e, 0x59, 0xf8, 0xaf, 0x46, - 0x88, 0x3b, 0x38, 0xe7, 0x9b, 0x8c, 0x74, 0xde, - 0xea, 0xe9, 0xdf, 0x13, 0x1f, 0x8b, 0x85, 0x6e, - 0x3a, 0xd6, 0xc8, 0x45, 0x5d, 0xab, 0x87, 0xcc, - 0x0d, 0xa8, 0xac, 0x97, 0x34, 0x17, 0xce, 0x4f, - 0x78, 0x78, 0x55, 0x7d, 0x6c, 0xdf, 0x40, 0xb3, - 0x5b, 0x4a, 0x0c, 0xa3, 0xeb, 0x31, 0x0c, 0x6a, - 0x95, 0xd6, 0x8c, 0xe2, 0x84, 0xad, 0x4e, 0x25, - 0xea, 0x28, 0x59, 0x16, 0x11, 0xee, 0x08, 0xb8, - 0x44, 0x4b, 0xd6, 0x4b, 0x25, 0xf3, 0xf7, 0xc5, - 0x72, 0x41, 0x0d, 0xdf, 0xb3, 0x9c, 0xc7, 0x28, - 0xb9, 0xc9, 0x36, 0xf8, 0x5f, 0x41, 0x91, 0x29, - 0x86, 0x99, 0x29, 0xcd, 0xb9, 0x09, 0xa6, 0xa3, - 0xa9, 0x9b, 0xbe, 0x08, 0x92, 0x16, 0x36, 0x81, - 0x71, 0xbd, 0x0b, 0xa8, 0x1d, 0xe4, 0xfe, 0x33 -}; - -struct dsa_test_param dsa_test_params = { - .y = { - .data = dsa_y, - .length = sizeof(dsa_y) - } -}; - -struct rte_crypto_asym_xform dsa_xform = { - .next = NULL, - .xform_type = RTE_CRYPTO_ASYM_XFORM_DSA, - .dsa = { - .p = { - .data = dsa_p, - .length = sizeof(dsa_p) - }, - .q = { - .data = dsa_q, - .length = sizeof(dsa_q) - }, - .g = { - .data = dsa_g, - .length = sizeof(dsa_g) - }, - .x = { - .data = dsa_x, - .length = sizeof(dsa_x) - } - - } -}; - -#endif /* TEST_CRYPTODEV_DSA_TEST_VECTORS_H__ */ diff --git a/test/test/test_cryptodev_hash_test_vectors.h b/test/test/test_cryptodev_hash_test_vectors.h deleted file mode 100644 index d3a26609c9..0000000000 --- a/test/test/test_cryptodev_hash_test_vectors.h +++ /dev/null @@ -1,747 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#ifndef TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ - -#ifdef RTE_LIBRTE_PMD_AESNI_MB -#include -#endif - -#if !defined(IMB_VERSION_NUM) -#define IMB_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) -#define IMB_VERSION_NUM IMB_VERSION(0, 49, 0) -#endif - -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, - .truncated_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, - .truncated_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, - .truncated_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, - .truncated_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, - .truncated_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_data -cmac_test_vector = { - .auth_algo = RTE_CRYPTO_AUTH_AES_CMAC, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .auth_key = { - .data = { - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C - }, - .len = 16 - }, - .digest = { - .data = { - 0x4C, 0x77, 0x87, 0xA0, 0x78, 0x8E, 0xEA, 0x96, - 0xC1, 0xEB, 0x1E, 0x4E, 0x95, 0x8F, 0xED, 0x27 - }, - .len = 16, - .truncated_len = 16 - } -}; - -static const struct blockcipher_test_data -cmac_test_vector_12 = { - .auth_algo = RTE_CRYPTO_AUTH_AES_CMAC, - .ciphertext = { - .data = plaintext_hash, - .len = 512 - }, - .auth_key = { - .data = { - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C - }, - .len = 16 - }, - .digest = { - .data = { - 0x4C, 0x77, 0x87, 0xA0, 0x78, 0x8E, 0xEA, 0x96, - 0xC1, 0xEB, 0x1E, 0x4E, 0x95, 0x8F, 0xED, 0x27 - }, - .len = 12, - .truncated_len = 12 - } -}; - -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 | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "MD5 Digest Verify", - .test_data = &md5_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA1 Digest", - .test_data = &sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA1 Digest Verify", - .test_data = &sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "HMAC-SHA1 Digest Scatter Gather", - .test_data = &hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "HMAC-SHA1 Digest Verify Scatter Gather", - .test_data = &hmac_sha1_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA224 Digest", - .test_data = &sha224_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA224 Digest Verify", - .test_data = &sha224_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA256 Digest", - .test_data = &sha256_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA256 Digest Verify", - .test_data = &sha256_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA384 Digest", - .test_data = &sha384_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA384 Digest Verify", - .test_data = &sha384_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA512 Digest", - .test_data = &sha512_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "SHA512 Digest Verify", - .test_data = &sha512_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | -#if IMB_VERSION_NUM >= IMB_VERSION(0, 52, 0) - BLOCKCIPHER_TEST_TARGET_PMD_MB | -#endif - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .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 | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC | - BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR | - BLOCKCIPHER_TEST_TARGET_PMD_QAT | - BLOCKCIPHER_TEST_TARGET_PMD_CCP | - BLOCKCIPHER_TEST_TARGET_PMD_MVSAM | - BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX - }, - { - .test_descr = "CMAC Digest 12B", - .test_data = &cmac_test_vector_12, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "CMAC Digest Verify 12B", - .test_data = &cmac_test_vector_12, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "CMAC Digest 16B", - .test_data = &cmac_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "CMAC Digest Verify 16B", - .test_data = &cmac_test_vector, - .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | - BLOCKCIPHER_TEST_TARGET_PMD_QAT - } -}; - -#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 deleted file mode 100644 index 77153a5c10..0000000000 --- a/test/test/test_cryptodev_hmac_test_vectors.h +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016 Intel Corporation - */ - -#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 deleted file mode 100644 index 5033d1830b..0000000000 --- a/test/test/test_cryptodev_kasumi_hash_test_vectors.h +++ /dev/null @@ -1,220 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#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), FRESH (4 bytes), message - * and DIRECTION (1 bit), plus 1 0*, with enough 0s, - * so total length is multiple of 8 or 64 bits - */ - struct { - uint8_t data[2056]; - unsigned len; /* length must be in Bits */ - } plaintext; - - 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 - }, - .plaintext = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, - 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 = 256 - }, - .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 - }, - .plaintext = { - .data = { - 0x3E, 0xDC, 0x87, 0xE2, 0xA4, 0xF2, 0xD8, 0xE2, - 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 = 320 - }, - .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 - }, - .plaintext = { - .data = { - 0x36, 0xAF, 0x61, 0x44, 0x98, 0x38, 0xF0, 0x3A, - 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 = 448 - }, - .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 - }, - .plaintext = { - .data = { - 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, - 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 = 512 - }, - .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 - }, - .plaintext = { - .data = { - 0x29, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0x77, 0x37, - 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 = 1088 - }, - .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 - }, - .plaintext = { - .data = { - 0x36, 0xAF, 0x61, 0x44, 0x4F, 0x30, 0x2A, 0xD2, - 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 = 840 - }, - .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 - }, - .plaintext = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, - 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, - 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 - }, - .len = 192 - }, - .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 deleted file mode 100644 index 58a696a339..0000000000 --- a/test/test/test_cryptodev_kasumi_test_vectors.h +++ /dev/null @@ -1,359 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#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; - } cipher_iv; - - /* - * Data may include COUNT (4 bytes), FRESH (4 bytes), - * DIRECTION (1 bit), plus 1 0*, with enough 0s, - * so total length is multiple of 8 or 64 bits - */ - struct { - uint8_t data[1024]; - 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 int len; - } validCipherOffsetInBits; - - /* Actual length of data to be hashed */ - struct { - unsigned len; - } validAuthLenInBits; - - 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 - }, - .cipher_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 - }, - .validCipherOffsetInBits = { - .len = 0 - } -}; - -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 - }, - .cipher_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 - }, - .validCipherOffsetInBits = { - .len = 0 - } -}; - -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 - }, - .cipher_iv = { - .data = { - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 - }, - .len = 8 - }, - .plaintext = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, - 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, - 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 - }, - .len = 192 - }, - .ciphertext = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, - 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, - 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25, 0xC0 - }, - .len = 192 - }, - .validDataLenInBits = { - .len = 192 - }, - .validCipherLenInBits = { - .len = 120 - }, - .validAuthLenInBits = { - .len = 192 - }, - .validCipherOffsetInBits = { - .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 - }, - .cipher_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 - }, - .validCipherOffsetInBits = { - .len = 0 - } -}; - -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 - }, - .cipher_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 - }, - .validCipherOffsetInBits = { - .len = 0 - } -}; - -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 - }, - .cipher_iv = { - .data = { - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 - }, - .len = 8 - }, - .plaintext = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, - 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, - 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8, 0xC0 - }, - .len = 192 - }, - .ciphertext = { - .data = { - 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, - 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, - 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25, 0xC0 - }, - .len = 192 - }, - .validDataLenInBits = { - .len = 192 - }, - .validCipherLenInBits = { - .len = 120 - }, - .validCipherOffsetInBits = { - .len = 64 - }, - .validAuthLenInBits = { - .len = 192 - }, - .digest = { - .data = {0x0F, 0xD2, 0xAA, 0xB5}, - .len = 4 - } -}; -#endif /* TEST_CRYPTODEV_KASUMI_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_mod_test_vectors.h b/test/test/test_cryptodev_mod_test_vectors.h deleted file mode 100644 index a25c676ac1..0000000000 --- a/test/test/test_cryptodev_mod_test_vectors.h +++ /dev/null @@ -1,103 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Cavium Networks - */ - -#ifndef TEST_CRYPTODEV_MOD_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_MOD_TEST_VECTORS_H_ - -/* modular operation test data */ -uint8_t base[] = { - 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, - 0xAE, 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, - 0xA8, 0xEB, 0x7E, 0x78, 0xA0, 0x50 -}; - -uint8_t mod_p[] = { - 0x00, 0xb3, 0xa1, 0xaf, 0xb7, 0x13, 0x08, 0x00, - 0x0a, 0x35, 0xdc, 0x2b, 0x20, 0x8d, 0xa1, 0xb5, - 0xce, 0x47, 0x8a, 0xc3, 0x80, 0xf4, 0x7d, 0x4a, - 0xa2, 0x62, 0xfd, 0x61, 0x7f, 0xb5, 0xa8, 0xde, - 0x0a, 0x17, 0x97, 0xa0, 0xbf, 0xdf, 0x56, 0x5a, - 0x3d, 0x51, 0x56, 0x4f, 0x70, 0x70, 0x3f, 0x63, - 0x6a, 0x44, 0x5b, 0xad, 0x84, 0x0d, 0x3f, 0x27, - 0x6e, 0x3b, 0x34, 0x91, 0x60, 0x14, 0xb9, 0xaa, - 0x72, 0xfd, 0xa3, 0x64, 0xd2, 0x03, 0xa7, 0x53, - 0x87, 0x9e, 0x88, 0x0b, 0xc1, 0x14, 0x93, 0x1a, - 0x62, 0xff, 0xb1, 0x5d, 0x74, 0xcd, 0x59, 0x63, - 0x18, 0x11, 0x3d, 0x4f, 0xba, 0x75, 0xd4, 0x33, - 0x4e, 0x23, 0x6b, 0x7b, 0x57, 0x44, 0xe1, 0xd3, - 0x03, 0x13, 0xa6, 0xf0, 0x8b, 0x60, 0xb0, 0x9e, - 0xee, 0x75, 0x08, 0x9d, 0x71, 0x63, 0x13, 0xcb, - 0xa6, 0x81, 0x92, 0x14, 0x03, 0x22, 0x2d, 0xde, - 0x55 -}; - -uint8_t mod_e[] = {0x01, 0x00, 0x01}; - -/* Precomputed modular exponentiation for verification */ -uint8_t mod_exp[] = { - 0x2C, 0x60, 0x75, 0x45, 0x98, 0x9D, 0xE0, 0x72, - 0xA0, 0x9D, 0x3A, 0x9E, 0x03, 0x38, 0x73, 0x3C, - 0x31, 0x83, 0x04, 0xFE, 0x75, 0x43, 0xE6, 0x17, - 0x5C, 0x01, 0x29, 0x51, 0x69, 0x33, 0x62, 0x2D, - 0x78, 0xBE, 0xAE, 0xC4, 0xBC, 0xDE, 0x7E, 0x2C, - 0x77, 0x84, 0xF2, 0xC5, 0x14, 0xB5, 0x2F, 0xF7, - 0xC5, 0x94, 0xEF, 0x86, 0x75, 0x75, 0xB5, 0x11, - 0xE5, 0x0E, 0x0A, 0x29, 0x76, 0xE2, 0xEA, 0x32, - 0x0E, 0x43, 0x77, 0x7E, 0x2C, 0x27, 0xAC, 0x3B, - 0x86, 0xA5, 0xDB, 0xC9, 0x48, 0x40, 0xE8, 0x99, - 0x9A, 0x0A, 0x3D, 0xD6, 0x74, 0xFA, 0x2E, 0x2E, - 0x5B, 0xAF, 0x8C, 0x99, 0x44, 0x2A, 0x67, 0x38, - 0x27, 0x41, 0x59, 0x9D, 0xB8, 0x51, 0xC9, 0xF7, - 0x43, 0x61, 0x31, 0x6E, 0xF1, 0x25, 0x38, 0x7F, - 0xAE, 0xC6, 0xD0, 0xBB, 0x29, 0x76, 0x3F, 0x46, - 0x2E, 0x1B, 0xE4, 0x67, 0x71, 0xE3, 0x87, 0x5A -}; - -/* Precomputed modular inverse for verification */ -uint8_t mod_inv[] = { - 0x52, 0xb1, 0xa3, 0x8c, 0xc5, 0x8a, 0xb9, 0x1f, - 0xb6, 0x82, 0xf5, 0x6a, 0x9a, 0xde, 0x8d, 0x2e, - 0x62, 0x4b, 0xac, 0x49, 0x21, 0x1d, 0x30, 0x4d, - 0x32, 0xac, 0x1f, 0x40, 0x6d, 0x52, 0xc7, 0x9b, - 0x6c, 0x0a, 0x82, 0x3a, 0x2c, 0xaf, 0x6b, 0x6d, - 0x17, 0xbe, 0x43, 0xed, 0x97, 0x78, 0xeb, 0x4c, - 0x92, 0x6f, 0xcf, 0xed, 0xb1, 0x09, 0xcb, 0x27, - 0xc2, 0xde, 0x62, 0xfd, 0x21, 0xe6, 0xbd, 0x4f, - 0xfe, 0x7a, 0x1b, 0x50, 0xfe, 0x10, 0x4a, 0xb0, - 0xb7, 0xcf, 0xdb, 0x7d, 0xca, 0xc2, 0xf0, 0x1c, - 0x39, 0x48, 0x6a, 0xb5, 0x4d, 0x8c, 0xfe, 0x63, - 0x91, 0x9c, 0x21, 0xc3, 0x0e, 0x76, 0xad, 0x44, - 0x8d, 0x54, 0x33, 0x99, 0xe1, 0x80, 0x19, 0xba, - 0xb5, 0xac, 0x7d, 0x9c, 0xce, 0x91, 0x2a, 0xd9, - 0x2c, 0xe1, 0x16, 0xd6, 0xd7, 0xcf, 0x9d, 0x05, - 0x9a, 0x66, 0x9a, 0x3a, 0xc1, 0xb8, 0x4b, 0xc3 -}; - -struct rte_crypto_asym_xform modex_xform = { - .next = NULL, - .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX, - .modex = { - .modulus = { - .data = mod_p, - .length = sizeof(mod_p) - }, - .exponent = { - .data = mod_e, - .length = sizeof(mod_e) - } - } -}; - -struct rte_crypto_asym_xform modinv_xform = { - .next = NULL, - .xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV, - .modinv = { - .modulus = { - .data = mod_p, - .length = sizeof(mod_p) - } - } -}; - -#endif /* TEST_CRYPTODEV_MOD_TEST_VECTORS_H__ */ diff --git a/test/test/test_cryptodev_rsa_test_vectors.h b/test/test/test_cryptodev_rsa_test_vectors.h deleted file mode 100644 index 3f8c41a673..0000000000 --- a/test/test/test_cryptodev_rsa_test_vectors.h +++ /dev/null @@ -1,88 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Cavium Networks - */ - -#ifndef TEST_CRYPTODEV_RSA_TEST_VECTORS_H__ -#define TEST_CRYPTODEV_RSA_TEST_VECTORS_H__ - -#include "rte_crypto_asym.h" - -#define TEST_DATA_SIZE 4096 - -struct rsa_test_data { - uint8_t data[TEST_DATA_SIZE]; - unsigned int len; -}; - -struct rsa_test_data rsaplaintext = { - .data = { - 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae, - 0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb, - 0x7e, 0x78, 0xa0, 0x50 - }, - .len = 20 -}; - -uint8_t rsa_n[] = { - 0xb3, 0xa1, 0xaf, 0xb7, 0x13, 0x08, 0x00, - 0x0a, 0x35, 0xdc, 0x2b, 0x20, 0x8d, 0xa1, 0xb5, - 0xce, 0x47, 0x8a, 0xc3, 0x80, 0xf4, 0x7d, 0x4a, - 0xa2, 0x62, 0xfd, 0x61, 0x7f, 0xb5, 0xa8, 0xde, - 0x0a, 0x17, 0x97, 0xa0, 0xbf, 0xdf, 0x56, 0x5a, - 0x3d, 0x51, 0x56, 0x4f, 0x70, 0x70, 0x3f, 0x63, - 0x6a, 0x44, 0x5b, 0xad, 0x84, 0x0d, 0x3f, 0x27, - 0x6e, 0x3b, 0x34, 0x91, 0x60, 0x14, 0xb9, 0xaa, - 0x72, 0xfd, 0xa3, 0x64, 0xd2, 0x03, 0xa7, 0x53, - 0x87, 0x9e, 0x88, 0x0b, 0xc1, 0x14, 0x93, 0x1a, - 0x62, 0xff, 0xb1, 0x5d, 0x74, 0xcd, 0x59, 0x63, - 0x18, 0x11, 0x3d, 0x4f, 0xba, 0x75, 0xd4, 0x33, - 0x4e, 0x23, 0x6b, 0x7b, 0x57, 0x44, 0xe1, 0xd3, - 0x03, 0x13, 0xa6, 0xf0, 0x8b, 0x60, 0xb0, 0x9e, - 0xee, 0x75, 0x08, 0x9d, 0x71, 0x63, 0x13, 0xcb, - 0xa6, 0x81, 0x92, 0x14, 0x03, 0x22, 0x2d, 0xde, - 0x55 -}; - -uint8_t rsa_d[] = { - 0x24, 0xd7, 0xea, 0xf4, 0x7f, 0xe0, 0xca, 0x31, - 0x4d, 0xee, 0xc4, 0xa1, 0xbe, 0xab, 0x06, 0x61, - 0x32, 0xe7, 0x51, 0x46, 0x27, 0xdf, 0x72, 0xe9, - 0x6f, 0xa8, 0x4c, 0xd1, 0x26, 0xef, 0x65, 0xeb, - 0x67, 0xff, 0x5f, 0xa7, 0x3b, 0x25, 0xb9, 0x08, - 0x8e, 0xa0, 0x47, 0x56, 0xe6, 0x8e, 0xf9, 0xd3, - 0x18, 0x06, 0x3d, 0xc6, 0xb1, 0xf8, 0xdc, 0x1b, - 0x8d, 0xe5, 0x30, 0x54, 0x26, 0xac, 0x16, 0x3b, - 0x7b, 0xad, 0x46, 0x9e, 0x21, 0x6a, 0x57, 0xe6, - 0x81, 0x56, 0x1d, 0x2a, 0xc4, 0x39, 0x63, 0x67, - 0x81, 0x2c, 0xca, 0xcc, 0xf8, 0x42, 0x04, 0xbe, - 0xcf, 0x8f, 0x6c, 0x5b, 0x81, 0x46, 0xb9, 0xc7, - 0x62, 0x90, 0x87, 0x35, 0x03, 0x9b, 0x89, 0xcb, - 0x37, 0xbd, 0xf1, 0x1b, 0x99, 0xa1, 0x9a, 0x78, - 0xd5, 0x4c, 0xdd, 0x3f, 0x41, 0x0c, 0xb7, 0x1a, - 0xd9, 0x7b, 0x87, 0x5f, 0xbe, 0xb1, 0x83, 0x41 -}; - -uint8_t rsa_e[] = {0x01, 0x00, 0x01}; - -/** rsa xform using exponent key */ -struct rte_crypto_asym_xform rsa_xform = { - .next = NULL, - .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA, - .rsa = { - .n = { - .data = rsa_n, - .length = sizeof(rsa_n) - }, - .e = { - .data = rsa_e, - .length = sizeof(rsa_e) - }, - .key_type = RTE_RSA_KEY_TYPE_EXP, - .d = { - .data = rsa_d, - .length = sizeof(rsa_d) - } - } -}; - -#endif /* TEST_CRYPTODEV_RSA_TEST_VECTORS_H__ */ diff --git a/test/test/test_cryptodev_snow3g_hash_test_vectors.h b/test/test/test_cryptodev_snow3g_hash_test_vectors.h deleted file mode 100644 index e9fb2147be..0000000000 --- a/test/test/test_cryptodev_snow3g_hash_test_vectors.h +++ /dev/null @@ -1,498 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#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; - } auth_iv; - - struct { - uint8_t data[2056]; - unsigned len; /* length must be in Bits */ - } plaintext; - - struct { - unsigned len; - } validAuthLenInBits; - - 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 - }, - .auth_iv = { - .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 - }, - .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 - }, - .auth_iv = { - .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 - }, - .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 - }, - .auth_iv = { - .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 - }, - .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 - }, - .auth_iv = { - .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 - }, - .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 - }, - .auth_iv = { - .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 - }, - .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 - }, - .auth_iv = { - .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 - }, - .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 deleted file mode 100644 index cb9dc4b350..0000000000 --- a/test/test/test_cryptodev_snow3g_test_vectors.h +++ /dev/null @@ -1,383 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015-2017 Intel Corporation - */ - -#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; - } cipher_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; - } validAuthLenInBits; - - struct { - uint8_t data[64]; - unsigned len; - } auth_iv; - - 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 - }, - .cipher_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 - }, - .auth_iv = { - .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 - }, - .cipher_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 - }, - .auth_iv = { - .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 - }, - .cipher_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 - }, - .auth_iv = { - .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 - } -}; - -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 - }, - .cipher_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 - } -}; - -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 - }, - .cipher_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 - }, -}; -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 - }, - .cipher_iv = { - .data = { - 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, - 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD - }, - .len = 16 - }, - .auth_iv = { - .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 - }, - .validAuthLenInBits = { - .len = 384 - }, -}; - -#endif /* TEST_CRYPTODEV_SNOW3G_TEST_VECTORS_H_ */ diff --git a/test/test/test_cryptodev_zuc_test_vectors.h b/test/test/test_cryptodev_zuc_test_vectors.h deleted file mode 100644 index 9ff821a18d..0000000000 --- a/test/test/test_cryptodev_zuc_test_vectors.h +++ /dev/null @@ -1,1043 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#ifndef TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ -#define TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ - -struct wireless_test_data { - struct { - uint8_t data[64]; - unsigned len; - } key; - - struct { - uint8_t data[64] __rte_aligned(16); - unsigned len; - } cipher_iv; - - struct { - uint8_t data[2048]; - unsigned len; /* length must be in Bits */ - } plaintext; - - struct { - uint8_t data[2048]; - unsigned len; /* length must be in Bits */ - } ciphertext; - - struct { - unsigned len; - } validDataLenInBits; - - struct { - unsigned len; - } validCipherLenInBits; - - struct { - unsigned len; - } validAuthLenInBits; - - struct { - uint8_t data[64]; - unsigned len; - } auth_iv; - - struct { - uint8_t data[64]; - unsigned len; - } digest; -}; -static struct wireless_test_data zuc_test_case_cipher_193b = { - .key = { - .data = { - 0x17, 0x3D, 0x14, 0xBA, 0x50, 0x03, 0x73, 0x1D, - 0x7A, 0x60, 0x04, 0x94, 0x70, 0xF0, 0x0A, 0x29 - }, - .len = 16 - }, - .cipher_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 - } -}; - -static struct wireless_test_data zuc_test_case_cipher_800b = { - .key = { - .data = { - 0xE5, 0xBD, 0x3E, 0xA0, 0xEB, 0x55, 0xAD, 0xE8, - 0x66, 0xC6, 0xAC, 0x58, 0xBD, 0x54, 0x30, 0x2A - }, - .len = 16 - }, - .cipher_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 - } -}; - -static struct wireless_test_data zuc_test_case_cipher_1570b = { - .key = { - .data = { - 0xD4, 0x55, 0x2A, 0x8F, 0xD6, 0xE6, 0x1C, 0xC8, - 0x1A, 0x20, 0x09, 0x14, 0x1A, 0x29, 0xC1, 0x0B - }, - .len = 16 - }, - .cipher_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 - } -}; - -static struct wireless_test_data zuc_test_case_cipher_2798b = { - .key = { - .data = { - 0xDB, 0x84, 0xB4, 0xFB, 0xCC, 0xDA, 0x56, 0x3B, - 0x66, 0x22, 0x7B, 0xFE, 0x45, 0x6F, 0x0F, 0x77 - }, - .len = 16 - }, - .cipher_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 - } -}; - -static struct wireless_test_data zuc_test_case_cipher_4019b = { - .key = { - .data = { - 0xE1, 0x3F, 0xED, 0x21, 0xB4, 0x6E, 0x4E, 0x7E, - 0xC3, 0x12, 0x53, 0xB2, 0xBB, 0x17, 0xB3, 0xE0 - }, - .len = 16 - }, - .cipher_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 - } -}; - -static struct wireless_test_data zuc_test_case_cipher_200b_auth_200b = { - .key = { - .data = { - 0x17, 0x3D, 0x14, 0xBA, 0x50, 0x03, 0x73, 0x1D, - 0x7A, 0x60, 0x04, 0x94, 0x70, 0xF0, 0x0A, 0x29 - }, - .len = 16 - }, - .cipher_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, - 0x10 - }, - .len = 200 - }, - .validDataLenInBits = { - .len = 200 - }, - .validCipherLenInBits = { - .len = 200 - }, - .auth_iv = { - .data = { - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .digest = { - .data = {0x01, 0xFE, 0x5E, 0x38}, - .len = 4 - }, - .validAuthLenInBits = { - .len = 200 - } -}; - -static struct wireless_test_data zuc_test_case_cipher_800b_auth_120b = { - .key = { - .data = { - 0xE5, 0xBD, 0x3E, 0xA0, 0xEB, 0x55, 0xAD, 0xE8, - 0x66, 0xC6, 0xAC, 0x58, 0xBD, 0x54, 0x30, 0x2A - }, - .len = 16 - }, - .cipher_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 - }, - .auth_iv = { - .data = { - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, - 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .digest = { - .data = {0x9D, 0x42, 0x1C, 0xEA}, - .len = 4 - }, - .validAuthLenInBits = { - .len = 120 - } -}; - -struct wireless_test_data zuc_test_case_auth_1b = { - .key = { - .data = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - .len = 16 - }, - .auth_iv = { - .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 - }, - .digest = { - .data = {0xC8, 0xA9, 0x59, 0x5E}, - .len = 4 - } -}; - -struct wireless_test_data zuc_test_case_auth_90b = { - .key = { - .data = { - 0x47, 0x05, 0x41, 0x25, 0x56, 0x1E, 0xB2, 0xDD, - 0xA9, 0x40, 0x59, 0xDA, 0x05, 0x09, 0x78, 0x50 - }, - .len = 16 - }, - .auth_iv = { - .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 - }, - .digest = { - .data = {0x67, 0x19, 0xA0, 0x88}, - .len = 4 - } -}; - -struct wireless_test_data zuc_test_case_auth_577b = { - .key = { - .data = { - 0xC9, 0xE6, 0xCE, 0xC4, 0x60, 0x7C, 0x72, 0xDB, - 0x00, 0x0A, 0xEF, 0xA8, 0x83, 0x85, 0xAB, 0x0A - }, - .len = 16 - }, - .auth_iv = { - .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 - }, - .digest = { - .data = {0xFA, 0xE8, 0xFF, 0x0B}, - .len = 4 - } -}; - -struct wireless_test_data zuc_test_case_auth_2079b = { - .key = { - .data = { - 0xC8, 0xA4, 0x82, 0x62, 0xD0, 0xC2, 0xE2, 0xBA, - 0xC4, 0xB9, 0x6E, 0xF7, 0x7E, 0x80, 0xCA, 0x59 - }, - .len = 16 - }, - .auth_iv = { - .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 - }, - .digest = { - .data = {0x00, 0x4A, 0xC4, 0xD6}, - .len = 4 - } -}; - -struct wireless_test_data zuc_test_auth_5670b = { - .key = { - .data = { - 0x6B, 0x8B, 0x08, 0xEE, 0x79, 0xE0, 0xB5, 0x98, - 0x2D, 0x6D, 0x12, 0x8E, 0xA9, 0xF2, 0x20, 0xCB - }, - .len = 16 - }, - .auth_iv = { - .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 - }, - .digest = { - .data = {0x0C, 0xA1, 0x27, 0x92}, - .len = 4 - } -}; - -static struct wireless_test_data zuc_test_case_auth_128b = { - .key = { - .data = { 0x0 }, - .len = 16 - }, - .auth_iv = { - .data = { 0x0 }, - .len = 16 - }, - .plaintext = { - .data = { 0x0 }, - .len = 8 - }, - .validAuthLenInBits = { - .len = 8 - }, - .digest = { - .data = { 0x39, 0x0a, 0x91, 0xb7 }, - .len = 4 - } -}; - -static struct wireless_test_data zuc_test_case_auth_2080b = { - .key = { - .data = { - 0xC8, 0xA4, 0x82, 0x62, 0xD0, 0xC2, 0xE2, 0xBA, - 0xC4, 0xB9, 0x6E, 0xF7, 0x7E, 0x80, 0xCA, 0x59 - }, - .len = 16 - }, - .auth_iv = { - .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 = 2080 - }, - .digest = { - .data = {0x03, 0x95, 0x32, 0xe1}, - .len = 4 - } -}; - -static struct wireless_test_data zuc_test_case_auth_584b = { - .key = { - .data = { - 0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb, - 0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 0xab, 0x0a - }, - .len = 16 - }, - .auth_iv = { - .data = { - 0xa9, 0x40, 0x59, 0xda, 0x50, 0x0, 0x0, 0x0, - 0x29, 0x40, 0x59, 0xda, 0x50, 0x0, 0x80, 0x0 - }, - .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, 0x00, 0x00, 0x00 - }, - .len = 584 - }, - .validAuthLenInBits = { - .len = 584 - }, - .digest = { - .data = {0x24, 0xa8, 0x42, 0xb3}, - .len = 4 - } -}; - -#endif /* TEST_CRYPTODEV_ZUC_TEST_VECTORS_H_ */ diff --git a/test/test/test_cycles.c b/test/test/test_cycles.c deleted file mode 100644 index c78e6a5b12..0000000000 --- a/test/test/test_cycles.c +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 -check_wait_one_second(void) -{ - uint64_t cycles, prev_cycles; - uint64_t hz = rte_get_timer_hz(); - uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */ - - /* 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; -} - -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; - } - - return check_wait_one_second(); -} - -REGISTER_TEST_COMMAND(cycles_autotest, test_cycles); - -/* - * One second precision test with rte_delay_us_sleep. - */ - -static int -test_delay_us_sleep(void) -{ - rte_delay_us_callback_register(rte_delay_us_sleep); - return check_wait_one_second(); -} - -REGISTER_TEST_COMMAND(delay_us_sleep_autotest, test_delay_us_sleep); - -/* - * 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 deleted file mode 100644 index faf2cf5573..0000000000 --- a/test/test/test_debug.c +++ /dev/null @@ -1,126 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#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; - - /* manually cleanup EAL memory, as the fork() below would otherwise - * cause the same hugepages to be free()-ed multiple times. - */ - rte_service_finalize(); - - 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_distributor.c b/test/test/test_distributor.c deleted file mode 100644 index 98919ec0cc..0000000000 --- a/test/test/test_distributor.c +++ /dev/null @@ -1,697 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2017 Intel Corporation - */ - -#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 - -struct worker_params { - char name[64]; - struct rte_distributor *dist; -}; - -struct worker_params worker_params; - -/* 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 *buf[8] __rte_cache_aligned; - struct worker_params *wp = arg; - struct rte_distributor *db = wp->dist; - unsigned int count = 0, num = 0; - unsigned int id = __sync_fetch_and_add(&worker_idx, 1); - int i; - - for (i = 0; i < 8; i++) - buf[i] = NULL; - num = rte_distributor_get_pkt(db, id, buf, buf, num); - while (!quit) { - worker_stats[id].handled_packets += num; - count += num; - num = rte_distributor_get_pkt(db, id, - buf, buf, num); - } - worker_stats[id].handled_packets += num; - count += num; - rte_distributor_return_pkt(db, id, buf, num); - 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 through 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 worker_params *wp, struct rte_mempool *p) -{ - struct rte_distributor *db = wp->dist; - struct rte_mbuf *bufs[BURST]; - struct rte_mbuf *returns[BURST*2]; - unsigned int i, count; - unsigned int retries; - - 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(db, bufs, BURST); - count = 0; - do { - - rte_distributor_flush(db); - count += rte_distributor_returned_pkts(db, - returns, BURST*2); - } while (count < BURST); - - 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"); - - /* 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(db, bufs, BURST); - count = 0; - do { - rte_distributor_flush(db); - count += rte_distributor_returned_pkts(db, - returns, BURST*2); - } while (count < BURST); - 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"); - } - - /* 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+1; - - rte_distributor_process(db, bufs, BURST); - count = 0; - do { - rte_distributor_flush(db); - count += rte_distributor_returned_pkts(db, - returns, BURST*2); - } while (count < BURST); - 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(db); - rte_distributor_clear_returns(db); - - 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; - - printf("=== testing big burst (%s) ===\n", wp->name); - for (i = 0; i < BIG_BATCH/BURST; i++) { - rte_distributor_process(db, - &many_bufs[i*BURST], BURST); - count = rte_distributor_returned_pkts(db, - &return_bufs[num_returned], - BIG_BATCH - num_returned); - num_returned += count; - } - rte_distributor_flush(db); - count = rte_distributor_returned_pkts(db, - &return_bufs[num_returned], - BIG_BATCH - num_returned); - num_returned += count; - retries = 0; - do { - rte_distributor_flush(db); - count = rte_distributor_returned_pkts(db, - &return_bufs[num_returned], - BIG_BATCH - num_returned); - num_returned += count; - retries++; - } while ((num_returned < BIG_BATCH) && (retries < 100)); - - if (num_returned != BIG_BATCH) { - printf("line %d: Missing packets, expected %d\n", - __LINE__, num_returned); - 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 *buf[8] __rte_cache_aligned; - struct worker_params *wp = arg; - struct rte_distributor *d = wp->dist; - unsigned int count = 0; - unsigned int i; - unsigned int num = 0; - unsigned int id = __sync_fetch_and_add(&worker_idx, 1); - - for (i = 0; i < 8; i++) - buf[i] = NULL; - num = rte_distributor_get_pkt(d, id, buf, buf, num); - while (!quit) { - worker_stats[id].handled_packets += num; - count += num; - for (i = 0; i < num; i++) - rte_pktmbuf_free(buf[i]); - num = rte_distributor_get_pkt(d, - id, buf, buf, num); - } - worker_stats[id].handled_packets += num; - count += num; - rte_distributor_return_pkt(d, id, buf, num); - 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 worker_params *wp, struct rte_mempool *p) -{ - struct rte_distributor *d = wp->dist; - unsigned i; - struct rte_mbuf *bufs[BURST]; - - printf("=== Sanity test with mbuf alloc/free (%s) ===\n", wp->name); - - 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); - - rte_delay_us(10000); - - if (total_packet_count() < (1<dist; - unsigned int count = 0; - unsigned int num = 0; - unsigned int total = 0; - unsigned int i; - unsigned int returned = 0; - const unsigned int id = __sync_fetch_and_add(&worker_idx, 1); - - num = rte_distributor_get_pkt(d, id, buf, buf, num); - - /* wait for quit single globally, or for worker zero, wait - * for zero_quit */ - while (!quit && !(id == 0 && zero_quit)) { - worker_stats[id].handled_packets += num; - count += num; - for (i = 0; i < num; i++) - rte_pktmbuf_free(buf[i]); - num = rte_distributor_get_pkt(d, - id, buf, buf, num); - total += num; - } - worker_stats[id].handled_packets += num; - count += num; - returned = rte_distributor_return_pkt(d, id, buf, num); - - if (id == 0) { - /* for worker zero, allow it to restart to pick up last packet - * when all workers are shutting down. - */ - while (zero_quit) - usleep(100); - - num = rte_distributor_get_pkt(d, - id, buf, buf, num); - - while (!quit) { - worker_stats[id].handled_packets++, count++; - rte_pktmbuf_free(pkt); - num = rte_distributor_get_pkt(d, id, buf, buf, num); - } - returned = rte_distributor_return_pkt(d, - id, buf, num); - printf("Num returned = %d\n", returned); - } - 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_worker_shutdown(struct worker_params *wp, - struct rte_mempool *p) -{ - struct rte_distributor *d = wp->dist; - struct rte_mbuf *bufs[BURST]; - unsigned i; - - printf("=== Sanity test of 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 same value so all - * pkts go to the one worker thread - */ - for (i = 0; i < BURST; i++) - bufs[i]->hash.usr = 1; - - rte_distributor_process(d, bufs, BURST); - rte_distributor_flush(d); - - /* 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 = 1; - - /* get worker zero to quit */ - zero_quit = 1; - rte_distributor_process(d, bufs, BURST); - - /* flush the distributor */ - rte_distributor_flush(d); - rte_delay_us(10000); - - for (i = 0; i < rte_lcore_count() - 1; i++) - printf("Worker %u handled %u packets\n", i, - worker_stats[i].handled_packets); - - 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; - } - - 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 worker_params *wp, - struct rte_mempool *p) -{ - struct rte_distributor *d = wp->dist; - struct rte_mbuf *bufs[BURST]; - unsigned i; - - printf("=== Test flush fn with worker shutdown (%s) ===\n", wp->name); - - 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); - - rte_delay_us(10000); - - zero_quit = 0; - for (i = 0; i < rte_lcore_count() - 1; i++) - printf("Worker %u handled %u packets\n", i, - worker_stats[i].handled_packets); - - 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; - } - - printf("Flush test with worker shutdown passed\n\n"); - return 0; -} - -static -int test_error_distributor_create_name(void) -{ - struct rte_distributor *d = NULL; - struct rte_distributor *db = NULL; - char *name = NULL; - - d = rte_distributor_create(name, rte_socket_id(), - rte_lcore_count() - 1, - RTE_DIST_ALG_SINGLE); - if (d != NULL || rte_errno != EINVAL) { - printf("ERROR: No error on create() with NULL name param\n"); - return -1; - } - - db = rte_distributor_create(name, rte_socket_id(), - rte_lcore_count() - 1, - RTE_DIST_ALG_BURST); - if (db != NULL || rte_errno != EINVAL) { - printf("ERROR: No error on create() with NULL param\n"); - return -1; - } - - return 0; -} - - -static -int test_error_distributor_create_numworkers(void) -{ - struct rte_distributor *ds = NULL; - struct rte_distributor *db = NULL; - - ds = rte_distributor_create("test_numworkers", rte_socket_id(), - RTE_MAX_LCORE + 10, - RTE_DIST_ALG_SINGLE); - if (ds != NULL || rte_errno != EINVAL) { - printf("ERROR: No error on create() with num_workers > MAX\n"); - return -1; - } - - db = rte_distributor_create("test_numworkers", rte_socket_id(), - RTE_MAX_LCORE + 10, - RTE_DIST_ALG_BURST); - if (db != NULL || rte_errno != EINVAL) { - printf("ERROR: No error on create() num_workers > MAX\n"); - return -1; - } - - return 0; -} - - -/* Useful function which ensures that all worker functions terminate */ -static void -quit_workers(struct worker_params *wp, struct rte_mempool *p) -{ - struct rte_distributor *d = wp->dist; - 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 *ds; - static struct rte_distributor *db; - static struct rte_distributor *dist[2]; - static struct rte_mempool *p; - int i; - - if (rte_lcore_count() < 2) { - printf("ERROR: not enough cores to test distributor\n"); - return -1; - } - - if (db == NULL) { - db = rte_distributor_create("Test_dist_burst", rte_socket_id(), - rte_lcore_count() - 1, - RTE_DIST_ALG_BURST); - if (db == NULL) { - printf("Error creating burst distributor\n"); - return -1; - } - } else { - rte_distributor_flush(db); - rte_distributor_clear_returns(db); - } - - if (ds == NULL) { - ds = rte_distributor_create("Test_dist_single", - rte_socket_id(), - rte_lcore_count() - 1, - RTE_DIST_ALG_SINGLE); - if (ds == NULL) { - printf("Error creating single distributor\n"); - return -1; - } - } else { - rte_distributor_flush(ds); - rte_distributor_clear_returns(ds); - } - - 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; - } - } - - dist[0] = ds; - dist[1] = db; - - for (i = 0; i < 2; i++) { - - worker_params.dist = dist[i]; - if (i) - sprintf(worker_params.name, "burst"); - else - sprintf(worker_params.name, "single"); - - rte_eal_mp_remote_launch(handle_work, - &worker_params, SKIP_MASTER); - if (sanity_test(&worker_params, p) < 0) - goto err; - quit_workers(&worker_params, p); - - rte_eal_mp_remote_launch(handle_work_with_free_mbufs, - &worker_params, SKIP_MASTER); - if (sanity_test_with_mbuf_alloc(&worker_params, p) < 0) - goto err; - quit_workers(&worker_params, p); - - if (rte_lcore_count() > 2) { - rte_eal_mp_remote_launch(handle_work_for_shutdown_test, - &worker_params, - SKIP_MASTER); - if (sanity_test_with_worker_shutdown(&worker_params, - p) < 0) - goto err; - quit_workers(&worker_params, p); - - rte_eal_mp_remote_launch(handle_work_for_shutdown_test, - &worker_params, - SKIP_MASTER); - if (test_flush_with_worker_shutdown(&worker_params, - p) < 0) - goto err; - quit_workers(&worker_params, p); - - } else { - printf("Too few cores to run worker shutdown test\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(&worker_params, 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 deleted file mode 100644 index edf1998ab0..0000000000 --- a/test/test/test_distributor_perf.c +++ /dev/null @@ -1,268 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2017 Intel Corporation - */ - -#include "test.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ITER_POWER_CL 25 /* log 2 of how many iterations for Cache Line test */ -#define ITER_POWER 21 /* log 2 of how many iterations we do when timing. */ -#define BURST 64 -#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 int -flip_bit(volatile uint64_t *arg) -{ - uint64_t old_val = 0; - while (old_val != 2) { - while (!*arg) - rte_pause(); - old_val = *arg; - *arg = 0; - } - return 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_CL); 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_CL); -} - -/* - * 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_distributor *d = arg; - unsigned int count = 0; - unsigned int num = 0; - int i; - unsigned int id = __sync_fetch_and_add(&worker_idx, 1); - struct rte_mbuf *buf[8] __rte_cache_aligned; - - for (i = 0; i < 8; i++) - buf[i] = NULL; - - num = rte_distributor_get_pkt(d, id, buf, buf, num); - while (!quit) { - worker_stats[id].handled_packets += num; - count += num; - num = rte_distributor_get_pkt(d, id, buf, buf, num); - } - worker_stats[id].handled_packets += num; - count += num; - rte_distributor_return_pkt(d, id, buf, num); - 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 int 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 int num_workers = rte_lcore_count() - 1; - unsigned int 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 *ds; - static struct rte_distributor *db; - 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 (ds == NULL) { - ds = rte_distributor_create("Test_perf", rte_socket_id(), - rte_lcore_count() - 1, - RTE_DIST_ALG_SINGLE); - if (ds == NULL) { - printf("Error creating distributor\n"); - return -1; - } - } else { - rte_distributor_clear_returns(ds); - } - - if (db == NULL) { - db = rte_distributor_create("Test_burst", rte_socket_id(), - rte_lcore_count() - 1, - RTE_DIST_ALG_BURST); - if (db == NULL) { - printf("Error creating burst distributor\n"); - return -1; - } - } else { - rte_distributor_clear_returns(db); - } - - 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; - } - } - - printf("=== Performance test of distributor (single mode) ===\n"); - rte_eal_mp_remote_launch(handle_work, ds, SKIP_MASTER); - if (perf_test(ds, p) < 0) - return -1; - quit_workers(ds, p); - - printf("=== Performance test of distributor (burst mode) ===\n"); - rte_eal_mp_remote_launch(handle_work, db, SKIP_MASTER); - if (perf_test(db, p) < 0) - return -1; - quit_workers(db, 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 deleted file mode 100644 index 81e345b879..0000000000 --- a/test/test/test_eal_flags.c +++ /dev/null @@ -1,1393 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation. - * Copyright(c) 2014 6WIND S.A. - */ - -#include - -#include "test.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "process.h" - -#define DEFAULT_MEM_SIZE "18" -#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 * 20) -#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 - -/* - * 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, no_huge, "-n", "1", - "-c", "1", vdev, "eth_dummy"}; - - /* Test with valid vdev option */ - const char *vdevval1[] = {prgname, prefix, no_huge, "-n", "1", - "-c", "1", vdev, "net_ring0"}; - - const char *vdevval2[] = {prgname, prefix, no_huge, "-n", "1", - "-c", "1", vdev, "net_ring0,args=test"}; - - const char *vdevval3[] = {prgname, prefix, no_huge, "-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" }; - /* core number is negative value */ - const char * const argv11[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "-5" }; - const char * const argv12[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "-5-7" }; - /* core number is maximum value */ - const char * const argv13[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", RTE_STR(RTE_MAX_LCORE) }; - const char * const argv14[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "1-"RTE_STR(RTE_MAX_LCORE) }; - /* sanity check test - valid corelist value */ - const char * const argv15[] = { prgname, prefix, mp_flag, - "-n", "3", "-l", "1-2,3" }; - - /* --lcores flag but no lcores value */ - const char * const argv16[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores" }; - const char * const argv17[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", " " }; - /* bad lcores value */ - const char * const argv18[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "1-3-5" }; - const char * const argv19[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "0-1,,2" }; - const char * const argv20[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "0-,1" }; - const char * const argv21[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(0-,2-4)" }; - const char * const argv22[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(-1,2)" }; - const char * const argv23[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(2-4)@(2-4-6)" }; - const char * const argv24[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(a,2)" }; - const char * const argv25[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "1-3@(1,3)" }; - const char * const argv26[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "3@((1,3)" }; - const char * const argv27[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "(4-7)=(1,3)" }; - const char * const argv28[] = { prgname, prefix, mp_flag, - "-n", "3", "--lcores", "[4-7]@(1,3)" }; - /* sanity check of tests - valid lcores value */ - const char * const argv29[] = { 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 - || launch_proc(argv11) == 0 - || launch_proc(argv12) == 0 - || launch_proc(argv13) == 0 - || launch_proc(argv14) == 0) { - printf("Error - " - "process ran without error with invalid -l flag\n"); - return -1; - } - if (launch_proc(argv15) != 0) { - printf("Error - " - "process did not run ok with valid corelist value\n"); - return -1; - } - - /* start --lcores tests */ - if (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(argv22) == 0 || launch_proc(argv23) == 0 || - launch_proc(argv24) == 0 || launch_proc(argv25) == 0 || - launch_proc(argv26) == 0 || launch_proc(argv27) == 0 || - launch_proc(argv28) == 0) { - printf("Error - " - "process ran without error with invalid --lcore flag\n"); - return -1; - } - - if (launch_proc(argv29) != 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] = ""; - -#ifdef RTE_EXEC_ENV_BSDAPP - return 0; -#else - char 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 - - /* 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; -} - -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 further 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, also use no-huge to ensure this test runs on BSD */ - const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE, - no_shconf, nosh_prefix, no_huge}; - - /* 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"}; - - /* run all tests also applicable to FreeBSD first */ - - 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(argv6) != 0) { - printf("Error - process did not run ok with --no-shconf flag\n"); - return -1; - } - -#ifdef RTE_EXEC_ENV_BSDAPP - /* no more tests to be done on FreeBSD */ - return 0; -#endif - - 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(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; -} - -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 in default and legacy - * mem mode - * 5. check if memtest1 hugefiles are created in case of legacy mem - * mode, and deleted in case of default mem mode - * 6. run a primary process with memtest2 prefix in default and legacy - * mem modes - * 7. check that memtest2 hugefiles are present in the hugedir after a - * run in legacy mode, and not present at all after run in default - * mem mode - */ - char prefix[PATH_MAX] = ""; - -#ifdef RTE_EXEC_ENV_BSDAPP - return 0; -#else - if (get_current_prefix(prefix, sizeof(prefix)) == NULL) { - printf("Error - unable to get current prefix!\n"); - return -1; - } -#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 and default mem mode */ - const char *argv1[] = {prgname, "-c", "1", "-n", "2", "-m", - DEFAULT_MEM_SIZE, "--file-prefix=" memtest1 }; - - /* primary process with memtest1 and legacy mem mode */ - const char *argv2[] = {prgname, "-c", "1", "-n", "2", "-m", - DEFAULT_MEM_SIZE, "--file-prefix=" memtest1, - "--legacy-mem" }; - - /* primary process with memtest2 and legacy mem mode */ - const char *argv3[] = {prgname, "-c", "1", "-n", "2", "-m", - DEFAULT_MEM_SIZE, "--file-prefix=" memtest2, - "--legacy-mem" }; - - /* primary process with memtest2 and default mem mode */ - const char *argv4[] = {prgname, "-c", "1", "-n", "2", "-m", - DEFAULT_MEM_SIZE, "--file-prefix=" memtest2 }; - - /* 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; - } - - /* we're running this process in default memory mode, which means it - * should clean up after itself on exit and leave no hugepages behind. - */ - if (launch_proc(argv1) != 0) { - printf("Error - failed to run with --file-prefix=%s\n", - memtest1); - return -1; - } - - /* check if memtest1_map0 is present */ - if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { - printf("Error - hugepage files for %s were not deleted!\n", - memtest1); - return -1; - } - - /* now, we're running a process under the same prefix, but with legacy - * mem mode - this should leave behind hugepage files. - */ - if (launch_proc(argv2) != 0) { - printf("Error - failed to run with --file-prefix=%s\n", - memtest1); - 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(argv3) != 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; - } - - /* this process will run in default mem mode, so it should not leave any - * hugepage files behind. - */ - if (launch_proc(argv4) != 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) != 0) { - printf("Error - hugepage files for %s were not deleted!\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}; - - /* valid (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 = RTE_MIN(get_number_of_sockets(), - RTE_MAX_NUMA_NODES); -#endif - - if (num_sockets <= 0) { - 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); - strlcpy(invalid_socket_mem, buf, sizeof(invalid_socket_mem)); - - if (num_sockets + 1 - i > 1) { - snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem); - strlcpy(invalid_socket_mem, buf, - sizeof(invalid_socket_mem)); - } - } - - /* 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); - strlcpy(valid_socket_mem, buf, sizeof(valid_socket_mem)); - - if (num_sockets - i > 1) { - snprintf(buf, sizeof(buf), "%s,", valid_socket_mem); - strlcpy(valid_socket_mem, buf, - sizeof(valid_socket_mem)); - } - } - - /* 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; - } - if (launch_proc(argv2) != 0) { - printf("Error - process failed with valid (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; - } - - ret = test_misc_flags(); - 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 deleted file mode 100644 index 7ca2164102..0000000000 --- a/test/test/test_eal_fs.c +++ /dev/null @@ -1,177 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index ced091aab6..0000000000 --- a/test/test/test_efd.c +++ /dev/null @@ -1,471 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#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, - (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 deleted file mode 100644 index 1dcb992c6e..0000000000 --- a/test/test/test_efd_perf.c +++ /dev/null @@ -1,385 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016-2017 Intel Corporation - */ - -#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 deleted file mode 100644 index 920a2cf890..0000000000 --- a/test/test/test_errno.c +++ /dev/null @@ -1,87 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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_event_crypto_adapter.c b/test/test/test_event_crypto_adapter.c deleted file mode 100644 index f750ce3d8c..0000000000 --- a/test/test/test_event_crypto_adapter.c +++ /dev/null @@ -1,941 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation. - * All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.h" - -#define PKT_TRACE 0 -#define NUM 1 -#define DEFAULT_NUM_XFORMS (2) -#define NUM_MBUFS (8191) -#define MBUF_CACHE_SIZE (256) -#define MAXIMUM_IV_LENGTH (16) -#define DEFAULT_NUM_OPS_INFLIGHT (128) -#define MAX_NB_SESSIONS 4 -#define TEST_APP_PORT_ID 0 -#define TEST_APP_EV_QUEUE_ID 0 -#define TEST_APP_EV_PRIORITY 0 -#define TEST_APP_EV_FLOWID 0xAABB -#define TEST_CRYPTO_EV_QUEUE_ID 1 -#define TEST_ADAPTER_ID 0 -#define TEST_CDEV_ID 0 -#define TEST_CDEV_QP_ID 0 -#define PACKET_LENGTH 64 -#define NB_TEST_PORTS 1 -#define NB_TEST_QUEUES 2 -#define NUM_CORES 1 -#define CRYPTODEV_NAME_NULL_PMD crypto_null - -#define MBUF_SIZE (sizeof(struct rte_mbuf) + \ - RTE_PKTMBUF_HEADROOM + PACKET_LENGTH) -#define IV_OFFSET (sizeof(struct rte_crypto_op) + \ - sizeof(struct rte_crypto_sym_op) + \ - DEFAULT_NUM_XFORMS * \ - sizeof(struct rte_crypto_sym_xform)) - -/* Handle log statements in same manner as test macros */ -#define LOG_DBG(...) RTE_LOG(DEBUG, EAL, __VA_ARGS__) - -static const uint8_t text_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 -}; - -struct event_crypto_adapter_test_params { - struct rte_mempool *mbuf_pool; - struct rte_mempool *op_mpool; - struct rte_mempool *session_mpool; - struct rte_mempool *session_priv_mpool; - struct rte_cryptodev_config *config; - uint8_t crypto_event_port_id; -}; - -struct rte_event response_info = { - .queue_id = TEST_APP_EV_QUEUE_ID, - .sched_type = RTE_SCHED_TYPE_ATOMIC, - .flow_id = TEST_APP_EV_FLOWID, - .priority = TEST_APP_EV_PRIORITY -}; - -struct rte_event_crypto_request request_info = { - .cdev_id = TEST_CDEV_ID, - .queue_pair_id = TEST_CDEV_QP_ID -}; - -static struct event_crypto_adapter_test_params params; -static uint8_t crypto_adapter_setup_done; -static uint32_t slcore_id; -static int evdev; - -static struct rte_mbuf * -alloc_fill_mbuf(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 int -send_recv_ev(struct rte_event *ev) -{ - struct rte_crypto_op *op; - struct rte_event recv_ev; - int ret; - - ret = rte_event_enqueue_burst(evdev, TEST_APP_PORT_ID, ev, NUM); - TEST_ASSERT_EQUAL(ret, NUM, - "Failed to send event to crypto adapter\n"); - - while (rte_event_dequeue_burst(evdev, - TEST_APP_PORT_ID, &recv_ev, NUM, 0) == 0) - rte_pause(); - - op = recv_ev.event_ptr; -#if PKT_TRACE - struct rte_mbuf *m = op->sym->m_src; - rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m)); -#endif - rte_pktmbuf_free(op->sym->m_src); - rte_crypto_op_free(op); - - return TEST_SUCCESS; -} - -static int -test_crypto_adapter_stats(void) -{ - struct rte_event_crypto_adapter_stats stats; - - rte_event_crypto_adapter_stats_get(TEST_ADAPTER_ID, &stats); - printf(" +------------------------------------------------------+\n"); - printf(" + Crypto adapter stats for instance %u:\n", TEST_ADAPTER_ID); - printf(" + Event port poll count %" PRIx64 "\n", - stats.event_poll_count); - printf(" + Event dequeue count %" PRIx64 "\n", - stats.event_deq_count); - printf(" + Cryptodev enqueue count %" PRIx64 "\n", - stats.crypto_enq_count); - printf(" + Cryptodev enqueue failed count %" PRIx64 "\n", - stats.crypto_enq_fail); - printf(" + Cryptodev dequeue count %" PRIx64 "\n", - stats.crypto_deq_count); - printf(" + Event enqueue count %" PRIx64 "\n", - stats.event_enq_count); - printf(" + Event enqueue retry count %" PRIx64 "\n", - stats.event_enq_retry_count); - printf(" + Event enqueue fail count %" PRIx64 "\n", - stats.event_enq_fail_count); - printf(" +------------------------------------------------------+\n"); - - rte_event_crypto_adapter_stats_reset(TEST_ADAPTER_ID); - return TEST_SUCCESS; -} - -static int -test_op_forward_mode(uint8_t session_less) -{ - struct rte_crypto_sym_xform cipher_xform; - struct rte_cryptodev_sym_session *sess; - union rte_event_crypto_metadata m_data; - struct rte_crypto_sym_op *sym_op; - struct rte_crypto_op *op; - struct rte_mbuf *m; - struct rte_event ev; - uint32_t cap; - int ret; - - memset(&m_data, 0, sizeof(m_data)); - - m = alloc_fill_mbuf(params.mbuf_pool, text_64B, PACKET_LENGTH, 0); - TEST_ASSERT_NOT_NULL(m, "Failed to allocate mbuf!\n"); -#if PKT_TRACE - rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m)); -#endif - /* Setup Cipher Parameters */ - cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform.next = NULL; - - cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_NULL; - cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - - op = rte_crypto_op_alloc(params.op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(op, - "Failed to allocate symmetric crypto operation struct\n"); - - sym_op = op->sym; - - if (!session_less) { - sess = rte_cryptodev_sym_session_create( - params.session_mpool); - TEST_ASSERT_NOT_NULL(sess, "Session creation failed\n"); - - /* Create Crypto session*/ - rte_cryptodev_sym_session_init(TEST_CDEV_ID, sess, - &cipher_xform, params.session_priv_mpool); - - ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, - evdev, &cap); - TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); - - if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA) { - /* Fill in private user data information */ - rte_memcpy(&m_data.response_info, &response_info, - sizeof(response_info)); - rte_memcpy(&m_data.request_info, &request_info, - sizeof(request_info)); - rte_cryptodev_sym_session_set_user_data(sess, - &m_data, sizeof(m_data)); - } - - rte_crypto_op_attach_sym_session(op, sess); - } else { - struct rte_crypto_sym_xform *first_xform; - - rte_crypto_op_sym_xforms_alloc(op, NUM); - op->sess_type = RTE_CRYPTO_OP_SESSIONLESS; - first_xform = &cipher_xform; - sym_op->xform = first_xform; - uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH + - (sizeof(struct rte_crypto_sym_xform) * 2); - op->private_data_offset = len; - /* Fill in private data information */ - rte_memcpy(&m_data.response_info, &response_info, - sizeof(response_info)); - rte_memcpy(&m_data.request_info, &request_info, - sizeof(request_info)); - rte_memcpy((uint8_t *)op + len, &m_data, sizeof(m_data)); - } - - sym_op->m_src = m; - sym_op->cipher.data.offset = 0; - sym_op->cipher.data.length = PACKET_LENGTH; - - /* Fill in event info and update event_ptr with rte_crypto_op */ - memset(&ev, 0, sizeof(ev)); - ev.queue_id = TEST_CRYPTO_EV_QUEUE_ID; - ev.sched_type = RTE_SCHED_TYPE_ATOMIC; - ev.flow_id = 0xAABB; - ev.event_ptr = op; - - ret = send_recv_ev(&ev); - TEST_ASSERT_SUCCESS(ret, "Failed to send/receive event to " - "crypto adapter\n"); - - test_crypto_adapter_stats(); - - return TEST_SUCCESS; -} - -static int -map_adapter_service_core(void) -{ - uint32_t adapter_service_id; - int ret; - - if (rte_event_crypto_adapter_service_id_get(TEST_ADAPTER_ID, - &adapter_service_id) == 0) { - uint32_t core_list[NUM_CORES]; - - ret = rte_service_lcore_list(core_list, NUM_CORES); - TEST_ASSERT(ret >= 0, "Failed to get service core list!"); - - if (core_list[0] != slcore_id) { - TEST_ASSERT_SUCCESS(rte_service_lcore_add(slcore_id), - "Failed to add service core"); - TEST_ASSERT_SUCCESS(rte_service_lcore_start(slcore_id), - "Failed to start service core"); - } - - TEST_ASSERT_SUCCESS(rte_service_map_lcore_set( - adapter_service_id, slcore_id, 1), - "Failed to map adapter service"); - } - - return TEST_SUCCESS; -} - -static int -test_sessionless_with_op_forward_mode(void) -{ - uint32_t cap; - int ret; - - ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); - TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); - - if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD)) - map_adapter_service_core(); - - TEST_ASSERT_SUCCESS(rte_event_crypto_adapter_start(TEST_ADAPTER_ID), - "Failed to start event crypto adapter"); - - ret = test_op_forward_mode(1); - TEST_ASSERT_SUCCESS(ret, "Sessionless - FORWARD mode test failed\n"); - return TEST_SUCCESS; -} - -static int -test_session_with_op_forward_mode(void) -{ - uint32_t cap; - int ret; - - ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); - TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); - - if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD)) - map_adapter_service_core(); - - TEST_ASSERT_SUCCESS(rte_event_crypto_adapter_start(TEST_ADAPTER_ID - ), "Failed to start event crypto adapter"); - - ret = test_op_forward_mode(0); - TEST_ASSERT_SUCCESS(ret, "Session based - FORWARD mode test failed\n"); - return TEST_SUCCESS; -} - -static int -send_op_recv_ev(struct rte_crypto_op *op) -{ - struct rte_crypto_op *recv_op; - struct rte_event ev; - int ret; - - ret = rte_cryptodev_enqueue_burst(TEST_CDEV_ID, TEST_CDEV_QP_ID, - &op, NUM); - TEST_ASSERT_EQUAL(ret, NUM, "Failed to enqueue to cryptodev\n"); - memset(&ev, 0, sizeof(ev)); - - while (rte_event_dequeue_burst(evdev, - TEST_APP_PORT_ID, &ev, NUM, 0) == 0) - rte_pause(); - - recv_op = ev.event_ptr; -#if PKT_TRACE - struct rte_mbuf *m = recv_op->sym->m_src; - rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m)); -#endif - rte_pktmbuf_free(recv_op->sym->m_src); - rte_crypto_op_free(recv_op); - - return TEST_SUCCESS; -} - -static int -test_op_new_mode(uint8_t session_less) -{ - struct rte_crypto_sym_xform cipher_xform; - struct rte_cryptodev_sym_session *sess; - union rte_event_crypto_metadata m_data; - struct rte_crypto_sym_op *sym_op; - struct rte_crypto_op *op; - struct rte_mbuf *m; - uint32_t cap; - int ret; - - memset(&m_data, 0, sizeof(m_data)); - - m = alloc_fill_mbuf(params.mbuf_pool, text_64B, PACKET_LENGTH, 0); - TEST_ASSERT_NOT_NULL(m, "Failed to allocate mbuf!\n"); -#if PKT_TRACE - rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m)); -#endif - /* Setup Cipher Parameters */ - cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform.next = NULL; - - cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_NULL; - cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - - op = rte_crypto_op_alloc(params.op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(op, "Failed to allocate crypto_op!\n"); - - sym_op = op->sym; - - if (!session_less) { - sess = rte_cryptodev_sym_session_create( - params.session_mpool); - TEST_ASSERT_NOT_NULL(sess, "Session creation failed\n"); - - ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, - evdev, &cap); - TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); - - if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA) { - /* Fill in private user data information */ - rte_memcpy(&m_data.response_info, &response_info, - sizeof(m_data)); - rte_cryptodev_sym_session_set_user_data(sess, - &m_data, sizeof(m_data)); - } - rte_cryptodev_sym_session_init(TEST_CDEV_ID, sess, - &cipher_xform, params.session_priv_mpool); - rte_crypto_op_attach_sym_session(op, sess); - } else { - struct rte_crypto_sym_xform *first_xform; - - rte_crypto_op_sym_xforms_alloc(op, NUM); - op->sess_type = RTE_CRYPTO_OP_SESSIONLESS; - first_xform = &cipher_xform; - sym_op->xform = first_xform; - uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH + - (sizeof(struct rte_crypto_sym_xform) * 2); - op->private_data_offset = len; - /* Fill in private data information */ - rte_memcpy(&m_data.response_info, &response_info, - sizeof(m_data)); - rte_memcpy((uint8_t *)op + len, &m_data, sizeof(m_data)); - } - - sym_op->m_src = m; - sym_op->cipher.data.offset = 0; - sym_op->cipher.data.length = PACKET_LENGTH; - - ret = send_op_recv_ev(op); - TEST_ASSERT_SUCCESS(ret, "Failed to enqueue op to cryptodev\n"); - - test_crypto_adapter_stats(); - - return TEST_SUCCESS; -} - -static int -test_sessionless_with_op_new_mode(void) -{ - uint32_t cap; - int ret; - - ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); - TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); - - if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) || - !(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_NEW)) - map_adapter_service_core(); - - /* start the event crypto adapter */ - TEST_ASSERT_SUCCESS(rte_event_crypto_adapter_start(TEST_ADAPTER_ID), - "Failed to start event crypto adapter"); - - ret = test_op_new_mode(1); - TEST_ASSERT_SUCCESS(ret, "Sessionless - NEW mode test failed\n"); - return TEST_SUCCESS; -} - -static int -test_session_with_op_new_mode(void) -{ - uint32_t cap; - int ret; - - ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); - TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); - - if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) || - !(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_NEW)) - map_adapter_service_core(); - - TEST_ASSERT_SUCCESS(rte_event_crypto_adapter_start(TEST_ADAPTER_ID), - "Failed to start event crypto adapter"); - - ret = test_op_new_mode(0); - TEST_ASSERT_SUCCESS(ret, "Session based - NEW mode test failed\n"); - return TEST_SUCCESS; -} - -static int -configure_cryptodev(void) -{ - struct rte_cryptodev_qp_conf qp_conf; - struct rte_cryptodev_config conf; - struct rte_cryptodev_info info; - unsigned int session_size; - uint8_t nb_devs; - int ret; - - params.mbuf_pool = rte_pktmbuf_pool_create( - "CRYPTO_ADAPTER_MBUFPOOL", - NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, - rte_socket_id()); - if (params.mbuf_pool == NULL) { - RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n"); - return TEST_FAILED; - } - - params.op_mpool = rte_crypto_op_pool_create( - "EVENT_CRYPTO_SYM_OP_POOL", - RTE_CRYPTO_OP_TYPE_SYMMETRIC, - NUM_MBUFS, MBUF_CACHE_SIZE, - DEFAULT_NUM_XFORMS * - sizeof(struct rte_crypto_sym_xform) + - MAXIMUM_IV_LENGTH, - rte_socket_id()); - if (params.op_mpool == NULL) { - RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); - return TEST_FAILED; - } - - /* Create a NULL crypto device */ - nb_devs = rte_cryptodev_device_count_by_driver( - rte_cryptodev_driver_id_get( - RTE_STR(CRYPTODEV_NAME_NULL_PMD))); - if (!nb_devs) { - ret = rte_vdev_init( - RTE_STR(CRYPTODEV_NAME_NULL_PMD), NULL); - - TEST_ASSERT(ret == 0, "Failed to create pmd:%s instance\n", - RTE_STR(CRYPTODEV_NAME_NULL_PMD)); - } - - nb_devs = rte_cryptodev_count(); - if (!nb_devs) { - RTE_LOG(ERR, USER1, "No crypto devices found!\n"); - return TEST_FAILED; - } - - /* - * Create mempool with maximum number of sessions * 2, - * to include the session headers & private data - */ - session_size = rte_cryptodev_sym_get_private_session_size(TEST_CDEV_ID); - session_size += sizeof(union rte_event_crypto_metadata); - - params.session_mpool = rte_cryptodev_sym_session_pool_create( - "CRYPTO_ADAPTER_SESSION_MP", - MAX_NB_SESSIONS, 0, 0, 0, SOCKET_ID_ANY); - TEST_ASSERT_NOT_NULL(params.session_mpool, - "session mempool allocation failed\n"); - - params.session_priv_mpool = rte_mempool_create( - "CRYPTO_ADAPTER_SESSION_MP_PRIV", - MAX_NB_SESSIONS, - session_size, - 0, 0, NULL, NULL, NULL, - NULL, SOCKET_ID_ANY, - 0); - TEST_ASSERT_NOT_NULL(params.session_priv_mpool, - "session mempool allocation failed\n"); - - rte_cryptodev_info_get(TEST_CDEV_ID, &info); - conf.nb_queue_pairs = info.max_nb_queue_pairs; - conf.socket_id = SOCKET_ID_ANY; - - TEST_ASSERT_SUCCESS(rte_cryptodev_configure(TEST_CDEV_ID, &conf), - "Failed to configure cryptodev %u with %u qps\n", - TEST_CDEV_ID, conf.nb_queue_pairs); - - qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; - qp_conf.mp_session = params.session_mpool; - qp_conf.mp_session_private = params.session_priv_mpool; - - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - TEST_CDEV_ID, TEST_CDEV_QP_ID, &qp_conf, - rte_cryptodev_socket_id(TEST_CDEV_ID)), - "Failed to setup queue pair %u on cryptodev %u\n", - TEST_CDEV_QP_ID, TEST_CDEV_ID); - - return TEST_SUCCESS; -} - -static inline void -evdev_set_conf_values(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - memset(dev_conf, 0, sizeof(struct rte_event_dev_config)); - dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns; - dev_conf->nb_event_ports = NB_TEST_PORTS; - dev_conf->nb_event_queues = NB_TEST_QUEUES; - dev_conf->nb_event_queue_flows = info->max_event_queue_flows; - dev_conf->nb_event_port_dequeue_depth = - info->max_event_port_dequeue_depth; - dev_conf->nb_event_port_enqueue_depth = - info->max_event_port_enqueue_depth; - dev_conf->nb_event_port_enqueue_depth = - info->max_event_port_enqueue_depth; - dev_conf->nb_events_limit = - info->max_num_events; -} - -static int -configure_eventdev(void) -{ - struct rte_event_queue_conf queue_conf; - struct rte_event_dev_config devconf; - struct rte_event_dev_info info; - uint32_t queue_count; - uint32_t port_count; - int ret; - uint8_t qid; - - if (!rte_event_dev_count()) { - /* If there is no hardware eventdev, or no software vdev was - * specified on the command line, create an instance of - * event_sw. - */ - LOG_DBG("Failed to find a valid event device... " - "testing with event_sw device\n"); - TEST_ASSERT_SUCCESS(rte_vdev_init("event_sw0", NULL), - "Error creating eventdev"); - evdev = rte_event_dev_get_dev_id("event_sw0"); - } - - ret = rte_event_dev_info_get(evdev, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info\n"); - - evdev_set_conf_values(&devconf, &info); - - ret = rte_event_dev_configure(evdev, &devconf); - TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev\n"); - - /* Set up event queue */ - ret = rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT, - &queue_count); - TEST_ASSERT_SUCCESS(ret, "Queue count get failed\n"); - TEST_ASSERT_EQUAL(queue_count, 2, "Unexpected queue count\n"); - - qid = TEST_APP_EV_QUEUE_ID; - ret = rte_event_queue_setup(evdev, qid, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%d\n", qid); - - queue_conf.nb_atomic_flows = info.max_event_queue_flows; - queue_conf.nb_atomic_order_sequences = 32; - queue_conf.schedule_type = RTE_SCHED_TYPE_ATOMIC; - queue_conf.priority = RTE_EVENT_DEV_PRIORITY_HIGHEST; - queue_conf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK; - - qid = TEST_CRYPTO_EV_QUEUE_ID; - ret = rte_event_queue_setup(evdev, qid, &queue_conf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%u\n", qid); - - /* Set up event port */ - ret = rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT, - &port_count); - TEST_ASSERT_SUCCESS(ret, "Port count get failed\n"); - TEST_ASSERT_EQUAL(port_count, 1, "Unexpected port count\n"); - - ret = rte_event_port_setup(evdev, TEST_APP_PORT_ID, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port=%d\n", - TEST_APP_PORT_ID); - - qid = TEST_APP_EV_QUEUE_ID; - ret = rte_event_port_link(evdev, TEST_APP_PORT_ID, &qid, NULL, 1); - TEST_ASSERT(ret >= 0, "Failed to link queue port=%d\n", - TEST_APP_PORT_ID); - - return TEST_SUCCESS; -} - -static void -test_crypto_adapter_free(void) -{ - rte_event_crypto_adapter_free(TEST_ADAPTER_ID); -} - -static int -test_crypto_adapter_create(void) -{ - struct rte_event_port_conf conf = { - .dequeue_depth = 8, - .enqueue_depth = 8, - .new_event_threshold = 1200, - }; - int ret; - - /* Create adapter with default port creation callback */ - ret = rte_event_crypto_adapter_create(TEST_ADAPTER_ID, - TEST_CDEV_ID, - &conf, 0); - TEST_ASSERT_SUCCESS(ret, "Failed to create event crypto adapter\n"); - - return TEST_SUCCESS; -} - -static int -test_crypto_adapter_qp_add_del(void) -{ - uint32_t cap; - int ret; - - ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); - TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); - - if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND) { - ret = rte_event_crypto_adapter_queue_pair_add(TEST_ADAPTER_ID, - TEST_CDEV_ID, TEST_CDEV_QP_ID, &response_info); - } else - ret = rte_event_crypto_adapter_queue_pair_add(TEST_ADAPTER_ID, - TEST_CDEV_ID, TEST_CDEV_QP_ID, NULL); - - TEST_ASSERT_SUCCESS(ret, "Failed to create add queue pair\n"); - - ret = rte_event_crypto_adapter_queue_pair_del(TEST_ADAPTER_ID, - TEST_CDEV_ID, TEST_CDEV_QP_ID); - TEST_ASSERT_SUCCESS(ret, "Failed to delete add queue pair\n"); - - return TEST_SUCCESS; -} - -static int -configure_event_crypto_adapter(enum rte_event_crypto_adapter_mode mode) -{ - struct rte_event_port_conf conf = { - .dequeue_depth = 8, - .enqueue_depth = 8, - .new_event_threshold = 1200, - }; - - uint32_t cap; - int ret; - - /* Create adapter with default port creation callback */ - ret = rte_event_crypto_adapter_create(TEST_ADAPTER_ID, - TEST_CDEV_ID, - &conf, mode); - TEST_ASSERT_SUCCESS(ret, "Failed to create event crypto adapter\n"); - - ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID, evdev, &cap); - TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); - - if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND) { - ret = rte_event_crypto_adapter_queue_pair_add(TEST_ADAPTER_ID, - TEST_CDEV_ID, TEST_CDEV_QP_ID, &response_info); - } else - ret = rte_event_crypto_adapter_queue_pair_add(TEST_ADAPTER_ID, - TEST_CDEV_ID, TEST_CDEV_QP_ID, NULL); - - TEST_ASSERT_SUCCESS(ret, "Failed to add queue pair\n"); - - ret = rte_event_crypto_adapter_event_port_get(TEST_ADAPTER_ID, - ¶ms.crypto_event_port_id); - TEST_ASSERT_SUCCESS(ret, "Failed to get event port\n"); - - return TEST_SUCCESS; -} - -static void -test_crypto_adapter_stop(void) -{ - uint32_t evdev_service_id, adapter_service_id; - - /* retrieve service ids & stop services */ - if (rte_event_crypto_adapter_service_id_get(TEST_ADAPTER_ID, - &adapter_service_id) == 0) { - rte_service_runstate_set(adapter_service_id, 0); - rte_service_lcore_stop(slcore_id); - rte_service_lcore_del(slcore_id); - rte_event_crypto_adapter_stop(TEST_ADAPTER_ID); - } - - if (rte_event_dev_service_id_get(evdev, &evdev_service_id) == 0) { - rte_service_runstate_set(evdev_service_id, 0); - rte_service_lcore_stop(slcore_id); - rte_service_lcore_del(slcore_id); - rte_event_dev_stop(evdev); - } -} - -static int -test_crypto_adapter_conf(enum rte_event_crypto_adapter_mode mode) -{ - uint32_t evdev_service_id; - uint8_t qid; - int ret; - - if (!crypto_adapter_setup_done) { - ret = configure_event_crypto_adapter(mode); - if (!ret) { - qid = TEST_CRYPTO_EV_QUEUE_ID; - ret = rte_event_port_link(evdev, - params.crypto_event_port_id, &qid, NULL, 1); - TEST_ASSERT(ret >= 0, "Failed to link queue %d " - "port=%u\n", qid, - params.crypto_event_port_id); - } - crypto_adapter_setup_done = 1; - } - - /* retrieve service ids */ - if (rte_event_dev_service_id_get(evdev, &evdev_service_id) == 0) { - /* add a service core and start it */ - TEST_ASSERT_SUCCESS(rte_service_lcore_add(slcore_id), - "Failed to add service core"); - TEST_ASSERT_SUCCESS(rte_service_lcore_start(slcore_id), - "Failed to start service core"); - - /* map services to it */ - TEST_ASSERT_SUCCESS(rte_service_map_lcore_set(evdev_service_id, - slcore_id, 1), "Failed to map evdev service"); - - /* set services to running */ - TEST_ASSERT_SUCCESS(rte_service_runstate_set(evdev_service_id, - 1), "Failed to start evdev service"); - } - - /* start the eventdev */ - TEST_ASSERT_SUCCESS(rte_event_dev_start(evdev), - "Failed to start event device"); - - return TEST_SUCCESS; -} - -static int -test_crypto_adapter_conf_op_forward_mode(void) -{ - enum rte_event_crypto_adapter_mode mode; - - mode = RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD; - test_crypto_adapter_conf(mode); - - return TEST_SUCCESS; -} - -static int -test_crypto_adapter_conf_op_new_mode(void) -{ - enum rte_event_crypto_adapter_mode mode; - - mode = RTE_EVENT_CRYPTO_ADAPTER_OP_NEW; - test_crypto_adapter_conf(mode); - return TEST_SUCCESS; -} - - -static int -testsuite_setup(void) -{ - int ret; - - slcore_id = rte_get_next_lcore(-1, 1, 0); - TEST_ASSERT_NOT_EQUAL(slcore_id, RTE_MAX_LCORE, "At least 2 lcores " - "are required to run this autotest\n"); - - /* Setup and start event device. */ - ret = configure_eventdev(); - TEST_ASSERT_SUCCESS(ret, "Failed to setup eventdev\n"); - - /* Setup and start crypto device. */ - ret = configure_cryptodev(); - TEST_ASSERT_SUCCESS(ret, "cryptodev initialization failed\n"); - - return TEST_SUCCESS; -} - -static void -crypto_teardown(void) -{ - /* Free mbuf mempool */ - if (params.mbuf_pool != NULL) { - RTE_LOG(DEBUG, USER1, "CRYPTO_ADAPTER_MBUFPOOL count %u\n", - rte_mempool_avail_count(params.mbuf_pool)); - rte_mempool_free(params.mbuf_pool); - params.mbuf_pool = NULL; - } - - /* Free session mempool */ - if (params.session_mpool != NULL) { - RTE_LOG(DEBUG, USER1, "CRYPTO_ADAPTER_SESSION_MP count %u\n", - rte_mempool_avail_count(params.session_mpool)); - rte_mempool_free(params.session_mpool); - params.session_mpool = NULL; - } - if (params.session_priv_mpool != NULL) { - rte_mempool_free(params.session_priv_mpool); - params.session_priv_mpool = NULL; - } - - /* Free ops mempool */ - if (params.op_mpool != NULL) { - RTE_LOG(DEBUG, USER1, "EVENT_CRYPTO_SYM_OP_POOL count %u\n", - rte_mempool_avail_count(params.op_mpool)); - rte_mempool_free(params.op_mpool); - params.op_mpool = NULL; - } -} - -static void -eventdev_teardown(void) -{ - rte_event_dev_stop(evdev); -} - -static void -testsuite_teardown(void) -{ - crypto_teardown(); - eventdev_teardown(); -} - -static struct unit_test_suite functional_testsuite = { - .suite_name = "Event crypto adapter test suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - - TEST_CASE_ST(NULL, test_crypto_adapter_free, - test_crypto_adapter_create), - - TEST_CASE_ST(test_crypto_adapter_create, - test_crypto_adapter_free, - test_crypto_adapter_qp_add_del), - - TEST_CASE_ST(test_crypto_adapter_create, - test_crypto_adapter_free, - test_crypto_adapter_stats), - - TEST_CASE_ST(test_crypto_adapter_conf_op_forward_mode, - test_crypto_adapter_stop, - test_session_with_op_forward_mode), - - TEST_CASE_ST(test_crypto_adapter_conf_op_forward_mode, - test_crypto_adapter_stop, - test_sessionless_with_op_forward_mode), - - TEST_CASE_ST(test_crypto_adapter_conf_op_new_mode, - test_crypto_adapter_stop, - test_session_with_op_new_mode), - - TEST_CASE_ST(test_crypto_adapter_conf_op_new_mode, - test_crypto_adapter_stop, - test_sessionless_with_op_new_mode), - - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_event_crypto_adapter(void) -{ - return unit_test_suite_runner(&functional_testsuite); -} - -REGISTER_TEST_COMMAND(event_crypto_adapter_autotest, - test_event_crypto_adapter); diff --git a/test/test/test_event_eth_rx_adapter.c b/test/test/test_event_eth_rx_adapter.c deleted file mode 100644 index 1d3be82b5a..0000000000 --- a/test/test/test_event_eth_rx_adapter.c +++ /dev/null @@ -1,714 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test.h" - -#define MAX_NUM_RX_QUEUE 64 -#define NB_MBUFS (8192 * num_ports * MAX_NUM_RX_QUEUE) -#define MBUF_CACHE_SIZE 512 -#define MBUF_PRIV_SIZE 0 -#define TEST_INST_ID 0 -#define TEST_DEV_ID 0 -#define TEST_ETHDEV_ID 0 - -struct event_eth_rx_adapter_test_params { - struct rte_mempool *mp; - uint16_t rx_rings, tx_rings; - uint32_t caps; - int rx_intr_port_inited; - uint16_t rx_intr_port; -}; - -static struct event_eth_rx_adapter_test_params default_params; - -static inline int -port_init_common(uint16_t port, const struct rte_eth_conf *port_conf, - struct rte_mempool *mp) -{ - const uint16_t rx_ring_size = 512, tx_ring_size = 512; - int retval; - uint16_t q; - struct rte_eth_dev_info dev_info; - - if (!rte_eth_dev_is_valid_port(port)) - return -1; - - retval = rte_eth_dev_configure(port, 0, 0, port_conf); - - rte_eth_dev_info_get(port, &dev_info); - - default_params.rx_rings = RTE_MIN(dev_info.max_rx_queues, - MAX_NUM_RX_QUEUE); - default_params.tx_rings = 1; - - /* Configure the Ethernet device. */ - retval = rte_eth_dev_configure(port, default_params.rx_rings, - default_params.tx_rings, port_conf); - if (retval != 0) - return retval; - - for (q = 0; q < default_params.rx_rings; q++) { - retval = rte_eth_rx_queue_setup(port, q, rx_ring_size, - rte_eth_dev_socket_id(port), NULL, mp); - if (retval < 0) - return retval; - } - - /* Allocate and set up 1 TX queue per Ethernet port. */ - for (q = 0; q < default_params.tx_rings; q++) { - retval = rte_eth_tx_queue_setup(port, q, tx_ring_size, - rte_eth_dev_socket_id(port), NULL); - if (retval < 0) - return retval; - } - - /* Start the Ethernet port. */ - retval = rte_eth_dev_start(port); - if (retval < 0) - return retval; - - /* Display the port MAC address. */ - struct ether_addr addr; - rte_eth_macaddr_get(port, &addr); - printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 - " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", - (unsigned int)port, - addr.addr_bytes[0], addr.addr_bytes[1], - addr.addr_bytes[2], addr.addr_bytes[3], - addr.addr_bytes[4], addr.addr_bytes[5]); - - /* Enable RX in promiscuous mode for the Ethernet device. */ - rte_eth_promiscuous_enable(port); - - return 0; -} - -static inline int -port_init_rx_intr(uint16_t port, struct rte_mempool *mp) -{ - static const struct rte_eth_conf port_conf_default = { - .rxmode = { - .mq_mode = ETH_MQ_RX_NONE, - }, - .intr_conf = { - .rxq = 1, - }, - }; - - return port_init_common(port, &port_conf_default, mp); -} - -static inline int -port_init(uint16_t port, struct rte_mempool *mp) -{ - static const struct rte_eth_conf port_conf_default = { - .rxmode = { - .mq_mode = ETH_MQ_RX_NONE, - }, - }; - - return port_init_common(port, &port_conf_default, mp); -} - -static int -init_port_rx_intr(int num_ports) -{ - int retval; - uint16_t portid; - int err; - - default_params.mp = rte_pktmbuf_pool_create("packet_pool", - NB_MBUFS, - MBUF_CACHE_SIZE, - MBUF_PRIV_SIZE, - RTE_MBUF_DEFAULT_BUF_SIZE, - rte_socket_id()); - if (!default_params.mp) - return -ENOMEM; - - RTE_ETH_FOREACH_DEV(portid) { - retval = port_init_rx_intr(portid, default_params.mp); - if (retval) - continue; - err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, portid, - &default_params.caps); - if (err) - continue; - if (!(default_params.caps & - RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT)) { - default_params.rx_intr_port_inited = 1; - default_params.rx_intr_port = portid; - return 0; - } - rte_eth_dev_stop(portid); - } - return 0; -} - -static int -init_ports(int num_ports) -{ - uint16_t portid; - int retval; - - struct rte_mempool *ptr = rte_mempool_lookup("packet_pool"); - - if (ptr == NULL) - default_params.mp = rte_pktmbuf_pool_create("packet_pool", - NB_MBUFS, - MBUF_CACHE_SIZE, - MBUF_PRIV_SIZE, - RTE_MBUF_DEFAULT_BUF_SIZE, - rte_socket_id()); - else - default_params.mp = ptr; - - if (!default_params.mp) - return -ENOMEM; - - RTE_ETH_FOREACH_DEV(portid) { - retval = port_init(portid, default_params.mp); - if (retval) - return retval; - } - - return 0; -} - -static int -testsuite_setup(void) -{ - int err; - uint8_t count; - struct rte_event_dev_info dev_info; - - count = rte_event_dev_count(); - if (!count) { - printf("Failed to find a valid event device," - " testing with event_skeleton device\n"); - rte_vdev_init("event_skeleton", NULL); - } - - struct rte_event_dev_config config = { - .nb_event_queues = 1, - .nb_event_ports = 1, - }; - - err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); - config.nb_event_queue_flows = dev_info.max_event_queue_flows; - config.nb_event_port_dequeue_depth = - dev_info.max_event_port_dequeue_depth; - config.nb_event_port_enqueue_depth = - dev_info.max_event_port_enqueue_depth; - config.nb_events_limit = - dev_info.max_num_events; - err = rte_event_dev_configure(TEST_DEV_ID, &config); - TEST_ASSERT(err == 0, "Event device initialization failed err %d\n", - err); - - /* - * eth devices like octeontx use event device to receive packets - * so rte_eth_dev_start invokes rte_event_dev_start internally, so - * call init_ports after rte_event_dev_configure - */ - err = init_ports(rte_eth_dev_count_total()); - TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err); - - err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID, - &default_params.caps); - TEST_ASSERT(err == 0, "Failed to get adapter cap err %d\n", - err); - - return err; -} - -static int -testsuite_setup_rx_intr(void) -{ - int err; - uint8_t count; - struct rte_event_dev_info dev_info; - - count = rte_event_dev_count(); - if (!count) { - printf("Failed to find a valid event device," - " testing with event_skeleton device\n"); - rte_vdev_init("event_skeleton", NULL); - } - - struct rte_event_dev_config config = { - .nb_event_queues = 1, - .nb_event_ports = 1, - }; - - err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); - config.nb_event_queue_flows = dev_info.max_event_queue_flows; - config.nb_event_port_dequeue_depth = - dev_info.max_event_port_dequeue_depth; - config.nb_event_port_enqueue_depth = - dev_info.max_event_port_enqueue_depth; - config.nb_events_limit = - dev_info.max_num_events; - - err = rte_event_dev_configure(TEST_DEV_ID, &config); - TEST_ASSERT(err == 0, "Event device initialization failed err %d\n", - err); - - /* - * eth devices like octeontx use event device to receive packets - * so rte_eth_dev_start invokes rte_event_dev_start internally, so - * call init_ports after rte_event_dev_configure - */ - err = init_port_rx_intr(rte_eth_dev_count_total()); - TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err); - - if (!default_params.rx_intr_port_inited) - return 0; - - err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, - default_params.rx_intr_port, - &default_params.caps); - TEST_ASSERT(err == 0, "Failed to get adapter cap err %d\n", err); - - return err; -} - -static void -testsuite_teardown(void) -{ - uint32_t i; - RTE_ETH_FOREACH_DEV(i) - rte_eth_dev_stop(i); - - rte_mempool_free(default_params.mp); -} - -static void -testsuite_teardown_rx_intr(void) -{ - if (!default_params.rx_intr_port_inited) - return; - - rte_eth_dev_stop(default_params.rx_intr_port); - rte_mempool_free(default_params.mp); -} - -static int -adapter_create(void) -{ - int err; - struct rte_event_dev_info dev_info; - struct rte_event_port_conf rx_p_conf; - - memset(&rx_p_conf, 0, sizeof(rx_p_conf)); - - err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - rx_p_conf.new_event_threshold = dev_info.max_num_events; - rx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; - rx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; - err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID, - &rx_p_conf); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - return err; -} - -static void -adapter_free(void) -{ - rte_event_eth_rx_adapter_free(TEST_INST_ID); -} - -static int -adapter_create_free(void) -{ - int err; - - struct rte_event_port_conf rx_p_conf = { - .dequeue_depth = 8, - .enqueue_depth = 8, - .new_event_threshold = 1200, - }; - - err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID, - NULL); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID, - &rx_p_conf); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_create(TEST_INST_ID, - TEST_DEV_ID, &rx_p_conf); - TEST_ASSERT(err == -EEXIST, "Expected -EEXIST %d got %d", -EEXIST, err); - - err = rte_event_eth_rx_adapter_free(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_free(TEST_INST_ID); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err); - - err = rte_event_eth_rx_adapter_free(1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err); - - return TEST_SUCCESS; -} - -static int -adapter_queue_add_del(void) -{ - int err; - struct rte_event ev; - uint32_t cap; - - struct rte_event_eth_rx_adapter_queue_conf queue_config; - - err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID, - &cap); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - ev.queue_id = 0; - ev.sched_type = RTE_SCHED_TYPE_ATOMIC; - ev.priority = 0; - - queue_config.rx_queue_flags = 0; - if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) { - ev.flow_id = 1; - queue_config.rx_queue_flags = - RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID; - } - queue_config.ev = ev; - queue_config.servicing_weight = 1; - - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - rte_eth_dev_count_total(), - -1, &queue_config); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) { - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, 0, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, 0); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, - -1, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } else { - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, - 0, - &queue_config); - TEST_ASSERT(err == -EINVAL, "Expected EINVAL got %d", err); - - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, -1, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, 0); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } - - err = rte_event_eth_rx_adapter_queue_add(1, TEST_ETHDEV_ID, -1, - &queue_config); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_rx_adapter_queue_del(1, TEST_ETHDEV_ID, -1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - return TEST_SUCCESS; -} - -static int -adapter_multi_eth_add_del(void) -{ - int err; - struct rte_event ev; - - uint16_t port_index, drv_id = 0; - char driver_name[50]; - - struct rte_event_eth_rx_adapter_queue_conf queue_config; - - ev.queue_id = 0; - ev.sched_type = RTE_SCHED_TYPE_ATOMIC; - ev.priority = 0; - - queue_config.rx_queue_flags = 0; - queue_config.ev = ev; - queue_config.servicing_weight = 1; - - /* stop eth devices for existing */ - port_index = 0; - for (; port_index < rte_eth_dev_count_total(); port_index += 1) - rte_eth_dev_stop(port_index); - - /* add the max port for rx_adapter */ - port_index = rte_eth_dev_count_total(); - for (; port_index < RTE_MAX_ETHPORTS; port_index += 1) { - sprintf(driver_name, "%s%u", "net_null", drv_id); - err = rte_vdev_init(driver_name, NULL); - TEST_ASSERT(err == 0, "Failed driver %s got %d", - driver_name, err); - drv_id += 1; - } - - err = init_ports(rte_eth_dev_count_total()); - TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err); - - /* eth_rx_adapter_queue_add for n ports */ - port_index = 0; - for (; port_index < rte_eth_dev_count_total(); port_index += 1) { - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - port_index, -1, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } - - /* eth_rx_adapter_queue_del n ports */ - port_index = 0; - for (; port_index < rte_eth_dev_count_total(); port_index += 1) { - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - port_index, -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } - - return TEST_SUCCESS; -} - -static int -adapter_intr_queue_add_del(void) -{ - int err; - struct rte_event ev; - uint32_t cap; - uint16_t eth_port; - struct rte_event_eth_rx_adapter_queue_conf queue_config; - - if (!default_params.rx_intr_port_inited) - return 0; - - eth_port = default_params.rx_intr_port; - err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, eth_port, &cap); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - ev.queue_id = 0; - ev.sched_type = RTE_SCHED_TYPE_ATOMIC; - ev.priority = 0; - - queue_config.rx_queue_flags = 0; - queue_config.ev = ev; - - /* weight = 0 => interrupt mode */ - queue_config.servicing_weight = 0; - - if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) { - /* add queue 0 */ - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, 0, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } - - /* add all queues */ - queue_config.servicing_weight = 0; - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, - -1, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) { - /* del queue 0 */ - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, - 0); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } - - /* del remaining queues */ - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - /* add all queues */ - queue_config.servicing_weight = 0; - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, - -1, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - /* intr -> poll mode queue */ - queue_config.servicing_weight = 1; - - if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) { - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, - 0, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } - - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, - -1, - &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - /* del queues */ - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - return TEST_SUCCESS; -} - -static int -adapter_start_stop(void) -{ - int err; - struct rte_event ev; - - ev.queue_id = 0; - ev.sched_type = RTE_SCHED_TYPE_ATOMIC; - ev.priority = 0; - - struct rte_event_eth_rx_adapter_queue_conf queue_config; - - queue_config.rx_queue_flags = 0; - if (default_params.caps & - RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) { - ev.flow_id = 1; - queue_config.rx_queue_flags = - RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID; - } - - queue_config.ev = ev; - queue_config.servicing_weight = 1; - - err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, TEST_ETHDEV_ID, - -1, &queue_config); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_start(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_stop(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_start(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_stop(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_start(1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_rx_adapter_stop(1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - return TEST_SUCCESS; -} - -static int -adapter_stats(void) -{ - int err; - struct rte_event_eth_rx_adapter_stats stats; - - err = rte_event_eth_rx_adapter_stats_get(TEST_INST_ID, NULL); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_rx_adapter_stats_get(TEST_INST_ID, &stats); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_rx_adapter_stats_get(1, &stats); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - return TEST_SUCCESS; -} - -static struct unit_test_suite event_eth_rx_tests = { - .suite_name = "rx event eth adapter test suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(NULL, NULL, adapter_create_free), - TEST_CASE_ST(adapter_create, adapter_free, - adapter_queue_add_del), - TEST_CASE_ST(adapter_create, adapter_free, - adapter_multi_eth_add_del), - TEST_CASE_ST(adapter_create, adapter_free, adapter_start_stop), - TEST_CASE_ST(adapter_create, adapter_free, adapter_stats), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static struct unit_test_suite event_eth_rx_intr_tests = { - .suite_name = "rx event eth adapter test suite", - .setup = testsuite_setup_rx_intr, - .teardown = testsuite_teardown_rx_intr, - .unit_test_cases = { - TEST_CASE_ST(adapter_create, adapter_free, - adapter_intr_queue_add_del), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_event_eth_rx_adapter_common(void) -{ - return unit_test_suite_runner(&event_eth_rx_tests); -} - -static int -test_event_eth_rx_intr_adapter_common(void) -{ - return unit_test_suite_runner(&event_eth_rx_intr_tests); -} - -REGISTER_TEST_COMMAND(event_eth_rx_adapter_autotest, - test_event_eth_rx_adapter_common); -REGISTER_TEST_COMMAND(event_eth_rx_intr_adapter_autotest, - test_event_eth_rx_intr_adapter_common); diff --git a/test/test/test_event_eth_tx_adapter.c b/test/test/test_event_eth_tx_adapter.c deleted file mode 100644 index c26c5152c2..0000000000 --- a/test/test/test_event_eth_tx_adapter.c +++ /dev/null @@ -1,699 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define MAX_NUM_QUEUE RTE_PMD_RING_MAX_RX_RINGS -#define TEST_INST_ID 0 -#define TEST_DEV_ID 0 -#define SOCKET0 0 -#define RING_SIZE 256 -#define ETH_NAME_LEN 32 -#define NUM_ETH_PAIR 1 -#define NUM_ETH_DEV (2 * NUM_ETH_PAIR) -#define NB_MBUF 512 -#define PAIR_PORT_INDEX(p) ((p) + NUM_ETH_PAIR) -#define PORT(p) default_params.port[(p)] -#define TEST_ETHDEV_ID PORT(0) -#define TEST_ETHDEV_PAIR_ID PORT(PAIR_PORT_INDEX(0)) - -#define EDEV_RETRY 0xffff - -struct event_eth_tx_adapter_test_params { - struct rte_mempool *mp; - uint16_t rx_rings, tx_rings; - struct rte_ring *r[NUM_ETH_DEV][MAX_NUM_QUEUE]; - int port[NUM_ETH_DEV]; -}; - -static int event_dev_delete; -static struct event_eth_tx_adapter_test_params default_params; -static uint64_t eid = ~0ULL; -static uint32_t tid; - -static inline int -port_init_common(uint8_t port, const struct rte_eth_conf *port_conf, - struct rte_mempool *mp) -{ - const uint16_t rx_ring_size = RING_SIZE, tx_ring_size = RING_SIZE; - int retval; - uint16_t q; - - if (!rte_eth_dev_is_valid_port(port)) - return -1; - - default_params.rx_rings = MAX_NUM_QUEUE; - default_params.tx_rings = MAX_NUM_QUEUE; - - /* Configure the Ethernet device. */ - retval = rte_eth_dev_configure(port, default_params.rx_rings, - default_params.tx_rings, port_conf); - if (retval != 0) - return retval; - - for (q = 0; q < default_params.rx_rings; q++) { - retval = rte_eth_rx_queue_setup(port, q, rx_ring_size, - rte_eth_dev_socket_id(port), NULL, mp); - if (retval < 0) - return retval; - } - - for (q = 0; q < default_params.tx_rings; q++) { - retval = rte_eth_tx_queue_setup(port, q, tx_ring_size, - rte_eth_dev_socket_id(port), NULL); - if (retval < 0) - return retval; - } - - /* Start the Ethernet port. */ - retval = rte_eth_dev_start(port); - if (retval < 0) - return retval; - - /* Display the port MAC address. */ - struct ether_addr addr; - rte_eth_macaddr_get(port, &addr); - printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 - " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", - (unsigned int)port, - addr.addr_bytes[0], addr.addr_bytes[1], - addr.addr_bytes[2], addr.addr_bytes[3], - addr.addr_bytes[4], addr.addr_bytes[5]); - - /* Enable RX in promiscuous mode for the Ethernet device. */ - rte_eth_promiscuous_enable(port); - - return 0; -} - -static inline int -port_init(uint8_t port, struct rte_mempool *mp) -{ - struct rte_eth_conf conf = { 0 }; - return port_init_common(port, &conf, mp); -} - -#define RING_NAME_LEN 20 -#define DEV_NAME_LEN 20 - -static int -init_ports(void) -{ - char ring_name[ETH_NAME_LEN]; - unsigned int i, j; - struct rte_ring * const *c1; - struct rte_ring * const *c2; - int err; - - if (!default_params.mp) - default_params.mp = rte_pktmbuf_pool_create("mbuf_pool", - NB_MBUF, 32, - 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - - if (!default_params.mp) - return -ENOMEM; - - for (i = 0; i < NUM_ETH_DEV; i++) { - for (j = 0; j < MAX_NUM_QUEUE; j++) { - snprintf(ring_name, sizeof(ring_name), "R%u%u", i, j); - default_params.r[i][j] = rte_ring_create(ring_name, - RING_SIZE, - SOCKET0, - RING_F_SP_ENQ | RING_F_SC_DEQ); - TEST_ASSERT((default_params.r[i][j] != NULL), - "Failed to allocate ring"); - } - } - - /* - * To create two pseudo-Ethernet ports where the traffic is - * switched between them, that is, traffic sent to port 1 is - * read back from port 2 and vice-versa - */ - for (i = 0; i < NUM_ETH_PAIR; i++) { - char dev_name[DEV_NAME_LEN]; - int p; - - c1 = default_params.r[i]; - c2 = default_params.r[PAIR_PORT_INDEX(i)]; - - snprintf(dev_name, DEV_NAME_LEN, "%u-%u", i, i + NUM_ETH_PAIR); - p = rte_eth_from_rings(dev_name, c1, MAX_NUM_QUEUE, - c2, MAX_NUM_QUEUE, SOCKET0); - TEST_ASSERT(p >= 0, "Port creation failed %s", dev_name); - err = port_init(p, default_params.mp); - TEST_ASSERT(err == 0, "Port init failed %s", dev_name); - default_params.port[i] = p; - - snprintf(dev_name, DEV_NAME_LEN, "%u-%u", i + NUM_ETH_PAIR, i); - p = rte_eth_from_rings(dev_name, c2, MAX_NUM_QUEUE, - c1, MAX_NUM_QUEUE, SOCKET0); - TEST_ASSERT(p > 0, "Port creation failed %s", dev_name); - err = port_init(p, default_params.mp); - TEST_ASSERT(err == 0, "Port init failed %s", dev_name); - default_params.port[PAIR_PORT_INDEX(i)] = p; - } - - return 0; -} - -static void -deinit_ports(void) -{ - uint16_t i, j; - char name[ETH_NAME_LEN]; - - for (i = 0; i < RTE_DIM(default_params.port); i++) { - rte_eth_dev_stop(default_params.port[i]); - rte_eth_dev_get_name_by_port(default_params.port[i], name); - rte_vdev_uninit(name); - for (j = 0; j < RTE_DIM(default_params.r[i]); j++) - rte_ring_free(default_params.r[i][j]); - } -} - -static int -testsuite_setup(void) -{ - const char *vdev_name = "event_sw0"; - - int err = init_ports(); - TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err); - - if (rte_event_dev_count() == 0) { - printf("Failed to find a valid event device," - " testing with event_sw0 device\n"); - err = rte_vdev_init(vdev_name, NULL); - TEST_ASSERT(err == 0, "vdev %s creation failed %d\n", - vdev_name, err); - event_dev_delete = 1; - } - return err; -} - -#define DEVICE_ID_SIZE 64 - -static void -testsuite_teardown(void) -{ - deinit_ports(); - rte_mempool_free(default_params.mp); - default_params.mp = NULL; - if (event_dev_delete) - rte_vdev_uninit("event_sw0"); -} - -static int -tx_adapter_create(void) -{ - int err; - struct rte_event_dev_info dev_info; - struct rte_event_port_conf tx_p_conf; - uint8_t priority; - uint8_t queue_id; - - struct rte_event_dev_config config = { - .nb_event_queues = 1, - .nb_event_ports = 1, - }; - - struct rte_event_queue_conf wkr_q_conf = { - .schedule_type = RTE_SCHED_TYPE_ORDERED, - .priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .nb_atomic_flows = 1024, - .nb_atomic_order_sequences = 1024, - }; - - memset(&tx_p_conf, 0, sizeof(tx_p_conf)); - err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); - config.nb_event_queue_flows = dev_info.max_event_queue_flows; - config.nb_event_port_dequeue_depth = - dev_info.max_event_port_dequeue_depth; - config.nb_event_port_enqueue_depth = - dev_info.max_event_port_enqueue_depth; - config.nb_events_limit = - dev_info.max_num_events; - - err = rte_event_dev_configure(TEST_DEV_ID, &config); - TEST_ASSERT(err == 0, "Event device initialization failed err %d\n", - err); - - queue_id = 0; - err = rte_event_queue_setup(TEST_DEV_ID, 0, &wkr_q_conf); - TEST_ASSERT(err == 0, "Event queue setup failed %d\n", err); - - err = rte_event_port_setup(TEST_DEV_ID, 0, NULL); - TEST_ASSERT(err == 0, "Event port setup failed %d\n", err); - - priority = RTE_EVENT_DEV_PRIORITY_LOWEST; - err = rte_event_port_link(TEST_DEV_ID, 0, &queue_id, &priority, 1); - TEST_ASSERT(err == 1, "Error linking port %s\n", - rte_strerror(rte_errno)); - err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - tx_p_conf.new_event_threshold = dev_info.max_num_events; - tx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; - tx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; - err = rte_event_eth_tx_adapter_create(TEST_INST_ID, TEST_DEV_ID, - &tx_p_conf); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - return err; -} - -static void -tx_adapter_free(void) -{ - rte_event_eth_tx_adapter_free(TEST_INST_ID); -} - -static int -tx_adapter_create_free(void) -{ - int err; - struct rte_event_dev_info dev_info; - struct rte_event_port_conf tx_p_conf; - - err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - tx_p_conf.new_event_threshold = dev_info.max_num_events; - tx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; - tx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; - - err = rte_event_eth_tx_adapter_create(TEST_INST_ID, TEST_DEV_ID, - NULL); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_tx_adapter_create(TEST_INST_ID, TEST_DEV_ID, - &tx_p_conf); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_create(TEST_INST_ID, - TEST_DEV_ID, &tx_p_conf); - TEST_ASSERT(err == -EEXIST, "Expected -EEXIST %d got %d", -EEXIST, err); - - err = rte_event_eth_tx_adapter_free(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_free(TEST_INST_ID); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err); - - err = rte_event_eth_tx_adapter_free(1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err); - - return TEST_SUCCESS; -} - -static int -tx_adapter_queue_add_del(void) -{ - int err; - uint32_t cap; - - err = rte_event_eth_tx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID, - &cap); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - - err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, - rte_eth_dev_count_total(), - -1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, - 0); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, - TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, - 0); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, - TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_queue_add(1, TEST_ETHDEV_ID, -1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_tx_adapter_queue_del(1, TEST_ETHDEV_ID, -1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - return TEST_SUCCESS; -} - -static int -tx_adapter_start_stop(void) -{ - int err; - - err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_start(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_stop(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_start(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_stop(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_start(1); - - err = rte_event_eth_tx_adapter_stop(1); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - return TEST_SUCCESS; -} - - -static int -tx_adapter_single(uint16_t port, uint16_t tx_queue_id, - struct rte_mbuf *m, uint8_t qid, - uint8_t sched_type) -{ - struct rte_event event; - struct rte_mbuf *r; - int ret; - unsigned int l; - - event.queue_id = qid; - event.op = RTE_EVENT_OP_NEW; - event.event_type = RTE_EVENT_TYPE_CPU; - event.sched_type = sched_type; - event.mbuf = m; - - m->port = port; - rte_event_eth_tx_adapter_txq_set(m, tx_queue_id); - - l = 0; - while (rte_event_enqueue_burst(TEST_DEV_ID, 0, &event, 1) != 1) { - l++; - if (l > EDEV_RETRY) - break; - } - - TEST_ASSERT(l < EDEV_RETRY, "Unable to enqueue to eventdev"); - l = 0; - while (l++ < EDEV_RETRY) { - - if (eid != ~0ULL) { - ret = rte_service_run_iter_on_app_lcore(eid, 0); - TEST_ASSERT(ret == 0, "failed to run service %d", ret); - } - - ret = rte_service_run_iter_on_app_lcore(tid, 0); - TEST_ASSERT(ret == 0, "failed to run service %d", ret); - - if (rte_eth_rx_burst(TEST_ETHDEV_PAIR_ID, tx_queue_id, - &r, 1)) { - TEST_ASSERT_EQUAL(r, m, "mbuf comparison failed" - " expected %p received %p", m, r); - return 0; - } - } - - TEST_ASSERT(0, "Failed to receive packet"); - return -1; -} - -static int -tx_adapter_service(void) -{ - struct rte_event_eth_tx_adapter_stats stats; - uint32_t i; - int err; - uint8_t ev_port, ev_qid; - struct rte_mbuf bufs[RING_SIZE]; - struct rte_mbuf *pbufs[RING_SIZE]; - struct rte_event_dev_info dev_info; - struct rte_event_dev_config dev_conf; - struct rte_event_queue_conf qconf; - uint32_t qcnt, pcnt; - uint16_t q; - int internal_port; - uint32_t cap; - - memset(&dev_conf, 0, sizeof(dev_conf)); - err = rte_event_eth_tx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID, - &cap); - TEST_ASSERT(err == 0, "Failed to get adapter cap err %d\n", err); - - internal_port = !!(cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT); - if (internal_port) - return TEST_SUCCESS; - - err = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_event_port_get(TEST_INST_ID, - &ev_port); - TEST_ASSERT_SUCCESS(err, "Failed to get event port %d", err); - - err = rte_event_dev_attr_get(TEST_DEV_ID, RTE_EVENT_DEV_ATTR_PORT_COUNT, - &pcnt); - TEST_ASSERT_SUCCESS(err, "Port count get failed"); - - err = rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &qcnt); - TEST_ASSERT_SUCCESS(err, "Queue count get failed"); - - err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info); - TEST_ASSERT_SUCCESS(err, "Dev info failed"); - - dev_conf.nb_event_queue_flows = dev_info.max_event_queue_flows; - dev_conf.nb_event_port_dequeue_depth = - dev_info.max_event_port_dequeue_depth; - dev_conf.nb_event_port_enqueue_depth = - dev_info.max_event_port_enqueue_depth; - dev_conf.nb_events_limit = - dev_info.max_num_events; - dev_conf.nb_event_queues = qcnt + 1; - dev_conf.nb_event_ports = pcnt; - err = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); - TEST_ASSERT(err == 0, "Event device initialization failed err %d\n", - err); - - ev_qid = qcnt; - qconf.nb_atomic_flows = dev_info.max_event_queue_flows; - qconf.nb_atomic_order_sequences = 32; - qconf.schedule_type = RTE_SCHED_TYPE_ATOMIC; - qconf.priority = RTE_EVENT_DEV_PRIORITY_HIGHEST; - qconf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK; - err = rte_event_queue_setup(TEST_DEV_ID, ev_qid, &qconf); - TEST_ASSERT_SUCCESS(err, "Failed to setup queue %u", ev_qid); - - /* - * Setup ports again so that the newly added queue is visible - * to them - */ - for (i = 0; i < pcnt; i++) { - - int n_links; - uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; - uint8_t priorities[RTE_EVENT_MAX_QUEUES_PER_DEV]; - - if (i == ev_port) - continue; - - n_links = rte_event_port_links_get(TEST_DEV_ID, i, queues, - priorities); - TEST_ASSERT(n_links > 0, "Failed to get port links %d\n", - n_links); - err = rte_event_port_setup(TEST_DEV_ID, i, NULL); - TEST_ASSERT(err == 0, "Failed to setup port err %d\n", err); - err = rte_event_port_link(TEST_DEV_ID, i, queues, priorities, - n_links); - TEST_ASSERT(n_links == err, "Failed to link all queues" - " err %s\n", rte_strerror(rte_errno)); - } - - err = rte_event_port_link(TEST_DEV_ID, ev_port, &ev_qid, NULL, 1); - TEST_ASSERT(err == 1, "Failed to link queue port %u", - ev_port); - - err = rte_event_eth_tx_adapter_start(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - if (!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED)) { - err = rte_event_dev_service_id_get(0, (uint32_t *)&eid); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_service_runstate_set(eid, 1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_service_set_runstate_mapped_check(eid, 0); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } - - err = rte_event_eth_tx_adapter_service_id_get(TEST_INST_ID, &tid); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_service_runstate_set(tid, 1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_service_set_runstate_mapped_check(tid, 0); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_dev_start(TEST_DEV_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - for (q = 0; q < MAX_NUM_QUEUE; q++) { - for (i = 0; i < RING_SIZE; i++) - pbufs[i] = &bufs[i]; - for (i = 0; i < RING_SIZE; i++) { - pbufs[i] = &bufs[i]; - err = tx_adapter_single(TEST_ETHDEV_ID, q, pbufs[i], - ev_qid, - RTE_SCHED_TYPE_ORDERED); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - } - for (i = 0; i < RING_SIZE; i++) { - TEST_ASSERT_EQUAL(pbufs[i], &bufs[i], - "Error: received data does not match" - " that transmitted"); - } - } - - err = rte_event_eth_tx_adapter_stats_get(TEST_INST_ID, NULL); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_tx_adapter_stats_get(TEST_INST_ID, &stats); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - TEST_ASSERT_EQUAL(stats.tx_packets, MAX_NUM_QUEUE * RING_SIZE, - "stats.tx_packets expected %u got %"PRIu64, - MAX_NUM_QUEUE * RING_SIZE, - stats.tx_packets); - - err = rte_event_eth_tx_adapter_stats_reset(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_stats_get(TEST_INST_ID, &stats); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - TEST_ASSERT_EQUAL(stats.tx_packets, 0, - "stats.tx_packets expected %u got %"PRIu64, - 0, - stats.tx_packets); - - err = rte_event_eth_tx_adapter_stats_get(1, &stats); - TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err); - - err = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, TEST_ETHDEV_ID, - -1); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - err = rte_event_eth_tx_adapter_free(TEST_INST_ID); - TEST_ASSERT(err == 0, "Expected 0 got %d", err); - - rte_event_dev_stop(TEST_DEV_ID); - - return TEST_SUCCESS; -} - -static int -tx_adapter_dynamic_device(void) -{ - uint16_t port_id = rte_eth_dev_count_avail(); - const char *null_dev[2] = { "eth_null0", "eth_null1" }; - struct rte_eth_conf dev_conf; - int ret; - size_t i; - - memset(&dev_conf, 0, sizeof(dev_conf)); - for (i = 0; i < RTE_DIM(null_dev); i++) { - ret = rte_vdev_init(null_dev[i], NULL); - TEST_ASSERT_SUCCESS(ret, "%s Port creation failed %d", - null_dev[i], ret); - - if (i == 0) { - ret = tx_adapter_create(); - TEST_ASSERT_SUCCESS(ret, "Adapter create failed %d", - ret); - } - - ret = rte_eth_dev_configure(port_id + i, MAX_NUM_QUEUE, - MAX_NUM_QUEUE, &dev_conf); - TEST_ASSERT_SUCCESS(ret, "Failed to configure device %d", ret); - - ret = rte_event_eth_tx_adapter_queue_add(TEST_INST_ID, - port_id + i, 0); - TEST_ASSERT_SUCCESS(ret, "Failed to add queues %d", ret); - - } - - for (i = 0; i < RTE_DIM(null_dev); i++) { - ret = rte_event_eth_tx_adapter_queue_del(TEST_INST_ID, - port_id + i, -1); - TEST_ASSERT_SUCCESS(ret, "Failed to delete queues %d", ret); - } - - tx_adapter_free(); - - for (i = 0; i < RTE_DIM(null_dev); i++) - rte_vdev_uninit(null_dev[i]); - - return TEST_SUCCESS; -} - -static struct unit_test_suite event_eth_tx_tests = { - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .suite_name = "tx event eth adapter test suite", - .unit_test_cases = { - TEST_CASE_ST(NULL, NULL, tx_adapter_create_free), - TEST_CASE_ST(tx_adapter_create, tx_adapter_free, - tx_adapter_queue_add_del), - TEST_CASE_ST(tx_adapter_create, tx_adapter_free, - tx_adapter_start_stop), - TEST_CASE_ST(tx_adapter_create, tx_adapter_free, - tx_adapter_service), - TEST_CASE_ST(NULL, NULL, tx_adapter_dynamic_device), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_event_eth_tx_adapter_common(void) -{ - return unit_test_suite_runner(&event_eth_tx_tests); -} - -REGISTER_TEST_COMMAND(event_eth_tx_adapter_autotest, - test_event_eth_tx_adapter_common); diff --git a/test/test/test_event_ring.c b/test/test/test_event_ring.c deleted file mode 100644 index 70eb9845e1..0000000000 --- a/test/test/test_event_ring.c +++ /dev/null @@ -1,247 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2017 Intel Corporation - */ - -#include - -#include - -#include "test.h" - -/* - * Event Ring - * =========== - * - * Test some basic ops for the event rings. - * Does not fully test everything, since most code is reused from rte_ring - * library and tested as part of the normal ring autotests. - */ - -#define RING_SIZE 4096 -#define MAX_BULK 32 - -static struct rte_event_ring *r; - -/* - * ensure failure to create ring with a bad ring size - */ -static int -test_event_ring_creation_with_wrong_size(void) -{ - struct rte_event_ring *rp = NULL; - - /* Test if ring size is not power of 2 */ - rp = rte_event_ring_create("test_bad_ring_size", RING_SIZE + 1, - SOCKET_ID_ANY, 0); - if (rp != NULL) - return -1; - - /* Test if ring size is exceeding the limit */ - rp = rte_event_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), - SOCKET_ID_ANY, 0); - if (rp != NULL) - return -1; - return 0; -} - -/* - * Test to check if a non-power-of-2 count causes the create - * function to fail correctly - */ -static int -test_create_count_odd(void) -{ - struct rte_event_ring *r = rte_event_ring_create("test_event_ring_count", - 4097, SOCKET_ID_ANY, 0); - if (r != NULL) - return -1; - return 0; -} - -static int -test_lookup_null(void) -{ - struct rte_event_ring *rlp = rte_event_ring_lookup("ring_not_found"); - if (rlp == NULL && rte_errno != ENOENT) { - printf("test failed to return error on null pointer\n"); - return -1; - } - return 0; -} - -static int -test_basic_event_enqueue_dequeue(void) -{ - struct rte_event_ring *sr = NULL; - struct rte_event evs[16]; - uint16_t ret, free_count, used_count; - - memset(evs, 0, sizeof(evs)); - sr = rte_event_ring_create("spsc_ring", 32, rte_socket_id(), - RING_F_SP_ENQ | RING_F_SC_DEQ); - if (sr == NULL) { - printf("Failed to create sp/sc ring\n"); - return -1; - } - if (rte_event_ring_get_capacity(sr) != 31) { - printf("Error, invalid capacity\n"); - goto error; - } - - /* test sp/sc ring */ - if (rte_event_ring_count(sr) != 0) { - printf("Error, ring not empty as expected\n"); - goto error; - } - if (rte_event_ring_free_count(sr) != rte_event_ring_get_capacity(sr)) { - printf("Error, ring free count not as expected\n"); - goto error; - } - - ret = rte_event_ring_enqueue_burst(sr, evs, RTE_DIM(evs), &free_count); - if (ret != RTE_DIM(evs) || - free_count != rte_event_ring_get_capacity(sr) - ret) { - printf("Error, status after enqueue is unexpected\n"); - goto error; - } - - ret = rte_event_ring_enqueue_burst(sr, evs, RTE_DIM(evs), &free_count); - if (ret != RTE_DIM(evs) - 1 || - free_count != 0) { - printf("Error, status after enqueue is unexpected\n"); - goto error; - } - - ret = rte_event_ring_dequeue_burst(sr, evs, RTE_DIM(evs), &used_count); - if (ret != RTE_DIM(evs) || - used_count != rte_event_ring_get_capacity(sr) - ret) { - printf("Error, status after enqueue is unexpected\n"); - goto error; - } - ret = rte_event_ring_dequeue_burst(sr, evs, RTE_DIM(evs), &used_count); - if (ret != RTE_DIM(evs) - 1 || - used_count != 0) { - printf("Error, status after enqueue is unexpected\n"); - goto error; - } - - rte_event_ring_free(sr); - return 0; -error: - rte_event_ring_free(sr); - return -1; -} - -static int -test_event_ring_with_exact_size(void) -{ - struct rte_event_ring *std_ring, *exact_sz_ring; - struct rte_event ev = { .mbuf = NULL }; - struct rte_event ev_array[16]; - static const unsigned int ring_sz = RTE_DIM(ev_array); - unsigned int i; - - std_ring = rte_event_ring_create("std", ring_sz, rte_socket_id(), - RING_F_SP_ENQ | RING_F_SC_DEQ); - if (std_ring == NULL) { - printf("%s: error, can't create std ring\n", __func__); - return -1; - } - exact_sz_ring = rte_event_ring_create("exact sz", - ring_sz, rte_socket_id(), - RING_F_SP_ENQ | RING_F_SC_DEQ | RING_F_EXACT_SZ); - if (exact_sz_ring == NULL) { - printf("%s: error, can't create exact size ring\n", __func__); - return -1; - } - - /* - * Check that the exact size ring is bigger than the standard ring - */ - if (rte_event_ring_get_size(std_ring) >= - rte_event_ring_get_size(exact_sz_ring)) { - printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n", - __func__, - rte_event_ring_get_size(std_ring), - rte_event_ring_get_size(exact_sz_ring)); - return -1; - } - /* - * check that the exact_sz_ring can hold one more element than the - * standard ring. (16 vs 15 elements) - */ - for (i = 0; i < ring_sz - 1; i++) { - rte_event_ring_enqueue_burst(std_ring, &ev, 1, NULL); - rte_event_ring_enqueue_burst(exact_sz_ring, &ev, 1, NULL); - } - if (rte_event_ring_enqueue_burst(std_ring, &ev, 1, NULL) != 0) { - printf("%s: error, unexpected successful enqueue\n", __func__); - return -1; - } - if (rte_event_ring_enqueue_burst(exact_sz_ring, &ev, 1, NULL) != 1) { - printf("%s: error, enqueue failed\n", __func__); - return -1; - } - - /* check that dequeue returns the expected number of elements */ - if (rte_event_ring_dequeue_burst(exact_sz_ring, ev_array, - RTE_DIM(ev_array), NULL) != ring_sz) { - printf("%s: error, failed to dequeue expected nb of elements\n", - __func__); - return -1; - } - - /* check that the capacity function returns expected value */ - if (rte_event_ring_get_capacity(exact_sz_ring) != ring_sz) { - printf("%s: error, incorrect ring capacity reported\n", - __func__); - return -1; - } - - rte_event_ring_free(std_ring); - rte_event_ring_free(exact_sz_ring); - return 0; -} - -static int -test_event_ring(void) -{ - if (r == NULL) - r = rte_event_ring_create("ev_test", RING_SIZE, - SOCKET_ID_ANY, 0); - if (r == NULL) - return -1; - - /* retrieve the ring from its name */ - if (rte_event_ring_lookup("ev_test") != r) { - printf("Cannot lookup ring from its name\n"); - return -1; - } - - /* basic operations */ - if (test_create_count_odd() < 0) { - printf("Test failed to detect odd count\n"); - return -1; - } - printf("Test detected odd count\n"); - - if (test_lookup_null() < 0) { - printf("Test failed to detect NULL ring lookup\n"); - return -1; - } - printf("Test detected NULL ring lookup\n"); - - /* test of creating ring with wrong size */ - if (test_event_ring_creation_with_wrong_size() < 0) - return -1; - - if (test_basic_event_enqueue_dequeue() < 0) - return -1; - - if (test_event_ring_with_exact_size() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(event_ring_autotest, test_event_ring); diff --git a/test/test/test_event_timer_adapter.c b/test/test/test_event_timer_adapter.c deleted file mode 100644 index a45b7d1957..0000000000 --- a/test/test/test_event_timer_adapter.c +++ /dev/null @@ -1,1830 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Cavium, Inc - * Copyright(c) 2017-2018 Intel Corporation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* 4K timers corresponds to sw evdev max inflight events */ -#define MAX_TIMERS (4 * 1024) -#define BKT_TCK_NSEC - -#define NSECPERSEC 1E9 -#define BATCH_SIZE 16 -/* Both the app lcore and adapter ports are linked to this queue */ -#define TEST_QUEUE_ID 0 -/* Port the application dequeues from */ -#define TEST_PORT_ID 0 -#define TEST_ADAPTER_ID 0 - -/* Handle log statements in same manner as test macros */ -#define LOG_DBG(...) RTE_LOG(DEBUG, EAL, __VA_ARGS__) - -static int evdev; -static struct rte_event_timer_adapter *timdev; -static struct rte_mempool *eventdev_test_mempool; -static struct rte_ring *timer_producer_ring; -static uint64_t global_bkt_tck_ns; -static volatile uint8_t arm_done; - -static bool using_services; -static uint32_t test_lcore1; -static uint32_t test_lcore2; -static uint32_t test_lcore3; -static uint32_t sw_evdev_slcore; -static uint32_t sw_adptr_slcore; - -static inline void -devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - memset(dev_conf, 0, sizeof(struct rte_event_dev_config)); - dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns; - dev_conf->nb_event_ports = 1; - dev_conf->nb_event_queues = 1; - dev_conf->nb_event_queue_flows = info->max_event_queue_flows; - dev_conf->nb_event_port_dequeue_depth = - info->max_event_port_dequeue_depth; - dev_conf->nb_event_port_enqueue_depth = - info->max_event_port_enqueue_depth; - dev_conf->nb_event_port_enqueue_depth = - info->max_event_port_enqueue_depth; - dev_conf->nb_events_limit = - info->max_num_events; -} - -static inline int -eventdev_setup(void) -{ - int ret; - struct rte_event_dev_config dev_conf; - struct rte_event_dev_info info; - uint32_t service_id; - - ret = rte_event_dev_info_get(evdev, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - TEST_ASSERT(info.max_num_events >= (int32_t)MAX_TIMERS, - "ERROR max_num_events=%d < max_events=%d", - info.max_num_events, MAX_TIMERS); - - devconf_set_default_sane_values(&dev_conf, &info); - ret = rte_event_dev_configure(evdev, &dev_conf); - TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); - - ret = rte_event_queue_setup(evdev, 0, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%d", 0); - - /* Configure event port */ - ret = rte_event_port_setup(evdev, 0, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port=%d", 0); - ret = rte_event_port_link(evdev, 0, NULL, NULL, 0); - TEST_ASSERT(ret >= 0, "Failed to link all queues port=%d", 0); - - /* If this is a software event device, map and start its service */ - if (rte_event_dev_service_id_get(evdev, &service_id) == 0) { - TEST_ASSERT_SUCCESS(rte_service_lcore_add(sw_evdev_slcore), - "Failed to add service core"); - TEST_ASSERT_SUCCESS(rte_service_lcore_start( - sw_evdev_slcore), - "Failed to start service core"); - TEST_ASSERT_SUCCESS(rte_service_map_lcore_set( - service_id, sw_evdev_slcore, 1), - "Failed to map evdev service"); - TEST_ASSERT_SUCCESS(rte_service_runstate_set( - service_id, 1), - "Failed to start evdev service"); - } - - ret = rte_event_dev_start(evdev); - TEST_ASSERT_SUCCESS(ret, "Failed to start device"); - - return TEST_SUCCESS; -} - -static int -testsuite_setup(void) -{ - /* Some of the multithreaded tests require 3 other lcores to run */ - unsigned int required_lcore_count = 4; - uint32_t service_id; - - /* To make it easier to map services later if needed, just reset - * service core state. - */ - (void) rte_service_lcore_reset_all(); - - if (!rte_event_dev_count()) { - /* If there is no hardware eventdev, or no software vdev was - * specified on the command line, create an instance of - * event_sw. - */ - LOG_DBG("Failed to find a valid event device... testing with" - " event_sw device\n"); - TEST_ASSERT_SUCCESS(rte_vdev_init("event_sw0", NULL), - "Error creating eventdev"); - evdev = rte_event_dev_get_dev_id("event_sw0"); - } - - if (rte_event_dev_service_id_get(evdev, &service_id) == 0) { - /* A software event device will use a software event timer - * adapter as well. 2 more cores required to convert to - * service cores. - */ - required_lcore_count += 2; - using_services = true; - } - - if (rte_lcore_count() < required_lcore_count) { - printf("%d lcores needed to run tests", required_lcore_count); - return TEST_FAILED; - } - - /* Assign lcores for various tasks */ - test_lcore1 = rte_get_next_lcore(-1, 1, 0); - test_lcore2 = rte_get_next_lcore(test_lcore1, 1, 0); - test_lcore3 = rte_get_next_lcore(test_lcore2, 1, 0); - if (using_services) { - sw_evdev_slcore = rte_get_next_lcore(test_lcore3, 1, 0); - sw_adptr_slcore = rte_get_next_lcore(sw_evdev_slcore, 1, 0); - } - - return eventdev_setup(); -} - -static void -testsuite_teardown(void) -{ - rte_event_dev_stop(evdev); - rte_event_dev_close(evdev); -} - -static int -setup_adapter_service(struct rte_event_timer_adapter *adptr) -{ - uint32_t adapter_service_id; - int ret; - - /* retrieve service ids */ - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_service_id_get(adptr, - &adapter_service_id), "Failed to get event timer " - "adapter service id"); - /* add a service core and start it */ - ret = rte_service_lcore_add(sw_adptr_slcore); - TEST_ASSERT(ret == 0 || ret == -EALREADY, - "Failed to add service core"); - ret = rte_service_lcore_start(sw_adptr_slcore); - TEST_ASSERT(ret == 0 || ret == -EALREADY, - "Failed to start service core"); - - /* map services to it */ - TEST_ASSERT_SUCCESS(rte_service_map_lcore_set(adapter_service_id, - sw_adptr_slcore, 1), - "Failed to map adapter service"); - - /* set services to running */ - TEST_ASSERT_SUCCESS(rte_service_runstate_set(adapter_service_id, 1), - "Failed to start event timer adapter service"); - - return TEST_SUCCESS; -} - -static int -test_port_conf_cb(uint16_t id, uint8_t event_dev_id, uint8_t *event_port_id, - void *conf_arg) -{ - struct rte_event_dev_config dev_conf; - struct rte_event_dev_info info; - struct rte_event_port_conf *port_conf, def_port_conf = {0}; - uint32_t started; - static int port_allocated; - static uint8_t port_id; - int ret; - - if (port_allocated) { - *event_port_id = port_id; - return 0; - } - - RTE_SET_USED(id); - - ret = rte_event_dev_attr_get(event_dev_id, RTE_EVENT_DEV_ATTR_STARTED, - &started); - if (ret < 0) - return ret; - - if (started) - rte_event_dev_stop(event_dev_id); - - ret = rte_event_dev_info_get(evdev, &info); - if (ret < 0) - return ret; - - devconf_set_default_sane_values(&dev_conf, &info); - - port_id = dev_conf.nb_event_ports; - dev_conf.nb_event_ports++; - - ret = rte_event_dev_configure(event_dev_id, &dev_conf); - if (ret < 0) { - if (started) - rte_event_dev_start(event_dev_id); - return ret; - } - - if (conf_arg != NULL) - port_conf = conf_arg; - else { - port_conf = &def_port_conf; - ret = rte_event_port_default_conf_get(event_dev_id, port_id, - port_conf); - if (ret < 0) - return ret; - } - - ret = rte_event_port_setup(event_dev_id, port_id, port_conf); - if (ret < 0) - return ret; - - *event_port_id = port_id; - - if (started) - rte_event_dev_start(event_dev_id); - - /* Reuse this port number next time this is called */ - port_allocated = 1; - - return 0; -} - -static int -_timdev_setup(uint64_t max_tmo_ns, uint64_t bkt_tck_ns) -{ - struct rte_event_timer_adapter_conf config = { - .event_dev_id = evdev, - .timer_adapter_id = TEST_ADAPTER_ID, - .timer_tick_ns = bkt_tck_ns, - .max_tmo_ns = max_tmo_ns, - .nb_timers = MAX_TIMERS * 10, - }; - uint32_t caps = 0; - const char *pool_name = "timdev_test_pool"; - - global_bkt_tck_ns = bkt_tck_ns; - - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_caps_get(evdev, &caps), - "failed to get adapter capabilities"); - if (!(caps & RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) { - timdev = rte_event_timer_adapter_create_ext(&config, - test_port_conf_cb, - NULL); - setup_adapter_service(timdev); - using_services = true; - } else - timdev = rte_event_timer_adapter_create(&config); - - TEST_ASSERT_NOT_NULL(timdev, - "failed to create event timer ring"); - - TEST_ASSERT_EQUAL(rte_event_timer_adapter_start(timdev), 0, - "failed to Start event timer adapter"); - - /* Create event timer mempool */ - eventdev_test_mempool = rte_mempool_create(pool_name, - MAX_TIMERS * 2, - sizeof(struct rte_event_timer), /* element size*/ - 0, /* cache size*/ - 0, NULL, NULL, NULL, NULL, - rte_socket_id(), 0); - if (!eventdev_test_mempool) { - printf("ERROR creating mempool\n"); - return TEST_FAILED; - } - - return TEST_SUCCESS; -} - -static int -timdev_setup_usec(void) -{ - return using_services ? - /* Max timeout is 10,000us and bucket interval is 100us */ - _timdev_setup(1E7, 1E5) : - /* Max timeout is 100us and bucket interval is 1us */ - _timdev_setup(1E5, 1E3); -} - -static int -timdev_setup_usec_multicore(void) -{ - return using_services ? - /* Max timeout is 10,000us and bucket interval is 100us */ - _timdev_setup(1E7, 1E5) : - /* Max timeout is 100us and bucket interval is 1us */ - _timdev_setup(1E5, 1E3); -} - -static int -timdev_setup_msec(void) -{ - /* Max timeout is 2 mins, and bucket interval is 100 ms */ - return _timdev_setup(180 * NSECPERSEC, NSECPERSEC / 10); -} - -static int -timdev_setup_sec(void) -{ - /* Max timeout is 100sec and bucket interval is 1sec */ - return _timdev_setup(1E11, 1E9); -} - -static int -timdev_setup_sec_multicore(void) -{ - /* Max timeout is 100sec and bucket interval is 1sec */ - return _timdev_setup(1E11, 1E9); -} - -static void -timdev_teardown(void) -{ - rte_event_timer_adapter_stop(timdev); - rte_event_timer_adapter_free(timdev); - - rte_mempool_free(eventdev_test_mempool); -} - -static inline int -test_timer_state(void) -{ - struct rte_event_timer *ev_tim; - struct rte_event ev; - const struct rte_event_timer tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = 0, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - }; - - rte_mempool_get(eventdev_test_mempool, (void **)&ev_tim); - *ev_tim = tim; - ev_tim->ev.event_ptr = ev_tim; - ev_tim->timeout_ticks = 120; - - TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 0, - "Armed timer exceeding max_timeout."); - TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_ERROR_TOOLATE, - "Improper timer state set expected %d returned %d", - RTE_EVENT_TIMER_ERROR_TOOLATE, ev_tim->state); - - ev_tim->state = RTE_EVENT_TIMER_NOT_ARMED; - ev_tim->timeout_ticks = 10; - - TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 1, - "Failed to arm timer with proper timeout."); - TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_ARMED, - "Improper timer state set expected %d returned %d", - RTE_EVENT_TIMER_ARMED, ev_tim->state); - - if (!using_services) - rte_delay_us(20); - else - rte_delay_us(1000 + 200); - TEST_ASSERT_EQUAL(rte_event_dequeue_burst(evdev, 0, &ev, 1, 0), 1, - "Armed timer failed to trigger."); - - ev_tim->state = RTE_EVENT_TIMER_NOT_ARMED; - ev_tim->timeout_ticks = 90; - TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 1, - "Failed to arm timer with proper timeout."); - TEST_ASSERT_EQUAL(rte_event_timer_cancel_burst(timdev, &ev_tim, 1), - 1, "Failed to cancel armed timer"); - TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_CANCELED, - "Improper timer state set expected %d returned %d", - RTE_EVENT_TIMER_CANCELED, ev_tim->state); - - rte_mempool_put(eventdev_test_mempool, (void *)ev_tim); - - return TEST_SUCCESS; -} - -static inline int -_arm_timers(uint64_t timeout_tcks, uint64_t timers) -{ - uint64_t i; - struct rte_event_timer *ev_tim; - const struct rte_event_timer tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = 0, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = timeout_tcks, - }; - - for (i = 0; i < timers; i++) { - - TEST_ASSERT_SUCCESS(rte_mempool_get(eventdev_test_mempool, - (void **)&ev_tim), - "mempool alloc failed"); - *ev_tim = tim; - ev_tim->ev.event_ptr = ev_tim; - - TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, - 1), 1, "Failed to arm timer %d", - rte_errno); - } - - return TEST_SUCCESS; -} - -static inline int -_wait_timer_triggers(uint64_t wait_sec, uint64_t arm_count, - uint64_t cancel_count) -{ - uint8_t valid_event; - uint64_t events = 0; - uint64_t wait_start, max_wait; - struct rte_event ev; - - max_wait = rte_get_timer_hz() * wait_sec; - wait_start = rte_get_timer_cycles(); - while (1) { - if (rte_get_timer_cycles() - wait_start > max_wait) { - if (events + cancel_count != arm_count) - TEST_ASSERT_SUCCESS(max_wait, - "Max time limit for timers exceeded."); - break; - } - - valid_event = rte_event_dequeue_burst(evdev, 0, &ev, 1, 0); - if (!valid_event) - continue; - - rte_mempool_put(eventdev_test_mempool, ev.event_ptr); - events++; - } - - return TEST_SUCCESS; -} - -static inline int -test_timer_arm(void) -{ - TEST_ASSERT_SUCCESS(_arm_timers(20, MAX_TIMERS), - "Failed to arm timers"); - TEST_ASSERT_SUCCESS(_wait_timer_triggers(10, MAX_TIMERS, 0), - "Timer triggered count doesn't match arm count"); - return TEST_SUCCESS; -} - -static int -_arm_wrapper(void *arg) -{ - RTE_SET_USED(arg); - - TEST_ASSERT_SUCCESS(_arm_timers(20, MAX_TIMERS), - "Failed to arm timers"); - - return TEST_SUCCESS; -} - -static inline int -test_timer_arm_multicore(void) -{ - - uint32_t lcore_1 = rte_get_next_lcore(-1, 1, 0); - uint32_t lcore_2 = rte_get_next_lcore(lcore_1, 1, 0); - - rte_eal_remote_launch(_arm_wrapper, NULL, lcore_1); - rte_eal_remote_launch(_arm_wrapper, NULL, lcore_2); - - rte_eal_mp_wait_lcore(); - TEST_ASSERT_SUCCESS(_wait_timer_triggers(10, MAX_TIMERS * 2, 0), - "Timer triggered count doesn't match arm count"); - - return TEST_SUCCESS; -} - -#define MAX_BURST 16 -static inline int -_arm_timers_burst(uint64_t timeout_tcks, uint64_t timers) -{ - uint64_t i; - int j; - struct rte_event_timer *ev_tim[MAX_BURST]; - const struct rte_event_timer tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = 0, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = timeout_tcks, - }; - - for (i = 0; i < timers / MAX_BURST; i++) { - TEST_ASSERT_SUCCESS(rte_mempool_get_bulk( - eventdev_test_mempool, - (void **)ev_tim, MAX_BURST), - "mempool alloc failed"); - - for (j = 0; j < MAX_BURST; j++) { - *ev_tim[j] = tim; - ev_tim[j]->ev.event_ptr = ev_tim[j]; - } - - TEST_ASSERT_EQUAL(rte_event_timer_arm_tmo_tick_burst(timdev, - ev_tim, tim.timeout_ticks, MAX_BURST), - MAX_BURST, "Failed to arm timer %d", rte_errno); - } - - return TEST_SUCCESS; -} - -static inline int -test_timer_arm_burst(void) -{ - TEST_ASSERT_SUCCESS(_arm_timers_burst(20, MAX_TIMERS), - "Failed to arm timers"); - TEST_ASSERT_SUCCESS(_wait_timer_triggers(10, MAX_TIMERS, 0), - "Timer triggered count doesn't match arm count"); - - return TEST_SUCCESS; -} - -static int -_arm_wrapper_burst(void *arg) -{ - RTE_SET_USED(arg); - - TEST_ASSERT_SUCCESS(_arm_timers_burst(20, MAX_TIMERS), - "Failed to arm timers"); - - return TEST_SUCCESS; -} - -static inline int -test_timer_arm_burst_multicore(void) -{ - rte_eal_remote_launch(_arm_wrapper_burst, NULL, test_lcore1); - rte_eal_remote_launch(_arm_wrapper_burst, NULL, test_lcore2); - - rte_eal_mp_wait_lcore(); - TEST_ASSERT_SUCCESS(_wait_timer_triggers(10, MAX_TIMERS * 2, 0), - "Timer triggered count doesn't match arm count"); - - return TEST_SUCCESS; -} - -static inline int -test_timer_cancel(void) -{ - uint64_t i; - struct rte_event_timer *ev_tim; - const struct rte_event_timer tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = 0, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 20, - }; - - for (i = 0; i < MAX_TIMERS; i++) { - TEST_ASSERT_SUCCESS(rte_mempool_get(eventdev_test_mempool, - (void **)&ev_tim), - "mempool alloc failed"); - *ev_tim = tim; - ev_tim->ev.event_ptr = ev_tim; - - TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, - 1), 1, "Failed to arm timer %d", - rte_errno); - - rte_delay_us(100 + (i % 5000)); - - TEST_ASSERT_EQUAL(rte_event_timer_cancel_burst(timdev, - &ev_tim, 1), 1, - "Failed to cancel event timer %d", rte_errno); - rte_mempool_put(eventdev_test_mempool, ev_tim); - } - - - TEST_ASSERT_SUCCESS(_wait_timer_triggers(30, MAX_TIMERS, - MAX_TIMERS), - "Timer triggered count doesn't match arm, cancel count"); - - return TEST_SUCCESS; -} - -static int -_cancel_producer(uint64_t timeout_tcks, uint64_t timers) -{ - uint64_t i; - struct rte_event_timer *ev_tim; - const struct rte_event_timer tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = 0, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = timeout_tcks, - }; - - for (i = 0; i < timers; i++) { - TEST_ASSERT_SUCCESS(rte_mempool_get(eventdev_test_mempool, - (void **)&ev_tim), - "mempool alloc failed"); - - *ev_tim = tim; - ev_tim->ev.event_ptr = ev_tim; - - TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, - 1), 1, "Failed to arm timer %d", - rte_errno); - - TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_ARMED, - "Failed to arm event timer"); - - while (rte_ring_enqueue(timer_producer_ring, ev_tim) != 0) - ; - } - - return TEST_SUCCESS; -} - -static int -_cancel_producer_burst(uint64_t timeout_tcks, uint64_t timers) -{ - - uint64_t i; - int j, ret; - struct rte_event_timer *ev_tim[MAX_BURST]; - const struct rte_event_timer tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = 0, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = timeout_tcks, - }; - int arm_count = 0; - - for (i = 0; i < timers / MAX_BURST; i++) { - TEST_ASSERT_SUCCESS(rte_mempool_get_bulk( - eventdev_test_mempool, - (void **)ev_tim, MAX_BURST), - "mempool alloc failed"); - - for (j = 0; j < MAX_BURST; j++) { - *ev_tim[j] = tim; - ev_tim[j]->ev.event_ptr = ev_tim[j]; - } - - TEST_ASSERT_EQUAL(rte_event_timer_arm_tmo_tick_burst(timdev, - ev_tim, tim.timeout_ticks, MAX_BURST), - MAX_BURST, "Failed to arm timer %d", rte_errno); - - for (j = 0; j < MAX_BURST; j++) - TEST_ASSERT_EQUAL(ev_tim[j]->state, - RTE_EVENT_TIMER_ARMED, - "Event timer not armed, state = %d", - ev_tim[j]->state); - - ret = rte_ring_enqueue_bulk(timer_producer_ring, - (void **)ev_tim, MAX_BURST, NULL); - TEST_ASSERT_EQUAL(ret, MAX_BURST, - "Failed to enqueue event timers to ring"); - arm_count += ret; - } - - TEST_ASSERT_EQUAL(arm_count, MAX_TIMERS, - "Failed to arm expected number of event timers"); - - return TEST_SUCCESS; -} - -static int -_cancel_producer_wrapper(void *args) -{ - RTE_SET_USED(args); - - return _cancel_producer(20, MAX_TIMERS); -} - -static int -_cancel_producer_burst_wrapper(void *args) -{ - RTE_SET_USED(args); - - return _cancel_producer_burst(100, MAX_TIMERS); -} - -static int -_cancel_thread(void *args) -{ - RTE_SET_USED(args); - struct rte_event_timer *ev_tim = NULL; - uint64_t cancel_count = 0; - uint16_t ret; - - while (!arm_done || rte_ring_count(timer_producer_ring) > 0) { - if (rte_ring_dequeue(timer_producer_ring, (void **)&ev_tim)) - continue; - - ret = rte_event_timer_cancel_burst(timdev, &ev_tim, 1); - TEST_ASSERT_EQUAL(ret, 1, "Failed to cancel timer"); - rte_mempool_put(eventdev_test_mempool, (void *)ev_tim); - cancel_count++; - } - - return TEST_SUCCESS; -} - -static int -_cancel_burst_thread(void *args) -{ - RTE_SET_USED(args); - - int ret, i, n; - struct rte_event_timer *ev_tim[MAX_BURST]; - uint64_t cancel_count = 0; - uint64_t dequeue_count = 0; - - while (!arm_done || rte_ring_count(timer_producer_ring) > 0) { - n = rte_ring_dequeue_burst(timer_producer_ring, - (void **)ev_tim, MAX_BURST, NULL); - if (!n) - continue; - - dequeue_count += n; - - for (i = 0; i < n; i++) - TEST_ASSERT_EQUAL(ev_tim[i]->state, - RTE_EVENT_TIMER_ARMED, - "Event timer not armed, state = %d", - ev_tim[i]->state); - - ret = rte_event_timer_cancel_burst(timdev, ev_tim, n); - TEST_ASSERT_EQUAL(n, ret, "Failed to cancel complete burst of " - "event timers"); - rte_mempool_put_bulk(eventdev_test_mempool, (void **)ev_tim, - RTE_MIN(ret, MAX_BURST)); - - cancel_count += ret; - } - - TEST_ASSERT_EQUAL(cancel_count, MAX_TIMERS, - "Failed to cancel expected number of timers: " - "expected = %d, cancel_count = %"PRIu64", " - "dequeue_count = %"PRIu64"\n", MAX_TIMERS, - cancel_count, dequeue_count); - - return TEST_SUCCESS; -} - -static inline int -test_timer_cancel_multicore(void) -{ - arm_done = 0; - timer_producer_ring = rte_ring_create("timer_cancel_queue", - MAX_TIMERS * 2, rte_socket_id(), 0); - TEST_ASSERT_NOT_NULL(timer_producer_ring, - "Unable to reserve memory for ring"); - - rte_eal_remote_launch(_cancel_thread, NULL, test_lcore3); - rte_eal_remote_launch(_cancel_producer_wrapper, NULL, test_lcore1); - rte_eal_remote_launch(_cancel_producer_wrapper, NULL, test_lcore2); - - rte_eal_wait_lcore(test_lcore1); - rte_eal_wait_lcore(test_lcore2); - arm_done = 1; - rte_eal_wait_lcore(test_lcore3); - rte_ring_free(timer_producer_ring); - - TEST_ASSERT_SUCCESS(_wait_timer_triggers(30, MAX_TIMERS * 2, - MAX_TIMERS * 2), - "Timer triggered count doesn't match arm count"); - - return TEST_SUCCESS; -} - -static inline int -test_timer_cancel_burst_multicore(void) -{ - arm_done = 0; - timer_producer_ring = rte_ring_create("timer_cancel_queue", - MAX_TIMERS * 2, rte_socket_id(), 0); - TEST_ASSERT_NOT_NULL(timer_producer_ring, - "Unable to reserve memory for ring"); - - rte_eal_remote_launch(_cancel_burst_thread, NULL, test_lcore2); - rte_eal_remote_launch(_cancel_producer_burst_wrapper, NULL, - test_lcore1); - - rte_eal_wait_lcore(test_lcore1); - arm_done = 1; - rte_eal_wait_lcore(test_lcore2); - rte_ring_free(timer_producer_ring); - - TEST_ASSERT_SUCCESS(_wait_timer_triggers(30, MAX_TIMERS, - MAX_TIMERS), - "Timer triggered count doesn't match arm count"); - - return TEST_SUCCESS; -} - -static inline int -test_timer_cancel_random(void) -{ - uint64_t i; - uint64_t events_canceled = 0; - struct rte_event_timer *ev_tim; - const struct rte_event_timer tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = 0, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 20, - }; - - for (i = 0; i < MAX_TIMERS; i++) { - - TEST_ASSERT_SUCCESS(rte_mempool_get(eventdev_test_mempool, - (void **)&ev_tim), - "mempool alloc failed"); - *ev_tim = tim; - ev_tim->ev.event_ptr = ev_tim; - - TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, - 1), 1, "Failed to arm timer %d", - rte_errno); - - if (rte_rand() & 1) { - rte_delay_us(100 + (i % 5000)); - TEST_ASSERT_EQUAL(rte_event_timer_cancel_burst( - timdev, - &ev_tim, 1), 1, - "Failed to cancel event timer %d", rte_errno); - rte_mempool_put(eventdev_test_mempool, ev_tim); - events_canceled++; - } - } - - TEST_ASSERT_SUCCESS(_wait_timer_triggers(30, MAX_TIMERS, - events_canceled), - "Timer triggered count doesn't match arm, cancel count"); - - return TEST_SUCCESS; -} - -/* Check that the adapter can be created correctly */ -static int -adapter_create(void) -{ - int adapter_id = 0; - struct rte_event_timer_adapter *adapter, *adapter2; - - struct rte_event_timer_adapter_conf conf = { - .event_dev_id = evdev + 1, // invalid event dev id - .timer_adapter_id = adapter_id, - .clk_src = RTE_EVENT_TIMER_ADAPTER_CPU_CLK, - .timer_tick_ns = NSECPERSEC / 10, - .max_tmo_ns = 180 * NSECPERSEC, - .nb_timers = MAX_TIMERS, - .flags = 0, - }; - uint32_t caps = 0; - - /* Test invalid conf */ - adapter = rte_event_timer_adapter_create(&conf); - TEST_ASSERT_NULL(adapter, "Created adapter with invalid " - "event device id"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Incorrect errno value for " - "invalid event device id"); - - /* Test valid conf */ - conf.event_dev_id = evdev; - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_caps_get(evdev, &caps), - "failed to get adapter capabilities"); - if (!(caps & RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) - adapter = rte_event_timer_adapter_create_ext(&conf, - test_port_conf_cb, - NULL); - else - adapter = rte_event_timer_adapter_create(&conf); - TEST_ASSERT_NOT_NULL(adapter, "Failed to create adapter with valid " - "configuration"); - - /* Test existing id */ - adapter2 = rte_event_timer_adapter_create(&conf); - TEST_ASSERT_NULL(adapter2, "Created adapter with in-use id"); - TEST_ASSERT(rte_errno == EEXIST, "Incorrect errno value for existing " - "id"); - - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(adapter), - "Failed to free adapter"); - - rte_mempool_free(eventdev_test_mempool); - - return TEST_SUCCESS; -} - - -/* Test that adapter can be freed correctly. */ -static int -adapter_free(void) -{ - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stop(timdev), - "Failed to stop adapter"); - - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(timdev), - "Failed to free valid adapter"); - - /* Test free of already freed adapter */ - TEST_ASSERT_FAIL(rte_event_timer_adapter_free(timdev), - "Freed adapter that was already freed"); - - /* Test free of null adapter */ - timdev = NULL; - TEST_ASSERT_FAIL(rte_event_timer_adapter_free(timdev), - "Freed null adapter"); - - rte_mempool_free(eventdev_test_mempool); - - return TEST_SUCCESS; -} - -/* Test that adapter info can be retrieved and is correct. */ -static int -adapter_get_info(void) -{ - struct rte_event_timer_adapter_info info; - - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_get_info(timdev, &info), - "Failed to get adapter info"); - - if (using_services) - TEST_ASSERT_EQUAL(info.event_dev_port_id, 1, - "Expected port id = 1, got port id = %d", - info.event_dev_port_id); - - return TEST_SUCCESS; -} - -/* Test adapter lookup via adapter ID. */ -static int -adapter_lookup(void) -{ - struct rte_event_timer_adapter *adapter; - - adapter = rte_event_timer_adapter_lookup(TEST_ADAPTER_ID); - TEST_ASSERT_NOT_NULL(adapter, "Failed to lookup adapter"); - - return TEST_SUCCESS; -} - -static int -adapter_start(void) -{ - TEST_ASSERT_SUCCESS(_timdev_setup(180 * NSECPERSEC, - NSECPERSEC / 10), - "Failed to start adapter"); - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_start(timdev), - "Failed to repeatedly start adapter"); - - return TEST_SUCCESS; -} - -/* Test that adapter stops correctly. */ -static int -adapter_stop(void) -{ - struct rte_event_timer_adapter *l_adapter = NULL; - - /* Test adapter stop */ - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stop(timdev), - "Failed to stop event adapter"); - - TEST_ASSERT_FAIL(rte_event_timer_adapter_stop(l_adapter), - "Erroneously stopped null event adapter"); - - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(timdev), - "Failed to free adapter"); - - rte_mempool_free(eventdev_test_mempool); - - return TEST_SUCCESS; -} - -/* Test increment and reset of ev_enq_count stat */ -static int -stat_inc_reset_ev_enq(void) -{ - int ret, i, n; - int num_evtims = MAX_TIMERS; - struct rte_event_timer *evtims[num_evtims]; - struct rte_event evs[BATCH_SIZE]; - struct rte_event_timer_adapter_stats stats; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 5, // expire in .5 sec - }; - - ret = rte_mempool_get_bulk(eventdev_test_mempool, (void **)evtims, - num_evtims); - TEST_ASSERT_EQUAL(ret, 0, "Failed to get array of timer objs: ret = %d", - ret); - - for (i = 0; i < num_evtims; i++) { - *evtims[i] = init_tim; - evtims[i]->ev.event_ptr = evtims[i]; - } - - ret = rte_event_timer_adapter_stats_get(timdev, &stats); - TEST_ASSERT_EQUAL(ret, 0, "Failed to get stats"); - TEST_ASSERT_EQUAL((int)stats.ev_enq_count, 0, "Stats not clear at " - "startup"); - - /* Test with the max value for the adapter */ - ret = rte_event_timer_arm_burst(timdev, evtims, num_evtims); - TEST_ASSERT_EQUAL(ret, num_evtims, - "Failed to arm all event timers: attempted = %d, " - "succeeded = %d, rte_errno = %s", - num_evtims, ret, rte_strerror(rte_errno)); - - rte_delay_ms(1000); - -#define MAX_TRIES num_evtims - int sum = 0; - int tries = 0; - bool done = false; - while (!done) { - sum += rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, - RTE_DIM(evs), 10); - if (sum >= num_evtims || ++tries >= MAX_TRIES) - done = true; - - rte_delay_ms(10); - } - - TEST_ASSERT_EQUAL(sum, num_evtims, "Expected %d timer expiry events, " - "got %d", num_evtims, sum); - - TEST_ASSERT(tries < MAX_TRIES, "Exceeded max tries"); - - rte_delay_ms(100); - - /* Make sure the eventdev is still empty */ - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), - 10); - - TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected number of timer expiry " - "events from event device"); - - /* Check stats again */ - ret = rte_event_timer_adapter_stats_get(timdev, &stats); - TEST_ASSERT_EQUAL(ret, 0, "Failed to get stats"); - TEST_ASSERT_EQUAL((int)stats.ev_enq_count, num_evtims, - "Expected enqueue stat = %d; got %d", num_evtims, - (int)stats.ev_enq_count); - - /* Reset and check again */ - ret = rte_event_timer_adapter_stats_reset(timdev); - TEST_ASSERT_EQUAL(ret, 0, "Failed to reset stats"); - - ret = rte_event_timer_adapter_stats_get(timdev, &stats); - TEST_ASSERT_EQUAL(ret, 0, "Failed to get stats"); - TEST_ASSERT_EQUAL((int)stats.ev_enq_count, 0, - "Expected enqueue stat = %d; got %d", 0, - (int)stats.ev_enq_count); - - rte_mempool_put_bulk(eventdev_test_mempool, (void **)evtims, - num_evtims); - - return TEST_SUCCESS; -} - -/* Test various cases in arming timers */ -static int -event_timer_arm(void) -{ - uint16_t n; - int ret; - struct rte_event_timer_adapter *adapter = timdev; - struct rte_event_timer *evtim = NULL; - struct rte_event evs[BATCH_SIZE]; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 5, // expire in .5 sec - }; - - rte_mempool_get(eventdev_test_mempool, (void **)&evtim); - if (evtim == NULL) { - /* Failed to get an event timer object */ - return TEST_FAILED; - } - - /* Set up a timer */ - *evtim = init_tim; - evtim->ev.event_ptr = evtim; - - /* Test single timer arm succeeds */ - ret = rte_event_timer_arm_burst(adapter, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", - rte_strerror(rte_errno)); - TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, "Event timer " - "in incorrect state"); - - /* Test arm of armed timer fails */ - ret = rte_event_timer_arm_burst(adapter, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 0, "expected return value from " - "rte_event_timer_arm_burst: 0, got: %d", ret); - TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value " - "after arming already armed timer"); - - /* Let timer expire */ - rte_delay_ms(1000); - - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); - TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry " - "events from event device"); - - rte_mempool_put(eventdev_test_mempool, evtim); - - return TEST_SUCCESS; -} - -/* This test checks that repeated references to the same event timer in the - * arm request work as expected; only the first one through should succeed. - */ -static int -event_timer_arm_double(void) -{ - uint16_t n; - int ret; - struct rte_event_timer_adapter *adapter = timdev; - struct rte_event_timer *evtim = NULL; - struct rte_event evs[BATCH_SIZE]; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 5, // expire in .5 sec - }; - - rte_mempool_get(eventdev_test_mempool, (void **)&evtim); - if (evtim == NULL) { - /* Failed to get an event timer object */ - return TEST_FAILED; - } - - /* Set up a timer */ - *evtim = init_tim; - evtim->ev.event_ptr = evtim; - - struct rte_event_timer *evtim_arr[] = {evtim, evtim}; - ret = rte_event_timer_arm_burst(adapter, evtim_arr, RTE_DIM(evtim_arr)); - TEST_ASSERT_EQUAL(ret, 1, "Unexpected return value from " - "rte_event_timer_arm_burst"); - TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value " - "after double-arm"); - - /* Let timer expire */ - rte_delay_ms(600); - - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); - TEST_ASSERT_EQUAL(n, 1, "Dequeued incorrect number of expiry events - " - "expected: 1, actual: %d", n); - - rte_mempool_put(eventdev_test_mempool, evtim); - - return TEST_SUCCESS; -} - -/* Test the timer expiry event is generated at the expected time. */ -static int -event_timer_arm_expiry(void) -{ - uint16_t n; - int ret; - struct rte_event_timer_adapter *adapter = timdev; - struct rte_event_timer *evtim = NULL; - struct rte_event_timer *evtim2 = NULL; - struct rte_event evs[BATCH_SIZE]; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - }; - - rte_mempool_get(eventdev_test_mempool, (void **)&evtim); - if (evtim == NULL) { - /* Failed to get an event timer object */ - return TEST_FAILED; - } - - /* Set up an event timer */ - *evtim = init_tim; - evtim->timeout_ticks = 30, // expire in 3 secs - evtim->ev.event_ptr = evtim; - - ret = rte_event_timer_arm_burst(adapter, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s", - rte_strerror(rte_errno)); - TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, "Event " - "timer in incorrect state"); - - rte_delay_ms(2999); - - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); - TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event"); - - /* Delay 100 ms to account for the adapter tick window - should let us - * dequeue one event - */ - rte_delay_ms(100); - - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); - TEST_ASSERT_EQUAL(n, 1, "Dequeued incorrect number (%d) of timer " - "expiry events", n); - TEST_ASSERT_EQUAL(evs[0].event_type, RTE_EVENT_TYPE_TIMER, - "Dequeued unexpected type of event"); - - /* Check that we recover the original event timer and then free it */ - evtim2 = evs[0].event_ptr; - TEST_ASSERT_EQUAL(evtim, evtim2, - "Failed to recover pointer to original event timer"); - rte_mempool_put(eventdev_test_mempool, evtim2); - - return TEST_SUCCESS; -} - -/* Check that rearming a timer works as expected. */ -static int -event_timer_arm_rearm(void) -{ - uint16_t n; - int ret; - struct rte_event_timer *evtim = NULL; - struct rte_event_timer *evtim2 = NULL; - struct rte_event evs[BATCH_SIZE]; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - }; - - rte_mempool_get(eventdev_test_mempool, (void **)&evtim); - if (evtim == NULL) { - /* Failed to get an event timer object */ - return TEST_FAILED; - } - - /* Set up a timer */ - *evtim = init_tim; - evtim->timeout_ticks = 1; // expire in 0.1 sec - evtim->ev.event_ptr = evtim; - - /* Arm it */ - ret = rte_event_timer_arm_burst(timdev, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", - rte_strerror(rte_errno)); - - /* Add 100ms to account for the adapter tick window */ - rte_delay_ms(100 + 100); - - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); - TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry " - "events from event device"); - - /* Recover the timer through the event that was dequeued. */ - evtim2 = evs[0].event_ptr; - TEST_ASSERT_EQUAL(evtim, evtim2, - "Failed to recover pointer to original event timer"); - - /* Need to reset state in case implementation can't do it */ - evtim2->state = RTE_EVENT_TIMER_NOT_ARMED; - - /* Rearm it */ - ret = rte_event_timer_arm_burst(timdev, &evtim2, 1); - TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", - rte_strerror(rte_errno)); - - /* Add 100ms to account for the adapter tick window */ - rte_delay_ms(100 + 100); - - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); - TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry " - "events from event device"); - - /* Free it */ - evtim2 = evs[0].event_ptr; - TEST_ASSERT_EQUAL(evtim, evtim2, - "Failed to recover pointer to original event timer"); - rte_mempool_put(eventdev_test_mempool, evtim2); - - return TEST_SUCCESS; -} - -/* Check that the adapter handles the max specified number of timers as - * expected. - */ -static int -event_timer_arm_max(void) -{ - int ret, i, n; - int num_evtims = MAX_TIMERS; - struct rte_event_timer *evtims[num_evtims]; - struct rte_event evs[BATCH_SIZE]; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 5, // expire in .5 sec - }; - - ret = rte_mempool_get_bulk(eventdev_test_mempool, (void **)evtims, - num_evtims); - TEST_ASSERT_EQUAL(ret, 0, "Failed to get array of timer objs: ret = %d", - ret); - - for (i = 0; i < num_evtims; i++) { - *evtims[i] = init_tim; - evtims[i]->ev.event_ptr = evtims[i]; - } - - /* Test with the max value for the adapter */ - ret = rte_event_timer_arm_burst(timdev, evtims, num_evtims); - TEST_ASSERT_EQUAL(ret, num_evtims, - "Failed to arm all event timers: attempted = %d, " - "succeeded = %d, rte_errno = %s", - num_evtims, ret, rte_strerror(rte_errno)); - - rte_delay_ms(1000); - -#define MAX_TRIES num_evtims - int sum = 0; - int tries = 0; - bool done = false; - while (!done) { - sum += rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, - RTE_DIM(evs), 10); - if (sum >= num_evtims || ++tries >= MAX_TRIES) - done = true; - - rte_delay_ms(10); - } - - TEST_ASSERT_EQUAL(sum, num_evtims, "Expected %d timer expiry events, " - "got %d", num_evtims, sum); - - TEST_ASSERT(tries < MAX_TRIES, "Exceeded max tries"); - - rte_delay_ms(100); - - /* Make sure the eventdev is still empty */ - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), - 10); - - TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected number of timer expiry " - "events from event device"); - - rte_mempool_put_bulk(eventdev_test_mempool, (void **)evtims, - num_evtims); - - return TEST_SUCCESS; -} - -/* Check that creating an event timer with incorrect event sched type fails. */ -static int -event_timer_arm_invalid_sched_type(void) -{ - int ret; - struct rte_event_timer *evtim = NULL; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 5, // expire in .5 sec - }; - - if (!using_services) - return -ENOTSUP; - - rte_mempool_get(eventdev_test_mempool, (void **)&evtim); - if (evtim == NULL) { - /* Failed to get an event timer object */ - return TEST_FAILED; - } - - *evtim = init_tim; - evtim->ev.event_ptr = evtim; - evtim->ev.sched_type = RTE_SCHED_TYPE_PARALLEL; // bad sched type - - ret = rte_event_timer_arm_burst(timdev, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 0, "Expected to fail timer arm with invalid " - "sched type, but didn't"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after" - " arm fail with invalid queue"); - - rte_mempool_put(eventdev_test_mempool, &evtim); - - return TEST_SUCCESS; -} - -/* Check that creating an event timer with a timeout value that is too small or - * too big fails. - */ -static int -event_timer_arm_invalid_timeout(void) -{ - int ret; - struct rte_event_timer *evtim = NULL; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 5, // expire in .5 sec - }; - - rte_mempool_get(eventdev_test_mempool, (void **)&evtim); - if (evtim == NULL) { - /* Failed to get an event timer object */ - return TEST_FAILED; - } - - *evtim = init_tim; - evtim->ev.event_ptr = evtim; - evtim->timeout_ticks = 0; // timeout too small - - ret = rte_event_timer_arm_burst(timdev, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 0, "Expected to fail timer arm with invalid " - "timeout, but didn't"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after" - " arm fail with invalid timeout"); - TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ERROR_TOOEARLY, - "Unexpected event timer state"); - - *evtim = init_tim; - evtim->ev.event_ptr = evtim; - evtim->timeout_ticks = 1801; // timeout too big - - ret = rte_event_timer_arm_burst(timdev, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 0, "Expected to fail timer arm with invalid " - "timeout, but didn't"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after" - " arm fail with invalid timeout"); - TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ERROR_TOOLATE, - "Unexpected event timer state"); - - rte_mempool_put(eventdev_test_mempool, evtim); - - return TEST_SUCCESS; -} - -static int -event_timer_cancel(void) -{ - uint16_t n; - int ret; - struct rte_event_timer_adapter *adapter = timdev; - struct rte_event_timer *evtim = NULL; - struct rte_event evs[BATCH_SIZE]; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - }; - - rte_mempool_get(eventdev_test_mempool, (void **)&evtim); - if (evtim == NULL) { - /* Failed to get an event timer object */ - return TEST_FAILED; - } - - /* Check that cancelling an uninited timer fails */ - ret = rte_event_timer_cancel_burst(adapter, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 0, "Succeeded unexpectedly in canceling " - "uninited timer"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after " - "cancelling uninited timer"); - - /* Set up a timer */ - *evtim = init_tim; - evtim->ev.event_ptr = evtim; - evtim->timeout_ticks = 30; // expire in 3 sec - - /* Check that cancelling an inited but unarmed timer fails */ - ret = rte_event_timer_cancel_burst(adapter, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 0, "Succeeded unexpectedly in canceling " - "unarmed timer"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Unexpected rte_errno value after " - "cancelling unarmed timer"); - - ret = rte_event_timer_arm_burst(adapter, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", - rte_strerror(rte_errno)); - TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, - "evtim in incorrect state"); - - /* Delay 1 sec */ - rte_delay_ms(1000); - - ret = rte_event_timer_cancel_burst(adapter, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 1, "Failed to cancel event_timer: %s\n", - rte_strerror(rte_errno)); - TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_CANCELED, - "evtim in incorrect state"); - - rte_delay_ms(3000); - - /* Make sure that no expiry event was generated */ - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); - TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event\n"); - - rte_mempool_put(eventdev_test_mempool, evtim); - - return TEST_SUCCESS; -} - -static int -event_timer_cancel_double(void) -{ - uint16_t n; - int ret; - struct rte_event_timer_adapter *adapter = timdev; - struct rte_event_timer *evtim = NULL; - struct rte_event evs[BATCH_SIZE]; - const struct rte_event_timer init_tim = { - .ev.op = RTE_EVENT_OP_NEW, - .ev.queue_id = TEST_QUEUE_ID, - .ev.sched_type = RTE_SCHED_TYPE_ATOMIC, - .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL, - .ev.event_type = RTE_EVENT_TYPE_TIMER, - .state = RTE_EVENT_TIMER_NOT_ARMED, - .timeout_ticks = 5, // expire in .5 sec - }; - - rte_mempool_get(eventdev_test_mempool, (void **)&evtim); - if (evtim == NULL) { - /* Failed to get an event timer object */ - return TEST_FAILED; - } - - /* Set up a timer */ - *evtim = init_tim; - evtim->ev.event_ptr = evtim; - evtim->timeout_ticks = 30; // expire in 3 sec - - ret = rte_event_timer_arm_burst(adapter, &evtim, 1); - TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n", - rte_strerror(rte_errno)); - TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, - "timer in unexpected state"); - - /* Now, test that referencing the same timer twice in the same call - * fails - */ - struct rte_event_timer *evtim_arr[] = {evtim, evtim}; - ret = rte_event_timer_cancel_burst(adapter, evtim_arr, - RTE_DIM(evtim_arr)); - - /* Two requests to cancel same timer, only one should succeed */ - TEST_ASSERT_EQUAL(ret, 1, "Succeeded unexpectedly in canceling timer " - "twice"); - - TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value " - "after double-cancel: rte_errno = %d", rte_errno); - - rte_delay_ms(3000); - - /* Still make sure that no expiry event was generated */ - n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0); - TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event\n"); - - rte_mempool_put(eventdev_test_mempool, evtim); - - return TEST_SUCCESS; -} - -/* Check that event timer adapter tick resolution works as expected by testing - * the number of adapter ticks that occur within a particular time interval. - */ -static int -adapter_tick_resolution(void) -{ - struct rte_event_timer_adapter_stats stats; - uint64_t adapter_tick_count; - - /* Only run this test in the software driver case */ - if (!using_services) - return -ENOTSUP; - - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stats_reset(timdev), - "Failed to reset stats"); - - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stats_get(timdev, - &stats), "Failed to get adapter stats"); - TEST_ASSERT_EQUAL(stats.adapter_tick_count, 0, "Adapter tick count " - "not zeroed out"); - - /* Delay 1 second; should let at least 10 ticks occur with the default - * adapter configuration used by this test. - */ - rte_delay_ms(1000); - - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_stats_get(timdev, - &stats), "Failed to get adapter stats"); - - adapter_tick_count = stats.adapter_tick_count; - TEST_ASSERT(adapter_tick_count >= 10 && adapter_tick_count <= 12, - "Expected 10-12 adapter ticks, got %"PRIu64"\n", - adapter_tick_count); - - return TEST_SUCCESS; -} - -static int -adapter_create_max(void) -{ - int i; - uint32_t svc_start_count, svc_end_count; - struct rte_event_timer_adapter *adapters[ - RTE_EVENT_TIMER_ADAPTER_NUM_MAX + 1]; - - struct rte_event_timer_adapter_conf conf = { - .event_dev_id = evdev, - // timer_adapter_id set in loop - .clk_src = RTE_EVENT_TIMER_ADAPTER_CPU_CLK, - .timer_tick_ns = NSECPERSEC / 10, - .max_tmo_ns = 180 * NSECPERSEC, - .nb_timers = MAX_TIMERS, - .flags = 0, - }; - - if (!using_services) - return -ENOTSUP; - - svc_start_count = rte_service_get_count(); - - /* This test expects that there are sufficient service IDs available - * to be allocated. I.e., RTE_EVENT_TIMER_ADAPTER_NUM_MAX may need to - * be less than RTE_SERVICE_NUM_MAX if anything else uses a service - * (the SW event device, for example). - */ - for (i = 0; i < RTE_EVENT_TIMER_ADAPTER_NUM_MAX; i++) { - conf.timer_adapter_id = i; - adapters[i] = rte_event_timer_adapter_create_ext(&conf, - test_port_conf_cb, NULL); - TEST_ASSERT_NOT_NULL(adapters[i], "Failed to create adapter " - "%d", i); - } - - conf.timer_adapter_id = i; - adapters[i] = rte_event_timer_adapter_create(&conf); - TEST_ASSERT_NULL(adapters[i], "Created too many adapters"); - - /* Check that at least RTE_EVENT_TIMER_ADAPTER_NUM_MAX services - * have been created - */ - svc_end_count = rte_service_get_count(); - TEST_ASSERT_EQUAL(svc_end_count - svc_start_count, - RTE_EVENT_TIMER_ADAPTER_NUM_MAX, - "Failed to create expected number of services"); - - for (i = 0; i < RTE_EVENT_TIMER_ADAPTER_NUM_MAX; i++) - TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(adapters[i]), - "Failed to free adapter %d", i); - - /* Check that service count is back to where it was at start */ - svc_end_count = rte_service_get_count(); - TEST_ASSERT_EQUAL(svc_start_count, svc_end_count, "Failed to release " - "correct number of services"); - - return TEST_SUCCESS; -} - -static struct unit_test_suite event_timer_adptr_functional_testsuite = { - .suite_name = "event timer functional test suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(timdev_setup_usec, timdev_teardown, - test_timer_state), - TEST_CASE_ST(timdev_setup_usec, timdev_teardown, - test_timer_arm), - TEST_CASE_ST(timdev_setup_usec, timdev_teardown, - test_timer_arm_burst), - TEST_CASE_ST(timdev_setup_sec, timdev_teardown, - test_timer_cancel), - TEST_CASE_ST(timdev_setup_sec, timdev_teardown, - test_timer_cancel_random), - TEST_CASE_ST(timdev_setup_usec_multicore, timdev_teardown, - test_timer_arm_multicore), - TEST_CASE_ST(timdev_setup_usec_multicore, timdev_teardown, - test_timer_arm_burst_multicore), - TEST_CASE_ST(timdev_setup_sec_multicore, timdev_teardown, - test_timer_cancel_multicore), - TEST_CASE_ST(timdev_setup_sec_multicore, timdev_teardown, - test_timer_cancel_burst_multicore), - TEST_CASE(adapter_create), - TEST_CASE_ST(timdev_setup_msec, NULL, adapter_free), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - adapter_get_info), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - adapter_lookup), - TEST_CASE_ST(NULL, timdev_teardown, - adapter_start), - TEST_CASE_ST(timdev_setup_msec, NULL, - adapter_stop), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - stat_inc_reset_ev_enq), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_arm), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_arm_double), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_arm_expiry), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_arm_rearm), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_arm_max), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_arm_invalid_sched_type), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_arm_invalid_timeout), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_cancel), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - event_timer_cancel_double), - TEST_CASE_ST(timdev_setup_msec, timdev_teardown, - adapter_tick_resolution), - TEST_CASE(adapter_create_max), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_event_timer_adapter_func(void) -{ - return unit_test_suite_runner(&event_timer_adptr_functional_testsuite); -} - -REGISTER_TEST_COMMAND(event_timer_adapter_test, test_event_timer_adapter_func); diff --git a/test/test/test_eventdev.c b/test/test/test_eventdev.c deleted file mode 100644 index 00d73275c8..0000000000 --- a/test/test/test_eventdev.c +++ /dev/null @@ -1,1018 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016 Cavium, Inc - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define TEST_DEV_ID 0 - -static int -testsuite_setup(void) -{ - RTE_BUILD_BUG_ON(sizeof(struct rte_event) != 16); - uint8_t count; - count = rte_event_dev_count(); - if (!count) { - printf("Failed to find a valid event device," - " testing with event_skeleton device\n"); - return rte_vdev_init("event_skeleton", NULL); - } - return TEST_SUCCESS; -} - -static void -testsuite_teardown(void) -{ -} - -static int -test_eventdev_count(void) -{ - uint8_t count; - count = rte_event_dev_count(); - TEST_ASSERT(count > 0, "Invalid eventdev count %" PRIu8, count); - return TEST_SUCCESS; -} - -static int -test_eventdev_get_dev_id(void) -{ - int ret; - ret = rte_event_dev_get_dev_id("not_a_valid_eventdev_driver"); - TEST_ASSERT_FAIL(ret, "Expected <0 for invalid dev name ret=%d", ret); - return TEST_SUCCESS; -} - -static int -test_eventdev_socket_id(void) -{ - int socket_id; - socket_id = rte_event_dev_socket_id(TEST_DEV_ID); - TEST_ASSERT(socket_id != -EINVAL, "Failed to get socket_id %d", - socket_id); - socket_id = rte_event_dev_socket_id(RTE_EVENT_MAX_DEVS); - TEST_ASSERT(socket_id == -EINVAL, "Expected -EINVAL %d", socket_id); - - return TEST_SUCCESS; -} - -static int -test_eventdev_info_get(void) -{ - int ret; - struct rte_event_dev_info info; - ret = rte_event_dev_info_get(TEST_DEV_ID, NULL); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - TEST_ASSERT(info.max_event_ports > 0, - "Not enough event ports %d", info.max_event_ports); - TEST_ASSERT(info.max_event_queues > 0, - "Not enough event queues %d", info.max_event_queues); - return TEST_SUCCESS; -} - -static inline void -devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - memset(dev_conf, 0, sizeof(struct rte_event_dev_config)); - dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns; - dev_conf->nb_event_ports = info->max_event_ports; - dev_conf->nb_event_queues = info->max_event_queues; - dev_conf->nb_event_queue_flows = info->max_event_queue_flows; - dev_conf->nb_event_port_dequeue_depth = - info->max_event_port_dequeue_depth; - dev_conf->nb_event_port_enqueue_depth = - info->max_event_port_enqueue_depth; - dev_conf->nb_event_port_enqueue_depth = - info->max_event_port_enqueue_depth; - dev_conf->nb_events_limit = - info->max_num_events; -} - -static int -test_ethdev_config_run(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info, - void (*fn)(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info)) -{ - devconf_set_default_sane_values(dev_conf, info); - fn(dev_conf, info); - return rte_event_dev_configure(TEST_DEV_ID, dev_conf); -} - -static void -max_dequeue_limit(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - dev_conf->dequeue_timeout_ns = info->max_dequeue_timeout_ns + 1; -} - -static void -max_events_limit(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - dev_conf->nb_events_limit = info->max_num_events + 1; -} - -static void -max_event_ports(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - dev_conf->nb_event_ports = info->max_event_ports + 1; -} - -static void -max_event_queues(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - dev_conf->nb_event_queues = info->max_event_queues + 1; -} - -static void -max_event_queue_flows(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - dev_conf->nb_event_queue_flows = info->max_event_queue_flows + 1; -} - -static void -max_event_port_dequeue_depth(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - dev_conf->nb_event_port_dequeue_depth = - info->max_event_port_dequeue_depth + 1; -} - -static void -max_event_port_enqueue_depth(struct rte_event_dev_config *dev_conf, - struct rte_event_dev_info *info) -{ - dev_conf->nb_event_port_enqueue_depth = - info->max_event_port_enqueue_depth + 1; -} - - -static int -test_eventdev_configure(void) -{ - int ret; - struct rte_event_dev_config dev_conf; - struct rte_event_dev_info info; - ret = rte_event_dev_configure(TEST_DEV_ID, NULL); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - /* Check limits */ - TEST_ASSERT_EQUAL(-EINVAL, - test_ethdev_config_run(&dev_conf, &info, max_dequeue_limit), - "Config negative test failed"); - TEST_ASSERT_EQUAL(-EINVAL, - test_ethdev_config_run(&dev_conf, &info, max_events_limit), - "Config negative test failed"); - TEST_ASSERT_EQUAL(-EINVAL, - test_ethdev_config_run(&dev_conf, &info, max_event_ports), - "Config negative test failed"); - TEST_ASSERT_EQUAL(-EINVAL, - test_ethdev_config_run(&dev_conf, &info, max_event_queues), - "Config negative test failed"); - TEST_ASSERT_EQUAL(-EINVAL, - test_ethdev_config_run(&dev_conf, &info, max_event_queue_flows), - "Config negative test failed"); - - if (info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE) { - TEST_ASSERT_EQUAL(-EINVAL, - test_ethdev_config_run(&dev_conf, &info, - max_event_port_dequeue_depth), - "Config negative test failed"); - TEST_ASSERT_EQUAL(-EINVAL, - test_ethdev_config_run(&dev_conf, &info, - max_event_port_enqueue_depth), - "Config negative test failed"); - } - - /* Positive case */ - devconf_set_default_sane_values(&dev_conf, &info); - ret = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); - TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); - - /* re-configure */ - devconf_set_default_sane_values(&dev_conf, &info); - dev_conf.nb_event_ports = RTE_MAX(info.max_event_ports/2, 1); - dev_conf.nb_event_queues = RTE_MAX(info.max_event_queues/2, 1); - ret = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); - TEST_ASSERT_SUCCESS(ret, "Failed to re configure eventdev"); - - /* re-configure back to max_event_queues and max_event_ports */ - devconf_set_default_sane_values(&dev_conf, &info); - ret = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); - TEST_ASSERT_SUCCESS(ret, "Failed to re-configure eventdev"); - - return TEST_SUCCESS; - -} - -static int -eventdev_configure_setup(void) -{ - int ret; - struct rte_event_dev_config dev_conf; - struct rte_event_dev_info info; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - devconf_set_default_sane_values(&dev_conf, &info); - ret = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); - TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); - - return TEST_SUCCESS; -} - -static int -test_eventdev_queue_default_conf_get(void) -{ - int i, ret; - struct rte_event_queue_conf qconf; - - ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, NULL); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - - for (i = 0; i < (int)queue_count; i++) { - ret = rte_event_queue_default_conf_get(TEST_DEV_ID, i, - &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get queue%d info", i); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_queue_setup(void) -{ - int i, ret; - struct rte_event_dev_info info; - struct rte_event_queue_conf qconf; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - /* Negative cases */ - ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get queue0 info"); - qconf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_ALL_TYPES; - qconf.nb_atomic_flows = info.max_event_queue_flows + 1; - ret = rte_event_queue_setup(TEST_DEV_ID, 0, &qconf); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - qconf.nb_atomic_flows = info.max_event_queue_flows; - qconf.schedule_type = RTE_SCHED_TYPE_ORDERED; - qconf.nb_atomic_order_sequences = info.max_event_queue_flows + 1; - ret = rte_event_queue_setup(TEST_DEV_ID, 0, &qconf); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - ret = rte_event_queue_setup(TEST_DEV_ID, info.max_event_queues, - &qconf); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - /* Positive case */ - ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get queue0 info"); - ret = rte_event_queue_setup(TEST_DEV_ID, 0, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue0"); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - - for (i = 0; i < (int)queue_count; i++) { - ret = rte_event_queue_setup(TEST_DEV_ID, i, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_queue_count(void) -{ - int ret; - struct rte_event_dev_info info; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - TEST_ASSERT_EQUAL(queue_count, info.max_event_queues, - "Wrong queue count"); - - return TEST_SUCCESS; -} - -static int -test_eventdev_queue_attr_priority(void) -{ - int i, ret; - struct rte_event_dev_info info; - struct rte_event_queue_conf qconf; - uint8_t priority; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - - for (i = 0; i < (int)queue_count; i++) { - ret = rte_event_queue_default_conf_get(TEST_DEV_ID, i, - &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get queue%d def conf", i); - qconf.priority = i % RTE_EVENT_DEV_PRIORITY_LOWEST; - ret = rte_event_queue_setup(TEST_DEV_ID, i, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); - } - - for (i = 0; i < (int)queue_count; i++) { - uint32_t tmp; - TEST_ASSERT_SUCCESS(rte_event_queue_attr_get(TEST_DEV_ID, i, - RTE_EVENT_QUEUE_ATTR_PRIORITY, &tmp), - "Queue priority get failed"); - priority = tmp; - - if (info.event_dev_cap & RTE_EVENT_DEV_CAP_QUEUE_QOS) - TEST_ASSERT_EQUAL(priority, - i % RTE_EVENT_DEV_PRIORITY_LOWEST, - "Wrong priority value for queue%d", i); - else - TEST_ASSERT_EQUAL(priority, - RTE_EVENT_DEV_PRIORITY_NORMAL, - "Wrong priority value for queue%d", i); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_queue_attr_nb_atomic_flows(void) -{ - int i, ret; - struct rte_event_dev_info info; - struct rte_event_queue_conf qconf; - uint32_t nb_atomic_flows; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - - ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get queue 0's def conf"); - - if (qconf.nb_atomic_flows == 0) - /* Assume PMD doesn't support atomic flows, return early */ - return -ENOTSUP; - - qconf.schedule_type = RTE_SCHED_TYPE_ATOMIC; - - for (i = 0; i < (int)queue_count; i++) { - ret = rte_event_queue_setup(TEST_DEV_ID, i, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); - } - - for (i = 0; i < (int)queue_count; i++) { - TEST_ASSERT_SUCCESS(rte_event_queue_attr_get(TEST_DEV_ID, i, - RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_FLOWS, - &nb_atomic_flows), - "Queue nb_atomic_flows get failed"); - - TEST_ASSERT_EQUAL(nb_atomic_flows, qconf.nb_atomic_flows, - "Wrong atomic flows value for queue%d", i); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_queue_attr_nb_atomic_order_sequences(void) -{ - int i, ret; - struct rte_event_dev_info info; - struct rte_event_queue_conf qconf; - uint32_t nb_atomic_order_sequences; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - - ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get queue 0's def conf"); - - if (qconf.nb_atomic_order_sequences == 0) - /* Assume PMD doesn't support reordering */ - return -ENOTSUP; - - qconf.schedule_type = RTE_SCHED_TYPE_ORDERED; - - for (i = 0; i < (int)queue_count; i++) { - ret = rte_event_queue_setup(TEST_DEV_ID, i, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); - } - - for (i = 0; i < (int)queue_count; i++) { - TEST_ASSERT_SUCCESS(rte_event_queue_attr_get(TEST_DEV_ID, i, - RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_ORDER_SEQUENCES, - &nb_atomic_order_sequences), - "Queue nb_atomic_order_sequencess get failed"); - - TEST_ASSERT_EQUAL(nb_atomic_order_sequences, - qconf.nb_atomic_order_sequences, - "Wrong atomic order sequences value for queue%d", - i); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_queue_attr_event_queue_cfg(void) -{ - int i, ret; - struct rte_event_dev_info info; - struct rte_event_queue_conf qconf; - uint32_t event_queue_cfg; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - - ret = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get queue0 def conf"); - - qconf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK; - - for (i = 0; i < (int)queue_count; i++) { - ret = rte_event_queue_setup(TEST_DEV_ID, i, &qconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); - } - - for (i = 0; i < (int)queue_count; i++) { - TEST_ASSERT_SUCCESS(rte_event_queue_attr_get(TEST_DEV_ID, i, - RTE_EVENT_QUEUE_ATTR_EVENT_QUEUE_CFG, - &event_queue_cfg), - "Queue event_queue_cfg get failed"); - - TEST_ASSERT_EQUAL(event_queue_cfg, qconf.event_queue_cfg, - "Wrong event_queue_cfg value for queue%d", - i); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_port_default_conf_get(void) -{ - int i, ret; - struct rte_event_port_conf pconf; - - ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, NULL); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - uint32_t port_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_PORT_COUNT, - &port_count), "Port count get failed"); - - ret = rte_event_port_default_conf_get(TEST_DEV_ID, - port_count + 1, NULL); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - for (i = 0; i < (int)port_count; i++) { - ret = rte_event_port_default_conf_get(TEST_DEV_ID, i, - &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get port%d info", i); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_port_setup(void) -{ - int i, ret; - struct rte_event_dev_info info; - struct rte_event_port_conf pconf; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - /* Negative cases */ - ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); - pconf.new_event_threshold = info.max_num_events + 1; - ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - pconf.new_event_threshold = info.max_num_events; - pconf.dequeue_depth = info.max_event_port_dequeue_depth + 1; - ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - pconf.dequeue_depth = info.max_event_port_dequeue_depth; - pconf.enqueue_depth = info.max_event_port_enqueue_depth + 1; - ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - if (!(info.event_dev_cap & - RTE_EVENT_DEV_CAP_IMPLICIT_RELEASE_DISABLE)) { - pconf.enqueue_depth = info.max_event_port_enqueue_depth; - pconf.disable_implicit_release = 1; - ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - pconf.disable_implicit_release = 0; - } - - ret = rte_event_port_setup(TEST_DEV_ID, info.max_event_ports, - &pconf); - TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); - - /* Positive case */ - ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); - ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port0"); - - uint32_t port_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_PORT_COUNT, - &port_count), "Port count get failed"); - - for (i = 0; i < (int)port_count; i++) { - ret = rte_event_port_setup(TEST_DEV_ID, i, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port%d", i); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_port_attr_dequeue_depth(void) -{ - int ret; - struct rte_event_dev_info info; - struct rte_event_port_conf pconf; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); - ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port0"); - - uint32_t value; - TEST_ASSERT_EQUAL(rte_event_port_attr_get(TEST_DEV_ID, 0, - RTE_EVENT_PORT_ATTR_DEQ_DEPTH, &value), - 0, "Call to get port dequeue depth failed"); - TEST_ASSERT_EQUAL(value, pconf.dequeue_depth, - "Wrong port dequeue depth"); - - return TEST_SUCCESS; -} - -static int -test_eventdev_port_attr_enqueue_depth(void) -{ - int ret; - struct rte_event_dev_info info; - struct rte_event_port_conf pconf; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); - ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port0"); - - uint32_t value; - TEST_ASSERT_EQUAL(rte_event_port_attr_get(TEST_DEV_ID, 0, - RTE_EVENT_PORT_ATTR_ENQ_DEPTH, &value), - 0, "Call to get port enqueue depth failed"); - TEST_ASSERT_EQUAL(value, pconf.enqueue_depth, - "Wrong port enqueue depth"); - - return TEST_SUCCESS; -} - -static int -test_eventdev_port_attr_new_event_threshold(void) -{ - int ret; - struct rte_event_dev_info info; - struct rte_event_port_conf pconf; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - ret = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to get port0 info"); - ret = rte_event_port_setup(TEST_DEV_ID, 0, &pconf); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port0"); - - uint32_t value; - TEST_ASSERT_EQUAL(rte_event_port_attr_get(TEST_DEV_ID, 0, - RTE_EVENT_PORT_ATTR_NEW_EVENT_THRESHOLD, &value), - 0, "Call to get port new event threshold failed"); - TEST_ASSERT_EQUAL((int32_t) value, pconf.new_event_threshold, - "Wrong port new event threshold"); - - return TEST_SUCCESS; -} - -static int -test_eventdev_port_count(void) -{ - int ret; - struct rte_event_dev_info info; - - ret = rte_event_dev_info_get(TEST_DEV_ID, &info); - TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info"); - - uint32_t port_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_PORT_COUNT, - &port_count), "Port count get failed"); - TEST_ASSERT_EQUAL(port_count, info.max_event_ports, "Wrong port count"); - - return TEST_SUCCESS; -} - -static int -test_eventdev_timeout_ticks(void) -{ - int ret; - uint64_t timeout_ticks; - - ret = rte_event_dequeue_timeout_ticks(TEST_DEV_ID, 100, &timeout_ticks); - if (ret != -ENOTSUP) - TEST_ASSERT_SUCCESS(ret, "Fail to get timeout_ticks"); - - return ret; -} - - -static int -test_eventdev_start_stop(void) -{ - int i, ret; - - ret = eventdev_configure_setup(); - TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - for (i = 0; i < (int)queue_count; i++) { - ret = rte_event_queue_setup(TEST_DEV_ID, i, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); - } - - uint32_t port_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_PORT_COUNT, - &port_count), "Port count get failed"); - - for (i = 0; i < (int)port_count; i++) { - ret = rte_event_port_setup(TEST_DEV_ID, i, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port%d", i); - } - - ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); - TEST_ASSERT(ret == (int)queue_count, "Failed to link port, device %d", - TEST_DEV_ID); - - ret = rte_event_dev_start(TEST_DEV_ID); - TEST_ASSERT_SUCCESS(ret, "Failed to start device%d", TEST_DEV_ID); - - rte_event_dev_stop(TEST_DEV_ID); - return TEST_SUCCESS; -} - - -static int -eventdev_setup_device(void) -{ - int i, ret; - - ret = eventdev_configure_setup(); - TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev"); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - for (i = 0; i < (int)queue_count; i++) { - ret = rte_event_queue_setup(TEST_DEV_ID, i, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup queue%d", i); - } - - uint32_t port_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_PORT_COUNT, - &port_count), "Port count get failed"); - - for (i = 0; i < (int)port_count; i++) { - ret = rte_event_port_setup(TEST_DEV_ID, i, NULL); - TEST_ASSERT_SUCCESS(ret, "Failed to setup port%d", i); - } - - ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); - TEST_ASSERT(ret == (int)queue_count, "Failed to link port, device %d", - TEST_DEV_ID); - - ret = rte_event_dev_start(TEST_DEV_ID); - TEST_ASSERT_SUCCESS(ret, "Failed to start device%d", TEST_DEV_ID); - - return TEST_SUCCESS; -} - -static void -eventdev_stop_device(void) -{ - rte_event_dev_stop(TEST_DEV_ID); -} - -static int -test_eventdev_link(void) -{ - int ret, nb_queues, i; - uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; - uint8_t priorities[RTE_EVENT_MAX_QUEUES_PER_DEV]; - - ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); - TEST_ASSERT(ret >= 0, "Failed to link with NULL device%d", - TEST_DEV_ID); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - nb_queues = queue_count; - for (i = 0; i < nb_queues; i++) { - queues[i] = i; - priorities[i] = RTE_EVENT_DEV_PRIORITY_NORMAL; - } - - ret = rte_event_port_link(TEST_DEV_ID, 0, queues, - priorities, nb_queues); - TEST_ASSERT(ret == nb_queues, "Failed to link(device%d) ret=%d", - TEST_DEV_ID, ret); - return TEST_SUCCESS; -} - -static int -test_eventdev_unlink(void) -{ - int ret, nb_queues, i; - uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; - - ret = rte_event_port_unlink(TEST_DEV_ID, 0, NULL, 0); - TEST_ASSERT(ret >= 0, "Failed to unlink with NULL device%d", - TEST_DEV_ID); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - nb_queues = queue_count; - for (i = 0; i < nb_queues; i++) - queues[i] = i; - - ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); - TEST_ASSERT(ret >= 0, "Failed to link with NULL device%d", - TEST_DEV_ID); - - ret = rte_event_port_unlink(TEST_DEV_ID, 0, queues, nb_queues); - TEST_ASSERT(ret == nb_queues, "Failed to unlink(device%d) ret=%d", - TEST_DEV_ID, ret); - return TEST_SUCCESS; -} - -static int -test_eventdev_link_get(void) -{ - int ret, i; - uint8_t queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; - uint8_t priorities[RTE_EVENT_MAX_QUEUES_PER_DEV]; - - /* link all queues */ - ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); - TEST_ASSERT(ret >= 0, "Failed to link with NULL device%d", - TEST_DEV_ID); - - uint32_t queue_count; - TEST_ASSERT_SUCCESS(rte_event_dev_attr_get(TEST_DEV_ID, - RTE_EVENT_DEV_ATTR_QUEUE_COUNT, &queue_count), - "Queue count get failed"); - const int nb_queues = queue_count; - for (i = 0; i < nb_queues; i++) - queues[i] = i; - - ret = rte_event_port_unlink(TEST_DEV_ID, 0, queues, nb_queues); - TEST_ASSERT(ret == nb_queues, "Failed to unlink(device%d) ret=%d", - TEST_DEV_ID, ret); - - ret = rte_event_port_links_get(TEST_DEV_ID, 0, queues, priorities); - TEST_ASSERT(ret == 0, "(%d)Wrong link get=%d", TEST_DEV_ID, ret); - - /* link all queues and get the links */ - for (i = 0; i < nb_queues; i++) { - queues[i] = i; - priorities[i] = RTE_EVENT_DEV_PRIORITY_NORMAL; - } - ret = rte_event_port_link(TEST_DEV_ID, 0, queues, priorities, - nb_queues); - TEST_ASSERT(ret == nb_queues, "Failed to link(device%d) ret=%d", - TEST_DEV_ID, ret); - ret = rte_event_port_links_get(TEST_DEV_ID, 0, queues, priorities); - TEST_ASSERT(ret == nb_queues, "(%d)Wrong link get ret=%d expected=%d", - TEST_DEV_ID, ret, nb_queues); - /* unlink all*/ - ret = rte_event_port_unlink(TEST_DEV_ID, 0, NULL, 0); - TEST_ASSERT(ret == nb_queues, "Failed to unlink(device%d) ret=%d", - TEST_DEV_ID, ret); - /* link just one queue */ - queues[0] = 0; - priorities[0] = RTE_EVENT_DEV_PRIORITY_NORMAL; - - ret = rte_event_port_link(TEST_DEV_ID, 0, queues, priorities, 1); - TEST_ASSERT(ret == 1, "Failed to link(device%d) ret=%d", - TEST_DEV_ID, ret); - ret = rte_event_port_links_get(TEST_DEV_ID, 0, queues, priorities); - TEST_ASSERT(ret == 1, "(%d)Wrong link get ret=%d expected=%d", - TEST_DEV_ID, ret, 1); - /* unlink the queue */ - ret = rte_event_port_unlink(TEST_DEV_ID, 0, NULL, 0); - TEST_ASSERT(ret == 1, "Failed to unlink(device%d) ret=%d", - TEST_DEV_ID, ret); - - /* 4links and 2 unlinks */ - if (nb_queues >= 4) { - for (i = 0; i < 4; i++) { - queues[i] = i; - priorities[i] = 0x40; - } - ret = rte_event_port_link(TEST_DEV_ID, 0, queues, priorities, - 4); - TEST_ASSERT(ret == 4, "Failed to link(device%d) ret=%d", - TEST_DEV_ID, ret); - - for (i = 0; i < 2; i++) - queues[i] = i; - - ret = rte_event_port_unlink(TEST_DEV_ID, 0, queues, 2); - TEST_ASSERT(ret == 2, "Failed to unlink(device%d) ret=%d", - TEST_DEV_ID, ret); - ret = rte_event_port_links_get(TEST_DEV_ID, 0, - queues, priorities); - TEST_ASSERT(ret == 2, "(%d)Wrong link get ret=%d expected=%d", - TEST_DEV_ID, ret, 2); - TEST_ASSERT(queues[0] == 2, "ret=%d expected=%d", ret, 2); - TEST_ASSERT(priorities[0] == 0x40, "ret=%d expected=%d", - ret, 0x40); - TEST_ASSERT(queues[1] == 3, "ret=%d expected=%d", ret, 3); - TEST_ASSERT(priorities[1] == 0x40, "ret=%d expected=%d", - ret, 0x40); - } - - return TEST_SUCCESS; -} - -static int -test_eventdev_close(void) -{ - rte_event_dev_stop(TEST_DEV_ID); - return rte_event_dev_close(TEST_DEV_ID); -} - -static struct unit_test_suite eventdev_common_testsuite = { - .suite_name = "eventdev common code unit test suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(NULL, NULL, - test_eventdev_count), - TEST_CASE_ST(NULL, NULL, - test_eventdev_get_dev_id), - TEST_CASE_ST(NULL, NULL, - test_eventdev_socket_id), - TEST_CASE_ST(NULL, NULL, - test_eventdev_info_get), - TEST_CASE_ST(NULL, NULL, - test_eventdev_configure), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_queue_default_conf_get), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_queue_setup), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_queue_count), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_queue_attr_priority), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_queue_attr_nb_atomic_flows), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_queue_attr_nb_atomic_order_sequences), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_queue_attr_event_queue_cfg), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_port_default_conf_get), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_port_setup), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_port_attr_dequeue_depth), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_port_attr_enqueue_depth), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_port_attr_new_event_threshold), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_port_count), - TEST_CASE_ST(eventdev_configure_setup, NULL, - test_eventdev_timeout_ticks), - TEST_CASE_ST(NULL, NULL, - test_eventdev_start_stop), - TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, - test_eventdev_link), - TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, - test_eventdev_unlink), - TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, - test_eventdev_link_get), - TEST_CASE_ST(eventdev_setup_device, NULL, - test_eventdev_close), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_eventdev_common(void) -{ - return unit_test_suite_runner(&eventdev_common_testsuite); -} - -static int -test_eventdev_selftest_impl(const char *pmd, const char *opts) -{ - rte_vdev_init(pmd, opts); - return rte_event_dev_selftest(rte_event_dev_get_dev_id(pmd)); -} - -static int -test_eventdev_selftest_sw(void) -{ - return test_eventdev_selftest_impl("event_sw", ""); -} - -static int -test_eventdev_selftest_octeontx(void) -{ - return test_eventdev_selftest_impl("event_octeontx", ""); -} - -REGISTER_TEST_COMMAND(eventdev_common_autotest, test_eventdev_common); -REGISTER_TEST_COMMAND(eventdev_selftest_sw, test_eventdev_selftest_sw); -REGISTER_TEST_COMMAND(eventdev_selftest_octeontx, - test_eventdev_selftest_octeontx); diff --git a/test/test/test_external_mem.c b/test/test/test_external_mem.c deleted file mode 100644 index 97bde1cfbc..0000000000 --- a/test/test/test_external_mem.c +++ /dev/null @@ -1,577 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define EXTERNAL_MEM_SZ (RTE_PGSIZE_4K << 10) /* 4M of data */ - -static int -check_mem(void *addr, rte_iova_t *iova, size_t pgsz, int n_pages) -{ - int i; - - /* check that we can get this memory from EAL now */ - for (i = 0; i < n_pages; i++) { - const struct rte_memseg_list *msl; - const struct rte_memseg *ms; - void *cur = RTE_PTR_ADD(addr, pgsz * i); - rte_iova_t expected_iova; - - msl = rte_mem_virt2memseg_list(cur); - if (!msl->external) { - printf("%s():%i: Memseg list is not marked as external\n", - __func__, __LINE__); - return -1; - } - - ms = rte_mem_virt2memseg(cur, msl); - if (ms == NULL) { - printf("%s():%i: Failed to retrieve memseg for external mem\n", - __func__, __LINE__); - return -1; - } - if (ms->addr != cur) { - printf("%s():%i: VA mismatch\n", __func__, __LINE__); - return -1; - } - expected_iova = (iova == NULL) ? RTE_BAD_IOVA : iova[i]; - if (ms->iova != expected_iova) { - printf("%s():%i: IOVA mismatch\n", __func__, __LINE__); - return -1; - } - } - return 0; -} - -static int -test_malloc_invalid_param(void *addr, size_t len, size_t pgsz, rte_iova_t *iova, - int n_pages) -{ - static const char * const names[] = { - NULL, /* NULL name */ - "", /* empty name */ - "this heap name is definitely way too long to be valid" - }; - const char *valid_name = "valid heap name"; - unsigned int i; - - /* check invalid name handling */ - for (i = 0; i < RTE_DIM(names); i++) { - const char *name = names[i]; - - /* these calls may fail for other reasons, so check errno */ - if (rte_malloc_heap_create(name) >= 0 || rte_errno != EINVAL) { - printf("%s():%i: Created heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_destroy(name) >= 0 || rte_errno != EINVAL) { - printf("%s():%i: Destroyed heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_get_socket(name) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Found socket for heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_memory_add(name, addr, len, - NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) { - printf("%s():%i: Added memory to heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_memory_remove(name, addr, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Removed memory from heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_memory_attach(name, addr, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Attached memory to heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_memory_detach(name, addr, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Detached memory from heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - } - - /* do same as above, but with a valid heap name */ - - /* skip create call */ - if (rte_malloc_heap_destroy(valid_name) >= 0 || rte_errno != ENOENT) { - printf("%s():%i: Destroyed heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_get_socket(valid_name) >= 0 || - rte_errno != ENOENT) { - printf("%s():%i: Found socket for heap with invalid name\n", - __func__, __LINE__); - goto fail; - } - - /* these calls may fail for other reasons, so check errno */ - if (rte_malloc_heap_memory_add(valid_name, addr, len, - NULL, 0, pgsz) >= 0 || rte_errno != ENOENT) { - printf("%s():%i: Added memory to non-existent heap\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_memory_remove(valid_name, addr, len) >= 0 || - rte_errno != ENOENT) { - printf("%s():%i: Removed memory from non-existent heap\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_memory_attach(valid_name, addr, len) >= 0 || - rte_errno != ENOENT) { - printf("%s():%i: Attached memory to non-existent heap\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_memory_detach(valid_name, addr, len) >= 0 || - rte_errno != ENOENT) { - printf("%s():%i: Detached memory from non-existent heap\n", - __func__, __LINE__); - goto fail; - } - - /* create a valid heap but test other invalid parameters */ - if (rte_malloc_heap_create(valid_name) != 0) { - printf("%s():%i: Failed to create valid heap\n", - __func__, __LINE__); - goto fail; - } - - /* zero length */ - if (rte_malloc_heap_memory_add(valid_name, addr, 0, - NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) { - printf("%s():%i: Added memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_memory_remove(valid_name, addr, 0) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Removed memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_memory_attach(valid_name, addr, 0) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Attached memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_memory_detach(valid_name, addr, 0) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Detached memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - - /* zero address */ - if (rte_malloc_heap_memory_add(valid_name, NULL, len, - NULL, 0, pgsz) >= 0 || rte_errno != EINVAL) { - printf("%s():%i: Added memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_memory_remove(valid_name, NULL, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Removed memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - - if (rte_malloc_heap_memory_attach(valid_name, NULL, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Attached memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_memory_detach(valid_name, NULL, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Detached memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - - /* the following tests are only valid if IOVA table is not NULL */ - if (iova != NULL) { - /* wrong page count */ - if (rte_malloc_heap_memory_add(valid_name, addr, len, - iova, 0, pgsz) >= 0 || rte_errno != EINVAL) { - printf("%s():%i: Added memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_memory_add(valid_name, addr, len, - iova, n_pages - 1, pgsz) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Added memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_memory_add(valid_name, addr, len, - iova, n_pages + 1, pgsz) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Added memory with invalid parameters\n", - __func__, __LINE__); - goto fail; - } - } - - /* tests passed, destroy heap */ - if (rte_malloc_heap_destroy(valid_name) != 0) { - printf("%s():%i: Failed to destroy valid heap\n", - __func__, __LINE__); - goto fail; - } - return 0; -fail: - rte_malloc_heap_destroy(valid_name); - return -1; -} - -static int -test_malloc_basic(void *addr, size_t len, size_t pgsz, rte_iova_t *iova, - int n_pages) -{ - const char *heap_name = "heap"; - void *ptr = NULL; - int socket_id; - const struct rte_memzone *mz = NULL, *contig_mz = NULL; - - /* create heap */ - if (rte_malloc_heap_create(heap_name) != 0) { - printf("%s():%i: Failed to create malloc heap\n", - __func__, __LINE__); - goto fail; - } - - /* get socket ID corresponding to this heap */ - socket_id = rte_malloc_heap_get_socket(heap_name); - if (socket_id < 0) { - printf("%s():%i: cannot find socket for external heap\n", - __func__, __LINE__); - goto fail; - } - - /* heap is empty, so any allocation should fail */ - ptr = rte_malloc_socket("EXTMEM", 64, 0, socket_id); - if (ptr != NULL) { - printf("%s():%i: Allocated from empty heap\n", __func__, - __LINE__); - goto fail; - } - - /* add memory to heap */ - if (rte_malloc_heap_memory_add(heap_name, addr, len, - iova, n_pages, pgsz) != 0) { - printf("%s():%i: Failed to add memory to heap\n", - __func__, __LINE__); - goto fail; - } - - /* check if memory is accessible from EAL */ - if (check_mem(addr, iova, pgsz, n_pages) < 0) - goto fail; - - /* allocate - this now should succeed */ - ptr = rte_malloc_socket("EXTMEM", 64, 0, socket_id); - if (ptr == NULL) { - printf("%s():%i: Failed to allocate from external heap\n", - __func__, __LINE__); - goto fail; - } - - /* check if address is in expected range */ - if (ptr < addr || ptr >= RTE_PTR_ADD(addr, len)) { - printf("%s():%i: Allocated from unexpected address space\n", - __func__, __LINE__); - goto fail; - } - - /* we've allocated something - removing memory should fail */ - if (rte_malloc_heap_memory_remove(heap_name, addr, len) >= 0 || - rte_errno != EBUSY) { - printf("%s():%i: Removing memory succeeded when memory is not free\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_destroy(heap_name) >= 0 || rte_errno != EBUSY) { - printf("%s():%i: Destroying heap succeeded when memory is not free\n", - __func__, __LINE__); - goto fail; - } - - /* try allocating a memzone */ - mz = rte_memzone_reserve("heap_test", pgsz * 2, socket_id, 0); - if (mz == NULL) { - printf("%s():%i: Failed to reserve memzone\n", - __func__, __LINE__); - goto fail; - } - /* try allocating an IOVA-contiguous memzone - this should succeed - * if we've set up a contiguous IOVA table, and fail if we haven't. - */ - contig_mz = rte_memzone_reserve("heap_test_contig", pgsz * 2, socket_id, - RTE_MEMZONE_IOVA_CONTIG); - if ((iova == NULL) != (contig_mz == NULL)) { - printf("%s():%i: Failed to reserve memzone\n", - __func__, __LINE__); - goto fail; - } - - rte_malloc_dump_stats(stdout, NULL); - rte_malloc_dump_heaps(stdout); - - /* free memory - removing it should now succeed */ - rte_free(ptr); - ptr = NULL; - - rte_memzone_free(mz); - mz = NULL; - rte_memzone_free(contig_mz); - contig_mz = NULL; - - if (rte_malloc_heap_memory_remove(heap_name, addr, len) != 0) { - printf("%s():%i: Removing memory from heap failed\n", - __func__, __LINE__); - goto fail; - } - if (rte_malloc_heap_destroy(heap_name) != 0) { - printf("%s():%i: Destroying heap failed\n", - __func__, __LINE__); - goto fail; - } - - return 0; -fail: - rte_memzone_free(contig_mz); - rte_memzone_free(mz); - rte_free(ptr); - /* even if something failed, attempt to clean up */ - rte_malloc_heap_memory_remove(heap_name, addr, len); - rte_malloc_heap_destroy(heap_name); - - return -1; -} - -static int -test_extmem_invalid_param(void *addr, size_t len, size_t pgsz, rte_iova_t *iova, - int n_pages) -{ - /* these calls may fail for other reasons, so check errno */ - if (rte_extmem_unregister(addr, len) >= 0 || - rte_errno != ENOENT) { - printf("%s():%i: Unregistered non-existent memory\n", - __func__, __LINE__); - return -1; - } - - if (rte_extmem_attach(addr, len) >= 0 || - rte_errno != ENOENT) { - printf("%s():%i: Attached to non-existent memory\n", - __func__, __LINE__); - return -1; - } - if (rte_extmem_attach(addr, len) >= 0 || - rte_errno != ENOENT) { - printf("%s():%i: Detached from non-existent memory\n", - __func__, __LINE__); - return -1; - } - - /* zero length */ - if (rte_extmem_register(addr, 0, NULL, 0, pgsz) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Registered memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - - if (rte_extmem_unregister(addr, 0) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Unregistered memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - - if (rte_extmem_attach(addr, 0) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Attached memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - if (rte_extmem_attach(addr, 0) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Detached memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - - /* zero address */ - if (rte_extmem_register(NULL, len, NULL, 0, pgsz) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Registered memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - - if (rte_extmem_unregister(NULL, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Unregistered memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - - if (rte_extmem_attach(NULL, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Attached memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - if (rte_extmem_attach(NULL, len) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Detached memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - - /* the following tests are only valid if IOVA table is not NULL */ - if (iova != NULL) { - /* wrong page count */ - if (rte_extmem_register(addr, len, - iova, 0, pgsz) >= 0 || rte_errno != EINVAL) { - printf("%s():%i: Registered memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - if (rte_extmem_register(addr, len, - iova, n_pages - 1, pgsz) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Registered memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - if (rte_extmem_register(addr, len, - iova, n_pages + 1, pgsz) >= 0 || - rte_errno != EINVAL) { - printf("%s():%i: Registered memory with invalid parameters\n", - __func__, __LINE__); - return -1; - } - } - - return 0; -} - -static int -test_extmem_basic(void *addr, size_t len, size_t pgsz, rte_iova_t *iova, - int n_pages) -{ - /* register memory */ - if (rte_extmem_register(addr, len, iova, n_pages, pgsz) != 0) { - printf("%s():%i: Failed to register memory\n", - __func__, __LINE__); - goto fail; - } - - /* check if memory is accessible from EAL */ - if (check_mem(addr, iova, pgsz, n_pages) < 0) - goto fail; - - if (rte_extmem_unregister(addr, len) != 0) { - printf("%s():%i: Removing memory from heap failed\n", - __func__, __LINE__); - goto fail; - } - - return 0; -fail: - /* even if something failed, attempt to clean up */ - rte_extmem_unregister(addr, len); - - return -1; -} - -/* we need to test attach/detach in secondary processes. */ -static int -test_external_mem(void) -{ - size_t len = EXTERNAL_MEM_SZ; - size_t pgsz = RTE_PGSIZE_4K; - rte_iova_t iova[len / pgsz]; - void *addr; - int ret, n_pages; - int i; - - /* create external memory area */ - n_pages = RTE_DIM(iova); - addr = mmap(NULL, len, PROT_WRITE | PROT_READ, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (addr == MAP_FAILED) { - printf("%s():%i: Failed to create dummy memory area\n", - __func__, __LINE__); - return -1; - } - for (i = 0; i < n_pages; i++) { - /* arbitrary IOVA */ - rte_iova_t tmp = 0x100000000 + i * pgsz; - iova[i] = tmp; - } - - /* test external heap memory */ - ret = test_malloc_invalid_param(addr, len, pgsz, iova, n_pages); - ret |= test_malloc_basic(addr, len, pgsz, iova, n_pages); - /* when iova table is NULL, everything should still work */ - ret |= test_malloc_invalid_param(addr, len, pgsz, NULL, n_pages); - ret |= test_malloc_basic(addr, len, pgsz, NULL, n_pages); - - /* test non-heap memory */ - ret |= test_extmem_invalid_param(addr, len, pgsz, iova, n_pages); - ret |= test_extmem_basic(addr, len, pgsz, iova, n_pages); - /* when iova table is NULL, everything should still work */ - ret |= test_extmem_invalid_param(addr, len, pgsz, NULL, n_pages); - ret |= test_extmem_basic(addr, len, pgsz, NULL, n_pages); - - munmap(addr, len); - - return ret; -} - -REGISTER_TEST_COMMAND(external_mem_autotest, test_external_mem); diff --git a/test/test/test_fbarray.c b/test/test/test_fbarray.c deleted file mode 100644 index 8c44e2c7e1..0000000000 --- a/test/test/test_fbarray.c +++ /dev/null @@ -1,576 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "test.h" - -struct fbarray_testsuite_params { - struct rte_fbarray arr; - int start; - int end; -}; - -static struct fbarray_testsuite_params param; - -#define FBARRAY_TEST_ARR_NAME "fbarray_autotest" -#define FBARRAY_TEST_LEN 256 -#define FBARRAY_TEST_ELT_SZ (sizeof(int)) - -static int autotest_setup(void) -{ - return rte_fbarray_init(¶m.arr, FBARRAY_TEST_ARR_NAME, - FBARRAY_TEST_LEN, FBARRAY_TEST_ELT_SZ); -} - -static void autotest_teardown(void) -{ - rte_fbarray_destroy(¶m.arr); -} - -static int init_array(void) -{ - int i; - for (i = param.start; i <= param.end; i++) { - if (rte_fbarray_set_used(¶m.arr, i)) - return -1; - } - return 0; -} - -static void reset_array(void) -{ - int i; - for (i = 0; i < FBARRAY_TEST_LEN; i++) - rte_fbarray_set_free(¶m.arr, i); -} - -static int first_msk_test_setup(void) -{ - /* put all within first mask */ - param.start = 3; - param.end = 10; - return init_array(); -} - -static int cross_msk_test_setup(void) -{ - /* put all within second and third mask */ - param.start = 70; - param.end = 160; - return init_array(); -} - -static int multi_msk_test_setup(void) -{ - /* put all within first and last mask */ - param.start = 3; - param.end = FBARRAY_TEST_LEN - 20; - return init_array(); -} - -static int last_msk_test_setup(void) -{ - /* put all within last mask */ - param.start = FBARRAY_TEST_LEN - 20; - param.end = FBARRAY_TEST_LEN - 1; - return init_array(); -} - -static int full_msk_test_setup(void) -{ - /* fill entire mask */ - param.start = 0; - param.end = FBARRAY_TEST_LEN - 1; - return init_array(); -} - -static int empty_msk_test_setup(void) -{ - /* do not fill anything in */ - reset_array(); - return 0; -} - -static int test_invalid(void) -{ - struct rte_fbarray dummy; - - /* invalid parameters */ - TEST_ASSERT_FAIL(rte_fbarray_attach(NULL), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT_FAIL(rte_fbarray_detach(NULL), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT_FAIL(rte_fbarray_destroy(NULL), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno valuey\n"); - TEST_ASSERT_FAIL(rte_fbarray_init(NULL, "fail", 16, 16), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, NULL, 16, 16), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", 0, 16), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", 16, 0), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - /* len must not be greater than INT_MAX */ - TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", INT_MAX + 1U, 16), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT_NULL(rte_fbarray_get(NULL, 0), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_idx(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_set_free(NULL, 0), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_set_used(NULL, 0), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_contig_free(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_contig_used(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_rev_contig_free(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_rev_contig_used(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_free(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_used(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_free(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_used(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_n_free(NULL, 0, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_n_used(NULL, 0, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_n_free(NULL, 0, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_n_used(NULL, 0, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_is_used(NULL, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT_SUCCESS(rte_fbarray_init(&dummy, "success", - FBARRAY_TEST_LEN, 8), - "Failed to initialize valid fbarray\n"); - - /* test API for handling invalid parameters with a valid fbarray */ - TEST_ASSERT_NULL(rte_fbarray_get(&dummy, FBARRAY_TEST_LEN), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_idx(&dummy, NULL) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_set_free(&dummy, FBARRAY_TEST_LEN), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_set_used(&dummy, FBARRAY_TEST_LEN), - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_contig_free(&dummy, FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_contig_used(&dummy, FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_rev_contig_free(&dummy, - FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_rev_contig_used(&dummy, - FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_next_free(&dummy, FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_next_used(&dummy, FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_prev_free(&dummy, FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_prev_used(&dummy, FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, - FBARRAY_TEST_LEN, 1) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 0, - FBARRAY_TEST_LEN + 1) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 0, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, - FBARRAY_TEST_LEN, 1) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 0, - FBARRAY_TEST_LEN + 1) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 0, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, - FBARRAY_TEST_LEN, 1) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 0, - FBARRAY_TEST_LEN + 1) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 0, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, - FBARRAY_TEST_LEN, 1) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 0, - FBARRAY_TEST_LEN + 1) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 0, 0) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT(rte_fbarray_is_used(&dummy, FBARRAY_TEST_LEN) < 0, - "Call succeeded with invalid parameters\n"); - TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); - - TEST_ASSERT_SUCCESS(rte_fbarray_destroy(&dummy), - "Failed to destroy valid fbarray\n"); - - return TEST_SUCCESS; -} - -static int check_free(void) -{ - const int idx = 0; - const int last_idx = FBARRAY_TEST_LEN - 1; - - /* ensure we can find a free spot */ - TEST_ASSERT_EQUAL(rte_fbarray_find_next_free(¶m.arr, idx), idx, - "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(¶m.arr, idx, 1), idx, - "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(¶m.arr, idx), - FBARRAY_TEST_LEN, - "Free space not found where expected\n"); - - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(¶m.arr, idx), idx, - "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(¶m.arr, idx, 1), idx, - "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, idx), 1, - "Free space not found where expected\n"); - - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(¶m.arr, last_idx), - last_idx, "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(¶m.arr, last_idx, 1), - last_idx, "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, - last_idx), FBARRAY_TEST_LEN, - "Free space not found where expected\n"); - - /* ensure we can't find any used spots */ - TEST_ASSERT(rte_fbarray_find_next_used(¶m.arr, idx) < 0, - "Used space found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_n_used(¶m.arr, idx, 1) < 0, - "Used space found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx), 0, - "Used space found where none was expected\n"); - - TEST_ASSERT(rte_fbarray_find_prev_used(¶m.arr, last_idx) < 0, - "Used space found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1) < 0, - "Used space found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, - last_idx), 0, - "Used space found where none was expected\n"); - - return 0; -} - -static int check_used_one(void) -{ - const int idx = 0; - const int last_idx = FBARRAY_TEST_LEN - 1; - - /* check that we can find used spots now */ - TEST_ASSERT_EQUAL(rte_fbarray_find_next_used(¶m.arr, idx), idx, - "Used space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(¶m.arr, idx, 1), idx, - "Used space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx), 1, - "Used space not found where expected\n"); - - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(¶m.arr, last_idx), idx, - "Used space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1), - idx, "Used space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, idx), 1, - "Used space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, - last_idx), idx, - "Used space not found where expected\n"); - - /* check if further indices are still free */ - TEST_ASSERT(rte_fbarray_find_next_used(¶m.arr, idx + 1) < 0, - "Used space not found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); - TEST_ASSERT(rte_fbarray_find_next_n_used(¶m.arr, idx + 1, 1) < 0, - "Used space not found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx + 1), 0, - "Used space not found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(¶m.arr, idx + 1), - FBARRAY_TEST_LEN - 1, - "Used space not found where none was expected\n"); - - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(¶m.arr, last_idx), 0, - "Used space not found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1), - 0, "Used space not found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, - last_idx), 0, - "Used space not found where none was expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, - last_idx), FBARRAY_TEST_LEN - 1, - "Used space not found where none was expected\n"); - - return 0; -} - -static int test_basic(void) -{ - const int idx = 0; - int i; - - /* check array count */ - TEST_ASSERT_EQUAL(param.arr.count, 0, "Wrong element count\n"); - - /* ensure we can find a free spot */ - if (check_free()) - return TEST_FAILED; - - /* check if used */ - TEST_ASSERT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, - "Used space found where not expected\n"); - - /* mark as used */ - TEST_ASSERT_SUCCESS(rte_fbarray_set_used(¶m.arr, idx), - "Failed to set as used\n"); - - /* check if used again */ - TEST_ASSERT_NOT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, - "Used space not found where expected\n"); - - if (check_used_one()) - return TEST_FAILED; - - /* check array count */ - TEST_ASSERT_EQUAL(param.arr.count, 1, "Wrong element count\n"); - - /* check if getting pointers works for every element */ - for (i = 0; i < FBARRAY_TEST_LEN; i++) { - void *td = rte_fbarray_get(¶m.arr, i); - TEST_ASSERT_NOT_NULL(td, "Invalid pointer returned\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_idx(¶m.arr, td), i, - "Wrong index returned\n"); - } - - /* mark as free */ - TEST_ASSERT_SUCCESS(rte_fbarray_set_free(¶m.arr, idx), - "Failed to set as free\n"); - - /* check array count */ - TEST_ASSERT_EQUAL(param.arr.count, 0, "Wrong element count\n"); - - /* check if used */ - TEST_ASSERT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, - "Used space found where not expected\n"); - - if (check_free()) - return TEST_FAILED; - - reset_array(); - - return TEST_SUCCESS; -} - -static int ensure_correct(struct rte_fbarray *arr, int first, int last, - bool used) -{ - int i, len = last - first + 1; - for (i = 0; i < len; i++) { - int cur = first + i; - int cur_len = len - i; - - if (used) { - TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(arr, - cur), cur_len, - "Used space length is wrong\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(arr, - last), len, - "Used space length is wrong\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(arr, - cur), i + 1, - "Used space length is wrong\n"); - - TEST_ASSERT_EQUAL(rte_fbarray_find_next_used(arr, cur), - cur, - "Used space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(arr, - cur, 1), cur, - "Used space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(arr, cur, - cur_len), cur, - "Used space not found where expected\n"); - - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(arr, cur), - cur, - "Used space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(arr, - last, cur_len), cur, - "Used space not found where expected\n"); - } else { - TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr, - cur), cur_len, - "Free space length is wrong\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, - last), len, - "Free space length is wrong\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, - cur), i + 1, - "Free space length is wrong\n"); - - TEST_ASSERT_EQUAL(rte_fbarray_find_next_free(arr, cur), - cur, - "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(arr, cur, - 1), cur, - "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(arr, cur, - cur_len), cur, - "Free space not found where expected\n"); - - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(arr, cur), - cur, - "Free space not found where expected\n"); - TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(arr, - last, cur_len), cur, - "Free space not found where expected\n"); - } - } - return 0; -} - -static int test_find(void) -{ - TEST_ASSERT_EQUAL((int)param.arr.count, param.end - param.start + 1, - "Wrong element count\n"); - /* ensure space is free before start */ - if (ensure_correct(¶m.arr, 0, param.start - 1, false)) - return TEST_FAILED; - /* ensure space is occupied where it's supposed to be */ - if (ensure_correct(¶m.arr, param.start, param.end, true)) - return TEST_FAILED; - /* ensure space after end is free as well */ - if (ensure_correct(¶m.arr, param.end + 1, FBARRAY_TEST_LEN - 1, - false)) - return TEST_FAILED; - return TEST_SUCCESS; -} - -static int test_empty(void) -{ - TEST_ASSERT_EQUAL((int)param.arr.count, 0, "Wrong element count\n"); - /* ensure space is free */ - if (ensure_correct(¶m.arr, 0, FBARRAY_TEST_LEN - 1, false)) - return TEST_FAILED; - return TEST_SUCCESS; -} - - -static struct unit_test_suite fbarray_test_suite = { - .suite_name = "fbarray autotest", - .setup = autotest_setup, - .teardown = autotest_teardown, - .unit_test_cases = { - TEST_CASE(test_invalid), - TEST_CASE(test_basic), - TEST_CASE_ST(first_msk_test_setup, reset_array, test_find), - TEST_CASE_ST(cross_msk_test_setup, reset_array, test_find), - TEST_CASE_ST(multi_msk_test_setup, reset_array, test_find), - TEST_CASE_ST(last_msk_test_setup, reset_array, test_find), - TEST_CASE_ST(full_msk_test_setup, reset_array, test_find), - TEST_CASE_ST(empty_msk_test_setup, reset_array, test_empty), - TEST_CASES_END() - } -}; - -static int -test_fbarray(void) -{ - return unit_test_suite_runner(&fbarray_test_suite); -} - -REGISTER_TEST_COMMAND(fbarray_autotest, test_fbarray); diff --git a/test/test/test_flow_classify.c b/test/test/test_flow_classify.c deleted file mode 100644 index 5f5beeee75..0000000000 --- a/test/test/test_flow_classify.c +++ /dev/null @@ -1,902 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#include -#include - -#include "test.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "packet_burst_generator.h" -#include "test_flow_classify.h" - - -#define FLOW_CLASSIFY_MAX_RULE_NUM 100 -#define MAX_PKT_BURST 32 -#define NB_SOCKETS 1 -#define MEMPOOL_CACHE_SIZE 256 -#define MBUF_SIZE 512 -#define NB_MBUF 512 - -/* test UDP, TCP and SCTP packets */ -static struct rte_mempool *mbufpool[NB_SOCKETS]; -static struct rte_mbuf *bufs[MAX_PKT_BURST]; - -static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { - /* first input field - always one byte long. */ - { - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint8_t), - .field_index = PROTO_FIELD_IPV4, - .input_index = PROTO_INPUT_IPV4, - .offset = sizeof(struct ether_hdr) + - offsetof(struct ipv4_hdr, next_proto_id), - }, - /* next input field (IPv4 source address) - 4 consecutive bytes. */ - { - /* rte_flow uses a bit mask for IPv4 addresses */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint32_t), - .field_index = SRC_FIELD_IPV4, - .input_index = SRC_INPUT_IPV4, - .offset = sizeof(struct ether_hdr) + - offsetof(struct ipv4_hdr, src_addr), - }, - /* next input field (IPv4 destination address) - 4 consecutive bytes. */ - { - /* rte_flow uses a bit mask for IPv4 addresses */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint32_t), - .field_index = DST_FIELD_IPV4, - .input_index = DST_INPUT_IPV4, - .offset = sizeof(struct ether_hdr) + - offsetof(struct ipv4_hdr, dst_addr), - }, - /* - * Next 2 fields (src & dst ports) form 4 consecutive bytes. - * They share the same input index. - */ - { - /* rte_flow uses a bit mask for protocol ports */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = SRCP_FIELD_IPV4, - .input_index = SRCP_DESTP_INPUT_IPV4, - .offset = sizeof(struct ether_hdr) + - sizeof(struct ipv4_hdr) + - offsetof(struct tcp_hdr, src_port), - }, - { - /* rte_flow uses a bit mask for protocol ports */ - .type = RTE_ACL_FIELD_TYPE_BITMASK, - .size = sizeof(uint16_t), - .field_index = DSTP_FIELD_IPV4, - .input_index = SRCP_DESTP_INPUT_IPV4, - .offset = sizeof(struct ether_hdr) + - sizeof(struct ipv4_hdr) + - offsetof(struct tcp_hdr, dst_port), - }, -}; - -/* parameters for rte_flow_classify_validate and rte_flow_classify_create */ - -/* test UDP pattern: - * "eth / ipv4 src spec 2.2.2.3 src mask 255.255.255.00 dst spec 2.2.2.7 - * dst mask 255.255.255.00 / udp src is 32 dst is 33 / end" - */ -static struct rte_flow_item_ipv4 ipv4_udp_spec_1 = { - { 0, 0, 0, 0, 0, 0, IPPROTO_UDP, 0, IPv4(2, 2, 2, 3), IPv4(2, 2, 2, 7)} -}; -static const struct rte_flow_item_ipv4 ipv4_mask_24 = { - .hdr = { - .next_proto_id = 0xff, - .src_addr = 0xffffff00, - .dst_addr = 0xffffff00, - }, -}; -static struct rte_flow_item_udp udp_spec_1 = { - { 32, 33, 0, 0 } -}; - -static struct rte_flow_item eth_item = { RTE_FLOW_ITEM_TYPE_ETH, - 0, 0, 0 }; -static struct rte_flow_item eth_item_bad = { -1, 0, 0, 0 }; - -static struct rte_flow_item ipv4_udp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, - &ipv4_udp_spec_1, 0, &ipv4_mask_24}; -static struct rte_flow_item ipv4_udp_item_bad = { RTE_FLOW_ITEM_TYPE_IPV4, - NULL, 0, NULL}; - -static struct rte_flow_item udp_item_1 = { RTE_FLOW_ITEM_TYPE_UDP, - &udp_spec_1, 0, &rte_flow_item_udp_mask}; -static struct rte_flow_item udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP, - NULL, 0, NULL}; - -static struct rte_flow_item end_item = { RTE_FLOW_ITEM_TYPE_END, - 0, 0, 0 }; -static struct rte_flow_item end_item_bad = { -1, 0, 0, 0 }; - -/* test TCP pattern: - * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8 - * dst mask 255.255.255.00 / tcp src is 16 dst is 17 / end" - */ -static struct rte_flow_item_ipv4 ipv4_tcp_spec_1 = { - { 0, 0, 0, 0, 0, 0, IPPROTO_TCP, 0, IPv4(1, 2, 3, 4), IPv4(5, 6, 7, 8)} -}; - -static struct rte_flow_item_tcp tcp_spec_1 = { - { 16, 17, 0, 0, 0, 0, 0, 0, 0} -}; - -static struct rte_flow_item ipv4_tcp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, - &ipv4_tcp_spec_1, 0, &ipv4_mask_24}; - -static struct rte_flow_item tcp_item_1 = { RTE_FLOW_ITEM_TYPE_TCP, - &tcp_spec_1, 0, &rte_flow_item_tcp_mask}; - -/* test SCTP pattern: - * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8 - * dst mask 255.255.255.00 / sctp src is 16 dst is 17/ end" - */ -static struct rte_flow_item_ipv4 ipv4_sctp_spec_1 = { - { 0, 0, 0, 0, 0, 0, IPPROTO_SCTP, 0, IPv4(11, 12, 13, 14), - IPv4(15, 16, 17, 18)} -}; - -static struct rte_flow_item_sctp sctp_spec_1 = { - { 10, 11, 0, 0} -}; - -static struct rte_flow_item ipv4_sctp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4, - &ipv4_sctp_spec_1, 0, &ipv4_mask_24}; - -static struct rte_flow_item sctp_item_1 = { RTE_FLOW_ITEM_TYPE_SCTP, - &sctp_spec_1, 0, &rte_flow_item_sctp_mask}; - - -/* test actions: - * "actions count / end" - */ -static struct rte_flow_query_count count = { - .reset = 1, - .hits_set = 1, - .bytes_set = 1, - .hits = 0, - .bytes = 0, -}; -static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT, - &count}; -static struct rte_flow_action count_action_bad = { -1, 0}; - -static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0}; -static struct rte_flow_action end_action_bad = { -1, 0}; - -static struct rte_flow_action actions[2]; - -/* test attributes */ -static struct rte_flow_attr attr; - -/* test error */ -static struct rte_flow_error error; - -/* test pattern */ -static struct rte_flow_item pattern[4]; - -/* flow classify data for UDP burst */ -static struct rte_flow_classify_ipv4_5tuple_stats udp_ntuple_stats; -static struct rte_flow_classify_stats udp_classify_stats = { - .stats = (void *)&udp_ntuple_stats -}; - -/* flow classify data for TCP burst */ -static struct rte_flow_classify_ipv4_5tuple_stats tcp_ntuple_stats; -static struct rte_flow_classify_stats tcp_classify_stats = { - .stats = (void *)&tcp_ntuple_stats -}; - -/* flow classify data for SCTP burst */ -static struct rte_flow_classify_ipv4_5tuple_stats sctp_ntuple_stats; -static struct rte_flow_classify_stats sctp_classify_stats = { - .stats = (void *)&sctp_ntuple_stats -}; - -struct flow_classifier_acl *cls; - -struct flow_classifier_acl { - struct rte_flow_classifier *cls; -} __rte_cache_aligned; - -/* - * test functions by passing invalid or - * non-workable parameters. - */ -static int -test_invalid_parameters(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - - ret = rte_flow_classify_validate(NULL, NULL, NULL, NULL, NULL); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", - __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL, - NULL, NULL); - if (rule) { - printf("Line %i: flow_classifier_table_entry_add", __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(NULL, NULL); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL); - if (!ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL, - NULL, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add ", __LINE__); - printf("with NULL param should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(NULL, NULL); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf("with NULL param should have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL); - if (!ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" with NULL param should have failed!\n"); - return -1; - } - return 0; -} - -static int -test_valid_parameters(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int key_found; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (ret) { - printf("Line %i: rte_flow_classify_validate", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - - if (!rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - return 0; -} - -static int -test_invalid_patterns(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int key_found; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item_bad; - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - pattern[0] = eth_item; - pattern[1] = ipv4_udp_item_bad; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should have failed!\n"); - return -1; - } - - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_bad; - pattern[3] = end_item_bad; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should have failed!\n"); - return -1; - } - return 0; -} - -static int -test_invalid_actions(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int key_found; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_1; - pattern[3] = end_item; - actions[0] = count_action_bad; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should have failed!\n"); - return -1; - } - - actions[0] = count_action; - actions[1] = end_action_bad; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (!ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (!ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf("should have failed!\n"); - return -1; - } - return 0; -} - -static int -init_ipv4_udp_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 src_addr = IPV4_ADDR(2, 2, 2, 3); - uint32_t dst_addr = IPV4_ADDR(2, 2, 2, 7); - uint16_t src_port = 32; - uint16_t dst_port = 33; - uint16_t pktlen; - - static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; - static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; - - printf("Set up IPv4 UDP traffic\n"); - initialize_eth_header(&pkt_eth_hdr, - (struct ether_addr *)src_mac, - (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0); - pktlen = (uint16_t)(sizeof(struct ether_hdr)); - printf("ETH pktlen %u\n", pktlen); - - pktlen = initialize_ipv4_header(&pkt_ipv4_hdr, src_addr, dst_addr, - pktlen); - printf("ETH + IPv4 pktlen %u\n", pktlen); - - pktlen = initialize_udp_header(&pkt_udp_hdr, src_port, dst_port, - pktlen); - printf("ETH + IPv4 + UDP pktlen %u\n\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_ipv4_tcp_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 tcp_hdr pkt_tcp_hdr; - uint32_t src_addr = IPV4_ADDR(1, 2, 3, 4); - uint32_t dst_addr = IPV4_ADDR(5, 6, 7, 8); - uint16_t src_port = 16; - uint16_t dst_port = 17; - uint16_t pktlen; - - static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; - static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; - - printf("Set up IPv4 TCP traffic\n"); - initialize_eth_header(&pkt_eth_hdr, - (struct ether_addr *)src_mac, - (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0); - pktlen = (uint16_t)(sizeof(struct ether_hdr)); - printf("ETH pktlen %u\n", pktlen); - - pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr, - dst_addr, pktlen, IPPROTO_TCP); - printf("ETH + IPv4 pktlen %u\n", pktlen); - - pktlen = initialize_tcp_header(&pkt_tcp_hdr, src_port, dst_port, - pktlen); - printf("ETH + IPv4 + TCP pktlen %u\n\n", pktlen); - - return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr, - 0, &pkt_ipv4_hdr, 1, IPPROTO_TCP, - &pkt_tcp_hdr, burst_size, - PACKET_BURST_GEN_PKT_LEN, 1); -} - -static int -init_ipv4_sctp_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 sctp_hdr pkt_sctp_hdr; - uint32_t src_addr = IPV4_ADDR(11, 12, 13, 14); - uint32_t dst_addr = IPV4_ADDR(15, 16, 17, 18); - uint16_t src_port = 10; - uint16_t dst_port = 11; - uint16_t pktlen; - - static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; - static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; - - printf("Set up IPv4 SCTP traffic\n"); - initialize_eth_header(&pkt_eth_hdr, - (struct ether_addr *)src_mac, - (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0); - pktlen = (uint16_t)(sizeof(struct ether_hdr)); - printf("ETH pktlen %u\n", pktlen); - - pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr, - dst_addr, pktlen, IPPROTO_SCTP); - printf("ETH + IPv4 pktlen %u\n", pktlen); - - pktlen = initialize_sctp_header(&pkt_sctp_hdr, src_port, dst_port, - pktlen); - printf("ETH + IPv4 + SCTP pktlen %u\n\n", pktlen); - - return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr, - 0, &pkt_ipv4_hdr, 1, IPPROTO_SCTP, - &pkt_sctp_hdr, burst_size, - PACKET_BURST_GEN_PKT_LEN, 1); -} - -static int -init_mbufpool(void) -{ - int socketid; - int ret = 0; - unsigned int 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) { - printf( - "Socket %d of lcore %u is out of range %d\n", - socketid, lcore_id, NB_SOCKETS); - ret = -1; - break; - } - 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, MBUF_SIZE, - socketid); - if (mbufpool[socketid]) { - printf("Allocated mbuf pool on socket %d\n", - socketid); - } else { - printf("Cannot init mbuf pool on socket %d\n", - socketid); - ret = -ENOMEM; - break; - } - } - } - return ret; -} - -static int -test_query_udp(void) -{ - struct rte_flow_error error; - struct rte_flow_classify_rule *rule; - int ret; - int i; - int key_found; - - ret = init_ipv4_udp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); - if (ret != MAX_PKT_BURST) { - printf("Line %i: init_udp_ipv4_traffic has failed!\n", - __LINE__); - return -1; - } - - for (i = 0; i < MAX_PKT_BURST; i++) - bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_udp_item_1; - pattern[2] = udp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (ret) { - printf("Line %i: rte_flow_classify_validate", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (!rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, - rule, &udp_classify_stats); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - return 0; -} - -static int -test_query_tcp(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int i; - int key_found; - - ret = init_ipv4_tcp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); - if (ret != MAX_PKT_BURST) { - printf("Line %i: init_ipv4_tcp_traffic has failed!\n", - __LINE__); - return -1; - } - - for (i = 0; i < MAX_PKT_BURST; i++) - bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; - - /* - * set up parameters for rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_tcp_item_1; - pattern[2] = tcp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (!rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, - rule, &tcp_classify_stats); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - return 0; -} - -static int -test_query_sctp(void) -{ - struct rte_flow_classify_rule *rule; - int ret; - int i; - int key_found; - - ret = init_ipv4_sctp_traffic(mbufpool[0], bufs, MAX_PKT_BURST); - if (ret != MAX_PKT_BURST) { - printf("Line %i: init_ipv4_tcp_traffic has failed!\n", - __LINE__); - return -1; - } - - for (i = 0; i < MAX_PKT_BURST; i++) - bufs[i]->packet_type = RTE_PTYPE_L3_IPV4; - - /* - * set up parameters rte_flow_classify_validate, - * rte_flow_classify_table_entry_add and - * rte_flow_classify_table_entry_delete - */ - - attr.ingress = 1; - attr.priority = 1; - pattern[0] = eth_item; - pattern[1] = ipv4_sctp_item_1; - pattern[2] = sctp_item_1; - pattern[3] = end_item; - actions[0] = count_action; - actions[1] = end_action; - - ret = rte_flow_classify_validate(cls->cls, &attr, pattern, - actions, &error); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern, - actions, &key_found, &error); - if (!rule) { - printf("Line %i: flow_classify_table_entry_add", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST, - rule, &sctp_classify_stats); - if (ret) { - printf("Line %i: flow_classifier_query", __LINE__); - printf(" should not have failed!\n"); - return -1; - } - - ret = rte_flow_classify_table_entry_delete(cls->cls, rule); - if (ret) { - printf("Line %i: rte_flow_classify_table_entry_delete", - __LINE__); - printf(" should not have failed!\n"); - return -1; - } - return 0; -} - -static int -test_flow_classify(void) -{ - struct rte_table_acl_params table_acl_params; - struct rte_flow_classify_table_params cls_table_params; - struct rte_flow_classifier_params cls_params; - int ret; - uint32_t size; - - /* Memory allocation */ - size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct flow_classifier_acl)); - cls = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE); - - cls_params.name = "flow_classifier"; - cls_params.socket_id = 0; - cls->cls = rte_flow_classifier_create(&cls_params); - - /* initialise ACL table params */ - table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs); - table_acl_params.name = "table_acl_ipv4_5tuple"; - table_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM; - memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs)); - - /* initialise table create params */ - cls_table_params.ops = &rte_table_acl_ops; - cls_table_params.arg_create = &table_acl_params; - cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE; - - ret = rte_flow_classify_table_create(cls->cls, &cls_table_params); - if (ret) { - printf("Line %i: f_create has failed!\n", __LINE__); - rte_flow_classifier_free(cls->cls); - rte_free(cls); - return TEST_FAILED; - } - printf("Created table_acl for for IPv4 five tuple packets\n"); - - ret = init_mbufpool(); - if (ret) { - printf("Line %i: init_mbufpool has failed!\n", __LINE__); - return TEST_FAILED; - } - - if (test_invalid_parameters() < 0) - return TEST_FAILED; - if (test_valid_parameters() < 0) - return TEST_FAILED; - if (test_invalid_patterns() < 0) - return TEST_FAILED; - if (test_invalid_actions() < 0) - return TEST_FAILED; - if (test_query_udp() < 0) - return TEST_FAILED; - if (test_query_tcp() < 0) - return TEST_FAILED; - if (test_query_sctp() < 0) - return TEST_FAILED; - - return TEST_SUCCESS; -} - -REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify); diff --git a/test/test/test_flow_classify.h b/test/test/test_flow_classify.h deleted file mode 100644 index 6bd10ec972..0000000000 --- a/test/test/test_flow_classify.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#ifndef TEST_FLOW_CLASSIFY_H_ -#define TEST_FLOW_CLASSIFY_H_ - -/* ACL field definitions for IPv4 5 tuple rule */ - -enum { - PROTO_FIELD_IPV4, - SRC_FIELD_IPV4, - DST_FIELD_IPV4, - SRCP_FIELD_IPV4, - DSTP_FIELD_IPV4, - NUM_FIELDS_IPV4 -}; - -enum { - PROTO_INPUT_IPV4, - SRC_INPUT_IPV4, - DST_INPUT_IPV4, - SRCP_DESTP_INPUT_IPV4 -}; - -#endif /* TEST_FLOW_CLASSIFY_H_ */ diff --git a/test/test/test_func_reentrancy.c b/test/test/test_func_reentrancy.c deleted file mode 100644 index e27d1e020f..0000000000 --- a/test/test/test_func_reentrancy.c +++ /dev/null @@ -1,498 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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_MULTI (16) -#define MAX_ITER_ONCE (4) -#define MAX_LPM_ITER_TIMES (6) - -#define MEMPOOL_ELT_SIZE (sizeof(uint32_t)) -#define MEMPOOL_SIZE (4) - -#define MAX_LCORES (RTE_MAX_MEMZONE / (MAX_ITER_MULTI * 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 void -ring_clean(unsigned int lcore_id) -{ - struct rte_ring *rp; - char ring_name[MAX_STRING_SIZE]; - int i; - - for (i = 0; i < MAX_ITER_MULTI; i++) { - snprintf(ring_name, sizeof(ring_name), - "fr_test_%d_%d", lcore_id, i); - rp = rte_ring_lookup(ring_name); - if (rp != NULL) - rte_ring_free(rp); - } -} - -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_ONCE; 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_MULTI; 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 successful */ - 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 void -mempool_clean(unsigned int lcore_id) -{ - struct rte_mempool *mp; - char mempool_name[MAX_STRING_SIZE]; - int i; - - /* verify all ring created successful */ - for (i = 0; i < MAX_ITER_MULTI; i++) { - snprintf(mempool_name, sizeof(mempool_name), "fr_test_%d_%d", - lcore_id, i); - mp = rte_mempool_lookup(mempool_name); - if (mp != NULL) - rte_mempool_free(mp); - } -} - -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_ONCE; 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_MULTI; 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 successful */ - 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_MULTI; 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_ONCE; 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_MULTI; 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 */ - 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_MULTI; 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_ONCE; 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_MULTI; 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 */ - 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 int 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_ONCE; 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 */ - 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, ring_clean, "ring create/lookup" }, - { mempool_create_lookup, NULL, mempool_clean, - "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 deleted file mode 100644 index fe607fadf2..0000000000 --- a/test/test/test_hash.c +++ /dev/null @@ -1,1778 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2015 Intel Corporation - */ - -#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; -} - -#define UNIT_TEST_HASH_VERBOSE 0 -/* - * Print out result of unit test hash operation. - */ -static void print_key_info(const char *msg, const struct flow_key *key, - int32_t pos) -{ - if (UNIT_TEST_HASH_VERBOSE) { - 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(" @ pos %d\n", pos); - } -} - -/* 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) - * - * Repeat the test case when 'free on delete' is disabled. - * - add - * - lookup (hit) - * - delete - * - lookup (miss) - * - free - */ -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, delPos1; - - ut_params.extra_flag = RTE_HASH_EXTRA_FLAGS_NO_FREE_ON_DEL; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - ut_params.extra_flag = 0; - - 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); - delPos1 = 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); - - pos1 = rte_hash_free_key_with_position(handle, delPos1); - print_key_info("Free", &keys[0], delPos1); - RETURN_IF_ERROR(pos1 != 0, - "failed to free key (pos1=%d)", delPos1); - - 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 a single key with 'disable free on del' set: - * - delete: miss - * - add - * - lookup: hit - * - add: update - * - lookup: hit (updated data) - * - delete: hit - * - delete: miss - * - lookup: miss - * - free: hit - * - lookup: miss - */ -static int test_add_update_delete_free(void) -{ - struct rte_hash *handle; - int pos0, expectedPos0, delPos0, result; - - ut_params.name = "test2"; - ut_params.extra_flag = RTE_HASH_EXTRA_FLAGS_NO_FREE_ON_DEL; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - ut_params.extra_flag = 0; - - 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); - - delPos0 = rte_hash_del_key(handle, &keys[0]); - print_key_info("Del", &keys[0], delPos0); - RETURN_IF_ERROR(delPos0 != expectedPos0, - "failed to delete key (pos0=%d)", delPos0); - - 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); - - result = rte_hash_free_key_with_position(handle, delPos0); - print_key_info("Free", &keys[0], delPos0); - RETURN_IF_ERROR(result != 0, - "failed to free key (pos1=%d)", delPos0); - - 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 - * - * Repeat the test case when 'free on delete' is disabled. - * - create table - * - add key - * - get the key with its position: hit - * - delete key - * - try to get the deleted key: hit - * - free 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, delPos, 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); - - ut_params.name = "hash_get_key_w_pos"; - ut_params.extra_flag = RTE_HASH_EXTRA_FLAGS_NO_FREE_ON_DEL; - handle = rte_hash_create(&ut_params); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - ut_params.extra_flag = 0; - - 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"); - - delPos = rte_hash_del_key(handle, &keys[0]); - print_key_info("Del", &keys[0], delPos); - RETURN_IF_ERROR(delPos != expectedPos, - "failed to delete key (pos0=%d)", delPos); - - result = rte_hash_get_key_with_position(handle, delPos, &key); - RETURN_IF_ERROR(result != -ENOENT, "non valid key retrieved"); - - result = rte_hash_free_key_with_position(handle, delPos); - print_key_info("Free", &keys[0], delPos); - RETURN_IF_ERROR(result != 0, - "failed to free key (pos1=%d)", delPos); - - result = rte_hash_get_key_with_position(handle, delPos, &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; -} - -/* - * Similar to the test above (full bucket test), but for extendable buckets. - */ -static int test_extendable_bucket(void) -{ - struct rte_hash_parameters params_pseudo_hash = { - .name = "test5", - .entries = 64, - .key_len = sizeof(struct flow_key), /* 13 */ - .hash_func = pseudo_hash, - .hash_func_init_val = 0, - .socket_id = 0, - .extra_flag = RTE_HASH_EXTRA_FLAGS_EXT_TABLE - }; - struct rte_hash *handle; - int pos[64]; - int expected_pos[64]; - unsigned int i; - struct flow_key rand_keys[64]; - - for (i = 0; i < 64; i++) { - rand_keys[i].port_dst = i; - rand_keys[i].port_src = i+1; - } - - handle = rte_hash_create(¶ms_pseudo_hash); - RETURN_IF_ERROR(handle == NULL, "hash creation failed"); - - /* Fill bucket */ - for (i = 0; i < 64; i++) { - pos[i] = rte_hash_add_key(handle, &rand_keys[i]); - print_key_info("Add", &rand_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 < 64; i++) { - pos[i] = rte_hash_lookup(handle, &rand_keys[i]); - print_key_info("Lkp", &rand_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 < 64; i++) { - pos[i] = rte_hash_add_key(handle, &rand_keys[i]); - print_key_info("Add", &rand_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 < 64; i++) { - pos[i] = rte_hash_lookup(handle, &rand_keys[i]); - print_key_info("Lkp", &rand_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[35] = rte_hash_del_key(handle, &rand_keys[35]); - print_key_info("Del", &rand_keys[35], pos[35]); - RETURN_IF_ERROR(pos[35] != expected_pos[35], - "failed to delete key (pos[1]=%d)", pos[35]); - pos[20] = rte_hash_lookup(handle, &rand_keys[20]); - print_key_info("Lkp", &rand_keys[20], pos[20]); - RETURN_IF_ERROR(pos[20] != expected_pos[20], - "failed lookup after deleting key from same bucket " - "(pos[20]=%d)", pos[20]); - - /* Go back to previous state */ - pos[35] = rte_hash_add_key(handle, &rand_keys[35]); - print_key_info("Add", &rand_keys[35], pos[35]); - expected_pos[35] = pos[35]; - RETURN_IF_ERROR(pos[35] < 0, "failed to add key (pos[1]=%d)", pos[35]); - - /* Delete */ - for (i = 0; i < 64; i++) { - pos[i] = rte_hash_del_key(handle, &rand_keys[i]); - print_key_info("Del", &rand_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 < 64; i++) { - pos[i] = rte_hash_lookup(handle, &rand_keys[i]); - print_key_info("Lkp", &rand_keys[i], pos[i]); - RETURN_IF_ERROR(pos[i] != -ENOENT, - "fail: found non-existent key (pos[%u]=%d)", i, pos[i]); - } - - /* Add again */ - for (i = 0; i < 64; i++) { - pos[i] = rte_hash_add_key(handle, &rand_keys[i]); - print_key_info("Add", &rand_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]; - } - - 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 successfully 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 successfully 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 successfully 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 successfully 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 successfully 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(uint32_t ext_table) -{ - struct rte_hash *handle; - uint8_t simple_key[MAX_KEYSIZE]; - unsigned i, j; - unsigned added_keys, average_keys_added = 0; - int ret; - unsigned int cnt; - - printf("\n# Running test to determine average utilization" - "\n before adding elements begins to fail\n"); - if (ext_table) - printf("ext table is enabled\n"); - else - printf("ext table is disabled\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; - if (ext_table) - ut_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE; - else - ut_params.extra_flag &= ~RTE_HASH_EXTRA_FLAGS_EXT_TABLE; - - 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 < 0) - break; - } - - if (ret != -ENOSPC) { - printf("Unexpected error when adding keys\n"); - rte_hash_free(handle); - return -1; - } - - cnt = rte_hash_count(handle); - if (cnt != added_keys) { - printf("rte_hash_count returned wrong value %u, %u," - "%u\n", j, added_keys, cnt); - rte_hash_free(handle); - return -1; - } - if (ext_table) { - if (cnt != ut_params.entries) { - printf("rte_hash_count returned wrong value " - "%u, %u, %u\n", j, added_keys, cnt); - 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(uint32_t ext_table) -{ - 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; - if (ext_table) - ut_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE; - else - ut_params.extra_flag &= ~RTE_HASH_EXTRA_FLAGS_EXT_TABLE; - - 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) { - if (ext_table) { - printf("Insertion failed for ext table\n"); - goto err; - } - 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_add_update_delete_free() < 0) - return -1; - if (test_five_keys() < 0) - return -1; - if (test_full_bucket() < 0) - return -1; - if (test_extendable_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; - - /* ext table disabled */ - if (test_average_table_utilization(0) < 0) - return -1; - if (test_hash_iteration(0) < 0) - return -1; - - /* ext table enabled */ - if (test_average_table_utilization(1) < 0) - return -1; - if (test_hash_iteration(1) < 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 deleted file mode 100644 index c1fc9492d5..0000000000 --- a/test/test/test_hash_functions.c +++ /dev/null @@ -1,293 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2015 Intel Corporation - */ - -#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 deleted file mode 100644 index 50018db56c..0000000000 --- a/test/test/test_hash_multiwriter.c +++ /dev/null @@ -1,294 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016 Intel Corporation - */ - -#include -#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 = 5*1024*1024; -const uint32_t nb_total_tsx_insertion = 4.5*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(void *arg) -{ - uint64_t i, offset; - uint16_t pos_core; - uint32_t lcore_id = rte_lcore_id(); - uint64_t begin, cycles; - uint16_t *enabled_core_ids = (uint16_t *)arg; - - for (pos_core = 0; pos_core < rte_lcore_count(); pos_core++) { - if (enabled_core_ids[pos_core] == lcore_id) - break; - } - - /* - * Calculate offset for entries based on the position of the - * logical core, from the master core (not counting not enabled cores) - */ - offset = pos_core * 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 - 1); - - 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; - uint16_t enabled_core_ids[RTE_MAX_LCORE]; - uint16_t core_id; - - uint32_t *keys; - uint32_t *found; - - struct rte_hash_parameters hash_params = { - .entries = nb_entries, - .key_len = sizeof(uint32_t), - .hash_func = rte_jhash, - .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; - uint32_t count; - - 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; - } - - for (i = 0; i < nb_entries; i++) - keys[i] = i; - - tbl_multiwriter_test_params.keys = keys; - - found = rte_zmalloc(NULL, sizeof(uint32_t) * nb_entries, 0); - if (found == NULL) { - printf("RTE_ZMALLOC failed\n"); - goto err2; - } - - tbl_multiwriter_test_params.found = found; - - rte_atomic64_init(&gcycles); - rte_atomic64_clear(&gcycles); - - rte_atomic64_init(&ginsertions); - rte_atomic64_clear(&ginsertions); - - /* Get list of enabled cores */ - i = 0; - for (core_id = 0; core_id < RTE_MAX_LCORE; core_id++) { - if (i == rte_lcore_count()) - break; - - if (rte_lcore_is_enabled(core_id)) { - enabled_core_ids[i] = core_id; - i++; - } - } - - if (i != rte_lcore_count()) { - printf("Number of enabled cores in list is different from " - "number given by rte_lcore_count()\n"); - goto err3; - } - - /* Fire all threads. */ - rte_eal_mp_remote_launch(test_hash_multiwriter_worker, - enabled_core_ids, CALL_MASTER); - rte_eal_mp_wait_lcore(); - - count = rte_hash_count(handle); - if (count != rounded_nb_total_tsx_insertion) { - printf("rte_hash_count returned wrong value %u, %d\n", - rounded_nb_total_tsx_insertion, count); - goto err3; - } - - 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 deleted file mode 100644 index 5252111803..0000000000 --- a/test/test/test_hash_perf.c +++ /dev/null @@ -1,699 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2015 Intel Corporation - */ - -#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) -#define ADD_PERCENT 0.75 /* 75% table utilization */ -#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ -/* BUCKET_SIZE should be same as RTE_HASH_BUCKET_ENTRIES in rte_hash library */ -#define BUCKET_SIZE 8 -#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 int with_data, unsigned int table_index, - unsigned int with_locks, unsigned int ext) -{ - 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]); - - - if (with_locks) - ut_params.extra_flag = - RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT - | RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY; - else - ut_params.extra_flag = 0; - - if (ext) - ut_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE; - - 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 int table_index, unsigned int ext) -{ - unsigned i; - uint32_t swap_idx; - uint8_t temp_key[MAX_KEYSIZE]; - hash_sig_t temp_signature; - int32_t temp_position; - unsigned int keys_to_add; - - if (!ext) - keys_to_add = KEYS_TO_ADD * ADD_PERCENT; - else - keys_to_add = KEYS_TO_ADD; - - 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 int with_pushes, unsigned int table_index, - unsigned int ext) -{ - unsigned i, j; - unsigned bucket_idx, incr, success = 1; - uint8_t k = 0; - int32_t ret; - const uint32_t bucket_bitmask = NUM_BUCKETS - 1; - unsigned int keys_to_add; - - if (!ext) - keys_to_add = KEYS_TO_ADD * ADD_PERCENT; - else - keys_to_add = KEYS_TO_ADD; - /* 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 int with_hash, unsigned int with_data, - unsigned int table_index, unsigned int ext) -{ - unsigned i; - const uint64_t start_tsc = rte_rdtsc(); - void *data; - int32_t ret; - unsigned int keys_to_add; - if (!ext) - keys_to_add = KEYS_TO_ADD * ADD_PERCENT; - else - keys_to_add = KEYS_TO_ADD; - - 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("H+D: Failed to add key number %u\n", i); - 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("H: Failed to add key number %u\n", i); - 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("D: Failed to add key number %u\n", i); - 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", i); - 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 int with_hash, unsigned int with_data, - unsigned int table_index, unsigned int ext) -{ - unsigned i, j; - const uint64_t start_tsc = rte_rdtsc(); - void *ret_data; - void *expected_data; - int32_t ret; - unsigned int keys_to_add, num_lookups; - - if (!ext) { - keys_to_add = KEYS_TO_ADD * ADD_PERCENT; - num_lookups = NUM_LOOKUPS * ADD_PERCENT; - } else { - keys_to_add = KEYS_TO_ADD; - num_lookups = NUM_LOOKUPS; - } - 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 int with_data, unsigned int table_index, - unsigned int ext) -{ - 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; - unsigned int keys_to_add, num_lookups; - - if (!ext) { - keys_to_add = KEYS_TO_ADD * ADD_PERCENT; - num_lookups = NUM_LOOKUPS * ADD_PERCENT; - } else { - keys_to_add = KEYS_TO_ADD; - num_lookups = NUM_LOOKUPS; - } - - 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 int with_hash, unsigned int with_data, - unsigned int table_index, unsigned int ext) -{ - unsigned i; - const uint64_t start_tsc = rte_rdtsc(); - int32_t ret; - unsigned int keys_to_add; - if (!ext) - keys_to_add = KEYS_TO_ADD * ADD_PERCENT; - else - keys_to_add = KEYS_TO_ADD; - - 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 delete key number %u\n", i); - 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 int with_pushes, unsigned int with_locks, - unsigned int ext) -{ - 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, with_locks, ext) < 0) - return -1; - - if (get_input_keys(with_pushes, i, ext) < 0) - return -1; - for (with_hash = 0; with_hash <= 1; with_hash++) { - if (timed_adds(with_hash, with_data, i, ext) < 0) - return -1; - - for (j = 0; j < NUM_SHUFFLES; j++) - shuffle_input_keys(i, ext); - - if (timed_lookups(with_hash, with_data, i, ext) < 0) - return -1; - - if (timed_lookups_multi(with_data, i, ext) < 0) - return -1; - - if (timed_deletes(with_hash, with_data, i, ext) < 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 int with_pushes, with_locks; - for (with_locks = 0; with_locks <= 1; with_locks++) { - if (with_locks) - printf("\nWith locks in the code\n"); - else - printf("\nWithout locks in the code\n"); - 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, with_locks, 0) < 0) - return -1; - } - } - - printf("\n EXTENDABLE BUCKETS PERFORMANCE\n"); - - if (run_all_tbl_perf_tests(1, 0, 1) < 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_readwrite.c b/test/test/test_hash_readwrite.c deleted file mode 100644 index 480ae97d85..0000000000 --- a/test/test/test_hash_readwrite.c +++ /dev/null @@ -1,709 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#define RTE_RWTEST_FAIL 0 - -#define TOTAL_ENTRY (5*1024*1024) -#define TOTAL_INSERT (4.5*1024*1024) -#define TOTAL_INSERT_EXT (5*1024*1024) - -#define NUM_TEST 3 -unsigned int core_cnt[NUM_TEST] = {2, 4, 8}; - -unsigned int slave_core_ids[RTE_MAX_LCORE]; -struct perf { - uint32_t single_read; - uint32_t single_write; - uint32_t read_only[NUM_TEST]; - uint32_t write_only[NUM_TEST]; - uint32_t read_write_r[NUM_TEST]; - uint32_t read_write_w[NUM_TEST]; -}; - -static struct perf htm_results, non_htm_results; - -struct { - uint32_t *keys; - uint8_t *found; - uint32_t num_insert; - uint32_t rounded_tot_insert; - struct rte_hash *h; -} tbl_rw_test_param; - -static rte_atomic64_t gcycles; -static rte_atomic64_t ginsertions; - -static rte_atomic64_t gread_cycles; -static rte_atomic64_t gwrite_cycles; - -static rte_atomic64_t greads; -static rte_atomic64_t gwrites; - -static int -test_hash_readwrite_worker(__attribute__((unused)) void *arg) -{ - uint64_t i, offset; - uint32_t lcore_id = rte_lcore_id(); - uint64_t begin, cycles; - int *ret; - - ret = rte_malloc(NULL, sizeof(int) * - tbl_rw_test_param.num_insert, 0); - for (i = 0; i < rte_lcore_count(); i++) { - if (slave_core_ids[i] == lcore_id) - break; - } - offset = tbl_rw_test_param.num_insert * i; - - printf("Core #%d inserting and reading %d: %'"PRId64" - %'"PRId64"\n", - lcore_id, tbl_rw_test_param.num_insert, - offset, offset + tbl_rw_test_param.num_insert - 1); - - begin = rte_rdtsc_precise(); - - for (i = offset; i < offset + tbl_rw_test_param.num_insert; i++) { - - if (rte_hash_lookup(tbl_rw_test_param.h, - tbl_rw_test_param.keys + i) > 0) - break; - - ret[i - offset] = rte_hash_add_key(tbl_rw_test_param.h, - tbl_rw_test_param.keys + i); - if (ret[i - offset] < 0) - break; - - /* lookup a random key */ - uint32_t rand = rte_rand() % (i + 1 - offset); - - if (rte_hash_lookup(tbl_rw_test_param.h, - tbl_rw_test_param.keys + rand) != ret[rand]) - break; - - - if (rte_hash_del_key(tbl_rw_test_param.h, - tbl_rw_test_param.keys + rand) != ret[rand]) - break; - - ret[rand] = rte_hash_add_key(tbl_rw_test_param.h, - tbl_rw_test_param.keys + rand); - if (ret[rand] < 0) - break; - - if (rte_hash_lookup(tbl_rw_test_param.h, - tbl_rw_test_param.keys + rand) != ret[rand]) - break; - } - - cycles = rte_rdtsc_precise() - begin; - rte_atomic64_add(&gcycles, cycles); - rte_atomic64_add(&ginsertions, i - offset); - - for (; i < offset + tbl_rw_test_param.num_insert; i++) - tbl_rw_test_param.keys[i] = RTE_RWTEST_FAIL; - - rte_free(ret); - return 0; -} - -static int -init_params(int use_ext, int use_htm, int use_jhash) -{ - unsigned int i; - - uint32_t *keys = NULL; - uint8_t *found = NULL; - struct rte_hash *handle; - - struct rte_hash_parameters hash_params = { - .entries = TOTAL_ENTRY, - .key_len = sizeof(uint32_t), - .hash_func_init_val = 0, - .socket_id = rte_socket_id(), - }; - if (use_jhash) - hash_params.hash_func = rte_jhash; - else - hash_params.hash_func = rte_hash_crc; - - if (use_htm) - hash_params.extra_flag = - RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT | - RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | - RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; - else - hash_params.extra_flag = - RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | - RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; - - if (use_ext) - hash_params.extra_flag |= - RTE_HASH_EXTRA_FLAGS_EXT_TABLE; - else - hash_params.extra_flag &= - ~RTE_HASH_EXTRA_FLAGS_EXT_TABLE; - - hash_params.name = "tests"; - - handle = rte_hash_create(&hash_params); - if (handle == NULL) { - printf("hash creation failed"); - return -1; - } - - tbl_rw_test_param.h = handle; - keys = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_ENTRY, 0); - - if (keys == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - found = rte_zmalloc(NULL, sizeof(uint8_t) * TOTAL_ENTRY, 0); - if (found == NULL) { - printf("RTE_ZMALLOC failed\n"); - goto err; - } - - tbl_rw_test_param.keys = keys; - tbl_rw_test_param.found = found; - - for (i = 0; i < TOTAL_ENTRY; i++) - keys[i] = i; - - return 0; - -err: - rte_free(keys); - rte_hash_free(handle); - - return -1; -} - -static int -test_hash_readwrite_functional(int use_ext, int use_htm) -{ - unsigned int i; - const void *next_key; - void *next_data; - uint32_t iter = 0; - - uint32_t duplicated_keys = 0; - uint32_t lost_keys = 0; - int use_jhash = 1; - int slave_cnt = rte_lcore_count() - 1; - uint32_t tot_insert = 0; - - rte_atomic64_init(&gcycles); - rte_atomic64_clear(&gcycles); - - rte_atomic64_init(&ginsertions); - rte_atomic64_clear(&ginsertions); - - if (init_params(use_ext, use_htm, use_jhash) != 0) - goto err; - - if (use_ext) - tot_insert = TOTAL_INSERT_EXT; - else - tot_insert = TOTAL_INSERT; - - tbl_rw_test_param.num_insert = - tot_insert / slave_cnt; - - tbl_rw_test_param.rounded_tot_insert = - tbl_rw_test_param.num_insert - * slave_cnt; - - printf("++++++++Start function tests:+++++++++\n"); - - /* Fire all threads. */ - rte_eal_mp_remote_launch(test_hash_readwrite_worker, - NULL, SKIP_MASTER); - rte_eal_mp_wait_lcore(); - - while (rte_hash_iterate(tbl_rw_test_param.h, &next_key, - &next_data, &iter) >= 0) { - /* Search for the key in the list of keys added .*/ - i = *(const uint32_t *)next_key; - tbl_rw_test_param.found[i]++; - } - - for (i = 0; i < tbl_rw_test_param.rounded_tot_insert; i++) { - if (tbl_rw_test_param.keys[i] != RTE_RWTEST_FAIL) { - if (tbl_rw_test_param.found[i] > 1) { - duplicated_keys++; - break; - } - if (tbl_rw_test_param.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 err_free; - } - - if (lost_keys > 0) { - printf("%d key lost\n", lost_keys); - goto err_free; - } - - printf("No key corrupted during read-write test.\n"); - - unsigned long long int cycles_per_insertion = - rte_atomic64_read(&gcycles) / - rte_atomic64_read(&ginsertions); - - printf("cycles per insertion and lookup: %llu\n", cycles_per_insertion); - - rte_free(tbl_rw_test_param.found); - rte_free(tbl_rw_test_param.keys); - rte_hash_free(tbl_rw_test_param.h); - printf("+++++++++Complete function tests+++++++++\n"); - return 0; - -err_free: - rte_free(tbl_rw_test_param.found); - rte_free(tbl_rw_test_param.keys); - rte_hash_free(tbl_rw_test_param.h); -err: - return -1; -} - -static int -test_rw_reader(void *arg) -{ - uint64_t i; - uint64_t begin, cycles; - uint64_t read_cnt = (uint64_t)((uintptr_t)arg); - - begin = rte_rdtsc_precise(); - for (i = 0; i < read_cnt; i++) { - void *data; - rte_hash_lookup_data(tbl_rw_test_param.h, - tbl_rw_test_param.keys + i, - &data); - if (i != (uint64_t)(uintptr_t)data) { - printf("lookup find wrong value %"PRIu64"," - "%"PRIu64"\n", i, - (uint64_t)(uintptr_t)data); - break; - } - } - - cycles = rte_rdtsc_precise() - begin; - rte_atomic64_add(&gread_cycles, cycles); - rte_atomic64_add(&greads, i); - return 0; -} - -static int -test_rw_writer(void *arg) -{ - uint64_t i; - uint32_t lcore_id = rte_lcore_id(); - uint64_t begin, cycles; - int ret; - uint64_t start_coreid = (uint64_t)(uintptr_t)arg; - uint64_t offset; - - for (i = 0; i < rte_lcore_count(); i++) { - if (slave_core_ids[i] == lcore_id) - break; - } - - offset = TOTAL_INSERT / 2 + (i - (start_coreid)) * - tbl_rw_test_param.num_insert; - begin = rte_rdtsc_precise(); - for (i = offset; i < offset + tbl_rw_test_param.num_insert; i++) { - ret = rte_hash_add_key_data(tbl_rw_test_param.h, - tbl_rw_test_param.keys + i, - (void *)((uintptr_t)i)); - if (ret < 0) { - printf("writer failed %"PRIu64"\n", i); - break; - } - } - - cycles = rte_rdtsc_precise() - begin; - rte_atomic64_add(&gwrite_cycles, cycles); - rte_atomic64_add(&gwrites, tbl_rw_test_param.num_insert); - return 0; -} - -static int -test_hash_readwrite_perf(struct perf *perf_results, int use_htm, - int reader_faster) -{ - unsigned int n; - int ret; - int start_coreid; - uint64_t i, read_cnt; - - const void *next_key; - void *next_data; - uint32_t iter; - int use_jhash = 0; - - uint32_t duplicated_keys = 0; - uint32_t lost_keys = 0; - - uint64_t start = 0, end = 0; - - rte_atomic64_init(&greads); - rte_atomic64_init(&gwrites); - rte_atomic64_clear(&gwrites); - rte_atomic64_clear(&greads); - - rte_atomic64_init(&gread_cycles); - rte_atomic64_clear(&gread_cycles); - rte_atomic64_init(&gwrite_cycles); - rte_atomic64_clear(&gwrite_cycles); - - if (init_params(0, use_htm, use_jhash) != 0) - goto err; - - /* - * Do a readers finish faster or writers finish faster test. - * When readers finish faster, we timing the readers, and when writers - * finish faster, we timing the writers. - * Divided by 10 or 2 is just experimental values to vary the workload - * of readers. - */ - if (reader_faster) { - printf("++++++Start perf test: reader++++++++\n"); - read_cnt = TOTAL_INSERT / 10; - } else { - printf("++++++Start perf test: writer++++++++\n"); - read_cnt = TOTAL_INSERT / 2; - } - - /* We first test single thread performance */ - start = rte_rdtsc_precise(); - /* Insert half of the keys */ - for (i = 0; i < TOTAL_INSERT / 2; i++) { - ret = rte_hash_add_key_data(tbl_rw_test_param.h, - tbl_rw_test_param.keys + i, - (void *)((uintptr_t)i)); - if (ret < 0) { - printf("Failed to insert half of keys\n"); - goto err_free; - } - } - end = rte_rdtsc_precise() - start; - perf_results->single_write = end / i; - - start = rte_rdtsc_precise(); - - for (i = 0; i < read_cnt; i++) { - void *data; - rte_hash_lookup_data(tbl_rw_test_param.h, - tbl_rw_test_param.keys + i, - &data); - if (i != (uint64_t)(uintptr_t)data) { - printf("lookup find wrong value" - " %"PRIu64",%"PRIu64"\n", i, - (uint64_t)(uintptr_t)data); - break; - } - } - end = rte_rdtsc_precise() - start; - perf_results->single_read = end / i; - - for (n = 0; n < NUM_TEST; n++) { - unsigned int tot_slave_lcore = rte_lcore_count() - 1; - if (tot_slave_lcore < core_cnt[n] * 2) - goto finish; - - rte_atomic64_clear(&greads); - rte_atomic64_clear(&gread_cycles); - rte_atomic64_clear(&gwrites); - rte_atomic64_clear(&gwrite_cycles); - - rte_hash_reset(tbl_rw_test_param.h); - - tbl_rw_test_param.num_insert = TOTAL_INSERT / 2 / core_cnt[n]; - tbl_rw_test_param.rounded_tot_insert = TOTAL_INSERT / 2 + - tbl_rw_test_param.num_insert * - core_cnt[n]; - - for (i = 0; i < TOTAL_INSERT / 2; i++) { - ret = rte_hash_add_key_data(tbl_rw_test_param.h, - tbl_rw_test_param.keys + i, - (void *)((uintptr_t)i)); - if (ret < 0) { - printf("Failed to insert half of keys\n"); - goto err_free; - } - } - - /* Then test multiple thread case but only all reads or - * all writes - */ - - /* Test only reader cases */ - for (i = 0; i < core_cnt[n]; i++) - rte_eal_remote_launch(test_rw_reader, - (void *)(uintptr_t)read_cnt, - slave_core_ids[i]); - - rte_eal_mp_wait_lcore(); - - start_coreid = i; - /* Test only writer cases */ - for (; i < core_cnt[n] * 2; i++) - rte_eal_remote_launch(test_rw_writer, - (void *)((uintptr_t)start_coreid), - slave_core_ids[i]); - - rte_eal_mp_wait_lcore(); - - if (reader_faster) { - unsigned long long int cycles_per_insertion = - rte_atomic64_read(&gread_cycles) / - rte_atomic64_read(&greads); - perf_results->read_only[n] = cycles_per_insertion; - printf("Reader only: cycles per lookup: %llu\n", - cycles_per_insertion); - } - - else { - unsigned long long int cycles_per_insertion = - rte_atomic64_read(&gwrite_cycles) / - rte_atomic64_read(&gwrites); - perf_results->write_only[n] = cycles_per_insertion; - printf("Writer only: cycles per writes: %llu\n", - cycles_per_insertion); - } - - rte_atomic64_clear(&greads); - rte_atomic64_clear(&gread_cycles); - rte_atomic64_clear(&gwrites); - rte_atomic64_clear(&gwrite_cycles); - - rte_hash_reset(tbl_rw_test_param.h); - - for (i = 0; i < TOTAL_INSERT / 2; i++) { - ret = rte_hash_add_key_data(tbl_rw_test_param.h, - tbl_rw_test_param.keys + i, - (void *)((uintptr_t)i)); - if (ret < 0) { - printf("Failed to insert half of keys\n"); - goto err_free; - } - } - - start_coreid = core_cnt[n]; - - if (reader_faster) { - for (i = core_cnt[n]; i < core_cnt[n] * 2; i++) - rte_eal_remote_launch(test_rw_writer, - (void *)((uintptr_t)start_coreid), - slave_core_ids[i]); - for (i = 0; i < core_cnt[n]; i++) - rte_eal_remote_launch(test_rw_reader, - (void *)(uintptr_t)read_cnt, - slave_core_ids[i]); - } else { - for (i = 0; i < core_cnt[n]; i++) - rte_eal_remote_launch(test_rw_reader, - (void *)(uintptr_t)read_cnt, - slave_core_ids[i]); - for (; i < core_cnt[n] * 2; i++) - rte_eal_remote_launch(test_rw_writer, - (void *)((uintptr_t)start_coreid), - slave_core_ids[i]); - } - - rte_eal_mp_wait_lcore(); - - iter = 0; - memset(tbl_rw_test_param.found, 0, TOTAL_ENTRY); - while (rte_hash_iterate(tbl_rw_test_param.h, - &next_key, &next_data, &iter) >= 0) { - /* Search for the key in the list of keys added .*/ - i = *(const uint32_t *)next_key; - tbl_rw_test_param.found[i]++; - } - - for (i = 0; i < tbl_rw_test_param.rounded_tot_insert; i++) { - if (tbl_rw_test_param.keys[i] != RTE_RWTEST_FAIL) { - if (tbl_rw_test_param.found[i] > 1) { - duplicated_keys++; - break; - } - if (tbl_rw_test_param.found[i] == 0) { - lost_keys++; - printf("key %"PRIu64" is lost\n", i); - break; - } - } - } - - if (duplicated_keys > 0) { - printf("%d key duplicated\n", duplicated_keys); - goto err_free; - } - - if (lost_keys > 0) { - printf("%d key lost\n", lost_keys); - goto err_free; - } - - printf("No key corrupted during read-write test.\n"); - - if (reader_faster) { - unsigned long long int cycles_per_insertion = - rte_atomic64_read(&gread_cycles) / - rte_atomic64_read(&greads); - perf_results->read_write_r[n] = cycles_per_insertion; - printf("Read-write cycles per lookup: %llu\n", - cycles_per_insertion); - } - - else { - unsigned long long int cycles_per_insertion = - rte_atomic64_read(&gwrite_cycles) / - rte_atomic64_read(&gwrites); - perf_results->read_write_w[n] = cycles_per_insertion; - printf("Read-write cycles per writes: %llu\n", - cycles_per_insertion); - } - } - -finish: - rte_free(tbl_rw_test_param.found); - rte_free(tbl_rw_test_param.keys); - rte_hash_free(tbl_rw_test_param.h); - return 0; - -err_free: - rte_free(tbl_rw_test_param.found); - rte_free(tbl_rw_test_param.keys); - rte_hash_free(tbl_rw_test_param.h); - -err: - return -1; -} - -static int -test_hash_readwrite_main(void) -{ - /* - * Variables used to choose different tests. - * use_htm indicates if hardware transactional memory should be used. - * reader_faster indicates if the reader threads should finish earlier - * than writer threads. This is to timing either reader threads or - * writer threads for performance numbers. - */ - int use_htm, use_ext, reader_faster; - unsigned int i = 0, core_id = 0; - - if (rte_lcore_count() <= 2) { - printf("More than two lcores are required " - "to do read write test\n"); - return -1; - } - - RTE_LCORE_FOREACH_SLAVE(core_id) { - slave_core_ids[i] = core_id; - i++; - } - - setlocale(LC_NUMERIC, ""); - - if (rte_tm_supported()) { - printf("Hardware transactional memory (lock elision) " - "is supported\n"); - - printf("Test read-write with Hardware transactional memory\n"); - - use_htm = 1; - use_ext = 0; - - if (test_hash_readwrite_functional(use_ext, use_htm) < 0) - return -1; - - use_ext = 1; - if (test_hash_readwrite_functional(use_ext, use_htm) < 0) - return -1; - - reader_faster = 1; - if (test_hash_readwrite_perf(&htm_results, use_htm, - reader_faster) < 0) - return -1; - - reader_faster = 0; - if (test_hash_readwrite_perf(&htm_results, use_htm, - reader_faster) < 0) - return -1; - } else { - printf("Hardware transactional memory (lock elision) " - "is NOT supported\n"); - } - - printf("Test read-write without Hardware transactional memory\n"); - use_htm = 0; - use_ext = 0; - if (test_hash_readwrite_functional(use_ext, use_htm) < 0) - return -1; - - use_ext = 1; - if (test_hash_readwrite_functional(use_ext, use_htm) < 0) - return -1; - - reader_faster = 1; - if (test_hash_readwrite_perf(&non_htm_results, use_htm, - reader_faster) < 0) - return -1; - reader_faster = 0; - if (test_hash_readwrite_perf(&non_htm_results, use_htm, - reader_faster) < 0) - return -1; - - printf("================\n"); - printf("Results summary:\n"); - printf("================\n"); - - printf("single read: %u\n", htm_results.single_read); - printf("single write: %u\n", htm_results.single_write); - for (i = 0; i < NUM_TEST; i++) { - printf("+++ core_cnt: %u +++\n", core_cnt[i]); - printf("HTM:\n"); - printf(" read only: %u\n", htm_results.read_only[i]); - printf(" write only: %u\n", htm_results.write_only[i]); - printf(" read-write read: %u\n", htm_results.read_write_r[i]); - printf(" read-write write: %u\n", htm_results.read_write_w[i]); - - printf("non HTM:\n"); - printf(" read only: %u\n", non_htm_results.read_only[i]); - printf(" write only: %u\n", non_htm_results.write_only[i]); - printf(" read-write read: %u\n", - non_htm_results.read_write_r[i]); - printf(" read-write write: %u\n", - non_htm_results.read_write_w[i]); - } - - return 0; -} - -REGISTER_TEST_COMMAND(hash_readwrite_autotest, test_hash_readwrite_main); diff --git a/test/test/test_hash_readwrite_lf.c b/test/test/test_hash_readwrite_lf.c deleted file mode 100644 index cbfd932269..0000000000 --- a/test/test/test_hash_readwrite_lf.c +++ /dev/null @@ -1,1220 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Arm Limited - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#ifndef RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF -#define RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF 0 -#endif - -#define BULK_LOOKUP_SIZE 32 - -#define RUN_WITH_HTM_DISABLED 0 - -#if (RUN_WITH_HTM_DISABLED) - -#define TOTAL_ENTRY (5*1024) -#define TOTAL_INSERT (5*1024) - -#else - -#define TOTAL_ENTRY (4*1024*1024) -#define TOTAL_INSERT (4*1024*1024) - -#endif - -#define READ_FAIL 1 -#define READ_PASS_NO_KEY_SHIFTS 2 -#define READ_PASS_SHIFT_PATH 4 -#define READ_PASS_NON_SHIFT_PATH 8 -#define BULK_LOOKUP 16 -#define NUM_TEST 3 -unsigned int rwc_core_cnt[NUM_TEST] = {1, 2, 4}; - -struct rwc_perf { - uint32_t w_no_ks_r_hit[2][NUM_TEST]; - uint32_t w_no_ks_r_miss[2][NUM_TEST]; - uint32_t w_ks_r_hit_nsp[2][NUM_TEST]; - uint32_t w_ks_r_hit_sp[2][NUM_TEST]; - uint32_t w_ks_r_miss[2][NUM_TEST]; - uint32_t multi_rw[NUM_TEST - 1][2][NUM_TEST]; -}; - -static struct rwc_perf rwc_lf_results, rwc_non_lf_results; - -struct { - uint32_t *keys; - uint32_t *keys_no_ks; - uint32_t *keys_ks; - uint32_t *keys_absent; - uint32_t *keys_shift_path; - uint32_t *keys_non_shift_path; - uint32_t count_keys_no_ks; - uint32_t count_keys_ks; - uint32_t count_keys_absent; - uint32_t count_keys_shift_path; - uint32_t count_keys_non_shift_path; - uint32_t single_insert; - struct rte_hash *h; -} tbl_rwc_test_param; - -static rte_atomic64_t gread_cycles; -static rte_atomic64_t greads; - -static volatile uint8_t writer_done; -static volatile uint8_t multi_writer_done[4]; - -uint16_t enabled_core_ids[RTE_MAX_LCORE]; - -uint8_t *scanned_bkts; - -static inline int -get_enabled_cores_list(void) -{ - uint32_t i = 0; - uint16_t core_id; - uint32_t max_cores = rte_lcore_count(); - for (core_id = 0; core_id < RTE_MAX_LCORE && i < max_cores; core_id++) { - if (rte_lcore_is_enabled(core_id)) { - enabled_core_ids[i] = core_id; - i++; - } - } - - if (i != max_cores) { - printf("Number of enabled cores in list is different from " - "number given by rte_lcore_count()\n"); - return -1; - } - return 0; -} - -static inline int -check_bucket(uint32_t bkt_idx, uint32_t key) -{ - uint32_t iter; - uint32_t prev_iter; - uint32_t diff; - uint32_t count = 0; - const void *next_key; - void *next_data; - - /* Temporary bucket to hold the keys */ - uint32_t keys_in_bkt[8]; - - iter = bkt_idx * 8; - prev_iter = iter; - while (rte_hash_iterate(tbl_rwc_test_param.h, - &next_key, &next_data, &iter) >= 0) { - - /* Check for duplicate entries */ - if (*(const uint32_t *)next_key == key) - return 1; - - /* Identify if there is any free entry in the bucket */ - diff = iter - prev_iter; - if (diff > 1) - break; - - prev_iter = iter; - keys_in_bkt[count] = *(const uint32_t *)next_key; - count++; - - /* All entries in the bucket are occupied */ - if (count == 8) { - - /* - * Check if bucket was not scanned before, to avoid - * duplicate keys. - */ - if (scanned_bkts[bkt_idx] == 0) { - /* - * Since this bucket (pointed to by bkt_idx) is - * full, it is likely that key(s) in this - * bucket will be on the shift path, when - * collision occurs. Thus, add it to - * keys_shift_path. - */ - memcpy(tbl_rwc_test_param.keys_shift_path + - tbl_rwc_test_param.count_keys_shift_path - , keys_in_bkt, 32); - tbl_rwc_test_param.count_keys_shift_path += 8; - scanned_bkts[bkt_idx] = 1; - } - return -1; - } - } - return 0; -} - -static int -generate_keys(void) -{ - uint32_t *keys = NULL; - uint32_t *keys_no_ks = NULL; - uint32_t *keys_ks = NULL; - uint32_t *keys_absent = NULL; - uint32_t *keys_non_shift_path = NULL; - uint32_t *found = NULL; - uint32_t count_keys_no_ks = 0; - uint32_t count_keys_ks = 0; - uint32_t i; - - /* - * keys will consist of a) keys whose addition to the hash table - * will result in shifting of the existing keys to their alternate - * locations b) keys whose addition to the hash table will not result - * in shifting of the existing keys. - */ - keys = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); - if (keys == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - /* - * keys_no_ks (no key-shifts): Subset of 'keys' - consists of keys that - * will NOT result in shifting of the existing keys to their alternate - * locations. Roughly around 900K keys. - */ - keys_no_ks = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); - if (keys_no_ks == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - /* - * keys_ks (key-shifts): Subset of 'keys' - consists of keys that will - * result in shifting of the existing keys to their alternate locations. - * Roughly around 146K keys. There might be repeating keys. More code is - * required to filter out these keys which will complicate the test case - */ - keys_ks = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); - if (keys_ks == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - /* Used to identify keys not inserted in the hash table */ - found = rte_zmalloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); - if (found == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - /* - * This consist of keys not inserted to the hash table. - * Used to test perf of lookup on keys that do not exist in the table. - */ - keys_absent = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0); - if (keys_absent == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - /* - * This consist of keys which are likely to be on the shift - * path (i.e. being moved to alternate location), when collision occurs - * on addition of a key to an already full primary bucket. - * Used to test perf of lookup on keys that are on the shift path. - */ - tbl_rwc_test_param.keys_shift_path = rte_malloc(NULL, sizeof(uint32_t) * - TOTAL_INSERT, 0); - if (tbl_rwc_test_param.keys_shift_path == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - /* - * This consist of keys which are never on the shift - * path (i.e. being moved to alternate location), when collision occurs - * on addition of a key to an already full primary bucket. - * Used to test perf of lookup on keys that are not on the shift path. - */ - keys_non_shift_path = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, - 0); - if (keys_non_shift_path == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - - hash_sig_t sig; - uint32_t prim_bucket_idx; - int ret; - uint32_t num_buckets; - uint32_t bucket_bitmask; - num_buckets = rte_align32pow2(TOTAL_ENTRY) / 8; - bucket_bitmask = num_buckets - 1; - - /* - * Used to mark bkts in which at least one key was shifted to its - * alternate location - */ - scanned_bkts = rte_malloc(NULL, sizeof(uint8_t) * num_buckets, 0); - if (scanned_bkts == NULL) { - printf("RTE_MALLOC failed\n"); - goto err; - } - - tbl_rwc_test_param.keys = keys; - tbl_rwc_test_param.keys_no_ks = keys_no_ks; - tbl_rwc_test_param.keys_ks = keys_ks; - tbl_rwc_test_param.keys_absent = keys_absent; - tbl_rwc_test_param.keys_non_shift_path = keys_non_shift_path; - /* Generate keys by adding previous two keys, neglect overflow */ - printf("Generating keys...\n"); - keys[0] = 0; - keys[1] = 1; - for (i = 2; i < TOTAL_INSERT; i++) - keys[i] = keys[i-1] + keys[i-2]; - - /* Segregate keys into keys_no_ks and keys_ks */ - for (i = 0; i < TOTAL_INSERT; i++) { - /* Check if primary bucket has space.*/ - sig = rte_hash_hash(tbl_rwc_test_param.h, - tbl_rwc_test_param.keys+i); - prim_bucket_idx = sig & bucket_bitmask; - ret = check_bucket(prim_bucket_idx, keys[i]); - if (ret < 0) { - /* - * Primary bucket is full, this key will result in - * shifting of the keys to their alternate locations. - */ - keys_ks[count_keys_ks] = keys[i]; - count_keys_ks++; - } else if (ret == 0) { - /* - * Primary bucket has space, this key will not result in - * shifting of the keys. Hence, add key to the table. - */ - ret = rte_hash_add_key_data(tbl_rwc_test_param.h, - keys+i, - (void *)((uintptr_t)i)); - if (ret < 0) { - printf("writer failed %"PRIu32"\n", i); - break; - } - keys_no_ks[count_keys_no_ks] = keys[i]; - count_keys_no_ks++; - } - } - - for (i = 0; i < count_keys_no_ks; i++) { - /* - * Identify keys in keys_no_ks with value less than - * 4M (HTM enabled) OR 5K (HTM disabled) - */ - if (keys_no_ks[i] < TOTAL_INSERT) - found[keys_no_ks[i]]++; - } - - for (i = 0; i < count_keys_ks; i++) { - /* - * Identify keys in keys_ks with value less than - * 4M (HTM enabled) OR 5K (HTM disabled) - */ - if (keys_ks[i] < TOTAL_INSERT) - found[keys_ks[i]]++; - } - - uint32_t count_keys_absent = 0; - for (i = 0; i < TOTAL_INSERT; i++) { - /* - * Identify missing keys between 0 and - * 4M (HTM enabled) OR 5K (HTM disabled) - */ - if (found[i] == 0) - keys_absent[count_keys_absent++] = i; - } - - /* Find keys that will not be on the shift path */ - uint32_t iter; - const void *next_key; - void *next_data; - uint32_t count = 0; - for (i = 0; i < num_buckets; i++) { - /* Check bucket for no keys shifted to alternate locations */ - if (scanned_bkts[i] == 0) { - iter = i * 8; - while (rte_hash_iterate(tbl_rwc_test_param.h, - &next_key, &next_data, &iter) >= 0) { - - /* Check if key belongs to the current bucket */ - if (i >= (iter-1)/8) - keys_non_shift_path[count++] - = *(const uint32_t *)next_key; - else - break; - } - } - } - - tbl_rwc_test_param.count_keys_no_ks = count_keys_no_ks; - tbl_rwc_test_param.count_keys_ks = count_keys_ks; - tbl_rwc_test_param.count_keys_absent = count_keys_absent; - tbl_rwc_test_param.count_keys_non_shift_path = count; - - printf("\nCount of keys NOT causing shifting of existing keys to " - "alternate location: %d\n", tbl_rwc_test_param.count_keys_no_ks); - printf("\nCount of keys causing shifting of existing keys to alternate " - "locations: %d\n\n", tbl_rwc_test_param.count_keys_ks); - printf("Count of absent keys that will never be added to the hash " - "table: %d\n\n", tbl_rwc_test_param.count_keys_absent); - printf("Count of keys likely to be on the shift path: %d\n\n", - tbl_rwc_test_param.count_keys_shift_path); - printf("Count of keys not likely to be on the shift path: %d\n\n", - tbl_rwc_test_param.count_keys_non_shift_path); - - rte_free(found); - rte_hash_free(tbl_rwc_test_param.h); - return 0; - -err: - rte_free(keys); - rte_free(keys_no_ks); - rte_free(keys_ks); - rte_free(keys_absent); - rte_free(found); - rte_free(tbl_rwc_test_param.keys_shift_path); - rte_free(scanned_bkts); - return -1; -} - -static int -init_params(int rwc_lf, int use_jhash, int htm) -{ - struct rte_hash *handle; - - struct rte_hash_parameters hash_params = { - .entries = TOTAL_ENTRY, - .key_len = sizeof(uint32_t), - .hash_func_init_val = 0, - .socket_id = rte_socket_id(), - }; - - if (use_jhash) - hash_params.hash_func = rte_jhash; - else - hash_params.hash_func = rte_hash_crc; - - if (rwc_lf) - hash_params.extra_flag = - RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF | - RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; - else if (htm) - hash_params.extra_flag = - RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT | - RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | - RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; - else - hash_params.extra_flag = - RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | - RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; - - hash_params.name = "tests"; - - handle = rte_hash_create(&hash_params); - if (handle == NULL) { - printf("hash creation failed"); - return -1; - } - - tbl_rwc_test_param.h = handle; - return 0; -} - -static int -test_rwc_reader(__attribute__((unused)) void *arg) -{ - uint32_t i, j; - int ret; - uint64_t begin, cycles; - uint32_t loop_cnt = 0; - uint8_t read_type = (uint8_t)((uintptr_t)arg); - uint32_t read_cnt; - uint32_t *keys; - uint32_t extra_keys; - int32_t *pos; - void *temp_a[BULK_LOOKUP_SIZE]; - - /* Used to identify keys not inserted in the hash table */ - pos = rte_zmalloc(NULL, sizeof(uint32_t) * BULK_LOOKUP_SIZE, 0); - if (pos == NULL) { - printf("RTE_MALLOC failed\n"); - return -1; - } - - if (read_type & READ_FAIL) { - keys = tbl_rwc_test_param.keys_absent; - read_cnt = tbl_rwc_test_param.count_keys_absent; - } else if (read_type & READ_PASS_NO_KEY_SHIFTS) { - keys = tbl_rwc_test_param.keys_no_ks; - read_cnt = tbl_rwc_test_param.count_keys_no_ks; - } else if (read_type & READ_PASS_SHIFT_PATH) { - keys = tbl_rwc_test_param.keys_shift_path; - read_cnt = tbl_rwc_test_param.count_keys_shift_path; - } else { - keys = tbl_rwc_test_param.keys_non_shift_path; - read_cnt = tbl_rwc_test_param.count_keys_non_shift_path; - } - - extra_keys = read_cnt & (BULK_LOOKUP_SIZE - 1); - - begin = rte_rdtsc_precise(); - do { - if (read_type & BULK_LOOKUP) { - for (i = 0; i < (read_cnt - extra_keys); - i += BULK_LOOKUP_SIZE) { - /* Array of pointer to the list of keys */ - for (j = 0; j < BULK_LOOKUP_SIZE; j++) - temp_a[j] = keys + i + j; - - rte_hash_lookup_bulk(tbl_rwc_test_param.h, - (const void **) - ((uintptr_t)temp_a), - BULK_LOOKUP_SIZE, pos); - /* Validate lookup result */ - for (j = 0; j < BULK_LOOKUP_SIZE; j++) - if ((read_type & READ_FAIL && - pos[j] != -ENOENT) || - (!(read_type & READ_FAIL) && - pos[j] == -ENOENT)) { - printf("lookup failed!" - "%"PRIu32"\n", - keys[i + j]); - return -1; - } - } - for (j = 0; j < extra_keys; j++) - temp_a[j] = keys + i + j; - - rte_hash_lookup_bulk(tbl_rwc_test_param.h, - (const void **) - ((uintptr_t)temp_a), - extra_keys, pos); - for (j = 0; j < extra_keys; j++) - if ((read_type & READ_FAIL && - pos[j] != -ENOENT) || - (!(read_type & READ_FAIL) && - pos[j] == -ENOENT)) { - printf("lookup failed! %"PRIu32"\n", - keys[i + j]); - return -1; - } - } else { - for (i = 0; i < read_cnt; i++) { - ret = rte_hash_lookup - (tbl_rwc_test_param.h, keys + i); - if (((read_type & READ_FAIL) && - (ret != -ENOENT)) || - (!(read_type & READ_FAIL) && - ret == -ENOENT)) { - printf("lookup failed! %"PRIu32"\n", - keys[i]); - return -1; - } - } - } - loop_cnt++; - } while (!writer_done); - - cycles = rte_rdtsc_precise() - begin; - rte_atomic64_add(&gread_cycles, cycles); - rte_atomic64_add(&greads, read_cnt*loop_cnt); - return 0; -} - -static int -write_keys(uint8_t key_shift) -{ - uint32_t i; - int ret; - uint32_t key_cnt; - uint32_t *keys; - if (key_shift) { - key_cnt = tbl_rwc_test_param.count_keys_ks; - keys = tbl_rwc_test_param.keys_ks; - } else { - key_cnt = tbl_rwc_test_param.count_keys_no_ks; - keys = tbl_rwc_test_param.keys_no_ks; - } - for (i = 0; i < key_cnt; i++) { - ret = rte_hash_add_key(tbl_rwc_test_param.h, keys + i); - if (!key_shift && ret < 0) { - printf("writer failed %"PRIu32"\n", i); - return -1; - } - } - return 0; -} - -static int -test_rwc_multi_writer(__attribute__((unused)) void *arg) -{ - uint32_t i, offset; - uint32_t pos_core = (uint32_t)((uintptr_t)arg); - offset = pos_core * tbl_rwc_test_param.single_insert; - for (i = offset; i < offset + tbl_rwc_test_param.single_insert; i++) - rte_hash_add_key(tbl_rwc_test_param.h, - tbl_rwc_test_param.keys_ks + i); - multi_writer_done[pos_core] = 1; - return 0; -} - -/* - * Test lookup perf: - * Reader(s) lookup keys present in the table. - */ -static int -test_hash_add_no_ks_lookup_hit(struct rwc_perf *rwc_perf_results, int rwc_lf, - int htm) -{ - unsigned int n, m; - uint64_t i; - int use_jhash = 0; - uint8_t key_shift = 0; - uint8_t read_type = READ_PASS_NO_KEY_SHIFTS; - - rte_atomic64_init(&greads); - rte_atomic64_init(&gread_cycles); - - if (init_params(rwc_lf, use_jhash, htm) != 0) - goto err; - printf("\nTest: Hash add - no key-shifts, read - hit\n"); - for (m = 0; m < 2; m++) { - if (m == 1) { - printf("\n** With bulk-lookup **\n"); - read_type |= BULK_LOOKUP; - } - for (n = 0; n < NUM_TEST; n++) { - unsigned int tot_lcore = rte_lcore_count(); - if (tot_lcore < rwc_core_cnt[n] + 1) - goto finish; - - printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); - - rte_atomic64_clear(&greads); - rte_atomic64_clear(&gread_cycles); - - rte_hash_reset(tbl_rwc_test_param.h); - writer_done = 0; - if (write_keys(key_shift) < 0) - goto err; - writer_done = 1; - for (i = 1; i <= rwc_core_cnt[n]; i++) - rte_eal_remote_launch(test_rwc_reader, - (void *)(uintptr_t)read_type, - enabled_core_ids[i]); - rte_eal_mp_wait_lcore(); - - for (i = 1; i <= rwc_core_cnt[n]; i++) - if (lcore_config[i].ret < 0) - goto err; - - unsigned long long cycles_per_lookup = - rte_atomic64_read(&gread_cycles) / - rte_atomic64_read(&greads); - rwc_perf_results->w_no_ks_r_hit[m][n] - = cycles_per_lookup; - printf("Cycles per lookup: %llu\n", cycles_per_lookup); - } - } - -finish: - rte_hash_free(tbl_rwc_test_param.h); - return 0; - -err: - rte_hash_free(tbl_rwc_test_param.h); - return -1; -} - -/* - * Test lookup perf: - * Reader(s) lookup keys absent in the table while - * 'Main' thread adds with no key-shifts. - */ -static int -test_hash_add_no_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf, - int htm) -{ - unsigned int n, m; - uint64_t i; - int use_jhash = 0; - uint8_t key_shift = 0; - uint8_t read_type = READ_FAIL; - int ret; - - rte_atomic64_init(&greads); - rte_atomic64_init(&gread_cycles); - - if (init_params(rwc_lf, use_jhash, htm) != 0) - goto err; - printf("\nTest: Hash add - no key-shifts, Hash lookup - miss\n"); - for (m = 0; m < 2; m++) { - if (m == 1) { - printf("\n** With bulk-lookup **\n"); - read_type |= BULK_LOOKUP; - } - for (n = 0; n < NUM_TEST; n++) { - unsigned int tot_lcore = rte_lcore_count(); - if (tot_lcore < rwc_core_cnt[n] + 1) - goto finish; - - printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); - - rte_atomic64_clear(&greads); - rte_atomic64_clear(&gread_cycles); - - rte_hash_reset(tbl_rwc_test_param.h); - writer_done = 0; - - for (i = 1; i <= rwc_core_cnt[n]; i++) - rte_eal_remote_launch(test_rwc_reader, - (void *)(uintptr_t)read_type, - enabled_core_ids[i]); - ret = write_keys(key_shift); - writer_done = 1; - rte_eal_mp_wait_lcore(); - - if (ret < 0) - goto err; - for (i = 1; i <= rwc_core_cnt[n]; i++) - if (lcore_config[i].ret < 0) - goto err; - - unsigned long long cycles_per_lookup = - rte_atomic64_read(&gread_cycles) / - rte_atomic64_read(&greads); - rwc_perf_results->w_no_ks_r_miss[m][n] - = cycles_per_lookup; - printf("Cycles per lookup: %llu\n", cycles_per_lookup); - } - } - -finish: - rte_hash_free(tbl_rwc_test_param.h); - return 0; - -err: - rte_hash_free(tbl_rwc_test_param.h); - return -1; -} - -/* - * Test lookup perf: - * Reader(s) lookup keys present in the table and not likely to be on the - * shift path while 'Main' thread adds keys causing key-shifts. - */ -static int -test_hash_add_ks_lookup_hit_non_sp(struct rwc_perf *rwc_perf_results, - int rwc_lf, int htm) -{ - unsigned int n, m; - uint64_t i; - int use_jhash = 0; - int ret; - uint8_t key_shift; - uint8_t read_type = READ_PASS_NON_SHIFT_PATH; - - rte_atomic64_init(&greads); - rte_atomic64_init(&gread_cycles); - - if (init_params(rwc_lf, use_jhash, htm) != 0) - goto err; - printf("\nTest: Hash add - key shift, Hash lookup - hit" - " (non-shift-path)\n"); - for (m = 0; m < 2; m++) { - if (m == 1) { - printf("\n** With bulk-lookup **\n"); - read_type |= BULK_LOOKUP; - } - for (n = 0; n < NUM_TEST; n++) { - unsigned int tot_lcore = rte_lcore_count(); - if (tot_lcore < rwc_core_cnt[n] + 1) - goto finish; - - printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); - - rte_atomic64_clear(&greads); - rte_atomic64_clear(&gread_cycles); - - rte_hash_reset(tbl_rwc_test_param.h); - writer_done = 0; - key_shift = 0; - if (write_keys(key_shift) < 0) - goto err; - for (i = 1; i <= rwc_core_cnt[n]; i++) - rte_eal_remote_launch(test_rwc_reader, - (void *)(uintptr_t)read_type, - enabled_core_ids[i]); - key_shift = 1; - ret = write_keys(key_shift); - writer_done = 1; - rte_eal_mp_wait_lcore(); - - if (ret < 0) - goto err; - for (i = 1; i <= rwc_core_cnt[n]; i++) - if (lcore_config[i].ret < 0) - goto err; - - unsigned long long cycles_per_lookup = - rte_atomic64_read(&gread_cycles) / - rte_atomic64_read(&greads); - rwc_perf_results->w_ks_r_hit_nsp[m][n] - = cycles_per_lookup; - printf("Cycles per lookup: %llu\n", cycles_per_lookup); - } - } - -finish: - rte_hash_free(tbl_rwc_test_param.h); - return 0; - -err: - rte_hash_free(tbl_rwc_test_param.h); - return -1; -} - -/* - * Test lookup perf: - * Reader(s) lookup keys present in the table and likely on the shift-path while - * 'Main' thread adds keys causing key-shifts. - */ -static int -test_hash_add_ks_lookup_hit_sp(struct rwc_perf *rwc_perf_results, int rwc_lf, - int htm) -{ - unsigned int n, m; - uint64_t i; - int use_jhash = 0; - int ret; - uint8_t key_shift; - uint8_t read_type = READ_PASS_SHIFT_PATH; - - rte_atomic64_init(&greads); - rte_atomic64_init(&gread_cycles); - - if (init_params(rwc_lf, use_jhash, htm) != 0) - goto err; - printf("\nTest: Hash add - key shift, Hash lookup - hit (shift-path)" - "\n"); - - for (m = 0; m < 2; m++) { - if (m == 1) { - printf("\n** With bulk-lookup **\n"); - read_type |= BULK_LOOKUP; - } - for (n = 0; n < NUM_TEST; n++) { - unsigned int tot_lcore = rte_lcore_count(); - if (tot_lcore < rwc_core_cnt[n]) - goto finish; - - printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); - rte_atomic64_clear(&greads); - rte_atomic64_clear(&gread_cycles); - - rte_hash_reset(tbl_rwc_test_param.h); - writer_done = 0; - key_shift = 0; - if (write_keys(key_shift) < 0) - goto err; - for (i = 1; i <= rwc_core_cnt[n]; i++) - rte_eal_remote_launch(test_rwc_reader, - (void *)(uintptr_t)read_type, - enabled_core_ids[i]); - key_shift = 1; - ret = write_keys(key_shift); - writer_done = 1; - rte_eal_mp_wait_lcore(); - - if (ret < 0) - goto err; - for (i = 1; i <= rwc_core_cnt[n]; i++) - if (lcore_config[i].ret < 0) - goto err; - - unsigned long long cycles_per_lookup = - rte_atomic64_read(&gread_cycles) / - rte_atomic64_read(&greads); - rwc_perf_results->w_ks_r_hit_sp[m][n] - = cycles_per_lookup; - printf("Cycles per lookup: %llu\n", cycles_per_lookup); - } - } - -finish: - rte_hash_free(tbl_rwc_test_param.h); - return 0; - -err: - rte_hash_free(tbl_rwc_test_param.h); - return -1; -} - -/* - * Test lookup perf: - * Reader(s) lookup keys absent in the table while - * 'Main' thread adds keys causing key-shifts. - */ -static int -test_hash_add_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf, int - htm) -{ - unsigned int n, m; - uint64_t i; - int use_jhash = 0; - int ret; - uint8_t key_shift; - uint8_t read_type = READ_FAIL; - - rte_atomic64_init(&greads); - rte_atomic64_init(&gread_cycles); - - if (init_params(rwc_lf, use_jhash, htm) != 0) - goto err; - printf("\nTest: Hash add - key shift, Hash lookup - miss\n"); - for (m = 0; m < 2; m++) { - if (m == 1) { - printf("\n** With bulk-lookup **\n"); - read_type |= BULK_LOOKUP; - } - for (n = 0; n < NUM_TEST; n++) { - unsigned int tot_lcore = rte_lcore_count(); - if (tot_lcore < rwc_core_cnt[n] + 1) - goto finish; - - printf("\nNumber of readers: %u\n", rwc_core_cnt[n]); - - rte_atomic64_clear(&greads); - rte_atomic64_clear(&gread_cycles); - - rte_hash_reset(tbl_rwc_test_param.h); - writer_done = 0; - key_shift = 0; - if (write_keys(key_shift) < 0) - goto err; - for (i = 1; i <= rwc_core_cnt[n]; i++) - rte_eal_remote_launch(test_rwc_reader, - (void *)(uintptr_t)read_type, - enabled_core_ids[i]); - key_shift = 1; - ret = write_keys(key_shift); - writer_done = 1; - rte_eal_mp_wait_lcore(); - - if (ret < 0) - goto err; - for (i = 1; i <= rwc_core_cnt[n]; i++) - if (lcore_config[i].ret < 0) - goto err; - - unsigned long long cycles_per_lookup = - rte_atomic64_read(&gread_cycles) / - rte_atomic64_read(&greads); - rwc_perf_results->w_ks_r_miss[m][n] = cycles_per_lookup; - printf("Cycles per lookup: %llu\n", cycles_per_lookup); - } - } - -finish: - rte_hash_free(tbl_rwc_test_param.h); - return 0; - -err: - rte_hash_free(tbl_rwc_test_param.h); - return -1; -} - -/* - * Test lookup perf for multi-writer: - * Reader(s) lookup keys present in the table and likely on the shift-path while - * Writers add keys causing key-shiftsi. - * Writers are running in parallel, on different data plane cores. - */ -static int -test_hash_multi_add_lookup(struct rwc_perf *rwc_perf_results, int rwc_lf, - int htm) -{ - unsigned int n, m, k; - uint64_t i; - int use_jhash = 0; - uint8_t key_shift; - uint8_t read_type = READ_PASS_SHIFT_PATH; - - rte_atomic64_init(&greads); - rte_atomic64_init(&gread_cycles); - - if (init_params(rwc_lf, use_jhash, htm) != 0) - goto err; - printf("\nTest: Multi-add-lookup\n"); - uint8_t pos_core; - for (m = 1; m < NUM_TEST; m++) { - /* Calculate keys added by each writer */ - tbl_rwc_test_param.single_insert = - tbl_rwc_test_param.count_keys_ks / rwc_core_cnt[m]; - for (k = 0; k < 2; k++) { - if (k == 1) { - printf("\n** With bulk-lookup **\n"); - read_type |= BULK_LOOKUP; - } - for (n = 0; n < NUM_TEST; n++) { - unsigned int tot_lcore = rte_lcore_count(); - if (tot_lcore < (rwc_core_cnt[n] + - rwc_core_cnt[m] + 1)) - goto finish; - - printf("\nNumber of writers: %u", - rwc_core_cnt[m]); - printf("\nNumber of readers: %u\n", - rwc_core_cnt[n]); - - rte_atomic64_clear(&greads); - rte_atomic64_clear(&gread_cycles); - - rte_hash_reset(tbl_rwc_test_param.h); - writer_done = 0; - for (i = 0; i < 4; i++) - multi_writer_done[i] = 0; - key_shift = 0; - if (write_keys(key_shift) < 0) - goto err; - - /* Launch reader(s) */ - for (i = 1; i <= rwc_core_cnt[n]; i++) - rte_eal_remote_launch(test_rwc_reader, - (void *)(uintptr_t)read_type, - enabled_core_ids[i]); - key_shift = 1; - pos_core = 0; - - /* Launch writers */ - for (; i <= rwc_core_cnt[m] - + rwc_core_cnt[n]; i++) { - rte_eal_remote_launch - (test_rwc_multi_writer, - (void *)(uintptr_t)pos_core, - enabled_core_ids[i]); - pos_core++; - } - - /* Wait for writers to complete */ - for (i = 0; i < rwc_core_cnt[m]; i++) - while - (multi_writer_done[i] == 0); - writer_done = 1; - - rte_eal_mp_wait_lcore(); - - for (i = 1; i <= rwc_core_cnt[n]; i++) - if (lcore_config[i].ret < 0) - goto err; - - unsigned long long cycles_per_lookup = - rte_atomic64_read(&gread_cycles) - / rte_atomic64_read(&greads); - rwc_perf_results->multi_rw[m][k][n] - = cycles_per_lookup; - printf("Cycles per lookup: %llu\n", - cycles_per_lookup); - } - } - } - -finish: - rte_hash_free(tbl_rwc_test_param.h); - return 0; - -err: - rte_hash_free(tbl_rwc_test_param.h); - return -1; -} - -static int -test_hash_readwrite_lf_main(void) -{ - /* - * Variables used to choose different tests. - * rwc_lf indicates if read-write concurrency lock-free support is - * enabled. - * htm indicates if Hardware transactional memory support is enabled. - */ - int rwc_lf = 0; - int htm; - int use_jhash = 0; - if (rte_lcore_count() == 1) { - printf("More than one lcore is required " - "to do read write lock-free concurrency test\n"); - return -1; - } - - setlocale(LC_NUMERIC, ""); - - if (rte_tm_supported()) - htm = 1; - else - htm = 0; - - if (init_params(rwc_lf, use_jhash, htm) != 0) - return -1; - if (generate_keys() != 0) - return -1; - if (get_enabled_cores_list() != 0) - return -1; - - if (RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF) { - rwc_lf = 1; - printf("Test lookup with read-write concurrency lock free support" - " enabled\n"); - if (test_hash_add_no_ks_lookup_hit(&rwc_lf_results, rwc_lf, - htm) < 0) - return -1; - if (test_hash_add_no_ks_lookup_miss(&rwc_lf_results, rwc_lf, - htm) < 0) - return -1; - if (test_hash_add_ks_lookup_hit_non_sp(&rwc_lf_results, rwc_lf, - htm) < 0) - return -1; - if (test_hash_add_ks_lookup_hit_sp(&rwc_lf_results, rwc_lf, - htm) < 0) - return -1; - if (test_hash_add_ks_lookup_miss(&rwc_lf_results, rwc_lf, htm) - < 0) - return -1; - if (test_hash_multi_add_lookup(&rwc_lf_results, rwc_lf, htm) - < 0) - return -1; - } - printf("\nTest lookup with read-write concurrency lock free support" - " disabled\n"); - rwc_lf = 0; - if (!htm) { - printf("With HTM Disabled\n"); - if (!RUN_WITH_HTM_DISABLED) { - printf("Enable RUN_WITH_HTM_DISABLED to test with" - " lock-free disabled"); - goto results; - } - } else - printf("With HTM Enabled\n"); - if (test_hash_add_no_ks_lookup_hit(&rwc_non_lf_results, rwc_lf, htm) - < 0) - return -1; - if (test_hash_add_no_ks_lookup_miss(&rwc_non_lf_results, rwc_lf, htm) - < 0) - return -1; - if (test_hash_add_ks_lookup_hit_non_sp(&rwc_non_lf_results, rwc_lf, - htm) < 0) - return -1; - if (test_hash_add_ks_lookup_hit_sp(&rwc_non_lf_results, rwc_lf, htm) - < 0) - return -1; - if (test_hash_add_ks_lookup_miss(&rwc_non_lf_results, rwc_lf, htm) < 0) - return -1; - if (test_hash_multi_add_lookup(&rwc_non_lf_results, rwc_lf, htm) < 0) - return -1; -results: - printf("\n\t\t\t\t\t\t********** Results summary **********\n\n"); - int i, j, k; - for (j = 0; j < 2; j++) { - if (j == 1) - printf("\n\t\t\t\t\t#######********** Bulk Lookup " - "**********#######\n\n"); - printf("_______\t\t_______\t\t_________\t___\t\t_________\t\t" - "\t\t\t\t_________________\n"); - printf("Writers\t\tReaders\t\tLock-free\tHTM\t\tTest-case\t\t\t" - "\t\t\tCycles per lookup\n"); - printf("_______\t\t_______\t\t_________\t___\t\t_________\t\t\t" - "\t\t\t_________________\n"); - for (i = 0; i < NUM_TEST; i++) { - printf("%u\t\t%u\t\t", 1, rwc_core_cnt[i]); - printf("Enabled\t\t"); - printf("N/A\t\t"); - printf("Hash add - no key-shifts, lookup - hit\t\t\t\t" - "%u\n\t\t\t\t\t\t\t\t", - rwc_lf_results.w_no_ks_r_hit[j][i]); - printf("Hash add - no key-shifts, lookup - miss\t\t\t\t" - "%u\n\t\t\t\t\t\t\t\t", - rwc_lf_results.w_no_ks_r_miss[j][i]); - printf("Hash add - key-shifts, lookup - hit" - "(non-shift-path)\t\t%u\n\t\t\t\t\t\t\t\t", - rwc_lf_results.w_ks_r_hit_nsp[j][i]); - printf("Hash add - key-shifts, lookup - hit " - "(shift-path)\t\t%u\n\t\t\t\t\t\t\t\t", - rwc_lf_results.w_ks_r_hit_sp[j][i]); - printf("Hash add - key-shifts, Hash lookup miss\t\t\t\t" - "%u\n\n\t\t\t\t", - rwc_lf_results.w_ks_r_miss[j][i]); - - printf("Disabled\t"); - if (htm) - printf("Enabled\t\t"); - else - printf("Disabled\t"); - printf("Hash add - no key-shifts, lookup - hit\t\t\t\t" - "%u\n\t\t\t\t\t\t\t\t", - rwc_non_lf_results.w_no_ks_r_hit[j][i]); - printf("Hash add - no key-shifts, lookup - miss\t\t\t\t" - "%u\n\t\t\t\t\t\t\t\t", - rwc_non_lf_results.w_no_ks_r_miss[j][i]); - printf("Hash add - key-shifts, lookup - hit " - "(non-shift-path)\t\t%u\n\t\t\t\t\t\t\t\t", - rwc_non_lf_results.w_ks_r_hit_nsp[j][i]); - printf("Hash add - key-shifts, lookup - hit " - "(shift-path)\t\t%u\n\t\t\t\t\t\t\t\t", - rwc_non_lf_results.w_ks_r_hit_sp[j][i]); - printf("Hash add - key-shifts, Hash lookup miss\t\t\t\t" - "%u\n", rwc_non_lf_results.w_ks_r_miss[j][i]); - - printf("_______\t\t_______\t\t_________\t___\t\t" - "_________\t\t\t\t\t\t_________________\n"); - } - - for (i = 1; i < NUM_TEST; i++) { - for (k = 0; k < NUM_TEST; k++) { - printf("%u", rwc_core_cnt[i]); - printf("\t\t%u\t\t", rwc_core_cnt[k]); - printf("Enabled\t\t"); - printf("N/A\t\t"); - printf("Multi-add-lookup\t\t\t\t\t\t%u\n\n\t\t" - "\t\t", - rwc_lf_results.multi_rw[i][j][k]); - printf("Disabled\t"); - if (htm) - printf("Enabled\t\t"); - else - printf("Disabled\t"); - printf("Multi-add-lookup\t\t\t\t\t\t%u\n", - rwc_non_lf_results.multi_rw[i][j][k]); - - printf("_______\t\t_______\t\t_________\t___" - "\t\t_________\t\t\t\t\t\t" - "_________________\n"); - } - } - } - rte_free(tbl_rwc_test_param.keys); - rte_free(tbl_rwc_test_param.keys_no_ks); - rte_free(tbl_rwc_test_param.keys_ks); - rte_free(tbl_rwc_test_param.keys_absent); - rte_free(tbl_rwc_test_param.keys_shift_path); - rte_free(scanned_bkts); - return 0; -} - -REGISTER_TEST_COMMAND(hash_readwrite_lf_autotest, test_hash_readwrite_lf_main); diff --git a/test/test/test_interrupts.c b/test/test/test_interrupts.c deleted file mode 100644 index 4e82e9a22d..0000000000 --- a/test/test/test_interrupts.c +++ /dev/null @@ -1,558 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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_VALID_DEV_EVENT, - 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_VALID_DEV_EVENT].fd = pfds.readfd; - intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT].type = - RTE_INTR_HANDLE_DEV_EVENT; - - 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(void *arg) -{ - struct rte_intr_handle *intr_handle = 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(void *arg) -{ - struct rte_intr_handle *intr_handle = 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 specific valid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT]; - 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 specific valid intr_handle */ - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT]; - 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, &test_intr_handle) < 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, &test_intr_handle) < 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 occurred 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 occurred during checking valid UIO interrupt " - "full path\n"); - goto out; - } - - printf("Check valid device event interrupt full path\n"); - if (test_interrupt_full_path_check( - TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT) < 0) { - printf("failure occurred during checking valid device event " - "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 occurred 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, &test_intr_handle) == 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, &test_intr_handle) == 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, &test_intr_handle) > 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, &test_intr_handle) < 0) { - printf("it fails to register test_interrupt_callback\n"); - goto out; - } - if (rte_intr_callback_register(&test_intr_handle, - test_interrupt_callback_1, &test_intr_handle) < 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, &test_intr_handle) <= 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); - - test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT]; - 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_ipsec.c b/test/test/test_ipsec.c deleted file mode 100644 index 80a2d255fb..0000000000 --- a/test/test/test_ipsec.c +++ /dev/null @@ -1,2499 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" -#include "test_cryptodev.h" - -#define VDEV_ARGS_SIZE 100 -#define MAX_NB_SESSIONS 100 -#define MAX_NB_SAS 2 -#define REPLAY_WIN_0 0 -#define REPLAY_WIN_32 32 -#define REPLAY_WIN_64 64 -#define REPLAY_WIN_128 128 -#define REPLAY_WIN_256 256 -#define DATA_64_BYTES 64 -#define DATA_80_BYTES 80 -#define DATA_100_BYTES 100 -#define ESN_ENABLED 1 -#define ESN_DISABLED 0 -#define INBOUND_SPI 7 -#define OUTBOUND_SPI 17 -#define BURST_SIZE 32 -#define REORDER_PKTS 1 - -struct user_params { - enum rte_crypto_sym_xform_type auth; - enum rte_crypto_sym_xform_type cipher; - enum rte_crypto_sym_xform_type aead; - - char auth_algo[128]; - char cipher_algo[128]; - char aead_algo[128]; -}; - -struct ipsec_testsuite_params { - struct rte_mempool *mbuf_pool; - struct rte_mempool *cop_mpool; - struct rte_cryptodev_config conf; - struct rte_cryptodev_qp_conf qp_conf; - - uint8_t valid_dev; - uint8_t valid_dev_found; -}; - -struct ipsec_unitest_params { - struct rte_crypto_sym_xform cipher_xform; - struct rte_crypto_sym_xform auth_xform; - struct rte_crypto_sym_xform aead_xform; - struct rte_crypto_sym_xform *crypto_xforms; - - struct rte_security_ipsec_xform ipsec_xform; - - struct rte_ipsec_sa_prm sa_prm; - struct rte_ipsec_session ss[MAX_NB_SAS]; - - struct rte_crypto_op *cop[BURST_SIZE]; - - struct rte_mbuf *obuf[BURST_SIZE], *ibuf[BURST_SIZE], - *testbuf[BURST_SIZE]; - - uint8_t *digest; - uint16_t pkt_index; -}; - -struct ipsec_test_cfg { - uint32_t replay_win_sz; - uint32_t esn; - uint64_t flags; - size_t pkt_sz; - uint16_t num_pkts; - uint32_t reorder_pkts; -}; - -static const struct ipsec_test_cfg test_cfg[] = { - - {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_64_BYTES, 1, 0}, - {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_80_BYTES, BURST_SIZE, - REORDER_PKTS}, - {REPLAY_WIN_32, ESN_ENABLED, 0, DATA_100_BYTES, 1, 0}, - {REPLAY_WIN_32, ESN_ENABLED, 0, DATA_100_BYTES, BURST_SIZE, - REORDER_PKTS}, - {REPLAY_WIN_64, ESN_ENABLED, 0, DATA_64_BYTES, 1, 0}, - {REPLAY_WIN_128, ESN_ENABLED, RTE_IPSEC_SAFLAG_SQN_ATOM, - DATA_80_BYTES, 1, 0}, - {REPLAY_WIN_256, ESN_DISABLED, 0, DATA_100_BYTES, 1, 0}, -}; - -static const int num_cfg = RTE_DIM(test_cfg); -static struct ipsec_testsuite_params testsuite_params = { NULL }; -static struct ipsec_unitest_params unittest_params; -static struct user_params uparams; - -static uint8_t global_key[128] = { 0 }; - -struct supported_cipher_algo { - const char *keyword; - enum rte_crypto_cipher_algorithm algo; - uint16_t iv_len; - uint16_t block_size; - uint16_t key_len; -}; - -struct supported_auth_algo { - const char *keyword; - enum rte_crypto_auth_algorithm algo; - uint16_t digest_len; - uint16_t key_len; - uint8_t key_not_req; -}; - -const struct supported_cipher_algo cipher_algos[] = { - { - .keyword = "null", - .algo = RTE_CRYPTO_CIPHER_NULL, - .iv_len = 0, - .block_size = 4, - .key_len = 0 - }, -}; - -const struct supported_auth_algo auth_algos[] = { - { - .keyword = "null", - .algo = RTE_CRYPTO_AUTH_NULL, - .digest_len = 0, - .key_len = 0, - .key_not_req = 1 - }, -}; - -static int -dummy_sec_create(void *device, struct rte_security_session_conf *conf, - struct rte_security_session *sess, struct rte_mempool *mp) -{ - RTE_SET_USED(device); - RTE_SET_USED(conf); - RTE_SET_USED(mp); - - sess->sess_private_data = NULL; - return 0; -} - -static int -dummy_sec_destroy(void *device, struct rte_security_session *sess) -{ - RTE_SET_USED(device); - RTE_SET_USED(sess); - return 0; -} - -static const struct rte_security_ops dummy_sec_ops = { - .session_create = dummy_sec_create, - .session_destroy = dummy_sec_destroy, -}; - -static struct rte_security_ctx dummy_sec_ctx = { - .ops = &dummy_sec_ops, -}; - -static const struct supported_cipher_algo * -find_match_cipher_algo(const char *cipher_keyword) -{ - size_t i; - - for (i = 0; i < RTE_DIM(cipher_algos); i++) { - const struct supported_cipher_algo *algo = - &cipher_algos[i]; - - if (strcmp(cipher_keyword, algo->keyword) == 0) - return algo; - } - - return NULL; -} - -static const struct supported_auth_algo * -find_match_auth_algo(const char *auth_keyword) -{ - size_t i; - - for (i = 0; i < RTE_DIM(auth_algos); i++) { - const struct supported_auth_algo *algo = - &auth_algos[i]; - - if (strcmp(auth_keyword, algo->keyword) == 0) - return algo; - } - - return NULL; -} - -static void -fill_crypto_xform(struct ipsec_unitest_params *ut_params, - const struct supported_auth_algo *auth_algo, - const struct supported_cipher_algo *cipher_algo) -{ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.auth.algo = auth_algo->algo; - ut_params->auth_xform.auth.key.data = global_key; - ut_params->auth_xform.auth.key.length = auth_algo->key_len; - ut_params->auth_xform.auth.digest_length = auth_algo->digest_len; - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.cipher.algo = cipher_algo->algo; - ut_params->cipher_xform.cipher.key.data = global_key; - ut_params->cipher_xform.cipher.key.length = cipher_algo->key_len; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET; - ut_params->cipher_xform.cipher.iv.length = cipher_algo->iv_len; - - if (ut_params->ipsec_xform.direction == - RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { - ut_params->crypto_xforms = &ut_params->auth_xform; - ut_params->auth_xform.next = &ut_params->cipher_xform; - ut_params->cipher_xform.next = NULL; - } else { - ut_params->crypto_xforms = &ut_params->cipher_xform; - ut_params->cipher_xform.next = &ut_params->auth_xform; - ut_params->auth_xform.next = NULL; - } -} - -static int -check_cryptodev_capablity(const struct ipsec_unitest_params *ut, - uint8_t dev_id) -{ - struct rte_cryptodev_sym_capability_idx cap_idx; - const struct rte_cryptodev_symmetric_capability *cap; - int rc = -1; - - cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; - cap_idx.algo.auth = ut->auth_xform.auth.algo; - cap = rte_cryptodev_sym_capability_get(dev_id, &cap_idx); - - if (cap != NULL) { - rc = rte_cryptodev_sym_capability_check_auth(cap, - ut->auth_xform.auth.key.length, - ut->auth_xform.auth.digest_length, 0); - if (rc == 0) { - cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cap_idx.algo.cipher = ut->cipher_xform.cipher.algo; - cap = rte_cryptodev_sym_capability_get( - dev_id, &cap_idx); - if (cap != NULL) - rc = rte_cryptodev_sym_capability_check_cipher( - cap, - ut->cipher_xform.cipher.key.length, - ut->cipher_xform.cipher.iv.length); - } - } - - return rc; -} - -static int -testsuite_setup(void) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - const struct supported_auth_algo *auth_algo; - const struct supported_cipher_algo *cipher_algo; - struct rte_cryptodev_info info; - uint32_t i, nb_devs, dev_id; - size_t sess_sz; - int rc; - - memset(ts_params, 0, sizeof(*ts_params)); - - uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH; - uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER; - strcpy(uparams.auth_algo, "null"); - strcpy(uparams.cipher_algo, "null"); - - auth_algo = find_match_auth_algo(uparams.auth_algo); - cipher_algo = find_match_cipher_algo(uparams.cipher_algo); - fill_crypto_xform(ut_params, auth_algo, cipher_algo); - - nb_devs = rte_cryptodev_count(); - if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?\n"); - return TEST_FAILED; - } - - /* Find first valid crypto device */ - for (i = 0; i < nb_devs; i++) { - rc = check_cryptodev_capablity(ut_params, i); - if (rc == 0) { - ts_params->valid_dev = i; - ts_params->valid_dev_found = 1; - break; - } - } - - if (ts_params->valid_dev_found == 0) - return TEST_FAILED; - - 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->cop_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) + - MAXIMUM_IV_LENGTH, - rte_socket_id()); - if (ts_params->cop_mpool == NULL) { - RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); - return TEST_FAILED; - } - - /* Set up all the qps on the first of the valid devices found */ - dev_id = ts_params->valid_dev; - - 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; - - sess_sz = rte_cryptodev_sym_get_private_session_size(dev_id); - sess_sz = RTE_MAX(sess_sz, sizeof(struct rte_security_session)); - - /* - * Create mempools for sessions - */ - if (info.sym.max_nb_sessions != 0 && - info.sym.max_nb_sessions < MAX_NB_SESSIONS) { - RTE_LOG(ERR, USER1, "Device does not support " - "at least %u sessions\n", - MAX_NB_SESSIONS); - return TEST_FAILED; - } - - ts_params->qp_conf.mp_session_private = rte_mempool_create( - "test_priv_sess_mp", - MAX_NB_SESSIONS, - sess_sz, - 0, 0, NULL, NULL, NULL, - NULL, SOCKET_ID_ANY, - 0); - - TEST_ASSERT_NOT_NULL(ts_params->qp_conf.mp_session_private, - "private session mempool allocation failed"); - - ts_params->qp_conf.mp_session = - rte_cryptodev_sym_session_pool_create("test_sess_mp", - MAX_NB_SESSIONS, 0, 0, 0, SOCKET_ID_ANY); - - TEST_ASSERT_NOT_NULL(ts_params->qp_conf.mp_session, - "session mempool allocation failed"); - - 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; - - TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( - dev_id, 0, &ts_params->qp_conf, - rte_cryptodev_socket_id(dev_id)), - "Failed to setup queue pair %u on cryptodev %u", - 0, dev_id); - - return TEST_SUCCESS; -} - -static void -testsuite_teardown(void) -{ - struct ipsec_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)); - rte_mempool_free(ts_params->mbuf_pool); - ts_params->mbuf_pool = NULL; - } - - if (ts_params->cop_mpool != NULL) { - RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n", - rte_mempool_avail_count(ts_params->cop_mpool)); - rte_mempool_free(ts_params->cop_mpool); - ts_params->cop_mpool = NULL; - } - - /* Free session mempools */ - if (ts_params->qp_conf.mp_session != NULL) { - rte_mempool_free(ts_params->qp_conf.mp_session); - ts_params->qp_conf.mp_session = NULL; - } - - if (ts_params->qp_conf.mp_session_private != NULL) { - rte_mempool_free(ts_params->qp_conf.mp_session_private); - ts_params->qp_conf.mp_session_private = NULL; - } -} - -static int -ut_setup(void) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - - /* 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; - - /* Start the device */ - TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_dev), - "Failed to start cryptodev %u", - ts_params->valid_dev); - - return TEST_SUCCESS; -} - -static void -ut_teardown(void) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - int i; - - for (i = 0; i < BURST_SIZE; i++) { - /* free crypto operation structure */ - if (ut_params->cop[i]) - rte_crypto_op_free(ut_params->cop[i]); - - /* - * 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[i]) { - rte_pktmbuf_free(ut_params->obuf[i]); - if (ut_params->ibuf[i] == ut_params->obuf[i]) - ut_params->ibuf[i] = 0; - ut_params->obuf[i] = 0; - } - if (ut_params->ibuf[i]) { - rte_pktmbuf_free(ut_params->ibuf[i]); - ut_params->ibuf[i] = 0; - } - - if (ut_params->testbuf[i]) { - rte_pktmbuf_free(ut_params->testbuf[i]); - ut_params->testbuf[i] = 0; - } - } - - if (ts_params->mbuf_pool != NULL) - RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", - rte_mempool_avail_count(ts_params->mbuf_pool)); - - /* Stop the device */ - rte_cryptodev_stop(ts_params->valid_dev); -} - -#define IPSEC_MAX_PAD_SIZE UINT8_MAX - -static const uint8_t esp_pad_bytes[IPSEC_MAX_PAD_SIZE] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, -}; - -/* ***** data for tests ***** */ - -const char null_plain_data[] = - "Network Security People Have A Strange Sense Of Humor unlike Other " - "People who have a normal sense of humour"; - -const char null_encrypted_data[] = - "Network Security People Have A Strange Sense Of Humor unlike Other " - "People who have a normal sense of humour"; - -struct ipv4_hdr ipv4_outer = { - .version_ihl = IPVERSION << 4 | - sizeof(ipv4_outer) / IPV4_IHL_MULTIPLIER, - .time_to_live = IPDEFTTL, - .next_proto_id = IPPROTO_ESP, - .src_addr = IPv4(192, 168, 1, 100), - .dst_addr = IPv4(192, 168, 2, 100), -}; - -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); - - if (m) { - memset(m->buf_addr, 0, m->buf_len); - 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; -} - -static struct rte_mbuf * -setup_test_string_tunneled(struct rte_mempool *mpool, const char *string, - size_t len, uint32_t spi, uint32_t seq) -{ - struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); - uint32_t hdrlen = sizeof(struct ipv4_hdr) + sizeof(struct esp_hdr); - uint32_t taillen = sizeof(struct esp_tail); - uint32_t t_len = len + hdrlen + taillen; - uint32_t padlen; - - struct esp_hdr esph = { - .spi = rte_cpu_to_be_32(spi), - .seq = rte_cpu_to_be_32(seq) - }; - - padlen = RTE_ALIGN(t_len, 4) - t_len; - t_len += padlen; - - struct esp_tail espt = { - .pad_len = padlen, - .next_proto = IPPROTO_IPIP, - }; - - if (m == NULL) - return NULL; - - memset(m->buf_addr, 0, m->buf_len); - char *dst = rte_pktmbuf_append(m, t_len); - - if (!dst) { - rte_pktmbuf_free(m); - return NULL; - } - /* copy outer IP and ESP header */ - ipv4_outer.total_length = rte_cpu_to_be_16(t_len); - ipv4_outer.packet_id = rte_cpu_to_be_16(seq); - rte_memcpy(dst, &ipv4_outer, sizeof(ipv4_outer)); - dst += sizeof(ipv4_outer); - m->l3_len = sizeof(ipv4_outer); - rte_memcpy(dst, &esph, sizeof(esph)); - dst += sizeof(esph); - - if (string != NULL) { - /* copy payload */ - rte_memcpy(dst, string, len); - dst += len; - /* copy pad bytes */ - rte_memcpy(dst, esp_pad_bytes, padlen); - dst += padlen; - /* copy ESP tail header */ - rte_memcpy(dst, &espt, sizeof(espt)); - } else - memset(dst, 0, t_len); - - return m; -} - -static int -create_dummy_sec_session(struct ipsec_unitest_params *ut, - struct rte_cryptodev_qp_conf *qp, uint32_t j) -{ - static struct rte_security_session_conf conf; - - ut->ss[j].security.ses = rte_security_session_create(&dummy_sec_ctx, - &conf, qp->mp_session_private); - - if (ut->ss[j].security.ses == NULL) - return -ENOMEM; - - ut->ss[j].security.ctx = &dummy_sec_ctx; - ut->ss[j].security.ol_flags = 0; - return 0; -} - -static int -create_crypto_session(struct ipsec_unitest_params *ut, - struct rte_cryptodev_qp_conf *qp, uint8_t dev_id, uint32_t j) -{ - int32_t rc; - struct rte_cryptodev_sym_session *s; - - s = rte_cryptodev_sym_session_create(qp->mp_session); - if (s == NULL) - return -ENOMEM; - - /* initiliaze SA crypto session for device */ - rc = rte_cryptodev_sym_session_init(dev_id, s, - ut->crypto_xforms, qp->mp_session_private); - if (rc == 0) { - ut->ss[j].crypto.ses = s; - return 0; - } else { - /* failure, do cleanup */ - rte_cryptodev_sym_session_clear(dev_id, s); - rte_cryptodev_sym_session_free(s); - return rc; - } -} - -static int -create_session(struct ipsec_unitest_params *ut, - struct rte_cryptodev_qp_conf *qp, uint8_t crypto_dev, uint32_t j) -{ - if (ut->ss[j].type == RTE_SECURITY_ACTION_TYPE_NONE) - return create_crypto_session(ut, qp, crypto_dev, j); - else - return create_dummy_sec_session(ut, qp, j); -} - -static int -fill_ipsec_param(uint32_t replay_win_sz, uint64_t flags) -{ - struct ipsec_unitest_params *ut_params = &unittest_params; - struct rte_ipsec_sa_prm *prm = &ut_params->sa_prm; - const struct supported_auth_algo *auth_algo; - const struct supported_cipher_algo *cipher_algo; - - memset(prm, 0, sizeof(*prm)); - - prm->userdata = 1; - prm->flags = flags; - prm->replay_win_sz = replay_win_sz; - - /* setup ipsec xform */ - prm->ipsec_xform = ut_params->ipsec_xform; - prm->ipsec_xform.salt = (uint32_t)rte_rand(); - - /* setup tunnel related fields */ - prm->tun.hdr_len = sizeof(ipv4_outer); - prm->tun.next_proto = IPPROTO_IPIP; - prm->tun.hdr = &ipv4_outer; - - /* setup crypto section */ - if (uparams.aead != 0) { - /* TODO: will need to fill out with other test cases */ - } else { - if (uparams.auth == 0 && uparams.cipher == 0) - return TEST_FAILED; - - auth_algo = find_match_auth_algo(uparams.auth_algo); - cipher_algo = find_match_cipher_algo(uparams.cipher_algo); - - fill_crypto_xform(ut_params, auth_algo, cipher_algo); - } - - prm->crypto_xform = ut_params->crypto_xforms; - return TEST_SUCCESS; -} - -static int -create_sa(enum rte_security_session_action_type action_type, - uint32_t replay_win_sz, uint64_t flags, uint32_t j) -{ - struct ipsec_testsuite_params *ts = &testsuite_params; - struct ipsec_unitest_params *ut = &unittest_params; - size_t sz; - int rc; - - memset(&ut->ss[j], 0, sizeof(ut->ss[j])); - - rc = fill_ipsec_param(replay_win_sz, flags); - if (rc != 0) - return TEST_FAILED; - - /* create rte_ipsec_sa*/ - sz = rte_ipsec_sa_size(&ut->sa_prm); - TEST_ASSERT(sz > 0, "rte_ipsec_sa_size() failed\n"); - - ut->ss[j].sa = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE); - TEST_ASSERT_NOT_NULL(ut->ss[j].sa, - "failed to allocate memory for rte_ipsec_sa\n"); - - ut->ss[j].type = action_type; - rc = create_session(ut, &ts->qp_conf, ts->valid_dev, j); - if (rc != 0) - return TEST_FAILED; - - rc = rte_ipsec_sa_init(ut->ss[j].sa, &ut->sa_prm, sz); - rc = (rc > 0 && (uint32_t)rc <= sz) ? 0 : -EINVAL; - if (rc == 0) - rc = rte_ipsec_session_prepare(&ut->ss[j]); - - return rc; -} - -static int -crypto_ipsec(uint16_t num_pkts) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint32_t k, ng; - struct rte_ipsec_group grp[1]; - - /* call crypto prepare */ - k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[0], ut_params->ibuf, - ut_params->cop, num_pkts); - if (k != num_pkts) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n"); - return TEST_FAILED; - } - k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0, - ut_params->cop, num_pkts); - if (k != num_pkts) { - RTE_LOG(ERR, USER1, "rte_cryptodev_enqueue_burst fail\n"); - return TEST_FAILED; - } - - k = rte_cryptodev_dequeue_burst(ts_params->valid_dev, 0, - ut_params->cop, num_pkts); - if (k != num_pkts) { - RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n"); - return TEST_FAILED; - } - - ng = rte_ipsec_pkt_crypto_group( - (const struct rte_crypto_op **)(uintptr_t)ut_params->cop, - ut_params->obuf, grp, num_pkts); - if (ng != 1 || - grp[0].m[0] != ut_params->obuf[0] || - grp[0].cnt != num_pkts || - grp[0].id.ptr != &ut_params->ss[0]) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail\n"); - return TEST_FAILED; - } - - /* call crypto process */ - k = rte_ipsec_pkt_process(grp[0].id.ptr, grp[0].m, grp[0].cnt); - if (k != num_pkts) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n"); - return TEST_FAILED; - } - - return TEST_SUCCESS; -} - -static int -lksd_proto_ipsec(uint16_t num_pkts) -{ - struct ipsec_unitest_params *ut_params = &unittest_params; - uint32_t i, k, ng; - struct rte_ipsec_group grp[1]; - - /* call crypto prepare */ - k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[0], ut_params->ibuf, - ut_params->cop, num_pkts); - if (k != num_pkts) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n"); - return TEST_FAILED; - } - - /* check crypto ops */ - for (i = 0; i != num_pkts; i++) { - TEST_ASSERT_EQUAL(ut_params->cop[i]->type, - RTE_CRYPTO_OP_TYPE_SYMMETRIC, - "%s: invalid crypto op type for %u-th packet\n", - __func__, i); - TEST_ASSERT_EQUAL(ut_params->cop[i]->status, - RTE_CRYPTO_OP_STATUS_NOT_PROCESSED, - "%s: invalid crypto op status for %u-th packet\n", - __func__, i); - TEST_ASSERT_EQUAL(ut_params->cop[i]->sess_type, - RTE_CRYPTO_OP_SECURITY_SESSION, - "%s: invalid crypto op sess_type for %u-th packet\n", - __func__, i); - TEST_ASSERT_EQUAL(ut_params->cop[i]->sym->m_src, - ut_params->ibuf[i], - "%s: invalid crypto op m_src for %u-th packet\n", - __func__, i); - } - - /* update crypto ops, pretend all finished ok */ - for (i = 0; i != num_pkts; i++) - ut_params->cop[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS; - - ng = rte_ipsec_pkt_crypto_group( - (const struct rte_crypto_op **)(uintptr_t)ut_params->cop, - ut_params->obuf, grp, num_pkts); - if (ng != 1 || - grp[0].m[0] != ut_params->obuf[0] || - grp[0].cnt != num_pkts || - grp[0].id.ptr != &ut_params->ss[0]) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail\n"); - return TEST_FAILED; - } - - /* call crypto process */ - k = rte_ipsec_pkt_process(grp[0].id.ptr, grp[0].m, grp[0].cnt); - if (k != num_pkts) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n"); - return TEST_FAILED; - } - - return TEST_SUCCESS; -} - -static int -crypto_ipsec_2sa(void) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - struct rte_ipsec_group grp[BURST_SIZE]; - - uint32_t k, ng, i, r; - - for (i = 0; i < BURST_SIZE; i++) { - r = i % 2; - /* call crypto prepare */ - k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[r], - ut_params->ibuf + i, ut_params->cop + i, 1); - if (k != 1) { - RTE_LOG(ERR, USER1, - "rte_ipsec_pkt_crypto_prepare fail\n"); - return TEST_FAILED; - } - k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0, - ut_params->cop + i, 1); - if (k != 1) { - RTE_LOG(ERR, USER1, - "rte_cryptodev_enqueue_burst fail\n"); - return TEST_FAILED; - } - } - - k = rte_cryptodev_dequeue_burst(ts_params->valid_dev, 0, - ut_params->cop, BURST_SIZE); - if (k != BURST_SIZE) { - RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n"); - return TEST_FAILED; - } - - ng = rte_ipsec_pkt_crypto_group( - (const struct rte_crypto_op **)(uintptr_t)ut_params->cop, - ut_params->obuf, grp, BURST_SIZE); - if (ng != BURST_SIZE) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail ng=%d\n", - ng); - return TEST_FAILED; - } - - /* call crypto process */ - for (i = 0; i < ng; i++) { - k = rte_ipsec_pkt_process(grp[i].id.ptr, grp[i].m, grp[i].cnt); - if (k != grp[i].cnt) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n"); - return TEST_FAILED; - } - } - return TEST_SUCCESS; -} - -#define PKT_4 4 -#define PKT_12 12 -#define PKT_21 21 - -static uint32_t -crypto_ipsec_4grp(uint32_t pkt_num) -{ - uint32_t sa_ind; - - /* group packets in 4 different size groups groups, 2 per SA */ - if (pkt_num < PKT_4) - sa_ind = 0; - else if (pkt_num < PKT_12) - sa_ind = 1; - else if (pkt_num < PKT_21) - sa_ind = 0; - else - sa_ind = 1; - - return sa_ind; -} - -static uint32_t -crypto_ipsec_4grp_check_mbufs(uint32_t grp_ind, struct rte_ipsec_group *grp) -{ - struct ipsec_unitest_params *ut_params = &unittest_params; - uint32_t i, j; - uint32_t rc = 0; - - if (grp_ind == 0) { - for (i = 0, j = 0; i < PKT_4; i++, j++) - if (grp[grp_ind].m[i] != ut_params->obuf[j]) { - rc = TEST_FAILED; - break; - } - } else if (grp_ind == 1) { - for (i = 0, j = PKT_4; i < (PKT_12 - PKT_4); i++, j++) { - if (grp[grp_ind].m[i] != ut_params->obuf[j]) { - rc = TEST_FAILED; - break; - } - } - } else if (grp_ind == 2) { - for (i = 0, j = PKT_12; i < (PKT_21 - PKT_12); i++, j++) - if (grp[grp_ind].m[i] != ut_params->obuf[j]) { - rc = TEST_FAILED; - break; - } - } else if (grp_ind == 3) { - for (i = 0, j = PKT_21; i < (BURST_SIZE - PKT_21); i++, j++) - if (grp[grp_ind].m[i] != ut_params->obuf[j]) { - rc = TEST_FAILED; - break; - } - } else - rc = TEST_FAILED; - - return rc; -} - -static uint32_t -crypto_ipsec_4grp_check_cnt(uint32_t grp_ind, struct rte_ipsec_group *grp) -{ - uint32_t rc = 0; - - if (grp_ind == 0) { - if (grp[grp_ind].cnt != PKT_4) - rc = TEST_FAILED; - } else if (grp_ind == 1) { - if (grp[grp_ind].cnt != PKT_12 - PKT_4) - rc = TEST_FAILED; - } else if (grp_ind == 2) { - if (grp[grp_ind].cnt != PKT_21 - PKT_12) - rc = TEST_FAILED; - } else if (grp_ind == 3) { - if (grp[grp_ind].cnt != BURST_SIZE - PKT_21) - rc = TEST_FAILED; - } else - rc = TEST_FAILED; - - return rc; -} - -static int -crypto_ipsec_2sa_4grp(void) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - struct rte_ipsec_group grp[BURST_SIZE]; - uint32_t k, ng, i, j; - uint32_t rc = 0; - - for (i = 0; i < BURST_SIZE; i++) { - j = crypto_ipsec_4grp(i); - - /* call crypto prepare */ - k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[j], - ut_params->ibuf + i, ut_params->cop + i, 1); - if (k != 1) { - RTE_LOG(ERR, USER1, - "rte_ipsec_pkt_crypto_prepare fail\n"); - return TEST_FAILED; - } - k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0, - ut_params->cop + i, 1); - if (k != 1) { - RTE_LOG(ERR, USER1, - "rte_cryptodev_enqueue_burst fail\n"); - return TEST_FAILED; - } - } - - k = rte_cryptodev_dequeue_burst(ts_params->valid_dev, 0, - ut_params->cop, BURST_SIZE); - if (k != BURST_SIZE) { - RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n"); - return TEST_FAILED; - } - - ng = rte_ipsec_pkt_crypto_group( - (const struct rte_crypto_op **)(uintptr_t)ut_params->cop, - ut_params->obuf, grp, BURST_SIZE); - if (ng != 4) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail ng=%d\n", - ng); - return TEST_FAILED; - } - - /* call crypto process */ - for (i = 0; i < ng; i++) { - k = rte_ipsec_pkt_process(grp[i].id.ptr, grp[i].m, grp[i].cnt); - if (k != grp[i].cnt) { - RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n"); - return TEST_FAILED; - } - rc = crypto_ipsec_4grp_check_cnt(i, grp); - if (rc != 0) { - RTE_LOG(ERR, USER1, - "crypto_ipsec_4grp_check_cnt fail\n"); - return TEST_FAILED; - } - rc = crypto_ipsec_4grp_check_mbufs(i, grp); - if (rc != 0) { - RTE_LOG(ERR, USER1, - "crypto_ipsec_4grp_check_mbufs fail\n"); - return TEST_FAILED; - } - } - return TEST_SUCCESS; -} - -static void -test_ipsec_reorder_inb_pkt_burst(uint16_t num_pkts) -{ - struct ipsec_unitest_params *ut_params = &unittest_params; - struct rte_mbuf *ibuf_tmp[BURST_SIZE]; - uint16_t j; - - /* reorder packets and create gaps in sequence numbers */ - static const uint32_t reorder[BURST_SIZE] = { - 24, 25, 26, 27, 28, 29, 30, 31, - 16, 17, 18, 19, 20, 21, 22, 23, - 8, 9, 10, 11, 12, 13, 14, 15, - 0, 1, 2, 3, 4, 5, 6, 7, - }; - - if (num_pkts != BURST_SIZE) - return; - - for (j = 0; j != BURST_SIZE; j++) - ibuf_tmp[j] = ut_params->ibuf[reorder[j]]; - - memcpy(ut_params->ibuf, ibuf_tmp, sizeof(ut_params->ibuf)); -} - -static int -test_ipsec_crypto_op_alloc(uint16_t num_pkts) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - int rc = 0; - uint16_t j; - - for (j = 0; j < num_pkts && rc == 0; j++) { - ut_params->cop[j] = rte_crypto_op_alloc(ts_params->cop_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - if (ut_params->cop[j] == NULL) { - RTE_LOG(ERR, USER1, - "Failed to allocate symmetric crypto op\n"); - rc = TEST_FAILED; - } - } - - return rc; -} - -static void -test_ipsec_dump_buffers(struct ipsec_unitest_params *ut_params, int i) -{ - uint16_t j = ut_params->pkt_index; - - printf("\ntest config: num %d\n", i); - printf(" replay_win_sz %u\n", test_cfg[i].replay_win_sz); - printf(" esn %u\n", test_cfg[i].esn); - printf(" flags 0x%" PRIx64 "\n", test_cfg[i].flags); - printf(" pkt_sz %zu\n", test_cfg[i].pkt_sz); - printf(" num_pkts %u\n\n", test_cfg[i].num_pkts); - - if (ut_params->ibuf[j]) { - printf("ibuf[%u] data:\n", j); - rte_pktmbuf_dump(stdout, ut_params->ibuf[j], - ut_params->ibuf[j]->data_len); - } - if (ut_params->obuf[j]) { - printf("obuf[%u] data:\n", j); - rte_pktmbuf_dump(stdout, ut_params->obuf[j], - ut_params->obuf[j]->data_len); - } - if (ut_params->testbuf[j]) { - printf("testbuf[%u] data:\n", j); - rte_pktmbuf_dump(stdout, ut_params->testbuf[j], - ut_params->testbuf[j]->data_len); - } -} - -static void -destroy_sa(uint32_t j) -{ - struct ipsec_unitest_params *ut = &unittest_params; - - rte_ipsec_sa_fini(ut->ss[j].sa); - rte_free(ut->ss[j].sa); - rte_cryptodev_sym_session_free(ut->ss[j].crypto.ses); - memset(&ut->ss[j], 0, sizeof(ut->ss[j])); -} - -static int -crypto_inb_burst_null_null_check(struct ipsec_unitest_params *ut_params, int i, - uint16_t num_pkts) -{ - uint16_t j; - - for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) { - ut_params->pkt_index = j; - - /* compare the data buffers */ - TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data, - rte_pktmbuf_mtod(ut_params->obuf[j], void *), - test_cfg[i].pkt_sz, - "input and output data does not match\n"); - TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, - ut_params->obuf[j]->pkt_len, - "data_len is not equal to pkt_len"); - TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, - test_cfg[i].pkt_sz, - "data_len is not equal to input data"); - } - - return 0; -} - -static int -test_ipsec_crypto_inb_burst_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j; - int rc; - - /* create rte_ipsec_sa */ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate test mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - /* packet with sequence number 0 is invalid */ - ut_params->ibuf[j] = setup_test_string_tunneled( - ts_params->mbuf_pool, null_encrypted_data, - test_cfg[i].pkt_sz, INBOUND_SPI, j + 1); - if (ut_params->ibuf[j] == NULL) - rc = TEST_FAILED; - } - - if (rc == 0) { - if (test_cfg[i].reorder_pkts) - test_ipsec_reorder_inb_pkt_burst(num_pkts); - rc = test_ipsec_crypto_op_alloc(num_pkts); - } - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(num_pkts); - if (rc == 0) - rc = crypto_inb_burst_null_null_check( - ut_params, i, num_pkts); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - return rc; -} - -static int -test_ipsec_crypto_inb_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_crypto_inb_burst_null_null(i); - } - - return rc; -} - -static int -crypto_outb_burst_null_null_check(struct ipsec_unitest_params *ut_params, - uint16_t num_pkts) -{ - void *obuf_data; - void *testbuf_data; - uint16_t j; - - for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) { - ut_params->pkt_index = j; - - testbuf_data = rte_pktmbuf_mtod(ut_params->testbuf[j], void *); - obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *); - /* compare the buffer data */ - TEST_ASSERT_BUFFERS_ARE_EQUAL(testbuf_data, obuf_data, - ut_params->obuf[j]->pkt_len, - "test and output data does not match\n"); - TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, - ut_params->testbuf[j]->data_len, - "obuf data_len is not equal to testbuf data_len"); - TEST_ASSERT_EQUAL(ut_params->obuf[j]->pkt_len, - ut_params->testbuf[j]->pkt_len, - "obuf pkt_len is not equal to testbuf pkt_len"); - } - - return 0; -} - -static int -test_ipsec_crypto_outb_burst_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j; - int32_t rc; - - /* create rte_ipsec_sa*/ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate input mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, 0); - if (ut_params->ibuf[j] == NULL) - rc = TEST_FAILED; - else { - /* Generate test mbuf data */ - /* packet with sequence number 0 is invalid */ - ut_params->testbuf[j] = setup_test_string_tunneled( - ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, - OUTBOUND_SPI, j + 1); - if (ut_params->testbuf[j] == NULL) - rc = TEST_FAILED; - } - } - - if (rc == 0) - rc = test_ipsec_crypto_op_alloc(num_pkts); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(num_pkts); - if (rc == 0) - rc = crypto_outb_burst_null_null_check(ut_params, - num_pkts); - else - RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", - i); - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - return rc; -} - -static int -test_ipsec_crypto_outb_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = OUTBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_crypto_outb_burst_null_null(i); - } - - return rc; -} - -static int -inline_inb_burst_null_null_check(struct ipsec_unitest_params *ut_params, int i, - uint16_t num_pkts) -{ - void *ibuf_data; - void *obuf_data; - uint16_t j; - - for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) { - ut_params->pkt_index = j; - - /* compare the buffer data */ - ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf[j], void *); - obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *); - - TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data, - ut_params->ibuf[j]->data_len, - "input and output data does not match\n"); - TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len, - ut_params->obuf[j]->data_len, - "ibuf data_len is not equal to obuf data_len"); - TEST_ASSERT_EQUAL(ut_params->ibuf[j]->pkt_len, - ut_params->obuf[j]->pkt_len, - "ibuf pkt_len is not equal to obuf pkt_len"); - TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len, - test_cfg[i].pkt_sz, - "data_len is not equal input data"); - } - return 0; -} - -static int -test_ipsec_inline_crypto_inb_burst_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j; - int32_t rc; - uint32_t n; - - /* create rte_ipsec_sa*/ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate inbound mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - ut_params->ibuf[j] = setup_test_string_tunneled( - ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, - INBOUND_SPI, j + 1); - if (ut_params->ibuf[j] == NULL) - rc = TEST_FAILED; - else { - /* Generate test mbuf data */ - ut_params->obuf[j] = setup_test_string( - ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, 0); - if (ut_params->obuf[j] == NULL) - rc = TEST_FAILED; - } - } - - if (rc == 0) { - n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf, - num_pkts); - if (n == num_pkts) - rc = inline_inb_burst_null_null_check(ut_params, i, - num_pkts); - else { - RTE_LOG(ERR, USER1, - "rte_ipsec_pkt_process failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - return rc; -} - -static int -test_ipsec_inline_crypto_inb_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_inline_crypto_inb_burst_null_null(i); - } - - return rc; -} - -static int -test_ipsec_inline_proto_inb_burst_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j; - int32_t rc; - uint32_t n; - - /* create rte_ipsec_sa*/ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate inbound mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - ut_params->ibuf[j] = setup_test_string( - ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, 0); - if (ut_params->ibuf[j] == NULL) - rc = TEST_FAILED; - else { - /* Generate test mbuf data */ - ut_params->obuf[j] = setup_test_string( - ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, 0); - if (ut_params->obuf[j] == NULL) - rc = TEST_FAILED; - } - } - - if (rc == 0) { - n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf, - num_pkts); - if (n == num_pkts) - rc = inline_inb_burst_null_null_check(ut_params, i, - num_pkts); - else { - RTE_LOG(ERR, USER1, - "rte_ipsec_pkt_process failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - return rc; -} - -static int -test_ipsec_inline_proto_inb_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_inline_proto_inb_burst_null_null(i); - } - - return rc; -} - -static int -inline_outb_burst_null_null_check(struct ipsec_unitest_params *ut_params, - uint16_t num_pkts) -{ - void *obuf_data; - void *ibuf_data; - uint16_t j; - - for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) { - ut_params->pkt_index = j; - - /* compare the buffer data */ - ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf[j], void *); - obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *); - TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data, - ut_params->ibuf[j]->data_len, - "input and output data does not match\n"); - TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len, - ut_params->obuf[j]->data_len, - "ibuf data_len is not equal to obuf data_len"); - TEST_ASSERT_EQUAL(ut_params->ibuf[j]->pkt_len, - ut_params->obuf[j]->pkt_len, - "ibuf pkt_len is not equal to obuf pkt_len"); - - /* check mbuf ol_flags */ - TEST_ASSERT(ut_params->ibuf[j]->ol_flags & PKT_TX_SEC_OFFLOAD, - "ibuf PKT_TX_SEC_OFFLOAD is not set"); - } - return 0; -} - -static int -test_ipsec_inline_crypto_outb_burst_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j; - int32_t rc; - uint32_t n; - - /* create rte_ipsec_sa */ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate test mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, 0); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - - if (rc == 0) { - /* Generate test tunneled mbuf data for comparison */ - ut_params->obuf[j] = setup_test_string_tunneled( - ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, - OUTBOUND_SPI, j + 1); - if (ut_params->obuf[j] == NULL) - rc = TEST_FAILED; - } - } - - if (rc == 0) { - n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf, - num_pkts); - if (n == num_pkts) - rc = inline_outb_burst_null_null_check(ut_params, - num_pkts); - else { - RTE_LOG(ERR, USER1, - "rte_ipsec_pkt_process failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - return rc; -} - -static int -test_ipsec_inline_crypto_outb_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = OUTBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_inline_crypto_outb_burst_null_null(i); - } - - return rc; -} - -static int -test_ipsec_inline_proto_outb_burst_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j; - int32_t rc; - uint32_t n; - - /* create rte_ipsec_sa */ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate test mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, 0); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - - if (rc == 0) { - /* Generate test tunneled mbuf data for comparison */ - ut_params->obuf[j] = setup_test_string( - ts_params->mbuf_pool, - null_plain_data, test_cfg[i].pkt_sz, 0); - if (ut_params->obuf[j] == NULL) - rc = TEST_FAILED; - } - } - - if (rc == 0) { - n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf, - num_pkts); - if (n == num_pkts) - rc = inline_outb_burst_null_null_check(ut_params, - num_pkts); - else { - RTE_LOG(ERR, USER1, - "rte_ipsec_pkt_process failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - return rc; -} - -static int -test_ipsec_inline_proto_outb_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = OUTBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_inline_proto_outb_burst_null_null(i); - } - - return rc; -} - -static int -test_ipsec_lksd_proto_inb_burst_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j; - int rc; - - /* create rte_ipsec_sa */ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate test mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - /* packet with sequence number 0 is invalid */ - ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, - null_encrypted_data, test_cfg[i].pkt_sz, 0); - if (ut_params->ibuf[j] == NULL) - rc = TEST_FAILED; - } - - if (rc == 0) { - if (test_cfg[i].reorder_pkts) - test_ipsec_reorder_inb_pkt_burst(num_pkts); - rc = test_ipsec_crypto_op_alloc(num_pkts); - } - - if (rc == 0) { - /* call ipsec library api */ - rc = lksd_proto_ipsec(num_pkts); - if (rc == 0) - rc = crypto_inb_burst_null_null_check(ut_params, i, - num_pkts); - else { - RTE_LOG(ERR, USER1, "%s failed, cfg %d\n", - __func__, i); - rc = TEST_FAILED; - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - return rc; -} - -static int -test_ipsec_lksd_proto_inb_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_lksd_proto_inb_burst_null_null(i); - } - - return rc; -} - -static int -test_ipsec_lksd_proto_outb_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_lksd_proto_inb_burst_null_null(i); - } - - return rc; -} - -static int -replay_inb_null_null_check(struct ipsec_unitest_params *ut_params, int i, - int num_pkts) -{ - uint16_t j; - - for (j = 0; j < num_pkts; j++) { - /* compare the buffer data */ - TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data, - rte_pktmbuf_mtod(ut_params->obuf[j], void *), - test_cfg[i].pkt_sz, - "input and output data does not match\n"); - - TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, - ut_params->obuf[j]->pkt_len, - "data_len is not equal to pkt_len"); - } - - return 0; -} - -static int -test_ipsec_replay_inb_inside_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - int rc; - - /* create rte_ipsec_sa*/ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate inbound mbuf data */ - ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool, - null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - else - rc = test_ipsec_crypto_op_alloc(1); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(1); - if (rc == 0) - rc = replay_inb_null_null_check(ut_params, i, 1); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) { - /* generate packet with seq number inside the replay window */ - if (ut_params->ibuf[0]) { - rte_pktmbuf_free(ut_params->ibuf[0]); - ut_params->ibuf[0] = 0; - } - - ut_params->ibuf[0] = setup_test_string_tunneled( - ts_params->mbuf_pool, null_encrypted_data, - test_cfg[i].pkt_sz, INBOUND_SPI, - test_cfg[i].replay_win_sz); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - else - rc = test_ipsec_crypto_op_alloc(1); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(1); - if (rc == 0) - rc = replay_inb_null_null_check( - ut_params, i, 1); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed\n"); - rc = TEST_FAILED; - } - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - - return rc; -} - -static int -test_ipsec_replay_inb_inside_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_replay_inb_inside_null_null(i); - } - - return rc; -} - -static int -test_ipsec_replay_inb_outside_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - int rc; - - /* create rte_ipsec_sa */ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate test mbuf data */ - ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool, - null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, - test_cfg[i].replay_win_sz + 2); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - else - rc = test_ipsec_crypto_op_alloc(1); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(1); - if (rc == 0) - rc = replay_inb_null_null_check(ut_params, i, 1); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) { - /* generate packet with seq number outside the replay window */ - if (ut_params->ibuf[0]) { - rte_pktmbuf_free(ut_params->ibuf[0]); - ut_params->ibuf[0] = 0; - } - ut_params->ibuf[0] = setup_test_string_tunneled( - ts_params->mbuf_pool, null_encrypted_data, - test_cfg[i].pkt_sz, INBOUND_SPI, 1); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - else - rc = test_ipsec_crypto_op_alloc(1); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(1); - if (rc == 0) { - if (test_cfg[i].esn == 0) { - RTE_LOG(ERR, USER1, - "packet is not outside the replay window, cfg %d pkt0_seq %u pkt1_seq %u\n", - i, - test_cfg[i].replay_win_sz + 2, - 1); - rc = TEST_FAILED; - } - } else { - RTE_LOG(ERR, USER1, - "packet is outside the replay window, cfg %d pkt0_seq %u pkt1_seq %u\n", - i, test_cfg[i].replay_win_sz + 2, 1); - rc = 0; - } - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - - return rc; -} - -static int -test_ipsec_replay_inb_outside_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_replay_inb_outside_null_null(i); - } - - return rc; -} - -static int -test_ipsec_replay_inb_repeat_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - int rc; - - /* create rte_ipsec_sa */ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", i); - return TEST_FAILED; - } - - /* Generate test mbuf data */ - ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool, - null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - else - rc = test_ipsec_crypto_op_alloc(1); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(1); - if (rc == 0) - rc = replay_inb_null_null_check(ut_params, i, 1); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) { - /* - * generate packet with repeat seq number in the replay - * window - */ - if (ut_params->ibuf[0]) { - rte_pktmbuf_free(ut_params->ibuf[0]); - ut_params->ibuf[0] = 0; - } - - ut_params->ibuf[0] = setup_test_string_tunneled( - ts_params->mbuf_pool, null_encrypted_data, - test_cfg[i].pkt_sz, INBOUND_SPI, 1); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - else - rc = test_ipsec_crypto_op_alloc(1); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(1); - if (rc == 0) { - RTE_LOG(ERR, USER1, - "packet is not repeated in the replay window, cfg %d seq %u\n", - i, 1); - rc = TEST_FAILED; - } else { - RTE_LOG(ERR, USER1, - "packet is repeated in the replay window, cfg %d seq %u\n", - i, 1); - rc = 0; - } - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - - return rc; -} - -static int -test_ipsec_replay_inb_repeat_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_replay_inb_repeat_null_null(i); - } - - return rc; -} - -static int -test_ipsec_replay_inb_inside_burst_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - int rc; - int j; - - /* create rte_ipsec_sa*/ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* Generate inbound mbuf data */ - ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool, - null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1); - if (ut_params->ibuf[0] == NULL) - rc = TEST_FAILED; - else - rc = test_ipsec_crypto_op_alloc(1); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(1); - if (rc == 0) - rc = replay_inb_null_null_check(ut_params, i, 1); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) { - /* - * generate packet(s) with seq number(s) inside the - * replay window - */ - if (ut_params->ibuf[0]) { - rte_pktmbuf_free(ut_params->ibuf[0]); - ut_params->ibuf[0] = 0; - } - - for (j = 0; j < num_pkts && rc == 0; j++) { - /* packet with sequence number 1 already processed */ - ut_params->ibuf[j] = setup_test_string_tunneled( - ts_params->mbuf_pool, null_encrypted_data, - test_cfg[i].pkt_sz, INBOUND_SPI, j + 2); - if (ut_params->ibuf[j] == NULL) - rc = TEST_FAILED; - } - - if (rc == 0) { - if (test_cfg[i].reorder_pkts) - test_ipsec_reorder_inb_pkt_burst(num_pkts); - rc = test_ipsec_crypto_op_alloc(num_pkts); - } - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec(num_pkts); - if (rc == 0) - rc = replay_inb_null_null_check( - ut_params, i, num_pkts); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed\n"); - rc = TEST_FAILED; - } - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - - return rc; -} - -static int -test_ipsec_replay_inb_inside_burst_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_replay_inb_inside_burst_null_null(i); - } - - return rc; -} - - -static int -crypto_inb_burst_2sa_null_null_check(struct ipsec_unitest_params *ut_params, - int i) -{ - uint16_t j; - - for (j = 0; j < BURST_SIZE; j++) { - ut_params->pkt_index = j; - - /* compare the data buffers */ - TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data, - rte_pktmbuf_mtod(ut_params->obuf[j], void *), - test_cfg[i].pkt_sz, - "input and output data does not match\n"); - TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, - ut_params->obuf[j]->pkt_len, - "data_len is not equal to pkt_len"); - TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len, - test_cfg[i].pkt_sz, - "data_len is not equal to input data"); - } - - return 0; -} - -static int -test_ipsec_crypto_inb_burst_2sa_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j, r; - int rc = 0; - - if (num_pkts != BURST_SIZE) - return rc; - - /* create rte_ipsec_sa */ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* create second rte_ipsec_sa */ - ut_params->ipsec_xform.spi = INBOUND_SPI + 1; - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 1); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - destroy_sa(0); - return TEST_FAILED; - } - - /* Generate test mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - r = j % 2; - /* packet with sequence number 0 is invalid */ - ut_params->ibuf[j] = setup_test_string_tunneled( - ts_params->mbuf_pool, null_encrypted_data, - test_cfg[i].pkt_sz, INBOUND_SPI + r, j + 1); - if (ut_params->ibuf[j] == NULL) - rc = TEST_FAILED; - } - - if (rc == 0) - rc = test_ipsec_crypto_op_alloc(num_pkts); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec_2sa(); - if (rc == 0) - rc = crypto_inb_burst_2sa_null_null_check( - ut_params, i); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - destroy_sa(1); - return rc; -} - -static int -test_ipsec_crypto_inb_burst_2sa_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_crypto_inb_burst_2sa_null_null(i); - } - - return rc; -} - -static int -test_ipsec_crypto_inb_burst_2sa_4grp_null_null(int i) -{ - struct ipsec_testsuite_params *ts_params = &testsuite_params; - struct ipsec_unitest_params *ut_params = &unittest_params; - uint16_t num_pkts = test_cfg[i].num_pkts; - uint16_t j, k; - int rc = 0; - - if (num_pkts != BURST_SIZE) - return rc; - - /* create rte_ipsec_sa */ - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - return TEST_FAILED; - } - - /* create second rte_ipsec_sa */ - ut_params->ipsec_xform.spi = INBOUND_SPI + 1; - rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, - test_cfg[i].replay_win_sz, test_cfg[i].flags, 1); - if (rc != 0) { - RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed, cfg %d\n", - i); - destroy_sa(0); - return TEST_FAILED; - } - - /* Generate test mbuf data */ - for (j = 0; j < num_pkts && rc == 0; j++) { - k = crypto_ipsec_4grp(j); - - /* packet with sequence number 0 is invalid */ - ut_params->ibuf[j] = setup_test_string_tunneled( - ts_params->mbuf_pool, null_encrypted_data, - test_cfg[i].pkt_sz, INBOUND_SPI + k, j + 1); - if (ut_params->ibuf[j] == NULL) - rc = TEST_FAILED; - } - - if (rc == 0) - rc = test_ipsec_crypto_op_alloc(num_pkts); - - if (rc == 0) { - /* call ipsec library api */ - rc = crypto_ipsec_2sa_4grp(); - if (rc == 0) - rc = crypto_inb_burst_2sa_null_null_check( - ut_params, i); - else { - RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n", - i); - rc = TEST_FAILED; - } - } - - if (rc == TEST_FAILED) - test_ipsec_dump_buffers(ut_params, i); - - destroy_sa(0); - destroy_sa(1); - return rc; -} - -static int -test_ipsec_crypto_inb_burst_2sa_4grp_null_null_wrapper(void) -{ - int i; - int rc = 0; - struct ipsec_unitest_params *ut_params = &unittest_params; - - ut_params->ipsec_xform.spi = INBOUND_SPI; - ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; - ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; - ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; - ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; - - for (i = 0; i < num_cfg && rc == 0; i++) { - ut_params->ipsec_xform.options.esn = test_cfg[i].esn; - rc = test_ipsec_crypto_inb_burst_2sa_4grp_null_null(i); - } - - return rc; -} - -static struct unit_test_suite ipsec_testsuite = { - .suite_name = "IPsec NULL Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_crypto_inb_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_crypto_outb_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_inline_crypto_inb_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_inline_crypto_outb_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_inline_proto_inb_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_inline_proto_outb_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_lksd_proto_inb_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_lksd_proto_outb_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_replay_inb_inside_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_replay_inb_outside_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_replay_inb_repeat_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_replay_inb_inside_burst_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_crypto_inb_burst_2sa_null_null_wrapper), - TEST_CASE_ST(ut_setup, ut_teardown, - test_ipsec_crypto_inb_burst_2sa_4grp_null_null_wrapper), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_ipsec(void) -{ - return unit_test_suite_runner(&ipsec_testsuite); -} - -REGISTER_TEST_COMMAND(ipsec_autotest, test_ipsec); diff --git a/test/test/test_kni.c b/test/test/test_kni.c deleted file mode 100644 index c92c09054f..0000000000 --- a/test/test/test_kni.c +++ /dev/null @@ -1,739 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#if !defined(RTE_EXEC_ENV_LINUXAPP) || !defined(RTE_LIBRTE_KNI) - -static int -test_kni(void) -{ - printf("KNI not supported, skipping test\n"); - return TEST_SKIPPED; -} - -#else - -#include -#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 1024 -#define NB_TXD 1024 -#define KNI_TIMEOUT_MS 5000 /* ms */ - -#define IFCONFIG "/sbin/ifconfig " -#define TEST_KNI_PORT "test_kni_port" -#define KNI_MODULE_PATH "/sys/module/rte_kni" -#define KNI_MODULE_PARAM_LO KNI_MODULE_PATH"/parameters/lo_mode" -#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 = { - .txmode = { - .mq_mode = ETH_DCB_NONE, - }, -}; - -static struct rte_kni_ops kni_ops = { - .change_mtu = NULL, - .config_network_if = NULL, - .config_mac_address = NULL, - .config_promiscusity = 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(uint16_t port_id, unsigned int 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; -} - -static int -test_kni_link_change(void) -{ - int ret; - int pid; - - pid = fork(); - if (pid < 0) { - printf("Error: Failed to fork a process\n"); - return -1; - } - - if (pid == 0) { - printf("Starting KNI Link status change tests.\n"); - if (system(IFCONFIG TEST_KNI_PORT" up") == -1) { - ret = -1; - goto error; - } - - ret = rte_kni_update_link(test_kni_ctx, 1); - if (ret < 0) { - printf("Failed to change link state to Up ret=%d.\n", - ret); - goto error; - } - rte_delay_ms(1000); - printf("KNI: Set LINKUP, previous state=%d\n", ret); - - ret = rte_kni_update_link(test_kni_ctx, 0); - if (ret != 1) { - printf( - "Failed! Previous link state should be 1, returned %d.\n", - ret); - goto error; - } - rte_delay_ms(1000); - printf("KNI: Set LINKDOWN, previous state=%d\n", ret); - - ret = rte_kni_update_link(test_kni_ctx, 1); - if (ret != 0) { - printf( - "Failed! Previous link state should be 0, returned %d.\n", - ret); - goto error; - } - printf("KNI: Set LINKUP, previous state=%d\n", ret); - - ret = 0; - rte_delay_ms(1000); - -error: - if (system(IFCONFIG TEST_KNI_PORT" down") == -1) - ret = -1; - - printf("KNI: Link status change tests: %s.\n", - (ret == 0) ? "Passed" : "Failed"); - exit(ret); - } else { - int p_ret, status; - - while (1) { - p_ret = waitpid(pid, &status, WNOHANG); - if (p_ret != 0) { - if (WIFEXITED(status)) - return WEXITSTATUS(status); - return -1; - } - rte_delay_ms(10); - rte_kni_handle_request(test_kni_ctx); - } - } -} -/** - * 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, - .config_mac_address = NULL, - .config_promiscusity = 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(uint16_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; - const struct rte_pci_device *pci_dev; - const struct rte_bus *bus = NULL; - - 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); - if (info.device) - bus = rte_bus_find_by_device(info.device); - if (bus && !strcmp(bus->name, "pci")) { - pci_dev = RTE_DEV_TO_PCI(info.device); - conf.addr = pci_dev->addr; - conf.id = 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 = 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; - } - - ret = test_kni_link_change(); - if (ret != 0) - 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 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; - uint16_t 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; - const struct rte_pci_device *pci_dev; - const struct rte_bus *bus; - FILE *fd; - DIR *dir; - char buf[16]; - - dir = opendir(KNI_MODULE_PATH); - if (!dir) { - if (errno == ENOENT) { - printf("Cannot run UT due to missing rte_kni module\n"); - return TEST_SKIPPED; - } - printf("opendir: %s", strerror(errno)); - return -1; - } - closedir(dir); - - /* 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; - } - - /* 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 */ - fd = fopen(KNI_MODULE_PARAM_LO, "r"); - if (fd == NULL) { - printf("fopen: %s", strerror(errno)); - return -1; - } - memset(&buf, 0, sizeof(buf)); - if (fgets(buf, sizeof(buf), fd)) { - if (!strncmp(buf, "lo_mode_fifo", strlen("lo_mode_fifo")) || - !strncmp(buf, "lo_mode_fifo_skb", - strlen("lo_mode_fifo_skb"))) { - ret = test_kni_processing(port_id, mp); - if (ret < 0) { - fclose(fd); - goto fail; - } - } else - printf("test_kni_processing skipped because of missing rte_kni module lo_mode argument\n"); - } - fclose(fd); - - /* 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); - if (info.device) - bus = rte_bus_find_by_device(info.device); - else - bus = NULL; - if (bus && !strcmp(bus->name, "pci")) { - pci_dev = RTE_DEV_TO_PCI(info.device); - conf.addr = pci_dev->addr; - conf.id = pci_dev->id; - } - conf.group_id = 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); - if (info.device) - bus = rte_bus_find_by_device(info.device); - else - bus = NULL; - if (bus && !strcmp(bus->name, "pci")) { - pci_dev = RTE_DEV_TO_PCI(info.device); - conf.addr = pci_dev->addr; - conf.id = pci_dev->id; - } - conf.group_id = 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; -} - -#endif - -REGISTER_TEST_COMMAND(kni_autotest, test_kni); diff --git a/test/test/test_kvargs.c b/test/test/test_kvargs.c deleted file mode 100644 index a42056f361..0000000000 --- a/test/test/test_kvargs.c +++ /dev/null @@ -1,227 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2014 6WIND S.A. - */ - -#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); - - /* third test using list as value */ - args = "foo=[0,1],check=value2"; - valid_keys = valid_keys_list; - kvlist = rte_kvargs_parse(args, valid_keys); - if (kvlist == NULL) { - printf("rte_kvargs_parse() error"); - goto fail; - } - if (strcmp(kvlist->pairs[0].value, "[0,1]") != 0) { - printf("wrong value %s", kvlist->pairs[0].value); - goto fail; - } - count = kvlist->count; - if (count != 2) { - printf("invalid count value %d\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 */ - "foo=[1,2", /* no closing bracket in value */ - ",=", /* 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_latencystats.c b/test/test/test_latencystats.c deleted file mode 100644 index 039c508cd1..0000000000 --- a/test/test/test_latencystats.c +++ /dev/null @@ -1,224 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include -#include -#include - -#include -#include "rte_lcore.h" -#include "rte_metrics.h" - -#include "sample_packet_forward.h" -#include "test.h" - -#define NUM_STATS 4 -#define LATENCY_NUM_PACKETS 10 -#define QUEUE_ID 0 - -uint16_t portid; -struct rte_ring *ring; - -struct rte_metric_name lat_stats_strings[] = { - {"min_latency_ns"}, - {"avg_latency_ns"}, - {"max_latency_ns"}, - {"jitter_ns"}, -}; - -/* Test case for latency init with metrics init */ -static int test_latency_init(void) -{ - int ret = 0; - - /* Metrics Initialization */ - rte_metrics_init(rte_socket_id()); - - ret = rte_latencystats_init(1, NULL); - TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_init failed"); - - return TEST_SUCCESS; -} - -/* Test case to update the latency stats */ -static int test_latency_update(void) -{ - int ret = 0; - - ret = rte_latencystats_update(); - TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_update failed"); - - return TEST_SUCCESS; -} - -/* Test case to uninit latency stats */ -static int test_latency_uninit(void) -{ - int ret = 0; - - ret = rte_latencystats_uninit(); - TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_uninit failed"); - - return TEST_SUCCESS; -} - -/* Test case to get names of latency stats */ -static int test_latencystats_get_names(void) -{ - int ret = 0, i = 0; - int size = 0; - struct rte_metric_name names[NUM_STATS]; - struct rte_metric_name wrongnames[NUM_STATS - 2]; - - size_t m_size = sizeof(struct rte_metric_name); - for (i = 0; i < NUM_STATS; i++) - memset(&names[i], 0, m_size); - for (i = 0; i < NUM_STATS - 2; i++) - memset(&wrongnames[i], 0, m_size); - - /* Success Test: Valid names and size */ - size = NUM_STATS; - ret = rte_latencystats_get_names(names, size); - for (i = 0; i <= NUM_STATS; i++) { - if (strcmp(lat_stats_strings[i].name, names[i].name) == 0) - printf(" %s\n", names[i].name); - else - printf("Failed: Names are not matched\n"); - } - TEST_ASSERT((ret == NUM_STATS), "Test Failed to get metrics names"); - - /* Failure Test: Invalid names and valid size */ - ret = rte_latencystats_get_names(NULL, size); - TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the metrics count," - "Actual: %d Expected: %d", ret, NUM_STATS); - - /* Failure Test: Valid names and invalid size */ - size = 0; - ret = rte_latencystats_get_names(names, size); - TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the metrics count," - "Actual: %d Expected: %d", ret, NUM_STATS); - - /* Failure Test: Invalid names (array size lesser than size) */ - size = NUM_STATS + 1; - ret = rte_latencystats_get_names(wrongnames, size); - TEST_ASSERT((ret == NUM_STATS), "Test Failed to get metrics names"); - return TEST_SUCCESS; -} - -/* Test case to get latency stats values */ -static int test_latencystats_get(void) -{ - int ret = 0, i = 0; - int size = 0; - struct rte_metric_value values[NUM_STATS]; - struct rte_metric_value wrongvalues[NUM_STATS - 2]; - - size_t v_size = sizeof(struct rte_metric_value); - for (i = 0; i < NUM_STATS; i++) - memset(&values[i], 0, v_size); - for (i = 0; i < NUM_STATS - 2; i++) - memset(&wrongvalues[i], 0, v_size); - - /* Success Test: Valid values and valid size */ - size = NUM_STATS; - ret = rte_latencystats_get(values, size); - TEST_ASSERT((ret == NUM_STATS), "Test Failed to get latency metrics" - " values"); - - /* Failure Test: Invalid values and valid size */ - ret = rte_latencystats_get(NULL, size); - TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the stats count," - "Actual: %d Expected: %d", ret, NUM_STATS); - - /* Failure Test: Valid values and invalid size */ - size = 0; - ret = rte_latencystats_get(values, size); - TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the stats count," - "Actual: %d Expected: %d", ret, NUM_STATS); - - /* Failure Test: Invalid values(array size lesser than size) - * and invalid size - */ - size = NUM_STATS + 2; - ret = rte_latencystats_get(wrongvalues, size); - TEST_ASSERT(ret == NUM_STATS, "Test Failed to get latency metrics" - " values"); - - return TEST_SUCCESS; -} - -static int test_latency_ring_setup(void) -{ - test_ring_setup(&ring, &portid); - - return TEST_SUCCESS; -} - -static void test_latency_ring_free(void) -{ - test_ring_free(ring); - test_vdev_uninit("net_ring_net_ringa"); -} - -static int test_latency_packet_forward(void) -{ - int ret; - struct rte_mbuf *pbuf[LATENCY_NUM_PACKETS] = { }; - struct rte_mempool *mp; - char poolname[] = "mbuf_pool"; - - ret = test_get_mbuf_from_pool(&mp, pbuf, poolname); - if (ret < 0) { - printf("allocate mbuf pool Failed\n"); - return TEST_FAILED; - } - ret = test_packet_forward(pbuf, portid, QUEUE_ID); - if (ret < 0) - printf("send pkts Failed\n"); - test_put_mbuf_to_pool(mp, pbuf); - - return TEST_SUCCESS; -} - -static struct -unit_test_suite latencystats_testsuite = { - .suite_name = "Latency Stats Unit Test Suite", - .setup = test_latency_ring_setup, - .teardown = test_latency_ring_free, - .unit_test_cases = { - - /* Test Case 1: To check latency init with - * metrics init - */ - TEST_CASE_ST(NULL, NULL, test_latency_init), - - /* Test Case 2: Do packet forwarding for metrics - * calculation and check the latency metrics values - * are updated - */ - TEST_CASE_ST(test_latency_packet_forward, NULL, - test_latency_update), - /* Test Case 3: To check whether latency stats names - * are retrieved - */ - TEST_CASE_ST(NULL, NULL, test_latencystats_get_names), - - /* Test Case 4: To check whether latency stats - * values are retrieved - */ - TEST_CASE_ST(NULL, NULL, test_latencystats_get), - - /* Test Case 5: To check uninit of latency test */ - TEST_CASE_ST(NULL, NULL, test_latency_uninit), - - TEST_CASES_END() - } -}; - -static int test_latencystats(void) -{ - return unit_test_suite_runner(&latencystats_testsuite); -} - -REGISTER_TEST_COMMAND(latencystats_autotest, test_latencystats); diff --git a/test/test/test_link_bonding.c b/test/test/test_link_bonding.c deleted file mode 100644 index 0fe1d78eb0..0000000000 --- a/test/test/test_link_bonding.c +++ /dev/null @@ -1,4906 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include "unistd.h" -#include -#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 1024 -#define RX_FREE_THRESH 32 -#define RX_PTHRESH 8 -#define RX_HTHRESH 8 -#define RX_WTHRESH 0 - -#define TX_RING_SIZE 1024 -#define TX_FREE_THRESH 32 -#define TX_PTHRESH 32 -#define TX_HTHRESH 0 -#define TX_WTHRESH 0 -#define TX_RSBIT_THRESH 32 - -#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 ("net_bonding_ut") - -#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 { - int16_t bonded_port_id; - int16_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS]; - uint16_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; - -static struct rte_eth_conf default_pmd_conf = { - .rxmode = { - .mq_mode = ETH_MQ_RX_NONE, - .split_hdr_size = 0, - .max_rx_pkt_len = ETHER_MAX_LEN, - }, - .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, -}; - -static void free_virtualpmd_tx_queue(void); - - - -static int -configure_ethdev(uint16_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; - - uint16_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; - - uint16_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; - uint16_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; - uint16_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; - uint16_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; - uint16_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; - uint16_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 */ - free_virtualpmd_tx_queue(); - 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; - - uint16_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("net_bonding_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, - uint16_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 int -test_bonding_lsc_event_callback(uint16_t port_id __rte_unused, - enum rte_eth_event_type type __rte_unused, - void *param __rte_unused, - void *ret_param __rte_unused) -{ - pthread_mutex_lock(&mutex); - test_lsc_interrupt_count++; - - pthread_cond_signal(&cvar); - pthread_mutex_unlock(&mutex); - - return 0; -} - -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; - uint16_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, uint16_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 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."); - - /* 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 initialise 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 (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; - uint16_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]); - } - - /* 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; - - uint16_t slaves[RTE_MAX_ETHPORTS]; - - int i, 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]); - - /* 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, 0, 1); -} - -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 initialise 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 initialise 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 initialise 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 initialise 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; - - uint16_t slaves[RTE_MAX_ETHPORTS]; - - int i, 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 initialise 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); - - /* 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 initialise 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 initialise 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 initialise 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 initialise 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 initialise 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; - - uint16_t slaves[RTE_MAX_ETHPORTS]; - - int i, 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 initialise 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); - - /* 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 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_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; - - uint16_t slaves[RTE_MAX_ETHPORTS]; - - int i, 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); - - /* 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 deleted file mode 100644 index e539f078dd..0000000000 --- a/test/test/test_link_bonding_mode4.c +++ /dev/null @@ -1,1645 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 1024 -#define TX_RING_SIZE 1024 - -#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 ("net_bonding_m4_bond_dev") - -#define SLAVE_DEV_NAME_FMT ("net_virt_%d") -#define SLAVE_RX_QUEUE_FMT ("net_virt_%d_rx") -#define SLAVE_TX_QUEUE_FMT ("net_virt_%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; - uint16_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, - }, - .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, NULL); -} - -/* - * 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, NULL); -} - -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(uint16_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(uint16_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(uint16_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; - uint16_t slaves[RTE_MAX_ETHPORTS]; - uint16_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(); - uint16_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_avail() - 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 -test_mode4_agg_mode_selection(void) -{ - int retval; - /* Test and verify for Stable mode */ - retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); - TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); - - - retval = rte_eth_bond_8023ad_agg_selection_set( - test_params.bonded_port_id, AGG_STABLE); - TEST_ASSERT_SUCCESS(retval, "Failed to initialize bond aggregation mode"); - retval = bond_handshake(); - TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); - - - retval = rte_eth_bond_8023ad_agg_selection_get( - test_params.bonded_port_id); - TEST_ASSERT_EQUAL(retval, AGG_STABLE, - "Wrong agg mode received from bonding device"); - - retval = remove_slaves_and_stop_bonded_device(); - TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); - - - /* test and verify for Bandwidth mode */ - retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); - TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); - - - retval = rte_eth_bond_8023ad_agg_selection_set( - test_params.bonded_port_id, - AGG_BANDWIDTH); - TEST_ASSERT_SUCCESS(retval, - "Failed to initialize bond aggregation mode"); - retval = bond_handshake(); - TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); - - retval = rte_eth_bond_8023ad_agg_selection_get( - test_params.bonded_port_id); - TEST_ASSERT_EQUAL(retval, AGG_BANDWIDTH, - "Wrong agg mode received from bonding device"); - - retval = remove_slaves_and_stop_bonded_device(); - TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); - - /* test and verify selection for count mode */ - retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); - TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); - - - retval = rte_eth_bond_8023ad_agg_selection_set( - test_params.bonded_port_id, AGG_COUNT); - TEST_ASSERT_SUCCESS(retval, - "Failed to initialize bond aggregation mode"); - retval = bond_handshake(); - TEST_ASSERT_SUCCESS(retval, "Initial handshake failed"); - - retval = rte_eth_bond_8023ad_agg_selection_get( - test_params.bonded_port_id); - TEST_ASSERT_EQUAL(retval, AGG_COUNT, - "Wrong agg mode received from bonding device"); - - 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 different 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 aggregate 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 suppose 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; - uint16_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_agg_mode_selection_wrapper(void){ - return test_mode4_executor(&test_mode4_agg_mode_selection); -} - -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_agg_mode_selection", - test_mode4_agg_mode_selection_wrapper), - 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 deleted file mode 100644 index d82de2cef5..0000000000 --- a/test/test/test_link_bonding_rssconf.c +++ /dev/null @@ -1,639 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015 Intel Corporation - */ - -#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 ("net_bonding_rss") - -#define SLAVE_DEV_NAME_FMT ("net_null%d") -#define SLAVE_RXTX_QUEUE_FMT ("rssconf_slave%d_q%d") - -#define NUM_MBUFS 8191 -#define MBUF_SIZE (1600 + 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 { - uint16_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, - }, - .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, - }, - .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(uint16_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(uint16_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; - struct ether_addr mac_addr = { .addr_bytes = {0} }; - - if (test_params.mbuf_pool == NULL) { - - test_params.mbuf_pool = rte_pktmbuf_pool_create( - "RSS_MBUF_POOL", NUM_MBUFS * SLAVE_COUNT, - MBUF_CACHE_SIZE, 0, MBUF_SIZE, rte_socket_id()); - - TEST_ASSERT(test_params.mbuf_pool != NULL, - "rte_pktmbuf_pool_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_avail(); - snprintf(name, sizeof(name), SLAVE_DEV_NAME_FMT, port_id); - - retval = rte_vdev_init(name, "size=64,copy=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); - - /* assign a non-zero MAC */ - mac_addr.addr_bytes[5] = 0x10 + port->port_id; - rte_eth_dev_default_mac_addr_set(port->port_id, &mac_addr); - - 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 deleted file mode 100644 index 425ae03cb9..0000000000 --- a/test/test/test_logs.c +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "test.h" - -/* for legacy log test */ -#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_legacy_logs(void) -{ - printf("== static log types\n"); - - /* set logtype level low to so we can test global level */ - rte_log_set_level(RTE_LOGTYPE_TESTAPP1, RTE_LOG_DEBUG); - rte_log_set_level(RTE_LOGTYPE_TESTAPP2, RTE_LOG_DEBUG); - - /* log in error level */ - rte_log_set_global_level(RTE_LOG_ERR); - RTE_LOG(ERR, TESTAPP1, "error message\n"); - RTE_LOG(CRIT, TESTAPP1, "critical message\n"); - - /* log in critical level */ - rte_log_set_global_level(RTE_LOG_CRIT); - RTE_LOG(ERR, TESTAPP2, "error message (not displayed)\n"); - RTE_LOG(CRIT, TESTAPP2, "critical message\n"); - - /* bump up single log type level above global to test it */ - rte_log_set_level(RTE_LOGTYPE_TESTAPP2, RTE_LOG_EMERG); - - /* log in error level */ - rte_log_set_global_level(RTE_LOG_ERR); - RTE_LOG(ERR, TESTAPP1, "error message\n"); - RTE_LOG(ERR, TESTAPP2, "error message (not displayed)\n"); - - return 0; -} - -static int -test_logs(void) -{ - int logtype1, logtype2; - int ret; - - printf("== dynamic log types\n"); - - logtype1 = rte_log_register("logtype1"); - if (logtype1 < 0) { - printf("Cannot register logtype1\n"); - return -1; - } - logtype2 = rte_log_register("logtype2"); - if (logtype2 < 0) { - printf("Cannot register logtype2\n"); - return -1; - } - - /* set logtype level low to so we can test global level */ - rte_log_set_level(logtype1, RTE_LOG_DEBUG); - rte_log_set_level(logtype2, RTE_LOG_DEBUG); - - /* log in error level */ - rte_log_set_global_level(RTE_LOG_ERR); - rte_log(RTE_LOG_ERR, logtype1, "error message\n"); - rte_log(RTE_LOG_CRIT, logtype1, "critical message\n"); - - /* log in critical level */ - rte_log_set_global_level(RTE_LOG_CRIT); - rte_log(RTE_LOG_ERR, logtype2, "error message (not displayed)\n"); - rte_log(RTE_LOG_CRIT, logtype2, "critical message\n"); - - /* bump up single log type level above global to test it */ - rte_log_set_level(logtype2, RTE_LOG_EMERG); - - /* log in error level */ - rte_log_set_global_level(RTE_LOG_ERR); - rte_log(RTE_LOG_ERR, logtype1, "error message\n"); - rte_log(RTE_LOG_ERR, logtype2, "error message (not displayed)\n"); - - ret = test_legacy_logs(); - if (ret < 0) - return ret; - - return 0; -} - -REGISTER_TEST_COMMAND(logs_autotest, test_logs); diff --git a/test/test/test_lpm.c b/test/test/test_lpm.c deleted file mode 100644 index 5d697dd0f6..0000000000 --- a/test/test/test_lpm.c +++ /dev/null @@ -1,1290 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 670aadb40e..0000000000 --- a/test/test/test_lpm6.c +++ /dev/null @@ -1,1796 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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); -static int32_t test28(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, - test28, -}; - -#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}; - uint32_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]; - int32_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; - uint32_t 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; - uint32_t 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; - uint32_t 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; - uint32_t 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; - uint32_t 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; - uint32_t 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; - uint32_t 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; - uint32_t 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; - uint32_t 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 = (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; - uint32_t 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; - uint32_t 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; - uint32_t 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; - uint32_t next_hop_add; - int32_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]; - uint32_t next_hop_add; - int32_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; - uint32_t 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; - uint32_t 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; - uint32_t next_hop_ip_10_32 = 100; - uint32_t next_hop_ip_10_24 = 105; - uint32_t next_hop_ip_20_25 = 111; - uint32_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); - 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_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); - 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_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); - 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_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; - uint32_t 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; -} - -/* - * Call add, lookup and delete for a single rule with maximum 21bit next_hop - * size. - * Check that next_hop returned from lookup is equal to provisioned value. - * Delete the rule and check that the same test returs a miss. - */ -int32_t -test28(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; - uint32_t next_hop_add = 0x001FFFFF, 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); - 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 deleted file mode 100644 index 565138a317..0000000000 --- a/test/test/test_lpm6_data.h +++ /dev/null @@ -1,1159 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2016 Intel Corporation - */ -#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 deleted file mode 100644 index 0b43ad824a..0000000000 --- a/test/test/test_lpm6_perf.c +++ /dev/null @@ -1,163 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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; - uint32_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]; - int32_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 deleted file mode 100644 index 3b98ce0c84..0000000000 --- a/test/test/test_lpm_perf.c +++ /dev/null @@ -1,484 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 6b6c6fec11..0000000000 --- a/test/test/test_malloc.c +++ /dev/null @@ -1,941 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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; - int overhead = 0; - - /* Dynamically calculate the overhead by allocating one cacheline and - * then comparing what was allocated from the heap. - */ - rte_malloc_get_socket_stats(socket, &pre_stats); - - void *dummy = rte_malloc_socket(NULL, RTE_CACHE_LINE_SIZE, 0, socket); - if (dummy == NULL) - return -1; - - rte_malloc_get_socket_stats(socket, &post_stats); - - /* after subtracting cache line, remainder is overhead */ - overhead = post_stats.heap_allocsz_bytes - pre_stats.heap_allocsz_bytes; - overhead -= RTE_CACHE_LINE_SIZE; - - rte_free(dummy); - - /* Now start the real tests */ - 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; - } - strlcpy(ptr1, hello_str, size1); - 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_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_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; -} - -static int -check_socket_mem(const struct rte_memseg_list *msl, void *arg) -{ - int32_t *socket = arg; - - if (msl->external) - return 0; - - return *socket == msl->socket_id; -} - -/* Check if memory is available on a specific socket */ -static int -is_mem_on_socket(int32_t socket) -{ - return rte_memseg_list_walk(check_socket_mem, &socket); -} - - -/* - * 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_mem_virt2memseg(addr, NULL); - return ms == NULL ? -1 : ms->socket_id; - -} - -/* 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 deleted file mode 100644 index 9e82a20be1..0000000000 --- a/test/test/test_mbuf.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 - -#ifdef RTE_MBUF_REFCNT_ATOMIC - -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(struct rte_mempool *pktmbuf_pool) -{ - 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(struct rte_mempool *pktmbuf_pool) -{ - 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(struct rte_mempool *pktmbuf_pool, - struct rte_mempool *pktmbuf_pool2) -{ - 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(struct rte_mempool *pktmbuf_pool) -{ - 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 efficiency, recommended to run with RTE_LIBRTE_MBUF_DEBUG defined. - */ - -#ifdef RTE_MBUF_REFCNT_ATOMIC - -static int -test_refcnt_slave(void *arg) -{ - unsigned lcore, free; - void *mp = 0; - struct rte_ring *refcnt_mbuf_ring = arg; - - 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(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 int lcore, unsigned int iter, - struct rte_mempool *refcnt_pool, - struct rte_ring *refcnt_mbuf_ring) -{ - 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(struct rte_mempool *refcnt_pool, - struct rte_ring *refcnt_mbuf_ring) -{ - 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_pool, refcnt_mbuf_ring); - - 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; - int ret = -1; - struct rte_mempool *refcnt_pool = NULL; - struct rte_ring *refcnt_mbuf_ring = NULL; - - 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 */ - - refcnt_pool = rte_pktmbuf_pool_create(MAKE_STRING(refcnt_pool), - REFCNT_MBUF_NUM, 0, 0, 0, - SOCKET_ID_ANY); - if (refcnt_pool == NULL) { - printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n", - __func__); - return -1; - } - - refcnt_mbuf_ring = rte_ring_create("refcnt_mbuf_ring", - rte_align32pow2(REFCNT_RING_SIZE), SOCKET_ID_ANY, - RING_F_SP_ENQ); - if (refcnt_mbuf_ring == NULL) { - printf("%s: cannot allocate " MAKE_STRING(refcnt_mbuf_ring) - "\n", __func__); - goto err; - } - - refcnt_stop_slaves = 0; - memset(refcnt_lcore, 0, sizeof (refcnt_lcore)); - - rte_eal_mp_remote_launch(test_refcnt_slave, refcnt_mbuf_ring, - SKIP_MASTER); - - test_refcnt_master(refcnt_pool, refcnt_mbuf_ring); - - 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); - - ret = 0; - -err: - rte_mempool_free(refcnt_pool); - rte_ring_free(refcnt_mbuf_ring); - return ret; -#else - return 0; -#endif -} - -#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(struct rte_mempool *pktmbuf_pool) -{ - 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_iova = 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(struct rte_mempool *pktmbuf_pool, 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(struct rte_mempool *pktmbuf_pool) -{ - 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(pktmbuf_pool, 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) -{ - int ret = -1; - struct rte_mempool *pktmbuf_pool = NULL; - struct rte_mempool *pktmbuf_pool2 = NULL; - - - RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != RTE_CACHE_LINE_MIN_SIZE * 2); - - /* create pktmbuf pool if it does not exist */ - 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"); - goto err; - } - - /* create a specific pktmbuf pool with a priv_size != 0 and no data - * room size */ - 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"); - goto err; - } - - /* test multiple mbuf alloc */ - if (test_pktmbuf_pool(pktmbuf_pool) < 0) { - printf("test_mbuf_pool() failed\n"); - goto err; - } - - /* do it another time to check that all mbufs were freed */ - if (test_pktmbuf_pool(pktmbuf_pool) < 0) { - printf("test_mbuf_pool() failed (2)\n"); - goto err; - } - - /* test that the pointer to the data on a packet mbuf is set properly */ - if (test_pktmbuf_pool_ptr(pktmbuf_pool) < 0) { - printf("test_pktmbuf_pool_ptr() failed\n"); - goto err; - } - - /* test data manipulation in mbuf */ - if (test_one_pktmbuf(pktmbuf_pool) < 0) { - printf("test_one_mbuf() failed\n"); - goto err; - } - - - /* - * do it another time, to check that allocation reinitialize - * the mbuf correctly - */ - if (test_one_pktmbuf(pktmbuf_pool) < 0) { - printf("test_one_mbuf() failed (2)\n"); - goto err; - } - - if (test_pktmbuf_with_non_ascii_data(pktmbuf_pool) < 0) { - printf("test_pktmbuf_with_non_ascii_data() failed\n"); - goto err; - } - - /* test free pktmbuf segment one by one */ - if (test_pktmbuf_free_segment(pktmbuf_pool) < 0) { - printf("test_pktmbuf_free_segment() failed.\n"); - goto err; - } - - if (testclone_testupdate_testdetach(pktmbuf_pool) < 0) { - printf("testclone_and_testupdate() failed \n"); - goto err; - } - - if (test_attach_from_different_pool(pktmbuf_pool, pktmbuf_pool2) < 0) { - printf("test_attach_from_different_pool() failed\n"); - goto err; - } - - if (test_refcnt_mbuf()<0){ - printf("test_refcnt_mbuf() failed \n"); - goto err; - } - - if (test_failing_mbuf_sanity_check(pktmbuf_pool) < 0) { - printf("test_failing_mbuf_sanity_check() failed\n"); - goto err; - } - - if (test_mbuf_linearize_check(pktmbuf_pool) < 0) { - printf("test_mbuf_linearize_check() failed\n"); - goto err; - } - ret = 0; - -err: - rte_mempool_free(pktmbuf_pool); - rte_mempool_free(pktmbuf_pool2); - return ret; -} - -REGISTER_TEST_COMMAND(mbuf_autotest, test_mbuf); diff --git a/test/test/test_member.c b/test/test/test_member.c deleted file mode 100644 index e2a3932f2e..0000000000 --- a/test/test/test_member.c +++ /dev/null @@ -1,715 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -/* This test is for membership library's simple feature test */ - -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -struct rte_member_setsum *setsum_ht; -struct rte_member_setsum *setsum_cache; -struct rte_member_setsum *setsum_vbf; - -/* 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)); - -/* Set ID Macros for multimatch test usage */ -#define M_MATCH_S 1 /* Not start with 0 since by default 0 means no match */ -#define M_MATCH_E 15 -#define M_MATCH_STEP 2 -#define M_MATCH_CNT \ - (1 + (M_MATCH_E - M_MATCH_S) / M_MATCH_STEP) - - -#define NUM_SAMPLES 5 -#define MAX_MATCH 32 - -/* Keys used by unit test functions */ -static struct flow_key keys[NUM_SAMPLES] = { - { - .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, - } -}; - -uint32_t test_set[NUM_SAMPLES] = {1, 2, 3, 4, 5}; - -#define ITERATIONS 3 -#define KEY_SIZE 4 - -#define MAX_ENTRIES (1 << 16) -uint8_t generated_keys[MAX_ENTRIES][KEY_SIZE]; - -static struct rte_member_parameters params = { - .num_keys = MAX_ENTRIES, /* Total hash table entries. */ - .key_len = KEY_SIZE, /* Length of hash key. */ - - /* num_set and false_positive_rate only relevant to vBF */ - .num_set = 16, - .false_positive_rate = 0.03, - .prim_hash_seed = 1, - .sec_hash_seed = 11, - .socket_id = 0 /* NUMA Socket ID for memory. */ -}; - -/* - * Sequence of operations for find existing setsummary - * - * - create setsum - * - find existing setsum: hit - * - find non-existing setsum: miss - * - */ -static int -test_member_find_existing(void) -{ - struct rte_member_setsum *tmp_setsum = NULL, *result = NULL; - struct rte_member_parameters tmp_params = { - .name = "member_find_existing", - .num_keys = MAX_ENTRIES, /* Total hash table entries. */ - .key_len = KEY_SIZE, /* Length of hash key. */ - .type = RTE_MEMBER_TYPE_HT, - .num_set = 32, - .false_positive_rate = 0.03, - .prim_hash_seed = 1, - .sec_hash_seed = 11, - .socket_id = 0 /* NUMA Socket ID for memory. */ - }; - - /* Create */ - tmp_setsum = rte_member_create(&tmp_params); - TEST_ASSERT(tmp_setsum != NULL, "setsum creation failed"); - - /* Try to find existing hash table */ - result = rte_member_find_existing("member_find_existing"); - TEST_ASSERT(result == tmp_setsum, "could not find existing setsum"); - - /* Try to find non-existing hash table */ - result = rte_member_find_existing("member_find_non_existing"); - TEST_ASSERT(result == NULL, "found setsum that shouldn't exist"); - - /* Cleanup. */ - rte_member_free(tmp_setsum); - - return 0; -} - -/* - * Test for bad creating parameters - */ -static int -test_member_create_bad_param(void) -{ - struct rte_member_setsum *bad_setsum = NULL; - struct rte_member_parameters bad_params = { - .num_keys = MAX_ENTRIES, /* Total hash table entries. */ - .key_len = KEY_SIZE, /* Length of hash key. */ - .type = RTE_MEMBER_TYPE_HT, - .num_set = 32, - .false_positive_rate = 0.03, - .prim_hash_seed = 1, - .sec_hash_seed = 11, - .socket_id = 0 /* NUMA Socket ID for memory. */ - }; - - printf("Expected error section begin...\n"); - bad_params.name = "bad_param1"; - bad_params.num_set = 0; - bad_params.type = RTE_MEMBER_TYPE_VBF; - /* Test with 0 set for vBF should fail */ - bad_setsum = rte_member_create(&bad_params); - if (bad_setsum != NULL) { - rte_member_free(bad_setsum); - printf("Impossible creating setsum successfully with invalid " - "number of set for vBF\n"); - return -1; - } - - bad_params.name = "bad_param2"; - bad_params.false_positive_rate = 0; - bad_params.num_set = 32; - /* Test with 0 false positive for vBF should fail */ - bad_setsum = rte_member_create(&bad_params); - if (bad_setsum != NULL) { - rte_member_free(bad_setsum); - printf("Impossible creating setsum successfully with invalid " - "false positive rate for vBF\n"); - return -1; - } - - bad_params.name = "bad_param3"; - bad_params.false_positive_rate = 0.03; - bad_params.num_keys = 0; - /* Test with 0 key per BF for vBF should fail */ - bad_setsum = rte_member_create(&bad_params); - if (bad_setsum != NULL) { - rte_member_free(bad_setsum); - printf("Impossible creating setsum successfully with invalid " - "num_keys for vBF\n"); - return -1; - } - - bad_params.name = "bad_param4"; - bad_params.type = RTE_MEMBER_TYPE_HT; - bad_params.num_keys = RTE_MEMBER_BUCKET_ENTRIES / 2; - /* Test with less than 1 bucket for HTSS should fail */ - bad_setsum = rte_member_create(&bad_params); - if (bad_setsum != NULL) { - rte_member_free(bad_setsum); - printf("Impossible creating setsum successfully with too few " - "number of keys(entries) for HT\n"); - return -1; - } - - bad_params.name = "bad_param5"; - bad_params.num_keys = RTE_MEMBER_ENTRIES_MAX + 1; - /* Test with more than maximum entries for HTSS should fail */ - bad_setsum = rte_member_create(&bad_params); - if (bad_setsum != NULL) { - rte_member_free(bad_setsum); - printf("Impossible creating setsum successfully with to many " - "number of keys(entries) for HT\n"); - return -1; - } - - bad_params.name = "bad_param5"; - /* Test with same name should fail */ - bad_setsum = rte_member_create(&bad_params); - if (bad_setsum != NULL) { - rte_member_free(bad_setsum); - printf("Impossible creating setsum successfully with existed " - "name\n"); - return -1; - } - printf("Expected error section end...\n"); - rte_member_free(bad_setsum); - return 0; -} - -/* Create test setsummaries. */ -static int test_member_create(void) -{ - params.key_len = sizeof(struct flow_key); - - params.name = "test_member_ht"; - params.is_cache = 0; - params.type = RTE_MEMBER_TYPE_HT; - setsum_ht = rte_member_create(¶ms); - - params.name = "test_member_cache"; - params.is_cache = 1; - setsum_cache = rte_member_create(¶ms); - - params.name = "test_member_vbf"; - params.type = RTE_MEMBER_TYPE_VBF; - setsum_vbf = rte_member_create(¶ms); - - if (setsum_ht == NULL || setsum_cache == NULL || setsum_vbf == NULL) { - printf("Creation of setsums fail\n"); - return -1; - } - printf("Creation of setsums success\n"); - return 0; -} - -static int test_member_insert(void) -{ - int ret_ht, ret_cache, ret_vbf, i; - - for (i = 0; i < NUM_SAMPLES; i++) { - ret_ht = rte_member_add(setsum_ht, &keys[i], test_set[i]); - ret_cache = rte_member_add(setsum_cache, &keys[i], - test_set[i]); - ret_vbf = rte_member_add(setsum_vbf, &keys[i], test_set[i]); - TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0, - "insert error"); - } - printf("insert key success\n"); - return 0; -} - -static int test_member_lookup(void) -{ - int ret_ht, ret_cache, ret_vbf, i; - uint16_t set_ht, set_cache, set_vbf; - member_set_t set_ids_ht[NUM_SAMPLES] = {0}; - member_set_t set_ids_cache[NUM_SAMPLES] = {0}; - member_set_t set_ids_vbf[NUM_SAMPLES] = {0}; - - uint32_t num_key_ht = NUM_SAMPLES; - uint32_t num_key_cache = NUM_SAMPLES; - uint32_t num_key_vbf = NUM_SAMPLES; - - const void *key_array[NUM_SAMPLES]; - - /* Single lookup test */ - for (i = 0; i < NUM_SAMPLES; i++) { - ret_ht = rte_member_lookup(setsum_ht, &keys[i], &set_ht); - ret_cache = rte_member_lookup(setsum_cache, &keys[i], - &set_cache); - ret_vbf = rte_member_lookup(setsum_vbf, &keys[i], &set_vbf); - TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0, - "single lookup function error"); - - TEST_ASSERT(set_ht == test_set[i] && - set_cache == test_set[i] && - set_vbf == test_set[i], - "single lookup set value error"); - } - printf("lookup single key success\n"); - - /* Bulk lookup test */ - for (i = 0; i < NUM_SAMPLES; i++) - key_array[i] = &keys[i]; - - ret_ht = rte_member_lookup_bulk(setsum_ht, key_array, - num_key_ht, set_ids_ht); - - ret_cache = rte_member_lookup_bulk(setsum_cache, key_array, - num_key_cache, set_ids_cache); - - ret_vbf = rte_member_lookup_bulk(setsum_vbf, key_array, - num_key_vbf, set_ids_vbf); - - TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0, - "bulk lookup function error"); - - for (i = 0; i < NUM_SAMPLES; i++) { - TEST_ASSERT((set_ids_ht[i] == test_set[i]) && - (set_ids_cache[i] == test_set[i]) && - (set_ids_vbf[i] == test_set[i]), - "bulk lookup result error"); - } - - return 0; -} - -static int test_member_delete(void) -{ - int ret_ht, ret_cache, ret_vbf, i; - uint16_t set_ht, set_cache, set_vbf; - const void *key_array[NUM_SAMPLES]; - member_set_t set_ids_ht[NUM_SAMPLES] = {0}; - member_set_t set_ids_cache[NUM_SAMPLES] = {0}; - member_set_t set_ids_vbf[NUM_SAMPLES] = {0}; - uint32_t num_key_ht = NUM_SAMPLES; - uint32_t num_key_cache = NUM_SAMPLES; - uint32_t num_key_vbf = NUM_SAMPLES; - - /* Delete part of all inserted keys */ - for (i = 0; i < NUM_SAMPLES / 2; i++) { - ret_ht = rte_member_delete(setsum_ht, &keys[i], test_set[i]); - ret_cache = rte_member_delete(setsum_cache, &keys[i], - test_set[i]); - ret_vbf = rte_member_delete(setsum_vbf, &keys[i], test_set[i]); - /* VBF does not support delete yet, so return error code */ - TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0, - "key deletion function error"); - TEST_ASSERT(ret_vbf < 0, - "vbf does not support deletion, error"); - } - - for (i = 0; i < NUM_SAMPLES; i++) - key_array[i] = &keys[i]; - - ret_ht = rte_member_lookup_bulk(setsum_ht, key_array, - num_key_ht, set_ids_ht); - - ret_cache = rte_member_lookup_bulk(setsum_cache, key_array, - num_key_cache, set_ids_cache); - - ret_vbf = rte_member_lookup_bulk(setsum_vbf, key_array, - num_key_vbf, set_ids_vbf); - - TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0, - "bulk lookup function error"); - - for (i = 0; i < NUM_SAMPLES / 2; i++) { - TEST_ASSERT((set_ids_ht[i] == RTE_MEMBER_NO_MATCH) && - (set_ids_cache[i] == RTE_MEMBER_NO_MATCH), - "bulk lookup result error"); - } - - for (i = NUM_SAMPLES / 2; i < NUM_SAMPLES; i++) { - TEST_ASSERT((set_ids_ht[i] == test_set[i]) && - (set_ids_cache[i] == test_set[i]) && - (set_ids_vbf[i] == test_set[i]), - "bulk lookup result error"); - } - - /* Delete the left of inserted keys */ - for (i = NUM_SAMPLES / 2; i < NUM_SAMPLES; i++) { - ret_ht = rte_member_delete(setsum_ht, &keys[i], test_set[i]); - ret_cache = rte_member_delete(setsum_cache, &keys[i], - test_set[i]); - ret_vbf = rte_member_delete(setsum_vbf, &keys[i], test_set[i]); - /* VBF does not support delete yet, so return error code */ - TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0, - "key deletion function error"); - TEST_ASSERT(ret_vbf < 0, - "vbf does not support deletion, error"); - } - - for (i = 0; i < NUM_SAMPLES; i++) { - ret_ht = rte_member_lookup(setsum_ht, &keys[i], &set_ht); - ret_cache = rte_member_lookup(setsum_cache, &keys[i], - &set_cache); - ret_vbf = rte_member_lookup(setsum_vbf, &keys[i], &set_vbf); - TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0, - "key lookup function error"); - TEST_ASSERT(set_ht == RTE_MEMBER_NO_MATCH && - ret_cache == RTE_MEMBER_NO_MATCH, - "key deletion failed"); - } - /* Reset vbf for other following tests */ - rte_member_reset(setsum_vbf); - - printf("delete success\n"); - return 0; -} - -static int test_member_multimatch(void) -{ - int ret_ht, ret_vbf, ret_cache; - member_set_t set_ids_ht[MAX_MATCH] = {0}; - member_set_t set_ids_vbf[MAX_MATCH] = {0}; - member_set_t set_ids_cache[MAX_MATCH] = {0}; - - member_set_t set_ids_ht_m[NUM_SAMPLES][MAX_MATCH] = {{0} }; - member_set_t set_ids_vbf_m[NUM_SAMPLES][MAX_MATCH] = {{0} }; - member_set_t set_ids_cache_m[NUM_SAMPLES][MAX_MATCH] = {{0} }; - - uint32_t match_count_ht[NUM_SAMPLES]; - uint32_t match_count_vbf[NUM_SAMPLES]; - uint32_t match_count_cache[NUM_SAMPLES]; - - uint32_t num_key_ht = NUM_SAMPLES; - uint32_t num_key_vbf = NUM_SAMPLES; - uint32_t num_key_cache = NUM_SAMPLES; - - const void *key_array[NUM_SAMPLES]; - - uint32_t i, j; - - /* Same key at most inserted 2*entry_per_bucket times for HT mode */ - for (i = M_MATCH_S; i <= M_MATCH_E; i += M_MATCH_STEP) { - for (j = 0; j < NUM_SAMPLES; j++) { - ret_ht = rte_member_add(setsum_ht, &keys[j], i); - ret_vbf = rte_member_add(setsum_vbf, &keys[j], i); - ret_cache = rte_member_add(setsum_cache, &keys[j], i); - - TEST_ASSERT(ret_ht >= 0 && ret_vbf >= 0 && - ret_cache >= 0, - "insert function error"); - } - } - - /* Single multimatch test */ - for (i = 0; i < NUM_SAMPLES; i++) { - ret_vbf = rte_member_lookup_multi(setsum_vbf, &keys[i], - MAX_MATCH, set_ids_vbf); - ret_ht = rte_member_lookup_multi(setsum_ht, &keys[i], - MAX_MATCH, set_ids_ht); - ret_cache = rte_member_lookup_multi(setsum_cache, &keys[i], - MAX_MATCH, set_ids_cache); - /* - * For cache mode, keys overwrite when signature same. - * the mutimatch should work like single match. - */ - TEST_ASSERT(ret_ht == M_MATCH_CNT && ret_vbf == M_MATCH_CNT && - ret_cache == 1, - "single lookup_multi error"); - TEST_ASSERT(set_ids_cache[0] == M_MATCH_E, - "single lookup_multi cache error"); - - for (j = 1; j <= M_MATCH_CNT; j++) { - TEST_ASSERT(set_ids_ht[j-1] == j * M_MATCH_STEP - 1 && - set_ids_vbf[j-1] == - j * M_MATCH_STEP - 1, - "single multimatch lookup error"); - } - } - printf("lookup single key for multimatch success\n"); - - /* Bulk multimatch test */ - for (i = 0; i < NUM_SAMPLES; i++) - key_array[i] = &keys[i]; - ret_vbf = rte_member_lookup_multi_bulk(setsum_vbf, - &key_array[0], num_key_ht, MAX_MATCH, match_count_vbf, - (member_set_t *)set_ids_vbf_m); - - ret_ht = rte_member_lookup_multi_bulk(setsum_ht, - &key_array[0], num_key_vbf, MAX_MATCH, match_count_ht, - (member_set_t *)set_ids_ht_m); - - ret_cache = rte_member_lookup_multi_bulk(setsum_cache, - &key_array[0], num_key_cache, MAX_MATCH, - match_count_cache, (member_set_t *)set_ids_cache_m); - - - for (j = 0; j < NUM_SAMPLES; j++) { - TEST_ASSERT(match_count_ht[j] == M_MATCH_CNT, - "bulk multimatch lookup HT match count error"); - TEST_ASSERT(match_count_vbf[j] == M_MATCH_CNT, - "bulk multimatch lookup vBF match count error"); - TEST_ASSERT(match_count_cache[j] == 1, - "bulk multimatch lookup CACHE match count error"); - TEST_ASSERT(set_ids_cache_m[j][0] == M_MATCH_E, - "bulk multimatch lookup CACHE set value error"); - - for (i = 1; i <= M_MATCH_CNT; i++) { - TEST_ASSERT(set_ids_ht_m[j][i-1] == - i * M_MATCH_STEP - 1, - "bulk multimatch lookup HT set value error"); - TEST_ASSERT(set_ids_vbf_m[j][i-1] == - i * M_MATCH_STEP - 1, - "bulk multimatch lookup vBF set value error"); - } - } - - printf("lookup for bulk multimatch success\n"); - - return 0; -} - -static int key_compare(const void *key1, const void *key2) -{ - return memcmp(key1, key2, KEY_SIZE); -} - -static void -setup_keys_and_data(void) -{ - unsigned int i, j; - int num_duplicates; - - /* Reset all arrays */ - for (i = 0; i < KEY_SIZE; i++) - generated_keys[0][i] = 0; - - /* Generate a list of keys, some of which may be duplicates */ - for (i = 0; i < MAX_ENTRIES; i++) { - for (j = 0; j < KEY_SIZE; j++) - generated_keys[i][j] = rte_rand() & 0xFF; - } - - /* Remove duplicates from the keys array */ - do { - num_duplicates = 0; - /* Sort the list of keys to make it easier to find duplicates */ - qsort(generated_keys, MAX_ENTRIES, KEY_SIZE, key_compare); - - /* Sift through the list of keys and look for duplicates */ - int num_duplicates = 0; - for (i = 0; i < MAX_ENTRIES - 1; i++) { - if (memcmp(generated_keys[i], generated_keys[i + 1], - KEY_SIZE) == 0) { - /* This key already exists, try again */ - num_duplicates++; - for (j = 0; j < KEY_SIZE; j++) - generated_keys[i][j] = - rte_rand() & 0xFF; - } - } - } while (num_duplicates != 0); -} - -static inline int -add_generated_keys(struct rte_member_setsum *setsum, unsigned int *added_keys) -{ - int ret = 0; - - for (*added_keys = 0; ret >= 0 && *added_keys < MAX_ENTRIES; - (*added_keys)++) { - uint16_t set = (rte_rand() & 0xf) + 1; - ret = rte_member_add(setsum, &generated_keys[*added_keys], set); - } - return ret; -} - -static inline int -add_generated_keys_cache(struct rte_member_setsum *setsum, - unsigned int *added_keys) -{ - int ret = 0; - - for (*added_keys = 0; ret == 0 && *added_keys < MAX_ENTRIES; - (*added_keys)++) { - uint16_t set = (rte_rand() & 0xf) + 1; - ret = rte_member_add(setsum, &generated_keys[*added_keys], set); - } - return ret; -} - -static int -test_member_loadfactor(void) -{ - unsigned int j; - unsigned int added_keys, average_keys_added = 0; - int ret; - - setup_keys_and_data(); - - rte_member_free(setsum_ht); - rte_member_free(setsum_cache); - rte_member_free(setsum_vbf); - - params.key_len = KEY_SIZE; - params.name = "test_member_ht"; - params.is_cache = 0; - params.type = RTE_MEMBER_TYPE_HT; - setsum_ht = rte_member_create(¶ms); - - params.name = "test_member_cache"; - params.is_cache = 1; - setsum_cache = rte_member_create(¶ms); - - - if (setsum_ht == NULL || setsum_cache == NULL) { - printf("Creation of setsums fail\n"); - return -1; - } - /* Test HT non-cache mode */ - for (j = 0; j < ITERATIONS; j++) { - /* Add random entries until key cannot be added */ - ret = add_generated_keys(setsum_ht, &added_keys); - if (ret != -ENOSPC) { - printf("Unexpected error when adding keys\n"); - return -1; - } - average_keys_added += added_keys; - - /* Reset the table */ - rte_member_reset(setsum_ht); - - /* Print a dot to show progress on operations */ - printf("."); - fflush(stdout); - } - - average_keys_added /= ITERATIONS; - - printf("\nKeys inserted when no space(non-cache) = %.2f%% (%u/%u)\n", - ((double) average_keys_added / params.num_keys * 100), - average_keys_added, params.num_keys); - - /* Test cache mode */ - added_keys = average_keys_added = 0; - for (j = 0; j < ITERATIONS; j++) { - /* Add random entries until key cannot be added */ - ret = add_generated_keys_cache(setsum_cache, &added_keys); - if (ret != 1) { - printf("Unexpected error when adding keys\n"); - return -1; - } - average_keys_added += added_keys; - - /* Reset the table */ - rte_member_reset(setsum_cache); - - /* Print a dot to show progress on operations */ - printf("."); - fflush(stdout); - } - - average_keys_added /= ITERATIONS; - - printf("\nKeys inserted when eviction happens(cache)= %.2f%% (%u/%u)\n", - ((double) average_keys_added / params.num_keys * 100), - average_keys_added, params.num_keys); - return 0; -} - -static void -perform_free(void) -{ - rte_member_free(setsum_ht); - rte_member_free(setsum_cache); - rte_member_free(setsum_vbf); -} - -static int -test_member(void) -{ - if (test_member_create_bad_param() < 0) - return -1; - - if (test_member_find_existing() < 0) - return -1; - - if (test_member_create() < 0) { - perform_free(); - return -1; - } - if (test_member_insert() < 0) { - perform_free(); - return -1; - } - if (test_member_lookup() < 0) { - perform_free(); - return -1; - } - if (test_member_delete() < 0) { - perform_free(); - return -1; - } - if (test_member_multimatch() < 0) { - perform_free(); - return -1; - } - if (test_member_loadfactor() < 0) { - rte_member_free(setsum_ht); - rte_member_free(setsum_cache); - return -1; - } - - perform_free(); - return 0; -} - -REGISTER_TEST_COMMAND(member_autotest, test_member); diff --git a/test/test/test_member_perf.c b/test/test/test_member_perf.c deleted file mode 100644 index 564a2b3c1e..0000000000 --- a/test/test/test_member_perf.c +++ /dev/null @@ -1,625 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#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 * 75 / 100) /* 75% table utilization */ -#define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ -#define VBF_SET_CNT 16 -#define BURST_SIZE 64 -#define VBF_FALSE_RATE 0.03 - -static unsigned int test_socket_id; - -enum sstype { - HT = 0, - CACHE, - VBF, - NUM_TYPE -}; - -enum operations { - ADD = 0, - LOOKUP, - LOOKUP_BULK, - LOOKUP_MULTI, - LOOKUP_MULTI_BULK, - DELETE, - LOOKUP_MISS, - NUM_OPERATIONS -}; - -struct member_perf_params { - struct rte_member_setsum *setsum[NUM_TYPE]; - 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_TYPE][NUM_KEYSIZES][NUM_OPERATIONS]; -uint64_t false_data[NUM_TYPE][NUM_KEYSIZES]; -uint64_t false_data_bulk[NUM_TYPE][NUM_KEYSIZES]; -uint64_t false_data_multi[NUM_TYPE][NUM_KEYSIZES]; -uint64_t false_data_multi_bulk[NUM_TYPE][NUM_KEYSIZES]; - -uint64_t false_hit[NUM_TYPE][NUM_KEYSIZES]; - -member_set_t data[NUM_TYPE][/* Array to store the 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 member_perf_params *params) -{ - member_set_t temp_data; - unsigned int i, j; - 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]); - memcpy(keys[i], keys[swap_idx], - hashtest_key_lens[params->cycle]); - memcpy(keys[swap_idx], temp_key, - hashtest_key_lens[params->cycle]); - for (j = 0; j < NUM_TYPE; j++) { - temp_data = data[j][i]; - data[j][i] = data[j][swap_idx]; - data[j][swap_idx] = temp_data; - } - } -} - -static int key_compare(const void *key1, const void *key2) -{ - return memcmp(key1, key2, MAX_KEYSIZE); -} - -struct rte_member_parameters member_params = { - .num_keys = MAX_ENTRIES, /* Total hash table entries. */ - .key_len = 4, /* Length of hash key. */ - - /* num_set and false_positive_rate only relevant to vBF */ - .num_set = VBF_SET_CNT, - .false_positive_rate = 0.03, - .prim_hash_seed = 0, - .sec_hash_seed = 1, - .socket_id = 0, /* NUMA Socket ID for memory. */ - }; - -static int -setup_keys_and_data(struct member_perf_params *params, unsigned int cycle, - int miss) -{ - 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[HT][i] = data[CACHE][i] = (rte_rand() & 0x7FFE) + 1; - data[VBF][i] = rte_rand() % VBF_SET_CNT + 1; - } - - /* 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); - - /* For testing miss lookup, we insert half and lookup the other half */ - unsigned int entry_cnt, bf_key_cnt; - if (!miss) { - entry_cnt = MAX_ENTRIES; - bf_key_cnt = KEYS_TO_ADD; - } else { - entry_cnt = MAX_ENTRIES / 2; - bf_key_cnt = KEYS_TO_ADD / 2; - } - member_params.false_positive_rate = VBF_FALSE_RATE; - member_params.key_len = params->key_size; - member_params.socket_id = test_socket_id; - member_params.num_keys = entry_cnt; - member_params.name = "test_member_ht"; - member_params.is_cache = 0; - member_params.type = RTE_MEMBER_TYPE_HT; - params->setsum[HT] = rte_member_create(&member_params); - if (params->setsum[HT] == NULL) - fprintf(stderr, "ht create fail\n"); - - member_params.name = "test_member_cache"; - member_params.is_cache = 1; - params->setsum[CACHE] = rte_member_create(&member_params); - if (params->setsum[CACHE] == NULL) - fprintf(stderr, "CACHE create fail\n"); - - member_params.name = "test_member_vbf"; - member_params.type = RTE_MEMBER_TYPE_VBF; - member_params.num_keys = bf_key_cnt; - params->setsum[VBF] = rte_member_create(&member_params); - if (params->setsum[VBF] == NULL) - fprintf(stderr, "VBF create fail\n"); - for (i = 0; i < NUM_TYPE; i++) { - if (params->setsum[i] == NULL) - return -1; - } - - return 0; -} - -static int -timed_adds(struct member_perf_params *params, int type) -{ - const uint64_t start_tsc = rte_rdtsc(); - unsigned int i, a; - int32_t ret; - - for (i = 0; i < KEYS_TO_ADD; i++) { - ret = rte_member_add(params->setsum[type], &keys[i], - data[type][i]); - if (ret < 0) { - printf("Error %d in rte_member_add - key=0x", ret); - for (a = 0; a < params->key_size; a++) - printf("%02x", keys[i][a]); - printf(" value=%d, type: %d\n", data[type][i], type); - - return -1; - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[type][params->cycle][ADD] = time_taken / KEYS_TO_ADD; - return 0; -} - -static int -timed_lookups(struct member_perf_params *params, int type) -{ - unsigned int i, j; - - false_data[type][params->cycle] = 0; - - const uint64_t start_tsc = rte_rdtsc(); - member_set_t result; - int ret; - - for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) { - for (j = 0; j < KEYS_TO_ADD; j++) { - ret = rte_member_lookup(params->setsum[type], &keys[j], - &result); - if (ret < 0) { - printf("lookup wrong internally"); - return -1; - } - if (type == HT && result == RTE_MEMBER_NO_MATCH) { - printf("HT mode shouldn't have false negative"); - return -1; - } - if (result != data[type][j]) - false_data[type][params->cycle]++; - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[type][params->cycle][LOOKUP] = time_taken / NUM_LOOKUPS; - - return 0; -} - -static int -timed_lookups_bulk(struct member_perf_params *params, int type) -{ - unsigned int i, j, k; - member_set_t result[BURST_SIZE] = {0}; - const void *keys_burst[BURST_SIZE]; - int ret; - - false_data_bulk[type][params->cycle] = 0; - - 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]; - - ret = rte_member_lookup_bulk(params->setsum[type], - keys_burst, - BURST_SIZE, - result); - if (ret <= 0) { - printf("lookup bulk has wrong return value\n"); - return -1; - } - for (k = 0; k < BURST_SIZE; k++) { - uint32_t data_idx = j * BURST_SIZE + k; - if (type == HT && result[k] == - RTE_MEMBER_NO_MATCH) { - printf("HT mode shouldn't have " - "false negative"); - return -1; - } - if (result[k] != data[type][data_idx]) - false_data_bulk[type][params->cycle]++; - } - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[type][params->cycle][LOOKUP_BULK] = time_taken / NUM_LOOKUPS; - - return 0; -} - -static int -timed_lookups_multimatch(struct member_perf_params *params, int type) -{ - unsigned int i, j; - member_set_t result[RTE_MEMBER_BUCKET_ENTRIES] = {0}; - int ret; - false_data_multi[type][params->cycle] = 0; - - const uint64_t start_tsc = rte_rdtsc(); - - for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) { - for (j = 0; j < KEYS_TO_ADD; j++) { - ret = rte_member_lookup_multi(params->setsum[type], - &keys[j], RTE_MEMBER_BUCKET_ENTRIES, result); - if (type != CACHE && ret <= 0) { - printf("lookup multi has wrong return value %d," - "type %d\n", ret, type); - } - if (type == HT && ret == 0) { - printf("HT mode shouldn't have false negative"); - return -1; - } - /* - * For performance test purpose, we do not iterate all - * results here. We assume most likely each key can only - * find one match which is result[0]. - */ - if (result[0] != data[type][j]) - false_data_multi[type][params->cycle]++; - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[type][params->cycle][LOOKUP_MULTI] = time_taken / NUM_LOOKUPS; - - return 0; -} - -static int -timed_lookups_multimatch_bulk(struct member_perf_params *params, int type) -{ - unsigned int i, j, k; - member_set_t result[BURST_SIZE][RTE_MEMBER_BUCKET_ENTRIES] = {{0} }; - const void *keys_burst[BURST_SIZE]; - uint32_t match_count[BURST_SIZE]; - int ret; - - false_data_multi_bulk[type][params->cycle] = 0; - - 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]; - - ret = rte_member_lookup_multi_bulk( - params->setsum[type], - keys_burst, BURST_SIZE, - RTE_MEMBER_BUCKET_ENTRIES, match_count, - (member_set_t *)result); - if (ret < 0) { - printf("lookup multimatch bulk has wrong return" - " value\n"); - return -1; - } - for (k = 0; k < BURST_SIZE; k++) { - if (type != CACHE && match_count[k] == 0) { - printf("lookup multimatch bulk get " - "wrong match count\n"); - return -1; - } - if (type == HT && match_count[k] == 0) { - printf("HT mode shouldn't have " - "false negative"); - return -1; - } - uint32_t data_idx = j * BURST_SIZE + k; - if (result[k][0] != data[type][data_idx]) - false_data_multi_bulk[type][params->cycle]++; - } - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[type][params->cycle][LOOKUP_MULTI_BULK] = time_taken / - NUM_LOOKUPS; - - return 0; -} - -static int -timed_deletes(struct member_perf_params *params, int type) -{ - unsigned int i; - int32_t ret; - - if (type == VBF) - return 0; - const uint64_t start_tsc = rte_rdtsc(); - for (i = 0; i < KEYS_TO_ADD; i++) { - ret = rte_member_delete(params->setsum[type], &keys[i], - data[type][i]); - if (type != CACHE && ret < 0) { - printf("delete error\n"); - return -1; - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[type][params->cycle][DELETE] = time_taken / KEYS_TO_ADD; - - return 0; -} - -static int -timed_miss_lookup(struct member_perf_params *params, int type) -{ - unsigned int i, j; - int ret; - - false_hit[type][params->cycle] = 0; - - for (i = 0; i < KEYS_TO_ADD / 2; i++) { - ret = rte_member_add(params->setsum[type], &keys[i], - data[type][i]); - if (ret < 0) { - unsigned int a; - printf("Error %d in rte_member_add - key=0x", ret); - for (a = 0; a < params->key_size; a++) - printf("%02x", keys[i][a]); - printf(" value=%d, type: %d\n", data[type][i], type); - - return -1; - } - } - - const uint64_t start_tsc = rte_rdtsc(); - member_set_t result; - - for (i = 0; i < 2 * NUM_LOOKUPS / KEYS_TO_ADD; i++) { - for (j = KEYS_TO_ADD / 2; j < KEYS_TO_ADD; j++) { - ret = rte_member_lookup(params->setsum[type], &keys[j], - &result); - if (ret < 0) { - printf("lookup wrong internally"); - return -1; - } - if (result != RTE_MEMBER_NO_MATCH) - false_hit[type][params->cycle]++; - } - } - - const uint64_t end_tsc = rte_rdtsc(); - const uint64_t time_taken = end_tsc - start_tsc; - - cycles[type][params->cycle][LOOKUP_MISS] = time_taken / NUM_LOOKUPS; - - return 0; -} - -static void -perform_frees(struct member_perf_params *params) -{ - int i; - for (i = 0; i < NUM_TYPE; i++) { - if (params->setsum[i] != NULL) { - rte_member_free(params->setsum[i]); - params->setsum[i] = NULL; - } - } -} - -static int -exit_with_fail(const char *testname, struct member_perf_params *params, - unsigned int i, unsigned int j) -{ - printf("<<<<>>>>\n", - testname, hashtest_key_lens[params->cycle], i, j); - perform_frees(params); - return -1; -} - -static int -run_all_tbl_perf_tests(void) -{ - unsigned int i, j, k; - struct member_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) < 0) { - printf("Could not create keys/data/table\n"); - return -1; - } - for (j = 0; j < NUM_TYPE; j++) { - - if (timed_adds(¶ms, j) < 0) - return exit_with_fail("timed_adds", ¶ms, - i, j); - - for (k = 0; k < NUM_SHUFFLES; k++) - shuffle_input_keys(¶ms); - - if (timed_lookups(¶ms, j) < 0) - return exit_with_fail("timed_lookups", ¶ms, - i, j); - - if (timed_lookups_bulk(¶ms, j) < 0) - return exit_with_fail("timed_lookups_bulk", - ¶ms, i, j); - - if (timed_lookups_multimatch(¶ms, j) < 0) - return exit_with_fail("timed_lookups_multi", - ¶ms, i, j); - - if (timed_lookups_multimatch_bulk(¶ms, j) < 0) - return exit_with_fail("timed_lookups_multi_bulk", - ¶ms, i, j); - - if (timed_deletes(¶ms, j) < 0) - return exit_with_fail("timed_deletes", ¶ms, - i, j); - - /* Print a dot to show progress on operations */ - } - printf("."); - fflush(stdout); - - perform_frees(¶ms); - } - - /* Test false positive rate using un-inserted keys */ - for (i = 0; i < NUM_KEYSIZES; i++) { - if (setup_keys_and_data(¶ms, i, 1) < 0) { - printf("Could not create keys/data/table\n"); - return -1; - } - for (j = 0; j < NUM_TYPE; j++) { - if (timed_miss_lookup(¶ms, j) < 0) - return exit_with_fail("timed_miss_lookup", - ¶ms, i, j); - } - perform_frees(¶ms); - } - - printf("\nResults (in CPU cycles/operation)\n"); - printf("-----------------------------------\n"); - printf("\n%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s\n", - "Keysize", "type", "Add", "Lookup", "Lookup_bulk", - "lookup_multi", "lookup_multi_bulk", "Delete", - "miss_lookup"); - for (i = 0; i < NUM_KEYSIZES; i++) { - for (j = 0; j < NUM_TYPE; j++) { - printf("%-18d", hashtest_key_lens[i]); - printf("%-18d", j); - for (k = 0; k < NUM_OPERATIONS; k++) - printf("%-18"PRIu64, cycles[j][i][k]); - printf("\n"); - } - } - - printf("\nFalse results rate (and false positive rate)\n"); - printf("-----------------------------------\n"); - printf("\n%-18s%-18s%-18s%-18s%-18s%-18s%-18s\n", - "Keysize", "type", "fr_single", "fr_bulk", "fr_multi", - "fr_multi_bulk", "false_positive_rate"); - /* Key size not influence False rate so just print out one key size */ - for (i = 0; i < 1; i++) { - for (j = 0; j < NUM_TYPE; j++) { - printf("%-18d", hashtest_key_lens[i]); - printf("%-18d", j); - printf("%-18f", (float)false_data[j][i] / NUM_LOOKUPS); - printf("%-18f", (float)false_data_bulk[j][i] / - NUM_LOOKUPS); - printf("%-18f", (float)false_data_multi[j][i] / - NUM_LOOKUPS); - printf("%-18f", (float)false_data_multi_bulk[j][i] / - NUM_LOOKUPS); - printf("%-18f", (float)false_hit[j][i] / - NUM_LOOKUPS); - printf("\n"); - } - } - return 0; -} - -static int -test_member_perf(void) -{ - - if (run_all_tbl_perf_tests() < 0) - return -1; - - return 0; -} - -REGISTER_TEST_COMMAND(member_perf_autotest, test_member_perf); diff --git a/test/test/test_memcpy.c b/test/test/test_memcpy.c deleted file mode 100644 index 2c69ad9647..0000000000 --- a/test/test/test_memcpy.c +++ /dev/null @@ -1,133 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 6f436f3ef3..0000000000 --- a/test/test/test_memcpy_perf.c +++ /dev/null @@ -1,352 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#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("%3.0f -", (double)total_time / TEST_ITERATIONS); \ - printf("%3.0f", (double)total_time2 / TEST_ITERATIONS); \ - printf("(%6.2f%%) ", ((double)total_time - total_time2)*100/total_time2); \ -} 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; - struct timeval tv_begin, tv_end; - double time_aligned, time_unaligned; - double time_aligned_const, time_unaligned_const; - - 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 */ - gettimeofday(&tv_begin, NULL); - perf_test_variable_aligned(); - gettimeofday(&tv_end, NULL); - time_aligned = (double)(tv_end.tv_sec - tv_begin.tv_sec) - + ((double)tv_end.tv_usec - tv_begin.tv_usec)/1000000; - printf("\n------- ----------------- ----------------- ----------------- -----------------"); - /* Do aligned tests where size is a compile-time constant */ - gettimeofday(&tv_begin, NULL); - perf_test_constant_aligned(); - gettimeofday(&tv_end, NULL); - time_aligned_const = (double)(tv_end.tv_sec - tv_begin.tv_sec) - + ((double)tv_end.tv_usec - tv_begin.tv_usec)/1000000; - printf("\n================================== Unaligned =================================="); - /* Do unaligned tests where size is a variable */ - gettimeofday(&tv_begin, NULL); - perf_test_variable_unaligned(); - gettimeofday(&tv_end, NULL); - time_unaligned = (double)(tv_end.tv_sec - tv_begin.tv_sec) - + ((double)tv_end.tv_usec - tv_begin.tv_usec)/1000000; - printf("\n------- ----------------- ----------------- ----------------- -----------------"); - /* Do unaligned tests where size is a compile-time constant */ - gettimeofday(&tv_begin, NULL); - perf_test_constant_unaligned(); - gettimeofday(&tv_end, NULL); - time_unaligned_const = (double)(tv_end.tv_sec - tv_begin.tv_sec) - + ((double)tv_end.tv_usec - tv_begin.tv_usec)/1000000; - printf("\n======= ================= ================= ================= =================\n\n"); - - printf("Test Execution Time (seconds):\n"); - printf("Aligned variable copy size = %8.3f\n", time_aligned); - printf("Aligned constant copy size = %8.3f\n", time_aligned_const); - printf("Unaligned variable copy size = %8.3f\n", time_unaligned); - printf("Unaligned constant copy size = %8.3f\n", time_unaligned_const); - 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 deleted file mode 100644 index 3da803e4e1..0000000000 --- a/test/test/test_memory.c +++ /dev/null @@ -1,108 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include - -#include -#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 -check_mem(const struct rte_memseg_list *msl __rte_unused, - const struct rte_memseg *ms, void *arg __rte_unused) -{ - volatile uint8_t *mem = (volatile uint8_t *) ms->addr; - size_t i, max = ms->len; - - for (i = 0; i < max; i++, mem++) - *mem; - return 0; -} - -static int -check_seg_fds(const struct rte_memseg_list *msl, const struct rte_memseg *ms, - void *arg __rte_unused) -{ - size_t offset; - int ret; - - /* skip external segments */ - if (msl->external) - return 0; - - /* try segment fd first. we're in a callback, so thread-unsafe */ - ret = rte_memseg_get_fd_thread_unsafe(ms); - if (ret < 0) { - /* ENOTSUP means segment is valid, but there is not support for - * segment fd API (e.g. on FreeBSD). - */ - if (errno == ENOTSUP) - return 1; - /* all other errors are treated as failures */ - return -1; - } - - /* we're able to get memseg fd - try getting its offset */ - ret = rte_memseg_get_fd_offset_thread_unsafe(ms, &offset); - if (ret < 0) { - if (errno == ENOTSUP) - return 1; - return -1; - } - return 0; -} - -static int -test_memory(void) -{ - uint64_t s; - int ret; - - /* - * 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) */ - rte_memseg_walk(check_mem, NULL); - - /* check segment fd support */ - ret = rte_memseg_walk(check_seg_fds, NULL); - if (ret == 1) { - printf("Segment fd API is unsupported\n"); - } else if (ret == -1) { - printf("Error getting segment fd's\n"); - return -1; - } - - return 0; -} - -REGISTER_TEST_COMMAND(memory_autotest, test_memory); diff --git a/test/test/test_mempool.c b/test/test/test_mempool.c deleted file mode 100644 index eebb1f24d3..0000000000 --- a/test/test/test_mempool.c +++ /dev/null @@ -1,594 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 - * ======= - * - * 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) - 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_virt2iova() not supported on bsd */ - printf("get physical address of an object\n"); - if (rte_mempool_virt2iova(obj) != rte_mem_virt2iova(obj)) - GOTO_ERR(ret, out); -#endif - - printf("put the object back\n"); - rte_mempool_generic_put(mp, &obj, 1, cache); - rte_mempool_dump(stdout, mp); - - printf("get 2 objects\n"); - if (rte_mempool_generic_get(mp, &obj, 1, cache) < 0) - GOTO_ERR(ret, out); - if (rte_mempool_generic_get(mp, &obj2, 1, cache) < 0) { - rte_mempool_generic_put(mp, &obj, 1, cache); - GOTO_ERR(ret, out); - } - rte_mempool_dump(stdout, mp); - - printf("put the objects back\n"); - rte_mempool_generic_put(mp, &obj, 1, cache); - rte_mempool_generic_put(mp, &obj2, 1, cache); - 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) - 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); - } - - 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"); - ret = -1; - goto err; - } - lcore_next = rte_get_next_lcore(lcore_id, 0, 1); - if (lcore_next >= RTE_MAX_LCORE) { - ret = -1; - goto err; - } - if (rte_eal_lcore_role(lcore_next) != ROLE_RTE) { - ret = -1; - goto 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; - -err: - rte_mempool_free(mp_spsc); - mp_spsc = NULL; - - 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; -} - -static void -walk_cb(struct rte_mempool *mp, void *userdata __rte_unused) -{ - printf("\t%s\n", mp->name); -} - -static int -test_mempool(void) -{ - int ret = -1; - struct rte_mempool *mp_cache = NULL; - struct rte_mempool *mp_nocache = NULL; - struct rte_mempool *mp_stack = NULL; - struct rte_mempool *default_pool = NULL; - const char *default_pool_ops = rte_mbuf_best_mempool_ops(); - - 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); - - /* Create a mempool based on Default handler */ - printf("Testing %s mempool handler\n", default_pool_ops); - default_pool = rte_mempool_create_empty("default_pool", - MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, - RTE_MEMPOOL_CACHE_MAX_SIZE, 0, - SOCKET_ID_ANY, 0); - - if (default_pool == NULL) { - printf("cannot allocate default mempool\n"); - goto err; - } - if (rte_mempool_set_ops_byname(default_pool, - default_pool_ops, NULL) < 0) { - printf("cannot set %s handler\n", default_pool_ops); - goto err; - } - if (rte_mempool_populate_default(default_pool) < 0) { - printf("cannot populate %s mempool\n", default_pool_ops); - goto err; - } - rte_mempool_obj_iter(default_pool, 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; - - /* test the stack handler */ - if (test_mempool_basic(mp_stack, 1) < 0) - goto err; - - if (test_mempool_basic(default_pool, 1) < 0) - goto err; - - rte_mempool_list_dump(stdout); - - ret = 0; - -err: - rte_mempool_free(mp_nocache); - rte_mempool_free(mp_cache); - rte_mempool_free(mp_stack); - rte_mempool_free(default_pool); - - return ret; -} - -REGISTER_TEST_COMMAND(mempool_autotest, test_mempool); diff --git a/test/test/test_mempool_perf.c b/test/test/test_mempool_perf.c deleted file mode 100644 index 4c877834e7..0000000000 --- a/test/test/test_mempool_perf.c +++ /dev/null @@ -1,399 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 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(void *arg) -{ - void *obj_table[MAX_KEEP]; - unsigned i, idx; - struct rte_mempool *mp = arg; - 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); - 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); - 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(struct rte_mempool *mp, unsigned int 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, - mp, lcore_id); - } - - /* start synchro and launch test on master */ - rte_atomic32_set(&synchro, 1); - - ret = per_lcore_mempool_test(mp); - - 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(struct rte_mempool *mp, unsigned int 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(mp, cores); - - if (ret < 0) - return -1; - } - } - } - return 0; -} - -static int -test_mempool_perf(void) -{ - struct rte_mempool *mp_cache = NULL; - struct rte_mempool *mp_nocache = NULL; - struct rte_mempool *default_pool = NULL; - const char *default_pool_ops; - int ret = -1; - - rte_atomic32_init(&synchro); - - /* create a mempool (without cache) */ - 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) - goto err; - - /* create a mempool (with cache) */ - 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) - goto err; - - default_pool_ops = rte_mbuf_best_mempool_ops(); - /* Create a mempool based on Default handler */ - default_pool = rte_mempool_create_empty("default_pool", - MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, - 0, 0, - SOCKET_ID_ANY, 0); - - if (default_pool == NULL) { - printf("cannot allocate %s mempool\n", default_pool_ops); - goto err; - } - - if (rte_mempool_set_ops_byname(default_pool, default_pool_ops, NULL) - < 0) { - printf("cannot set %s handler\n", default_pool_ops); - goto err; - } - - if (rte_mempool_populate_default(default_pool) < 0) { - printf("cannot populate %s mempool\n", default_pool_ops); - goto err; - } - - rte_mempool_obj_iter(default_pool, my_obj_init, NULL); - - /* performance test with 1, 2 and max cores */ - printf("start performance test (without cache)\n"); - - if (do_one_mempool_test(mp_nocache, 1) < 0) - goto err; - - if (do_one_mempool_test(mp_nocache, 2) < 0) - goto err; - - if (do_one_mempool_test(mp_nocache, rte_lcore_count()) < 0) - goto err; - - /* performance test with 1, 2 and max cores */ - printf("start performance test for %s (without cache)\n", - default_pool_ops); - - if (do_one_mempool_test(default_pool, 1) < 0) - goto err; - - if (do_one_mempool_test(default_pool, 2) < 0) - goto err; - - if (do_one_mempool_test(default_pool, rte_lcore_count()) < 0) - goto err; - - /* performance test with 1, 2 and max cores */ - printf("start performance test (with cache)\n"); - - if (do_one_mempool_test(mp_cache, 1) < 0) - goto err; - - if (do_one_mempool_test(mp_cache, 2) < 0) - goto err; - - if (do_one_mempool_test(mp_cache, rte_lcore_count()) < 0) - goto err; - - /* performance test with 1, 2 and max cores */ - printf("start performance test (with user-owned cache)\n"); - use_external_cache = 1; - - if (do_one_mempool_test(mp_nocache, 1) < 0) - goto err; - - if (do_one_mempool_test(mp_nocache, 2) < 0) - goto err; - - if (do_one_mempool_test(mp_nocache, rte_lcore_count()) < 0) - goto err; - - rte_mempool_list_dump(stdout); - - ret = 0; - -err: - rte_mempool_free(mp_cache); - rte_mempool_free(mp_nocache); - rte_mempool_free(default_pool); - return ret; -} - -REGISTER_TEST_COMMAND(mempool_perf_autotest, test_mempool_perf); diff --git a/test/test/test_memzone.c b/test/test/test_memzone.c deleted file mode 100644 index 9fe465e621..0000000000 --- a/test/test/test_memzone.c +++ /dev/null @@ -1,1116 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#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 - */ - -#define TEST_MEMZONE_NAME(suffix) "MZ_TEST_" suffix - -/* Test if memory overlaps: return 1 if true, or 0 if false. */ -static int -is_memory_overlap(rte_iova_t ptr1, size_t len1, rte_iova_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(TEST_MEMZONE_NAME("invalid_alignment")); - if (mz != NULL) { - printf("Zone with invalid alignment has been reserved\n"); - return -1; - } - - mz = rte_memzone_reserve_aligned(TEST_MEMZONE_NAME("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( - TEST_MEMZONE_NAME("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( - TEST_MEMZONE_NAME("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; -} - -struct walk_arg { - int hugepage_2MB_avail; - int hugepage_1GB_avail; - int hugepage_16MB_avail; - int hugepage_16GB_avail; -}; -static int -find_available_pagesz(const struct rte_memseg_list *msl, void *arg) -{ - struct walk_arg *wa = arg; - - if (msl->external) - return 0; - - if (msl->page_sz == RTE_PGSIZE_2M) - wa->hugepage_2MB_avail = 1; - if (msl->page_sz == RTE_PGSIZE_1G) - wa->hugepage_1GB_avail = 1; - if (msl->page_sz == RTE_PGSIZE_16M) - wa->hugepage_16MB_avail = 1; - if (msl->page_sz == RTE_PGSIZE_16G) - wa->hugepage_16GB_avail = 1; - - return 0; -} - -static int -test_memzone_reserve_flags(void) -{ - const struct rte_memzone *mz; - struct walk_arg wa; - int hugepage_2MB_avail, hugepage_1GB_avail; - int hugepage_16MB_avail, hugepage_16GB_avail; - const size_t size = 100; - - memset(&wa, 0, sizeof(wa)); - - rte_memseg_list_walk(find_available_pagesz, &wa); - - hugepage_2MB_avail = wa.hugepage_2MB_avail; - hugepage_1GB_avail = wa.hugepage_1GB_avail; - hugepage_16MB_avail = wa.hugepage_16MB_avail; - hugepage_16GB_avail = wa.hugepage_16GB_avail; - - /* 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(TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - - mz = rte_memzone_reserve(TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\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( - TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - - mz = rte_memzone_reserve( - TEST_MEMZONE_NAME("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(TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - - mz = rte_memzone_reserve(TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\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( - TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - mz = rte_memzone_reserve( - TEST_MEMZONE_NAME("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( - TEST_MEMZONE_NAME("flag_zone_2M_HINT"), - size, SOCKET_ID_ANY, - RTE_MEMZONE_2MB|RTE_MEMZONE_1GB); - if (mz == NULL) { - printf("BOTH SIZES SET\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_1G && - mz->hugepage_sz != RTE_PGSIZE_2M) { - printf("Wrong size when both sizes set\n"); - return -1; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\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(TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - - mz = rte_memzone_reserve( - TEST_MEMZONE_NAME("flag_zone_16M_HINT"), size, - SOCKET_ID_ANY, - RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY); - 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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\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( - TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - - mz = rte_memzone_reserve( - TEST_MEMZONE_NAME("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(TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - - mz = rte_memzone_reserve( - TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\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( - TEST_MEMZONE_NAME("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; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - mz = rte_memzone_reserve( - TEST_MEMZONE_NAME("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( - TEST_MEMZONE_NAME("flag_zone_16M_HINT"), - size, SOCKET_ID_ANY, - RTE_MEMZONE_16MB|RTE_MEMZONE_16GB); - if (mz == NULL) { - printf("BOTH SIZES SET\n"); - return -1; - } - if (mz->hugepage_sz != RTE_PGSIZE_16G && - mz->hugepage_sz != RTE_PGSIZE_16M) { - printf("Wrong size when both sizes set\n"); - return -1; - } - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - } - } - return 0; -} - - -/* Find the heap with the greatest free block size */ -static size_t -find_max_block_free_size(unsigned int align, unsigned int socket_id) -{ - struct rte_malloc_socket_stats stats; - size_t len, overhead; - - rte_malloc_get_socket_stats(socket_id, &stats); - - len = stats.greatest_free_size; - overhead = MALLOC_ELEM_OVERHEAD; - - if (len == 0) - return 0; - - align = RTE_CACHE_LINE_ROUNDUP(align); - overhead += align; - - if (len < overhead) - return 0; - - return len - overhead; -} - -static int -test_memzone_reserve_max(void) -{ - unsigned int i; - - for (i = 0; i < rte_socket_count(); i++) { - const struct rte_memzone *mz; - size_t maxlen; - int socket; - - socket = rte_socket_id_by_idx(i); - maxlen = find_max_block_free_size(0, socket); - - if (maxlen == 0) { - printf("There is no space left!\n"); - return 0; - } - - mz = rte_memzone_reserve(TEST_MEMZONE_NAME("max_zone"), 0, - socket, 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; - } - - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - } - - return 0; -} - -static int -test_memzone_reserve_max_aligned(void) -{ - unsigned int i; - - for (i = 0; i < rte_socket_count(); i++) { - const struct rte_memzone *mz; - size_t maxlen, minlen = 0; - int socket; - - socket = rte_socket_id_by_idx(i); - - /* random alignment */ - rte_srand((unsigned int)rte_rdtsc()); - const unsigned int align = 1 << ((rte_rand() % 8) + 5); /* from 128 up to 4k alignment */ - - /* memzone size may be between size and size - align */ - minlen = find_max_block_free_size(align, socket); - maxlen = find_max_block_free_size(0, socket); - - if (minlen == 0 || maxlen == 0) { - printf("There is no space left for biggest %u-aligned memzone!\n", - align); - return 0; - } - - mz = rte_memzone_reserve_aligned( - TEST_MEMZONE_NAME("max_zone_aligned"), - 0, socket, 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->addr != RTE_PTR_ALIGN(mz->addr, align)) { - printf("Memzone reserve with 0 size and alignment %u did not return aligned block\n", - align); - rte_dump_physmem_layout(stdout); - rte_memzone_dump(stdout); - return -1; - } - - if (mz->len < minlen || mz->len > maxlen) { - printf("Memzone reserve with 0 size and alignment %u did not return" - " bigest block\n", align); - printf("Expected size = %zu-%zu, actual size = %zu\n", - minlen, maxlen, mz->len); - rte_dump_physmem_layout(stdout); - rte_memzone_dump(stdout); - return -1; - } - - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - 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( - TEST_MEMZONE_NAME("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( - TEST_MEMZONE_NAME("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( - TEST_MEMZONE_NAME("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( - TEST_MEMZONE_NAME("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( - TEST_MEMZONE_NAME("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->iova & 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->iova & 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->iova & 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->iova & 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->iova & 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->iova, memzone_aligned_32->len, - memzone_aligned_128->iova, memzone_aligned_128->len)) - return -1; - if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len, - memzone_aligned_256->iova, memzone_aligned_256->len)) - return -1; - if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len, - memzone_aligned_512->iova, memzone_aligned_512->len)) - return -1; - if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len, - memzone_aligned_1024->iova, memzone_aligned_1024->len)) - return -1; - if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len, - memzone_aligned_256->iova, memzone_aligned_256->len)) - return -1; - if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len, - memzone_aligned_512->iova, memzone_aligned_512->len)) - return -1; - if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len, - memzone_aligned_1024->iova, memzone_aligned_1024->len)) - return -1; - if (is_memory_overlap(memzone_aligned_256->iova, memzone_aligned_256->len, - memzone_aligned_512->iova, memzone_aligned_512->len)) - return -1; - if (is_memory_overlap(memzone_aligned_256->iova, memzone_aligned_256->len, - memzone_aligned_1024->iova, memzone_aligned_1024->len)) - return -1; - if (is_memory_overlap(memzone_aligned_512->iova, memzone_aligned_512->len, - memzone_aligned_1024->iova, memzone_aligned_1024->len)) - return -1; - - /* free all used zones */ - if (rte_memzone_free(memzone_aligned_32)) { - printf("Fail memzone free\n"); - return -1; - } - if (rte_memzone_free(memzone_aligned_128)) { - printf("Fail memzone free\n"); - return -1; - } - if (rte_memzone_free(memzone_aligned_256)) { - printf("Fail memzone free\n"); - return -1; - } - if (rte_memzone_free(memzone_aligned_512)) { - printf("Fail memzone free\n"); - return -1; - } - if (rte_memzone_free(memzone_aligned_1024)) { - printf("Fail memzone free\n"); - 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; - rte_iova_t bmask; - - bmask = ~((rte_iova_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->iova & ((rte_iova_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->iova & bmask) != - ((mz->iova + mz->len - 1) & bmask)) { - printf("%s(%s): invalid memzone boundary %u crossed\n", - __func__, mz->name, bound); - return -1; - } - - if (rte_memzone_free(mz)) { - printf("Fail memzone free\n"); - return -1; - } - - return 0; -} - -static int -test_memzone_bounded(void) -{ - const struct rte_memzone *memzone_err; - int rc; - - /* should fail as boundary is not power of two */ - memzone_err = rte_memzone_reserve_bounded( - TEST_MEMZONE_NAME("bounded_error_31"), 100, - SOCKET_ID_ANY, 0, 32, UINT32_MAX); - if (memzone_err != 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 */ - memzone_err = rte_memzone_reserve_bounded( - TEST_MEMZONE_NAME("bounded_error_32"), 100, - SOCKET_ID_ANY, 0, 32, 32); - if (memzone_err != NULL) { - printf("%s(%s)created a memzone with invalid boundary " - "conditions\n", __func__, memzone_err->name); - return -1; - } - - rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_128"), 100, 128, - 128); - if (rc != 0) - return rc; - - rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_256"), 100, 256, - 128); - if (rc != 0) - return rc; - - rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_1K"), 100, 64, - 1024); - if (rc != 0) - return rc; - - rc = check_memzone_bounded(TEST_MEMZONE_NAME("bounded_1K_MAX"), 0, 64, - 1024); - if (rc != 0) - return rc; - - return 0; -} - -static int -test_memzone_free(void) -{ - const struct rte_memzone *mz[RTE_MAX_MEMZONE + 1]; - int i; - char name[20]; - - mz[0] = rte_memzone_reserve(TEST_MEMZONE_NAME("tempzone0"), 2000, - SOCKET_ID_ANY, 0); - mz[1] = rte_memzone_reserve(TEST_MEMZONE_NAME("tempzone1"), 4000, - SOCKET_ID_ANY, 0); - - if (mz[0] > mz[1]) - return -1; - if (!rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone0"))) - return -1; - if (!rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone1"))) - return -1; - - if (rte_memzone_free(mz[0])) { - printf("Fail memzone free - tempzone0\n"); - return -1; - } - if (rte_memzone_lookup(TEST_MEMZONE_NAME("tempzone0"))) { - printf("Found previously free memzone - tempzone0\n"); - return -1; - } - mz[2] = rte_memzone_reserve(TEST_MEMZONE_NAME("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(TEST_MEMZONE_NAME("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(TEST_MEMZONE_NAME("tempzone1"))) { - printf("Found previously free memzone - tempzone1\n"); - return -1; - } - - i = 0; - do { - snprintf(name, sizeof(name), TEST_MEMZONE_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(TEST_MEMZONE_NAME("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_basic(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; - int memzone_cnt_after, memzone_cnt_expected; - int memzone_cnt_before = - rte_eal_get_configuration()->mem_config->memzones.count; - - memzone1 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone1"), 100, - SOCKET_ID_ANY, 0); - - memzone2 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone2"), 1000, - 0, 0); - - memzone3 = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone3"), 1000, - 1, 0); - - memzone4 = rte_memzone_reserve(TEST_MEMZONE_NAME("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; - - /* check how many memzones we are expecting */ - memzone_cnt_expected = memzone_cnt_before + - (memzone1 != NULL) + (memzone2 != NULL) + - (memzone3 != NULL) + (memzone4 != NULL); - - memzone_cnt_after = - rte_eal_get_configuration()->mem_config->memzones.count; - - if (memzone_cnt_after != memzone_cnt_expected) - return -1; - - - rte_memzone_dump(stdout); - - /* check cache-line alignments */ - printf("check alignments and lengths\n"); - - if ((memzone1->iova & RTE_CACHE_LINE_MASK) != 0) - return -1; - if ((memzone2->iova & RTE_CACHE_LINE_MASK) != 0) - return -1; - if (memzone3 != NULL && (memzone3->iova & 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->iova, memzone1->len, - memzone2->iova, memzone2->len)) - return -1; - if (memzone3 != NULL && - is_memory_overlap(memzone1->iova, memzone1->len, - memzone3->iova, memzone3->len)) - return -1; - if (memzone3 != NULL && - is_memory_overlap(memzone2->iova, memzone2->len, - memzone3->iova, 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(TEST_MEMZONE_NAME("testzone1")); - if (mz != memzone1) - return -1; - - printf("test duplcate zone name\n"); - mz = rte_memzone_reserve(TEST_MEMZONE_NAME("testzone1"), 100, - SOCKET_ID_ANY, 0); - if (mz != NULL) - return -1; - - if (rte_memzone_free(memzone1)) { - printf("Fail memzone free - memzone1\n"); - return -1; - } - if (rte_memzone_free(memzone2)) { - printf("Fail memzone free - memzone2\n"); - return -1; - } - if (memzone3 && rte_memzone_free(memzone3)) { - printf("Fail memzone free - memzone3\n"); - return -1; - } - if (rte_memzone_free(memzone4)) { - printf("Fail memzone free - memzone4\n"); - return -1; - } - - memzone_cnt_after = - rte_eal_get_configuration()->mem_config->memzones.count; - if (memzone_cnt_after != memzone_cnt_before) - return -1; - - return 0; -} - -static int test_memzones_left; -static int memzone_walk_cnt; -static void memzone_walk_clb(const struct rte_memzone *mz, - void *arg __rte_unused) -{ - memzone_walk_cnt++; - if (!strncmp(TEST_MEMZONE_NAME(""), mz->name, RTE_MEMZONE_NAMESIZE)) - test_memzones_left++; -} - -static int -test_memzone(void) -{ - /* take note of how many memzones were allocated before running */ - int memzone_cnt = - rte_eal_get_configuration()->mem_config->memzones.count; - - printf("test basic memzone API\n"); - if (test_memzone_basic() < 0) - 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; - - printf("check memzone cleanup\n"); - memzone_walk_cnt = 0; - test_memzones_left = 0; - rte_memzone_walk(memzone_walk_clb, NULL); - if (memzone_walk_cnt != memzone_cnt || test_memzones_left > 0) { - printf("there are some memzones left after test\n"); - rte_memzone_dump(stdout); - 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 deleted file mode 100644 index f935faa539..0000000000 --- a/test/test/test_meter.c +++ /dev/null @@ -1,716 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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_EIR_DF 69000000 -#define TM_TEST_TRTCM_CBS_DF 2048 -#define TM_TEST_TRTCM_PBS_DF 4096 -#define TM_TEST_TRTCM_EBS_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,}; - -static struct rte_meter_trtcm_rfc4115_params rfc4115params = - {.cir = TM_TEST_TRTCM_CIR_DF, - .eir = TM_TEST_TRTCM_EIR_DF, - .cbs = TM_TEST_TRTCM_CBS_DF, - .ebs = TM_TEST_TRTCM_EBS_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_profile sp; - struct rte_meter_srtcm_params sparams1; - - /* invalid parameter test */ - if (rte_meter_srtcm_profile_config(NULL, NULL) == 0) - melog(SRTCM_CFG_MSG); - if (rte_meter_srtcm_profile_config(&sp, NULL) == 0) - melog(SRTCM_CFG_MSG); - if (rte_meter_srtcm_profile_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_profile_config(&sp, &sparams1) == 0) - melog(SRTCM_CFG_MSG); - - /* cir should never be 0 */ - sparams1 = sparams; - sparams1.cir = 0; - if (rte_meter_srtcm_profile_config(&sp, &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_profile_config(&sp, &sparams1) != 0) - melog(SRTCM_CFG_MSG); - - sparams1 = sparams; - sparams1.cbs = 0; - if (rte_meter_srtcm_profile_config(&sp, &sparams1) != 0) - melog(SRTCM_CFG_MSG); - - /* usual parameter, should be successful */ - if (rte_meter_srtcm_profile_config(&sp, &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_profile tp; - struct rte_meter_trtcm_params tparams1; -#define TRTCM_CFG_MSG "trtcm_config" - - /* invalid parameter test */ - if (rte_meter_trtcm_profile_config(NULL, NULL) == 0) - melog(TRTCM_CFG_MSG); - if (rte_meter_trtcm_profile_config(&tp, NULL) == 0) - melog(TRTCM_CFG_MSG); - if (rte_meter_trtcm_profile_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_profile_config(&tp, &tparams1) == 0) - melog(TRTCM_CFG_MSG); - - tparams1 = tparams; - tparams1.cbs = 0; - if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0) - melog(TRTCM_CFG_MSG); - - tparams1 = tparams; - tparams1.pbs = 0; - if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0) - melog(TRTCM_CFG_MSG); - - tparams1 = tparams; - tparams1.pir = 0; - if (rte_meter_trtcm_profile_config(&tp, &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_profile_config(&tp, &tparams1) == 0) - melog(TRTCM_CFG_MSG" pir < cir test"); - - /* usual parameter, should be successful */ - if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) - melog(TRTCM_CFG_MSG); - - return 0; -} - -/** - * functional test for rte_meter_trtcm_rfc4115_config - */ -static inline int -tm_test_trtcm_rfc4115_config(void) -{ - struct rte_meter_trtcm_rfc4115_profile tp; - struct rte_meter_trtcm_rfc4115_params rfc4115params1; -#define TRTCM_RFC4115_CFG_MSG "trtcm_rfc4115_config" - - /* invalid parameter test */ - if (rte_meter_trtcm_rfc4115_profile_config(NULL, NULL) == 0) - melog(TRTCM_RFC4115_CFG_MSG); - if (rte_meter_trtcm_rfc4115_profile_config(&tp, NULL) == 0) - melog(TRTCM_RFC4115_CFG_MSG); - if (rte_meter_trtcm_rfc4115_profile_config(NULL, &rfc4115params) == 0) - melog(TRTCM_RFC4115_CFG_MSG); - - /* - * cbs and pbs should be none-zero if cir and eir are none-zero - * respectively - */ - rfc4115params1 = rfc4115params; - rfc4115params1.cbs = 0; - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params1) == 0) - melog(TRTCM_RFC4115_CFG_MSG); - - rfc4115params1 = rfc4115params; - rfc4115params1.ebs = 0; - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params1) == 0) - melog(TRTCM_RFC4115_CFG_MSG); - - /* usual parameter, should be successful */ - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_RFC4115_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_profile sp; - struct rte_meter_srtcm sm; - uint64_t time; - uint64_t hz = rte_get_tsc_hz(); - - /* Test green */ - if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - if (rte_meter_srtcm_config(&sm, &sp) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_srtcm_color_blind_check( - &sm, &sp, time, TM_TEST_SRTCM_CBS_DF - 1) - != e_RTE_METER_GREEN) - melog(SRTCM_BLIND_CHECK_MSG" GREEN"); - - /* Test yellow */ - if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - if (rte_meter_srtcm_config(&sm, &sp) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_srtcm_color_blind_check( - &sm, &sp, time, TM_TEST_SRTCM_CBS_DF + 1) - != e_RTE_METER_YELLOW) - melog(SRTCM_BLIND_CHECK_MSG" YELLOW"); - - if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - if (rte_meter_srtcm_config(&sm, &sp) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_srtcm_color_blind_check( - &sm, &sp, time, (uint32_t)sp.ebs - 1) != e_RTE_METER_YELLOW) - melog(SRTCM_BLIND_CHECK_MSG" YELLOW"); - - /* Test red */ - if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - if (rte_meter_srtcm_config(&sm, &sp) != 0) - melog(SRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_srtcm_color_blind_check( - &sm, &sp, 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_profile tp; - struct rte_meter_trtcm tm; - uint64_t hz = rte_get_tsc_hz(); - - /* Test green */ - if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - if (rte_meter_trtcm_config(&tm, &tp) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_color_blind_check( - &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1) - != e_RTE_METER_GREEN) - melog(TRTCM_BLIND_CHECK_MSG" GREEN"); - - /* Test yellow */ - if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - if (rte_meter_trtcm_config(&tm, &tp) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_color_blind_check( - &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1) - != e_RTE_METER_YELLOW) - melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); - - if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - if (rte_meter_trtcm_config(&tm, &tp) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_color_blind_check( - &tm, &tp, time, TM_TEST_TRTCM_PBS_DF - 1) - != e_RTE_METER_YELLOW) - melog(TRTCM_BLIND_CHECK_MSG" YELLOW"); - - /* Test red */ - if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - if (rte_meter_trtcm_config(&tm, &tp) != 0) - melog(TRTCM_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_color_blind_check( - &tm, &tp, time, TM_TEST_TRTCM_PBS_DF + 1) - != e_RTE_METER_RED) - melog(TRTCM_BLIND_CHECK_MSG" RED"); - - return 0; -} - -/** - * functional test for rte_meter_trtcm_rfc4115_color_blind_check - */ -static inline int -tm_test_trtcm_rfc4115_color_blind_check(void) -{ -#define TRTCM_RFC4115_BLIND_CHECK_MSG "trtcm_rfc4115_blind_check" - - uint64_t time; - struct rte_meter_trtcm_rfc4115_profile tp; - struct rte_meter_trtcm_rfc4115 tm; - uint64_t hz = rte_get_tsc_hz(); - - /* Test green */ - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG); - if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_rfc4115_color_blind_check( - &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1) - != e_RTE_METER_GREEN) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG" GREEN"); - - /* Test yellow */ - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG); - if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_rfc4115_color_blind_check( - &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1) - != e_RTE_METER_YELLOW) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG" YELLOW"); - - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG); - if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_rfc4115_color_blind_check( - &tm, &tp, time, TM_TEST_TRTCM_EBS_DF - 1) - != e_RTE_METER_YELLOW) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG" YELLOW"); - - /* Test red */ - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG); - if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) - melog(TRTCM_RFC4115_BLIND_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_rfc4115_color_blind_check( - &tm, &tp, time, TM_TEST_TRTCM_EBS_DF + 1) - != e_RTE_METER_RED) - melog(TRTCM_RFC4115_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_profile sp; - struct rte_meter_srtcm sm; - uint64_t time; - uint64_t hz = rte_get_tsc_hz(); - - if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - if (rte_meter_srtcm_config(&sm, &sp) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_srtcm_color_aware_check( - &sm, &sp, 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_profile_config(&sp, &sparams) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - if (rte_meter_srtcm_config(&sm, &sp) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_srtcm_color_aware_check( - &sm, &sp, 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_profile_config(&sp, &sparams) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - if (rte_meter_srtcm_config(&sm, &sp) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_srtcm_color_aware_check( - &sm, &sp, 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_profile_config(&sp, &sparams) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - if (rte_meter_srtcm_config(&sm, &sp) != 0) - melog(SRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_srtcm_color_aware_check( - &sm, &sp, 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_profile tp; - struct rte_meter_trtcm tm; - uint64_t time; - uint64_t hz = rte_get_tsc_hz(); - - if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - if (rte_meter_trtcm_config(&tm, &tp) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_color_aware_check( - &tm, &tp, 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_profile_config(&tp, &tparams) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - if (rte_meter_trtcm_config(&tm, &tp) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_color_aware_check( - &tm, &tp, 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_profile_config(&tp, &tparams) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - if (rte_meter_trtcm_config(&tm, &tp) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_color_aware_check( - &tm, &tp, 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_profile_config(&tp, &tparams) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - if (rte_meter_trtcm_config(&tm, &tp) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_color_aware_check( - &tm, &tp, 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; -} - -/** - * @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_rfc4115_aware_check -(enum rte_meter_color in[4], enum rte_meter_color out[4]) -{ -#define TRTCM_RFC4115_AWARE_CHECK_MSG "trtcm_rfc4115_aware_check" - struct rte_meter_trtcm_rfc4115_profile tp; - struct rte_meter_trtcm_rfc4115 tm; - uint64_t time; - uint64_t hz = rte_get_tsc_hz(); - - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_AWARE_CHECK_MSG); - if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_rfc4115_color_aware_check( - &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0]) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG" %u:%u", in[0], out[0]); - - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG); - if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_rfc4115_color_aware_check( - &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1]) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG" %u:%u", in[1], out[1]); - - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG); - if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_rfc4115_color_aware_check( - &tm, &tp, time, TM_TEST_TRTCM_EBS_DF - 1, in[2]) != out[2]) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG" %u:%u", in[2], out[2]); - - if (rte_meter_trtcm_rfc4115_profile_config(&tp, &rfc4115params) != 0) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG); - if (rte_meter_trtcm_rfc4115_config(&tm, &tp) != 0) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG); - time = rte_get_tsc_cycles() + hz; - if (rte_meter_trtcm_rfc4115_color_aware_check( - &tm, &tp, time, TM_TEST_TRTCM_EBS_DF + 1, in[3]) != out[3]) - melog(TRTCM_RFC4115_AWARE_CHECK_MSG" %u:%u", in[3], out[3]); - - return 0; -} - -/** - * functional test for rte_meter_trtcm_rfc4115_color_aware_check - */ -static inline int -tm_test_trtcm_rfc4115_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_rfc4115_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_rfc4115_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_rfc4115_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_trtcm_rfc4115_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_trtcm_rfc4115_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; - - if (tm_test_trtcm_rfc4115_color_aware_check() != 0) - return -1; - - return 0; - -} - -REGISTER_TEST_COMMAND(meter_autotest, test_meter); diff --git a/test/test/test_metrics.c b/test/test/test_metrics.c deleted file mode 100644 index 3c2f36b8a4..0000000000 --- a/test/test/test_metrics.c +++ /dev/null @@ -1,313 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#include -#include -#include -#include - -#include -#include - -#include "test.h" - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#define REG_METRIC_COUNT 6 -#define METRIC_LESSER_COUNT 3 -#define KEY 1 -#define VALUE 1 - -/* Initializes metric module. This function must be called - * from a primary process before metrics are used - */ -static int -test_metrics_init(void) -{ - rte_metrics_init(rte_socket_id()); - return TEST_SUCCESS; -} - - /* Test Case to check failures when memzone init is not done */ -static int -test_metrics_without_init(void) -{ - int err = 0; - const uint64_t value[REG_METRIC_COUNT] = {0}; - const char * const mnames[] = { - "mean_bits_in", "mean_bits_out", - "peak_bits_in", "peak_bits_out", - }; - - /* Failure Test: Checking for memzone initialization */ - err = rte_metrics_reg_name("peak_bits_in"); - TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); - - err = rte_metrics_reg_names(&mnames[0], 1); - TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); - - err = rte_metrics_update_value(RTE_METRICS_GLOBAL, KEY, VALUE); - TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); - - err = rte_metrics_update_values(RTE_METRICS_GLOBAL, KEY, &value[0], 4); - TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); - - err = rte_metrics_get_names(NULL, 0); - TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); - - err = rte_metrics_get_values(RTE_METRICS_GLOBAL, NULL, 0); - TEST_ASSERT(err == -EIO, "%s, %d", __func__, __LINE__); - - return TEST_SUCCESS; -} - -/* Test Case to validate registering a single metric */ -static int -test_metrics_reg_name_with_validname(void) -{ - int err = 0; - - /* Test to register the new metric name */ - err = rte_metrics_reg_name("peak_bits_out"); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Test to register the same metric name */ - err = rte_metrics_reg_name("peak_bits_out"); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Test case to validate registering a invalid metric */ - err = rte_metrics_reg_name(NULL); - TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); - - return TEST_SUCCESS; -} - -/* Test case to validate registering a list of valid metric names */ -static int -test_metrics_reg_names(void) -{ - int err = 0; - const char * const mnames[] = { - "mean_bits_in", "mean_bits_out", - "peak_bits_in", "peak_bits_out", - }; - - /* Success Test: valid array and count size */ - err = rte_metrics_reg_names(&mnames[0], ARRAY_SIZE(mnames)); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - return TEST_SUCCESS; -} - -/* Test case to validate update a metric */ -static int -test_metrics_update_value(void) -{ - int err = 0; - - /* Successful Test: Valid port_id, key and value */ - err = rte_metrics_update_value(RTE_METRICS_GLOBAL, KEY, VALUE); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Successful Test: Valid port_id otherthan RTE_METRICS_GLOBAL, key - * and value - */ - err = rte_metrics_update_value(9, KEY, VALUE); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Failed Test: Invalid port_id with lower value */ - err = rte_metrics_update_value(-2, KEY, VALUE); - TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); - - /* Failed Test: Invalid port_id with higher value */ - err = rte_metrics_update_value(39, KEY, VALUE); - TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); - - /* Failed Test: valid port id, value with invalid key */ - err = rte_metrics_update_value(RTE_METRICS_GLOBAL, KEY+12, VALUE); - TEST_ASSERT(err < 0, "%s, %d", __func__, __LINE__); - - return TEST_SUCCESS; -} - -/* Test case to validate update a list of metrics */ -static int -test_metrics_update_values(void) -{ - int err = 0; - const uint64_t value[REG_METRIC_COUNT] = {1, 2, 3, 4, 5, 6}; - - /* Successful Test: update metrics with first set */ - err = rte_metrics_update_values(RTE_METRICS_GLOBAL, 0, - &value[0], 1); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Successful Test: update metrics with second set */ - err = rte_metrics_update_values(RTE_METRICS_GLOBAL, 1, - &value[1], 1); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Successful Test: update metrics with third set */ - err = rte_metrics_update_values(RTE_METRICS_GLOBAL, 2, - &value[2], 4); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Failed Test: Invalid count size */ - err = rte_metrics_update_values(RTE_METRICS_GLOBAL, - KEY, &value[0], ARRAY_SIZE(value)); - TEST_ASSERT(err < 0, "%s, %d", __func__, __LINE__); - - /* Failed Test: Invalid port_id(lower value) and valid data */ - err = rte_metrics_update_values(-2, KEY, &value[0], ARRAY_SIZE(value)); - TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); - - /* Failed Test: Invalid port_id(higher value) and valid data */ - err = rte_metrics_update_values(39, 1, &value[0], ARRAY_SIZE(value)); - TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); - - /* Failed Test: Invalid array */ - err = rte_metrics_update_values(RTE_METRICS_GLOBAL, - KEY, NULL, ARRAY_SIZE(value)); - TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); - - return TEST_SUCCESS; -} - -/* Test to validate get metric name-key lookup table */ -static int -test_metrics_get_names(void) -{ - int err = 0; - struct rte_metric_name metrics[METRIC_LESSER_COUNT]; - struct rte_metric_name success_metrics[REG_METRIC_COUNT]; - - /* Successful Test: Invalid array list */ - err = rte_metrics_get_names(NULL, 0); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Successful Test: Valid array list, Correct Count Stats same - * as memzone stats - */ - err = rte_metrics_get_names(success_metrics, REG_METRIC_COUNT); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Successful Test: Valid array list, Increase Count Stats than - * memzone stats - */ - err = rte_metrics_get_names(success_metrics, REG_METRIC_COUNT+5); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Successful Test, Not update results: - * Invalid array list, Lesser Count Stats than allocated stats - */ - err = rte_metrics_get_names(metrics, METRIC_LESSER_COUNT); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - return TEST_SUCCESS; -} - -/* Test to validate get list of metric values */ -static int -test_metrics_get_values(void) -{ - int i = 0; - int err = 0; - struct rte_metric_value getvalues[REG_METRIC_COUNT]; - - size_t m_size = sizeof(struct rte_metric_value); - for (i = 0; i < REG_METRIC_COUNT; i++) - memset(&getvalues[i], 0, m_size); - - /* Successful Test, Not update results: valid arguments - * count lessthan the memzone stats - */ - err = rte_metrics_get_values(RTE_METRICS_GLOBAL, getvalues, - METRIC_LESSER_COUNT); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Successful Test, update results: valid arguments */ - err = rte_metrics_get_values(RTE_METRICS_GLOBAL, getvalues, - REG_METRIC_COUNT); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Successful Test : valid arguments count greaterthan the - * memzone stats - */ - err = rte_metrics_get_values(RTE_METRICS_GLOBAL, getvalues, - REG_METRIC_COUNT+2); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - /* Failure Test: Invalid port_id(lower value) with correct values - * and Capacity - */ - err = rte_metrics_get_values(-2, getvalues, REG_METRIC_COUNT); - TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); - - /* Failure Test: Invalid port_id(higher value) with correct values - * and Capacity - */ - err = rte_metrics_get_values(33, getvalues, REG_METRIC_COUNT); - TEST_ASSERT(err == -EINVAL, "%s, %d", __func__, __LINE__); - - /* Successful Test: valid port_id with incorrect values and valid - * capacity - */ - err = rte_metrics_get_values(RTE_METRICS_GLOBAL, NULL, - REG_METRIC_COUNT); - TEST_ASSERT(err >= 0, "%s, %d", __func__, __LINE__); - - return TEST_SUCCESS; -} - -static struct unit_test_suite metrics_testsuite = { - .suite_name = "Metrics Unit Test Suite", - .setup = NULL, - .teardown = NULL, - .unit_test_cases = { - /* Test Case 1: Test to check all metric APIs without - * metrics init - */ - TEST_CASE(test_metrics_without_init), - - /* TEST CASE 2: Test to register valid metrics*/ - TEST_CASE_ST(test_metrics_init, NULL, - test_metrics_reg_name_with_validname), - - /* TEST CASE 3: Test to register list of metrics with valid - * names and valid count size, invalid names and invalid - * count size - */ - TEST_CASE(test_metrics_reg_names), - - /* TEST CASE 4: Test to register a update value with valid port - * id and invalid port id - */ - TEST_CASE(test_metrics_update_value), - - /* TEST CASE 5: Test to register update list of values with - * valid port id, key, value, count size and invalid port id, - * key, value, count size - */ - TEST_CASE(test_metrics_update_values), - - /* TEST CASE 6: Test to get metric names-key with valid - * array list, count size and invalid array list, count size - */ - TEST_CASE(test_metrics_get_names), - - /* TEST CASE 7: Test to get list of metric values with valid - * port id, array list, count size and invalid port id, - * arraylist, count size - */ - TEST_CASE(test_metrics_get_values), - TEST_CASES_END() - } -}; - -static int -test_metrics(void) -{ - return unit_test_suite_runner(&metrics_testsuite); -} - -REGISTER_TEST_COMMAND(metrics_autotest, test_metrics); diff --git a/test/test/test_mp_secondary.c b/test/test/test_mp_secondary.c deleted file mode 100644 index b597dfcdf1..0000000000 --- a/test/test/test_mp_secondary.c +++ /dev/null @@ -1,209 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 - -#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__) - -/* - * 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 - - 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) { - 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_pdump.c b/test/test/test_pdump.c deleted file mode 100644 index 4a894c0e1b..0000000000 --- a/test/test/test_pdump.c +++ /dev/null @@ -1,219 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ -#include -#include -#include -#include - -#include -#include -#include "rte_eal.h" -#include "rte_lcore.h" -#include "rte_mempool.h" -#include "rte_ring.h" - -#include "sample_packet_forward.h" -#include "test.h" -#include "process.h" -#include "test_pdump.h" - -#define launch_p(ARGV) process_dup(ARGV, \ - sizeof(ARGV)/(sizeof(ARGV[0])), __func__) - -struct rte_ring *ring_server; -uint16_t portid; -uint16_t flag_for_send_pkts = 1; - -int -test_pdump_init(void) -{ - int ret = 0; - - ret = rte_pdump_init(); - if (ret < 0) { - printf("rte_pdump_init failed\n"); - return -1; - } - ret = test_ring_setup(&ring_server, &portid); - if (ret < 0) { - printf("test_ring_setup failed\n"); - return -1; - } - printf("pdump_init success\n"); - return ret; -} - -int -run_pdump_client_tests(void) -{ - int flags = RTE_PDUMP_FLAG_TX, ret = 0, itr; - char deviceid[] = "net_ring_net_ringa"; - struct rte_ring *ring_client; - struct rte_mempool *mp = NULL; - struct rte_eth_dev *eth_dev = NULL; - char poolname[] = "mbuf_pool_client"; - - ret = test_get_mempool(&mp, poolname); - if (ret < 0) - return -1; - mp->flags = 0x0000; - ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(), - RING_F_SP_ENQ | RING_F_SC_DEQ); - if (ring_client == NULL) { - printf("rte_ring_create SR0 failed"); - return -1; - } - - eth_dev = rte_eth_dev_attach_secondary(deviceid); - if (!eth_dev) { - printf("Failed to probe %s", deviceid); - return -1; - } - rte_eth_dev_probing_finish(eth_dev); - - ring_client->prod.single = 0; - ring_client->cons.single = 0; - - printf("\n***** flags = RTE_PDUMP_FLAG_TX *****\n"); - - for (itr = 0; itr < NUM_ITR; itr++) { - ret = rte_pdump_enable(portid, QUEUE_ID, flags, ring_client, - mp, NULL); - if (ret < 0) { - printf("rte_pdump_enable failed\n"); - return -1; - } - printf("pdump_enable success\n"); - - ret = rte_pdump_disable(portid, QUEUE_ID, flags); - if (ret < 0) { - printf("rte_pdump_disable failed\n"); - return -1; - } - printf("pdump_disable success\n"); - - ret = rte_pdump_enable_by_deviceid(deviceid, QUEUE_ID, flags, - ring_client, mp, NULL); - if (ret < 0) { - printf("rte_pdump_enable_by_deviceid failed\n"); - return -1; - } - printf("pdump_enable_by_deviceid success\n"); - - ret = rte_pdump_disable_by_deviceid(deviceid, QUEUE_ID, flags); - if (ret < 0) { - printf("rte_pdump_disable_by_deviceid failed\n"); - return -1; - } - printf("pdump_disable_by_deviceid success\n"); - - if (itr == 0) { - flags = RTE_PDUMP_FLAG_RX; - printf("\n***** flags = RTE_PDUMP_FLAG_RX *****\n"); - } else if (itr == 1) { - flags = RTE_PDUMP_FLAG_RXTX; - printf("\n***** flags = RTE_PDUMP_FLAG_RXTX *****\n"); - } - } - if (ring_client != NULL) - test_ring_free(ring_client); - if (mp != NULL) - test_mp_free(mp); - - return ret; -} - -int -test_pdump_uninit(void) -{ - int ret = 0; - - ret = rte_pdump_uninit(); - if (ret < 0) { - printf("rte_pdump_uninit failed\n"); - return -1; - } - if (ring_server != NULL) - test_ring_free(ring_server); - printf("pdump_uninit success\n"); - test_vdev_uninit("net_ring_net_ringa"); - return ret; -} - -void * -send_pkts(void *empty) -{ - int ret = 0; - struct rte_mbuf *pbuf[NUM_PACKETS] = { }; - struct rte_mempool *mp; - char poolname[] = "mbuf_pool_server"; - - ret = test_get_mbuf_from_pool(&mp, pbuf, poolname); - if (ret < 0) - printf("get_mbuf_from_pool failed\n"); - do { - ret = test_packet_forward(pbuf, portid, QUEUE_ID); - if (ret < 0) - printf("send pkts Failed\n"); - } while (flag_for_send_pkts); - test_put_mbuf_to_pool(mp, pbuf); - return empty; -} - -/* - * 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 - */ - -int -run_pdump_server_tests(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 *const argv1[] = { - prgname, "-c", coremask, "--proc-type=secondary", - prefix - }; - - snprintf(coremask, sizeof(coremask), "%x", - (1 << rte_get_master_lcore())); - - ret = test_pdump_init(); - ret |= launch_p(argv1); - ret |= test_pdump_uninit(); - return ret; -} - -int -test_pdump(void) -{ - int ret = 0; - if (rte_eal_process_type() == RTE_PROC_PRIMARY) { - printf("IN PRIMARY PROCESS\n"); - ret = run_pdump_server_tests(); - if (ret < 0) - return TEST_FAILED; - } else if (rte_eal_process_type() == RTE_PROC_SECONDARY) { - printf("IN SECONDARY PROCESS\n"); - sleep(5); - ret = run_pdump_client_tests(); - if (ret < 0) - return TEST_FAILED; - } - return TEST_SUCCESS; -} - -REGISTER_TEST_COMMAND(pdump_autotest, test_pdump); diff --git a/test/test/test_pdump.h b/test/test/test_pdump.h deleted file mode 100644 index abef9a85ec..0000000000 --- a/test/test/test_pdump.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation - */ - -#ifndef _TEST_PDUMP_H_ -#define _TEST_PDUMP_H_ - -#define QUEUE_ID 0 -#define NUM_ITR 3 - -/* sample test to send packets to the pdump client recursively */ -void *send_pkts(void *port); - -/* Sample test to create setup for the pdump server tests */ -int test_pdump_init(void); - -/* Sample test to teardown the pdump server setup */ -int test_pdump_uninit(void); - -/* Sample test to run the pdump client tests */ -int run_pdump_client_tests(void); - -/* Sample test to run the pdump server tests */ -int run_pdump_server_tests(void); - -/* Sample test to run the pdump client and server tests based on - * the process type - */ -int test_pdump(void); - -#endif /* _TEST_PDUMP_H_ */ diff --git a/test/test/test_per_lcore.c b/test/test/test_per_lcore.c deleted file mode 100644 index 19b55f2642..0000000000 --- a/test/test/test_per_lcore.c +++ /dev/null @@ -1,108 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index ed8524a176..0000000000 --- a/test/test/test_pmd_perf.c +++ /dev/null @@ -1,870 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - - -#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 (1024) -#define RTE_TEST_TX_DESC_DEFAULT (1024) -#define RTE_PORT_ALL (~(uint16_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, - }, - .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 */ -}; - -enum { - LCORE_INVALID = 0, - LCORE_AVAIL, - LCORE_USED, -}; - -struct lcore_conf { - uint8_t status; - uint8_t socketid; - uint16_t nb_ports; - uint16_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(uint16_t port_num, uint32_t port_mask) -{ -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */ - uint16_t portid; - uint8_t 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", - portid, 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", 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; -} - -static volatile uint64_t stop; -static uint64_t count; -static uint64_t drop; -static uint64_t idle; - -static void -reset_count(void) -{ - count = 0; - drop = 0; - idle = 0; -} - -static void -stats_display(uint16_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(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(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(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 = 0; - uint64_t timeout = 10000; - do { /* dry out */ - nb_rx = rte_eth_rx_burst(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; - - if (unlikely(nb_rx == 0)) - timeout--; - } while (nb_free != pkt_per_port && timeout != 0); - printf("free %d (expected %d) mbuf left in port %u\n", nb_free, - 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; -} - -static 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; - int num[RTE_MAX_ETHPORTS]; - - 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; - num[portid] = 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(portid, 0, - &pkts_burst[next[portid]], - RTE_MIN(MAX_PKT_BURST, num[portid])); - if (unlikely(nb_rx == 0)) { - timeout--; - if (unlikely(timeout == 0)) - goto timeout; - continue; - } - next[portid] += nb_rx; - num[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 * conf->nb_ports; - - 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]; - nb_tx = 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_avail(); - 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; - RTE_ETH_FOREACH_DEV(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 */ - RTE_ETH_FOREACH_DEV(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.tx_rs_thresh = 32; - tx_conf.tx_free_thresh = 32; - return 0; - } else if (!strcmp(mode, "scalar")) { - /* bulk alloc rx, full-featured tx */ - tx_conf.tx_rs_thresh = 32; - tx_conf.tx_free_thresh = 32; - port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CHECKSUM; - 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.tx_rs_thresh = 32; - tx_conf.tx_free_thresh = 32; - port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CHECKSUM; - return 0; - } else if (!strcmp(mode, "full")) { - /* full feature rx,tx pair */ - tx_conf.tx_rs_thresh = 32; - tx_conf.tx_free_thresh = 32; - port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_SCATTER; - 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 deleted file mode 100644 index 6414bbd189..0000000000 --- a/test/test/test_pmd_ring.c +++ /dev/null @@ -1,566 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2015 Intel Corporation - */ -#include "test.h" -#include - -#include - -#include -#include -#include - -#define SOCKET0 0 -#define RING_SIZE 256 -#define NUM_RINGS 2 -#define NB_MBUF 512 - -static struct rte_mempool *mp; -struct rte_ring *rxtx[NUM_RINGS]; -static int tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte; - -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 TEST_FAILED; - } - - 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 TEST_FAILED; - } - - for (i = 0; i < RING_SIZE/2; i++) - if (pbufs[i] != &bufs[i]) { - printf("Error: received data does not match that transmitted\n"); - return TEST_FAILED; - } - - return TEST_SUCCESS; -} - -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(void) -{ - struct rte_eth_stats stats, stats2; - struct rte_mbuf buf, *pbuf = &buf; - struct rte_eth_conf null_conf; - - memset(&null_conf, 0, sizeof(struct rte_eth_conf)); - - if ((rte_eth_dev_configure(rxtx_portd, 1, 1, &null_conf) < 0) - || (rte_eth_dev_configure(rxtx_porte, 1, 1, - &null_conf) < 0)) { - printf("Configure failed for port\n"); - return TEST_FAILED; - } - - if ((rte_eth_tx_queue_setup(rxtx_portd, 0, RING_SIZE, - SOCKET0, NULL) < 0) - || (rte_eth_tx_queue_setup(rxtx_porte, 0, RING_SIZE, - SOCKET0, NULL) < 0)) { - printf("TX queue setup failed\n"); - return TEST_FAILED; - } - - if ((rte_eth_rx_queue_setup(rxtx_portd, 0, RING_SIZE, - SOCKET0, NULL, mp) < 0) - || (rte_eth_rx_queue_setup(rxtx_porte, 0, RING_SIZE, - SOCKET0, NULL, mp) < 0)) { - printf("RX queue setup failed\n"); - return TEST_FAILED; - } - - if ((rte_eth_dev_start(rxtx_portd) < 0) - || (rte_eth_dev_start(rxtx_porte) < 0)) { - printf("Error starting port\n"); - return TEST_FAILED; - } - - rte_eth_stats_reset(rxtx_portd); - /* check stats of port, should all be zero */ - rte_eth_stats_get(rxtx_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", rxtx_portd); - return TEST_FAILED; - } - - rte_eth_stats_reset(rxtx_porte); - /* check stats of port, should all be zero */ - rte_eth_stats_get(rxtx_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", rxtx_porte); - return TEST_FAILED; - } - - /* - * send and receive 1 packet (rxtx_portd -> rxtx_porte) - * and check for stats update - */ - printf("Testing send and receive 1 packet (rxtx_portd -> rxtx_porte)\n"); - if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", rxtx_portd); - return TEST_FAILED; - } - - if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", rxtx_porte); - return TEST_FAILED; - } - - rte_eth_stats_get(rxtx_portd, &stats); - rte_eth_stats_get(rxtx_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", - rxtx_portd); - return TEST_FAILED; - } - - 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", - rxtx_porte); - return TEST_FAILED; - } - - /* - * send and receive 1 packet (rxtx_porte -> rxtx_portd) - * and check for stats update - */ - printf("Testing send and receive 1 packet " - "(rxtx_porte -> rxtx_portd)\n"); - if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", rxtx_porte); - return TEST_FAILED; - } - - if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", rxtx_portd); - return TEST_FAILED; - } - - rte_eth_stats_get(rxtx_portd, &stats); - rte_eth_stats_get(rxtx_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", - rxtx_portd); - return TEST_FAILED; - } - - 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", - rxtx_porte); - return TEST_FAILED; - } - - /* - * send and receive 1 packet (rxtx_portd -> rxtx_portd) - * and check for stats update - */ - printf("Testing send and receive 1 packet " - "(rxtx_portd -> rxtx_portd)\n"); - if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", rxtx_portd); - return TEST_FAILED; - } - - if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", rxtx_porte); - return TEST_FAILED; - } - - rte_eth_stats_get(rxtx_portd, &stats); - rte_eth_stats_get(rxtx_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", - rxtx_portd); - return TEST_FAILED; - } - - 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", - rxtx_porte); - return TEST_FAILED; - } - - /* - * send and receive 1 packet (rxtx_porte -> rxtx_porte) - * and check for stats update - */ - printf("Testing send and receive 1 packet " - "(rxtx_porte -> rxtx_porte)\n"); - if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { - printf("Error sending packet to port %d\n", rxtx_porte); - return TEST_FAILED; - } - - if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { - printf("Error receiving packet from port %d\n", rxtx_porte); - return TEST_FAILED; - } - - rte_eth_stats_get(rxtx_portd, &stats); - rte_eth_stats_get(rxtx_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", - rxtx_portd); - return TEST_FAILED; - } - - 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", - rxtx_porte); - return TEST_FAILED; - } - - rte_eth_dev_stop(rxtx_portd); - rte_eth_dev_stop(rxtx_porte); - - return TEST_SUCCESS; -} - -static void -test_cleanup_resources(void) -{ - int itr; - for (itr = 0; itr < NUM_RINGS; itr++) - rte_ring_free(rxtx[itr]); - - rte_eth_dev_stop(tx_porta); - rte_eth_dev_stop(rx_portb); - rte_eth_dev_stop(rxtx_portc); - - rte_mempool_free(mp); - rte_vdev_uninit("net_ring_net_ringa"); - rte_vdev_uninit("net_ring_net_ringb"); - rte_vdev_uninit("net_ring_net_ringc"); - rte_vdev_uninit("net_ring_net_ringd"); - rte_vdev_uninit("net_ring_net_ringe"); -} - -static int -test_pmd_ringcreate_setup(void) -{ - uint8_t nb_ports; - - nb_ports = rte_eth_dev_count_avail(); - 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; - } - return 0; -} - -static int -test_command_line_ring_port(void) -{ - int port, cmdl_port0 = -1; - /* find a port created with the --vdev=net_ring0 command line option */ - RTE_ETH_FOREACH_DEV(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) { - TEST_ASSERT((test_ethdev_configure_port(cmdl_port0) < 0), - "test ethdev configure port cmdl_port0 is failed"); - TEST_ASSERT((test_send_basic_packets_port(cmdl_port0) < 0), - "test send basic packets port cmdl_port0 is failed"); - TEST_ASSERT((test_stats_reset(cmdl_port0) < 0), - "test stats reset cmdl_port0 is failed"); - TEST_ASSERT((test_get_stats(cmdl_port0) < 0), - "test get stats cmdl_port0 is failed"); - rte_eth_dev_stop(cmdl_port0); - } - return TEST_SUCCESS; -} - -static int -test_ethdev_configure_ports(void) -{ - TEST_ASSERT((test_ethdev_configure_port(tx_porta) == 0), - "test ethdev configure ports tx_porta is failed"); - TEST_ASSERT((test_ethdev_configure_port(rx_portb) == 0), - "test ethdev configure ports rx_portb is failed"); - TEST_ASSERT((test_ethdev_configure_port(rxtx_portc) == 0), - "test ethdev configure ports rxtx_portc is failed"); - - return TEST_SUCCESS; -} - -static int -test_get_stats_for_port(void) -{ - TEST_ASSERT(test_get_stats(rxtx_portc) == 0, "test get stats failed"); - return TEST_SUCCESS; -} - -static int -test_stats_reset_for_port(void) -{ - TEST_ASSERT(test_stats_reset(rxtx_portc) == 0, "test stats reset failed"); - return TEST_SUCCESS; -} - -static struct -unit_test_suite test_pmd_ring_suite = { - .setup = test_pmd_ringcreate_setup, - .teardown = test_cleanup_resources, - .suite_name = "Test Pmd Ring Unit Test Suite", - .unit_test_cases = { - TEST_CASE(test_ethdev_configure_ports), - TEST_CASE(test_send_basic_packets), - TEST_CASE(test_get_stats_for_port), - TEST_CASE(test_stats_reset_for_port), - TEST_CASE(test_pmd_ring_pair_create_attach), - TEST_CASE(test_command_line_ring_port), - TEST_CASES_END() - } -}; - -static int -test_pmd_ring(void) -{ - return unit_test_suite_runner(&test_pmd_ring_suite); -} - -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 deleted file mode 100644 index 6318da18f2..0000000000 --- a/test/test/test_pmd_ring_perf.c +++ /dev/null @@ -1,165 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015 Intel Corporation - */ - - -#include -#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 uint16_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], NULL); - 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, NULL); - rte_ring_dequeue_bulk(r, &burst, 1, NULL); - } - 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], NULL); - rte_ring_sc_dequeue_bulk(r, (void *)burst, - bulk_sizes[sz], NULL); - } - 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) -{ - char name[RTE_ETH_NAME_MAX_LEN]; - - 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(); - - /* release port and ring resources */ - rte_eth_dev_stop(ring_ethdev_port); - rte_eth_dev_get_name_by_port(ring_ethdev_port, name); - rte_vdev_uninit(name); - rte_ring_free(r); - 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 deleted file mode 100644 index a0ee219830..0000000000 --- a/test/test/test_power.c +++ /dev/null @@ -1,90 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include -#include -#include - -#include "test.h" - -#ifndef RTE_LIBRTE_POWER - -static int -test_power(void) -{ - printf("Power management library not supported, skipping test\n"); - return TEST_SKIPPED; -} - -#else - -#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; -} -#endif - -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 deleted file mode 100644 index 61b1da05ae..0000000000 --- a/test/test/test_power_acpi_cpufreq.c +++ /dev/null @@ -1,572 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include -#include -#include -#include - -#include "test.h" - -#ifndef RTE_LIBRTE_POWER - -static int -test_power_acpi_cpufreq(void) -{ - printf("Power management library not supported, skipping test\n"); - return TEST_SKIPPED; -} - -static int -test_power_acpi_caps(void) -{ - printf("Power management library not supported, skipping test\n"); - return TEST_SKIPPED; -} - -#else -#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/cpuinfo_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; - - /* 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 TEST_SKIPPED; - } - - /* Test environment configuration */ - env = rte_power_get_env(); - if ((env != PM_ENV_ACPI_CPUFREQ) && (env != PM_ENV_PSTATE_CPUFREQ)) { - printf("Unexpectedly got an environment other than ACPI/PSTATE\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; - } - - 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 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 TEST_SKIPPED; - } - - /** - * 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; -} - -static int -test_power_acpi_caps(void) -{ - struct rte_power_core_capabilities caps; - int ret; - - 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; - } - - ret = rte_power_get_capabilities(TEST_POWER_LCORE_ID, &caps); - if (ret) { - printf("POWER: Error getting capabilities\n"); - return -1; - } - - printf("POWER: Capabilities %"PRIx64"\n", caps.capabilities); - - rte_power_unset_env(); - return 0; -} - -#endif - -REGISTER_TEST_COMMAND(power_acpi_cpufreq_autotest, test_power_acpi_cpufreq); -REGISTER_TEST_COMMAND(power_acpi_caps_autotest, test_power_acpi_caps); diff --git a/test/test/test_power_kvm_vm.c b/test/test/test_power_kvm_vm.c deleted file mode 100644 index 785cd048df..0000000000 --- a/test/test/test_power_kvm_vm.c +++ /dev/null @@ -1,302 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2018 Intel Corporation - */ - -#include -#include -#include -#include -#include - -#include "test.h" - -#ifndef RTE_LIBRTE_POWER - -static int -test_power_kvm_vm(void) -{ - printf("Power management library not supported, skipping test\n"); - return TEST_SKIPPED; -} - -#else -#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 TEST_SKIPPED; - } - - /* 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 KVM_VM Enable Turbo of valid core */ - ret = rte_power_freq_enable_turbo(TEST_POWER_VM_LCORE_ID); - if (ret == -1) { - printf("rte_power_freq_enable_turbo failed on valid lcore" - "%u\n", TEST_POWER_VM_LCORE_ID); - goto fail_all; - } - - /* Test KVM_VM Disable Turbo of valid core */ - ret = rte_power_freq_disable_turbo(TEST_POWER_VM_LCORE_ID); - if (ret == -1) { - printf("rte_power_freq_disable_turbo failed on valid lcore" - "%u\n", TEST_POWER_VM_LCORE_ID); - 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; -} -#endif - -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 deleted file mode 100644 index 41f219af78..0000000000 --- a/test/test/test_prefetch.c +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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_rawdev.c b/test/test/test_rawdev.c deleted file mode 100644 index 043a38a13f..0000000000 --- a/test/test/test_rawdev.c +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2017 NXP - */ -#include -#include -#include -#include -#include -#include -#include - -#include "test.h" - -static int -test_rawdev_selftest_impl(const char *pmd, const char *opts) -{ - rte_vdev_init(pmd, opts); - return rte_rawdev_selftest(rte_rawdev_get_dev_id(pmd)); -} - -static int -test_rawdev_selftest_skeleton(void) -{ - return test_rawdev_selftest_impl("rawdev_skeleton", ""); -} - -REGISTER_TEST_COMMAND(rawdev_autotest, test_rawdev_selftest_skeleton); diff --git a/test/test/test_reciprocal_division.c b/test/test/test_reciprocal_division.c deleted file mode 100644 index 8ea9b1d24d..0000000000 --- a/test/test/test_reciprocal_division.c +++ /dev/null @@ -1,167 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Cavium, Inc - */ - -#include "test.h" - -#include -#include -#include - -#include -#include -#include -#include - -#define MAX_ITERATIONS (1ULL << 32) -#define DIVIDE_ITER (100) - -static int -test_reciprocal(void) -{ - int result = 0; - uint32_t divisor_u32 = 0; - uint32_t dividend_u32; - uint32_t nresult_u32; - uint32_t rresult_u32; - uint64_t i, j; - uint64_t divisor_u64 = 0; - uint64_t dividend_u64; - uint64_t nresult_u64; - uint64_t rresult_u64; - struct rte_reciprocal reci_u32 = {0}; - struct rte_reciprocal_u64 reci_u64 = {0}; - - rte_srand(rte_rdtsc()); - printf("Validating unsigned 32bit division.\n"); - for (i = 0; i < MAX_ITERATIONS; i++) { - /* Change divisor every DIVIDE_ITER iterations. */ - if (i % DIVIDE_ITER == 0) { - divisor_u32 = rte_rand(); - reci_u32 = rte_reciprocal_value(divisor_u32); - } - - dividend_u32 = rte_rand(); - nresult_u32 = dividend_u32 / divisor_u32; - rresult_u32 = rte_reciprocal_divide(dividend_u32, - reci_u32); - if (nresult_u32 != rresult_u32) { - printf("Division failed, %"PRIu32"/%"PRIu32" = " - "expected %"PRIu32" result %"PRIu32"\n", - dividend_u32, divisor_u32, - nresult_u32, rresult_u32); - result = 1; - break; - } - } - - printf("Validating unsigned 64bit division.\n"); - for (i = 0; i < MAX_ITERATIONS; i++) { - /* Change divisor every DIVIDE_ITER iterations. */ - if (i % DIVIDE_ITER == 0) { - divisor_u64 = rte_rand(); - reci_u64 = rte_reciprocal_value_u64(divisor_u64); - } - - dividend_u64 = rte_rand(); - nresult_u64 = dividend_u64 / divisor_u64; - rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, - &reci_u64); - if (nresult_u64 != rresult_u64) { - printf("Division failed, %"PRIu64"/%"PRIu64" = " - "expected %"PRIu64" result %"PRIu64"\n", - dividend_u64, divisor_u64, - nresult_u64, rresult_u64); - result = 1; - break; - } - } - - printf("Validating unsigned 64bit division with 32bit divisor.\n"); - for (i = 0; i < MAX_ITERATIONS; i++) { - /* Change divisor every DIVIDE_ITER iterations. */ - if (i % DIVIDE_ITER == 0) { - divisor_u64 = rte_rand() >> 32; - reci_u64 = rte_reciprocal_value_u64(divisor_u64); - } - - dividend_u64 = rte_rand(); - - nresult_u64 = dividend_u64 / divisor_u64; - rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, - &reci_u64); - - if (nresult_u64 != rresult_u64) { - printf("Division failed, %"PRIu64"/%"PRIu64" = " - "expected %"PRIu64" result %"PRIu64"\n", - dividend_u64, divisor_u64, - nresult_u64, rresult_u64); - result = 1; - break; - } - } - - printf("Validating division by power of 2.\n"); - for (i = 0; i < 32; i++) { - divisor_u64 = 1ull << i; - reci_u64 = rte_reciprocal_value_u64(divisor_u64); - reci_u32 = rte_reciprocal_value((uint32_t)divisor_u64); - - for (j = 0; j < MAX_ITERATIONS >> 4; j++) { - dividend_u64 = rte_rand(); - - nresult_u64 = dividend_u64 / divisor_u64; - rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, - &reci_u64); - - if (nresult_u64 != rresult_u64) { - printf( - "Division 64 failed, %"PRIu64"/%"PRIu64" = " - "expected %"PRIu64" result %"PRIu64"\n", - dividend_u64, divisor_u64, - nresult_u64, rresult_u64); - result = 1; - } - - nresult_u32 = (dividend_u64 >> 32) / divisor_u64; - rresult_u32 = rte_reciprocal_divide( - (dividend_u64 >> 32), reci_u32); - - if (nresult_u32 != rresult_u32) { - printf( - "Division 32 failed, %"PRIu64"/%"PRIu64" = " - "expected %"PRIu64" result %"PRIu64"\n", - dividend_u64 >> 32, divisor_u64, - nresult_u64, rresult_u64); - result = 1; - break; - } - } - } - - for (; i < 64; i++) { - divisor_u64 = 1ull << i; - reci_u64 = rte_reciprocal_value_u64(divisor_u64); - - for (j = 0; j < MAX_ITERATIONS >> 4; j++) { - dividend_u64 = rte_rand(); - - nresult_u64 = dividend_u64 / divisor_u64; - rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, - &reci_u64); - - if (nresult_u64 != rresult_u64) { - printf("Division failed, %"PRIu64"/%"PRIu64" = " - "expected %"PRIu64" result %"PRIu64"\n", - dividend_u64, divisor_u64, - nresult_u64, rresult_u64); - result = 1; - break; - } - } - } - - return result; -} - -REGISTER_TEST_COMMAND(reciprocal_division, test_reciprocal); diff --git a/test/test/test_reciprocal_division_perf.c b/test/test/test_reciprocal_division_perf.c deleted file mode 100644 index a7be8aa71a..0000000000 --- a/test/test/test_reciprocal_division_perf.c +++ /dev/null @@ -1,201 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Cavium, Inc - */ - -#include "test.h" - -#include -#include -#include - -#include -#include -#include -#include - -#define MAX_ITERATIONS (1ULL << 32) -#define DIVIDE_ITER (1ULL << 28) - -static int -test_reciprocal_division_perf(void) -{ - int result = 0; - uint32_t divisor_u32 = 0; - uint32_t dividend_u32; - uint64_t divisor_u64 = 0; - uint64_t dividend_u64; - volatile uint32_t nresult_u32; - volatile uint32_t rresult_u32; - volatile uint64_t nresult_u64; - volatile uint64_t rresult_u64; - uint64_t start_cyc; - uint64_t split_cyc; - uint64_t end_cyc; - uint64_t tot_cyc_n = 0; - uint64_t tot_cyc_r = 0; - uint64_t i; - struct rte_reciprocal reci_u32 = {0}; - struct rte_reciprocal_u64 reci_u64 = {0}; - - rte_srand(rte_rdtsc()); - - printf("Validating unsigned 32bit division.\n"); - for (i = 0; i < MAX_ITERATIONS; i++) { - /* Change divisor every DIVIDE_ITER iterations. */ - if (i % DIVIDE_ITER == 0) { - divisor_u32 = rte_rand(); - reci_u32 = rte_reciprocal_value(divisor_u32); - } - - dividend_u32 = rte_rand(); - - start_cyc = rte_rdtsc(); - nresult_u32 = dividend_u32 / divisor_u32; - split_cyc = rte_rdtsc(); - rresult_u32 = rte_reciprocal_divide(dividend_u32, - reci_u32); - end_cyc = rte_rdtsc(); - - tot_cyc_n += split_cyc - start_cyc; - tot_cyc_r += end_cyc - split_cyc; - if (nresult_u32 != rresult_u32) { - printf("Division failed, expected %"PRIu32" " - "result %"PRIu32"", - nresult_u32, rresult_u32); - result = 1; - break; - } - } - printf("32bit Division results:\n"); - printf("Total number of cycles normal division : %"PRIu64"\n", - tot_cyc_n); - printf("Total number of cycles reciprocal division : %"PRIu64"\n", - tot_cyc_r); - printf("Cycles per division(normal) : %3.2f\n", - ((double)tot_cyc_n)/i); - printf("Cycles per division(reciprocal) : %3.2f\n\n", - ((double)tot_cyc_r)/i); - - tot_cyc_n = 0; - tot_cyc_r = 0; - - printf("Validating unsigned 64bit division.\n"); - for (i = 0; i < MAX_ITERATIONS; i++) { - /* Change divisor every DIVIDE_ITER iterations. */ - if (i % DIVIDE_ITER == 0) { - divisor_u64 = rte_rand(); - reci_u64 = rte_reciprocal_value_u64(divisor_u64); - } - - dividend_u64 = rte_rand(); - - start_cyc = rte_rdtsc(); - nresult_u64 = dividend_u64 / divisor_u64; - split_cyc = rte_rdtsc(); - rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, - &reci_u64); - end_cyc = rte_rdtsc(); - - tot_cyc_n += split_cyc - start_cyc; - tot_cyc_r += end_cyc - split_cyc; - if (nresult_u64 != rresult_u64) { - printf("Division failed, expected %"PRIu64" " - "result %"PRIu64"", - nresult_u64, rresult_u64); - result = 1; - break; - } - } - printf("64bit Division results:\n"); - printf("Total number of cycles normal division : %"PRIu64"\n", - tot_cyc_n); - printf("Total number of cycles reciprocal division : %"PRIu64"\n", - tot_cyc_r); - printf("Cycles per division(normal) : %3.2f\n", - ((double)tot_cyc_n)/i); - printf("Cycles per division(reciprocal) : %3.2f\n\n", - ((double)tot_cyc_r)/i); - - tot_cyc_n = 0; - tot_cyc_r = 0; - - printf("Validating unsigned 64bit division with 32bit divisor.\n"); - for (i = 0; i < MAX_ITERATIONS; i++) { - /* Change divisor every DIVIDE_ITER iterations. */ - if (i % DIVIDE_ITER == 0) { - divisor_u64 = rte_rand() >> 32; - reci_u64 = rte_reciprocal_value_u64(divisor_u64); - } - - dividend_u64 = rte_rand(); - - start_cyc = rte_rdtsc(); - nresult_u64 = dividend_u64 / divisor_u64; - split_cyc = rte_rdtsc(); - rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, - &reci_u64); - end_cyc = rte_rdtsc(); - - tot_cyc_n += split_cyc - start_cyc; - tot_cyc_r += end_cyc - split_cyc; - if (nresult_u64 != rresult_u64) { - printf("Division failed, expected %"PRIu64" " - "result %"PRIu64"", - nresult_u64, rresult_u64); - result = 1; - break; - } - } - - printf("64bit Division results:\n"); - printf("Total number of cycles normal division : %"PRIu64"\n", - tot_cyc_n); - printf("Total number of cycles reciprocal division : %"PRIu64"\n", - tot_cyc_r); - printf("Cycles per division(normal) : %3.2f\n", - ((double)tot_cyc_n)/i); - printf("Cycles per division(reciprocal) : %3.2f\n\n", - ((double)tot_cyc_r)/i); - - tot_cyc_n = 0; - tot_cyc_r = 0; - - printf("Validating division by power of 2.\n"); - for (i = 0; i < 64; i++) { - divisor_u64 = 1ull << i; - reci_u64 = rte_reciprocal_value_u64(divisor_u64); - - dividend_u64 = rte_rand(); - - start_cyc = rte_rdtsc(); - nresult_u64 = dividend_u64 / divisor_u64; - split_cyc = rte_rdtsc(); - rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, - &reci_u64); - end_cyc = rte_rdtsc(); - - tot_cyc_n += split_cyc - start_cyc; - tot_cyc_r += end_cyc - split_cyc; - if (nresult_u64 != rresult_u64) { - printf("Division 64 failed, %"PRIu64"/%"PRIu64" = " - "expected %"PRIu64" result %"PRIu64"\n", - dividend_u64, divisor_u64, - nresult_u64, rresult_u64); - result = 1; - break; - } - } - printf("64bit Division results:\n"); - printf("Total number of cycles normal division : %"PRIu64"\n", - tot_cyc_n); - printf("Total number of cycles reciprocal division : %"PRIu64"\n", - tot_cyc_r); - printf("Cycles per division(normal) : %3.2f\n", - ((double)tot_cyc_n)/i); - printf("Cycles per division(reciprocal) : %3.2f\n", - ((double)tot_cyc_r)/i); - - return result; -} - -REGISTER_TEST_COMMAND(reciprocal_division_perf, test_reciprocal_division_perf); diff --git a/test/test/test_red.c b/test/test/test_red.c deleted file mode 100644 index e973f3131e..0000000000 --- a/test/test/test_red.c +++ /dev/null @@ -1,1856 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 58fa9c71b5..0000000000 --- a/test/test/test_reorder.c +++ /dev/null @@ -1,393 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#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"); - - for (i = 0; i < num_bufs; i++) { - bufs[i] = rte_pktmbuf_alloc(p); - TEST_ASSERT_NOT_NULL(bufs[i], "Packet allocation failed\n"); - 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; - } - bufs[i] = NULL; - } - - /* 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; - } - bufs[4] = NULL; - - /* 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; - } - bufs[5] = NULL; - - /* 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; - } - bufs[6] = NULL; - - ret = 0; -exit: - rte_reorder_free(b); - for (i = 0; i < num_bufs; i++) { - if (bufs[i] != NULL) - rte_pktmbuf_free(bufs[i]); - } - 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; - - /* initialize all robufs to NULL */ - for (i = 0; i < num_bufs; i++) - robufs[i] = NULL; - - /* 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"); - - /* 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] = rte_pktmbuf_alloc(p); - TEST_ASSERT_NOT_NULL(bufs[i], "Packet allocation failed\n"); - 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]); - bufs[1] = NULL; - - 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; - } - if (robufs[0] != NULL) - rte_pktmbuf_free(robufs[0]); - - /* 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]); - bufs[2] = NULL; - bufs[3] = NULL; - - /* Insert more packets - * RB[] = {NULL, NULL, NULL, NULL} - * OB[] = {NULL, 2, 3, 4} - */ - rte_reorder_insert(b, bufs[4]); - bufs[4] = NULL; - - /* Insert more packets - * RB[] = {2, 3, 4, NULL} - * OB[] = {NULL, NULL, 7, NULL} - */ - rte_reorder_insert(b, bufs[7]); - bufs[7] = NULL; - - /* 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; - } - for (i = 0; i < 3; i++) { - if (robufs[i] != NULL) - rte_pktmbuf_free(robufs[i]); - } - - /* - * 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_reorder_free(b); - for (i = 0; i < num_bufs; i++) { - if (bufs[i] != NULL) - rte_pktmbuf_free(bufs[i]); - if (robufs[i] != NULL) - rte_pktmbuf_free(robufs[i]); - } - 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 void -test_teardown(void) -{ - rte_reorder_free(test_params->b); - test_params->b = NULL; - rte_mempool_free(test_params->p); - test_params->p = NULL; -} - - -static struct unit_test_suite reorder_test_suite = { - - .setup = test_setup, - .teardown = test_teardown, - .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 deleted file mode 100644 index 8f41e3babd..0000000000 --- a/test/test/test_resource.c +++ /dev/null @@ -1,104 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2016 RehiveTech. All rights reserved. - */ - -#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 deleted file mode 100644 index aaf1e70ad8..0000000000 --- a/test/test/test_ring.c +++ /dev/null @@ -1,876 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 - * - * #. Performance tests. - * - * Tests done in test_ring_perf.c - */ - -#define RING_SIZE 4096 -#define MAX_BULK 32 - -static rte_atomic32_t synchro; - -#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 - -/* - * helper routine for test_ring_basic - */ -static int -test_ring_basic_full_empty(struct rte_ring *r, 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(rte_ring_enqueue_bulk(r, src, rand, - NULL) != 0); - TEST_RING_VERIFY(rte_ring_dequeue_bulk(r, dst, rand, - NULL) == rand); - - /* fill the ring */ - TEST_RING_VERIFY(rte_ring_enqueue_bulk(r, src, rsz, NULL) != 0); - 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(rte_ring_dequeue_bulk(r, dst, rsz, - NULL) == 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(struct rte_ring *r) -{ - 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, NULL); - cur_src += 1; - if (ret == 0) - goto fail; - - printf("enqueue 2 objs\n"); - ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2, NULL); - 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, NULL); - cur_src += MAX_BULK; - if (ret == 0) - goto fail; - - printf("dequeue 1 obj\n"); - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1, NULL); - cur_dst += 1; - if (ret == 0) - goto fail; - - printf("dequeue 2 objs\n"); - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2, NULL); - 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, NULL); - 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, NULL); - cur_src += 1; - if (ret == 0) - goto fail; - - printf("enqueue 2 objs\n"); - ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2, NULL); - 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, NULL); - cur_src += MAX_BULK; - if (ret == 0) - goto fail; - - printf("dequeue 1 obj\n"); - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1, NULL); - cur_dst += 1; - if (ret == 0) - goto fail; - - printf("dequeue 2 objs\n"); - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2, NULL); - 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, NULL); - 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; i= rte_ring_get_size(exact_sz_ring)) { - printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n", - __func__, - rte_ring_get_size(std_ring), - rte_ring_get_size(exact_sz_ring)); - goto end; - } - /* - * check that the exact_sz_ring can hold one more element than the - * standard ring. (16 vs 15 elements) - */ - for (i = 0; i < ring_sz - 1; i++) { - rte_ring_enqueue(std_ring, NULL); - rte_ring_enqueue(exact_sz_ring, NULL); - } - if (rte_ring_enqueue(std_ring, NULL) != -ENOBUFS) { - printf("%s: error, unexpected successful enqueue\n", __func__); - goto end; - } - if (rte_ring_enqueue(exact_sz_ring, NULL) == -ENOBUFS) { - printf("%s: error, enqueue failed\n", __func__); - goto end; - } - - /* check that dequeue returns the expected number of elements */ - if (rte_ring_dequeue_burst(exact_sz_ring, ptr_array, - RTE_DIM(ptr_array), NULL) != ring_sz) { - printf("%s: error, failed to dequeue expected nb of elements\n", - __func__); - goto end; - } - - /* check that the capacity function returns expected value */ - if (rte_ring_get_capacity(exact_sz_ring) != ring_sz) { - printf("%s: error, incorrect ring capacity reported\n", - __func__); - goto end; - } - - ret = 0; /* all ok if we get here */ -end: - rte_ring_free(std_ring); - rte_ring_free(exact_sz_ring); - return ret; -} - -static int -test_ring(void) -{ - struct rte_ring *r = NULL; - - /* some more basic operations */ - if (test_ring_basic_ex() < 0) - goto test_fail; - - rte_atomic32_init(&synchro); - - r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0); - if (r == NULL) - goto test_fail; - - /* retrieve the ring from its name */ - if (rte_ring_lookup("test") != r) { - printf("Cannot lookup ring from its name\n"); - goto test_fail; - } - - /* burst operations */ - if (test_ring_burst_basic(r) < 0) - goto test_fail; - - /* basic operations */ - if (test_ring_basic(r) < 0) - goto test_fail; - - /* basic operations */ - if ( test_create_count_odd() < 0){ - printf("Test failed to detect odd count\n"); - goto test_fail; - } else - printf("Test detected odd count\n"); - - if ( test_lookup_null() < 0){ - printf("Test failed to detect NULL ring lookup\n"); - goto test_fail; - } else - printf("Test detected NULL ring lookup\n"); - - /* test of creating ring with wrong size */ - if (test_ring_creation_with_wrong_size() < 0) - goto test_fail; - - /* test of creation ring with an used name */ - if (test_ring_creation_with_an_used_name() < 0) - goto test_fail; - - if (test_ring_with_exact_size() < 0) - goto test_fail; - - /* dump the ring status */ - rte_ring_list_dump(stdout); - - rte_ring_free(r); - - return 0; - -test_fail: - rte_ring_free(r); - - return -1; -} - -REGISTER_TEST_COMMAND(ring_autotest, test_ring); diff --git a/test/test/test_ring_perf.c b/test/test/test_ring_perf.c deleted file mode 100644 index ebb3939f51..0000000000 --- a/test/test/test_ring_perf.c +++ /dev/null @@ -1,401 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - - -#include -#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 }; - -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(struct rte_ring *r) -{ - const unsigned iter_shift = 26; - const unsigned iterations = 1<r; - const unsigned size = params->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, NULL) == 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, NULL) == 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<r; - const unsigned size = params->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, NULL) == 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, NULL) == 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, struct rte_ring *r, - 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]; - param1.r = param2.r = r; - 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(struct rte_ring *r) -{ - 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(struct rte_ring *r) -{ - 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(struct rte_ring *r) -{ - 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 - * =========== - * Provides UT for rte_rwlock API. - * Main concern is on functional testing, but also provides some - * performance measurements. - * Obviously for proper testing need to be executed with more than one lcore. - */ - -#define ITER_NUM 0x80 - -#define TEST_SEC 5 - -static rte_rwlock_t sl; -static rte_rwlock_t sl_tab[RTE_MAX_LCORE]; - -enum { - LC_TYPE_RDLOCK, - LC_TYPE_WRLOCK, -}; - -static struct { - rte_rwlock_t lock; - uint64_t tick; - volatile union { - uint8_t u8[RTE_CACHE_LINE_SIZE]; - uint64_t u64[RTE_CACHE_LINE_SIZE / sizeof(uint64_t)]; - } data; -} __rte_cache_aligned try_rwlock_data; - -struct try_rwlock_lcore { - int32_t rc; - int32_t type; - struct { - uint64_t tick; - uint64_t fail; - uint64_t success; - } stat; -} __rte_cache_aligned; - -static struct try_rwlock_lcore try_lcore_data[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; -} - -/* - * - 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 int -rwlock_test1(void) -{ - int i; - - rte_rwlock_init(&sl); - for (i=0; itype = LC_TYPE_RDLOCK; - - ftm = try_rwlock_data.tick; - stm = rte_get_timer_cycles(); - - do { - for (i = 0; i != ITER_NUM; i++) { - rc = try_read(lc); - if (rc == 0) - lcd->stat.success++; - else if (rc == -EBUSY) - lcd->stat.fail++; - else - break; - rc = 0; - } - tm = rte_get_timer_cycles() - stm; - } while (tm < ftm && rc == 0); - - lcd->rc = rc; - lcd->stat.tick = tm; - return rc; -} - -static int -try_write_lcore(__rte_unused void *data) -{ - int32_t rc; - uint32_t i, lc; - uint64_t ftm, stm, tm; - struct try_rwlock_lcore *lcd; - - lc = rte_lcore_id(); - lcd = try_lcore_data + lc; - lcd->type = LC_TYPE_WRLOCK; - - ftm = try_rwlock_data.tick; - stm = rte_get_timer_cycles(); - - do { - for (i = 0; i != ITER_NUM; i++) { - rc = try_write(lc); - if (rc == 0) - lcd->stat.success++; - else if (rc == -EBUSY) - lcd->stat.fail++; - else - break; - rc = 0; - } - tm = rte_get_timer_cycles() - stm; - } while (tm < ftm && rc == 0); - - lcd->rc = rc; - lcd->stat.tick = tm; - return rc; -} - -static void -print_try_lcore_stats(const struct try_rwlock_lcore *tlc, uint32_t lc) -{ - uint64_t f, s; - - f = RTE_MAX(tlc->stat.fail, 1ULL); - s = RTE_MAX(tlc->stat.success, 1ULL); - - printf("try_lcore_data[%u]={\n" - "\trc=%d,\n" - "\ttype=%s,\n" - "\tfail=%" PRIu64 ",\n" - "\tsuccess=%" PRIu64 ",\n" - "\tcycles=%" PRIu64 ",\n" - "\tcycles/op=%#Lf,\n" - "\tcycles/success=%#Lf,\n" - "\tsuccess/fail=%#Lf,\n" - "};\n", - lc, - tlc->rc, - tlc->type == LC_TYPE_RDLOCK ? "RDLOCK" : "WRLOCK", - tlc->stat.fail, - tlc->stat.success, - tlc->stat.tick, - (long double)tlc->stat.tick / - (tlc->stat.fail + tlc->stat.success), - (long double)tlc->stat.tick / s, - (long double)tlc->stat.success / f); -} - -static void -collect_try_lcore_stats(struct try_rwlock_lcore *tlc, - const struct try_rwlock_lcore *lc) -{ - tlc->stat.tick += lc->stat.tick; - tlc->stat.fail += lc->stat.fail; - tlc->stat.success += lc->stat.success; -} - -/* - * Process collected results: - * - check status - * - collect and print statistics - */ -static int -process_try_lcore_stats(void) -{ - int32_t rc; - uint32_t lc, rd, wr; - struct try_rwlock_lcore rlc, wlc; - - memset(&rlc, 0, sizeof(rlc)); - memset(&wlc, 0, sizeof(wlc)); - - rlc.type = LC_TYPE_RDLOCK; - wlc.type = LC_TYPE_WRLOCK; - rd = 0; - wr = 0; - - rc = 0; - RTE_LCORE_FOREACH(lc) { - rc |= try_lcore_data[lc].rc; - if (try_lcore_data[lc].type == LC_TYPE_RDLOCK) { - collect_try_lcore_stats(&rlc, try_lcore_data + lc); - rd++; - } else { - collect_try_lcore_stats(&wlc, try_lcore_data + lc); - wr++; - } - } - - if (rc == 0) { - RTE_LCORE_FOREACH(lc) - print_try_lcore_stats(try_lcore_data + lc, lc); - - if (rd != 0) { - printf("aggregated stats for %u RDLOCK cores:\n", rd); - print_try_lcore_stats(&rlc, rd); - } - - if (wr != 0) { - printf("aggregated stats for %u WRLOCK cores:\n", wr); - print_try_lcore_stats(&wlc, wr); - } - } - - return rc; -} - -static void -try_test_reset(void) -{ - memset(&try_lcore_data, 0, sizeof(try_lcore_data)); - memset(&try_rwlock_data, 0, sizeof(try_rwlock_data)); - try_rwlock_data.tick = TEST_SEC * rte_get_tsc_hz(); -} - -/* all lcores grab RDLOCK */ -static int -try_rwlock_test_rda(void) -{ - try_test_reset(); - - /* start read test on all avaialble lcores */ - rte_eal_mp_remote_launch(try_read_lcore, NULL, CALL_MASTER); - rte_eal_mp_wait_lcore(); - - return process_try_lcore_stats(); -} - -/* all slave lcores grab RDLOCK, master one grabs WRLOCK */ -static int -try_rwlock_test_rds_wrm(void) -{ - try_test_reset(); - - rte_eal_mp_remote_launch(try_read_lcore, NULL, SKIP_MASTER); - try_write_lcore(NULL); - rte_eal_mp_wait_lcore(); - - return process_try_lcore_stats(); -} - -/* master and even slave lcores grab RDLOCK, odd lcores grab WRLOCK */ -static int -try_rwlock_test_rde_wro(void) -{ - uint32_t lc, mlc; - - try_test_reset(); - - mlc = rte_get_master_lcore(); - - RTE_LCORE_FOREACH(lc) { - if (lc != mlc) { - if ((lc & 1) == 0) - rte_eal_remote_launch(try_read_lcore, - NULL, lc); - else - rte_eal_remote_launch(try_write_lcore, - NULL, lc); - } - } - try_read_lcore(NULL); - rte_eal_mp_wait_lcore(); - - return process_try_lcore_stats(); -} - -static int -test_rwlock(void) -{ - uint32_t i; - int32_t rc, ret; - - static const struct { - const char *name; - int (*ftst)(void); - } test[] = { - { - .name = "rwlock_test1", - .ftst = rwlock_test1, - }, - { - .name = "try_rwlock_test_rda", - .ftst = try_rwlock_test_rda, - }, - { - .name = "try_rwlock_test_rds_wrm", - .ftst = try_rwlock_test_rds_wrm, - }, - { - .name = "try_rwlock_test_rde_wro", - .ftst = try_rwlock_test_rde_wro, - }, - }; - - ret = 0; - for (i = 0; i != RTE_DIM(test); i++) { - printf("starting test %s;\n", test[i].name); - rc = test[i].ftst(); - printf("test %s completed with status %d\n", test[i].name, rc); - ret |= rc; - } - - return ret; -} - -REGISTER_TEST_COMMAND(rwlock_autotest, test_rwlock); diff --git a/test/test/test_sched.c b/test/test/test_sched.c deleted file mode 100644 index 40e411cabe..0000000000 --- a/test/test/test_sched.c +++ /dev/null @@ -1,188 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#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_sched_port *port, 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(port, 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(port, 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(port, 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_service_cores.c b/test/test/test_service_cores.c deleted file mode 100644 index ec31882d99..0000000000 --- a/test/test/test_service_cores.c +++ /dev/null @@ -1,919 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2017 Intel Corporation - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "test.h" - -/* used as the service core ID */ -static uint32_t slcore_id; -/* used as timestamp to detect if a service core is running */ -static uint64_t service_tick; -/* used as a flag to check if a function was run */ -static uint32_t service_remote_launch_flag; - -#define SERVICE_DELAY 1 - -#define DUMMY_SERVICE_NAME "dummy_service" -#define MT_SAFE_SERVICE_NAME "mt_safe_service" - -static int -testsuite_setup(void) -{ - slcore_id = rte_get_next_lcore(/* start core */ -1, - /* skip master */ 1, - /* wrap */ 0); - - return TEST_SUCCESS; -} - -static void -testsuite_teardown(void) -{ - /* release service cores? */ -} - -static int32_t dummy_cb(void *args) -{ - RTE_SET_USED(args); - service_tick++; - rte_delay_ms(SERVICE_DELAY); - return 0; -} - -static int32_t dummy_mt_unsafe_cb(void *args) -{ - /* before running test, the initialization has set pass_test to 1. - * If the cmpset in service-cores is working correctly, the code here - * should never fail to take the lock. If the lock *is* taken, fail the - * test, because two threads are concurrently in a non-MT safe callback. - */ - uint32_t *test_params = args; - uint32_t *atomic_lock = &test_params[0]; - uint32_t *pass_test = &test_params[1]; - int lock_taken = rte_atomic32_cmpset(atomic_lock, 0, 1); - if (lock_taken) { - /* delay with the lock held */ - rte_delay_ms(250); - rte_atomic32_clear((rte_atomic32_t *)atomic_lock); - } else { - /* 2nd thread will fail to take lock, so set pass flag */ - *pass_test = 0; - } - - return 0; -} - - -static int32_t dummy_mt_safe_cb(void *args) -{ - /* Atomic checks to ensure MT safe services allow > 1 thread to - * concurrently run the callback. The concept is as follows; - * 1) if lock is available, take the lock then delay - * 2) if first lock is taken, and a thread arrives in the CB, we know - * that 2 threads are running the callback at the same time: MT safe - */ - uint32_t *test_params = args; - uint32_t *atomic_lock = &test_params[0]; - uint32_t *pass_test = &test_params[1]; - int lock_taken = rte_atomic32_cmpset(atomic_lock, 0, 1); - if (lock_taken) { - /* delay with the lock held */ - rte_delay_ms(250); - rte_atomic32_clear((rte_atomic32_t *)atomic_lock); - } else { - /* 2nd thread will fail to take lock, so set pass flag */ - *pass_test = 1; - } - - return 0; -} - -/* unregister all services */ -static int -unregister_all(void) -{ - uint32_t i; - - TEST_ASSERT_EQUAL(-EINVAL, rte_service_component_unregister(1000), - "Unregistered invalid service id"); - - uint32_t c = rte_service_get_count(); - for (i = 0; i < c; i++) { - TEST_ASSERT_EQUAL(0, rte_service_component_unregister(i), - "Error unregistering a valid service"); - } - - rte_service_lcore_reset_all(); - - return TEST_SUCCESS; -} - -/* register a single dummy service */ -static int -dummy_register(void) -{ - /* make sure there are no remains from previous tests */ - unregister_all(); - - struct rte_service_spec service; - memset(&service, 0, sizeof(struct rte_service_spec)); - - TEST_ASSERT_EQUAL(-EINVAL, - rte_service_component_register(&service, NULL), - "Invalid callback"); - service.callback = dummy_cb; - - TEST_ASSERT_EQUAL(-EINVAL, - rte_service_component_register(&service, NULL), - "Invalid name"); - snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); - - uint32_t id; - TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), - "Failed to register valid service"); - - rte_service_component_runstate_set(id, 1); - - return TEST_SUCCESS; -} - -/* verify get_by_name() service lookup */ -static int -service_get_by_name(void) -{ - unregister_all(); - - uint32_t sid; - TEST_ASSERT_EQUAL(-ENODEV, - rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid), - "get by name with invalid name should return -ENODEV"); - TEST_ASSERT_EQUAL(-EINVAL, - rte_service_get_by_name(DUMMY_SERVICE_NAME, 0x0), - "get by name with NULL ptr should return -ENODEV"); - - /* register service */ - struct rte_service_spec service; - memset(&service, 0, sizeof(struct rte_service_spec)); - TEST_ASSERT_EQUAL(-EINVAL, - rte_service_component_register(&service, NULL), - "Invalid callback"); - service.callback = dummy_cb; - TEST_ASSERT_EQUAL(-EINVAL, - rte_service_component_register(&service, NULL), - "Invalid name"); - snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); - TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL), - "Failed to register valid service"); - - /* we unregistered all service, now registering 1, should be id 0 */ - uint32_t service_id_as_expected = 0; - TEST_ASSERT_EQUAL(0, rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid), - "Service get_by_name should return 0 on valid inputs"); - TEST_ASSERT_EQUAL(service_id_as_expected, sid, - "Service get_by_name should equal expected id"); - - unregister_all(); - - /* ensure after unregister, get_by_name returns NULL */ - TEST_ASSERT_EQUAL(-ENODEV, - rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid), - "get by name should return -ENODEV after unregister"); - - return TEST_SUCCESS; -} - -/* verify probe of capabilities */ -static int -service_probe_capability(void) -{ - unregister_all(); - - struct rte_service_spec service; - memset(&service, 0, sizeof(struct rte_service_spec)); - service.callback = dummy_cb; - snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); - service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; - TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL), - "Register of MT SAFE service failed"); - - /* verify flag is enabled */ - const uint32_t sid = 0; - int32_t mt = rte_service_probe_capability(sid, RTE_SERVICE_CAP_MT_SAFE); - TEST_ASSERT_EQUAL(1, mt, "MT SAFE capability flag not set."); - - - unregister_all(); - - memset(&service, 0, sizeof(struct rte_service_spec)); - service.callback = dummy_cb; - snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); - TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL), - "Register of non-MT safe service failed"); - - /* verify flag is enabled */ - mt = rte_service_probe_capability(sid, RTE_SERVICE_CAP_MT_SAFE); - TEST_ASSERT_EQUAL(0, mt, "MT SAFE cap flag set on non MT SAFE service"); - - return unregister_all(); -} - -/* verify the service name */ -static int -service_name(void) -{ - const char *name = rte_service_get_name(0); - int equal = strcmp(name, DUMMY_SERVICE_NAME); - TEST_ASSERT_EQUAL(0, equal, "Error: Service name not correct"); - - return unregister_all(); -} - -/* verify service attr get */ -static int -service_attr_get(void) -{ - /* ensure all services unregistered so cycle counts are zero */ - unregister_all(); - - struct rte_service_spec service; - memset(&service, 0, sizeof(struct rte_service_spec)); - service.callback = dummy_cb; - snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); - service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; - uint32_t id; - TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), - "Register of service failed"); - rte_service_component_runstate_set(id, 1); - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(id, 1), - "Error: Service start returned non-zero"); - rte_service_set_stats_enable(id, 1); - - uint32_t attr_id = UINT32_MAX; - uint32_t attr_value = 0xdead; - /* check error return values */ - TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(id, attr_id, - &attr_value), - "Invalid attr_id didn't return -EINVAL"); - - attr_id = RTE_SERVICE_ATTR_CYCLES; - TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(UINT32_MAX, attr_id, - &attr_value), - "Invalid service id didn't return -EINVAL"); - - TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(id, attr_id, NULL), - "Invalid attr_value pointer id didn't return -EINVAL"); - - /* check correct (zero) return value and correct value (zero) */ - TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value), - "Valid attr_get() call didn't return success"); - TEST_ASSERT_EQUAL(0, attr_value, - "attr_get() call didn't set correct cycles (zero)"); - /* check correct call count */ - const int attr_calls = RTE_SERVICE_ATTR_CALL_COUNT; - TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value), - "Valid attr_get() call didn't return success"); - TEST_ASSERT_EQUAL(0, attr_value, - "attr_get() call didn't get call count (zero)"); - - /* Call service to increment cycle count */ - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), - "Service core add did not return zero"); - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(id, slcore_id, 1), - "Enabling valid service and core failed"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id), - "Starting service core failed"); - - /* wait for the service lcore to run */ - rte_delay_ms(200); - - TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value), - "Valid attr_get() call didn't return success"); - int cycles_gt_zero = attr_value > 0; - TEST_ASSERT_EQUAL(1, cycles_gt_zero, - "attr_get() failed to get cycles (expected > zero)"); - - rte_service_lcore_stop(slcore_id); - - TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value), - "Valid attr_get() call didn't return success"); - TEST_ASSERT_EQUAL(1, (attr_value > 0), - "attr_get() call didn't get call count (zero)"); - - TEST_ASSERT_EQUAL(0, rte_service_attr_reset_all(id), - "Valid attr_reset_all() return success"); - - TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value), - "Valid attr_get() call didn't return success"); - TEST_ASSERT_EQUAL(0, attr_value, - "attr_get() call didn't set correct cycles (zero)"); - /* ensure call count > zero */ - TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value), - "Valid attr_get() call didn't return success"); - TEST_ASSERT_EQUAL(0, (attr_value > 0), - "attr_get() call didn't get call count (zero)"); - - return unregister_all(); -} - -/* verify service lcore attr get */ -static int -service_lcore_attr_get(void) -{ - /* ensure all services unregistered so cycle counts are zero */ - unregister_all(); - - struct rte_service_spec service; - memset(&service, 0, sizeof(struct rte_service_spec)); - service.callback = dummy_cb; - snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME); - service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; - uint32_t id; - TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), - "Register of service failed"); - rte_service_component_runstate_set(id, 1); - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(id, 1), - "Error: Service start returned non-zero"); - rte_service_set_stats_enable(id, 1); - - uint64_t lcore_attr_value = 0xdead; - uint32_t lcore_attr_id = UINT32_MAX; - - /* check error return values */ - TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_attr_get(UINT32_MAX, - lcore_attr_id, &lcore_attr_value), - "Invalid lcore_id didn't return -EINVAL"); - TEST_ASSERT_EQUAL(-ENOTSUP, rte_service_lcore_attr_get(rte_lcore_id(), - lcore_attr_id, &lcore_attr_value), - "Non-service core didn't return -ENOTSUP"); - - /* Start service core to increment loop count */ - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), - "Service core add did not return zero"); - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(id, slcore_id, 1), - "Enabling valid service and core failed"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id), - "Starting service core failed"); - - /* wait for the service lcore to run */ - rte_delay_ms(200); - - lcore_attr_id = RTE_SERVICE_LCORE_ATTR_LOOPS; - TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_get(slcore_id, - lcore_attr_id, &lcore_attr_value), - "Valid lcore_attr_get() call didn't return success"); - int loops_gt_zero = lcore_attr_value > 0; - TEST_ASSERT_EQUAL(1, loops_gt_zero, - "lcore_attr_get() failed to get loops " - "(expected > zero)"); - - lcore_attr_id++; // invalid lcore attr id - TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_attr_get(slcore_id, - lcore_attr_id, &lcore_attr_value), - "Invalid lcore attr didn't return -EINVAL"); - - rte_service_lcore_stop(slcore_id); - - TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_reset_all(slcore_id), - "Valid lcore_attr_reset_all() didn't return success"); - - lcore_attr_id = RTE_SERVICE_LCORE_ATTR_LOOPS; - TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_get(slcore_id, - lcore_attr_id, &lcore_attr_value), - "Valid lcore_attr_get() call didn't return success"); - TEST_ASSERT_EQUAL(0, lcore_attr_value, - "lcore_attr_get() didn't get correct loop count " - "(zero)"); - - return unregister_all(); -} - -/* verify service dump */ -static int -service_dump(void) -{ - const uint32_t sid = 0; - rte_service_set_stats_enable(sid, 1); - rte_service_dump(stdout, 0); - rte_service_set_stats_enable(sid, 0); - rte_service_dump(stdout, 0); - return unregister_all(); -} - -/* start and stop a service */ -static int -service_start_stop(void) -{ - const uint32_t sid = 0; - - /* runstate_get() returns if service is running and slcore is mapped */ - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), - "Service core add did not return zero"); - int ret = rte_service_map_lcore_set(sid, slcore_id, 1); - TEST_ASSERT_EQUAL(0, ret, - "Enabling service core, expected 0 got %d", ret); - - TEST_ASSERT_EQUAL(0, rte_service_runstate_get(sid), - "Error: Service should be stopped"); - - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), - "Error: Service stopped returned non-zero"); - - TEST_ASSERT_EQUAL(0, rte_service_runstate_get(sid), - "Error: Service is running - should be stopped"); - - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1), - "Error: Service start returned non-zero"); - - TEST_ASSERT_EQUAL(1, rte_service_runstate_get(sid), - "Error: Service is not running"); - - return unregister_all(); -} - - -static int -service_remote_launch_func(void *arg) -{ - RTE_SET_USED(arg); - service_remote_launch_flag = 1; - return 0; -} - -/* enable and disable a lcore for a service */ -static int -service_lcore_en_dis_able(void) -{ - const uint32_t sid = 0; - - /* expected failure cases */ - TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, 100000, 1), - "Enable on invalid core did not fail"); - TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, 100000, 0), - "Disable on invalid core did not fail"); - - /* add service core to allow enabling */ - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), - "Add service core failed when not in use before"); - - /* valid enable */ - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1), - "Enabling valid service and core failed"); - TEST_ASSERT_EQUAL(1, rte_service_map_lcore_get(sid, slcore_id), - "Enabled core returned not-enabled"); - - /* valid disable */ - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 0), - "Disabling valid service and lcore failed"); - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_get(sid, slcore_id), - "Disabled core returned enabled"); - - /* call remote_launch to verify that app can launch ex-service lcore */ - service_remote_launch_flag = 0; - rte_eal_wait_lcore(slcore_id); - int ret = rte_eal_remote_launch(service_remote_launch_func, NULL, - slcore_id); - TEST_ASSERT_EQUAL(0, ret, "Ex-service core remote launch failed."); - rte_eal_mp_wait_lcore(); - TEST_ASSERT_EQUAL(1, service_remote_launch_flag, - "Ex-service core function call had no effect."); - - return unregister_all(); -} - -static int -service_lcore_running_check(void) -{ - uint64_t tick = service_tick; - rte_delay_ms(SERVICE_DELAY * 100); - /* if (tick != service_tick) we know the lcore as polled the service */ - return tick != service_tick; -} - -static int -service_lcore_add_del(void) -{ - /* check initial count */ - TEST_ASSERT_EQUAL(0, rte_service_lcore_count(), - "Service lcore count has value before adding a lcore"); - - /* check service lcore add */ - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), - "Add service core failed when not in use before"); - TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_add(slcore_id), - "Add service core failed to refuse in-use lcore"); - - /* check count */ - TEST_ASSERT_EQUAL(1, rte_service_lcore_count(), - "Service core count not equal to one"); - - /* retrieve core list, checking lcore ids */ - const uint32_t size = 4; - uint32_t service_core_ids[size]; - int32_t n = rte_service_lcore_list(service_core_ids, size); - TEST_ASSERT_EQUAL(1, n, "Service core list return should equal 1"); - TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0], - "Service core list lcore must equal slcore_id"); - - /* recheck count, add more cores, and check count */ - TEST_ASSERT_EQUAL(1, rte_service_lcore_count(), - "Service core count not equal to one"); - uint32_t slcore_1 = rte_get_next_lcore(/* start core */ -1, - /* skip master */ 1, - /* wrap */ 0); - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_1), - "Service core add did not return zero"); - uint32_t slcore_2 = rte_get_next_lcore(/* start core */ slcore_1, - /* skip master */ 1, - /* wrap */ 0); - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_2), - "Service core add did not return zero"); - - uint32_t count = rte_service_lcore_count(); - const uint32_t cores_at_this_point = 3; - TEST_ASSERT_EQUAL(cores_at_this_point, count, - "Service core count %d, expected %d", count, - cores_at_this_point); - - /* check longer service core list */ - n = rte_service_lcore_list(service_core_ids, size); - TEST_ASSERT_EQUAL(3, n, "Service core list return should equal 3"); - TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0], - "Service core list[0] lcore must equal 1"); - TEST_ASSERT_EQUAL(slcore_1, service_core_ids[1], - "Service core list[1] lcore must equal 2"); - TEST_ASSERT_EQUAL(slcore_2, service_core_ids[2], - "Service core list[2] lcore must equal 3"); - - /* recheck count, remove lcores, check remaining lcore_id is correct */ - TEST_ASSERT_EQUAL(3, rte_service_lcore_count(), - "Service core count not equal to three"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_1), - "Service core add did not return zero"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_2), - "Service core add did not return zero"); - TEST_ASSERT_EQUAL(1, rte_service_lcore_count(), - "Service core count not equal to one"); - n = rte_service_lcore_list(service_core_ids, size); - TEST_ASSERT_EQUAL(1, n, "Service core list return should equal one"); - TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0], - "Service core list[0] lcore must equal %d", - slcore_id); - - return unregister_all(); -} - -static int -service_threaded_test(int mt_safe) -{ - unregister_all(); - - /* add next 2 cores */ - uint32_t slcore_1 = rte_get_next_lcore(/* start core */ -1, - /* skip master */ 1, - /* wrap */ 0); - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_1), - "mt safe lcore add fail"); - uint32_t slcore_2 = rte_get_next_lcore(/* start core */ slcore_1, - /* skip master */ 1, - /* wrap */ 0); - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_2), - "mt safe lcore add fail"); - - /* Use atomic locks to verify that two threads are in the same function - * at the same time. These are passed to the unit tests through the - * callback userdata parameter - */ - uint32_t test_params[2]; - memset(test_params, 0, sizeof(uint32_t) * 2); - - /* register MT safe service. */ - struct rte_service_spec service; - memset(&service, 0, sizeof(struct rte_service_spec)); - service.callback_userdata = test_params; - snprintf(service.name, sizeof(service.name), MT_SAFE_SERVICE_NAME); - - if (mt_safe) { - service.callback = dummy_mt_safe_cb; - service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; - } else - service.callback = dummy_mt_unsafe_cb; - - uint32_t id; - TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), - "Register of MT SAFE service failed"); - - const uint32_t sid = 0; - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1), - "Starting valid service failed"); - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_1, 1), - "Failed to enable lcore 1 on mt safe service"); - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_2, 1), - "Failed to enable lcore 2 on mt safe service"); - rte_service_lcore_start(slcore_1); - rte_service_lcore_start(slcore_2); - - /* wait for the worker threads to run */ - rte_delay_ms(500); - rte_service_lcore_stop(slcore_1); - rte_service_lcore_stop(slcore_2); - - TEST_ASSERT_EQUAL(0, test_params[1], - "Service run with component runstate = 0"); - - /* enable backend runstate: the service should run after this */ - rte_service_component_runstate_set(id, 1); - - /* initialize to pass, see callback comment for details */ - if (!mt_safe) - test_params[1] = 1; - - /* wait for lcores before start() */ - rte_eal_wait_lcore(slcore_1); - rte_eal_wait_lcore(slcore_2); - - rte_service_lcore_start(slcore_1); - rte_service_lcore_start(slcore_2); - - /* wait for the worker threads to run */ - rte_delay_ms(500); - rte_service_lcore_stop(slcore_1); - rte_service_lcore_stop(slcore_2); - - TEST_ASSERT_EQUAL(1, test_params[1], - "MT Safe service not run by two cores concurrently"); - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), - "Failed to stop MT Safe service"); - - rte_eal_wait_lcore(slcore_1); - rte_eal_wait_lcore(slcore_2); - unregister_all(); - - /* return the value of the callback pass_test variable to caller */ - return test_params[1]; -} - -/* tests an MT SAFE service with two cores. The callback function ensures that - * two threads access the callback concurrently. - */ -static int -service_mt_safe_poll(void) -{ - int mt_safe = 1; - TEST_ASSERT_EQUAL(1, service_threaded_test(mt_safe), - "Error: MT Safe service not run by two cores concurrently"); - return TEST_SUCCESS; -} - -/* tests a NON mt safe service with two cores, the callback is serialized - * using the atomic cmpset. - */ -static int -service_mt_unsafe_poll(void) -{ - int mt_safe = 0; - TEST_ASSERT_EQUAL(1, service_threaded_test(mt_safe), - "Error: NON MT Safe service run by two cores concurrently"); - return TEST_SUCCESS; -} - -static int32_t -delay_as_a_mt_safe_service(void *args) -{ - RTE_SET_USED(args); - uint32_t *params = args; - - /* retrieve done flag and atomic lock to inc/dec */ - uint32_t *done = ¶ms[0]; - rte_atomic32_t *lock = (rte_atomic32_t *)¶ms[1]; - - while (!*done) { - rte_atomic32_inc(lock); - rte_delay_us(500); - if (rte_atomic32_read(lock) > 1) - /* pass: second core has simultaneously incremented */ - *done = 1; - rte_atomic32_dec(lock); - } - - return 0; -} - -static int32_t -delay_as_a_service(void *args) -{ - uint32_t *done = (uint32_t *)args; - while (!*done) - rte_delay_ms(5); - return 0; -} - -static int -service_run_on_app_core_func(void *arg) -{ - uint32_t *delay_service_id = (uint32_t *)arg; - return rte_service_run_iter_on_app_lcore(*delay_service_id, 1); -} - -static int -service_app_lcore_poll_impl(const int mt_safe) -{ - uint32_t params[2] = {0}; - - struct rte_service_spec service; - memset(&service, 0, sizeof(struct rte_service_spec)); - snprintf(service.name, sizeof(service.name), MT_SAFE_SERVICE_NAME); - if (mt_safe) { - service.callback = delay_as_a_mt_safe_service; - service.callback_userdata = params; - service.capabilities |= RTE_SERVICE_CAP_MT_SAFE; - } else { - service.callback = delay_as_a_service; - service.callback_userdata = ¶ms; - } - - uint32_t id; - TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id), - "Register of app lcore delay service failed"); - - rte_service_component_runstate_set(id, 1); - rte_service_runstate_set(id, 1); - - uint32_t app_core2 = rte_get_next_lcore(slcore_id, 1, 1); - rte_eal_wait_lcore(app_core2); - int app_core2_ret = rte_eal_remote_launch(service_run_on_app_core_func, - &id, app_core2); - - rte_delay_ms(100); - - int app_core1_ret = service_run_on_app_core_func(&id); - - /* flag done, then wait for the spawned 2nd core to return */ - params[0] = 1; - rte_eal_mp_wait_lcore(); - - /* core two gets launched first - and should hold the service lock */ - TEST_ASSERT_EQUAL(0, app_core2_ret, - "App core2 : run service didn't return zero"); - - if (mt_safe) { - /* mt safe should have both cores return 0 for success */ - TEST_ASSERT_EQUAL(0, app_core1_ret, - "MT Safe: App core1 didn't return 0"); - } else { - /* core one attempts to run later - should be blocked */ - TEST_ASSERT_EQUAL(-EBUSY, app_core1_ret, - "MT Unsafe: App core1 didn't return -EBUSY"); - } - - unregister_all(); - - return TEST_SUCCESS; -} - -static int -service_app_lcore_mt_safe(void) -{ - const int mt_safe = 1; - return service_app_lcore_poll_impl(mt_safe); -} - -static int -service_app_lcore_mt_unsafe(void) -{ - const int mt_safe = 0; - return service_app_lcore_poll_impl(mt_safe); -} - -/* start and stop a service core - ensuring it goes back to sleep */ -static int -service_lcore_start_stop(void) -{ - /* start service core and service, create mapping so tick() runs */ - const uint32_t sid = 0; - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1), - "Starting valid service failed"); - TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, slcore_id, 1), - "Enabling valid service on non-service core must fail"); - - /* core start */ - TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_start(slcore_id), - "Service core start without add should return EINVAL"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), - "Service core add did not return zero"); - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1), - "Enabling valid service on valid core failed"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id), - "Service core start after add failed"); - TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_start(slcore_id), - "Service core expected as running but was stopped"); - - /* ensures core really is running the service function */ - TEST_ASSERT_EQUAL(1, service_lcore_running_check(), - "Service core expected to poll service but it didn't"); - - /* core stop */ - TEST_ASSERT_EQUAL(-EBUSY, rte_service_lcore_stop(slcore_id), - "Service core running a service should return -EBUSY"); - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), - "Stopping valid service failed"); - TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_stop(100000), - "Invalid Service core stop should return -EINVAL"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_stop(slcore_id), - "Service core stop expected to return 0"); - TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_stop(slcore_id), - "Already stopped service core should return -EALREADY"); - - /* ensure service is not longer running */ - TEST_ASSERT_EQUAL(0, service_lcore_running_check(), - "Service core expected to poll service but it didn't"); - - TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_id), - "Service core del did not return zero"); - - return unregister_all(); -} - -/* stop a service and wait for it to become inactive */ -static int -service_may_be_active(void) -{ - const uint32_t sid = 0; - int i; - - /* expected failure cases */ - TEST_ASSERT_EQUAL(-EINVAL, rte_service_may_be_active(10000), - "Invalid service may be active check did not fail"); - - /* start the service */ - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1), - "Starting valid service failed"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id), - "Add service core failed when not in use before"); - TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1), - "Enabling valid service on valid core failed"); - TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id), - "Service core start after add failed"); - - /* ensures core really is running the service function */ - TEST_ASSERT_EQUAL(1, service_lcore_running_check(), - "Service core expected to poll service but it didn't"); - - /* stop the service */ - TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), - "Error: Service stop returned non-zero"); - - /* give the service 100ms to stop running */ - for (i = 0; i < 100; i++) { - if (!rte_service_may_be_active(sid)) - break; - rte_delay_ms(SERVICE_DELAY); - } - - TEST_ASSERT_EQUAL(0, rte_service_may_be_active(sid), - "Error: Service not stopped after 100ms"); - - return unregister_all(); -} - -static struct unit_test_suite service_tests = { - .suite_name = "service core test suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(dummy_register, NULL, unregister_all), - TEST_CASE_ST(dummy_register, NULL, service_name), - TEST_CASE_ST(dummy_register, NULL, service_get_by_name), - TEST_CASE_ST(dummy_register, NULL, service_dump), - TEST_CASE_ST(dummy_register, NULL, service_attr_get), - TEST_CASE_ST(dummy_register, NULL, service_lcore_attr_get), - TEST_CASE_ST(dummy_register, NULL, service_probe_capability), - TEST_CASE_ST(dummy_register, NULL, service_start_stop), - TEST_CASE_ST(dummy_register, NULL, service_lcore_add_del), - TEST_CASE_ST(dummy_register, NULL, service_lcore_start_stop), - TEST_CASE_ST(dummy_register, NULL, service_lcore_en_dis_able), - TEST_CASE_ST(dummy_register, NULL, service_mt_unsafe_poll), - TEST_CASE_ST(dummy_register, NULL, service_mt_safe_poll), - TEST_CASE_ST(dummy_register, NULL, service_app_lcore_mt_safe), - TEST_CASE_ST(dummy_register, NULL, service_app_lcore_mt_unsafe), - TEST_CASE_ST(dummy_register, NULL, service_may_be_active), - TEST_CASES_END() /**< NULL terminate unit test array */ - } -}; - -static int -test_service_common(void) -{ - return unit_test_suite_runner(&service_tests); -} - -REGISTER_TEST_COMMAND(service_autotest, test_service_common); diff --git a/test/test/test_spinlock.c b/test/test/test_spinlock.c deleted file mode 100644 index 73bff128e6..0000000000 --- a/test/test/test_spinlock.c +++ /dev/null @@ -1,305 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 successfully, 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_rte_strlcat(void) -{ - /* only run actual unit tests if we have system-provided strlcat */ -#if defined(__BSD_VISIBLE) || defined(RTE_USE_LIBBSD) -#define BUF_LEN 32 - const char dst[BUF_LEN] = "Test string"; - const char src[] = " appended"; - char bsd_dst[BUF_LEN]; - char rte_dst[BUF_LEN]; - size_t i, bsd_ret, rte_ret; - - LOG("dst = '%s', strlen(dst) = %zu\n", dst, strlen(dst)); - LOG("src = '%s', strlen(src) = %zu\n", src, strlen(src)); - LOG("---\n"); - - for (i = 0; i < BUF_LEN; i++) { - /* initialize destination buffers */ - memcpy(bsd_dst, dst, BUF_LEN); - memcpy(rte_dst, dst, BUF_LEN); - /* compare implementations */ - bsd_ret = strlcat(bsd_dst, src, i); - rte_ret = rte_strlcat(rte_dst, src, i); - if (bsd_ret != rte_ret) { - LOG("Incorrect retval for buf length = %zu\n", i); - LOG("BSD: '%zu', rte: '%zu'\n", bsd_ret, rte_ret); - return -1; - } - if (memcmp(bsd_dst, rte_dst, BUF_LEN) != 0) { - LOG("Resulting buffers don't match\n"); - LOG("BSD: '%s', rte: '%s'\n", bsd_dst, rte_dst); - return -1; - } - LOG("buffer size = %zu: dst = '%s', ret = %zu\n", - i, rte_dst, rte_ret); - } - LOG("Checked %zu combinations\n", i); -#undef BUF_LEN -#endif /* defined(__BSD_VISIBLE) || defined(RTE_USE_LIBBSD) */ - - return 0; -} - -static int -test_string_fns(void) -{ - if (test_rte_strsplit() < 0) - return -1; - if (test_rte_strlcat() < 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 deleted file mode 100644 index a4b0ed65f9..0000000000 --- a/test/test/test_table.c +++ /dev/null @@ -1,197 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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)) void *key_mask, - __attribute__((unused)) uint32_t key_size, - __attribute__((unused)) uint64_t seed) -{ - uint32_t *k32 = key; - uint32_t ip_dst = rte_be_to_cpu_32(k32[0]); - uint64_t signature = ip_dst; - - return signature; -} - -uint32_t pipeline_test_hash_cuckoo(const void *key, - __attribute__((unused)) uint32_t key_size, - __attribute__((unused)) uint32_t seed) -{ - const uint32_t *k32 = key; - uint32_t ip_dst = rte_be_to_cpu_32(k32[0]); - uint32_t signature = ip_dst; - - return signature; -} - -static void -app_free_resources(void) { - int i; - for (i = 0; i < N_PORTS; i++) - rte_ring_free(rings_rx[i]); - rte_mempool_free(pool); -} - -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, ret; - unsigned i; - - ret = TEST_SUCCESS; - - app_init_rings(); - app_init_mbuf_pools(); - - printf("\n\n\n\n************Pipeline tests************\n"); - - if (test_table_pipeline() < 0) { - ret = TEST_FAILED; - goto end; - } - - 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); - ret = TEST_FAILED; - goto end; - } - } - - 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); - ret = TEST_FAILED; - goto end; - } - } - - 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); - ret = TEST_FAILED; - goto end; - } - } - -#ifdef RTE_LIBRTE_ACL - printf("\n\n\n\n************ACL tests************\n"); - if (test_table_acl() < 0) { - ret = TEST_FAILED; - goto end; - } -#endif - -end: - app_free_resources(); - - return ret; -} - -REGISTER_TEST_COMMAND(table_autotest, test_table); diff --git a/test/test/test_table.h b/test/test/test_table.h deleted file mode 100644 index a66342cb65..0000000000 --- a/test/test/test_table.h +++ /dev/null @@ -1,184 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#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, NULL, 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)) void *key_mask, - __attribute__((unused)) uint32_t key_size, - __attribute__((unused)) uint64_t seed); - -uint32_t pipeline_test_hash_cuckoo( - const void *key, - __attribute__((unused)) uint32_t key_size, - __attribute__((unused)) uint32_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 deleted file mode 100644 index 33e2f6ee64..0000000000 --- a/test/test/test_table_acl.c +++ /dev/null @@ -1,733 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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]; - - memset(table_entries, 0, sizeof(table_entries)); - - 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, NULL); - 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 = 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 deleted file mode 100644 index a6ae7d2838..0000000000 --- a/test/test/test_table_acl.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -/* Test prototypes */ -int test_table_acl(void); diff --git a/test/test/test_table_combined.c b/test/test/test_table_combined.c deleted file mode 100644 index 73ad0155d6..0000000000 --- a/test/test/test_table_combined.c +++ /dev/null @@ -1,843 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2016 Intel Corporation - */ - -#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_params key8lru_params = { - .name = "TABLE", - .key_size = 8, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 16, - .n_buckets = 1 << 16, - .f_hash = pipeline_test_hash, - .seed = 0, - }; - - 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_keys = 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_keys = 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_params key16lru_params = { - .name = "TABLE", - .key_size = 16, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 16, - .n_buckets = 1 << 16, - .f_hash = pipeline_test_hash, - .seed = 0, - }; - - 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_keys = 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_keys = 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_params key32lru_params = { - .name = "TABLE", - .key_size = 32, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 16, - .n_buckets = 1 << 16, - .f_hash = pipeline_test_hash, - .seed = 0, - }; - - 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_keys = 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_keys = 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_params key8ext_params = { - .name = "TABLE", - .key_size = 8, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 16, - .n_buckets = 1 << 16, - .f_hash = pipeline_test_hash, - .seed = 0, - }; - - 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_keys = 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_keys = 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); - - return 0; -} - -int -test_table_hash16ext(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_params key16ext_params = { - .name = "TABLE", - .key_size = 16, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 16, - .n_buckets = 1 << 16, - .f_hash = pipeline_test_hash, - .seed = 0, - }; - - 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_keys = 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_keys = 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); - - return 0; -} - -int -test_table_hash32ext(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_params key32ext_params = { - .name = "TABLE", - .key_size = 32, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 16, - .n_buckets = 1 << 16, - .f_hash = pipeline_test_hash, - .seed = 0, - }; - - 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_keys = 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_keys = 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); - - return 0; -} - -int -test_table_hash_cuckoo_combined(void) -{ - int status, i; - - /* Traffic flow */ - struct rte_table_hash_cuckoo_params cuckoo_params = { - .name = "TABLE", - .key_size = 32, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 16, - .n_buckets = 1 << 16, - .f_hash = pipeline_test_hash_cuckoo, - .seed = 0, - }; - - 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_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_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_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_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 deleted file mode 100644 index d05866240f..0000000000 --- a/test/test/test_table_combined.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2016 Intel Corporation - */ - -/* 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 deleted file mode 100644 index 441338ac01..0000000000 --- a/test/test/test_table_pipeline.c +++ /dev/null @@ -1,569 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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); - -static int -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; -} - -static int -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, NULL); - 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 = 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 = 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 = 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 deleted file mode 100644 index d66d09d6f1..0000000000 --- a/test/test/test_table_pipeline.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -/* Test prototypes */ -int test_table_pipeline(void); diff --git a/test/test/test_table_ports.c b/test/test/test_table_ports.c deleted file mode 100644 index d921b2e207..0000000000 --- a/test/test/test_table_ports.c +++ /dev/null @@ -1,191 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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, NULL); - 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, NULL); - 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, NULL); - - 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, NULL); - - 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, NULL); - - 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, NULL); - - 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 deleted file mode 100644 index dfa6119319..0000000000 --- a/test/test/test_table_ports.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -/* 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 deleted file mode 100644 index 20df2e9225..0000000000 --- a/test/test/test_table_tables.c +++ /dev/null @@ -1,1054 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2016 Intel Corporation - */ - -#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, NULL, 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, uint32_t key_size); -static int -test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size); - -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, uint32_t key_size) -{ - 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_params hash_params = { - .name = "TABLE", - .key_size = key_size, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 10, - .n_buckets = 1 << 10, - .f_hash = pipeline_test_hash, - .seed = 0, - }; - - hash_params.n_keys = 0; - - table = ops->f_create(&hash_params, 0, 1); - if (table != NULL) - return -1; - - hash_params.n_keys = 1 << 10; - 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, uint32_t key_size) -{ - 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_params hash_params = { - .name = "TABLE", - .key_size = key_size, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 10, - .n_buckets = 1 << 10, - .f_hash = pipeline_test_hash, - .seed = 0, - }; - - hash_params.n_keys = 0; - - table = ops->f_create(&hash_params, 0, 1); - if (table != NULL) - return -1; - - hash_params.n_keys = 1 << 10; - 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, - 8); - if (status < 0) - return status; - - status = test_table_hash_lru_generic( - &rte_table_hash_key16_lru_ops, - 16); - if (status < 0) - return status; - - status = test_table_hash_lru_generic( - &rte_table_hash_key32_lru_ops, - 32); - 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, 8); - if (status < 0) - return status; - - status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops, 16); - if (status < 0) - return status; - - status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops, 32); - 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 = { - .name = "TABLE", - .key_size = 32, - .key_offset = APP_METADATA_OFFSET(32), - .key_mask = NULL, - .n_keys = 1 << 16, - .n_buckets = 1 << 16, - .f_hash = pipeline_test_hash_cuckoo, - .seed = 0, - }; - - table = rte_table_hash_cuckoo_ops.f_create(NULL, 0, entry_size); - if (table != NULL) - return -1; - - cuckoo_params.key_size = 0; - - table = rte_table_hash_cuckoo_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_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_ops.f_create(&cuckoo_params, - 0, entry_size); - if (table != NULL) - return -4; - - cuckoo_params.f_hash = pipeline_test_hash_cuckoo; - cuckoo_params.name = NULL; - - table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, - 0, entry_size); - if (table != NULL) - return -5; - - cuckoo_params.name = "CUCKOO"; - - table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, - 0, entry_size); - if (table == NULL) - return -6; - - /* Free */ - status = rte_table_hash_cuckoo_ops.f_free(table); - if (status < 0) - return -7; - - status = rte_table_hash_cuckoo_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_ops.f_create(&cuckoo_params, 0, 1); - if (table == NULL) - return -9; - - entry = 'A'; - status = rte_table_hash_cuckoo_ops.f_add(NULL, &key_cuckoo, - &entry, &key_found, &entry_ptr); - if (status == 0) - return -10; - - status = rte_table_hash_cuckoo_ops.f_add(table, NULL, &entry, - &key_found, &entry_ptr); - if (status == 0) - return -11; - - status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, - NULL, &key_found, &entry_ptr); - if (status == 0) - return -12; - - status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, - &entry, &key_found, &entry_ptr); - if (status != 0) - return -13; - - status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, - &entry, &key_found, &entry_ptr); - if (status != 0) - return -14; - - /* Delete */ - status = rte_table_hash_cuckoo_ops.f_delete(NULL, &key_cuckoo, - &key_found, NULL); - if (status == 0) - return -15; - - status = rte_table_hash_cuckoo_ops.f_delete(table, NULL, - &key_found, NULL); - if (status == 0) - return -16; - - status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo, - &key_found, NULL); - if (status != 0) - return -17; - - status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo, - &key_found, NULL); - if (status != -ENOENT) - return -18; - - /* Traffic flow */ - entry = 'A'; - status = rte_table_hash_cuckoo_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_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_ops.f_free(table); - - return 0; -} - diff --git a/test/test/test_table_tables.h b/test/test/test_table_tables.h deleted file mode 100644 index 7570e99639..0000000000 --- a/test/test/test_table_tables.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2016 Intel Corporation - */ - -/* 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 deleted file mode 100644 index a4ecea2d8d..0000000000 --- a/test/test/test_tailq.c +++ /dev/null @@ -1,128 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 61754a9475..0000000000 --- a/test/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/test/test/test_timer.c b/test/test/test_timer.c deleted file mode 100644 index e2aab53085..0000000000 --- a/test/test/test_timer.c +++ /dev/null @@ -1,600 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 -#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); - - rte_free(tms); - 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 deleted file mode 100644 index d29048eaf1..0000000000 --- a/test/test/test_timer_racecond.c +++ /dev/null @@ -1,206 +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 -#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 4 /* 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 deleted file mode 100644 index 1e1ff18656..0000000000 --- a/test/test/test_version.c +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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 deleted file mode 100644 index 8bcf0b2617..0000000000 --- a/test/test/test_xmmt_ops.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015 Cavium, Inc - */ - -#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 __rte_always_inline xmm_t -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 __rte_always_inline xmm_t -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 deleted file mode 100644 index f8ddc2db82..0000000000 --- a/test/test/virtual_pmd.c +++ /dev/null @@ -1,604 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include -#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 int -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)); - - return 0; -} - -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 int -virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev, - __rte_unused struct ether_addr *addr) -{ - return 0; -} - -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, - .mac_addr_set = virtual_ethdev_mac_address_set, - .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(uint16_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(uint16_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(uint16_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(uint16_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(uint16_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, NULL); - - /* 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 = 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, NULL); - - /* 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 = 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(uint16_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(uint16_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(uint16_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(uint16_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(uint16_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(uint16_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, NULL); -} - -int -virtual_ethdev_get_mbufs_from_tx_queue(uint16_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, NULL); -} - - -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 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 - */ - - pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, socket_id); - if (pci_dev == 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_dev->device.name = eth_dev->data->name; - 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_dev->device = &pci_dev->device; - eth_dev->device->driver = &pci_drv->driver; - - 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 = &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; - - rte_eth_dev_probing_finish(eth_dev); - - return eth_dev->data->port_id; - -err: - rte_free(pci_dev); - rte_free(pci_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 deleted file mode 100644 index 5ca02bb503..0000000000 --- a/test/test/virtual_pmd.h +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#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(uint16_t port_id, uint8_t link_status); - -void -virtual_ethdev_simulate_link_status_interrupt(uint16_t port_id, - uint8_t link_status); - -int -virtual_ethdev_add_mbufs_to_rx_queue(uint16_t port_id, - struct rte_mbuf **pkts_burst, int burst_length); - -int -virtual_ethdev_get_mbufs_from_tx_queue(uint16_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(uint16_t port_id, uint8_t success); - -void -virtual_ethdev_stop_fn_set_success(uint16_t port_id, uint8_t success); - -void -virtual_ethdev_configure_fn_set_success(uint16_t port_id, uint8_t success); - -void -virtual_ethdev_rx_queue_setup_fn_set_success(uint16_t port_id, - uint8_t success); - -void -virtual_ethdev_tx_queue_setup_fn_set_success(uint16_t port_id, - uint8_t success); - -void -virtual_ethdev_link_update_fn_set_success(uint16_t port_id, uint8_t success); - -void -virtual_ethdev_rx_burst_fn_set_success(uint16_t port_id, uint8_t success); - -void -virtual_ethdev_tx_burst_fn_set_success(uint16_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(uint16_t port_id, - uint8_t packet_fail_count); - -#ifdef __cplusplus -} -#endif - -#endif /* __VIRTUAL_ETHDEV_H_ */