diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2014-10-30 23:40:35 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-10-30 23:40:35 +0000 |
commit | 50c5887524b08d011bacc91be927c9117533867d (patch) | |
tree | 23daa3ab5f43e8aa6b34cf844c86f659b3d9c218 | |
parent | b15568c8ee15f2bc78b9bff8d4e107b3d4150dc3 (diff) | |
parent | 1352a3a26c4d7c32b38b7fadb837799a23014aa6 (diff) | |
download | android_external_android-clat-50c5887524b08d011bacc91be927c9117533867d.tar.gz android_external_android-clat-50c5887524b08d011bacc91be927c9117533867d.tar.bz2 android_external_android-clat-50c5887524b08d011bacc91be927c9117533867d.zip |
am 1352a3a2: Unduplicate IPv6 address setting code.
* commit '1352a3a26c4d7c32b38b7fadb837799a23014aa6':
Unduplicate IPv6 address setting code.
-rw-r--r-- | clatd.c | 95 | ||||
-rw-r--r-- | config.c | 37 | ||||
-rw-r--r-- | config.h | 3 |
3 files changed, 59 insertions, 76 deletions
@@ -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) { @@ -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: @@ -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; }; |