Support legacy routes added by apps via ensureRouteToHost().
This adds the routes to two fixed tables:
+ LEGACY, which has higher priority than other non-explicit lookup tables
(per-network and default network).
+ PRIVILEGED_LEGACY, available only to system apps and has higher priority than
VPNs (system apps are those with the CONNECTIVITY_INTERNAL permission).
This will be changed to per-UID tables once the kernel supports UID-based
routing, so that these legacy routes are scoped to each app and not global.
Also, fix a TODO: The framework (as of http://ag/471599) will not set the
gateway argument if it's actually a direct-connected route.
Change-Id: I0ee1ca89fdc859d75a89021ca8c1902811b1e4a9
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 7f9ce39..36773d7 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -25,13 +25,19 @@
namespace {
+const uint32_t RULE_PRIORITY_PRIVILEGED_LEGACY = 11000;
const uint32_t RULE_PRIORITY_PER_NETWORK_EXPLICIT = 13000;
const uint32_t RULE_PRIORITY_PER_NETWORK_INTERFACE = 14000;
+const uint32_t RULE_PRIORITY_LEGACY = 16000;
const uint32_t RULE_PRIORITY_PER_NETWORK_NORMAL = 17000;
const uint32_t RULE_PRIORITY_DEFAULT_NETWORK = 19000;
const uint32_t RULE_PRIORITY_MAIN = 20000;
const uint32_t RULE_PRIORITY_UNREACHABLE = 21000;
+// TODO: These should be turned into per-UID tables once the kernel supports UID-based routing.
+const int ROUTE_TABLE_PRIVILEGED_LEGACY = RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX - 901;
+const int ROUTE_TABLE_LEGACY = RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX - 902;
+
uint32_t getRouteTableForInterface(const char* interface) {
uint32_t index = if_nametoindex(interface);
return index ? index + RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX : 0;
@@ -202,8 +208,24 @@
}
bool modifyRoute(const char* interface, const char* destination, const char* nexthop,
- const char* action) {
- uint32_t table = getRouteTableForInterface(interface);
+ const char* action, RouteController::TableType tableType, unsigned /* uid */) {
+ uint32_t table = 0;
+ switch (tableType) {
+ case RouteController::INTERFACE: {
+ table = getRouteTableForInterface(interface);
+ break;
+ }
+ case RouteController::LEGACY: {
+ // TODO: Use the UID to assign a unique table per UID instead of this fixed table.
+ table = ROUTE_TABLE_LEGACY;
+ break;
+ }
+ case RouteController::PRIVILEGED_LEGACY: {
+ // TODO: Use the UID to assign a unique table per UID instead of this fixed table.
+ table = ROUTE_TABLE_PRIVILEGED_LEGACY;
+ break;
+ }
+ }
if (!table) {
return false;
}
@@ -252,6 +274,25 @@
runIpRuleCommand(ADD, RULE_PRIORITY_MAIN, RT_TABLE_MAIN, fwmark.intValue, mask.intValue, NULL);
+ // Add rules to allow lookup of legacy routes.
+ //
+ // TODO: Remove these once the kernel supports UID-based routing. Instead, add them on demand
+ // when routes are added.
+ fwmark.netId = 0;
+ mask.netId = 0;
+
+ fwmark.explicitlySelected = false;
+ mask.explicitlySelected = true;
+
+ runIpRuleCommand(ADD, RULE_PRIORITY_LEGACY, ROUTE_TABLE_LEGACY, fwmark.intValue, mask.intValue,
+ NULL);
+
+ fwmark.permission = PERMISSION_CONNECTIVITY_INTERNAL;
+ mask.permission = PERMISSION_CONNECTIVITY_INTERNAL;
+
+ runIpRuleCommand(ADD, RULE_PRIORITY_PRIVILEGED_LEGACY, ROUTE_TABLE_PRIVILEGED_LEGACY,
+ fwmark.intValue, mask.intValue, NULL);
+
// TODO: Uncomment once we are sure everything works.
#if 0
// Add a rule to preempt the pre-defined "from all lookup main" rule. This ensures that packets
@@ -287,11 +328,11 @@
}
bool RouteController::addRoute(const char* interface, const char* destination,
- const char* nexthop) {
- return modifyRoute(interface, destination, nexthop, ADD);
+ const char* nexthop, TableType tableType, unsigned uid) {
+ return modifyRoute(interface, destination, nexthop, ADD, tableType, uid);
}
bool RouteController::removeRoute(const char* interface, const char* destination,
- const char* nexthop) {
- return modifyRoute(interface, destination, nexthop, DEL);
+ const char* nexthop, TableType tableType, unsigned uid) {
+ return modifyRoute(interface, destination, nexthop, DEL, tableType, uid);
}