Fix DadProxyTest when forwarding is on. am: b6bffbca95 am: 3f29d3ef39
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1664401 Change-Id: I5715c990a0de3b3de1a09e44a25bf96d7027feb5
This commit is contained in:
@@ -21,9 +21,8 @@ import static android.system.OsConstants.IPPROTO_ICMPV6;
|
|||||||
import static com.android.net.module.util.IpUtils.icmpv6Checksum;
|
import static com.android.net.module.util.IpUtils.icmpv6Checksum;
|
||||||
import static com.android.net.module.util.NetworkStackConstants.ETHER_SRC_ADDR_OFFSET;
|
import static com.android.net.module.util.NetworkStackConstants.ETHER_SRC_ADDR_OFFSET;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import android.app.Instrumentation;
|
import android.app.Instrumentation;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -52,13 +51,14 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class DadProxyTest {
|
public class DadProxyTest {
|
||||||
private static final int DATA_BUFFER_LEN = 4096;
|
private static final int DATA_BUFFER_LEN = 4096;
|
||||||
private static final int PACKET_TIMEOUT_MS = 5_000;
|
private static final int PACKET_TIMEOUT_MS = 2_000; // Long enough for DAD to succeed.
|
||||||
|
|
||||||
// Start the readers manually on a common handler shared with DadProxy, for simplicity
|
// Start the readers manually on a common handler shared with DadProxy, for simplicity
|
||||||
@Rule
|
@Rule
|
||||||
@@ -119,16 +119,18 @@ public class DadProxyTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupTapInterfaces() {
|
private void setupTapInterfaces() throws Exception {
|
||||||
// Create upstream test iface.
|
// Create upstream test iface.
|
||||||
mUpstreamReader.start(mHandler);
|
mUpstreamReader.start(mHandler);
|
||||||
mUpstreamParams = InterfaceParams.getByName(mUpstreamReader.iface.getInterfaceName());
|
final String upstreamIface = mUpstreamReader.iface.getInterfaceName();
|
||||||
|
mUpstreamParams = InterfaceParams.getByName(upstreamIface);
|
||||||
assertNotNull(mUpstreamParams);
|
assertNotNull(mUpstreamParams);
|
||||||
mUpstreamPacketReader = mUpstreamReader.getReader();
|
mUpstreamPacketReader = mUpstreamReader.getReader();
|
||||||
|
|
||||||
// Create tethered test iface.
|
// Create tethered test iface.
|
||||||
mTetheredReader.start(mHandler);
|
mTetheredReader.start(mHandler);
|
||||||
mTetheredParams = InterfaceParams.getByName(mTetheredReader.getIface().getInterfaceName());
|
final String tetheredIface = mTetheredReader.getIface().getInterfaceName();
|
||||||
|
mTetheredParams = InterfaceParams.getByName(tetheredIface);
|
||||||
assertNotNull(mTetheredParams);
|
assertNotNull(mTetheredParams);
|
||||||
mTetheredPacketReader = mTetheredReader.getReader();
|
mTetheredPacketReader = mTetheredReader.getReader();
|
||||||
}
|
}
|
||||||
@@ -224,6 +226,12 @@ public class DadProxyTest {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ByteBuffer copy(ByteBuffer buf) {
|
||||||
|
// There does not seem to be a way to copy ByteBuffers. ByteBuffer does not implement
|
||||||
|
// clone() and duplicate() copies the metadata but shares the contents.
|
||||||
|
return ByteBuffer.wrap(buf.array().clone());
|
||||||
|
}
|
||||||
|
|
||||||
private void updateDstMac(ByteBuffer buf, MacAddress mac) {
|
private void updateDstMac(ByteBuffer buf, MacAddress mac) {
|
||||||
buf.put(mac.toByteArray());
|
buf.put(mac.toByteArray());
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
@@ -234,14 +242,50 @@ public class DadProxyTest {
|
|||||||
buf.rewind();
|
buf.rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void receivePacketAndMaybeExpectForwarded(boolean expectForwarded,
|
||||||
|
ByteBuffer in, TapPacketReader inReader, ByteBuffer out, TapPacketReader outReader)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
inReader.sendResponse(in);
|
||||||
|
if (waitForPacket(out, outReader)) return;
|
||||||
|
|
||||||
|
// When the test runs, DAD may be in progress, because the interface has just been created.
|
||||||
|
// If so, the DAD proxy will get EADDRNOTAVAIL when trying to send packets. It is not
|
||||||
|
// possible to work around this using IPV6_FREEBIND or IPV6_TRANSPARENT options because the
|
||||||
|
// kernel rawv6 code doesn't consider those options either when binding or when sending, and
|
||||||
|
// doesn't get the source address from the packet even in IPPROTO_RAW/HDRINCL mode (it only
|
||||||
|
// gets it from the socket or from cmsg).
|
||||||
|
//
|
||||||
|
// If DAD was in progress when the above was attempted, try again and expect the packet to
|
||||||
|
// be forwarded. Don't disable DAD in the test because if we did, the test would not notice
|
||||||
|
// if, for example, the DAD proxy code just crashed if it received EADDRNOTAVAIL.
|
||||||
|
final String msg = expectForwarded
|
||||||
|
? "Did not receive expected packet even after waiting for DAD:"
|
||||||
|
: "Unexpectedly received packet:";
|
||||||
|
|
||||||
|
inReader.sendResponse(in);
|
||||||
|
assertEquals(msg, expectForwarded, waitForPacket(out, outReader));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void receivePacketAndExpectForwarded(ByteBuffer in, TapPacketReader inReader,
|
||||||
|
ByteBuffer out, TapPacketReader outReader) throws IOException {
|
||||||
|
receivePacketAndMaybeExpectForwarded(true, in, inReader, out, outReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void receivePacketAndExpectNotForwarded(ByteBuffer in, TapPacketReader inReader,
|
||||||
|
ByteBuffer out, TapPacketReader outReader) throws IOException {
|
||||||
|
receivePacketAndMaybeExpectForwarded(false, in, inReader, out, outReader);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNaForwardingFromUpstreamToTether() throws Exception {
|
public void testNaForwardingFromUpstreamToTether() throws Exception {
|
||||||
ByteBuffer na = createDadPacket(NeighborPacketForwarder.ICMPV6_NEIGHBOR_ADVERTISEMENT);
|
ByteBuffer na = createDadPacket(NeighborPacketForwarder.ICMPV6_NEIGHBOR_ADVERTISEMENT);
|
||||||
|
|
||||||
mUpstreamPacketReader.sendResponse(na);
|
ByteBuffer out = copy(na);
|
||||||
updateDstMac(na, MacAddress.fromString("33:33:00:00:00:01"));
|
updateDstMac(out, MacAddress.fromString("33:33:00:00:00:01"));
|
||||||
updateSrcMac(na, mTetheredParams);
|
updateSrcMac(out, mTetheredParams);
|
||||||
assertTrue(waitForPacket(na, mTetheredPacketReader));
|
|
||||||
|
receivePacketAndExpectForwarded(na, mUpstreamPacketReader, out, mTetheredPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -249,19 +293,21 @@ public class DadProxyTest {
|
|||||||
public void testNaForwardingFromTetherToUpstream() throws Exception {
|
public void testNaForwardingFromTetherToUpstream() throws Exception {
|
||||||
ByteBuffer na = createDadPacket(NeighborPacketForwarder.ICMPV6_NEIGHBOR_ADVERTISEMENT);
|
ByteBuffer na = createDadPacket(NeighborPacketForwarder.ICMPV6_NEIGHBOR_ADVERTISEMENT);
|
||||||
|
|
||||||
mTetheredPacketReader.sendResponse(na);
|
ByteBuffer out = copy(na);
|
||||||
updateDstMac(na, MacAddress.fromString("33:33:00:00:00:01"));
|
updateDstMac(out, MacAddress.fromString("33:33:00:00:00:01"));
|
||||||
updateSrcMac(na, mTetheredParams);
|
updateSrcMac(out, mTetheredParams);
|
||||||
assertFalse(waitForPacket(na, mUpstreamPacketReader));
|
|
||||||
|
receivePacketAndExpectNotForwarded(na, mTetheredPacketReader, out, mUpstreamPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNsForwardingFromTetherToUpstream() throws Exception {
|
public void testNsForwardingFromTetherToUpstream() throws Exception {
|
||||||
ByteBuffer ns = createDadPacket(NeighborPacketForwarder.ICMPV6_NEIGHBOR_SOLICITATION);
|
ByteBuffer ns = createDadPacket(NeighborPacketForwarder.ICMPV6_NEIGHBOR_SOLICITATION);
|
||||||
|
|
||||||
mTetheredPacketReader.sendResponse(ns);
|
ByteBuffer out = copy(ns);
|
||||||
updateSrcMac(ns, mUpstreamParams);
|
updateSrcMac(out, mUpstreamParams);
|
||||||
assertTrue(waitForPacket(ns, mUpstreamPacketReader));
|
|
||||||
|
receivePacketAndExpectForwarded(ns, mTetheredPacketReader, out, mUpstreamPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -269,8 +315,9 @@ public class DadProxyTest {
|
|||||||
public void testNsForwardingFromUpstreamToTether() throws Exception {
|
public void testNsForwardingFromUpstreamToTether() throws Exception {
|
||||||
ByteBuffer ns = createDadPacket(NeighborPacketForwarder.ICMPV6_NEIGHBOR_SOLICITATION);
|
ByteBuffer ns = createDadPacket(NeighborPacketForwarder.ICMPV6_NEIGHBOR_SOLICITATION);
|
||||||
|
|
||||||
mUpstreamPacketReader.sendResponse(ns);
|
ByteBuffer out = copy(ns);
|
||||||
updateSrcMac(ns, mUpstreamParams);
|
updateSrcMac(ns, mUpstreamParams);
|
||||||
assertFalse(waitForPacket(ns, mTetheredPacketReader));
|
|
||||||
|
receivePacketAndExpectNotForwarded(ns, mUpstreamPacketReader, out, mTetheredPacketReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user