]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/test_ipaddr.cc
update sources to 12.2.2
[ceph.git] / ceph / src / test / test_ipaddr.cc
1 #include "include/ipaddr.h"
2 #include "common/pick_address.h"
3 #include "global/global_context.h"
4 #include "gtest/gtest.h"
5
6 #if defined(__FreeBSD__)
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <netinet/in.h>
10 #endif
11 #include <arpa/inet.h>
12 #include <ifaddrs.h>
13
14 static void ipv4(struct sockaddr_in *addr, const char *s) {
15 int err;
16
17 addr->sin_family = AF_INET;
18 err = inet_pton(AF_INET, s, &addr->sin_addr);
19 ASSERT_EQ(1, err);
20 }
21
22 static void ipv6(struct sockaddr_in6 *addr, const char *s) {
23 int err;
24
25 addr->sin6_family = AF_INET6;
26 err = inet_pton(AF_INET6, s, &addr->sin6_addr);
27 ASSERT_EQ(1, err);
28 }
29
30 static char eth0[] = "eth0";
31 static char eth1[] = "eth1";
32
33 TEST(CommonIPAddr, TestNotFound)
34 {
35 struct ifaddrs one, two;
36 struct sockaddr_in a_one;
37 struct sockaddr_in6 a_two;
38 struct sockaddr_in net;
39 const struct ifaddrs *result;
40
41 memset(&net, '0', sizeof(net));
42
43 one.ifa_next = &two;
44 one.ifa_addr = (struct sockaddr*)&a_one;
45 one.ifa_name = eth0;
46
47 two.ifa_next = NULL;
48 two.ifa_addr = (struct sockaddr*)&a_two;
49 two.ifa_name = eth1;
50
51 ipv4(&a_one, "10.11.12.13");
52 ipv6(&a_two, "2001:1234:5678:90ab::cdef");
53 ipv4(&net, "10.11.234.56");
54
55 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 24);
56 ASSERT_EQ(0, result);
57 }
58
59 TEST(CommonIPAddr, TestV4_Simple)
60 {
61 struct ifaddrs one, two;
62 struct sockaddr_in a_one;
63 struct sockaddr_in6 a_two;
64 struct sockaddr_in net;
65 const struct ifaddrs *result;
66
67 memset(&net, '0', sizeof(net));
68
69 one.ifa_next = &two;
70 one.ifa_addr = (struct sockaddr*)&a_one;
71 one.ifa_name = eth0;
72
73 two.ifa_next = NULL;
74 two.ifa_addr = (struct sockaddr*)&a_two;
75 two.ifa_name = eth1;
76
77 ipv4(&a_one, "10.11.12.13");
78 ipv6(&a_two, "2001:1234:5678:90ab::cdef");
79 ipv4(&net, "10.11.12.42");
80
81 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 24);
82 ASSERT_EQ((struct sockaddr*)&a_one, result->ifa_addr);
83 }
84
85 TEST(CommonIPAddr, TestV4_Prefix25)
86 {
87 struct ifaddrs one, two;
88 struct sockaddr_in a_one;
89 struct sockaddr_in a_two;
90 struct sockaddr_in net;
91 const struct ifaddrs *result;
92
93 memset(&net, '0', sizeof(net));
94
95 one.ifa_next = &two;
96 one.ifa_addr = (struct sockaddr*)&a_one;
97 one.ifa_name = eth0;
98
99 two.ifa_next = NULL;
100 two.ifa_addr = (struct sockaddr*)&a_two;
101 two.ifa_name = eth1;
102
103 ipv4(&a_one, "10.11.12.13");
104 ipv4(&a_two, "10.11.12.129");
105 ipv4(&net, "10.11.12.128");
106
107 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 25);
108 ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr);
109 }
110
111 TEST(CommonIPAddr, TestV4_Prefix16)
112 {
113 struct ifaddrs one, two;
114 struct sockaddr_in a_one;
115 struct sockaddr_in a_two;
116 struct sockaddr_in net;
117 const struct ifaddrs *result;
118
119 memset(&net, '0', sizeof(net));
120
121 one.ifa_next = &two;
122 one.ifa_addr = (struct sockaddr*)&a_one;
123 one.ifa_name = eth0;
124
125 two.ifa_next = NULL;
126 two.ifa_addr = (struct sockaddr*)&a_two;
127 two.ifa_name = eth1;
128
129 ipv4(&a_one, "10.1.1.2");
130 ipv4(&a_two, "10.2.1.123");
131 ipv4(&net, "10.2.0.0");
132
133 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 16);
134 ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr);
135 }
136
137 TEST(CommonIPAddr, TestV4_PrefixTooLong)
138 {
139 struct ifaddrs one;
140 struct sockaddr_in a_one;
141 struct sockaddr_in net;
142 const struct ifaddrs *result;
143
144 memset(&net, '0', sizeof(net));
145
146 one.ifa_next = NULL;
147 one.ifa_addr = (struct sockaddr*)&a_one;
148 one.ifa_name = eth0;
149
150 ipv4(&a_one, "10.11.12.13");
151 ipv4(&net, "10.11.12.12");
152
153 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 42);
154 ASSERT_EQ(0, result);
155 }
156
157 TEST(CommonIPAddr, TestV4_PrefixZero)
158 {
159 struct ifaddrs one, two;
160 struct sockaddr_in6 a_one;
161 struct sockaddr_in a_two;
162 struct sockaddr_in net;
163 const struct ifaddrs *result;
164
165 memset(&net, '0', sizeof(net));
166
167 one.ifa_next = &two;
168 one.ifa_addr = (struct sockaddr*)&a_one;
169 one.ifa_name = eth0;
170
171 two.ifa_next = NULL;
172 two.ifa_addr = (struct sockaddr*)&a_two;
173 two.ifa_name = eth1;
174
175 ipv6(&a_one, "2001:1234:5678:900F::cdef");
176 ipv4(&a_two, "10.1.2.3");
177 ipv4(&net, "255.0.1.2");
178
179 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 0);
180 ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr);
181 }
182
183 TEST(CommonIPAddr, TestV6_Simple)
184 {
185 struct ifaddrs one, two;
186 struct sockaddr_in a_one;
187 struct sockaddr_in6 a_two;
188 struct sockaddr_in6 net;
189 const struct ifaddrs *result;
190
191 memset(&net, '0', sizeof(net));
192
193 one.ifa_next = &two;
194 one.ifa_addr = (struct sockaddr*)&a_one;
195 one.ifa_name = eth0;
196
197 two.ifa_next = NULL;
198 two.ifa_addr = (struct sockaddr*)&a_two;
199 two.ifa_name = eth1;
200
201 ipv4(&a_one, "10.11.12.13");
202 ipv6(&a_two, "2001:1234:5678:90ab::cdef");
203 ipv6(&net, "2001:1234:5678:90ab::dead:beef");
204
205 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 64);
206 ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr);
207 }
208
209 TEST(CommonIPAddr, TestV6_Prefix57)
210 {
211 struct ifaddrs one, two;
212 struct sockaddr_in6 a_one;
213 struct sockaddr_in6 a_two;
214 struct sockaddr_in6 net;
215 const struct ifaddrs *result;
216
217 memset(&net, '0', sizeof(net));
218
219 one.ifa_next = &two;
220 one.ifa_addr = (struct sockaddr*)&a_one;
221 one.ifa_name = eth0;
222
223 two.ifa_next = NULL;
224 two.ifa_addr = (struct sockaddr*)&a_two;
225 two.ifa_name = eth1;
226
227 ipv6(&a_one, "2001:1234:5678:900F::cdef");
228 ipv6(&a_two, "2001:1234:5678:90ab::cdef");
229 ipv6(&net, "2001:1234:5678:90ab::dead:beef");
230
231 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 57);
232 ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr);
233 }
234
235 TEST(CommonIPAddr, TestV6_PrefixTooLong)
236 {
237 struct ifaddrs one;
238 struct sockaddr_in6 a_one;
239 struct sockaddr_in6 net;
240 const struct ifaddrs *result;
241
242 memset(&net, '0', sizeof(net));
243
244 one.ifa_next = NULL;
245 one.ifa_addr = (struct sockaddr*)&a_one;
246 one.ifa_name = eth0;
247
248 ipv6(&a_one, "2001:1234:5678:900F::cdef");
249 ipv6(&net, "2001:1234:5678:900F::cdee");
250
251 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 9000);
252 ASSERT_EQ(0, result);
253 }
254
255 TEST(CommonIPAddr, TestV6_PrefixZero)
256 {
257 struct ifaddrs one, two;
258 struct sockaddr_in a_one;
259 struct sockaddr_in6 a_two;
260 struct sockaddr_in6 net;
261 const struct ifaddrs *result;
262
263 one.ifa_next = &two;
264 one.ifa_addr = (struct sockaddr*)&a_one;
265 one.ifa_name = eth0;
266
267 two.ifa_next = NULL;
268 two.ifa_addr = (struct sockaddr*)&a_two;
269 two.ifa_name = eth1;
270
271 ipv4(&a_one, "10.2.3.4");
272 ipv6(&a_two, "2001:f00b::1");
273 ipv6(&net, "ff00::1");
274
275 result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 0);
276 ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr);
277 }
278
279 TEST(CommonIPAddr, ParseNetwork_Empty)
280 {
281 struct sockaddr_storage network;
282 unsigned int prefix_len;
283 bool ok;
284
285 ok = parse_network("", &network, &prefix_len);
286 ASSERT_EQ(ok, false);
287 }
288
289 TEST(CommonIPAddr, ParseNetwork_Bad_Junk)
290 {
291 struct sockaddr_storage network;
292 unsigned int prefix_len;
293 bool ok;
294
295 ok = parse_network("foo", &network, &prefix_len);
296 ASSERT_EQ(ok, false);
297 }
298
299 TEST(CommonIPAddr, ParseNetwork_Bad_SlashNum)
300 {
301 struct sockaddr_storage network;
302 unsigned int prefix_len;
303 bool ok;
304
305 ok = parse_network("/24", &network, &prefix_len);
306 ASSERT_EQ(ok, false);
307 }
308
309 TEST(CommonIPAddr, ParseNetwork_Bad_Slash)
310 {
311 struct sockaddr_storage network;
312 unsigned int prefix_len;
313 bool ok;
314
315 ok = parse_network("/", &network, &prefix_len);
316 ASSERT_EQ(ok, false);
317 }
318
319 TEST(CommonIPAddr, ParseNetwork_Bad_IPv4)
320 {
321 struct sockaddr_storage network;
322 unsigned int prefix_len;
323 bool ok;
324
325 ok = parse_network("123.123.123.123", &network, &prefix_len);
326 ASSERT_EQ(ok, false);
327 }
328
329 TEST(CommonIPAddr, ParseNetwork_Bad_IPv4Slash)
330 {
331 struct sockaddr_storage network;
332 unsigned int prefix_len;
333 bool ok;
334
335 ok = parse_network("123.123.123.123/", &network, &prefix_len);
336 ASSERT_EQ(ok, false);
337 }
338
339 TEST(CommonIPAddr, ParseNetwork_Bad_IPv4SlashNegative)
340 {
341 struct sockaddr_storage network;
342 unsigned int prefix_len;
343 bool ok;
344
345 ok = parse_network("123.123.123.123/-3", &network, &prefix_len);
346 ASSERT_EQ(ok, false);
347 }
348
349 TEST(CommonIPAddr, ParseNetwork_Bad_IPv4SlashJunk)
350 {
351 struct sockaddr_storage network;
352 unsigned int prefix_len;
353 bool ok;
354
355 ok = parse_network("123.123.123.123/foo", &network, &prefix_len);
356 ASSERT_EQ(ok, false);
357 }
358
359 TEST(CommonIPAddr, ParseNetwork_Bad_IPv6)
360 {
361 struct sockaddr_storage network;
362 unsigned int prefix_len;
363 bool ok;
364
365 ok = parse_network("2001:1234:5678:90ab::dead:beef", &network, &prefix_len);
366 ASSERT_EQ(ok, false);
367 }
368
369 TEST(CommonIPAddr, ParseNetwork_Bad_IPv6Slash)
370 {
371 struct sockaddr_storage network;
372 unsigned int prefix_len;
373 bool ok;
374
375 ok = parse_network("2001:1234:5678:90ab::dead:beef/", &network, &prefix_len);
376 ASSERT_EQ(ok, false);
377 }
378
379 TEST(CommonIPAddr, ParseNetwork_Bad_IPv6SlashNegative)
380 {
381 struct sockaddr_storage network;
382 unsigned int prefix_len;
383 bool ok;
384
385 ok = parse_network("2001:1234:5678:90ab::dead:beef/-3", &network, &prefix_len);
386 ASSERT_EQ(ok, false);
387 }
388
389 TEST(CommonIPAddr, ParseNetwork_Bad_IPv6SlashJunk)
390 {
391 struct sockaddr_storage network;
392 unsigned int prefix_len;
393 bool ok;
394
395 ok = parse_network("2001:1234:5678:90ab::dead:beef/foo", &network, &prefix_len);
396 ASSERT_EQ(ok, false);
397 }
398
399 TEST(CommonIPAddr, ParseNetwork_IPv4_0)
400 {
401 struct sockaddr_in network;
402 struct sockaddr_storage net_storage;
403 unsigned int prefix_len;
404 bool ok;
405
406 ok = parse_network("123.123.123.123/0", &net_storage, &prefix_len);
407 network = *(struct sockaddr_in *) &net_storage;
408 ASSERT_EQ(ok, true);
409 ASSERT_EQ(0U, prefix_len);
410 ASSERT_EQ(AF_INET, network.sin_family);
411 ASSERT_EQ(0, network.sin_port);
412 struct sockaddr_in want;
413 ipv4(&want, "123.123.123.123");
414 ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr);
415 }
416
417 TEST(CommonIPAddr, ParseNetwork_IPv4_13)
418 {
419 struct sockaddr_in network;
420 struct sockaddr_storage net_storage;
421 unsigned int prefix_len;
422 bool ok;
423
424 ok = parse_network("123.123.123.123/13", &net_storage, &prefix_len);
425 network = *(struct sockaddr_in *) &net_storage;
426 ASSERT_EQ(ok, true);
427 ASSERT_EQ(13U, prefix_len);
428 ASSERT_EQ(AF_INET, network.sin_family);
429 ASSERT_EQ(0, network.sin_port);
430 struct sockaddr_in want;
431 ipv4(&want, "123.123.123.123");
432 ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr);
433 }
434
435 TEST(CommonIPAddr, ParseNetwork_IPv4_32)
436 {
437 struct sockaddr_in network;
438 struct sockaddr_storage net_storage;
439 unsigned int prefix_len;
440 bool ok;
441
442 ok = parse_network("123.123.123.123/32", &net_storage, &prefix_len);
443 network = *(struct sockaddr_in *) &net_storage;
444 ASSERT_EQ(ok, true);
445 ASSERT_EQ(32U, prefix_len);
446 ASSERT_EQ(AF_INET, network.sin_family);
447 ASSERT_EQ(0, network.sin_port);
448 struct sockaddr_in want;
449 ipv4(&want, "123.123.123.123");
450 ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr);
451 }
452
453 TEST(CommonIPAddr, ParseNetwork_IPv4_42)
454 {
455 struct sockaddr_in network;
456 struct sockaddr_storage net_storage;
457 unsigned int prefix_len;
458 bool ok;
459
460 ok = parse_network("123.123.123.123/42", &net_storage, &prefix_len);
461 network = *(struct sockaddr_in *) &net_storage;
462 ASSERT_EQ(ok, true);
463 ASSERT_EQ(42U, prefix_len);
464 ASSERT_EQ(AF_INET, network.sin_family);
465 ASSERT_EQ(0, network.sin_port);
466 struct sockaddr_in want;
467 ipv4(&want, "123.123.123.123");
468 ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr);
469 }
470
471 TEST(CommonIPAddr, ParseNetwork_IPv6_0)
472 {
473 struct sockaddr_in6 network;
474 struct sockaddr_storage net_storage;
475 unsigned int prefix_len;
476 bool ok;
477
478 ok = parse_network("2001:1234:5678:90ab::dead:beef/0", &net_storage, &prefix_len);
479 network = *(struct sockaddr_in6 *) &net_storage;
480 ASSERT_EQ(ok, true);
481 ASSERT_EQ(0U, prefix_len);
482 ASSERT_EQ(AF_INET6, network.sin6_family);
483 ASSERT_EQ(0, network.sin6_port);
484 struct sockaddr_in6 want;
485 ipv6(&want, "2001:1234:5678:90ab::dead:beef");
486 ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
487 }
488
489 TEST(CommonIPAddr, ParseNetwork_IPv6_67)
490 {
491 struct sockaddr_in6 network;
492 struct sockaddr_storage net_storage;
493 unsigned int prefix_len;
494 bool ok;
495
496 ok = parse_network("2001:1234:5678:90ab::dead:beef/67", &net_storage, &prefix_len);
497 network = *(struct sockaddr_in6 *) &net_storage;
498 ASSERT_EQ(ok, true);
499 ASSERT_EQ(67U, prefix_len);
500 ASSERT_EQ(AF_INET6, network.sin6_family);
501 ASSERT_EQ(0, network.sin6_port);
502 struct sockaddr_in6 want;
503 ipv6(&want, "2001:1234:5678:90ab::dead:beef");
504 ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
505 }
506
507 TEST(CommonIPAddr, ParseNetwork_IPv6_128)
508 {
509 struct sockaddr_in6 network;
510 struct sockaddr_storage net_storage;
511 unsigned int prefix_len;
512 bool ok;
513
514 ok = parse_network("2001:1234:5678:90ab::dead:beef/128", &net_storage, &prefix_len);
515 network = *(struct sockaddr_in6 *) &net_storage;
516 ASSERT_EQ(ok, true);
517 ASSERT_EQ(128U, prefix_len);
518 ASSERT_EQ(AF_INET6, network.sin6_family);
519 ASSERT_EQ(0, network.sin6_port);
520 struct sockaddr_in6 want;
521 ipv6(&want, "2001:1234:5678:90ab::dead:beef");
522 ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
523 }
524
525 TEST(CommonIPAddr, ParseNetwork_IPv6_9000)
526 {
527 struct sockaddr_in6 network;
528 struct sockaddr_storage net_storage;
529 unsigned int prefix_len;
530 bool ok;
531
532 ok = parse_network("2001:1234:5678:90ab::dead:beef/9000", &net_storage, &prefix_len);
533 network = *(struct sockaddr_in6 *) &net_storage;
534 ASSERT_EQ(ok, true);
535 ASSERT_EQ(9000U, prefix_len);
536 ASSERT_EQ(AF_INET6, network.sin6_family);
537 ASSERT_EQ(0, network.sin6_port);
538 struct sockaddr_in6 want;
539 ipv6(&want, "2001:1234:5678:90ab::dead:beef");
540 ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
541 }
542
543 TEST(pick_address, find_ip_in_subnet_list)
544 {
545 struct ifaddrs one, two;
546 struct sockaddr_in a_one;
547 struct sockaddr_in a_two;
548 const struct sockaddr *result;
549
550 one.ifa_next = &two;
551 one.ifa_addr = (struct sockaddr*)&a_one;
552 one.ifa_name = eth0;
553
554 two.ifa_next = NULL;
555 two.ifa_addr = (struct sockaddr*)&a_two;
556 two.ifa_name = eth1;
557
558 ipv4(&a_one, "10.1.1.2");
559 ipv4(&a_two, "10.2.1.123");
560
561 // match by network
562 result = find_ip_in_subnet_list(
563 g_ceph_context,
564 &one,
565 "10.1.0.0/16",
566 "eth0");
567 ASSERT_EQ((struct sockaddr*)&a_one, result);
568
569 result = find_ip_in_subnet_list(
570 g_ceph_context,
571 &one,
572 "10.2.0.0/16",
573 "eth1");
574 ASSERT_EQ((struct sockaddr*)&a_two, result);
575
576 // match by eth name
577 result = find_ip_in_subnet_list(
578 g_ceph_context,
579 &one,
580 "10.0.0.0/8",
581 "eth0");
582 ASSERT_EQ((struct sockaddr*)&a_one, result);
583
584 result = find_ip_in_subnet_list(
585 g_ceph_context,
586 &one,
587 "10.0.0.0/8",
588 "eth1");
589 ASSERT_EQ((struct sockaddr*)&a_two, result);
590 }