X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Ftest%2Ftest_ipaddr.cc;fp=src%2Fceph%2Fsrc%2Ftest%2Ftest_ipaddr.cc;h=8cd0281af157f611dee9d8000da329e0a4de1fb6;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/test/test_ipaddr.cc b/src/ceph/src/test/test_ipaddr.cc new file mode 100644 index 0000000..8cd0281 --- /dev/null +++ b/src/ceph/src/test/test_ipaddr.cc @@ -0,0 +1,590 @@ +#include "include/ipaddr.h" +#include "common/pick_address.h" +#include "global/global_context.h" +#include "gtest/gtest.h" + +#if defined(__FreeBSD__) +#include +#include +#include +#endif +#include +#include + +static void ipv4(struct sockaddr_in *addr, const char *s) { + int err; + + addr->sin_family = AF_INET; + err = inet_pton(AF_INET, s, &addr->sin_addr); + ASSERT_EQ(1, err); +} + +static void ipv6(struct sockaddr_in6 *addr, const char *s) { + int err; + + addr->sin6_family = AF_INET6; + err = inet_pton(AF_INET6, s, &addr->sin6_addr); + ASSERT_EQ(1, err); +} + +static char eth0[] = "eth0"; +static char eth1[] = "eth1"; + +TEST(CommonIPAddr, TestNotFound) +{ + struct ifaddrs one, two; + struct sockaddr_in a_one; + struct sockaddr_in6 a_two; + struct sockaddr_in net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = &two; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + two.ifa_next = NULL; + two.ifa_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv4(&a_one, "10.11.12.13"); + ipv6(&a_two, "2001:1234:5678:90ab::cdef"); + ipv4(&net, "10.11.234.56"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 24); + ASSERT_EQ(0, result); +} + +TEST(CommonIPAddr, TestV4_Simple) +{ + struct ifaddrs one, two; + struct sockaddr_in a_one; + struct sockaddr_in6 a_two; + struct sockaddr_in net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = &two; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + two.ifa_next = NULL; + two.ifa_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv4(&a_one, "10.11.12.13"); + ipv6(&a_two, "2001:1234:5678:90ab::cdef"); + ipv4(&net, "10.11.12.42"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 24); + ASSERT_EQ((struct sockaddr*)&a_one, result->ifa_addr); +} + +TEST(CommonIPAddr, TestV4_Prefix25) +{ + struct ifaddrs one, two; + struct sockaddr_in a_one; + struct sockaddr_in a_two; + struct sockaddr_in net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = &two; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + two.ifa_next = NULL; + two.ifa_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv4(&a_one, "10.11.12.13"); + ipv4(&a_two, "10.11.12.129"); + ipv4(&net, "10.11.12.128"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 25); + ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr); +} + +TEST(CommonIPAddr, TestV4_Prefix16) +{ + struct ifaddrs one, two; + struct sockaddr_in a_one; + struct sockaddr_in a_two; + struct sockaddr_in net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = &two; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + two.ifa_next = NULL; + two.ifa_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv4(&a_one, "10.1.1.2"); + ipv4(&a_two, "10.2.1.123"); + ipv4(&net, "10.2.0.0"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 16); + ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr); +} + +TEST(CommonIPAddr, TestV4_PrefixTooLong) +{ + struct ifaddrs one; + struct sockaddr_in a_one; + struct sockaddr_in net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = NULL; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + ipv4(&a_one, "10.11.12.13"); + ipv4(&net, "10.11.12.12"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 42); + ASSERT_EQ(0, result); +} + +TEST(CommonIPAddr, TestV4_PrefixZero) +{ + struct ifaddrs one, two; + struct sockaddr_in6 a_one; + struct sockaddr_in a_two; + struct sockaddr_in net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = &two; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + two.ifa_next = NULL; + two.ifa_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv6(&a_one, "2001:1234:5678:900F::cdef"); + ipv4(&a_two, "10.1.2.3"); + ipv4(&net, "255.0.1.2"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 0); + ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr); +} + +TEST(CommonIPAddr, TestV6_Simple) +{ + struct ifaddrs one, two; + struct sockaddr_in a_one; + struct sockaddr_in6 a_two; + struct sockaddr_in6 net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = &two; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + two.ifa_next = NULL; + two.ifa_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv4(&a_one, "10.11.12.13"); + ipv6(&a_two, "2001:1234:5678:90ab::cdef"); + ipv6(&net, "2001:1234:5678:90ab::dead:beef"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 64); + ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr); +} + +TEST(CommonIPAddr, TestV6_Prefix57) +{ + struct ifaddrs one, two; + struct sockaddr_in6 a_one; + struct sockaddr_in6 a_two; + struct sockaddr_in6 net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = &two; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + two.ifa_next = NULL; + two.ifa_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv6(&a_one, "2001:1234:5678:900F::cdef"); + ipv6(&a_two, "2001:1234:5678:90ab::cdef"); + ipv6(&net, "2001:1234:5678:90ab::dead:beef"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 57); + ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr); +} + +TEST(CommonIPAddr, TestV6_PrefixTooLong) +{ + struct ifaddrs one; + struct sockaddr_in6 a_one; + struct sockaddr_in6 net; + const struct ifaddrs *result; + + memset(&net, '0', sizeof(net)); + + one.ifa_next = NULL; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + ipv6(&a_one, "2001:1234:5678:900F::cdef"); + ipv6(&net, "2001:1234:5678:900F::cdee"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 9000); + ASSERT_EQ(0, result); +} + +TEST(CommonIPAddr, TestV6_PrefixZero) +{ + struct ifaddrs one, two; + struct sockaddr_in a_one; + struct sockaddr_in6 a_two; + struct sockaddr_in6 net; + const struct ifaddrs *result; + + one.ifa_next = &two; + one.ifa_addr = (struct sockaddr*)&a_one; + one.ifa_name = eth0; + + two.ifa_next = NULL; + two.ifa_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv4(&a_one, "10.2.3.4"); + ipv6(&a_two, "2001:f00b::1"); + ipv6(&net, "ff00::1"); + + result = find_ip_in_subnet(&one, (struct sockaddr*)&net, 0); + ASSERT_EQ((struct sockaddr*)&a_two, result->ifa_addr); +} + +TEST(CommonIPAddr, ParseNetwork_Empty) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_Junk) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("foo", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_SlashNum) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("/24", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_Slash) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("/", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_IPv4) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("123.123.123.123", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_IPv4Slash) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("123.123.123.123/", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_IPv4SlashNegative) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("123.123.123.123/-3", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_IPv4SlashJunk) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("123.123.123.123/foo", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_IPv6) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("2001:1234:5678:90ab::dead:beef", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_IPv6Slash) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("2001:1234:5678:90ab::dead:beef/", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_IPv6SlashNegative) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("2001:1234:5678:90ab::dead:beef/-3", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_Bad_IPv6SlashJunk) +{ + struct sockaddr_storage network; + unsigned int prefix_len; + bool ok; + + ok = parse_network("2001:1234:5678:90ab::dead:beef/foo", &network, &prefix_len); + ASSERT_EQ(ok, false); +} + +TEST(CommonIPAddr, ParseNetwork_IPv4_0) +{ + struct sockaddr_in network; + struct sockaddr_storage net_storage; + unsigned int prefix_len; + bool ok; + + ok = parse_network("123.123.123.123/0", &net_storage, &prefix_len); + network = *(struct sockaddr_in *) &net_storage; + ASSERT_EQ(ok, true); + ASSERT_EQ(0U, prefix_len); + ASSERT_EQ(AF_INET, network.sin_family); + ASSERT_EQ(0, network.sin_port); + struct sockaddr_in want; + ipv4(&want, "123.123.123.123"); + ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr); +} + +TEST(CommonIPAddr, ParseNetwork_IPv4_13) +{ + struct sockaddr_in network; + struct sockaddr_storage net_storage; + unsigned int prefix_len; + bool ok; + + ok = parse_network("123.123.123.123/13", &net_storage, &prefix_len); + network = *(struct sockaddr_in *) &net_storage; + ASSERT_EQ(ok, true); + ASSERT_EQ(13U, prefix_len); + ASSERT_EQ(AF_INET, network.sin_family); + ASSERT_EQ(0, network.sin_port); + struct sockaddr_in want; + ipv4(&want, "123.123.123.123"); + ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr); +} + +TEST(CommonIPAddr, ParseNetwork_IPv4_32) +{ + struct sockaddr_in network; + struct sockaddr_storage net_storage; + unsigned int prefix_len; + bool ok; + + ok = parse_network("123.123.123.123/32", &net_storage, &prefix_len); + network = *(struct sockaddr_in *) &net_storage; + ASSERT_EQ(ok, true); + ASSERT_EQ(32U, prefix_len); + ASSERT_EQ(AF_INET, network.sin_family); + ASSERT_EQ(0, network.sin_port); + struct sockaddr_in want; + ipv4(&want, "123.123.123.123"); + ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr); +} + +TEST(CommonIPAddr, ParseNetwork_IPv4_42) +{ + struct sockaddr_in network; + struct sockaddr_storage net_storage; + unsigned int prefix_len; + bool ok; + + ok = parse_network("123.123.123.123/42", &net_storage, &prefix_len); + network = *(struct sockaddr_in *) &net_storage; + ASSERT_EQ(ok, true); + ASSERT_EQ(42U, prefix_len); + ASSERT_EQ(AF_INET, network.sin_family); + ASSERT_EQ(0, network.sin_port); + struct sockaddr_in want; + ipv4(&want, "123.123.123.123"); + ASSERT_EQ(want.sin_addr.s_addr, network.sin_addr.s_addr); +} + +TEST(CommonIPAddr, ParseNetwork_IPv6_0) +{ + struct sockaddr_in6 network; + struct sockaddr_storage net_storage; + unsigned int prefix_len; + bool ok; + + ok = parse_network("2001:1234:5678:90ab::dead:beef/0", &net_storage, &prefix_len); + network = *(struct sockaddr_in6 *) &net_storage; + ASSERT_EQ(ok, true); + ASSERT_EQ(0U, prefix_len); + ASSERT_EQ(AF_INET6, network.sin6_family); + ASSERT_EQ(0, network.sin6_port); + struct sockaddr_in6 want; + ipv6(&want, "2001:1234:5678:90ab::dead:beef"); + ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr))); +} + +TEST(CommonIPAddr, ParseNetwork_IPv6_67) +{ + struct sockaddr_in6 network; + struct sockaddr_storage net_storage; + unsigned int prefix_len; + bool ok; + + ok = parse_network("2001:1234:5678:90ab::dead:beef/67", &net_storage, &prefix_len); + network = *(struct sockaddr_in6 *) &net_storage; + ASSERT_EQ(ok, true); + ASSERT_EQ(67U, prefix_len); + ASSERT_EQ(AF_INET6, network.sin6_family); + ASSERT_EQ(0, network.sin6_port); + struct sockaddr_in6 want; + ipv6(&want, "2001:1234:5678:90ab::dead:beef"); + ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr))); +} + +TEST(CommonIPAddr, ParseNetwork_IPv6_128) +{ + struct sockaddr_in6 network; + struct sockaddr_storage net_storage; + unsigned int prefix_len; + bool ok; + + ok = parse_network("2001:1234:5678:90ab::dead:beef/128", &net_storage, &prefix_len); + network = *(struct sockaddr_in6 *) &net_storage; + ASSERT_EQ(ok, true); + ASSERT_EQ(128U, prefix_len); + ASSERT_EQ(AF_INET6, network.sin6_family); + ASSERT_EQ(0, network.sin6_port); + struct sockaddr_in6 want; + ipv6(&want, "2001:1234:5678:90ab::dead:beef"); + ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr))); +} + +TEST(CommonIPAddr, ParseNetwork_IPv6_9000) +{ + struct sockaddr_in6 network; + struct sockaddr_storage net_storage; + unsigned int prefix_len; + bool ok; + + ok = parse_network("2001:1234:5678:90ab::dead:beef/9000", &net_storage, &prefix_len); + network = *(struct sockaddr_in6 *) &net_storage; + ASSERT_EQ(ok, true); + ASSERT_EQ(9000U, prefix_len); + ASSERT_EQ(AF_INET6, network.sin6_family); + ASSERT_EQ(0, network.sin6_port); + struct sockaddr_in6 want; + ipv6(&want, "2001:1234:5678:90ab::dead:beef"); + ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr))); +} + +TEST(pick_address, find_ip_in_subnet_list) +{ + struct ifaddrs one, two; + struct sockaddr_in a_one; + struct sockaddr_in a_two; + 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_addr = (struct sockaddr*)&a_two; + two.ifa_name = eth1; + + ipv4(&a_one, "10.1.1.2"); + ipv4(&a_two, "10.2.1.123"); + + // match by network + result = find_ip_in_subnet_list( + g_ceph_context, + &one, + "10.1.0.0/16", + "eth0"); + ASSERT_EQ((struct sockaddr*)&a_one, result); + + result = find_ip_in_subnet_list( + g_ceph_context, + &one, + "10.2.0.0/16", + "eth1"); + ASSERT_EQ((struct sockaddr*)&a_two, result); + + // match by eth name + result = find_ip_in_subnet_list( + g_ceph_context, + &one, + "10.0.0.0/8", + "eth0"); + ASSERT_EQ((struct sockaddr*)&a_one, result); + + result = find_ip_in_subnet_list( + g_ceph_context, + &one, + "10.0.0.0/8", + "eth1"); + ASSERT_EQ((struct sockaddr*)&a_two, result); +}