Add flag to test BpfNetMaps refactoring

Following CLs will switch previous codepath (JNI) and new codepath
(Java) for bpf map operations based on this flag.

Bug: 217624062
Test: atest BpfNetMapsTest
Change-Id: I74f10d5c97390993acea110f6528ef8980bb2aa4
This commit is contained in:
Motomu Utsumi
2022-07-22 03:47:35 +00:00
parent 6bcb3c290c
commit f688eeb10a
6 changed files with 39 additions and 14 deletions

View File

@@ -164,7 +164,7 @@ public class NetworkStatsFactory {
} }
public NetworkStatsFactory(@NonNull Context ctx) { public NetworkStatsFactory(@NonNull Context ctx) {
this(ctx, new File("/proc/"), true, new BpfNetMaps()); this(ctx, new File("/proc/"), true, new BpfNetMaps(ctx));
} }
@VisibleForTesting @VisibleForTesting

View File

@@ -31,9 +31,11 @@ import static android.system.OsConstants.ENODEV;
import static android.system.OsConstants.ENOENT; import static android.system.OsConstants.ENOENT;
import static android.system.OsConstants.EOPNOTSUPP; import static android.system.OsConstants.EOPNOTSUPP;
import android.content.Context;
import android.net.INetd; import android.net.INetd;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceSpecificException; import android.os.ServiceSpecificException;
import android.provider.DeviceConfig;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
import android.util.Log; import android.util.Log;
@@ -42,6 +44,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel; import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BpfMap; import com.android.net.module.util.BpfMap;
import com.android.net.module.util.DeviceConfigUtils;
import com.android.net.module.util.Struct.U32; import com.android.net.module.util.Struct.U32;
import java.io.FileDescriptor; import java.io.FileDescriptor;
@@ -70,6 +73,10 @@ public class BpfNetMaps {
// Use legacy netd for releases before T. // Use legacy netd for releases before T.
private static boolean sInitialized = false; private static boolean sInitialized = false;
private static Boolean sEnableJavaBpfMap = null;
private static final String BPF_NET_MAPS_ENABLE_JAVA_BPF_MAP =
"bpf_net_maps_enable_java_bpf_map";
// Lock for sConfigurationMap entry for UID_RULES_CONFIGURATION_KEY. // Lock for sConfigurationMap entry for UID_RULES_CONFIGURATION_KEY.
// This entry is not accessed by others. // This entry is not accessed by others.
// BpfNetMaps acquires this lock while sequence of read, modify, and write. // BpfNetMaps acquires this lock while sequence of read, modify, and write.
@@ -100,6 +107,14 @@ public class BpfNetMaps {
@VisibleForTesting public static final long OEM_DENY_3_MATCH = (1 << 11); @VisibleForTesting public static final long OEM_DENY_3_MATCH = (1 << 11);
// LINT.ThenChange(packages/modules/Connectivity/bpf_progs/bpf_shared.h) // LINT.ThenChange(packages/modules/Connectivity/bpf_progs/bpf_shared.h)
/**
* Set sEnableJavaBpfMap for test.
*/
@VisibleForTesting
public static void setEnableJavaBpfMapForTest(boolean enable) {
sEnableJavaBpfMap = enable;
}
/** /**
* Set configurationMap for test. * Set configurationMap for test.
*/ */
@@ -147,8 +162,15 @@ public class BpfNetMaps {
* Initializes the class if it is not already initialized. This method will open maps but not * Initializes the class if it is not already initialized. This method will open maps but not
* cause any other effects. This method may be called multiple times on any thread. * cause any other effects. This method may be called multiple times on any thread.
*/ */
private static synchronized void ensureInitialized() { private static synchronized void ensureInitialized(final Context context) {
if (sInitialized) return; if (sInitialized) return;
if (sEnableJavaBpfMap == null) {
sEnableJavaBpfMap = DeviceConfigUtils.isFeatureEnabled(context,
DeviceConfig.NAMESPACE_TETHERING, BPF_NET_MAPS_ENABLE_JAVA_BPF_MAP,
SdkLevel.isAtLeastU() /* defaultValue */);
}
Log.d(TAG, "BpfNetMaps is initialized with sEnableJavaBpfMap=" + sEnableJavaBpfMap);
setBpfMaps(); setBpfMaps();
native_init(); native_init();
sInitialized = true; sInitialized = true;
@@ -168,20 +190,20 @@ public class BpfNetMaps {
} }
/** Constructor used after T that doesn't need to use netd anymore. */ /** Constructor used after T that doesn't need to use netd anymore. */
public BpfNetMaps() { public BpfNetMaps(final Context context) {
this(null); this(context, null);
if (PRE_T) throw new IllegalArgumentException("BpfNetMaps need to use netd before T"); if (PRE_T) throw new IllegalArgumentException("BpfNetMaps need to use netd before T");
} }
public BpfNetMaps(final INetd netd) { public BpfNetMaps(final Context context, final INetd netd) {
this(netd, new Dependencies()); this(context, netd, new Dependencies());
} }
@VisibleForTesting @VisibleForTesting
public BpfNetMaps(final INetd netd, final Dependencies deps) { public BpfNetMaps(final Context context, final INetd netd, final Dependencies deps) {
if (!PRE_T) { if (!PRE_T) {
ensureInitialized(); ensureInitialized(context);
} }
mNetd = netd; mNetd = netd;
mDeps = deps; mDeps = deps;

View File

@@ -1399,8 +1399,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
* @param netd * @param netd
* @return BpfNetMaps implementation. * @return BpfNetMaps implementation.
*/ */
public BpfNetMaps getBpfNetMaps(INetd netd) { public BpfNetMaps getBpfNetMaps(Context context, INetd netd) {
return new BpfNetMaps(netd); return new BpfNetMaps(context, netd);
} }
/** /**
@@ -1529,7 +1529,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
mNetd = netd; mNetd = netd;
mBpfNetMaps = mDeps.getBpfNetMaps(netd); mBpfNetMaps = mDeps.getBpfNetMaps(mContext, netd);
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext); mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);

View File

@@ -209,7 +209,7 @@ class ConnectivityServiceIntegrationTest {
doReturn(mock(ProxyTracker::class.java)).`when`(deps).makeProxyTracker(any(), any()) doReturn(mock(ProxyTracker::class.java)).`when`(deps).makeProxyTracker(any(), any())
doReturn(mock(MockableSystemProperties::class.java)).`when`(deps).systemProperties doReturn(mock(MockableSystemProperties::class.java)).`when`(deps).systemProperties
doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager() doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager()
doReturn(mock(BpfNetMaps::class.java)).`when`(deps).getBpfNetMaps(any()) doReturn(mock(BpfNetMaps::class.java)).`when`(deps).getBpfNetMaps(any(), any())
doAnswer { inv -> doAnswer { inv ->
object : MultinetworkPolicyTracker(inv.getArgument(0), inv.getArgument(1), object : MultinetworkPolicyTracker(inv.getArgument(0), inv.getArgument(1),
inv.getArgument(2)) { inv.getArgument(2)) {

View File

@@ -46,6 +46,7 @@ import static org.junit.Assume.assumeFalse;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import android.content.Context;
import android.net.INetd; import android.net.INetd;
import android.os.Build; import android.os.Build;
import android.os.ServiceSpecificException; import android.os.ServiceSpecificException;
@@ -102,6 +103,7 @@ public final class BpfNetMapsTest {
@Mock INetd mNetd; @Mock INetd mNetd;
@Mock BpfNetMaps.Dependencies mDeps; @Mock BpfNetMaps.Dependencies mDeps;
@Mock Context mContext;
private final BpfMap<U32, U32> mConfigurationMap = new TestBpfMap<>(U32.class, U32.class); private final BpfMap<U32, U32> mConfigurationMap = new TestBpfMap<>(U32.class, U32.class);
private final BpfMap<U32, UidOwnerValue> mUidOwnerMap = private final BpfMap<U32, UidOwnerValue> mUidOwnerMap =
new TestBpfMap<>(U32.class, UidOwnerValue.class); new TestBpfMap<>(U32.class, UidOwnerValue.class);
@@ -110,9 +112,10 @@ public final class BpfNetMapsTest {
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
doReturn(TEST_IF_INDEX).when(mDeps).getIfIndex(TEST_IF_NAME); doReturn(TEST_IF_INDEX).when(mDeps).getIfIndex(TEST_IF_NAME);
BpfNetMaps.setEnableJavaBpfMapForTest(true /* enable */);
BpfNetMaps.setConfigurationMapForTest(mConfigurationMap); BpfNetMaps.setConfigurationMapForTest(mConfigurationMap);
BpfNetMaps.setUidOwnerMapForTest(mUidOwnerMap); BpfNetMaps.setUidOwnerMapForTest(mUidOwnerMap);
mBpfNetMaps = new BpfNetMaps(mNetd, mDeps); mBpfNetMaps = new BpfNetMaps(mContext, mNetd, mDeps);
} }
@Test @Test

View File

@@ -2061,7 +2061,7 @@ public class ConnectivityServiceTest {
} }
@Override @Override
public BpfNetMaps getBpfNetMaps(INetd netd) { public BpfNetMaps getBpfNetMaps(Context context, INetd netd) {
return mBpfNetMaps; return mBpfNetMaps;
} }