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

Commit e6dfc173 authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

Ignore the checksum when comparing RAs for equality.

When comparing two RAs for equality, Ra#matches intentionally
ignores lifetimes. It should ignore the checksum instead, because
otherwise-identical packets with different lifetimes will almost
certainly have different checksums.

In order to avoid the generated APF program also matching the
checksum, we treat the checksum as if it were a lifetime, but
take care not to use its value when calculating mMinLifetime or
when checking the lifetimes in the APF program.

Bug: 27595799
Bug: 26238573
Change-Id: I526fdc17e99803a1ddec6275a3c542014434c429
parent 8829e6b7
Loading
Loading
Loading
Loading
+21 −1
Original line number Original line Diff line number Diff line
@@ -155,6 +155,9 @@ public class ApfFilter {


        // From RFC4861:
        // From RFC4861:
        private static final int ICMP6_RA_HEADER_LEN = 16;
        private static final int ICMP6_RA_HEADER_LEN = 16;
        private static final int ICMP6_RA_CHECKSUM_OFFSET =
                ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
        private static final int ICMP6_RA_CHECKSUM_LEN = 2;
        private static final int ICMP6_RA_OPTION_OFFSET =
        private static final int ICMP6_RA_OPTION_OFFSET =
                ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
                ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
        private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
        private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
@@ -216,9 +219,16 @@ public class ApfFilter {
            mPacket.clear();
            mPacket.clear();
            mLastSeen = curTime();
            mLastSeen = curTime();


            // Ignore the checksum.
            int lastNonLifetimeStart = addNonLifetime(0,
                    ICMP6_RA_CHECKSUM_OFFSET,
                    ICMP6_RA_CHECKSUM_LEN);

            // Parse router lifetime
            // Parse router lifetime
            int lastNonLifetimeStart = addNonLifetime(0, ICMP6_RA_ROUTER_LIFETIME_OFFSET,
            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
                    ICMP6_RA_ROUTER_LIFETIME_OFFSET,
                    ICMP6_RA_ROUTER_LIFETIME_LEN);
                    ICMP6_RA_ROUTER_LIFETIME_LEN);

            // Parse ICMP6 options
            // Parse ICMP6 options
            mPacket.position(ICMP6_RA_OPTION_OFFSET);
            mPacket.position(ICMP6_RA_OPTION_OFFSET);
            while (mPacket.hasRemaining()) {
            while (mPacket.hasRemaining()) {
@@ -282,6 +292,12 @@ public class ApfFilter {
            ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
            ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
            for (int i = 0; (i + 1) < mNonLifetimes.size(); i++) {
            for (int i = 0; (i + 1) < mNonLifetimes.size(); i++) {
                int offset = mNonLifetimes.get(i).first + mNonLifetimes.get(i).second;
                int offset = mNonLifetimes.get(i).first + mNonLifetimes.get(i).second;

                // The checksum is in mNonLifetimes, but it's not a lifetime.
                if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
                     continue;
                }

                int lifetimeLength = mNonLifetimes.get(i+1).first - offset;
                int lifetimeLength = mNonLifetimes.get(i+1).first - offset;
                long val;
                long val;
                switch (lifetimeLength) {
                switch (lifetimeLength) {
@@ -329,6 +345,10 @@ public class ApfFilter {
                if ((i + 1) < mNonLifetimes.size()) {
                if ((i + 1) < mNonLifetimes.size()) {
                    Pair<Integer, Integer> nextNonLifetime = mNonLifetimes.get(i + 1);
                    Pair<Integer, Integer> nextNonLifetime = mNonLifetimes.get(i + 1);
                    int offset = nonLifetime.first + nonLifetime.second;
                    int offset = nonLifetime.first + nonLifetime.second;
                    // Skip the checksum.
                    if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
                        continue;
                    }
                    int length = nextNonLifetime.first - offset;
                    int length = nextNonLifetime.first - offset;
                    switch (length) {
                    switch (length) {
                        case 4: gen.addLoad32(Register.R0, offset); break;
                        case 4: gen.addLoad32(Register.R0, offset); break;