Treat new OEM VPN types like the corresponding non-OEM types.
Bug: 389829981
Test: new CTS tests
Change-Id: I9455a1e00db6fdca3706e83e26daa60db6c73d09
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index b2e49e7..46039b3 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -7482,7 +7482,7 @@
private boolean isLegacyLockdownNai(NetworkAgentInfo nai) {
return mLockdownEnabled
- && getVpnType(nai) == VpnManager.TYPE_VPN_LEGACY
+ && isLegacyVpn(nai)
&& nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID);
}
@@ -10116,8 +10116,8 @@
* interfaces.
* Ingress discard rule is added to the address iff
* 1. The address is not a link local address
- * 2. The address is used by a single interface of VPN whose VPN type is not TYPE_VPN_LEGACY
- * or TYPE_VPN_OEM and the address is not used by any other interfaces even non-VPN ones
+ * 2. The address is used by a single interface of VPN whose VPN type is not LEGACY, OEM or
+ * OEM_LEGACY and the address is not used by any other interfaces even non-VPN ones
* Ingress discard rule is not be added to TYPE_VPN_LEGACY or TYPE_VPN_OEM VPN since these VPNs
* might need to receive packet to VPN address via non-VPN interface.
* This method can be called during network disconnects, when nai has already been removed from
@@ -10155,9 +10155,7 @@
final Set<Pair<InetAddress, String>> ingressDiscardRules = new ArraySet<>();
for (final NetworkAgentInfo agent : nais) {
final int vpnType = getVpnType(agent);
- if (!agent.isVPN() || agent.isDestroyed()
- || vpnType == VpnManager.TYPE_VPN_LEGACY
- || vpnType == VpnManager.TYPE_VPN_OEM) {
+ if (!agent.isVPN() || agent.isDestroyed() || !vpnSupportsInterfaceFiltering(agent)) {
continue;
}
final LinkProperties agentLp = (nai == agent) ? lp : agent.linkProperties;
@@ -12800,6 +12798,23 @@
return ((VpnTransportInfo) ti).getType();
}
+ private boolean isVpnServiceVpn(NetworkAgentInfo nai) {
+ final int vpnType = getVpnType(nai);
+ return vpnType == VpnManager.TYPE_VPN_SERVICE || vpnType == VpnManager.TYPE_VPN_OEM_SERVICE;
+ }
+
+ private boolean isLegacyVpn(NetworkAgentInfo nai) {
+ final int vpnType = getVpnType(nai);
+ return vpnType == VpnManager.TYPE_VPN_LEGACY || vpnType == VpnManager.TYPE_VPN_OEM_LEGACY;
+ }
+
+ private boolean vpnSupportsInterfaceFiltering(NetworkAgentInfo vpn) {
+ final int vpnType = getVpnType(vpn);
+ return vpnType != VpnManager.TYPE_VPN_LEGACY
+ && vpnType != VpnManager.TYPE_VPN_OEM
+ && vpnType != VpnManager.TYPE_VPN_OEM_LEGACY;
+ }
+
private void maybeUpdateWifiRoamTimestamp(@NonNull NetworkAgentInfo nai,
@NonNull NetworkCapabilities nc) {
final TransportInfo prevInfo = nai.networkCapabilities.getTransportInfo();
@@ -12833,7 +12848,7 @@
if (hasNetworkStackPermission()) return uid;
final NetworkAgentInfo vpn = getVpnForUid(uid);
- if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE
+ if (vpn == null || !isVpnServiceVpn(vpn)
|| vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) {
return INVALID_UID;
}
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 8fcc703..0aa491e 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -1055,6 +1055,47 @@
callback.expect<Lost>(agent.network!!)
}
+ fun doTestOemVpnType(type: Int) {
+ val mySessionId = "MySession12345"
+ val nc = NetworkCapabilities().apply {
+ addTransportType(TRANSPORT_TEST)
+ addTransportType(TRANSPORT_VPN)
+ addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ removeCapability(NET_CAPABILITY_NOT_VPN)
+ setTransportInfo(VpnTransportInfo(type, mySessionId))
+ }
+
+ val agent = createNetworkAgent(initialNc = nc)
+ agent.register()
+ agent.markConnected()
+
+ val request = NetworkRequest.Builder()
+ .clearCapabilities()
+ .addTransportType(TRANSPORT_VPN)
+ .removeCapability(NET_CAPABILITY_NOT_VPN)
+ .build()
+ val callback = TestableNetworkCallback()
+ registerNetworkCallback(request, callback)
+
+ callback.expectAvailableThenValidatedCallbacks(agent.network!!)
+
+ var vpnNc = mCM.getNetworkCapabilities(agent.network!!)
+ assertNotNull(vpnNc)
+ assertEquals(type, (vpnNc!!.transportInfo as VpnTransportInfo).type)
+
+ agent.unregister()
+ callback.expect<Lost>(agent.network!!)
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ fun testOemVpnTypes() {
+ // TODO: why is this necessary given the @IgnoreUpTo above?
+ assumeTrue(SdkLevel.isAtLeastB())
+ doTestOemVpnType(VpnManager.TYPE_VPN_OEM_SERVICE)
+ doTestOemVpnType(VpnManager.TYPE_VPN_OEM_LEGACY)
+ }
+
private fun unregister(agent: TestableNetworkAgent) {
agent.unregister()
agent.eventuallyExpect<OnNetworkUnwanted>()