Implement the "network route add/remove" API.
(cherry picked from commit 909c52248a4ad832548c5feb5e9a58323e30ab7b)
Change-Id: Idb09b0c22a3a519dda232995ced406e470ab9768
diff --git a/RouteController.cpp b/RouteController.cpp
index a8f6700..ec82d1a 100644
--- a/RouteController.cpp
+++ b/RouteController.cpp
@@ -40,10 +40,10 @@
bool runIpRuleCommand(const char* action, uint32_t priority, uint32_t table,
uint32_t fwmark, uint32_t mask, const char* interface) {
-
char priorityString[UINT32_STRLEN];
- char tableString[UINT32_STRLEN];
snprintf(priorityString, sizeof(priorityString), "%u", priority);
+
+ char tableString[UINT32_STRLEN];
snprintf(tableString, sizeof(tableString), "%u", table);
char fwmarkString[sizeof("0x12345678/0x12345678")];
@@ -78,6 +78,32 @@
return true;
}
+bool runIpRouteCommand(const char* action, uint32_t table, const char* interface,
+ const char* destination, const char* nexthop) {
+ char tableString[UINT32_STRLEN];
+ snprintf(tableString, sizeof(tableString), "%u", table);
+
+ int argc = 0;
+ const char* argv[16];
+
+ argv[argc++] = IP_PATH;
+ argv[argc++] = "route";
+ argv[argc++] = action;
+ argv[argc++] = "table";
+ argv[argc++] = tableString;
+ if (destination) {
+ argv[argc++] = destination;
+ argv[argc++] = "dev";
+ argv[argc++] = interface;
+ if (nexthop) {
+ argv[argc++] = "via";
+ argv[argc++] = nexthop;
+ }
+ }
+
+ return android_fork_execvp(argc, const_cast<char**>(argv), NULL, false, false);
+}
+
bool modifyPerNetworkRules(unsigned netId, const char* interface, Permission permission, bool add,
bool modifyIptables) {
uint32_t table = getRouteTableForInterface(interface);
@@ -152,11 +178,16 @@
uint32_t mask = getFwmarkMask(FWMARK_USE_NET_ID, !FWMARK_USE_EXPLICIT, !FWMARK_USE_PROTECT,
permission);
- if (!runIpRuleCommand(action, RULE_PRIORITY_DEFAULT_NETWORK, table, fwmark, mask, NULL)) {
+ return runIpRuleCommand(action, RULE_PRIORITY_DEFAULT_NETWORK, table, fwmark, mask, NULL);
+}
+
+bool modifyRoute(const char* interface, const char* destination, const char* nexthop, bool add) {
+ uint32_t table = getRouteTableForInterface(interface);
+ if (!table) {
return false;
}
- return true;
+ return runIpRouteCommand(add ? ADD : DEL, table, interface, destination, nexthop);
}
} // namespace
@@ -184,3 +215,13 @@
bool RouteController::removeDefaultNetwork(const char* interface, Permission permission) {
return modifyDefaultNetworkRules(interface, permission, DEL);
}
+
+bool RouteController::addRoute(const char* interface, const char* destination,
+ const char* nexthop) {
+ return modifyRoute(interface, destination, nexthop, true);
+}
+
+bool RouteController::removeRoute(const char* interface, const char* destination,
+ const char* nexthop) {
+ return modifyRoute(interface, destination, nexthop, false);
+}