]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/test_ipaddr.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / test / test_ipaddr.cc
1 #include "include/ipaddr.h"
2 #include "common/pick_address.h"
3 #include "gtest/gtest.h"
4 #include "include/stringify.h"
5 #include "common/ceph_context.h"
6
7 #include <boost/smart_ptr/intrusive_ptr.hpp>
8
9 #if defined(__FreeBSD__)
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #endif
14 #include <arpa/inet.h>
15 #include <ifaddrs.h>
16 #ifdef _WIN32
17 #include <ws2tcpip.h>
18 #else
19 #include <net/if.h>
20 #endif
21
22 using namespace std;
23
24 static void ipv4(struct sockaddr_in *addr, const char *s) {
25 int err;
26
27 addr->sin_family = AF_INET;
28 err = inet_pton(AF_INET, s, &addr->sin_addr);
29 ASSERT_EQ(1, err);
30 }
31
32 static void ipv6(struct sockaddr_in6 *addr, const char *s) {
33 int err;
34
35 addr->sin6_family = AF_INET6;
36 err = inet_pton(AF_INET6, s, &addr->sin6_addr);
37 ASSERT_EQ(1, err);
38 }
39
40 static char eth0[] = "eth0";
41 static char eth1[] = "eth1";
42
43 TEST(CommonIPAddr, TestNotFound)
44 {
45 struct ifaddrs one, two;
46 struct sockaddr_in a_one;
47 struct sockaddr_in6 a_two;
48 struct sockaddr_in net;
49
50 memset(&net, 0, sizeof(net));
51
52 one.ifa_next = &two;
53 one.ifa_addr = (struct sockaddr*)&a_one;
54 one.ifa_name = eth0;
55
56 two.ifa_next = NULL;
57 two.ifa_addr = (struct sockaddr*)&a_two;
58 two.ifa_name = eth1;
59
60 ipv4(&a_one, "10.11.12.13");
61 ipv6(&a_two, "2001:1234:5678:90ab::cdef");
62 ipv4(&net, "10.11.234.56");
63 ASSERT_FALSE(matches_ipv4_in_subnet(one, (struct sockaddr_in*)&net, 24));
64 ASSERT_FALSE(matches_ipv6_in_subnet(two, (struct sockaddr_in6*)&net, 24));
65 }
66
67 TEST(CommonIPAddr, TestV4_Simple)
68 {
69 struct ifaddrs one, two;
70 struct sockaddr_in a_one;
71 struct sockaddr_in6 a_two;
72 struct sockaddr_in net;
73
74 memset(&net, 0, sizeof(net));
75
76 one.ifa_next = &two;
77 one.ifa_addr = (struct sockaddr*)&a_one;
78 one.ifa_name = eth0;
79
80 two.ifa_next = NULL;
81 two.ifa_addr = (struct sockaddr*)&a_two;
82 two.ifa_name = eth1;
83
84 ipv4(&a_one, "10.11.12.13");
85 ipv6(&a_two, "2001:1234:5678:90ab::cdef");
86 ipv4(&net, "10.11.12.42");
87
88 ASSERT_TRUE(matches_ipv4_in_subnet(one, (struct sockaddr_in*)&net, 24));
89 ASSERT_FALSE(matches_ipv4_in_subnet(two, (struct sockaddr_in*)&net, 24));
90 }
91
92 TEST(CommonIPAddr, TestV4_Prefix25)
93 {
94 struct ifaddrs one, two;
95 struct sockaddr_in a_one;
96 struct sockaddr_in a_two;
97 struct sockaddr_in net;
98
99 memset(&net, 0, sizeof(net));
100
101 one.ifa_next = &two;
102 one.ifa_addr = (struct sockaddr*)&a_one;
103 one.ifa_name = eth0;
104
105 two.ifa_next = NULL;
106 two.ifa_addr = (struct sockaddr*)&a_two;
107 two.ifa_name = eth1;
108
109 ipv4(&a_one, "10.11.12.13");
110 ipv4(&a_two, "10.11.12.129");
111 ipv4(&net, "10.11.12.128");
112
113 ASSERT_FALSE(matches_ipv4_in_subnet(one, (struct sockaddr_in*)&net, 25));
114 ASSERT_TRUE(matches_ipv4_in_subnet(two, (struct sockaddr_in*)&net, 25));
115 }
116
117 TEST(CommonIPAddr, TestV4_Prefix16)
118 {
119 struct ifaddrs one, two;
120 struct sockaddr_in a_one;
121 struct sockaddr_in a_two;
122 struct sockaddr_in net;
123
124 memset(&net, 0, sizeof(net));
125
126 one.ifa_next = &two;
127 one.ifa_addr = (struct sockaddr*)&a_one;
128 one.ifa_name = eth0;
129
130 two.ifa_next = NULL;
131 two.ifa_addr = (struct sockaddr*)&a_two;
132 two.ifa_name = eth1;
133
134 ipv4(&a_one, "10.1.1.2");
135 ipv4(&a_two, "10.2.1.123");
136 ipv4(&net, "10.2.0.0");
137
138 ASSERT_FALSE(matches_ipv4_in_subnet(one, (struct sockaddr_in*)&net, 16));
139 ASSERT_TRUE(matches_ipv4_in_subnet(two, (struct sockaddr_in*)&net, 16));
140 }
141
142 TEST(CommonIPAddr, TestV4_PrefixTooLong)
143 {
144 struct ifaddrs one;
145 struct sockaddr_in a_one;
146 struct sockaddr_in net;
147
148 memset(&net, 0, sizeof(net));
149
150 one.ifa_next = NULL;
151 one.ifa_addr = (struct sockaddr*)&a_one;
152 one.ifa_name = eth0;
153
154 ipv4(&a_one, "10.11.12.13");
155 ipv4(&net, "10.11.12.12");
156
157 ASSERT_FALSE(matches_ipv4_in_subnet(one, (struct sockaddr_in*)&net, 42));
158 }
159
160 TEST(CommonIPAddr, TestV4_PrefixZero)
161 {
162 struct ifaddrs one, two;
163 struct sockaddr_in6 a_one;
164 struct sockaddr_in a_two;
165 struct sockaddr_in net;
166
167 memset(&net, 0, sizeof(net));
168
169 one.ifa_next = &two;
170 one.ifa_addr = (struct sockaddr*)&a_one;
171 one.ifa_name = eth0;
172
173 two.ifa_next = NULL;
174 two.ifa_addr = (struct sockaddr*)&a_two;
175 two.ifa_name = eth1;
176
177 ipv6(&a_one, "2001:1234:5678:900F::cdef");
178 ipv4(&a_two, "10.1.2.3");
179 ipv4(&net, "255.0.1.2");
180
181 ASSERT_FALSE(matches_ipv4_in_subnet(one, (struct sockaddr_in*)&net, 0));
182 ASSERT_TRUE(matches_ipv4_in_subnet(two, (struct sockaddr_in*)&net, 0));
183 }
184
185 static char lo[] = "lo";
186 static char lo0[] = "lo:0";
187
188 TEST(CommonIPAddr, TestV4_SkipLoopback)
189 {
190 struct ifaddrs one, two, three;
191 struct sockaddr_in a_one;
192 struct sockaddr_in a_two;
193 struct sockaddr_in a_three;
194
195 one.ifa_next = &two;
196 one.ifa_flags &= ~IFF_UP;
197 one.ifa_addr = (struct sockaddr*)&a_one;
198 one.ifa_name = lo;
199
200 two.ifa_next = &three;
201 two.ifa_flags = IFF_UP;
202 two.ifa_addr = (struct sockaddr*)&a_two;
203 two.ifa_name = lo0;
204
205 three.ifa_next = NULL;
206 three.ifa_flags = IFF_UP;
207 three.ifa_addr = (struct sockaddr*)&a_three;
208 three.ifa_name = eth0;
209
210 ipv4(&a_one, "127.0.0.1");
211 ipv4(&a_two, "127.0.0.1");
212 ipv4(&a_three, "10.1.2.3");
213
214 const struct sockaddr *result = nullptr;
215 // we prefer the non-loopback address despite the loopback addresses
216 result =
217 find_ip_in_subnet_list(nullptr, (struct ifaddrs*)&one,
218 CEPH_PICK_ADDRESS_IPV4 | CEPH_PICK_ADDRESS_IPV6,
219 "", "");
220 ASSERT_EQ(three.ifa_addr, result);
221 // the subnet criteria leaves us no choice but the UP loopback address
222 result =
223 find_ip_in_subnet_list(nullptr, (struct ifaddrs*)&one,
224 CEPH_PICK_ADDRESS_IPV4 | CEPH_PICK_ADDRESS_IPV6,
225 "127.0.0.0/8", "");
226 ASSERT_EQ(two.ifa_addr, result);
227 }
228
229 TEST(CommonIPAddr, TestV6_Simple)
230 {
231 struct ifaddrs one, two;
232 struct sockaddr_in a_one;
233 struct sockaddr_in6 a_two;
234 struct sockaddr_in6 net;
235
236 memset(&net, 0, sizeof(net));
237
238 one.ifa_next = &two;
239 one.ifa_addr = (struct sockaddr*)&a_one;
240 one.ifa_name = eth0;
241
242 two.ifa_next = NULL;
243 two.ifa_addr = (struct sockaddr*)&a_two;
244 two.ifa_name = eth1;
245
246 ipv4(&a_one, "10.11.12.13");
247 ipv6(&a_two, "2001:1234:5678:90ab::cdef");
248 ipv6(&net, "2001:1234:5678:90ab::dead:beef");
249
250 ASSERT_FALSE(matches_ipv6_in_subnet(one, (struct sockaddr_in6*)&net, 64));
251 ASSERT_TRUE(matches_ipv6_in_subnet(two, (struct sockaddr_in6*)&net, 64));
252 }
253
254 TEST(CommonIPAddr, TestV6_Prefix57)
255 {
256 struct ifaddrs one, two;
257 struct sockaddr_in6 a_one;
258 struct sockaddr_in6 a_two;
259 struct sockaddr_in6 net;
260
261 memset(&net, 0, sizeof(net));
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 ipv6(&a_one, "2001:1234:5678:900F::cdef");
272 ipv6(&a_two, "2001:1234:5678:90ab::cdef");
273 ipv6(&net, "2001:1234:5678:90ab::dead:beef");
274
275 ASSERT_FALSE(matches_ipv6_in_subnet(one, (struct sockaddr_in6*)&net, 57));
276 ASSERT_TRUE(matches_ipv6_in_subnet(two, (struct sockaddr_in6*)&net, 57));
277 }
278
279 TEST(CommonIPAddr, TestV6_PrefixTooLong)
280 {
281 struct ifaddrs one;
282 struct sockaddr_in6 a_one;
283 struct sockaddr_in6 net;
284
285 memset(&net, 0, sizeof(net));
286
287 one.ifa_next = NULL;
288 one.ifa_addr = (struct sockaddr*)&a_one;
289 one.ifa_name = eth0;
290
291 ipv6(&a_one, "2001:1234:5678:900F::cdef");
292 ipv6(&net, "2001:1234:5678:900F::cdee");
293
294 ASSERT_FALSE(matches_ipv6_in_subnet(one, (struct sockaddr_in6*)&net, 9000));
295 }
296
297 TEST(CommonIPAddr, TestV6_PrefixZero)
298 {
299 struct ifaddrs one, two;
300 struct sockaddr_in a_one;
301 struct sockaddr_in6 a_two;
302 struct sockaddr_in6 net;
303
304 one.ifa_next = &two;
305 one.ifa_addr = (struct sockaddr*)&a_one;
306 one.ifa_name = eth0;
307
308 two.ifa_next = NULL;
309 two.ifa_addr = (struct sockaddr*)&a_two;
310 two.ifa_name = eth1;
311
312 ipv4(&a_one, "10.2.3.4");
313 ipv6(&a_two, "2001:f00b::1");
314 ipv6(&net, "ff00::1");
315
316 ASSERT_FALSE(matches_ipv6_in_subnet(one, (struct sockaddr_in6*)&net, 0));
317 ASSERT_TRUE(matches_ipv6_in_subnet(two, (struct sockaddr_in6*)&net, 0));
318 }
319
320 TEST(CommonIPAddr, TestV6_SkipLoopback)
321 {
322 struct ifaddrs one, two, three;
323 struct sockaddr_in6 a_one;
324 struct sockaddr_in6 a_two;
325 struct sockaddr_in6 a_three;
326
327 one.ifa_next = &two;
328 one.ifa_flags &= ~IFF_UP;
329 ipv6(&a_one, "::1");
330 one.ifa_addr = (struct sockaddr*)&a_one;
331 one.ifa_name = lo;
332
333 two.ifa_next = &three;
334 two.ifa_flags = IFF_UP;
335 ipv6(&a_two, "::1");
336 two.ifa_addr = (struct sockaddr*)&a_two;
337 two.ifa_name = lo0;
338
339 three.ifa_next = NULL;
340 three.ifa_flags = IFF_UP;
341 ipv6(&a_three, "2001:1234:5678:90ab::beef");
342 three.ifa_addr = (struct sockaddr*)&a_three;
343 three.ifa_name = eth0;
344
345 const struct sockaddr *result = nullptr;
346 // we prefer the non-loopback address despite the loopback addresses
347 result =
348 find_ip_in_subnet_list(nullptr, (struct ifaddrs*)&one,
349 CEPH_PICK_ADDRESS_IPV4 | CEPH_PICK_ADDRESS_IPV6,
350 "", "");
351 ASSERT_EQ(three.ifa_addr, result);
352 // the subnet criteria leaves us no choice but the UP loopback address
353 result =
354 find_ip_in_subnet_list(nullptr, (struct ifaddrs*)&one,
355 CEPH_PICK_ADDRESS_IPV4 | CEPH_PICK_ADDRESS_IPV6,
356 "::1/128", "");
357 ASSERT_EQ(two.ifa_addr, result);
358 }
359
360 TEST(CommonIPAddr, ParseNetwork_Empty)
361 {
362 struct sockaddr_storage network;
363 unsigned int prefix_len;
364 bool ok;
365
366 ok = parse_network("", &network, &prefix_len);
367 ASSERT_EQ(ok, false);
368 }
369
370 TEST(CommonIPAddr, ParseNetwork_Bad_Junk)
371 {
372 struct sockaddr_storage network;
373 unsigned int prefix_len;
374 bool ok;
375
376 ok = parse_network("foo", &network, &prefix_len);
377 ASSERT_EQ(ok, false);
378 }
379
380 TEST(CommonIPAddr, ParseNetwork_Bad_SlashNum)
381 {
382 struct sockaddr_storage network;
383 unsigned int prefix_len;
384 bool ok;
385
386 ok = parse_network("/24", &network, &prefix_len);
387 ASSERT_EQ(ok, false);
388 }
389
390 TEST(CommonIPAddr, ParseNetwork_Bad_Slash)
391 {
392 struct sockaddr_storage network;
393 unsigned int prefix_len;
394 bool ok;
395
396 ok = parse_network("/", &network, &prefix_len);
397 ASSERT_EQ(ok, false);
398 }
399
400 TEST(CommonIPAddr, ParseNetwork_Bad_IPv4)
401 {
402 struct sockaddr_storage network;
403 unsigned int prefix_len;
404 bool ok;
405
406 ok = parse_network("123.123.123.123", &network, &prefix_len);
407 ASSERT_EQ(ok, false);
408 }
409
410 TEST(CommonIPAddr, ParseNetwork_Bad_IPv4Slash)
411 {
412 struct sockaddr_storage network;
413 unsigned int prefix_len;
414 bool ok;
415
416 ok = parse_network("123.123.123.123/", &network, &prefix_len);
417 ASSERT_EQ(ok, false);
418 }
419
420 TEST(CommonIPAddr, ParseNetwork_Bad_IPv4SlashNegative)
421 {
422 struct sockaddr_storage network;
423 unsigned int prefix_len;
424 bool ok;
425
426 ok = parse_network("123.123.123.123/-3", &network, &prefix_len);
427 ASSERT_EQ(ok, false);
428 }
429
430 TEST(CommonIPAddr, ParseNetwork_Bad_IPv4SlashJunk)
431 {
432 struct sockaddr_storage network;
433 unsigned int prefix_len;
434 bool ok;
435
436 ok = parse_network("123.123.123.123/foo", &network, &prefix_len);
437 ASSERT_EQ(ok, false);
438 }
439
440 TEST(CommonIPAddr, ParseNetwork_Bad_IPv6)
441 {
442 struct sockaddr_storage network;
443 unsigned int prefix_len;
444 bool ok;
445
446 ok = parse_network("2001:1234:5678:90ab::dead:beef", &network, &prefix_len);
447 ASSERT_EQ(ok, false);
448 }
449
450 TEST(CommonIPAddr, ParseNetwork_Bad_IPv6Slash)
451 {
452 struct sockaddr_storage network;
453 unsigned int prefix_len;
454 bool ok;
455
456 ok = parse_network("2001:1234:5678:90ab::dead:beef/", &network, &prefix_len);
457 ASSERT_EQ(ok, false);
458 }
459
460 TEST(CommonIPAddr, ParseNetwork_Bad_IPv6SlashNegative)
461 {
462 struct sockaddr_storage network;
463 unsigned int prefix_len;
464 bool ok;
465
466 ok = parse_network("2001:1234:5678:90ab::dead:beef/-3", &network, &prefix_len);
467 ASSERT_EQ(ok, false);
468 }
469
470 TEST(CommonIPAddr, ParseNetwork_Bad_IPv6SlashJunk)
471 {
472 struct sockaddr_storage network;
473 unsigned int prefix_len;
474 bool ok;
475
476 ok = parse_network("2001:1234:5678:90ab::dead:beef/foo", &network, &prefix_len);
477 ASSERT_EQ(ok, false);
478 }
479
480 TEST(CommonIPAddr, ParseNetwork_IPv4_0)
481 {
482 struct sockaddr_in network;
483 struct sockaddr_storage net_storage;
484 unsigned int prefix_len;
485 bool ok;
486
487 ok = parse_network("123.123.123.123/0", &net_storage, &prefix_len);
488 network = *(struct sockaddr_in *) &net_storage;
489 ASSERT_EQ(ok, true);
490 ASSERT_EQ(0U, prefix_len);
491 ASSERT_EQ(AF_INET, network.sin_family);
492 ASSERT_EQ(0, network.sin_port);
493 struct sockaddr_in want;
494 ipv4(&want, "123.123.123.123");
495 ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr);
496 }
497
498 TEST(CommonIPAddr, ParseNetwork_IPv4_13)
499 {
500 struct sockaddr_in network;
501 struct sockaddr_storage net_storage;
502 unsigned int prefix_len;
503 bool ok;
504
505 ok = parse_network("123.123.123.123/13", &net_storage, &prefix_len);
506 network = *(struct sockaddr_in *) &net_storage;
507 ASSERT_EQ(ok, true);
508 ASSERT_EQ(13U, prefix_len);
509 ASSERT_EQ(AF_INET, network.sin_family);
510 ASSERT_EQ(0, network.sin_port);
511 struct sockaddr_in want;
512 ipv4(&want, "123.123.123.123");
513 ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr);
514 }
515
516 TEST(CommonIPAddr, ParseNetwork_IPv4_32)
517 {
518 struct sockaddr_in network;
519 struct sockaddr_storage net_storage;
520 unsigned int prefix_len;
521 bool ok;
522
523 ok = parse_network("123.123.123.123/32", &net_storage, &prefix_len);
524 network = *(struct sockaddr_in *) &net_storage;
525 ASSERT_EQ(ok, true);
526 ASSERT_EQ(32U, prefix_len);
527 ASSERT_EQ(AF_INET, network.sin_family);
528 ASSERT_EQ(0, network.sin_port);
529 struct sockaddr_in want;
530 ipv4(&want, "123.123.123.123");
531 ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr);
532 }
533
534 TEST(CommonIPAddr, ParseNetwork_IPv4_42)
535 {
536 struct sockaddr_in network;
537 struct sockaddr_storage net_storage;
538 unsigned int prefix_len;
539 bool ok;
540
541 ok = parse_network("123.123.123.123/42", &net_storage, &prefix_len);
542 network = *(struct sockaddr_in *) &net_storage;
543 ASSERT_EQ(ok, true);
544 ASSERT_EQ(42U, prefix_len);
545 ASSERT_EQ(AF_INET, network.sin_family);
546 ASSERT_EQ(0, network.sin_port);
547 struct sockaddr_in want;
548 ipv4(&want, "123.123.123.123");
549 ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr);
550 }
551
552 TEST(CommonIPAddr, ParseNetwork_IPv6_0)
553 {
554 struct sockaddr_in6 network;
555 struct sockaddr_storage net_storage;
556 unsigned int prefix_len;
557 bool ok;
558
559 ok = parse_network("2001:1234:5678:90ab::dead:beef/0", &net_storage, &prefix_len);
560 network = *(struct sockaddr_in6 *) &net_storage;
561 ASSERT_EQ(ok, true);
562 ASSERT_EQ(0U, prefix_len);
563 ASSERT_EQ(AF_INET6, network.sin6_family);
564 ASSERT_EQ(0, network.sin6_port);
565 struct sockaddr_in6 want;
566 ipv6(&want, "2001:1234:5678:90ab::dead:beef");
567 ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
568 }
569
570 TEST(CommonIPAddr, ParseNetwork_IPv6_67)
571 {
572 struct sockaddr_in6 network;
573 struct sockaddr_storage net_storage;
574 unsigned int prefix_len;
575 bool ok;
576
577 ok = parse_network("2001:1234:5678:90ab::dead:beef/67", &net_storage, &prefix_len);
578 network = *(struct sockaddr_in6 *) &net_storage;
579 ASSERT_EQ(ok, true);
580 ASSERT_EQ(67U, prefix_len);
581 ASSERT_EQ(AF_INET6, network.sin6_family);
582 ASSERT_EQ(0, network.sin6_port);
583 struct sockaddr_in6 want;
584 ipv6(&want, "2001:1234:5678:90ab::dead:beef");
585 ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
586 }
587
588 TEST(CommonIPAddr, ParseNetwork_IPv6_128)
589 {
590 struct sockaddr_in6 network;
591 struct sockaddr_storage net_storage;
592 unsigned int prefix_len;
593 bool ok;
594
595 ok = parse_network("2001:1234:5678:90ab::dead:beef/128", &net_storage, &prefix_len);
596 network = *(struct sockaddr_in6 *) &net_storage;
597 ASSERT_EQ(ok, true);
598 ASSERT_EQ(128U, prefix_len);
599 ASSERT_EQ(AF_INET6, network.sin6_family);
600 ASSERT_EQ(0, network.sin6_port);
601 struct sockaddr_in6 want;
602 ipv6(&want, "2001:1234:5678:90ab::dead:beef");
603 ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
604 }
605
606 TEST(CommonIPAddr, ParseNetwork_IPv6_9000)
607 {
608 struct sockaddr_in6 network;
609 struct sockaddr_storage net_storage;
610 unsigned int prefix_len;
611 bool ok;
612
613 ok = parse_network("2001:1234:5678:90ab::dead:beef/9000", &net_storage, &prefix_len);
614 network = *(struct sockaddr_in6 *) &net_storage;
615 ASSERT_EQ(ok, true);
616 ASSERT_EQ(9000U, prefix_len);
617 ASSERT_EQ(AF_INET6, network.sin6_family);
618 ASSERT_EQ(0, network.sin6_port);
619 struct sockaddr_in6 want;
620 ipv6(&want, "2001:1234:5678:90ab::dead:beef");
621 ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
622 }
623
624 TEST(CommonIPAddr, ambiguous)
625 {
626 entity_addr_t a;
627 bool ok;
628
629 ok = a.parse("1.2.3.4", nullptr, entity_addr_t::TYPE_ANY);
630 ASSERT_TRUE(ok);
631 ASSERT_EQ(entity_addr_t::TYPE_ANY, a.get_type());
632
633 ok = a.parse("any:1.2.3.4", nullptr, entity_addr_t::TYPE_ANY);
634 ASSERT_TRUE(ok);
635 ASSERT_EQ(entity_addr_t::TYPE_ANY, a.get_type());
636
637 ok = a.parse("v1:1.2.3.4", nullptr, entity_addr_t::TYPE_ANY);
638 ASSERT_TRUE(ok);
639 ASSERT_EQ(entity_addr_t::TYPE_LEGACY, a.get_type());
640
641 ok = a.parse("v2:1.2.3.4", nullptr, entity_addr_t::TYPE_ANY);
642 ASSERT_TRUE(ok);
643 ASSERT_EQ(entity_addr_t::TYPE_MSGR2, a.get_type());
644 }
645
646 TEST(CommonIPAddr, network_contains)
647 {
648 entity_addr_t network, addr;
649 unsigned int prefix;
650 bool ok;
651
652 ok = parse_network("2001:1234:5678:90ab::dead:beef/32", &network, &prefix);
653 ASSERT_TRUE(ok);
654 ASSERT_EQ(32U, prefix);
655 ok = addr.parse("2001:1234:5678:90ab::dead:beef", nullptr);
656 ASSERT_TRUE(ok);
657 ASSERT_TRUE(network_contains(network, prefix, addr));
658 ok = addr.parse("2001:1334:5678:90ab::dead:beef", nullptr);
659 ASSERT_TRUE(ok);
660 ASSERT_FALSE(network_contains(network, prefix, addr));
661 ok = addr.parse("127.0.0.1", nullptr);
662 ASSERT_TRUE(ok);
663 ASSERT_FALSE(network_contains(network, prefix, addr));
664
665 ok = parse_network("10.1.2.3/16", &network, &prefix);
666 ASSERT_TRUE(ok);
667 ASSERT_EQ(16U, prefix);
668 ok = addr.parse("2001:1234:5678:90ab::dead:beef", nullptr);
669 ASSERT_TRUE(ok);
670 ASSERT_FALSE(network_contains(network, prefix, addr));
671 ok = addr.parse("1.2.3.4", nullptr);
672 ASSERT_TRUE(ok);
673 ASSERT_FALSE(network_contains(network, prefix, addr));
674 ok = addr.parse("10.1.22.44", nullptr);
675 ASSERT_TRUE(ok);
676 ASSERT_TRUE(network_contains(network, prefix, addr));
677 ok = addr.parse("10.2.22.44", nullptr);
678 ASSERT_TRUE(ok);
679 ASSERT_FALSE(network_contains(network, prefix, addr));
680 }
681
682 TEST(pick_address, find_ip_in_subnet_list)
683 {
684 struct ifaddrs one, two, three;
685 struct sockaddr_in a_one;
686 struct sockaddr_in a_two;
687 struct sockaddr_in6 a_three;
688 const struct sockaddr *result;
689
690 one.ifa_next = &two;
691 one.ifa_addr = (struct sockaddr*)&a_one;
692 one.ifa_name = eth0;
693
694 two.ifa_next = &three;
695 two.ifa_addr = (struct sockaddr*)&a_two;
696 two.ifa_name = eth1;
697
698 three.ifa_next = NULL;
699 three.ifa_addr = (struct sockaddr*)&a_three;
700 three.ifa_name = eth1;
701
702 ipv4(&a_one, "10.1.1.2");
703 ipv4(&a_two, "10.2.1.123");
704 ipv6(&a_three, "2001:1234:5678:90ab::cdef");
705
706 boost::intrusive_ptr<CephContext> cct = new CephContext(CEPH_ENTITY_TYPE_OSD);
707
708 // match by network
709 result = find_ip_in_subnet_list(
710 cct.get(),
711 &one,
712 CEPH_PICK_ADDRESS_IPV4,
713 "10.1.0.0/16",
714 "eth0");
715 ASSERT_EQ(one.ifa_addr, result);
716
717 result = find_ip_in_subnet_list(
718 cct.get(),
719 &one,
720 CEPH_PICK_ADDRESS_IPV4,
721 "10.2.0.0/16",
722 "eth1");
723 ASSERT_EQ(two.ifa_addr, result);
724
725 // match by eth name
726 result = find_ip_in_subnet_list(
727 cct.get(),
728 &one,
729 CEPH_PICK_ADDRESS_IPV4,
730 "10.0.0.0/8",
731 "eth0");
732 ASSERT_EQ(one.ifa_addr, result);
733
734 result = find_ip_in_subnet_list(
735 cct.get(),
736 &one,
737 CEPH_PICK_ADDRESS_IPV4,
738 "10.0.0.0/8",
739 "eth1");
740 ASSERT_EQ(two.ifa_addr, result);
741
742 result = find_ip_in_subnet_list(
743 cct.get(),
744 &one,
745 CEPH_PICK_ADDRESS_IPV6,
746 "2001::/16",
747 "eth1");
748 ASSERT_EQ(three.ifa_addr, result);
749 }
750
751 TEST(pick_address, filtering)
752 {
753 struct ifaddrs one, two, three;
754 struct sockaddr_in a_one;
755 struct sockaddr_in a_two;
756 struct sockaddr_in6 a_three;
757
758 one.ifa_next = &two;
759 one.ifa_addr = (struct sockaddr*)&a_one;
760 one.ifa_name = eth0;
761
762 two.ifa_next = &three;
763 two.ifa_addr = (struct sockaddr*)&a_two;
764 two.ifa_name = eth1;
765
766 three.ifa_next = NULL;
767 three.ifa_addr = (struct sockaddr*)&a_three;
768 three.ifa_name = eth1;
769
770 ipv4(&a_one, "10.1.1.2");
771 ipv4(&a_two, "10.2.1.123");
772 ipv6(&a_three, "2001:1234:5678:90ab::cdef");
773
774 boost::intrusive_ptr<CephContext> cct = new CephContext(CEPH_ENTITY_TYPE_MON);
775 cct->_conf._clear_safe_to_start_threads(); // so we can set configs
776
777 cct->_conf.set_val("public_addr", "");
778 cct->_conf.set_val("public_network", "");
779 cct->_conf.set_val("public_network_interface", "");
780 cct->_conf.set_val("cluster_addr", "");
781 cct->_conf.set_val("cluster_network", "");
782 cct->_conf.set_val("cluster_network_interface", "");
783
784 entity_addrvec_t av;
785 {
786 int r = pick_addresses(cct.get(),
787 CEPH_PICK_ADDRESS_PUBLIC |
788 CEPH_PICK_ADDRESS_IPV4 |
789 CEPH_PICK_ADDRESS_MSGR1,
790 &one, &av);
791 ASSERT_EQ(0, r);
792 ASSERT_EQ(1u, av.v.size());
793 ASSERT_EQ(string("v1:0.0.0.0:0/0"), stringify(av.v[0]));
794 }
795 {
796 int r = pick_addresses(cct.get(),
797 CEPH_PICK_ADDRESS_PUBLIC |
798 CEPH_PICK_ADDRESS_IPV6 |
799 CEPH_PICK_ADDRESS_MSGR1,
800 &one, &av);
801 ASSERT_EQ(0, r);
802 ASSERT_EQ(1u, av.v.size());
803 ASSERT_EQ(string("v1:[::]:0/0"), stringify(av.v[0]));
804 }
805 {
806 cct->_conf.set_val("public_network", "10.2.0.0/16");
807 int r = pick_addresses(cct.get(),
808 CEPH_PICK_ADDRESS_PUBLIC |
809 CEPH_PICK_ADDRESS_IPV4 |
810 CEPH_PICK_ADDRESS_MSGR1,
811 &one, &av);
812 ASSERT_EQ(0, r);
813 ASSERT_EQ(1u, av.v.size());
814 ASSERT_EQ(string("v1:10.2.1.123:0/0"), stringify(av.v[0]));
815 cct->_conf.set_val("public_network", "");
816 }
817 {
818 cct->_conf.set_val("public_network", "10.0.0.0/8");
819 cct->_conf.set_val("public_network_interface", "eth1");
820 int r = pick_addresses(cct.get(),
821 CEPH_PICK_ADDRESS_PUBLIC |
822 CEPH_PICK_ADDRESS_IPV4 |
823 CEPH_PICK_ADDRESS_MSGR2,
824 &one, &av);
825 ASSERT_EQ(0, r);
826 ASSERT_EQ(1u, av.v.size());
827 ASSERT_EQ(string("v2:10.2.1.123:0/0"), stringify(av.v[0]));
828 cct->_conf.set_val("public_network", "");
829 cct->_conf.set_val("public_network_interface", "");
830 }
831 {
832 cct->_conf.set_val("public_network", "10.2.0.0/16");
833 cct->_conf.set_val("cluster_network", "10.1.0.0/16");
834 int r = pick_addresses(cct.get(),
835 CEPH_PICK_ADDRESS_PUBLIC |
836 CEPH_PICK_ADDRESS_IPV4 |
837 CEPH_PICK_ADDRESS_MSGR2,
838 &one, &av);
839 ASSERT_EQ(0, r);
840 ASSERT_EQ(1u, av.v.size());
841 ASSERT_EQ(string("v2:10.2.1.123:0/0"), stringify(av.v[0]));
842 cct->_conf.set_val("public_network", "");
843 cct->_conf.set_val("cluster_network", "");
844 }
845 {
846 cct->_conf.set_val("public_network", "10.2.0.0/16");
847 cct->_conf.set_val("cluster_network", "10.1.0.0/16");
848 int r = pick_addresses(cct.get(),
849 CEPH_PICK_ADDRESS_CLUSTER |
850 CEPH_PICK_ADDRESS_IPV4 |
851 CEPH_PICK_ADDRESS_MSGR1,
852 &one, &av);
853 ASSERT_EQ(0, r);
854 ASSERT_EQ(1u, av.v.size());
855 ASSERT_EQ(string("v1:10.1.1.2:0/0"), stringify(av.v[0]));
856 cct->_conf.set_val("public_network", "");
857 cct->_conf.set_val("cluster_network", "");
858 }
859
860 {
861 cct->_conf.set_val("public_network", "2001::/16");
862 int r = pick_addresses(cct.get(),
863 CEPH_PICK_ADDRESS_PUBLIC |
864 CEPH_PICK_ADDRESS_IPV6 |
865 CEPH_PICK_ADDRESS_MSGR2,
866 &one, &av);
867 ASSERT_EQ(0, r);
868 ASSERT_EQ(1u, av.v.size());
869 ASSERT_EQ(string("v2:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[0]));
870 cct->_conf.set_val("public_network", "");
871 }
872 {
873 cct->_conf.set_val("public_network", "2001::/16 10.0.0.0/8");
874 cct->_conf.set_val("public_network_interface", "eth1");
875 int r = pick_addresses(cct.get(),
876 CEPH_PICK_ADDRESS_PUBLIC |
877 CEPH_PICK_ADDRESS_IPV4 |
878 CEPH_PICK_ADDRESS_IPV6 |
879 CEPH_PICK_ADDRESS_MSGR2,
880 &one, &av);
881 ASSERT_EQ(0, r);
882 ASSERT_EQ(2u, av.v.size());
883 ASSERT_EQ(string("v2:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[0]));
884 ASSERT_EQ(string("v2:10.2.1.123:0/0"), stringify(av.v[1]));
885 cct->_conf.set_val("public_network", "");
886 cct->_conf.set_val("public_network_interface", "");
887 }
888 {
889 cct->_conf.set_val("public_network", "2001::/16 10.0.0.0/8");
890 cct->_conf.set_val("public_network_interface", "eth1");
891 int r = pick_addresses(cct.get(),
892 CEPH_PICK_ADDRESS_PUBLIC |
893 CEPH_PICK_ADDRESS_IPV4 |
894 CEPH_PICK_ADDRESS_IPV6 |
895 CEPH_PICK_ADDRESS_MSGR1 |
896 CEPH_PICK_ADDRESS_PREFER_IPV4,
897 &one, &av);
898 ASSERT_EQ(0, r);
899 ASSERT_EQ(2u, av.v.size());
900 ASSERT_EQ(string("v1:10.2.1.123:0/0"), stringify(av.v[0]));
901 ASSERT_EQ(string("v1:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[1]));
902 cct->_conf.set_val("public_network", "");
903 cct->_conf.set_val("public_network_interface", "");
904 }
905
906 {
907 cct->_conf.set_val("public_network", "2001::/16");
908 int r = pick_addresses(cct.get(),
909 CEPH_PICK_ADDRESS_PUBLIC |
910 CEPH_PICK_ADDRESS_IPV6 |
911 CEPH_PICK_ADDRESS_MSGR1 |
912 CEPH_PICK_ADDRESS_MSGR2,
913 &one, &av);
914 ASSERT_EQ(0, r);
915 ASSERT_EQ(2u, av.v.size());
916 ASSERT_EQ(string("v2:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[0]));
917 ASSERT_EQ(string("v1:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[1]));
918 cct->_conf.set_val("public_network", "");
919 }
920
921 {
922 int r = pick_addresses(cct.get(),
923 CEPH_PICK_ADDRESS_PUBLIC |
924 CEPH_PICK_ADDRESS_IPV4 |
925 CEPH_PICK_ADDRESS_MSGR1 |
926 CEPH_PICK_ADDRESS_MSGR2,
927 &one, &av);
928 ASSERT_EQ(0, r);
929 ASSERT_EQ(2u, av.v.size());
930 ASSERT_EQ(string("v2:0.0.0.0:0/0"), stringify(av.v[0]));
931 ASSERT_EQ(string("v1:0.0.0.0:0/0"), stringify(av.v[1]));
932 }
933 }
934
935 TEST(pick_address, ipv4_ipv6_enabled)
936 {
937 struct ifaddrs one;
938 struct sockaddr_in a_one;
939
940 one.ifa_next = NULL;
941 one.ifa_addr = (struct sockaddr*)&a_one;
942 one.ifa_name = eth0;
943
944 ipv4(&a_one, "10.1.1.2");
945
946 boost::intrusive_ptr<CephContext> cct = new CephContext(CEPH_ENTITY_TYPE_OSD);
947 cct->_conf._clear_safe_to_start_threads(); // so we can set configs
948
949 cct->_conf.set_val("public_addr", "");
950 cct->_conf.set_val("public_network", "10.1.1.0/24");
951 cct->_conf.set_val("public_network_interface", "");
952 cct->_conf.set_val("cluster_addr", "");
953 cct->_conf.set_val("cluster_network", "");
954 cct->_conf.set_val("cluster_network_interface", "");
955 cct->_conf.set_val("ms_bind_ipv6", "true");
956
957 entity_addrvec_t av;
958 {
959 int r = pick_addresses(cct.get(),
960 CEPH_PICK_ADDRESS_PUBLIC |
961 CEPH_PICK_ADDRESS_MSGR1,
962 &one, &av);
963 ASSERT_EQ(-1, r);
964 }
965 }
966
967 TEST(pick_address, ipv4_ipv6_enabled2)
968 {
969 struct ifaddrs one;
970 struct sockaddr_in6 a_one;
971
972 one.ifa_next = NULL;
973 one.ifa_addr = (struct sockaddr*)&a_one;
974 one.ifa_name = eth0;
975
976 ipv6(&a_one, "2001:1234:5678:90ab::cdef");
977
978 boost::intrusive_ptr<CephContext> cct = new CephContext(CEPH_ENTITY_TYPE_OSD);
979 cct->_conf._clear_safe_to_start_threads(); // so we can set configs
980
981 cct->_conf.set_val("public_addr", "");
982 cct->_conf.set_val("public_network", "2001::/16");
983 cct->_conf.set_val("public_network_interface", "");
984 cct->_conf.set_val("cluster_addr", "");
985 cct->_conf.set_val("cluster_network", "");
986 cct->_conf.set_val("cluster_network_interface", "");
987 cct->_conf.set_val("ms_bind_ipv6", "true");
988
989 entity_addrvec_t av;
990 {
991 int r = pick_addresses(cct.get(),
992 CEPH_PICK_ADDRESS_PUBLIC |
993 CEPH_PICK_ADDRESS_MSGR1,
994 &one, &av);
995 ASSERT_EQ(-1, r);
996 }
997 }