diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java index b2db9f5af07ec..8dcc547508ec2 100644 --- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java +++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java @@ -23,7 +23,6 @@ import android.net.ConnectivityManager.NetworkCallback; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; -import android.net.NetworkCapabilities.NetCapability; import android.net.NetworkRequest; import android.net.TelephonyNetworkSpecifier; import android.os.Handler; @@ -115,33 +114,61 @@ public class UnderlyingNetworkTracker { getWifiNetworkRequest(), mHandler, mWifiBringupCallback); updateSubIdsAndCellularRequests(); - // register Network-selection request used to decide selected underlying Network + // Register Network-selection request used to decide selected underlying Network. All + // underlying networks must be VCN managed in order to be used. mConnectivityManager.requestBackgroundNetwork( - getNetworkRequestBase().build(), mHandler, mRouteSelectionCallback); + getBaseNetworkRequest(true /* requireVcnManaged */).build(), + mHandler, + mRouteSelectionCallback); } private NetworkRequest getWifiNetworkRequest() { - return getNetworkRequestBase().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build(); + // Request exclusively VCN managed networks to ensure that we only ever keep carrier wifi + // alive. + return getBaseNetworkRequest(true /* requireVcnManaged */) + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); } private NetworkRequest getCellNetworkRequestForSubId(int subId) { - return getNetworkRequestBase() + // Do not request NOT_VCN_MANAGED to ensure that the TelephonyNetworkFactory has a + // fulfillable request to bring up underlying cellular Networks even if the VCN is already + // connected. + return getBaseNetworkRequest(false /* requireVcnManaged */) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .setNetworkSpecifier(new TelephonyNetworkSpecifier(subId)) .build(); } - private NetworkRequest.Builder getNetworkRequestBase() { - NetworkRequest.Builder requestBase = new NetworkRequest.Builder(); - for (@NetCapability int capability : mRequiredUnderlyingNetworkCapabilities) { + /** + * Builds and returns a NetworkRequest builder common to all Underlying Network requests + * + *
A NetworkRequest may either (1) Require the presence of a capability by using
+ * addCapability(), (2) require the absence of a capability using unwanted capabilities, or (3)
+ * allow any state. Underlying networks are never desired to have the NOT_VCN_MANAGED
+ * capability, and only cases (2) and (3) are used.
+ *
+ * @param requireVcnManaged whether the underlying network is required to be VCN managed to
+ * match this request. If {@code true}, the NOT_VCN_MANAGED capability will be set as
+ * unwanted. Else, the NOT_VCN_MANAGED capability will be removed, and any state is
+ * acceptable.
+ */
+ private NetworkRequest.Builder getBaseNetworkRequest(boolean requireVcnManaged) {
+ NetworkRequest.Builder requestBase =
+ new NetworkRequest.Builder()
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+ for (int capability : mRequiredUnderlyingNetworkCapabilities) {
requestBase.addCapability(capability);
}
- return requestBase
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ if (requireVcnManaged) {
+ requestBase.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ }
+
+ return requestBase;
}
/**
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index c55913e2e547c..3f74938005a71 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -299,9 +299,7 @@ public class Vcn extends Handler {
for (VcnGatewayConnectionConfig gatewayConnectionConfig :
mConfig.getGatewayConnectionConfigs()) {
if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
- Slog.v(
- getLogTag(),
- "Bringing up new VcnGatewayConnection for request " + request.requestId);
+ Slog.v(getLogTag(), "Bringing up new VcnGatewayConnection for request " + request);
final VcnGatewayConnection vcnGatewayConnection =
mDeps.newVcnGatewayConnection(
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 15429f455d6e3..69a153f79a1ba 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -20,6 +20,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR;
@@ -59,6 +60,7 @@ import android.net.ipsec.ike.exceptions.AuthenticationFailedException;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeInternalException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.vcn.VcnControlPlaneIkeConfig;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
@@ -1348,7 +1350,7 @@ public class VcnGatewayConnection extends StateMachine {
mIkeSession = null;
}
- mIkeSession = buildIkeSession();
+ mIkeSession = buildIkeSession(mUnderlying.network);
}
@Override
@@ -1726,6 +1728,7 @@ public class VcnGatewayConnection extends StateMachine {
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
builder.addTransportType(TRANSPORT_CELLULAR);
+ builder.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
builder.addCapability(NET_CAPABILITY_NOT_CONGESTED);
builder.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
@@ -1939,23 +1942,29 @@ public class VcnGatewayConnection extends StateMachine {
new EventDisconnectRequestedInfo(reason, shouldQuit));
}
- private IkeSessionParams buildIkeParams() {
- // TODO: Implement this once IkeSessionParams is persisted
- return null;
+ private IkeSessionParams buildIkeParams(@NonNull Network network) {
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+ final IkeSessionParams.Builder builder =
+ new IkeSessionParams.Builder(controlPlaneConfig.getIkeSessionParams());
+ builder.setConfiguredNetwork(network);
+
+ return builder.build();
}
private ChildSessionParams buildChildParams() {
- // TODO: Implement this once IkeSessionParams is persisted
- return null;
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+ return controlPlaneConfig.getChildSessionParams();
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
- VcnIkeSession buildIkeSession() {
+ VcnIkeSession buildIkeSession(@NonNull Network network) {
final int token = ++mCurrentToken;
return mDeps.newIkeSession(
mVcnContext,
- buildIkeParams(),
+ buildIkeParams(network),
buildChildParams(),
new IkeSessionCallbackImpl(token),
new VcnChildSessionCallback(token));
diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
index 1d459a3475267..1ef1a61f17ea6 100644
--- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
@@ -194,29 +194,35 @@ public class UnderlyingNetworkTrackerTest {
}
private NetworkRequest getWifiRequest() {
- return getExpectedRequestBase()
+ return getExpectedRequestBase(true)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
}
private NetworkRequest getCellRequestForSubId(int subId) {
- return getExpectedRequestBase()
+ return getExpectedRequestBase(false)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
.build();
}
private NetworkRequest getRouteSelectionRequest() {
- return getExpectedRequestBase().build();
+ return getExpectedRequestBase(true).build();
}
- private NetworkRequest.Builder getExpectedRequestBase() {
- return new NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ private NetworkRequest.Builder getExpectedRequestBase(boolean requireVcnManaged) {
+ final NetworkRequest.Builder builder =
+ new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+ if (requireVcnManaged) {
+ builder.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ }
+
+ return builder;
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 4bf849111a5d7..0e5f5e43f2823 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -73,7 +73,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
- mIkeSession = mGatewayConnection.buildIkeSession();
+ mIkeSession = mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_1.network);
mGatewayConnection.setIkeSession(mIkeSession);
mGatewayConnection.transitionTo(mGatewayConnection.mConnectedState);
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index d07d2cf4f1bbb..7afa4494ee8b4 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -25,12 +25,15 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.net.ipsec.ike.IkeSessionParams;
+
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
/** Tests for VcnGatewayConnection.ConnectingState */
@RunWith(AndroidJUnit4.class)
@@ -51,7 +54,12 @@ public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectio
@Test
public void testEnterStateCreatesNewIkeSession() throws Exception {
- verify(mDeps).newIkeSession(any(), any(), any(), any(), any());
+ final ArgumentCaptor