summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2019-01-06 21:00:32 -0800
committerandroid-build-merger <android-build-merger@google.com>2019-01-06 21:00:32 -0800
commitf8b9b7d17da0e2f7c1823715303f1bcce3b4e66c (patch)
treeab6193bf151756a59faa9b69819753e1f1770833
parente3924ff1e94e3b503b4e595e06842950e0fd104d (diff)
parent210b0dd705a4ca24fc519c200bab6219f602e952 (diff)
downloadplatform_external_android-clat-f8b9b7d17da0e2f7c1823715303f1bcce3b4e66c.tar.gz
platform_external_android-clat-f8b9b7d17da0e2f7c1823715303f1bcce3b4e66c.tar.bz2
platform_external_android-clat-f8b9b7d17da0e2f7c1823715303f1bcce3b4e66c.zip
Drop support for updating IPv6 addresses in clatd. am: 66deecd38f am: 8f81d511b1
am: 210b0dd705 Change-Id: Ib4290a671f7f3266f8dd0c17a1b5e5a4dcbbb123
-rw-r--r--clatd.c57
-rw-r--r--clatd.h2
-rw-r--r--clatd_test.cpp37
-rw-r--r--main.c3
4 files changed, 71 insertions, 28 deletions
diff --git a/clatd.c b/clatd.c
index 2ef10a5..bcbd9c5 100644
--- a/clatd.c
+++ b/clatd.c
@@ -228,13 +228,36 @@ void open_sockets(struct tun_data *tunnel, uint32_t mark) {
}
}
-/* function: update_clat_ipv6_address
+int ipv6_address_changed(const char *interface) {
+ union anyip *interface_ip;
+
+ interface_ip = getinterface_ip(interface, AF_INET6);
+ if (!interface_ip) {
+ logmsg(ANDROID_LOG_ERROR, "Unable to find an IPv6 address on interface %s", interface);
+ return 1;
+ }
+
+ if (!ipv6_prefix_equal(&interface_ip->ip6, &Global_Clatd_Config.ipv6_local_subnet)) {
+ char oldstr[INET6_ADDRSTRLEN];
+ char newstr[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, oldstr, sizeof(oldstr));
+ inet_ntop(AF_INET6, &interface_ip->ip6, newstr, sizeof(newstr));
+ logmsg(ANDROID_LOG_INFO, "IPv6 prefix on %s changed: %s -> %s", interface, oldstr, newstr);
+ free(interface_ip);
+ return 1;
+ } else {
+ free(interface_ip);
+ return 0;
+ }
+}
+
+/* function: configure_clat_ipv6_address
* picks the clat IPv6 address and configures packet translation to use it.
* tunnel - tun device data
* interface - uplink interface name
* returns: 1 on success, 0 on failure
*/
-int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interface) {
+int configure_clat_ipv6_address(const struct tun_data *tunnel, const char *interface) {
union anyip *interface_ip;
char addrstr[INET6_ADDRSTRLEN];
@@ -245,27 +268,10 @@ int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interfac
return 0;
}
- // If our prefix hasn't changed, do nothing. (If this is the first time we configure an IPv6
- // address, Global_Clatd_Config.ipv6_local_subnet will be ::, which won't match our new prefix.)
- if (ipv6_prefix_equal(&interface_ip->ip6, &Global_Clatd_Config.ipv6_local_subnet)) {
- free(interface_ip);
- return 1;
- }
-
// Generate an interface ID.
config_generate_local_ipv6_subnet(&interface_ip->ip6);
inet_ntop(AF_INET6, &interface_ip->ip6, addrstr, sizeof(addrstr));
-
- if (IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_local_subnet)) {
- // Startup.
- logmsg(ANDROID_LOG_INFO, "Using IPv6 address %s on %s", addrstr, interface);
- } else {
- // Prefix change.
- char from_addr[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, from_addr, sizeof(from_addr));
- logmsg(ANDROID_LOG_INFO, "clat IPv6 address changed from %s to %s", from_addr, addrstr);
- del_anycast_address(tunnel->write_fd6, &Global_Clatd_Config.ipv6_local_subnet);
- }
+ logmsg(ANDROID_LOG_INFO, "Using IPv6 address %s on %s", addrstr, interface);
// Start translating packets to the new prefix.
Global_Clatd_Config.ipv6_local_subnet = interface_ip->ip6;
@@ -276,7 +282,7 @@ int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interfac
if (!configure_packet_socket(tunnel->read_fd6)) {
// Things aren't going to work. Bail out and hope we have better luck next time.
// We don't log an error here because configure_packet_socket has already done so.
- exit(1);
+ return 0;
}
return 1;
@@ -330,6 +336,10 @@ void configure_interface(const char *uplink_interface, const char *plat_prefix,
}
configure_tun_ip(tunnel);
+
+ if (!configure_clat_ipv6_address(tunnel, uplink_interface)) {
+ exit(1);
+ }
}
/* function: read_packet
@@ -418,8 +428,9 @@ void event_loop(struct tun_data *tunnel) {
time_t now = time(NULL);
if (last_interface_poll < (now - INTERFACE_POLL_FREQUENCY)) {
- update_clat_ipv6_address(tunnel, Global_Clatd_Config.default_pdp_interface);
- last_interface_poll = now;
+ if (ipv6_address_changed(Global_Clatd_Config.default_pdp_interface)) {
+ break;
+ }
}
}
}
diff --git a/clatd.h b/clatd.h
index 32f8cd5..67ba990 100644
--- a/clatd.h
+++ b/clatd.h
@@ -39,7 +39,7 @@ void set_capability(uint64_t target_cap);
void drop_root_but_keep_caps();
void open_sockets(struct tun_data *tunnel, uint32_t mark);
int ipv6_address_changed(const char *interface);
-int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interface);
+int configure_clat_ipv6_address(const struct tun_data *tunnel, const char *interface);
void configure_interface(const char *uplink_interface, const char *plat_prefix,
struct tun_data *tunnel, unsigned net_id);
void event_loop(struct tun_data *tunnel);
diff --git a/clatd_test.cpp b/clatd_test.cpp
index 4f998ea..81af41d 100644
--- a/clatd_test.cpp
+++ b/clatd_test.cpp
@@ -24,6 +24,8 @@
#include <sys/uio.h>
#include <gtest/gtest.h>
+
+#include "netutils/ifc.h"
#include "tun_interface.h"
extern "C" {
@@ -963,16 +965,16 @@ TEST_F(ClatdTest, GetInterfaceIp) {
expect_ipv6_addr_equal(&expected, &actual);
}
-TEST_F(ClatdTest, UpdateIpv6Address) {
+TEST_F(ClatdTest, ConfigureIpv6Address) {
// 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.
+ // Run configure_clat_ipv6_address.
ASSERT_TRUE(IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_local_subnet));
- ASSERT_EQ(1, update_clat_ipv6_address(&tunnel, sTun.name().c_str()));
+ ASSERT_EQ(1, configure_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.
@@ -990,3 +992,32 @@ TEST_F(ClatdTest, UpdateIpv6Address) {
EXPECT_EQ(htons(ETH_P_IPV6), sll.sll_protocol);
EXPECT_EQ(sll.sll_ifindex, sTun.ifindex());
}
+
+TEST_F(ClatdTest, Ipv6AddressChanged) {
+ // Configure the clat IPv6 address.
+ 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)),
+ };
+ const char *ifname = sTun.name().c_str();
+ ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, ifname));
+ EXPECT_EQ(0, ipv6_address_changed(ifname));
+ EXPECT_EQ(0, ipv6_address_changed(ifname));
+
+ // Change the IP address on the tun interface to a new prefix.
+ char srcaddr[INET6_ADDRSTRLEN];
+ char dstaddr[INET6_ADDRSTRLEN];
+ ASSERT_NE(nullptr, inet_ntop(AF_INET6, &sTun.srcAddr(), srcaddr, sizeof(srcaddr)));
+ ASSERT_NE(nullptr, inet_ntop(AF_INET6, &sTun.dstAddr(), dstaddr, sizeof(dstaddr)));
+ EXPECT_EQ(0, ifc_del_address(ifname, srcaddr, 64));
+ EXPECT_EQ(0, ifc_del_address(ifname, dstaddr, 64));
+
+ // Check that we can tell that the address has changed.
+ EXPECT_EQ(0, ifc_add_address(ifname, "2001:db8::1:2", 64));
+ EXPECT_EQ(1, ipv6_address_changed(ifname));
+ EXPECT_EQ(1, ipv6_address_changed(ifname));
+
+ // Restore the tun interface configuration.
+ sTun.destroy();
+ ASSERT_EQ(0, sTun.init());
+}
diff --git a/main.c b/main.c
index e717498..11c51a5 100644
--- a/main.c
+++ b/main.c
@@ -127,7 +127,8 @@ int main(int argc, char **argv) {
configure_interface(uplink_interface, plat_prefix, &tunnel, net_id);
- update_clat_ipv6_address(&tunnel, uplink_interface);
+ // Drop all remaining capabilities.
+ set_capability(0);
// Loop until someone sends us a signal or brings down the tun interface.
if (signal(SIGTERM, stop_loop) == SIG_ERR) {