summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2019-04-08 17:46:48 -0700
committerMaciej Żenczykowski <maze@google.com>2019-05-08 21:02:19 -0700
commit8addcc0f6360cc3762e9ef27437ded250e785da3 (patch)
treeac9a90d6280e22785aaca68db210bf5612ea1b13
parent3297c7d7bca85db2b178e8838138b71e9d2a86ad (diff)
downloadandroid-clat-android10-qpr1-mainline-release.tar.gz
Test: atest clatd_test, built and installed on aosp_blueline device connected to ipv6-only wifi network: ping 8.8.8.8 still works and it is via v4-wlan0 clat tun interface Bug: 65674744 Bug: 131268436 Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I8c9e235e9a5bf1a1436e8dc3af8d0aa86f6dc1a5 Merged-In: I8c9e235e9a5bf1a1436e8dc3af8d0aa86f6dc1a5 (cherry picked from commit 716518d9b9ca52182498b1d7ed0f0ed8ab42cbe1)
-rw-r--r--Android.bp1
-rw-r--r--clatd.c24
-rw-r--r--clatd.h24
-rw-r--r--clatd_microbenchmark.c2
-rw-r--r--main.c24
-rw-r--r--tun.c29
-rw-r--r--tun.h17
7 files changed, 56 insertions, 65 deletions
diff --git a/Android.bp b/Android.bp
index 98b4010..b495dac 100644
--- a/Android.bp
+++ b/Android.bp
@@ -35,7 +35,6 @@ filegroup {
"netlink_msg.c",
"ring.c",
"setif.c",
- "tun.c",
"translate.c",
],
}
diff --git a/clatd.c b/clatd.c
index d68dc05..d332e1e 100644
--- a/clatd.c
+++ b/clatd.c
@@ -355,7 +355,6 @@ int configure_clat_ipv6_address(const struct tun_data *tunnel, const char *inter
*/
void configure_interface(const char *uplink_interface, const char *plat_prefix, const char *v4_addr,
const char *v6_addr, struct tun_data *tunnel, unsigned net_id) {
- int error;
if (!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix, net_id)) {
logmsg(ANDROID_LOG_FATAL, "read_config failed");
@@ -381,18 +380,6 @@ void configure_interface(const char *uplink_interface, const char *plat_prefix,
logmsg(ANDROID_LOG_WARN, "ipv4mtu now set to = %d", Global_Clatd_Config.ipv4mtu);
}
- error = tun_alloc(tunnel->device4, tunnel->fd4, sizeof(tunnel->device4));
- if (error < 0) {
- logmsg(ANDROID_LOG_FATAL, "tun_alloc/4 failed: %s", strerror(errno));
- exit(1);
- }
-
- error = set_nonblocking(tunnel->fd4);
- if (error < 0) {
- logmsg(ANDROID_LOG_FATAL, "set_nonblocking failed: %s", strerror(errno));
- exit(1);
- }
-
configure_tun_ip(tunnel, v4_addr);
if (!configure_clat_ipv6_address(tunnel, uplink_interface, v6_addr)) {
@@ -497,14 +484,3 @@ void event_loop(struct tun_data *tunnel) {
}
}
}
-
-/* function: parse_unsigned
- * parses a string as a decimal/hex/octal unsigned integer
- * str - the string to parse
- * out - the unsigned integer to write to, gets clobbered on failure
- */
-int parse_unsigned(const char *str, unsigned *out) {
- char *end_ptr;
- *out = strtoul(str, &end_ptr, 0);
- return *str && !*end_ptr;
-}
diff --git a/clatd.h b/clatd.h
index f7f7315..d3869bf 100644
--- a/clatd.h
+++ b/clatd.h
@@ -18,6 +18,7 @@
#ifndef __CLATD_H__
#define __CLATD_H__
+#include <stdlib.h>
#include <sys/uio.h>
struct tun_data;
@@ -45,6 +46,27 @@ int configure_clat_ipv6_address(const struct tun_data *tunnel, const char *inter
void configure_interface(const char *uplink_interface, const char *plat_prefix, const char *v4_addr,
const char *v6, struct tun_data *tunnel, unsigned net_id);
void event_loop(struct tun_data *tunnel);
-int parse_unsigned(const char *str, unsigned *out);
+
+/* function: parse_int
+ * parses a string as a decimal/hex/octal signed integer
+ * str - the string to parse
+ * out - the signed integer to write to, gets clobbered on failure
+ */
+static inline int parse_int(const char *str, int *out) {
+ char *end_ptr;
+ *out = strtol(str, &end_ptr, 0);
+ return *str && !*end_ptr;
+}
+
+/* function: parse_unsigned
+ * parses a string as a decimal/hex/octal unsigned integer
+ * str - the string to parse
+ * out - the unsigned integer to write to, gets clobbered on failure
+ */
+static inline int parse_unsigned(const char *str, unsigned *out) {
+ char *end_ptr;
+ *out = strtoul(str, &end_ptr, 0);
+ return *str && !*end_ptr;
+}
#endif /* __CLATD_H__ */
diff --git a/clatd_microbenchmark.c b/clatd_microbenchmark.c
index 15a0376..ea58a8a 100644
--- a/clatd_microbenchmark.c
+++ b/clatd_microbenchmark.c
@@ -200,12 +200,10 @@ int main() {
close(fd);
fd = setup_tun();
- set_nonblocking(fd);
benchmark("No read", fd, sock, NUMPACKETS, 0, payload, sizeof(payload), payload_sum);
close(fd);
fd = setup_tun();
- set_nonblocking(fd);
benchmark("Nonblocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum);
close(fd);
diff --git a/main.c b/main.c
index 54d12d1..9e796fd 100644
--- a/main.c
+++ b/main.c
@@ -46,6 +46,7 @@ void print_help() {
printf("-6 [IPv6 address]\n");
printf("-n [NetId]\n");
printf("-m [socket mark]\n");
+ printf("-t [tun file descriptor number]\n");
}
/* function: main
@@ -55,12 +56,12 @@ int main(int argc, char **argv) {
struct tun_data tunnel;
int opt;
char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL, *mark_str = NULL;
- char *v4_addr = NULL, *v6_addr = NULL;
+ char *v4_addr = NULL, *v6_addr = NULL, *tunfd_str = NULL;
unsigned net_id = NETID_UNSET;
uint32_t mark = MARK_UNSET;
unsigned len;
- while ((opt = getopt(argc, argv, "i:p:4:6:n:m:h")) != -1) {
+ while ((opt = getopt(argc, argv, "i:p:4:6:n:m:t:h")) != -1) {
switch (opt) {
case 'i':
uplink_interface = optarg;
@@ -80,6 +81,9 @@ int main(int argc, char **argv) {
case 'm':
mark_str = optarg;
break;
+ case 't':
+ tunfd_str = optarg;
+ break;
case 'h':
print_help();
exit(0);
@@ -104,6 +108,15 @@ int main(int argc, char **argv) {
exit(1);
}
+ if (tunfd_str != NULL && !parse_int(tunfd_str, &tunnel.fd4)) {
+ logmsg(ANDROID_LOG_FATAL, "invalid tunfd %s", tunfd_str);
+ exit(1);
+ }
+ if (!tunnel.fd4) {
+ logmsg(ANDROID_LOG_FATAL, "no tunfd specified on commandline.");
+ exit(1);
+ }
+
len = snprintf(tunnel.device4, sizeof(tunnel.device4), "%s%s", DEVICEPREFIX, uplink_interface);
if (len >= sizeof(tunnel.device4)) {
logmsg(ANDROID_LOG_FATAL, "interface name too long '%s'", tunnel.device4);
@@ -124,13 +137,6 @@ int main(int argc, char **argv) {
// keeps only admin capability
set_capability(1 << CAP_NET_ADMIN);
- // we can create tun devices as non-root because we're in the VPN group.
- tunnel.fd4 = tun_open();
- if (tunnel.fd4 < 0) {
- logmsg(ANDROID_LOG_FATAL, "tun_open4 failed: %s", strerror(errno));
- exit(1);
- }
-
// When run from netd, the environment variable ANDROID_DNS_MODE is set to
// "local", but that only works for the netd process itself. Removing the
// following line causes XLAT failure in permissive mode.
diff --git a/tun.c b/tun.c
index 7ecbf2c..e2f1342 100644
--- a/tun.c
+++ b/tun.c
@@ -21,20 +21,19 @@
#include <linux/if_tun.h>
#include <string.h>
#include <sys/ioctl.h>
-#include <sys/uio.h>
#include <unistd.h>
#include "common.h"
/* function: tun_open
- * tries to open the tunnel device
+ * tries to open the tunnel device in non-blocking mode
*/
int tun_open() {
int fd;
- fd = open("/dev/tun", O_RDWR | O_CLOEXEC);
+ fd = open("/dev/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
if (fd < 0) {
- fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
+ fd = open("/dev/net/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
}
return fd;
@@ -65,25 +64,3 @@ int tun_alloc(char *dev, int fd, size_t len) {
strlcpy(dev, ifr.ifr_name, len);
return 0;
}
-
-/* function: set_nonblocking
- * sets a filedescriptor to non-blocking mode
- * fd - the filedescriptor
- * returns: 0 on success, -1 on failure
- */
-int set_nonblocking(int fd) {
- int flags = fcntl(fd, F_GETFL);
- if (flags == -1) {
- return flags;
- }
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-}
-
-/* function: send_tun
- * sends a clat_packet to a tun interface
- * fd - the tun filedescriptor
- * out - the packet to send
- * iov_len - the number of entries in the clat_packet
- * returns: number of bytes read on success, -1 on failure
- */
-int send_tun(int fd, clat_packet out, int iov_len) { return writev(fd, out, iov_len); }
diff --git a/tun.h b/tun.h
index 95650fa..05f62c1 100644
--- a/tun.h
+++ b/tun.h
@@ -18,7 +18,10 @@
#ifndef __TUN_H__
#define __TUN_H__
+#include <fcntl.h>
#include <linux/if.h>
+#include <sys/uio.h>
+#include <unistd.h>
#include "common.h"
#include "ring.h"
@@ -29,9 +32,19 @@ struct tun_data {
struct packet_ring ring;
};
+// tun_open and tun_alloc are defined in tun.c and only used by clatd_microbenchmark.c
int tun_open();
int tun_alloc(char *dev, int fd, size_t len);
-int send_tun(int fd, clat_packet out, int iov_len);
-int set_nonblocking(int fd);
+
+/* function: send_tun
+ * sends a clat_packet to a tun interface
+ * fd - the tun filedescriptor
+ * out - the packet to send
+ * iov_len - the number of entries in the clat_packet
+ * returns: number of bytes read on success, -1 on failure
+ */
+static inline int send_tun(int fd, clat_packet out, int iov_len) {
+ return writev(fd, out, iov_len);
+}
#endif