]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/test_ipaddr.cc
update ceph source to reef 18.2.0
[ceph.git] / ceph / src / test / test_ipaddr.cc
CommitLineData
7c673cae 1#include "include/ipaddr.h"
3efd9988 2#include "common/pick_address.h"
7c673cae 3#include "gtest/gtest.h"
11fdf7f2
TL
4#include "include/stringify.h"
5#include "common/ceph_context.h"
7c673cae 6
f67539c2
TL
7#include <boost/smart_ptr/intrusive_ptr.hpp>
8
7c673cae
FG
9#if defined(__FreeBSD__)
10#include <sys/types.h>
11#include <sys/socket.h>
31f18b77 12#include <netinet/in.h>
7c673cae
FG
13#endif
14#include <arpa/inet.h>
31f18b77 15#include <ifaddrs.h>
522d829b
TL
16#ifdef _WIN32
17#include <ws2tcpip.h>
18#else
19#include <net/if.h>
20#endif
7c673cae 21
20effc67
TL
22using namespace std;
23
7c673cae
FG
24static 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
32static 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
40static char eth0[] = "eth0";
41static char eth1[] = "eth1";
42
43TEST(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;
7c673cae 49
11fdf7f2 50 memset(&net, 0, sizeof(net));
7c673cae
FG
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");
522d829b
TL
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));
7c673cae
FG
65}
66
67TEST(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;
7c673cae 73
11fdf7f2 74 memset(&net, 0, sizeof(net));
7c673cae
FG
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
522d829b
TL
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));
7c673cae
FG
90}
91
92TEST(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;
7c673cae 98
11fdf7f2 99 memset(&net, 0, sizeof(net));
7c673cae
FG
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
522d829b
TL
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));
7c673cae
FG
115}
116
117TEST(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;
7c673cae 123
11fdf7f2 124 memset(&net, 0, sizeof(net));
7c673cae
FG
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
522d829b
TL
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));
7c673cae
FG
140}
141
142TEST(CommonIPAddr, TestV4_PrefixTooLong)
143{
144 struct ifaddrs one;
145 struct sockaddr_in a_one;
146 struct sockaddr_in net;
7c673cae 147
11fdf7f2 148 memset(&net, 0, sizeof(net));
7c673cae
FG
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
522d829b 157 ASSERT_FALSE(matches_ipv4_in_subnet(one, (struct sockaddr_in*)&net, 42));
7c673cae
FG
158}
159
160TEST(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;
7c673cae 166
11fdf7f2 167 memset(&net, 0, sizeof(net));
7c673cae
FG
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
522d829b
TL
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));
7c673cae
FG
183}
184
f67539c2
TL
185static char lo[] = "lo";
186static char lo0[] = "lo:0";
187
188TEST(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;
f67539c2
TL
194
195 one.ifa_next = &two;
20effc67 196 one.ifa_flags &= ~IFF_UP;
f67539c2
TL
197 one.ifa_addr = (struct sockaddr*)&a_one;
198 one.ifa_name = lo;
199
200 two.ifa_next = &three;
522d829b 201 two.ifa_flags = IFF_UP;
f67539c2
TL
202 two.ifa_addr = (struct sockaddr*)&a_two;
203 two.ifa_name = lo0;
204
205 three.ifa_next = NULL;
522d829b 206 three.ifa_flags = IFF_UP;
f67539c2
TL
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");
f67539c2 213
522d829b
TL
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 "", "");
20effc67 220 ASSERT_EQ(three.ifa_addr, result);
522d829b
TL
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", "");
20effc67 226 ASSERT_EQ(two.ifa_addr, result);
f67539c2
TL
227}
228
7c673cae
FG
229TEST(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;
7c673cae 235
11fdf7f2
TL
236 memset(&net, 0, sizeof(net));
237
7c673cae
FG
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
522d829b
TL
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));
7c673cae
FG
252}
253
254TEST(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;
7c673cae 260
11fdf7f2 261 memset(&net, 0, sizeof(net));
7c673cae
FG
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
522d829b
TL
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));
7c673cae
FG
277}
278
279TEST(CommonIPAddr, TestV6_PrefixTooLong)
280{
281 struct ifaddrs one;
282 struct sockaddr_in6 a_one;
283 struct sockaddr_in6 net;
7c673cae 284
11fdf7f2 285 memset(&net, 0, sizeof(net));
7c673cae
FG
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
522d829b 294 ASSERT_FALSE(matches_ipv6_in_subnet(one, (struct sockaddr_in6*)&net, 9000));
7c673cae
FG
295}
296
297TEST(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;
7c673cae
FG
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
522d829b
TL
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));
7c673cae
FG
318}
319
f67539c2
TL
320TEST(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;
f67539c2
TL
326
327 one.ifa_next = &two;
20effc67 328 one.ifa_flags &= ~IFF_UP;
522d829b 329 ipv6(&a_one, "::1");
f67539c2
TL
330 one.ifa_addr = (struct sockaddr*)&a_one;
331 one.ifa_name = lo;
332
333 two.ifa_next = &three;
522d829b
TL
334 two.ifa_flags = IFF_UP;
335 ipv6(&a_two, "::1");
f67539c2
TL
336 two.ifa_addr = (struct sockaddr*)&a_two;
337 two.ifa_name = lo0;
338
339 three.ifa_next = NULL;
522d829b
TL
340 three.ifa_flags = IFF_UP;
341 ipv6(&a_three, "2001:1234:5678:90ab::beef");
f67539c2
TL
342 three.ifa_addr = (struct sockaddr*)&a_three;
343 three.ifa_name = eth0;
344
522d829b
TL
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 "", "");
20effc67 351 ASSERT_EQ(three.ifa_addr, result);
522d829b
TL
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", "");
20effc67 357 ASSERT_EQ(two.ifa_addr, result);
f67539c2
TL
358}
359
7c673cae
FG
360TEST(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
370TEST(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
380TEST(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
390TEST(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
400TEST(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
410TEST(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
420TEST(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
430TEST(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
440TEST(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
450TEST(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
460TEST(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
470TEST(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
480TEST(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
498TEST(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
516TEST(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
534TEST(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
552TEST(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
570TEST(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
588TEST(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
606TEST(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}
3efd9988 623
11fdf7f2
TL
624TEST(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
646TEST(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
3efd9988
FG
682TEST(pick_address, find_ip_in_subnet_list)
683{
11fdf7f2 684 struct ifaddrs one, two, three;
3efd9988
FG
685 struct sockaddr_in a_one;
686 struct sockaddr_in a_two;
11fdf7f2 687 struct sockaddr_in6 a_three;
3efd9988
FG
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
11fdf7f2 694 two.ifa_next = &three;
3efd9988
FG
695 two.ifa_addr = (struct sockaddr*)&a_two;
696 two.ifa_name = eth1;
697
11fdf7f2
TL
698 three.ifa_next = NULL;
699 three.ifa_addr = (struct sockaddr*)&a_three;
700 three.ifa_name = eth1;
701
3efd9988
FG
702 ipv4(&a_one, "10.1.1.2");
703 ipv4(&a_two, "10.2.1.123");
11fdf7f2 704 ipv6(&a_three, "2001:1234:5678:90ab::cdef");
3efd9988 705
f67539c2
TL
706 boost::intrusive_ptr<CephContext> cct = new CephContext(CEPH_ENTITY_TYPE_OSD);
707
3efd9988
FG
708 // match by network
709 result = find_ip_in_subnet_list(
f67539c2 710 cct.get(),
3efd9988 711 &one,
11fdf7f2 712 CEPH_PICK_ADDRESS_IPV4,
3efd9988
FG
713 "10.1.0.0/16",
714 "eth0");
20effc67 715 ASSERT_EQ(one.ifa_addr, result);
3efd9988
FG
716
717 result = find_ip_in_subnet_list(
f67539c2 718 cct.get(),
3efd9988 719 &one,
11fdf7f2 720 CEPH_PICK_ADDRESS_IPV4,
3efd9988
FG
721 "10.2.0.0/16",
722 "eth1");
20effc67 723 ASSERT_EQ(two.ifa_addr, result);
3efd9988
FG
724
725 // match by eth name
726 result = find_ip_in_subnet_list(
f67539c2 727 cct.get(),
3efd9988 728 &one,
11fdf7f2 729 CEPH_PICK_ADDRESS_IPV4,
3efd9988
FG
730 "10.0.0.0/8",
731 "eth0");
20effc67 732 ASSERT_EQ(one.ifa_addr, result);
3efd9988
FG
733
734 result = find_ip_in_subnet_list(
f67539c2 735 cct.get(),
3efd9988 736 &one,
11fdf7f2 737 CEPH_PICK_ADDRESS_IPV4,
3efd9988
FG
738 "10.0.0.0/8",
739 "eth1");
20effc67 740 ASSERT_EQ(two.ifa_addr, result);
11fdf7f2
TL
741
742 result = find_ip_in_subnet_list(
f67539c2 743 cct.get(),
11fdf7f2
TL
744 &one,
745 CEPH_PICK_ADDRESS_IPV6,
746 "2001::/16",
747 "eth1");
20effc67 748 ASSERT_EQ(three.ifa_addr, result);
11fdf7f2
TL
749}
750
751TEST(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
f67539c2 774 boost::intrusive_ptr<CephContext> cct = new CephContext(CEPH_ENTITY_TYPE_MON);
11fdf7f2
TL
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 {
f67539c2 786 int r = pick_addresses(cct.get(),
11fdf7f2
TL
787 CEPH_PICK_ADDRESS_PUBLIC |
788 CEPH_PICK_ADDRESS_IPV4 |
789 CEPH_PICK_ADDRESS_MSGR1,
790 &one, &av);
11fdf7f2
TL
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 {
f67539c2 796 int r = pick_addresses(cct.get(),
11fdf7f2
TL
797 CEPH_PICK_ADDRESS_PUBLIC |
798 CEPH_PICK_ADDRESS_IPV6 |
799 CEPH_PICK_ADDRESS_MSGR1,
800 &one, &av);
11fdf7f2
TL
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");
f67539c2 807 int r = pick_addresses(cct.get(),
11fdf7f2
TL
808 CEPH_PICK_ADDRESS_PUBLIC |
809 CEPH_PICK_ADDRESS_IPV4 |
810 CEPH_PICK_ADDRESS_MSGR1,
811 &one, &av);
11fdf7f2
TL
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");
f67539c2 820 int r = pick_addresses(cct.get(),
11fdf7f2
TL
821 CEPH_PICK_ADDRESS_PUBLIC |
822 CEPH_PICK_ADDRESS_IPV4 |
823 CEPH_PICK_ADDRESS_MSGR2,
824 &one, &av);
11fdf7f2
TL
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");
f67539c2 834 int r = pick_addresses(cct.get(),
11fdf7f2
TL
835 CEPH_PICK_ADDRESS_PUBLIC |
836 CEPH_PICK_ADDRESS_IPV4 |
837 CEPH_PICK_ADDRESS_MSGR2,
838 &one, &av);
11fdf7f2
TL
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");
f67539c2 848 int r = pick_addresses(cct.get(),
11fdf7f2
TL
849 CEPH_PICK_ADDRESS_CLUSTER |
850 CEPH_PICK_ADDRESS_IPV4 |
851 CEPH_PICK_ADDRESS_MSGR1,
852 &one, &av);
11fdf7f2
TL
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");
f67539c2 862 int r = pick_addresses(cct.get(),
11fdf7f2
TL
863 CEPH_PICK_ADDRESS_PUBLIC |
864 CEPH_PICK_ADDRESS_IPV6 |
865 CEPH_PICK_ADDRESS_MSGR2,
866 &one, &av);
11fdf7f2
TL
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");
f67539c2 875 int r = pick_addresses(cct.get(),
11fdf7f2
TL
876 CEPH_PICK_ADDRESS_PUBLIC |
877 CEPH_PICK_ADDRESS_IPV4 |
878 CEPH_PICK_ADDRESS_IPV6 |
879 CEPH_PICK_ADDRESS_MSGR2,
880 &one, &av);
11fdf7f2
TL
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");
f67539c2 891 int r = pick_addresses(cct.get(),
11fdf7f2
TL
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);
11fdf7f2
TL
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");
f67539c2 908 int r = pick_addresses(cct.get(),
11fdf7f2
TL
909 CEPH_PICK_ADDRESS_PUBLIC |
910 CEPH_PICK_ADDRESS_IPV6 |
911 CEPH_PICK_ADDRESS_MSGR1 |
912 CEPH_PICK_ADDRESS_MSGR2,
913 &one, &av);
11fdf7f2
TL
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 {
f67539c2 922 int r = pick_addresses(cct.get(),
11fdf7f2
TL
923 CEPH_PICK_ADDRESS_PUBLIC |
924 CEPH_PICK_ADDRESS_IPV4 |
925 CEPH_PICK_ADDRESS_MSGR1 |
926 CEPH_PICK_ADDRESS_MSGR2,
927 &one, &av);
11fdf7f2
TL
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
935TEST(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
f67539c2 946 boost::intrusive_ptr<CephContext> cct = new CephContext(CEPH_ENTITY_TYPE_OSD);
11fdf7f2
TL
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 {
f67539c2 959 int r = pick_addresses(cct.get(),
11fdf7f2
TL
960 CEPH_PICK_ADDRESS_PUBLIC |
961 CEPH_PICK_ADDRESS_MSGR1,
962 &one, &av);
11fdf7f2
TL
963 ASSERT_EQ(-1, r);
964 }
965}
966
967TEST(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
f67539c2 978 boost::intrusive_ptr<CephContext> cct = new CephContext(CEPH_ENTITY_TYPE_OSD);
11fdf7f2
TL
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 {
f67539c2 991 int r = pick_addresses(cct.get(),
11fdf7f2
TL
992 CEPH_PICK_ADDRESS_PUBLIC |
993 CEPH_PICK_ADDRESS_MSGR1,
994 &one, &av);
11fdf7f2
TL
995 ASSERT_EQ(-1, r);
996 }
3efd9988 997}