Delete the clatd code that assigns IPv4 and IPv6 addresses.

The IPv4 and IPv6 address assignment code, and its tests, were
migrated to ClatdController in Q, and this code has been unused
since then.

This code is not only unused, it also *should* never be used,
because if it were, many parts of 464xlat on Android would not
work as expected. This includes 464xlat BPF offload and data
usage accounting, both of which require netd to know exactly
which IPv4 and IPv6 addresses are used by clatd at any given
time.

Most of the code is deleted, but the function to generate random
checksum-neutral IIDs was moved to the tests instead.

This change does not delete the configuration file parsing code.
That will be done in a follow-up CL.

Bug: 144730808
Bug: 150738490
Test: atest clatd_test
Test: atest netd_integration_test
Test: IPv6-only wifi continues to work
Change-Id: I8265e9bb04d44ed1dda445fa91881fcd1601dc47
diff --git a/clatd.c b/clatd.c
index 3f9dc71..50693f5 100644
--- a/clatd.c
+++ b/clatd.c
@@ -109,52 +109,15 @@
   return 1;
 }
 
-/* function: ipv4_address_generate
- * picks a free IPv4 address from the local subnet or exits if there are no free addresses
- *   returns: the IPv4 address as an in_addr_t
- */
-static in_addr_t ipv4_address_generate() {
-  // Pick an IPv4 address to use by finding a free address in the configured prefix. Technically,
-  // there is a race here - if another clatd calls config_select_ipv4_address after we do, but
-  // before we call add_address, it can end up having the same IP address as we do. But the time
-  // window in which this can happen is extremely small, and even if we end up with a duplicate
-  // address, the only damage is that IPv4 TCP connections won't be reset until both interfaces go
-  // down.
-  in_addr_t localaddr = config_select_ipv4_address(&Global_Clatd_Config.ipv4_local_subnet,
-                                                   Global_Clatd_Config.ipv4_local_prefixlen);
-  if (localaddr == INADDR_NONE) {
-    logmsg(ANDROID_LOG_FATAL, "No free IPv4 address in %s/%d",
-           inet_ntoa(Global_Clatd_Config.ipv4_local_subnet),
-           Global_Clatd_Config.ipv4_local_prefixlen);
-    exit(1);
-  }
-  return localaddr;
-}
-
-/* function: ipv4_address_from_cmdline
- * configures the IPv4 address specified on the command line, or exits if the address is not valid
- *   v4_addr - a string, the IPv4 address
- *   returns: the IPv4 address as an in_addr_t
- */
-static in_addr_t ipv4_address_from_cmdline(const char *v4_addr) {
-  in_addr_t localaddr;
-  if (!inet_pton(AF_INET, v4_addr, &localaddr)) {
-    logmsg(ANDROID_LOG_FATAL, "Invalid IPv4 address %s", v4_addr);
-    exit(1);
-  }
-  return localaddr;
-}
-
 /* function: configure_tun_ip
  * configures the ipv4 and ipv6 addresses on the tunnel interface
  *   tunnel - tun device data
  *   mtu    - mtu of tun device
  */
 void configure_tun_ip(const struct tun_data *tunnel, const char *v4_addr, int mtu) {
-  if (v4_addr) {
-    Global_Clatd_Config.ipv4_local_subnet.s_addr = ipv4_address_from_cmdline(v4_addr);
-  } else {
-    Global_Clatd_Config.ipv4_local_subnet.s_addr = ipv4_address_generate();
+  if (!v4_addr || !inet_pton(AF_INET, v4_addr, &Global_Clatd_Config.ipv4_local_subnet.s_addr)) {
+    logmsg(ANDROID_LOG_FATAL, "Invalid IPv4 address %s", v4_addr);
+    exit(1);
   }
 
   char addrstr[INET_ADDRSTRLEN];
@@ -272,43 +235,6 @@
   }
 }
 
-/* function: clat_ipv6_address_from_interface
- * picks the clat IPv6 address based on the interface address
- *   interface - uplink interface name
- *   returns: 1 on success, 0 on failure
- */
-static int clat_ipv6_address_from_interface(const char *interface) {
-  union anyip *interface_ip;
-
-  // 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;
-  }
-
-  // Generate an interface ID.
-  config_generate_local_ipv6_subnet(&interface_ip->ip6);
-
-  Global_Clatd_Config.ipv6_local_subnet = interface_ip->ip6;
-  free(interface_ip);
-  return 1;
-}
-
-/* function: clat_ipv6_address_from_cmdline
- * parses the clat IPv6 address from the command line
- *   v4_addr - a string, the IPv6 address
- *   returns: 1 on success, 0 on failure
- */
-static int clat_ipv6_address_from_cmdline(const char *v6_addr) {
-  if (!inet_pton(AF_INET6, v6_addr, &Global_Clatd_Config.ipv6_local_subnet)) {
-    logmsg(ANDROID_LOG_FATAL, "Invalid source address %s", v6_addr);
-    return 0;
-  }
-
-  return 1;
-}
-
 /* function: configure_clat_ipv6_address
  * picks the clat IPv6 address and configures packet translation to use it.
  *   tunnel - tun device data
@@ -317,13 +243,10 @@
  */
 int configure_clat_ipv6_address(const struct tun_data *tunnel, const char *interface,
                                 const char *v6_addr) {
-  int ret;
-  if (v6_addr) {
-    ret = clat_ipv6_address_from_cmdline(v6_addr);
-  } else {
-    ret = clat_ipv6_address_from_interface(interface);
+  if (!v6_addr || !inet_pton(AF_INET6, v6_addr, &Global_Clatd_Config.ipv6_local_subnet)) {
+    logmsg(ANDROID_LOG_FATAL, "Invalid source address %s", v6_addr);
+    return 0;
   }
-  if (!ret) return 0;
 
   char addrstr[INET6_ADDRSTRLEN];
   inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, addrstr, sizeof(addrstr));
diff --git a/clatd.conf b/clatd.conf
index 1025fb2..36fcafd 100644
--- a/clatd.conf
+++ b/clatd.conf
@@ -1,13 +1 @@
-# Host IID to use as the source of CLAT traffic.
-# This is a /128 taken out of the /64 on the parent interface.
-# A host IID of :: means to generate a checksum-neutral, random IID.
-ipv6_host_id ::
-
-# IPv4 address configuration to use when selecting a host address. The first
-# clat daemon started will use the address specified by ipv4_local_subnet. If
-# more than one daemon is run at the same time, subsequent daemons will use
-# other addresses in the prefix of length ipv4_local prefixlen that contains
-# ipv4_local_subnet. The default is to use the IANA-assigned range 192.0.0.0/29,
-# which allows up to 8 clat daemons (.4, .5, .6, .7, .0, .1, .2, .3).
-ipv4_local_subnet 192.0.0.4
-ipv4_local_prefixlen 29
+temporary_placeholder 0
diff --git a/clatd_test.cpp b/clatd_test.cpp
index 5de7b63..8f10e32 100644
--- a/clatd_test.cpp
+++ b/clatd_test.cpp
@@ -627,183 +627,12 @@
   EXPECT_FALSE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet));
 }
 
-int count_onebits(const void *data, size_t size) {
-  int onebits = 0;
-  for (size_t pos = 0; pos < size; pos++) {
-    uint8_t *byte = ((uint8_t *)data) + pos;
-    for (int shift = 0; shift < 8; shift++) {
-      onebits += (*byte >> shift) & 1;
-    }
-  }
-  return onebits;
-}
-
-TEST_F(ClatdTest, TestCountOnebits) {
-  uint64_t i;
-  i = 1;
-  ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
-  i <<= 61;
-  ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
-  i |= ((uint64_t)1 << 33);
-  ASSERT_EQ(2, count_onebits(&i, sizeof(i)));
-  i = 0xf1000202020000f0;
-  ASSERT_EQ(5 + 1 + 1 + 1 + 4, count_onebits(&i, sizeof(i)));
-}
-
-TEST_F(ClatdTest, TestGenIIDConfigured) {
-  struct in6_addr myaddr, expected;
-  Global_Clatd_Config.use_dynamic_iid = 0;
-  ASSERT_TRUE(inet_pton(AF_INET6, "::bad:ace:d00d", &Global_Clatd_Config.ipv6_host_id));
-  ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:0:bad:ace:d00d", &expected));
-  ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &myaddr));
-  config_generate_local_ipv6_subnet(&myaddr);
-  expect_ipv6_addr_equal(&expected, &myaddr);
-
-  Global_Clatd_Config.use_dynamic_iid = 1;
-  config_generate_local_ipv6_subnet(&myaddr);
-  EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&expected, &myaddr));
-}
-
-TEST_F(ClatdTest, TestGenIIDRandom) {
-  struct in6_addr interface_ipv6;
-  ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &interface_ipv6));
-  Global_Clatd_Config.ipv6_host_id = in6addr_any;
-
-  // Generate a boatload of random IIDs.
-  int onebits       = 0;
-  uint64_t prev_iid = 0;
-  for (int i = 0; i < 100000; i++) {
-    struct in6_addr myaddr = interface_ipv6;
-
-    config_generate_local_ipv6_subnet(&myaddr);
-
-    // Check the generated IP address is in the same prefix as the interface IPv6 address.
-    EXPECT_TRUE(ipv6_prefix_equal(&interface_ipv6, &myaddr));
-
-    // Check that consecutive IIDs are not the same.
-    uint64_t iid = *(uint64_t *)(&myaddr.s6_addr[8]);
-    ASSERT_TRUE(iid != prev_iid)
-        << "Two consecutive random IIDs are the same: "
-        << std::showbase << std::hex
-        << iid << "\n";
-    prev_iid = iid;
-
-    // Check that the IID is checksum-neutral with the NAT64 prefix and the
-    // local prefix.
-    struct in_addr *ipv4addr     = &Global_Clatd_Config.ipv4_local_subnet;
-    struct in6_addr *plat_subnet = &Global_Clatd_Config.plat_subnet;
-
-    uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, ipv4addr, sizeof(*ipv4addr)));
-    uint16_t c2 = ip_checksum_finish(ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
-                                     ip_checksum_add(0, &myaddr, sizeof(myaddr)));
-
-    if (c1 != c2) {
-      char myaddr_str[INET6_ADDRSTRLEN], plat_str[INET6_ADDRSTRLEN], ipv4_str[INET6_ADDRSTRLEN];
-      inet_ntop(AF_INET6, &myaddr, myaddr_str, sizeof(myaddr_str));
-      inet_ntop(AF_INET6, plat_subnet, plat_str, sizeof(plat_str));
-      inet_ntop(AF_INET, ipv4addr, ipv4_str, sizeof(ipv4_str));
-      FAIL()
-          << "Bad IID: " << myaddr_str
-          << " not checksum-neutral with " << ipv4_str << " and " << plat_str
-          << std::showbase << std::hex
-          << "\n  IPv4 checksum: " << c1
-          << "\n  IPv6 checksum: " << c2
-          << "\n";
-    }
-
-    // Check that IIDs are roughly random and use all the bits by counting the
-    // total number of bits set to 1 in a random sample of 100000 generated IIDs.
-    onebits += count_onebits(&iid, sizeof(iid));
-  }
-  EXPECT_LE(3190000, onebits);
-  EXPECT_GE(3210000, onebits);
-}
-
-extern "C" addr_free_func config_is_ipv4_address_free;
-int never_free(in_addr_t /* addr */) { return 0; }
-int always_free(in_addr_t /* addr */) { return 1; }
-int only2_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 2; }
-int over6_free(in_addr_t addr) { return (ntohl(addr) & 0xff) >= 6; }
-int only10_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 10; }
-
-TEST_F(ClatdTest, SelectIPv4Address) {
-  struct in_addr addr;
-
-  inet_pton(AF_INET, kIPv4LocalAddr, &addr);
-
-  addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
-
-  // If no addresses are free, return INADDR_NONE.
-  config_is_ipv4_address_free = never_free;
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 16));
-
-  // If the configured address is free, pick that. But a prefix that's too big is invalid.
-  config_is_ipv4_address_free = always_free;
-  EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 29));
-  EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 20));
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 15));
-
-  // A prefix length of 32 works, but anything above it is invalid.
-  EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 32));
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 33));
-
-  // If another address is free, pick it.
-  config_is_ipv4_address_free = over6_free;
-  EXPECT_EQ(inet_addr("192.0.0.6"), config_select_ipv4_address(&addr, 29));
-
-  // Check that we wrap around to addresses that are lower than the first address.
-  config_is_ipv4_address_free = only2_free;
-  EXPECT_EQ(inet_addr("192.0.0.2"), config_select_ipv4_address(&addr, 29));
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 30));
-
-  // If a free address exists outside the prefix, we don't pick it.
-  config_is_ipv4_address_free = only10_free;
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
-  EXPECT_EQ(inet_addr("192.0.0.10"), config_select_ipv4_address(&addr, 24));
-
-  // Now try using the real function which sees if IP addresses are free using bind().
-  // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8.
-  config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
-  addr.s_addr                 = inet_addr("8.8.8.8");
-  EXPECT_EQ(inet_addr("8.8.8.8"), config_select_ipv4_address(&addr, 29));
-
-  addr.s_addr = inet_addr("127.0.0.1");
-  EXPECT_EQ(inet_addr("127.0.0.2"), config_select_ipv4_address(&addr, 29));
-}
-
 TEST_F(ClatdTest, DetectMtu) {
   // ::1 with bottom 32 bits set to 1 is still ::1 which routes via lo with mtu of 64KiB
   ASSERT_EQ(detect_mtu(&in6addr_loopback, htonl(1), 0 /*MARK_UNSET*/), 65536);
 }
 
-TEST_F(ClatdTest, ConfigureTunIp) {
-  addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
-  config_is_ipv4_address_free                     = over6_free;
-
-  Global_Clatd_Config.ipv4_local_prefixlen = 29;
-
-  // Create an interface for configure_tun_ip to configure and bring up.
-  TunInterface v4Iface;
-  ASSERT_EQ(0, v4Iface.init());
-  struct tun_data tunnel = makeTunData();
-  strlcpy(tunnel.device4, v4Iface.name().c_str(), sizeof(tunnel.device4));
-
-  configure_tun_ip(&tunnel, nullptr /* v4_addr */, 1472);
-  EXPECT_EQ(inet_addr("192.0.0.6"), Global_Clatd_Config.ipv4_local_subnet.s_addr);
-
-  union anyip *ip = getinterface_ip(v4Iface.name().c_str(), AF_INET);
-  EXPECT_EQ(inet_addr("192.0.0.6"), ip->ip4.s_addr);
-  free(ip);
-
-  config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
-  v4Iface.destroy();
-}
-
 TEST_F(ClatdTest, ConfigureTunIpManual) {
-  addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
-  config_is_ipv4_address_free                     = over6_free;
-
   Global_Clatd_Config.ipv4_local_prefixlen = 29;
 
   // Create an interface for configure_tun_ip to configure and bring up.
@@ -820,7 +649,6 @@
   EXPECT_EQ(inet_addr("192.0.2.1"), ip->ip4.s_addr);
   free(ip);
 
-  config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
   v4Iface.destroy();
 }
 
@@ -986,6 +814,29 @@
                              ARRAYSIZE(kIPv6Fragments), "IPv6->IPv4 fragment translation");
 }
 
+// picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix
+void gen_random_iid(struct in6_addr *myaddr, struct in_addr *ipv4_local_subnet,
+                    struct in6_addr *plat_subnet) {
+  // Fill last 8 bytes of IPv6 address with random bits.
+  arc4random_buf(&myaddr->s6_addr[8], 8);
+
+  // Make the IID checksum-neutral. That is, make it so that:
+  //   checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6)
+  // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4):
+  //   checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix)
+  // Do this by adjusting the two bytes in the middle of the IID.
+
+  uint16_t middlebytes = (myaddr->s6_addr[11] << 8) + myaddr->s6_addr[12];
+
+  uint32_t c1 = ip_checksum_add(0, ipv4_local_subnet, sizeof(*ipv4_local_subnet));
+  uint32_t c2 = ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
+                ip_checksum_add(0, myaddr, sizeof(*myaddr));
+
+  uint16_t delta      = ip_checksum_adjust(middlebytes, c1, c2);
+  myaddr->s6_addr[11] = delta >> 8;
+  myaddr->s6_addr[12] = delta & 0xff;
+}
+
 void check_translate_checksum_neutral(const uint8_t *original, size_t original_len,
                                       size_t expected_len, const char *msg) {
   uint8_t translated[MAXMTU];
@@ -1006,7 +857,10 @@
   Global_Clatd_Config.ipv6_host_id = in6addr_any;
   ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54",
                         &Global_Clatd_Config.ipv6_local_subnet));
-  config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet);
+
+  gen_random_iid(&Global_Clatd_Config.ipv6_local_subnet, &Global_Clatd_Config.ipv4_local_subnet,
+                 &Global_Clatd_Config.plat_subnet);
+
   ASSERT_NE(htonl((uint32_t)0x00000464), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
   ASSERT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
 
@@ -1079,7 +933,13 @@
     .write_fd6 = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW),
   };
   const char *ifname = sTun.name().c_str();
-  ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, ifname, nullptr));
+
+  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)));
+
+  ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, ifname, addrstr));
   EXPECT_EQ(0, ipv6_address_changed(ifname));
   EXPECT_EQ(0, ipv6_address_changed(ifname));
 
diff --git a/config.c b/config.c
index db0abc8..d4cc9af 100644
--- a/config.c
+++ b/config.c
@@ -157,107 +157,6 @@
  */
 int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2) { return !memcmp(a1, a2, 8); }
 
-/* function: gen_random_iid
- * picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix
- *   myaddr            - IPv6 address to write to
- *   ipv4_local_subnet - clat IPv4 address
- *   plat_subnet       - NAT64 prefix
- */
-void gen_random_iid(struct in6_addr *myaddr, struct in_addr *ipv4_local_subnet,
-                    struct in6_addr *plat_subnet) {
-  // Fill last 8 bytes of IPv6 address with random bits.
-  arc4random_buf(&myaddr->s6_addr[8], 8);
-
-  // Make the IID checksum-neutral. That is, make it so that:
-  //   checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6)
-  // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4):
-  //   checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix)
-  // Do this by adjusting the two bytes in the middle of the IID.
-
-  uint16_t middlebytes = (myaddr->s6_addr[11] << 8) + myaddr->s6_addr[12];
-
-  uint32_t c1 = ip_checksum_add(0, ipv4_local_subnet, sizeof(*ipv4_local_subnet));
-  uint32_t c2 = ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
-                ip_checksum_add(0, myaddr, sizeof(*myaddr));
-
-  uint16_t delta      = ip_checksum_adjust(middlebytes, c1, c2);
-  myaddr->s6_addr[11] = delta >> 8;
-  myaddr->s6_addr[12] = delta & 0xff;
-}
-
-// Factored out to a separate function for testability.
-int connect_is_ipv4_address_free(in_addr_t addr) {
-  int s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
-  if (s == -1) {
-    return 0;
-  }
-
-  // Attempt to connect to the address. If the connection succeeds and getsockname returns the same
-  // the address then the address is already assigned to the system and we can't use it.
-  struct sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = { addr }, .sin_port = htons(53) };
-  socklen_t len          = sizeof(sin);
-  int inuse              = connect(s, (struct sockaddr *)&sin, sizeof(sin)) == 0 &&
-              getsockname(s, (struct sockaddr *)&sin, &len) == 0 && (size_t)len >= sizeof(sin) &&
-              sin.sin_addr.s_addr == addr;
-
-  close(s);
-  return !inuse;
-}
-
-addr_free_func config_is_ipv4_address_free = connect_is_ipv4_address_free;
-
-/* function: config_select_ipv4_address
- * picks a free IPv4 address, starting from ip and trying all addresses in the prefix in order
- *   ip        - the IP address from the configuration file
- *   prefixlen - the length of the prefix from which addresses may be selected.
- *   returns: the IPv4 address, or INADDR_NONE if no addresses were available
- */
-in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen) {
-  in_addr_t chosen = INADDR_NONE;
-
-  // Don't accept prefixes that are too large because we scan addresses one by one.
-  if (prefixlen < 16 || prefixlen > 32) {
-    return chosen;
-  }
-
-  // All these are in host byte order.
-  in_addr_t mask       = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen);
-  in_addr_t ipv4       = ntohl(ip->s_addr);
-  in_addr_t first_ipv4 = ipv4;
-  in_addr_t prefix     = ipv4 & mask;
-
-  // Pick the first IPv4 address in the pool, wrapping around if necessary.
-  // So, for example, 192.0.0.4 -> 192.0.0.5 -> 192.0.0.6 -> 192.0.0.7 -> 192.0.0.0.
-  do {
-    if (config_is_ipv4_address_free(htonl(ipv4))) {
-      chosen = htonl(ipv4);
-      break;
-    }
-    ipv4 = prefix | ((ipv4 + 1) & ~mask);
-  } while (ipv4 != first_ipv4);
-
-  return chosen;
-}
-
-/* function: config_generate_local_ipv6_subnet
- * generates the local ipv6 subnet when given the interface ip requires config.ipv6_host_id
- *   interface_ip - in: interface ip, out: local ipv6 host address
- */
-void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip) {
-  int i;
-
-  if (Global_Clatd_Config.use_dynamic_iid) {
-    /* Generate a random interface ID. */
-    gen_random_iid(interface_ip, &Global_Clatd_Config.ipv4_local_subnet,
-                   &Global_Clatd_Config.plat_subnet);
-  } else {
-    /* Use the specified interface ID. */
-    for (i = 2; i < 4; i++) {
-      interface_ip->s6_addr32[i] = Global_Clatd_Config.ipv6_host_id.s6_addr32[i];
-    }
-  }
-}
-
 /* function: read_config
  * reads the config file and parses it into the global variable Global_Clatd_Config. returns 0 on
  * failure, 1 on success
diff --git a/config.h b/config.h
index c47fc88..50efeeb 100644
--- a/config.h
+++ b/config.h
@@ -37,10 +37,6 @@
 extern struct clat_config Global_Clatd_Config;
 
 int read_config(const char *file, const char *uplink_interface);
-void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip);
-in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen);
 int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2);
 
-typedef int (*addr_free_func)(in_addr_t addr);
-
 #endif /* __CONFIG_H__ */