1a152c68eSDaniel Mrzyglod/*
2a152c68eSDaniel Mrzyglod * Copyright (c) 2016  Intel Corporation.
3a152c68eSDaniel Mrzyglod * Licensed under the Apache License, Version 2.0 (the "License");
4a152c68eSDaniel Mrzyglod * you may not use this file except in compliance with the License.
5a152c68eSDaniel Mrzyglod * You may obtain a copy of the License at:
6a152c68eSDaniel Mrzyglod *
7a152c68eSDaniel Mrzyglod *     http://www.apache.org/licenses/LICENSE-2.0
8a152c68eSDaniel Mrzyglod *
9a152c68eSDaniel Mrzyglod * Unless required by applicable law or agreed to in writing, software
10a152c68eSDaniel Mrzyglod * distributed under the License is distributed on an "AS IS" BASIS,
11a152c68eSDaniel Mrzyglod * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a152c68eSDaniel Mrzyglod * See the License for the specific language governing permissions and
13a152c68eSDaniel Mrzyglod * limitations under the License.
14a152c68eSDaniel Mrzyglod */
15a152c68eSDaniel Mrzyglod
16a152c68eSDaniel Mrzyglod#ifndef TEST_TLE_UDP_STREAM_H_
17a152c68eSDaniel Mrzyglod#define TEST_TLE_UDP_STREAM_H_
18a152c68eSDaniel Mrzyglod#include <iostream>
19aa97dd1cSKonstantin Ananyev#include <algorithm>
20aa97dd1cSKonstantin Ananyev#include <string>
21a152c68eSDaniel Mrzyglod#include <arpa/inet.h>
22aa97dd1cSKonstantin Ananyev#include <netinet/in.h>
23aa97dd1cSKonstantin Ananyev#include <netinet/ip6.h>
24a152c68eSDaniel Mrzyglod#include <gtest/gtest.h>
25a152c68eSDaniel Mrzyglod#include <gmock/gmock.h>
26a152c68eSDaniel Mrzyglod#include <rte_errno.h>
27a152c68eSDaniel Mrzyglod
28aa97dd1cSKonstantin Ananyev#include <tle_udp.h>
29a152c68eSDaniel Mrzyglod#include <tle_event.h>
30a152c68eSDaniel Mrzyglod
31aa97dd1cSKonstantin Ananyev#include "test_common.h"
32128f0192SKonstantin Ananyev
33aa97dd1cSKonstantin Ananyev#define MAX_STREAMS 0xFFFF
34aa97dd1cSKonstantin Ananyev#define MAX_STREAM_RBUFS 0x100
35aa97dd1cSKonstantin Ananyev#define MAX_STREAM_SBUFS 0x100
36aa97dd1cSKonstantin Ananyev#define RX_OFFLOAD 0x100
37aa97dd1cSKonstantin Ananyev#define TX_OFFLOAD 0x100
38aa97dd1cSKonstantin Ananyev
39aa97dd1cSKonstantin Ananyevusing namespace std;
40128f0192SKonstantin Ananyev
41aa97dd1cSKonstantin Ananyevstruct tle_ctx_param ctx_prm_tmpl = {
42a152c68eSDaniel Mrzyglod	.socket_id = SOCKET_ID_ANY,
43aa97dd1cSKonstantin Ananyev	.proto = TLE_PROTO_UDP,
44aa97dd1cSKonstantin Ananyev	.max_streams = MAX_STREAMS,
45aa97dd1cSKonstantin Ananyev	.max_stream_rbufs = MAX_STREAM_RBUFS,
46aa97dd1cSKonstantin Ananyev	.max_stream_sbufs = MAX_STREAM_SBUFS
47a152c68eSDaniel Mrzyglod};
48a152c68eSDaniel Mrzyglod
49aa97dd1cSKonstantin Ananyevstruct tle_dev_param dev_prm_tmpl = {
50aa97dd1cSKonstantin Ananyev	.rx_offload = RX_OFFLOAD,
51aa97dd1cSKonstantin Ananyev	.tx_offload = TX_OFFLOAD
52a152c68eSDaniel Mrzyglod};
53a152c68eSDaniel Mrzyglod
54a152c68eSDaniel Mrzyglodclass test_tle_udp_stream: public ::testing::Test {
55a152c68eSDaniel Mrzyglodpublic:
56aa97dd1cSKonstantin Ananyev	void setup_dev_prm(struct tle_dev_param *,
57a152c68eSDaniel Mrzyglod			char const *, char const *);
58aa97dd1cSKonstantin Ananyev	struct tle_ctx *setup_ctx(struct tle_ctx_param *prm);
59aa97dd1cSKonstantin Ananyev	struct tle_dev *setup_dev(struct tle_ctx *ctx,
60aa97dd1cSKonstantin Ananyev			struct tle_dev_param *dev_prm);
61a152c68eSDaniel Mrzyglod	struct tle_evq *setup_event();
62a152c68eSDaniel Mrzyglod
63a152c68eSDaniel Mrzyglod	virtual void SetUp(void)
64a152c68eSDaniel Mrzyglod	{
65aa97dd1cSKonstantin Ananyev		char const *ipv4_laddr = "192.0.0.1";
66aa97dd1cSKonstantin Ananyev		char const *ipv4_raddr = "10.0.0.1";
67a152c68eSDaniel Mrzyglod		char const *ipv6 = "fe80::21e:67ff:fec2:2568";
68aa97dd1cSKonstantin Ananyev		struct tle_ctx_param cprm;
69aa97dd1cSKonstantin Ananyev		port = 10000;
70a152c68eSDaniel Mrzyglod
71a152c68eSDaniel Mrzyglod		ctx = nullptr;
72a152c68eSDaniel Mrzyglod		dev = nullptr;
73a152c68eSDaniel Mrzyglod		stream = nullptr;
74a152c68eSDaniel Mrzyglod		/* Setup Context */
75128f0192SKonstantin Ananyev		cprm = ctx_prm_tmpl;
76aa97dd1cSKonstantin Ananyev		cprm.max_streams = 0xA;
77128f0192SKonstantin Ananyev		cprm.lookup4 = dummy_lookup4;
78128f0192SKonstantin Ananyev		cprm.lookup6 = dummy_lookup6;
79128f0192SKonstantin Ananyev		ctx = setup_ctx(&cprm);
80aa97dd1cSKonstantin Ananyev		ASSERT_NE(ctx, nullptr);
81aa97dd1cSKonstantin Ananyev
82a152c68eSDaniel Mrzyglod		/* Setup Dev */
83a152c68eSDaniel Mrzyglod		memset(&dev_prm, 0, sizeof(dev_prm));
84a152c68eSDaniel Mrzyglod		setup_dev_prm(&dev_prm, ipv4_laddr, ipv6);
85a152c68eSDaniel Mrzyglod		dev = setup_dev(ctx, &dev_prm);
86aa97dd1cSKonstantin Ananyev		ASSERT_NE(dev, nullptr);
87a152c68eSDaniel Mrzyglod
88a152c68eSDaniel Mrzyglod		/* Stream Param & Event param */
89a152c68eSDaniel Mrzyglod		memset(&stream_prm, 0, sizeof(struct tle_udp_stream_param));
90aa97dd1cSKonstantin Ananyev
91aa97dd1cSKonstantin Ananyev		ip4_addr = (struct sockaddr_in *) &stream_prm.local_addr;
92aa97dd1cSKonstantin Ananyev		ip4_addr->sin_family = AF_INET;
93aa97dd1cSKonstantin Ananyev		ip4_addr->sin_port = htons(port);
94aa97dd1cSKonstantin Ananyev		ip4_addr->sin_addr.s_addr = inet_addr(ipv4_laddr);
95aa97dd1cSKonstantin Ananyev
96aa97dd1cSKonstantin Ananyev		ip4_addr = (struct sockaddr_in *) &stream_prm.remote_addr;
97aa97dd1cSKonstantin Ananyev		ip4_addr->sin_family = AF_INET;
98aa97dd1cSKonstantin Ananyev		ip4_addr->sin_port = htons(port);
99aa97dd1cSKonstantin Ananyev		ip4_addr->sin_addr.s_addr = inet_addr(ipv4_raddr);
100aa97dd1cSKonstantin Ananyev
101a152c68eSDaniel Mrzyglod		stream_prm.recv_ev = tle_event_alloc(setup_event(), nullptr);
102a152c68eSDaniel Mrzyglod		stream_prm.send_ev = tle_event_alloc(setup_event(), nullptr);
103a152c68eSDaniel Mrzyglod	}
104a152c68eSDaniel Mrzyglod
105a152c68eSDaniel Mrzyglod	virtual void TearDown(void)
106a152c68eSDaniel Mrzyglod	{
107a152c68eSDaniel Mrzyglod		ret = 0;
108aa97dd1cSKonstantin Ananyev		for (auto s : streams)
109aa97dd1cSKonstantin Ananyev			tle_udp_stream_close(s);
110aa97dd1cSKonstantin Ananyev
111aa97dd1cSKonstantin Ananyev		tle_del_dev(dev);
112aa97dd1cSKonstantin Ananyev		tle_ctx_destroy(ctx);
113a152c68eSDaniel Mrzyglod	}
114a152c68eSDaniel Mrzyglod
115a152c68eSDaniel Mrzyglod	int ret;
116aa97dd1cSKonstantin Ananyev	int port;
117aa97dd1cSKonstantin Ananyev	struct tle_ctx *ctx;
118aa97dd1cSKonstantin Ananyev	struct tle_dev *dev;
119aa97dd1cSKonstantin Ananyev	struct tle_stream *stream;
120aa97dd1cSKonstantin Ananyev	struct tle_ctx_param ctx_prm;
121aa97dd1cSKonstantin Ananyev	struct tle_dev_param dev_prm;
122a152c68eSDaniel Mrzyglod	struct tle_udp_stream_param stream_prm;
123aa97dd1cSKonstantin Ananyev	struct sockaddr_in *ip4_addr;
124aa97dd1cSKonstantin Ananyev
125aa97dd1cSKonstantin Ananyev	vector<tle_stream *> streams;
126a152c68eSDaniel Mrzyglod};
127a152c68eSDaniel Mrzyglod
128aa97dd1cSKonstantin Ananyevstruct tle_evq *
129aa97dd1cSKonstantin Ananyevtest_tle_udp_stream::setup_event()
130aa97dd1cSKonstantin Ananyev{
131a152c68eSDaniel Mrzyglod	int32_t socket_id;
132a152c68eSDaniel Mrzyglod	uint32_t max_events;
133a152c68eSDaniel Mrzyglod	struct tle_evq_param evq_params;
134a152c68eSDaniel Mrzyglod	struct tle_evq *evq;
135a152c68eSDaniel Mrzyglod
136a152c68eSDaniel Mrzyglod	socket_id = SOCKET_ID_ANY;
137a152c68eSDaniel Mrzyglod	max_events = 10;
138a152c68eSDaniel Mrzyglod	rte_errno = 0;
139a152c68eSDaniel Mrzyglod	memset(&evq_params, 0, sizeof(struct tle_evq_param));
140a152c68eSDaniel Mrzyglod	evq_params.socket_id = socket_id;
141a152c68eSDaniel Mrzyglod	evq_params.max_events = max_events;
142a152c68eSDaniel Mrzyglod	evq = tle_evq_create(&evq_params);
143a152c68eSDaniel Mrzyglod	return evq;
144a152c68eSDaniel Mrzyglod}
145a152c68eSDaniel Mrzyglod
146aa97dd1cSKonstantin Ananyevstruct tle_ctx
147aa97dd1cSKonstantin Ananyev*test_tle_udp_stream::setup_ctx(struct tle_ctx_param *prm)
148aa97dd1cSKonstantin Ananyev{
149aa97dd1cSKonstantin Ananyev	struct tle_ctx *ctx;
150a152c68eSDaniel Mrzyglod
151aa97dd1cSKonstantin Ananyev	ctx = tle_ctx_create(prm);
152a152c68eSDaniel Mrzyglod
153a152c68eSDaniel Mrzyglod	return ctx;
154a152c68eSDaniel Mrzyglod}
155a152c68eSDaniel Mrzyglod
156aa97dd1cSKonstantin Ananyevstruct tle_dev
157aa97dd1cSKonstantin Ananyev*test_tle_udp_stream::setup_dev(struct tle_ctx *ctx,
158aa97dd1cSKonstantin Ananyev	struct tle_dev_param *dev_prm)
159aa97dd1cSKonstantin Ananyev{
160aa97dd1cSKonstantin Ananyev	struct tle_dev *dev;
161a152c68eSDaniel Mrzyglod
162aa97dd1cSKonstantin Ananyev	dev = tle_add_dev(ctx, dev_prm);
163a152c68eSDaniel Mrzyglod
164a152c68eSDaniel Mrzyglod	return dev;
165a152c68eSDaniel Mrzyglod}
166a152c68eSDaniel Mrzyglod
167aa97dd1cSKonstantin Ananyevvoid
168aa97dd1cSKonstantin Ananyevtest_tle_udp_stream::setup_dev_prm(struct tle_dev_param *dev_prm,
169aa97dd1cSKonstantin Ananyev	char const *ipv4, char const *ipv6)
170aa97dd1cSKonstantin Ananyev{
171a152c68eSDaniel Mrzyglod	inet_pton(AF_INET, ipv4, &dev_prm->local_addr4);
172a152c68eSDaniel Mrzyglod	inet_pton(AF_INET6, ipv6, &dev_prm->local_addr6);
173a152c68eSDaniel Mrzyglod
174a152c68eSDaniel Mrzyglod}
175a152c68eSDaniel Mrzyglod
176aa97dd1cSKonstantin Ananyev/* Fixture for max number of streams on single ctx + multiple devices */
177aa97dd1cSKonstantin Ananyevclass test_tle_udp_stream_max: public ::test_tle_udp_stream {
178aa97dd1cSKonstantin Ananyevpublic:
179aa97dd1cSKonstantin Ananyev
180aa97dd1cSKonstantin Ananyev	virtual void SetUp(void)
181aa97dd1cSKonstantin Ananyev	{
182aa97dd1cSKonstantin Ananyev		/* Create enough devices and streams to exceed
183aa97dd1cSKonstantin Ananyev		 * MAX_STREAMS on ctx
184aa97dd1cSKonstantin Ananyev		 */
185aa97dd1cSKonstantin Ananyev		nb_devs = 10;
186aa97dd1cSKonstantin Ananyev		nb_streams = 6554;
187aa97dd1cSKonstantin Ananyev
188aa97dd1cSKonstantin Ananyev		in_addr_t src;
189aa97dd1cSKonstantin Ananyev		string ssrc;
190aa97dd1cSKonstantin Ananyev
191aa97dd1cSKonstantin Ananyev		memset(&ctx_prm, 0, sizeof(ctx_prm));
192aa97dd1cSKonstantin Ananyev		ctx_prm = ctx_prm_tmpl;
193aa97dd1cSKonstantin Ananyev		ctx_prm.lookup4 = dummy_lookup4;
194aa97dd1cSKonstantin Ananyev		ctx_prm.lookup6 = dummy_lookup6;
195aa97dd1cSKonstantin Ananyev		ctx = setup_ctx(&ctx_prm);
196aa97dd1cSKonstantin Ananyev		ASSERT_NE(ctx, (void *)NULL);
197aa97dd1cSKonstantin Ananyev
198aa97dd1cSKonstantin Ananyev		memset(&dev_prm, 0, sizeof(dev_prm));
199aa97dd1cSKonstantin Ananyev		setup_dev_prm(&dev_prm, base_l_ipv4, base_l_ipv6);
200aa97dd1cSKonstantin Ananyev
201aa97dd1cSKonstantin Ananyev		memset(&stream_prm, 0, sizeof(struct tle_udp_stream_param));
202aa97dd1cSKonstantin Ananyev		stream_prm.recv_ev = tle_event_alloc(setup_event(), nullptr);
203aa97dd1cSKonstantin Ananyev		stream_prm.send_ev = tle_event_alloc(setup_event(), nullptr);
204aa97dd1cSKonstantin Ananyev
205aa97dd1cSKonstantin Ananyev		for (i = 0; i < nb_devs; i++) {
206aa97dd1cSKonstantin Ananyev			ssrc = inet_ntoa(dev_prm.local_addr4);
207aa97dd1cSKonstantin Ananyev
208aa97dd1cSKonstantin Ananyev			dev = setup_dev(ctx, &dev_prm);
209aa97dd1cSKonstantin Ananyev			ASSERT_NE(dev, (void *)NULL);
210aa97dd1cSKonstantin Ananyev			devs.push_back(dev);
211aa97dd1cSKonstantin Ananyev
212aa97dd1cSKonstantin Ananyev			/* Modify base IP addresses for next loops */
213aa97dd1cSKonstantin Ananyev			src = dev_prm.local_addr4.s_addr;
214aa97dd1cSKonstantin Ananyev			src += 1;
215aa97dd1cSKonstantin Ananyev			dev_prm.local_addr4.s_addr = src;
216aa97dd1cSKonstantin Ananyev		}
217aa97dd1cSKonstantin Ananyev	}
218aa97dd1cSKonstantin Ananyev
219aa97dd1cSKonstantin Ananyev	virtual void TearDown(void)
220aa97dd1cSKonstantin Ananyev	{
221aa97dd1cSKonstantin Ananyev		for (auto s : streams)
222aa97dd1cSKonstantin Ananyev			tle_udp_stream_close(s);
223aa97dd1cSKonstantin Ananyev
224aa97dd1cSKonstantin Ananyev		for (auto d : devs)
225aa97dd1cSKonstantin Ananyev			tle_del_dev(d);
226aa97dd1cSKonstantin Ananyev
227aa97dd1cSKonstantin Ananyev		tle_ctx_destroy(ctx);
228aa97dd1cSKonstantin Ananyev	}
229aa97dd1cSKonstantin Ananyev
230aa97dd1cSKonstantin Ananyev	int i;
231aa97dd1cSKonstantin Ananyev	int nb_devs;
232aa97dd1cSKonstantin Ananyev	int nb_streams;
233aa97dd1cSKonstantin Ananyev	char const *base_l_ipv4 = "10.0.0.1";
234aa97dd1cSKonstantin Ananyev	char const *base_r_ipv4 = "190.0.0.1";
235aa97dd1cSKonstantin Ananyev	char const *base_l_ipv6 = "2000::1";
236aa97dd1cSKonstantin Ananyev	vector<tle_dev *> devs;
237aa97dd1cSKonstantin Ananyev	vector<tle_stream *> streams;
238aa97dd1cSKonstantin Ananyev};
239aa97dd1cSKonstantin Ananyev
240a152c68eSDaniel Mrzyglod#endif /* TEST_TLE_UDP_STREAM_H_ */
241