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_TCP_STREAM_H_
17aa97dd1cSKonstantin Ananyev#define TEST_TLE_TCP_STREAM_H_
18aa97dd1cSKonstantin Ananyev
19aa97dd1cSKonstantin Ananyev#include <iostream>
20aa97dd1cSKonstantin Ananyev#include <arpa/inet.h>
21aa97dd1cSKonstantin Ananyev#include <netinet/ip6.h>
22aa97dd1cSKonstantin Ananyev#include <sys/socket.h>
23aa97dd1cSKonstantin Ananyev#include <netdb.h>
24aa97dd1cSKonstantin Ananyev#include <gtest/gtest.h>
25aa97dd1cSKonstantin Ananyev#include <gmock/gmock.h>
26aa97dd1cSKonstantin Ananyev#include <rte_errno.h>
27aa97dd1cSKonstantin Ananyev
28aa97dd1cSKonstantin Ananyev#include <tle_event.h>
29aa97dd1cSKonstantin Ananyev#include <tle_ctx.h>
30aa97dd1cSKonstantin Ananyev#include <tle_tcp.h>
31aa97dd1cSKonstantin Ananyev
32aa97dd1cSKonstantin Ananyev#include "test_common.h"
33aa97dd1cSKonstantin Ananyev
34aa97dd1cSKonstantin Ananyev#define MAX_STREAMS          0x100
35aa97dd1cSKonstantin Ananyev#define MAX_STREAM_RBUFS     0x100
36aa97dd1cSKonstantin Ananyev#define MAX_STREAM_SBUFS     0x100
37aa97dd1cSKonstantin Ananyev#define RX_NO_OFFLOAD        0x0
38aa97dd1cSKonstantin Ananyev#define TX_NO_OFFLOAD        0x0
39aa97dd1cSKonstantin Ananyev
40aa97dd1cSKonstantin Ananyevstatic struct tle_ctx_param ctx_prm_tmpl = {
41aa97dd1cSKonstantin Ananyev	.socket_id = SOCKET_ID_ANY,
42aa97dd1cSKonstantin Ananyev	.proto = TLE_PROTO_TCP,
43aa97dd1cSKonstantin Ananyev	.max_streams = MAX_STREAMS,
44b8f1ef2bSKonstantin Ananyev	. free_streams = {
45b8f1ef2bSKonstantin Ananyev		.min = 0,
46b8f1ef2bSKonstantin Ananyev		.max = 0,
47b8f1ef2bSKonstantin Ananyev	},
48aa97dd1cSKonstantin Ananyev	.max_stream_rbufs = MAX_STREAM_RBUFS,
49aa97dd1cSKonstantin Ananyev	.max_stream_sbufs = MAX_STREAM_SBUFS,
50aa97dd1cSKonstantin Ananyev};
51aa97dd1cSKonstantin Ananyev
52aa97dd1cSKonstantin Ananyevstatic struct tle_dev_param dev_prm_tmpl = {
53aa97dd1cSKonstantin Ananyev	.rx_offload = RX_NO_OFFLOAD,
54aa97dd1cSKonstantin Ananyev	.tx_offload = TX_NO_OFFLOAD
55aa97dd1cSKonstantin Ananyev};
56aa97dd1cSKonstantin Ananyev
57aa97dd1cSKonstantin Ananyevclass tcp_stream_base: public ::testing::Test {
58aa97dd1cSKonstantin Ananyev
59aa97dd1cSKonstantin Ananyevpublic:
60aa97dd1cSKonstantin Ananyev	struct tle_ctx *setup_ctx(struct tle_ctx_param *prm);
61aa97dd1cSKonstantin Ananyev	struct tle_dev *setup_dev(struct tle_ctx *ctx,
62aa97dd1cSKonstantin Ananyev				struct tle_dev_param *dev_prm);
63aa97dd1cSKonstantin Ananyev	void setup_dev_prm(struct tle_dev_param *dev_prm,
64aa97dd1cSKonstantin Ananyev			char const *ipv4, char const *ipv6);
65aa97dd1cSKonstantin Ananyev	int setup_stream_prm(struct tle_tcp_stream_param *stream_prm,
66aa97dd1cSKonstantin Ananyev			char const *l_ip, char const *r_ip,
67aa97dd1cSKonstantin Ananyev			int l_port, int r_port);
68aa97dd1cSKonstantin Ananyev	struct tle_evq *setup_event();
69aa97dd1cSKonstantin Ananyev};
70aa97dd1cSKonstantin Ananyev
71aa97dd1cSKonstantin Ananyevstruct tle_evq
72aa97dd1cSKonstantin Ananyev*tcp_stream_base::setup_event()
73aa97dd1cSKonstantin Ananyev{
74aa97dd1cSKonstantin Ananyev	int32_t socket_id;
75aa97dd1cSKonstantin Ananyev	uint32_t max_events;
76aa97dd1cSKonstantin Ananyev	struct tle_evq_param evq_params;
77aa97dd1cSKonstantin Ananyev	struct tle_evq *evq;
78aa97dd1cSKonstantin Ananyev
79aa97dd1cSKonstantin Ananyev	socket_id = SOCKET_ID_ANY;
80aa97dd1cSKonstantin Ananyev	max_events = 10;
81aa97dd1cSKonstantin Ananyev	rte_errno = 0;
82aa97dd1cSKonstantin Ananyev	memset(&evq_params, 0, sizeof(struct tle_evq_param));
83aa97dd1cSKonstantin Ananyev	evq_params.socket_id = socket_id;
84aa97dd1cSKonstantin Ananyev	evq_params.max_events = max_events;
85aa97dd1cSKonstantin Ananyev	evq = tle_evq_create(&evq_params);
86aa97dd1cSKonstantin Ananyev	return evq;
87aa97dd1cSKonstantin Ananyev}
88aa97dd1cSKonstantin Ananyev
89aa97dd1cSKonstantin Ananyevstruct tle_ctx
90aa97dd1cSKonstantin Ananyev*tcp_stream_base::setup_ctx(struct tle_ctx_param *prm)
91aa97dd1cSKonstantin Ananyev{
92aa97dd1cSKonstantin Ananyev	struct tle_ctx *ctx;
93aa97dd1cSKonstantin Ananyev
94aa97dd1cSKonstantin Ananyev	prm->lookup4 = dummy_lookup4;
95aa97dd1cSKonstantin Ananyev	prm->lookup6 = dummy_lookup6;
96aa97dd1cSKonstantin Ananyev
97aa97dd1cSKonstantin Ananyev	ctx = tle_ctx_create(prm);
98aa97dd1cSKonstantin Ananyev
99aa97dd1cSKonstantin Ananyev	return ctx;
100aa97dd1cSKonstantin Ananyev}
101aa97dd1cSKonstantin Ananyev
102aa97dd1cSKonstantin Ananyevstruct tle_dev
103aa97dd1cSKonstantin Ananyev*tcp_stream_base::setup_dev(struct tle_ctx *ctx, struct tle_dev_param *dev_prm)
104aa97dd1cSKonstantin Ananyev{
105aa97dd1cSKonstantin Ananyev	struct tle_dev *dev;
106aa97dd1cSKonstantin Ananyev
107aa97dd1cSKonstantin Ananyev	dev = tle_add_dev(ctx, dev_prm);
108aa97dd1cSKonstantin Ananyev
109aa97dd1cSKonstantin Ananyev	return dev;
110aa97dd1cSKonstantin Ananyev}
111aa97dd1cSKonstantin Ananyev
112aa97dd1cSKonstantin Ananyevvoid
113aa97dd1cSKonstantin Ananyevtcp_stream_base::setup_dev_prm(struct tle_dev_param *dev_prm, char const *ipv4,
114aa97dd1cSKonstantin Ananyev	char const *ipv6)
115aa97dd1cSKonstantin Ananyev{
116aa97dd1cSKonstantin Ananyev	inet_pton(AF_INET, ipv4, &dev_prm->local_addr4);
117aa97dd1cSKonstantin Ananyev	inet_pton(AF_INET6, ipv6, &dev_prm->local_addr6);
118aa97dd1cSKonstantin Ananyev}
119aa97dd1cSKonstantin Ananyev
120aa97dd1cSKonstantin Ananyevint
121aa97dd1cSKonstantin Ananyevtcp_stream_base::setup_stream_prm(struct tle_tcp_stream_param *stream_prm,
122aa97dd1cSKonstantin Ananyev	char const *l_ip, char const *r_ip, int l_port, int r_port)
123aa97dd1cSKonstantin Ananyev{
124aa97dd1cSKonstantin Ananyev	int32_t ret;
125aa97dd1cSKonstantin Ananyev	struct sockaddr_in *ip4_addr;
126aa97dd1cSKonstantin Ananyev	struct sockaddr_in6 *ip6_addr;
127aa97dd1cSKonstantin Ananyev	struct addrinfo hint, *res = NULL;
128aa97dd1cSKonstantin Ananyev	struct tle_tcp_stream_cfg stream_cfg;
129aa97dd1cSKonstantin Ananyev
130aa97dd1cSKonstantin Ananyev	memset(&hint, '\0', sizeof(hint));
131aa97dd1cSKonstantin Ananyev	memset(&stream_cfg, 0, sizeof(stream_cfg));
132aa97dd1cSKonstantin Ananyev
133aa97dd1cSKonstantin Ananyev	ret = getaddrinfo(l_ip, NULL, &hint, &res);
134aa97dd1cSKonstantin Ananyev	if (ret != 0)
135aa97dd1cSKonstantin Ananyev		return -EINVAL;
136aa97dd1cSKonstantin Ananyev
137aa97dd1cSKonstantin Ananyev	if (res->ai_family == AF_INET) {
138aa97dd1cSKonstantin Ananyev		ip4_addr = (struct sockaddr_in *) &stream_prm->addr.local;
139aa97dd1cSKonstantin Ananyev		ip4_addr->sin_family = AF_INET;
140aa97dd1cSKonstantin Ananyev		ip4_addr->sin_port = htons(l_port);
141aa97dd1cSKonstantin Ananyev		ip4_addr->sin_addr.s_addr = inet_addr(l_ip);
142aa97dd1cSKonstantin Ananyev	} else if (res->ai_family == AF_INET6) {
143aa97dd1cSKonstantin Ananyev		ip6_addr = (struct sockaddr_in6 *) &stream_prm->addr.local;
144aa97dd1cSKonstantin Ananyev		ip6_addr->sin6_family = AF_INET6;
145aa97dd1cSKonstantin Ananyev		inet_pton(AF_INET6, l_ip, &ip6_addr->sin6_addr);
146aa97dd1cSKonstantin Ananyev		ip6_addr->sin6_port = htons(l_port);
147aa97dd1cSKonstantin Ananyev	} else {
148aa97dd1cSKonstantin Ananyev		freeaddrinfo(res);
149aa97dd1cSKonstantin Ananyev		return -EINVAL;
150aa97dd1cSKonstantin Ananyev	}
151aa97dd1cSKonstantin Ananyev	freeaddrinfo(res);
152aa97dd1cSKonstantin Ananyev
153aa97dd1cSKonstantin Ananyev	memset(&hint, '\0', sizeof(hint));
154aa97dd1cSKonstantin Ananyev	ret = getaddrinfo(r_ip, NULL, &hint, &res);
155aa97dd1cSKonstantin Ananyev	if (ret != 0)
156aa97dd1cSKonstantin Ananyev		return -EINVAL;
157aa97dd1cSKonstantin Ananyev
158aa97dd1cSKonstantin Ananyev	if (res->ai_family == AF_INET) {
159aa97dd1cSKonstantin Ananyev		ip4_addr = (struct sockaddr_in *) &stream_prm->addr.remote;
160aa97dd1cSKonstantin Ananyev		ip4_addr->sin_family = AF_INET;
161aa97dd1cSKonstantin Ananyev		ip4_addr->sin_port = htons(r_port);
162aa97dd1cSKonstantin Ananyev		ip4_addr->sin_addr.s_addr = inet_addr(r_ip);
163aa97dd1cSKonstantin Ananyev	} else if (res->ai_family == AF_INET6) {
164aa97dd1cSKonstantin Ananyev		ip6_addr = (struct sockaddr_in6 *) &stream_prm->addr.remote;
165aa97dd1cSKonstantin Ananyev		ip6_addr->sin6_family = AF_INET6;
166aa97dd1cSKonstantin Ananyev		inet_pton(AF_INET6, r_ip, &ip6_addr->sin6_addr);
167aa97dd1cSKonstantin Ananyev		ip6_addr->sin6_port = htons(r_port);
168aa97dd1cSKonstantin Ananyev	} else {
169aa97dd1cSKonstantin Ananyev		freeaddrinfo(res);
170aa97dd1cSKonstantin Ananyev		return -EINVAL;
171aa97dd1cSKonstantin Ananyev	}
172aa97dd1cSKonstantin Ananyev	freeaddrinfo(res);
173aa97dd1cSKonstantin Ananyev
174aa97dd1cSKonstantin Ananyev	stream_prm->cfg = stream_cfg;
175aa97dd1cSKonstantin Ananyev
176aa97dd1cSKonstantin Ananyev	return 0;
177aa97dd1cSKonstantin Ananyev}
178aa97dd1cSKonstantin Ananyev
179aa97dd1cSKonstantin Ananyevclass test_tle_tcp_stream: public ::tcp_stream_base {
180aa97dd1cSKonstantin Ananyevprotected:
181aa97dd1cSKonstantin Ananyev	virtual void SetUp(void)
182aa97dd1cSKonstantin Ananyev	{
183aa97dd1cSKonstantin Ananyev		ipv4_laddr = "192.0.0.1";
184aa97dd1cSKonstantin Ananyev		ipv4_raddr = "192.0.0.2";
185aa97dd1cSKonstantin Ananyev		ipv6_laddr = "2001::1000";
186aa97dd1cSKonstantin Ananyev		ipv6_raddr = "2001::2000";
187aa97dd1cSKonstantin Ananyev		l_port = 10000;
188aa97dd1cSKonstantin Ananyev		r_port = 10000;
189aa97dd1cSKonstantin Ananyev
190aa97dd1cSKonstantin Ananyev		memset(&ctx_prm, 0, sizeof(ctx_prm));
191aa97dd1cSKonstantin Ananyev		memset(&dev_prm, 0, sizeof(dev_prm));
192aa97dd1cSKonstantin Ananyev		memset(&stream_prm, 0, sizeof(stream_prm));
193aa97dd1cSKonstantin Ananyev		memset(&stream_prm6, 0, sizeof(stream_prm6));
194aa97dd1cSKonstantin Ananyev
195aa97dd1cSKonstantin Ananyev		ctx_prm = ctx_prm_tmpl;
196aa97dd1cSKonstantin Ananyev		dev_prm = dev_prm_tmpl;
197aa97dd1cSKonstantin Ananyev		setup_dev_prm(&dev_prm, ipv4_laddr, ipv6_laddr);
198aa97dd1cSKonstantin Ananyev		ret = setup_stream_prm(&stream_prm, ipv4_laddr, ipv4_raddr,
199aa97dd1cSKonstantin Ananyev			l_port, r_port);
200aa97dd1cSKonstantin Ananyev		ASSERT_EQ(ret, 0);
201aa97dd1cSKonstantin Ananyev		setup_stream_prm(&stream_prm6, ipv6_laddr, ipv6_raddr, l_port,
202aa97dd1cSKonstantin Ananyev			r_port);
203aa97dd1cSKonstantin Ananyev		ASSERT_EQ(ret, 0);
204aa97dd1cSKonstantin Ananyev
205aa97dd1cSKonstantin Ananyev		ctx = setup_ctx(&ctx_prm);
206aa97dd1cSKonstantin Ananyev		ASSERT_NE(ctx, (void *) NULL);
207aa97dd1cSKonstantin Ananyev		dev = setup_dev(ctx, &dev_prm);
208aa97dd1cSKonstantin Ananyev		ASSERT_NE(dev, (void *) NULL);
209aa97dd1cSKonstantin Ananyev	}
210aa97dd1cSKonstantin Ananyev
211aa97dd1cSKonstantin Ananyev	virtual void TearDown(void)
212aa97dd1cSKonstantin Ananyev	{
213aa97dd1cSKonstantin Ananyev		ret = 0;
214aa97dd1cSKonstantin Ananyev		tle_del_dev(dev);
215aa97dd1cSKonstantin Ananyev		tle_ctx_destroy(ctx);
216aa97dd1cSKonstantin Ananyev	}
217aa97dd1cSKonstantin Ananyev
218aa97dd1cSKonstantin Ananyev	int ret;
219aa97dd1cSKonstantin Ananyev	struct tle_ctx *ctx;
220aa97dd1cSKonstantin Ananyev	struct tle_dev *dev;
221aa97dd1cSKonstantin Ananyev	struct tle_stream *stream;
222aa97dd1cSKonstantin Ananyev	struct tle_stream *stream6;
223aa97dd1cSKonstantin Ananyev
224aa97dd1cSKonstantin Ananyev	struct tle_ctx_param ctx_prm;
225aa97dd1cSKonstantin Ananyev	struct tle_dev_param dev_prm;
226aa97dd1cSKonstantin Ananyev	struct tle_tcp_stream_param stream_prm;
227aa97dd1cSKonstantin Ananyev	struct tle_tcp_stream_param stream_prm6;
228aa97dd1cSKonstantin Ananyev
229aa97dd1cSKonstantin Ananyev	int l_port, r_port;
230aa97dd1cSKonstantin Ananyev	char const *ipv4_laddr;
231aa97dd1cSKonstantin Ananyev	char const *ipv4_raddr;
232aa97dd1cSKonstantin Ananyev	char const *ipv6_laddr;
233aa97dd1cSKonstantin Ananyev	char const *ipv6_raddr;
234aa97dd1cSKonstantin Ananyev};
235aa97dd1cSKonstantin Ananyev
236aa97dd1cSKonstantin Ananyevclass test_tle_tcp_stream_ops: public ::test_tle_tcp_stream {
237aa97dd1cSKonstantin Ananyevpublic:
238aa97dd1cSKonstantin Ananyev	virtual void SetUp(void)
239aa97dd1cSKonstantin Ananyev	{
240aa97dd1cSKonstantin Ananyev		test_tle_tcp_stream::SetUp();
241aa97dd1cSKonstantin Ananyev		stream = tle_tcp_stream_open(ctx,
242aa97dd1cSKonstantin Ananyev			(const struct tle_tcp_stream_param *)&stream_prm);
243aa97dd1cSKonstantin Ananyev		stream6 = tle_tcp_stream_open(ctx,
244aa97dd1cSKonstantin Ananyev			(const struct tle_tcp_stream_param *)&stream_prm6);
245aa97dd1cSKonstantin Ananyev	}
246aa97dd1cSKonstantin Ananyev
247aa97dd1cSKonstantin Ananyev	virtual void TearDown(void)
248aa97dd1cSKonstantin Ananyev	{
249aa97dd1cSKonstantin Ananyev		tle_tcp_stream_close(stream6);
250aa97dd1cSKonstantin Ananyev		tle_tcp_stream_close(stream);
251aa97dd1cSKonstantin Ananyev		test_tle_tcp_stream::TearDown();
252aa97dd1cSKonstantin Ananyev	}
253aa97dd1cSKonstantin Ananyev};
254aa97dd1cSKonstantin Ananyev
255aa97dd1cSKonstantin Ananyev#endif /* TEST_TLE_TCP_STREAM_H_ */
256