summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-20 14:12:06 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-20 14:12:06 +0000
commitafe9b7dc7fa54cc4958a13aee30eb7eb1ca04f45 (patch)
tree7079b623b3832bfd7ec0ac58c772d4d3621a28cb
parent357913e954a272aa181b5f0417c71c4311519072 (diff)
parent85447d8c1ac9116298b34d08ab565ca0e1a1c863 (diff)
downloadnetd-android13-frc-permission-release.tar.gz
Snap for 8745897 from 85447d8c1ac9116298b34d08ab565ca0e1a1c863 to tm-frc-permission-releaset_frc_per_330444010android13-frc-permission-release
Change-Id: I257b8baaa79e9beeb90f70caf670bd48f11bfec4
-rw-r--r--Android.bp11
-rw-r--r--include/mainline/XtBpfProgLocations.h37
-rw-r--r--server/Android.bp30
-rw-r--r--server/BandwidthController.cpp7
-rw-r--r--server/BandwidthControllerTest.cpp2
-rw-r--r--server/Controllers.cpp10
-rw-r--r--server/TcUtils.h52
-rw-r--r--server/TetherController.h3
-rw-r--r--tests/Android.bp12
-rw-r--r--tests/benchmarks/Android.bp6
-rw-r--r--tests/binder_test.cpp304
11 files changed, 93 insertions, 381 deletions
diff --git a/Android.bp b/Android.bp
index 88379109..b654f76b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -33,6 +33,17 @@ cc_library_headers {
min_sdk_version: "29",
}
+cc_library_headers {
+ name: "netd_mainline_headers",
+ export_include_dirs: ["include/mainline"],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
+ ],
+ sdk_version: "29",
+ min_sdk_version: "29",
+}
+
cc_defaults {
name: "netd_defaults",
cflags: [
diff --git a/include/mainline/XtBpfProgLocations.h b/include/mainline/XtBpfProgLocations.h
new file mode 100644
index 00000000..95a5742c
--- /dev/null
+++ b/include/mainline/XtBpfProgLocations.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+/* -=-=-=-=-= WARNING -=-=-=-=-=-
+ *
+ * DO *NOT* *EVER* CHANGE THESE - they *MUST* match what the Tethering mainline module provides!
+ *
+ * You cannot even change them in sync, since newer module must work on older Android T releases.
+ *
+ * You could with difficulty, uprevs of the bpfloader, api detection logic in mainline, etc,
+ * change this in Android U or later, but even that is a very bad idea and not worth the hassle.
+ *
+ *
+ * Mainline Tethering module on T+ is expected to make available to netd (for use by
+ * BandwidthController iptables initialization code) four xt_bpf programs at the following
+ * locations:
+ */
+#define XT_BPF_NETD(NAME) "/sys/fs/bpf/netd_shared/prog_netd_skfilter_" NAME "_xtbpf"
+#define XT_BPF_ALLOWLIST_PROG_PATH XT_BPF_NETD("allowlist")
+#define XT_BPF_DENYLIST_PROG_PATH XT_BPF_NETD("denylist")
+#define XT_BPF_EGRESS_PROG_PATH XT_BPF_NETD("egress")
+#define XT_BPF_INGRESS_PROG_PATH XT_BPF_NETD("ingress")
diff --git a/server/Android.bp b/server/Android.bp
index f29f6cfc..06ea0bab 100644
--- a/server/Android.bp
+++ b/server/Android.bp
@@ -37,12 +37,15 @@ filegroup {
// Modules common to both netd and netd_unit_test
cc_library_static {
name: "libnetd_server",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_shared",
+ "netd_defaults",
+ ],
include_dirs: [
"system/netd/include",
"system/netd/server/binder",
],
- header_libs: ["bpf_connectivity_headers"],
+ header_libs: ["bpf_headers"],
srcs: [
"BandwidthController.cpp",
"Controllers.cpp",
@@ -71,7 +74,6 @@ cc_library_static {
"libpcap",
"libssl",
"libsysutils",
- "netd_aidl_interface-V8-cpp",
"netd_event_listener_interface-V1-cpp",
],
static_libs: [
@@ -86,7 +88,10 @@ cc_library_static {
cc_binary {
name: "netd",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_shared",
+ "netd_defaults",
+ ],
include_dirs: [
"external/mdnsresponder/mDNSShared",
"system/netd/include",
@@ -95,7 +100,7 @@ cc_binary {
required: [
"bpfloader",
],
- header_libs: ["bpf_connectivity_headers"],
+ header_libs: ["bpf_headers"],
shared_libs: [
"android.system.net.netd@1.0",
"android.system.net.netd@1.1",
@@ -116,7 +121,6 @@ cc_binary {
"libsysutils",
"libutils",
"mdns_aidl_interface-V1-cpp",
- "netd_aidl_interface-V8-cpp",
"netd_event_listener_interface-V1-cpp",
"oemnetd_aidl_interface-cpp",
],
@@ -156,7 +160,10 @@ cc_binary {
cc_binary {
name: "ndc",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_shared",
+ "netd_defaults",
+ ],
include_dirs: [
"system/netd/include",
],
@@ -172,7 +179,6 @@ cc_binary {
"libutils",
"libbinder",
"dnsresolver_aidl_interface-V7-cpp",
- "netd_aidl_interface-V8-cpp",
],
srcs: [
"ndc.cpp",
@@ -187,7 +193,10 @@ cc_binary {
cc_test {
name: "netd_unit_test",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_static",
+ "netd_defaults",
+ ],
test_suites: ["device-tests"],
require_root: true,
include_dirs: [
@@ -195,7 +204,7 @@ cc_test {
"system/netd/server/binder",
"system/netd/tests",
],
- header_libs: ["bpf_connectivity_headers"],
+ header_libs: ["bpf_headers"],
tidy_timeout_srcs: [
"BandwidthControllerTest.cpp",
"InterfaceControllerTest.cpp",
@@ -223,7 +232,6 @@ cc_test {
"libnetd_server",
"libnetd_test_tun_interface",
"libtcutils",
- "netd_aidl_interface-V8-cpp",
"netd_event_listener_interface-V1-cpp",
],
shared_libs: [
diff --git a/server/BandwidthController.cpp b/server/BandwidthController.cpp
index 96a82e23..8dba75a5 100644
--- a/server/BandwidthController.cpp
+++ b/server/BandwidthController.cpp
@@ -55,6 +55,7 @@
#include "FirewallController.h" /* For makeCriticalCommands */
#include "Fwmark.h"
#include "NetdConstants.h"
+#include "android/net/INetd.h"
#include "bpf/BpfUtils.h"
/* Alphabetical */
@@ -66,9 +67,6 @@ const char BandwidthController::LOCAL_RAW_PREROUTING[] = "bw_raw_PREROUTING";
const char BandwidthController::LOCAL_MANGLE_POSTROUTING[] = "bw_mangle_POSTROUTING";
const char BandwidthController::LOCAL_GLOBAL_ALERT[] = "bw_global_alert";
-// Sync from packages/modules/Connectivity/bpf_progs/clatd.c
-#define CLAT_MARK 0xdeadc1a7
-
auto BandwidthController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
using android::base::Join;
@@ -76,6 +74,7 @@ using android::base::StartsWith;
using android::base::StringAppendF;
using android::base::StringPrintf;
using android::net::FirewallController;
+using android::net::INetd::CLAT_MARK;
using android::netdutils::StatusOr;
using android::netdutils::UniqueFile;
@@ -147,8 +146,6 @@ const std::string NEW_CHAIN_COMMAND = "-N ";
*/
const std::string COMMIT_AND_CLOSE = "COMMIT\n";
-const std::string BPF_PENALTY_BOX_MATCH_DENYLIST_COMMAND = StringPrintf(
- "-I bw_penalty_box -m bpf --object-pinned %s -j REJECT", XT_BPF_DENYLIST_PROG_PATH);
static const std::vector<std::string> IPT_FLUSH_COMMANDS = {
/*
diff --git a/server/BandwidthControllerTest.cpp b/server/BandwidthControllerTest.cpp
index e7d29d23..844681d0 100644
--- a/server/BandwidthControllerTest.cpp
+++ b/server/BandwidthControllerTest.cpp
@@ -34,7 +34,7 @@
#include "BandwidthController.h"
#include "Fwmark.h"
#include "IptablesBaseTest.h"
-#include "bpf_shared.h"
+#include "mainline/XtBpfProgLocations.h"
#include "tun_interface.h"
using ::testing::_;
diff --git a/server/Controllers.cpp b/server/Controllers.cpp
index 0df6b0ee..00ee186d 100644
--- a/server/Controllers.cpp
+++ b/server/Controllers.cpp
@@ -277,7 +277,15 @@ void Controllers::init() {
initIptablesRules();
Stopwatch s;
- bandwidthCtrl.enableBandwidthControl();
+ if (int ret = bandwidthCtrl.enableBandwidthControl()) {
+ gLog.error("Failed to initialize BandwidthController (%s)", strerror(-ret));
+ // A failure to init almost definitely means that iptables failed to load
+ // our static ruleset, which then basically means network accounting will not work.
+ // As such simply exit netd. This may crash loop the system, but by failing
+ // to bootup we will trigger rollback and thus this offers us protection against
+ // a mainline update breaking things.
+ exit(1);
+ }
gLog.info("Enabling bandwidth control: %" PRId64 "us", s.getTimeAndResetUs());
if (int ret = RouteController::Init(NetworkController::LOCAL_NET_ID)) {
diff --git a/server/TcUtils.h b/server/TcUtils.h
index d205c04b..4b1b2b9f 100644
--- a/server/TcUtils.h
+++ b/server/TcUtils.h
@@ -26,42 +26,10 @@
#include <string>
#include "bpf/BpfUtils.h"
-#include "bpf_shared.h"
namespace android {
namespace net {
-// For better code clarity - do not change values - used for booleans like
-// with_ethernet_header or isEthernet.
-constexpr bool RAWIP = false;
-constexpr bool ETHER = true;
-
-// For better code clarity when used for 'bool ingress' parameter.
-constexpr bool EGRESS = false;
-constexpr bool INGRESS = true;
-
-// The priority of clat hook - must be after tethering.
-constexpr uint16_t PRIO_CLAT = 4;
-
-inline base::Result<bool> isEthernet(const std::string& interface) {
- bool result = false;
- if (int error = ::android::isEthernet(interface.c_str(), result)) {
- errno = error;
- return ErrnoErrorf("isEthernet failed for interface {}", interface);
- }
- return result;
-}
-
-inline int getClatEgress4MapFd(void) {
- const int fd = bpf::mapRetrieveRW(CLAT_EGRESS4_MAP_PATH);
- return (fd == -1) ? -errno : fd;
-}
-
-inline int getClatIngress6MapFd(void) {
- const int fd = bpf::mapRetrieveRW(CLAT_INGRESS6_MAP_PATH);
- return (fd == -1) ? -errno : fd;
-}
-
inline int tcQdiscAddDevClsact(int ifIndex) {
return doTcQdiscClsact(ifIndex, RTM_NEWQDISC, NLM_F_EXCL | NLM_F_CREATE);
}
@@ -74,25 +42,5 @@ inline int tcQdiscDelDevClsact(int ifIndex) {
return doTcQdiscClsact(ifIndex, RTM_DELQDISC, 0);
}
-// tc filter add dev .. ingress prio 4 protocol ipv6 bpf object-pinned /sys/fs/bpf/... direct-action
-inline int tcFilterAddDevIngressClatIpv6(int ifIndex, const std::string& bpfProgPath) {
- return tcAddBpfFilter(ifIndex, INGRESS, PRIO_CLAT, ETH_P_IPV6, bpfProgPath.c_str());
-}
-
-// tc filter add dev .. egress prio 4 protocol ip bpf object-pinned /sys/fs/bpf/... direct-action
-inline int tcFilterAddDevEgressClatIpv4(int ifIndex, const std::string& bpfProgPath) {
- return tcAddBpfFilter(ifIndex, EGRESS, PRIO_CLAT, ETH_P_IP, bpfProgPath.c_str());
-}
-
-// tc filter del dev .. ingress prio 4 protocol ipv6
-inline int tcFilterDelDevIngressClatIpv6(int ifIndex) {
- return tcDeleteFilter(ifIndex, INGRESS, PRIO_CLAT, ETH_P_IPV6);
-}
-
-// tc filter del dev .. egress prio 4 protocol ip
-inline int tcFilterDelDevEgressClatIpv4(int ifIndex) {
- return tcDeleteFilter(ifIndex, EGRESS, PRIO_CLAT, ETH_P_IP);
-}
-
} // namespace net
} // namespace android
diff --git a/server/TetherController.h b/server/TetherController.h
index b4472bd5..d2195f23 100644
--- a/server/TetherController.h
+++ b/server/TetherController.h
@@ -28,10 +28,11 @@
#include "NetdConstants.h"
#include "android-base/result.h"
#include "bpf/BpfMap.h"
-#include "bpf_shared.h"
#include "android/net/TetherOffloadRuleParcel.h"
+#include "mainline/XtBpfProgLocations.h"
+
namespace android {
namespace net {
diff --git a/tests/Android.bp b/tests/Android.bp
index 21830d6d..ff918cc1 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -37,7 +37,10 @@ cc_test_library {
cc_test_library {
name: "libnetd_test_unsol_service",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_shared",
+ "netd_defaults",
+ ],
srcs: [
"TestUnsolService.cpp"
],
@@ -52,7 +55,6 @@ cc_test_library {
"libnetutils",
"libsysutils",
"libutils",
- "netd_aidl_interface-V8-cpp",
],
}
@@ -74,7 +76,10 @@ cc_test {
"vts"
],
require_root: true,
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_static",
+ "netd_defaults",
+ ],
tidy: false, // cuts test build time by almost 1 minute
srcs: [
":netd_integration_test_shared",
@@ -109,7 +114,6 @@ cc_test {
"libnettestutils",
"libtcutils",
"mdns_aidl_interface-V1-cpp",
- "netd_aidl_interface-V8-cpp",
"netd_event_listener_interface-V1-cpp",
"oemnetd_aidl_interface-cpp",
],
diff --git a/tests/benchmarks/Android.bp b/tests/benchmarks/Android.bp
index 95c00aa6..13c8105f 100644
--- a/tests/benchmarks/Android.bp
+++ b/tests/benchmarks/Android.bp
@@ -11,7 +11,10 @@ package {
cc_benchmark {
name: "netd_benchmark",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_static",
+ "netd_defaults",
+ ],
shared_libs: [
"libbase",
"libbinder_ndk",
@@ -23,7 +26,6 @@ cc_benchmark {
static_libs: [
"libnetd_test_dnsresponder_ndk",
"dnsresolver_aidl_interface-lateststable-ndk",
- "netd_aidl_interface-lateststable-cpp", // system/netd/server/UidRanges.h
"netd_aidl_interface-lateststable-ndk",
"netd_event_listener_interface-lateststable-ndk",
],
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index f423ea38..bc1e7393 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -54,7 +54,6 @@
#include <binder/IPCThreadState.h>
#include <bpf/BpfMap.h>
#include <bpf/BpfUtils.h>
-#include <bpf_shared.h>
#include <com/android/internal/net/BnOemNetdUnsolicitedEventListener.h>
#include <com/android/internal/net/IOemNetd.h>
#include <cutils/multiuser.h>
@@ -3769,275 +3768,6 @@ TEST_F(NetdBinderTest, GetFwmarkForNetwork) {
EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}
-namespace {
-
-TetherOffloadRuleParcel makeTetherOffloadRule(int inputInterfaceIndex, int outputInterfaceIndex,
- const std::vector<uint8_t>& destination,
- int prefixLength,
- const std::vector<uint8_t>& srcL2Address,
- const std::vector<uint8_t>& dstL2Address, int pmtu) {
- android::net::TetherOffloadRuleParcel parcel;
- parcel.inputInterfaceIndex = inputInterfaceIndex;
- parcel.outputInterfaceIndex = outputInterfaceIndex;
- parcel.destination = destination;
- parcel.prefixLength = prefixLength;
- parcel.srcL2Address = srcL2Address;
- parcel.dstL2Address = dstL2Address;
- parcel.pmtu = pmtu;
- return parcel;
-}
-
-} // namespace
-
-// TODO: probably remove the test because TetherOffload* binder calls are deprecated.
-TEST_F(NetdBinderTest, DISABLED_TetherOffloadRule) {
- // TODO: Perhaps verify invalid interface index once the netd handle the error in methods.
- constexpr uint32_t kIfaceInt = 101;
- constexpr uint32_t kIfaceExt = 102;
- constexpr uint32_t kIfaceNonExistent = 103;
-
- const std::vector<uint8_t> kAddr6 = {0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88};
- const std::vector<uint8_t> kSrcMac = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0a};
- const std::vector<uint8_t> kDstMac = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0b};
-
- const std::vector<uint8_t> kInvalidAddr4 = {0xac, 0x0a, 0x0d, 0xb8}; // should be IPv6 address
- const std::vector<uint8_t> kInvalidMac = {0xde, 0xad, 0xbe, 0xef}; // should be 6-byte length
-
- // Invalid IP address, add rule
- TetherOffloadRuleParcel rule = makeTetherOffloadRule(
- kIfaceExt, kIfaceInt, kInvalidAddr4 /*bad*/, 128, kSrcMac, kDstMac, 1500);
- auto status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EAFNOSUPPORT, status.serviceSpecificErrorCode());
-
- // Invalid source L2 address, add rule
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kInvalidMac /*bad*/, kDstMac,
- 1500);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENXIO, status.serviceSpecificErrorCode());
-
- // Invalid destination L2 address, add rule
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kInvalidMac /*bad*/,
- 1500);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENXIO, status.serviceSpecificErrorCode());
-
- // Invalid IP address, remove rule
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kInvalidAddr4 /*bad*/, 128, kSrcMac, kDstMac,
- 1500);
- status = mNetd->tetherOffloadRuleRemove(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EAFNOSUPPORT, status.serviceSpecificErrorCode());
-
- // Invalid prefix length
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 64 /*bad*/, kSrcMac, kDstMac, 1500);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
- status = mNetd->tetherOffloadRuleRemove(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
-
- // Invalid interface index
- rule = makeTetherOffloadRule(kIfaceExt, 0, kAddr6, 128, kSrcMac, kDstMac, 1500);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());
- rule = makeTetherOffloadRule(0, kIfaceInt, kAddr6, 64, kSrcMac, kDstMac, 1500);
- status = mNetd->tetherOffloadRuleRemove(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());
-
- // Invalid pmtu (too low)
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1279);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
-
- // Invalid pmtu (too high)
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 65536);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
-
- // Remove non existent rule. Expect that silently return success if the rule did not exist.
- rule = makeTetherOffloadRule(kIfaceNonExistent, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1500);
- EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());
-
- // Add and remove rule normally.
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1500);
- EXPECT_TRUE(mNetd->tetherOffloadRuleAdd(rule).isOk());
- EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());
-}
-
-static bool expectPacket(int fd, uint8_t* ipPacket, ssize_t ipLen) {
- constexpr bool kDebug = false;
-
- uint8_t buf[ETHER_HDR_LEN + 1500];
-
- // Wait a bit to ensure that the packet we're interested in has arrived.
- // TODO: speed this up.
- usleep(100 * 1000);
-
- ssize_t bytesRead;
- ssize_t expectedLen = ipLen + ETHER_HDR_LEN;
- while ((bytesRead = read(fd, buf, sizeof(buf))) >= 0) {
- if (kDebug) {
- std::cerr << fmt::format(
- "Expected: {:02x}\n Actual: {:02x}\n",
- fmt::join(ipPacket, ipPacket + ipLen, " "),
- fmt::join(buf + ETHER_HDR_LEN, buf + ETHER_HDR_LEN + ipLen, " "));
- }
-
- if (bytesRead != expectedLen) {
- continue;
- }
-
- if (!memcmp(ipPacket, buf + ETHER_HDR_LEN, ipLen)) {
- return true;
- }
- }
-
- return false;
-}
-
-static bool tcQdiscExists(const std::string& interface) {
- std::string command = StringPrintf("tc qdisc show dev %s", interface.c_str());
- std::vector<std::string> lines = runCommand(command);
- for (const auto& line : lines) {
- if (StartsWith(line, "qdisc clsact ffff:")) return true;
- }
- return false;
-}
-
-static bool tcFilterExists(const std::string& interface) {
- std::string command = StringPrintf("tc filter show dev %s ingress", interface.c_str());
- std::vector<std::string> lines = runCommand(command);
- const std::basic_regex regex("^filter .* bpf .* prog_offload_schedcls_tether_.*$");
- for (const auto& line : lines) {
- if (std::regex_match(Trim(line), regex)) return true;
- }
- return false;
-}
-
-// TODO: probably remove the test because TetherOffload* binder calls are deprecated.
-TEST_F(NetdBinderTest, DISABLED_TetherOffloadForwarding) {
- SKIP_IF_EXTENDED_BPF_NOT_SUPPORTED;
-
- constexpr const char* kDownstreamPrefix = "2001:db8:2::/64";
-
- // 1500-byte packet.
- constexpr unsigned short kPayloadLen = 1500 - sizeof(ipv6hdr);
- struct packet {
- ipv6hdr hdr;
- char data[kPayloadLen];
- } __attribute__((packed)) pkt = {
- .hdr =
- {
- .version = 6,
- .payload_len = htons(kPayloadLen),
- .nexthdr = 59, // No next header.
- .hop_limit = 64,
- .saddr = {{{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}},
- .daddr = {{{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0f, 0x00, 0xca, 0xfe}}},
- },
- };
- ASSERT_EQ(1500U, sizeof(pkt));
-
- // Use one of the test's tun interfaces as upstream.
- // It must be part of a network or it will not have the clsact attached.
- const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false, false);
- EXPECT_TRUE(mNetd->networkCreate(config).isOk());
- EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
- int fd1 = sTun.getFdForTesting();
- EXPECT_TRUE(tcQdiscExists(sTun.name()));
-
- // Create our own tap as a downstream.
- TunInterface tap;
- ASSERT_EQ(0, tap.init(true /* isTap */));
- ASSERT_LE(tap.name().size(), static_cast<size_t>(IFNAMSIZ));
- int fd2 = tap.getFdForTesting();
-
- // Set it to nonblocking so that expectPacket can work.
- int flags = fcntl(fd2, F_GETFL, 0);
- fcntl(fd2, F_SETFL, flags | O_NONBLOCK);
-
- // Downstream interface setup. Add to local network, add directly-connected route, etc.
- binder::Status status = mNetd->networkAddInterface(INetd::LOCAL_NET_ID, tap.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- status = mNetd->tetherInterfaceAdd(tap.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- expectTetherInterfaceConfigureForIPv6Router(tap.name());
- EXPECT_TRUE(tcQdiscExists(tap.name()));
-
- // Can't easily use INetd::NEXTHOP_NONE because it is a String16 constant. Use "" instead.
- status = mNetd->networkAddRoute(INetd::LOCAL_NET_ID, tap.name(), kDownstreamPrefix, "");
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-
- // Set up forwarding. All methods take intIface first and extIface second.
- status = mNetd->tetherAddForward(tap.name(), sTun.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- status = mNetd->ipfwdAddInterfaceForward(tap.name(), sTun.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- EXPECT_TRUE(tcFilterExists(sTun.name()));
-
- std::vector<uint8_t> kDummyMac = {02, 00, 00, 00, 00, 00};
- uint8_t* daddr = reinterpret_cast<uint8_t*>(&pkt.hdr.daddr);
- std::vector<uint8_t> dstAddr(daddr, daddr + sizeof(pkt.hdr.daddr));
-
- TetherOffloadRuleParcel rule = makeTetherOffloadRule(sTun.ifindex(), tap.ifindex(), dstAddr,
- 128, kDummyMac, kDummyMac, sizeof(pkt));
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-
- // Set data limit to one byte less than two packets.
- // If you get rid of the '- 1' then the second packet will get forwarded
- // and the EXPECT_FALSE(expectPacket(...)) a dozen lines down will fail.
- status = mNetd->tetherOffloadSetInterfaceQuota(sTun.ifindex(), sizeof(pkt) * 2 - 1);
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-
- // Receive a packet on sTun.
- EXPECT_EQ((ssize_t)sizeof(pkt), write(fd1, &pkt, sizeof(pkt)));
-
- // Expect a packet identical to pkt, except with a TTL of 63.
- struct packet pkt2 = pkt;
- ASSERT_EQ(1500U, sizeof(pkt2));
- pkt2.hdr.hop_limit = pkt.hdr.hop_limit - 1;
- EXPECT_TRUE(expectPacket(fd2, (uint8_t*)&pkt2, sizeof(pkt2)));
-
- // Receive a second packet on sTun.
- EXPECT_EQ((ssize_t)sizeof(pkt), write(fd1, &pkt, sizeof(pkt)));
-
- // Should fail to forward due to quota limit.
- EXPECT_FALSE(expectPacket(fd2, (uint8_t*)&pkt2, sizeof(pkt2)));
-
- // Clean up.
- EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());
-
- TetherStatsParcel tetherStats;
- EXPECT_TRUE(mNetd->tetherOffloadGetAndClearStats(sTun.ifindex(), &tetherStats).isOk());
- EXPECT_EQ("", tetherStats.iface);
- EXPECT_EQ(static_cast<int64_t>(sizeof(pkt)), tetherStats.rxBytes);
- EXPECT_EQ(1, tetherStats.rxPackets);
- EXPECT_EQ(0, tetherStats.txBytes);
- EXPECT_EQ(0, tetherStats.txPackets);
- EXPECT_EQ(sTun.ifindex(), tetherStats.ifIndex);
-
- EXPECT_TRUE(mNetd->ipfwdRemoveInterfaceForward(tap.name(), sTun.name()).isOk());
- EXPECT_TRUE(mNetd->tetherRemoveForward(tap.name(), sTun.name()).isOk());
- EXPECT_TRUE(mNetd->networkRemoveRoute(INetd::LOCAL_NET_ID, tap.name(), kDownstreamPrefix, "")
- .isOk());
- EXPECT_TRUE(mNetd->tetherInterfaceRemove(tap.name()).isOk());
- EXPECT_TRUE(mNetd->networkRemoveInterface(INetd::LOCAL_NET_ID, tap.name()).isOk());
- EXPECT_TRUE(mNetd->networkRemoveInterface(TEST_NETID1, sTun.name()).isOk());
-}
-
TEST_F(NetdBinderTest, TestServiceDump) {
sp<IBinder> binder = INetd::asBinder(mNetd);
ASSERT_NE(nullptr, binder);
@@ -4119,40 +3849,6 @@ TEST_F(NetdBinderTest, TestServiceDump) {
}
}
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadRuleAdd) {
- TetherOffloadRuleParcel emptyRule;
- auto status = mNetd->tetherOffloadRuleAdd(emptyRule);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadRuleRemove) {
- TetherOffloadRuleParcel emptyRule;
- auto status = mNetd->tetherOffloadRuleRemove(emptyRule);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadGetStats) {
- std::vector<TetherStatsParcel> tetherStatsList;
- auto status = mNetd->tetherOffloadGetStats(&tetherStatsList);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadSetInterfaceQuota) {
- auto status = mNetd->tetherOffloadSetInterfaceQuota(0 /* ifIndex */, 0 /* quotaBytes */);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadGetAndClearStats) {
- TetherStatsParcel tetherStats;
- auto status = mNetd->tetherOffloadGetAndClearStats(0 /* ifIndex */, &tetherStats);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
namespace {
// aliases for better reading