1aa97dd1cSKonstantin Ananyev/*
2aa97dd1cSKonstantin Ananyev * Copyright (c) 2016  Intel Corporation.
3aa97dd1cSKonstantin Ananyev * Licensed under the Apache License, Version 2.0 (the "License");
4aa97dd1cSKonstantin Ananyev * you may not use this file except in compliance with the License.
5aa97dd1cSKonstantin Ananyev * You may obtain a copy of the License at:
6aa97dd1cSKonstantin Ananyev *
7aa97dd1cSKonstantin Ananyev *     http://www.apache.org/licenses/LICENSE-2.0
8aa97dd1cSKonstantin Ananyev *
9aa97dd1cSKonstantin Ananyev * Unless required by applicable law or agreed to in writing, software
10aa97dd1cSKonstantin Ananyev * distributed under the License is distributed on an "AS IS" BASIS,
11aa97dd1cSKonstantin Ananyev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12aa97dd1cSKonstantin Ananyev * See the License for the specific language governing permissions and
13aa97dd1cSKonstantin Ananyev * limitations under the License.
14aa97dd1cSKonstantin Ananyev */
15aa97dd1cSKonstantin Ananyev
16aa97dd1cSKonstantin Ananyev#ifndef TEST_TLE_UDP_STREAM_GEN_H_
17aa97dd1cSKonstantin Ananyev#define TEST_TLE_UDP_STREAM_GEN_H_
18aa97dd1cSKonstantin Ananyev
19aa97dd1cSKonstantin Ananyev#include <sys/types.h>
20aa97dd1cSKonstantin Ananyev
21aa97dd1cSKonstantin Ananyev#include <stdio.h>
22aa97dd1cSKonstantin Ananyev#include <map>
23aa97dd1cSKonstantin Ananyev#include <string>
24aa97dd1cSKonstantin Ananyev#include <algorithm>
25aa97dd1cSKonstantin Ananyev#include <arpa/inet.h>
26aa97dd1cSKonstantin Ananyev#include <netinet/ip6.h>
27aa97dd1cSKonstantin Ananyev#include <sys/socket.h>
28aa97dd1cSKonstantin Ananyev#include <netdb.h>
29aa97dd1cSKonstantin Ananyev#include <gtest/gtest.h>
30aa97dd1cSKonstantin Ananyev
31aa97dd1cSKonstantin Ananyev#include <rte_version.h>
32aa97dd1cSKonstantin Ananyev
33aa97dd1cSKonstantin Ananyev#include <tle_udp.h>
34aa97dd1cSKonstantin Ananyev#include <tle_event.h>
35aa97dd1cSKonstantin Ananyev
36aa97dd1cSKonstantin Ananyev#include "test_common.h"
37aa97dd1cSKonstantin Ananyev
38aa97dd1cSKonstantin Ananyev#define RX_NO_OFFLOAD 0
39aa97dd1cSKonstantin Ananyev#define TX_NO_OFFLOAD 0
40aa97dd1cSKonstantin Ananyev#define CTX_MAX_RBUFS 0x100
41aa97dd1cSKonstantin Ananyev#define CTX_MAX_SBUFS 0x100
42aa97dd1cSKonstantin Ananyev
43aa97dd1cSKonstantin Ananyev#define RX_PCAP "rx_pcap.cap"
44aa97dd1cSKonstantin Ananyev#define TX_PCAP "tx_pcap.cap"
45aa97dd1cSKonstantin Ananyev
46aa97dd1cSKonstantin Ananyev/*
47aa97dd1cSKonstantin Ananyev * Check DPDK version:
48aa97dd1cSKonstantin Ananyev * Previous "eth_pcap" was changed to "net_pcap" after DPDK 16.07.
49aa97dd1cSKonstantin Ananyev * Use correct vdev name depending on version.
50aa97dd1cSKonstantin Ananyev */
51aa97dd1cSKonstantin Ananyev#if (RTE_VERSION_NUM(16, 7, 0, 0) < \
52aa97dd1cSKonstantin Ananyev	RTE_VERSION_NUM(RTE_VER_YEAR, RTE_VER_MONTH, 0, 0))
53aa97dd1cSKonstantin Ananyev	#define VDEV_NAME "net_pcap0"
54aa97dd1cSKonstantin Ananyev#else
55aa97dd1cSKonstantin Ananyev	#define VDEV_NAME "eth_pcap0"
56aa97dd1cSKonstantin Ananyev#endif
57aa97dd1cSKonstantin Ananyev
58aa97dd1cSKonstantin Ananyevusing namespace std;
59aa97dd1cSKonstantin Ananyev
60aa97dd1cSKonstantin Ananyevextern struct rte_mempool *mbuf_pool;
61aa97dd1cSKonstantin Ananyev
62aa97dd1cSKonstantin Ananyev/* Dummy lookup functions, TX operations are not performed in these tests */
63aa97dd1cSKonstantin Ananyev
64aa97dd1cSKonstantin Ananyevstatic int
65aa97dd1cSKonstantin Ananyevlookup4_function(void *opaque, const struct in_addr *addr, struct tle_dest *res)
66aa97dd1cSKonstantin Ananyev{
67aa97dd1cSKonstantin Ananyev	struct in_addr route;
68aa97dd1cSKonstantin Ananyev	struct ether_hdr *eth;
69aa97dd1cSKonstantin Ananyev	struct ipv4_hdr *ip4h;
70aa97dd1cSKonstantin Ananyev	auto routes = static_cast<map<string, tle_dev *> *>(opaque);
71aa97dd1cSKonstantin Ananyev
72aa97dd1cSKonstantin Ananyev	/* Check all routes added in map for a match with dest *addr */
73aa97dd1cSKonstantin Ananyev	for (auto it = routes->begin(); it != routes->end(); ++it) {
74aa97dd1cSKonstantin Ananyev		inet_pton(AF_INET, it->first.c_str(), &route);
75aa97dd1cSKonstantin Ananyev
76aa97dd1cSKonstantin Ananyev		/* If it matches then fill *res and return with 0 code */
77aa97dd1cSKonstantin Ananyev		if (memcmp(&route, addr, sizeof(struct in_addr)) == 0) {
78aa97dd1cSKonstantin Ananyev			memset(res, 0, sizeof(*res));
79aa97dd1cSKonstantin Ananyev			res->dev = it->second;
80aa97dd1cSKonstantin Ananyev			res->mtu = 1500;
81aa97dd1cSKonstantin Ananyev			res->l2_len = sizeof(*eth);
82aa97dd1cSKonstantin Ananyev			res->l3_len = sizeof(*ip4h);
83aa97dd1cSKonstantin Ananyev			res->head_mp = mbuf_pool;
84aa97dd1cSKonstantin Ananyev			eth = (struct ether_hdr *)res->hdr;
85aa97dd1cSKonstantin Ananyev			eth->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
86aa97dd1cSKonstantin Ananyev			ip4h = (struct ipv4_hdr *)(eth + 1);
87aa97dd1cSKonstantin Ananyev			ip4h->version_ihl = (4 << 4) |
88aa97dd1cSKonstantin Ananyev				(sizeof(*ip4h) / IPV4_IHL_MULTIPLIER);
89aa97dd1cSKonstantin Ananyev			ip4h->time_to_live = 64;
90aa97dd1cSKonstantin Ananyev			ip4h->next_proto_id = IPPROTO_UDP;
91aa97dd1cSKonstantin Ananyev			ip4h->fragment_offset = 0;
92aa97dd1cSKonstantin Ananyev
93aa97dd1cSKonstantin Ananyev			return 0;
94aa97dd1cSKonstantin Ananyev		}
95aa97dd1cSKonstantin Ananyev	}
96aa97dd1cSKonstantin Ananyev
97aa97dd1cSKonstantin Ananyev	return -ENOENT;
98aa97dd1cSKonstantin Ananyev}
99aa97dd1cSKonstantin Ananyev
100aa97dd1cSKonstantin Ananyevstatic int
101aa97dd1cSKonstantin Ananyevlookup6_function(void *opaque, const struct in6_addr *addr,
102aa97dd1cSKonstantin Ananyev	struct tle_dest *res)
103aa97dd1cSKonstantin Ananyev{
104aa97dd1cSKonstantin Ananyev	struct ether_hdr *eth;
105aa97dd1cSKonstantin Ananyev	struct ipv6_hdr *ip6h;
106aa97dd1cSKonstantin Ananyev	struct in6_addr route;
107aa97dd1cSKonstantin Ananyev	auto routes = static_cast<map<string, tle_dev *> *>(opaque);
108aa97dd1cSKonstantin Ananyev
109aa97dd1cSKonstantin Ananyev	/* Check all routes added in map for a match with dest *addr */
110aa97dd1cSKonstantin Ananyev	for (auto it = routes->begin(); it != routes->end(); ++it) {
111aa97dd1cSKonstantin Ananyev		inet_pton(AF_INET6, it->first.c_str(), &route);
112aa97dd1cSKonstantin Ananyev
113aa97dd1cSKonstantin Ananyev		/* If it matches then fill *res and return with 0 code */
114aa97dd1cSKonstantin Ananyev		if (memcmp(&route, addr, sizeof(struct in6_addr)) == 0) {
115aa97dd1cSKonstantin Ananyev			memset(res, 0, sizeof(*res));
116aa97dd1cSKonstantin Ananyev			res->dev = it->second;
117aa97dd1cSKonstantin Ananyev			res->mtu = 1500;
118aa97dd1cSKonstantin Ananyev			res->l2_len = sizeof(*eth);
119aa97dd1cSKonstantin Ananyev			res->l3_len = sizeof(*ip6h);
120aa97dd1cSKonstantin Ananyev			res->head_mp = mbuf_pool;
121aa97dd1cSKonstantin Ananyev			eth = (struct ether_hdr *)res->hdr;
122aa97dd1cSKonstantin Ananyev			eth->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
123aa97dd1cSKonstantin Ananyev			ip6h = (struct ipv6_hdr *)(eth + 1);
124aa97dd1cSKonstantin Ananyev			ip6h->vtc_flow = 6 << 4;
125aa97dd1cSKonstantin Ananyev			ip6h->proto = IPPROTO_UDP;
126aa97dd1cSKonstantin Ananyev			ip6h->hop_limits = 64;
127aa97dd1cSKonstantin Ananyev
128aa97dd1cSKonstantin Ananyev			return 0;
129aa97dd1cSKonstantin Ananyev		}
130aa97dd1cSKonstantin Ananyev	}
131aa97dd1cSKonstantin Ananyev	return -ENOENT;
132aa97dd1cSKonstantin Ananyev}
133aa97dd1cSKonstantin Ananyev
134aa97dd1cSKonstantin Ananyev/*
135aa97dd1cSKonstantin Ananyev * Structures used to describe test instances:
136aa97dd1cSKonstantin Ananyev * test_str - main structure for describing test case instance; contains
137aa97dd1cSKonstantin Ananyev *            instance description, and vectors with information about
138aa97dd1cSKonstantin Ananyev *            devices, streams & streams to be generated for RX/TX path.
139aa97dd1cSKonstantin Ananyev * dev_s    - structure describing single device; contains device addresses,
140aa97dd1cSKonstantin Ananyev *            checksum offload information and expected number of received /
141aa97dd1cSKonstantin Ananyev *            transmitted packets.
142aa97dd1cSKonstantin Ananyev *            packets for that device in scenario.
143aa97dd1cSKonstantin Ananyev * stream_s - structure describing single stream to be created; contains
144aa97dd1cSKonstantin Ananyev *            information on local & remote IP's and port numbers, expected
145aa97dd1cSKonstantin Ananyev *            number of received and transmitted packets.
146aa97dd1cSKonstantin Ananyev * stream_g - structure describing a stream which to generate via scapy script;
147aa97dd1cSKonstantin Ananyev *            Contains information on IP addresses and port numbers and if
148aa97dd1cSKonstantin Ananyev *            L3/L4 checksums should be incorrectly calculated.
149aa97dd1cSKonstantin Ananyev *            In future: if packet should be fragmented.
150aa97dd1cSKonstantin Ananyev */
151aa97dd1cSKonstantin Ananyev
152aa97dd1cSKonstantin Ananyevstruct stream_g {
153aa97dd1cSKonstantin Ananyev	int family;
154aa97dd1cSKonstantin Ananyev	string src_ip;
155aa97dd1cSKonstantin Ananyev	string dst_ip;
156aa97dd1cSKonstantin Ananyev	int src_port;
157aa97dd1cSKonstantin Ananyev	int dst_port;
158aa97dd1cSKonstantin Ananyev	int nb_pkts;
159aa97dd1cSKonstantin Ananyev	bool bad_chksum_l3;
160aa97dd1cSKonstantin Ananyev	bool bad_chksum_l4;
161aa97dd1cSKonstantin Ananyev	bool fragment;
162aa97dd1cSKonstantin Ananyev};
163aa97dd1cSKonstantin Ananyev
164aa97dd1cSKonstantin Ananyevstruct stream_s {
165aa97dd1cSKonstantin Ananyev	int family;
166aa97dd1cSKonstantin Ananyev	int l_port;
167aa97dd1cSKonstantin Ananyev	int r_port;
168aa97dd1cSKonstantin Ananyev	string l_ip;
169aa97dd1cSKonstantin Ananyev	string r_ip;
170aa97dd1cSKonstantin Ananyev	int exp_pkts_rx;
171aa97dd1cSKonstantin Ananyev	int exp_pkts_tx;
172aa97dd1cSKonstantin Ananyev	int act_pkts_rx;
173aa97dd1cSKonstantin Ananyev	int act_pkts_tx;
174aa97dd1cSKonstantin Ananyev	tle_stream *ptr;
175aa97dd1cSKonstantin Ananyev};
176aa97dd1cSKonstantin Ananyev
177aa97dd1cSKonstantin Ananyevstruct dev_s {
178aa97dd1cSKonstantin Ananyev	string l_ipv4;
179aa97dd1cSKonstantin Ananyev	string l_ipv6;
1805c795f7bSKonstantin Ananyev	uint64_t rx_offload;
1815c795f7bSKonstantin Ananyev	uint64_t tx_offload;
182aa97dd1cSKonstantin Ananyev	int exp_pkts_bulk_rx;
183aa97dd1cSKonstantin Ananyev	int exp_pkts_bulk_tx;
184aa97dd1cSKonstantin Ananyev	int exp_pkts_enoent;
185aa97dd1cSKonstantin Ananyev	int act_pkts_bulk_rx;
186aa97dd1cSKonstantin Ananyev	int act_pkts_bulk_tx;
187aa97dd1cSKonstantin Ananyev	int act_pkts_enoent;
188aa97dd1cSKonstantin Ananyev	tle_dev *ptr;
189aa97dd1cSKonstantin Ananyev};
190aa97dd1cSKonstantin Ananyev
191aa97dd1cSKonstantin Ananyevstruct test_str {
192aa97dd1cSKonstantin Ananyev	string test_desc;
193aa97dd1cSKonstantin Ananyev	vector<dev_s> devs;
194aa97dd1cSKonstantin Ananyev	vector<stream_s> streams;
195aa97dd1cSKonstantin Ananyev	vector<stream_g> gen_streams;
196aa97dd1cSKonstantin Ananyev};
197aa97dd1cSKonstantin Ananyev
198cecfc87fSJianfeng Tanconst char *vdevargs = "rx_pcap=" RX_PCAP ",tx_pcap=" TX_PCAP;
199aa97dd1cSKonstantin Ananyev
200aa97dd1cSKonstantin Ananyevclass test_tle_udp_gen_base : public testing::TestWithParam<test_str> {
201aa97dd1cSKonstantin Ananyevpublic:
202aa97dd1cSKonstantin Ananyev
203aa97dd1cSKonstantin Ananyev	tle_ctx *setup_ctx(void);
2045c795f7bSKonstantin Ananyev	tle_dev *setup_dev(tle_ctx *ctx, uint64_t rx_offload,
2055c795f7bSKonstantin Ananyev		uint64_t tx_offload, const char *local_ipv4,
206aa97dd1cSKonstantin Ananyev		const char *local_ipv6);
207aa97dd1cSKonstantin Ananyev	tle_evq *setup_evq(void);
208aa97dd1cSKonstantin Ananyev	tle_event *setup_event(void);
209aa97dd1cSKonstantin Ananyev	tle_stream *setup_stream(struct tle_ctx *ctx, int family,
210aa97dd1cSKonstantin Ananyev		const char *l_ip, const char *r_ip, int l_port, int r_port);
2115c795f7bSKonstantin Ananyev	int setup_devices(dpdk_port_t *portid);
2125c795f7bSKonstantin Ananyev	int cleanup_devices(dpdk_port_t portid);
213aa97dd1cSKonstantin Ananyev	int prepare_pcaps(string l_ip, string r_ip, int l_port, int r_port,
214aa97dd1cSKonstantin Ananyev		int nb_pkts, int l3_chksum, int l4_chksum, string rx_pcap_dest);
215aa97dd1cSKonstantin Ananyev
216aa97dd1cSKonstantin Ananyev	int cleanup_pcaps(const char *file);
217aa97dd1cSKonstantin Ananyev	int close_streams(vector<struct stream_s> streams);
218aa97dd1cSKonstantin Ananyev	int del_devs(vector<struct dev_s> devs);
219aa97dd1cSKonstantin Ananyev
220aa97dd1cSKonstantin Ananyev	virtual void SetUp(void)
221aa97dd1cSKonstantin Ananyev	{
222aa97dd1cSKonstantin Ananyev		nb_ports = 1;
223aa97dd1cSKonstantin Ananyev		tp = GetParam();
224aa97dd1cSKonstantin Ananyev
225aa97dd1cSKonstantin Ananyev		/* Usual tldk stuff below -> ctx, dev, events etc. */
226aa97dd1cSKonstantin Ananyev		ctx = setup_ctx();
227aa97dd1cSKonstantin Ananyev		ASSERT_NE(ctx, nullptr);
228aa97dd1cSKonstantin Ananyev
229aa97dd1cSKonstantin Ananyev		evq = setup_evq();
230aa97dd1cSKonstantin Ananyev		ASSERT_NE(evq, nullptr);
231aa97dd1cSKonstantin Ananyev
232aa97dd1cSKonstantin Ananyev		for (auto &d : tp.devs) {
233aa97dd1cSKonstantin Ananyev			dev = setup_dev(ctx, d.rx_offload, d.tx_offload,
234aa97dd1cSKonstantin Ananyev				d.l_ipv4.c_str(), d.l_ipv6.c_str());
235aa97dd1cSKonstantin Ananyev			ASSERT_NE(dev, nullptr);
236aa97dd1cSKonstantin Ananyev
237aa97dd1cSKonstantin Ananyev			/* Initialize counters for verifying results */
238aa97dd1cSKonstantin Ananyev			d.act_pkts_bulk_rx = 0;
239aa97dd1cSKonstantin Ananyev			d.act_pkts_bulk_tx = 0;
240aa97dd1cSKonstantin Ananyev			d.act_pkts_enoent = 0;
241aa97dd1cSKonstantin Ananyev
242aa97dd1cSKonstantin Ananyev			/* Save pointer to device */
243aa97dd1cSKonstantin Ananyev			d.ptr = dev;
244aa97dd1cSKonstantin Ananyev		}
245aa97dd1cSKonstantin Ananyev
246aa97dd1cSKonstantin Ananyev		for (auto &s : tp.streams) {
247aa97dd1cSKonstantin Ananyev			stream = setup_stream(ctx, s.family,
248aa97dd1cSKonstantin Ananyev					s.l_ip.c_str(), s.r_ip.c_str(),
249aa97dd1cSKonstantin Ananyev					s.l_port, s.r_port);
250aa97dd1cSKonstantin Ananyev			ASSERT_NE(stream, nullptr);
251aa97dd1cSKonstantin Ananyev
252aa97dd1cSKonstantin Ananyev			/* Initialize counters for verifying results */
253aa97dd1cSKonstantin Ananyev			s.act_pkts_rx = 0;
254aa97dd1cSKonstantin Ananyev			s.act_pkts_tx = 0;
255aa97dd1cSKonstantin Ananyev
256aa97dd1cSKonstantin Ananyev			/* Save pointer to stream */
257aa97dd1cSKonstantin Ananyev			s.ptr = stream;
258aa97dd1cSKonstantin Ananyev
259aa97dd1cSKonstantin Ananyev			/* Find which dev has the same address as streams
260aa97dd1cSKonstantin Ananyev			 * local address and save destination for later use
261aa97dd1cSKonstantin Ananyev			 * in lookup functions
262aa97dd1cSKonstantin Ananyev			 */
263aa97dd1cSKonstantin Ananyev			if (s.family == AF_INET) {
264aa97dd1cSKonstantin Ananyev				for (auto &d : tp.devs) {
265aa97dd1cSKonstantin Ananyev					if (s.l_ip.compare(d.l_ipv4) == 0)
266aa97dd1cSKonstantin Ananyev						routes4.insert(pair<string,
267aa97dd1cSKonstantin Ananyev							tle_dev *>(s.r_ip,
268aa97dd1cSKonstantin Ananyev								d.ptr));
269aa97dd1cSKonstantin Ananyev				}
270aa97dd1cSKonstantin Ananyev			} else if (s.family == AF_INET6) {
271aa97dd1cSKonstantin Ananyev				for (auto &d : tp.devs) {
272aa97dd1cSKonstantin Ananyev					if (s.l_ip.compare(d.l_ipv6) == 0)
273aa97dd1cSKonstantin Ananyev						routes6.insert(pair<string,
274aa97dd1cSKonstantin Ananyev							tle_dev *>(s.r_ip,
275aa97dd1cSKonstantin Ananyev								d.ptr));
276aa97dd1cSKonstantin Ananyev				}
277aa97dd1cSKonstantin Ananyev			}
278aa97dd1cSKonstantin Ananyev		}
279aa97dd1cSKonstantin Ananyev
280aa97dd1cSKonstantin Ananyev		/* setup pcap/eth devices */
281aa97dd1cSKonstantin Ananyev		setup_devices(&portid);
282aa97dd1cSKonstantin Ananyev	}
283aa97dd1cSKonstantin Ananyev
284aa97dd1cSKonstantin Ananyev	virtual void TearDown(void)
285aa97dd1cSKonstantin Ananyev	{
286aa97dd1cSKonstantin Ananyev		/*
287aa97dd1cSKonstantin Ananyev		 * Remember to shutdown & detach rte devices
288aa97dd1cSKonstantin Ananyev		 * and clean / delete .pcap files so not to
289aa97dd1cSKonstantin Ananyev		 * interfere with next test
290aa97dd1cSKonstantin Ananyev		 */
291aa97dd1cSKonstantin Ananyev		close_streams(tp.streams);
292aa97dd1cSKonstantin Ananyev		del_devs(tp.devs);
293aa97dd1cSKonstantin Ananyev		tle_ctx_destroy(ctx);
294aa97dd1cSKonstantin Ananyev		cleanup_devices(portid);
295aa97dd1cSKonstantin Ananyev		cleanup_pcaps(RX_PCAP);
296aa97dd1cSKonstantin Ananyev		cleanup_pcaps(TX_PCAP);
297aa97dd1cSKonstantin Ananyev	}
298aa97dd1cSKonstantin Ananyev
2995c795f7bSKonstantin Ananyev	dpdk_port_t nb_ports;
3005c795f7bSKonstantin Ananyev	dpdk_port_t portid;
301aa97dd1cSKonstantin Ananyev	uint32_t socket_id;
302aa97dd1cSKonstantin Ananyev	uint32_t max_events;
303aa97dd1cSKonstantin Ananyev	struct tle_ctx *ctx;
304aa97dd1cSKonstantin Ananyev	struct tle_dev *dev;
305aa97dd1cSKonstantin Ananyev	struct tle_evq *evq;
306aa97dd1cSKonstantin Ananyev	struct tle_stream *stream;
307aa97dd1cSKonstantin Ananyev	map<string, tle_dev *> routes4;
308aa97dd1cSKonstantin Ananyev	map<string, tle_dev *> routes6;
309aa97dd1cSKonstantin Ananyev	test_str tp;
310cecfc87fSJianfeng Tan	const void *cb;
311aa97dd1cSKonstantin Ananyev};
312aa97dd1cSKonstantin Ananyev
313aa97dd1cSKonstantin Ananyevint
3145c795f7bSKonstantin Ananyevtest_tle_udp_gen_base::setup_devices(dpdk_port_t *portid)
315aa97dd1cSKonstantin Ananyev{
316aa97dd1cSKonstantin Ananyev	/* attach + configure + start pmd device */
317cecfc87fSJianfeng Tan	if (rte_eal_hotplug_add("vdev", VDEV_NAME, vdevargs) < 0 ||
318cecfc87fSJianfeng Tan			rte_eth_dev_get_port_by_name(VDEV_NAME, portid) != 0)
319aa97dd1cSKonstantin Ananyev		return -1;
320aa97dd1cSKonstantin Ananyev	cb = rte_eth_add_rx_callback(*portid, 0,
321aa97dd1cSKonstantin Ananyev		typen_rx_callback, nullptr);
322aa97dd1cSKonstantin Ananyev	if (port_init(*portid, mbuf_pool) != 0)
323aa97dd1cSKonstantin Ananyev		return -1;
324aa97dd1cSKonstantin Ananyev
325aa97dd1cSKonstantin Ananyev	return 0;
326aa97dd1cSKonstantin Ananyev}
327aa97dd1cSKonstantin Ananyev
328aa97dd1cSKonstantin Ananyevint
3295c795f7bSKonstantin Ananyevtest_tle_udp_gen_base::cleanup_devices(dpdk_port_t portid)
330aa97dd1cSKonstantin Ananyev{
331aa97dd1cSKonstantin Ananyev	/* release mbufs + detach device */
332aa97dd1cSKonstantin Ananyev	char name[RTE_ETH_NAME_MAX_LEN];
333aa97dd1cSKonstantin Ananyev
334aa97dd1cSKonstantin Ananyev	rte_eth_dev_stop(portid);
335aa97dd1cSKonstantin Ananyev	rte_eth_dev_close(portid);
336cecfc87fSJianfeng Tan	rte_eal_hotplug_remove("vdev", VDEV_NAME);
337aa97dd1cSKonstantin Ananyev
338aa97dd1cSKonstantin Ananyev	return 0;
339aa97dd1cSKonstantin Ananyev}
340aa97dd1cSKonstantin Ananyev
341aa97dd1cSKonstantin Ananyevint
342aa97dd1cSKonstantin Ananyevtest_tle_udp_gen_base::prepare_pcaps(string l_ip, string r_ip, int l_port,
343aa97dd1cSKonstantin Ananyev	int r_port, int nb_pkts, int l3_chksum, int l4_chksum,
344aa97dd1cSKonstantin Ananyev	string rx_pcap_dest)
345aa97dd1cSKonstantin Ananyev{
346aa97dd1cSKonstantin Ananyev	string py_cmd;
347aa97dd1cSKonstantin Ananyev
348aa97dd1cSKonstantin Ananyev	/* generate pcap rx & tx files * for tests using scapy */
34968f21c31SKopec, TomaszX	py_cmd = "python " + string(binpath) + "/test_scapy_gen.py ";
350aa97dd1cSKonstantin Ananyev	py_cmd = py_cmd + " " + l_ip + " " + r_ip + " " +
351aa97dd1cSKonstantin Ananyev			to_string(l_port) + " " + to_string(r_port) + " " +
352aa97dd1cSKonstantin Ananyev			to_string(nb_pkts);
353aa97dd1cSKonstantin Ananyev
354aa97dd1cSKonstantin Ananyev	if (l3_chksum > 0)
355aa97dd1cSKonstantin Ananyev		py_cmd = py_cmd + " -bc3 " + to_string(l3_chksum);
356aa97dd1cSKonstantin Ananyev	if (l4_chksum > 0)
357aa97dd1cSKonstantin Ananyev		py_cmd = py_cmd + " -bc4 " + to_string(l4_chksum);
358aa97dd1cSKonstantin Ananyev	py_cmd = py_cmd + " " + rx_pcap_dest;
359aa97dd1cSKonstantin Ananyev	system(py_cmd.c_str());
360aa97dd1cSKonstantin Ananyev	return 0;
361aa97dd1cSKonstantin Ananyev}
362aa97dd1cSKonstantin Ananyev
363aa97dd1cSKonstantin Ananyevint
364aa97dd1cSKonstantin Ananyevtest_tle_udp_gen_base::cleanup_pcaps(const char *file)
365aa97dd1cSKonstantin Ananyev{
366aa97dd1cSKonstantin Ananyev	if (remove(file) != 0)
367aa97dd1cSKonstantin Ananyev		perror("Error deleting pcap file");
368aa97dd1cSKonstantin Ananyev