On Wed, Dec 17, 2014 at 6:17 PM, Stuart Haslam <[email protected]>
wrote:
>
> This is primarily sunny day basic functional testing, all tests are
> single threaded.
>
> On platforms other than linux-generic testing will be performed using
> the "loop" interface by default.
>
> For linux-generic, since we don't have a working "loop" device, a
> wrapper script is run that attempts to create a pair of virtual
> Ethernet interfaces for testing. If creating the interfaces fails
> the test is skipped and "make check" reports it as such.
>
> Signed-off-by: Stuart Haslam <[email protected]>
> ---
>
> Changes in v3;
>
> - mostly changes addressing review comments from Anders.
>
> - removed test for odp_pktio_inq_remdef()
>
> - added check for empty ODP_PLATFORM in odp_pktio_run
>
> test/validation/.gitignore | 1 +
> test/validation/Makefile.am | 7 +-
> test/validation/odp_pktio.c | 501
> ++++++++++++++++++++++++++++++++++++++++++
> test/validation/odp_pktio_run | 132 +++++++++++
> 4 files changed, 639 insertions(+), 2 deletions(-)
> create mode 100644 test/validation/odp_pktio.c
> create mode 100755 test/validation/odp_pktio_run
>
> diff --git a/test/validation/.gitignore b/test/validation/.gitignore
> index 32834ae..c727223 100644
> --- a/test/validation/.gitignore
> +++ b/test/validation/.gitignore
> @@ -5,3 +5,4 @@ odp_queue
> odp_crypto
> odp_schedule
> odp_shm
> +odp_pktio
> diff --git a/test/validation/Makefile.am b/test/validation/Makefile.am
> index d0b5426..cbeef5d 100644
> --- a/test/validation/Makefile.am
> +++ b/test/validation/Makefile.am
> @@ -3,10 +3,12 @@ include $(top_srcdir)/test/Makefile.inc
> AM_CFLAGS += -I$(srcdir)/common
> AM_LDFLAGS += -static
>
> +AM_TESTS_ENVIRONMENT = ODP_PLATFORM=${with_platform}
> +
> if ODP_CUNIT_ENABLED
> -TESTS = ${bin_PROGRAMS}
> +TESTS = odp_init odp_queue odp_crypto odp_shm odp_schedule odp_pktio_run
> check_PROGRAMS = ${bin_PROGRAMS}
> -bin_PROGRAMS = odp_init odp_queue odp_crypto odp_shm odp_schedule
> +bin_PROGRAMS = odp_init odp_queue odp_crypto odp_shm odp_schedule
> odp_pktio
> odp_init_LDFLAGS = $(AM_LDFLAGS)
> odp_queue_LDFLAGS = $(AM_LDFLAGS)
> odp_crypto_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/crypto
> @@ -18,6 +20,7 @@ odp_schedule_LDFLAGS = $(AM_LDFLAGS)
> endif
>
> dist_odp_init_SOURCES = odp_init.c
> +dist_odp_pktio_SOURCES = odp_pktio.c common/odp_cunit_common.c
> dist_odp_queue_SOURCES = odp_queue.c common/odp_cunit_common.c
> dist_odp_crypto_SOURCES = crypto/odp_crypto_test_async_inp.c \
> crypto/odp_crypto_test_sync_inp.c \
> diff --git a/test/validation/odp_pktio.c b/test/validation/odp_pktio.c
> new file mode 100644
> index 0000000..75a9859
> --- /dev/null
> +++ b/test/validation/odp_pktio.c
> @@ -0,0 +1,501 @@
> +/* Copyright (c) 2014, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier: BSD-3-Clause
> + */
> +#include <odp.h>
> +#include <odp_cunit_common.h>
> +#include <odp_packet.h>
> +
> +#include <odph_eth.h>
> +#include <odph_ip.h>
> +#include <odph_udp.h>
> +
> +#include <stdlib.h>
> +
> +#define SHM_PKT_POOL_SIZE (32*2048)
> +#define SHM_PKT_POOL_BUF_SIZE 1856
> +#define MAX_NUM_IFACES 2
> +#define TEST_SEQ_INVALID ((uint32_t)~0)
> +#define TEST_SEQ_MAGIC 0x92749451
> +
> +/** interface names used for testing */
> +static const char *iface_name[MAX_NUM_IFACES];
> +
> +/** number of interfaces being used (1=loopback, 2=pair) */
> +static int num_ifaces;
> +
> +/** local container for pktio attributes */
> +typedef struct {
> + const char *name;
> + odp_pktio_t id;
> + odp_queue_t outq;
> + odp_queue_t inq;
> +} pktio_info_t;
> +
> +/** structure of test packet UDP payload */
> +typedef struct {
> + uint32be_t magic;
> + uint32be_t seq;
> +} pkt_test_data_t;
> +
> +/** default packet pool */
> +odp_buffer_pool_t default_pkt_pool = ODP_BUFFER_POOL_INVALID;
> +
> +/** sequence number of IP packets */
> +odp_atomic_u32_t ip_seq;
> +
> +static void pktio_pkt_set_macs(odp_packet_t pkt,
> + pktio_info_t *src, pktio_info_t *dst)
> +{
> + uint32_t len;
> + odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len);
> + int ret;
> +
> + ret = odp_pktio_mac_addr(src->id, ð->src, sizeof(eth->src));
> + CU_ASSERT(ret == ODPH_ETHADDR_LEN);
> +
> + ret = odp_pktio_mac_addr(dst->id, ð->dst, sizeof(eth->dst));
> + CU_ASSERT(ret == ODPH_ETHADDR_LEN);
> +}
> +
> +static int pktio_pkt_set_seq(odp_packet_t pkt)
> +{
> + static uint32_t tstseq;
> + size_t l4_off;
> + pkt_test_data_t data;
> +
> + data.magic = TEST_SEQ_MAGIC;
> + data.seq = tstseq;
> +
> + l4_off = odp_packet_l4_offset(pkt);
> + if (!l4_off) {
> + CU_FAIL("packet L4 offset not set");
> + return -1;
> + }
> +
> + odp_packet_copydata_in(pkt, l4_off+ODPH_UDPHDR_LEN,
> + sizeof(data), &data);
> +
> + tstseq++;
> +
> + return 0;
> +}
> +
> +static uint32_t pktio_pkt_seq(odp_packet_t pkt)
> +{
> + size_t l4_off;
> + pkt_test_data_t data;
> +
> + l4_off = odp_packet_l4_offset(pkt);
> + if (l4_off) {
> + odp_packet_copydata_out(pkt, l4_off+ODPH_UDPHDR_LEN,
> + sizeof(data), &data);
> +
> + if (data.magic == TEST_SEQ_MAGIC)
> + return data.seq;
> + }
> +
> + return TEST_SEQ_INVALID;
> +}
> +
> +static odp_packet_t pktio_create_packet(void)
> +{
> + odp_packet_t pkt;
> + odph_ethhdr_t *eth;
> + odph_ipv4hdr_t *ip;
> + odph_udphdr_t *udp;
> + char *buf;
> + uint16_t seq;
> + size_t payload_len = sizeof(pkt_test_data_t);
> + uint8_t mac[ODPH_ETHADDR_LEN] = {0};
> +
> + pkt = odp_packet_alloc(default_pkt_pool, payload_len +
> ODPH_UDPHDR_LEN +
> + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
> + if (pkt == ODP_PACKET_INVALID) {
> + CU_FAIL("failed to allocate packet buffer");
> + return ODP_PACKET_INVALID;
> + }
> + buf = odp_packet_data(pkt);
> +
> + /* Ethernet */
> + odp_packet_l2_offset_set(pkt, 0);
> + eth = (odph_ethhdr_t *)buf;
> + memcpy(eth->src.addr, mac, ODPH_ETHADDR_LEN);
> + memcpy(eth->dst.addr, mac, ODPH_ETHADDR_LEN);
> + eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
> +
> + /* IP */
> + odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
> + ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
> + ip->dst_addr = odp_cpu_to_be_32(0);
> + ip->src_addr = odp_cpu_to_be_32(0);
> + ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
> + ip->tot_len = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN +
> + ODPH_IPV4HDR_LEN);
> + ip->ttl = 128;
> + ip->proto = ODPH_IPPROTO_UDP;
> + seq = odp_atomic_fetch_inc_u32(&ip_seq);
> + ip->id = odp_cpu_to_be_16(seq);
> + ip->chksum = 0;
> + odph_ipv4_csum_update(pkt);
> +
> + /* UDP */
> + odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
> + udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
> + udp->src_port = odp_cpu_to_be_16(0);
> + udp->dst_port = odp_cpu_to_be_16(0);
> + udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
> + udp->chksum = 0;
> +
> + if (pktio_pkt_set_seq(pkt) != 0) {
> + odp_packet_free(pkt);
> + return ODP_PACKET_INVALID;
> + }
> +
> + return pkt;
> +}
> +
> +static int pktio_fixup_checksums(odp_packet_t pkt)
> +{
> + odph_ipv4hdr_t *ip;
> + odph_udphdr_t *udp;
> + uint32_t len;
> +
> + ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, &len);
> +
> + if (ip->proto != ODPH_IPPROTO_UDP) {
> + CU_FAIL("unexpected L4 protocol");
> + return -1;
> + }
> +
> + udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, &len);
> +
> + ip->chksum = 0;
> + odph_ipv4_csum_update(pkt);
> + udp->chksum = 0;
> + udp->chksum = odph_ipv4_udp_chksum(pkt);
> +
> + return 0;
> +}
> +
> +static int default_pool_create(void)
> +{
> + odp_buffer_pool_param_t params;
> +
> + if (default_pkt_pool != ODP_BUFFER_POOL_INVALID)
> + return -1;
> +
> + params.buf_size = SHM_PKT_POOL_BUF_SIZE;
> + params.buf_align = 0;
> + params.num_bufs = SHM_PKT_POOL_SIZE/SHM_PKT_POOL_BUF_SIZE;
>
This convention for specifying a buffer count is vestigial from the prior
odp_buffer_pool_create() API which
didn't support a num_bufs specification. Since you're letting ODP
calculate the pool size rather than passing a SHM object yourself (which is
the preferred form of this API), it's better to just state directly how
many buffers you want the pool to contain rather than doing math to derive
it. Similar comments apply to all other instances of pool creation here
since they're just copying this model.
Also, note that SHM_PKT_POOL_SIZE is not an integral multiple of
SHM_PKT_POOL_BUF_SIZE here, so you're requesting 35.3 buffers, which
certainly looks odd (it will be truncated to 35 by integer math).
> + params.buf_type = ODP_BUFFER_TYPE_PACKET;
> +
> + default_pkt_pool = odp_buffer_pool_create("pkt_pool_default",
> + ODP_SHM_NULL, ¶ms);
> + if (default_pkt_pool == ODP_BUFFER_POOL_INVALID)
> + return -1;
> +
> + return 0;
> +}
> +
> +static odp_pktio_t create_pktio(const char *iface)
> +{
> + odp_buffer_pool_t pool;
> + odp_pktio_t pktio;
> + char pool_name[ODP_BUFFER_POOL_NAME_LEN];
> + odp_buffer_pool_param_t params;
> +
> + params.buf_size = SHM_PKT_POOL_BUF_SIZE;
> + params.buf_align = 0;
> + params.num_bufs = SHM_PKT_POOL_SIZE/SHM_PKT_POOL_BUF_SIZE;
> + params.buf_type = ODP_BUFFER_TYPE_PACKET;
> +
> + snprintf(pool_name, sizeof(pool_name), "pkt_pool_%s", iface);
> + pool = odp_buffer_pool_lookup(pool_name);
> + if (pool == ODP_BUFFER_POOL_INVALID)
> + pool = odp_buffer_pool_create(pool_name, ODP_SHM_NULL,
> ¶ms);
> + CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> +
> + pktio = odp_pktio_open(iface, pool);
> + CU_ASSERT(pktio != ODP_PKTIO_INVALID);
> +
> + return pktio;
> +}
> +
> +static int create_inq(odp_pktio_t pktio)
> +{
> + odp_queue_param_t qparam;
> + odp_queue_t inq_def;
> + char inq_name[ODP_QUEUE_NAME_LEN];
> +
> + qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT;
> + qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC;
> + qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
> +
> + snprintf(inq_name, sizeof(inq_name), "inq-pktio-%d", pktio);
> + inq_def = odp_queue_lookup(inq_name);
> + if (inq_def == ODP_QUEUE_INVALID)
> + inq_def = odp_queue_create(inq_name,
> + ODP_QUEUE_TYPE_PKTIN, &qparam);
> + CU_ASSERT(inq_def != ODP_QUEUE_INVALID);
> +
> + return odp_pktio_inq_setdef(pktio, inq_def);
> +}
> +
> +static odp_buffer_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns)
> +{
> + uint64_t start, now, diff;
> + odp_buffer_t buf;
> +
> + start = odp_time_cycles();
> +
> + do {
> + buf = odp_queue_deq(queue);
> + if (buf != ODP_BUFFER_INVALID)
> + return buf;
> + now = odp_time_cycles();
> + diff = odp_time_diff_cycles(start, now);
> + } while (odp_time_cycles_to_ns(diff) < ns);
> +
> + return ODP_BUFFER_INVALID;
> +}
> +
> +static odp_packet_t wait_for_packet(odp_queue_t queue,
> + uint32_t seq, uint64_t ns)
> +{
> + uint64_t start, now, diff;
> + odp_buffer_t buf;
> + odp_packet_t pkt = ODP_PACKET_INVALID;
> +
> + start = odp_time_cycles();
> +
> + do {
> + if (queue != ODP_QUEUE_INVALID)
> + buf = queue_deq_wait_time(queue, ns);
> + else
> + buf = odp_schedule(NULL, ns);
> +
> + if (buf != ODP_BUFFER_INVALID &&
> + odp_buffer_type(buf) == ODP_BUFFER_TYPE_PACKET) {
> + pkt = odp_packet_from_buffer(buf);
> + if (pktio_pkt_seq(pkt) == seq)
> + return pkt;
> + }
> +
> + now = odp_time_cycles();
> + diff = odp_time_diff_cycles(start, now);
> + } while (odp_time_cycles_to_ns(diff) < ns);
> +
> + CU_FAIL("failed to receive transmitted packet");
> +
> + return ODP_PACKET_INVALID;
> +}
> +
> +static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
> + int num_pkts)
> +{
> + odp_packet_t tx_pkt[num_pkts];
> + odp_buffer_t tx_buf[num_pkts];
> + odp_packet_t rx_pkt;
> + uint32_t tx_seq[num_pkts];
> + int i, ret;
> +
> + /* generate test packets to send */
> + for (i = 0; i < num_pkts; ++i) {
> + tx_pkt[i] = pktio_create_packet();
> + if (tx_pkt[i] == ODP_PACKET_INVALID)
> + break;
> +
> + tx_seq[i] = pktio_pkt_seq(tx_pkt[i]);
> + if (tx_seq[i] == TEST_SEQ_INVALID)
> + break;
> +
> + pktio_pkt_set_macs(tx_pkt[i], pktio_a, pktio_b);
> + if (pktio_fixup_checksums(tx_pkt[i]) != 0)
> + break;
> +
> + tx_buf[i] = odp_packet_to_buffer(tx_pkt[i]);
> + }
> +
> + if (i != num_pkts) {
> + CU_FAIL("failed to generate test packets");
> + return;
> + }
> +
> + /* send packet(s) out */
> + if (num_pkts == 1)
> + ret = odp_queue_enq(pktio_a->outq, tx_buf[0]);
> + else
> + ret = odp_queue_enq_multi(pktio_a->outq, tx_buf, num_pkts);
> +
> + if (ret != 0) {
> + CU_FAIL("failed to enqueue test packets");
> + return;
> + }
> +
> + /* and wait for them to arrive back */
> + for (i = 0; i < num_pkts; ++i) {
> + rx_pkt = wait_for_packet(pktio_b->inq, tx_seq[i],
> ODP_TIME_SEC);
> +
> + if (rx_pkt == ODP_PACKET_INVALID)
> + break;
> + CU_ASSERT(odp_packet_input(rx_pkt) == pktio_b->id);
> + CU_ASSERT(odp_packet_error(rx_pkt) == 0);
> + odp_packet_free(rx_pkt);
> + }
> +
> + CU_ASSERT(i == num_pkts);
> +}
> +
> +static void pktio_test_txrx(odp_queue_type_t q_type, int num_pkts)
> +{
> + int ret, i, if_b;
> + pktio_info_t pktios[MAX_NUM_IFACES];
> + pktio_info_t *io;
> +
> + /* create pktios and associate input/output queues */
> + for (i = 0; i < num_ifaces; ++i) {
> + io = &pktios[i];
> +
> + io->name = iface_name[i];
> + io->id = create_pktio(iface_name[i]);
> + if (io->id == ODP_PKTIO_INVALID) {
> + CU_FAIL("failed to open iface");
> + return;
> + }
> + create_inq(io->id);
> + io->outq = odp_pktio_outq_getdef(io->id);
> + if (q_type == ODP_QUEUE_TYPE_POLL)
> + io->inq = odp_pktio_inq_getdef(io->id);
> + else
> + io->inq = ODP_QUEUE_INVALID;
> + }
> +
> + /* if we have two interfaces then send through one and receive on
> + * another but if there's only one assume it's a loopback */
> + if_b = (num_ifaces == 1) ? 0 : 1;
> + pktio_txrx_multi(&pktios[0], &pktios[if_b], num_pkts);
> +
> + for (i = 0; i < num_ifaces; ++i) {
> + ret = odp_pktio_close(pktios[i].id);
> + CU_ASSERT(ret == 0);
> + }
> +}
> +
> +static void test_odp_pktio_poll_queue(void)
> +{
> + pktio_test_txrx(ODP_QUEUE_TYPE_POLL, 1);
> +}
> +
> +static void test_odp_pktio_poll_multi(void)
> +{
> + pktio_test_txrx(ODP_QUEUE_TYPE_POLL, 4);
> +}
> +
> +static void test_odp_pktio_sched_queue(void)
> +{
> + pktio_test_txrx(ODP_QUEUE_TYPE_SCHED, 1);
> +}
> +
> +static void test_odp_pktio_sched_multi(void)
> +{
> + pktio_test_txrx(ODP_QUEUE_TYPE_SCHED, 4);
> +}
> +
> +static void test_odp_pktio_open(void)
> +{
> + odp_pktio_t pktio;
> + int i;
> +
> + /* test the sequence open->close->open->close() */
> + for (i = 0; i < 2; ++i) {
> + pktio = create_pktio(iface_name[0]);
> + CU_ASSERT(pktio != ODP_PKTIO_INVALID);
> + CU_ASSERT(odp_pktio_close(pktio) == 0);
> + }
> +
> + pktio = odp_pktio_open("nothere", default_pkt_pool);
> + CU_ASSERT(pktio == ODP_PKTIO_INVALID);
> +}
> +
> +static void test_odp_pktio_inq(void)
> +{
> + odp_pktio_t pktio;
> +
> + pktio = create_pktio(iface_name[0]);
> + CU_ASSERT(pktio != ODP_PKTIO_INVALID);
> +
> + CU_ASSERT(create_inq(pktio) == 0);
> +
> + CU_ASSERT(odp_pktio_close(pktio) == 0);
> +}
> +
> +static void test_odp_pktio_outq(void)
> +{
> + odp_queue_t testq;
> +
> + testq = odp_pktio_outq_getdef(ODP_PKTIO_INVALID);
> + CU_ASSERT(testq == ODP_QUEUE_INVALID);
> +}
> +
> +static void test_odp_pktio_close(void)
> +{
> + int res;
> +
> + res = odp_pktio_close(ODP_PKTIO_INVALID);
> + CU_ASSERT_EQUAL(res, -1);
> +}
> +
> +static int init_pktio_suite(void)
> +{
> + iface_name[0] = getenv("ODP_PKTIO_IF0");
> + iface_name[1] = getenv("ODP_PKTIO_IF1");
> + num_ifaces = 1;
> +
> + if (!iface_name[0]) {
> + printf("No interfaces specified, using default
> \"loop\".\n");
> + iface_name[0] = "loop";
> + } else if (!iface_name[1]) {
> + printf("Using loopback interface: %s\n", iface_name[0]);
> + } else {
> + num_ifaces = 2;
> + printf("Using paired interfaces: %s %s\n",
> + iface_name[0], iface_name[1]);
> + }
> +
> + if (default_pool_create() != 0) {
> + fprintf(stderr, "error: failed to create default pool\n");
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int term_pktio_suite(void)
> +{
> + if (odp_buffer_pool_destroy(default_pkt_pool) != 0) {
> + fprintf(stderr, "error: failed to destroy default pool\n");
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +CU_TestInfo pktio_tests[] = {
> + {"pktio open", test_odp_pktio_open},
> + {"pktio close", test_odp_pktio_close},
> + {"pktio inq", test_odp_pktio_inq},
> + {"pktio outq", test_odp_pktio_outq},
> + {"pktio poll queues", test_odp_pktio_poll_queue},
> + {"pktio poll multi", test_odp_pktio_poll_multi},
> + {"pktio sched queues", test_odp_pktio_sched_queue},
> + {"pktio sched multi", test_odp_pktio_sched_multi},
> + CU_TEST_INFO_NULL
> +};
> +
> +CU_SuiteInfo odp_testsuites[] = {
> + {"odp_pktio",
> + init_pktio_suite, term_pktio_suite, NULL, NULL,
> pktio_tests},
> + CU_SUITE_INFO_NULL
> +};
> diff --git a/test/validation/odp_pktio_run b/test/validation/odp_pktio_run
> new file mode 100755
> index 0000000..d4d6b2c
> --- /dev/null
> +++ b/test/validation/odp_pktio_run
> @@ -0,0 +1,132 @@
> +#!/bin/sh
> +#
> +# Test script wrapper for running ODP pktio tests on linux-generic.
> +#
> +# For platforms other than linux-generic this script does nothing other
> +# than running the odp_pktio binary, odp_pktio will then attempt to
> +# open and use the special device named "loop" for testing.
> +#
> +# For linux-generic the default behaviour is to create a pair of
> +# virtual Ethernet interfaces and provide the names of these via
> +# environment variables to odp_pktio, the interfaces will be removed
> +# before the script exits. Note that the creation of virtual Ethernet
> +# devices depends on having CONFIG_VETH enabled in the kernel, if not
> +# enabled the test will be skipped.
> +#
> +# The evironment variable ODP_PLATFORM is used to determine the
> +# platform under test, when this script is invoked via 'make check'
> +# this variable is set automatically.
> +#
> +# It's also possible to split up the steps, which makes it easier when
> +# debugging, for example;
> +#
> +# export ODP_PLATFORM=linux-generic
> +# odp_pktio_run setup
> +# wireshark -i pktio-p0 -k &
> +# odp_pktio_run
> +# (repeat running test multiple times..)
> +# odp_pktio_run cleanup
> +#
> +TEST_DIR=$(dirname $0)
> +IF0=pktio-p0
> +IF1=pktio-p1
> +
> +# exit codes expected by automake for skipped tests
> +TEST_SKIPPED=77
> +
> +setup_env1()
> +{
> + ip link show $IF0 2> /dev/null
> + if [ $? = 0 ]; then
> + ip link show $IF1 2> /dev/null
> + if [ $? = 0 ]; then
> + echo "pktio: interfaces $IF0 and $IF1 already
> exist"
> + return
> + fi
> + fi
> +
> + echo "pktio: setting up test interfaces $IF0 and $IF1"
> +
> + if [ "$1" = "clean" ]; then
> + trap cleanup_env1 EXIT
> + fi
> +
> + ip link add $IF0 type veth peer name $IF1
> + if [ $? != 0 ]; then
> + echo "pktio: error: unable to create veth pair"
> + exit $TEST_SKIPPED
> + fi
> + ip link set $IF0 up
> + ip link set $IF1 up
> +
> + # network needs a little time to come up
> + sleep 1
> +}
> +
> +cleanup_env1()
> +{
> + echo "pktio: removing test interfaces $IF0 and $IF1"
> + ip link del $IF0 2> /dev/null
> + ip link del $IF1 2> /dev/null
> +}
> +
> +run_test()
> +{
> + local ret=0
> +
> + # the linux-generic implementation uses environment variables to
> + # control which socket method is used, so try each combination to
> + # ensure decent coverage.
> + for distype in MMAP MMSG BASIC; do
> + unset ODP_PKTIO_DISABLE_SOCKET_${distype}
> + done
> +
> + for distype in SKIP MMAP MMSG; do
> + if [ "$disabletype" != "SKIP" ]; then
> + export ODP_PKTIO_DISABLE_SOCKET_${distype}=y
> + fi
> + $TEST_DIR/odp_pktio
> + if [ $? != 0 ]; then
> + ret=1
> + fi
> + done
> +
> + if [ $ret != 0 ]; then
> + echo "!!! FAILED !!!"
> + fi
> +
> + exit $ret
> +}
> +
> +run()
> +{
> + if [ "$ODP_PLATFORM" != "linux-generic" ]; then
> + echo "pktio: using 'loop' device"
> + $TEST_DIR/odp_pktio
> + exit $?
> + elif [ "$ODP_PKTIO_IF0" = "" ]; then
> + # no interfaces specified on linux-generic, use defaults
> + setup_env1 clean
> + export ODP_PKTIO_IF0=$IF0
> + export ODP_PKTIO_IF1=$IF1
> + fi
> +
> + run_test
> +}
> +
> +if [ "$ODP_PLATFORM" = "" ]; then
> + echo "pktio: error: ODP_PLATFORM must be defined"
> + # not skipped as this should never happen via "make check"
> + exit 1
> +fi
> +
> +if [ "$(id -u)" != "0" ]; then
> + echo "pktio: error: must be run as root"
> + exit $TEST_SKIPPED
> +fi
> +
> +case "$1" in
> + setup) setup_env1 ;;
> + cleanup) cleanup_env1 ;;
> + *) run ;;
> +esac
> --
> 2.1.1
>
>
>
> _______________________________________________
> lng-odp mailing list
> [email protected]
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp