From bc95a339797d248485666b4a86c74803cd16b2f9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 31 May 2018 06:49:44 -0500 Subject: [PATCH] common/pick_addresses: add filtering by ipv4 and ipv6 Signed-off-by: Sage Weil --- src/common/pick_address.cc | 22 ++++++++++++++++++++-- src/common/pick_address.h | 11 +++++++++-- src/test/test_ipaddr.cc | 22 ++++++++++++++++++++-- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/common/pick_address.cc b/src/common/pick_address.cc index 48ba7b6dcb744..f25ff65af7d12 100644 --- a/src/common/pick_address.cc +++ b/src/common/pick_address.cc @@ -26,6 +26,7 @@ const struct sockaddr *find_ip_in_subnet_list( CephContext *cct, const struct ifaddrs *ifa, + unsigned ipv, const std::string &networks, const std::string &interfaces) { @@ -78,6 +79,19 @@ const struct sockaddr *find_ip_in_subnet_list( exit(1); } + switch (net.ss_family) { + case AF_INET: + if (!(ipv & CEPH_PICK_ADDRESS_IPV4)) { + continue; + } + break; + case AF_INET6: + if (!(ipv & CEPH_PICK_ADDRESS_IPV6)) { + continue; + } + break; + } + const struct ifaddrs *found = find_ip_in_subnet( filtered, (struct sockaddr *) &net, prefix_len); @@ -121,8 +135,12 @@ static void fill_in_one_address(CephContext *cct, const string interfaces, const char *conf_var) { - const struct sockaddr *found = find_ip_in_subnet_list(cct, ifa, networks, - interfaces); + const struct sockaddr *found = find_ip_in_subnet_list( + cct, + ifa, + CEPH_PICK_ADDRESS_IPV4|CEPH_PICK_ADDRESS_IPV6, + networks, + interfaces); if (!found) { lderr(cct) << "unable to find any IP address in networks '" << networks << "' interfaces '" << interfaces << "'" << dendl; diff --git a/src/common/pick_address.h b/src/common/pick_address.h index 73020602b7eef..6176473318612 100644 --- a/src/common/pick_address.h +++ b/src/common/pick_address.h @@ -6,8 +6,14 @@ class CephContext; -#define CEPH_PICK_ADDRESS_PUBLIC 0x01 -#define CEPH_PICK_ADDRESS_CLUSTER 0x02 +#define CEPH_PICK_ADDRESS_PUBLIC 0x01 +#define CEPH_PICK_ADDRESS_CLUSTER 0x02 +#define CEPH_PICK_ADDRESS_MSGR1 0x04 +#define CEPH_PICK_ADDRESS_MSGR2 0x08 +#define CEPH_PICK_ADDRESS_IPV4 0x10 +#define CEPH_PICK_ADDRESS_IPV6 0x20 +#define CEPH_PICK_ADDRESS_PREFER_IPV4 0x40 +#define CEPH_PICK_ADDRESS_DEFAULT_MON_PORTS 0x80 /* Pick addresses based on subnets if needed. @@ -51,6 +57,7 @@ bool have_local_addr(CephContext *cct, const list& ls, entity_add const struct sockaddr *find_ip_in_subnet_list( CephContext *cct, const struct ifaddrs *ifa, + unsigned ipv, const std::string &networks, const std::string &interfaces); diff --git a/src/test/test_ipaddr.cc b/src/test/test_ipaddr.cc index 15546d34f15fc..6db389325148e 100644 --- a/src/test/test_ipaddr.cc +++ b/src/test/test_ipaddr.cc @@ -542,26 +542,33 @@ TEST(CommonIPAddr, ParseNetwork_IPv6_9000) TEST(pick_address, find_ip_in_subnet_list) { - struct ifaddrs one, two; + struct ifaddrs one, two, three; struct sockaddr_in a_one; struct sockaddr_in a_two; + struct sockaddr_in6 a_three; const struct sockaddr *result; one.ifa_next = &two; one.ifa_addr = (struct sockaddr*)&a_one; one.ifa_name = eth0; - two.ifa_next = NULL; + two.ifa_next = &three; two.ifa_addr = (struct sockaddr*)&a_two; two.ifa_name = eth1; + three.ifa_next = NULL; + three.ifa_addr = (struct sockaddr*)&a_three; + three.ifa_name = eth1; + ipv4(&a_one, "10.1.1.2"); ipv4(&a_two, "10.2.1.123"); + ipv6(&a_three, "2001:1234:5678:90ab::cdef"); // match by network result = find_ip_in_subnet_list( g_ceph_context, &one, + CEPH_PICK_ADDRESS_IPV4, "10.1.0.0/16", "eth0"); ASSERT_EQ((struct sockaddr*)&a_one, result); @@ -569,6 +576,7 @@ TEST(pick_address, find_ip_in_subnet_list) result = find_ip_in_subnet_list( g_ceph_context, &one, + CEPH_PICK_ADDRESS_IPV4, "10.2.0.0/16", "eth1"); ASSERT_EQ((struct sockaddr*)&a_two, result); @@ -577,6 +585,7 @@ TEST(pick_address, find_ip_in_subnet_list) result = find_ip_in_subnet_list( g_ceph_context, &one, + CEPH_PICK_ADDRESS_IPV4, "10.0.0.0/8", "eth0"); ASSERT_EQ((struct sockaddr*)&a_one, result); @@ -584,7 +593,16 @@ TEST(pick_address, find_ip_in_subnet_list) result = find_ip_in_subnet_list( g_ceph_context, &one, + CEPH_PICK_ADDRESS_IPV4, "10.0.0.0/8", "eth1"); ASSERT_EQ((struct sockaddr*)&a_two, result); + + result = find_ip_in_subnet_list( + g_ceph_context, + &one, + CEPH_PICK_ADDRESS_IPV6, + "2001::/16", + "eth1"); + ASSERT_EQ((struct sockaddr*)&a_three, result); } -- 2.39.5