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

Commit f0f82dff authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by android-build-merger
Browse files

Merge "Fix RAs with different retansmission timer would be dropped by apf" am: dfc4f7c2

am: 7436ed4b

Change-Id: I47c88b94af5502b9b84ee8c9bca792dee3cd90a5
parents e8d4d842 7436ed4b
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -514,9 +514,9 @@ public class ApfFilter {
        public final Type type;
        /** Offset into the packet at which this section begins. */
        public final int start;
        /** Length of this section. */
        /** Length of this section in bytes. */
        public final int length;
        /** If this is a lifetime, the ICMP option that the defined it. 0 for router lifetime. */
        /** If this is a lifetime, the ICMP option that defined it. 0 for router lifetime. */
        public final int option;
        /** If this is a lifetime, the lifetime value. */
        public final long lifetime;
@@ -785,8 +785,9 @@ public class ApfFilter {
            addLifetimeSection(ICMP6_RA_ROUTER_LIFETIME_LEN, 0, routerLifetime);
            builder.updateRouterLifetime(routerLifetime);

            // Ensures that the RA is not truncated.
            mPacket.position(ICMP6_RA_OPTION_OFFSET);
            // Add remaining fields (reachable time and retransmission timer) to match section.
            addMatchUntil(ICMP6_RA_OPTION_OFFSET);

            while (mPacket.hasRemaining()) {
                final int position = mPacket.position();
                final int optionType = getUint8(mPacket, position);
@@ -797,7 +798,7 @@ public class ApfFilter {
                        mPrefixOptionOffsets.add(position);

                        // Parse valid lifetime
                        addMatchSection(ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN);
                        addMatchSection(ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET);
                        lifetime = getUint32(mPacket, mPacket.position());
                        addLifetimeSection(ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN,
                                ICMP6_PREFIX_OPTION_TYPE, lifetime);
+76 −11
Original line number Diff line number Diff line
@@ -1056,10 +1056,14 @@ public class ApfTest {
    private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;

    private static final int ICMP6_RA_HEADER_LEN = 16;
    private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
            IP_HEADER_OFFSET + IPV6_HEADER_LEN + 6;
    private static final int ICMP6_RA_CHECKSUM_OFFSET =
            IP_HEADER_OFFSET + IPV6_HEADER_LEN + 2;
    private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
            IP_HEADER_OFFSET + IPV6_HEADER_LEN + 6;
    private static final int ICMP6_RA_REACHABLE_TIME_OFFSET =
            IP_HEADER_OFFSET + IPV6_HEADER_LEN + 8;
    private static final int ICMP6_RA_RETRANSMISSION_TIMER_OFFSET =
            IP_HEADER_OFFSET + IPV6_HEADER_LEN + 12;
    private static final int ICMP6_RA_OPTION_OFFSET =
            IP_HEADER_OFFSET + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;

@@ -2000,6 +2004,25 @@ public class ApfTest {
        ipClientCallback.assertNoProgramUpdate();
    }

    private ByteBuffer makeBaseRaPacket() {
        ByteBuffer basePacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
        final int ROUTER_LIFETIME = 1000;
        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET = ETH_HEADER_LEN;
        // IPv6, traffic class = 0, flow label = 0x12345
        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL = 0x60012345;

        basePacket.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IPV6);
        basePacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
                VERSION_TRAFFIC_CLASS_FLOW_LABEL);
        basePacket.put(IPV6_NEXT_HEADER_OFFSET, (byte) IPPROTO_ICMPV6);
        basePacket.put(ICMP6_TYPE_OFFSET, (byte) ICMP6_ROUTER_ADVERTISEMENT);
        basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short) ROUTER_LIFETIME);
        basePacket.position(IPV6_DEST_ADDR_OFFSET);
        basePacket.put(IPV6_ALL_NODES_ADDRESS);

        return basePacket;
    }

    @Test
    public void testApfFilterRa() throws Exception {
        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
@@ -2021,15 +2044,7 @@ public class ApfTest {
        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL = 0x60012345;

        // Verify RA is passed the first time
        ByteBuffer basePacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
        basePacket.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
        basePacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
                VERSION_TRAFFIC_CLASS_FLOW_LABEL);
        basePacket.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
        basePacket.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_ADVERTISEMENT);
        basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)ROUTER_LIFETIME);
        basePacket.position(IPV6_DEST_ADDR_OFFSET);
        basePacket.put(IPV6_ALL_NODES_ADDRESS);
        ByteBuffer basePacket = makeBaseRaPacket();
        assertPass(program, basePacket.array());

        verifyRaLifetime(apfFilter, ipClientCallback, basePacket, ROUTER_LIFETIME);
@@ -2083,6 +2098,16 @@ public class ApfTest {
        verifyRaLifetime(apfFilter, ipClientCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1));

        // Check that RIOs differing only in the first 4 bytes are different.
        ByteBuffer similarRouteInfoOptionPacket = ByteBuffer.wrap(
                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN + IPV6_ADDR_LEN]);
        basePacket.clear();
        similarRouteInfoOptionPacket.put(basePacket);
        addRioOption(similarRouteInfoOptionPacket, ROUTE_LIFETIME, "64:ff9b::/64");
        // Packet should be passed because it is different.
        program = ipClientCallback.getApfProgram();
        assertPass(program, similarRouteInfoOptionPacket.array());

        ByteBuffer dnsslOptionPacket = ByteBuffer.wrap(
                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
        basePacket.clear();
@@ -2111,6 +2136,46 @@ public class ApfTest {
        apfFilter.shutdown();
    }

    @Test
    public void testRaWithDifferentReachableTimeAndRetransTimer() throws Exception {
        final MockIpClientCallback ipClientCallback = new MockIpClientCallback();
        final ApfConfiguration config = getDefaultConfig();
        config.multicastFilter = DROP_MULTICAST;
        config.ieee802_3Filter = DROP_802_3_FRAMES;
        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
        byte[] program = ipClientCallback.getApfProgram();
        final int RA_REACHABLE_TIME = 1800;
        final int RA_RETRANSMISSION_TIMER = 1234;

        // Create an Ra packet without options
        // Reachable time = 1800, retransmission timer = 1234
        ByteBuffer raPacket = makeBaseRaPacket();
        raPacket.position(ICMP6_RA_REACHABLE_TIME_OFFSET);
        raPacket.putInt(RA_REACHABLE_TIME);
        raPacket.putInt(RA_RETRANSMISSION_TIMER);
        // First RA passes filter
        assertPass(program, raPacket.array());

        // Assume apf is shown the given RA, it generates program to filter it.
        ipClientCallback.resetApfProgramWait();
        apfFilter.pretendPacketReceived(raPacket.array());
        program = ipClientCallback.getApfProgram();
        assertDrop(program, raPacket.array());

        // A packet with different reachable time should be passed.
        // Reachable time = 2300, retransmission timer = 1234
        raPacket.clear();
        raPacket.putInt(ICMP6_RA_REACHABLE_TIME_OFFSET, RA_REACHABLE_TIME + 500);
        assertPass(program, raPacket.array());

        // A packet with different retransmission timer should be passed.
        // Reachable time = 1800, retransmission timer = 2234
        raPacket.clear();
        raPacket.putInt(ICMP6_RA_REACHABLE_TIME_OFFSET, RA_REACHABLE_TIME);
        raPacket.putInt(ICMP6_RA_RETRANSMISSION_TIMER_OFFSET, RA_RETRANSMISSION_TIMER + 1000);
        assertPass(program, raPacket.array());
    }

    /**
     * Stage a file for testing, i.e. make it native accessible. Given a resource ID,
     * copy that resource into the app's data directory and return the path to it.