Loading core/res/res/values/config.xml +11 −0 Original line number Diff line number Diff line Loading @@ -301,6 +301,17 @@ less than 0x600 --> <bool translatable="false" name="config_apfDrop802_3Frames">true</bool> <!-- An array of Black listed EtherType, packets with EtherTypes within this array will be dropped TODO: need to put proper values, these are for testing purposes only --> <integer-array translatable="false" name="config_apfEthTypeBlackList"> <item>0x88A2</item> <item>0x88A4</item> <item>0x88B8</item> <item>0x88CD</item> <item>0x88E3</item> </integer-array> <!-- Default value for ConnectivityManager.getMultipathPreference() on metered networks. Actual device behaviour is controlled by Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE. This is the default value of that setting. --> Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1828,6 +1828,7 @@ <java-symbol type="integer" name="config_networkWakeupPacketMark" /> <java-symbol type="integer" name="config_networkWakeupPacketMask" /> <java-symbol type="bool" name="config_apfDrop802_3Frames" /> <java-symbol type="array" name="config_apfEthTypeBlackList" /> <java-symbol type="integer" name="config_networkMeteredMultipathPreference" /> <java-symbol type="integer" name="config_notificationsBatteryFullARGB" /> <java-symbol type="integer" name="config_notificationsBatteryLedOff" /> Loading services/net/java/android/net/apf/ApfFilter.java +50 −3 Original line number Diff line number Diff line Loading @@ -180,6 +180,7 @@ public class ApfFilter { private static final int ETH_DEST_ADDR_OFFSET = 0; private static final int ETH_ETHERTYPE_OFFSET = 12; private static final int ETH_TYPE_MIN = 0x0600; private static final int ETH_TYPE_MAX = 0xFFFF; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN. Loading Loading @@ -232,6 +233,9 @@ public class ApfFilter { private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; // Do not log ApfProgramEvents whose actual lifetimes was less than this. private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2; // Limit on the Black List size to cap on program usage for this // TODO: Select a proper max length private static final int APF_MAX_ETH_TYPE_BLACK_LIST_LEN = 20; private final ApfCapabilities mApfCapabilities; private final IpManager.Callback mIpManagerCallback; Loading @@ -247,6 +251,8 @@ public class ApfFilter { @GuardedBy("this") private boolean mMulticastFilter; private final boolean mDrop802_3Frames; private final int[] mEthTypeBlackList; // Our IPv4 address, if we have just one, otherwise null. @GuardedBy("this") private byte[] mIPv4Address; Loading @@ -257,12 +263,16 @@ public class ApfFilter { @VisibleForTesting ApfFilter(ApfCapabilities apfCapabilities, NetworkInterface networkInterface, IpManager.Callback ipManagerCallback, boolean multicastFilter, boolean ieee802_3Filter, IpConnectivityLog log) { boolean ieee802_3Filter, int[] ethTypeBlackList, IpConnectivityLog log) { mApfCapabilities = apfCapabilities; mIpManagerCallback = ipManagerCallback; mNetworkInterface = networkInterface; mMulticastFilter = multicastFilter; mDrop802_3Frames = ieee802_3Filter; // Now fill the black list from the passed array mEthTypeBlackList = filterEthTypeBlackList(ethTypeBlackList); mMetricsLog = log; // TODO: ApfFilter should not generate programs until IpManager sends provisioning success. Loading @@ -278,6 +288,35 @@ public class ApfFilter { return mUniqueCounter++; } @GuardedBy("this") private static int[] filterEthTypeBlackList(int[] ethTypeBlackList) { ArrayList<Integer> bl = new ArrayList<Integer>(); for (int p : ethTypeBlackList) { // Check if the protocol is a valid ether type if ((p < ETH_TYPE_MIN) || (p > ETH_TYPE_MAX)) { continue; } // Check if the protocol is not repeated in the passed array if (bl.contains(p)) { continue; } // Check if list reach its max size if (bl.size() == APF_MAX_ETH_TYPE_BLACK_LIST_LEN) { Log.w(TAG, "Passed EthType Black List size too large (" + bl.size() + ") using top " + APF_MAX_ETH_TYPE_BLACK_LIST_LEN + " protocols"); break; } // Now add the protocol to the list bl.add(p); } return bl.stream().mapToInt(Integer::intValue).toArray(); } /** * Attempt to start listening for RAs and, if RAs are received, generating and installing * filters to ignore useless RAs. Loading Loading @@ -891,6 +930,7 @@ public class ApfFilter { * Begin generating an APF program to: * <ul> * <li>Drop/Pass 802.3 frames (based on policy) * <li>Drop packets with EtherType within the Black List * <li>Drop ARP requests not for us, if mIPv4Address is set, * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC, * <li>Drop IPv4 multicast packets, if mMulticastFilter, Loading @@ -914,6 +954,8 @@ public class ApfFilter { // // if it's a 802.3 Frame (ethtype < 0x0600): // drop or pass based on configurations // if it has a ether-type that belongs to the black list // drop // if it's ARP: // insert ARP filter to drop or pass these appropriately // if it's IPv4: Loading @@ -931,6 +973,11 @@ public class ApfFilter { gen.addJumpIfR0LessThan(ETH_TYPE_MIN, gen.DROP_LABEL); } // Handle ether-type black list for (int p : mEthTypeBlackList) { gen.addJumpIfR0Equals(p, gen.DROP_LABEL); } // Add ARP filters: String skipArpFiltersLabel = "skipArpFilters"; gen.addJumpIfR0NotEquals(ETH_P_ARP, skipArpFiltersLabel); Loading Loading @@ -1115,7 +1162,7 @@ public class ApfFilter { */ public static ApfFilter maybeCreate(ApfCapabilities apfCapabilities, NetworkInterface networkInterface, IpManager.Callback ipManagerCallback, boolean multicastFilter, boolean ieee802_3Filter) { boolean multicastFilter, boolean ieee802_3Filter, int[] ethTypeBlackList) { if (apfCapabilities == null || networkInterface == null) return null; if (apfCapabilities.apfVersionSupported == 0) return null; if (apfCapabilities.maximumApfProgramSize < 512) { Loading @@ -1132,7 +1179,7 @@ public class ApfFilter { return null; } return new ApfFilter(apfCapabilities, networkInterface, ipManagerCallback, multicastFilter, ieee802_3Filter, new IpConnectivityLog()); multicastFilter, ieee802_3Filter, ethTypeBlackList, new IpConnectivityLog()); } public synchronized void shutdown() { Loading services/net/java/android/net/ip/IpManager.java +4 −1 Original line number Diff line number Diff line Loading @@ -1423,8 +1423,11 @@ public class IpManager extends StateMachine { boolean filter802_3Frames = mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames); int[] ethTypeBlackList = mContext.getResources().getIntArray( R.array.config_apfEthTypeBlackList); mApfFilter = ApfFilter.maybeCreate(mConfiguration.mApfCapabilities, mNetworkInterface, mCallback, mMulticastFiltering, filter802_3Frames); mCallback, mMulticastFiltering, filter802_3Frames, ethTypeBlackList); // TODO: investigate the effects of any multicast filtering racing/interfering with the // rest of this IP configuration startup. if (mApfFilter == null) { Loading tests/net/java/android/net/apf/ApfTest.java +85 −12 Original line number Diff line number Diff line Loading @@ -614,9 +614,10 @@ public class ApfTest extends AndroidTestCase { private final long mFixedTimeMs = SystemClock.elapsedRealtime(); public TestApfFilter(IpManager.Callback ipManagerCallback, boolean multicastFilter, boolean ieee802_3Filter, IpConnectivityLog log) throws Exception { boolean ieee802_3Filter, int[] ethTypeBlackList, IpConnectivityLog log) throws Exception { super(new ApfCapabilities(2, 1700, ARPHRD_ETHER), NetworkInterface.getByName("lo"), ipManagerCallback, multicastFilter, ieee802_3Filter, log); ipManagerCallback, multicastFilter, ieee802_3Filter, ethTypeBlackList, log); } // Pretend an RA packet has been received and show it to ApfFilter. Loading Loading @@ -744,9 +745,10 @@ public class ApfTest extends AndroidTestCase { LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); final int[] ethTypeBlackList = {}; ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, ALLOW_802_3_FRAMES, mLog); ALLOW_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); Loading Loading @@ -796,9 +798,10 @@ public class ApfTest extends AndroidTestCase { @SmallTest public void testApfFilterIPv6() throws Exception { final int[] ethTypeBlackList = {}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, mLog); ALLOW_802_3_FRAMES, ethTypeBlackList, mLog); byte[] program = ipManagerCallback.getApfProgram(); // Verify empty IPv6 packet is passed Loading Loading @@ -833,6 +836,7 @@ public class ApfTest extends AndroidTestCase { final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255}; final byte[] multicastIpv4Addr = {(byte)224,0,0,1}; final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb}; final int[] ethTypeBlackList = {}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24); Loading @@ -840,7 +844,7 @@ public class ApfTest extends AndroidTestCase { lp.addLinkAddress(link); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); Loading Loading @@ -903,7 +907,7 @@ public class ApfTest extends AndroidTestCase { ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); assertDrop(program, mcastv4packet.array()); Loading @@ -924,9 +928,10 @@ public class ApfTest extends AndroidTestCase { LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); final int[] ethTypeBlackList = {}; ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, mLog); ALLOW_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); Loading @@ -948,7 +953,7 @@ public class ApfTest extends AndroidTestCase { ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); Loading @@ -968,6 +973,70 @@ public class ApfTest extends AndroidTestCase { apfFilter.shutdown(); } @SmallTest public void testApfFilterEthTypeBL() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); final int[] emptyBlackList = {}; final int[] ipv4BlackList = {ETH_P_IP}; final int[] ipv4Ipv6BlackList = {ETH_P_IP, ETH_P_IPV6}; ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, emptyBlackList, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); // Verify empty packet of 100 zero bytes is passed // Note that eth-type = 0 makes it an IEEE802.3 frame ByteBuffer packet = ByteBuffer.wrap(new byte[100]); assertPass(program, packet.array()); // Verify empty packet with IPv4 is passed packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); assertPass(program, packet.array()); // Verify empty IPv6 packet is passed packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); assertPass(program, packet.array()); // Now add IPv4 to the black list ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, ipv4BlackList, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); // Verify that IPv4 frame will be dropped packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); assertDrop(program, packet.array()); // Verify that IPv6 frame will pass packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); assertPass(program, packet.array()); // Now let us have both IPv4 and IPv6 in the black list ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, ipv4Ipv6BlackList, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); // Verify that IPv4 frame will be dropped packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); assertDrop(program, packet.array()); // Verify that IPv6 frame will be dropped packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); assertDrop(program, packet.array()); apfFilter.shutdown(); } private byte[] getProgram(MockIpManagerCallback cb, ApfFilter filter, LinkProperties lp) { cb.resetApfProgramWait(); filter.setLinkProperties(lp); Loading @@ -991,9 +1060,10 @@ public class ApfTest extends AndroidTestCase { @SmallTest public void testApfFilterArp() throws Exception { final int[] ethTypeBlackList = {}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); // Verify initially ARP request filter is off, and GARP filter is on. verifyArpFilter(ipManagerCallback.getApfProgram(), PASS); Loading Loading @@ -1114,8 +1184,9 @@ public class ApfTest extends AndroidTestCase { @SmallTest public void testApfFilterRa() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); final int[] ethTypeBlackList = {}; TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); byte[] program = ipManagerCallback.getApfProgram(); final int ROUTER_LIFETIME = 1000; Loading Loading @@ -1256,9 +1327,10 @@ public class ApfTest extends AndroidTestCase { public void testRaParsing() throws Exception { final int maxRandomPacketSize = 512; final Random r = new Random(); final int[] ethTypeBlackList = {}; MockIpManagerCallback cb = new MockIpManagerCallback(); TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); for (int i = 0; i < 1000; i++) { byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)]; r.nextBytes(packet); Loading @@ -1275,9 +1347,10 @@ public class ApfTest extends AndroidTestCase { public void testRaProcessing() throws Exception { final int maxRandomPacketSize = 512; final Random r = new Random(); final int[] ethTypeBlackList = {}; MockIpManagerCallback cb = new MockIpManagerCallback(); TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); for (int i = 0; i < 1000; i++) { byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)]; r.nextBytes(packet); Loading Loading
core/res/res/values/config.xml +11 −0 Original line number Diff line number Diff line Loading @@ -301,6 +301,17 @@ less than 0x600 --> <bool translatable="false" name="config_apfDrop802_3Frames">true</bool> <!-- An array of Black listed EtherType, packets with EtherTypes within this array will be dropped TODO: need to put proper values, these are for testing purposes only --> <integer-array translatable="false" name="config_apfEthTypeBlackList"> <item>0x88A2</item> <item>0x88A4</item> <item>0x88B8</item> <item>0x88CD</item> <item>0x88E3</item> </integer-array> <!-- Default value for ConnectivityManager.getMultipathPreference() on metered networks. Actual device behaviour is controlled by Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE. This is the default value of that setting. --> Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1828,6 +1828,7 @@ <java-symbol type="integer" name="config_networkWakeupPacketMark" /> <java-symbol type="integer" name="config_networkWakeupPacketMask" /> <java-symbol type="bool" name="config_apfDrop802_3Frames" /> <java-symbol type="array" name="config_apfEthTypeBlackList" /> <java-symbol type="integer" name="config_networkMeteredMultipathPreference" /> <java-symbol type="integer" name="config_notificationsBatteryFullARGB" /> <java-symbol type="integer" name="config_notificationsBatteryLedOff" /> Loading
services/net/java/android/net/apf/ApfFilter.java +50 −3 Original line number Diff line number Diff line Loading @@ -180,6 +180,7 @@ public class ApfFilter { private static final int ETH_DEST_ADDR_OFFSET = 0; private static final int ETH_ETHERTYPE_OFFSET = 12; private static final int ETH_TYPE_MIN = 0x0600; private static final int ETH_TYPE_MAX = 0xFFFF; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN. Loading Loading @@ -232,6 +233,9 @@ public class ApfFilter { private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; // Do not log ApfProgramEvents whose actual lifetimes was less than this. private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2; // Limit on the Black List size to cap on program usage for this // TODO: Select a proper max length private static final int APF_MAX_ETH_TYPE_BLACK_LIST_LEN = 20; private final ApfCapabilities mApfCapabilities; private final IpManager.Callback mIpManagerCallback; Loading @@ -247,6 +251,8 @@ public class ApfFilter { @GuardedBy("this") private boolean mMulticastFilter; private final boolean mDrop802_3Frames; private final int[] mEthTypeBlackList; // Our IPv4 address, if we have just one, otherwise null. @GuardedBy("this") private byte[] mIPv4Address; Loading @@ -257,12 +263,16 @@ public class ApfFilter { @VisibleForTesting ApfFilter(ApfCapabilities apfCapabilities, NetworkInterface networkInterface, IpManager.Callback ipManagerCallback, boolean multicastFilter, boolean ieee802_3Filter, IpConnectivityLog log) { boolean ieee802_3Filter, int[] ethTypeBlackList, IpConnectivityLog log) { mApfCapabilities = apfCapabilities; mIpManagerCallback = ipManagerCallback; mNetworkInterface = networkInterface; mMulticastFilter = multicastFilter; mDrop802_3Frames = ieee802_3Filter; // Now fill the black list from the passed array mEthTypeBlackList = filterEthTypeBlackList(ethTypeBlackList); mMetricsLog = log; // TODO: ApfFilter should not generate programs until IpManager sends provisioning success. Loading @@ -278,6 +288,35 @@ public class ApfFilter { return mUniqueCounter++; } @GuardedBy("this") private static int[] filterEthTypeBlackList(int[] ethTypeBlackList) { ArrayList<Integer> bl = new ArrayList<Integer>(); for (int p : ethTypeBlackList) { // Check if the protocol is a valid ether type if ((p < ETH_TYPE_MIN) || (p > ETH_TYPE_MAX)) { continue; } // Check if the protocol is not repeated in the passed array if (bl.contains(p)) { continue; } // Check if list reach its max size if (bl.size() == APF_MAX_ETH_TYPE_BLACK_LIST_LEN) { Log.w(TAG, "Passed EthType Black List size too large (" + bl.size() + ") using top " + APF_MAX_ETH_TYPE_BLACK_LIST_LEN + " protocols"); break; } // Now add the protocol to the list bl.add(p); } return bl.stream().mapToInt(Integer::intValue).toArray(); } /** * Attempt to start listening for RAs and, if RAs are received, generating and installing * filters to ignore useless RAs. Loading Loading @@ -891,6 +930,7 @@ public class ApfFilter { * Begin generating an APF program to: * <ul> * <li>Drop/Pass 802.3 frames (based on policy) * <li>Drop packets with EtherType within the Black List * <li>Drop ARP requests not for us, if mIPv4Address is set, * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC, * <li>Drop IPv4 multicast packets, if mMulticastFilter, Loading @@ -914,6 +954,8 @@ public class ApfFilter { // // if it's a 802.3 Frame (ethtype < 0x0600): // drop or pass based on configurations // if it has a ether-type that belongs to the black list // drop // if it's ARP: // insert ARP filter to drop or pass these appropriately // if it's IPv4: Loading @@ -931,6 +973,11 @@ public class ApfFilter { gen.addJumpIfR0LessThan(ETH_TYPE_MIN, gen.DROP_LABEL); } // Handle ether-type black list for (int p : mEthTypeBlackList) { gen.addJumpIfR0Equals(p, gen.DROP_LABEL); } // Add ARP filters: String skipArpFiltersLabel = "skipArpFilters"; gen.addJumpIfR0NotEquals(ETH_P_ARP, skipArpFiltersLabel); Loading Loading @@ -1115,7 +1162,7 @@ public class ApfFilter { */ public static ApfFilter maybeCreate(ApfCapabilities apfCapabilities, NetworkInterface networkInterface, IpManager.Callback ipManagerCallback, boolean multicastFilter, boolean ieee802_3Filter) { boolean multicastFilter, boolean ieee802_3Filter, int[] ethTypeBlackList) { if (apfCapabilities == null || networkInterface == null) return null; if (apfCapabilities.apfVersionSupported == 0) return null; if (apfCapabilities.maximumApfProgramSize < 512) { Loading @@ -1132,7 +1179,7 @@ public class ApfFilter { return null; } return new ApfFilter(apfCapabilities, networkInterface, ipManagerCallback, multicastFilter, ieee802_3Filter, new IpConnectivityLog()); multicastFilter, ieee802_3Filter, ethTypeBlackList, new IpConnectivityLog()); } public synchronized void shutdown() { Loading
services/net/java/android/net/ip/IpManager.java +4 −1 Original line number Diff line number Diff line Loading @@ -1423,8 +1423,11 @@ public class IpManager extends StateMachine { boolean filter802_3Frames = mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames); int[] ethTypeBlackList = mContext.getResources().getIntArray( R.array.config_apfEthTypeBlackList); mApfFilter = ApfFilter.maybeCreate(mConfiguration.mApfCapabilities, mNetworkInterface, mCallback, mMulticastFiltering, filter802_3Frames); mCallback, mMulticastFiltering, filter802_3Frames, ethTypeBlackList); // TODO: investigate the effects of any multicast filtering racing/interfering with the // rest of this IP configuration startup. if (mApfFilter == null) { Loading
tests/net/java/android/net/apf/ApfTest.java +85 −12 Original line number Diff line number Diff line Loading @@ -614,9 +614,10 @@ public class ApfTest extends AndroidTestCase { private final long mFixedTimeMs = SystemClock.elapsedRealtime(); public TestApfFilter(IpManager.Callback ipManagerCallback, boolean multicastFilter, boolean ieee802_3Filter, IpConnectivityLog log) throws Exception { boolean ieee802_3Filter, int[] ethTypeBlackList, IpConnectivityLog log) throws Exception { super(new ApfCapabilities(2, 1700, ARPHRD_ETHER), NetworkInterface.getByName("lo"), ipManagerCallback, multicastFilter, ieee802_3Filter, log); ipManagerCallback, multicastFilter, ieee802_3Filter, ethTypeBlackList, log); } // Pretend an RA packet has been received and show it to ApfFilter. Loading Loading @@ -744,9 +745,10 @@ public class ApfTest extends AndroidTestCase { LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); final int[] ethTypeBlackList = {}; ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, ALLOW_802_3_FRAMES, mLog); ALLOW_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); Loading Loading @@ -796,9 +798,10 @@ public class ApfTest extends AndroidTestCase { @SmallTest public void testApfFilterIPv6() throws Exception { final int[] ethTypeBlackList = {}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, mLog); ALLOW_802_3_FRAMES, ethTypeBlackList, mLog); byte[] program = ipManagerCallback.getApfProgram(); // Verify empty IPv6 packet is passed Loading Loading @@ -833,6 +836,7 @@ public class ApfTest extends AndroidTestCase { final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255}; final byte[] multicastIpv4Addr = {(byte)224,0,0,1}; final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb}; final int[] ethTypeBlackList = {}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24); Loading @@ -840,7 +844,7 @@ public class ApfTest extends AndroidTestCase { lp.addLinkAddress(link); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); Loading Loading @@ -903,7 +907,7 @@ public class ApfTest extends AndroidTestCase { ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); assertDrop(program, mcastv4packet.array()); Loading @@ -924,9 +928,10 @@ public class ApfTest extends AndroidTestCase { LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); final int[] ethTypeBlackList = {}; ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, mLog); ALLOW_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); Loading @@ -948,7 +953,7 @@ public class ApfTest extends AndroidTestCase { ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); Loading @@ -968,6 +973,70 @@ public class ApfTest extends AndroidTestCase { apfFilter.shutdown(); } @SmallTest public void testApfFilterEthTypeBL() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); final int[] emptyBlackList = {}; final int[] ipv4BlackList = {ETH_P_IP}; final int[] ipv4Ipv6BlackList = {ETH_P_IP, ETH_P_IPV6}; ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, emptyBlackList, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); // Verify empty packet of 100 zero bytes is passed // Note that eth-type = 0 makes it an IEEE802.3 frame ByteBuffer packet = ByteBuffer.wrap(new byte[100]); assertPass(program, packet.array()); // Verify empty packet with IPv4 is passed packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); assertPass(program, packet.array()); // Verify empty IPv6 packet is passed packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); assertPass(program, packet.array()); // Now add IPv4 to the black list ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, ipv4BlackList, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); // Verify that IPv4 frame will be dropped packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); assertDrop(program, packet.array()); // Verify that IPv6 frame will pass packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); assertPass(program, packet.array()); // Now let us have both IPv4 and IPv6 in the black list ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, ALLOW_802_3_FRAMES, ipv4Ipv6BlackList, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); // Verify that IPv4 frame will be dropped packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); assertDrop(program, packet.array()); // Verify that IPv6 frame will be dropped packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); assertDrop(program, packet.array()); apfFilter.shutdown(); } private byte[] getProgram(MockIpManagerCallback cb, ApfFilter filter, LinkProperties lp) { cb.resetApfProgramWait(); filter.setLinkProperties(lp); Loading @@ -991,9 +1060,10 @@ public class ApfTest extends AndroidTestCase { @SmallTest public void testApfFilterArp() throws Exception { final int[] ethTypeBlackList = {}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); // Verify initially ARP request filter is off, and GARP filter is on. verifyArpFilter(ipManagerCallback.getApfProgram(), PASS); Loading Loading @@ -1114,8 +1184,9 @@ public class ApfTest extends AndroidTestCase { @SmallTest public void testApfFilterRa() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); final int[] ethTypeBlackList = {}; TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); byte[] program = ipManagerCallback.getApfProgram(); final int ROUTER_LIFETIME = 1000; Loading Loading @@ -1256,9 +1327,10 @@ public class ApfTest extends AndroidTestCase { public void testRaParsing() throws Exception { final int maxRandomPacketSize = 512; final Random r = new Random(); final int[] ethTypeBlackList = {}; MockIpManagerCallback cb = new MockIpManagerCallback(); TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); for (int i = 0; i < 1000; i++) { byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)]; r.nextBytes(packet); Loading @@ -1275,9 +1347,10 @@ public class ApfTest extends AndroidTestCase { public void testRaProcessing() throws Exception { final int maxRandomPacketSize = 512; final Random r = new Random(); final int[] ethTypeBlackList = {}; MockIpManagerCallback cb = new MockIpManagerCallback(); TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST, DROP_802_3_FRAMES, mLog); DROP_802_3_FRAMES, ethTypeBlackList, mLog); for (int i = 0; i < 1000; i++) { byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)]; r.nextBytes(packet); Loading