diff --git a/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java b/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java index 1f27f068d4..75546109ef 100644 --- a/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java +++ b/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java @@ -41,6 +41,7 @@ import static com.google.common.io.BaseEncoding.base16; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assume.assumeNotNull; @@ -450,6 +451,55 @@ public class BorderRoutingTest { ICMPV6_ECHO_REQUEST_TYPE, ftd.getOmrAddress(), GROUP_ADDR_SCOPE_3)); } + @Test + public void multicastRouting_outboundForwarding_llaToScope4IsNotForwarded() throws Exception { + assumeTrue(isKernelVersionAtLeast(KERNEL_VERSION_MULTICAST_ROUTING_SUPPORTED)); + /* + *
+         * Topology:
+         *                 infra network                       Thread
+         * infra device -------------------- Border Router -------------- Full Thread device
+         *                                   (Cuttlefish)
+         * 
+ */ + + FullThreadDevice ftd = mFtds.get(0); + startFtdChild(ftd); + Inet6Address ftdLla = ftd.getLinkLocalAddress(); + assertNotNull(ftdLla); + + ftd.ping(GROUP_ADDR_SCOPE_4, ftdLla, 100 /* size */, 1 /* count */); + + assertNull( + pollForPacketOnInfraNetwork(ICMPV6_ECHO_REQUEST_TYPE, ftdLla, GROUP_ADDR_SCOPE_4)); + } + + @Test + public void multicastRouting_outboundForwarding_mlaToScope4IsNotForwarded() throws Exception { + assumeTrue(isKernelVersionAtLeast(KERNEL_VERSION_MULTICAST_ROUTING_SUPPORTED)); + /* + *
+         * Topology:
+         *                 infra network                       Thread
+         * infra device -------------------- Border Router -------------- Full Thread device
+         *                                   (Cuttlefish)
+         * 
+ */ + + FullThreadDevice ftd = mFtds.get(0); + startFtdChild(ftd); + List ftdMlas = ftd.getMeshLocalAddresses(); + assertFalse(ftdMlas.isEmpty()); + + for (Inet6Address ftdMla : ftdMlas) { + ftd.ping(GROUP_ADDR_SCOPE_4, ftdMla, 100 /* size */, 1 /* count */); + + assertNull( + pollForPacketOnInfraNetwork( + ICMPV6_ECHO_REQUEST_TYPE, ftdMla, GROUP_ADDR_SCOPE_4)); + } + } + @Test public void multicastRouting_infraNetworkSwitch_ftdRepliesToSubscribedAddress() throws Exception { diff --git a/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java b/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java index bb0034afd9..6cb16758fe 100644 --- a/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java +++ b/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java @@ -106,6 +106,39 @@ public final class FullThreadDevice { return (Inet6Address) InetAddresses.parseNumericAddress(addresses.get(0)); } + /** + * Returns the link-local address of the device. + * + *

This methods goes through all unicast addresses on the device and returns the address that + * begins with fe80. + */ + public Inet6Address getLinkLocalAddress() { + List output = executeCommand("ipaddr linklocal"); + if (!output.isEmpty() && output.get(0).startsWith("fe80:")) { + return (Inet6Address) InetAddresses.parseNumericAddress(output.get(0)); + } + return null; + } + + /** + * Returns the mesh-local addresses of the device. + * + *

This methods goes through all unicast addresses on the device and returns the address that + * begins with mesh-local prefix. + */ + public List getMeshLocalAddresses() { + List addresses = executeCommand("ipaddr"); + List meshLocalAddresses = new ArrayList<>(); + IpPrefix meshLocalPrefix = mActiveOperationalDataset.getMeshLocalPrefix(); + for (String address : addresses) { + Inet6Address addr = (Inet6Address) InetAddresses.parseNumericAddress(address); + if (meshLocalPrefix.contains(addr)) { + meshLocalAddresses.add(addr); + } + } + return meshLocalAddresses; + } + /** * Joins the Thread network using the given {@link ActiveOperationalDataset}. *