diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 953fd763ff..0a970280b7 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -9400,8 +9400,10 @@ public class ConnectivityService extends IConnectivityManager.Stub * 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 VPN interface and not used by any other + * 2. The address is used by a single non-Legacy VPN interface and not used by any other * interfaces even non-VPN ones + * Ingress discard rule is not be added to Legacy VPN since some Legacy VPNs 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 * mNetworkAgentInfos. * @@ -9436,7 +9438,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // for different network. final Set> ingressDiscardRules = new ArraySet<>(); for (final NetworkAgentInfo agent : nais) { - if (!agent.isVPN() || agent.isDestroyed()) { + if (!agent.isVPN() || agent.isDestroyed() + || getVpnType(agent) == VpnManager.TYPE_VPN_LEGACY) { continue; } final LinkProperties agentLp = (nai == agent) ? lp : agent.linkProperties; diff --git a/tests/unit/java/com/android/server/connectivityservice/CSIngressDiscardRuleTests.kt b/tests/unit/java/com/android/server/connectivityservice/CSIngressDiscardRuleTests.kt index 93f6e81d03..1ae77e581b 100644 --- a/tests/unit/java/com/android/server/connectivityservice/CSIngressDiscardRuleTests.kt +++ b/tests/unit/java/com/android/server/connectivityservice/CSIngressDiscardRuleTests.kt @@ -27,6 +27,7 @@ import android.net.NetworkCapabilities.TRANSPORT_VPN import android.net.NetworkCapabilities.TRANSPORT_WIFI import android.net.NetworkRequest import android.net.VpnManager.TYPE_VPN_SERVICE +import android.net.VpnManager.TYPE_VPN_LEGACY import android.net.VpnTransportInfo import android.os.Build import androidx.test.filters.SmallTest @@ -49,19 +50,20 @@ private const val WIFI_IFNAME = "wlan0" private const val TIMEOUT_MS = 1_000L private const val LONG_TIMEOUT_MS = 5_000 -private fun vpnNc() = NetworkCapabilities.Builder() - .addTransportType(TRANSPORT_VPN) - .removeCapability(NET_CAPABILITY_NOT_VPN) - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) - .setTransportInfo( - VpnTransportInfo( - TYPE_VPN_SERVICE, - "MySession12345", - false /* bypassable */, - false /* longLivedTcpConnectionsExpensive */ - ) - ) - .build() +private fun vpnNc(legacyVpn: Boolean = false) = NetworkCapabilities.Builder().apply { + addTransportType(TRANSPORT_VPN) + removeCapability(NET_CAPABILITY_NOT_VPN) + addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) + val vpnType = if (legacyVpn) { TYPE_VPN_LEGACY } else { TYPE_VPN_SERVICE } + setTransportInfo( + VpnTransportInfo( + vpnType, + "MySession12345", + false /* bypassable */, + false /* longLivedTcpConnectionsExpensive */ + ) + ) +}.build() private fun wifiNc() = NetworkCapabilities.Builder() .addTransportType(TRANSPORT_WIFI) @@ -310,4 +312,19 @@ class CSIngressDiscardRuleTests : CSTest() { // IngressDiscardRule should not be added since feature is disabled verify(bpfNetMaps, never()).setIngressDiscardRule(any(), any()) } + + @Test + fun testVpnIngressDiscardRule_LegacyVpn() { + val nr = nr(TRANSPORT_VPN) + val cb = TestableNetworkCallback() + cm.registerNetworkCallback(nr, cb) + val nc = vpnNc(legacyVpn = true) + val lp = lp(VPN_IFNAME, IPV6_LINK_ADDRESS, LOCAL_IPV6_LINK_ADDRRESS) + val agent = Agent(nc = nc, lp = lp) + agent.connect() + cb.expectAvailableCallbacks(agent.network, validated = false) + + // IngressDiscardRule should not be added to Legacy VPN + verify(bpfNetMaps, never()).setIngressDiscardRule(any(), any()) + } }