diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2019-01-06 21:00:32 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-01-06 21:00:32 -0800 |
commit | f8b9b7d17da0e2f7c1823715303f1bcce3b4e66c (patch) | |
tree | ab6193bf151756a59faa9b69819753e1f1770833 | |
parent | e3924ff1e94e3b503b4e595e06842950e0fd104d (diff) | |
parent | 210b0dd705a4ca24fc519c200bab6219f602e952 (diff) | |
download | platform_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.c | 57 | ||||
-rw-r--r-- | clatd.h | 2 | ||||
-rw-r--r-- | clatd_test.cpp | 37 | ||||
-rw-r--r-- | main.c | 3 |
4 files changed, 71 insertions, 28 deletions
@@ -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; + } } } } @@ -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()); +} @@ -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) { |