Fix tethering in the case of a regular upstream connection.

Fixes tethering via Ethernet, Bluetooth and WiFi (hotspot).

Tethering when the upstream has a DUN-specific APN is likely still broken
(untested).

For now, assign a fixed NetId (a hack) until we can change the framework to
create a valid NetworkAgent and all that jazz.

Bug: 15968336
Bug: 14988803
Change-Id: Idcf4d492d9329a9c87913e27be6dd835a792bea2
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index fbee5a2..47b620d 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -33,8 +33,10 @@
 
 #include "NetdConstants.h"
 #include "TetherController.h"
+#include "NetworkController.h"
 
-TetherController::TetherController() {
+TetherController::TetherController(NetworkController* networkController) :
+        mNetworkController(networkController) {
     mInterfaces = new InterfaceCollection();
     mDnsForwarders = new NetAddressCollection();
     mDaemonFd = -1;
@@ -170,6 +172,17 @@
         ALOGD("Tethering services running");
     }
 
+    unsigned netId = mNetworkController->getNetIdForLocalNetwork();
+    if (int ret = mNetworkController->createLocalNetwork(netId)) {
+        return ret;
+    }
+    // If any interfaces have already been configured, add them to the local network now.
+    for (InterfaceCollection::iterator it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
+        if (int ret = mNetworkController->addInterfaceToNetwork(netId, *it)) {
+            return ret;
+        }
+    }
+
     return 0;
 }
 
@@ -182,6 +195,9 @@
 
     ALOGD("Stopping tethering services");
 
+    // Ignore any error.
+    (void) mNetworkController->destroyNetwork(mNetworkController->getNetIdForLocalNetwork());
+
     kill(mDaemonPid, SIGTERM);
     waitpid(mDaemonPid, NULL, 0);
     mDaemonPid = 0;
@@ -291,6 +307,10 @@
         }
         return -1;
     } else {
+        if (isTetheringStarted()) {
+            unsigned netId = mNetworkController->getNetIdForLocalNetwork();
+            return mNetworkController->addInterfaceToNetwork(netId, interface);
+        }
         return 0;
     }
 }
@@ -300,6 +320,12 @@
 
     ALOGD("untetherInterface(%s)", interface);
 
+    if (isTetheringStarted()) {
+        unsigned netId = mNetworkController->getNetIdForLocalNetwork();
+        // Ignore any error.
+        (void) mNetworkController->removeInterfaceFromNetwork(netId, interface);
+    }
+
     for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
         if (!strcmp(interface, *it)) {
             free(*it);