summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2021-08-12 12:03:24 -0700
committerXin Li <delphij@google.com>2021-08-12 22:34:55 +0000
commitf237df3092cb6d8316a49e9abccdf8c94ae7cb46 (patch)
tree389d5f648f0e28282ce9b077d1c0ff513f88b78c
parent2d4975f0c055ed9ee6ef9050c03fb19214d648b5 (diff)
parent99f5d10a0267a330e3aabeb9503c8bb9531f612c (diff)
downloadnetd-f237df3092cb6d8316a49e9abccdf8c94ae7cb46.tar.gz
Merge ab/7633965
Bug: 169893837 Merged-In: I14e544285d4096c404e33b79bc877836210523db Change-Id: I5129e704a57d5ba0aa21be90ad81f2af79839dcd
-rw-r--r--server/Android.bp15
-rw-r--r--server/NetdNativeService.cpp21
-rw-r--r--server/NetdNativeService.h4
-rw-r--r--server/Network.cpp62
-rw-r--r--server/Network.h21
-rw-r--r--server/NetworkController.cpp52
-rw-r--r--server/NetworkController.h6
-rw-r--r--server/PhysicalNetwork.cpp26
-rw-r--r--server/PhysicalNetwork.h5
-rw-r--r--server/RouteController.cpp203
-rw-r--r--server/RouteController.h31
-rw-r--r--server/UidRanges.cpp2
-rw-r--r--server/UidRanges.h4
-rw-r--r--server/UnreachableNetwork.cpp22
-rw-r--r--server/UnreachableNetwork.h5
-rw-r--r--server/VirtualNetwork.cpp25
-rw-r--r--server/VirtualNetwork.h5
-rw-r--r--server/aidl_api/netd_aidl_interface/7/.hash1
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/INetd.aidl200
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/INetdUnsolicitedEventListener.aidl48
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/InterfaceConfigurationParcel.aidl42
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/MarkMaskParcel.aidl39
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkConfig.aidl43
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkType.aidl39
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/NativeVpnType.aidl41
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/RouteInfoParcel.aidl40
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/TetherConfigParcel.aidl39
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/TetherOffloadRuleParcel.aidl44
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/TetherStatsParcel.aidl43
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/UidRangeParcel.aidl40
-rw-r--r--server/aidl_api/netd_aidl_interface/7/android/net/netd/aidl/NativeUidRangeConfig.aidl41
-rw-r--r--server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl2
-rw-r--r--server/aidl_api/netd_aidl_interface/current/android/net/netd/aidl/NativeUidRangeConfig.aidl41
-rw-r--r--server/binder/android/net/INetd.aidl28
-rw-r--r--server/binder/android/net/netd/aidl/NativeUidRangeConfig.aidl41
-rw-r--r--tests/Android.bp4
-rw-r--r--tests/binder_test.cpp351
37 files changed, 1458 insertions, 218 deletions
diff --git a/server/Android.bp b/server/Android.bp
index cf0a29c5..9c89041a 100644
--- a/server/Android.bp
+++ b/server/Android.bp
@@ -12,7 +12,7 @@ java_library {
sdk_version: "system_current",
min_sdk_version: "29",
static_libs: [
- "netd_aidl_interface-V6-java",
+ "netd_aidl_interface-V7-java",
],
apex_available: [
"//apex_available:platform", // used from services.net
@@ -36,7 +36,7 @@ cc_library_static {
cc_library_static {
name: "netd_aidl_interface-lateststable-ndk_platform",
whole_static_libs: [
- "netd_aidl_interface-V6-ndk_platform",
+ "netd_aidl_interface-V7-ndk_platform",
],
apex_available: [
"com.android.resolv",
@@ -47,7 +47,7 @@ cc_library_static {
cc_library_static {
name: "netd_aidl_interface-lateststable-cpp",
whole_static_libs: [
- "netd_aidl_interface-V6-cpp",
+ "netd_aidl_interface-V7-cpp",
],
}
@@ -68,6 +68,8 @@ aidl_interface {
"binder/android/net/TetherOffloadRuleParcel.aidl",
"binder/android/net/TetherStatsParcel.aidl",
"binder/android/net/UidRangeParcel.aidl",
+ // Add new AIDL classes in android.net.netd.aidl to consist with other network modules.
+ "binder/android/net/netd/aidl/**/*.aidl",
],
backend: {
cpp: {
@@ -101,6 +103,7 @@ aidl_interface {
"4",
"5",
"6",
+ "7",
],
}
@@ -219,7 +222,7 @@ cc_library_static {
"libqtaguid",
"libssl",
"libsysutils",
- "netd_aidl_interface-V6-cpp",
+ "netd_aidl_interface-V7-cpp",
"netd_event_listener_interface-V1-cpp",
],
aidl: {
@@ -262,7 +265,7 @@ cc_binary {
"libselinux",
"libsysutils",
"libutils",
- "netd_aidl_interface-V6-cpp",
+ "netd_aidl_interface-V7-cpp",
"netd_event_listener_interface-V1-cpp",
"oemnetd_aidl_interface-cpp",
],
@@ -360,7 +363,7 @@ cc_test {
"libnetd_server",
"libnetd_test_tun_interface",
"libqtaguid",
- "netd_aidl_interface-V6-cpp",
+ "netd_aidl_interface-V7-cpp",
"netd_event_listener_interface-V1-cpp",
],
shared_libs: [
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index 05c515d3..1f5dc976 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -56,6 +56,7 @@ using android::net::NativeNetworkType;
using android::net::TetherOffloadRuleParcel;
using android::net::TetherStatsParcel;
using android::net::UidRangeParcel;
+using android::net::netd::aidl::NativeUidRangeConfig;
using android::netdutils::DumpWriter;
using android::netdutils::ScopedIndent;
using android::os::ParcelFileDescriptor;
@@ -400,7 +401,8 @@ binder::Status NetdNativeService::networkAddUidRanges(
int32_t netId, const std::vector<UidRangeParcel>& uidRangeArray) {
// NetworkController::addUsersToNetwork is thread-safe.
ENFORCE_NETWORK_STACK_PERMISSIONS();
- int ret = gCtls->netCtrl.addUsersToNetwork(netId, UidRanges(uidRangeArray));
+ int ret = gCtls->netCtrl.addUsersToNetwork(netId, UidRanges(uidRangeArray),
+ UidRanges::DEFAULT_SUB_PRIORITY);
return statusFromErrcode(ret);
}
@@ -408,7 +410,22 @@ binder::Status NetdNativeService::networkRemoveUidRanges(
int32_t netId, const std::vector<UidRangeParcel>& uidRangeArray) {
// NetworkController::removeUsersFromNetwork is thread-safe.
ENFORCE_NETWORK_STACK_PERMISSIONS();
- int ret = gCtls->netCtrl.removeUsersFromNetwork(netId, UidRanges(uidRangeArray));
+ int ret = gCtls->netCtrl.removeUsersFromNetwork(netId, UidRanges(uidRangeArray),
+ UidRanges::DEFAULT_SUB_PRIORITY);
+ return statusFromErrcode(ret);
+}
+
+binder::Status NetdNativeService::networkAddUidRangesParcel(const NativeUidRangeConfig& config) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int ret = gCtls->netCtrl.addUsersToNetwork(config.netId, UidRanges(config.uidRanges),
+ config.subPriority);
+ return statusFromErrcode(ret);
+}
+
+binder::Status NetdNativeService::networkRemoveUidRangesParcel(const NativeUidRangeConfig& config) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int ret = gCtls->netCtrl.removeUsersFromNetwork(config.netId, UidRanges(config.uidRanges),
+ config.subPriority);
return statusFromErrcode(ret);
}
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index 1e995ef2..9779f368 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -74,6 +74,10 @@ class NetdNativeService : public BinderService<NetdNativeService>, public BnNetd
const std::vector<UidRangeParcel>& uids) override;
binder::Status networkRemoveUidRanges(int32_t netId,
const std::vector<UidRangeParcel>& uids) override;
+ binder::Status networkAddUidRangesParcel(
+ const netd::aidl::NativeUidRangeConfig& uidRangesConfig) override;
+ binder::Status networkRemoveUidRangesParcel(
+ const netd::aidl::NativeUidRangeConfig& uidRangesConfig) override;
binder::Status networkRejectNonSecureVpn(bool enable,
const std::vector<UidRangeParcel>& uids) override;
binder::Status networkAddRouteParcel(int32_t netId, const RouteInfoParcel& route) override;
diff --git a/server/Network.cpp b/server/Network.cpp
index cba9edf5..72a15454 100644
--- a/server/Network.cpp
+++ b/server/Network.cpp
@@ -70,22 +70,66 @@ std::string Network::toString() const {
return repr.str();
}
-bool Network::appliesToUser(uid_t uid) const {
- return mUidRanges.hasUid(uid);
+std::string Network::uidRangesToString() const {
+ if (mUidRangeMap.empty()) {
+ return "";
+ }
+
+ std::ostringstream result;
+ for (auto it = mUidRangeMap.begin(); it != mUidRangeMap.end(); ++it) {
+ result << "prio " << it->first << " " << it->second.toString();
+ if (std::next(it) != mUidRangeMap.end()) result << "; ";
+ }
+ return result.str();
+}
+
+// Check if the user has been added to this network. If yes, the highest priority of matching
+// setting is returned by subPriority. Thus caller can make choice among several matching
+// networks.
+bool Network::appliesToUser(uid_t uid, uint32_t* subPriority) const {
+ for (const auto& [priority, uidRanges] : mUidRangeMap) {
+ if (uidRanges.hasUid(uid)) {
+ *subPriority = priority;
+ return true;
+ }
+ }
+ return false;
}
-bool Network::hasInvalidUidRanges(const UidRanges& uidRanges) const {
+void Network::addToUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority) {
+ auto iter = mUidRangeMap.find(subPriority);
+ if (iter != mUidRangeMap.end()) {
+ iter->second.add(uidRanges);
+ } else {
+ mUidRangeMap[subPriority] = uidRanges;
+ }
+}
+
+void Network::removeFromUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority) {
+ auto iter = mUidRangeMap.find(subPriority);
+ if (iter != mUidRangeMap.end()) {
+ iter->second.remove(uidRanges);
+ if (iter->second.empty()) {
+ mUidRangeMap.erase(subPriority);
+ }
+ } else {
+ ALOGW("uidRanges with priority %u not found", subPriority);
+ }
+}
+
+bool Network::canAddUidRanges(const UidRanges& uidRanges, uint32_t subPriority) const {
if (uidRanges.overlapsSelf()) {
ALOGE("uid range %s overlaps self", uidRanges.toString().c_str());
- return true;
+ return false;
}
- if (uidRanges.overlaps(mUidRanges)) {
- ALOGE("uid range %s overlaps %s", uidRanges.toString().c_str(),
- mUidRanges.toString().c_str());
- return true;
+ auto iter = mUidRangeMap.find(subPriority);
+ if (iter != mUidRangeMap.end() && uidRanges.overlaps(iter->second)) {
+ ALOGE("uid range %s overlaps priority %u %s", uidRanges.toString().c_str(), subPriority,
+ iter->second.toString().c_str());
+ return false;
}
- return false;
+ return true;
}
bool Network::isSecure() const {
diff --git a/server/Network.h b/server/Network.h
index d5110d02..aa1b21a1 100644
--- a/server/Network.h
+++ b/server/Network.h
@@ -24,6 +24,8 @@
namespace android::net {
+typedef std::map<uint32_t, UidRanges> UidRangeMap;
+
// A Network represents a collection of interfaces participating as a single administrative unit.
class Network {
public:
@@ -44,22 +46,31 @@ public:
[[nodiscard]] int clearInterfaces();
std::string toString() const;
- bool appliesToUser(uid_t uid) const;
- [[nodiscard]] virtual int addUsers(const UidRanges&) { return -EINVAL; };
- [[nodiscard]] virtual int removeUsers(const UidRanges&) { return -EINVAL; };
+ std::string uidRangesToString() const;
+ bool appliesToUser(uid_t uid, uint32_t* subPriority) const;
+ [[nodiscard]] virtual int addUsers(const UidRanges&, uint32_t /*subPriority*/) {
+ return -EINVAL;
+ };
+ [[nodiscard]] virtual int removeUsers(const UidRanges&, uint32_t /*subPriority*/) {
+ return -EINVAL;
+ };
bool isSecure() const;
virtual bool isPhysical() { return false; }
virtual bool isUnreachable() { return false; }
virtual bool isVirtual() { return false; }
virtual bool canAddUsers() { return false; }
+ virtual bool isValidSubPriority(uint32_t /*priority*/) { return false; }
+ virtual void addToUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority);
+ virtual void removeFromUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority);
protected:
explicit Network(unsigned netId, bool mSecure = false);
- bool hasInvalidUidRanges(const UidRanges& uidRanges) const;
+ bool canAddUidRanges(const UidRanges& uidRanges, uint32_t subPriority) const;
const unsigned mNetId;
std::set<std::string> mInterfaces;
- UidRanges mUidRanges;
+ // Each subsidiary priority maps to a set of UID ranges of a feature.
+ std::map<uint32_t, UidRanges> mUidRangeMap;
const bool mSecure;
private:
diff --git a/server/NetworkController.cpp b/server/NetworkController.cpp
index ff52db5b..602639cb 100644
--- a/server/NetworkController.cpp
+++ b/server/NetworkController.cpp
@@ -616,22 +616,24 @@ int isWrongNetworkForUidRanges(unsigned netId, Network* network) {
} // namespace
-int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) {
+int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges,
+ uint32_t subPriority) {
ScopedWLock lock(mRWLock);
Network* network = getNetworkLocked(netId);
if (int ret = isWrongNetworkForUidRanges(netId, network)) {
return ret;
}
- return network->addUsers(uidRanges);
+ return network->addUsers(uidRanges, subPriority);
}
-int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) {
+int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges,
+ uint32_t subPriority) {
ScopedWLock lock(mRWLock);
Network* network = getNetworkLocked(netId);
if (int ret = isWrongNetworkForUidRanges(netId, network)) {
return ret;
}
- return network->removeUsers(uidRanges);
+ return network->removeUsers(uidRanges, subPriority);
}
int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination,
@@ -740,6 +742,11 @@ void NetworkController::dump(DumpWriter& dw) {
dw.println("Required permission: %s", permissionToName(permission));
dw.decIndent();
}
+ if (const auto& str = network->uidRangesToString(); !str.empty()) {
+ dw.incIndent();
+ dw.println(str);
+ dw.decIndent();
+ }
dw.blankline();
}
dw.decIndent();
@@ -776,30 +783,32 @@ Network* NetworkController::getNetworkLocked(unsigned netId) const {
}
VirtualNetwork* NetworkController::getVirtualNetworkForUserLocked(uid_t uid) const {
+ uint32_t subPriority;
for (const auto& [_, network] : mNetworks) {
- if (network->isVirtual() && network->appliesToUser(uid)) {
+ if (network->isVirtual() && network->appliesToUser(uid, &subPriority)) {
return static_cast<VirtualNetwork*>(network);
}
}
return nullptr;
}
+// Returns a network with the highest subsidiary priority among physical and unreachable networks
+// that applies to uid. For a single subsidiary priority, an uid should belong to only one network.
+// If the uid apply to different network with the same priority at the same time, the behavior is
+// undefined. That is a configuration error.
Network* NetworkController::getPhysicalOrUnreachableNetworkForUserLocked(uid_t uid) const {
- // OEM-paid network take precedence over the unreachable network.
- for (const auto& [_, network] : mNetworks) {
- if (network->isPhysical() && network->appliesToUser(uid)) {
- // Return the first physical network that matches UID.
- // If there is more than one such network, the behaviour is undefined.
- // This is a configuration error.
- return network;
+ Network* bestNetwork = nullptr;
+ unsigned bestSubPriority = UidRanges::LOWEST_SUB_PRIORITY + 1;
+ for (const auto& [netId, network] : mNetworks) {
+ uint32_t subPriority;
+ if (!network->isPhysical() && !network->isUnreachable()) continue;
+ if (!network->appliesToUser(uid, &subPriority)) continue;
+ if (subPriority < bestSubPriority) {
+ bestNetwork = network;
+ bestSubPriority = subPriority;
}
}
-
- auto iter = mNetworks.find(UNREACHABLE_NET_ID);
- if (iter != mNetworks.end() && iter->second->appliesToUser(uid)) {
- return iter->second;
- }
- return nullptr;
+ return bestNetwork;
}
Permission NetworkController::getPermissionForUserLocked(uid_t uid) const {
@@ -827,8 +836,9 @@ int NetworkController::checkUserNetworkAccessLocked(uid_t uid, unsigned netId) c
return 0;
}
// If the UID wants to use a VPN, it can do so if and only if the VPN applies to the UID.
+ uint32_t subPriority;
if (network->isVirtual()) {
- return network->appliesToUser(uid) ? 0 : -EPERM;
+ return network->appliesToUser(uid, &subPriority) ? 0 : -EPERM;
}
// If a VPN applies to the UID, and the VPN is secure (i.e., not bypassable), then the UID can
// only select a different network if it has the ability to protect its sockets.
@@ -839,12 +849,12 @@ int NetworkController::checkUserNetworkAccessLocked(uid_t uid, unsigned netId) c
}
// If the UID wants to use a physical network and it has a UID range that includes the UID, the
// UID has permission to use it regardless of whether the permission bits match.
- if (network->isPhysical() && network->appliesToUser(uid)) {
+ if (network->isPhysical() && network->appliesToUser(uid, &subPriority)) {
return 0;
}
// Only apps that are configured as "no default network" can use the unreachable network.
if (network->isUnreachable()) {
- return network->appliesToUser(uid) ? 0 : -EPERM;
+ return network->appliesToUser(uid, &subPriority) ? 0 : -EPERM;
}
// Check whether the UID's permission bits are sufficient to use the network.
// Because the permission of the system default network is PERMISSION_NONE(0x0), apps can always
diff --git a/server/NetworkController.h b/server/NetworkController.h
index 46302252..a61ac39f 100644
--- a/server/NetworkController.h
+++ b/server/NetworkController.h
@@ -119,8 +119,10 @@ public:
[[nodiscard]] int setPermissionForNetworks(Permission permission,
const std::vector<unsigned>& netIds);
- [[nodiscard]] int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges);
- [[nodiscard]] int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges);
+ [[nodiscard]] int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges,
+ uint32_t subPriority);
+ [[nodiscard]] int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges,
+ uint32_t subPriority);
// |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
// route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
diff --git a/server/PhysicalNetwork.cpp b/server/PhysicalNetwork.cpp
index 894d56ab..7b9a19a1 100644
--- a/server/PhysicalNetwork.cpp
+++ b/server/PhysicalNetwork.cpp
@@ -158,32 +158,35 @@ int PhysicalNetwork::removeAsDefault() {
return 0;
}
-int PhysicalNetwork::addUsers(const UidRanges& uidRanges) {
- if (hasInvalidUidRanges(uidRanges)) {
+int PhysicalNetwork::addUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+ if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges, subPriority)) {
return -EINVAL;
}
for (const std::string& interface : mInterfaces) {
- int ret = RouteController::addUsersToPhysicalNetwork(mNetId, interface.c_str(), uidRanges);
+ int ret = RouteController::addUsersToPhysicalNetwork(mNetId, interface.c_str(),
+ {{subPriority, uidRanges}});
if (ret) {
ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
return ret;
}
}
- mUidRanges.add(uidRanges);
+ addToUidRangeMap(uidRanges, subPriority);
return 0;
}
-int PhysicalNetwork::removeUsers(const UidRanges& uidRanges) {
+int PhysicalNetwork::removeUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+ if (!isValidSubPriority(subPriority)) return -EINVAL;
+
for (const std::string& interface : mInterfaces) {
int ret = RouteController::removeUsersFromPhysicalNetwork(mNetId, interface.c_str(),
- uidRanges);
+ {{subPriority, uidRanges}});
if (ret) {
ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
return ret;
}
}
- mUidRanges.remove(uidRanges);
+ removeFromUidRangeMap(uidRanges, subPriority);
return 0;
}
@@ -192,7 +195,7 @@ int PhysicalNetwork::addInterface(const std::string& interface) {
return 0;
}
if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
- mPermission, mUidRanges)) {
+ mPermission, mUidRangeMap)) {
ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
return ret;
}
@@ -219,7 +222,7 @@ int PhysicalNetwork::removeInterface(const std::string& interface) {
// to find the interface index in the cache in cases where the interface is already gone
// (e.g. bt-pan).
if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
- mPermission, mUidRanges)) {
+ mPermission, mUidRangeMap)) {
ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
return ret;
}
@@ -227,4 +230,9 @@ int PhysicalNetwork::removeInterface(const std::string& interface) {
return 0;
}
+bool PhysicalNetwork::isValidSubPriority(uint32_t priority) {
+ return priority >= UidRanges::DEFAULT_SUB_PRIORITY &&
+ priority <= UidRanges::LOWEST_SUB_PRIORITY;
+}
+
} // namespace android::net
diff --git a/server/PhysicalNetwork.h b/server/PhysicalNetwork.h
index df2bd225..d9461b2e 100644
--- a/server/PhysicalNetwork.h
+++ b/server/PhysicalNetwork.h
@@ -42,8 +42,8 @@ class PhysicalNetwork : public Network {
[[nodiscard]] int addAsDefault();
[[nodiscard]] int removeAsDefault();
- [[nodiscard]] int addUsers(const UidRanges& uidRanges) override;
- [[nodiscard]] int removeUsers(const UidRanges& uidRanges) override;
+ [[nodiscard]] int addUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
+ [[nodiscard]] int removeUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
bool isPhysical() override { return true; }
bool canAddUsers() override { return true; }
@@ -53,6 +53,7 @@ class PhysicalNetwork : public Network {
[[nodiscard]] int removeInterface(const std::string& interface) override;
int destroySocketsLackingPermission(Permission permission);
void invalidateRouteCache(const std::string& interface);
+ bool isValidSubPriority(uint32_t priority) override;
Delegate* const mDelegate;
Permission mPermission;
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 666a88a7..ba305e69 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -27,14 +27,11 @@
#include <map>
-#define LOG_TAG "Netd"
-
#include "DummyNetwork.h"
#include "Fwmark.h"
#include "NetdConstants.h"
#include "NetlinkCommands.h"
#include "OffloadUtils.h"
-#include "UidRanges.h"
#include <android-base/file.h>
#include <android-base/stringprintf.h>
@@ -495,7 +492,7 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
// have, if they are subject to this VPN, their traffic has to go through it. Allows the traffic to
// bypass the VPN if the protectedFromVpn bit is set.
[[nodiscard]] static int modifyVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd,
- bool secure, bool add) {
+ uint32_t subPriority, bool secure, bool add) {
Fwmark fwmark;
Fwmark mask;
@@ -513,8 +510,8 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
mask.explicitlySelected = true;
}
- return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, priority, table, fwmark.intValue,
- mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
+ return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, priority + subPriority, table,
+ fwmark.intValue, mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
}
// A rule to allow system apps to send traffic over this VPN even if they are not part of the target
@@ -548,7 +545,7 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
// modifyNetworkPermission().
[[nodiscard]] static int modifyExplicitNetworkRule(unsigned netId, uint32_t table,
Permission permission, uid_t uidStart,
- uid_t uidEnd, bool add) {
+ uid_t uidEnd, uint32_t subPriority, bool add) {
Fwmark fwmark;
Fwmark mask;
@@ -561,8 +558,9 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
fwmark.permission = permission;
mask.permission = permission;
- return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_EXPLICIT_NETWORK, table,
- fwmark.intValue, mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
+ return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE,
+ RULE_PRIORITY_EXPLICIT_NETWORK + subPriority, table, fwmark.intValue,
+ mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
}
// A rule to route traffic based on a chosen outgoing interface.
@@ -571,7 +569,7 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
// the outgoing interface (typically for link-local communications).
[[nodiscard]] static int modifyOutputInterfaceRules(const char* interface, uint32_t table,
Permission permission, uid_t uidStart,
- uid_t uidEnd, bool add) {
+ uid_t uidEnd, uint32_t subPriority, bool add) {
Fwmark fwmark;
Fwmark mask;
@@ -589,8 +587,9 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
}
}
- return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_OUTPUT_INTERFACE, table,
- fwmark.intValue, mask.intValue, IIF_LOOPBACK, interface, uidStart, uidEnd);
+ return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE,
+ RULE_PRIORITY_OUTPUT_INTERFACE + subPriority, table, fwmark.intValue,
+ mask.intValue, IIF_LOOPBACK, interface, uidStart, uidEnd);
}
// A rule to route traffic based on the chosen network.
@@ -670,7 +669,8 @@ int RouteController::modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId
// Add rules to lookup the local network when specified explicitly or otherwise.
[[nodiscard]] static int addLocalNetworkRules(unsigned localNetId) {
if (int ret = modifyExplicitNetworkRule(localNetId, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
- INVALID_UID, INVALID_UID, ACTION_ADD)) {
+ INVALID_UID, INVALID_UID,
+ UidRanges::DEFAULT_SUB_PRIORITY, ACTION_ADD)) {
return ret;
}
@@ -701,8 +701,9 @@ int RouteController::configureDummyNetwork() {
return -errno;
}
- if ((ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE,
- INVALID_UID, INVALID_UID, ACTION_ADD))) {
+ if ((ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE, INVALID_UID,
+ INVALID_UID, UidRanges::DEFAULT_SUB_PRIORITY,
+ ACTION_ADD))) {
ALOGE("Can't create oif rules for %s: %s", interface, strerror(-ret));
return ret;
}
@@ -735,11 +736,13 @@ int RouteController::configureDummyNetwork() {
}
maybeModifyQdiscClsact(interface, add);
return modifyOutputInterfaceRules(interface, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
- INVALID_UID, INVALID_UID, add);
+ INVALID_UID, INVALID_UID, UidRanges::DEFAULT_SUB_PRIORITY,
+ add);
}
[[nodiscard]] static int modifyUidNetworkRule(unsigned netId, uint32_t table, uid_t uidStart,
- uid_t uidEnd, bool add, bool explicitSelect) {
+ uid_t uidEnd, uint32_t subPriority, bool add,
+ bool explicitSelect) {
if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
ALOGE("modifyUidNetworkRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
return -EUSERS;
@@ -759,14 +762,14 @@ int RouteController::configureDummyNetwork() {
mask.permission = PERMISSION_NONE;
return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE,
- explicitSelect ? RULE_PRIORITY_UID_EXPLICIT_NETWORK
- : RULE_PRIORITY_UID_IMPLICIT_NETWORK,
+ explicitSelect ? (RULE_PRIORITY_UID_EXPLICIT_NETWORK + subPriority)
+ : (RULE_PRIORITY_UID_IMPLICIT_NETWORK + subPriority),
table, fwmark.intValue, mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart,
uidEnd);
}
[[nodiscard]] static int modifyUidDefaultNetworkRule(uint32_t table, uid_t uidStart, uid_t uidEnd,
- bool add) {
+ uint32_t subPriority, bool add) {
if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
ALOGE("modifyUidDefaultNetworkRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
return -EUSERS;
@@ -782,28 +785,34 @@ int RouteController::configureDummyNetwork() {
fwmark.permission = PERMISSION_NONE;
mask.permission = PERMISSION_NONE;
- return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_UID_DEFAULT_NETWORK, table,
- fwmark.intValue, mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
+ return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE,
+ RULE_PRIORITY_UID_DEFAULT_NETWORK + subPriority, table, fwmark.intValue,
+ mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
}
/* static */
int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges, Permission permission,
+ const UidRangeMap& uidRangeMap, Permission permission,
bool add, bool modifyNonUidBasedRules) {
uint32_t table = getRouteTableForInterface(interface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
- for (const UidRangeParcel& range : uidRanges.getRanges()) {
- if (int ret = modifyUidNetworkRule(netId, table, range.start, range.stop, add, EXPLICIT)) {
- return ret;
- }
- if (int ret = modifyUidNetworkRule(netId, table, range.start, range.stop, add, IMPLICIT)) {
- return ret;
- }
- if (int ret = modifyUidDefaultNetworkRule(table, range.start, range.stop, add)) {
- return ret;
+ for (const auto& [subPriority, uidRanges] : uidRangeMap) {
+ for (const UidRangeParcel& range : uidRanges.getRanges()) {
+ if (int ret = modifyUidNetworkRule(netId, table, range.start, range.stop, subPriority,
+ add, EXPLICIT)) {
+ return ret;
+ }
+ if (int ret = modifyUidNetworkRule(netId, table, range.start, range.stop, subPriority,
+ add, IMPLICIT)) {
+ return ret;
+ }
+ if (int ret = modifyUidDefaultNetworkRule(table, range.start, range.stop, subPriority,
+ add)) {
+ return ret;
+ }
}
}
@@ -816,11 +825,11 @@ int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface
return ret;
}
if (int ret = modifyExplicitNetworkRule(netId, table, permission, INVALID_UID, INVALID_UID,
- add)) {
+ UidRanges::DEFAULT_SUB_PRIORITY, add)) {
return ret;
}
if (int ret = modifyOutputInterfaceRules(interface, table, permission, INVALID_UID, INVALID_UID,
- add)) {
+ UidRanges::DEFAULT_SUB_PRIORITY, add)) {
return ret;
}
@@ -851,7 +860,8 @@ int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface
}
[[nodiscard]] static int modifyUidUnreachableRule(unsigned netId, uid_t uidStart, uid_t uidEnd,
- bool add, bool explicitSelect) {
+ uint32_t subPriority, bool add,
+ bool explicitSelect) {
if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
ALOGE("modifyUidUnreachableRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
return -EUSERS;
@@ -871,15 +881,16 @@ int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface
mask.permission = PERMISSION_NONE;
return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE,
- explicitSelect ? RULE_PRIORITY_UID_EXPLICIT_NETWORK
- : RULE_PRIORITY_UID_IMPLICIT_NETWORK,
+ explicitSelect ? (RULE_PRIORITY_UID_EXPLICIT_NETWORK + subPriority)
+ : (RULE_PRIORITY_UID_IMPLICIT_NETWORK + subPriority),
FR_ACT_UNREACHABLE, RT_TABLE_UNSPEC, fwmark.intValue, mask.intValue,
IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
}
-[[nodiscard]] static int modifyUidDefaultUnreachableRule(uid_t uidStart, uid_t uidEnd, bool add) {
+[[nodiscard]] static int modifyUidDefaultUnreachableRule(uid_t uidStart, uid_t uidEnd,
+ uint32_t subPriority, bool add) {
if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
- ALOGE("modifyUidDefaultNetworkRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
+ ALOGE("modifyUidDefaultUnreachableRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
return -EUSERS;
}
@@ -893,22 +904,28 @@ int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface
fwmark.permission = PERMISSION_NONE;
mask.permission = PERMISSION_NONE;
- return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_UID_DEFAULT_UNREACHABLE,
- FR_ACT_UNREACHABLE, RT_TABLE_UNSPEC, fwmark.intValue, mask.intValue,
- IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
+ return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE,
+ RULE_PRIORITY_UID_DEFAULT_UNREACHABLE + subPriority, FR_ACT_UNREACHABLE,
+ RT_TABLE_UNSPEC, fwmark.intValue, mask.intValue, IIF_LOOPBACK, OIF_NONE,
+ uidStart, uidEnd);
}
-int RouteController::modifyUnreachableNetwork(unsigned netId, const UidRanges& uidRanges,
+int RouteController::modifyUnreachableNetwork(unsigned netId, const UidRangeMap& uidRangeMap,
bool add) {
- for (const UidRangeParcel& range : uidRanges.getRanges()) {
- if (int ret = modifyUidUnreachableRule(netId, range.start, range.stop, add, EXPLICIT)) {
- return ret;
- }
- if (int ret = modifyUidUnreachableRule(netId, range.start, range.stop, add, IMPLICIT)) {
- return ret;
- }
- if (int ret = modifyUidDefaultUnreachableRule(range.start, range.stop, add)) {
- return ret;
+ for (const auto& [subPriority, uidRanges] : uidRangeMap) {
+ for (const UidRangeParcel& range : uidRanges.getRanges()) {
+ if (int ret = modifyUidUnreachableRule(netId, range.start, range.stop, subPriority, add,
+ EXPLICIT)) {
+ return ret;
+ }
+ if (int ret = modifyUidUnreachableRule(netId, range.start, range.stop, subPriority, add,
+ IMPLICIT)) {
+ return ret;
+ }
+ if (int ret = modifyUidDefaultUnreachableRule(range.start, range.stop, subPriority,
+ add)) {
+ return ret;
+ }
}
}
@@ -933,24 +950,27 @@ int RouteController::modifyUnreachableNetwork(unsigned netId, const UidRanges& u
}
int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges, bool secure, bool add,
+ const UidRangeMap& uidRangeMap, bool secure, bool add,
bool modifyNonUidBasedRules) {
uint32_t table = getRouteTableForInterface(interface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
- for (const UidRangeParcel& range : uidRanges.getRanges()) {
- if (int ret = modifyVpnUidRangeRule(table, range.start, range.stop, secure, add)) {
- return ret;
- }
- if (int ret = modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, range.start,
- range.stop, add)) {
- return ret;
- }
- if (int ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE, range.start,
- range.stop, add)) {
- return ret;
+ for (const auto& [subPriority, uidRanges] : uidRangeMap) {
+ for (const UidRangeParcel& range : uidRanges.getRanges()) {
+ if (int ret = modifyVpnUidRangeRule(table, range.start, range.stop, subPriority, secure,
+ add)) {
+ return ret;
+ }
+ if (int ret = modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, range.start,
+ range.stop, subPriority, add)) {
+ return ret;
+ }
+ if (int ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE, range.start,
+ range.stop, subPriority, add)) {
+ return ret;
+ }
}
}
@@ -964,7 +984,8 @@ int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
if (int ret = modifyVpnSystemPermissionRule(netId, table, secure, add)) {
return ret;
}
- return modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT, add);
+ return modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT,
+ UidRanges::DEFAULT_SUB_PRIORITY, add);
}
return 0;
@@ -1166,8 +1187,8 @@ int RouteController::removeInterfaceFromLocalNetwork(unsigned netId, const char*
int RouteController::addInterfaceToPhysicalNetwork(unsigned netId, const char* interface,
Permission permission,
- const UidRanges& uidRanges) {
- if (int ret = modifyPhysicalNetwork(netId, interface, uidRanges, permission, ACTION_ADD,
+ const UidRangeMap& uidRangeMap) {
+ if (int ret = modifyPhysicalNetwork(netId, interface, uidRangeMap, permission, ACTION_ADD,
MODIFY_NON_UID_BASED_RULES)) {
return ret;
}
@@ -1178,8 +1199,8 @@ int RouteController::addInterfaceToPhysicalNetwork(unsigned netId, const char* i
int RouteController::removeInterfaceFromPhysicalNetwork(unsigned netId, const char* interface,
Permission permission,
- const UidRanges& uidRanges) {
- if (int ret = modifyPhysicalNetwork(netId, interface, uidRanges, permission, ACTION_DEL,
+ const UidRangeMap& uidRangeMap) {
+ if (int ret = modifyPhysicalNetwork(netId, interface, uidRangeMap, permission, ACTION_DEL,
MODIFY_NON_UID_BASED_RULES)) {
return ret;
}
@@ -1195,8 +1216,8 @@ int RouteController::removeInterfaceFromPhysicalNetwork(unsigned netId, const ch
}
int RouteController::addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRanges& uidRanges) {
- if (int ret = modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_ADD,
+ bool secure, const UidRangeMap& uidRangeMap) {
+ if (int ret = modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_ADD,
MODIFY_NON_UID_BASED_RULES)) {
return ret;
}
@@ -1205,8 +1226,9 @@ int RouteController::addInterfaceToVirtualNetwork(unsigned netId, const char* in
}
int RouteController::removeInterfaceFromVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRanges& uidRanges) {
- if (int ret = modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_DEL,
+ bool secure,
+ const UidRangeMap& uidRangeMap) {
+ if (int ret = modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_DEL,
MODIFY_NON_UID_BASED_RULES)) {
return ret;
}
@@ -1220,13 +1242,15 @@ int RouteController::removeInterfaceFromVirtualNetwork(unsigned netId, const cha
int RouteController::modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
Permission oldPermission,
Permission newPermission) {
- UidRanges noUidRanges;
+ // Physical network rules either use permission bits or UIDs, but not both.
+ // So permission changes don't affect any UID-based rules.
+ UidRangeMap emptyUidRangeMap;
// Add the new rules before deleting the old ones, to avoid race conditions.
- if (int ret = modifyPhysicalNetwork(netId, interface, noUidRanges, newPermission, ACTION_ADD,
- MODIFY_NON_UID_BASED_RULES)) {
+ if (int ret = modifyPhysicalNetwork(netId, interface, emptyUidRangeMap, newPermission,
+ ACTION_ADD, MODIFY_NON_UID_BASED_RULES)) {
return ret;
}
- return modifyPhysicalNetwork(netId, interface, noUidRanges, oldPermission, ACTION_DEL,
+ return modifyPhysicalNetwork(netId, interface, emptyUidRangeMap, oldPermission, ACTION_DEL,
MODIFY_NON_UID_BASED_RULES);
}
@@ -1239,14 +1263,14 @@ int RouteController::removeUsersFromRejectNonSecureNetworkRule(const UidRanges&
}
int RouteController::addUsersToVirtualNetwork(unsigned netId, const char* interface, bool secure,
- const UidRanges& uidRanges) {
- return modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_ADD,
+ const UidRangeMap& uidRangeMap) {
+ return modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_ADD,
!MODIFY_NON_UID_BASED_RULES);
}
int RouteController::removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRanges& uidRanges) {
- return modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_DEL,
+ bool secure, const UidRangeMap& uidRangeMap) {
+ return modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_DEL,
!MODIFY_NON_UID_BASED_RULES);
}
@@ -1297,23 +1321,24 @@ int RouteController::removeVirtualNetworkFallthrough(unsigned vpnNetId,
}
int RouteController::addUsersToPhysicalNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges) {
- return modifyPhysicalNetwork(netId, interface, uidRanges, PERMISSION_NONE, ACTION_ADD,
+ const UidRangeMap& uidRangeMap) {
+ return modifyPhysicalNetwork(netId, interface, uidRangeMap, PERMISSION_NONE, ACTION_ADD,
!MODIFY_NON_UID_BASED_RULES);
}
int RouteController::removeUsersFromPhysicalNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges) {
- return modifyPhysicalNetwork(netId, interface, uidRanges, PERMISSION_NONE, ACTION_DEL,
+ const UidRangeMap& uidRangeMap) {
+ return modifyPhysicalNetwork(netId, interface, uidRangeMap, PERMISSION_NONE, ACTION_DEL,
!MODIFY_NON_UID_BASED_RULES);
}
-int RouteController::addUsersToUnreachableNetwork(unsigned netId, const UidRanges& uidRanges) {
- return modifyUnreachableNetwork(netId, uidRanges, ACTION_ADD);
+int RouteController::addUsersToUnreachableNetwork(unsigned netId, const UidRangeMap& uidRangeMap) {
+ return modifyUnreachableNetwork(netId, uidRangeMap, ACTION_ADD);
}
-int RouteController::removeUsersFromUnreachableNetwork(unsigned netId, const UidRanges& uidRanges) {
- return modifyUnreachableNetwork(netId, uidRanges, ACTION_DEL);
+int RouteController::removeUsersFromUnreachableNetwork(unsigned netId,
+ const UidRangeMap& uidRangeMap) {
+ return modifyUnreachableNetwork(netId, uidRangeMap, ACTION_DEL);
}
// Protects sInterfaceToTable.
diff --git a/server/RouteController.h b/server/RouteController.h
index 7f1f960f..38d2d621 100644
--- a/server/RouteController.h
+++ b/server/RouteController.h
@@ -17,6 +17,7 @@
#pragma once
#include "NetdConstants.h" // IptablesTarget
+#include "Network.h" // UidRangeMap
#include "Permission.h"
#include <android-base/thread_annotations.h>
@@ -107,26 +108,28 @@ public:
[[nodiscard]] static int addInterfaceToPhysicalNetwork(unsigned netId, const char* interface,
Permission permission,
- const UidRanges& uidRanges);
+ const UidRangeMap& uidRangeMap);
[[nodiscard]] static int removeInterfaceFromPhysicalNetwork(unsigned netId,
const char* interface,
Permission permission,
- const UidRanges& uidRanges);
+ const UidRangeMap& uidRangeMap);
[[nodiscard]] static int addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRanges& uidRanges);
+ bool secure,
+ const UidRangeMap& uidRangeMap);
[[nodiscard]] static int removeInterfaceFromVirtualNetwork(unsigned netId,
const char* interface, bool secure,
- const UidRanges& uidRanges);
+ const UidRangeMap& uidRangeMap);
[[nodiscard]] static int modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
Permission oldPermission,
Permission newPermission);
[[nodiscard]] static int addUsersToVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRanges& uidRanges);
+ bool secure, const UidRangeMap& uidRangeMap);
[[nodiscard]] static int removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRanges& uidRanges);
+ bool secure,
+ const UidRangeMap& uidRangeMap);
[[nodiscard]] static int addUsersToRejectNonSecureNetworkRule(const UidRanges& uidRanges);
[[nodiscard]] static int removeUsersFromRejectNonSecureNetworkRule(const UidRanges& uidRanges);
@@ -158,16 +161,16 @@ public:
Permission permission);
[[nodiscard]] static int addUsersToPhysicalNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges);
+ const UidRangeMap& uidRangeMap);
[[nodiscard]] static int removeUsersFromPhysicalNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges);
+ const UidRangeMap& uidRangeMap);
[[nodiscard]] static int addUsersToUnreachableNetwork(unsigned netId,
- const UidRanges& uidRanges);
+ const UidRangeMap& uidRangeMap);
[[nodiscard]] static int removeUsersFromUnreachableNetwork(unsigned netId,
- const UidRanges& uidRanges);
+ const UidRangeMap& uidRangeMap);
// For testing.
static int (*iptablesRestoreCommandFunction)(IptablesTarget, const std::string&,
@@ -187,9 +190,9 @@ private:
static uint32_t getRouteTableForInterface(const char *interface) EXCLUDES(sInterfaceToTableLock);
static int modifyDefaultNetwork(uint16_t action, const char* interface, Permission permission);
static int modifyPhysicalNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges, Permission permission, bool add,
- bool modifyNonUidBasedRules);
- static int modifyUnreachableNetwork(unsigned netId, const UidRanges& uidRanges, bool add);
+ const UidRangeMap& uidRangeMap, Permission permission,
+ bool add, bool modifyNonUidBasedRules);
+ static int modifyUnreachableNetwork(unsigned netId, const UidRangeMap& uidRangeMap, bool add);
static int modifyRoute(uint16_t action, uint16_t flags, const char* interface,
const char* destination, const char* nexthop, TableType tableType,
int mtu);
@@ -198,7 +201,7 @@ private:
static int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
const char* physicalInterface, Permission permission);
static int modifyVirtualNetwork(unsigned netId, const char* interface,
- const UidRanges& uidRanges, bool secure, bool add,
+ const UidRangeMap& uidRangeMap, bool secure, bool add,
bool modifyNonUidBasedRules);
static void updateTableNamesFile() EXCLUDES(sInterfaceToTableLock);
};
diff --git a/server/UidRanges.cpp b/server/UidRanges.cpp
index 5b4f59ff..093a1e27 100644
--- a/server/UidRanges.cpp
+++ b/server/UidRanges.cpp
@@ -155,7 +155,7 @@ bool UidRanges::overlaps(const UidRanges& other) const {
}
std::string UidRanges::toString() const {
- std::string s("UidRanges{ ");
+ std::string s("uids{ ");
for (const auto &range : mRanges) {
if (length(range) == 0) {
StringAppendF(&s, "<BAD: %u-%u> ", range.start, range.stop);
diff --git a/server/UidRanges.h b/server/UidRanges.h
index f3223905..99e7a99d 100644
--- a/server/UidRanges.h
+++ b/server/UidRanges.h
@@ -28,6 +28,9 @@ namespace net {
class UidRanges {
public:
+ static constexpr int DEFAULT_SUB_PRIORITY = 0;
+ static constexpr int LOWEST_SUB_PRIORITY = 999;
+
UidRanges() {}
UidRanges(const std::vector<android::net::UidRangeParcel>& ranges);
@@ -44,6 +47,7 @@ public:
bool overlapsSelf() const;
// check if this object has uid overlap with the input object.
bool overlaps(const UidRanges& other) const;
+ bool empty() const { return mRanges.empty(); }
private:
// a utility to check if two UidRangeParcels have uid overlap.
diff --git a/server/UnreachableNetwork.cpp b/server/UnreachableNetwork.cpp
index b17c9981..2f801f0c 100644
--- a/server/UnreachableNetwork.cpp
+++ b/server/UnreachableNetwork.cpp
@@ -26,29 +26,37 @@ namespace net {
// The unreachable network is used to reject traffic. It is used for system purposes only.
UnreachableNetwork::UnreachableNetwork(unsigned netId) : Network(netId) {}
-int UnreachableNetwork::addUsers(const UidRanges& uidRanges) {
- if (hasInvalidUidRanges(uidRanges)) {
+int UnreachableNetwork::addUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+ if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges, subPriority)) {
return -EINVAL;
}
- int ret = RouteController::addUsersToUnreachableNetwork(mNetId, uidRanges);
+ int ret = RouteController::addUsersToUnreachableNetwork(mNetId, {{subPriority, uidRanges}});
if (ret) {
ALOGE("failed to add users to unreachable network");
return ret;
}
- mUidRanges.add(uidRanges);
+ addToUidRangeMap(uidRanges, subPriority);
return 0;
}
-int UnreachableNetwork::removeUsers(const UidRanges& uidRanges) {
- int ret = RouteController::removeUsersFromUnreachableNetwork(mNetId, uidRanges);
+int UnreachableNetwork::removeUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+ if (!isValidSubPriority(subPriority)) return -EINVAL;
+
+ int ret =
+ RouteController::removeUsersFromUnreachableNetwork(mNetId, {{subPriority, uidRanges}});
if (ret) {
ALOGE("failed to remove users from unreachable network");
return ret;
}
- mUidRanges.remove(uidRanges);
+ removeFromUidRangeMap(uidRanges, subPriority);
return 0;
}
+bool UnreachableNetwork::isValidSubPriority(uint32_t priority) {
+ return priority >= UidRanges::DEFAULT_SUB_PRIORITY &&
+ priority <= UidRanges::LOWEST_SUB_PRIORITY;
+}
+
} // namespace net
} // namespace android
diff --git a/server/UnreachableNetwork.h b/server/UnreachableNetwork.h
index a80f3f39..f1547d60 100644
--- a/server/UnreachableNetwork.h
+++ b/server/UnreachableNetwork.h
@@ -23,13 +23,14 @@ namespace android::net {
class UnreachableNetwork : public Network {
public:
explicit UnreachableNetwork(unsigned netId);
- [[nodiscard]] int addUsers(const UidRanges& uidRanges) override;
- [[nodiscard]] int removeUsers(const UidRanges& uidRanges) override;
+ [[nodiscard]] int addUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
+ [[nodiscard]] int removeUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
bool isUnreachable() override { return true; }
bool canAddUsers() override { return true; }
private:
std::string getTypeString() const override { return "UNREACHABLE"; };
+ bool isValidSubPriority(uint32_t priority) override;
};
} // namespace android::net \ No newline at end of file
diff --git a/server/VirtualNetwork.cpp b/server/VirtualNetwork.cpp
index 93f4c3e8..1906e208 100644
--- a/server/VirtualNetwork.cpp
+++ b/server/VirtualNetwork.cpp
@@ -31,33 +31,35 @@ VirtualNetwork::VirtualNetwork(unsigned netId, bool secure) : Network(netId, sec
VirtualNetwork::~VirtualNetwork() {}
-int VirtualNetwork::addUsers(const UidRanges& uidRanges) {
- if (hasInvalidUidRanges(uidRanges)) {
+int VirtualNetwork::addUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+ if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges, subPriority)) {
return -EINVAL;
}
for (const std::string& interface : mInterfaces) {
int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure,
- uidRanges);
+ {{subPriority, uidRanges}});
if (ret) {
ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
return ret;
}
}
- mUidRanges.add(uidRanges);
+ addToUidRangeMap(uidRanges, subPriority);
return 0;
}
-int VirtualNetwork::removeUsers(const UidRanges& uidRanges) {
+int VirtualNetwork::removeUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+ if (!isValidSubPriority(subPriority)) return -EINVAL;
+
for (const std::string& interface : mInterfaces) {
int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(), mSecure,
- uidRanges);
+ {{subPriority, uidRanges}});
if (ret) {
ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
return ret;
}
}
- mUidRanges.remove(uidRanges);
+ removeFromUidRangeMap(uidRanges, subPriority);
return 0;
}
@@ -66,7 +68,7 @@ int VirtualNetwork::addInterface(const std::string& interface) {
return 0;
}
if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure,
- mUidRanges)) {
+ mUidRangeMap)) {
ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId);
return ret;
}
@@ -79,7 +81,7 @@ int VirtualNetwork::removeInterface(const std::string& interface) {
return 0;
}
if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(),
- mSecure, mUidRanges)) {
+ mSecure, mUidRangeMap)) {
ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId);
return ret;
}
@@ -87,5 +89,10 @@ int VirtualNetwork::removeInterface(const std::string& interface) {
return 0;
}
+bool VirtualNetwork::isValidSubPriority(uint32_t priority) {
+ // Only supports default subsidiary permissions.
+ return priority == UidRanges::DEFAULT_SUB_PRIORITY;
+}
+
} // namespace net
} // namespace android
diff --git a/server/VirtualNetwork.h b/server/VirtualNetwork.h
index ebda7da5..20c9e2c2 100644
--- a/server/VirtualNetwork.h
+++ b/server/VirtualNetwork.h
@@ -33,8 +33,8 @@ class VirtualNetwork : public Network {
public:
VirtualNetwork(unsigned netId, bool secure);
virtual ~VirtualNetwork();
- [[nodiscard]] int addUsers(const UidRanges& uidRanges) override;
- [[nodiscard]] int removeUsers(const UidRanges& uidRanges) override;
+ [[nodiscard]] int addUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
+ [[nodiscard]] int removeUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
bool isVirtual() override { return true; }
bool canAddUsers() override { return true; }
@@ -42,6 +42,7 @@ public:
std::string getTypeString() const override { return "VIRTUAL"; };
[[nodiscard]] int addInterface(const std::string& interface) override;
[[nodiscard]] int removeInterface(const std::string& interface) override;
+ bool isValidSubPriority(uint32_t priority) override;
};
} // namespace android::net
diff --git a/server/aidl_api/netd_aidl_interface/7/.hash b/server/aidl_api/netd_aidl_interface/7/.hash
new file mode 100644
index 00000000..cad59dfd
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/.hash
@@ -0,0 +1 @@
+850353de5d19a0dd718f8fd20791f0532e6a34c7
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/INetd.aidl
new file mode 100644
index 00000000..ec03d86b
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/INetd.aidl
@@ -0,0 +1,200 @@
+/**
+ * Copyright (c) 2016, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetd {
+ boolean isAlive();
+ boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isAllowlist, in int[] uids);
+ boolean bandwidthEnableDataSaver(boolean enable);
+ /**
+ * @deprecated use networkCreate() instead.
+ */
+ void networkCreatePhysical(int netId, int permission);
+ /**
+ * @deprecated use networkCreate() instead.
+ */
+ void networkCreateVpn(int netId, boolean secure);
+ void networkDestroy(int netId);
+ void networkAddInterface(int netId, in @utf8InCpp String iface);
+ void networkRemoveInterface(int netId, in @utf8InCpp String iface);
+ void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
+ void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
+ void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
+ void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
+ boolean tetherApplyDnsInterfaces();
+ android.net.TetherStatsParcel[] tetherGetStats();
+ void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
+ void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
+ @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
+ void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
+ void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
+ int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
+ void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
+ void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
+ void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
+ void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
+ void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
+ void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
+ void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
+ void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
+ void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
+ void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
+ void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
+ void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
+ void strictUidCleartextPenalty(int uid, int policyPenalty);
+ @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
+ void clatdStop(in @utf8InCpp String ifName);
+ boolean ipfwdEnabled();
+ @utf8InCpp String[] ipfwdGetRequesterList();
+ void ipfwdEnableForwarding(in @utf8InCpp String requester);
+ void ipfwdDisableForwarding(in @utf8InCpp String requester);
+ void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
+ void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
+ void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
+ void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
+ void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
+ void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
+ void bandwidthSetGlobalAlert(long bytes);
+ void bandwidthAddNaughtyApp(int uid);
+ void bandwidthRemoveNaughtyApp(int uid);
+ void bandwidthAddNiceApp(int uid);
+ void bandwidthRemoveNiceApp(int uid);
+ void tetherStart(in @utf8InCpp String[] dhcpRanges);
+ void tetherStop();
+ boolean tetherIsEnabled();
+ void tetherInterfaceAdd(in @utf8InCpp String ifName);
+ void tetherInterfaceRemove(in @utf8InCpp String ifName);
+ @utf8InCpp String[] tetherInterfaceList();
+ void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
+ @utf8InCpp String[] tetherDnsList();
+ void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
+ void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
+ void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
+ void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
+ int networkGetDefault();
+ void networkSetDefault(int netId);
+ void networkClearDefault();
+ void networkSetPermissionForNetwork(int netId, int permission);
+ void networkSetPermissionForUser(int permission, in int[] uids);
+ void networkClearPermissionForUser(in int[] uids);
+ void trafficSetNetPermForUids(int permission, in int[] uids);
+ void networkSetProtectAllow(int uid);
+ void networkSetProtectDeny(int uid);
+ boolean networkCanProtect(int uid);
+ void firewallSetFirewallType(int firewalltype);
+ void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
+ void firewallSetUidRule(int childChain, int uid, int firewallRule);
+ void firewallEnableChildChain(int childChain, boolean enable);
+ @utf8InCpp String[] interfaceGetList();
+ android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
+ void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
+ void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
+ void interfaceClearAddrs(in @utf8InCpp String ifName);
+ void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
+ void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
+ void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
+ void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
+ void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
+ void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
+ void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
+ void firewallRemoveUidInterfaceRules(in int[] uids);
+ void trafficSwapActiveStatsMap();
+ IBinder getOemNetd();
+ void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
+ android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
+ void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
+ void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
+ android.net.TetherStatsParcel[] tetherOffloadGetStats();
+ void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
+ android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
+ void networkCreate(in android.net.NativeNetworkConfig config);
+ void networkAddUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+ void networkRemoveUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+ const int IPV4 = 4;
+ const int IPV6 = 6;
+ const int CONF = 1;
+ const int NEIGH = 2;
+ const String IPSEC_INTERFACE_PREFIX = "ipsec";
+ const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
+ const int IPV6_ADDR_GEN_MODE_NONE = 1;
+ const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
+ const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
+ const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
+ const int PENALTY_POLICY_ACCEPT = 1;
+ const int PENALTY_POLICY_LOG = 2;
+ const int PENALTY_POLICY_REJECT = 3;
+ const int LOCAL_NET_ID = 99;
+ const int DUMMY_NET_ID = 51;
+ const int UNREACHABLE_NET_ID = 52;
+ const String NEXTHOP_NONE = "";
+ const String NEXTHOP_UNREACHABLE = "unreachable";
+ const String NEXTHOP_THROW = "throw";
+ const int PERMISSION_NONE = 0;
+ const int PERMISSION_NETWORK = 1;
+ const int PERMISSION_SYSTEM = 2;
+ const int NO_PERMISSIONS = 0;
+ const int PERMISSION_INTERNET = 4;
+ const int PERMISSION_UPDATE_DEVICE_STATS = 8;
+ const int PERMISSION_UNINSTALLED = -1;
+ /**
+ * @deprecated use FIREWALL_ALLOWLIST.
+ */
+ const int FIREWALL_WHITELIST = 0;
+ const int FIREWALL_ALLOWLIST = 0;
+ /**
+ * @deprecated use FIREWALL_DENYLIST.
+ */
+ const int FIREWALL_BLACKLIST = 1;
+ const int FIREWALL_DENYLIST = 1;
+ const int FIREWALL_RULE_ALLOW = 1;
+ const int FIREWALL_RULE_DENY = 2;
+ const int FIREWALL_CHAIN_NONE = 0;
+ const int FIREWALL_CHAIN_DOZABLE = 1;
+ const int FIREWALL_CHAIN_STANDBY = 2;
+ const int FIREWALL_CHAIN_POWERSAVE = 3;
+ const int FIREWALL_CHAIN_RESTRICTED = 4;
+ const String IF_STATE_UP = "up";
+ const String IF_STATE_DOWN = "down";
+ const String IF_FLAG_BROADCAST = "broadcast";
+ const String IF_FLAG_LOOPBACK = "loopback";
+ const String IF_FLAG_POINTOPOINT = "point-to-point";
+ const String IF_FLAG_RUNNING = "running";
+ const String IF_FLAG_MULTICAST = "multicast";
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/INetdUnsolicitedEventListener.aidl
new file mode 100644
index 00000000..31775dfd
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/INetdUnsolicitedEventListener.aidl
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2018, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetdUnsolicitedEventListener {
+ oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
+ oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
+ oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
+ oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
+ oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
+ oneway void onInterfaceAdded(@utf8InCpp String ifName);
+ oneway void onInterfaceRemoved(@utf8InCpp String ifName);
+ oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
+ oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
+ oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
+ oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/InterfaceConfigurationParcel.aidl
new file mode 100644
index 00000000..1869d8d4
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/InterfaceConfigurationParcel.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable InterfaceConfigurationParcel {
+ @utf8InCpp String ifName;
+ @utf8InCpp String hwAddr;
+ @utf8InCpp String ipv4Addr;
+ int prefixLength;
+ @utf8InCpp String[] flags;
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/MarkMaskParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/MarkMaskParcel.aidl
new file mode 100644
index 00000000..8ea20d11
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/MarkMaskParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable MarkMaskParcel {
+ int mark;
+ int mask;
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkConfig.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkConfig.aidl
new file mode 100644
index 00000000..76562b29
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeNetworkConfig {
+ int netId;
+ android.net.NativeNetworkType networkType = android.net.NativeNetworkType.PHYSICAL;
+ int permission;
+ boolean secure;
+ android.net.NativeVpnType vpnType = android.net.NativeVpnType.PLATFORM;
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkType.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkType.aidl
new file mode 100644
index 00000000..06c8979d
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@Backing(type="int")
+enum NativeNetworkType {
+ PHYSICAL = 0,
+ VIRTUAL = 1,
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/NativeVpnType.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/NativeVpnType.aidl
new file mode 100644
index 00000000..8a8be839
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/NativeVpnType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@Backing(type="int")
+enum NativeVpnType {
+ SERVICE = 1,
+ PLATFORM = 2,
+ LEGACY = 3,
+ OEM = 4,
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/RouteInfoParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/RouteInfoParcel.aidl
new file mode 100644
index 00000000..5ef95e67
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/RouteInfoParcel.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2020, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable RouteInfoParcel {
+ @utf8InCpp String destination;
+ @utf8InCpp String ifName;
+ @utf8InCpp String nextHop;
+ int mtu;
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/TetherConfigParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/TetherConfigParcel.aidl
new file mode 100644
index 00000000..7b39c22e
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/TetherConfigParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherConfigParcel {
+ boolean usingLegacyDnsProxy;
+ @utf8InCpp String[] dhcpRanges;
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/TetherOffloadRuleParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/TetherOffloadRuleParcel.aidl
new file mode 100644
index 00000000..983e9860
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/TetherOffloadRuleParcel.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherOffloadRuleParcel {
+ int inputInterfaceIndex;
+ int outputInterfaceIndex;
+ byte[] destination;
+ int prefixLength;
+ byte[] srcL2Address;
+ byte[] dstL2Address;
+ int pmtu = 1500;
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/TetherStatsParcel.aidl
new file mode 100644
index 00000000..5f1b7226
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/TetherStatsParcel.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherStatsParcel {
+ @utf8InCpp String iface;
+ long rxBytes;
+ long rxPackets;
+ long txBytes;
+ long txPackets;
+ int ifIndex = 0;
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/UidRangeParcel.aidl
new file mode 100644
index 00000000..72e987a2
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/UidRangeParcel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable UidRangeParcel {
+ int start;
+ int stop;
+}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/netd/aidl/NativeUidRangeConfig.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/netd/aidl/NativeUidRangeConfig.aidl
new file mode 100644
index 00000000..9bb679f1
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/7/android/net/netd/aidl/NativeUidRangeConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.netd.aidl;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeUidRangeConfig {
+ int netId;
+ android.net.UidRangeParcel[] uidRanges;
+ int subPriority;
+}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
index a7952f28..ec03d86b 100644
--- a/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
+++ b/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
@@ -145,6 +145,8 @@ interface INetd {
void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
void networkCreate(in android.net.NativeNetworkConfig config);
+ void networkAddUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+ void networkRemoveUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
const int IPV4 = 4;
const int IPV6 = 6;
const int CONF = 1;
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/netd/aidl/NativeUidRangeConfig.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/netd/aidl/NativeUidRangeConfig.aidl
new file mode 100644
index 00000000..9bb679f1
--- /dev/null
+++ b/server/aidl_api/netd_aidl_interface/current/android/net/netd/aidl/NativeUidRangeConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.netd.aidl;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeUidRangeConfig {
+ int netId;
+ android.net.UidRangeParcel[] uidRanges;
+ int subPriority;
+}
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index 8a028314..d6398c12 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -25,6 +25,7 @@ import android.net.TetherConfigParcel;
import android.net.TetherOffloadRuleParcel;
import android.net.TetherStatsParcel;
import android.net.UidRangeParcel;
+import android.net.netd.aidl.NativeUidRangeConfig;
/** {@hide} */
interface INetd {
@@ -1349,4 +1350,31 @@ interface INetd {
* unix errno.
*/
void networkCreate(in NativeNetworkConfig config);
+
+ /**
+ * Adds the specified UID ranges to the specified network. The network can be physical or
+ * virtual. Traffic from the UID ranges will be routed to the network by default. The possible
+ * value of subsidiary priority for physical and unreachable networks is 0-999. 0 is the highest
+ * priority. 0 is also the default value. Virtual network supports only the default value.
+ *
+ * @param NativeUidRangeConfig a parcel contains netId, UID ranges, subsidiary priority, etc.
+ *
+ * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
+ * unix errno.
+ */
+ void networkAddUidRangesParcel(in NativeUidRangeConfig uidRangesConfig);
+
+ /**
+ * Removes the specified UID ranges from the specified network. The network can be physical or
+ * virtual. Traffic from the UID ranges will no longer be routed to the network by default. The
+ * possible value of subsidiary priority for physical and unreachable networks is 0-999. 0 is
+ * the highest priority. 0 is also the default value. Virtual network supports only the default
+ * value.
+ *
+ * @param NativeUidRangeConfig a parcel contains netId, UID ranges, subsidiary priority, etc.
+ *
+ * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
+ * unix errno.
+ */
+ void networkRemoveUidRangesParcel(in NativeUidRangeConfig uidRangesConfig);
}
diff --git a/server/binder/android/net/netd/aidl/NativeUidRangeConfig.aidl b/server/binder/android/net/netd/aidl/NativeUidRangeConfig.aidl
new file mode 100644
index 00000000..99497a86
--- /dev/null
+++ b/server/binder/android/net/netd/aidl/NativeUidRangeConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.net.netd.aidl;
+
+import android.net.UidRangeParcel;
+
+/**
+ * The configuration to add or remove UID ranges.
+ *
+ * {@hide}
+ */
+@JavaDerive(toString=true, equals=true)
+@JavaOnlyImmutable
+parcelable NativeUidRangeConfig {
+ /** The network ID of the network to add/remove the ranges to/from. */
+ int netId;
+
+ /** A set of non-overlapping ranges of UIDs. */
+ UidRangeParcel[] uidRanges;
+
+ /**
+ * The priority of this UID range config. 0 is the highest priority; 999 is the lowest priority.
+ * The function of this parameter is to adjust the priority when the same UID is set to
+ * different networks for different features.
+ */
+ int subPriority;
+} \ No newline at end of file
diff --git a/tests/Android.bp b/tests/Android.bp
index 6ae752b8..c5d9bb53 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -52,7 +52,7 @@ cc_test_library {
"libnetutils",
"libsysutils",
"libutils",
- "netd_aidl_interface-V6-cpp",
+ "netd_aidl_interface-V7-cpp",
],
}
@@ -107,7 +107,7 @@ cc_test {
"libnetdbpf",
"libnetdutils",
"libqtaguid",
- "netd_aidl_interface-V6-cpp",
+ "netd_aidl_interface-V7-cpp",
"netd_event_listener_interface-V1-cpp",
"oemnetd_aidl_interface-cpp",
],
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index 69d1f9b5..22d1f226 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -43,7 +43,6 @@
#include <openssl/base64.h>
#include <sys/socket.h>
#include <sys/types.h>
-#include <sys/utsname.h>
#include <android-base/file.h>
#include <android-base/format.h>
@@ -109,8 +108,10 @@ using android::net::MarkMaskParcel;
using android::net::NativeNetworkConfig;
using android::net::NativeNetworkType;
using android::net::NativeVpnType;
+using android::net::RULE_PRIORITY_BYPASSABLE_VPN;
using android::net::RULE_PRIORITY_DEFAULT_NETWORK;
using android::net::RULE_PRIORITY_EXPLICIT_NETWORK;
+using android::net::RULE_PRIORITY_OUTPUT_INTERFACE;
using android::net::RULE_PRIORITY_PROHIBIT_NON_VPN;
using android::net::RULE_PRIORITY_SECURE_VPN;
using android::net::RULE_PRIORITY_TETHERING;
@@ -124,6 +125,8 @@ using android::net::TetherOffloadRuleParcel;
using android::net::TetherStatsParcel;
using android::net::TunInterface;
using android::net::UidRangeParcel;
+using android::net::UidRanges;
+using android::net::netd::aidl::NativeUidRangeConfig;
using android::netdutils::IPAddress;
using android::netdutils::ScopedAddrinfo;
using android::netdutils::sSyscalls;
@@ -134,6 +137,7 @@ static const char* IP_RULE_V6 = "-6";
static const int TEST_NETID1 = 65501;
static const int TEST_NETID2 = 65502;
static const int TEST_NETID3 = 65503;
+static const int TEST_NETID4 = 65504;
static const int TEST_DUMP_NETID = 65123;
static const char* DNSMASQ = "dnsmasq";
@@ -142,6 +146,9 @@ static const char* DNSMASQ = "dnsmasq";
static const int TEST_UID1 = 99999;
static const int TEST_UID2 = 99998;
static const int TEST_UID3 = 99997;
+static const int TEST_UID4 = 99996;
+static const int TEST_UID5 = 99995;
+static const int TEST_UID6 = 99994;
constexpr int BASE_UID = AID_USER_OFFSET * 5;
@@ -170,6 +177,7 @@ class NetdBinderTest : public ::testing::Test {
mNetd->networkDestroy(TEST_NETID1);
mNetd->networkDestroy(TEST_NETID2);
mNetd->networkDestroy(TEST_NETID3);
+ mNetd->networkDestroy(TEST_NETID4);
setNetworkForProcess(NETID_UNSET);
// Restore default network
if (mStoredDefaultNetwork >= 0) mNetd->networkSetDefault(mStoredDefaultNetwork);
@@ -182,9 +190,11 @@ class NetdBinderTest : public ::testing::Test {
ASSERT_EQ(0, sTun.init());
ASSERT_EQ(0, sTun2.init());
ASSERT_EQ(0, sTun3.init());
+ ASSERT_EQ(0, sTun4.init());
ASSERT_LE(sTun.name().size(), static_cast<size_t>(IFNAMSIZ));
ASSERT_LE(sTun2.name().size(), static_cast<size_t>(IFNAMSIZ));
ASSERT_LE(sTun3.name().size(), static_cast<size_t>(IFNAMSIZ));
+ ASSERT_LE(sTun4.name().size(), static_cast<size_t>(IFNAMSIZ));
}
static void TearDownTestCase() {
@@ -192,6 +202,7 @@ class NetdBinderTest : public ::testing::Test {
sTun.destroy();
sTun2.destroy();
sTun3.destroy();
+ sTun4.destroy();
}
static void fakeRemoteSocketPair(unique_fd* clientSocket, unique_fd* serverSocket,
@@ -224,11 +235,13 @@ class NetdBinderTest : public ::testing::Test {
static TunInterface sTun;
static TunInterface sTun2;
static TunInterface sTun3;
+ static TunInterface sTun4;
};
TunInterface NetdBinderTest::sTun;
TunInterface NetdBinderTest::sTun2;
TunInterface NetdBinderTest::sTun3;
+TunInterface NetdBinderTest::sTun4;
class TimedOperation : public Stopwatch {
public:
@@ -551,14 +564,22 @@ TEST_F(NetdBinderTest, BandwidthEnableDataSaver) {
}
static bool ipRuleExistsForRange(const uint32_t priority, const UidRangeParcel& range,
- const std::string& action, const char* ipVersion) {
+ const std::string& action, const char* ipVersion,
+ const char* oif) {
// Output looks like this:
+ // "<priority>:\tfrom all iif lo oif netdc0ca6 uidrange 500000-500000 lookup netdc0ca6"
// "<priority>:\tfrom all fwmark 0x0/0x20000 iif lo uidrange 1000-2000 prohibit"
std::vector<std::string> rules = listIpRules(ipVersion);
std::string prefix = StringPrintf("%" PRIu32 ":", priority);
- std::string suffix =
- StringPrintf(" iif lo uidrange %d-%d %s\n", range.start, range.stop, action.c_str());
+ std::string suffix;
+ if (oif) {
+ suffix = StringPrintf(" iif lo oif %s uidrange %d-%d %s\n", oif, range.start, range.stop,
+ action.c_str());
+ } else {
+ suffix = StringPrintf(" iif lo uidrange %d-%d %s\n", range.start, range.stop,
+ action.c_str());
+ }
for (const auto& line : rules) {
if (android::base::StartsWith(line, prefix) && android::base::EndsWith(line, suffix)) {
return true;
@@ -567,14 +588,20 @@ static bool ipRuleExistsForRange(const uint32_t priority, const UidRangeParcel&
return false;
}
+// Overloads function with oif parameter for VPN rules compare.
static bool ipRuleExistsForRange(const uint32_t priority, const UidRangeParcel& range,
- const std::string& action) {
- bool existsIp4 = ipRuleExistsForRange(priority, range, action, IP_RULE_V4);
- bool existsIp6 = ipRuleExistsForRange(priority, range, action, IP_RULE_V6);
+ const std::string& action, const char* oif) {
+ bool existsIp4 = ipRuleExistsForRange(priority, range, action, IP_RULE_V4, oif);
+ bool existsIp6 = ipRuleExistsForRange(priority, range, action, IP_RULE_V6, oif);
EXPECT_EQ(existsIp4, existsIp6);
return existsIp4;
}
+static bool ipRuleExistsForRange(const uint32_t priority, const UidRangeParcel& range,
+ const std::string& action) {
+ return ipRuleExistsForRange(priority, range, action, nullptr);
+}
+
namespace {
UidRangeParcel makeUidRangeParcel(int start, int stop) {
@@ -585,6 +612,17 @@ UidRangeParcel makeUidRangeParcel(int start, int stop) {
return res;
}
+NativeUidRangeConfig makeNativeUidRangeConfig(unsigned netId,
+ std::vector<UidRangeParcel>&& uidRanges,
+ uint32_t subPriority) {
+ NativeUidRangeConfig res;
+ res.netId = netId;
+ res.uidRanges = uidRanges;
+ res.subPriority = subPriority;
+
+ return res;
+}
+
} // namespace
TEST_F(NetdBinderTest, NetworkInterfaces) {
@@ -1229,16 +1267,6 @@ void expectIdletimerInterfaceRuleNotExists(const std::string& ifname, int timeou
} // namespace
TEST_F(NetdBinderTest, IdletimerAddRemoveInterface) {
- // TODO(b/175745224): Temporarily disable idletimer test on >5.10 kernels
- utsname u;
- if (!uname(&u)) {
- unsigned long major, minor;
- char *p;
- major = strtoul(u.release, &p, 10);
- minor = strtoul(++p, NULL, 10);
- if (major > 5 || (major == 5 && minor >= 10)) return;
- }
-
// TODO: We will get error in if expectIdletimerInterfaceRuleNotExists if there are the same
// rule in the table. Because we only check the result after calling remove function. We might
// check the actual rule which is removed by our function (maybe compare the results between
@@ -3948,32 +3976,69 @@ namespace {
#define VPN_NETID TEST_NETID3
void verifyAppUidRules(std::vector<bool>&& expectedResults, std::vector<UidRangeParcel>& uidRanges,
- const std::string& iface) {
+ const std::string& iface, uint32_t subPriority) {
ASSERT_EQ(expectedResults.size(), uidRanges.size());
if (iface.size()) {
std::string action = StringPrintf("lookup %s ", iface.c_str());
for (unsigned long i = 0; i < uidRanges.size(); i++) {
- EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(RULE_PRIORITY_UID_EXPLICIT_NETWORK,
- uidRanges[i], action));
- EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(RULE_PRIORITY_UID_IMPLICIT_NETWORK,
- uidRanges[i], action));
- EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(RULE_PRIORITY_UID_DEFAULT_NETWORK,
- uidRanges[i], action));
+ EXPECT_EQ(expectedResults[i],
+ ipRuleExistsForRange(RULE_PRIORITY_UID_EXPLICIT_NETWORK + subPriority,
+ uidRanges[i], action));
+ EXPECT_EQ(expectedResults[i],
+ ipRuleExistsForRange(RULE_PRIORITY_UID_IMPLICIT_NETWORK + subPriority,
+ uidRanges[i], action));
+ EXPECT_EQ(expectedResults[i],
+ ipRuleExistsForRange(RULE_PRIORITY_UID_DEFAULT_NETWORK + subPriority,
+ uidRanges[i], action));
}
} else {
std::string action = "unreachable";
for (unsigned long i = 0; i < uidRanges.size(); i++) {
- EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(RULE_PRIORITY_UID_EXPLICIT_NETWORK,
- uidRanges[i], action));
- EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(RULE_PRIORITY_UID_IMPLICIT_NETWORK,
- uidRanges[i], action));
EXPECT_EQ(expectedResults[i],
- ipRuleExistsForRange(RULE_PRIORITY_UID_DEFAULT_UNREACHABLE, uidRanges[i],
- action));
+ ipRuleExistsForRange(RULE_PRIORITY_UID_EXPLICIT_NETWORK + subPriority,
+ uidRanges[i], action));
+ EXPECT_EQ(expectedResults[i],
+ ipRuleExistsForRange(RULE_PRIORITY_UID_IMPLICIT_NETWORK + subPriority,
+ uidRanges[i], action));
+ EXPECT_EQ(expectedResults[i],
+ ipRuleExistsForRange(RULE_PRIORITY_UID_DEFAULT_UNREACHABLE + subPriority,
+ uidRanges[i], action));
}
}
}
+void verifyAppUidRules(std::vector<bool>&& expectedResults, NativeUidRangeConfig& uidRangeConfig,
+ const std::string& iface) {
+ verifyAppUidRules(move(expectedResults), uidRangeConfig.uidRanges, iface,
+ uidRangeConfig.subPriority);
+}
+
+void verifyVpnUidRules(std::vector<bool>&& expectedResults, NativeUidRangeConfig& uidRangeConfig,
+ const std::string& iface, bool secure) {
+ ASSERT_EQ(expectedResults.size(), uidRangeConfig.uidRanges.size());
+ std::string action = StringPrintf("lookup %s ", iface.c_str());
+
+ uint32_t priority;
+ if (secure) {
+ priority = RULE_PRIORITY_SECURE_VPN;
+ } else {
+ priority = RULE_PRIORITY_BYPASSABLE_VPN;
+ }
+ for (unsigned long i = 0; i < uidRangeConfig.uidRanges.size(); i++) {
+ EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(priority + uidRangeConfig.subPriority,
+ uidRangeConfig.uidRanges[i], action));
+ EXPECT_EQ(expectedResults[i],
+ ipRuleExistsForRange(RULE_PRIORITY_EXPLICIT_NETWORK + uidRangeConfig.subPriority,
+ uidRangeConfig.uidRanges[i], action));
+ EXPECT_EQ(expectedResults[i],
+ ipRuleExistsForRange(RULE_PRIORITY_OUTPUT_INTERFACE + uidRangeConfig.subPriority,
+ uidRangeConfig.uidRanges[i], action, iface.c_str()));
+ }
+}
+
+constexpr int SUB_PRIORITY_1 = UidRanges::DEFAULT_SUB_PRIORITY + 1;
+constexpr int SUB_PRIORITY_2 = UidRanges::DEFAULT_SUB_PRIORITY + 2;
+
constexpr int IMPLICITLY_SELECT = 0;
constexpr int EXPLICITLY_SELECT = 1;
constexpr int UNCONNECTED_SOCKET = 2;
@@ -4087,18 +4152,24 @@ TEST_F(NetdBinderTest, PerAppDefaultNetwork_VerifyIpRules) {
makeUidRangeParcel(BASE_UID + 8090, BASE_UID + 8099)};
EXPECT_TRUE(mNetd->networkAddUidRanges(APP_DEFAULT_NETID, uidRanges).isOk());
- verifyAppUidRules({true, true} /*expectedResults*/, uidRanges, sTun.name());
+ verifyAppUidRules({true, true} /*expectedResults*/, uidRanges, sTun.name(),
+ UidRanges::DEFAULT_SUB_PRIORITY);
EXPECT_TRUE(mNetd->networkRemoveUidRanges(APP_DEFAULT_NETID, {uidRanges.at(0)}).isOk());
- verifyAppUidRules({false, true} /*expectedResults*/, uidRanges, sTun.name());
+ verifyAppUidRules({false, true} /*expectedResults*/, uidRanges, sTun.name(),
+ UidRanges::DEFAULT_SUB_PRIORITY);
EXPECT_TRUE(mNetd->networkRemoveUidRanges(APP_DEFAULT_NETID, {uidRanges.at(1)}).isOk());
- verifyAppUidRules({false, false} /*expectedResults*/, uidRanges, sTun.name());
+ verifyAppUidRules({false, false} /*expectedResults*/, uidRanges, sTun.name(),
+ UidRanges::DEFAULT_SUB_PRIORITY);
EXPECT_TRUE(mNetd->networkAddUidRanges(INetd::UNREACHABLE_NET_ID, uidRanges).isOk());
- verifyAppUidRules({true, true} /*expectedResults*/, uidRanges, "");
+ verifyAppUidRules({true, true} /*expectedResults*/, uidRanges, "",
+ UidRanges::DEFAULT_SUB_PRIORITY);
EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID, {uidRanges.at(0)}).isOk());
- verifyAppUidRules({false, true} /*expectedResults*/, uidRanges, "");
+ verifyAppUidRules({false, true} /*expectedResults*/, uidRanges, "",
+ UidRanges::DEFAULT_SUB_PRIORITY);
EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID, {uidRanges.at(1)}).isOk());
- verifyAppUidRules({false, false} /*expectedResults*/, uidRanges, "");
+ verifyAppUidRules({false, false} /*expectedResults*/, uidRanges, "",
+ UidRanges::DEFAULT_SUB_PRIORITY);
}
// Verify whether packets go through the right network with and without per-app default network.
@@ -4420,3 +4491,211 @@ TEST_F(NetdBinderTest, NetworkCreate) {
wrongConfig.vpnType = static_cast<NativeVpnType>(-1);
EXPECT_EQ(EINVAL, mNetd->networkCreate(wrongConfig).serviceSpecificErrorCode());
}
+
+// Verifies valid and invalid inputs on networkAddUidRangesParcel method.
+TEST_F(NetdBinderTest, UidRangeSubPriority_ValidateInputs) {
+ createVpnAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID, VPN_NETID,
+ /*isSecureVPN=*/true);
+ // Invalid priority -1 on a physical network.
+ NativeUidRangeConfig uidRangeConfig =
+ makeNativeUidRangeConfig(APP_DEFAULT_NETID, {makeUidRangeParcel(BASE_UID, BASE_UID)},
+ UidRanges::DEFAULT_SUB_PRIORITY - 1);
+ binder::Status status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
+
+ // Invalid priority 1000 on a physical network.
+ uidRangeConfig.subPriority = UidRanges::LOWEST_SUB_PRIORITY + 1;
+ status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
+
+ // Virtual networks support only default priority.
+ uidRangeConfig.netId = VPN_NETID;
+ uidRangeConfig.subPriority = SUB_PRIORITY_1;
+ status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
+
+ // For a single network, identical UID ranges with different priorities are allowed.
+ uidRangeConfig.netId = APP_DEFAULT_NETID;
+ uidRangeConfig.subPriority = SUB_PRIORITY_1;
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig).isOk());
+ uidRangeConfig.subPriority = SUB_PRIORITY_2;
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig).isOk());
+
+ // For a single network, identical UID ranges with the same priority is invalid.
+ status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
+
+ // Overlapping ranges is invalid.
+ uidRangeConfig.uidRanges = {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1),
+ makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1)};
+ status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
+}
+
+// Examines whether IP rules for app default network with subsidiary priorities are correctly added
+// and removed.
+TEST_F(NetdBinderTest, UidRangeSubPriority_VerifyPhysicalNwIpRules) {
+ createPhysicalNetwork(TEST_NETID1, sTun.name());
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
+ createPhysicalNetwork(TEST_NETID2, sTun2.name());
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID2, sTun2.name(), "::/0", "").isOk());
+
+ // Adds priority 1 setting
+ NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
+ TEST_NETID1, {makeUidRangeParcel(BASE_UID, BASE_UID)}, SUB_PRIORITY_1);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
+ verifyAppUidRules({true}, uidRangeConfig1, sTun.name());
+ // Adds priority 2 setting
+ NativeUidRangeConfig uidRangeConfig2 = makeNativeUidRangeConfig(
+ TEST_NETID2, {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1)}, SUB_PRIORITY_2);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
+ verifyAppUidRules({true}, uidRangeConfig2, sTun2.name());
+ // Adds another priority 2 setting
+ NativeUidRangeConfig uidRangeConfig3 = makeNativeUidRangeConfig(
+ INetd::UNREACHABLE_NET_ID, {makeUidRangeParcel(BASE_UID + 2, BASE_UID + 2)},
+ SUB_PRIORITY_2);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig3).isOk());
+ verifyAppUidRules({true}, uidRangeConfig3, "");
+
+ // Removes.
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
+ verifyAppUidRules({false}, uidRangeConfig1, sTun.name());
+ verifyAppUidRules({true}, uidRangeConfig2, sTun2.name());
+ verifyAppUidRules({true}, uidRangeConfig3, "");
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig2).isOk());
+ verifyAppUidRules({false}, uidRangeConfig1, sTun.name());
+ verifyAppUidRules({false}, uidRangeConfig2, sTun2.name());
+ verifyAppUidRules({true}, uidRangeConfig3, "");
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig3).isOk());
+ verifyAppUidRules({false}, uidRangeConfig1, sTun.name());
+ verifyAppUidRules({false}, uidRangeConfig2, sTun2.name());
+ verifyAppUidRules({false}, uidRangeConfig3, "");
+}
+
+// Verify uid range rules on virtual network.
+TEST_P(VpnParameterizedTest, UidRangeSubPriority_VerifyVpnIpRules) {
+ const bool isSecureVPN = GetParam();
+ constexpr int VPN_NETID2 = TEST_NETID2;
+
+ // Create 2 VPNs, using sTun and sTun2.
+ auto config = makeNativeNetworkConfig(VPN_NETID, NativeNetworkType::VIRTUAL,
+ INetd::PERMISSION_NONE, isSecureVPN);
+ EXPECT_TRUE(mNetd->networkCreate(config).isOk());
+ EXPECT_TRUE(mNetd->networkAddInterface(VPN_NETID, sTun.name()).isOk());
+
+ config = makeNativeNetworkConfig(VPN_NETID2, NativeNetworkType::VIRTUAL, INetd::PERMISSION_NONE,
+ isSecureVPN);
+ EXPECT_TRUE(mNetd->networkCreate(config).isOk());
+ EXPECT_TRUE(mNetd->networkAddInterface(VPN_NETID2, sTun2.name()).isOk());
+
+ // Assign uid ranges to different VPNs. Check if rules match.
+ NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
+ VPN_NETID, {makeUidRangeParcel(BASE_UID, BASE_UID)}, UidRanges::DEFAULT_SUB_PRIORITY);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
+ verifyVpnUidRules({true}, uidRangeConfig1, sTun.name(), isSecureVPN);
+
+ NativeUidRangeConfig uidRangeConfig2 =
+ makeNativeUidRangeConfig(VPN_NETID2, {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1)},
+ UidRanges::DEFAULT_SUB_PRIORITY);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
+ verifyVpnUidRules({true}, uidRangeConfig2, sTun2.name(), isSecureVPN);
+
+ // Remove uid configs one-by-one. Check if rules match.
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
+ verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN);
+ verifyVpnUidRules({true}, uidRangeConfig2, sTun2.name(), isSecureVPN);
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig2).isOk());
+ verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN);
+ verifyVpnUidRules({false}, uidRangeConfig2, sTun2.name(), isSecureVPN);
+}
+
+// Verify if packets go through the right network when subsidiary priority and VPN works together.
+//
+// Test config:
+// +----------+------------------------+-------------------------------------------+
+// | Priority | UID | Assigned Network |
+// +----------+------------------------+-------------------------------------------+
+// | 0 | TEST_UID1 | VPN bypassable (VPN_NETID) |
+// +----------+------------------------+-------------------------------------------+
+// | 1 | TEST_UID1, TEST_UID2, | Physical Network 1 (APP_DEFAULT_1_NETID) |
+// | 1 | TEST_UID3 | Physical Network 2 (APP_DEFAULT_2_NETID) |
+// | 1 | TEST_UID5 | Unreachable Network (UNREACHABLE_NET_ID) |
+// +----------+------------------------+-------------------------------------------+
+// | 2 | TEST_UID3 | Physical Network 1 (APP_DEFAULT_1_NETID) |
+// | 2 | TEST_UID4, TEST_UID5 | Physical Network 2 (APP_DEFAULT_2_NETID) |
+// +----------+------------------------+-------------------------------------------+
+//
+// Expected results:
+// +-----------+------------------------+
+// | UID | Using Network |
+// +-----------+------------------------+
+// | TEST_UID1 | VPN |
+// | TEST_UID2 | Physical Network 1 |
+// | TEST_UID3 | Physical Network 2 |
+// | TEST_UID4 | Physical Network 2 |
+// | TEST_UID5 | Unreachable Network |
+// | TEST_UID6 | System Default Network |
+// +-----------+------------------------+
+//
+// SYSTEM_DEFAULT_NETID uses sTun.
+// APP_DEFAULT_1_NETID uses sTun2.
+// VPN_NETID uses sTun3.
+// APP_DEFAULT_2_NETID uses sTun4.
+//
+TEST_F(NetdBinderTest, UidRangeSubPriority_ImplicitlySelectNetwork) {
+ constexpr int APP_DEFAULT_1_NETID = TEST_NETID2;
+ constexpr int APP_DEFAULT_2_NETID = TEST_NETID4;
+
+ // Creates 4 networks.
+ createVpnAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_1_NETID, VPN_NETID,
+ /*isSecureVPN=*/false);
+ createPhysicalNetwork(APP_DEFAULT_2_NETID, sTun4.name());
+ EXPECT_TRUE(mNetd->networkAddRoute(APP_DEFAULT_2_NETID, sTun4.name(), "::/0", "").isOk());
+
+ // Adds VPN setting.
+ NativeUidRangeConfig uidRangeConfigVpn = makeNativeUidRangeConfig(
+ VPN_NETID, {makeUidRangeParcel(TEST_UID1, TEST_UID1)}, UidRanges::DEFAULT_SUB_PRIORITY);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfigVpn).isOk());
+
+ // Adds uidRangeConfig1 setting.
+ NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
+ APP_DEFAULT_1_NETID,
+ {makeUidRangeParcel(TEST_UID1, TEST_UID1), makeUidRangeParcel(TEST_UID2, TEST_UID2)},
+ SUB_PRIORITY_1);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
+ uidRangeConfig1.netId = APP_DEFAULT_2_NETID;
+ uidRangeConfig1.uidRanges = {makeUidRangeParcel(TEST_UID3, TEST_UID3)};
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
+ uidRangeConfig1.netId = INetd::UNREACHABLE_NET_ID;
+ uidRangeConfig1.uidRanges = {makeUidRangeParcel(TEST_UID5, TEST_UID5)};
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
+
+ // Adds uidRangeConfig2 setting.
+ NativeUidRangeConfig uidRangeConfig2 = makeNativeUidRangeConfig(
+ APP_DEFAULT_1_NETID, {makeUidRangeParcel(TEST_UID3, TEST_UID3)}, SUB_PRIORITY_2);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
+ uidRangeConfig2.netId = APP_DEFAULT_2_NETID;
+ uidRangeConfig2.uidRanges = {makeUidRangeParcel(TEST_UID4, TEST_UID4),
+ makeUidRangeParcel(TEST_UID5, TEST_UID5)};
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
+
+ int systemDefaultFd = sTun.getFdForTesting();
+ int appDefault_1_Fd = sTun2.getFdForTesting();
+ int vpnFd = sTun3.getFdForTesting();
+ int appDefault_2_Fd = sTun4.getFdForTesting();
+ // Verify routings.
+ expectPacketSentOnNetId(TEST_UID1, VPN_NETID, vpnFd, IMPLICITLY_SELECT);
+ expectPacketSentOnNetId(TEST_UID2, APP_DEFAULT_1_NETID, appDefault_1_Fd, IMPLICITLY_SELECT);
+ expectPacketSentOnNetId(TEST_UID3, APP_DEFAULT_2_NETID, appDefault_2_Fd, IMPLICITLY_SELECT);
+ expectPacketSentOnNetId(TEST_UID4, APP_DEFAULT_2_NETID, appDefault_2_Fd, IMPLICITLY_SELECT);
+ expectUnreachableError(TEST_UID5, INetd::UNREACHABLE_NET_ID, IMPLICITLY_SELECT);
+ expectPacketSentOnNetId(TEST_UID6, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);
+
+ // Remove test rules from the unreachable network.
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
+} \ No newline at end of file