From 245b09badc7a37c7e1a5ba15c896dffb2c59cbf0 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Fri, 20 Jan 2023 01:31:00 +0000 Subject: [PATCH] Utility improvements for handling V6 encap and XFRM_MIGRATE This commit is a preparation CL for testing the ability to update IpSecTransform with new addresses. This commit adds three supports in utility classes: - Support verifying outbound v6 encap packets - Allow awaitEspPacketNoPlaintext to wait for a packet with expected length until timeout. Previously this method would fail immediately when it received an ESP packet with incorrect length. This old behavior would make the tests flaky since the test device might send ESP containing RA message instead of the test data. - Support checking the existence of XFRM_MIGRATE feature Bug: 266149275 Test: atest CtsNetTestCases Change-Id: Ia50aeda8d134c5edd2d1b86bf43a521084ce9866 --- .../cts/net/src/android/net/cts/TunUtils.java | 27 ++++++++++--------- .../android/net/cts/util/CtsNetUtils.java | 12 +++++++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java index 03771608e4..268d8d2603 100644 --- a/tests/cts/net/src/android/net/cts/TunUtils.java +++ b/tests/cts/net/src/android/net/cts/TunUtils.java @@ -22,7 +22,6 @@ import static android.net.cts.PacketUtils.IPPROTO_ESP; import static android.net.cts.PacketUtils.UDP_HDRLEN; import static android.system.OsConstants.IPPROTO_UDP; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import android.os.ParcelFileDescriptor; @@ -32,6 +31,7 @@ import com.android.net.module.util.CollectionUtils; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -140,10 +140,8 @@ public class TunUtils { public byte[] awaitEspPacketNoPlaintext( int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception { final byte[] espPkt = awaitPacket( - (pkt) -> isEspFailIfSpecifiedPlaintextFound(pkt, spi, useEncap, plaintext)); - - // Validate packet size - assertEquals(expectedPacketSize, espPkt.length); + (pkt) -> expectedPacketSize == pkt.length + && isEspFailIfSpecifiedPlaintextFound(pkt, spi, useEncap, plaintext)); return espPkt; // We've found the packet we're looking for. } @@ -153,11 +151,11 @@ public class TunUtils { } private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) { - // Check SPI byte by byte. - return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff) - && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff) - && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff) - && pkt[espOffset + 3] == (byte) (spi & 0xff); + ByteBuffer buffer = ByteBuffer.wrap(pkt); + buffer.get(new byte[espOffset]); // Skip IP, UDP header + int actualSpi = buffer.getInt(); + + return actualSpi == spi; } /** @@ -180,8 +178,13 @@ public class TunUtils { private static boolean isEsp(byte[] pkt, int spi, boolean encap) { if (isIpv6(pkt)) { - // IPv6 UDP encap not supported by kernels; assume non-encap. - return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi); + if (encap) { + return pkt[IP6_PROTO_OFFSET] == IPPROTO_UDP + && isSpiEqual(pkt, IP6_HDRLEN + UDP_HDRLEN, spi); + } else { + return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi); + } + } else { // Use default IPv4 header length (assuming no options) if (encap) { diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java index df3a4aa052..d81763077f 100644 --- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java +++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java @@ -75,6 +75,13 @@ import java.util.concurrent.TimeoutException; public final class CtsNetUtils { private static final String TAG = CtsNetUtils.class.getSimpleName(); + + // Redefine this flag here so that IPsec code shipped in a mainline module can build on old + // platforms before FEATURE_IPSEC_TUNNEL_MIGRATION API is released. + // TODO: b/275378783 Remove this flag and use the platform API when it is available. + private static final String FEATURE_IPSEC_TUNNEL_MIGRATION = + "android.software.ipsec_tunnel_migration"; + private static final int SOCKET_TIMEOUT_MS = 2000; private static final int PRIVATE_DNS_PROBE_MS = 1_000; @@ -115,6 +122,11 @@ public final class CtsNetUtils { || getFirstApiLevel() >= Build.VERSION_CODES.Q; } + /** Checks if FEATURE_IPSEC_TUNNEL_MIGRATION is enabled on the device */ + public boolean hasIpsecTunnelMigrateFeature() { + return mContext.getPackageManager().hasSystemFeature(FEATURE_IPSEC_TUNNEL_MIGRATION); + } + /** * Sets the given appop using shell commands *