diff options
| -rw-r--r-- | services/net/java/android/net/apf/ApfFilter.java | 24 | ||||
| -rw-r--r-- | tests/net/java/android/net/apf/ApfTest.java | 13 |
2 files changed, 35 insertions, 2 deletions
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java index 985a12c13c19..71201ce8650a 100644 --- a/services/net/java/android/net/apf/ApfFilter.java +++ b/services/net/java/android/net/apf/ApfFilter.java @@ -193,6 +193,11 @@ public class ApfFilter { private static final int IPV4_ANY_HOST_ADDRESS = 0; private static final int IPV4_BROADCAST_ADDRESS = -1; // 255.255.255.255 + // Traffic class and Flow label are not byte aligned. Luckily we + // don't care about either value so we'll consider bytes 1-3 of the + // IPv6 header as don't care. + private static final int IPV6_FLOW_LABEL_OFFSET = ETH_HEADER_LEN + 1; + private static final int IPV6_FLOW_LABEL_LEN = 3; private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6; private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8; private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24; @@ -472,8 +477,13 @@ public class ApfFilter { RaEvent.Builder builder = new RaEvent.Builder(); - // Ignore the checksum. + // Ignore the flow label and low 4 bits of traffic class. int lastNonLifetimeStart = addNonLifetime(0, + IPV6_FLOW_LABEL_OFFSET, + IPV6_FLOW_LABEL_LEN); + + // Ignore the checksum. + lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart, ICMP6_RA_CHECKSUM_OFFSET, ICMP6_RA_CHECKSUM_LEN); @@ -564,9 +574,14 @@ public class ApfFilter { for (int i = 0; (i + 1) < mNonLifetimes.size(); i++) { int offset = mNonLifetimes.get(i).first + mNonLifetimes.get(i).second; + // The flow label is in mNonLifetimes, but it's not a lifetime. + if (offset == IPV6_FLOW_LABEL_OFFSET) { + continue; + } + // The checksum is in mNonLifetimes, but it's not a lifetime. if (offset == ICMP6_RA_CHECKSUM_OFFSET) { - continue; + continue; } final int lifetimeLength = mNonLifetimes.get(i+1).first - offset; @@ -628,6 +643,11 @@ public class ApfFilter { if ((i + 1) < mNonLifetimes.size()) { Pair<Integer, Integer> nextNonLifetime = mNonLifetimes.get(i + 1); int offset = nonLifetime.first + nonLifetime.second; + + // Skip the Flow label. + if (offset == IPV6_FLOW_LABEL_OFFSET) { + continue; + } // Skip the checksum. if (offset == ICMP6_RA_CHECKSUM_OFFSET) { continue; diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java index d4896264cae8..6bf3b6bc8441 100644 --- a/tests/net/java/android/net/apf/ApfTest.java +++ b/tests/net/java/android/net/apf/ApfTest.java @@ -1066,10 +1066,15 @@ public class ApfTest extends AndroidTestCase { final int ROUTE_LIFETIME = 400; // Note that lifetime of 2000 will be ignored in favor of shorter route lifetime of 1000. final int DNSSL_LIFETIME = 2000; + 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; // 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); @@ -1080,6 +1085,13 @@ public class ApfTest extends AndroidTestCase { testRaLifetime(apfFilter, ipManagerCallback, basePacket, ROUTER_LIFETIME); verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1)); + ByteBuffer newFlowLabelPacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]); + basePacket.clear(); + newFlowLabelPacket.put(basePacket); + // Check that changes are ignored in every byte of the flow label. + newFlowLabelPacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET, + VERSION_TRAFFIC_CLASS_FLOW_LABEL + 0x11111); + // Ensure zero-length options cause the packet to be silently skipped. // Do this before we test other packets. http://b/29586253 ByteBuffer zeroLengthOptionPacket = ByteBuffer.wrap( @@ -1145,6 +1157,7 @@ public class ApfTest extends AndroidTestCase { // Verify that current program filters all five RAs: program = ipManagerCallback.getApfProgram(); verifyRaLifetime(program, basePacket, ROUTER_LIFETIME); + verifyRaLifetime(program, newFlowLabelPacket, ROUTER_LIFETIME); verifyRaLifetime(program, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME); verifyRaLifetime(program, rdnssOptionPacket, RDNSS_LIFETIME); verifyRaLifetime(program, routeInfoOptionPacket, ROUTE_LIFETIME); |