From 1cda4503f236d06d40c747ba69a99772b0333d0c Mon Sep 17 00:00:00 2001 From: Motomu Utsumi Date: Fri, 20 Jun 2025 15:48:24 +0900 Subject: [PATCH] Add test for ingress to VPN address filtering aosp/3201971 and aosp/3208090 updated ConnectivityService not to add filtering rule for TYPE_VPN_LEGACY and TYPE_VPN_OEM to fix the issue in b/352424251 This CL adds tests to veirfy the fix. Test: NetworkAgentTest Bug: 364982471 Flag: EXEMPT test only change Change-Id: Ic3c108b9018f2137c1ae870a88c06e03518874c6 --- .../src/android/net/cts/NetworkAgentTest.kt | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index b2d988f1aa..777b55a31f 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -181,6 +181,8 @@ private const val DEFAULT_TIMEOUT_MS = 5000L private const val QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER = "queue_network_agent_events_in_system_server" +private const val INGRESS_TO_VPN_ADDRESS_FILTERING = + "ingress_to_vpn_address_filtering" // When waiting for a NetworkCallback to determine there was no timeout, waiting is the // only possible thing (the relevant handler is the one in the real ConnectivityService, @@ -2079,4 +2081,67 @@ class NetworkAgentTest { } while (SystemClock.elapsedRealtime() < deadline) fail("Binder Proxy is leaked: $startCount -> $endCount") } + + fun doTestIngressToVpnAddressFiltering(vpnType: Int, expectFiltering: Boolean) { + assumeTrue(mCM.isConnectivityServiceFeatureEnabledForTesting( + INGRESS_TO_VPN_ADDRESS_FILTERING + )) + + val ifname = createTunInterface(listOf(LINK_ADDRESS)).interfaceName + val lp = makeTestLinkProperties(ifname) + val nc = makeTestNetworkCapabilities(transports = intArrayOf(TRANSPORT_VPN)).apply { + setTransportInfo(VpnTransportInfo( + vpnType, + "MySession12345", + /*bypassable=*/ + false, + /*longLivedTcpConnectionsExpensive=*/ + false + )) + } + val agent = createNetworkAgent(initialNc = nc, initialLp = lp) + agent.register() + agent.markConnected() + + val cb = TestableNetworkCallback() + registerNetworkCallback(makeTestNetworkRequest(), cb) + cb.eventuallyExpect { + it.network == agent.network + } + + val ifIndex = Os.if_nametoindex(ifname) + val ruleString = "[" + LINK_ADDRESS.address + "]: " + ifIndex + "(" + ifname + ")" + assertEquals( + expectFiltering, + "dumpsys connectivity trafficcontroller".execute().contains(ruleString) + ) + } + + @Test + fun testIngressToVpnAddressFiltering_VpnPlatform() { + doTestIngressToVpnAddressFiltering( + vpnType = VpnManager.TYPE_VPN_PLATFORM, + expectFiltering = true + ) + } + + @Test + fun testIngressToVpnAddressFiltering_VpnOem() { + // Ingress to VPN address filtering rule should not be added because OEM VPNs might need to + // receive packets to VPN address via non-VPN interface. + doTestIngressToVpnAddressFiltering( + vpnType = VpnManager.TYPE_VPN_OEM, + expectFiltering = false + ) + } + + @Test + fun testIngressToVpnAddressFiltering_VpnLegacy() { + // Ingress to VPN address filtering rule should not be added because legacy VPNs might need + // to receive packets to VPN address via non-VPN interface. + doTestIngressToVpnAddressFiltering( + vpnType = VpnManager.TYPE_VPN_LEGACY, + expectFiltering = false + ) + } }