Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8b8f1b4 authored by Paul Jensen's avatar Paul Jensen Committed by android-build-merger
Browse files

Merge "Don\'t drop IPv4 broadcast packets when WiFi multicast lock is held" into nyc-dev

am: 83e50327

* commit '83e50327':
  Don't drop IPv4 broadcast packets when WiFi multicast lock is held

Change-Id: Ib76e96a84820fa36357d820ef6845f6155ec902c
parents 22132cb6 83e50327
Loading
Loading
Loading
Loading
+27 −26
Original line number Diff line number Diff line
@@ -597,7 +597,8 @@ public class ApfFilter {
    private void generateIPv4FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
        // Here's a basic summary of what the IPv4 filter program does:
        //
        // if it's multicast and we're dropping multicast:
        // if filtering multicast (i.e. multicast lock not held):
        //   if it's multicast:
        //     drop
        //   if it's not broadcast:
        //     pass
@@ -610,7 +611,6 @@ public class ApfFilter {
            gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
            gen.addAnd(0xf0);
            gen.addJumpIfR0Equals(0xe0, gen.DROP_LABEL);
        }

            // Drop all broadcasts besides DHCP addressed to us
            // If not a broadcast packet, pass
@@ -631,6 +631,7 @@ public class ApfFilter {
            // NOTE: Relies on R1 containing IPv4 header offset.
            gen.addAddR1();
            gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, gen.DROP_LABEL);
        }

        // Otherwise, pass
        gen.addJump(gen.PASS_LABEL);
+32 −21
Original line number Diff line number Diff line
@@ -663,7 +663,7 @@ public class ApfTest extends AndroidTestCase {
    @LargeTest
    public void testApfFilterIPv4() throws Exception {
        MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
        ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, false /* multicastFilter */);
        ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, true /* multicastFilter */);
        byte[] program = ipManagerCallback.getApfProgram();

        // Verify empty packet of 100 zero bytes is passed
@@ -726,46 +726,57 @@ public class ApfTest extends AndroidTestCase {
        byte[] program = ipManagerCallback.getApfProgram();

        // Construct IPv4 and IPv6 multicast packets.
        ByteBuffer v4packet = ByteBuffer.wrap(new byte[100]);
        v4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
        v4packet.position(IPV4_DEST_ADDR_OFFSET);
        v4packet.put(new byte[]{(byte)224,0,0,1});

        ByteBuffer v6packet = ByteBuffer.wrap(new byte[100]);
        v6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
        v6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP);
        v6packet.position(IPV6_DEST_ADDR_OFFSET);
        v6packet.put(new byte[]{(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb});
        ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]);
        mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
        mcastv4packet.position(IPV4_DEST_ADDR_OFFSET);
        mcastv4packet.put(new byte[]{(byte)224,0,0,1});

        ByteBuffer mcastv6packet = ByteBuffer.wrap(new byte[100]);
        mcastv6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP);
        mcastv6packet.position(IPV6_DEST_ADDR_OFFSET);
        mcastv6packet.put(new byte[]{(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb});

        // Construct IPv4 broadcast packet.
        ByteBuffer bcastv4packet = ByteBuffer.wrap(new byte[100]);
        bcastv4packet.put(ETH_BROADCAST_MAC_ADDRESS);
        bcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
        bcastv4packet.position(IPV4_DEST_ADDR_OFFSET);
        bcastv4packet.put(new byte[]{(byte)192,(byte)0,(byte)2,(byte)63});

        // Verify initially disabled multicast filter is off
        assertPass(program, v4packet.array(), 0);
        assertPass(program, v6packet.array(), 0);
        assertPass(program, bcastv4packet.array(), 0);
        assertPass(program, mcastv4packet.array(), 0);
        assertPass(program, mcastv6packet.array(), 0);

        // Turn on multicast filter and verify it works
        ipManagerCallback.resetApfProgramWait();
        apfFilter.setMulticastFilter(true);
        program = ipManagerCallback.getApfProgram();
        assertDrop(program, v4packet.array(), 0);
        assertDrop(program, v6packet.array(), 0);
        assertDrop(program, bcastv4packet.array(), 0);
        assertDrop(program, mcastv4packet.array(), 0);
        assertDrop(program, mcastv6packet.array(), 0);

        // Turn off multicast filter and verify it's off
        ipManagerCallback.resetApfProgramWait();
        apfFilter.setMulticastFilter(false);
        program = ipManagerCallback.getApfProgram();
        assertPass(program, v4packet.array(), 0);
        assertPass(program, v6packet.array(), 0);
        assertPass(program, bcastv4packet.array(), 0);
        assertPass(program, mcastv4packet.array(), 0);
        assertPass(program, mcastv6packet.array(), 0);

        // Verify it can be initialized to on
        ipManagerCallback.resetApfProgramWait();
        apfFilter.shutdown();
        apfFilter = new TestApfFilter(ipManagerCallback, true /* multicastFilter */);
        program = ipManagerCallback.getApfProgram();
        assertDrop(program, v4packet.array(), 0);
        assertDrop(program, v6packet.array(), 0);
        assertDrop(program, bcastv4packet.array(), 0);
        assertDrop(program, mcastv4packet.array(), 0);
        assertDrop(program, mcastv6packet.array(), 0);

        // Verify that ICMPv6 multicast is not dropped.
        v6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
        assertPass(program, v6packet.array(), 0);
        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
        assertPass(program, mcastv6packet.array(), 0);

        apfFilter.shutdown();
    }