diff options
author | Maciej Żenczykowski <maze@google.com> | 2023-03-16 13:27:35 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2023-03-16 13:27:35 +0000 |
commit | 3ec1c43e4cbb2ef830503e8c00a5f2ca3d8efe8a (patch) | |
tree | 12d9ce155a76a8f441e8e7426fa8497f94cefafb | |
parent | b8c834410e39b68410c2a03863ed47be27d6327a (diff) | |
parent | ca9466c76809f6bec044669dc2ffb35552e6b404 (diff) | |
download | android-clat-3ec1c43e4cbb2ef830503e8c00a5f2ca3d8efe8a.tar.gz |
Merge "clatd: remove ipv6 address monitoring"
-rw-r--r-- | Android.bp | 1 | ||||
-rw-r--r-- | clatd.c | 38 | ||||
-rw-r--r-- | clatd.h | 7 | ||||
-rw-r--r-- | clatd_test.cpp | 53 | ||||
-rw-r--r-- | getaddr.c | 169 | ||||
-rw-r--r-- | getaddr.h | 30 |
6 files changed, 1 insertions, 297 deletions
@@ -40,7 +40,6 @@ filegroup { srcs: [ "clatd.c", "dump.c", - "getaddr.c", "icmp.c", "ipv4.c", "ipv6.c", @@ -44,7 +44,6 @@ #include "checksum.h" #include "config.h" #include "dump.h" -#include "getaddr.h" #include "logging.h" #include "translate.h" @@ -52,29 +51,6 @@ struct clat_config Global_Clatd_Config; volatile sig_atomic_t running = 1; -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; - } -} - // reads IPv6 packet from AF_PACKET socket, translates to IPv4, writes to tun void process_packet_6_to_4(struct tun_data *tunnel) { // ethernet header is 14 bytes, plus 4 for a normal VLAN tag or 8 for Q-in-Q @@ -297,17 +273,13 @@ void event_loop(struct tun_data *tunnel) { // TODO: actually perform true DAD send_dad(tunnel->write_fd6, &Global_Clatd_Config.ipv6_local_subnet); - time_t last_interface_poll; struct pollfd wait_fd[] = { { tunnel->read_fd6, POLLIN, 0 }, { tunnel->fd4, POLLIN, 0 }, }; - // start the poll timer - last_interface_poll = time(NULL); - while (running) { - if (poll(wait_fd, ARRAY_SIZE(wait_fd), NO_TRAFFIC_INTERFACE_POLL_FREQUENCY * 1000) == -1) { + if (poll(wait_fd, ARRAY_SIZE(wait_fd), -1) == -1) { if (errno != EINTR) { logmsg(ANDROID_LOG_WARN, "event_loop/poll returned an error: %s", strerror(errno)); } @@ -320,13 +292,5 @@ void event_loop(struct tun_data *tunnel) { if (wait_fd[0].revents) process_packet_6_to_4(tunnel); if (wait_fd[1].revents) process_packet_4_to_6(tunnel); } - - time_t now = time(NULL); - if (now >= (last_interface_poll + INTERFACE_POLL_FREQUENCY)) { - last_interface_poll = now; - if (ipv6_address_changed(Global_Clatd_Config.native_ipv6_interface)) { - break; - } - } } } @@ -52,15 +52,8 @@ struct tun_data; #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -// how frequently (in seconds) to poll for an address change while traffic is passing -#define INTERFACE_POLL_FREQUENCY 30 - -// how frequently (in seconds) to poll for an address change while there is no traffic -#define NO_TRAFFIC_INTERFACE_POLL_FREQUENCY 90 - extern volatile sig_atomic_t running; -int ipv6_address_changed(const char *interface); void event_loop(struct tun_data *tunnel); /* function: parse_int diff --git a/clatd_test.cpp b/clatd_test.cpp index 8eef738..94ae0b5 100644 --- a/clatd_test.cpp +++ b/clatd_test.cpp @@ -33,7 +33,6 @@ extern "C" { #include "checksum.h" #include "clatd.h" #include "config.h" -#include "getaddr.h" #include "translate.h" } @@ -836,55 +835,3 @@ 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, GetInterfaceIpV4) { - TunInterface v4Iface; - ASSERT_EQ(0, v4Iface.init()); - EXPECT_EQ(0, v4Iface.addAddress("192.0.2.1", 32)); - - union anyip *ip = getinterface_ip(v4Iface.name().c_str(), AF_INET); - ASSERT_NE(nullptr, ip); - EXPECT_EQ(inet_addr("192.0.2.1"), ip->ip4.s_addr); - free(ip); - - v4Iface.destroy(); -} - -TEST_F(ClatdTest, GetInterfaceIpV6) { - 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, Ipv6AddressChanged) { - // Configure the clat IPv6 address. - const char *ifname = sTun.name().c_str(); - - in6_addr myaddr = sTun.srcAddr(); - gen_random_iid(&myaddr, &Global_Clatd_Config.ipv4_local_subnet, &Global_Clatd_Config.plat_subnet); - char addrstr[INET6_ADDRSTRLEN]; - ASSERT_NE(nullptr, inet_ntop(AF_INET6, &myaddr, addrstr, sizeof(addrstr))); - - Global_Clatd_Config.ipv6_local_subnet = myaddr; - 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/getaddr.c b/getaddr.c deleted file mode 100644 index ba8052d..0000000 --- a/getaddr.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2012 Daniel Drown - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * getaddr.c - get a locally configured address - */ -#include "getaddr.h" - -#include <errno.h> -#include <linux/if_addr.h> -#include <linux/rtnetlink.h> -#include <net/if.h> -#include <netinet/in.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <unistd.h> - -#include "logging.h" - -// Kernel suggests that keep the packet under 8KiB (NLMSG_GOODSIZE) in include/linux/netlink.h. -#define NLMSG_SIZE 8192 - -// shared state between getinterface_ip and parse_ifaddrmsg -// TODO: refactor the communication between getinterface_ip and parse_ifaddrmsg because there -// is no netlink callback anymore. -struct target { - int family; - unsigned int ifindex; - union anyip ip; - int foundip; -}; - -/* function: parse_ifaddrmsg - * parse ifaddrmsg for getinterface_ip - * nh - netlink message header - * targ_p - (struct target) info for which address we're looking for - * and the parsed result if any. - */ -static void parse_ifaddrmsg(struct nlmsghdr *nh, struct target *targ_p) { - struct ifaddrmsg *ifa_p; - struct rtattr *rta_p; - int rta_len; - - ifa_p = (struct ifaddrmsg *)NLMSG_DATA(nh); - rta_p = (struct rtattr *)IFA_RTA(ifa_p); - - if (ifa_p->ifa_index != targ_p->ifindex) return; - - if (ifa_p->ifa_scope != RT_SCOPE_UNIVERSE) return; - - rta_len = IFA_PAYLOAD(nh); - for (; RTA_OK(rta_p, rta_len); rta_p = RTA_NEXT(rta_p, rta_len)) { - switch (rta_p->rta_type) { - case IFA_ADDRESS: - if ((targ_p->family == AF_INET6) && !(ifa_p->ifa_flags & IFA_F_SECONDARY)) { - memcpy(&targ_p->ip.ip6, RTA_DATA(rta_p), rta_p->rta_len - sizeof(struct rtattr)); - targ_p->foundip = 1; - return; - } - break; - case IFA_LOCAL: - if (targ_p->family == AF_INET) { - memcpy(&targ_p->ip.ip4, RTA_DATA(rta_p), rta_p->rta_len - sizeof(struct rtattr)); - targ_p->foundip = 1; - return; - } - break; - } - } -} - -void sendrecv_ifaddrmsg(struct target *targ_p) { - int s = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE); - if (s < 0) { - logmsg(ANDROID_LOG_ERROR, "open NETLINK_ROUTE socket failed %s", strerror(errno)); - return; - } - - // Fill in netlink structures. - struct { - struct nlmsghdr n; - struct ifaddrmsg r; - } req = { - // Netlink message header. - .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), - .n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT, - .n.nlmsg_type = RTM_GETADDR, - - // Interface address message header. - .r.ifa_family = targ_p->family, - }; - - // Send interface address message. - if ((send(s, &req, req.n.nlmsg_len, 0)) < 0) { - logmsg(ANDROID_LOG_ERROR, "send netlink socket failed %s", strerror(errno)); - close(s); - return; - } - - // Read interface address message and parse the result if any. - ssize_t bytes_read; - char buf[NLMSG_SIZE]; - while ((bytes_read = recv(s, buf, sizeof(buf), 0)) > 0) { - struct nlmsghdr *nh = (struct nlmsghdr *)buf; - for (; NLMSG_OK(nh, bytes_read); nh = NLMSG_NEXT(nh, bytes_read)) { - if (nh->nlmsg_type == NLMSG_DONE) { - close(s); - return; - } - if (nh->nlmsg_type == NLMSG_ERROR) { - logmsg(ANDROID_LOG_ERROR, "netlink message error"); - close(s); - return; - } - if (nh->nlmsg_type == RTM_NEWADDR) { - // Walk through the all messages and update struct target variable as the deleted - // callback behavior of getaddr_cb() which always returns NL_OK. - // TODO: review if this can early return once address has been found. - parse_ifaddrmsg(nh, targ_p); - } - } - } - close(s); -} - -/* function: getinterface_ip - * finds the first global non-privacy IP of the given family for the given interface, or returns - * NULL. caller frees pointer - * interface - interface to look for - * family - family - */ -union anyip *getinterface_ip(const char *interface, int family) { - union anyip *retval = NULL; - struct target targ = { - .family = family, - .foundip = 0, - .ifindex = if_nametoindex(interface), - }; - - if (targ.ifindex == 0) { - return NULL; // interface not found - } - - // sends message and receives the response. - sendrecv_ifaddrmsg(&targ); - - if (targ.foundip) { - retval = malloc(sizeof(union anyip)); - if (!retval) { - logmsg(ANDROID_LOG_FATAL, "getinterface_ip/out of memory"); - return NULL; - } - memcpy(retval, &targ.ip, sizeof(union anyip)); - } - - return retval; -} diff --git a/getaddr.h b/getaddr.h deleted file mode 100644 index 482ac13..0000000 --- a/getaddr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011 Daniel Drown - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * getaddr.h - get a locally configured address - */ -#ifndef __GETADDR_H__ -#define __GETADDR_H__ - -#include <netinet/in.h> - -union anyip { - struct in6_addr ip6; - struct in_addr ip4; -}; - -union anyip *getinterface_ip(const char *interface, int family); - -#endif |