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);