summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2014-10-21 13:41:21 +0900
committerLorenzo Colitti <lorenzo@google.com>2014-10-29 11:53:05 +0900
commit1352a3a26c4d7c32b38b7fadb837799a23014aa6 (patch)
treebe714f0c749e3e6bfc7694dc1c95c5328c20c243
parent7612916deb5f40a8dcf3a31db8849450e146fc8d (diff)
downloadandroid_external_android-clat-1352a3a26c4d7c32b38b7fadb837799a23014aa6.tar.gz
android_external_android-clat-1352a3a26c4d7c32b38b7fadb837799a23014aa6.tar.bz2
android_external_android-clat-1352a3a26c4d7c32b38b7fadb837799a23014aa6.zip
Unduplicate IPv6 address setting code.
Currently, the IPv6 address gets set in two different codepaths depending on whether it's being configured on startup or happens because the interface changed its prefix. Refactor the two into a common function. Change-Id: I37035401bef7a57ff40540bd0f2aed0f6863269d
-rw-r--r--clatd.c95
-rw-r--r--config.c37
-rw-r--r--config.h3
3 files changed, 59 insertions, 76 deletions
diff --git a/clatd.c b/clatd.c
index f5d625d..78ccccc 100644
--- a/clatd.c
+++ b/clatd.c
@@ -150,42 +150,6 @@ int configure_packet_socket(int sock) {
return 1;
}
-/* function: interface_poll
- * polls the uplink network interface for address changes
- * tunnel - tun device data
- */
-void interface_poll(const struct tun_data *tunnel) {
- union anyip *interface_ip;
- char *interface = Global_Clatd_Config.default_pdp_interface;
-
- interface_ip = getinterface_ip(interface, AF_INET6);
- if(!interface_ip) {
- logmsg(ANDROID_LOG_WARN,"unable to find an ipv6 ip on interface %s", interface);
- return;
- }
-
- if(!ipv6_prefix_equal(&interface_ip->ip6, &Global_Clatd_Config.ipv6_local_subnet)) {
- config_generate_local_ipv6_subnet(&interface_ip->ip6);
-
- char from_addr[INET6_ADDRSTRLEN], to_addr[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, from_addr, sizeof(from_addr));
- inet_ntop(AF_INET6, &interface_ip->ip6, to_addr, sizeof(to_addr));
- logmsg(ANDROID_LOG_WARN, "clat IPv6 address changed from %s to %s", from_addr, to_addr);
-
- // Start translating packets to the new prefix.
- Global_Clatd_Config.ipv6_local_subnet = interface_ip->ip6;
-
- // Update our packet socket filter to reflect the new 464xlat IP address.
- 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);
- }
- }
-
- free(interface_ip);
-}
-
/* function: configure_tun_ip
* configures the ipv4 and ipv6 addresses on the tunnel interface
* tunnel - tun device data
@@ -275,6 +239,58 @@ void open_sockets(struct tun_data *tunnel, uint32_t mark) {
tunnel->read_fd6 = packetsock;
}
+/* function: update_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) {
+ union anyip *interface_ip;
+ char addrstr[INET6_ADDRSTRLEN];
+
+ // TODO: check that the prefix length is /64.
+ 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 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 %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);
+ }
+
+ // Start translating packets to the new prefix.
+ Global_Clatd_Config.ipv6_local_subnet = interface_ip->ip6;
+ free(interface_ip);
+
+ // Update our packet socket filter to reflect the new 464xlat IP address.
+ 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 1;
+}
+
/* function: configure_interface
* reads the configuration and applies it to the interface
* uplink_interface - network interface to use to reach the ipv6 internet
@@ -404,7 +420,7 @@ void event_loop(const struct tun_data *tunnel) {
time_t now = time(NULL);
if(last_interface_poll < (now - INTERFACE_POLL_FREQUENCY)) {
- interface_poll(tunnel);
+ update_clat_ipv6_address(tunnel, Global_Clatd_Config.default_pdp_interface);
last_interface_poll = now;
}
}
@@ -511,10 +527,7 @@ int main(int argc, char **argv) {
configure_interface(uplink_interface, plat_prefix, &tunnel, net_id);
- if (!configure_packet_socket(tunnel.read_fd6)) {
- // We've already logged an error.
- exit(1);
- }
+ update_clat_ipv6_address(&tunnel, uplink_interface);
// Loop until someone sends us a signal or brings down the tun interface.
if(signal(SIGTERM, stop_loop) == SIG_ERR) {
diff --git a/config.c b/config.c
index 09d3df0..4939478 100644
--- a/config.c
+++ b/config.c
@@ -229,36 +229,6 @@ void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip) {
}
}
-/* function: subnet_from_interface
- * finds the ipv6 subnet configured on the specified interface
- * root - parsed configuration
- * interface - network interface name
- */
-int subnet_from_interface(cnode *root, const char *interface) {
- union anyip *interface_ip;
- char addrstr[INET6_ADDRSTRLEN];
-
- if(!config_item_ip6(root, "ipv6_host_id", "::", &Global_Clatd_Config.ipv6_host_id))
- return 0;
-
- // TODO: check that the prefix length is /64.
- interface_ip = getinterface_ip(interface, AF_INET6);
- if(!interface_ip) {
- logmsg(ANDROID_LOG_FATAL,"unable to find an ipv6 ip on interface %s",interface);
- return 0;
- }
-
- memcpy(&Global_Clatd_Config.ipv6_local_subnet, &interface_ip->ip6, sizeof(struct in6_addr));
- free(interface_ip);
-
- config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet);
-
- inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, addrstr, sizeof(addrstr));
- logmsg(ANDROID_LOG_INFO, "Using %s on %s", addrstr, interface);
-
- return 1;
-}
-
/* function: read_config
* reads the config file and parses it into the global variable Global_Clatd_Config. returns 0 on failure, 1 on success
* file - filename to parse
@@ -284,7 +254,9 @@ int read_config(const char *file, const char *uplink_interface, const char *plat
goto failed;
}
- strncpy(Global_Clatd_Config.default_pdp_interface, uplink_interface, sizeof(Global_Clatd_Config.default_pdp_interface));
+ Global_Clatd_Config.default_pdp_interface = strdup(uplink_interface);
+ if (!Global_Clatd_Config.default_pdp_interface)
+ goto failed;
if(!config_item_int16_t(root, "mtu", "-1", &Global_Clatd_Config.mtu))
goto failed;
@@ -318,10 +290,9 @@ int read_config(const char *file, const char *uplink_interface, const char *plat
}
}
- if(!subnet_from_interface(root,Global_Clatd_Config.default_pdp_interface))
+ if (!config_item_ip6(root, "ipv6_host_id", "::", &Global_Clatd_Config.ipv6_host_id))
goto failed;
-
return 1;
failed:
diff --git a/config.h b/config.h
index 654e909..a56d6fc 100644
--- a/config.h
+++ b/config.h
@@ -19,7 +19,6 @@
#define __CONFIG_H__
#include <netinet/in.h>
-#include <sys/system_properties.h>
#define DEFAULT_IPV4_LOCAL_SUBNET "192.0.0.4"
@@ -31,7 +30,7 @@ struct clat_config {
struct in6_addr ipv6_host_id;
struct in_addr ipv4_local_subnet;
struct in6_addr plat_subnet;
- char default_pdp_interface[PROP_VALUE_MAX];
+ char *default_pdp_interface;
char *plat_from_dns64_hostname;
};