diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java index eed2006382260..efe78377575e8 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java @@ -1518,13 +1518,6 @@ public class VcnGatewayConnection extends StateMachine { } } - protected void setupInterface( - int token, - @NonNull IpSecTunnelInterface tunnelIface, - @NonNull VcnChildSessionConfiguration childConfig) { - setupInterface(token, tunnelIface, childConfig, null); - } - protected void setupInterface( int token, @NonNull IpSecTunnelInterface tunnelIface, @@ -1609,9 +1602,11 @@ public class VcnGatewayConnection extends StateMachine { transformCreatedInfo.direction); break; case EVENT_SETUP_COMPLETED: + final VcnChildSessionConfiguration oldChildConfig = mChildConfig; mChildConfig = ((EventSetupCompletedInfo) msg.obj).childSessionConfig; - setupInterfaceAndNetworkAgent(mCurrentToken, mTunnelIface, mChildConfig); + setupInterfaceAndNetworkAgent( + mCurrentToken, mTunnelIface, mChildConfig, oldChildConfig); break; case EVENT_DISCONNECT_REQUESTED: handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj); @@ -1655,8 +1650,9 @@ public class VcnGatewayConnection extends StateMachine { protected void setupInterfaceAndNetworkAgent( int token, @NonNull IpSecTunnelInterface tunnelIface, - @NonNull VcnChildSessionConfiguration childConfig) { - setupInterface(token, tunnelIface, childConfig); + @NonNull VcnChildSessionConfiguration childConfig, + @NonNull VcnChildSessionConfiguration oldChildConfig) { + setupInterface(token, tunnelIface, childConfig, oldChildConfig); if (mNetworkAgent == null) { mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig); diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java index 3b0be301edde3..54086c2a332f6 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java @@ -42,6 +42,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import android.net.ConnectivityManager; +import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkAgent; import android.net.NetworkCapabilities; @@ -60,8 +61,11 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import java.io.IOException; +import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.function.Consumer; /** Tests for VcnGatewayConnection.ConnectedState */ @@ -169,12 +173,14 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection } private void triggerChildOpened() { + triggerChildOpened(Collections.singletonList(TEST_INTERNAL_ADDR), TEST_DNS_ADDR); + } + + private void triggerChildOpened(List internalAddresses, InetAddress dnsAddress) { final VcnChildSessionConfiguration mMockChildSessionConfig = mock(VcnChildSessionConfiguration.class); - doReturn(Collections.singletonList(TEST_INTERNAL_ADDR)) - .when(mMockChildSessionConfig) - .getInternalAddresses(); - doReturn(Collections.singletonList(TEST_DNS_ADDR)) + doReturn(internalAddresses).when(mMockChildSessionConfig).getInternalAddresses(); + doReturn(Collections.singletonList(dnsAddress)) .when(mMockChildSessionConfig) .getInternalDnsServers(); @@ -248,6 +254,59 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection assertFalse(mGatewayConnection.isInSafeMode()); } + @Test + public void testInternalAndDnsAddressesChanged() throws Exception { + final List startingInternalAddrs = + Arrays.asList(new LinkAddress[] {TEST_INTERNAL_ADDR, TEST_INTERNAL_ADDR_2}); + triggerChildOpened(startingInternalAddrs, TEST_DNS_ADDR); + mTestLooper.dispatchAll(); + + for (LinkAddress addr : startingInternalAddrs) { + verify(mIpSecSvc) + .addAddressToTunnelInterface( + eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(addr), any()); + } + + verify(mDeps) + .newNetworkAgent( + any(), + any(), + any(), + argThat( + lp -> + startingInternalAddrs.equals(lp.getLinkAddresses()) + && Collections.singletonList(TEST_DNS_ADDR) + .equals(lp.getDnsServers())), + anyInt(), + any(), + any(), + any(), + any()); + + // Trigger another connection event, and verify that the addresses change + final List newInternalAddrs = + Arrays.asList(new LinkAddress[] {TEST_INTERNAL_ADDR_2, TEST_INTERNAL_ADDR_3}); + triggerChildOpened(newInternalAddrs, TEST_DNS_ADDR_2); + mTestLooper.dispatchAll(); + + // Verify addresses on tunnel network added/removed + for (LinkAddress addr : newInternalAddrs) { + verify(mIpSecSvc) + .addAddressToTunnelInterface( + eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(addr), any()); + } + verify(mIpSecSvc) + .removeAddressFromTunnelInterface( + eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_INTERNAL_ADDR), any()); + + // TODO(b/184579891): Also verify link properties updated and sent when sendLinkProperties + // is mockable + + // Verify that IpSecTunnelInterface only created once + verify(mIpSecSvc).createTunnelInterface(any(), any(), any(), any(), any()); + verifyNoMoreInteractions(mIpSecSvc); + } + @Test public void testSuccessfulConnectionExitsSafeMode() throws Exception { verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent( diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java index 884b2338d877e..c5ed8f6ddcc7c 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java @@ -74,8 +74,14 @@ public class VcnGatewayConnectionTestBase { protected static final ParcelUuid TEST_SUB_GRP = new ParcelUuid(UUID.randomUUID()); protected static final InetAddress TEST_DNS_ADDR = InetAddresses.parseNumericAddress("2001:DB8:0:1::"); + protected static final InetAddress TEST_DNS_ADDR_2 = + InetAddresses.parseNumericAddress("2001:DB8:0:2::"); protected static final LinkAddress TEST_INTERNAL_ADDR = - new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:0:2::"), 64); + new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:1::"), 64); + protected static final LinkAddress TEST_INTERNAL_ADDR_2 = + new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:2::"), 64); + protected static final LinkAddress TEST_INTERNAL_ADDR_3 = + new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:3::"), 64); protected static final int TEST_IPSEC_SPI_VALUE = 0x1234; protected static final int TEST_IPSEC_SPI_RESOURCE_ID = 1;