From 81c2160a63440af0a8217a1b299aa8f0e558963f Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Thu, 20 Oct 2022 22:23:15 +0000 Subject: [PATCH] Expose APIs to migrate IpSecTransform This commit exposes APIs to migrate a tunnel mode transform to new source/destination addresses, as required by MOBIKE. By calling the exposed API, the caller only caches the new address in the transform. To complete the migration, caller MUST apply the tranform to the appropriate tunnel. This API design is mainly based on the kernel interface and use cases. The Linux kernel requires Android to provide both the IpSecTransform and the IpSecTunnelInterface to perform the migration. And in most cases those two instances are managed by different entities: IpSecTranform is managed by the key exchange protocol (e.g. IKE) and IpSecTunnelInterface is managed by the security tunnel provider (e.g. VPN, VCN, and IWLAN). Thus the migration process has been designed to have two steps where the key exchange protocol negotiates and caches the new address, passes out the updated transform, and the security tunnel provider applies the transform to a tunnel. Another benefit of this API is it can also apply to the case where the network peer does not support MOBIKE and thus cannot update the existing transforms. In this case, the key exchange protocol can create a new transform and give it to the security tunnel provider, and the tunnel provider can still call "apply" to perform migration without needing to know the details of the transform update process. Bug: 169171001 Test: atest FrameworksNetTests, IpSecManagerTunnelTest Change-Id: I0658cdb09fb31f7e0fb9d0b07f37c2b72b6e705f --- framework-t/api/system-current.txt | 1 + framework-t/src/android/net/IpSecManager.java | 14 ++++++++------ .../unit/java/android/net/IpSecTransformTest.java | 10 ++++++---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/framework-t/api/system-current.txt b/framework-t/api/system-current.txt index c2d245c837..87b0a6414f 100644 --- a/framework-t/api/system-current.txt +++ b/framework-t/api/system-current.txt @@ -260,6 +260,7 @@ package android.net { public class IpSecManager { method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void applyTunnelModeTransform(@NonNull android.net.IpSecManager.IpSecTunnelInterface, int, @NonNull android.net.IpSecTransform) throws java.io.IOException; method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecManager.IpSecTunnelInterface createIpSecTunnelInterface(@NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull android.net.Network) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException; + method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void startTunnelModeTransformMigration(@NonNull android.net.IpSecTransform, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress); } public static final class IpSecManager.IpSecTunnelInterface implements java.lang.AutoCloseable { diff --git a/framework-t/src/android/net/IpSecManager.java b/framework-t/src/android/net/IpSecManager.java index 1c83e09026..4480566529 100644 --- a/framework-t/src/android/net/IpSecManager.java +++ b/framework-t/src/android/net/IpSecManager.java @@ -823,16 +823,18 @@ public class IpSecManager { * Update the underlying network for this IpSecTunnelInterface. * *

This new underlying network will be used for all transforms applied AFTER this call is - * complete. Before new {@link IpSecTransform}(s) with matching addresses are applied to - * this tunnel interface, traffic will still use the old SA, and be routed on the old + * complete. Before {@link IpSecTransform}(s) with matching addresses are applied to this + * tunnel interface, traffic will still use the old transform, and be routed on the old * underlying network. * *

To migrate IPsec tunnel mode traffic, a caller should: * *

    *
  1. Update the IpSecTunnelInterface’s underlying network. - *
  2. Apply {@link IpSecTransform}(s) with matching addresses to this - * IpSecTunnelInterface. + *
  3. Apply the new {@link IpSecTransform}(s) to this IpSecTunnelInterface. These can be + * new {@link IpSecTransform}(s) with matching addresses, or {@link IpSecTransform}(s) + * that have started migration (see {@link + * IpSecManager#startTunnelModeTransformMigration}). *
* * @param underlyingNetwork the new {@link Network} that will carry traffic for this tunnel. @@ -841,7 +843,6 @@ public class IpSecManager { * method will throw an {@link IllegalArgumentException}. If the IpSecTunnelInterface is * later added to this network, all outbound traffic will be blackholed. */ - // TODO: b/169171001 Update the documentation when transform migration is supported. // The purpose of making updating network and applying transforms separate is to leave open // the possibility to support lossless migration procedures. To do that, Android platform // will need to support multiple inbound tunnel mode transforms, just like it can support @@ -1033,9 +1034,10 @@ public class IpSecManager { * @param newDestinationAddress the new destination address * @hide */ + @SystemApi @RequiresFeature(FEATURE_IPSEC_TUNNEL_MIGRATION) @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) - public void startMigration( + public void startTunnelModeTransformMigration( @NonNull IpSecTransform transform, @NonNull InetAddress newSourceAddress, @NonNull InetAddress newDestinationAddress) { diff --git a/tests/unit/java/android/net/IpSecTransformTest.java b/tests/unit/java/android/net/IpSecTransformTest.java index ec59064e3a..8bc1bbd7fe 100644 --- a/tests/unit/java/android/net/IpSecTransformTest.java +++ b/tests/unit/java/android/net/IpSecTransformTest.java @@ -143,8 +143,9 @@ public class IpSecTransformTest { @Test @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) - public void testStartMigration() throws Exception { - mIpSecManager.startMigration(buildTestTransform(), SRC_ADDRESS_V6, DST_ADDRESS_V6); + public void testStartTransformMigration() throws Exception { + mIpSecManager.startTunnelModeTransformMigration( + buildTestTransform(), SRC_ADDRESS_V6, DST_ADDRESS_V6); verify(mMockIpSecService) .migrateTransform( anyInt(), @@ -155,9 +156,10 @@ public class IpSecTransformTest { @Test @DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.TIRAMISU) - public void testStartMigrationOnSdkBeforeU() throws Exception { + public void testStartTransformMigrationOnSdkBeforeU() throws Exception { try { - mIpSecManager.startMigration(buildTestTransform(), SRC_ADDRESS_V6, DST_ADDRESS_V6); + mIpSecManager.startTunnelModeTransformMigration( + buildTestTransform(), SRC_ADDRESS_V6, DST_ADDRESS_V6); fail("Expect to fail since migration is not supported before U"); } catch (UnsupportedOperationException expected) { }