Merge "Move config_apf* resources to NetworkStack" am: 67d47cdf83 am: 7085c94008
Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/1684468
Change-Id: Iea4b815f30231456572790c8b155559a201bee8d
diff --git a/res/values/config.xml b/res/values/config.xml
index d6a11ab..805ca04 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -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>
diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml
index b2967b9..bfb450e 100644
--- a/res/values/overlayable.xml
+++ b/res/values/overlayable.xml
@@ -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>
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index b03d653..a57e99d 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -36,6 +36,7 @@
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;
@@ -94,6 +95,7 @@
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;
@@ -605,6 +607,16 @@
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,
@@ -2195,10 +2207,19 @@
apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;
apfConfig.multicastFilter = mMulticastFiltering;
// Get the Configuration for ApfFilter from Context
- apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames();
- apfConfig.ethTypeBlackList = ApfCapabilities.getApfEtherTypeBlackList();
+ // 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) {
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java
index e991ea7..7260332 100644
--- a/tests/unit/src/android/net/ip/IpClientTest.java
+++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -18,12 +18,14 @@
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;
@@ -48,22 +50,30 @@
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;
@@ -85,6 +95,9 @@
@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";
@@ -631,6 +644,71 @@
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;
}