diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2019-01-06 21:00:28 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-01-06 21:00:28 -0800 |
commit | e3924ff1e94e3b503b4e595e06842950e0fd104d (patch) | |
tree | cc5d68a0042a890e28aaf7b6aa0d13fa6d9bc14d | |
parent | 9e10d3dba8b8f6f81ea736295881a6b541570bb5 (diff) | |
parent | 2dc24135b48ebd612b73e31b14e04ec5366f44b8 (diff) | |
download | platform_external_android-clat-e3924ff1e94e3b503b4e595e06842950e0fd104d.tar.gz platform_external_android-clat-e3924ff1e94e3b503b4e595e06842950e0fd104d.tar.bz2 platform_external_android-clat-e3924ff1e94e3b503b4e595e06842950e0fd104d.zip |
Test clatd methods that affect interface IP addresses. am: 72f770c4ad am: 20a5158d92
am: 2dc24135b4
Change-Id: Iff031bc23d4705c90c6d11e17c93ef39fc198e5b
-rw-r--r-- | clatd_test.cpp | 62 |
1 files changed, 60 insertions, 2 deletions
diff --git a/clatd_test.cpp b/clatd_test.cpp index 2a10101..4f998ea 100644 --- a/clatd_test.cpp +++ b/clatd_test.cpp @@ -24,17 +24,22 @@ #include <sys/uio.h> #include <gtest/gtest.h> +#include "tun_interface.h" extern "C" { #include "checksum.h" #include "clatd.h" #include "config.h" +#include "getaddr.h" #include "translate.h" +#include "tun.h" } // For convenience. #define ARRAYSIZE(x) sizeof((x)) / sizeof((x)[0]) +using android::net::TunInterface; + // Default translation parameters. static const char kIPv4LocalAddr[] = "192.0.0.4"; static const char kIPv6LocalAddr[] = "2001:db8:0:b11::464"; @@ -557,15 +562,26 @@ struct clat_config Global_Clatd_Config; class ClatdTest : public ::testing::Test { protected: + static TunInterface sTun; + virtual void SetUp() { inet_pton(AF_INET, kIPv4LocalAddr, &Global_Clatd_Config.ipv4_local_subnet); inet_pton(AF_INET6, kIPv6PlatSubnet, &Global_Clatd_Config.plat_subnet); - inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet); + memset(&Global_Clatd_Config.ipv6_local_subnet, 0, sizeof(in6_addr)); Global_Clatd_Config.ipv6_host_id = in6addr_any; Global_Clatd_Config.use_dynamic_iid = 1; + Global_Clatd_Config.default_pdp_interface = const_cast<char *>(sTun.name().c_str()); } + + // Static because setting up the tun interface takes about 40ms. + static void SetUpTestCase() { ASSERT_EQ(0, sTun.init()); } + + // Closing the socket removes the interface and IP addresses. + static void TearDownTestCase() { sTun.destroy(); } }; +TunInterface ClatdTest::sTun; + void expect_ipv6_addr_equal(struct in6_addr *expected, struct in6_addr *actual) { if (!IN6_ARE_ADDR_EQUAL(expected, actual)) { char expected_str[INET6_ADDRSTRLEN], actual_str[INET6_ADDRSTRLEN]; @@ -868,6 +884,9 @@ TEST_F(ClatdTest, AdjustChecksum) { } TEST_F(ClatdTest, Translate) { + // This test uses hardcoded packets so the clatd address must be fixed. + inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet); + uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD }; uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD }; fix_udp_checksum(udp_ipv4); @@ -886,6 +905,9 @@ TEST_F(ClatdTest, Translate) { } TEST_F(ClatdTest, Fragmentation) { + // This test uses hardcoded packets so the clatd address must be fixed. + inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet); + check_fragment_translation(kIPv4Fragments, kIPv4FragLengths, kIPv6Fragments, kIPv6FragLengths, ARRAYSIZE(kIPv4Fragments), "IPv4->IPv6 fragment translation"); @@ -914,7 +936,7 @@ TEST_F(ClatdTest, TranslateChecksumNeutral) { ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &Global_Clatd_Config.ipv6_local_subnet)); config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet); - ASSERT_NE((uint32_t)0x00000464, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); + ASSERT_NE(htonl((uint32_t)0x00000464), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); ASSERT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); // Check that translating UDP packets is checksum-neutral. First, IPv4. @@ -932,3 +954,39 @@ TEST_F(ClatdTest, TranslateChecksumNeutral) { check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20, "UDP/IPv4 -> UDP/IPv6 checksum neutral"); } + +TEST_F(ClatdTest, GetInterfaceIp) { + union anyip *ip = getinterface_ip(sTun.name().c_str(), AF_INET6); + ASSERT_NE(nullptr, ip); + in6_addr expected = sTun.srcAddr(); + in6_addr actual = ip->ip6; + expect_ipv6_addr_equal(&expected, &actual); +} + +TEST_F(ClatdTest, UpdateIpv6Address) { + // Create some fake but realistic-looking sockets so update_clat_ipv6_address doesn't balk. + struct tun_data tunnel = { + .write_fd6 = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW), + .read_fd6 = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)), + }; + + // Run update_clat_ipv6_address with no local IID yet picked. + ASSERT_TRUE(IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_local_subnet)); + ASSERT_EQ(1, update_clat_ipv6_address(&tunnel, sTun.name().c_str())); + + // Check that it generated an IID in the same prefix as the address assigned to the interface, + // and that the IID is not the default IID. + in6_addr addr = sTun.srcAddr(); + EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &addr)); + EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&Global_Clatd_Config.ipv6_local_subnet, &addr)); + EXPECT_NE(htonl((uint32_t)0x00000464), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); + EXPECT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); + + // Check that the packet socket is bound to the interface. We can't check the socket filter + // because there is no way to fetch it from the kernel. + sockaddr_ll sll; + socklen_t len = sizeof(sll); + ASSERT_EQ(0, getsockname(tunnel.read_fd6, reinterpret_cast<sockaddr *>(&sll), &len)); + EXPECT_EQ(htons(ETH_P_IPV6), sll.sll_protocol); + EXPECT_EQ(sll.sll_ifindex, sTun.ifindex()); +} |