Snap for 11401239 from 1b16a52be12524bc9c325b16be4b530076625585 to mainline-media-release Change-Id: I5502f9531cdfefb864c3a62bcd3c72bf9e654b54
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java index 9a3d58b..cfd54bc 100644 --- a/src/android/net/apf/ApfFilter.java +++ b/src/android/net/apf/ApfFilter.java
@@ -16,6 +16,8 @@ package android.net.apf; +import static android.net.apf.ApfV4Generator.Register.R0; +import static android.net.apf.ApfV4Generator.Register.R1; import static android.net.util.SocketUtils.makePacketSocketAddress; import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED; import static android.os.PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED; @@ -47,7 +49,6 @@ import android.net.TcpKeepalivePacketDataParcelable; import android.net.apf.ApfCounterTracker.Counter; import android.net.apf.ApfV4Generator.IllegalInstructionException; -import android.net.apf.ApfV4Generator.Register; import android.net.ip.IpClient.IpClientCallbacksWrapper; import android.os.PowerManager; import android.os.SystemClock; @@ -141,7 +142,7 @@ */ private void maybeSetupCounter(ApfV4Generator gen, Counter c) { if (mApfCapabilities.hasDataAccess()) { - gen.addLoadImmediate(Register.R1, c.offset()); + gen.addLoadImmediate(R1, c.offset()); } } @@ -1138,15 +1139,15 @@ throws IllegalInstructionException { String nextFilterLabel = "Ra" + getUniqueNumberLocked(); // Skip if packet is not the right size - gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R0, gen.PACKET_SIZE_MEMORY_SLOT); gen.addJumpIfR0NotEquals(mPacket.capacity(), nextFilterLabel); // Skip filter if expired - gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT); + gen.addLoadFromMemory(R0, gen.FILTER_AGE_MEMORY_SLOT); gen.addJumpIfR0GreaterThan(getRemainingFilterLft(timeSeconds), nextFilterLabel); for (PacketSection section : mPacketSections) { // Generate code to match the packet bytes. if (section.type == PacketSection.Type.MATCH) { - gen.addLoadImmediate(Register.R0, section.start); + gen.addLoadImmediate(R0, section.start); gen.addJumpIfBytesAtR0NotEqual( Arrays.copyOfRange(mPacket.array(), section.start, section.start + section.length), @@ -1154,8 +1155,8 @@ } else { switch (section.length) { // length asserted to be either 2 or 4 on PacketSection construction - case 2: gen.addLoad16(Register.R0, section.start); break; - case 4: gen.addLoad32(Register.R0, section.start); break; + case 2: gen.addLoad16(R0, section.start); break; + case 4: gen.addLoad32(R0, section.start); break; } // WARNING: keep this in sync with matches()! @@ -1282,21 +1283,21 @@ void generateFilterLocked(ApfV4Generator gen) throws IllegalInstructionException { final String nextFilterLabel = "natt_keepalive_filter" + getUniqueNumberLocked(); - gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(mSrcDstAddr, nextFilterLabel); // A NAT-T keepalive packet contains 1 byte payload with the value 0xff // Check payload length is 1 - gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); gen.addAdd(UDP_HEADER_LEN); gen.addSwap(); - gen.addLoad16(Register.R0, IPV4_TOTAL_LENGTH_OFFSET); - gen.addNeg(Register.R1); + gen.addLoad16(R0, IPV4_TOTAL_LENGTH_OFFSET); + gen.addNeg(R1); gen.addAddR1(); gen.addJumpIfR0NotEquals(1, nextFilterLabel); // Check that the ports match - gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); gen.addAdd(ETH_HEADER_LEN); gen.addJumpIfBytesAtR0NotEqual(mPortFingerprint, nextFilterLabel); @@ -1398,28 +1399,28 @@ void generateFilterLocked(ApfV4Generator gen) throws IllegalInstructionException { final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked(); - gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(mSrcDstAddr, nextFilterLabel); // Skip to the next filter if it's not zero-sized : // TCP_HEADER_SIZE + IPV4_HEADER_SIZE - ipv4_total_length == 0 // Load the IP header size into R1 - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); // Load the TCP header size into R0 (it's indexed by R1) - gen.addLoad8Indexed(Register.R0, ETH_HEADER_LEN + TCP_HEADER_SIZE_OFFSET); + gen.addLoad8Indexed(R0, ETH_HEADER_LEN + TCP_HEADER_SIZE_OFFSET); // Size offset is in the top nibble, but it must be multiplied by 4, and the two // top bits of the low nibble are guaranteed to be zeroes. Right-shift R0 by 2. gen.addRightShift(2); // R0 += R1 -> R0 contains TCP + IP headers length gen.addAddR1(); // Load IPv4 total length - gen.addLoad16(Register.R1, IPV4_TOTAL_LENGTH_OFFSET); - gen.addNeg(Register.R0); + gen.addLoad16(R1, IPV4_TOTAL_LENGTH_OFFSET); + gen.addNeg(R0); gen.addAddR1(); gen.addJumpIfR0NotEquals(0, nextFilterLabel); // Add IPv4 header length - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); - gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadImmediate(R0, ETH_HEADER_LEN); gen.addAddR1(); gen.addJumpIfBytesAtR0NotEqual(mPortSeqAckFingerprint, nextFilterLabel); @@ -1521,23 +1522,23 @@ final String checkTargetIPv4 = "checkTargetIPv4"; // Drop if not ARP IPv4. - gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET); + gen.addLoadImmediate(R0, ARP_HEADER_OFFSET); maybeSetupCounter(gen, Counter.DROPPED_ARP_NON_IPV4); gen.addJumpIfBytesAtR0NotEqual(ARP_IPV4_HEADER, mCountAndDropLabel); // Drop if unknown ARP opcode. - gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET); + gen.addLoad16(R0, ARP_OPCODE_OFFSET); gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check maybeSetupCounter(gen, Counter.DROPPED_ARP_UNKNOWN); gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndDropLabel); // Drop if ARP reply source IP is 0.0.0.0 - gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET); + gen.addLoad32(R0, ARP_SOURCE_IP_ADDRESS_OFFSET); maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST); gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel); // Pass if non-broadcast reply. - gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_DEST_ADDR_OFFSET); maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY); gen.addJumpIfBytesAtR0NotEqual(ETHER_BROADCAST, mCountAndPassLabel); @@ -1545,13 +1546,13 @@ gen.defineLabel(checkTargetIPv4); if (mIPv4Address == null) { // When there is no IPv4 address, drop GARP replies (b/29404209). - gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET); + gen.addLoad32(R0, ARP_TARGET_IP_ADDRESS_OFFSET); maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY); gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel); } else { // When there is an IPv4 address, drop unicast/broadcast requests // and broadcast replies with a different target IPv4 address. - gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET); + gen.addLoadImmediate(R0, ARP_TARGET_IP_ADDRESS_OFFSET); maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST); gen.addJumpIfBytesAtR0NotEqual(mIPv4Address, mCountAndDropLabel); } @@ -1588,17 +1589,17 @@ // Pass DHCP addressed to us. // Check it's UDP. - gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET); + gen.addLoad8(R0, IPV4_PROTOCOL_OFFSET); gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipDhcpv4Filter); // Check it's not a fragment or is the initial fragment. - gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET); + gen.addLoad16(R0, IPV4_FRAGMENT_OFFSET_OFFSET); gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_OFFSET_MASK, skipDhcpv4Filter); // Check it's addressed to DHCP client port. - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); - gen.addLoad16Indexed(Register.R0, TCP_UDP_DESTINATION_PORT_OFFSET); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoad16Indexed(R0, TCP_UDP_DESTINATION_PORT_OFFSET); gen.addJumpIfR0NotEquals(DHCP_CLIENT_PORT, skipDhcpv4Filter); // Check it's DHCP to our MAC address. - gen.addLoadImmediate(Register.R0, DHCP_CLIENT_MAC_OFFSET); + gen.addLoadImmediate(R0, DHCP_CLIENT_MAC_OFFSET); // NOTE: Relies on R1 containing IPv4 header offset. gen.addAddR1(); gen.addJumpIfBytesAtR0NotEqual(mHardwareAddress, skipDhcpv4Filter); @@ -1609,14 +1610,14 @@ gen.defineLabel(skipDhcpv4Filter); // If IPv4 destination address is in multicast range, drop. - gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET); + gen.addLoad8(R0, IPV4_DEST_ADDR_OFFSET); gen.addAnd(0xf0); maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST); gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel); // If IPv4 broadcast packet, drop regardless of L2 (b/30231088). maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR); - gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET); + gen.addLoad32(R0, IPV4_DEST_ADDR_OFFSET); gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel); if (mIPv4Address != null && mIPv4PrefixLength < 31) { maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET); @@ -1639,7 +1640,7 @@ // If L2 broadcast packet, drop. // TODO: can we invert this condition to fall through to the common pass case below? maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST); - gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_DEST_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(ETHER_BROADCAST, mCountAndPassLabel); maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST); gen.addJump(mCountAndDropLabel); @@ -1660,7 +1661,7 @@ if (!haveKeepaliveResponses) return; // If not the right proto, skip keepalive filters - gen.addLoad8(Register.R0, offset); + gen.addLoad8(R0, offset); gen.addJumpIfR0NotEquals(proto, label); // Drop Keepalive responses @@ -1709,7 +1710,7 @@ // if keepalive ack // drop - gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET); + gen.addLoad8(R0, IPV6_NEXT_HEADER_OFFSET); // MLD packets set the router-alert hop-by-hop option. // TODO: be smarter about not blindly passing every packet with HBH options. @@ -1728,7 +1729,7 @@ // ICMPv6 but not ECHO? -> Skip the multicast filter. // (ICMPv6 ECHO requests will go through the multicast filter below). - gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET); + gen.addLoad8(R0, ICMP6_TYPE_OFFSET); gen.addJumpIfR0NotEquals(ICMPV6_ECHO_REQUEST_TYPE, skipIPv6MulticastFilterLabel); } else { gen.addJumpIfR0Equals(IPPROTO_ICMPV6, skipIPv6MulticastFilterLabel); @@ -1737,7 +1738,7 @@ // Drop all other packets sent to ff00::/8 (multicast prefix). gen.defineLabel(dropAllIPv6MulticastsLabel); maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST); - gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET); + gen.addLoad8(R0, IPV6_DEST_ADDR_OFFSET); gen.addJumpIfR0Equals(0xff, mCountAndDropLabel); // If any keepalive filter matches, drop generateV6KeepaliveFilters(gen); @@ -1756,7 +1757,7 @@ // Add unsolicited multicast neighbor announcements filter String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA"; - gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET); + gen.addLoad8(R0, ICMP6_TYPE_OFFSET); // Drop all router solicitations (b/32833400) maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION); gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel); @@ -1766,7 +1767,7 @@ // This is a way to cover ff02::1 and ff02::2 with a single JNEBS. // TODO: Drop only if they don't contain the address of on-link neighbours. final byte[] unsolicitedNaDropPrefix = Arrays.copyOf(IPV6_ALL_NODES_ADDRESS, 15); - gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, IPV6_DEST_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(unsolicitedNaDropPrefix, skipUnsolicitedMulticastNALabel); maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA); @@ -1823,24 +1824,24 @@ // 3. it is a UDP packet with port 5353 // Check it's L2 mDNS multicast address. - gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_DEST_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(ETH_MULTICAST_MDNS_V4_MAC_ADDRESS, skipMdnsv4Filter); // Checks it's IPv4. - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + gen.addLoad16(R0, ETH_ETHERTYPE_OFFSET); gen.addJumpIfR0NotEquals(ETH_P_IP, skipMdnsFilter); // Check it's not a fragment. - gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET); + gen.addLoad16(R0, IPV4_FRAGMENT_OFFSET_OFFSET); gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_MORE_FRAGS_MASK | IPV4_FRAGMENT_OFFSET_MASK, skipMdnsFilter); // Checks it's UDP. - gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET); + gen.addLoad8(R0, IPV4_PROTOCOL_OFFSET); gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipMdnsFilter); // Set R1 to IPv4 header. - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); gen.addJump(checkMdnsUdpPort); gen.defineLabel(skipMdnsv4Filter); @@ -1850,28 +1851,28 @@ gen.addJumpIfBytesAtR0NotEqual(ETH_MULTICAST_MDNS_V6_MAC_ADDRESS, skipMdnsFilter); // Checks it's IPv6. - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + gen.addLoad16(R0, ETH_ETHERTYPE_OFFSET); gen.addJumpIfR0NotEquals(ETH_P_IPV6, skipMdnsFilter); // Checks it's UDP. - gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET); + gen.addLoad8(R0, IPV6_NEXT_HEADER_OFFSET); gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipMdnsFilter); // Set R1 to IPv6 header. - gen.addLoadImmediate(Register.R1, IPV6_HEADER_LEN); + gen.addLoadImmediate(R1, IPV6_HEADER_LEN); // Checks it's mDNS UDP port gen.defineLabel(checkMdnsUdpPort); - gen.addLoad16Indexed(Register.R0, TCP_UDP_DESTINATION_PORT_OFFSET); + gen.addLoad16Indexed(R0, TCP_UDP_DESTINATION_PORT_OFFSET); gen.addJumpIfR0NotEquals(MDNS_PORT, skipMdnsFilter); - gen.addLoad16Indexed(Register.R0, MDNS_QDCOUNT_OFFSET); + gen.addLoad16Indexed(R0, MDNS_QDCOUNT_OFFSET); // If QDCOUNT != 1, pass the packet gen.addJumpIfR0NotEquals(1, mDnsAcceptPacket); // If QDCOUNT == 1, matches the QNAME with allowlist. // Load offset for the first QNAME. - gen.addLoadImmediate(Register.R0, MDNS_QNAME_OFFSET); + gen.addLoadImmediate(R0, MDNS_QNAME_OFFSET); gen.addAddR1(); // Check first QNAME against allowlist @@ -1909,16 +1910,16 @@ final String skipPort7V4Filter = "skip_port7_v4_filter"; // Check it's TCP. - gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET); + gen.addLoad8(R0, IPV4_PROTOCOL_OFFSET); gen.addJumpIfR0NotEquals(IPPROTO_TCP, skipPort7V4Filter); // Check it's not a fragment or is the initial fragment. - gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET); + gen.addLoad16(R0, IPV4_FRAGMENT_OFFSET_OFFSET); gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_OFFSET_MASK, skipPort7V4Filter); // Check it's destination port 7. - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); - gen.addLoad16Indexed(Register.R0, TCP_UDP_DESTINATION_PORT_OFFSET); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoad16Indexed(R0, TCP_UDP_DESTINATION_PORT_OFFSET); gen.addJumpIfR0NotEquals(ECHO_PORT, skipPort7V4Filter); // Drop it. @@ -1964,9 +1965,9 @@ if (mApfCapabilities.hasDataAccess()) { // Increment TOTAL_PACKETS maybeSetupCounter(gen, Counter.TOTAL_PACKETS); - gen.addLoadData(Register.R0, 0); // load counter + gen.addLoadData(R0, 0); // load counter gen.addAdd(1); - gen.addStoreData(Register.R0, 0); // write-back counter + gen.addStoreData(R0, 0); // write-back counter } // Here's a basic summary of what the initial program does: @@ -1985,7 +1986,7 @@ // pass // insert IPv6 filter to drop, pass, or fall off the end for ICMPv6 packets - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + gen.addLoad16(R0, ETH_ETHERTYPE_OFFSET); if (mDrop802_3Frames) { // drop 802.3 frames (ethtype < 0x0600) @@ -2007,7 +2008,7 @@ // Add mDNS filter: generateMdnsFilterLocked(gen); - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + gen.addLoad16(R0, ETH_ETHERTYPE_OFFSET); // Add IPv4 filters: String skipIPv4FiltersLabel = "skipIPv4Filters"; @@ -2023,7 +2024,7 @@ gen.addJumpIfR0Equals(ETH_P_IPV6, ipv6FilterLabel); // Drop non-IP non-ARP broadcasts, pass the rest - gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_DEST_ADDR_OFFSET); maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST); gen.addJumpIfBytesAtR0NotEqual(ETHER_BROADCAST, mCountAndPassLabel); maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST); @@ -2055,16 +2056,16 @@ // pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting // the entire sequence inline for every counter. gen.defineLabel(mCountAndPassLabel); - gen.addLoadData(Register.R0, 0); // R0 = *(R1 + 0) + gen.addLoadData(R0, 0); // R0 = *(R1 + 0) gen.addAdd(1); // R0++ - gen.addStoreData(Register.R0, 0); // *(R1 + 0) = R0 + gen.addStoreData(R0, 0); // *(R1 + 0) = R0 gen.addJump(gen.PASS_LABEL); // Same as above for the count & drop trampoline. gen.defineLabel(mCountAndDropLabel); - gen.addLoadData(Register.R0, 0); // R0 = *(R1 + 0) + gen.addLoadData(R0, 0); // R0 = *(R1 + 0) gen.addAdd(1); // R0++ - gen.addStoreData(Register.R0, 0); // *(R1 + 0) = R0 + gen.addStoreData(R0, 0); // *(R1 + 0) = R0 gen.addJump(gen.DROP_LABEL); }
diff --git a/src/android/net/apf/ApfV4Generator.java b/src/android/net/apf/ApfV4Generator.java index bc48bef..3330c36 100644 --- a/src/android/net/apf/ApfV4Generator.java +++ b/src/android/net/apf/ApfV4Generator.java
@@ -16,6 +16,8 @@ package android.net.apf; +import static android.net.apf.ApfV4Generator.Rbit.Rbit0; +import static android.net.apf.ApfV4Generator.Rbit.Rbit1; import static android.net.apf.ApfV4Generator.Register.R0; import static android.net.apf.ApfV4Generator.Register.R1; @@ -161,12 +163,17 @@ } } public enum Register { - R0(0), - R1(1); + R0, + R1; + } + + public enum Rbit { + Rbit0(0), + Rbit1(1); final int value; - private Register(int value) { + Rbit(int value) { this.value = value; } } @@ -296,7 +303,7 @@ class Instruction { private final byte mOpcode; // A "Opcode" value. - private final byte mRegister; // A "Register" value. + private final Rbit mRbit; // A "Rbit" value. public final List<IntImmediate> mIntImms = new ArrayList<>(); // When mOpcode is a jump: private int mTargetLabelSize; @@ -308,9 +315,18 @@ // Offset in bytes from the beginning of this program. Set by {@link ApfGenerator#generate}. int offset; - Instruction(Opcodes opcode, Register register) { + Instruction(Opcodes opcode, Rbit rbit) { mOpcode = (byte) opcode.value; - mRegister = (byte) register.value; + mRbit = rbit; + } + + Instruction(Opcodes opcode, Register register) { + this(opcode, register == R0 ? Rbit0 : Rbit1); + } + + Instruction(ExtendedOpcodes extendedOpcodes, Rbit rbit) { + this(Opcodes.EXT, rbit); + addUnsigned(extendedOpcodes.value); } Instruction(ExtendedOpcodes extendedOpcodes, Register register) { @@ -482,7 +498,7 @@ */ private byte generateInstructionByte() { int sizeField = generateImmSizeField(); - return (byte)((mOpcode << 3) | (sizeField << 1) | mRegister); + return (byte) ((mOpcode << 3) | (sizeField << 1) | (byte) mRbit.value); } /** @@ -999,8 +1015,8 @@ * Add an instruction to the end of the program to let the program immediately return PASS. */ public ApfV4Generator addPass() { - // PASS requires using R0 because it shares opcode with DROP - return append(new Instruction(Opcodes.PASSDROP)); + // PASS requires using Rbit0 because it shares opcode with DROP + return append(new Instruction(Opcodes.PASSDROP, Rbit0)); } static void checkRange(@NonNull String variableName, long value, long lowerBound,
diff --git a/src/android/net/apf/ApfV6Generator.java b/src/android/net/apf/ApfV6Generator.java index ff6bb4d..808c697 100644 --- a/src/android/net/apf/ApfV6Generator.java +++ b/src/android/net/apf/ApfV6Generator.java
@@ -15,8 +15,8 @@ */ package android.net.apf; -import static android.net.apf.ApfV4Generator.Register.R0; -import static android.net.apf.ApfV4Generator.Register.R1; +import static android.net.apf.ApfV4Generator.Rbit.Rbit0; +import static android.net.apf.ApfV4Generator.Rbit.Rbit1; import androidx.annotation.NonNull; @@ -46,16 +46,16 @@ public ApfV4Generator addCountAndPass(int cnt) { checkRange("CounterNumber", cnt /* value */, 1 /* lowerBound */, 1000 /* upperBound */); - // PASS requires using R0 because it shares opcode with DROP - return append(new Instruction(Opcodes.PASSDROP).addUnsigned(cnt)); + // PASS requires using Rbit0 because it shares opcode with DROP + return append(new Instruction(Opcodes.PASSDROP, Rbit0).addUnsigned(cnt)); } /** * Add an instruction to the end of the program to let the program immediately return DROP. */ public ApfV4Generator addDrop() { - // DROP requires using R1 because it shares opcode with PASS - return append(new Instruction(Opcodes.PASSDROP, R1)); + // DROP requires using Rbit1 because it shares opcode with PASS + return append(new Instruction(Opcodes.PASSDROP, Rbit1)); } /** @@ -65,8 +65,8 @@ public ApfV4Generator addCountAndDrop(int cnt) { checkRange("CounterNumber", cnt /* value */, 1 /* lowerBound */, 1000 /* upperBound */); - // DROP requires using R1 because it shares opcode with PASS - return append(new Instruction(Opcodes.PASSDROP, R1).addUnsigned(cnt)); + // DROP requires using Rbit1 because it shares opcode with PASS + return append(new Instruction(Opcodes.PASSDROP, Rbit1).addUnsigned(cnt)); } /** @@ -83,8 +83,8 @@ * @param size the buffer length to be allocated. */ public ApfV4Generator addAllocate(int size) { - // R1 means the extra be16 immediate is present - return append(new Instruction(ExtendedOpcodes.ALLOCATE, R1).addU16(size)); + // Rbit1 means the extra be16 immediate is present + return append(new Instruction(ExtendedOpcodes.ALLOCATE, Rbit1).addU16(size)); } /** @@ -95,23 +95,24 @@ if (!mInstructions.isEmpty()) { throw new IllegalInstructionException("data instruction has to come first"); } - return append(new Instruction(Opcodes.JMP, R1).addUnsigned(data.length).setBytesImm(data)); + return append(new Instruction(Opcodes.JMP, Rbit1).addUnsigned(data.length) + .setBytesImm(data)); } /** * Add an instruction to the end of the program to transmit the allocated buffer. */ public ApfV4Generator addTransmit() { - // TRANSMIT requires using R0 because it shares opcode with DISCARD - return append(new Instruction(ExtendedOpcodes.TRANSMITDISCARD)); + // TRANSMIT requires using Rbit0 because it shares opcode with DISCARD + return append(new Instruction(ExtendedOpcodes.TRANSMITDISCARD, Rbit0)); } /** * Add an instruction to the end of the program to discard the allocated buffer. */ public ApfV4Generator addDiscard() { - // DISCARD requires using R1 because it shares opcode with TRANSMIT - return append(new Instruction(ExtendedOpcodes.TRANSMITDISCARD, R1)); + // DISCARD requires using Rbit1 because it shares opcode with TRANSMIT + return append(new Instruction(ExtendedOpcodes.TRANSMITDISCARD, Rbit1)); } /** @@ -169,7 +170,7 @@ * @return the ApfGenerator object */ public ApfV4Generator addDataCopy(int src, int len) { - return append(new Instruction(Opcodes.PKTDATACOPY, R1).addUnsigned(src).addU8(len)); + return append(new Instruction(Opcodes.PKTDATACOPY, Rbit1).addUnsigned(src).addU8(len)); } /** @@ -182,7 +183,7 @@ * @return the ApfGenerator object */ public ApfV4Generator addPacketCopy(int src, int len) { - return append(new Instruction(Opcodes.PKTDATACOPY, R0).addUnsigned(src).addU8(len)); + return append(new Instruction(Opcodes.PKTDATACOPY, Rbit0).addUnsigned(src).addU8(len)); } /** @@ -194,7 +195,7 @@ * @return the ApfGenerator object */ public ApfV4Generator addDataCopyFromR0(int len) { - return append(new Instruction(ExtendedOpcodes.EDATACOPY).addU8(len)); + return append(new Instruction(ExtendedOpcodes.EDATACOPY, Rbit0).addU8(len)); } /** @@ -206,7 +207,7 @@ * @return the ApfGenerator object */ public ApfV4Generator addPacketCopyFromR0(int len) { - return append(new Instruction(ExtendedOpcodes.EPKTCOPY).addU8(len)); + return append(new Instruction(ExtendedOpcodes.EPKTCOPY, Rbit0).addU8(len)); } /** @@ -218,7 +219,7 @@ * @return the ApfGenerator object */ public ApfV4Generator addDataCopyFromR0LenR1() { - return append(new Instruction(ExtendedOpcodes.EDATACOPY, R1)); + return append(new Instruction(ExtendedOpcodes.EDATACOPY, Rbit1)); } /** @@ -230,7 +231,7 @@ * @return the ApfGenerator object */ public ApfV4Generator addPacketCopyFromR0LenR1() { - return append(new Instruction(ExtendedOpcodes.EPKTCOPY, R1)); + return append(new Instruction(ExtendedOpcodes.EPKTCOPY, Rbit1)); } /** @@ -242,7 +243,7 @@ public ApfV4Generator addJumpIfPktAtR0DoesNotContainDnsQ(@NonNull byte[] qnames, int qtype, @NonNull String tgt) { validateNames(qnames); - return append(new Instruction(ExtendedOpcodes.JDNSQMATCH).setTargetLabel(tgt).addU8( + return append(new Instruction(ExtendedOpcodes.JDNSQMATCH, Rbit0).setTargetLabel(tgt).addU8( qtype).setBytesImm(qnames)); } @@ -255,7 +256,7 @@ public ApfV4Generator addJumpIfPktAtR0ContainDnsQ(@NonNull byte[] qnames, int qtype, @NonNull String tgt) { validateNames(qnames); - return append(new Instruction(ExtendedOpcodes.JDNSQMATCH, R1).setTargetLabel(tgt).addU8( + return append(new Instruction(ExtendedOpcodes.JDNSQMATCH, Rbit1).setTargetLabel(tgt).addU8( qtype).setBytesImm(qnames)); } @@ -268,8 +269,8 @@ public ApfV4Generator addJumpIfPktAtR0DoesNotContainDnsA(@NonNull byte[] names, @NonNull String tgt) { validateNames(names); - return append(new Instruction(ExtendedOpcodes.JDNSAMATCH).setTargetLabel(tgt).setBytesImm( - names)); + return append(new Instruction(ExtendedOpcodes.JDNSAMATCH, Rbit0).setTargetLabel(tgt) + .setBytesImm(names)); } /** @@ -281,7 +282,7 @@ public ApfV4Generator addJumpIfPktAtR0ContainDnsA(@NonNull byte[] names, @NonNull String tgt) { validateNames(names); - return append(new Instruction(ExtendedOpcodes.JDNSAMATCH, R1).setTargetLabel( + return append(new Instruction(ExtendedOpcodes.JDNSAMATCH, Rbit1).setTargetLabel( tgt).setBytesImm(names)); }
diff --git a/src/android/net/apf/LegacyApfFilter.java b/src/android/net/apf/LegacyApfFilter.java index d81f8b4..14ed176 100644 --- a/src/android/net/apf/LegacyApfFilter.java +++ b/src/android/net/apf/LegacyApfFilter.java
@@ -16,6 +16,8 @@ package android.net.apf; +import static android.net.apf.ApfV4Generator.Register.R0; +import static android.net.apf.ApfV4Generator.Register.R1; import static android.net.util.SocketUtils.makePacketSocketAddress; import static android.system.OsConstants.AF_PACKET; import static android.system.OsConstants.ARPHRD_ETHER; @@ -44,7 +46,6 @@ import android.net.TcpKeepalivePacketDataParcelable; import android.net.apf.ApfCounterTracker.Counter; import android.net.apf.ApfV4Generator.IllegalInstructionException; -import android.net.apf.ApfV4Generator.Register; import android.net.ip.IpClient.IpClientCallbacksWrapper; import android.net.metrics.ApfProgramEvent; import android.net.metrics.ApfStats; @@ -126,7 +127,7 @@ */ private void maybeSetupCounter(ApfV4Generator gen, Counter c) { if (mApfCapabilities.hasDataAccess()) { - gen.addLoadImmediate(Register.R1, c.offset()); + gen.addLoadImmediate(R1, c.offset()); } } @@ -972,15 +973,15 @@ long generateFilterLocked(ApfV4Generator gen) throws IllegalInstructionException { String nextFilterLabel = "Ra" + getUniqueNumberLocked(); // Skip if packet is not the right size - gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R0, gen.PACKET_SIZE_MEMORY_SLOT); gen.addJumpIfR0NotEquals(mPacket.capacity(), nextFilterLabel); // Skip filter if expired - gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT); + gen.addLoadFromMemory(R0, gen.FILTER_AGE_MEMORY_SLOT); gen.addJumpIfR0GreaterThan(filterLifetime(), nextFilterLabel); for (PacketSection section : mPacketSections) { // Generate code to match the packet bytes. if (section.type == PacketSection.Type.MATCH) { - gen.addLoadImmediate(Register.R0, section.start); + gen.addLoadImmediate(R0, section.start); gen.addJumpIfBytesAtR0NotEqual( Arrays.copyOfRange(mPacket.array(), section.start, section.start + section.length), @@ -991,8 +992,8 @@ // The packet is accepted if any non-ignored lifetime is lower than filterLifetime. if (isRelevantLifetime(section)) { switch (section.length) { - case 4: gen.addLoad32(Register.R0, section.start); break; - case 2: gen.addLoad16(Register.R0, section.start); break; + case 4: gen.addLoad32(R0, section.start); break; + case 2: gen.addLoad16(R0, section.start); break; default: throw new IllegalStateException( "bogus lifetime size " + section.length); @@ -1064,21 +1065,21 @@ void generateFilterLocked(ApfV4Generator gen) throws IllegalInstructionException { final String nextFilterLabel = "natt_keepalive_filter" + getUniqueNumberLocked(); - gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(mSrcDstAddr, nextFilterLabel); // A NAT-T keepalive packet contains 1 byte payload with the value 0xff // Check payload length is 1 - gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); gen.addAdd(UDP_HEADER_LEN); gen.addSwap(); - gen.addLoad16(Register.R0, IPV4_TOTAL_LENGTH_OFFSET); - gen.addNeg(Register.R1); + gen.addLoad16(R0, IPV4_TOTAL_LENGTH_OFFSET); + gen.addNeg(R1); gen.addAddR1(); gen.addJumpIfR0NotEquals(1, nextFilterLabel); // Check that the ports match - gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); gen.addAdd(ETH_HEADER_LEN); gen.addJumpIfBytesAtR0NotEqual(mPortFingerprint, nextFilterLabel); @@ -1180,28 +1181,28 @@ void generateFilterLocked(ApfV4Generator gen) throws IllegalInstructionException { final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked(); - gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(mSrcDstAddr, nextFilterLabel); // Skip to the next filter if it's not zero-sized : // TCP_HEADER_SIZE + IPV4_HEADER_SIZE - ipv4_total_length == 0 // Load the IP header size into R1 - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); // Load the TCP header size into R0 (it's indexed by R1) - gen.addLoad8Indexed(Register.R0, ETH_HEADER_LEN + TCP_HEADER_SIZE_OFFSET); + gen.addLoad8Indexed(R0, ETH_HEADER_LEN + TCP_HEADER_SIZE_OFFSET); // Size offset is in the top nibble, but it must be multiplied by 4, and the two // top bits of the low nibble are guaranteed to be zeroes. Right-shift R0 by 2. gen.addRightShift(2); // R0 += R1 -> R0 contains TCP + IP headers length gen.addAddR1(); // Load IPv4 total length - gen.addLoad16(Register.R1, IPV4_TOTAL_LENGTH_OFFSET); - gen.addNeg(Register.R0); + gen.addLoad16(R1, IPV4_TOTAL_LENGTH_OFFSET); + gen.addNeg(R0); gen.addAddR1(); gen.addJumpIfR0NotEquals(0, nextFilterLabel); // Add IPv4 header length - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); - gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadImmediate(R0, ETH_HEADER_LEN); gen.addAddR1(); gen.addJumpIfBytesAtR0NotEqual(mPortSeqAckFingerprint, nextFilterLabel); @@ -1315,23 +1316,23 @@ final String checkTargetIPv4 = "checkTargetIPv4"; // Pass if not ARP IPv4. - gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET); + gen.addLoadImmediate(R0, ARP_HEADER_OFFSET); maybeSetupCounter(gen, Counter.PASSED_ARP_NON_IPV4); gen.addJumpIfBytesAtR0NotEqual(ARP_IPV4_HEADER, mCountAndPassLabel); // Pass if unknown ARP opcode. - gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET); + gen.addLoad16(R0, ARP_OPCODE_OFFSET); gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check maybeSetupCounter(gen, Counter.PASSED_ARP_UNKNOWN); gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel); // Drop if ARP reply source IP is 0.0.0.0 - gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET); + gen.addLoad32(R0, ARP_SOURCE_IP_ADDRESS_OFFSET); maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST); gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel); // Pass if unicast reply. - gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_DEST_ADDR_OFFSET); maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY); gen.addJumpIfBytesAtR0NotEqual(ETHER_BROADCAST, mCountAndPassLabel); @@ -1339,13 +1340,13 @@ gen.defineLabel(checkTargetIPv4); if (mIPv4Address == null) { // When there is no IPv4 address, drop GARP replies (b/29404209). - gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET); + gen.addLoad32(R0, ARP_TARGET_IP_ADDRESS_OFFSET); maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY); gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel); } else { // When there is an IPv4 address, drop unicast/broadcast requests // and broadcast replies with a different target IPv4 address. - gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET); + gen.addLoadImmediate(R0, ARP_TARGET_IP_ADDRESS_OFFSET); maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST); gen.addJumpIfBytesAtR0NotEqual(mIPv4Address, mCountAndDropLabel); } @@ -1382,17 +1383,17 @@ // Pass DHCP addressed to us. // Check it's UDP. - gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET); + gen.addLoad8(R0, IPV4_PROTOCOL_OFFSET); gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipDhcpv4Filter); // Check it's not a fragment. This matches the BPF filter installed by the DHCP client. - gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET); + gen.addLoad16(R0, IPV4_FRAGMENT_OFFSET_OFFSET); gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_OFFSET_MASK, skipDhcpv4Filter); // Check it's addressed to DHCP client port. - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); - gen.addLoad16Indexed(Register.R0, UDP_DESTINATION_PORT_OFFSET); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoad16Indexed(R0, UDP_DESTINATION_PORT_OFFSET); gen.addJumpIfR0NotEquals(DHCP_CLIENT_PORT, skipDhcpv4Filter); // Check it's DHCP to our MAC address. - gen.addLoadImmediate(Register.R0, DHCP_CLIENT_MAC_OFFSET); + gen.addLoadImmediate(R0, DHCP_CLIENT_MAC_OFFSET); // NOTE: Relies on R1 containing IPv4 header offset. gen.addAddR1(); gen.addJumpIfBytesAtR0NotEqual(mHardwareAddress, skipDhcpv4Filter); @@ -1403,14 +1404,14 @@ gen.defineLabel(skipDhcpv4Filter); // If IPv4 destination address is in multicast range, drop. - gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET); + gen.addLoad8(R0, IPV4_DEST_ADDR_OFFSET); gen.addAnd(0xf0); maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST); gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel); // If IPv4 broadcast packet, drop regardless of L2 (b/30231088). maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR); - gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET); + gen.addLoad32(R0, IPV4_DEST_ADDR_OFFSET); gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel); if (mIPv4Address != null && mIPv4PrefixLength < 31) { maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET); @@ -1428,7 +1429,7 @@ // If L2 broadcast packet, drop. // TODO: can we invert this condition to fall through to the common pass case below? maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST); - gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_DEST_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(ETHER_BROADCAST, mCountAndPassLabel); maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST); gen.addJump(mCountAndDropLabel); @@ -1452,7 +1453,7 @@ if (!haveKeepaliveResponses) return; // If not the right proto, skip keepalive filters - gen.addLoad8(Register.R0, offset); + gen.addLoad8(R0, offset); gen.addJumpIfR0NotEquals(proto, label); // Drop Keepalive responses @@ -1501,7 +1502,7 @@ // if keepalive ack // drop - gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET); + gen.addLoad8(R0, IPV6_NEXT_HEADER_OFFSET); // MLD packets set the router-alert hop-by-hop option. // TODO: be smarter about not blindly passing every packet with HBH options. @@ -1520,7 +1521,7 @@ // ICMPv6 but not ECHO? -> Skip the multicast filter. // (ICMPv6 ECHO requests will go through the multicast filter below). - gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET); + gen.addLoad8(R0, ICMP6_TYPE_OFFSET); gen.addJumpIfR0NotEquals(ICMPV6_ECHO_REQUEST_TYPE, skipIPv6MulticastFilterLabel); } else { gen.addJumpIfR0Equals(IPPROTO_ICMPV6, skipIPv6MulticastFilterLabel); @@ -1529,7 +1530,7 @@ // Drop all other packets sent to ff00::/8 (multicast prefix). gen.defineLabel(dropAllIPv6MulticastsLabel); maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST); - gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET); + gen.addLoad8(R0, IPV6_DEST_ADDR_OFFSET); gen.addJumpIfR0Equals(0xff, mCountAndDropLabel); // If any keepalive filter matches, drop generateV6KeepaliveFilters(gen); @@ -1548,7 +1549,7 @@ // Add unsolicited multicast neighbor announcements filter String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA"; - gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET); + gen.addLoad8(R0, ICMP6_TYPE_OFFSET); // Drop all router solicitations (b/32833400) maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION); gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel); @@ -1558,7 +1559,7 @@ // This is a way to cover ff02::1 and ff02::2 with a single JNEBS. // TODO: Drop only if they don't contain the address of on-link neighbours. final byte[] unsolicitedNaDropPrefix = Arrays.copyOf(IPV6_ALL_NODES_ADDRESS, 15); - gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, IPV6_DEST_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(unsolicitedNaDropPrefix, skipUnsolicitedMulticastNALabel); maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA); @@ -1615,19 +1616,19 @@ // 3. it is a UDP packet with port 5353 // Check it's L2 mDNS multicast address. - gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_DEST_ADDR_OFFSET); gen.addJumpIfBytesAtR0NotEqual(ETH_MULTICAST_MDNS_V4_MAC_ADDRESS, skipMdnsv4Filter); // Checks it's IPv4. - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + gen.addLoad16(R0, ETH_ETHERTYPE_OFFSET); gen.addJumpIfR0NotEquals(ETH_P_IP, skipMdnsFilter); // Checks it's UDP. - gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET); + gen.addLoad8(R0, IPV4_PROTOCOL_OFFSET); gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipMdnsFilter); // Set R1 to IPv4 header. - gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); + gen.addLoadFromMemory(R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); gen.addJump(checkMdnsUdpPort); gen.defineLabel(skipMdnsv4Filter); @@ -1637,28 +1638,28 @@ gen.addJumpIfBytesAtR0NotEqual(ETH_MULTICAST_MDNS_V6_MAC_ADDRESS, skipMdnsFilter); // Checks it's IPv6. - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + gen.addLoad16(R0, ETH_ETHERTYPE_OFFSET); gen.addJumpIfR0NotEquals(ETH_P_IPV6, skipMdnsFilter); // Checks it's UDP. - gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET); + gen.addLoad8(R0, IPV6_NEXT_HEADER_OFFSET); gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipMdnsFilter); // Set R1 to IPv6 header. - gen.addLoadImmediate(Register.R1, IPV6_HEADER_LEN); + gen.addLoadImmediate(R1, IPV6_HEADER_LEN); // Checks it's mDNS UDP port gen.defineLabel(checkMdnsUdpPort); - gen.addLoad16Indexed(Register.R0, UDP_DESTINATION_PORT_OFFSET); + gen.addLoad16Indexed(R0, UDP_DESTINATION_PORT_OFFSET); gen.addJumpIfR0NotEquals(MDNS_PORT, skipMdnsFilter); - gen.addLoad16Indexed(Register.R0, MDNS_QDCOUNT_OFFSET); + gen.addLoad16Indexed(R0, MDNS_QDCOUNT_OFFSET); // If QDCOUNT != 1, pass the packet gen.addJumpIfR0NotEquals(1, mDnsAcceptPacket); // If QDCOUNT == 1, matches the QNAME with allowlist. // Load offset for the first QNAME. - gen.addLoadImmediate(Register.R0, MDNS_QNAME_OFFSET); + gen.addLoadImmediate(R0, MDNS_QNAME_OFFSET); gen.addAddR1(); // Check first QNAME against allowlist @@ -1718,9 +1719,9 @@ if (mApfCapabilities.hasDataAccess()) { // Increment TOTAL_PACKETS maybeSetupCounter(gen, Counter.TOTAL_PACKETS); - gen.addLoadData(Register.R0, 0); // load counter + gen.addLoadData(R0, 0); // load counter gen.addAdd(1); - gen.addStoreData(Register.R0, 0); // write-back counter + gen.addStoreData(R0, 0); // write-back counter } // Here's a basic summary of what the initial program does: @@ -1739,7 +1740,7 @@ // pass // insert IPv6 filter to drop, pass, or fall off the end for ICMPv6 packets - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + gen.addLoad16(R0, ETH_ETHERTYPE_OFFSET); if (mDrop802_3Frames) { // drop 802.3 frames (ethtype < 0x0600) @@ -1761,7 +1762,7 @@ // Add mDNS filter: generateMdnsFilterLocked(gen); - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + gen.addLoad16(R0, ETH_ETHERTYPE_OFFSET); // Add IPv4 filters: String skipIPv4FiltersLabel = "skipIPv4Filters"; @@ -1777,7 +1778,7 @@ gen.addJumpIfR0Equals(ETH_P_IPV6, ipv6FilterLabel); // Drop non-IP non-ARP broadcasts, pass the rest - gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); + gen.addLoadImmediate(R0, ETH_DEST_ADDR_OFFSET); maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST); gen.addJumpIfBytesAtR0NotEqual(ETHER_BROADCAST, mCountAndPassLabel); maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST); @@ -1809,16 +1810,16 @@ // pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting // the entire sequence inline for every counter. gen.defineLabel(mCountAndPassLabel); - gen.addLoadData(Register.R0, 0); // R0 = *(R1 + 0) + gen.addLoadData(R0, 0); // R0 = *(R1 + 0) gen.addAdd(1); // R0++ - gen.addStoreData(Register.R0, 0); // *(R1 + 0) = R0 + gen.addStoreData(R0, 0); // *(R1 + 0) = R0 gen.addJump(gen.PASS_LABEL); // Same as above for the count & drop trampoline. gen.defineLabel(mCountAndDropLabel); - gen.addLoadData(Register.R0, 0); // R0 = *(R1 + 0) + gen.addLoadData(R0, 0); // R0 = *(R1 + 0) gen.addAdd(1); // R0++ - gen.addStoreData(Register.R0, 0); // *(R1 + 0) = R0 + gen.addStoreData(R0, 0); // *(R1 + 0) = R0 gen.addJump(gen.DROP_LABEL); }
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java index c4dc40a..72b9050 100644 --- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java +++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -306,10 +306,10 @@ protected static final long TEST_TIMEOUT_MS = 2_000L; private static final long TEST_WAIT_ENOBUFS_TIMEOUT_MS = 30_000L; private static final long TEST_WAIT_RENEW_REBIND_RETRANSMIT_MS = 15_000L; - // To prevent the flakiness about deprecationTime and expirationTime check, +/- 2s tolerance + // To prevent the flakiness about deprecationTime and expirationTime check, +/- 4s tolerance // should be enough between the timestamp when the IP provisioning completes successfully and // when IpClientLinkObserver sees the RTM_NEWADDR netlink events. - private static final long TEST_LIFETIME_TOLERANCE_MS = 2_000L; + private static final long TEST_LIFETIME_TOLERANCE_MS = 4_000L; @Rule public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
diff --git a/tests/unit/src/android/net/apf/ApfTest.java b/tests/unit/src/android/net/apf/ApfTest.java index 5c6a906..37b9060 100644 --- a/tests/unit/src/android/net/apf/ApfTest.java +++ b/tests/unit/src/android/net/apf/ApfTest.java
@@ -263,6 +263,12 @@ ApfV4Generator gen = new ApfV4Generator(MIN_APF_VERSION); assertPass(gen); + // Test pass opcode + gen = new ApfV4Generator(MIN_APF_VERSION); + gen.addPass(); + gen.addJump(DROP_LABEL); + assertPass(gen); + // Test jumping to pass label. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addJump(PASS_LABEL);
diff --git a/tests/unit/src/android/net/apf/Bpf2Apf.java b/tests/unit/src/android/net/apf/Bpf2Apf.java index 795c2b3..0a315e8 100644 --- a/tests/unit/src/android/net/apf/Bpf2Apf.java +++ b/tests/unit/src/android/net/apf/Bpf2Apf.java
@@ -16,6 +16,9 @@ package android.net.apf; +import static android.net.apf.ApfV4Generator.Register.R0; +import static android.net.apf.ApfV4Generator.Register.R1; + import android.net.apf.ApfV4Generator.IllegalInstructionException; import android.net.apf.ApfV4Generator.Register; @@ -67,7 +70,7 @@ case "ldx": case "ldxb": case "ldxh": - Register dest = opcode.contains("x") ? Register.R1 : Register.R0; + Register dest = opcode.contains("x") ? R1 : R0; if (arg.equals("4*([14]&0xf)")) { if (!opcode.equals("ldxb")) { throw new IllegalArgumentException("Unhandled instruction: " + line); @@ -140,7 +143,7 @@ break; case "st": case "stx": - Register src = opcode.contains("x") ? Register.R1 : Register.R0; + Register src = opcode.contains("x") ? R1 : R0; if (!arg.startsWith("M[")) { throw new IllegalArgumentException("Unhandled instruction: " + line); } @@ -169,9 +172,9 @@ gen.addOrR1(); break; case "sub": - gen.addNeg(Register.R1); + gen.addNeg(R1); gen.addAddR1(); - gen.addNeg(Register.R1); + gen.addNeg(R1); break; } } else { @@ -291,10 +294,10 @@ } break; case "tax": - gen.addMove(Register.R1); + gen.addMove(R1); break; case "txa": - gen.addMove(Register.R0); + gen.addMove(R0); break; default: throw new IllegalArgumentException("Unhandled instruction: " + line);
diff --git a/tests/unit/src/android/net/apf/JumpTableTest.kt b/tests/unit/src/android/net/apf/JumpTableTest.kt index 3858aac..31b089f 100644 --- a/tests/unit/src/android/net/apf/JumpTableTest.kt +++ b/tests/unit/src/android/net/apf/JumpTableTest.kt
@@ -16,6 +16,7 @@ package android.net.apf +import android.net.apf.ApfV4Generator.Register.R0 import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 import com.android.testutils.assertThrows @@ -94,7 +95,7 @@ j.generate(gen) inOrder.verify(gen).defineLabel(name) - inOrder.verify(gen).addLoadFromMemory(ApfV4Generator.Register.R0, slot) + inOrder.verify(gen).addLoadFromMemory(R0, slot) inOrder.verify(gen).addJumpIfR0Equals(0, "foo") inOrder.verify(gen).addJumpIfR0Equals(1, "bar") inOrder.verify(gen).addJumpIfR0Equals(2, "baz")
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java index d3647f5..d6e9c8e 100644 --- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java +++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -278,8 +278,10 @@ private @Mock TcpSocketTracker.Dependencies mTstDependencies; private @Mock INetd mNetd; private @Mock TcpSocketTracker mTst; - private HashSet<WrappedNetworkMonitor> mCreatedNetworkMonitors; - private HashSet<BroadcastReceiver> mRegisteredReceivers; + @GuardedBy("mCreatedNetworkMonitors") + private final HashSet<WrappedNetworkMonitor> mCreatedNetworkMonitors = new HashSet<>(); + @GuardedBy("mRegisteredReceivers") + private final HashSet<BroadcastReceiver> mRegisteredReceivers = new HashSet<>(); private @Mock Context mMccContext; private @Mock Resources mMccResource; private @Mock WifiInfo mWifiInfo; @@ -681,16 +683,22 @@ mFakeDns.setAnswer(PRIVATE_DNS_PROBE_HOST_SUFFIX, new String[]{"2001:db8::1"}, TYPE_AAAA); doAnswer((invocation) -> { - mRegisteredReceivers.add(invocation.getArgument(0)); + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.add(invocation.getArgument(0)); + } return new Intent(); }).when(mContext).registerReceiver(any(BroadcastReceiver.class), any()); doAnswer((invocation) -> { - mRegisteredReceivers.add(invocation.getArgument(0)); + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.add(invocation.getArgument(0)); + } return new Intent(); }).when(mContext).registerReceiver(any(BroadcastReceiver.class), any(), anyInt()); doAnswer((invocation) -> { - mRegisteredReceivers.remove(invocation.getArgument(0)); + synchronized (mRegisteredReceivers) { + mRegisteredReceivers.remove(invocation.getArgument(0)); + } return null; }).when(mContext).unregisterReceiver(any()); @@ -700,12 +708,10 @@ setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS); setValidDataStallDnsTimeThreshold(TEST_MIN_VALID_STALL_DNS_TIME_THRESHOLD_MS); setConsecutiveDnsTimeoutThreshold(5); - mCreatedNetworkMonitors = new HashSet<>(); - mRegisteredReceivers = new HashSet<>(); } - private static <T> void quitThreadsThat(Supplier<List<T>> supplier, ThrowingConsumer terminator) - throws Exception { + private static <T> void quitResourcesThat(Supplier<List<T>> supplier, + ThrowingConsumer terminator) throws Exception { // Run it multiple times since new threads might be generated in a thread // that is about to be terminated, e.g. each thread that runs // isCaptivePortal could generate 2 more probing threads. @@ -720,8 +726,29 @@ assertEquals(Collections.emptyList(), supplier.get()); } + private void quitNetworkMonitors() throws Exception { + quitResourcesThat(() -> { + synchronized (mCreatedNetworkMonitors) { + final ArrayList<WrappedNetworkMonitor> ret = + new ArrayList<>(mCreatedNetworkMonitors); + mCreatedNetworkMonitors.clear(); + return ret; + } + }, (it) -> { + final WrappedNetworkMonitor nm = (WrappedNetworkMonitor) it; + nm.notifyNetworkDisconnected(); + nm.awaitQuit(); + }); + synchronized (mRegisteredReceivers) { + assertEquals("BroadcastReceiver still registered after disconnect", + 0, mRegisteredReceivers.size()); + } + quitThreads(); + quitExecutorServices(); + } + private void quitExecutorServices() throws Exception { - quitThreadsThat(() -> { + quitResourcesThat(() -> { synchronized (mExecutorServiceToBeCleared) { final ArrayList<ExecutorService> ret = new ArrayList<>(mExecutorServiceToBeCleared); mExecutorServiceToBeCleared.clear(); @@ -734,7 +761,7 @@ } private void quitThreads() throws Exception { - quitThreadsThat(() -> { + quitResourcesThat(() -> { synchronized (mThreadsToBeCleared) { final ArrayList<Thread> ret = new ArrayList<>(mThreadsToBeCleared); mThreadsToBeCleared.clear(); @@ -751,20 +778,7 @@ @After public void tearDown() throws Exception { mFakeDns.clearAll(); - // Make a local copy of mCreatedNetworkMonitors because during the iteration below, - // WrappedNetworkMonitor#onQuitting will delete elements from it on the handler threads. - WrappedNetworkMonitor[] networkMonitors = mCreatedNetworkMonitors.toArray( - new WrappedNetworkMonitor[0]); - for (WrappedNetworkMonitor nm : networkMonitors) { - nm.notifyNetworkDisconnected(); - nm.awaitQuit(); - } - assertEquals("NetworkMonitor still running after disconnect", - 0, mCreatedNetworkMonitors.size()); - assertEquals("BroadcastReceiver still registered after disconnect", - 0, mRegisteredReceivers.size()); - quitThreads(); - quitExecutorServices(); + quitNetworkMonitors(); // Clear mocks to prevent from stubs holding instances and cause memory leaks. Mockito.framework().clearInlineMocks(); } @@ -849,7 +863,6 @@ @Override protected void onQuitting() { super.onQuitting(); - assertTrue(mCreatedNetworkMonitors.remove(this)); mQuitCv.open(); } @@ -1171,7 +1184,9 @@ verify(mContext, never()).registerReceiver(receiverCaptor.capture(), argThat(receiver -> ACTION_CONFIGURATION_CHANGED.equals(receiver.getAction(0)))); nm.start(); - mCreatedNetworkMonitors.add(nm); + synchronized (mCreatedNetworkMonitors) { + mCreatedNetworkMonitors.add(nm); + } HandlerUtils.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS); verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(), argThat(receiver -> ACTION_CONFIGURATION_CHANGED.equals(receiver.getAction(0)))); @@ -3773,6 +3788,8 @@ // started. If captive portal app receiver is registered, then the size of the registered // receivers will be 2. Otherwise, mRegisteredReceivers should only contain 1 configuration // change receiver. - assertEquals(isPortal ? 2 : 1, mRegisteredReceivers.size()); + synchronized (mRegisteredReceivers) { + assertEquals(isPortal ? 2 : 1, mRegisteredReceivers.size()); + } } }