summaryrefslogtreecommitdiff
path: root/server/RouteController.cpp
diff options
context:
space:
mode:
authorSreeram Ramachandran <sreeram@google.com>2014-07-22 22:23:20 -0700
committerSreeram Ramachandran <sreeram@google.com>2014-07-25 16:27:04 -0700
commit48e19b037e7e20674048ef76bf31ce65c741347c (patch)
treef449b95624750c10d406bb65b6d8574d027e973c /server/RouteController.cpp
parent95684ba176a9fe5ea59207d7202e47fa12bbfdbe (diff)
Implement the fallthrough rule to support split tunnel VPNs.
Change-Id: Ibc48caedb5954c6b12bfa553d978bab56c4b09aa
Diffstat (limited to 'server/RouteController.cpp')
-rw-r--r--server/RouteController.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 92aead0c..92b4a947 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -46,7 +46,7 @@ const uint32_t RULE_PRIORITY_LOCAL_NETWORK = 17000;
const uint32_t RULE_PRIORITY_TETHERING = 18000;
const uint32_t RULE_PRIORITY_IMPLICIT_NETWORK = 19000;
const uint32_t RULE_PRIORITY_BYPASSABLE_VPN = 20000;
-// const uint32_t RULE_PRIORITY_VPN_FALLTHROUGH = 21000;
+const uint32_t RULE_PRIORITY_VPN_FALLTHROUGH = 21000;
const uint32_t RULE_PRIORITY_DEFAULT_NETWORK = 22000;
const uint32_t RULE_PRIORITY_DIRECTLY_CONNECTED = 23000;
const uint32_t RULE_PRIORITY_UNREACHABLE = 24000;
@@ -554,6 +554,35 @@ WARN_UNUSED_RESULT int modifyImplicitNetworkRule(unsigned netId, uint32_t table,
fwmark.intValue, mask.intValue);
}
+// A rule to enable split tunnel VPNs.
+//
+// If a packet with a VPN's netId doesn't find a route in the VPN's routing table, it's allowed to
+// go over the default network, provided it wasn't explicitly restricted to the VPN and has the
+// permissions required by the default network.
+WARN_UNUSED_RESULT int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
+ const char* physicalInterface,
+ Permission permission) {
+ uint32_t table = getRouteTableForInterface(physicalInterface);
+ if (table == RT_TABLE_UNSPEC) {
+ return -ESRCH;
+ }
+
+ Fwmark fwmark;
+ Fwmark mask;
+
+ fwmark.netId = vpnNetId;
+ mask.netId = FWMARK_NET_ID_MASK;
+
+ fwmark.explicitlySelected = false;
+ mask.explicitlySelected = true;
+
+ fwmark.permission = permission;
+ mask.permission = permission;
+
+ return modifyIpRule(action, RULE_PRIORITY_VPN_FALLTHROUGH, table, fwmark.intValue,
+ mask.intValue);
+}
+
// Add rules to allow legacy routes added through the requestRouteToHost() API.
WARN_UNUSED_RESULT int addLegacyRouteRules() {
Fwmark fwmark;
@@ -938,3 +967,14 @@ int RouteController::enableTethering(const char* inputInterface, const char* out
int RouteController::disableTethering(const char* inputInterface, const char* outputInterface) {
return modifyTetheredNetwork(RTM_DELRULE, inputInterface, outputInterface);
}
+
+int RouteController::addVirtualNetworkFallthrough(unsigned vpnNetId, const char* physicalInterface,
+ Permission permission) {
+ return modifyVpnFallthroughRule(RTM_NEWRULE, vpnNetId, physicalInterface, permission);
+}
+
+int RouteController::removeVirtualNetworkFallthrough(unsigned vpnNetId,
+ const char* physicalInterface,
+ Permission permission) {
+ return modifyVpnFallthroughRule(RTM_DELRULE, vpnNetId, physicalInterface, permission);
+}