#include "common/pick_address.h"
#include "global/global_context.h"
#include "gtest/gtest.h"
+#include "include/stringify.h"
+#include "common/ceph_context.h"
#if defined(__FreeBSD__)
#include <sys/types.h>
struct sockaddr_in net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
+ memset(&net, 0, sizeof(net));
one.ifa_next = &two;
one.ifa_addr = (struct sockaddr*)&a_one;
struct sockaddr_in net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
+ memset(&net, 0, sizeof(net));
one.ifa_next = &two;
one.ifa_addr = (struct sockaddr*)&a_one;
struct sockaddr_in net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
+ memset(&net, 0, sizeof(net));
one.ifa_next = &two;
one.ifa_addr = (struct sockaddr*)&a_one;
struct sockaddr_in net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
+ memset(&net, 0, sizeof(net));
one.ifa_next = &two;
one.ifa_addr = (struct sockaddr*)&a_one;
struct sockaddr_in net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
+ memset(&net, 0, sizeof(net));
one.ifa_next = NULL;
one.ifa_addr = (struct sockaddr*)&a_one;
struct sockaddr_in net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
+ memset(&net, 0, sizeof(net));
one.ifa_next = &two;
one.ifa_addr = (struct sockaddr*)&a_one;
struct sockaddr_in6 net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
-
+ memset(&net, 0, sizeof(net));
+
one.ifa_next = &two;
one.ifa_addr = (struct sockaddr*)&a_one;
one.ifa_name = eth0;
struct sockaddr_in6 net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
+ memset(&net, 0, sizeof(net));
one.ifa_next = &two;
one.ifa_addr = (struct sockaddr*)&a_one;
struct sockaddr_in6 net;
const struct ifaddrs *result;
- memset(&net, '0', sizeof(net));
+ memset(&net, 0, sizeof(net));
one.ifa_next = NULL;
one.ifa_addr = (struct sockaddr*)&a_one;
ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
}
+TEST(CommonIPAddr, ambiguous)
+{
+ entity_addr_t a;
+ bool ok;
+
+ ok = a.parse("1.2.3.4", nullptr, entity_addr_t::TYPE_ANY);
+ ASSERT_TRUE(ok);
+ ASSERT_EQ(entity_addr_t::TYPE_ANY, a.get_type());
+
+ ok = a.parse("any:1.2.3.4", nullptr, entity_addr_t::TYPE_ANY);
+ ASSERT_TRUE(ok);
+ ASSERT_EQ(entity_addr_t::TYPE_ANY, a.get_type());
+
+ ok = a.parse("v1:1.2.3.4", nullptr, entity_addr_t::TYPE_ANY);
+ ASSERT_TRUE(ok);
+ ASSERT_EQ(entity_addr_t::TYPE_LEGACY, a.get_type());
+
+ ok = a.parse("v2:1.2.3.4", nullptr, entity_addr_t::TYPE_ANY);
+ ASSERT_TRUE(ok);
+ ASSERT_EQ(entity_addr_t::TYPE_MSGR2, a.get_type());
+}
+
+TEST(CommonIPAddr, network_contains)
+{
+ entity_addr_t network, addr;
+ unsigned int prefix;
+ bool ok;
+
+ ok = parse_network("2001:1234:5678:90ab::dead:beef/32", &network, &prefix);
+ ASSERT_TRUE(ok);
+ ASSERT_EQ(32U, prefix);
+ ok = addr.parse("2001:1234:5678:90ab::dead:beef", nullptr);
+ ASSERT_TRUE(ok);
+ ASSERT_TRUE(network_contains(network, prefix, addr));
+ ok = addr.parse("2001:1334:5678:90ab::dead:beef", nullptr);
+ ASSERT_TRUE(ok);
+ ASSERT_FALSE(network_contains(network, prefix, addr));
+ ok = addr.parse("127.0.0.1", nullptr);
+ ASSERT_TRUE(ok);
+ ASSERT_FALSE(network_contains(network, prefix, addr));
+
+ ok = parse_network("10.1.2.3/16", &network, &prefix);
+ ASSERT_TRUE(ok);
+ ASSERT_EQ(16U, prefix);
+ ok = addr.parse("2001:1234:5678:90ab::dead:beef", nullptr);
+ ASSERT_TRUE(ok);
+ ASSERT_FALSE(network_contains(network, prefix, addr));
+ ok = addr.parse("1.2.3.4", nullptr);
+ ASSERT_TRUE(ok);
+ ASSERT_FALSE(network_contains(network, prefix, addr));
+ ok = addr.parse("10.1.22.44", nullptr);
+ ASSERT_TRUE(ok);
+ ASSERT_TRUE(network_contains(network, prefix, addr));
+ ok = addr.parse("10.2.22.44", nullptr);
+ ASSERT_TRUE(ok);
+ ASSERT_FALSE(network_contains(network, prefix, addr));
+}
+
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);
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);
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);
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);
+}
+
+TEST(pick_address, filtering)
+{
+ struct ifaddrs one, two, three;
+ struct sockaddr_in a_one;
+ struct sockaddr_in a_two;
+ struct sockaddr_in6 a_three;
+
+ one.ifa_next = &two;
+ one.ifa_addr = (struct sockaddr*)&a_one;
+ one.ifa_name = eth0;
+
+ 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");
+
+ CephContext *cct = new CephContext(CEPH_ENTITY_TYPE_MON);
+ cct->_conf._clear_safe_to_start_threads(); // so we can set configs
+
+ cct->_conf.set_val("public_addr", "");
+ cct->_conf.set_val("public_network", "");
+ cct->_conf.set_val("public_network_interface", "");
+ cct->_conf.set_val("cluster_addr", "");
+ cct->_conf.set_val("cluster_network", "");
+ cct->_conf.set_val("cluster_network_interface", "");
+
+ entity_addrvec_t av;
+ {
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV4 |
+ CEPH_PICK_ADDRESS_MSGR1,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(1u, av.v.size());
+ ASSERT_EQ(string("v1:0.0.0.0:0/0"), stringify(av.v[0]));
+ }
+ {
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV6 |
+ CEPH_PICK_ADDRESS_MSGR1,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(1u, av.v.size());
+ ASSERT_EQ(string("v1:[::]:0/0"), stringify(av.v[0]));
+ }
+ {
+ cct->_conf.set_val("public_network", "10.2.0.0/16");
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV4 |
+ CEPH_PICK_ADDRESS_MSGR1,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(1u, av.v.size());
+ ASSERT_EQ(string("v1:10.2.1.123:0/0"), stringify(av.v[0]));
+ cct->_conf.set_val("public_network", "");
+ }
+ {
+ cct->_conf.set_val("public_network", "10.0.0.0/8");
+ cct->_conf.set_val("public_network_interface", "eth1");
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV4 |
+ CEPH_PICK_ADDRESS_MSGR2,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(1u, av.v.size());
+ ASSERT_EQ(string("v2:10.2.1.123:0/0"), stringify(av.v[0]));
+ cct->_conf.set_val("public_network", "");
+ cct->_conf.set_val("public_network_interface", "");
+ }
+ {
+ cct->_conf.set_val("public_network", "10.2.0.0/16");
+ cct->_conf.set_val("cluster_network", "10.1.0.0/16");
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV4 |
+ CEPH_PICK_ADDRESS_MSGR2,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(1u, av.v.size());
+ ASSERT_EQ(string("v2:10.2.1.123:0/0"), stringify(av.v[0]));
+ cct->_conf.set_val("public_network", "");
+ cct->_conf.set_val("cluster_network", "");
+ }
+ {
+ cct->_conf.set_val("public_network", "10.2.0.0/16");
+ cct->_conf.set_val("cluster_network", "10.1.0.0/16");
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_CLUSTER |
+ CEPH_PICK_ADDRESS_IPV4 |
+ CEPH_PICK_ADDRESS_MSGR1,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(1u, av.v.size());
+ ASSERT_EQ(string("v1:10.1.1.2:0/0"), stringify(av.v[0]));
+ cct->_conf.set_val("public_network", "");
+ cct->_conf.set_val("cluster_network", "");
+ }
+
+ {
+ cct->_conf.set_val("public_network", "2001::/16");
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV6 |
+ CEPH_PICK_ADDRESS_MSGR2,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(1u, av.v.size());
+ ASSERT_EQ(string("v2:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[0]));
+ cct->_conf.set_val("public_network", "");
+ }
+ {
+ cct->_conf.set_val("public_network", "2001::/16 10.0.0.0/8");
+ cct->_conf.set_val("public_network_interface", "eth1");
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV4 |
+ CEPH_PICK_ADDRESS_IPV6 |
+ CEPH_PICK_ADDRESS_MSGR2,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(2u, av.v.size());
+ ASSERT_EQ(string("v2:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[0]));
+ ASSERT_EQ(string("v2:10.2.1.123:0/0"), stringify(av.v[1]));
+ cct->_conf.set_val("public_network", "");
+ cct->_conf.set_val("public_network_interface", "");
+ }
+ {
+ cct->_conf.set_val("public_network", "2001::/16 10.0.0.0/8");
+ cct->_conf.set_val("public_network_interface", "eth1");
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV4 |
+ CEPH_PICK_ADDRESS_IPV6 |
+ CEPH_PICK_ADDRESS_MSGR1 |
+ CEPH_PICK_ADDRESS_PREFER_IPV4,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(2u, av.v.size());
+ ASSERT_EQ(string("v1:10.2.1.123:0/0"), stringify(av.v[0]));
+ ASSERT_EQ(string("v1:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[1]));
+ cct->_conf.set_val("public_network", "");
+ cct->_conf.set_val("public_network_interface", "");
+ }
+
+ {
+ cct->_conf.set_val("public_network", "2001::/16");
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV6 |
+ CEPH_PICK_ADDRESS_MSGR1 |
+ CEPH_PICK_ADDRESS_MSGR2,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(2u, av.v.size());
+ ASSERT_EQ(string("v2:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[0]));
+ ASSERT_EQ(string("v1:[2001:1234:5678:90ab::cdef]:0/0"), stringify(av.v[1]));
+ cct->_conf.set_val("public_network", "");
+ }
+
+ {
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_IPV4 |
+ CEPH_PICK_ADDRESS_MSGR1 |
+ CEPH_PICK_ADDRESS_MSGR2,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(2u, av.v.size());
+ ASSERT_EQ(string("v2:0.0.0.0:0/0"), stringify(av.v[0]));
+ ASSERT_EQ(string("v1:0.0.0.0:0/0"), stringify(av.v[1]));
+ }
+}
+
+TEST(pick_address, ipv4_ipv6_enabled)
+{
+ struct ifaddrs one;
+ struct sockaddr_in a_one;
+
+ one.ifa_next = NULL;
+ one.ifa_addr = (struct sockaddr*)&a_one;
+ one.ifa_name = eth0;
+
+ ipv4(&a_one, "10.1.1.2");
+
+ CephContext *cct = new CephContext(CEPH_ENTITY_TYPE_OSD);
+ cct->_conf._clear_safe_to_start_threads(); // so we can set configs
+
+ cct->_conf.set_val("public_addr", "");
+ cct->_conf.set_val("public_network", "10.1.1.0/24");
+ cct->_conf.set_val("public_network_interface", "");
+ cct->_conf.set_val("cluster_addr", "");
+ cct->_conf.set_val("cluster_network", "");
+ cct->_conf.set_val("cluster_network_interface", "");
+ cct->_conf.set_val("ms_bind_ipv6", "true");
+
+ entity_addrvec_t av;
+ {
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_MSGR1,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(-1, r);
+ }
+}
+
+TEST(pick_address, ipv4_ipv6_enabled2)
+{
+ struct ifaddrs one;
+ struct sockaddr_in6 a_one;
+
+ one.ifa_next = NULL;
+ one.ifa_addr = (struct sockaddr*)&a_one;
+ one.ifa_name = eth0;
+
+ ipv6(&a_one, "2001:1234:5678:90ab::cdef");
+
+ CephContext *cct = new CephContext(CEPH_ENTITY_TYPE_OSD);
+ cct->_conf._clear_safe_to_start_threads(); // so we can set configs
+
+ cct->_conf.set_val("public_addr", "");
+ cct->_conf.set_val("public_network", "2001::/16");
+ cct->_conf.set_val("public_network_interface", "");
+ cct->_conf.set_val("cluster_addr", "");
+ cct->_conf.set_val("cluster_network", "");
+ cct->_conf.set_val("cluster_network_interface", "");
+ cct->_conf.set_val("ms_bind_ipv6", "true");
+
+ entity_addrvec_t av;
+ {
+ int r = pick_addresses(cct,
+ CEPH_PICK_ADDRESS_PUBLIC |
+ CEPH_PICK_ADDRESS_MSGR1,
+ &one, &av);
+ cout << av << std::endl;
+ ASSERT_EQ(-1, r);
+ }
}
+