Merge changes from topic "ipsec-tunnel-tests" into qt-dev

* changes:
  Remove mContext from IpSecBaseTest
  Add reflected-packet based data tests
  Cleanup IPsec CTS tests
diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
index 26049cc..10e43e7 100644
--- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
@@ -76,11 +76,9 @@
 
     protected ConnectivityManager mCM;
     protected IpSecManager mISM;
-    protected Context mContext;
 
     @Before
     public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getContext();
         mISM =
                 (IpSecManager)
                         InstrumentationRegistry.getContext()
@@ -475,7 +473,7 @@
     private IpSecTransform buildDefaultTransform(InetAddress localAddr) throws Exception {
         try (IpSecManager.SecurityParameterIndex spi =
                 mISM.allocateSecurityParameterIndex(localAddr)) {
-            return buildIpSecTransform(mContext, spi, null, localAddr);
+            return buildIpSecTransform(InstrumentationRegistry.getContext(), spi, null, localAddr);
         }
     }
 
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
index 1241785..355b496 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
@@ -41,6 +41,7 @@
 import android.system.Os;
 import android.system.OsConstants;
 
+import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
 import java.io.FileDescriptor;
@@ -73,12 +74,6 @@
 
     private static final byte[] AEAD_KEY = getKey(288);
 
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-    }
-
     /*
      * Allocate a random SPI
      * Allocate a specific SPI using previous randomly created SPI value
@@ -244,7 +239,7 @@
                 mISM.allocateSecurityParameterIndex(localAddr);
 
         IpSecTransform transform =
-                new IpSecTransform.Builder(mContext)
+                new IpSecTransform.Builder(InstrumentationRegistry.getContext())
                         .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
                         .setAuthentication(
                                 new IpSecAlgorithm(
@@ -462,7 +457,8 @@
                 IpSecManager.SecurityParameterIndex spi =
                         mISM.allocateSecurityParameterIndex(local)) {
 
-            IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(mContext);
+            IpSecTransform.Builder transformBuilder =
+                    new IpSecTransform.Builder(InstrumentationRegistry.getContext());
             if (crypt != null) {
                 transformBuilder.setEncryption(crypt);
             }
@@ -623,7 +619,7 @@
             try (IpSecManager.SecurityParameterIndex spi =
                             mISM.allocateSecurityParameterIndex(local);
                     IpSecTransform transform =
-                            new IpSecTransform.Builder(mContext)
+                            new IpSecTransform.Builder(InstrumentationRegistry.getContext())
                                     .setEncryption(crypt)
                                     .setAuthentication(auth)
                                     .setIpv4Encapsulation(encapSocket, encapSocket.getPort())
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
index ef6bfc0..999d2f1 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
@@ -129,15 +129,15 @@
         // right appop permissions.
         setAppop(OP_MANAGE_IPSEC_TUNNELS, true);
 
-        TestNetworkInterface testIntf =
+        TestNetworkInterface testIface =
                 sTNM.createTunInterface(
                         new LinkAddress[] {
                             new LinkAddress(LOCAL_OUTER_4, IP4_PREFIX_LEN),
                             new LinkAddress(LOCAL_OUTER_6, IP6_PREFIX_LEN)
                         });
 
-        sTunFd = testIntf.getFileDescriptor();
-        sTunNetworkCallback = setupAndGetTestNetwork(testIntf.getInterfaceName());
+        sTunFd = testIface.getFileDescriptor();
+        sTunNetworkCallback = setupAndGetTestNetwork(testIface.getInterfaceName());
         sTunNetwork = sTunNetworkCallback.getNetworkBlocking();
 
         sTunUtils = new TunUtils(sTunFd);
@@ -242,8 +242,16 @@
     }
 
     /* Test runnables for callbacks after IPsec tunnels are set up. */
-    private interface TestRunnable {
-        void run(Network ipsecNetwork) throws Exception;
+    private abstract class IpSecTunnelTestRunnable {
+        /**
+         * Runs the test code, and returns the inner socket port, if any.
+         *
+         * @param ipsecNetwork The IPsec Interface based Network for binding sockets on
+         * @return the integer port of the inner socket if outbound, or 0 if inbound
+         *     IpSecTunnelTestRunnable
+         * @throws Exception if any part of the test failed.
+         */
+        public abstract int run(Network ipsecNetwork) throws Exception;
     }
 
     private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
@@ -290,8 +298,8 @@
         return expectedPacketSize;
     }
 
-    private interface TestRunnableFactory {
-        TestRunnable getTestRunnable(
+    private interface IpSecTunnelTestRunnableFactory {
+        IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
                 boolean transportInTunnelMode,
                 int spi,
                 InetAddress localInner,
@@ -301,12 +309,13 @@
                 IpSecTransform inTransportTransform,
                 IpSecTransform outTransportTransform,
                 int encapPort,
+                int innerSocketPort,
                 int expectedPacketSize)
                 throws Exception;
     }
 
-    private class OutputTestRunnableFactory implements TestRunnableFactory {
-        public TestRunnable getTestRunnable(
+    private class OutputIpSecTunnelTestRunnableFactory implements IpSecTunnelTestRunnableFactory {
+        public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
                 boolean transportInTunnelMode,
                 int spi,
                 InetAddress localInner,
@@ -316,13 +325,15 @@
                 IpSecTransform inTransportTransform,
                 IpSecTransform outTransportTransform,
                 int encapPort,
+                int unusedInnerSocketPort,
                 int expectedPacketSize) {
-            return new TestRunnable() {
+            return new IpSecTunnelTestRunnable() {
                 @Override
-                public void run(Network ipsecNetwork) throws Exception {
+                public int run(Network ipsecNetwork) throws Exception {
                     // Build a socket and send traffic
                     JavaUdpSocket socket = new JavaUdpSocket(localInner);
                     ipsecNetwork.bindSocket(socket.mSocket);
+                    int innerSocketPort = socket.getPort();
 
                     // For Transport-In-Tunnel mode, apply transform to socket
                     if (transportInTunnelMode) {
@@ -335,19 +346,22 @@
                     socket.sendTo(TEST_DATA, remoteInner, socket.getPort());
 
                     // Verify that an encrypted packet is sent. As of right now, checking encrypted
-                    // body is not possible, due to our not knowing some of the fields of the
+                    // body is not possible, due to the test not knowing some of the fields of the
                     // inner IP header (flow label, flags, etc)
                     sTunUtils.awaitEspPacketNoPlaintext(
                             spi, TEST_DATA, encapPort != 0, expectedPacketSize);
 
                     socket.close();
+
+                    return innerSocketPort;
                 }
             };
         }
     }
 
-    private class InputPacketGeneratorTestRunnableFactory implements TestRunnableFactory {
-        public TestRunnable getTestRunnable(
+    private class InputReflectedIpSecTunnelTestRunnableFactory
+            implements IpSecTunnelTestRunnableFactory {
+        public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
                 boolean transportInTunnelMode,
                 int spi,
                 InetAddress localInner,
@@ -357,14 +371,57 @@
                 IpSecTransform inTransportTransform,
                 IpSecTransform outTransportTransform,
                 int encapPort,
+                int innerSocketPort,
                 int expectedPacketSize)
                 throws Exception {
-            return new TestRunnable() {
+            return new IpSecTunnelTestRunnable() {
                 @Override
-                public void run(Network ipsecNetwork) throws Exception {
+                public int run(Network ipsecNetwork) throws Exception {
+                    // Build a socket and receive traffic
+                    JavaUdpSocket socket = new JavaUdpSocket(localInner, innerSocketPort);
+                    ipsecNetwork.bindSocket(socket.mSocket);
+
+                    // For Transport-In-Tunnel mode, apply transform to socket
+                    if (transportInTunnelMode) {
+                        mISM.applyTransportModeTransform(
+                                socket.mSocket, IpSecManager.DIRECTION_IN, outTransportTransform);
+                        mISM.applyTransportModeTransform(
+                                socket.mSocket, IpSecManager.DIRECTION_OUT, inTransportTransform);
+                    }
+
+                    sTunUtils.reflectPackets();
+
+                    // Receive packet from socket, and validate that the payload is correct
+                    receiveAndValidatePacket(socket);
+
+                    socket.close();
+
+                    return 0;
+                }
+            };
+        }
+    }
+
+    private class InputPacketGeneratorIpSecTunnelTestRunnableFactory
+            implements IpSecTunnelTestRunnableFactory {
+        public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
+                boolean transportInTunnelMode,
+                int spi,
+                InetAddress localInner,
+                InetAddress remoteInner,
+                InetAddress localOuter,
+                InetAddress remoteOuter,
+                IpSecTransform inTransportTransform,
+                IpSecTransform outTransportTransform,
+                int encapPort,
+                int innerSocketPort,
+                int expectedPacketSize)
+                throws Exception {
+            return new IpSecTunnelTestRunnable() {
+                @Override
+                public int run(Network ipsecNetwork) throws Exception {
                     // Build a socket and receive traffic
                     JavaUdpSocket socket = new JavaUdpSocket(localInner);
-                    // JavaUdpSocket socket = new JavaUdpSocket(localInner, socketPort.get());
                     ipsecNetwork.bindSocket(socket.mSocket);
 
                     // For Transport-In-Tunnel mode, apply transform to socket
@@ -404,6 +461,8 @@
                     receiveAndValidatePacket(socket);
 
                     socket.close();
+
+                    return 0;
                 }
             };
         }
@@ -417,7 +476,7 @@
                 outerFamily,
                 useEncap,
                 transportInTunnelMode,
-                new OutputTestRunnableFactory());
+                new OutputIpSecTunnelTestRunnableFactory());
     }
 
     private void checkTunnelInput(
@@ -428,7 +487,91 @@
                 outerFamily,
                 useEncap,
                 transportInTunnelMode,
-                new InputPacketGeneratorTestRunnableFactory());
+                new InputPacketGeneratorIpSecTunnelTestRunnableFactory());
+    }
+
+    /**
+     * Validates that the kernel can talk to itself.
+     *
+     * <p>This test takes an outbound IPsec packet, reflects it (by flipping IP src/dst), and
+     * injects it back into the TUN. This test then verifies that a packet with the correct payload
+     * is found on the specified socket/port.
+     */
+    public void checkTunnelReflected(
+            int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
+            throws Exception {
+        if (!hasTunnelsFeature()) return;
+
+        InetAddress localInner = innerFamily == AF_INET ? LOCAL_INNER_4 : LOCAL_INNER_6;
+        InetAddress remoteInner = innerFamily == AF_INET ? REMOTE_INNER_4 : REMOTE_INNER_6;
+
+        InetAddress localOuter = outerFamily == AF_INET ? LOCAL_OUTER_4 : LOCAL_OUTER_6;
+        InetAddress remoteOuter = outerFamily == AF_INET ? REMOTE_OUTER_4 : REMOTE_OUTER_6;
+
+        // Preselect both SPI and encap port, to be used for both inbound and outbound tunnels.
+        int spi = getRandomSpi(localOuter, remoteOuter);
+        int expectedPacketSize =
+                getPacketSize(innerFamily, outerFamily, useEncap, transportInTunnelMode);
+
+        try (IpSecManager.SecurityParameterIndex inTransportSpi =
+                        mISM.allocateSecurityParameterIndex(localInner, spi);
+                IpSecManager.SecurityParameterIndex outTransportSpi =
+                        mISM.allocateSecurityParameterIndex(remoteInner, spi);
+                IpSecTransform inTransportTransform =
+                        buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
+                IpSecTransform outTransportTransform =
+                        buildIpSecTransform(sContext, outTransportSpi, null, localInner);
+                UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
+
+            // Run output direction tests
+            IpSecTunnelTestRunnable outputIpSecTunnelTestRunnable =
+                    new OutputIpSecTunnelTestRunnableFactory()
+                            .getIpSecTunnelTestRunnable(
+                                    transportInTunnelMode,
+                                    spi,
+                                    localInner,
+                                    remoteInner,
+                                    localOuter,
+                                    remoteOuter,
+                                    inTransportTransform,
+                                    outTransportTransform,
+                                    useEncap ? encapSocket.getPort() : 0,
+                                    0,
+                                    expectedPacketSize);
+            int innerSocketPort =
+                    buildTunnelNetworkAndRunTests(
+                    localInner,
+                    remoteInner,
+                    localOuter,
+                    remoteOuter,
+                    spi,
+                    useEncap ? encapSocket : null,
+                    outputIpSecTunnelTestRunnable);
+
+            // Input direction tests, with matching inner socket ports.
+            IpSecTunnelTestRunnable inputIpSecTunnelTestRunnable =
+                    new InputReflectedIpSecTunnelTestRunnableFactory()
+                            .getIpSecTunnelTestRunnable(
+                                    transportInTunnelMode,
+                                    spi,
+                                    remoteInner,
+                                    localInner,
+                                    localOuter,
+                                    remoteOuter,
+                                    inTransportTransform,
+                                    outTransportTransform,
+                                    useEncap ? encapSocket.getPort() : 0,
+                                    innerSocketPort,
+                                    expectedPacketSize);
+            buildTunnelNetworkAndRunTests(
+                    remoteInner,
+                    localInner,
+                    localOuter,
+                    remoteOuter,
+                    spi,
+                    useEncap ? encapSocket : null,
+                    inputIpSecTunnelTestRunnable);
+        }
     }
 
     public void checkTunnel(
@@ -436,7 +579,7 @@
             int outerFamily,
             boolean useEncap,
             boolean transportInTunnelMode,
-            TestRunnableFactory factory)
+            IpSecTunnelTestRunnableFactory factory)
             throws Exception {
         if (!hasTunnelsFeature()) return;
 
@@ -463,14 +606,14 @@
                         buildIpSecTransform(sContext, outTransportSpi, null, localInner);
                 UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
 
-            buildTunnelAndNetwork(
+            buildTunnelNetworkAndRunTests(
                     localInner,
                     remoteInner,
                     localOuter,
                     remoteOuter,
                     spi,
                     useEncap ? encapSocket : null,
-                    factory.getTestRunnable(
+                    factory.getIpSecTunnelTestRunnable(
                             transportInTunnelMode,
                             spi,
                             localInner,
@@ -480,41 +623,42 @@
                             inTransportTransform,
                             outTransportTransform,
                             useEncap ? encapSocket.getPort() : 0,
+                            0,
                             expectedPacketSize));
         }
     }
 
-    private void buildTunnelAndNetwork(
+    private int buildTunnelNetworkAndRunTests(
             InetAddress localInner,
             InetAddress remoteInner,
             InetAddress localOuter,
             InetAddress remoteOuter,
             int spi,
             UdpEncapsulationSocket encapSocket,
-            TestRunnable test)
+            IpSecTunnelTestRunnable test)
             throws Exception {
         int innerPrefixLen = localInner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN;
         TestNetworkCallback testNetworkCb = null;
+        int innerSocketPort;
 
         try (IpSecManager.SecurityParameterIndex inSpi =
                         mISM.allocateSecurityParameterIndex(localOuter, spi);
                 IpSecManager.SecurityParameterIndex outSpi =
                         mISM.allocateSecurityParameterIndex(remoteOuter, spi);
-                IpSecManager.IpSecTunnelInterface tunnelIntf =
+                IpSecManager.IpSecTunnelInterface tunnelIface =
                         mISM.createIpSecTunnelInterface(localOuter, remoteOuter, sTunNetwork)) {
             // Build the test network
-            tunnelIntf.addAddress(localInner, innerPrefixLen);
-            testNetworkCb = setupAndGetTestNetwork(tunnelIntf.getInterfaceName());
+            tunnelIface.addAddress(localInner, innerPrefixLen);
+            testNetworkCb = setupAndGetTestNetwork(tunnelIface.getInterfaceName());
             Network testNetwork = testNetworkCb.getNetworkBlocking();
 
             // Check interface was created
-            NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName());
-            assertNotNull(netIntf);
+            assertNotNull(NetworkInterface.getByName(tunnelIface.getInterfaceName()));
 
             // Verify address was added
-            netIntf = NetworkInterface.getByInetAddress(localInner);
-            assertNotNull(netIntf);
-            assertEquals(tunnelIntf.getInterfaceName(), netIntf.getDisplayName());
+            final NetworkInterface netIface = NetworkInterface.getByInetAddress(localInner);
+            assertNotNull(netIface);
+            assertEquals(tunnelIface.getInterfaceName(), netIface.getDisplayName());
 
             // Configure Transform parameters
             IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext);
@@ -533,28 +677,31 @@
                             transformBuilder.buildTunnelModeTransform(remoteOuter, inSpi);
                     IpSecTransform outTransform =
                             transformBuilder.buildTunnelModeTransform(localOuter, outSpi)) {
-                mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_IN, inTransform);
-                mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_OUT, outTransform);
+                mISM.applyTunnelModeTransform(tunnelIface, IpSecManager.DIRECTION_IN, inTransform);
+                mISM.applyTunnelModeTransform(
+                        tunnelIface, IpSecManager.DIRECTION_OUT, outTransform);
 
-                test.run(testNetwork);
+                innerSocketPort = test.run(testNetwork);
             }
 
             // Teardown the test network
             sTNM.teardownTestNetwork(testNetwork);
 
             // Remove addresses and check that interface is still present, but fails lookup-by-addr
-            tunnelIntf.removeAddress(localInner, innerPrefixLen);
-            assertNotNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName()));
+            tunnelIface.removeAddress(localInner, innerPrefixLen);
+            assertNotNull(NetworkInterface.getByName(tunnelIface.getInterfaceName()));
             assertNull(NetworkInterface.getByInetAddress(localInner));
 
             // Check interface was cleaned up
-            tunnelIntf.close();
-            assertNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName()));
+            tunnelIface.close();
+            assertNull(NetworkInterface.getByName(tunnelIface.getInterfaceName()));
         } finally {
             if (testNetworkCb != null) {
                 sCM.unregisterNetworkCallback(testNetworkCb);
             }
         }
+
+        return innerSocketPort;
     }
 
     private static void receiveAndValidatePacket(JavaUdpSocket socket) throws Exception {
@@ -678,35 +825,65 @@
     }
 
     @Test
+    public void testTransportInTunnelModeV4InV4Reflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET, false, true);
+    }
+
+    @Test
     public void testTransportInTunnelModeV4InV4UdpEncap() throws Exception {
         checkTunnelOutput(AF_INET, AF_INET, true, true);
         checkTunnelInput(AF_INET, AF_INET, true, true);
     }
 
     @Test
+    public void testTransportInTunnelModeV4InV4UdpEncapReflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET, false, true);
+    }
+
+    @Test
     public void testTransportInTunnelModeV4InV6() throws Exception {
         checkTunnelOutput(AF_INET, AF_INET6, false, true);
         checkTunnelInput(AF_INET, AF_INET6, false, true);
     }
 
     @Test
+    public void testTransportInTunnelModeV4InV6Reflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET, false, true);
+    }
+
+    @Test
     public void testTransportInTunnelModeV6InV4() throws Exception {
         checkTunnelOutput(AF_INET6, AF_INET, false, true);
         checkTunnelInput(AF_INET6, AF_INET, false, true);
     }
 
     @Test
+    public void testTransportInTunnelModeV6InV4Reflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET, false, true);
+    }
+
+    @Test
     public void testTransportInTunnelModeV6InV4UdpEncap() throws Exception {
         checkTunnelOutput(AF_INET6, AF_INET, true, true);
         checkTunnelInput(AF_INET6, AF_INET, true, true);
     }
 
     @Test
+    public void testTransportInTunnelModeV6InV4UdpEncapReflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET, false, true);
+    }
+
+    @Test
     public void testTransportInTunnelModeV6InV6() throws Exception {
         checkTunnelOutput(AF_INET, AF_INET6, false, true);
         checkTunnelInput(AF_INET, AF_INET6, false, true);
     }
 
+    @Test
+    public void testTransportInTunnelModeV6InV6Reflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET, false, true);
+    }
+
     // Tunnel mode tests
     @Test
     public void testTunnelV4InV4() throws Exception {
@@ -715,32 +892,62 @@
     }
 
     @Test
+    public void testTunnelV4InV4Reflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET, false, false);
+    }
+
+    @Test
     public void testTunnelV4InV4UdpEncap() throws Exception {
         checkTunnelOutput(AF_INET, AF_INET, true, false);
         checkTunnelInput(AF_INET, AF_INET, true, false);
     }
 
     @Test
+    public void testTunnelV4InV4UdpEncapReflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET, true, false);
+    }
+
+    @Test
     public void testTunnelV4InV6() throws Exception {
         checkTunnelOutput(AF_INET, AF_INET6, false, false);
         checkTunnelInput(AF_INET, AF_INET6, false, false);
     }
 
     @Test
+    public void testTunnelV4InV6Reflected() throws Exception {
+        checkTunnelReflected(AF_INET, AF_INET6, false, false);
+    }
+
+    @Test
     public void testTunnelV6InV4() throws Exception {
         checkTunnelOutput(AF_INET6, AF_INET, false, false);
         checkTunnelInput(AF_INET6, AF_INET, false, false);
     }
 
     @Test
+    public void testTunnelV6InV4Reflected() throws Exception {
+        checkTunnelReflected(AF_INET6, AF_INET, false, false);
+    }
+
+    @Test
     public void testTunnelV6InV4UdpEncap() throws Exception {
         checkTunnelOutput(AF_INET6, AF_INET, true, false);
         checkTunnelInput(AF_INET6, AF_INET, true, false);
     }
 
     @Test
+    public void testTunnelV6InV4UdpEncapReflected() throws Exception {
+        checkTunnelReflected(AF_INET6, AF_INET, true, false);
+    }
+
+    @Test
     public void testTunnelV6InV6() throws Exception {
         checkTunnelOutput(AF_INET6, AF_INET6, false, false);
         checkTunnelInput(AF_INET6, AF_INET6, false, false);
     }
+
+    @Test
+    public void testTunnelV6InV6Reflected() throws Exception {
+        checkTunnelReflected(AF_INET6, AF_INET6, false, false);
+    }
 }