summaryrefslogtreecommitdiffstats
path: root/clatd_test.cpp
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2019-01-06 21:00:28 -0800
committerandroid-build-merger <android-build-merger@google.com>2019-01-06 21:00:28 -0800
commite3924ff1e94e3b503b4e595e06842950e0fd104d (patch)
treecc5d68a0042a890e28aaf7b6aa0d13fa6d9bc14d /clatd_test.cpp
parent9e10d3dba8b8f6f81ea736295881a6b541570bb5 (diff)
parent2dc24135b48ebd612b73e31b14e04ec5366f44b8 (diff)
downloadplatform_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
Diffstat (limited to 'clatd_test.cpp')
-rw-r--r--clatd_test.cpp62
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());
+}