Merge "clatd: remove ipv6 address monitoring" am: 3ec1c43e4c

Original change: https://android-review.googlesource.com/c/platform/external/android-clat/+/2491075

Change-Id: Id52ca01684faf5bdd07cacc410e935fe247b036d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index 982e656..983ee00 100644
--- a/Android.bp
+++ b/Android.bp
@@ -40,7 +40,6 @@
     srcs: [
         "clatd.c",
         "dump.c",
-        "getaddr.c",
         "icmp.c",
         "ipv4.c",
         "ipv6.c",
diff --git a/clatd.c b/clatd.c
index f8973f9..9a7a45a 100644
--- a/clatd.c
+++ b/clatd.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 @@
 
 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 @@
   // 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 @@
       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;
-      }
-    }
   }
 }
diff --git a/clatd.h b/clatd.h
index 59f78ab..85e2c49 100644
--- a/clatd.h
+++ b/clatd.h
@@ -52,15 +52,8 @@
 
 #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 @@
 #include "checksum.h"
 #include "clatd.h"
 #include "config.h"
-#include "getaddr.h"
 #include "translate.h"
 }
 
@@ -836,55 +835,3 @@
   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