summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-07-03 03:10:00 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-07-03 03:10:00 +0000
commite27bf9edf55a77172ab26b2b494cbdf19b545268 (patch)
tree3b9df12f00cecbbb81104974cdc583d1cddc3889
parent4f2e8937214f02a954143390f221a77f3ca7a371 (diff)
parentcfc15dd03578051f88a40d94dcb42b2597614a1f (diff)
downloadnetd-android10-s3-release.tar.gz
Change-Id: I275627be5b536b5ba4b034b5ed4407135a29dd72
-rw-r--r--server/ClatdController.cpp24
-rw-r--r--server/ClatdController.h10
-rw-r--r--server/ClatdControllerTest.cpp36
-rw-r--r--server/Controllers.cpp1
-rw-r--r--server/ControllersTest.cpp2
5 files changed, 70 insertions, 3 deletions
diff --git a/server/ClatdController.cpp b/server/ClatdController.cpp
index d82198b1..5a5566b3 100644
--- a/server/ClatdController.cpp
+++ b/server/ClatdController.cpp
@@ -36,6 +36,7 @@
#include "android-base/properties.h"
#include "android-base/scopeguard.h"
+#include "android-base/stringprintf.h"
#include "android-base/unique_fd.h"
#include "bpf/BpfMap.h"
#include "netdbpf/bpf_shared.h"
@@ -59,6 +60,7 @@ static const char* kV4AddrString = "192.0.0.4";
static const in_addr kV4Addr = {inet_addr(kV4AddrString)};
static const int kV4AddrLen = 29;
+using android::base::StringPrintf;
using android::base::unique_fd;
using android::bpf::BpfMap;
using android::netdutils::DumpWriter;
@@ -312,6 +314,18 @@ void ClatdController::maybeStartBpf(const ClatdTracker& tracker) {
// success
}
+void ClatdController::maybeSetIptablesDropRule(bool add, const char* pfx96Str, const char* v6Str) {
+ if (mClatEbpfMode == ClatEbpfDisabled) return;
+
+ std::string cmd = StringPrintf(
+ "*raw\n"
+ "%s %s -s %s/96 -d %s -j DROP\n"
+ "COMMIT\n",
+ (add ? "-A" : "-D"), LOCAL_RAW_PREROUTING, pfx96Str, v6Str);
+
+ iptablesRestoreFunction(V6, cmd);
+}
+
void ClatdController::maybeStopBpf(const ClatdTracker& tracker) {
if (mClatEbpfMode == ClatEbpfDisabled) return;
@@ -502,14 +516,17 @@ int ClatdController::startClatd(const std::string& interface, const std::string&
return -res;
}
- // 11. actually perform vfork/dup2/execve
+ // 11. If necessary, add the drop rule for iptables.
+ maybeSetIptablesDropRule(true, tracker.pfx96String, tracker.v6Str);
+
+ // 12. 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;
}
- // 12. configure eBPF offload - if possible
+ // 13. configure eBPF offload - if possible
maybeStartBpf(tracker);
mClatdTrackers[interface] = tracker;
@@ -534,6 +551,8 @@ int ClatdController::stopClatd(const std::string& interface) {
kill(tracker->pid, SIGTERM);
waitpid(tracker->pid, nullptr, 0);
+
+ maybeSetIptablesDropRule(false, tracker->pfx96String, tracker->v6Str);
mClatdTrackers.erase(interface);
ALOGD("clatd on %s stopped", interface.c_str());
@@ -593,6 +612,7 @@ void ClatdController::dump(DumpWriter& dw) {
}
auto ClatdController::isIpv4AddressFreeFunc = isIpv4AddressFree;
+auto ClatdController::iptablesRestoreFunction = execIptablesRestore;
} // namespace net
} // namespace android
diff --git a/server/ClatdController.h b/server/ClatdController.h
index a00f7133..8648f17e 100644
--- a/server/ClatdController.h
+++ b/server/ClatdController.h
@@ -52,6 +52,8 @@ class ClatdController {
void dump(netdutils::DumpWriter& dw) EXCLUDES(mutex);
+ static constexpr const char LOCAL_RAW_PREROUTING[] = "clat_raw_PREROUTING";
+
private:
struct ClatdTracker {
pid_t pid = -1;
@@ -91,17 +93,25 @@ class ClatdController {
ClatEbpfEnabled, // >=4.9 kernel && >=Q api shipping level -- must work
};
eClatEbpfMode mClatEbpfMode GUARDED_BY(mutex);
+ eClatEbpfMode getEbpfMode() EXCLUDES(mutex) {
+ std::lock_guard guard(mutex);
+ return mClatEbpfMode;
+ }
+
base::unique_fd mNetlinkFd GUARDED_BY(mutex);
bpf::BpfMap<ClatIngressKey, ClatIngressValue> mClatIngressMap GUARDED_BY(mutex);
void maybeStartBpf(const ClatdTracker& tracker) REQUIRES(mutex);
void maybeStopBpf(const ClatdTracker& tracker) REQUIRES(mutex);
+ void maybeSetIptablesDropRule(bool add, const char* pfx96Str, const char* v6Str)
+ REQUIRES(mutex);
// For testing.
friend class ClatdControllerTest;
static bool (*isIpv4AddressFreeFunc)(in_addr_t);
static bool isIpv4AddressFree(in_addr_t addr);
+ static int (*iptablesRestoreFunction)(IptablesTarget target, const std::string& commands);
};
} // namespace net
diff --git a/server/ClatdControllerTest.cpp b/server/ClatdControllerTest.cpp
index a4a271ad..e90dd1a9 100644
--- a/server/ClatdControllerTest.cpp
+++ b/server/ClatdControllerTest.cpp
@@ -31,6 +31,8 @@ extern "C" {
}
#include "ClatdController.h"
+#include "IptablesBaseTest.h"
+#include "NetworkController.h"
#include "tun_interface.h"
static const char kIPv4LocalAddr[] = "192.0.0.4";
@@ -57,11 +59,21 @@ bool only10Free(in_addr_t addr) {
return (ntohl(addr) & 0xff) == 10;
}
-class ClatdControllerTest : public ::testing::Test {
+class ClatdControllerTest : public IptablesBaseTest {
public:
+ ClatdControllerTest() : mClatdCtrl(nullptr) {
+ ClatdController::iptablesRestoreFunction = fakeExecIptablesRestore;
+ }
+
void SetUp() { resetIpv4AddressFreeFunc(); }
protected:
+ ClatdController mClatdCtrl;
+ bool isEbpfDisabled() { return mClatdCtrl.getEbpfMode() == ClatdController::ClatEbpfDisabled; }
+ void maybeSetIptablesDropRule(bool a, const char* b, const char* c) {
+ std::lock_guard guard(mClatdCtrl.mutex);
+ return mClatdCtrl.maybeSetIptablesDropRule(a, b, c);
+ }
void setIpv4AddressFreeFunc(bool (*func)(in_addr_t)) {
ClatdController::isIpv4AddressFreeFunc = func;
}
@@ -175,5 +187,27 @@ TEST_F(ClatdControllerTest, MakeChecksumNeutral) {
EXPECT_GE(3210000, onebits);
}
+TEST_F(ClatdControllerTest, AddRemoveIptablesRule) {
+ if (isEbpfDisabled()) return;
+
+ ExpectedIptablesCommands expected = {
+ {V6,
+ "*raw\n"
+ "-A clat_raw_PREROUTING -s 64:ff9b::/96 -d 2001:db8::1:2:3:4 -j DROP\n"
+ "COMMIT\n"},
+ };
+ maybeSetIptablesDropRule(true, "64:ff9b::", "2001:db8::1:2:3:4");
+ expectIptablesRestoreCommands(expected);
+
+ expected = {
+ {V6,
+ "*raw\n"
+ "-D clat_raw_PREROUTING -s 64:ff9b::/96 -d 2001:db8::a:b:c:d -j DROP\n"
+ "COMMIT\n"},
+ };
+ maybeSetIptablesDropRule(false, "64:ff9b::", "2001:db8::a:b:c:d");
+ expectIptablesRestoreCommands(expected);
+}
+
} // namespace net
} // namespace android
diff --git a/server/Controllers.cpp b/server/Controllers.cpp
index 01eae773..c941a804 100644
--- a/server/Controllers.cpp
+++ b/server/Controllers.cpp
@@ -73,6 +73,7 @@ static const std::vector<const char*> FILTER_OUTPUT = {
};
static const std::vector<const char*> RAW_PREROUTING = {
+ ClatdController::LOCAL_RAW_PREROUTING,
BandwidthController::LOCAL_RAW_PREROUTING,
IdletimerController::LOCAL_RAW_PREROUTING,
TetherController::LOCAL_RAW_PREROUTING,
diff --git a/server/ControllersTest.cpp b/server/ControllersTest.cpp
index cc8b1aaa..ebaa38f6 100644
--- a/server/ControllersTest.cpp
+++ b/server/ControllersTest.cpp
@@ -96,6 +96,8 @@ TEST_F(ControllersTest, TestInitIptablesRules) {
"*raw\n"
":PREROUTING -\n"
"-F PREROUTING\n"
+ ":clat_raw_PREROUTING -\n"
+ "-A PREROUTING -j clat_raw_PREROUTING\n"
":bw_raw_PREROUTING -\n"
"-A PREROUTING -j bw_raw_PREROUTING\n"
":idletimer_raw_PREROUTING -\n"