aboutsummaryrefslogtreecommitdiff
path: root/test/common_plat
diff options
context:
space:
mode:
authorBalakrishna Garapati <balakrishna.garapati@linaro.org>2017-03-03 15:13:43 +0100
committerBalakrishna Garapati <balakrishna.garapati@linaro.org>2017-03-03 15:13:43 +0100
commit4478de9683f9fc875d75220550e7e38f1e4e8224 (patch)
treef8c8fdfa95d1a4c954e9e5c34e00a9b3336b0b68 /test/common_plat
parent7f5fa185004547dd74304c8c33ebab485891682e (diff)
parenta652887cfebadb30843a6fbfe9d5655031d46881 (diff)
Merge tag 'v1.14.0.0' into odp_dpdk_v1.14.0.0
Diffstat (limited to 'test/common_plat')
-rw-r--r--test/common_plat/common/odp_cunit_common.c2
-rw-r--r--test/common_plat/miscellaneous/odp_api_from_cpp.cpp2
-rw-r--r--test/common_plat/performance/.gitignore2
-rw-r--r--test/common_plat/performance/Makefile.am19
-rw-r--r--test/common_plat/performance/dummy_crc.h493
-rw-r--r--test/common_plat/performance/odp_bench_packet.c1611
-rw-r--r--test/common_plat/performance/odp_crypto.c2
-rw-r--r--test/common_plat/performance/odp_l2fwd.c26
-rwxr-xr-xtest/common_plat/performance/odp_l2fwd_run.sh10
-rw-r--r--test/common_plat/performance/odp_pktio_ordered.c1342
-rwxr-xr-xtest/common_plat/performance/odp_pktio_ordered_run.sh42
-rw-r--r--test/common_plat/performance/odp_pktio_perf.c5
-rw-r--r--test/common_plat/performance/odp_sched_latency.c2
-rw-r--r--test/common_plat/performance/odp_scheduling.c2
-rw-r--r--test/common_plat/performance/udp64.pcapbin0 -> 7624 bytes
-rw-r--r--test/common_plat/validation/api/classification/classification.h25
-rw-r--r--test/common_plat/validation/api/classification/odp_classification_common.c170
-rw-r--r--test/common_plat/validation/api/classification/odp_classification_test_pmr.c749
-rw-r--r--test/common_plat/validation/api/classification/odp_classification_tests.c46
-rw-r--r--test/common_plat/validation/api/classification/odp_classification_testsuites.h17
-rw-r--r--test/common_plat/validation/api/crypto/crypto.c6
-rw-r--r--test/common_plat/validation/api/crypto/odp_crypto_test_inp.c398
-rw-r--r--test/common_plat/validation/api/crypto/odp_crypto_test_inp.h1
-rw-r--r--test/common_plat/validation/api/packet/packet.c472
-rw-r--r--test/common_plat/validation/api/packet/packet.h2
-rw-r--r--test/common_plat/validation/api/pktio/pktio.c4
-rw-r--r--test/common_plat/validation/api/timer/timer.c2
-rw-r--r--test/common_plat/validation/api/traffic_mngr/traffic_mngr.c6
28 files changed, 5245 insertions, 213 deletions
diff --git a/test/common_plat/common/odp_cunit_common.c b/test/common_plat/common/odp_cunit_common.c
index 2337c92b0..d3328af6c 100644
--- a/test/common_plat/common/odp_cunit_common.c
+++ b/test/common_plat/common/odp_cunit_common.c
@@ -7,7 +7,7 @@
#include <string.h>
#include <odp_api.h>
#include <odp_cunit_common.h>
-#include <odp/helper/linux.h>
+#include <odp/helper/odph_api.h>
/* Globals */
static odph_odpthread_t thread_tbl[MAX_WORKERS];
static odp_instance_t instance;
diff --git a/test/common_plat/miscellaneous/odp_api_from_cpp.cpp b/test/common_plat/miscellaneous/odp_api_from_cpp.cpp
index be74c275c..2b3078642 100644
--- a/test/common_plat/miscellaneous/odp_api_from_cpp.cpp
+++ b/test/common_plat/miscellaneous/odp_api_from_cpp.cpp
@@ -1,6 +1,6 @@
#include <cstdio>
#include <odp_api.h>
-#include <odp/helper/linux.h>
+#include <odp/helper/threads.h>
int main(int argc ODP_UNUSED, const char *argv[] ODP_UNUSED)
{
diff --git a/test/common_plat/performance/.gitignore b/test/common_plat/performance/.gitignore
index 1527d2516..72035e002 100644
--- a/test/common_plat/performance/.gitignore
+++ b/test/common_plat/performance/.gitignore
@@ -1,8 +1,10 @@
*.log
*.trs
odp_atomic
+odp_bench_packet
odp_crypto
odp_l2fwd
+odp_pktio_ordered
odp_pktio_perf
odp_sched_latency
odp_scheduling
diff --git a/test/common_plat/performance/Makefile.am b/test/common_plat/performance/Makefile.am
index f1846095b..9111c0c2d 100644
--- a/test/common_plat/performance/Makefile.am
+++ b/test/common_plat/performance/Makefile.am
@@ -2,13 +2,17 @@ include $(top_srcdir)/test/Makefile.inc
TESTS_ENVIRONMENT += TEST_DIR=${builddir}
-EXECUTABLES = odp_crypto$(EXEEXT) odp_pktio_perf$(EXEEXT)
+EXECUTABLES = odp_bench_packet$(EXEEXT) \
+ odp_crypto$(EXEEXT) \
+ odp_pktio_perf$(EXEEXT)
COMPILE_ONLY = odp_l2fwd$(EXEEXT) \
+ odp_pktio_ordered$(EXEEXT) \
odp_sched_latency$(EXEEXT) \
odp_scheduling$(EXEEXT)
TESTSCRIPTS = odp_l2fwd_run.sh \
+ odp_pktio_ordered_run.sh \
odp_sched_latency_run.sh \
odp_scheduling_run.sh
@@ -20,17 +24,28 @@ endif
bin_PROGRAMS = $(EXECUTABLES) $(COMPILE_ONLY)
+odp_bench_packet_LDFLAGS = $(AM_LDFLAGS) -static
+odp_bench_packet_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static
odp_crypto_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
+odp_pktio_perf_LDFLAGS = $(AM_LDFLAGS) -static
+odp_pktio_perf_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
+odp_l2fwd_LDFLAGS = $(AM_LDFLAGS) -static
+odp_l2fwd_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
+odp_pktio_ordered_LDFLAGS = $(AM_LDFLAGS) -static
+odp_pktio_ordered_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
odp_sched_latency_LDFLAGS = $(AM_LDFLAGS) -static
odp_sched_latency_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
odp_scheduling_LDFLAGS = $(AM_LDFLAGS) -static
odp_scheduling_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/test
noinst_HEADERS = \
- $(top_srcdir)/test/test_debug.h
+ $(top_srcdir)/test/test_debug.h \
+ dummy_crc.h
+dist_odp_bench_packet_SOURCES = odp_bench_packet.c
dist_odp_crypto_SOURCES = odp_crypto.c
+dist_odp_pktio_ordered_SOURCES = odp_pktio_ordered.c
dist_odp_sched_latency_SOURCES = odp_sched_latency.c
dist_odp_scheduling_SOURCES = odp_scheduling.c
dist_odp_pktio_perf_SOURCES = odp_pktio_perf.c
diff --git a/test/common_plat/performance/dummy_crc.h b/test/common_plat/performance/dummy_crc.h
new file mode 100644
index 000000000..38da44455
--- /dev/null
+++ b/test/common_plat/performance/dummy_crc.h
@@ -0,0 +1,493 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *
+ * This file is meant only for generating dummy processing work.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+static const uint32_t dummy_crc32c_tables[8][256] = {{
+ 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C,
+ 0x26A1E7E8, 0xD4CA64EB, 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+ 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, 0x105EC76F, 0xE235446C,
+ 0xF165B798, 0x030E349B, 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+ 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 0x5D1D08BF, 0xAF768BBC,
+ 0xBC267848, 0x4E4DFB4B, 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+ 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, 0xAA64D611, 0x580F5512,
+ 0x4B5FA6E6, 0xB93425E5, 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+ 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 0xF779DEAE, 0x05125DAD,
+ 0x1642AE59, 0xE4292D5A, 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+ 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, 0x417B1DBC, 0xB3109EBF,
+ 0xA0406D4B, 0x522BEE48, 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+ 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 0x0C38D26C, 0xFE53516F,
+ 0xED03A29B, 0x1F682198, 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+ 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, 0xDBFC821C, 0x2997011F,
+ 0x3AC7F2EB, 0xC8AC71E8, 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+ 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 0xA65C047D, 0x5437877E,
+ 0x4767748A, 0xB50CF789, 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+ 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, 0x7198540D, 0x83F3D70E,
+ 0x90A324FA, 0x62C8A7F9, 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+ 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 0x3CDB9BDD, 0xCEB018DE,
+ 0xDDE0EB2A, 0x2F8B6829, 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+ 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, 0x082F63B7, 0xFA44E0B4,
+ 0xE9141340, 0x1B7F9043, 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+ 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 0x55326B08, 0xA759E80B,
+ 0xB4091BFF, 0x466298FC, 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+ 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, 0xA24BB5A6, 0x502036A5,
+ 0x4370C551, 0xB11B4652, 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+ 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 0xEF087A76, 0x1D63F975,
+ 0x0E330A81, 0xFC588982, 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+ 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, 0x38CC2A06, 0xCAA7A905,
+ 0xD9F75AF1, 0x2B9CD9F2, 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+ 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 0x0417B1DB, 0xF67C32D8,
+ 0xE52CC12C, 0x1747422F, 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+ 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, 0xD3D3E1AB, 0x21B862A8,
+ 0x32E8915C, 0xC083125F, 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+ 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 0x9E902E7B, 0x6CFBAD78,
+ 0x7FAB5E8C, 0x8DC0DD8F, 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+ 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, 0x69E9F0D5, 0x9B8273D6,
+ 0x88D28022, 0x7AB90321, 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+ 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 0x34F4F86A, 0xC69F7B69,
+ 0xD5CF889D, 0x27A40B9E, 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+ 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351,
+},
+{
+ 0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899, 0x4E8A61DC, 0x5D28F9AB,
+ 0x69CF5132, 0x7A6DC945, 0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
+ 0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD, 0x3FC5F181, 0x2C6769F6,
+ 0x1880C16F, 0x0B225918, 0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
+ 0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0, 0xEC5B53E5, 0xFFF9CB92,
+ 0xCB1E630B, 0xD8BCFB7C, 0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
+ 0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47, 0xE29F20BA, 0xF13DB8CD,
+ 0xC5DA1054, 0xD6788823, 0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
+ 0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A, 0x0EC4735F, 0x1D66EB28,
+ 0x298143B1, 0x3A23DBC6, 0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
+ 0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E, 0xFF17C604, 0xECB55E73,
+ 0xD852F6EA, 0xCBF06E9D, 0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
+ 0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25, 0x2C896460, 0x3F2BFC17,
+ 0x0BCC548E, 0x186ECCF9, 0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
+ 0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0, 0x5DC6F43D, 0x4E646C4A,
+ 0x7A83C4D3, 0x69215CA4, 0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
+ 0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F, 0xCE1644DA, 0xDDB4DCAD,
+ 0xE9537434, 0xFAF1EC43, 0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
+ 0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB, 0xBF59D487, 0xACFB4CF0,
+ 0x981CE469, 0x8BBE7C1E, 0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
+ 0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6, 0x6CC776E3, 0x7F65EE94,
+ 0x4B82460D, 0x5820DE7A, 0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
+ 0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC, 0x66D73941, 0x7575A136,
+ 0x419209AF, 0x523091D8, 0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
+ 0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1, 0x8A8C6AA4, 0x992EF2D3,
+ 0xADC95A4A, 0xBE6BC23D, 0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
+ 0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185, 0x844819FB, 0x97EA818C,
+ 0xA30D2915, 0xB0AFB162, 0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
+ 0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA, 0x57D6BB9F, 0x447423E8,
+ 0x70938B71, 0x63311306, 0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
+ 0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F, 0x26992BC2, 0x353BB3B5,
+ 0x01DC1B2C, 0x127E835B, 0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
+ 0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464, 0x4A5E5D21, 0x59FCC556,
+ 0x6D1B6DCF, 0x7EB9F5B8, 0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
+ 0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600, 0x3B11CD7C, 0x28B3550B,
+ 0x1C54FD92, 0x0FF665E5, 0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
+ 0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D, 0xE88F6F18, 0xFB2DF76F,
+ 0xCFCA5FF6, 0xDC68C781, 0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
+ 0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA, 0xE64B1C47, 0xF5E98430,
+ 0xC10E2CA9, 0xD2ACB4DE, 0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
+ 0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7, 0x0A104FA2, 0x19B2D7D5,
+ 0x2D557F4C, 0x3EF7E73B, 0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
+ 0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483,
+},
+{
+ 0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073, 0x9EDEA41A, 0x3B9F3664,
+ 0xD1B1F617, 0x74F06469, 0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
+ 0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC, 0x70A27D8A, 0xD5E3EFF4,
+ 0x3FCD2F87, 0x9A8CBDF9, 0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
+ 0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C, 0xD62DE755, 0x736C752B,
+ 0x9942B558, 0x3C032726, 0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
+ 0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D, 0xD915C5D1, 0x7C5457AF,
+ 0x967A97DC, 0x333B05A2, 0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
+ 0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED, 0x0F382284, 0xAA79B0FA,
+ 0x40577089, 0xE516E2F7, 0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
+ 0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32, 0xC76580D9, 0x622412A7,
+ 0x880AD2D4, 0x2D4B40AA, 0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
+ 0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F, 0x61EA1A06, 0xC4AB8878,
+ 0x2E85480B, 0x8BC4DA75, 0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
+ 0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A, 0x8F96C396, 0x2AD751E8,
+ 0xC0F9919B, 0x65B803E5, 0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
+ 0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE, 0xB8FFDFD7, 0x1DBE4DA9,
+ 0xF7908DDA, 0x52D11FA4, 0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
+ 0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161, 0x56830647, 0xF3C29439,
+ 0x19EC544A, 0xBCADC634, 0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
+ 0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1, 0xF00C9C98, 0x554D0EE6,
+ 0xBF63CE95, 0x1A225CEB, 0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
+ 0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A, 0xB3764986, 0x1637DBF8,
+ 0xFC191B8B, 0x595889F5, 0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
+ 0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA, 0x655BAED3, 0xC01A3CAD,
+ 0x2A34FCDE, 0x8F756EA0, 0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
+ 0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065, 0x6A638C57, 0xCF221E29,
+ 0x250CDE5A, 0x804D4C24, 0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
+ 0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1, 0xCCEC1688, 0x69AD84F6,
+ 0x83834485, 0x26C2D6FB, 0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
+ 0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4, 0x2290CF18, 0x87D15D66,
+ 0x6DFF9D15, 0xC8BE0F6B, 0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
+ 0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9, 0xD29C5380, 0x77DDC1FE,
+ 0x9DF3018D, 0x38B293F3, 0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
+ 0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36, 0x3CE08A10, 0x99A1186E,
+ 0x738FD81D, 0xD6CE4A63, 0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
+ 0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6, 0x9A6F10CF, 0x3F2E82B1,
+ 0xD50042C2, 0x7041D0BC, 0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
+ 0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7, 0x9557324B, 0x3016A035,
+ 0xDA386046, 0x7F79F238, 0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
+ 0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177, 0x437AD51E, 0xE63B4760,
+ 0x0C158713, 0xA954156D, 0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
+ 0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8,
+},
+{
+ 0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939, 0x7B2231F3, 0xA6679B4B,
+ 0xC4451272, 0x1900B8CA, 0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
+ 0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C, 0xE964B13D, 0x34211B85,
+ 0x560392BC, 0x8B463804, 0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
+ 0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2, 0x6402E328, 0xB9474990,
+ 0xDB65C0A9, 0x06206A11, 0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
+ 0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41, 0x2161776D, 0xFC24DDD5,
+ 0x9E0654EC, 0x4343FE54, 0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
+ 0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F, 0x45639445, 0x98263EFD,
+ 0xFA04B7C4, 0x27411D7C, 0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
+ 0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A, 0xABA65FE7, 0x76E3F55F,
+ 0x14C17C66, 0xC984D6DE, 0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
+ 0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538, 0x26C00DF2, 0xFB85A74A,
+ 0x99A72E73, 0x44E284CB, 0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
+ 0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610, 0xB4868D3C, 0x69C32784,
+ 0x0BE1AEBD, 0xD6A40405, 0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
+ 0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255, 0x07A17A9F, 0xDAE4D027,
+ 0xB8C6591E, 0x6583F3A6, 0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
+ 0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040, 0x95E7FA51, 0x48A250E9,
+ 0x2A80D9D0, 0xF7C57368, 0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
+ 0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E, 0x1881A844, 0xC5C402FC,
+ 0xA7E68BC5, 0x7AA3217D, 0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
+ 0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5, 0xA4E4AAD9, 0x79A10061,
+ 0x1B838958, 0xC6C623E0, 0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
+ 0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B, 0xC0E649F1, 0x1DA3E349,
+ 0x7F816A70, 0xA2C4C0C8, 0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
+ 0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E, 0x8585DDB4, 0x58C0770C,
+ 0x3AE2FE35, 0xE7A7548D, 0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
+ 0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B, 0x08E38FA1, 0xD5A62519,
+ 0xB784AC20, 0x6AC10698, 0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
+ 0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443, 0x9AA50F6F, 0x47E0A5D7,
+ 0x25C22CEE, 0xF8878656, 0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
+ 0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1, 0x8224A72B, 0x5F610D93,
+ 0x3D4384AA, 0xE0062E12, 0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
+ 0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4, 0x106227E5, 0xCD278D5D,
+ 0xAF050464, 0x7240AEDC, 0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
+ 0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A, 0x9D0475F0, 0x4041DF48,
+ 0x22635671, 0xFF26FCC9, 0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
+ 0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99, 0xD867E1B5, 0x05224B0D,
+ 0x6700C234, 0xBA45688C, 0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
+ 0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57, 0xBC65029D, 0x6120A825,
+ 0x0302211C, 0xDE478BA4, 0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
+ 0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842,
+},
+{
+ 0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4, 0xE045BEB0, 0xD854D11C,
+ 0x906761E8, 0xA8760E44, 0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
+ 0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5, 0x8F2261D3, 0xB7330E7F,
+ 0xFF00BE8B, 0xC711D127, 0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
+ 0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6, 0xAA00D4F2, 0x9211BB5E,
+ 0xDA220BAA, 0xE2336406, 0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
+ 0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13, 0xDECFBEC6, 0xE6DED16A,
+ 0xAEED619E, 0x96FC0E32, 0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
+ 0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470, 0x74CF6A34, 0x4CDE0598,
+ 0x04EDB56C, 0x3CFCDAC0, 0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
+ 0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151, 0x37516AAE, 0x0F400502,
+ 0x4773B5F6, 0x7F62DA5A, 0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
+ 0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB, 0x1273DF8F, 0x2A62B023,
+ 0x625100D7, 0x5A406F7B, 0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
+ 0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539, 0x7D1400EC, 0x45056F40,
+ 0x0D36DFB4, 0x3527B018, 0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
+ 0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D, 0xCCBC6149, 0xF4AD0EE5,
+ 0xBC9EBE11, 0x848FD1BD, 0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
+ 0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C, 0xA3DBBE2A, 0x9BCAD186,
+ 0xD3F96172, 0xEBE80EDE, 0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
+ 0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F, 0x86F90B0B, 0xBEE864A7,
+ 0xF6DBD453, 0xCECABBFF, 0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
+ 0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18, 0xABC5DECD, 0x93D4B161,
+ 0xDBE70195, 0xE3F66E39, 0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
+ 0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B, 0x01C50A3F, 0x39D46593,
+ 0x71E7D567, 0x49F6BACB, 0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
+ 0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A, 0x750A600B, 0x4D1B0FA7,
+ 0x0528BF53, 0x3D39D0FF, 0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
+ 0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E, 0x5028D52A, 0x6839BA86,
+ 0x200A0A72, 0x181B65DE, 0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
+ 0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C, 0x3F4F0A49, 0x075E65E5,
+ 0x4F6DD511, 0x777CBABD, 0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
+ 0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06, 0xB9B60142, 0x81A76EEE,
+ 0xC994DE1A, 0xF185B1B6, 0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
+ 0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27, 0xD6D1DE21, 0xEEC0B18D,
+ 0xA6F30179, 0x9EE26ED5, 0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
+ 0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544, 0xF3F36B00, 0xCBE204AC,
+ 0x83D1B458, 0xBBC0DBF4, 0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
+ 0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1, 0x873C0134, 0xBF2D6E98,
+ 0xF71EDE6C, 0xCF0FB1C0, 0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
+ 0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82, 0x2D3CD5C6, 0x152DBA6A,
+ 0x5D1E0A9E, 0x650F6532, 0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
+ 0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3,
+},
+{
+ 0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA, 0xB2F53777, 0x5DC55C6E,
+ 0x697997B4, 0x8649FCAD, 0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
+ 0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2, 0xC00C303E, 0x2F3C5B27,
+ 0x1B8090FD, 0xF4B0FBE4, 0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
+ 0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB, 0x12FF1F56, 0xFDCF744F,
+ 0xC973BF95, 0x2643D48C, 0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
+ 0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20, 0xE5F20E92, 0x0AC2658B,
+ 0x3E7EAE51, 0xD14EC548, 0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
+ 0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69, 0xF70D11C4, 0x183D7ADD,
+ 0x2C81B107, 0xC3B1DA1E, 0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
+ 0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201, 0x0E045BEB, 0xE13430F2,
+ 0xD588FB28, 0x3AB89031, 0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
+ 0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E, 0xDCF77483, 0x33C71F9A,
+ 0x077BD440, 0xE84BBF59, 0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
+ 0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778, 0xAE0E73CA, 0x413E18D3,
+ 0x7582D309, 0x9AB2B810, 0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
+ 0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC, 0x39057A11, 0xD6351108,
+ 0xE289DAD2, 0x0DB9B1CB, 0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
+ 0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4, 0x4BFC7D58, 0xA4CC1641,
+ 0x9070DD9B, 0x7F40B682, 0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
+ 0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D, 0x990F5230, 0x763F3929,
+ 0x4283F2F3, 0xADB399EA, 0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
+ 0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B, 0x7C0EAFC9, 0x933EC4D0,
+ 0xA7820F0A, 0x48B26413, 0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
+ 0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32, 0x6EF1B09F, 0x81C1DB86,
+ 0xB57D105C, 0x5A4D7B45, 0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
+ 0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A, 0x99FCA15B, 0x76CCCA42,
+ 0x42700198, 0xAD406A81, 0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
+ 0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E, 0x4B0F8E33, 0xA43FE52A,
+ 0x90832EF0, 0x7FB345E9, 0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
+ 0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8, 0x39F6897A, 0xD6C6E263,
+ 0xE27A29B9, 0x0D4A42A0, 0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
+ 0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7, 0xA0F9DB4A, 0x4FC9B053,
+ 0x7B757B89, 0x94451090, 0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
+ 0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F, 0xD200DC03, 0x3D30B71A,
+ 0x098C7CC0, 0xE6BC17D9, 0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
+ 0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6, 0x00F3F36B, 0xEFC39872,
+ 0xDB7F53A8, 0x344F38B1, 0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
+ 0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D, 0xF7FEE2AF, 0x18CE89B6,
+ 0x2C72426C, 0xC3422975, 0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
+ 0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154, 0xE501FDF9, 0x0A3196E0,
+ 0x3E8D5D3A, 0xD1BD3623, 0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
+ 0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C,
+},
+{
+ 0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558, 0xA5E0C5D1, 0xCDE3E919,
+ 0x75E69C41, 0x1DE5B089, 0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
+ 0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA, 0x9C5BFAA6, 0xF458D66E,
+ 0x4C5DA336, 0x245E8FFE, 0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
+ 0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD, 0x7796C224, 0x1F95EEEC,
+ 0xA7909BB4, 0xCF93B77C, 0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
+ 0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334, 0x73767EEE, 0x1B755226,
+ 0xA370277E, 0xCB730BB6, 0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
+ 0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43, 0x04E0BCCA, 0x6CE39002,
+ 0xD4E6E55A, 0xBCE5C992, 0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
+ 0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1, 0x7AB7077A, 0x12B42BB2,
+ 0xAAB15EEA, 0xC2B27222, 0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
+ 0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71, 0x917A3FF8, 0xF9791330,
+ 0x417C6668, 0x297F4AA0, 0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
+ 0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55, 0xA8C1008F, 0xC0C22C47,
+ 0x78C7591F, 0x10C475D7, 0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
+ 0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F, 0xE20C4116, 0x8A0F6DDE,
+ 0x320A1886, 0x5A09344E, 0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
+ 0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D, 0xDBB77E61, 0xB3B452A9,
+ 0x0BB127F1, 0x63B20B39, 0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
+ 0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A, 0x307A46E3, 0x58796A2B,
+ 0xE07C1F73, 0x887F33BB, 0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
+ 0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D, 0xBB43F3A7, 0xD340DF6F,
+ 0x6B45AA37, 0x034686FF, 0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
+ 0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A, 0xCCD53183, 0xA4D61D4B,
+ 0x1CD36813, 0x74D044DB, 0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
+ 0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988, 0xC8358D49, 0xA036A181,
+ 0x1833D4D9, 0x7030F811, 0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
+ 0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542, 0x23F8B5CB, 0x4BFB9903,
+ 0xF3FEEC5B, 0x9BFDC093, 0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
+ 0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766, 0x1A438ABC, 0x7240A674,
+ 0xCA45D32C, 0xA246FFE4, 0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
+ 0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6, 0x2A39CC5F, 0x423AE097,
+ 0xFA3F95CF, 0x923CB907, 0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
+ 0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454, 0x1382F328, 0x7B81DFE0,
+ 0xC384AAB8, 0xAB878670, 0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
+ 0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23, 0xF84FCBAA, 0x904CE762,
+ 0x2849923A, 0x404ABEF2, 0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
+ 0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA, 0xFCAF7760, 0x94AC5BA8,
+ 0x2CA92EF0, 0x44AA0238, 0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
+ 0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD, 0x8B39B544, 0xE33A998C,
+ 0x5B3FECD4, 0x333CC01C, 0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
+ 0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F,
+},
+{
+ 0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769, 0x211D826D, 0x6821FF4A,
+ 0xB3657823, 0xFA590504, 0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
+ 0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE, 0x847609B4, 0xCD4A7493,
+ 0x160EF3FA, 0x5F328EDD, 0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
+ 0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07, 0xE7508F03, 0xAE6CF224,
+ 0x7528754D, 0x3C14086A, 0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
+ 0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D, 0x4F3B6143, 0x06071C64,
+ 0xDD439B0D, 0x947FE62A, 0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
+ 0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44, 0xA86BEE40, 0xE1579367,
+ 0x3A13140E, 0x732F6929, 0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
+ 0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3, 0x1A00CB32, 0x533CB615,
+ 0x8878317C, 0xC1444C5B, 0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
+ 0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881, 0x79264D85, 0x301A30A2,
+ 0xEB5EB7CB, 0xA262CAEC, 0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
+ 0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782, 0xDC4DC65C, 0x9571BB7B,
+ 0x4E353C12, 0x07094135, 0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
+ 0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2, 0x361D2CC6, 0x7F2151E1,
+ 0xA465D688, 0xED59ABAF, 0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
+ 0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75, 0x9376A71F, 0xDA4ADA38,
+ 0x010E5D51, 0x48322076, 0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
+ 0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC, 0xF05021A8, 0xB96C5C8F,
+ 0x6228DBE6, 0x2B14A6C1, 0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
+ 0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360, 0x763A92BE, 0x3F06EF99,
+ 0xE44268F0, 0xAD7E15D7, 0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
+ 0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9, 0x916A1DBD, 0xD856609A,
+ 0x0312E7F3, 0x4A2E9AD4, 0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
+ 0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E, 0x3901F3FD, 0x703D8EDA,
+ 0xAB7909B3, 0xE2457494, 0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
+ 0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E, 0x5A27754A, 0x131B086D,
+ 0xC85F8F04, 0x8163F223, 0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
+ 0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D, 0xFF4CFE93, 0xB67083B4,
+ 0x6D3404DD, 0x240879FA, 0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
+ 0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F, 0x0F1CDF3B, 0x4620A21C,
+ 0x9D642575, 0xD4585852, 0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
+ 0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88, 0xAA7754E2, 0xE34B29C5,
+ 0x380FAEAC, 0x7133D38B, 0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
+ 0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751, 0xC951D255, 0x806DAF72,
+ 0x5B29281B, 0x1215553C, 0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
+ 0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB, 0x613A3C15, 0x28064132,
+ 0xF342C65B, 0xBA7EBB7C, 0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
+ 0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612, 0x866AB316, 0xCF56CE31,
+ 0x14124958, 0x5D2E347F, 0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
+ 0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5,
+} };
+
+#define DUMMY_CRC32_UPD(crc, n) \
+ (dummy_crc32c_tables[(n)][(crc) & 0xff] ^ \
+ dummy_crc32c_tables[(n) - 1][((crc) >> 8) & 0xff])
+
+static inline uint32_t dummy_crc32c_u32(uint32_t data, uint32_t init_val)
+{
+ uint32_t crc, term1, term2;
+
+ crc = init_val;
+ crc ^= data;
+
+ term1 = DUMMY_CRC32_UPD(crc, 3);
+ term2 = crc >> 16;
+ crc = term1 ^ DUMMY_CRC32_UPD(term2, 1);
+
+ return crc;
+}
+
+static inline uint32_t dummy_crc32c_u64(uint64_t data, uint32_t init_val)
+{
+ union {
+ uint64_t u64;
+ uint32_t u32[2];
+ } d;
+ d.u64 = data;
+
+ uint32_t crc, term1, term2;
+
+ crc = init_val;
+ crc ^= d.u32[0];
+
+ term1 = DUMMY_CRC32_UPD(crc, 7);
+ term2 = crc >> 16;
+ crc = term1 ^ DUMMY_CRC32_UPD(term2, 5);
+ term1 = DUMMY_CRC32_UPD(d.u32[1], 3);
+ term2 = d.u32[1] >> 16;
+ crc ^= term1 ^ DUMMY_CRC32_UPD(term2, 1);
+
+ return crc;
+}
+
+static inline uint32_t dummy_hash_crc32c(const void *data, uint32_t data_len,
+ uint32_t init_val)
+{
+ size_t i;
+ uint64_t temp = 0;
+ uintptr_t pd = (uintptr_t)data;
+
+ for (i = 0; i < data_len / 8; i++) {
+ init_val = dummy_crc32c_u64(*(const uint64_t *)pd, init_val);
+ pd += 8;
+ }
+
+ switch (7 - (data_len & 0x07)) {
+ case 0:
+ temp |= (uint64_t)*((const uint8_t *)pd + 6) << 48;
+ /* Fallthrough */
+ case 1:
+ temp |= (uint64_t)*((const uint8_t *)pd + 5) << 40;
+ /* Fallthrough */
+ case 2:
+ temp |= (uint64_t)*((const uint8_t *)pd + 4) << 32;
+ temp |= *(const uint32_t *)pd;
+ init_val = dummy_crc32c_u64(temp, init_val);
+ break;
+ case 3:
+ init_val = dummy_crc32c_u32(*(const uint32_t *)pd, init_val);
+ break;
+ case 4:
+ temp |= *((const uint8_t *)pd + 2) << 16;
+ /* Fallthrough */
+ case 5:
+ temp |= *((const uint8_t *)pd + 1) << 8;
+ /* Fallthrough */
+ case 6:
+ temp |= *(const uint8_t *)pd;
+ init_val = dummy_crc32c_u32(temp, init_val);
+ /* Fallthrough */
+ default:
+ break;
+ }
+
+ return init_val;
+}
diff --git a/test/common_plat/performance/odp_bench_packet.c b/test/common_plat/performance/odp_bench_packet.c
new file mode 100644
index 000000000..1aa9d819d
--- /dev/null
+++ b/test/common_plat/performance/odp_bench_packet.c
@@ -0,0 +1,1611 @@
+/* Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * @example odp_bench_packet.c Microbenchmarks for packet functions
+ */
+
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <signal.h>
+
+#include <test_debug.h>
+
+#include <odp_api.h>
+#include <odp/helper/threads.h>
+#include <odp/helper/eth.h>
+#include <odp/helper/ip.h>
+#include <odp/helper/udp.h>
+
+/** Minimum number of packet data bytes in the first segment */
+#define PKT_POOL_SEG_LEN 128
+
+/** Packet user area size in bytes */
+#define PKT_POOL_UAREA_SIZE 8
+
+/** Minimum test packet size */
+#define TEST_MIN_PKT_SIZE 64
+
+/** Maximum test packet size */
+#define TEST_MAX_PKT_SIZE 2048
+
+/** Number of test runs per individual benchmark */
+#define TEST_REPEAT_COUNT 1000
+
+/** Number of times to run tests for each packet size */
+#define TEST_SIZE_RUN_COUNT 10
+
+/** Maximum burst size for *_multi operations */
+#define TEST_MAX_BURST 64
+
+/** Offset of the contiguous area */
+#define TEST_ALIGN_OFFSET 16
+
+/** Length of the contiguous area */
+#define TEST_ALIGN_LEN 32
+
+/** Minimum byte alignment of contiguous area */
+#define TEST_ALIGN 32
+
+/** Test packet offsets */
+#define TEST_L2_OFFSET 0
+#define TEST_L3_OFFSET (TEST_MIN_PKT_SIZE / 4)
+#define TEST_L4_OFFSET (TEST_MIN_PKT_SIZE / 2)
+
+/** Default burst size for *_multi operations */
+#define TEST_DEF_BURST 8
+
+/** Get rid of path in filename - only for unix-type paths using '/' */
+#define NO_PATH(file_name) (strrchr((file_name), '/') ? \
+ strrchr((file_name), '/') + 1 : (file_name))
+
+#define BENCH_INFO(run, init, term, name) \
+ {#run, run, init, term, name}
+
+ODP_STATIC_ASSERT((TEST_ALIGN_OFFSET + TEST_ALIGN_LEN) <= TEST_MIN_PKT_SIZE,
+ "Invalid_alignment");
+
+/** Warm up round packet size */
+#define WARM_UP TEST_MIN_PKT_SIZE
+
+/** Test packet sizes */
+const uint32_t test_packet_len[] = {WARM_UP, TEST_MIN_PKT_SIZE, 128, 256, 512,
+ 1024, 1518, TEST_MAX_PKT_SIZE};
+
+/**
+ * Parsed command line arguments
+ */
+typedef struct {
+ int bench_idx; /** Benchmark index to run indefinitely */
+ int burst_size; /** Burst size for *_multi operations */
+} appl_args_t;
+
+/**
+ * Initialize benchmark resources
+ */
+typedef void (*bench_init_fn_t)(void);
+
+/**
+ * Run benchmark
+ *
+ * @retval >0 on success
+ * */
+typedef int (*bench_run_fn_t)(void);
+
+/**
+ * Release benchmark resources
+ */
+typedef void (*bench_term_fn_t)(void);
+
+/**
+ * Benchmark data
+ */
+typedef struct {
+ const char *name;
+ bench_run_fn_t run;
+ bench_init_fn_t init;
+ bench_term_fn_t term;
+ const char *desc;
+} bench_info_t;
+
+/**
+ * Grouping of all global data
+ */
+typedef struct {
+ /** Application (parsed) arguments */
+ appl_args_t appl;
+ /** Packet pool */
+ odp_pool_t pool;
+ /** Benchmark functions */
+ bench_info_t *bench;
+ /** Number of benchmark functions */
+ int num_bench;
+ struct {
+ /** Test packet length */
+ uint32_t len;
+ /** Minimum test packet headroom */
+ uint32_t headroom;
+ /** Minimum test packet tailroom */
+ uint32_t tailroom;
+ /** Minimum test packet segment length */
+ uint32_t seg_len;
+ } pkt;
+ /** Array for storing test packets */
+ odp_packet_t pkt_tbl[TEST_REPEAT_COUNT * TEST_MAX_BURST];
+ /** Array for storing test packets */
+ odp_packet_t pkt2_tbl[TEST_REPEAT_COUNT];
+ /** Array for storing test event */
+ odp_event_t event_tbl[TEST_REPEAT_COUNT];
+ /** Array for storing test pointers */
+ void *ptr_tbl[TEST_REPEAT_COUNT];
+ /** Array for storing test segments */
+ odp_packet_seg_t seg_tbl[TEST_REPEAT_COUNT];
+ /** Array for storing test outputs */
+ uint32_t output_tbl[TEST_REPEAT_COUNT];
+ /** Array for storing test pool handles */
+ odp_pool_t pool_tbl[TEST_REPEAT_COUNT];
+ /** Array for storing test pktio handles */
+ odp_pktio_t pktio_tbl[TEST_REPEAT_COUNT];
+ /** Array for storing test timestamps */
+ odp_time_t ts_tbl[TEST_REPEAT_COUNT];
+ /** Array for storing test data */
+ uint8_t data_tbl[TEST_REPEAT_COUNT][TEST_MAX_PKT_SIZE];
+ /** Benchmark run failed */
+ uint8_t bench_failed;
+} args_t;
+
+/** Global pointer to args */
+static args_t *gbl_args;
+/** Global barrier to synchronize main and worker */
+static odp_barrier_t barrier;
+/** Break worker loop if set to 1 */
+static int exit_thread;
+
+static void sig_handler(int signo ODP_UNUSED)
+{
+ exit_thread = 1;
+}
+
+/**
+ * Run given benchmark indefinitely
+ */
+static void run_indef(args_t *args, int idx)
+{
+ const char *desc;
+
+ desc = args->bench[idx].desc != NULL ?
+ args->bench[idx].desc : args->bench[idx].name;
+
+ printf("Running %s() indefinitely\n", desc);
+
+ while (!exit_thread) {
+ int ret;
+
+ if (args->bench[idx].init != NULL)
+ args->bench[idx].init();
+
+ ret = args->bench[idx].run();
+
+ if (args->bench[idx].term != NULL)
+ args->bench[idx].term();
+
+ if (!ret)
+ LOG_ABORT("Benchmark %s failed\n", desc);
+ }
+}
+
+/**
+ * Master function for running the microbenchmarks
+ */
+static int run_benchmarks(void *arg)
+{
+ int i, j, k;
+ args_t *args = arg;
+ int num_sizes = sizeof(test_packet_len) / sizeof(test_packet_len[0]);
+ double results[gbl_args->num_bench][num_sizes];
+
+ memset(results, 0, sizeof(results));
+
+ printf("\nRunning benchmarks (cycles per call)\n"
+ "------------------------------------\n");
+
+ for (i = 0; i < num_sizes; i++) {
+ uint64_t tot_cycles = 0;
+
+ printf("\nPacket length: %6d bytes\n"
+ "---------------------------\n", test_packet_len[i]);
+
+ gbl_args->pkt.len = test_packet_len[i];
+
+ for (j = 0, k = 1; j < gbl_args->num_bench; k++) {
+ int ret;
+ uint64_t c1, c2;
+ const char *desc;
+
+ if (args->appl.bench_idx &&
+ (j + 1) != args->appl.bench_idx) {
+ j++;
+ continue;
+ } else if (args->appl.bench_idx &&
+ (j + 1) == args->appl.bench_idx) {
+ run_indef(args, j);
+ return 0;
+ }
+
+ desc = args->bench[j].desc != NULL ?
+ args->bench[j].desc :
+ args->bench[j].name;
+
+ if (args->bench[j].init != NULL)
+ args->bench[j].init();
+
+ c1 = odp_cpu_cycles();
+ ret = args->bench[j].run();
+ c2 = odp_cpu_cycles();
+
+ if (args->bench[j].term != NULL)
+ args->bench[j].term();
+
+ if (!ret) {
+ LOG_ERR("Benchmark %s failed\n", desc);
+ args->bench_failed = 1;
+ return -1;
+ }
+
+ tot_cycles += odp_cpu_cycles_diff(c2, c1);
+
+ if (k >= TEST_SIZE_RUN_COUNT) {
+ double cycles;
+
+ /** Each benchmark runs internally
+ * TEST_REPEAT_COUNT times. */
+ cycles = ((double)tot_cycles) /
+ (TEST_SIZE_RUN_COUNT *
+ TEST_REPEAT_COUNT);
+ results[j][i] = cycles;
+
+ printf("%-30s: %8.1f\n", desc, cycles);
+
+ j++;
+ k = 0;
+ tot_cycles = 0;
+ }
+ }
+ }
+ printf("\n%-30s", "Benchmark / packet_size [B]");
+ for (i = 0; i < num_sizes; i++) {
+ if (i == 0)
+ printf(" WARM UP ");
+ else
+ printf("%8.1d ", test_packet_len[i]);
+ }
+ printf("\n---------------------------------");
+ for (i = 0; i < num_sizes; i++)
+ printf("----------");
+
+ for (i = 0; i < gbl_args->num_bench; i++) {
+ printf("\n[%02d] %-30s", i + 1, args->bench[i].desc != NULL ?
+ args->bench[i].desc : args->bench[i].name);
+
+ for (j = 0; j < num_sizes; j++)
+ printf("%8.1f ", results[i][j]);
+ }
+ printf("\n\n");
+ return 0;
+}
+
+static void allocate_test_packets(uint32_t len, odp_packet_t pkt[], int num)
+{
+ int pkts = 0;
+
+ while (pkts < num) {
+ int ret;
+
+ ret = odp_packet_alloc_multi(gbl_args->pool, len, &pkt[pkts],
+ num - pkts);
+ if (ret < 0)
+ LOG_ABORT("Allocating test packets failed\n");
+
+ pkts += ret;
+ }
+}
+
+static void alloc_packets_half(void)
+{
+ allocate_test_packets(gbl_args->pkt.len / 2, gbl_args->pkt_tbl,
+ TEST_REPEAT_COUNT);
+}
+
+static void alloc_packets_multi(void)
+{
+ allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt_tbl,
+ TEST_REPEAT_COUNT * gbl_args->appl.burst_size);
+}
+
+static void alloc_concat_packets(void)
+{
+ allocate_test_packets(gbl_args->pkt.len / 2, gbl_args->pkt_tbl,
+ TEST_REPEAT_COUNT);
+ allocate_test_packets(gbl_args->pkt.len / 2, gbl_args->pkt2_tbl,
+ TEST_REPEAT_COUNT);
+}
+
+static void alloc_packets_twice(void)
+{
+ allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt_tbl,
+ TEST_REPEAT_COUNT);
+ allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt2_tbl,
+ TEST_REPEAT_COUNT);
+}
+
+static void create_packets(void)
+{
+ int i;
+ uint32_t headroom, tailroom, seg_len;
+ uint32_t min_headroom = 0;
+ uint32_t min_tailroom = 0;
+ uint32_t min_seg_len = 0;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ odp_packet_seg_t *seg_tbl = gbl_args->seg_tbl;
+
+ allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt_tbl,
+ TEST_REPEAT_COUNT);
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++) {
+ headroom = odp_packet_headroom(pkt_tbl[i]);
+ tailroom = odp_packet_tailroom(pkt_tbl[i]);
+ seg_len = odp_packet_seg_len(pkt_tbl[i]);
+
+ seg_tbl[i] = odp_packet_first_seg(pkt_tbl[i]);
+
+ if (i == 0) {
+ min_headroom = headroom;
+ min_tailroom = tailroom;
+ min_seg_len = seg_len;
+ } else {
+ if (headroom < min_headroom)
+ min_headroom = headroom;
+ if (tailroom < min_tailroom)
+ min_tailroom = tailroom;
+ if (seg_len < min_seg_len)
+ min_seg_len = seg_len;
+ }
+
+ if (odp_packet_l2_offset_set(pkt_tbl[i], TEST_L2_OFFSET) ||
+ odp_packet_l3_offset_set(pkt_tbl[i], TEST_L3_OFFSET) ||
+ odp_packet_l4_offset_set(pkt_tbl[i], TEST_L4_OFFSET))
+ LOG_ABORT("Setting test packet offsets failed\n");
+
+ odp_packet_flow_hash_set(pkt_tbl[i], i);
+ odp_packet_ts_set(pkt_tbl[i], odp_time_local());
+ }
+ gbl_args->pkt.headroom = min_headroom;
+ gbl_args->pkt.tailroom = min_tailroom;
+ gbl_args->pkt.seg_len = min_seg_len;
+}
+
+static void create_events(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ create_packets();
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->event_tbl[i] = odp_packet_to_event(pkt_tbl[i]);
+}
+
+static void free_packets(void)
+{
+ odp_packet_free_multi(gbl_args->pkt_tbl, TEST_REPEAT_COUNT);
+}
+
+static void free_packets_multi(void)
+{
+ odp_packet_free_multi(gbl_args->pkt_tbl,
+ TEST_REPEAT_COUNT * gbl_args->appl.burst_size);
+}
+
+static void free_packets_twice(void)
+{
+ odp_packet_free_multi(gbl_args->pkt_tbl, TEST_REPEAT_COUNT);
+ odp_packet_free_multi(gbl_args->pkt2_tbl, TEST_REPEAT_COUNT);
+}
+
+static int bench_empty(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->output_tbl[i] = i;
+
+ return i;
+}
+
+static int bench_packet_alloc(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++) {
+ odp_packet_t pkt;
+
+ pkt = odp_packet_alloc(gbl_args->pool, gbl_args->pkt.len);
+
+ gbl_args->pkt_tbl[i] = pkt;
+ }
+
+ return i;
+}
+
+static int bench_packet_alloc_multi(void)
+{
+ int i;
+ int pkts = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ pkts += odp_packet_alloc_multi(gbl_args->pool,
+ gbl_args->pkt.len,
+ &gbl_args->pkt_tbl[pkts],
+ gbl_args->appl.burst_size);
+ return pkts;
+}
+
+static int bench_packet_free(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ odp_packet_free(gbl_args->pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_free_multi(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++) {
+ int pkt_idx = i * gbl_args->appl.burst_size;
+
+ odp_packet_free_multi(&gbl_args->pkt_tbl[pkt_idx],
+ gbl_args->appl.burst_size);
+ }
+ return i;
+}
+
+static int bench_packet_alloc_free(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++) {
+ odp_packet_t pkt;
+
+ pkt = odp_packet_alloc(gbl_args->pool, gbl_args->pkt.len);
+
+ odp_packet_free(pkt);
+ }
+ return i;
+}
+
+static int bench_packet_alloc_free_multi(void)
+{
+ int i;
+ int pkts;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++) {
+ pkts = odp_packet_alloc_multi(gbl_args->pool, gbl_args->pkt.len,
+ gbl_args->pkt_tbl,
+ gbl_args->appl.burst_size);
+ odp_packet_free_multi(gbl_args->pkt_tbl, pkts);
+ }
+ return i;
+}
+
+static int bench_packet_reset(void)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_reset(gbl_args->pkt_tbl[i],
+ gbl_args->pkt.len);
+ return !ret;
+}
+
+static int bench_packet_from_event(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ pkt_tbl[i] = odp_packet_from_event(gbl_args->event_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_to_event(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->event_tbl[i] = odp_packet_to_event(pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_head(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_head(gbl_args->pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_buf_len(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_buf_len(gbl_args->pkt_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_data(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_data(gbl_args->pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_seg_len(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_seg_len(gbl_args->pkt_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_len(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_len(gbl_args->pkt_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_headroom(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_headroom(gbl_args->pkt_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_tailroom(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_tailroom(gbl_args->pkt_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_tail(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_tail(gbl_args->pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_offset(void)
+{
+ int i;
+ uint32_t offset = gbl_args->pkt.len / 2;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_offset(gbl_args->pkt_tbl[i],
+ offset, NULL, NULL);
+ return i;
+}
+
+static int bench_packet_prefetch(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ odp_packet_prefetch(gbl_args->pkt_tbl[i], 0, gbl_args->pkt.len);
+
+ return i;
+}
+
+static int bench_packet_push_head(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ uint32_t hroom = gbl_args->pkt.headroom;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_push_head(pkt_tbl[i], hroom);
+
+ return i;
+}
+
+static int bench_packet_pull_head(void)
+{
+ int i;
+ uint32_t len = gbl_args->pkt.seg_len - 1;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_pull_head(pkt_tbl[i], len);
+
+ return i;
+}
+
+static int bench_packet_push_tail(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ uint32_t troom = gbl_args->pkt.tailroom;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_push_tail(pkt_tbl[i], troom);
+
+ return i;
+}
+
+static int bench_packet_pull_tail(void)
+{
+ int i;
+ uint32_t len = gbl_args->pkt.seg_len - 1;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_pull_tail(pkt_tbl[i], len);
+
+ return i;
+}
+
+static int bench_packet_extend_head(void)
+{
+ int i;
+ int ret = 0;
+ uint32_t len = gbl_args->pkt.len / 2;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ void **ptr_tbl = gbl_args->ptr_tbl;
+ uint32_t *data_tbl = gbl_args->output_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_extend_head(&pkt_tbl[i], len, ptr_tbl[i],
+ &data_tbl[i]);
+ return ret >= 0;
+}
+
+static int bench_packet_trunc_head(void)
+{
+ int i;
+ int ret = 0;
+ uint32_t len = gbl_args->pkt.len / 2;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ void **ptr_tbl = gbl_args->ptr_tbl;
+ uint32_t *data_tbl = gbl_args->output_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_trunc_head(&pkt_tbl[i], len, ptr_tbl[i],
+ &data_tbl[i]);
+ return ret >= 0;
+}
+
+static int bench_packet_extend_tail(void)
+{
+ int i;
+ int ret = 0;
+ uint32_t len = gbl_args->pkt.len / 2;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ void **ptr_tbl = gbl_args->ptr_tbl;
+ uint32_t *data_tbl = gbl_args->output_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_extend_tail(&pkt_tbl[i], len, ptr_tbl[i],
+ &data_tbl[i]);
+ return ret >= 0;
+}
+
+static int bench_packet_trunc_tail(void)
+{
+ int i;
+ int ret = 0;
+ uint32_t len = gbl_args->pkt.len / 2;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ void **ptr_tbl = gbl_args->ptr_tbl;
+ uint32_t *data_tbl = gbl_args->output_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_trunc_tail(&pkt_tbl[i], len, ptr_tbl[i],
+ &data_tbl[i]);
+ return ret >= 0;
+}
+
+static int bench_packet_add_data(void)
+{
+ int i;
+ int ret = 0;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ uint32_t len = gbl_args->pkt.len / 2;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_add_data(&pkt_tbl[i], 0, len);
+
+ return ret >= 0;
+}
+
+static int bench_packet_rem_data(void)
+{
+ int i;
+ int ret = 0;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ uint32_t len = gbl_args->pkt.len / 2;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_rem_data(&pkt_tbl[i], 0, len);
+
+ return ret >= 0;
+}
+
+static int bench_packet_align(void)
+{
+ int i;
+ int ret = 0;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_align(&pkt_tbl[i], TEST_ALIGN_OFFSET,
+ TEST_ALIGN_LEN, TEST_ALIGN);
+ return ret >= 0;
+}
+
+static int bench_packet_is_segmented(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_is_segmented(gbl_args->pkt_tbl[i]);
+
+ return (ret == 0) ? 1 : ret;
+}
+
+static int bench_packet_num_segs(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_num_segs(gbl_args->pkt_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_first_seg(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->seg_tbl[i] = odp_packet_first_seg(pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_last_seg(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->seg_tbl[i] = odp_packet_last_seg(pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_next_seg(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ odp_packet_seg_t *seg_tbl = gbl_args->seg_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->seg_tbl[i] = odp_packet_next_seg(pkt_tbl[i],
+ seg_tbl[i]);
+ return i;
+}
+
+static int bench_packet_seg_data(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ odp_packet_seg_t *seg_tbl = gbl_args->seg_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_seg_data(pkt_tbl[i],
+ seg_tbl[i]);
+ return i;
+}
+
+static int bench_packet_seg_data_len(void)
+{
+ int i;
+ uint32_t ret = 0;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ odp_packet_seg_t *seg_tbl = gbl_args->seg_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_seg_data_len(pkt_tbl[i], seg_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_concat(void)
+{
+ int i;
+ int ret = 0;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ odp_packet_t *frag_tbl = gbl_args->pkt2_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_concat(&pkt_tbl[i], frag_tbl[i]);
+
+ return ret >= 0;
+}
+
+static int bench_packet_split(void)
+{
+ int i;
+ int ret = 0;
+ uint32_t head_len;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ odp_packet_t *frag_tbl = gbl_args->pkt2_tbl;
+
+ head_len = odp_packet_len(pkt_tbl[0]) / 2;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_split(&pkt_tbl[i], head_len, &frag_tbl[i]);
+
+ return ret >= 0;
+}
+
+static int bench_packet_copy(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ odp_packet_t *cpy_tbl = gbl_args->pkt2_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ cpy_tbl[i] = odp_packet_copy(pkt_tbl[i], gbl_args->pool);
+
+ return i;
+}
+
+static int bench_packet_copy_part(void)
+{
+ int i;
+ uint32_t len = gbl_args->pkt.len / 2;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+ odp_packet_t *cpy_tbl = gbl_args->pkt2_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ cpy_tbl[i] = odp_packet_copy_part(pkt_tbl[i], 0, len,
+ gbl_args->pool);
+ return i;
+}
+
+static int bench_packet_copy_to_mem(void)
+{
+ int i;
+ uint32_t ret = 0;
+ uint32_t len = gbl_args->pkt.len;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_copy_to_mem(pkt_tbl[i], 0, len,
+ gbl_args->data_tbl[i]);
+ return !ret;
+}
+
+static int bench_packet_copy_from_mem(void)
+{
+ int i;
+ uint32_t ret = 0;
+ uint32_t len = gbl_args->pkt.len;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_copy_from_mem(pkt_tbl[i], 0, len,
+ gbl_args->data_tbl[i]);
+ return !ret;
+}
+
+static int bench_packet_copy_from_pkt(void)
+{
+ int i;
+ uint32_t ret = 0;
+ uint32_t len = gbl_args->pkt.len;
+ odp_packet_t *dst_tbl = gbl_args->pkt_tbl;
+ odp_packet_t *src_tbl = gbl_args->pkt2_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_copy_from_pkt(dst_tbl[i], 0, src_tbl[i], 0,
+ len);
+ return !ret;
+}
+
+static int bench_packet_copy_data(void)
+{
+ int i;
+ uint32_t ret = 0;
+ uint32_t len = gbl_args->pkt.len / 2;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_copy_data(pkt_tbl[i], 0, len, len);
+
+ return !ret;
+}
+
+static int bench_packet_move_data(void)
+{
+ int i;
+ uint32_t ret = 0;
+ uint32_t len = gbl_args->pkt.len / 2;
+ uint32_t offset = len / 2;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_move_data(pkt_tbl[i], offset, len, len);
+
+ return !ret;
+}
+
+static int bench_packet_pool(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->pool_tbl[i] = odp_packet_pool(gbl_args->pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_input(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->pktio_tbl[i] = odp_packet_input(gbl_args->pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_input_index(void)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_input_index(gbl_args->pkt_tbl[i]);
+
+ return (ret == 0) ? 1 : ret;
+}
+
+static int bench_packet_user_ptr(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_user_ptr(pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_user_ptr_set(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ odp_packet_user_ptr_set(gbl_args->pkt_tbl[i],
+ gbl_args->ptr_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_user_area(void)
+{
+ int i;
+ odp_packet_t *pkt_tbl = gbl_args->pkt_tbl;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_user_area(pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_user_area_size(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_user_area_size(gbl_args->pkt_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_l2_ptr(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_l2_ptr(gbl_args->pkt_tbl[i],
+ NULL);
+ return i;
+}
+
+static int bench_packet_l2_offset(void)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_l2_offset(gbl_args->pkt_tbl[i]);
+
+ return ret >= 0;
+}
+
+static int bench_packet_l2_offset_set(void)
+{
+ int i;
+ uint32_t ret = 0;
+ uint32_t offset = gbl_args->pkt.len / 2;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_l2_offset_set(gbl_args->pkt_tbl[i], offset);
+
+ return !ret;
+}
+
+static int bench_packet_l3_ptr(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_l3_ptr(gbl_args->pkt_tbl[i],
+ NULL);
+ return i;
+}
+
+static int bench_packet_l3_offset(void)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_l3_offset(gbl_args->pkt_tbl[i]);
+
+ return ret >= 0;
+}
+
+static int bench_packet_l3_offset_set(void)
+{
+ int i;
+ uint32_t ret = 0;
+ uint32_t offset = gbl_args->pkt.len / 2;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_l3_offset_set(gbl_args->pkt_tbl[i], offset);
+
+ return !ret;
+}
+
+static int bench_packet_l4_ptr(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ptr_tbl[i] = odp_packet_l4_ptr(gbl_args->pkt_tbl[i],
+ NULL);
+ return i;
+}
+
+static int bench_packet_l4_offset(void)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_l4_offset(gbl_args->pkt_tbl[i]);
+
+ return ret >= 0;
+}
+
+static int bench_packet_l4_offset_set(void)
+{
+ int i;
+ uint32_t ret = 0;
+ uint32_t offset = gbl_args->pkt.len / 2;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_l4_offset_set(gbl_args->pkt_tbl[i], offset);
+
+ return !ret;
+}
+
+static int bench_packet_flow_hash(void)
+{
+ int i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ ret += odp_packet_flow_hash(gbl_args->pkt_tbl[i]);
+
+ return ret;
+}
+
+static int bench_packet_flow_hash_set(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ odp_packet_flow_hash_set(gbl_args->pkt_tbl[i], i);
+
+ return i;
+}
+
+static int bench_packet_ts(void)
+{
+ int i;
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ gbl_args->ts_tbl[i] = odp_packet_ts(gbl_args->pkt_tbl[i]);
+
+ return i;
+}
+
+static int bench_packet_ts_set(void)
+{
+ int i;
+ odp_time_t ts = odp_time_local();
+
+ for (i = 0; i < TEST_REPEAT_COUNT; i++)
+ odp_packet_ts_set(gbl_args->pkt_tbl[i], ts);
+
+ return i;
+}
+
+/**
+ * Prinf usage information
+ */
+static void usage(char *progname)
+{
+ printf("\n"
+ "OpenDataPlane Packet function microbenchmark.\n"
+ "\n"
+ "Usage: %s OPTIONS\n"
+ " E.g. %s\n"
+ "\n"
+ "Optional OPTIONS:\n"
+ " -b, --burst Test packet burst size.\n"
+ " -i, --index Benchmark index to run indefinitely.\n"
+ " -h, --help Display help and exit.\n\n"
+ "\n", NO_PATH(progname), NO_PATH(progname));
+}
+
+/**
+ * Parse and store the command line arguments
+ *
+ * @param argc argument count
+ * @param argv[] argument vector
+ * @param appl_args Store application arguments here
+ */
+static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
+{
+ int opt;
+ int long_index;
+ static const struct option longopts[] = {
+ {"burst", required_argument, NULL, 'b'},
+ {"help", no_argument, NULL, 'h'},
+ {"index", required_argument, NULL, 'i'},
+ {NULL, 0, NULL, 0}
+ };
+
+ static const char *shortopts = "b:i:h";
+
+ /* Let helper collect its own arguments (e.g. --odph_proc) */
+ odph_parse_options(argc, argv, shortopts, longopts);
+
+ opterr = 0; /* Do not issue errors on helper options */
+
+ appl_args->bench_idx = 0; /* Run all benchmarks */
+ appl_args->burst_size = TEST_DEF_BURST;
+
+ while (1) {
+ opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
+
+ if (opt == -1)
+ break; /* No more options */
+
+ switch (opt) {
+ case 'b':
+ appl_args->burst_size = atoi(optarg);
+ break;
+ case 'h':
+ usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ break;
+ case 'i':
+ appl_args->bench_idx = atoi(optarg);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (appl_args->burst_size < 1 ||
+ appl_args->burst_size > TEST_MAX_BURST) {
+ printf("Invalid burst size (max %d)\n", TEST_MAX_BURST);
+ exit(EXIT_FAILURE);
+ }
+
+ optind = 1; /* Reset 'extern optind' from the getopt lib */
+}
+
+/**
+ * Print system and application info
+ */
+static void print_info(char *progname, appl_args_t *appl_args ODP_UNUSED)
+{
+ printf("\n"
+ "ODP system info\n"
+ "---------------\n"
+ "ODP API version: %s\n"
+ "ODP impl name: %s\n"
+ "CPU model: %s\n"
+ "CPU freq (hz): %" PRIu64 "\n"
+ "Cache line size: %i\n"
+ "CPU count: %i\n"
+ "\n",
+ odp_version_api_str(), odp_version_impl_name(),
+ odp_cpu_model_str(), odp_cpu_hz_max(),
+ odp_sys_cache_line_size(), odp_cpu_count());
+
+ printf("Running ODP appl: \"%s\"\n"
+ "-----------------\n", progname);
+ fflush(NULL);
+}
+
+/**
+ * Test functions
+ */
+bench_info_t test_suite[] = {
+ BENCH_INFO(bench_empty, NULL, NULL, NULL),
+ BENCH_INFO(bench_packet_alloc, NULL, free_packets, NULL),
+ BENCH_INFO(bench_packet_alloc_multi, NULL, free_packets_multi,
+ NULL),
+ BENCH_INFO(bench_packet_free, create_packets, NULL, NULL),
+ BENCH_INFO(bench_packet_free_multi, alloc_packets_multi, NULL,
+ NULL),
+ BENCH_INFO(bench_packet_alloc_free, NULL, NULL, NULL),
+ BENCH_INFO(bench_packet_alloc_free_multi, NULL, NULL, NULL),
+ BENCH_INFO(bench_packet_reset, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_from_event, create_events, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_to_event, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_head, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_buf_len, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_data, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_seg_len, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_len, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_headroom, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_tailroom, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_tail, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_offset, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_prefetch, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_push_head, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_pull_head, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_push_tail, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_pull_tail, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_extend_head, alloc_packets_half,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_trunc_head, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_extend_tail, alloc_packets_half,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_trunc_tail, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_add_data, alloc_packets_half,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_rem_data, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_align, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_is_segmented, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_num_segs, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_first_seg, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_last_seg, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_next_seg, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_seg_data, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_seg_data_len, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_concat, alloc_concat_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_split, create_packets,
+ free_packets_twice, NULL),
+ BENCH_INFO(bench_packet_copy, create_packets,
+ free_packets_twice, NULL),
+ BENCH_INFO(bench_packet_copy_part, create_packets,
+ free_packets_twice, NULL),
+ BENCH_INFO(bench_packet_copy_to_mem, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_copy_from_mem, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_copy_from_pkt, alloc_packets_twice,
+ free_packets_twice, NULL),
+ BENCH_INFO(bench_packet_copy_data, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_move_data, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_pool, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_input, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_input_index, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_user_ptr, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_user_ptr_set, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_user_area, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_user_area_size, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_l2_ptr, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_l2_offset, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_l2_offset_set, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_l3_ptr, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_l3_offset, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_l3_offset_set, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_l4_ptr, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_l4_offset, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_l4_offset_set, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_flow_hash, create_packets, free_packets,
+ NULL),
+ BENCH_INFO(bench_packet_flow_hash_set, create_packets,
+ free_packets, NULL),
+ BENCH_INFO(bench_packet_ts, create_packets, free_packets, NULL),
+ BENCH_INFO(bench_packet_ts_set, create_packets, free_packets,
+ NULL),
+};
+
+/**
+ * ODP packet microbenchmark application
+ */
+int main(int argc, char *argv[])
+{
+ odph_odpthread_t worker_thread;
+ int cpu;
+ odp_shm_t shm;
+ odp_cpumask_t cpumask;
+ char cpumaskstr[ODP_CPUMASK_STR_SIZE];
+ odp_pool_capability_t capa;
+ odp_pool_param_t params;
+ odp_instance_t instance;
+ uint32_t pkt_num;
+ uint8_t ret;
+
+ /* Init ODP before calling anything else */
+ if (odp_init_global(&instance, NULL, NULL)) {
+ LOG_ERR("Error: ODP global init failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Init this thread */
+ if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
+ LOG_ERR("Error: ODP local init failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Reserve memory for args from shared mem */
+ shm = odp_shm_reserve("shm_args", sizeof(args_t),
+ ODP_CACHE_LINE_SIZE, 0);
+
+ if (shm == ODP_SHM_INVALID) {
+ LOG_ERR("Error: shared mem reserve failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ gbl_args = odp_shm_addr(shm);
+
+ if (gbl_args == NULL) {
+ LOG_ERR("Error: shared mem alloc failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(gbl_args, 0, sizeof(args_t));
+
+ gbl_args->bench = test_suite;
+ gbl_args->num_bench = sizeof(test_suite) / sizeof(test_suite[0]);
+
+ /* Parse and store the application arguments */
+ parse_args(argc, argv, &gbl_args->appl);
+
+ /* Print both system and application information */
+ print_info(NO_PATH(argv[0]), &gbl_args->appl);
+
+ /* Get default worker cpumask */
+ if (odp_cpumask_default_worker(&cpumask, 1) != 1) {
+ LOG_ERR("Error: unable to allocate worker thread.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));
+
+ /* Check pool capability */
+ if (odp_pool_capability(&capa)) {
+ LOG_ERR("Error: unable to query pool capability.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* At least 2 x TEST_REPEAT_COUNT packets required */
+ pkt_num = (gbl_args->appl.burst_size > 2) ?
+ gbl_args->appl.burst_size * TEST_REPEAT_COUNT :
+ 2 * TEST_REPEAT_COUNT;
+
+ if (capa.pkt.max_num && capa.pkt.max_num < pkt_num) {
+ LOG_ERR("Error: packet pool size not supported.\n");
+ printf("MAX: %" PRIu32 "\n", capa.pkt.max_num);
+ exit(EXIT_FAILURE);
+ } else if (capa.pkt.max_len && capa.pkt.max_len < TEST_MAX_PKT_SIZE) {
+ LOG_ERR("Error: packet length not supported.\n");
+ exit(EXIT_FAILURE);
+ } else if (capa.pkt.max_seg_len &&
+ capa.pkt.max_seg_len < PKT_POOL_SEG_LEN) {
+ LOG_ERR("Error: segment length not supported.\n");
+ exit(EXIT_FAILURE);
+ } else if (capa.pkt.max_uarea_size &&
+ capa.pkt.max_uarea_size < PKT_POOL_UAREA_SIZE) {
+ LOG_ERR("Error: user area size not supported.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Create packet pool */
+ odp_pool_param_init(&params);
+ params.pkt.seg_len = PKT_POOL_SEG_LEN;
+ params.pkt.len = TEST_MAX_PKT_SIZE;
+ params.pkt.num = pkt_num;
+ params.pkt.uarea_size = PKT_POOL_UAREA_SIZE;
+ params.type = ODP_POOL_PACKET;
+
+ gbl_args->pool = odp_pool_create("packet pool", &params);
+
+ if (gbl_args->pool == ODP_POOL_INVALID) {
+ LOG_ERR("Error: packet pool create failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("CPU: %i\n", odp_cpumask_first(&cpumask));
+ printf("CPU mask: %s\n", cpumaskstr);
+ printf("Burst size: %d\n", gbl_args->appl.burst_size);
+ printf("Bench repeat: %d\n", TEST_REPEAT_COUNT);
+
+ odp_pool_print(gbl_args->pool);
+
+ memset(&worker_thread, 0, sizeof(odph_odpthread_t));
+
+ odp_barrier_init(&barrier, 1 + 1);
+
+ signal(SIGINT, sig_handler);
+
+ /* Create worker threads */
+ cpu = odp_cpumask_first(&cpumask);
+
+ odp_cpumask_t thd_mask;
+ odph_odpthread_params_t thr_params;
+
+ memset(&thr_params, 0, sizeof(thr_params));
+ thr_params.start = run_benchmarks;
+ thr_params.arg = gbl_args;
+ thr_params.thr_type = ODP_THREAD_WORKER;
+ thr_params.instance = instance;
+
+ odp_cpumask_zero(&thd_mask);
+ odp_cpumask_set(&thd_mask, cpu);
+ odph_odpthreads_create(&worker_thread, &thd_mask,
+ &thr_params);
+
+ odph_odpthreads_join(&worker_thread);
+
+ ret = gbl_args->bench_failed;
+
+ if (odp_pool_destroy(gbl_args->pool)) {
+ LOG_ERR("Error: pool destroy\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_shm_free(shm)) {
+ LOG_ERR("Error: shm free\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_term_local()) {
+ LOG_ERR("Error: term local\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_term_global(instance)) {
+ LOG_ERR("Error: term global\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return ret;
+}
diff --git a/test/common_plat/performance/odp_crypto.c b/test/common_plat/performance/odp_crypto.c
index 993628830..954bdb794 100644
--- a/test/common_plat/performance/odp_crypto.c
+++ b/test/common_plat/performance/odp_crypto.c
@@ -17,7 +17,7 @@
#include <sys/resource.h>
#include <odp_api.h>
-#include <odp/helper/linux.h>
+#include <odp/helper/odph_api.h>
#define app_err(fmt, ...) \
fprintf(stderr, "%s:%d:%s(): Error: " fmt, __FILE__, \
diff --git a/test/common_plat/performance/odp_l2fwd.c b/test/common_plat/performance/odp_l2fwd.c
index 82c3a251f..8f5c5e152 100644
--- a/test/common_plat/performance/odp_l2fwd.c
+++ b/test/common_plat/performance/odp_l2fwd.c
@@ -25,9 +25,7 @@
#include <test_debug.h>
#include <odp_api.h>
-#include <odp/helper/linux.h>
-#include <odp/helper/eth.h>
-#include <odp/helper/ip.h>
+#include <odp/helper/odph_api.h>
/** @def MAX_WORKERS
* @brief Maximum number of worker threads
@@ -243,15 +241,13 @@ static inline void fill_eth_addrs(odp_packet_t pkt_tbl[],
odp_packet_prefetch(pkt, 0, ODPH_ETHHDR_LEN);
- if (odp_packet_has_eth(pkt)) {
- eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ eth = odp_packet_data(pkt);
- if (gbl_args->appl.src_change)
- eth->src = gbl_args->port_eth_addr[dst_port];
+ if (gbl_args->appl.src_change)
+ eth->src = gbl_args->port_eth_addr[dst_port];
- if (gbl_args->appl.dst_change)
- eth->dst = gbl_args->dst_eth_addr[dst_port];
- }
+ if (gbl_args->appl.dst_change)
+ eth->dst = gbl_args->dst_eth_addr[dst_port];
}
}
@@ -605,6 +601,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx,
odp_pktio_op_mode_t mode_rx;
odp_pktio_op_mode_t mode_tx;
pktin_mode_t in_mode = gbl_args->appl.in_mode;
+ odp_pktio_info_t info;
odp_pktio_param_init(&pktio_param);
@@ -622,8 +619,13 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx,
return -1;
}
- printf("created pktio %" PRIu64 " (%s)\n",
- odp_pktio_to_u64(pktio), dev);
+ if (odp_pktio_info(pktio, &info)) {
+ LOG_ERR("Error: pktio info failed %s\n", dev);
+ return -1;
+ }
+
+ printf("created pktio %" PRIu64 ", dev: %s, drv: %s\n",
+ odp_pktio_to_u64(pktio), dev, info.drv_name);
if (odp_pktio_capability(pktio, &capa)) {
LOG_ERR("Error: capability query failed %s\n", dev);
diff --git a/test/common_plat/performance/odp_l2fwd_run.sh b/test/common_plat/performance/odp_l2fwd_run.sh
index 757cf5353..dd42ede97 100755
--- a/test/common_plat/performance/odp_l2fwd_run.sh
+++ b/test/common_plat/performance/odp_l2fwd_run.sh
@@ -66,12 +66,14 @@ run_l2fwd()
exit 1
fi
- #@todo: limit odp_generator to cores
- #https://bugs.linaro.org/show_bug.cgi?id=1398
+ # Max 4 workers
+ # @todo: ensure that generator and l2fwd workers are not allocated to
+ # the same CPUs
(odp_generator${EXEEXT} --interval $FLOOD_MODE -I $IF0 \
--srcip 192.168.0.1 --dstip 192.168.0.2 \
- -m u 2>&1 > /dev/null) \
+ -m u -w 4 2>&1 > /dev/null) \
2>&1 > /dev/null &
+
GEN_PID=$!
# this just turns off output buffering so that you still get periodic
@@ -82,6 +84,8 @@ run_l2fwd()
STDBUF=
fi
LOG=odp_l2fwd_tmp.log
+
+ # Max 2 workers
$STDBUF odp_l2fwd${EXEEXT} -i $IF1,$IF2 -m 0 -t 30 -c 2 | tee $LOG
ret=$?
diff --git a/test/common_plat/performance/odp_pktio_ordered.c b/test/common_plat/performance/odp_pktio_ordered.c
new file mode 100644
index 000000000..bff4586e5
--- /dev/null
+++ b/test/common_plat/performance/odp_pktio_ordered.c
@@ -0,0 +1,1342 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * @example odp_pktio_ordered.c ODP ordered pktio test application
+ */
+
+/** enable strtok */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <test_debug.h>
+#include <dummy_crc.h>
+
+#include <odp_api.h>
+#include <odp/helper/threads.h>
+#include <odp/helper/eth.h>
+#include <odp/helper/ip.h>
+#include <odp/helper/udp.h>
+
+/** Jenkins hash support.
+ *
+ * Copyright (C) 2006 Bob Jenkins (bob_jenkins@burtleburtle.net)
+ *
+ * http://burtleburtle.net/bob/hash/
+ *
+ * These are the credits from Bob's sources:
+ *
+ * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+ *
+ * These are functions for producing 32-bit hashes for hash table lookup.
+ * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+ * are externally useful functions. Routines to test the hash are included
+ * if SELF_TEST is defined. You can use this free for any purpose. It's in
+ * the public domain. It has no warranty.
+ *
+ * $FreeBSD$
+ */
+#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
+
+#define mix(a, b, c) \
+{ \
+ a -= c; a ^= rot(c, 4); c += b; \
+ b -= a; b ^= rot(a, 6); a += c; \
+ c -= b; c ^= rot(b, 8); b += a; \
+ a -= c; a ^= rot(c, 16); c += b; \
+ b -= a; b ^= rot(a, 19); a += c; \
+ c -= b; c ^= rot(b, 4); b += a; \
+}
+
+#define final(a, b, c) \
+{ \
+ c ^= b; c -= rot(b, 14); \
+ a ^= c; a -= rot(c, 11); \
+ b ^= a; b -= rot(a, 25); \
+ c ^= b; c -= rot(b, 16); \
+ a ^= c; a -= rot(c, 4); \
+ b ^= a; b -= rot(a, 14); \
+ c ^= b; c -= rot(b, 24); \
+}
+
+#define JHASH_GOLDEN_RATIO 0x9e3779b9
+
+/** Maximum number of worker threads */
+#define MAX_WORKERS 64
+
+/** Number of packet buffers in the memory pool */
+#define PKT_POOL_SIZE 8192
+
+/** Buffer size of the packet pool buffer in bytes*/
+#define PKT_POOL_BUF_SIZE 1856
+
+/** Packet user area size in bytes */
+#define PKT_UAREA_SIZE 32
+
+/** Maximum number of packets in a burst */
+#define MAX_PKT_BURST 32
+
+/** Maximum number of pktio queues per interface */
+#define MAX_QUEUES 32
+
+/** Maximum number of pktio interfaces */
+#define MAX_PKTIOS 8
+
+/** Maximum number of packet flows */
+#define MAX_FLOWS 128
+
+ODP_STATIC_ASSERT(MAX_PKTIOS < MAX_FLOWS,
+ "MAX_FLOWS must be greater than MAX_PKTIOS\n");
+
+/** Minimum valid packet length */
+#define MIN_PACKET_LEN (ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_UDPHDR_LEN)
+
+/** Default number of input queues */
+#define DEF_NUM_RX_QUEUES 1
+
+/** Default number of flows */
+#define DEF_NUM_FLOWS 12
+
+/** Default number of extra processing rounds */
+#define DEF_EXTRA_ROUNDS 15
+
+/** Default statistics print interval in seconds */
+#define DEF_STATS_INT 1
+
+/** Get rid of path in filename - only for unix-type paths using '/' */
+#define NO_PATH(file_name) (strrchr((file_name), '/') ? \
+ strrchr((file_name), '/') + 1 : (file_name))
+
+/**
+ * Packet input mode
+ */
+typedef enum pktin_mode_t {
+ SCHED_ORDERED = 0,
+ SCHED_ATOMIC,
+ SCHED_PARALLEL
+} pktin_mode_t;
+
+/**
+ * Parsed command line application arguments
+ */
+typedef struct {
+ int cpu_count; /**< CPU count */
+ int if_count; /**< Number of interfaces to be used */
+ int addr_count; /**< Number of dst addresses to be used */
+ int num_rx_q; /**< Number of input queues per interface */
+ int num_flows; /**< Number of packet flows */
+ int extra_rounds; /**< Number of extra input processing rounds */
+ char **if_names; /**< Array of pointers to interface names */
+ odph_ethaddr_t addrs[MAX_PKTIOS]; /**< Array of dst addresses */
+ pktin_mode_t in_mode; /**< Packet input mode */
+ int time; /**< Time in seconds to run. */
+ int accuracy; /**< Statistics print interval */
+ char *if_str; /**< Storage for interface names */
+} appl_args_t;
+
+static int exit_threads; /**< Break workers loop if set to 1 */
+
+/**
+ * Queue context
+ */
+typedef struct {
+ odp_bool_t input_queue; /**< Input queue */
+ uint64_t idx; /**< Queue index */
+ uint64_t seq[MAX_FLOWS]; /**< Per flow sequence numbers */
+} qcontext_t;
+
+/**
+ * Flow info stored in the packet user area
+ */
+typedef struct {
+ uint64_t seq; /**< Sequence number */
+ uint32_t crc; /**< CRC hash */
+ uint16_t idx; /**< Flow index */
+ uint8_t src_idx; /**< Source port index */
+ uint8_t dst_idx; /**< Destination port index */
+
+} flow_t;
+ODP_STATIC_ASSERT(sizeof(flow_t) <= PKT_UAREA_SIZE,
+ "Flow data doesn't fit in the packet user area\n");
+
+/**
+ * Statistics
+ */
+typedef union {
+ struct {
+ /** Number of forwarded packets */
+ uint64_t packets;
+ /** Packets dropped due to a receive error */
+ uint64_t rx_drops;
+ /** Packets dropped due to a transmit error */
+ uint64_t tx_drops;
+ /** Packets with invalid sequence number */
+ uint64_t invalid_seq;
+ } s;
+
+ uint8_t padding[ODP_CACHE_LINE_SIZE];
+} stats_t ODP_ALIGNED_CACHE;
+
+/**
+ * IPv4 5-tuple
+ */
+typedef struct {
+ int32_t src_ip;
+ int32_t dst_ip;
+ int16_t src_port;
+ int16_t dst_port;
+ int8_t proto;
+ int8_t pad0;
+ int16_t pad1;
+} ipv4_tuple5_t;
+
+/**
+ * Packet headers
+ */
+typedef struct {
+ odph_ethhdr_t *eth;
+ odph_ipv4hdr_t *ipv4;
+ odph_udphdr_t *udp;
+} packet_hdr_t;
+
+/**
+ * Thread specific arguments
+ */
+typedef struct thread_args_t {
+ stats_t *stats; /**< Pointer to per thread statistics */
+} thread_args_t;
+
+/**
+ * Grouping of all global data
+ */
+typedef struct {
+ /** Per thread packet stats */
+ stats_t stats[MAX_WORKERS];
+ /** Application (parsed) arguments */
+ appl_args_t appl;
+ /** Thread specific arguments */
+ thread_args_t thread[MAX_WORKERS];
+ /** Table of port ethernet addresses */
+ odph_ethaddr_t port_eth_addr[MAX_PKTIOS];
+ /** Table of dst ethernet addresses */
+ odph_ethaddr_t dst_eth_addr[MAX_PKTIOS];
+ /** Table of dst ports */
+ int dst_port[MAX_PKTIOS];
+ /** Table of atomic queues for flows */
+ odp_queue_t fqueue[MAX_PKTIOS][MAX_FLOWS];
+ /** Table of flow queue contexts */
+ qcontext_t flow_qcontext[MAX_PKTIOS][MAX_FLOWS];
+ /** Table of input queue contexts */
+ qcontext_t input_qcontext[MAX_PKTIOS][MAX_QUEUES];
+ /** Table of pktio handles */
+ struct {
+ odp_pktio_t pktio;
+ odp_pktout_queue_t pktout[MAX_FLOWS];
+ odp_queue_t pktin[MAX_QUEUES];
+ int num_rx_queue;
+ int num_tx_queue;
+ } pktios[MAX_PKTIOS];
+} args_t;
+
+/** Global pointer to args */
+static args_t *gbl_args;
+
+/** Global barrier to synchronize main and workers */
+static odp_barrier_t barrier;
+
+/**
+ * Lookup the destination port for a given packet
+ *
+ * @param pkt ODP packet handle
+ */
+static inline int lookup_dest_port(odp_packet_t pkt)
+{
+ int i, src_idx;
+ odp_pktio_t pktio_src;
+
+ pktio_src = odp_packet_input(pkt);
+
+ for (src_idx = -1, i = 0; gbl_args->pktios[i].pktio
+ != ODP_PKTIO_INVALID; i++)
+ if (gbl_args->pktios[i].pktio == pktio_src)
+ src_idx = i;
+
+ if (src_idx == -1)
+ LOG_ABORT("Failed to determine pktio input\n");
+
+ return gbl_args->dst_port[src_idx];
+}
+
+/**
+ * Map required packet headers
+ *
+ * @param pkt Packet handle
+ * @param hdr[out] Packet headers
+ *
+ * @retval 0 on success
+ * @retval -1 on failure
+ */
+static inline int packet_hdr(odp_packet_t pkt, packet_hdr_t *hdr)
+{
+ uint8_t *udp;
+ uint16_t eth_type;
+ uint8_t ihl;
+
+ if (odp_unlikely(odp_packet_seg_len(pkt) < MIN_PACKET_LEN))
+ return -1;
+
+ if (odp_unlikely(!odp_packet_has_eth(pkt)))
+ return -1;
+
+ hdr->eth = odp_packet_l2_ptr(pkt, NULL);
+ eth_type = odp_be_to_cpu_16(hdr->eth->type);
+ if (odp_unlikely(eth_type != ODPH_ETHTYPE_IPV4))
+ return -1;
+
+ hdr->ipv4 = (odph_ipv4hdr_t *)(hdr->eth + 1);
+ if (odp_unlikely(hdr->ipv4->proto != ODPH_IPPROTO_UDP))
+ return -1;
+
+ ihl = ODPH_IPV4HDR_IHL(hdr->ipv4->ver_ihl);
+ if (odp_unlikely(ihl < ODPH_IPV4HDR_IHL_MIN))
+ return -1;
+
+ udp = (uint8_t *)hdr->ipv4 + (ihl * 4);
+
+ hdr->udp = (odph_udphdr_t *)udp;
+
+ return 0;
+}
+
+/**
+ * Compute hash from a 5-tuple
+ *
+ * @param key IPv4 5-tuple
+ *
+ * @return 32-bit hash value
+ */
+static inline uint64_t calc_ipv4_5tuple_hash(ipv4_tuple5_t *tuple)
+{
+ uint32_t a, b, c;
+
+ a = tuple->proto + JHASH_GOLDEN_RATIO;
+ b = tuple->src_ip + JHASH_GOLDEN_RATIO;
+ c = tuple->dst_ip + JHASH_GOLDEN_RATIO;
+
+ mix(a, b, c);
+
+ a += (tuple->src_port << 16) + tuple->dst_port + JHASH_GOLDEN_RATIO;
+ final(a, b, c);
+
+ return c;
+}
+
+/**
+ * Compute packet flow index
+ *
+ * @param hdr Packet headers
+ *
+ * @return Flow index
+ */
+static inline uint64_t calc_flow_idx(packet_hdr_t *hdr)
+{
+ ipv4_tuple5_t tuple;
+ uint64_t idx;
+
+ tuple.dst_ip = odp_be_to_cpu_32(hdr->ipv4->dst_addr);
+ tuple.src_ip = odp_be_to_cpu_32(hdr->ipv4->src_addr);
+ tuple.proto = hdr->ipv4->proto;
+ tuple.src_port = odp_be_to_cpu_16(hdr->udp->src_port);
+ tuple.dst_port = odp_be_to_cpu_16(hdr->udp->dst_port);
+ tuple.pad0 = 0;
+ tuple.pad1 = 0;
+ idx = calc_ipv4_5tuple_hash(&tuple);
+
+ return idx % gbl_args->appl.num_flows;
+}
+
+/**
+ * Fill packet's eth addresses according to the destination port
+ *
+ * @param hdr[out] Packet headers
+ * @param dst_port Destination port
+ */
+static inline void fill_eth_addrs(packet_hdr_t *hdr, int dst_port)
+{
+ hdr->eth->src = gbl_args->port_eth_addr[dst_port];
+ hdr->eth->dst = gbl_args->dst_eth_addr[dst_port];
+}
+
+/**
+ * Process flow queue
+ *
+ * @param ev_tbl Array of events
+ * @param num Number of events in the array
+ * @param stats Pointer for storing thread statistics
+ * @param qcontext Source queue context
+ * @param pktout Arrays of output queues
+ */
+static inline void process_flow(odp_event_t ev_tbl[], int num, stats_t *stats,
+ qcontext_t *qcontext,
+ odp_pktout_queue_t pktout[][MAX_FLOWS])
+{
+ odp_packet_t pkt;
+ flow_t *flow;
+ uint64_t queue_seq;
+ int dst_if;
+ int i;
+ int sent;
+
+ for (i = 0; i < num; i++) {
+ pkt = odp_packet_from_event(ev_tbl[i]);
+
+ flow = odp_packet_user_area(pkt);
+
+ queue_seq = qcontext->seq[flow->src_idx];
+
+ /* Check sequence number */
+ if (gbl_args->appl.in_mode != SCHED_PARALLEL &&
+ odp_unlikely(flow->seq != queue_seq)) {
+ printf("Invalid sequence number: packet_seq=%" PRIu64 ""
+ " queue_seq=%" PRIu64 ", src_if=%" PRIu8 ", "
+ "dst_if=%" PRIu8 ", flow=%" PRIu16 "\n",
+ flow->seq, queue_seq, flow->src_idx,
+ flow->dst_idx, flow->idx);
+ qcontext->seq[flow->src_idx] = flow->seq + 1;
+ stats->s.invalid_seq++;
+ } else {
+ qcontext->seq[flow->src_idx]++;
+ }
+
+ dst_if = flow->dst_idx;
+ sent = odp_pktout_send(pktout[dst_if][flow->idx], &pkt, 1);
+
+ if (odp_unlikely(sent != 1)) {
+ stats->s.tx_drops++;
+ odp_packet_free(pkt);
+ }
+ stats->s.packets++;
+ }
+}
+
+/**
+ * Process input queue
+ *
+ * @param ev_tbl Array of events
+ * @param num Number of events in the array
+ * @param stats Pointer for storing thread statistics
+ * @param qcontext Source queue context
+ */
+static inline void process_input(odp_event_t ev_tbl[], int num, stats_t *stats,
+ qcontext_t *qcontext)
+{
+ flow_t *flow;
+ flow_t *flow_tbl[MAX_PKT_BURST];
+ int ret;
+ int i, j;
+ int pkts = 0;
+
+ for (i = 0; i < num; i++) {
+ odp_packet_t pkt;
+ packet_hdr_t hdr;
+ int flow_idx;
+
+ pkt = odp_packet_from_event(ev_tbl[i]);
+
+ odp_packet_prefetch(pkt, 0, MIN_PACKET_LEN);
+
+ ret = packet_hdr(pkt, &hdr);
+ if (odp_unlikely(ret)) {
+ odp_packet_free(pkt);
+ stats->s.rx_drops++;
+ continue;
+ }
+
+ flow_idx = calc_flow_idx(&hdr);
+
+ fill_eth_addrs(&hdr, flow_idx);
+
+ flow = odp_packet_user_area(pkt);
+ flow->idx = flow_idx;
+ flow->src_idx = qcontext->idx;
+ flow->dst_idx = lookup_dest_port(pkt);
+ flow_tbl[pkts] = flow;
+
+ /* Simulate "fat pipe" processing by generating extra work */
+ for (j = 0; j < gbl_args->appl.extra_rounds; j++)
+ flow->crc = dummy_hash_crc32c(odp_packet_data(pkt),
+ odp_packet_len(pkt), 0);
+ pkts++;
+ }
+
+ if (odp_unlikely(!pkts))
+ return;
+
+ /* Set sequence numbers */
+ if (gbl_args->appl.in_mode == SCHED_ORDERED)
+ odp_schedule_order_lock(0);
+
+ for (i = 0; i < pkts; i++) {
+ flow = flow_tbl[i];
+ flow->seq = qcontext->seq[flow->idx]++;
+ }
+
+ if (gbl_args->appl.in_mode == SCHED_ORDERED)
+ odp_schedule_order_unlock(0);
+
+ for (i = 0; i < pkts; i++) {
+ flow = flow_tbl[i];
+ ret = odp_queue_enq(gbl_args->fqueue[flow->dst_idx][flow->idx],
+ ev_tbl[i]);
+
+ if (odp_unlikely(ret != 0)) {
+ LOG_ERR("odp_queue_enq() failed\n");
+ stats->s.tx_drops++;
+ odp_event_free(ev_tbl[i]);
+ } else {
+ stats->s.packets++;
+ }
+ }
+}
+
+/**
+ * Worker thread
+ *
+ * @param arg Thread arguments of type 'thread_args_t *'
+ */
+static int run_worker(void *arg)
+{
+ odp_event_t ev_tbl[MAX_PKT_BURST];
+ odp_queue_t queue;
+ odp_pktout_queue_t pktout[MAX_PKTIOS][MAX_FLOWS];
+ qcontext_t *qcontext;
+ thread_args_t *thr_args = arg;
+ stats_t *stats = thr_args->stats;
+ int pkts;
+ int i, j;
+
+ memset(pktout, 0, sizeof(pktout));
+
+ for (i = 0; i < gbl_args->appl.if_count; i++) {
+ for (j = 0; j < gbl_args->appl.num_flows; j++) {
+ pktout[i][j] = gbl_args->pktios[i].pktout[j %
+ gbl_args->pktios[i].num_tx_queue];
+ }
+ }
+ odp_barrier_wait(&barrier);
+
+ /* Loop packets */
+ while (!exit_threads) {
+ pkts = odp_schedule_multi(&queue, ODP_SCHED_NO_WAIT, ev_tbl,
+ MAX_PKT_BURST);
+ if (pkts <= 0)
+ continue;
+
+ qcontext = odp_queue_context(queue);
+
+ if (qcontext->input_queue)
+ process_input(ev_tbl, pkts, stats, qcontext);
+ else
+ process_flow(ev_tbl, pkts, stats, qcontext, pktout);
+ }
+
+ /* Free remaining events in queues */
+ while (1) {
+ odp_event_t ev;
+
+ ev = odp_schedule(NULL,
+ odp_schedule_wait_time(ODP_TIME_SEC_IN_NS));
+
+ if (ev == ODP_EVENT_INVALID)
+ break;
+
+ odp_event_free(ev);
+ }
+
+ return 0;
+}
+
+/**
+ * Create a pktio handle and associate with input queues
+ *
+ * @param dev Name of device to open
+ * @param index Pktio index
+ * @param num_rx Number of input queues
+ * @param num_tx Number of output queues
+ * @param pool Pool to associate with device for packet RX/TX
+ *
+ * @retval 0 on success
+ * @retval -1 on failure
+ */
+static int create_pktio(const char *dev, int idx, int num_rx, int num_tx,
+ odp_pool_t pool)
+{
+ odp_pktio_t pktio;
+ odp_pktio_param_t pktio_param;
+ odp_pktio_capability_t capa;
+ odp_pktin_queue_param_t pktin_param;
+ odp_pktout_queue_param_t pktout_param;
+ odp_pktio_op_mode_t mode_rx;
+ odp_pktio_op_mode_t mode_tx;
+ int i;
+
+ odp_pktio_param_init(&pktio_param);
+
+ pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
+
+ pktio = odp_pktio_open(dev, pool, &pktio_param);
+ if (pktio == ODP_PKTIO_INVALID) {
+ LOG_ERR("Error: failed to open %s\n", dev);
+ return -1;
+ }
+
+ printf("Created pktio %" PRIu64 " (%s)\n",
+ odp_pktio_to_u64(pktio), dev);
+
+ if (odp_pktio_capability(pktio, &capa)) {
+ LOG_ERR("Error: capability query failed %s\n", dev);
+ odp_pktio_close(pktio);
+ return -1;
+ }
+
+ odp_pktin_queue_param_init(&pktin_param);
+ odp_pktout_queue_param_init(&pktout_param);
+
+ mode_tx = ODP_PKTIO_OP_MT;
+ mode_rx = ODP_PKTIO_OP_MT;
+
+ if (gbl_args->appl.in_mode == SCHED_ATOMIC) {
+ pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;
+ } else if (gbl_args->appl.in_mode == SCHED_PARALLEL) {
+ pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_PARALLEL;
+ } else {
+ pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ORDERED;
+ pktin_param.queue_param.sched.lock_count = 1;
+ }
+ pktin_param.queue_param.sched.prio = ODP_SCHED_PRIO_DEFAULT;
+ pktin_param.queue_param.sched.group = ODP_SCHED_GROUP_ALL;
+
+ if (num_rx > (int)capa.max_input_queues) {
+ printf("Allocating %i shared input queues, %i requested\n",
+ capa.max_input_queues, num_rx);
+ num_rx = capa.max_input_queues;
+ mode_rx = ODP_PKTIO_OP_MT;
+ }
+
+ if (num_tx > (int)capa.max_output_queues) {
+ printf("Allocating %i shared output queues, %i requested\n",
+ capa.max_output_queues, num_tx);
+ num_tx = capa.max_output_queues;
+ mode_tx = ODP_PKTIO_OP_MT;
+ }
+
+ pktin_param.hash_enable = 1;
+ pktin_param.hash_proto.proto.ipv4_udp = 1;
+ pktin_param.num_queues = num_rx;
+ pktin_param.op_mode = mode_rx;
+
+ pktout_param.op_mode = mode_tx;
+ pktout_param.num_queues = num_tx;
+
+ if (odp_pktin_queue_config(pktio, &pktin_param)) {
+ LOG_ERR("Error: input queue config failed %s\n", dev);
+ return -1;
+ }
+
+ if (odp_pktout_queue_config(pktio, &pktout_param)) {
+ LOG_ERR("Error: output queue config failed %s\n", dev);
+ return -1;
+ }
+
+ if (odp_pktin_event_queue(pktio, gbl_args->pktios[idx].pktin,
+ num_rx) != num_rx) {
+ LOG_ERR("Error: pktin event queue query failed %s\n",
+ dev);
+ return -1;
+ }
+
+ /* Set queue contexts */
+ for (i = 0; i < num_rx; i++) {
+ gbl_args->input_qcontext[idx][i].idx = idx;
+ gbl_args->input_qcontext[idx][i].input_queue = 1;
+
+ if (odp_queue_context_set(gbl_args->pktios[idx].pktin[i],
+ &gbl_args->input_qcontext[idx][i],
+ sizeof(qcontext_t))) {
+ LOG_ERR("Error: pktin queue context set failed %s\n",
+ dev);
+ return -1;
+ }
+ }
+
+ if (odp_pktout_queue(pktio,
+ gbl_args->pktios[idx].pktout,
+ num_tx) != num_tx) {
+ LOG_ERR("Error: pktout queue query failed %s\n", dev);
+ return -1;
+ }
+
+ printf("Created %i input and %i output queues on (%s)\n",
+ num_rx, num_tx, dev);
+
+ gbl_args->pktios[idx].num_rx_queue = num_rx;
+ gbl_args->pktios[idx].num_tx_queue = num_tx;
+ gbl_args->pktios[idx].pktio = pktio;
+
+ return 0;
+}
+
+/**
+ * Print statistics
+ *
+ * @param num_workers Number of worker threads
+ * @param thr_stats Pointer to stats storage
+ * @param duration Number of seconds to loop in
+ * @param timeout Number of seconds for stats calculation
+ *
+ */
+static int print_speed_stats(int num_workers, stats_t *thr_stats,
+ int duration, int timeout)
+{
+ uint64_t pkts = 0;
+ uint64_t pkts_prev = 0;
+ uint64_t pps;
+ uint64_t rx_drops, tx_drops, invalid_seq;
+ uint64_t maximum_pps = 0;
+ int i;
+ int elapsed = 0;
+ int stats_enabled = 1;
+ int loop_forever = (duration == 0);
+
+ if (timeout <= 0) {
+ stats_enabled = 0;
+ timeout = 1;
+ }
+ /* Wait for all threads to be ready*/
+ odp_barrier_wait(&barrier);
+
+ do {
+ pkts = 0;
+ rx_drops = 0;
+ tx_drops = 0;
+ invalid_seq = 0;
+
+ sleep(timeout);
+
+ for (i = 0; i < num_workers; i++) {
+ pkts += thr_stats[i].s.packets;
+ rx_drops += thr_stats[i].s.rx_drops;
+ tx_drops += thr_stats[i].s.tx_drops;
+ invalid_seq += thr_stats[i].s.invalid_seq;
+ }
+ if (stats_enabled) {
+ pps = (pkts - pkts_prev) / timeout;
+ if (pps > maximum_pps)
+ maximum_pps = pps;
+ printf("%" PRIu64 " pps, %" PRIu64 " max pps, ", pps,
+ maximum_pps);
+
+ printf("%" PRIu64 " rx drops, %" PRIu64 " tx drops, ",
+ rx_drops, tx_drops);
+
+ printf("%" PRIu64 " invalid seq\n", invalid_seq);
+
+ pkts_prev = pkts;
+ }
+ elapsed += timeout;
+ } while (loop_forever || (elapsed < duration));
+
+ if (stats_enabled)
+ printf("TEST RESULT: %" PRIu64 " maximum packets per second.\n",
+ maximum_pps);
+
+ return (pkts > 100 && !invalid_seq) ? 0 : -1;
+}
+
+/**
+ * Find the destination port for a given input port
+ *
+ * @param port Input port index
+ */
+static int find_dest_port(int port)
+{
+ /* Even number of ports */
+ if (gbl_args->appl.if_count % 2 == 0)
+ return (port % 2 == 0) ? port + 1 : port - 1;
+
+ /* Odd number of ports */
+ if (port == gbl_args->appl.if_count - 1)
+ return 0;
+ else
+ return port + 1;
+}
+
+/**
+ * Initialize port forwarding table
+ */
+static void init_forwarding_tbl(void)
+{
+ int rx_idx;
+
+ for (rx_idx = 0; rx_idx < gbl_args->appl.if_count; rx_idx++)
+ gbl_args->dst_port[rx_idx] = find_dest_port(rx_idx);
+}
+
+/**
+ * Prinf usage information
+ */
+static void usage(char *progname)
+{
+ printf("\n"
+ "OpenDataPlane ordered pktio application.\n"
+ "\n"
+ "Usage: %s OPTIONS\n"
+ " E.g. %s -i eth0,eth1\n"
+ " In the above example,\n"
+ " eth0 will send pkts to eth1 and vice versa\n"
+ "\n"
+ "Mandatory OPTIONS:\n"
+ " -i, --interface Eth interfaces (comma-separated, no spaces)\n"
+ " Interface count min 1, max %i\n"
+ "\n"
+ "Optional OPTIONS:\n"
+ " -m, --mode Packet input mode\n"
+ " 0: Scheduled ordered queues (default)\n"
+ " 1: Scheduled atomic queues\n"
+ " 2: Scheduled parallel queues (packet order not maintained)\n"
+ " -r, --num_rx_q Number of RX queues per interface\n"
+ " -f, --num_flows Number of packet flows\n"
+ " -e, --extra_input <number> Number of extra input processing rounds\n"
+ " -c, --count <number> CPU count.\n"
+ " -t, --time <number> Time in seconds to run.\n"
+ " -a, --accuracy <number> Statistics print interval in seconds\n"
+ " (default is 1 second).\n"
+ " -d, --dst_addr Destination addresses (comma-separated, no spaces)\n"
+ " -h, --help Display help and exit.\n\n"
+ "\n", NO_PATH(progname), NO_PATH(progname), MAX_PKTIOS
+ );
+}
+
+/**
+ * Parse and store the command line arguments
+ *
+ * @param argc argument count
+ * @param argv[] argument vector
+ * @param appl_args Store application arguments here
+ */
+static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
+{
+ int opt;
+ int long_index;
+ char *token;
+ char *addr_str;
+ size_t len;
+ int i;
+ static const struct option longopts[] = {
+ {"count", required_argument, NULL, 'c'},
+ {"time", required_argument, NULL, 't'},
+ {"accuracy", required_argument, NULL, 'a'},
+ {"interface", required_argument, NULL, 'i'},
+ {"mode", required_argument, NULL, 'm'},
+ {"dst_addr", required_argument, NULL, 'd'},
+ {"num_rx_q", required_argument, NULL, 'r'},
+ {"num_flows", required_argument, NULL, 'f'},
+ {"extra_input", required_argument, NULL, 'e'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+
+ static const char *shortopts = "+c:+t:+a:i:m:d:r:f:e:h";
+
+ /* let helper collect its own arguments (e.g. --odph_proc) */
+ odph_parse_options(argc, argv, shortopts, longopts);
+
+ appl_args->time = 0; /* loop forever if time to run is 0 */
+ appl_args->accuracy = DEF_STATS_INT;
+ appl_args->num_rx_q = DEF_NUM_RX_QUEUES;
+ appl_args->num_flows = DEF_NUM_FLOWS;
+ appl_args->extra_rounds = DEF_EXTRA_ROUNDS;
+
+ opterr = 0; /* do not issue errors on helper options */
+
+ while (1) {
+ opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
+
+ if (opt == -1)
+ break; /* No more options */
+
+ switch (opt) {
+ case 'c':
+ appl_args->cpu_count = atoi(optarg);
+ break;
+ case 't':
+ appl_args->time = atoi(optarg);
+ break;
+ case 'a':
+ appl_args->accuracy = atoi(optarg);
+ break;
+ /* parse packet-io interface names */
+ case 'd':
+ len = strlen(optarg);
+ if (len == 0) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ len += 1; /* add room for '\0' */
+
+ addr_str = malloc(len);
+ if (addr_str == NULL) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ /* store the mac addresses names */
+ strcpy(addr_str, optarg);
+ for (token = strtok(addr_str, ","), i = 0;
+ token != NULL; token = strtok(NULL, ","), i++) {
+ if (i >= MAX_PKTIOS) {
+ printf("too many MAC addresses\n");
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ if (odph_eth_addr_parse(&appl_args->addrs[i],
+ token) != 0) {
+ printf("invalid MAC address\n");
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ }
+ appl_args->addr_count = i;
+ if (appl_args->addr_count < 1) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ free(addr_str);
+ break;
+ case 'i':
+ len = strlen(optarg);
+ if (len == 0) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ len += 1; /* add room for '\0' */
+
+ appl_args->if_str = malloc(len);
+ if (appl_args->if_str == NULL) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ /* count the number of tokens separated by ',' */
+ strcpy(appl_args->if_str, optarg);
+ for (token = strtok(appl_args->if_str, ","), i = 0;
+ token != NULL;
+ token = strtok(NULL, ","), i++)
+ ;
+
+ appl_args->if_count = i;
+
+ if (appl_args->if_count < 1 ||
+ appl_args->if_count > MAX_PKTIOS) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ /* allocate storage for the if names */
+ appl_args->if_names =
+ calloc(appl_args->if_count, sizeof(char *));
+
+ /* store the if names (reset names string) */
+ strcpy(appl_args->if_str, optarg);
+ for (token = strtok(appl_args->if_str, ","), i = 0;
+ token != NULL; token = strtok(NULL, ","), i++) {
+ appl_args->if_names[i] = token;
+ }
+ break;
+ case 'm':
+ i = atoi(optarg);
+ if (i == 1)
+ appl_args->in_mode = SCHED_ATOMIC;
+ else if (i == 2)
+ appl_args->in_mode = SCHED_PARALLEL;
+ else
+ appl_args->in_mode = SCHED_ORDERED;
+ break;
+ case 'r':
+ appl_args->num_rx_q = atoi(optarg);
+ break;
+ case 'f':
+ appl_args->num_flows = atoi(optarg);
+ break;
+ case 'e':
+ appl_args->extra_rounds = atoi(optarg);
+ break;
+ case 'h':
+ usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (appl_args->cpu_count > MAX_WORKERS) {
+ printf("Too many workers requested %d, max: %d\n",
+ appl_args->cpu_count, MAX_WORKERS);
+ exit(EXIT_FAILURE);
+ }
+
+ if (appl_args->num_flows > MAX_FLOWS) {
+ printf("Too many flows requested %d, max: %d\n",
+ appl_args->num_flows, MAX_FLOWS);
+ exit(EXIT_FAILURE);
+ }
+
+ if (appl_args->if_count == 0 || appl_args->num_flows == 0 ||
+ appl_args->num_rx_q == 0) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ if (appl_args->addr_count != 0 &&
+ appl_args->addr_count != appl_args->if_count) {
+ printf("Number of destination addresses differs from number"
+ " of interfaces\n");
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ optind = 1; /* reset 'extern optind' from the getopt lib */
+}
+
+/**
+ * Print system and application info
+ */
+static void print_info(char *progname, appl_args_t *appl_args)
+{
+ int i;
+
+ printf("\n"
+ "ODP system info\n"
+ "---------------\n"
+ "ODP API version: %s\n"
+ "ODP impl name: %s\n"
+ "CPU model: %s\n"
+ "CPU freq (hz): %" PRIu64 "\n"
+ "Cache line size: %i\n"
+ "CPU count: %i\n"
+ "\n",
+ odp_version_api_str(), odp_version_impl_name(),
+ odp_cpu_model_str(), odp_cpu_hz_max(),
+ odp_sys_cache_line_size(), odp_cpu_count());
+
+ printf("Running ODP appl: \"%s\"\n"
+ "-----------------\n"
+ "IF-count: %i\n"
+ "Using IFs: ",
+ progname, appl_args->if_count);
+ for (i = 0; i < appl_args->if_count; ++i)
+ printf(" %s", appl_args->if_names[i]);
+ printf("\n\n");
+ fflush(NULL);
+}
+
+static void gbl_args_init(args_t *args)
+{
+ int pktio, queue;
+
+ memset(args, 0, sizeof(args_t));
+
+ for (pktio = 0; pktio < MAX_PKTIOS; pktio++) {
+ args->pktios[pktio].pktio = ODP_PKTIO_INVALID;
+
+ for (queue = 0; queue < MAX_QUEUES; queue++)
+ args->pktios[pktio].pktin[queue] = ODP_QUEUE_INVALID;
+ }
+}
+
+/**
+ * ODP ordered pktio application
+ */
+int main(int argc, char *argv[])
+{
+ odp_cpumask_t cpumask;
+ odp_instance_t instance;
+ odp_pool_t pool;
+ odp_pool_param_t params;
+ odp_shm_t shm;
+ odp_queue_capability_t capa;
+ odph_ethaddr_t new_addr;
+ odph_odpthread_t thread_tbl[MAX_WORKERS];
+ stats_t *stats;
+ char cpumaskstr[ODP_CPUMASK_STR_SIZE];
+ int cpu;
+ int i, j;
+ int if_count;
+ int ret;
+ int num_workers;
+ int in_mode;
+
+ /* Init ODP before calling anything else */
+ if (odp_init_global(&instance, NULL, NULL)) {
+ LOG_ERR("Error: ODP global init failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Init this thread */
+ if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
+ LOG_ERR("Error: ODP local init failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Reserve memory for args from shared mem */
+ shm = odp_shm_reserve("shm_args", sizeof(args_t),
+ ODP_CACHE_LINE_SIZE, 0);
+
+ if (shm == ODP_SHM_INVALID) {
+ LOG_ERR("Error: shared mem reserve failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ gbl_args = odp_shm_addr(shm);
+
+ if (gbl_args == NULL) {
+ LOG_ERR("Error: shared mem alloc failed.\n");
+ odp_shm_free(shm);
+ exit(EXIT_FAILURE);
+ }
+ gbl_args_init(gbl_args);
+
+ /* Parse and store the application arguments */
+ parse_args(argc, argv, &gbl_args->appl);
+
+ if (gbl_args->appl.in_mode == SCHED_ORDERED) {
+ /* At least one ordered lock required */
+ odp_queue_capability(&capa);
+ if (capa.max_ordered_locks < 1) {
+ LOG_ERR("Error: Ordered locks not available.\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ /* Print both system and application information */
+ print_info(NO_PATH(argv[0]), &gbl_args->appl);
+
+ /* Default to system CPU count unless user specified */
+ num_workers = MAX_WORKERS;
+ if (gbl_args->appl.cpu_count)
+ num_workers = gbl_args->appl.cpu_count;
+
+ /* Get default worker cpumask */
+ num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
+ (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));
+
+ if_count = gbl_args->appl.if_count;
+
+ printf("Num worker threads: %i\n", num_workers);
+ printf("First CPU: %i\n", odp_cpumask_first(&cpumask));
+ printf("CPU mask: %s\n\n", cpumaskstr);
+
+ /* Create packet pool */
+ odp_pool_param_init(&params);
+ params.pkt.seg_len = PKT_POOL_BUF_SIZE;
+ params.pkt.len = PKT_POOL_BUF_SIZE;
+ params.pkt.num = PKT_POOL_SIZE;
+ params.pkt.uarea_size = PKT_UAREA_SIZE;
+ params.type = ODP_POOL_PACKET;
+
+ pool = odp_pool_create("packet pool", &params);
+
+ if (pool == ODP_POOL_INVALID) {
+ LOG_ERR("Error: packet pool create failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ odp_pool_print(pool);
+
+ init_forwarding_tbl();
+
+ for (i = 0; i < if_count; ++i) {
+ const char *dev = gbl_args->appl.if_names[i];
+ int num_rx, num_tx;
+
+ num_rx = gbl_args->appl.num_rx_q;
+ num_tx = gbl_args->appl.num_flows;
+
+ if (create_pktio(dev, i, num_rx, num_tx, pool))
+ exit(EXIT_FAILURE);
+
+ /* Save interface ethernet address */
+ if (odp_pktio_mac_addr(gbl_args->pktios[i].pktio,
+ gbl_args->port_eth_addr[i].addr,
+ ODPH_ETHADDR_LEN) != ODPH_ETHADDR_LEN) {
+ LOG_ERR("Error: interface ethernet address unknown\n");
+ exit(EXIT_FAILURE);
+ }
+
+ odp_pktio_print(gbl_args->pktios[i].pktio);
+
+ /* Save destination eth address */
+ /* 02:00:00:00:00:XX */
+ memset(&new_addr, 0, sizeof(odph_ethaddr_t));
+ if (gbl_args->appl.addr_count) {
+ memcpy(&new_addr, &gbl_args->appl.addrs[i],
+ sizeof(odph_ethaddr_t));
+ } else {
+ new_addr.addr[0] = 0x02;
+ new_addr.addr[5] = i;
+ }
+ gbl_args->dst_eth_addr[i] = new_addr;
+ }
+
+ gbl_args->pktios[i].pktio = ODP_PKTIO_INVALID;
+
+ /* Allocate the same number of flows to each interface */
+ for (i = 0; i < if_count; i++) {
+ odp_pktio_capability_t capa;
+
+ if (odp_pktio_capability(gbl_args->pktios[i].pktio, &capa)) {
+ LOG_ERR("Error: pktio capability failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if ((unsigned)gbl_args->appl.num_flows > capa.max_output_queues)
+ gbl_args->appl.num_flows = capa.max_output_queues;
+ }
+
+ /* Create atomic queues for packet tagging */
+ for (i = 0; i < if_count; i++) {
+ for (j = 0; j < gbl_args->appl.num_flows; j++) {
+ odp_queue_t queue;
+ odp_queue_param_t qparam;
+ char qname[ODP_QUEUE_NAME_LEN];
+
+ snprintf(qname, sizeof(qname), "flow_%d_%d", i, j);
+
+ odp_queue_param_init(&qparam);
+ qparam.type = ODP_QUEUE_TYPE_SCHED;
+ qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT;
+ qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC;
+ qparam.sched.group = ODP_SCHED_GROUP_ALL;
+
+ gbl_args->flow_qcontext[i][j].idx = i;
+ gbl_args->flow_qcontext[i][j].input_queue = 0;
+ qparam.context = &gbl_args->flow_qcontext[i][j];
+ qparam.context_len = sizeof(qcontext_t);
+
+ queue = odp_queue_create(qname, &qparam);
+ if (queue == ODP_QUEUE_INVALID) {
+ LOG_ERR("Error: flow queue create failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ gbl_args->fqueue[i][j] = queue;
+ }
+ }
+
+ in_mode = gbl_args->appl.in_mode;
+ printf("\nApplication parameters\n"
+ "----------------------\n"
+ "Input queues: %d\n"
+ "Mode: %s\n"
+ "Flows: %d\n"
+ "Extra rounds: %d\n\n", gbl_args->appl.num_rx_q,
+ (in_mode == SCHED_ATOMIC) ? "PKTIN_SCHED_ATOMIC" :
+ (in_mode == SCHED_PARALLEL ? "PKTIN_SCHED_PARALLEL" :
+ "PKTIN_SCHED_ORDERED"), gbl_args->appl.num_flows,
+ gbl_args->appl.extra_rounds);
+
+ memset(thread_tbl, 0, sizeof(thread_tbl));
+
+ stats = gbl_args->stats;
+
+ odp_barrier_init(&barrier, num_workers + 1);
+
+ /* Create worker threads */
+ cpu = odp_cpumask_first(&cpumask);
+ for (i = 0; i < num_workers; ++i) {
+ odp_cpumask_t thd_mask;
+ odph_odpthread_params_t thr_params;
+
+ memset(&thr_params, 0, sizeof(thr_params));
+ thr_params.start = run_worker;
+ thr_params.arg = &gbl_args->thread[i];
+ thr_params.thr_type = ODP_THREAD_WORKER;
+ thr_params.instance = instance;
+
+ gbl_args->thread[i].stats = &stats[i];
+
+ odp_cpumask_zero(&thd_mask);
+ odp_cpumask_set(&thd_mask, cpu);
+ odph_odpthreads_create(&thread_tbl[i], &thd_mask,
+ &thr_params);
+ cpu = odp_cpumask_next(&cpumask, cpu);
+ }
+
+ /* Start packet receive and transmit */
+ for (i = 0; i < if_count; ++i) {
+ odp_pktio_t pktio;
+
+ pktio = gbl_args->pktios[i].pktio;
+ ret = odp_pktio_start(pktio);
+ if (ret) {
+ LOG_ERR("Error: unable to start %s\n",
+ gbl_args->appl.if_names[i]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ ret = print_speed_stats(num_workers, stats, gbl_args->appl.time,
+ gbl_args->appl.accuracy);
+
+ /* Stop receiving new packet */
+ for (i = 0; i < if_count; i++)
+ odp_pktio_stop(gbl_args->pktios[i].pktio);
+
+ exit_threads = 1;
+
+ /* Master thread waits for other threads to exit */
+ for (i = 0; i < num_workers; ++i)
+ odph_odpthreads_join(&thread_tbl[i]);
+
+ for (i = 0; i < if_count; i++) {
+ odp_pktio_close(gbl_args->pktios[i].pktio);
+
+ for (j = 0; j < gbl_args->appl.num_flows; j++)
+ odp_queue_destroy(gbl_args->fqueue[i][j]);
+ }
+
+ free(gbl_args->appl.if_names);
+ free(gbl_args->appl.if_str);
+
+ if (odp_pool_destroy(pool)) {
+ LOG_ERR("Error: pool destroy\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_shm_free(shm)) {
+ LOG_ERR("Error: shm free\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_term_local()) {
+ LOG_ERR("Error: term local\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_term_global(instance)) {
+ LOG_ERR("Error: term global\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return ret;
+}
diff --git a/test/common_plat/performance/odp_pktio_ordered_run.sh b/test/common_plat/performance/odp_pktio_ordered_run.sh
new file mode 100755
index 000000000..d91211c0c
--- /dev/null
+++ b/test/common_plat/performance/odp_pktio_ordered_run.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# Copyright (c) 2016, Linaro Limited
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+DURATION=5
+LOG=odp_pktio_ordered.log
+LOOPS=100000000
+PASS_PPS=5000
+PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
+PCAP_OUT=/dev/null
+
+# This just turns off output buffering so that you still get periodic
+# output while piping to tee, as long as stdbuf is available.
+if [ "$(which stdbuf)" != "" ]; then
+ STDBUF="stdbuf -o 0"
+else
+ STDBUF=
+fi
+
+$STDBUF ./odp_pktio_ordered${EXEEXT} -i pcap:in=${PCAP_IN}:loops=$LOOPS,\
+pcap:out=${PCAP_OUT} -t $DURATION | tee $LOG
+
+ret=$?
+
+if [ ! -f $LOG ]; then
+ echo "FAIL: $LOG not found"
+ ret=1
+elif [ $ret -eq 0 ]; then
+ MAX_PPS=$(awk '/TEST RESULT/ {print $3}' $LOG)
+ if [ "$MAX_PPS" -lt "$PASS_PPS" ]; then
+ echo "FAIL: pps below threshold $MAX_PPS < $PASS_PPS"
+ ret=1
+ fi
+fi
+
+rm -f $LOG
+
+exit $ret
diff --git a/test/common_plat/performance/odp_pktio_perf.c b/test/common_plat/performance/odp_pktio_perf.c
index 92d979d37..094630811 100644
--- a/test/common_plat/performance/odp_pktio_perf.c
+++ b/test/common_plat/performance/odp_pktio_perf.c
@@ -22,10 +22,7 @@
*/
#include <odp_api.h>
-#include <odp/helper/eth.h>
-#include <odp/helper/ip.h>
-#include <odp/helper/udp.h>
-#include <odp/helper/linux.h>
+#include <odp/helper/odph_api.h>
#include <getopt.h>
#include <stdlib.h>
diff --git a/test/common_plat/performance/odp_sched_latency.c b/test/common_plat/performance/odp_sched_latency.c
index 063fb21c1..2b28cd7bc 100644
--- a/test/common_plat/performance/odp_sched_latency.c
+++ b/test/common_plat/performance/odp_sched_latency.c
@@ -20,7 +20,7 @@
#include <odp_api.h>
/* ODP helper for Linux apps */
-#include <odp/helper/linux.h>
+#include <odp/helper/odph_api.h>
/* GNU lib C */
#include <getopt.h>
diff --git a/test/common_plat/performance/odp_scheduling.c b/test/common_plat/performance/odp_scheduling.c
index e2a49d34d..c74a07133 100644
--- a/test/common_plat/performance/odp_scheduling.c
+++ b/test/common_plat/performance/odp_scheduling.c
@@ -20,7 +20,7 @@
#include <odp_api.h>
/* ODP helper for Linux apps */
-#include <odp/helper/linux.h>
+#include <odp/helper/odph_api.h>
/* Needs librt*/
#include <time.h>
diff --git a/test/common_plat/performance/udp64.pcap b/test/common_plat/performance/udp64.pcap
new file mode 100644
index 000000000..45f9d6e63
--- /dev/null
+++ b/test/common_plat/performance/udp64.pcap
Binary files differ
diff --git a/test/common_plat/validation/api/classification/classification.h b/test/common_plat/validation/api/classification/classification.h
index d73c82161..53c527f38 100644
--- a/test/common_plat/validation/api/classification/classification.h
+++ b/test/common_plat/validation/api/classification/classification.h
@@ -55,6 +55,27 @@
#define DATA_MAGIC 0x01020304
#define TEST_SEQ_INVALID ((uint32_t)~0)
+/* Test packet Time-to-live */
+#define DEFAULT_TTL 128
+
+/* Test packet default DSCP value */
+#define LOW_DROP_PRECEDENCE 0x02
+#define MEDIUM_DROP_PRECEDENCE 0x04
+#define HIGH_DROP_PRECEDENCE 0x06
+#define DROP_PRECEDENCE_MASK 0x06
+#define DSCP_CLASS1 0x08
+#define DSCP_CLASS2 0x10
+#define DSCP_CLASS3 0x18
+#define DSCP_CLASS4 0x20
+#define DEFAULT_DSCP (DSCP_CLASS2 | LOW_DROP_PRECEDENCE)
+
+/* Test packet default ECN */
+#define DEFAULT_ECN ODPH_IP_ECN_ECT0
+
+/* Test packet default TOS */
+#define DEFAULT_TOS ((DEFAULT_DSCP << ODPH_IP_TOS_DSCP_SHIFT) | \
+ DEFAULT_ECN)
+
/* test functions: */
void classification_test_create_cos(void);
void classification_test_destroy_cos(void);
@@ -77,6 +98,10 @@ void classification_test_pmr_term_udp_sport(void);
void classification_test_pmr_term_ipproto(void);
void classification_test_pmr_term_dmac(void);
void classification_test_pmr_term_packet_len(void);
+void classification_test_pmr_term_vlan_id_0(void);
+void classification_test_pmr_term_vlan_id_x(void);
+void classification_test_pmr_term_eth_type_0(void);
+void classification_test_pmr_term_eth_type_x(void);
/* test arrays: */
extern odp_testinfo_t classification_suite_basic[];
diff --git a/test/common_plat/validation/api/classification/odp_classification_common.c b/test/common_plat/validation/api/classification/odp_classification_common.c
index 2923a711d..3b379c14c 100644
--- a/test/common_plat/validation/api/classification/odp_classification_common.c
+++ b/test/common_plat/validation/api/classification/odp_classification_common.c
@@ -7,10 +7,6 @@
#include "odp_classification_testsuites.h"
#include "classification.h"
#include <odp_cunit_common.h>
-#include <odp/helper/eth.h>
-#include <odp/helper/ip.h>
-#include <odp/helper/udp.h>
-#include <odp/helper/tcp.h>
#include "test_debug.h"
typedef struct cls_test_packet {
@@ -18,6 +14,16 @@ typedef struct cls_test_packet {
odp_u32be_t seq;
} cls_test_packet_t;
+static uint8_t IPV6_SRC_ADDR[ODPH_IPV6ADDR_LEN] = {
+ /* I.e. ::ffff:10.0.0.1 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 0, 0, 1
+};
+
+static uint8_t IPV6_DST_ADDR[ODPH_IPV6ADDR_LEN] = {
+ /* I.e. ::ffff:10.0.0.100 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 0, 0, 100
+};
+
odp_pktio_t create_pktio(odp_queue_type_t q_type, odp_pool_t pool)
{
odp_pktio_t pktio;
@@ -215,30 +221,32 @@ odp_pool_t pool_create(const char *poolname)
return odp_pool_create(poolname, &param);
}
-odp_packet_t create_packet(odp_pool_t pool, bool vlan,
- odp_atomic_u32_t *seq, bool flag_udp)
-{
- return create_packet_len(pool, vlan, seq, flag_udp, 0);
-}
-
-odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
- odp_atomic_u32_t *seq, bool flag_udp,
- uint16_t len)
+odp_packet_t create_packet(cls_packet_info_t pkt_info)
{
uint32_t seqno;
odph_ethhdr_t *ethhdr;
odph_udphdr_t *udp;
odph_tcphdr_t *tcp;
odph_ipv4hdr_t *ip;
+ odph_ipv6hdr_t *ipv6;
uint16_t payload_len;
uint64_t src_mac = CLS_DEFAULT_SMAC;
uint64_t dst_mac = CLS_DEFAULT_DMAC;
uint64_t dst_mac_be;
uint32_t addr = 0;
uint32_t mask;
- int offset;
odp_packet_t pkt;
int packet_len = 0;
+ uint32_t version, tc, flow, ver_tc_flow;
+ uint8_t *buf, next_hdr;
+ uint32_t l4_len, l3_len, l2_len, l3_offset, l4_offset;
+ uint16_t vlan_hdr_len = 0;
+ uint16_t l2_hdr_len = 0;
+ uint16_t l3_hdr_len = 0;
+ uint16_t l4_hdr_len = 0;
+ uint16_t eth_type;
+ odp_u16be_t *vlan_type;
+ odph_vlanhdr_t *vlan_hdr;
/* 48 bit ethernet address needs to be left shifted for proper
value after changing to be*/
@@ -246,77 +254,94 @@ odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
if (dst_mac != dst_mac_be)
dst_mac_be = dst_mac_be >> (64 - 8 * ODPH_ETHADDR_LEN);
- payload_len = sizeof(cls_test_packet_t) + len;
- packet_len += ODPH_ETHHDR_LEN;
- packet_len += ODPH_IPV4HDR_LEN;
- if (flag_udp)
- packet_len += ODPH_UDPHDR_LEN;
- else
- packet_len += ODPH_TCPHDR_LEN;
- packet_len += payload_len;
-
- if (vlan)
- packet_len += ODPH_VLANHDR_LEN;
-
- pkt = odp_packet_alloc(pool, packet_len);
+ payload_len = sizeof(cls_test_packet_t) + pkt_info.len;
+ seqno = odp_atomic_fetch_inc_u32(pkt_info.seq);
+
+ vlan_hdr_len = pkt_info.vlan ? ODPH_VLANHDR_LEN : 0;
+ vlan_hdr_len = pkt_info.vlan_qinq ? 2 * vlan_hdr_len : vlan_hdr_len;
+ l3_hdr_len = pkt_info.ipv6 ? ODPH_IPV6HDR_LEN : ODPH_IPV4HDR_LEN;
+ l4_hdr_len = pkt_info.udp ? ODPH_UDPHDR_LEN : ODPH_TCPHDR_LEN;
+ eth_type = pkt_info.ipv6 ? ODPH_ETHTYPE_IPV6 : ODPH_ETHTYPE_IPV4;
+ next_hdr = pkt_info.udp ? ODPH_IPPROTO_UDP : ODPH_IPPROTO_TCP;
+ l2_hdr_len = ODPH_ETHHDR_LEN + vlan_hdr_len;
+ l4_len = l4_hdr_len + payload_len;
+ l3_len = l3_hdr_len + l4_len;
+ l2_len = l2_hdr_len + l3_len;
+ packet_len = l2_len;
+
+ pkt = odp_packet_alloc(pkt_info.pool, packet_len);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
/* Ethernet Header */
- offset = 0;
- odp_packet_l2_offset_set(pkt, offset);
+ buf = odp_packet_data(pkt);
+ odp_packet_l2_offset_set(pkt, 0);
ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
memcpy(ethhdr->src.addr, &src_mac, ODPH_ETHADDR_LEN);
memcpy(ethhdr->dst.addr, &dst_mac_be, ODPH_ETHADDR_LEN);
- offset += sizeof(odph_ethhdr_t);
- if (vlan) {
- /* Default vlan header */
- odph_vlanhdr_t *vlan_hdr;
+ vlan_type = (odp_u16be_t *)&ethhdr->type;
+ vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1);
- ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
- vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1);
+ if (pkt_info.vlan_qinq) {
+ odp_packet_has_vlan_qinq_set(pkt, 1);
+ *vlan_type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN_OUTER);
+ vlan_hdr->tci = odp_cpu_to_be_16(0);
+ vlan_type = (uint16_t *)&vlan_hdr->type;
+ vlan_hdr++;
+ }
+ if (pkt_info.vlan) {
+ /* Default vlan header */
+ odp_packet_has_vlan_set(pkt, 1);
+ *vlan_type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
vlan_hdr->tci = odp_cpu_to_be_16(0);
- vlan_hdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
- offset += sizeof(odph_vlanhdr_t);
+ vlan_hdr->type = odp_cpu_to_be_16(eth_type);
} else {
- ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
+ ethhdr->type = odp_cpu_to_be_16(eth_type);
}
- odp_packet_l3_offset_set(pkt, offset);
-
- /* ipv4 */
- ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
-
- parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
- ip->dst_addr = odp_cpu_to_be_32(addr);
-
- parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
- ip->src_addr = odp_cpu_to_be_32(addr);
- ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
- odp_packet_has_ipv4_set(pkt, 1);
-
- if (flag_udp)
- ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
- ODPH_IPV4HDR_LEN);
- else
- ip->tot_len = odp_cpu_to_be_16(ODPH_TCPHDR_LEN + payload_len +
- ODPH_IPV4HDR_LEN);
-
- ip->ttl = 128;
- if (flag_udp)
- ip->proto = ODPH_IPPROTO_UDP;
- else
- ip->proto = ODPH_IPPROTO_TCP;
+ l3_offset = l2_hdr_len;
+ odp_packet_l3_offset_set(pkt, l3_offset);
+
+ if (!pkt_info.ipv6) {
+ /* ipv4 */
+ ip = (odph_ipv4hdr_t *)(buf + l3_offset);
+
+ parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
+ ip->dst_addr = odp_cpu_to_be_32(addr);
+
+ parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
+ ip->src_addr = odp_cpu_to_be_32(addr);
+ ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
+ ip->id = odp_cpu_to_be_16(seqno);
+ ip->chksum = 0;
+ ip->chksum = odph_ipv4_csum_update(pkt);
+ ip->proto = next_hdr;
+ ip->tot_len = odp_cpu_to_be_16(l3_len);
+ ip->ttl = DEFAULT_TTL;
+ odp_packet_has_ipv4_set(pkt, 1);
+ } else {
+ /* ipv6 */
+ odp_packet_has_ipv6_set(pkt, 1);
+ ipv6 = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+ version = ODPH_IPV6 << ODPH_IPV6HDR_VERSION_SHIFT;
+ tc = DEFAULT_TOS << ODPH_IPV6HDR_TC_SHIFT;
+ flow = seqno << ODPH_IPV6HDR_FLOW_LABEL_SHIFT;
+ ver_tc_flow = version | tc | flow;
+
+ ipv6->ver_tc_flow = odp_cpu_to_be_32(ver_tc_flow);
+ ipv6->payload_len = odp_cpu_to_be_16(l4_len);
+ ipv6->next_hdr = next_hdr;
+ ipv6->hop_limit = DEFAULT_TTL;
+ memcpy(ipv6->src_addr, IPV6_SRC_ADDR, ODPH_IPV6ADDR_LEN);
+ memcpy(ipv6->dst_addr, IPV6_DST_ADDR, ODPH_IPV6ADDR_LEN);
+ }
- seqno = odp_atomic_fetch_inc_u32(seq);
- ip->id = odp_cpu_to_be_16(seqno);
- ip->chksum = 0;
- ip->chksum = odph_ipv4_csum_update(pkt);
- offset += ODPH_IPV4HDR_LEN;
+ l4_offset = l3_offset + l3_hdr_len;
+ odp_packet_l4_offset_set(pkt, l4_offset);
+ tcp = (odph_tcphdr_t *)(buf + l4_offset);
+ udp = (odph_udphdr_t *)(buf + l4_offset);
/* udp */
- if (flag_udp) {
- odp_packet_l4_offset_set(pkt, offset);
- udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+ if (pkt_info.udp) {
udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
@@ -327,8 +352,6 @@ odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
return ODP_PACKET_INVALID;
}
} else {
- odp_packet_l4_offset_set(pkt, offset);
- tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
tcp->hl = ODPH_TCPHDR_LEN / 4;
@@ -338,6 +361,7 @@ odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
LOG_ERR("odph_udp_tcp_chksum failed\n");
return ODP_PACKET_INVALID;
}
+
}
/* set pkt sequence number */
diff --git a/test/common_plat/validation/api/classification/odp_classification_test_pmr.c b/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
index 88fbf8f48..d95242055 100644
--- a/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
+++ b/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
@@ -7,16 +7,13 @@
#include "odp_classification_testsuites.h"
#include "classification.h"
#include <odp_cunit_common.h>
-#include <odp/helper/eth.h>
-#include <odp/helper/ip.h>
-#include <odp/helper/udp.h>
-#include <odp/helper/tcp.h>
static odp_pool_t pkt_pool;
-
/** sequence number of IP packets */
odp_atomic_u32_t seq;
+static cls_packet_info_t default_pkt_info;
+
int classification_suite_pmr_init(void)
{
pkt_pool = pool_create("classification_pmr_pool");
@@ -25,7 +22,12 @@ int classification_suite_pmr_init(void)
return -1;
}
+ memset(&default_pkt_info, 0, sizeof(cls_packet_info_t));
+ default_pkt_info.pool = pkt_pool;
+ default_pkt_info.seq = &seq;
+
odp_atomic_init_u32(&seq, 0);
+
return 0;
}
@@ -107,7 +109,6 @@ void classification_test_pmr_term_tcp_dport(void)
odp_pool_t pool_recv;
odp_pmr_param_t pmr_param;
odph_ethhdr_t *eth;
-
val = CLS_DEFAULT_DPORT;
mask = 0xffff;
seqno = 0;
@@ -144,7 +145,7 @@ void classification_test_pmr_term_tcp_dport(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -167,7 +168,7 @@ void classification_test_pmr_term_tcp_dport(void)
odp_packet_free(pkt);
/* Other packets are delivered to default queue */
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -258,7 +259,7 @@ void classification_test_pmr_term_tcp_sport(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -279,7 +280,7 @@ void classification_test_pmr_term_tcp_sport(void)
CU_ASSERT(recvpool == pool);
odp_packet_free(pkt);
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -333,6 +334,7 @@ void classification_test_pmr_term_udp_dport(void)
odp_pmr_param_t pmr_param;
odp_cls_cos_param_t cls_param;
odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
val = CLS_DEFAULT_DPORT;
mask = 0xffff;
@@ -370,7 +372,9 @@ void classification_test_pmr_term_udp_dport(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -392,7 +396,7 @@ void classification_test_pmr_term_udp_dport(void)
odp_packet_free(pkt);
/* Other packets received in default queue */
- pkt = create_packet(pkt_pool, false, &seq, true);
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -446,6 +450,7 @@ void classification_test_pmr_term_udp_sport(void)
odp_pmr_param_t pmr_param;
odp_cls_cos_param_t cls_param;
odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
val = CLS_DEFAULT_SPORT;
mask = 0xffff;
@@ -483,7 +488,9 @@ void classification_test_pmr_term_udp_sport(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -504,7 +511,7 @@ void classification_test_pmr_term_udp_sport(void)
CU_ASSERT(recvpool == pool);
odp_packet_free(pkt);
- pkt = create_packet(pkt_pool, false, &seq, true);
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -557,6 +564,7 @@ void classification_test_pmr_term_ipproto(void)
odp_cls_cos_param_t cls_param;
odp_pmr_param_t pmr_param;
odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
val = ODPH_IPPROTO_UDP;
mask = 0xff;
@@ -594,7 +602,9 @@ void classification_test_pmr_term_ipproto(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -613,7 +623,7 @@ void classification_test_pmr_term_ipproto(void)
odp_packet_free(pkt);
/* Other packets delivered to default queue */
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -663,6 +673,7 @@ void classification_test_pmr_term_dmac(void)
odp_cls_cos_param_t cls_param;
odp_pmr_param_t pmr_param;
odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
val = CLS_DEFAULT_DMAC; /* 48 bit Ethernet Mac address */
mask = 0xffffffffffff;
@@ -700,7 +711,9 @@ void classification_test_pmr_term_dmac(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -716,7 +729,7 @@ void classification_test_pmr_term_dmac(void)
odp_packet_free(pkt);
/* Other packets delivered to default queue */
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
memset(eth->dst.addr, 0, ODPH_ETHADDR_LEN);
@@ -766,6 +779,7 @@ void classification_test_pmr_term_packet_len(void)
odp_cls_cos_param_t cls_param;
odp_pmr_param_t pmr_param;
odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
val = 1024;
/*Mask value will match any packet of length 1000 - 1099*/
@@ -805,7 +819,365 @@ void classification_test_pmr_term_packet_len(void)
CU_ASSERT(pmr != ODP_PMR_INVAL);
/* create packet of payload length 1024 */
- pkt = create_packet_len(pkt_pool, false, &seq, true, 1024);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt_info.len = 1024;
+ pkt = create_packet(pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ recvpool = odp_packet_pool(pkt);
+ CU_ASSERT(recvpool == pool);
+ CU_ASSERT(retqueue == queue);
+ odp_packet_free(pkt);
+
+ /* Other packets delivered to default queue */
+ pkt = create_packet(default_pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ recvpool = odp_packet_pool(pkt);
+ CU_ASSERT(recvpool == default_pool);
+ CU_ASSERT(retqueue == default_queue);
+
+ odp_cos_destroy(cos);
+ odp_cos_destroy(default_cos);
+ odp_cls_pmr_destroy(pmr);
+ odp_packet_free(pkt);
+ stop_pktio(pktio);
+ odp_pool_destroy(default_pool);
+ odp_pool_destroy(pool);
+ odp_queue_destroy(queue);
+ odp_queue_destroy(default_queue);
+ odp_pktio_close(pktio);
+}
+
+void classification_test_pmr_term_vlan_id_0(void)
+{
+ odp_packet_t pkt;
+ uint32_t seqno;
+ uint16_t val;
+ uint16_t mask;
+ int retval;
+ odp_pktio_t pktio;
+ odp_queue_t queue;
+ odp_queue_t retqueue;
+ odp_queue_t default_queue;
+ odp_cos_t default_cos;
+ odp_pool_t default_pool;
+ odp_pool_t pool;
+ odp_pool_t recvpool;
+ odp_pmr_t pmr;
+ odp_cos_t cos;
+ char cosname[ODP_COS_NAME_LEN];
+ odp_cls_cos_param_t cls_param;
+ odp_pmr_param_t pmr_param;
+ odph_ethhdr_t *eth;
+ odph_vlanhdr_t *vlan_0;
+ cls_packet_info_t pkt_info;
+
+ val = 1024;
+ mask = 0xff00;
+ seqno = 0;
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+ CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
+ retval = start_pktio(pktio);
+ CU_ASSERT(retval == 0);
+
+ configure_default_cos(pktio, &default_cos,
+ &default_queue, &default_pool);
+
+ queue = queue_create("vlan_id_0", true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ pool = pool_create("vlan_id_0");
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ sprintf(cosname, "vlan_id_0");
+ odp_cls_cos_param_init(&cls_param);
+ cls_param.pool = pool;
+ cls_param.queue = queue;
+ cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+ cos = odp_cls_cos_create(cosname, &cls_param);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ odp_cls_pmr_param_init(&pmr_param);
+ pmr_param.term = ODP_PMR_VLAN_ID_0;
+ pmr_param.match.value = &val;
+ pmr_param.match.mask = &mask;
+ pmr_param.val_sz = sizeof(val);
+
+ pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ /* create packet of payload length 1024 */
+ pkt_info = default_pkt_info;
+ pkt_info.vlan = true;
+ pkt_info.vlan_qinq = true;
+ pkt = create_packet(pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+ vlan_0 = (odph_vlanhdr_t *)(eth + 1);
+ vlan_0->tci = odp_cpu_to_be_16(1024);
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ recvpool = odp_packet_pool(pkt);
+ CU_ASSERT(recvpool == pool);
+ CU_ASSERT(retqueue == queue);
+ odp_packet_free(pkt);
+
+ /* Other packets delivered to default queue */
+ pkt = create_packet(default_pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ recvpool = odp_packet_pool(pkt);
+ CU_ASSERT(recvpool == default_pool);
+ CU_ASSERT(retqueue == default_queue);
+
+ odp_cos_destroy(cos);
+ odp_cos_destroy(default_cos);
+ odp_cls_pmr_destroy(pmr);
+ odp_packet_free(pkt);
+ stop_pktio(pktio);
+ odp_pool_destroy(default_pool);
+ odp_pool_destroy(pool);
+ odp_queue_destroy(queue);
+ odp_queue_destroy(default_queue);
+ odp_pktio_close(pktio);
+}
+
+void classification_test_pmr_term_vlan_id_x(void)
+{
+ odp_packet_t pkt;
+ uint32_t seqno;
+ uint16_t val;
+ uint16_t mask;
+ int retval;
+ odp_pktio_t pktio;
+ odp_queue_t queue;
+ odp_queue_t retqueue;
+ odp_queue_t default_queue;
+ odp_cos_t default_cos;
+ odp_pool_t default_pool;
+ odp_pool_t pool;
+ odp_pool_t recvpool;
+ odp_pmr_t pmr;
+ odp_cos_t cos;
+ char cosname[ODP_COS_NAME_LEN];
+ odp_cls_cos_param_t cls_param;
+ odp_pmr_param_t pmr_param;
+ odph_ethhdr_t *eth;
+ odph_vlanhdr_t *vlan_x;
+ cls_packet_info_t pkt_info;
+
+ val = 1024;
+ mask = 0xff00;
+ seqno = 0;
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+ CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
+ retval = start_pktio(pktio);
+ CU_ASSERT(retval == 0);
+
+ configure_default_cos(pktio, &default_cos,
+ &default_queue, &default_pool);
+
+ queue = queue_create("vlan_id_x", true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ pool = pool_create("vlan_id_x");
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ sprintf(cosname, "vlan_id_x");
+ odp_cls_cos_param_init(&cls_param);
+ cls_param.pool = pool;
+ cls_param.queue = queue;
+ cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+ cos = odp_cls_cos_create(cosname, &cls_param);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ odp_cls_pmr_param_init(&pmr_param);
+ pmr_param.term = ODP_PMR_VLAN_ID_X;
+ pmr_param.match.value = &val;
+ pmr_param.match.mask = &mask;
+ pmr_param.val_sz = sizeof(val);
+
+ pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ /* create packet of payload length 1024 */
+ pkt_info = default_pkt_info;
+ pkt_info.vlan = true;
+ pkt_info.vlan_qinq = true;
+ pkt = create_packet(pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+ vlan_x = (odph_vlanhdr_t *)(eth + 1);
+ vlan_x++;
+ vlan_x->tci = odp_cpu_to_be_16(1024);
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ recvpool = odp_packet_pool(pkt);
+ CU_ASSERT(recvpool == pool);
+ CU_ASSERT(retqueue == queue);
+ odp_packet_free(pkt);
+
+ /* Other packets delivered to default queue */
+ pkt = create_packet(default_pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ recvpool = odp_packet_pool(pkt);
+ CU_ASSERT(recvpool == default_pool);
+ CU_ASSERT(retqueue == default_queue);
+
+ odp_cos_destroy(cos);
+ odp_cos_destroy(default_cos);
+ odp_cls_pmr_destroy(pmr);
+ odp_packet_free(pkt);
+ stop_pktio(pktio);
+ odp_pool_destroy(default_pool);
+ odp_pool_destroy(pool);
+ odp_queue_destroy(queue);
+ odp_queue_destroy(default_queue);
+ odp_pktio_close(pktio);
+}
+
+void classification_test_pmr_term_eth_type_0(void)
+{
+ odp_packet_t pkt;
+ uint32_t seqno;
+ uint16_t val;
+ uint16_t mask;
+ int retval;
+ odp_pktio_t pktio;
+ odp_queue_t queue;
+ odp_queue_t retqueue;
+ odp_queue_t default_queue;
+ odp_cos_t default_cos;
+ odp_pool_t default_pool;
+ odp_pool_t pool;
+ odp_pool_t recvpool;
+ odp_pmr_t pmr;
+ odp_cos_t cos;
+ char cosname[ODP_COS_NAME_LEN];
+ odp_cls_cos_param_t cls_param;
+ odp_pmr_param_t pmr_param;
+ odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
+
+ val = 0x88A8;
+ mask = 0xffff;
+ seqno = 0;
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+ CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
+ retval = start_pktio(pktio);
+ CU_ASSERT(retval == 0);
+
+ configure_default_cos(pktio, &default_cos,
+ &default_queue, &default_pool);
+
+ queue = queue_create("eth_type_0", true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ pool = pool_create("eth_type_0");
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ sprintf(cosname, "eth_type_0");
+ odp_cls_cos_param_init(&cls_param);
+ cls_param.pool = pool;
+ cls_param.queue = queue;
+ cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+ cos = odp_cls_cos_create(cosname, &cls_param);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ odp_cls_pmr_param_init(&pmr_param);
+ pmr_param.term = ODP_PMR_ETHTYPE_0;
+ pmr_param.match.value = &val;
+ pmr_param.match.mask = &mask;
+ pmr_param.val_sz = sizeof(val);
+
+ pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ pkt_info = default_pkt_info;
+ pkt_info.vlan = true;
+ pkt_info.vlan_qinq = true;
+ pkt = create_packet(pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ recvpool = odp_packet_pool(pkt);
+ CU_ASSERT(recvpool == pool);
+ CU_ASSERT(retqueue == queue);
+ odp_packet_free(pkt);
+
+ /* Other packets delivered to default queue */
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -819,12 +1191,106 @@ void classification_test_pmr_term_packet_len(void)
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
recvpool = odp_packet_pool(pkt);
+ CU_ASSERT(recvpool == default_pool);
+ CU_ASSERT(retqueue == default_queue);
+
+ odp_cos_destroy(cos);
+ odp_cos_destroy(default_cos);
+ odp_cls_pmr_destroy(pmr);
+ odp_packet_free(pkt);
+ stop_pktio(pktio);
+ odp_pool_destroy(default_pool);
+ odp_pool_destroy(pool);
+ odp_queue_destroy(queue);
+ odp_queue_destroy(default_queue);
+ odp_pktio_close(pktio);
+}
+
+void classification_test_pmr_term_eth_type_x(void)
+{
+ odp_packet_t pkt;
+ uint32_t seqno;
+ uint16_t val;
+ uint16_t mask;
+ int retval;
+ odp_pktio_t pktio;
+ odp_queue_t queue;
+ odp_queue_t retqueue;
+ odp_queue_t default_queue;
+ odp_cos_t default_cos;
+ odp_pool_t default_pool;
+ odp_pool_t pool;
+ odp_pool_t recvpool;
+ odp_pmr_t pmr;
+ odp_cos_t cos;
+ char cosname[ODP_COS_NAME_LEN];
+ odp_cls_cos_param_t cls_param;
+ odp_pmr_param_t pmr_param;
+ odph_ethhdr_t *eth;
+ odph_vlanhdr_t *vlan_x;
+ cls_packet_info_t pkt_info;
+
+ val = 0x8100;
+ mask = 0xff00;
+ seqno = 0;
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+ CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
+ retval = start_pktio(pktio);
+ CU_ASSERT(retval == 0);
+
+ configure_default_cos(pktio, &default_cos,
+ &default_queue, &default_pool);
+
+ queue = queue_create("eth_type_x", true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ pool = pool_create("eth_type_x");
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ sprintf(cosname, "eth_type_x");
+ odp_cls_cos_param_init(&cls_param);
+ cls_param.pool = pool;
+ cls_param.queue = queue;
+ cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+ cos = odp_cls_cos_create(cosname, &cls_param);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ odp_cls_pmr_param_init(&pmr_param);
+ pmr_param.term = ODP_PMR_ETHTYPE_X;
+ pmr_param.match.value = &val;
+ pmr_param.match.mask = &mask;
+ pmr_param.val_sz = sizeof(val);
+
+ pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ /* create packet of payload length 1024 */
+ pkt_info = default_pkt_info;
+ pkt_info.vlan = true;
+ pkt_info.vlan_qinq = true;
+ pkt = create_packet(pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+ vlan_x = (odph_vlanhdr_t *)(eth + 1);
+ vlan_x->tci = odp_cpu_to_be_16(1024);
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ recvpool = odp_packet_pool(pkt);
CU_ASSERT(recvpool == pool);
CU_ASSERT(retqueue == queue);
odp_packet_free(pkt);
/* Other packets delivered to default queue */
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -875,6 +1341,7 @@ static void classification_test_pmr_pool_set(void)
odp_cls_cos_param_t cls_param;
odp_pmr_param_t pmr_param;
odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
val = ODPH_IPPROTO_UDP;
mask = 0xff;
@@ -919,7 +1386,9 @@ static void classification_test_pmr_pool_set(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -971,6 +1440,7 @@ static void classification_test_pmr_queue_set(void)
odp_cls_cos_param_t cls_param;
odp_pmr_param_t pmr_param;
odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
val = ODPH_IPPROTO_UDP;
mask = 0xff;
@@ -1014,8 +1484,9 @@ static void classification_test_pmr_queue_set(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
CU_ASSERT(pmr != ODP_PMR_INVAL);
-
- pkt = create_packet(pkt_pool, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -1102,7 +1573,7 @@ static void classification_test_pmr_term_daddr(void)
/* packet with dst ip address matching PMR rule to be
received in the CoS queue*/
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
@@ -1123,7 +1594,229 @@ static void classification_test_pmr_term_daddr(void)
odp_packet_free(pkt);
/* Other packets delivered to default queue */
- pkt = create_packet(pkt_pool, false, &seq, false);
+ pkt = create_packet(default_pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ CU_ASSERT(retqueue == default_queue);
+
+ odp_cos_destroy(cos);
+ odp_cos_destroy(default_cos);
+ odp_cls_pmr_destroy(pmr);
+ odp_packet_free(pkt);
+ stop_pktio(pktio);
+ odp_pool_destroy(default_pool);
+ odp_pool_destroy(pool);
+ odp_queue_destroy(queue);
+ odp_queue_destroy(default_queue);
+ odp_pktio_close(pktio);
+}
+
+static void classification_test_pmr_term_ipv6daddr(void)
+{
+ odp_packet_t pkt;
+ uint32_t seqno;
+ int retval;
+ odp_pktio_t pktio;
+ odp_queue_t queue;
+ odp_queue_t retqueue;
+ odp_queue_t default_queue;
+ odp_pool_t pool;
+ odp_pool_t default_pool;
+ odp_pmr_t pmr;
+ odp_cos_t cos;
+ odp_cos_t default_cos;
+ char cosname[ODP_QUEUE_NAME_LEN];
+ odp_pmr_param_t pmr_param;
+ odp_cls_cos_param_t cls_param;
+ odph_ipv6hdr_t *ip;
+ odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
+
+ uint8_t IPV6_DST_ADDR[ODPH_IPV6ADDR_LEN] = {
+ /* I.e. ::ffff:10.1.1.100 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 1, 1, 100
+ };
+ uint8_t ipv6_mask[ODPH_IPV6ADDR_LEN] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ };
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+ retval = start_pktio(pktio);
+ CU_ASSERT(retval == 0);
+
+ configure_default_cos(pktio, &default_cos,
+ &default_queue, &default_pool);
+
+ queue = queue_create("daddr", true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ pool = pool_create("daddr");
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ sprintf(cosname, "daddr");
+ odp_cls_cos_param_init(&cls_param);
+ cls_param.pool = pool;
+ cls_param.queue = queue;
+ cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+ cos = odp_cls_cos_create(cosname, &cls_param);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ odp_cls_pmr_param_init(&pmr_param);
+ pmr_param.term = ODP_PMR_DIP6_ADDR;
+ pmr_param.match.value = IPV6_DST_ADDR;
+ pmr_param.match.mask = ipv6_mask;
+ pmr_param.val_sz = ODPH_IPV6ADDR_LEN;
+
+ pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+ CU_ASSERT_FATAL(pmr != ODP_PMR_INVAL);
+
+ /* packet with dst ip address matching PMR rule to be
+ received in the CoS queue*/
+ pkt_info = default_pkt_info;
+ pkt_info.ipv6 = true;
+ pkt = create_packet(pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+ ip = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+ memcpy(ip->dst_addr, IPV6_DST_ADDR, ODPH_IPV6ADDR_LEN);
+
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ CU_ASSERT(retqueue == queue);
+ odp_packet_free(pkt);
+
+ /* Other packets delivered to default queue */
+ pkt = create_packet(pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ CU_ASSERT(retqueue == default_queue);
+
+ odp_cos_destroy(cos);
+ odp_cos_destroy(default_cos);
+ odp_cls_pmr_destroy(pmr);
+ odp_packet_free(pkt);
+ stop_pktio(pktio);
+ odp_pool_destroy(default_pool);
+ odp_pool_destroy(pool);
+ odp_queue_destroy(queue);
+ odp_queue_destroy(default_queue);
+ odp_pktio_close(pktio);
+}
+
+static void classification_test_pmr_term_ipv6saddr(void)
+{
+ odp_packet_t pkt;
+ uint32_t seqno;
+ int retval;
+ odp_pktio_t pktio;
+ odp_queue_t queue;
+ odp_queue_t retqueue;
+ odp_queue_t default_queue;
+ odp_pool_t pool;
+ odp_pool_t default_pool;
+ odp_pmr_t pmr;
+ odp_cos_t cos;
+ odp_cos_t default_cos;
+ char cosname[ODP_QUEUE_NAME_LEN];
+ odp_pmr_param_t pmr_param;
+ odp_cls_cos_param_t cls_param;
+ odph_ipv6hdr_t *ip;
+ odph_ethhdr_t *eth;
+ cls_packet_info_t pkt_info;
+ uint8_t IPV6_SRC_ADDR[ODPH_IPV6ADDR_LEN] = {
+ /* I.e. ::ffff:10.0.0.100 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 1, 1, 1
+ };
+ uint8_t ipv6_mask[ODPH_IPV6ADDR_LEN] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ };
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+ retval = start_pktio(pktio);
+ CU_ASSERT(retval == 0);
+
+ configure_default_cos(pktio, &default_cos,
+ &default_queue, &default_pool);
+
+ queue = queue_create("saddr", true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ pool = pool_create("saddr");
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ sprintf(cosname, "saddr");
+ odp_cls_cos_param_init(&cls_param);
+ cls_param.pool = pool;
+ cls_param.queue = queue;
+ cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+ cos = odp_cls_cos_create(cosname, &cls_param);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ odp_cls_pmr_param_init(&pmr_param);
+ pmr_param.term = ODP_PMR_SIP6_ADDR;
+ pmr_param.match.value = IPV6_SRC_ADDR;
+ pmr_param.match.mask = ipv6_mask;
+ pmr_param.val_sz = ODPH_IPV6ADDR_LEN;
+
+ pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+ CU_ASSERT_FATAL(pmr != ODP_PMR_INVAL);
+
+ /* packet with dst ip address matching PMR rule to be
+ received in the CoS queue*/
+ pkt_info = default_pkt_info;
+ pkt_info.ipv6 = true;
+
+ pkt = create_packet(pkt_info);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+ odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+ odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+ ip = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+ memcpy(ip->src_addr, IPV6_SRC_ADDR, ODPH_IPV6ADDR_LEN);
+
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+ CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ CU_ASSERT(retqueue == queue);
+ odp_packet_free(pkt);
+
+ /* Other packets delivered to default queue */
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -1160,6 +1853,12 @@ odp_testinfo_t classification_suite_pmr[] = {
ODP_TEST_INFO(classification_test_pmr_pool_set),
ODP_TEST_INFO(classification_test_pmr_queue_set),
ODP_TEST_INFO(classification_test_pmr_term_daddr),
+ ODP_TEST_INFO(classification_test_pmr_term_ipv6saddr),
+ ODP_TEST_INFO(classification_test_pmr_term_ipv6daddr),
ODP_TEST_INFO(classification_test_pmr_term_packet_len),
+ ODP_TEST_INFO(classification_test_pmr_term_vlan_id_0),
+ ODP_TEST_INFO(classification_test_pmr_term_vlan_id_x),
+ ODP_TEST_INFO(classification_test_pmr_term_eth_type_0),
+ ODP_TEST_INFO(classification_test_pmr_term_eth_type_x),
ODP_TEST_INFO_NULL,
};
diff --git a/test/common_plat/validation/api/classification/odp_classification_tests.c b/test/common_plat/validation/api/classification/odp_classification_tests.c
index ed45518be..4f4308264 100644
--- a/test/common_plat/validation/api/classification/odp_classification_tests.c
+++ b/test/common_plat/validation/api/classification/odp_classification_tests.c
@@ -7,10 +7,6 @@
#include "odp_classification_testsuites.h"
#include "classification.h"
#include <odp_cunit_common.h>
-#include <odp/helper/eth.h>
-#include <odp/helper/ip.h>
-#include <odp/helper/udp.h>
-#include <odp/helper/tcp.h>
static odp_cos_t cos_list[CLS_ENTRIES];
static odp_pmr_t pmr_list[CLS_ENTRIES];
@@ -23,6 +19,9 @@ static odp_pktio_t pktio_loop;
/** sequence number of IP packets */
odp_atomic_u32_t seq;
+/* default packet info */
+static cls_packet_info_t default_pkt_info;
+
int classification_suite_init(void)
{
int i;
@@ -47,6 +46,10 @@ int classification_suite_init(void)
return -1;
}
+ memset(&default_pkt_info, 0, sizeof(cls_packet_info_t));
+ default_pkt_info.pool = pool_default;
+ default_pkt_info.seq = &seq;
+
odp_pktin_queue_param_init(&pktin_param);
pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;
@@ -220,8 +223,11 @@ void test_cls_pmr_chain(void)
uint32_t addr = 0;
uint32_t mask;
uint32_t seqno = 0;
+ cls_packet_info_t pkt_info;
- pkt = create_packet(pool_default, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -244,7 +250,7 @@ void test_cls_pmr_chain(void)
CU_ASSERT(pool == pool_list[CLS_PMR_CHAIN_DST]);
odp_packet_free(pkt);
- pkt = create_packet(pool_default, false, &seq, true);
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -305,8 +311,12 @@ void test_pktio_default_cos(void)
odp_queue_t queue;
uint32_t seqno = 0;
odp_pool_t pool;
+ cls_packet_info_t pkt_info;
+
/* create a default packet */
- pkt = create_packet(pool_default, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -364,9 +374,12 @@ void test_pktio_error_cos(void)
odp_queue_t queue;
odp_packet_t pkt;
odp_pool_t pool;
+ cls_packet_info_t pkt_info;
/*Create an error packet */
- pkt = create_packet(pool_default, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
@@ -476,10 +489,15 @@ void test_cos_with_l2_priority(void)
odp_queue_t queue;
odp_pool_t pool;
uint32_t seqno = 0;
+ cls_packet_info_t pkt_info;
uint8_t i;
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt_info.vlan = true;
+
for (i = 0; i < CLS_L2_QOS_MAX; i++) {
- pkt = create_packet(pool_default, true, &seq, true);
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -550,8 +568,11 @@ void test_pmr_cos(void)
odp_queue_t queue;
odp_pool_t pool;
uint32_t seqno = 0;
+ cls_packet_info_t pkt_info;
- pkt = create_packet(pool_default, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -633,8 +654,11 @@ void test_pktio_pmr_composite_cos(void)
odp_pool_t pool;
odp_queue_t queue;
uint32_t seqno = 0;
+ cls_packet_info_t pkt_info;
- pkt = create_packet(pool_default, false, &seq, true);
+ pkt_info = default_pkt_info;
+ pkt_info.udp = true;
+ pkt = create_packet(pkt_info);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
diff --git a/test/common_plat/validation/api/classification/odp_classification_testsuites.h b/test/common_plat/validation/api/classification/odp_classification_testsuites.h
index aea3de1b1..d296923ad 100644
--- a/test/common_plat/validation/api/classification/odp_classification_testsuites.h
+++ b/test/common_plat/validation/api/classification/odp_classification_testsuites.h
@@ -8,9 +8,20 @@
#define ODP_CLASSIFICATION_TESTSUITES_H_
#include <odp_api.h>
+#include <odp/helper/odph_api.h>
#include <odp_cunit_common.h>
#include <stdbool.h>
+typedef struct cls_packet_info {
+ odp_pool_t pool;
+ bool vlan;
+ bool vlan_qinq;
+ odp_atomic_u32_t *seq;
+ bool udp;
+ bool ipv6;
+ uint32_t len;
+} cls_packet_info_t;
+
extern odp_testinfo_t classification_suite[];
extern odp_testinfo_t classification_suite_basic[];
extern odp_testinfo_t classification_suite_pmr[];
@@ -21,11 +32,7 @@ int classification_suite_term(void);
int classification_suite_pmr_term(void);
int classification_suite_pmr_init(void);
-odp_packet_t create_packet(odp_pool_t pool, bool vlan,
- odp_atomic_u32_t *seq, bool udp);
-odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
- odp_atomic_u32_t *seq, bool flag_udp,
- uint16_t len);
+odp_packet_t create_packet(cls_packet_info_t pkt_info);
int cls_pkt_set_seq(odp_packet_t pkt);
uint32_t cls_pkt_get_seq(odp_packet_t pkt);
odp_pktio_t create_pktio(odp_queue_type_t q_type, odp_pool_t pool);
diff --git a/test/common_plat/validation/api/crypto/crypto.c b/test/common_plat/validation/api/crypto/crypto.c
index 208901682..e7c2bf320 100644
--- a/test/common_plat/validation/api/crypto/crypto.c
+++ b/test/common_plat/validation/api/crypto/crypto.c
@@ -13,8 +13,10 @@
#define PKT_POOL_LEN (1 * 1024)
odp_suiteinfo_t crypto_suites[] = {
- {ODP_CRYPTO_SYNC_INP, crypto_suite_sync_init, NULL, crypto_suite},
- {ODP_CRYPTO_ASYNC_INP, crypto_suite_async_init, NULL, crypto_suite},
+ {ODP_CRYPTO_SYNC_INP, crypto_suite_sync_init, crypto_suite_term,
+ crypto_suite},
+ {ODP_CRYPTO_ASYNC_INP, crypto_suite_async_init, crypto_suite_term,
+ crypto_suite},
ODP_SUITE_INFO_NULL,
};
diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
index de9d6e459..43ddb2ffd 100644
--- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
@@ -21,6 +21,40 @@ struct suite_context_s {
static struct suite_context_s suite_context;
+static const char *auth_alg_name(odp_auth_alg_t auth)
+{
+ switch (auth) {
+ case ODP_AUTH_ALG_NULL:
+ return "ODP_AUTH_ALG_NULL";
+ case ODP_AUTH_ALG_MD5_HMAC:
+ return "ODP_AUTH_ALG_MD5_HMAC";
+ case ODP_AUTH_ALG_SHA256_HMAC:
+ return "ODP_AUTH_ALG_SHA256_HMAC";
+ case ODP_AUTH_ALG_AES_GCM:
+ return "ODP_AUTH_ALG_AES_GCM";
+ default:
+ return "Unknown";
+ }
+}
+
+static const char *cipher_alg_name(odp_cipher_alg_t cipher)
+{
+ switch (cipher) {
+ case ODP_CIPHER_ALG_NULL:
+ return "ODP_CIPHER_ALG_NULL";
+ case ODP_CIPHER_ALG_DES:
+ return "ODP_CIPHER_ALG_DES";
+ case ODP_CIPHER_ALG_3DES_CBC:
+ return "ODP_CIPHER_ALG_3DES_CBC";
+ case ODP_CIPHER_ALG_AES_CBC:
+ return "ODP_CIPHER_ALG_AES_CBC";
+ case ODP_CIPHER_ALG_AES_GCM:
+ return "ODP_CIPHER_ALG_AES_GCM";
+ default:
+ return "Unknown";
+ }
+}
+
/* Basic algorithm run function for async inplace mode.
* Creates a session from input parameters and runs one operation
* on input_vec. Checks the output of the crypto operation against
@@ -47,7 +81,7 @@ static void alg_test(odp_crypto_op_t op,
uint32_t digest_len)
{
odp_crypto_session_t session;
- odp_crypto_capability_t capability;
+ odp_crypto_capability_t capa;
int rc;
odp_crypto_ses_create_err_t status;
odp_bool_t posted;
@@ -63,50 +97,43 @@ static void alg_test(odp_crypto_op_t op,
int num, i;
int found;
- rc = odp_crypto_capability(&capability);
+ rc = odp_crypto_capability(&capa);
CU_ASSERT(!rc);
- if (capability.hw_ciphers.all_bits) {
- if (cipher_alg == ODP_CIPHER_ALG_3DES_CBC &&
- !(capability.hw_ciphers.bit.trides_cbc))
- rc = -1;
- if (cipher_alg == ODP_CIPHER_ALG_AES_CBC &&
- !(capability.hw_ciphers.bit.aes_cbc))
- rc = -1;
- if (cipher_alg == ODP_CIPHER_ALG_AES_GCM &&
- !(capability.hw_ciphers.bit.aes_gcm))
- rc = -1;
- } else {
- if (cipher_alg == ODP_CIPHER_ALG_3DES_CBC &&
- !(capability.ciphers.bit.trides_cbc))
- rc = -1;
- if (cipher_alg == ODP_CIPHER_ALG_AES_CBC &&
- !(capability.ciphers.bit.aes_cbc))
- rc = -1;
- if (cipher_alg == ODP_CIPHER_ALG_AES_GCM &&
- !(capability.ciphers.bit.aes_gcm))
- rc = -1;
- }
+ if (cipher_alg == ODP_CIPHER_ALG_3DES_CBC &&
+ !(capa.ciphers.bit.trides_cbc))
+ rc = -1;
+ if (cipher_alg == ODP_CIPHER_ALG_AES_CBC &&
+ !(capa.ciphers.bit.aes_cbc))
+ rc = -1;
+ if (cipher_alg == ODP_CIPHER_ALG_AES_GCM &&
+ !(capa.ciphers.bit.aes_gcm))
+ rc = -1;
+ if (cipher_alg == ODP_CIPHER_ALG_DES &&
+ !(capa.ciphers.bit.des))
+ rc = -1;
+ if (cipher_alg == ODP_CIPHER_ALG_NULL &&
+ !(capa.ciphers.bit.null))
+ rc = -1;
CU_ASSERT(!rc);
-
- if (capability.hw_auths.all_bits) {
- if (auth_alg == ODP_AUTH_ALG_AES_GCM &&
- !(capability.hw_auths.bit.aes_gcm))
- rc = -1;
- if (auth_alg == ODP_AUTH_ALG_NULL &&
- !(capability.hw_auths.bit.null))
- rc = -1;
- } else {
- if (auth_alg == ODP_AUTH_ALG_AES_GCM &&
- !(capability.auths.bit.aes_gcm))
- rc = -1;
- if (auth_alg == ODP_AUTH_ALG_NULL &&
- !(capability.auths.bit.null))
- rc = -1;
- }
+ CU_ASSERT((~capa.ciphers.all_bits & capa.hw_ciphers.all_bits) == 0);
+
+ if (auth_alg == ODP_AUTH_ALG_AES_GCM &&
+ !(capa.auths.bit.aes_gcm))
+ rc = -1;
+ if (auth_alg == ODP_AUTH_ALG_MD5_HMAC &&
+ !(capa.auths.bit.md5_hmac))
+ rc = -1;
+ if (auth_alg == ODP_AUTH_ALG_NULL &&
+ !(capa.auths.bit.null))
+ rc = -1;
+ if (auth_alg == ODP_AUTH_ALG_SHA256_HMAC &&
+ !(capa.auths.bit.sha256_hmac))
+ rc = -1;
CU_ASSERT(!rc);
+ CU_ASSERT((~capa.auths.all_bits & capa.hw_auths.all_bits) == 0);
num = odp_crypto_cipher_capability(cipher_alg, cipher_capa,
MAX_ALG_CAPA);
@@ -250,6 +277,150 @@ cleanup:
odp_packet_free(pkt);
}
+/**
+ * Check if given cipher and authentication algorithms are supported
+ *
+ * @param cipher Cipher algorithm
+ * @param auth Authentication algorithm
+ *
+ * @retval ODP_TEST_ACTIVE when both algorithms are supported
+ * @retval ODP_TEST_INACTIVE when either algorithm is not supported
+ */
+static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth)
+{
+ odp_crypto_capability_t capability;
+
+ if (odp_crypto_capability(&capability))
+ return ODP_TEST_INACTIVE;
+
+ /* Cipher algorithms */
+ switch (cipher) {
+ case ODP_CIPHER_ALG_NULL:
+ if (!capability.ciphers.bit.null)
+ return ODP_TEST_INACTIVE;
+ break;
+ case ODP_CIPHER_ALG_DES:
+ if (!capability.ciphers.bit.des)
+ return ODP_TEST_INACTIVE;
+ break;
+ case ODP_CIPHER_ALG_3DES_CBC:
+ if (!capability.ciphers.bit.trides_cbc)
+ return ODP_TEST_INACTIVE;
+ break;
+ case ODP_CIPHER_ALG_AES_CBC:
+ if (!capability.ciphers.bit.aes_cbc)
+ return ODP_TEST_INACTIVE;
+ break;
+ case ODP_CIPHER_ALG_AES_GCM:
+ if (!capability.ciphers.bit.aes_gcm)
+ return ODP_TEST_INACTIVE;
+ break;
+ default:
+ fprintf(stderr, "Unsupported cipher algorithm\n");
+ return ODP_TEST_INACTIVE;
+ }
+
+ /* Authentication algorithms */
+ switch (auth) {
+ case ODP_AUTH_ALG_NULL:
+ if (!capability.auths.bit.null)
+ return ODP_TEST_INACTIVE;
+ break;
+ case ODP_AUTH_ALG_MD5_HMAC:
+ if (!capability.auths.bit.md5_hmac)
+ return ODP_TEST_INACTIVE;
+ break;
+ case ODP_AUTH_ALG_SHA256_HMAC:
+ if (!capability.auths.bit.sha256_hmac)
+ return ODP_TEST_INACTIVE;
+ break;
+ case ODP_AUTH_ALG_AES_GCM:
+ if (!capability.auths.bit.aes_gcm)
+ return ODP_TEST_INACTIVE;
+ break;
+ default:
+ fprintf(stderr, "Unsupported authentication algorithm\n");
+ return ODP_TEST_INACTIVE;
+ }
+
+ return ODP_TEST_ACTIVE;
+}
+
+/**
+ * Check if given cipher options are supported
+ *
+ * @param cipher Cipher algorithm
+ * @param key_len Key length
+ * @param iv_len IV length
+ *
+ * @retval non-zero if both cipher options are supported
+ * @retval 0 if both options are not supported
+ */
+static int check_cipher_options(odp_cipher_alg_t cipher, uint32_t key_len,
+ uint32_t iv_len)
+{
+ int i;
+ int num;
+ odp_crypto_cipher_capability_t cipher_capa[MAX_ALG_CAPA];
+
+ num = odp_crypto_cipher_capability(cipher, cipher_capa, MAX_ALG_CAPA);
+ CU_ASSERT_FATAL(num >= 1);
+
+ for (i = 0; i < num; i++) {
+ if (key_len == cipher_capa[i].key_len &&
+ iv_len == cipher_capa[i].iv_len)
+ break;
+ }
+
+ if (i == num) {
+ printf("\n Unsupported: alg=%s, key_len=%" PRIu32 ", "
+ "iv_len=%" PRIu32 "\n", cipher_alg_name(cipher), key_len,
+ iv_len);
+ return 0;
+ }
+ return 1;
+}
+
+/**
+ * Check if given authentication options are supported
+ *
+ * @param auth Authentication algorithm
+ * @param key_len Key length
+ * @param digest_len Digest length
+ *
+ * @retval non-zero if both authentication options are supported
+ * @retval 0 if both options are not supported
+ */
+static int check_auth_options(odp_auth_alg_t auth, uint32_t key_len,
+ uint32_t digest_len)
+{
+ int i;
+ int num;
+ odp_crypto_auth_capability_t capa[MAX_ALG_CAPA];
+
+ num = odp_crypto_auth_capability(auth, capa, MAX_ALG_CAPA);
+ CU_ASSERT_FATAL(num >= 1);
+
+ for (i = 0; i < num; i++) {
+ if (key_len == capa[i].key_len &&
+ digest_len == capa[i].digest_len)
+ break;
+ }
+
+ if (i == num) {
+ printf("\n Unsupported: alg=%s, key_len=%" PRIu32 ", "
+ "digest_len=%" PRIu32 "\n", auth_alg_name(auth), key_len,
+ digest_len);
+ return 0;
+ }
+ return 1;
+}
+
+static int check_alg_3des_cbc(void)
+{
+ return check_alg_support(ODP_CIPHER_ALG_3DES_CBC, ODP_AUTH_ALG_NULL);
+}
+
/* This test verifies the correctness of encode (plaintext -> ciphertext)
* operation for 3DES_CBC algorithm. IV for the operation is the session IV.
* In addition the test verifies if the implementation can use the
@@ -269,6 +440,10 @@ void crypto_test_enc_alg_3des_cbc(void)
iv.data = tdes_cbc_reference_iv[i];
iv.length = sizeof(tdes_cbc_reference_iv[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_3DES_CBC,
+ cipher_key.length, iv.length))
+ continue;
+
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_3DES_CBC,
iv,
@@ -300,6 +475,10 @@ void crypto_test_enc_alg_3des_cbc_ovr_iv(void)
cipher_key.data = tdes_cbc_reference_key[i];
cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_3DES_CBC,
+ cipher_key.length, iv.length))
+ continue;
+
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_3DES_CBC,
iv,
@@ -335,6 +514,10 @@ void crypto_test_dec_alg_3des_cbc(void)
iv.data = tdes_cbc_reference_iv[i];
iv.length = sizeof(tdes_cbc_reference_iv[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_3DES_CBC,
+ cipher_key.length, iv.length))
+ continue;
+
alg_test(ODP_CRYPTO_OP_DECODE,
ODP_CIPHER_ALG_3DES_CBC,
iv,
@@ -368,6 +551,10 @@ void crypto_test_dec_alg_3des_cbc_ovr_iv(void)
cipher_key.data = tdes_cbc_reference_key[i];
cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_3DES_CBC,
+ cipher_key.length, iv.length))
+ continue;
+
alg_test(ODP_CRYPTO_OP_DECODE,
ODP_CIPHER_ALG_3DES_CBC,
iv,
@@ -383,6 +570,11 @@ void crypto_test_dec_alg_3des_cbc_ovr_iv(void)
}
}
+static int check_alg_aes_gcm(void)
+{
+ return check_alg_support(ODP_CIPHER_ALG_AES_GCM, ODP_AUTH_ALG_AES_GCM);
+}
+
/* This test verifies the correctness of encode (plaintext -> ciphertext)
* operation for AES128_GCM algorithm. IV for the operation is the session IV.
* In addition the test verifies if the implementation can use the
@@ -402,6 +594,13 @@ void crypto_test_enc_alg_aes128_gcm(void)
iv.data = aes128_gcm_reference_iv[i];
iv.length = sizeof(aes128_gcm_reference_iv[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_AES_GCM,
+ cipher_key.length, iv.length))
+ continue;
+ if (!check_auth_options(ODP_AUTH_ALG_AES_GCM,
+ auth_key.length, AES128_GCM_CHECK_LEN))
+ continue;
+
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_AES_GCM,
iv,
@@ -438,6 +637,13 @@ void crypto_test_enc_alg_aes128_gcm_ovr_iv(void)
cipher_key.data = aes128_gcm_reference_key[i];
cipher_key.length = sizeof(aes128_gcm_reference_key[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_AES_GCM,
+ cipher_key.length, iv.length))
+ continue;
+ if (!check_auth_options(ODP_AUTH_ALG_AES_GCM,
+ auth_key.length, AES128_GCM_CHECK_LEN))
+ continue;
+
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_AES_GCM,
iv,
@@ -477,6 +683,13 @@ void crypto_test_dec_alg_aes128_gcm(void)
iv.data = aes128_gcm_reference_iv[i];
iv.length = sizeof(aes128_gcm_reference_iv[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_AES_GCM,
+ cipher_key.length, iv.length))
+ continue;
+ if (!check_auth_options(ODP_AUTH_ALG_AES_GCM,
+ auth_key.length, AES128_GCM_CHECK_LEN))
+ continue;
+
alg_test(ODP_CRYPTO_OP_DECODE,
ODP_CIPHER_ALG_AES_GCM,
iv,
@@ -514,6 +727,13 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void)
cipher_key.data = aes128_gcm_reference_key[i];
cipher_key.length = sizeof(aes128_gcm_reference_key[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_AES_GCM,
+ cipher_key.length, iv.length))
+ continue;
+ if (!check_auth_options(ODP_AUTH_ALG_AES_GCM,
+ auth_key.length, AES128_GCM_CHECK_LEN))
+ continue;
+
alg_test(ODP_CRYPTO_OP_DECODE,
ODP_CIPHER_ALG_AES_GCM,
iv,
@@ -533,6 +753,11 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void)
}
}
+static int check_alg_aes_cbc(void)
+{
+ return check_alg_support(ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_NULL);
+}
+
/* This test verifies the correctness of encode (plaintext -> ciphertext)
* operation for AES128_CBC algorithm. IV for the operation is the session IV.
* In addition the test verifies if the implementation can use the
@@ -552,6 +777,10 @@ void crypto_test_enc_alg_aes128_cbc(void)
iv.data = aes128_cbc_reference_iv[i];
iv.length = sizeof(aes128_cbc_reference_iv[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_AES_CBC,
+ cipher_key.length, iv.length))
+ continue;
+
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_AES_CBC,
iv,
@@ -583,6 +812,10 @@ void crypto_test_enc_alg_aes128_cbc_ovr_iv(void)
cipher_key.data = aes128_cbc_reference_key[i];
cipher_key.length = sizeof(aes128_cbc_reference_key[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_AES_CBC,
+ cipher_key.length, iv.length))
+ continue;
+
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_AES_CBC,
iv,
@@ -618,6 +851,10 @@ void crypto_test_dec_alg_aes128_cbc(void)
iv.data = aes128_cbc_reference_iv[i];
iv.length = sizeof(aes128_cbc_reference_iv[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_AES_CBC,
+ cipher_key.length, iv.length))
+ continue;
+
alg_test(ODP_CRYPTO_OP_DECODE,
ODP_CIPHER_ALG_AES_CBC,
iv,
@@ -651,6 +888,10 @@ void crypto_test_dec_alg_aes128_cbc_ovr_iv(void)
cipher_key.data = aes128_cbc_reference_key[i];
cipher_key.length = sizeof(aes128_cbc_reference_key[i]);
+ if (!check_cipher_options(ODP_CIPHER_ALG_AES_CBC,
+ cipher_key.length, iv.length))
+ continue;
+
alg_test(ODP_CRYPTO_OP_DECODE,
ODP_CIPHER_ALG_AES_CBC,
iv,
@@ -666,6 +907,11 @@ void crypto_test_dec_alg_aes128_cbc_ovr_iv(void)
}
}
+static int check_alg_hmac_md5(void)
+{
+ return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_MD5_HMAC);
+}
+
/* This test verifies the correctness of HMAC_MD5 digest operation.
* The output check length is truncated to 12 bytes (96 bits) as
* returned by the crypto operation API call.
@@ -687,6 +933,10 @@ void crypto_test_alg_hmac_md5(void)
auth_key.data = hmac_md5_reference_key[i];
auth_key.length = sizeof(hmac_md5_reference_key[i]);
+ if (!check_auth_options(ODP_AUTH_ALG_MD5_HMAC, auth_key.length,
+ HMAC_MD5_96_CHECK_LEN))
+ continue;
+
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_NULL,
iv,
@@ -703,6 +953,11 @@ void crypto_test_alg_hmac_md5(void)
}
}
+static int check_alg_hmac_sha256(void)
+{
+ return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC);
+}
+
/* This test verifies the correctness of HMAC_MD5 digest operation.
* The output check length is truncated to 12 bytes (96 bits) as
* returned by the crypto operation API call.
@@ -725,6 +980,11 @@ void crypto_test_alg_hmac_sha256(void)
auth_key.data = hmac_sha256_reference_key[i];
auth_key.length = sizeof(hmac_sha256_reference_key[i]);
+ if (!check_auth_options(ODP_AUTH_ALG_SHA256_HMAC,
+ auth_key.length,
+ HMAC_SHA256_128_CHECK_LEN))
+ continue;
+
alg_test(ODP_CRYPTO_OP_ENCODE,
ODP_CIPHER_ALG_NULL,
iv,
@@ -766,19 +1026,51 @@ int crypto_suite_async_init(void)
}
odp_testinfo_t crypto_suite[] = {
- ODP_TEST_INFO(crypto_test_enc_alg_3des_cbc),
- ODP_TEST_INFO(crypto_test_dec_alg_3des_cbc),
- ODP_TEST_INFO(crypto_test_enc_alg_3des_cbc_ovr_iv),
- ODP_TEST_INFO(crypto_test_dec_alg_3des_cbc_ovr_iv),
- ODP_TEST_INFO(crypto_test_enc_alg_aes128_cbc),
- ODP_TEST_INFO(crypto_test_dec_alg_aes128_cbc),
- ODP_TEST_INFO(crypto_test_enc_alg_aes128_cbc_ovr_iv),
- ODP_TEST_INFO(crypto_test_dec_alg_aes128_cbc_ovr_iv),
- ODP_TEST_INFO(crypto_test_enc_alg_aes128_gcm),
- ODP_TEST_INFO(crypto_test_enc_alg_aes128_gcm_ovr_iv),
- ODP_TEST_INFO(crypto_test_dec_alg_aes128_gcm),
- ODP_TEST_INFO(crypto_test_dec_alg_aes128_gcm_ovr_iv),
- ODP_TEST_INFO(crypto_test_alg_hmac_md5),
- ODP_TEST_INFO(crypto_test_alg_hmac_sha256),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_cbc,
+ check_alg_3des_cbc),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_cbc,
+ check_alg_3des_cbc),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_cbc_ovr_iv,
+ check_alg_3des_cbc),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_cbc_ovr_iv,
+ check_alg_3des_cbc),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes128_cbc,
+ check_alg_aes_cbc),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes128_cbc,
+ check_alg_aes_cbc),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes128_cbc_ovr_iv,
+ check_alg_aes_cbc),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes128_cbc_ovr_iv,
+ check_alg_aes_cbc),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes128_gcm,
+ check_alg_aes_gcm),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes128_gcm_ovr_iv,
+ check_alg_aes_gcm),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes128_gcm,
+ check_alg_aes_gcm),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes128_gcm_ovr_iv,
+ check_alg_aes_gcm),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_md5,
+ check_alg_hmac_md5),
+ ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha256,
+ check_alg_hmac_sha256),
ODP_TEST_INFO_NULL,
};
+
+int crypto_suite_term(void)
+{
+ int i;
+ int first = 1;
+
+ for (i = 0; crypto_suite[i].pName; i++) {
+ if (crypto_suite[i].check_active &&
+ crypto_suite[i].check_active() == ODP_TEST_INACTIVE) {
+ if (first) {
+ first = 0;
+ printf("\n\n Inactive tests:\n");
+ }
+ printf(" %s\n", crypto_suite[i].pName);
+ }
+ }
+ return 0;
+}
diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.h b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.h
index 8bda34472..0f6933790 100644
--- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.h
+++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.h
@@ -17,5 +17,6 @@ extern odp_testinfo_t crypto_suite[];
int crypto_suite_sync_init(void);
int crypto_suite_async_init(void);
+int crypto_suite_term(void);
#endif
diff --git a/test/common_plat/validation/api/packet/packet.c b/test/common_plat/validation/api/packet/packet.c
index 2b1ef802b..4aa3f598e 100644
--- a/test/common_plat/validation/api/packet/packet.c
+++ b/test/common_plat/validation/api/packet/packet.c
@@ -111,8 +111,10 @@ int packet_suite_init(void)
uint32_t i;
uint32_t num = 200;
- if (odp_pool_capability(&capa) < 0)
+ if (odp_pool_capability(&capa) < 0) {
+ printf("pool_capability failed\n");
return -1;
+ }
/* Pick a typical packet size and decrement it to the single segment
* limit if needed (min_seg_len maybe equal to max_len
@@ -139,14 +141,17 @@ int packet_suite_init(void)
params.pkt.uarea_size = sizeof(struct udata_struct);
packet_pool = odp_pool_create("packet_pool", &params);
- if (packet_pool == ODP_POOL_INVALID)
+ if (packet_pool == ODP_POOL_INVALID) {
+ printf("pool_create failed: 1\n");
return -1;
+ }
params.pkt.uarea_size = 0;
packet_pool_no_uarea = odp_pool_create("packet_pool_no_uarea",
&params);
if (packet_pool_no_uarea == ODP_POOL_INVALID) {
odp_pool_destroy(packet_pool);
+ printf("pool_create failed: 2\n");
return -1;
}
@@ -157,6 +162,7 @@ int packet_suite_init(void)
if (packet_pool_double_uarea == ODP_POOL_INVALID) {
odp_pool_destroy(packet_pool_no_uarea);
odp_pool_destroy(packet_pool);
+ printf("pool_create failed: 3\n");
return -1;
}
@@ -177,8 +183,10 @@ int packet_suite_init(void)
} while (segmented_test_packet == ODP_PACKET_INVALID);
if (odp_packet_is_valid(test_packet) == 0 ||
- odp_packet_is_valid(segmented_test_packet) == 0)
+ odp_packet_is_valid(segmented_test_packet) == 0) {
+ printf("packet_is_valid failed\n");
return -1;
+ }
segmentation_supported = odp_packet_is_segmented(segmented_test_packet);
@@ -190,16 +198,21 @@ int packet_suite_init(void)
udat = odp_packet_user_area(test_packet);
udat_size = odp_packet_user_area_size(test_packet);
- if (!udat || udat_size != sizeof(struct udata_struct))
+ if (!udat || udat_size != sizeof(struct udata_struct)) {
+ printf("packet_user_area failed: 1\n");
return -1;
+ }
odp_pool_print(packet_pool);
memcpy(udat, &test_packet_udata, sizeof(struct udata_struct));
udat = odp_packet_user_area(segmented_test_packet);
udat_size = odp_packet_user_area_size(segmented_test_packet);
- if (udat == NULL || udat_size != sizeof(struct udata_struct))
+ if (udat == NULL || udat_size != sizeof(struct udata_struct)) {
+ printf("packet_user_area failed: 2\n");
return -1;
+ }
+
memcpy(udat, &test_packet_udata, sizeof(struct udata_struct));
return 0;
@@ -235,6 +248,7 @@ void packet_test_alloc_free(void)
params.pkt.num = 1;
pool = odp_pool_create("packet_pool_alloc", &params);
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
/* Allocate the only buffer from the pool */
packet = odp_packet_alloc(pool, packet_len);
@@ -1434,7 +1448,7 @@ void packet_test_concat_extend_trunc(void)
param.pkt.num = 100;
pool = odp_pool_create("packet_pool_concat", &param);
- CU_ASSERT(packet_pool != ODP_POOL_INVALID);
+ CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID);
pkt = odp_packet_alloc(pool, alloc_len);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
@@ -1453,6 +1467,7 @@ void packet_test_concat_extend_trunc(void)
CU_ASSERT(odp_packet_len(pkt) == (cur_len + alloc_len));
cur_len = odp_packet_len(pkt);
+ CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
}
ret = odp_packet_extend_tail(&pkt, ext_len, NULL, NULL);
@@ -1460,12 +1475,14 @@ void packet_test_concat_extend_trunc(void)
CU_ASSERT(odp_packet_len(pkt) == (cur_len + ext_len));
cur_len = odp_packet_len(pkt);
+ CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
ret = odp_packet_extend_head(&pkt, ext_len, NULL, NULL);
CU_ASSERT(ret >= 0);
CU_ASSERT(odp_packet_len(pkt) == (cur_len + ext_len));
cur_len = odp_packet_len(pkt);
+ CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
pkt2 = odp_packet_alloc(pool, alloc_len);
CU_ASSERT_FATAL(pkt2 != ODP_PACKET_INVALID);
@@ -1478,18 +1495,21 @@ void packet_test_concat_extend_trunc(void)
CU_ASSERT(odp_packet_len(pkt) == (cur_len + alloc_len));
cur_len = odp_packet_len(pkt);
+ CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
ret = odp_packet_trunc_head(&pkt, trunc_len, NULL, NULL);
CU_ASSERT(ret >= 0);
CU_ASSERT(odp_packet_len(pkt) == (cur_len - trunc_len));
cur_len = odp_packet_len(pkt);
+ CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
ret = odp_packet_trunc_tail(&pkt, trunc_len, NULL, NULL);
CU_ASSERT(ret >= 0);
CU_ASSERT(odp_packet_len(pkt) == (cur_len - trunc_len));
cur_len = odp_packet_len(pkt);
+ CU_ASSERT(cur_len == odp_packet_unshared_len(pkt));
odp_packet_free(pkt);
@@ -1521,7 +1541,7 @@ void packet_test_extend_small(void)
param.pkt.num = 100;
pool = odp_pool_create("packet_pool_extend", &param);
- CU_ASSERT(packet_pool != ODP_POOL_INVALID);
+ CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID);
for (round = 0; round < 2; round++) {
pkt = odp_packet_alloc(pool, 1);
@@ -1557,6 +1577,7 @@ void packet_test_extend_small(void)
}
CU_ASSERT(odp_packet_len(pkt) == len);
+ CU_ASSERT(odp_packet_unshared_len(pkt) == len);
len = odp_packet_len(pkt);
@@ -1615,7 +1636,7 @@ void packet_test_extend_large(void)
param.pkt.num = 100;
pool = odp_pool_create("packet_pool_extend", &param);
- CU_ASSERT(packet_pool != ODP_POOL_INVALID);
+ CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID);
for (round = 0; round < 2 * num_div; round++) {
ext_len = len / div;
@@ -1734,7 +1755,7 @@ void packet_test_extend_mix(void)
param.pkt.num = 100;
pool = odp_pool_create("packet_pool_extend", &param);
- CU_ASSERT(packet_pool != ODP_POOL_INVALID);
+ CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID);
for (round = 0; round < 2; round++) {
small_count = 30;
@@ -1822,6 +1843,114 @@ void packet_test_extend_mix(void)
CU_ASSERT(odp_pool_destroy(pool) == 0);
}
+void packet_test_extend_ref(void)
+{
+ odp_packet_t max_pkt, ref;
+ uint32_t hr, tr, max_len;
+
+ max_pkt = odp_packet_copy(segmented_test_packet,
+ odp_packet_pool(segmented_test_packet));
+ CU_ASSERT_FATAL(max_pkt != ODP_PACKET_INVALID);
+ max_len = odp_packet_len(max_pkt);
+
+ /* Maximize the max pkt */
+ hr = odp_packet_headroom(max_pkt);
+ tr = odp_packet_tailroom(max_pkt);
+ odp_packet_push_head(max_pkt, hr);
+ odp_packet_push_tail(max_pkt, tr);
+
+ /* Max packet should not be extendable at either end */
+ CU_ASSERT(odp_packet_extend_tail(&max_pkt, 1, NULL, NULL) < 0);
+ CU_ASSERT(odp_packet_extend_head(&max_pkt, 1, NULL, NULL) < 0);
+
+ /* See if we can trunc and extend anyway */
+ CU_ASSERT(odp_packet_trunc_tail(&max_pkt, hr + tr + 1,
+ NULL, NULL) >= 0);
+ CU_ASSERT(odp_packet_extend_head(&max_pkt, 1, NULL, NULL) >= 0);
+ CU_ASSERT(odp_packet_len(max_pkt) == max_len);
+ CU_ASSERT(odp_packet_unshared_len(max_pkt) == max_len);
+
+ /* Now try with a reference in place */
+ CU_ASSERT(odp_packet_trunc_tail(&max_pkt, 100, NULL, NULL) >= 0);
+ ref = odp_packet_ref(max_pkt, 100);
+
+ /* Verify ref lengths */
+ CU_ASSERT(ref != ODP_PACKET_INVALID);
+ CU_ASSERT(odp_packet_len(ref) == max_len - 200);
+ if (odp_packet_has_ref(ref) == 1) {
+ CU_ASSERT(odp_packet_unshared_len(ref) == 0);
+
+ /* And ref's affect on max_pkt */
+ CU_ASSERT(odp_packet_has_ref(max_pkt) == 1);
+ CU_ASSERT(odp_packet_unshared_len(max_pkt) == 100);
+ } else {
+ CU_ASSERT(odp_packet_unshared_len(ref) == odp_packet_len(ref));
+ CU_ASSERT(odp_packet_unshared_len(max_pkt) ==
+ odp_packet_len(max_pkt));
+ }
+
+ /* Now extend max_pkt and verify effect */
+ CU_ASSERT(odp_packet_extend_head(&max_pkt, 10, NULL, NULL) >= 0);
+ CU_ASSERT(odp_packet_len(max_pkt) == max_len - 90);
+
+ if (odp_packet_has_ref(max_pkt) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(max_pkt) == 110);
+ }
+
+ /* Extend on max_pkt should not affect ref */
+ CU_ASSERT(odp_packet_len(ref) == max_len - 200);
+
+ if (odp_packet_has_ref(ref) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref) == 0);
+ }
+
+ /* Now extend ref and verify effect*/
+ CU_ASSERT(odp_packet_extend_head(&ref, 20, NULL, NULL) >= 0);
+ CU_ASSERT(odp_packet_len(ref) == max_len - 180);
+
+ if (odp_packet_has_ref(ref) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref) == 20);
+ }
+
+ /* Extend on ref should not affect max_pkt */
+ CU_ASSERT(odp_packet_len(max_pkt) == max_len - 90);
+
+ if (odp_packet_has_ref(max_pkt) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(max_pkt) == 110);
+ }
+
+ /* Trunc max_pkt of all unshared len */
+ CU_ASSERT(odp_packet_trunc_head(&max_pkt, 110, NULL, NULL) >= 0);
+
+ /* Verify effect on max_pkt */
+ CU_ASSERT(odp_packet_len(max_pkt) == max_len - 200);
+
+ if (odp_packet_has_ref(max_pkt) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(max_pkt) == 0);
+ }
+
+ /* Verify that ref is unchanged */
+ CU_ASSERT(odp_packet_len(ref) == max_len - 180);
+
+ if (odp_packet_has_ref(ref) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref) == 20);
+ }
+
+ /* Free ref and verify that max_pkt is back to being unreferenced */
+ odp_packet_free(ref);
+ CU_ASSERT(odp_packet_has_ref(max_pkt) == 0);
+ CU_ASSERT(odp_packet_len(max_pkt) == max_len - 200);
+ CU_ASSERT(odp_packet_unshared_len(max_pkt) == max_len - 200);
+
+ odp_packet_free(max_pkt);
+}
+
void packet_test_align(void)
{
odp_packet_t pkt;
@@ -1926,6 +2055,329 @@ void packet_test_offset(void)
CU_ASSERT_PTR_NOT_NULL(ptr);
}
+void packet_test_ref(void)
+{
+ odp_packet_t base_pkt, segmented_base_pkt, hdr_pkt[4],
+ ref_pkt[4], refhdr_pkt[4], hdr_cpy;
+ uint32_t pkt_len, segmented_pkt_len, hdr_len[4], offset[4], hr[4],
+ base_hr, ref_len[4];
+ int i;
+
+ base_pkt = odp_packet_copy(test_packet, odp_packet_pool(test_packet));
+ base_hr = odp_packet_headroom(base_pkt);
+ pkt_len = odp_packet_len(test_packet);
+ CU_ASSERT_FATAL(base_pkt != ODP_PACKET_INVALID);
+
+ segmented_base_pkt =
+ odp_packet_copy(segmented_test_packet,
+ odp_packet_pool(segmented_test_packet));
+ segmented_pkt_len = odp_packet_len(segmented_test_packet);
+ CU_ASSERT_FATAL(segmented_base_pkt != ODP_PACKET_INVALID);
+
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ hdr_pkt[0] =
+ odp_packet_copy_part(segmented_test_packet, 0,
+ odp_packet_len(segmented_test_packet) / 4,
+ odp_packet_pool(segmented_test_packet));
+ CU_ASSERT_FATAL(hdr_pkt[0] != ODP_PACKET_INVALID);
+ hdr_len[0] = odp_packet_len(hdr_pkt[0]);
+ offset[0] = 0;
+
+ hdr_pkt[1] =
+ odp_packet_copy_part(segmented_test_packet, 10,
+ odp_packet_len(segmented_test_packet) / 8,
+ odp_packet_pool(segmented_test_packet));
+ CU_ASSERT_FATAL(hdr_pkt[1] != ODP_PACKET_INVALID);
+ hdr_len[1] = odp_packet_len(hdr_pkt[1]);
+ offset[1] = 5;
+
+ hdr_pkt[2] = odp_packet_copy_part(test_packet, 0,
+ odp_packet_len(test_packet) / 4,
+ odp_packet_pool(test_packet));
+ CU_ASSERT_FATAL(hdr_pkt[2] != ODP_PACKET_INVALID);
+ hdr_len[2] = odp_packet_len(hdr_pkt[2]);
+ offset[2] = 64;
+
+ hdr_pkt[3] = odp_packet_copy_part(test_packet, 0,
+ odp_packet_len(test_packet) / 4,
+ odp_packet_pool(test_packet));
+ CU_ASSERT_FATAL(hdr_pkt[3] != ODP_PACKET_INVALID);
+ hdr_len[3] = odp_packet_len(hdr_pkt[3]);
+ offset[3] = 64;
+
+ /* Nothing is a ref or has a ref before we start */
+ for (i = 0; i < 4; i++) {
+ CU_ASSERT(odp_packet_has_ref(hdr_pkt[i]) == 0);
+ CU_ASSERT(odp_packet_len(hdr_pkt[i]) ==
+ odp_packet_unshared_len(hdr_pkt[i]));
+ }
+
+ /* Create a couple of refs */
+ refhdr_pkt[0] = odp_packet_ref_pkt(base_pkt, offset[0], hdr_pkt[0]);
+ refhdr_pkt[1] = odp_packet_ref_pkt(base_pkt, offset[1], hdr_pkt[1]);
+
+ CU_ASSERT(refhdr_pkt[0] != ODP_PACKET_INVALID);
+ CU_ASSERT(refhdr_pkt[1] != ODP_PACKET_INVALID);
+
+ /* If base packet has now references, ref packet should be also
+ * references. */
+ if (odp_packet_has_ref(base_pkt) == 1) {
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1);
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[1]) == 1);
+
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) == 0);
+ } else {
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) == pkt_len);
+ }
+
+ CU_ASSERT(odp_packet_len(refhdr_pkt[0]) ==
+ hdr_len[0] + pkt_len - offset[0]);
+ CU_ASSERT(odp_packet_len(refhdr_pkt[1]) ==
+ hdr_len[1] + pkt_len - offset[1]);
+
+ if (odp_packet_has_ref(refhdr_pkt[0]) == 1) {
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == hdr_len[0]);
+ } else {
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) ==
+ odp_packet_len(refhdr_pkt[0]));
+ }
+
+ if (odp_packet_has_ref(refhdr_pkt[1]) == 1) {
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[1]) == hdr_len[1]);
+ } else {
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[1]) ==
+ odp_packet_len(refhdr_pkt[1]));
+ }
+
+ packet_compare_offset(refhdr_pkt[0], hdr_len[0],
+ base_pkt, offset[0],
+ pkt_len - offset[0]);
+
+ packet_compare_offset(refhdr_pkt[1], hdr_len[1],
+ base_pkt, offset[1],
+ pkt_len - offset[1]);
+
+ /* See if compound references are supported and if so that they
+ * operate properly */
+ hdr_cpy = odp_packet_copy(hdr_pkt[2], odp_packet_pool(hdr_pkt[2]));
+ CU_ASSERT_FATAL(hdr_cpy != ODP_PACKET_INVALID);
+
+ refhdr_pkt[2] = odp_packet_ref_pkt(refhdr_pkt[0], 2, hdr_cpy);
+ CU_ASSERT(refhdr_pkt[2] != ODP_PACKET_INVALID);
+
+ if (odp_packet_has_ref(refhdr_pkt[2]) == 1) {
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1);
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[2]) == hdr_len[2]);
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == 2);
+ }
+
+ /* Delete the refs */
+ odp_packet_free(refhdr_pkt[0]);
+ odp_packet_free(refhdr_pkt[1]);
+ odp_packet_free(refhdr_pkt[2]);
+
+ /* Verify that base_pkt no longer has a ref */
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ /* Now create a two more shared refs */
+ refhdr_pkt[2] = odp_packet_ref_pkt(base_pkt, offset[2], hdr_pkt[2]);
+ refhdr_pkt[3] = odp_packet_ref_pkt(base_pkt, offset[3], hdr_pkt[3]);
+
+ CU_ASSERT(hdr_pkt[2] != ODP_PACKET_INVALID);
+ CU_ASSERT(hdr_pkt[3] != ODP_PACKET_INVALID);
+
+ if (odp_packet_has_ref(base_pkt) == 1) {
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[2]) == 1);
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[3]) == 1);
+ }
+
+ CU_ASSERT(odp_packet_len(refhdr_pkt[2]) ==
+ odp_packet_len(refhdr_pkt[3]));
+
+ packet_compare_offset(refhdr_pkt[2], 0,
+ refhdr_pkt[3], 0,
+ odp_packet_len(hdr_pkt[2]));
+
+ /* Delete the headers */
+ odp_packet_free(refhdr_pkt[2]);
+ odp_packet_free(refhdr_pkt[3]);
+
+ /* Verify that base_pkt is no longer ref'd */
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ /* Create a static reference */
+ ref_pkt[0] = odp_packet_ref_static(base_pkt);
+ CU_ASSERT(ref_pkt[0] != ODP_PACKET_INVALID);
+
+ if (odp_packet_has_ref(base_pkt) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_has_ref(ref_pkt[0]) == 1);
+ }
+
+ CU_ASSERT(odp_packet_len(ref_pkt[0]) == odp_packet_len(base_pkt));
+ packet_compare_offset(ref_pkt[0], 0, base_pkt, 0,
+ odp_packet_len(base_pkt));
+
+ /* Now delete it */
+ odp_packet_free(ref_pkt[0]);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ /* Create references */
+ ref_pkt[0] = odp_packet_ref(segmented_base_pkt, offset[0]);
+ if (odp_packet_has_ref(ref_pkt[0]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1);
+ }
+
+ ref_pkt[1] = odp_packet_ref(segmented_base_pkt, offset[1]);
+
+ if (odp_packet_has_ref(ref_pkt[1]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1);
+ }
+
+ /* Verify reference lengths */
+ CU_ASSERT(odp_packet_len(ref_pkt[0]) == segmented_pkt_len - offset[0]);
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) == segmented_pkt_len - offset[1]);
+
+ if (odp_packet_has_ref(ref_pkt[0]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0);
+ }
+
+ if (odp_packet_has_ref(ref_pkt[1]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+ }
+
+ /* Free the base pkts -- references should still be valid */
+ odp_packet_free(base_pkt);
+ odp_packet_free(segmented_base_pkt);
+
+ packet_compare_offset(ref_pkt[0], 0,
+ segmented_test_packet, offset[0],
+ segmented_pkt_len - offset[0]);
+ packet_compare_offset(ref_pkt[1], 0,
+ segmented_test_packet, offset[1],
+ segmented_pkt_len - offset[1]);
+
+ /* Verify we can modify the refs */
+ hr[0] = odp_packet_headroom(ref_pkt[0]);
+ hr[1] = odp_packet_headroom(ref_pkt[1]);
+
+ CU_ASSERT(odp_packet_push_head(ref_pkt[0], hr[0]) != NULL);
+
+ if (odp_packet_has_ref(ref_pkt[0]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]);
+ }
+
+ CU_ASSERT(odp_packet_len(ref_pkt[0]) ==
+ hr[0] + segmented_pkt_len - offset[0]);
+
+ CU_ASSERT(odp_packet_pull_head(ref_pkt[0], hr[0] / 2) != NULL);
+
+ if (odp_packet_has_ref(ref_pkt[0]) == 1) {
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) ==
+ hr[0] - (hr[0] / 2));
+ }
+
+ if (hr[1] > 0) {
+ CU_ASSERT(odp_packet_push_head(ref_pkt[1], 1) != NULL);
+ if (odp_packet_has_ref(ref_pkt[1]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 1);
+ }
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) ==
+ 1 + segmented_pkt_len - offset[1]);
+ CU_ASSERT(odp_packet_pull_head(ref_pkt[1], 1) != NULL);
+ if (odp_packet_has_ref(ref_pkt[1]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+ }
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) ==
+ segmented_pkt_len - offset[1]);
+ }
+
+ odp_packet_free(ref_pkt[0]);
+ odp_packet_free(ref_pkt[1]);
+
+ /* Verify we can modify base packet after reference is created */
+ base_pkt = odp_packet_copy(test_packet, odp_packet_pool(test_packet));
+
+ ref_pkt[1] = odp_packet_ref(base_pkt, offset[1]);
+ CU_ASSERT_FATAL(ref_pkt[1] != ODP_PACKET_INVALID);
+ ref_len[1] = odp_packet_len(ref_pkt[1]);
+ CU_ASSERT(ref_len[1] == odp_packet_len(base_pkt) - offset[1]);
+
+ if (odp_packet_has_ref(ref_pkt[1]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+ }
+
+ CU_ASSERT(odp_packet_push_head(base_pkt, base_hr / 2) != NULL);
+
+ if (odp_packet_has_ref(base_pkt) == 1) {
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) ==
+ base_hr / 2 + offset[1]);
+ }
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) == ref_len[1]);
+ if (odp_packet_has_ref(ref_pkt[1]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+ }
+
+ ref_pkt[0] = odp_packet_ref(base_pkt, offset[0]);
+ CU_ASSERT_FATAL(ref_pkt[0] != ODP_PACKET_INVALID);
+ ref_len[0] = odp_packet_len(ref_pkt[0]);
+ CU_ASSERT(ref_len[0] = odp_packet_len(base_pkt) - offset[0]);
+ if (odp_packet_has_ref(ref_pkt[0]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0);
+ }
+
+ CU_ASSERT(odp_packet_push_head(base_pkt,
+ base_hr - base_hr / 2) != NULL);
+ if (odp_packet_has_ref(base_pkt) == 1) {
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) ==
+ base_hr - base_hr / 2 + offset[0]);
+ }
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) == ref_len[1]);
+ CU_ASSERT(odp_packet_len(ref_pkt[0]) == ref_len[0]);
+
+ if (odp_packet_has_ref(ref_pkt[1]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+ }
+ if (odp_packet_has_ref(ref_pkt[0]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0);
+ }
+
+ hr[0] = odp_packet_headroom(ref_pkt[0]);
+ hr[1] = odp_packet_headroom(ref_pkt[1]);
+ CU_ASSERT(odp_packet_push_head(ref_pkt[0], hr[0]) != NULL);
+ CU_ASSERT(odp_packet_push_head(ref_pkt[1], hr[1]) != NULL);
+ if (odp_packet_has_ref(ref_pkt[0]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]);
+ }
+ if (odp_packet_has_ref(ref_pkt[1]) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == hr[1]);
+ }
+ if (odp_packet_has_ref(base_pkt) == 1) {
+ /* CU_ASSERT needs braces */
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) ==
+ base_hr - base_hr / 2 + offset[0]);
+ }
+
+ odp_packet_free(base_pkt);
+ odp_packet_free(ref_pkt[0]);
+ odp_packet_free(ref_pkt[1]);
+}
+
odp_testinfo_t packet_suite[] = {
ODP_TEST_INFO(packet_test_alloc_free),
ODP_TEST_INFO(packet_test_alloc_free_multi),
@@ -1952,8 +2404,10 @@ odp_testinfo_t packet_suite[] = {
ODP_TEST_INFO(packet_test_extend_small),
ODP_TEST_INFO(packet_test_extend_large),
ODP_TEST_INFO(packet_test_extend_mix),
+ ODP_TEST_INFO(packet_test_extend_ref),
ODP_TEST_INFO(packet_test_align),
ODP_TEST_INFO(packet_test_offset),
+ ODP_TEST_INFO(packet_test_ref),
ODP_TEST_INFO_NULL,
};
diff --git a/test/common_plat/validation/api/packet/packet.h b/test/common_plat/validation/api/packet/packet.h
index 9bc3d6362..783b7a117 100644
--- a/test/common_plat/validation/api/packet/packet.h
+++ b/test/common_plat/validation/api/packet/packet.h
@@ -35,8 +35,10 @@ void packet_test_concat_extend_trunc(void);
void packet_test_extend_small(void);
void packet_test_extend_large(void);
void packet_test_extend_mix(void);
+void packet_test_extend_ref(void);
void packet_test_align(void);
void packet_test_offset(void);
+void packet_test_ref(void);
/* test arrays: */
extern odp_testinfo_t packet_suite[];
diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c
index c23e2cc76..4f3c0c0f7 100644
--- a/test/common_plat/validation/api/pktio/pktio.c
+++ b/test/common_plat/validation/api/pktio/pktio.c
@@ -6,9 +6,7 @@
#include <odp_api.h>
#include <odp_cunit_common.h>
-#include <odp/helper/eth.h>
-#include <odp/helper/ip.h>
-#include <odp/helper/udp.h>
+#include <odp/helper/odph_api.h>
#include <stdlib.h>
#include "pktio.h"
diff --git a/test/common_plat/validation/api/timer/timer.c b/test/common_plat/validation/api/timer/timer.c
index 1945afaa3..b7d84c649 100644
--- a/test/common_plat/validation/api/timer/timer.c
+++ b/test/common_plat/validation/api/timer/timer.c
@@ -15,7 +15,7 @@
#include <time.h>
#include <odp.h>
-#include <odp/helper/linux.h>
+#include <odp/helper/odph_api.h>
#include "odp_cunit_common.h"
#include "test_debug.h"
#include "timer.h"
diff --git a/test/common_plat/validation/api/traffic_mngr/traffic_mngr.c b/test/common_plat/validation/api/traffic_mngr/traffic_mngr.c
index 027175807..88a7d8c7e 100644
--- a/test/common_plat/validation/api/traffic_mngr/traffic_mngr.c
+++ b/test/common_plat/validation/api/traffic_mngr/traffic_mngr.c
@@ -12,11 +12,7 @@
#include <unistd.h>
#include <math.h>
#include <odp.h>
-#include <odp/helper/eth.h>
-#include <odp/helper/ip.h>
-#include <odp/helper/udp.h>
-#include <odp/helper/tcp.h>
-#include <odp/helper/chksum.h>
+#include <odp/helper/odph_api.h>
#include <test_debug.h>
#include "odp_cunit_common.h"
#include "traffic_mngr.h"