summaryrefslogtreecommitdiff
path: root/server/RouteController.cpp
diff options
context:
space:
mode:
authorChiachang Wang <chiachangwang@google.com>2022-01-14 22:55:36 +0800
committerChiachang Wang <chiachangwang@google.com>2022-01-14 22:57:42 +0800
commit2e9443fa515639c8a16ee46b071639b5fe61a1a6 (patch)
tree28b67af2f4bbd6f5bc4ac9bfb8f0a89b9ba91eb4 /server/RouteController.cpp
parent3e5d07190e2b6c587170cd75ea2b077d1903d780 (diff)
[ELR#2] Split RULE_PRIORITY_BYPASSABLE_VPN
Split RULE_PRIORITY_BYPASSABLE_VPN into two depending on whether the VPN excludes local routes: RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION (24000) and RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION (26000). Only one of them will exist at any given time determined by whether the VPN excludes local routes. Local exclusion will not work until the new priority rules for local routes are added. The new sets of rules have priority above VPN_FALLTHROUGH, so update the rule priority of VPN_FALLTHROUGH and rules after it. Bug: 184750836 Test: cd system/netd ; atest Change-Id: I23caa68c61276c5e59dc4a85a60be054f1ccc15a
Diffstat (limited to 'server/RouteController.cpp')
-rw-r--r--server/RouteController.cpp45
1 files changed, 29 insertions, 16 deletions
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index c290db9e..1082b8ad 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -491,7 +491,8 @@ 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,
- int32_t subPriority, bool secure, bool add) {
+ int32_t subPriority, bool secure, bool add,
+ bool excludeLocalRoutes) {
Fwmark fwmark;
Fwmark mask;
@@ -503,7 +504,8 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
if (secure) {
priority = RULE_PRIORITY_SECURE_VPN;
} else {
- priority = RULE_PRIORITY_BYPASSABLE_VPN;
+ priority = excludeLocalRoutes ? RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION
+ : RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION;
fwmark.explicitlySelected = false;
mask.explicitlySelected = true;
@@ -519,7 +521,7 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
// This is needed for DnsProxyListener to correctly resolve a request for a user who is in the
// target set, but where the DnsProxyListener itself is not.
[[nodiscard]] static int modifyVpnSystemPermissionRule(unsigned netId, uint32_t table, bool secure,
- bool add) {
+ bool add, bool excludeLocalRoutes) {
Fwmark fwmark;
Fwmark mask;
@@ -529,7 +531,14 @@ int modifyIncomingPacketMark(unsigned netId, const char* interface, Permission p
fwmark.permission = PERMISSION_SYSTEM;
mask.permission = PERMISSION_SYSTEM;
- uint32_t priority = secure ? RULE_PRIORITY_SECURE_VPN : RULE_PRIORITY_BYPASSABLE_VPN;
+ uint32_t priority;
+
+ if (secure) {
+ priority = RULE_PRIORITY_SECURE_VPN;
+ } else {
+ priority = excludeLocalRoutes ? RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION
+ : RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION;
+ }
return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, priority, table, fwmark.intValue,
mask.intValue);
@@ -950,7 +959,7 @@ int RouteController::modifyUnreachableNetwork(unsigned netId, const UidRangeMap&
int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
const UidRangeMap& uidRangeMap, bool secure, bool add,
- bool modifyNonUidBasedRules) {
+ bool modifyNonUidBasedRules, bool excludeLocalRoutes) {
uint32_t table = getRouteTableForInterface(interface);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
@@ -959,7 +968,7 @@ int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
for (const auto& [subPriority, uidRanges] : uidRangeMap) {
for (const UidRangeParcel& range : uidRanges.getRanges()) {
if (int ret = modifyVpnUidRangeRule(table, range.start, range.stop, subPriority, secure,
- add)) {
+ add, excludeLocalRoutes)) {
return ret;
}
if (int ret = modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, range.start,
@@ -980,7 +989,8 @@ int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
if (int ret = modifyVpnOutputToLocalRule(interface, add)) {
return ret;
}
- if (int ret = modifyVpnSystemPermissionRule(netId, table, secure, add)) {
+ if (int ret =
+ modifyVpnSystemPermissionRule(netId, table, secure, add, excludeLocalRoutes)) {
return ret;
}
return modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT,
@@ -1215,9 +1225,10 @@ int RouteController::removeInterfaceFromPhysicalNetwork(unsigned netId, const ch
}
int RouteController::addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRangeMap& uidRangeMap) {
+ bool secure, const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes) {
if (int ret = modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_ADD,
- MODIFY_NON_UID_BASED_RULES)) {
+ MODIFY_NON_UID_BASED_RULES, excludeLocalRoutes)) {
return ret;
}
updateTableNamesFile();
@@ -1225,10 +1236,10 @@ int RouteController::addInterfaceToVirtualNetwork(unsigned netId, const char* in
}
int RouteController::removeInterfaceFromVirtualNetwork(unsigned netId, const char* interface,
- bool secure,
- const UidRangeMap& uidRangeMap) {
+ bool secure, const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes) {
if (int ret = modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_DEL,
- MODIFY_NON_UID_BASED_RULES)) {
+ MODIFY_NON_UID_BASED_RULES, excludeLocalRoutes)) {
return ret;
}
if (int ret = flushRoutes(interface)) {
@@ -1262,15 +1273,17 @@ int RouteController::removeUsersFromRejectNonSecureNetworkRule(const UidRanges&
}
int RouteController::addUsersToVirtualNetwork(unsigned netId, const char* interface, bool secure,
- const UidRangeMap& uidRangeMap) {
+ const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes) {
return modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_ADD,
- !MODIFY_NON_UID_BASED_RULES);
+ !MODIFY_NON_UID_BASED_RULES, excludeLocalRoutes);
}
int RouteController::removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRangeMap& uidRangeMap) {
+ bool secure, const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes) {
return modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_DEL,
- !MODIFY_NON_UID_BASED_RULES);
+ !MODIFY_NON_UID_BASED_RULES, excludeLocalRoutes);
}
int RouteController::addInterfaceToDefaultNetwork(const char* interface, Permission permission) {