Fix WiFi-Direct and Tethering.

A LocalNetwork object now always exists in the NetworkController, with a fixed
NetId that's guaranteed not to collide with NetIds created by the framework.

When routes are added on an interface tracked by the LocalNetwork, they are
added to a fixed "local_network" table.

When NAT is enabled, we add a special "iif -> oif" tethering rule.

Bug: 15413694
Bug: 15413741

Change-Id: I36effc438d5ac193a77174493bf196cb68a5b97a
diff --git a/server/NatController.cpp b/server/NatController.cpp
index 8340b73..3594a5d 100644
--- a/server/NatController.cpp
+++ b/server/NatController.cpp
@@ -32,14 +32,14 @@
 #include <logwrap/logwrap.h>
 
 #include "NatController.h"
-#include "NetworkController.h"
 #include "NetdConstants.h"
+#include "RouteController.h"
 
 const char* NatController::LOCAL_FORWARD = "natctrl_FORWARD";
 const char* NatController::LOCAL_NAT_POSTROUTING = "natctrl_nat_POSTROUTING";
 const char* NatController::LOCAL_TETHER_COUNTERS_CHAIN = "natctrl_tether_counters";
 
-NatController::NatController(NetworkController* net_ctrl) : mNetCtrl(net_ctrl) {
+NatController::NatController() {
 }
 
 NatController::~NatController() {
@@ -112,7 +112,6 @@
         {{IPTABLES_PATH, "-F", LOCAL_FORWARD,}, 1},
         {{IPTABLES_PATH, "-A", LOCAL_FORWARD, "-j", "DROP"}, 1},
         {{IPTABLES_PATH, "-t", "nat", "-F", LOCAL_NAT_POSTROUTING}, 1},
-        {{IP_PATH, "route", "flush", "cache"}, 0},
     };
     for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) {
         if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) &&
@@ -126,34 +125,7 @@
     return 0;
 }
 
-int NatController::routesOp(bool add, const char *intIface, char **argv, int addrCount) {
-    unsigned netId = mNetCtrl->getNetworkForInterface(intIface);
-    int ret = 0;
-
-    for (int i = 0; i < addrCount; i++) {
-        if (add) {
-            ret |= mNetCtrl->addRoute(netId, intIface, argv[5+i], NULL, false, INVALID_UID);
-        } else {
-            ret |= mNetCtrl->addRoute(netId, intIface, argv[5+i], NULL, false, INVALID_UID);
-        }
-    }
-    const char *cmd[] = {
-            IP_PATH,
-            "route",
-            "flush",
-            "cache"
-    };
-    runCmd(ARRAY_SIZE(cmd), cmd);
-    return ret;
-}
-
-//  0    1       2       3       4            5
-// nat enable intface extface addrcnt nated-ipaddr/prelength
-int NatController::enableNat(const int argc, char **argv) {
-    int addrCount = atoi(argv[4]);
-    const char *intIface = argv[2];
-    const char *extIface = argv[3];
-
+int NatController::enableNat(const char* intIface, const char* extIface) {
     ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface);
 
     if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
@@ -168,18 +140,6 @@
         return -1;
     }
 
-    if (argc < 5 + addrCount) {
-        ALOGE("Missing Argument");
-        errno = EINVAL;
-        return -1;
-    }
-    if (routesOp(true, intIface, argv, addrCount)) {
-        ALOGE("Error setting route rules");
-        routesOp(false, intIface, argv, addrCount);
-        errno = ENODEV;
-        return -1;
-    }
-
     // add this if we are the first added nat
     if (natCount == 0) {
         const char *cmd[] = {
@@ -194,18 +154,15 @@
                 "MASQUERADE"
         };
         if (runCmd(ARRAY_SIZE(cmd), cmd)) {
-            ALOGE("Error seting postroute rule: iface=%s", extIface);
+            ALOGE("Error setting postroute rule: iface=%s", extIface);
             // unwind what's been done, but don't care about success - what more could we do?
-            routesOp(false, intIface, argv, addrCount);
             setDefaults();
             return -1;
         }
     }
 
-
     if (setForwardRules(true, intIface, extIface) != 0) {
         ALOGE("Error setting forward rules");
-        routesOp(false, intIface, argv, addrCount);
         if (natCount == 0) {
             setDefaults();
         }
@@ -231,6 +188,12 @@
     };
     runCmd(ARRAY_SIZE(cmd2), cmd2);
 
+    if (int ret = RouteController::enableTethering(intIface, extIface)) {
+        ALOGE("failed to add tethering rule for iif=%s oif=%s", intIface, extIface);
+        errno = -ret;
+        return -1;
+    }
+
     natCount++;
     return 0;
 }
@@ -385,27 +348,19 @@
     return rc;
 }
 
-// nat disable intface extface
-//  0    1       2       3       4            5
-// nat enable intface extface addrcnt nated-ipaddr/prelength
-int NatController::disableNat(const int argc, char **argv) {
-    int addrCount = atoi(argv[4]);
-    const char *intIface = argv[2];
-    const char *extIface = argv[3];
-
+int NatController::disableNat(const char* intIface, const char* extIface) {
     if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
         errno = ENODEV;
         return -1;
     }
 
-    if (argc < 5 + addrCount) {
-        ALOGE("Missing Argument");
-        errno = EINVAL;
+    if (int ret = RouteController::disableTethering(intIface, extIface)) {
+        ALOGE("failed to remove tethering rule for iif=%s oif=%s", intIface, extIface);
+        errno = -ret;
         return -1;
     }
 
     setForwardRules(false, intIface, extIface);
-    routesOp(false, intIface, argv, addrCount);
     if (--natCount <= 0) {
         // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
         setDefaults();