Separate network and interface addition/removal netd APIs.
This should facilitate stacked interfaces (i.e. clatd).
Change-Id: Ib3e7a4d3847ef6ec4449451f6da42e75959baa4f
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 2dcc544..0a09fcb 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -642,6 +642,35 @@
return result;
}
+ /**
+ * Compares all interface names in this LinkProperties with another
+ * LinkProperties, examining both the the base link and all stacked links.
+ *
+ * @param target a LinkProperties with the new list of interface names
+ * @return the differences between the interface names.
+ * @hide
+ */
+ public CompareResult<String> compareAllInterfaceNames(LinkProperties target) {
+ /*
+ * Duplicate the interface names into removed, we will be removing
+ * interface names which are common between this and target
+ * leaving the interface names that are different. And interface names which
+ * are in target but not in this are placed in added.
+ */
+ CompareResult<String> result = new CompareResult<String>();
+
+ result.removed = getAllInterfaceNames();
+ result.added.clear();
+ if (target != null) {
+ for (String r : target.getAllInterfaceNames()) {
+ if (! result.removed.remove(r)) {
+ result.added.add(r);
+ }
+ }
+ }
+ return result;
+ }
+
@Override
/**
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 0784800..eb9ba13 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -410,15 +410,25 @@
boolean isNetworkActive();
/**
- * setup a new network
+ * Setup a new network.
*/
- void createNetwork(int netId, String iface);
+ void createNetwork(int netId);
/**
- * remove a network
+ * Remove a network.
*/
void removeNetwork(int netId);
+ /**
+ * Add an interface to a network.
+ */
+ void addInterfaceToNetwork(String iface, int netId);
+
+ /**
+ * Remove an Interface from a network.
+ */
+ void removeInterfaceFromNetwork(String iface, int netId);
+
void addLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
void removeLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index cdb82e7..6cc738b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5088,6 +5088,7 @@
LinkProperties newLp = networkAgent.linkProperties;
int netId = networkAgent.network.netId;
+ updateInterfaces(newLp, oldLp, netId);
updateMtu(newLp, oldLp);
// TODO - figure out what to do for clat
// for (LinkProperties lp : newLp.getStackedLinks()) {
@@ -5096,6 +5097,30 @@
updateRoutes(newLp, oldLp, netId);
updateDnses(newLp, oldLp, netId);
}
+
+ private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId) {
+ CompareResult<String> interfaceDiff = new CompareResult<String>();
+ if (oldLp != null) {
+ interfaceDiff = oldLp.compareAllInterfaceNames(newLp);
+ } else if (newLp != null) {
+ interfaceDiff.added = newLp.getAllInterfaceNames();
+ }
+ for (String iface : interfaceDiff.added) {
+ try {
+ mNetd.addInterfaceToNetwork(iface, netId);
+ } catch (Exception e) {
+ loge("Exception adding interface: " + e);
+ }
+ }
+ for (String iface : interfaceDiff.removed) {
+ try {
+ mNetd.removeInterfaceFromNetwork(iface, netId);
+ } catch (Exception e) {
+ loge("Exception removing interface: " + e);
+ }
+ }
+ }
+
private void updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
if (oldLp != null) {
@@ -5300,8 +5325,7 @@
if (state == NetworkInfo.State.CONNECTED) {
// TODO - check if we want it (optimization)
try {
- mNetd.createNetwork(networkAgent.network.netId,
- networkAgent.linkProperties.getInterfaceName());
+ mNetd.createNetwork(networkAgent.network.netId);
} catch (Exception e) {
loge("Error creating Network " + networkAgent.network.netId);
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index a0da2c0..cf91782 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1938,11 +1938,11 @@
}
@Override
- public void createNetwork(int netId, String iface) {
+ public void createNetwork(int netId) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mConnector.execute("network", "create", netId, iface);
+ mConnector.execute("network", "create", netId);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
@@ -1960,6 +1960,28 @@
}
@Override
+ public void addInterfaceToNetwork(String iface, int netId) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+ try {
+ mConnector.execute("network", "addiface", netId, iface);
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
+ }
+ }
+
+ @Override
+ public void removeInterfaceFromNetwork(String iface, int netId) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+ try {
+ mConnector.execute("network", "removeiface", netId, iface);
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
+ }
+ }
+
+ @Override
public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
modifyLegacyRouteForNetId(netId, routeInfo, uid, ADD);
}