Merge "Delete the clatd code that assigns IPv4 and IPv6 addresses."
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__ */