From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id 4CBDB1C9BC for ; Thu, 5 Apr 2018 10:30:48 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Apr 2018 01:30:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,410,1517904000"; d="scan'208";a="48164917" Received: from unknown (HELO localhost.localdomain) ([10.224.122.203]) by orsmga002.jf.intel.com with ESMTP; 05 Apr 2018 01:30:45 -0700 From: Vipin Varghese To: dev@dpdk.org Cc: pascal.mazon@6wind.com, ferruh.yigit@intel.com, Vipin Varghese Date: Thu, 5 Apr 2018 14:01:15 +0530 Message-Id: <1522917075-5156-1-git-send-email-vipin.varghese@intel.com> X-Mailer: git-send-email 1.9.1 Subject: [dpdk-dev] [PATCH] test/tun: add new test for tun X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Apr 2018 08:30:49 -0000 Add TUN PMD validation for create, port setup, tx, rx and stats functions. Signed-off-by: Vipin Varghese --- test/test/Makefile | 4 + test/test/autotest_data.py | 13 ++ test/test/meson.build | 4 + test/test/test_tun.c | 333 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 354 insertions(+) create mode 100644 test/test/test_tun.c diff --git a/test/test/Makefile b/test/test/Makefile index a88cc38..e5d8200 100644 --- a/test/test/Makefile +++ b/test/test/Makefile @@ -193,6 +193,10 @@ endif SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c +ifeq ($(CONFIG_RTE_LIBRTE_PMD_TAP),y) +SRCS-y += test_tun.c +endif + CFLAGS += -DALLOW_EXPERIMENTAL_API CFLAGS += -O3 diff --git a/test/test/autotest_data.py b/test/test/autotest_data.py index aacfe0a..35f3aab 100644 --- a/test/test/autotest_data.py +++ b/test/test/autotest_data.py @@ -357,6 +357,19 @@ def per_sockets(num): ] }, { + "Prefix": "tun", + "Memory": "512", + "Tests": + [ + { + "Name": "TUN autotest", + "Command": "tun_autotest", + "Func": default_autotest, + "Report": None, + }, + ] + }, + { "Prefix": "mempool_perf", "Memory": per_sockets(256), "Tests": diff --git a/test/test/meson.build b/test/test/meson.build index eb3d87a..fbb4cf7 100644 --- a/test/test/meson.build +++ b/test/test/meson.build @@ -93,6 +93,7 @@ test_sources = files('commands.c', 'test_timer.c', 'test_timer_perf.c', 'test_timer_racecond.c', + 'test_tun.c', 'test_version.c', 'virtual_pmd.c' ) @@ -227,6 +228,9 @@ endif if dpdk_conf.has('RTE_LIBRTE_RING_PMD') test_deps += 'pmd_ring' endif +if dpdk_conf.has('RTE_LIBRTE_TAP_PMD') + test_deps += 'pmd_tap' +endif if dpdk_conf.has('RTE_LIBRTE_POWER') test_deps += 'power' endif diff --git a/test/test/test_tun.c b/test/test/test_tun.c new file mode 100644 index 0000000..c165a94 --- /dev/null +++ b/test/test/test_tun.c @@ -0,0 +1,333 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NB_MBUF 8192 +#define MAX_PACKET_SZ 2048 +#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM) +#define PKT_BURST_SZ 32 +#define MEMPOOL_CACHE_SZ PKT_BURST_SZ +#define SOCKET 0 +#define NB_RXD 1024 +#define NB_TXD 1024 +#define MAX_PKT_BURST 32 +#define IFCONFIG "/sbin/ifconfig " +#define PING "/bin/ping -qr -c 10 -i 0.2 15.0.0.1 -I " + +static int tun_id; +static int socket_id; +static uint16_t nb_ports, port_id; + +static struct rte_eth_dev_info info; +static struct rte_eth_stats stats; +static struct rte_mempool *mp; +static struct rte_mbuf *mbuf; + +static char tun_drv_name[20] = "net_tun"; +static char tun_intf_name[20] = "atest"; +static char tun_intf_cmd[20] = "\0"; +static char portname[25] = "\0"; +static char cmd_exec[70] = "\0"; + +static const struct rte_eth_rxconf rx_conf = { + .rx_thresh = { + .pthresh = 8, + .hthresh = 8, + .wthresh = 4, + }, + .rx_free_thresh = 0, +}; + +static const struct rte_eth_txconf tx_conf = { + .tx_thresh = { + .pthresh = 36, + .hthresh = 0, + .wthresh = 0, + }, + .tx_free_thresh = 0, + .tx_rs_thresh = 0, +}; + +static const struct rte_eth_conf port_conf = { + .rxmode = { + .header_split = 0, + .hw_ip_checksum = 0, + .hw_vlan_filter = 0, + .jumbo_frame = 0, + .hw_strip_crc = 0, + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE | ETH_DCB_NONE, + }, +}; + +static void +send_ping(void *param) +{ + char *tun_intf_name = (char *) param; + + sprintf(cmd_exec, "%s %s &", PING, tun_intf_name); + if (system(cmd_exec) != 0) + printf("fail to execute (%s)!\n", cmd_exec); + + fflush(stdout); +} + +static int +tun_port_setup(uint16_t port_id) +{ + int ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf); + if (ret < 0) { + printf("fail to configure port %d\n", port_id); + return -1; + } + + ret = rte_eth_rx_queue_setup(port_id, 0, NB_RXD, socket_id, + &rx_conf, mp); + if (ret < 0) { + printf("fail to setup rx queue for port %d\n", port_id); + return -1; + } + + ret = rte_eth_tx_queue_setup(port_id, 0, NB_TXD, socket_id, + &tx_conf); + if (ret < 0) { + printf("fail to setup tx queue for port %d\n", port_id); + return -1; + } + + ret = rte_eth_dev_start(port_id); + if (ret < 0) { + printf("fail to start port %d\n", port_id); + return -2; + } + + rte_eth_promiscuous_enable(port_id); + return 0; +} + +static int +setup_interface(char *tun_intf_name) +{ + sprintf(cmd_exec, "%s %s 15.0.0.254/24 up", IFCONFIG, tun_intf_name); + int ret = system(cmd_exec); + if (ret != 0) { + printf("fail to execute (%s)!\n", cmd_exec); + return -1; + } + + printf("Stats after interface config\n"); + sprintf(cmd_exec, "%s %s | grep packets", IFCONFIG, tun_intf_name); + ret = system(cmd_exec); + if (ret != 0) { + printf("fail to execute (%s)!\n", cmd_exec); + return -1; + } + + return 0; +} + +static int +test_tun(void) +{ + int ret = -1, i; + int8_t count = 10, recv_pkts = 10; + uint64_t rx_pkts, tx_pkts, rx_err, tx_err; + socket_id = rte_lcore_to_socket_id(rte_lcore_id()); + + mp = rte_mempool_lookup("tun_mempool"); + if (!mp) + mp = rte_pktmbuf_pool_create("tun_mempool", + NB_MBUF, + MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, + socket_id); + + nb_ports = rte_eth_dev_count(); + printf("Found (%d) ports\n", nb_ports); + + sprintf(tun_drv_name, "%s%d", tun_drv_name, tun_id); + sprintf(tun_intf_name, "%s%d", tun_intf_name, tun_id++); + sprintf(tun_intf_cmd, "iface=%s", tun_intf_name); + + if (rte_vdev_init(tun_drv_name, tun_intf_cmd) != 0) { + printf("failed to add tun device!\n"); + goto fail; + } + + nb_ports = rte_eth_dev_count(); + printf("Found port (%d) with PMD TUN\n", nb_ports); + + for (i = 0; i < nb_ports; i++) { + memset(&info, 0, sizeof(info)); + rte_eth_dev_info_get(i, &info); + + if_indextoname(info.if_index, portname); + + ret = rte_eth_dev_get_name_by_port(i, portname); + if (ret != 0) { + printf("Fail to get port name for (%d)", i); + goto fail; + } + + printf("port (%d) driver (%s) interface name (%s)\n", + i, info.driver_name, portname); + } + port_id = i - 1; + + /* configuring new port for the test is enough */ + ret = tun_port_setup(port_id); + if (ret != 0) + goto fail; + + ret = rte_eth_stats_get(port_id, &stats); + if (ret != 0) + goto port_fail; + + rx_pkts = stats.ipackets; + tx_pkts = stats.opackets; + rx_err = stats.ierrors; + tx_err = stats.oerrors; + + ret = setup_interface(tun_intf_name); + if (ret != 0) + goto port_fail; + + printf("send 1 packet through tun interface\n"); + mbuf = rte_pktmbuf_alloc(mp); + if (mbuf == NULL) { + printf("fail to allocate mbuf!\n"); + goto port_fail; + } + + mbuf->nb_segs = 1; + mbuf->next = NULL; + mbuf->pkt_len = 64; + mbuf->data_len = 64; + + struct ipv4_hdr *v4 = rte_pktmbuf_mtod(mbuf, struct ipv4_hdr *); + v4->src_addr = 0x0a0a0a0a; + v4->dst_addr = 0x0b0b0b0b; + v4->time_to_live = 0x2; + v4->fragment_offset = 0x00; + v4->version_ihl = 0x45; + + /* sent one pkt out */ + ret = rte_eth_tx_burst(port_id, 0, &mbuf, 1); + if (ret != 1) { + printf("fail to send nbuf via tun port!\n"); + goto port_fail; + } + + ret = rte_eth_stats_get(port_id, &stats); + if (ret != 0) + goto port_fail; + + if (((stats.opackets - tx_pkts) != 1) || + (stats.ipackets - rx_pkts) || + (stats.ierrors - rx_err) || + (stats.oerrors - tx_err)) { + printf("Fail to match the expected stats\n"); + goto port_fail; +} + + rx_pkts = stats.ipackets; + tx_pkts = stats.opackets; + rx_err = stats.ierrors; + tx_err = stats.oerrors; + + rte_eal_alarm_set(1, send_ping, (void *) tun_intf_name); + rte_delay_ms(1000); + + printf("Stats after 1 pkt TX"); + sprintf(cmd_exec, "%s %s | grep packets", IFCONFIG, tun_intf_name); + ret = system(cmd_exec); + if (ret != 0) { + printf("fail to execute (%s)!\n", cmd_exec); + goto port_fail; + } + + while ((count > 0) && (recv_pkts > 0)) { + struct rte_mbuf *rx_pkts_burst[MAX_PKT_BURST]; + uint16_t nb_pkts = rte_eth_rx_burst(port_id, 0, rx_pkts_burst, + 10); + + if (!nb_pkts) { + rte_delay_ms(500); + count = count - 1; + } + + recv_pkts -= nb_pkts; + + for (i = 0; i < nb_pkts; i++) { + struct ipv4_hdr *v4 = rte_pktmbuf_mtod(rx_pkts_burst[i], + struct ipv4_hdr *); + v4->src_addr = v4->src_addr ^ v4->dst_addr; + v4->dst_addr = v4->src_addr ^ v4->dst_addr; + v4->src_addr = v4->src_addr ^ v4->dst_addr; + + struct icmp_hdr *icmp = (struct icmp_hdr *)(v4 + 1); + icmp->icmp_type = 0x00; + + /* sent one pkt out */ + ret = rte_eth_tx_burst(port_id, 0, &mbuf, 1); + if (ret != 1) { + printf("fail to send nbuf via tun port!\n"); + goto port_fail; + } + } + + count = count - 1; + } + + printf("Stats after ping replies\n"); + sprintf(cmd_exec, "%s %s | grep packets", IFCONFIG, tun_intf_name); + ret = system(cmd_exec); + if (ret != 0) { + printf("fail to execute (%s)!\n", cmd_exec); + goto port_fail; + } + + ret = rte_eth_stats_get(port_id, &stats); + if (ret != 0) + goto port_fail; + + if (((stats.opackets - tx_pkts) != 10) || + ((stats.ipackets - rx_pkts) != 10) || + (stats.ierrors - rx_err) || + (stats.oerrors - tx_err)) { + printf("Fail to match the expected stats\n"); + goto port_fail; +} + +port_fail: + rte_eth_dev_stop(port_id); + +fail: + rte_vdev_uninit(tun_drv_name); + + fflush(stdout); + + rte_delay_ms(2000); + return ret; +} + +REGISTER_TEST_COMMAND(tun_autotest, test_tun); -- 1.9.1