diff --git a/bpf_progs/Android.bp b/bpf_progs/Android.bp index bb9f5ead63..e228df0c13 100644 --- a/bpf_progs/Android.bp +++ b/bpf_progs/Android.bp @@ -43,6 +43,7 @@ cc_library_headers { // calls to JNI in libservices.core. "//frameworks/base/services/core/jni", "//packages/modules/Connectivity/Tethering", + "//packages/modules/Connectivity/service/native", "//packages/modules/Connectivity/tests/unit/jni", // TODO: remove system/netd/* when all BPF code is moved out of Netd. "//system/netd/libnetdbpf", diff --git a/service/native/Android.bp b/service/native/Android.bp new file mode 100644 index 0000000000..ce18b8398d --- /dev/null +++ b/service/native/Android.bp @@ -0,0 +1,49 @@ +/* + * 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. + */ + +cc_library { + name: "libtraffic_controller", + defaults: ["netd_defaults"], + srcs: [ + "TrafficController.cpp", + ], + header_libs: [ + "bpf_connectivity_headers", + "bpf_headers", + "bpf_syscall_wrappers", + ], + static_libs: [ + "libnetdutils", + // TrafficController would use the constants of INetd so that add + // netd_aidl_interface-lateststable-ndk. + "netd_aidl_interface-lateststable-ndk", + ], + shared_libs: [ + // TODO: Find a good way to remove libbase. + "libbase", + "libcutils", + "libutils", + "liblog", + ], + export_include_dirs: ["include"], + sanitize: { + cfi: true, + }, + apex_available: [ + "com.android.tethering", + ], + min_sdk_version: "30", +} diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp index c24a41bcc8..cac545d4bc 100644 --- a/service/native/TrafficController.cpp +++ b/service/native/TrafficController.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -38,12 +39,12 @@ #include #include #include - #include #include +#include + #include "TrafficController.h" #include "bpf/BpfMap.h" - #include "netdutils/DumpWriter.h" namespace android { @@ -186,18 +187,12 @@ Status TrafficController::initMaps() { } Status TrafficController::start() { - /* When netd restarts from a crash without total system reboot, the program - * is still attached to the cgroup, detach it so the program can be freed - * and we can load and attach new program into the target cgroup. - * - * TODO: Scrape existing socket when run-time restart and clean up the map - * if the socket no longer exist - */ - RETURN_IF_NOT_OK(initMaps()); // Fetch the list of currently-existing interfaces. At this point NetlinkHandler is // already running, so it will call addInterface() when any new interface appears. + // TODO: Clean-up addInterface() after interface monitoring is in + // NetworkStatsService. std::map ifacePairs; ASSIGN_OR_RETURN(ifacePairs, getIfaceList()); for (const auto& ifacePair:ifacePairs) { @@ -406,18 +401,16 @@ Status TrafficController::addRule(uint32_t uid, UidOwnerMatchType match, uint32_ return netdutils::status::ok; } -Status TrafficController::updateUidOwnerMap(const std::vector& appUids, +Status TrafficController::updateUidOwnerMap(const uint32_t uid, UidOwnerMatchType matchType, IptOp op) { std::lock_guard guard(mMutex); - for (uint32_t uid : appUids) { - if (op == IptOpDelete) { - RETURN_IF_NOT_OK(removeRule(uid, matchType)); - } else if (op == IptOpInsert) { - RETURN_IF_NOT_OK(addRule(uid, matchType)); - } else { - // Cannot happen. - return statusFromErrno(EINVAL, StringPrintf("invalid IptOp: %d, %d", op, matchType)); - } + if (op == IptOpDelete) { + RETURN_IF_NOT_OK(removeRule(uid, matchType)); + } else if (op == IptOpInsert) { + RETURN_IF_NOT_OK(addRule(uid, matchType)); + } else { + // Cannot happen. + return statusFromErrno(EINVAL, StringPrintf("invalid IptOp: %d, %d", op, matchType)); } return netdutils::status::ok; } @@ -752,7 +745,7 @@ void TrafficController::dump(DumpWriter& dw, bool verbose) { dw.println("mCookieTagMap print end with error: %s", res.error().message().c_str()); } - // Print UidCounterSetMap Content + // Print UidCounterSetMap content. dumpBpfMap("mUidCounterSetMap", dw, ""); const auto printUidInfo = [&dw](const uint32_t& key, const uint8_t& value, const BpfMap&) { @@ -764,7 +757,7 @@ void TrafficController::dump(DumpWriter& dw, bool verbose) { dw.println("mUidCounterSetMap print end with error: %s", res.error().message().c_str()); } - // Print AppUidStatsMap content + // Print AppUidStatsMap content. std::string appUidStatsHeader = StringPrintf("uid rxBytes rxPackets txBytes txPackets"); dumpBpfMap("mAppUidStatsMap:", dw, appUidStatsHeader); auto printAppUidStatsInfo = [&dw](const uint32_t& key, const StatsValue& value, @@ -778,7 +771,7 @@ void TrafficController::dump(DumpWriter& dw, bool verbose) { dw.println("mAppUidStatsMap print end with error: %s", res.error().message().c_str()); } - // Print uidStatsMap content + // Print uidStatsMap content. std::string statsHeader = StringPrintf("ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes" " rxPackets txBytes txPackets"); dumpBpfMap("mStatsMapA", dw, statsHeader); diff --git a/service/native/include/Common.h b/service/native/include/Common.h new file mode 100644 index 0000000000..7c0b797f78 --- /dev/null +++ b/service/native/include/Common.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 +// TODO: deduplicate with the constants in NetdConstants.h. +#include + +using aidl::android::net::INetd; + +enum FirewallRule { ALLOW = INetd::FIREWALL_RULE_ALLOW, DENY = INetd::FIREWALL_RULE_DENY }; + +// ALLOWLIST means the firewall denies all by default, uids must be explicitly ALLOWed +// DENYLIST means the firewall allows all by default, uids must be explicitly DENYed + +enum FirewallType { ALLOWLIST = INetd::FIREWALL_ALLOWLIST, DENYLIST = INetd::FIREWALL_DENYLIST }; + +enum ChildChain { + NONE = INetd::FIREWALL_CHAIN_NONE, + DOZABLE = INetd::FIREWALL_CHAIN_DOZABLE, + STANDBY = INetd::FIREWALL_CHAIN_STANDBY, + POWERSAVE = INetd::FIREWALL_CHAIN_POWERSAVE, + RESTRICTED = INetd::FIREWALL_CHAIN_RESTRICTED, + INVALID_CHAIN +}; diff --git a/service/native/include/TrafficController.h b/service/native/include/TrafficController.h index 3e98b68c34..c0508719fe 100644 --- a/service/native/include/TrafficController.h +++ b/service/native/include/TrafficController.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -14,12 +14,11 @@ * limitations under the License. */ -#ifndef NETD_SERVER_TRAFFIC_CONTROLLER_H -#define NETD_SERVER_TRAFFIC_CONTROLLER_H +#pragma once -#include +#include +#include -#include "NetlinkListener.h" #include "android-base/thread_annotations.h" #include "bpf/BpfMap.h" #include "bpf_shared.h" @@ -31,6 +30,8 @@ namespace android { namespace net { +using netdutils::StatusOr; + class TrafficController { public: /* @@ -38,9 +39,6 @@ class TrafficController { */ netdutils::Status start(); - /* - * Similiar as above, no external lock required. - */ int setCounterSet(int counterSetNum, uid_t uid, uid_t callingUid) EXCLUDES(mMutex); /* @@ -84,7 +82,7 @@ class TrafficController { EXCLUDES(mMutex); netdutils::Status removeUidInterfaceRules(const std::vector& uids) EXCLUDES(mMutex); - netdutils::Status updateUidOwnerMap(const std::vector& appStrUids, + netdutils::Status updateUidOwnerMap(const uint32_t uid, UidOwnerMatchType matchType, IptOp op) EXCLUDES(mMutex); static const String16 DUMP_KEYWORD; @@ -187,21 +185,6 @@ class TrafficController { netdutils::Status addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif = 0) REQUIRES(mMutex); - // mMutex guards all accesses to mConfigurationMap, mUidOwnerMap, mUidPermissionMap, - // mStatsMapA, mStatsMapB and mPrivilegedUser. It is designed to solve the following - // problems: - // 1. Prevent concurrent access and modification to mConfigurationMap, mUidOwnerMap, - // mUidPermissionMap, and mPrivilegedUser. These data members are controlled by netd but can - // be modified from different threads. TrafficController provides several APIs directly - // called by the binder RPC, and different binder threads can concurrently access these data - // members mentioned above. Some of the data members such as mUidPermissionMap and - // mPrivilegedUsers are also accessed from a different thread when tagging sockets or - // setting the counterSet through FwmarkServer - // 2. Coordinate the deletion of uid stats in mStatsMapA and mStatsMapB. The system server - // always call into netd to ask for a live stats map change before it pull and clean up the - // stats from the inactive map. The mMutex will block netd from accessing the stats map when - // the mConfigurationMap is updating the current stats map so netd will not accidentally - // read the map that system_server is cleaning up. std::mutex mMutex; netdutils::Status initMaps() EXCLUDES(mMutex); @@ -218,5 +201,3 @@ class TrafficController { } // namespace net } // namespace android - -#endif // NETD_SERVER_TRAFFIC_CONTROLLER_H