Loading res/values/config.xml +16 −0 Original line number Diff line number Diff line Loading @@ -105,4 +105,20 @@ increased until reaching the config_max_retry_timer. --> <integer name="config_evaluating_bandwidth_min_retry_timer_ms"></integer> <integer name="config_evaluating_bandwidth_max_retry_timer_ms"></integer> <!-- Whether the APF Filter in the device should filter out IEEE 802.3 Frames Those frames are identified by the field Eth-type having values less than 0x600 --> <bool name="config_apfDrop802_3Frames">true</bool> <!-- An array of Denylisted EtherType, packets with EtherTypes within this array will be dropped TODO: need to put proper values, these are for testing purposes only --> <integer-array name="config_apfEthTypeDenyList"> <item>0x88A2</item> <item>0x88A4</item> <item>0x88B8</item> <item>0x88CD</item> <item>0x88E3</item> </integer-array> </resources> res/values/overlayable.xml +7 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,13 @@ <item type="integer" name="config_evaluating_bandwidth_timeout_ms"/> <item type="integer" name="config_evaluating_bandwidth_min_retry_timer_ms"/> <item type="integer" name="config_evaluating_bandwidth_max_retry_timer_ms"/> <!-- Whether the APF Filter in the device should filter out IEEE 802.3 Frames Those frames are identified by the field Eth-type having values less than 0x600 --> <item type="bool" name="config_apfDrop802_3Frames"/> <!-- An array of Denylisted EtherType, packets with EtherTypes within this array will be dropped --> <item type="array" name="config_apfEthTypeDenyList"/> </policy> </overlayable> </resources> src/android/net/ip/IpClient.java +24 −3 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import static com.android.net.module.util.NetworkStackConstants.VENDOR_SPECIFIC_ import static com.android.server.util.PermissionUtil.enforceNetworkStackCallingPermission; import android.content.Context; import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.DhcpResults; import android.net.INetd; Loading Loading @@ -94,6 +95,7 @@ import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.WakeupMessage; import com.android.net.module.util.DeviceConfigUtils; import com.android.networkstack.R; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; import com.android.networkstack.apishim.common.NetworkInformationShim; Loading Loading @@ -605,6 +607,16 @@ public class IpClient extends StateMachine { return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name, defaultEnabled); } /** * Create an APF filter if apfCapabilities indicates support for packet filtering using * APF programs. * @see ApfFilter#maybeCreate */ public ApfFilter maybeCreateApfFilter(Context context, ApfFilter.ApfConfiguration config, InterfaceParams ifParams, IpClientCallbacksWrapper cb) { return ApfFilter.maybeCreate(context, config, ifParams, cb); } } public IpClient(Context context, String ifName, IIpClientCallbacks callback, Loading Loading @@ -2195,10 +2207,19 @@ public class IpClient extends StateMachine { apfConfig.apfCapabilities = mConfiguration.mApfCapabilities; apfConfig.multicastFilter = mMulticastFiltering; // Get the Configuration for ApfFilter from Context // Resource settings were moved from ApfCapabilities APIs to NetworkStack resources in S if (ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.R)) { final Resources res = mContext.getResources(); apfConfig.ieee802_3Filter = res.getBoolean(R.bool.config_apfDrop802_3Frames); apfConfig.ethTypeBlackList = res.getIntArray(R.array.config_apfEthTypeDenyList); } else { apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames(); apfConfig.ethTypeBlackList = ApfCapabilities.getApfEtherTypeBlackList(); } apfConfig.minRdnssLifetimeSec = mMinRdnssLifetimeSec; mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback); mApfFilter = mDependencies.maybeCreateApfFilter(mContext, apfConfig, mInterfaceParams, mCallback); // TODO: investigate the effects of any multicast filtering racing/interfering with the // rest of this IP configuration startup. if (mApfFilter == null) { Loading tests/unit/src/android/net/ip/IpClientTest.java +78 −0 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ package android.net.ip; import static android.system.OsConstants.RT_SCOPE_UNIVERSE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; Loading @@ -48,22 +50,30 @@ import android.net.LinkProperties; import android.net.MacAddress; import android.net.NetworkStackIpMemoryStore; import android.net.RouteInfo; import android.net.apf.ApfCapabilities; import android.net.apf.ApfFilter.ApfConfiguration; import android.net.ipmemorystore.NetworkAttributes; import android.net.metrics.IpConnectivityLog; import android.net.shared.InitialConfiguration; import android.net.shared.ProvisioningConfiguration; import android.net.util.InterfaceParams; import android.os.Build; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.networkstack.R; import com.android.server.NetworkObserver; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService; import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService; import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; import com.android.testutils.HandlerUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; Loading @@ -85,6 +95,9 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) @SmallTest public class IpClientTest { @Rule public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(); private static final String VALID = "VALID"; private static final String INVALID = "INVALID"; private static final String TEST_IFNAME = "test_wlan0"; Loading Loading @@ -631,6 +644,71 @@ public class IpClientTest { return out; } private ApfConfiguration verifyApfFilterCreatedOnStart(IpClient ipc) { ProvisioningConfiguration config = new ProvisioningConfiguration.Builder() .withoutIPv4() .withoutIpReachabilityMonitor() .withInitialConfiguration( conf(links(TEST_LOCAL_ADDRESSES), prefixes(TEST_PREFIXES), ips())) .withApfCapabilities(new ApfCapabilities( 4 /* version */, 4096 /* maxProgramSize */, 4 /* format */)) .build(); ipc.startProvisioning(config); final ArgumentCaptor<ApfConfiguration> configCaptor = ArgumentCaptor.forClass( ApfConfiguration.class); verify(mDependencies, timeout(TEST_TIMEOUT_MS)).maybeCreateApfFilter( any(), configCaptor.capture(), any(), any()); return configCaptor.getValue(); } @Test @IgnoreAfter(Build.VERSION_CODES.R) public void testApfConfiguration_R() throws Exception { final IpClient ipc = makeIpClient(TEST_IFNAME); final ApfConfiguration config = verifyApfFilterCreatedOnStart(ipc); assertEquals(ApfCapabilities.getApfDrop8023Frames(), config.ieee802_3Filter); assertArrayEquals(ApfCapabilities.getApfEtherTypeBlackList(), config.ethTypeBlackList); verify(mResources, never()).getBoolean(R.bool.config_apfDrop802_3Frames); verify(mResources, never()).getIntArray(R.array.config_apfEthTypeDenyList); verifyShutdown(ipc); } @Test @IgnoreUpTo(Build.VERSION_CODES.R) public void testApfConfiguration() throws Exception { doReturn(true).when(mResources).getBoolean(R.bool.config_apfDrop802_3Frames); final int[] ethTypeDenyList = new int[] { 0x88A2, 0x88A4 }; doReturn(ethTypeDenyList).when(mResources).getIntArray( R.array.config_apfEthTypeDenyList); final IpClient ipc = makeIpClient(TEST_IFNAME); final ApfConfiguration config = verifyApfFilterCreatedOnStart(ipc); assertTrue(config.ieee802_3Filter); assertArrayEquals(ethTypeDenyList, config.ethTypeBlackList); verifyShutdown(ipc); } @Test @IgnoreUpTo(Build.VERSION_CODES.R) public void testApfConfiguration_NoApfDrop8023Frames() throws Exception { doReturn(false).when(mResources).getBoolean(R.bool.config_apfDrop802_3Frames); final int[] ethTypeDenyList = new int[] { 0x88A3, 0x88A5 }; doReturn(ethTypeDenyList).when(mResources).getIntArray( R.array.config_apfEthTypeDenyList); final IpClient ipc = makeIpClient(TEST_IFNAME); final ApfConfiguration config = verifyApfFilterCreatedOnStart(ipc); assertFalse(config.ieee802_3Filter); assertArrayEquals(ethTypeDenyList, config.ethTypeBlackList); verifyShutdown(ipc); } interface Fn<A,B> { B call(A a) throws Exception; } Loading Loading
res/values/config.xml +16 −0 Original line number Diff line number Diff line Loading @@ -105,4 +105,20 @@ increased until reaching the config_max_retry_timer. --> <integer name="config_evaluating_bandwidth_min_retry_timer_ms"></integer> <integer name="config_evaluating_bandwidth_max_retry_timer_ms"></integer> <!-- Whether the APF Filter in the device should filter out IEEE 802.3 Frames Those frames are identified by the field Eth-type having values less than 0x600 --> <bool name="config_apfDrop802_3Frames">true</bool> <!-- An array of Denylisted EtherType, packets with EtherTypes within this array will be dropped TODO: need to put proper values, these are for testing purposes only --> <integer-array name="config_apfEthTypeDenyList"> <item>0x88A2</item> <item>0x88A4</item> <item>0x88B8</item> <item>0x88CD</item> <item>0x88E3</item> </integer-array> </resources>
res/values/overlayable.xml +7 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,13 @@ <item type="integer" name="config_evaluating_bandwidth_timeout_ms"/> <item type="integer" name="config_evaluating_bandwidth_min_retry_timer_ms"/> <item type="integer" name="config_evaluating_bandwidth_max_retry_timer_ms"/> <!-- Whether the APF Filter in the device should filter out IEEE 802.3 Frames Those frames are identified by the field Eth-type having values less than 0x600 --> <item type="bool" name="config_apfDrop802_3Frames"/> <!-- An array of Denylisted EtherType, packets with EtherTypes within this array will be dropped --> <item type="array" name="config_apfEthTypeDenyList"/> </policy> </overlayable> </resources>
src/android/net/ip/IpClient.java +24 −3 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import static com.android.net.module.util.NetworkStackConstants.VENDOR_SPECIFIC_ import static com.android.server.util.PermissionUtil.enforceNetworkStackCallingPermission; import android.content.Context; import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.DhcpResults; import android.net.INetd; Loading Loading @@ -94,6 +95,7 @@ import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.WakeupMessage; import com.android.net.module.util.DeviceConfigUtils; import com.android.networkstack.R; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; import com.android.networkstack.apishim.common.NetworkInformationShim; Loading Loading @@ -605,6 +607,16 @@ public class IpClient extends StateMachine { return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name, defaultEnabled); } /** * Create an APF filter if apfCapabilities indicates support for packet filtering using * APF programs. * @see ApfFilter#maybeCreate */ public ApfFilter maybeCreateApfFilter(Context context, ApfFilter.ApfConfiguration config, InterfaceParams ifParams, IpClientCallbacksWrapper cb) { return ApfFilter.maybeCreate(context, config, ifParams, cb); } } public IpClient(Context context, String ifName, IIpClientCallbacks callback, Loading Loading @@ -2195,10 +2207,19 @@ public class IpClient extends StateMachine { apfConfig.apfCapabilities = mConfiguration.mApfCapabilities; apfConfig.multicastFilter = mMulticastFiltering; // Get the Configuration for ApfFilter from Context // Resource settings were moved from ApfCapabilities APIs to NetworkStack resources in S if (ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.R)) { final Resources res = mContext.getResources(); apfConfig.ieee802_3Filter = res.getBoolean(R.bool.config_apfDrop802_3Frames); apfConfig.ethTypeBlackList = res.getIntArray(R.array.config_apfEthTypeDenyList); } else { apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames(); apfConfig.ethTypeBlackList = ApfCapabilities.getApfEtherTypeBlackList(); } apfConfig.minRdnssLifetimeSec = mMinRdnssLifetimeSec; mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback); mApfFilter = mDependencies.maybeCreateApfFilter(mContext, apfConfig, mInterfaceParams, mCallback); // TODO: investigate the effects of any multicast filtering racing/interfering with the // rest of this IP configuration startup. if (mApfFilter == null) { Loading
tests/unit/src/android/net/ip/IpClientTest.java +78 −0 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ package android.net.ip; import static android.system.OsConstants.RT_SCOPE_UNIVERSE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; Loading @@ -48,22 +50,30 @@ import android.net.LinkProperties; import android.net.MacAddress; import android.net.NetworkStackIpMemoryStore; import android.net.RouteInfo; import android.net.apf.ApfCapabilities; import android.net.apf.ApfFilter.ApfConfiguration; import android.net.ipmemorystore.NetworkAttributes; import android.net.metrics.IpConnectivityLog; import android.net.shared.InitialConfiguration; import android.net.shared.ProvisioningConfiguration; import android.net.util.InterfaceParams; import android.os.Build; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.networkstack.R; import com.android.server.NetworkObserver; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService; import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService; import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; import com.android.testutils.HandlerUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; Loading @@ -85,6 +95,9 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) @SmallTest public class IpClientTest { @Rule public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(); private static final String VALID = "VALID"; private static final String INVALID = "INVALID"; private static final String TEST_IFNAME = "test_wlan0"; Loading Loading @@ -631,6 +644,71 @@ public class IpClientTest { return out; } private ApfConfiguration verifyApfFilterCreatedOnStart(IpClient ipc) { ProvisioningConfiguration config = new ProvisioningConfiguration.Builder() .withoutIPv4() .withoutIpReachabilityMonitor() .withInitialConfiguration( conf(links(TEST_LOCAL_ADDRESSES), prefixes(TEST_PREFIXES), ips())) .withApfCapabilities(new ApfCapabilities( 4 /* version */, 4096 /* maxProgramSize */, 4 /* format */)) .build(); ipc.startProvisioning(config); final ArgumentCaptor<ApfConfiguration> configCaptor = ArgumentCaptor.forClass( ApfConfiguration.class); verify(mDependencies, timeout(TEST_TIMEOUT_MS)).maybeCreateApfFilter( any(), configCaptor.capture(), any(), any()); return configCaptor.getValue(); } @Test @IgnoreAfter(Build.VERSION_CODES.R) public void testApfConfiguration_R() throws Exception { final IpClient ipc = makeIpClient(TEST_IFNAME); final ApfConfiguration config = verifyApfFilterCreatedOnStart(ipc); assertEquals(ApfCapabilities.getApfDrop8023Frames(), config.ieee802_3Filter); assertArrayEquals(ApfCapabilities.getApfEtherTypeBlackList(), config.ethTypeBlackList); verify(mResources, never()).getBoolean(R.bool.config_apfDrop802_3Frames); verify(mResources, never()).getIntArray(R.array.config_apfEthTypeDenyList); verifyShutdown(ipc); } @Test @IgnoreUpTo(Build.VERSION_CODES.R) public void testApfConfiguration() throws Exception { doReturn(true).when(mResources).getBoolean(R.bool.config_apfDrop802_3Frames); final int[] ethTypeDenyList = new int[] { 0x88A2, 0x88A4 }; doReturn(ethTypeDenyList).when(mResources).getIntArray( R.array.config_apfEthTypeDenyList); final IpClient ipc = makeIpClient(TEST_IFNAME); final ApfConfiguration config = verifyApfFilterCreatedOnStart(ipc); assertTrue(config.ieee802_3Filter); assertArrayEquals(ethTypeDenyList, config.ethTypeBlackList); verifyShutdown(ipc); } @Test @IgnoreUpTo(Build.VERSION_CODES.R) public void testApfConfiguration_NoApfDrop8023Frames() throws Exception { doReturn(false).when(mResources).getBoolean(R.bool.config_apfDrop802_3Frames); final int[] ethTypeDenyList = new int[] { 0x88A3, 0x88A5 }; doReturn(ethTypeDenyList).when(mResources).getIntArray( R.array.config_apfEthTypeDenyList); final IpClient ipc = makeIpClient(TEST_IFNAME); final ApfConfiguration config = verifyApfFilterCreatedOnStart(ipc); assertFalse(config.ieee802_3Filter); assertArrayEquals(ethTypeDenyList, config.ethTypeBlackList); verifyShutdown(ipc); } interface Fn<A,B> { B call(A a) throws Exception; } Loading