xref: /linux/tools/testing/selftests/net/bind_wildcard.c (revision 5e9e9afdb50449f35d3e65dd6b1cdf87e8ce185e)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright Amazon.com Inc. or its affiliates. */
3 
4 #include <sys/socket.h>
5 #include <netinet/in.h>
6 
7 #include "../kselftest_harness.h"
8 
9 static const __u32 in4addr_any = INADDR_ANY;
10 static const __u32 in4addr_loopback = INADDR_LOOPBACK;
11 static const struct in6_addr in6addr_v4mapped_any = {
12 	.s6_addr = {
13 		0, 0, 0, 0,
14 		0, 0, 0, 0,
15 		0, 0, 255, 255,
16 		0, 0, 0, 0
17 	}
18 };
19 static const struct in6_addr in6addr_v4mapped_loopback = {
20 	.s6_addr = {
21 		0, 0, 0, 0,
22 		0, 0, 0, 0,
23 		0, 0, 255, 255,
24 		127, 0, 0, 1
25 	}
26 };
27 
28 FIXTURE(bind_wildcard)
29 {
30 	socklen_t addrlen[2];
31 	union {
32 		struct sockaddr addr;
33 		struct sockaddr_in addr4;
34 		struct sockaddr_in6 addr6;
35 	} addr[2];
36 };
37 
38 FIXTURE_VARIANT(bind_wildcard)
39 {
40 	sa_family_t family[2];
41 	const void *addr[2];
42 	int expected_errno;
43 };
44 
45 /* (IPv4, IPv4) */
46 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v4_local)
47 {
48 	.family = {AF_INET, AF_INET},
49 	.addr = {&in4addr_any, &in4addr_loopback},
50 	.expected_errno = EADDRINUSE,
51 };
52 
53 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v4_any)
54 {
55 	.family = {AF_INET, AF_INET},
56 	.addr = {&in4addr_loopback, &in4addr_any},
57 	.expected_errno = EADDRINUSE,
58 };
59 
60 /* (IPv4, IPv6) */
61 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_any)
62 {
63 	.family = {AF_INET, AF_INET6},
64 	.addr = {&in4addr_any, &in6addr_any},
65 	.expected_errno = EADDRINUSE,
66 };
67 
68 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_local)
69 {
70 	.family = {AF_INET, AF_INET6},
71 	.addr = {&in4addr_any, &in6addr_loopback},
72 	.expected_errno = 0,
73 };
74 
75 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_v4mapped_any)
76 {
77 	.family = {AF_INET, AF_INET6},
78 	.addr = {&in4addr_any, &in6addr_v4mapped_any},
79 	.expected_errno = EADDRINUSE,
80 };
81 
82 FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_v4mapped_local)
83 {
84 	.family = {AF_INET, AF_INET6},
85 	.addr = {&in4addr_any, &in6addr_v4mapped_loopback},
86 	.expected_errno = EADDRINUSE,
87 };
88 
89 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_any)
90 {
91 	.family = {AF_INET, AF_INET6},
92 	.addr = {&in4addr_loopback, &in6addr_any},
93 	.expected_errno = EADDRINUSE,
94 };
95 
96 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_local)
97 {
98 	.family = {AF_INET, AF_INET6},
99 	.addr = {&in4addr_loopback, &in6addr_loopback},
100 	.expected_errno = 0,
101 };
102 
103 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_v4mapped_any)
104 {
105 	.family = {AF_INET, AF_INET6},
106 	.addr = {&in4addr_loopback, &in6addr_v4mapped_any},
107 	.expected_errno = EADDRINUSE,
108 };
109 
110 FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_v4mapped_local)
111 {
112 	.family = {AF_INET, AF_INET6},
113 	.addr = {&in4addr_loopback, &in6addr_v4mapped_loopback},
114 	.expected_errno = EADDRINUSE,
115 };
116 
117 /* (IPv6, IPv4) */
118 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v4_any)
119 {
120 	.family = {AF_INET6, AF_INET},
121 	.addr = {&in6addr_any, &in4addr_any},
122 	.expected_errno = EADDRINUSE,
123 };
124 
125 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v4_local)
126 {
127 	.family = {AF_INET6, AF_INET},
128 	.addr = {&in6addr_any, &in4addr_loopback},
129 	.expected_errno = EADDRINUSE,
130 };
131 
132 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v4_any)
133 {
134 	.family = {AF_INET6, AF_INET},
135 	.addr = {&in6addr_loopback, &in4addr_any},
136 	.expected_errno = 0,
137 };
138 
139 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v4_local)
140 {
141 	.family = {AF_INET6, AF_INET},
142 	.addr = {&in6addr_loopback, &in4addr_loopback},
143 	.expected_errno = 0,
144 };
145 
146 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v4_any)
147 {
148 	.family = {AF_INET6, AF_INET},
149 	.addr = {&in6addr_v4mapped_any, &in4addr_any},
150 	.expected_errno = EADDRINUSE,
151 };
152 
153 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v4_local)
154 {
155 	.family = {AF_INET6, AF_INET},
156 	.addr = {&in6addr_v4mapped_any, &in4addr_loopback},
157 	.expected_errno = EADDRINUSE,
158 };
159 
160 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_local_v4_any)
161 {
162 	.family = {AF_INET6, AF_INET},
163 	.addr = {&in6addr_v4mapped_loopback, &in4addr_any},
164 	.expected_errno = EADDRINUSE,
165 };
166 
167 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_local_v4_local)
168 {
169 	.family = {AF_INET6, AF_INET},
170 	.addr = {&in6addr_v4mapped_loopback, &in4addr_loopback},
171 	.expected_errno = EADDRINUSE,
172 };
173 
174 /* (IPv6, IPv6) */
175 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v6_local)
176 {
177 	.family = {AF_INET6, AF_INET6},
178 	.addr = {&in6addr_any, &in6addr_loopback},
179 	.expected_errno = EADDRINUSE,
180 };
181 
182 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v6_v4mapped_any)
183 {
184 	.family = {AF_INET6, AF_INET6},
185 	.addr = {&in6addr_any, &in6addr_v4mapped_any},
186 	.expected_errno = EADDRINUSE,
187 };
188 
189 FIXTURE_VARIANT_ADD(bind_wildcard, v6_any_v6_v4mapped_local)
190 {
191 	.family = {AF_INET6, AF_INET6},
192 	.addr = {&in6addr_any, &in6addr_v4mapped_loopback},
193 	.expected_errno = EADDRINUSE,
194 };
195 
196 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v6_any)
197 {
198 	.family = {AF_INET6, AF_INET6},
199 	.addr = {&in6addr_loopback, &in6addr_any},
200 	.expected_errno = EADDRINUSE,
201 };
202 
203 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v6_v4mapped_any)
204 {
205 	.family = {AF_INET6, AF_INET6},
206 	.addr = {&in6addr_loopback, &in6addr_v4mapped_any},
207 	.expected_errno = 0,
208 };
209 
210 FIXTURE_VARIANT_ADD(bind_wildcard, v6_local_v6_v4mapped_local)
211 {
212 	.family = {AF_INET6, AF_INET6},
213 	.addr = {&in6addr_loopback, &in6addr_v4mapped_loopback},
214 	.expected_errno = 0,
215 };
216 
217 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v6_any)
218 {
219 	.family = {AF_INET6, AF_INET6},
220 	.addr = {&in6addr_v4mapped_any, &in6addr_any},
221 	.expected_errno = EADDRINUSE,
222 };
223 
224 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v6_local)
225 {
226 	.family = {AF_INET6, AF_INET6},
227 	.addr = {&in6addr_v4mapped_any, &in6addr_loopback},
228 	.expected_errno = 0,
229 };
230 
231 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_any_v6_v4mapped_local)
232 {
233 	.family = {AF_INET6, AF_INET6},
234 	.addr = {&in6addr_v4mapped_any, &in6addr_v4mapped_loopback},
235 	.expected_errno = EADDRINUSE,
236 };
237 
238 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_loopback_v6_any)
239 {
240 	.family = {AF_INET6, AF_INET6},
241 	.addr = {&in6addr_v4mapped_loopback, &in6addr_any},
242 	.expected_errno = EADDRINUSE,
243 };
244 
245 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_loopback_v6_local)
246 {
247 	.family = {AF_INET6, AF_INET6},
248 	.addr = {&in6addr_v4mapped_loopback, &in6addr_loopback},
249 	.expected_errno = 0,
250 };
251 
252 FIXTURE_VARIANT_ADD(bind_wildcard, v6_v4mapped_loopback_v6_v4mapped_any)
253 {
254 	.family = {AF_INET6, AF_INET6},
255 	.addr = {&in6addr_v4mapped_loopback, &in6addr_v4mapped_any},
256 	.expected_errno = EADDRINUSE,
257 };
258 
259 static void setup_addr(FIXTURE_DATA(bind_wildcard) *self, int i,
260 		       int family, const void *addr_const)
261 {
262 	if (family == AF_INET) {
263 		struct sockaddr_in *addr4 = &self->addr[i].addr4;
264 		const __u32 *addr4_const = addr_const;
265 
266 		addr4->sin_family = AF_INET;
267 		addr4->sin_port = htons(0);
268 		addr4->sin_addr.s_addr = htonl(*addr4_const);
269 
270 		self->addrlen[i] = sizeof(struct sockaddr_in);
271 	} else {
272 		struct sockaddr_in6 *addr6 = &self->addr[i].addr6;
273 		const struct in6_addr *addr6_const = addr_const;
274 
275 		addr6->sin6_family = AF_INET6;
276 		addr6->sin6_port = htons(0);
277 		addr6->sin6_addr = *addr6_const;
278 
279 		self->addrlen[i] = sizeof(struct sockaddr_in6);
280 	}
281 }
282 
283 FIXTURE_SETUP(bind_wildcard)
284 {
285 	setup_addr(self, 0, variant->family[0], variant->addr[0]);
286 	setup_addr(self, 1, variant->family[1], variant->addr[1]);
287 }
288 
289 FIXTURE_TEARDOWN(bind_wildcard)
290 {
291 }
292 
293 void bind_sockets(struct __test_metadata *_metadata,
294 		  FIXTURE_DATA(bind_wildcard) *self,
295 		  int expected_errno,
296 		  struct sockaddr *addr1, socklen_t addrlen1,
297 		  struct sockaddr *addr2, socklen_t addrlen2)
298 {
299 	int fd[2];
300 	int ret;
301 
302 	fd[0] = socket(addr1->sa_family, SOCK_STREAM, 0);
303 	ASSERT_GT(fd[0], 0);
304 
305 	ret = bind(fd[0], addr1, addrlen1);
306 	ASSERT_EQ(ret, 0);
307 
308 	ret = getsockname(fd[0], addr1, &addrlen1);
309 	ASSERT_EQ(ret, 0);
310 
311 	((struct sockaddr_in *)addr2)->sin_port = ((struct sockaddr_in *)addr1)->sin_port;
312 
313 	fd[1] = socket(addr2->sa_family, SOCK_STREAM, 0);
314 	ASSERT_GT(fd[1], 0);
315 
316 	ret = bind(fd[1], addr2, addrlen2);
317 	if (expected_errno) {
318 		ASSERT_EQ(ret, -1);
319 		ASSERT_EQ(errno, expected_errno);
320 	} else {
321 		ASSERT_EQ(ret, 0);
322 	}
323 
324 	close(fd[1]);
325 	close(fd[0]);
326 }
327 
328 TEST_F(bind_wildcard, plain)
329 {
330 	bind_sockets(_metadata, self, variant->expected_errno,
331 		     &self->addr[0].addr, self->addrlen[0],
332 		     &self->addr[1].addr, self->addrlen[1]);
333 }
334 
335 TEST_HARNESS_MAIN
336