summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHungming Chen <nuccachen@google.com>2021-11-24 20:28:36 +0800
committerHungming Chen <nuccachen@google.com>2021-12-30 22:48:29 +0800
commit7dadf8bf149376e0b4a15d94d24179b6fefd7339 (patch)
tree9670186a1d3c3edfdf0f8f3413afd7ea45555c00
parentd55a1cfc03dac6fd12443eb1c13501f739b2bbbc (diff)
downloadnetd-7dadf8bf149376e0b4a15d94d24179b6fefd7339.tar.gz
[RN#3] Move tun interface setup from clatd
Netd setup tun interface address/mtu and bring up the tun interface. Then, pass the prepared tun fd to clatd. This is a preparation for reducing the clatd required capability. Test: manual test 1. Connect to ipv6-only wifi. 2. Try IPv4 traffic. $ ping 8.8.8.8 Bug: 212345928 Change-Id: If95b2673638c9f481a8443959ff18d223ea1bcb1
-rw-r--r--server/ClatdController.cpp73
-rw-r--r--server/ClatdController.h7
2 files changed, 74 insertions, 6 deletions
diff --git a/server/ClatdController.cpp b/server/ClatdController.cpp
index 59b1b0c2..70058e91 100644
--- a/server/ClatdController.cpp
+++ b/server/ClatdController.cpp
@@ -34,6 +34,9 @@
#include "ClatdController.h"
#include "InterfaceController.h"
+#include <android/net/InterfaceConfigurationParcel.h>
+#include <netdutils/Status.h>
+
#include "android-base/properties.h"
#include "android-base/scopeguard.h"
#include "android-base/stringprintf.h"
@@ -422,6 +425,56 @@ int ClatdController::ClatdTracker::init(unsigned networkId, const std::string& i
return 0;
}
+/* function: configure_tun_ip
+ * configures the ipv4 address on the tunnel interface
+ * v4iface - tunnel interface name
+ * v4Str - tunnel ipv4 address
+ * mtu - mtu of tun device
+ * returns: 0 on success, errno on failure
+ */
+int ClatdController::configure_tun_ip(const char* v4iface, const char* v4Str, int mtu) {
+ ALOGI("Using IPv4 address %s on %s", v4Str, v4iface);
+
+ // Configure the interface before bringing it up. As soon as we bring the interface up, the
+ // framework will be notified and will assume the interface's configuration has been finalized.
+ std::string mtuStr = std::to_string(mtu);
+ if (int res = InterfaceController::setMtu(v4iface, mtuStr.c_str())) {
+ ALOGE("setMtu %s failed (%s)", v4iface, strerror(res));
+ return res;
+ }
+
+ InterfaceConfigurationParcel ifConfig;
+ ifConfig.ifName = std::string(v4iface);
+ ifConfig.ipv4Addr = std::string(v4Str);
+ ifConfig.prefixLength = 32;
+ ifConfig.hwAddr = std::string("");
+ ifConfig.flags = std::vector<std::string>{std::string(String8(INetd::IF_STATE_UP().string()))};
+ const auto& status = InterfaceController::setCfg(ifConfig);
+ if (!status.ok()) {
+ ALOGE("configure_tun_ip/setCfg failed: %s", strerror(-status.code()));
+ return -status.code();
+ }
+
+ return 0;
+}
+
+/* function: configure_interface
+ * reads the configuration and applies it to the interface
+ * tracker - clat tracker
+ * tunnel - tun device data
+ * returns: 0 on success, errno on failure
+ */
+int ClatdController::configure_interface(struct ClatdTracker* tracker,
+ struct tun_data* /*tunnel*/) {
+ int mtu = 1280; // TODO: detect MTU
+ ALOGI("ipv4 mtu is %d", mtu);
+
+ if (int ret = configure_tun_ip(tracker->v4iface, tracker->v4Str, mtu)) return ret;
+
+ // TODO: picks the clat IPv6 address and configures packet translation to use it.
+ return 0;
+}
+
int ClatdController::startClatd(const std::string& interface, const std::string& nat64Prefix,
std::string* v6Str) {
std::lock_guard guard(mutex);
@@ -541,7 +594,15 @@ int ClatdController::startClatd(const std::string& interface, const std::string&
char passedPacketSockStr[INT32_STRLEN];
snprintf(passedPacketSockStr, sizeof(passedPacketSock), "%d", passedPacketSock.get());
- // 10. we're going to use this as argv[0] to clatd to make ps output more useful
+ // 10. configure tun and clat interface
+ struct tun_data tunnel = {.fd4 = tmpTunFd, .read_fd6 = tmpPacketSock, .write_fd6 = tmpRawSock};
+ res = configure_interface(&tracker, &tunnel);
+ if (res) {
+ ALOGE("configure interface failed: %s", strerror(res));
+ return -res;
+ }
+
+ // 11. we're going to use this as argv[0] to clatd to make ps output more useful
std::string progname("clatd-");
progname += tracker.iface;
@@ -558,7 +619,7 @@ int ClatdController::startClatd(const std::string& interface, const std::string&
nullptr};
// clang-format on
- // 11. register vfork requirement
+ // 12. register vfork requirement
posix_spawnattr_t attr;
res = posix_spawnattr_init(&attr);
if (res) {
@@ -572,7 +633,7 @@ int ClatdController::startClatd(const std::string& interface, const std::string&
return -res;
}
- // 12. register dup2() action: this is what 'clears' the CLOEXEC flag
+ // 13. register dup2() action: this is what 'clears' the CLOEXEC flag
// on the tun fd that we want the child clatd process to inherit
// (this will happen after the vfork, and before the execve)
posix_spawn_file_actions_t fa;
@@ -598,17 +659,17 @@ int ClatdController::startClatd(const std::string& interface, const std::string&
return -res;
}
- // 13. add the drop rule for iptables.
+ // 14. add the drop rule for iptables.
setIptablesDropRule(true, tracker.iface, tracker.pfx96String, tracker.v6Str);
- // 14. actually perform vfork/dup2/execve
+ // 15. actually perform vfork/dup2/execve
res = posix_spawn(&tracker.pid, kClatdPath, &fa, &attr, (char* const*)args, nullptr);
if (res) {
ALOGE("posix_spawn failed (%s)", strerror(res));
return -res;
}
- // 15. configure eBPF offload - if possible
+ // 16. configure eBPF offload - if possible
maybeStartBpf(tracker);
mClatdTrackers[interface] = tracker;
diff --git a/server/ClatdController.h b/server/ClatdController.h
index 9da452a7..9d50907a 100644
--- a/server/ClatdController.h
+++ b/server/ClatdController.h
@@ -74,6 +74,10 @@ class ClatdController {
const std::string& nat64Prefix);
};
+ struct tun_data {
+ int read_fd6, write_fd6, fd4;
+ };
+
std::mutex mutex;
const NetworkController* mNetCtrl GUARDED_BY(mutex);
@@ -97,6 +101,9 @@ class ClatdController {
void setIptablesDropRule(bool add, const char* iface, const char* pfx96Str, const char* v6Str)
REQUIRES(mutex);
+ int configure_interface(struct ClatdTracker* tracker, struct tun_data* tunnel) REQUIRES(mutex);
+ int configure_tun_ip(const char* v4iface, const char* v4Str, int mtu) REQUIRES(mutex);
+
// For testing.
friend class ClatdControllerTest;