]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/test/test_ipaddr.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / test_ipaddr.cc
index 8cd0281af157f611dee9d8000da329e0a4de1fb6..2fc5d48398671fae26e9c5e1ca367b9891a945cd 100644 (file)
@@ -2,6 +2,8 @@
 #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>
@@ -38,7 +40,7 @@ TEST(CommonIPAddr, TestNotFound)
   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;
@@ -64,7 +66,7 @@ TEST(CommonIPAddr, TestV4_Simple)
   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;
@@ -90,7 +92,7 @@ TEST(CommonIPAddr, TestV4_Prefix25)
   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;
@@ -116,7 +118,7 @@ TEST(CommonIPAddr, TestV4_Prefix16)
   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;
@@ -141,7 +143,7 @@ TEST(CommonIPAddr, TestV4_PrefixTooLong)
   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;
@@ -162,7 +164,7 @@ TEST(CommonIPAddr, TestV4_PrefixZero)
   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;
@@ -188,8 +190,8 @@ TEST(CommonIPAddr, TestV6_Simple)
   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;
@@ -214,7 +216,7 @@ TEST(CommonIPAddr, TestV6_Prefix57)
   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;
@@ -239,7 +241,7 @@ TEST(CommonIPAddr, TestV6_PrefixTooLong)
   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;
@@ -540,28 +542,93 @@ TEST(CommonIPAddr, ParseNetwork_IPv6_9000)
   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);
@@ -569,6 +636,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 +645,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 +653,278 @@ 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);
+}
+
+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);
+  }
 }
+