Implement network default set/clear.

(cherry picked from commit 4cc7df247a7ec67da3b5edfb9356077fbbf0150c)

Change-Id: Ib35d54816884c6a6ba28231c9b1f54e362d1d16a
diff --git a/RouteController.cpp b/RouteController.cpp
index 737dd9f..a8f6700 100644
--- a/RouteController.cpp
+++ b/RouteController.cpp
@@ -24,13 +24,14 @@
 
 namespace {
 
-const uint32_t RULE_PRIORITY_PER_NETWORK_EXPLICIT = 300;
-const uint32_t RULE_PRIORITY_PER_NETWORK_OIF = 400;
-const uint32_t RULE_PRIORITY_PER_NETWORK_NORMAL = 700;
+const uint32_t RULE_PRIORITY_PER_NETWORK_EXPLICIT  =  300;
+const uint32_t RULE_PRIORITY_PER_NETWORK_INTERFACE =  400;
+const uint32_t RULE_PRIORITY_PER_NETWORK_NORMAL    =  700;
+const uint32_t RULE_PRIORITY_DEFAULT_NETWORK       =  900;
 
-const bool FWMARK_USE_NET_ID = true;
+const bool FWMARK_USE_NET_ID   = true;
 const bool FWMARK_USE_EXPLICIT = true;
-const bool FWMARK_USE_PROTECT = true;
+const bool FWMARK_USE_PROTECT  = true;
 
 uint32_t getRouteTableForInterface(const char* interface) {
     uint32_t index = if_nametoindex(interface);
@@ -38,7 +39,7 @@
 }
 
 bool runIpRuleCommand(const char* action, uint32_t priority, uint32_t table,
-                      uint32_t fwmark, uint32_t mask, const char* oif) {
+                      uint32_t fwmark, uint32_t mask, const char* interface) {
 
     char priorityString[UINT32_STRLEN];
     char tableString[UINT32_STRLEN];
@@ -65,9 +66,9 @@
             argv[argc++] = "fwmark";
             argv[argc++] = fwmarkString;
         }
-        if (oif) {
+        if (interface) {
             argv[argc++] = "oif";
-            argv[argc++] = oif;
+            argv[argc++] = interface;
         }
         if (android_fork_execvp(argc, const_cast<char**>(argv), NULL, false, false)) {
             return false;
@@ -77,8 +78,8 @@
     return true;
 }
 
-bool modifyRules(unsigned netId, const char* interface, Permission permission, bool add,
-                 bool modifyIptables) {
+bool modifyPerNetworkRules(unsigned netId, const char* interface, Permission permission, bool add,
+                           bool modifyIptables) {
     uint32_t table = getRouteTableForInterface(interface);
     if (!table) {
         return false;
@@ -105,7 +106,8 @@
     // knows the outgoing interface (typically for link-local communications).
     fwmark = getFwmark(0, !FWMARK_USE_EXPLICIT, !FWMARK_USE_PROTECT, permission);
     mask = getFwmark(!FWMARK_USE_NET_ID, !FWMARK_USE_EXPLICIT, !FWMARK_USE_PROTECT, permission);
-    if (!runIpRuleCommand(action, RULE_PRIORITY_PER_NETWORK_OIF, table, fwmark, mask, interface)) {
+    if (!runIpRuleCommand(action, RULE_PRIORITY_PER_NETWORK_INTERFACE, table, fwmark, mask,
+                          interface)) {
         return false;
     }
 
@@ -140,20 +142,45 @@
     return true;
 }
 
+bool modifyDefaultNetworkRules(const char* interface, Permission permission, const char* action) {
+    uint32_t table = getRouteTableForInterface(interface);
+    if (!table) {
+        return false;
+    }
+
+    uint32_t fwmark = getFwmark(0, !FWMARK_USE_EXPLICIT, !FWMARK_USE_PROTECT, permission);
+    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 false;
+    }
+
+    return true;
+}
+
 }  // namespace
 
 bool RouteController::createNetwork(unsigned netId, const char* interface, Permission permission) {
-    return modifyRules(netId, interface, permission, true, true);
+    return modifyPerNetworkRules(netId, interface, permission, true, true);
 }
 
 bool RouteController::destroyNetwork(unsigned netId, const char* interface, Permission permission) {
-    return modifyRules(netId, interface, permission, false, true);
+    return modifyPerNetworkRules(netId, interface, permission, false, true);
     // TODO: Flush the routing table.
 }
 
 bool RouteController::modifyNetworkPermission(unsigned netId, const char* interface,
                                               Permission oldPermission, Permission newPermission) {
     // Add the new rules before deleting the old ones, to avoid race conditions.
-    return modifyRules(netId, interface, newPermission, true, false) &&
-           modifyRules(netId, interface, oldPermission, false, false);
+    return modifyPerNetworkRules(netId, interface, newPermission, true, false) &&
+           modifyPerNetworkRules(netId, interface, oldPermission, false, false);
+}
+
+bool RouteController::addDefaultNetwork(const char* interface, Permission permission) {
+    return modifyDefaultNetworkRules(interface, permission, ADD);
+}
+
+bool RouteController::removeDefaultNetwork(const char* interface, Permission permission) {
+    return modifyDefaultNetworkRules(interface, permission, DEL);
 }