[NETD-TC#15] Make ConnectivityService and PermissionMonitor
calls BpfNetMaps on T
Since TrafficController moves to mainline module for T, so some netd binder
interfaces revelant to BPF are going to deprecated. Provide JNI APIs to
call TrafficController inside mainline module for T.
Bug: 209935649
Test: atest CtsHostsideNetworkTests
Change-Id: Ib3b43cf2840e02806395af9f1e019ca6fccd032e
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 9d89788..e444a12 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -16,6 +16,8 @@
package com.android.server;
+import android.net.INetd;
+import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.system.Os;
import android.util.Log;
@@ -27,10 +29,19 @@
*/
public class BpfNetMaps {
private static final String TAG = "BpfNetMaps";
+ private final INetd mNetd;
+ // TODO: change USE_JNI to SdkLevel.isAtLeastT()
+ private static final boolean USE_JNI = false;
static {
- System.loadLibrary("traffic_controller_jni");
- native_init();
+ if (USE_JNI) {
+ System.loadLibrary("traffic_controller_jni");
+ native_init();
+ }
+ }
+
+ public BpfNetMaps(INetd netd) {
+ mNetd = netd;
}
/**
@@ -41,6 +52,14 @@
* cause of the failure.
*/
public void addNaughtyApp(final int uid) {
+ if (!USE_JNI) {
+ try {
+ mNetd.bandwidthAddNaughtyApp(uid);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ return;
+ }
final int err = native_addNaughtyApp(uid);
if (err != 0) {
throw new ServiceSpecificException(err, "Unable to add naughty app: "
@@ -56,6 +75,14 @@
* cause of the failure.
*/
public void removeNaughtyApp(final int uid) {
+ if (!USE_JNI) {
+ try {
+ mNetd.bandwidthRemoveNaughtyApp(uid);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ return;
+ }
final int err = native_removeNaughtyApp(uid);
if (err != 0) {
throw new ServiceSpecificException(err, "Unable to remove naughty app: "
@@ -71,6 +98,14 @@
* cause of the failure.
*/
public void addNiceApp(final int uid) {
+ if (!USE_JNI) {
+ try {
+ mNetd.bandwidthAddNiceApp(uid);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ return;
+ }
final int err = native_addNiceApp(uid);
if (err != 0) {
throw new ServiceSpecificException(err, "Unable to add nice app: "
@@ -86,6 +121,14 @@
* cause of the failure.
*/
public void removeNiceApp(final int uid) {
+ if (!USE_JNI) {
+ try {
+ mNetd.bandwidthRemoveNiceApp(uid);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ return;
+ }
final int err = native_removeNiceApp(uid);
if (err != 0) {
throw new ServiceSpecificException(err, "Unable to remove nice app: "
@@ -102,6 +145,14 @@
* cause of the failure.
*/
public void setChildChain(final int childChain, final boolean enable) {
+ if (!USE_JNI) {
+ try {
+ mNetd.firewallEnableChildChain(childChain, enable);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ return;
+ }
final int err = native_setChildChain(childChain, enable);
if (err != 0) {
throw new ServiceSpecificException(-err, "Unable to set child chain: "
@@ -124,6 +175,14 @@
*/
public int replaceUidChain(final String chainName, final boolean isAllowlist,
final int[] uids) {
+ if (!USE_JNI) {
+ try {
+ mNetd.firewallReplaceUidChain(chainName, isAllowlist, uids);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ return 0;
+ }
final int err = native_replaceUidChain(chainName, isAllowlist, uids);
if (err != 0) {
Log.e(TAG, "replaceUidChain failed: " + Os.strerror(-err));
@@ -140,8 +199,15 @@
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the failure.
*/
- public void setUidRule(final int childChain, final int uid,
- final int firewallRule) {
+ public void setUidRule(final int childChain, final int uid, final int firewallRule) {
+ if (!USE_JNI) {
+ try {
+ mNetd.firewallSetUidRule(childChain, uid, firewallRule);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ return;
+ }
final int err = native_setUidRule(childChain, uid, firewallRule);
if (err != 0) {
throw new ServiceSpecificException(-err, "Unable to set uid rule: "
@@ -166,6 +232,14 @@
* cause of the failure.
*/
public void addUidInterfaceRules(final String ifName, final int[] uids) {
+ if (!USE_JNI) {
+ try {
+ mNetd.firewallAddUidInterfaceRules(ifName, uids);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception when updating permissions: " + e);
+ }
+ return;
+ }
final int err = native_addUidInterfaceRules(ifName, uids);
if (err != 0) {
throw new ServiceSpecificException(err, "Unable to add uid interface rules: "
@@ -184,6 +258,14 @@
* cause of the failure.
*/
public void removeUidInterfaceRules(final int[] uids) {
+ if (!USE_JNI) {
+ try {
+ mNetd.firewallRemoveUidInterfaceRules(uids);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception when updating permissions: " + e);
+ }
+ return;
+ }
final int err = native_removeUidInterfaceRules(uids);
if (err != 0) {
throw new ServiceSpecificException(err, "Unable to remove uid interface rules: "
@@ -197,6 +279,14 @@
* cause of the failure.
*/
public void swapActiveStatsMap() {
+ if (!USE_JNI) {
+ try {
+ mNetd.trafficSwapActiveStatsMap();
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ return;
+ }
final int err = native_swapActiveStatsMap();
if (err != 0) {
throw new ServiceSpecificException(err, "Unable to swap active stats map: "
@@ -213,8 +303,16 @@
* revoke all permissions for the uids.
* @param uids uid of users to grant permission
*/
- public void setNetPermForUids(final int permission, final int[] uids) {
- native_setPermissionForUids(permission, uids);
+ public void setNetPermForUids(final int permissions, final int[] uids) {
+ if (!USE_JNI) {
+ try {
+ mNetd.trafficSetNetPermForUids(permissions, uids);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Pass appId list of special permission failed." + e);
+ }
+ return;
+ }
+ native_setPermissionForUids(permissions, uids);
}
/**
@@ -255,7 +353,7 @@
private native int native_addUidInterfaceRules(String ifName, int[] uids);
private native int native_removeUidInterfaceRules(int[] uids);
private native int native_swapActiveStatsMap();
- private native void native_setPermissionForUids(int permission, int[] uids);
+ private native void native_setPermissionForUids(int permissions, int[] uids);
private native int native_setCounterSet(int counterSet, int uid);
private native int native_deleteTagData(int tag, int uid);
}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index fa7dfa9..0259f7d 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -396,6 +396,7 @@
private NetworkStatsManager mStatsManager;
private NetworkPolicyManager mPolicyManager;
private final NetdCallback mNetdCallback;
+ private final BpfNetMaps mBpfNetMaps;
/**
* TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
@@ -1335,6 +1336,15 @@
return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name,
TETHERING_MODULE_NAME, defaultEnabled);
}
+
+ /**
+ * Get the BpfNetMaps implementation to use in ConnectivityService.
+ * @param netd
+ * @return BpfNetMaps implementation.
+ */
+ public BpfNetMaps getBpfNetMaps(INetd netd) {
+ return new BpfNetMaps(netd);
+ }
}
public ConnectivityService(Context context) {
@@ -1403,6 +1413,7 @@
mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
mNetd = netd;
+ mBpfNetMaps = mDeps.getBpfNetMaps(netd);
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
@@ -1430,7 +1441,7 @@
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
+ mPermissionMonitor = new PermissionMonitor(mContext, mNetd, mBpfNetMaps);
mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
// Listen for user add/removes to inform PermissionMonitor.
@@ -10709,11 +10720,11 @@
try {
if (add) {
- mNetd.bandwidthAddNiceApp(uid);
+ mBpfNetMaps.addNiceApp(uid);
} else {
- mNetd.bandwidthRemoveNiceApp(uid);
+ mBpfNetMaps.removeNiceApp(uid);
}
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -10724,11 +10735,11 @@
try {
if (add) {
- mNetd.bandwidthAddNaughtyApp(uid);
+ mBpfNetMaps.addNaughtyApp(uid);
} else {
- mNetd.bandwidthRemoveNaughtyApp(uid);
+ mBpfNetMaps.removeNaughtyApp(uid);
}
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -10738,9 +10749,9 @@
enforceNetworkStackOrSettingsPermission();
try {
- mNetd.firewallSetUidRule(chain, uid,
+ mBpfNetMaps.setUidRule(chain, uid,
allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY);
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -10750,8 +10761,8 @@
enforceNetworkStackOrSettingsPermission();
try {
- mNetd.firewallEnableChildChain(chain, enable);
- } catch (RemoteException | ServiceSpecificException e) {
+ mBpfNetMaps.setChildChain(chain, enable);
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -10763,22 +10774,22 @@
try {
switch (chain) {
case ConnectivityManager.FIREWALL_CHAIN_DOZABLE:
- mNetd.firewallReplaceUidChain("fw_dozable", true /* isAllowList */, uids);
+ mBpfNetMaps.replaceUidChain("fw_dozable", true /* isAllowList */, uids);
break;
case ConnectivityManager.FIREWALL_CHAIN_STANDBY:
- mNetd.firewallReplaceUidChain("fw_standby", false /* isAllowList */, uids);
+ mBpfNetMaps.replaceUidChain("fw_standby", false /* isAllowList */, uids);
break;
case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE:
- mNetd.firewallReplaceUidChain("fw_powersave", true /* isAllowList */, uids);
+ mBpfNetMaps.replaceUidChain("fw_powersave", true /* isAllowList */, uids);
break;
case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED:
- mNetd.firewallReplaceUidChain("fw_restricted", true /* isAllowList */, uids);
+ mBpfNetMaps.replaceUidChain("fw_restricted", true /* isAllowList */, uids);
break;
default:
throw new IllegalArgumentException("replaceFirewallChain with invalid chain: "
+ chain);
}
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -10787,8 +10798,8 @@
public void swapActiveStatsMap() {
enforceNetworkStackOrSettingsPermission();
try {
- mNetd.trafficSwapActiveStatsMap();
- } catch (RemoteException | ServiceSpecificException e) {
+ mBpfNetMaps.swapActiveStatsMap();
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index 439db89..c9c1776 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -68,6 +68,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.net.module.util.CollectionUtils;
+import com.android.server.BpfNetMaps;
import java.util.ArrayList;
import java.util.HashMap;
@@ -93,6 +94,7 @@
private final INetd mNetd;
private final Dependencies mDeps;
private final Context mContext;
+ private final BpfNetMaps mBpfNetMaps;
@GuardedBy("this")
private final Set<UserHandle> mUsers = new HashSet<>();
@@ -184,12 +186,14 @@
}
}
- public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) {
- this(context, netd, new Dependencies());
+ public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd,
+ @NonNull final BpfNetMaps bpfNetMaps) {
+ this(context, netd, bpfNetMaps, new Dependencies());
}
@VisibleForTesting
PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd,
+ @NonNull final BpfNetMaps bpfNetMaps,
@NonNull final Dependencies deps) {
mPackageManager = context.getPackageManager();
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
@@ -197,6 +201,7 @@
mNetd = netd;
mDeps = deps;
mContext = context;
+ mBpfNetMaps = bpfNetMaps;
}
private int getPackageNetdNetworkPermission(@NonNull final PackageInfo app) {
@@ -803,9 +808,9 @@
}
try {
if (add) {
- mNetd.firewallAddUidInterfaceRules(iface, toIntArray(uids));
+ mBpfNetMaps.addUidInterfaceRules(iface, toIntArray(uids));
} else {
- mNetd.firewallRemoveUidInterfaceRules(toIntArray(uids));
+ mBpfNetMaps.removeUidInterfaceRules(toIntArray(uids));
}
} catch (ServiceSpecificException e) {
// Silently ignore exception when device does not support eBPF, otherwise just log
@@ -813,8 +818,6 @@
if (e.errorCode != OsConstants.EOPNOTSUPP) {
loge("Exception when updating permissions: ", e);
}
- } catch (RemoteException e) {
- loge("Exception when updating permissions: ", e);
}
}
@@ -878,26 +881,27 @@
try {
// TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids()
if (allPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(
+ mBpfNetMaps.setNetPermForUids(
PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS,
toIntArray(allPermissionAppIds));
}
if (internetPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(PERMISSION_INTERNET,
+ mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET,
toIntArray(internetPermissionAppIds));
}
if (updateStatsPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS,
+ mBpfNetMaps.setNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS,
toIntArray(updateStatsPermissionAppIds));
}
if (noPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(PERMISSION_NONE, toIntArray(noPermissionAppIds));
+ mBpfNetMaps.setNetPermForUids(PERMISSION_NONE,
+ toIntArray(noPermissionAppIds));
}
if (uninstalledAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(PERMISSION_UNINSTALLED,
+ mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED,
toIntArray(uninstalledAppIds));
}
- } catch (RemoteException e) {
+ } catch (ServiceSpecificException e) {
Log.e(TAG, "Pass appId list of special permission failed." + e);
}
}