]>
Commit | Line | Data |
---|---|---|
9fd3c5d5 ZC |
1 | /* |
2 | * QTest testcase for filter-redirector | |
3 | * | |
4 | * Copyright (c) 2016 FUJITSU LIMITED | |
5 | * Author: Zhang Chen <zhangchen.fnst@cn.fujitsu.com> | |
6 | * | |
7 | * This work is licensed under the terms of the GNU GPL, version 2 or | |
8 | * later. See the COPYING file in the top-level directory. | |
9 | * | |
10 | * Case 1, tx traffic flow: | |
11 | * | |
12 | * qemu side | test side | |
13 | * | | |
14 | * +---------+ | +-------+ | |
15 | * | backend <---------------+ sock0 | | |
16 | * +----+----+ | +-------+ | |
17 | * | | | |
18 | * +----v----+ +-------+ | | |
19 | * | rd0 +->+chardev| | | |
20 | * +---------+ +---+---+ | | |
21 | * | | | |
22 | * +---------+ | | | |
23 | * | rd1 <------+ | | |
24 | * +----+----+ | | |
25 | * | | | |
26 | * +----v----+ | +-------+ | |
27 | * | rd2 +--------------->sock1 | | |
28 | * +---------+ | +-------+ | |
29 | * + | |
30 | * | |
31 | * -------------------------------------- | |
32 | * Case 2, rx traffic flow | |
33 | * qemu side | test side | |
34 | * | | |
35 | * +---------+ | +-------+ | |
36 | * | backend +---------------> sock1 | | |
37 | * +----^----+ | +-------+ | |
38 | * | | | |
39 | * +----+----+ +-------+ | | |
40 | * | rd0 +<-+chardev| | | |
41 | * +---------+ +---+---+ | | |
42 | * ^ | | |
43 | * +---------+ | | | |
44 | * | rd1 +------+ | | |
45 | * +----^----+ | | |
46 | * | | | |
47 | * +----+----+ | +-------+ | |
48 | * | rd2 <---------------+sock0 | | |
49 | * +---------+ | +-------+ | |
50 | * + | |
51 | */ | |
52 | ||
53 | #include "qemu/osdep.h" | |
a8d25326 | 54 | #include "qemu-common.h" |
9fd3c5d5 | 55 | #include "libqtest.h" |
055a1efc | 56 | #include "qapi/qmp/qdict.h" |
9fd3c5d5 ZC |
57 | #include "qemu/iov.h" |
58 | #include "qemu/sockets.h" | |
59 | #include "qemu/error-report.h" | |
60 | #include "qemu/main-loop.h" | |
61 | ||
055a1efc | 62 | /* TODO actually test the results and get rid of this */ |
a2569b00 | 63 | #define qmp_discard_response(qs, ...) qobject_unref(qtest_qmp(qs, __VA_ARGS__)) |
055a1efc | 64 | |
ea5bef49 TH |
65 | static const char *get_devstr(void) |
66 | { | |
67 | if (g_str_equal(qtest_get_arch(), "s390x")) { | |
68 | return "virtio-net-ccw"; | |
69 | } | |
70 | ||
71 | return "rtl8139"; | |
72 | } | |
73 | ||
74 | ||
9fd3c5d5 ZC |
75 | static void test_redirector_tx(void) |
76 | { | |
9fd3c5d5 | 77 | int backend_sock[2], recv_sock; |
9fd3c5d5 ZC |
78 | uint32_t ret = 0, len = 0; |
79 | char send_buf[] = "Hello!!"; | |
80 | char sock_path0[] = "filter-redirector0.XXXXXX"; | |
81 | char sock_path1[] = "filter-redirector1.XXXXXX"; | |
82 | char *recv_buf; | |
83 | uint32_t size = sizeof(send_buf); | |
84 | size = htonl(size); | |
a2569b00 | 85 | QTestState *qts; |
9fd3c5d5 ZC |
86 | |
87 | ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock); | |
88 | g_assert_cmpint(ret, !=, -1); | |
89 | ||
90 | ret = mkstemp(sock_path0); | |
91 | g_assert_cmpint(ret, !=, -1); | |
92 | ret = mkstemp(sock_path1); | |
93 | g_assert_cmpint(ret, !=, -1); | |
94 | ||
a2569b00 | 95 | qts = qtest_initf( |
78b27bad EB |
96 | "-netdev socket,id=qtest-bn0,fd=%d " |
97 | "-device %s,netdev=qtest-bn0,id=qtest-e0 " | |
98 | "-chardev socket,id=redirector0,path=%s,server,nowait " | |
99 | "-chardev socket,id=redirector1,path=%s,server,nowait " | |
767abe7f | 100 | "-chardev socket,id=redirector2,path=%s " |
78b27bad EB |
101 | "-object filter-redirector,id=qtest-f0,netdev=qtest-bn0," |
102 | "queue=tx,outdev=redirector0 " | |
103 | "-object filter-redirector,id=qtest-f1,netdev=qtest-bn0," | |
104 | "queue=tx,indev=redirector2 " | |
105 | "-object filter-redirector,id=qtest-f2,netdev=qtest-bn0," | |
106 | "queue=tx,outdev=redirector1 ", backend_sock[1], get_devstr(), | |
107 | sock_path0, sock_path1, sock_path0); | |
9fd3c5d5 ZC |
108 | |
109 | recv_sock = unix_connect(sock_path1, NULL); | |
110 | g_assert_cmpint(recv_sock, !=, -1); | |
111 | ||
112 | /* send a qmp command to guarantee that 'connected' is setting to true. */ | |
a2569b00 | 113 | qmp_discard_response(qts, "{ 'execute' : 'query-status'}"); |
9fd3c5d5 ZC |
114 | |
115 | struct iovec iov[] = { | |
116 | { | |
117 | .iov_base = &size, | |
118 | .iov_len = sizeof(size), | |
119 | }, { | |
120 | .iov_base = send_buf, | |
121 | .iov_len = sizeof(send_buf), | |
122 | }, | |
123 | }; | |
124 | ||
125 | ret = iov_send(backend_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf)); | |
126 | g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size)); | |
127 | close(backend_sock[0]); | |
128 | ||
129 | ret = qemu_recv(recv_sock, &len, sizeof(len), 0); | |
130 | g_assert_cmpint(ret, ==, sizeof(len)); | |
131 | len = ntohl(len); | |
132 | ||
133 | g_assert_cmpint(len, ==, sizeof(send_buf)); | |
134 | recv_buf = g_malloc(len); | |
135 | ret = qemu_recv(recv_sock, recv_buf, len, 0); | |
136 | g_assert_cmpstr(recv_buf, ==, send_buf); | |
137 | ||
138 | g_free(recv_buf); | |
139 | close(recv_sock); | |
140 | unlink(sock_path0); | |
141 | unlink(sock_path1); | |
a2569b00 | 142 | qtest_quit(qts); |
9fd3c5d5 ZC |
143 | } |
144 | ||
145 | static void test_redirector_rx(void) | |
146 | { | |
9fd3c5d5 | 147 | int backend_sock[2], send_sock; |
9fd3c5d5 ZC |
148 | uint32_t ret = 0, len = 0; |
149 | char send_buf[] = "Hello!!"; | |
150 | char sock_path0[] = "filter-redirector0.XXXXXX"; | |
151 | char sock_path1[] = "filter-redirector1.XXXXXX"; | |
152 | char *recv_buf; | |
153 | uint32_t size = sizeof(send_buf); | |
154 | size = htonl(size); | |
a2569b00 | 155 | QTestState *qts; |
9fd3c5d5 ZC |
156 | |
157 | ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock); | |
158 | g_assert_cmpint(ret, !=, -1); | |
159 | ||
160 | ret = mkstemp(sock_path0); | |
161 | g_assert_cmpint(ret, !=, -1); | |
162 | ret = mkstemp(sock_path1); | |
163 | g_assert_cmpint(ret, !=, -1); | |
164 | ||
a2569b00 | 165 | qts = qtest_initf( |
78b27bad EB |
166 | "-netdev socket,id=qtest-bn0,fd=%d " |
167 | "-device %s,netdev=qtest-bn0,id=qtest-e0 " | |
168 | "-chardev socket,id=redirector0,path=%s,server,nowait " | |
169 | "-chardev socket,id=redirector1,path=%s,server,nowait " | |
767abe7f | 170 | "-chardev socket,id=redirector2,path=%s " |
78b27bad EB |
171 | "-object filter-redirector,id=qtest-f0,netdev=qtest-bn0," |
172 | "queue=rx,indev=redirector0 " | |
173 | "-object filter-redirector,id=qtest-f1,netdev=qtest-bn0," | |
174 | "queue=rx,outdev=redirector2 " | |
175 | "-object filter-redirector,id=qtest-f2,netdev=qtest-bn0," | |
176 | "queue=rx,indev=redirector1 ", backend_sock[1], get_devstr(), | |
177 | sock_path0, sock_path1, sock_path0); | |
9fd3c5d5 ZC |
178 | |
179 | struct iovec iov[] = { | |
180 | { | |
181 | .iov_base = &size, | |
182 | .iov_len = sizeof(size), | |
183 | }, { | |
184 | .iov_base = send_buf, | |
185 | .iov_len = sizeof(send_buf), | |
186 | }, | |
187 | }; | |
188 | ||
189 | send_sock = unix_connect(sock_path1, NULL); | |
190 | g_assert_cmpint(send_sock, !=, -1); | |
191 | /* send a qmp command to guarantee that 'connected' is setting to true. */ | |
a2569b00 | 192 | qmp_discard_response(qts, "{ 'execute' : 'query-status'}"); |
9fd3c5d5 ZC |
193 | |
194 | ret = iov_send(send_sock, iov, 2, 0, sizeof(size) + sizeof(send_buf)); | |
195 | g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size)); | |
9fd3c5d5 ZC |
196 | |
197 | ret = qemu_recv(backend_sock[0], &len, sizeof(len), 0); | |
198 | g_assert_cmpint(ret, ==, sizeof(len)); | |
199 | len = ntohl(len); | |
200 | ||
201 | g_assert_cmpint(len, ==, sizeof(send_buf)); | |
202 | recv_buf = g_malloc(len); | |
203 | ret = qemu_recv(backend_sock[0], recv_buf, len, 0); | |
204 | g_assert_cmpstr(recv_buf, ==, send_buf); | |
205 | ||
8f6d7010 | 206 | close(send_sock); |
9fd3c5d5 ZC |
207 | g_free(recv_buf); |
208 | unlink(sock_path0); | |
209 | unlink(sock_path1); | |
a2569b00 | 210 | qtest_quit(qts); |
9fd3c5d5 ZC |
211 | } |
212 | ||
213 | int main(int argc, char **argv) | |
214 | { | |
9fd3c5d5 ZC |
215 | g_test_init(&argc, &argv, NULL); |
216 | qtest_add_func("/netfilter/redirector_tx", test_redirector_tx); | |
217 | qtest_add_func("/netfilter/redirector_rx", test_redirector_rx); | |
9be38598 | 218 | return g_test_run(); |
9fd3c5d5 | 219 | } |