Separate network and interface addition/removal netd APIs.
This should facilitate stacked interfaces (i.e. clatd).
Change-Id: Ib3e7a4d3847ef6ec4449451f6da42e75959baa4f
diff --git a/NetworkController.cpp b/NetworkController.cpp
index 93e1c1b..b36dd9d 100644
--- a/NetworkController.cpp
+++ b/NetworkController.cpp
@@ -143,8 +143,17 @@
return NETID_UNSET;
}
-bool NetworkController::createNetwork(unsigned netId, const char* interface,
- Permission permission) {
+bool NetworkController::createNetwork(unsigned netId, Permission permission) {
+ if (!isNetIdValid(netId)) {
+ ALOGE("invalid netId %u", netId);
+ return false;
+ }
+
+ mPermissionsController->setPermissionForNetwork(permission, netId);
+ return true;
+}
+
+bool NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) {
if (!isNetIdValid(netId) || !interface) {
ALOGE("invalid netId %u or interface null", netId);
return false;
@@ -156,16 +165,62 @@
return false;
}
- if (!mRouteController->createNetwork(netId, interface, permission)) {
+ Permission permission = mPermissionsController->getPermissionForNetwork(netId);
+ if (!mRouteController->addInterfaceToNetwork(netId, interface, permission)) {
+ ALOGE("failed to add rules for interface %s to netId %u", interface, netId);
return false;
}
- mPermissionsController->setPermissionForNetwork(permission, netId);
mNetIdToInterfaces.insert(std::pair<unsigned, std::string>(netId, interface));
mIfaceNetidMap[interface] = netId;
+
+ if (netId == getDefaultNetwork() &&
+ !mRouteController->addDefaultNetwork(interface, permission)) {
+ ALOGE("failed to add interface %s to default network %u", interface, netId);
+ return false;
+ }
+
return true;
}
+bool NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) {
+ if (!isNetIdValid(netId) || !interface) {
+ ALOGE("invalid netId %u or interface null", netId);
+ return false;
+ }
+
+ bool status = true;
+ bool found = false;
+ InterfaceRange range = interfacesForNetId(netId, &status);
+ for (InterfaceIterator iter = range.first; iter != range.second; ++iter) {
+ if (iter->second == interface) {
+ mNetIdToInterfaces.erase(iter);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ ALOGE("interface %s not a member of netId %u", interface, netId);
+ status = false;
+ }
+
+ Permission permission = mPermissionsController->getPermissionForNetwork(netId);
+ if (!mRouteController->removeInterfaceFromNetwork(netId, interface, permission)) {
+ ALOGE("failed to remove rules for interface %s from netId %u", interface, netId);
+ status = false;
+ }
+
+ if (netId == getDefaultNetwork() &&
+ !mRouteController->removeDefaultNetwork(interface, permission)) {
+ ALOGE("failed to remove interface %s from default network %u", interface, netId);
+ status = false;
+ }
+
+ mIfaceNetidMap.erase(interface);
+
+ return status;
+}
+
bool NetworkController::destroyNetwork(unsigned netId) {
if (!isNetIdValid(netId)) {
ALOGE("invalid netId %u", netId);
@@ -176,10 +231,11 @@
bool status = true;
- Permission permission = mPermissionsController->getPermissionForNetwork(netId);
InterfaceRange range = interfacesForNetId(netId, &status);
- for (InterfaceIterator iter = range.first; iter != range.second; ++iter) {
- if (!mRouteController->destroyNetwork(netId, iter->second.c_str(), permission)) {
+ for (InterfaceIterator iter = range.first; iter != range.second; ) {
+ InterfaceIterator toErase = iter;
+ ++iter;
+ if (!removeInterfaceFromNetwork(netId, toErase->second.c_str())) {
status = false;
}
}
@@ -193,7 +249,6 @@
}
mPermissionsController->setPermissionForNetwork(PERMISSION_NONE, netId);
- mNetIdToInterfaces.erase(netId);
// TODO: Uncomment once this API has been added to bionic.
#if 0