Remove native code path in BpfNetMaps.java
BpfNetMaps uses java library for updating bpf map as the default code path. This is already released to 100% production without any issues. So this CL removes the old code path from BpfNetMaps. Note that native_init only opens the bpf maps if sEnableJavaBpfMap is true. But if sEnableJavaBpfMap is true, no native code in TrafficController access the bpf map. So this CL can remove native_init. Following CL will remove the nativce codes for old code path. Bug: 217624062 Test: NetworkStaticLibsTests Change-Id: Ifba198d9e6f93b53fd1dbf3b2aafb644da0b147d
This commit is contained in:
@@ -34,14 +34,6 @@ import static android.net.BpfNetMapsUtils.PRE_T;
|
|||||||
import static android.net.BpfNetMapsUtils.getMatchByFirewallChain;
|
import static android.net.BpfNetMapsUtils.getMatchByFirewallChain;
|
||||||
import static android.net.BpfNetMapsUtils.isFirewallAllowList;
|
import static android.net.BpfNetMapsUtils.isFirewallAllowList;
|
||||||
import static android.net.BpfNetMapsUtils.matchToString;
|
import static android.net.BpfNetMapsUtils.matchToString;
|
||||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
|
|
||||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
|
|
||||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1;
|
|
||||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2;
|
|
||||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3;
|
|
||||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
|
|
||||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
|
|
||||||
import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
|
|
||||||
import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
|
import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
|
||||||
import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
|
import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
|
||||||
import static android.net.INetd.PERMISSION_INTERNET;
|
import static android.net.INetd.PERMISSION_INTERNET;
|
||||||
@@ -75,10 +67,8 @@ import androidx.annotation.RequiresApi;
|
|||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.modules.utils.BackgroundThread;
|
import com.android.modules.utils.BackgroundThread;
|
||||||
import com.android.modules.utils.build.SdkLevel;
|
|
||||||
import com.android.net.module.util.BpfDump;
|
import com.android.net.module.util.BpfDump;
|
||||||
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.IBpfMap;
|
import com.android.net.module.util.IBpfMap;
|
||||||
import com.android.net.module.util.Struct;
|
import com.android.net.module.util.Struct;
|
||||||
import com.android.net.module.util.Struct.S32;
|
import com.android.net.module.util.Struct.S32;
|
||||||
@@ -112,7 +102,6 @@ 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_FORCE_DISABLE_JAVA_BPF_MAP =
|
private static final String BPF_NET_MAPS_FORCE_DISABLE_JAVA_BPF_MAP =
|
||||||
"bpf_net_maps_force_disable_java_bpf_map";
|
"bpf_net_maps_force_disable_java_bpf_map";
|
||||||
|
|
||||||
@@ -143,14 +132,6 @@ public class BpfNetMaps {
|
|||||||
Pair.create(PERMISSION_UPDATE_DEVICE_STATS, "PERMISSION_UPDATE_DEVICE_STATS")
|
Pair.create(PERMISSION_UPDATE_DEVICE_STATS, "PERMISSION_UPDATE_DEVICE_STATS")
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set sEnableJavaBpfMap for test.
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
public static void setEnableJavaBpfMapForTest(boolean enable) {
|
|
||||||
sEnableJavaBpfMap = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set configurationMap for test.
|
* Set configurationMap for test.
|
||||||
*/
|
*/
|
||||||
@@ -287,20 +268,12 @@ public class BpfNetMaps {
|
|||||||
*/
|
*/
|
||||||
private static synchronized void ensureInitialized(final Context context) {
|
private static synchronized void ensureInitialized(final Context context) {
|
||||||
if (sInitialized) return;
|
if (sInitialized) return;
|
||||||
if (sEnableJavaBpfMap == null) {
|
|
||||||
sEnableJavaBpfMap = SdkLevel.isAtLeastU() ||
|
|
||||||
DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context,
|
|
||||||
BPF_NET_MAPS_FORCE_DISABLE_JAVA_BPF_MAP);
|
|
||||||
}
|
|
||||||
Log.d(TAG, "BpfNetMaps is initialized with sEnableJavaBpfMap=" + sEnableJavaBpfMap);
|
|
||||||
|
|
||||||
initBpfMaps();
|
initBpfMaps();
|
||||||
native_init(!sEnableJavaBpfMap /* startSkDestroyListener */);
|
|
||||||
sInitialized = true;
|
sInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSkDestroyListenerRunning() {
|
public boolean isSkDestroyListenerRunning() {
|
||||||
return !sEnableJavaBpfMap;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -437,12 +410,7 @@ public class BpfNetMaps {
|
|||||||
public void addNaughtyApp(final int uid) {
|
public void addNaughtyApp(final int uid) {
|
||||||
throwIfPreT("addNaughtyApp is not available on pre-T devices");
|
throwIfPreT("addNaughtyApp is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
addRule(uid, PENALTY_BOX_MATCH, "addNaughtyApp");
|
||||||
addRule(uid, PENALTY_BOX_MATCH, "addNaughtyApp");
|
|
||||||
} else {
|
|
||||||
final int err = native_addNaughtyApp(uid);
|
|
||||||
maybeThrow(err, "Unable to add naughty app");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -456,12 +424,7 @@ public class BpfNetMaps {
|
|||||||
public void removeNaughtyApp(final int uid) {
|
public void removeNaughtyApp(final int uid) {
|
||||||
throwIfPreT("removeNaughtyApp is not available on pre-T devices");
|
throwIfPreT("removeNaughtyApp is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
removeRule(uid, PENALTY_BOX_MATCH, "removeNaughtyApp");
|
||||||
removeRule(uid, PENALTY_BOX_MATCH, "removeNaughtyApp");
|
|
||||||
} else {
|
|
||||||
final int err = native_removeNaughtyApp(uid);
|
|
||||||
maybeThrow(err, "Unable to remove naughty app");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -475,12 +438,7 @@ public class BpfNetMaps {
|
|||||||
public void addNiceApp(final int uid) {
|
public void addNiceApp(final int uid) {
|
||||||
throwIfPreT("addNiceApp is not available on pre-T devices");
|
throwIfPreT("addNiceApp is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
addRule(uid, HAPPY_BOX_MATCH, "addNiceApp");
|
||||||
addRule(uid, HAPPY_BOX_MATCH, "addNiceApp");
|
|
||||||
} else {
|
|
||||||
final int err = native_addNiceApp(uid);
|
|
||||||
maybeThrow(err, "Unable to add nice app");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -494,12 +452,7 @@ public class BpfNetMaps {
|
|||||||
public void removeNiceApp(final int uid) {
|
public void removeNiceApp(final int uid) {
|
||||||
throwIfPreT("removeNiceApp is not available on pre-T devices");
|
throwIfPreT("removeNiceApp is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
removeRule(uid, HAPPY_BOX_MATCH, "removeNiceApp");
|
||||||
removeRule(uid, HAPPY_BOX_MATCH, "removeNiceApp");
|
|
||||||
} else {
|
|
||||||
final int err = native_removeNiceApp(uid);
|
|
||||||
maybeThrow(err, "Unable to remove nice app");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -515,21 +468,16 @@ public class BpfNetMaps {
|
|||||||
public void setChildChain(final int childChain, final boolean enable) {
|
public void setChildChain(final int childChain, final boolean enable) {
|
||||||
throwIfPreT("setChildChain is not available on pre-T devices");
|
throwIfPreT("setChildChain is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
final long match = getMatchByFirewallChain(childChain);
|
||||||
final long match = getMatchByFirewallChain(childChain);
|
try {
|
||||||
try {
|
synchronized (sUidRulesConfigBpfMapLock) {
|
||||||
synchronized (sUidRulesConfigBpfMapLock) {
|
final U32 config = sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY);
|
||||||
final U32 config = sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY);
|
final long newConfig = enable ? (config.val | match) : (config.val & ~match);
|
||||||
final long newConfig = enable ? (config.val | match) : (config.val & ~match);
|
sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(newConfig));
|
||||||
sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(newConfig));
|
|
||||||
}
|
|
||||||
} catch (ErrnoException e) {
|
|
||||||
throw new ServiceSpecificException(e.errno,
|
|
||||||
"Unable to set child chain: " + Os.strerror(e.errno));
|
|
||||||
}
|
}
|
||||||
} else {
|
} catch (ErrnoException e) {
|
||||||
final int err = native_setChildChain(childChain, enable);
|
throw new ServiceSpecificException(e.errno,
|
||||||
maybeThrow(err, "Unable to set child chain");
|
"Unable to set child chain: " + Os.strerror(e.errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,75 +520,38 @@ public class BpfNetMaps {
|
|||||||
public void replaceUidChain(final int chain, final int[] uids) {
|
public void replaceUidChain(final int chain, final int[] uids) {
|
||||||
throwIfPreT("replaceUidChain is not available on pre-T devices");
|
throwIfPreT("replaceUidChain is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
final long match;
|
||||||
final long match;
|
try {
|
||||||
try {
|
match = getMatchByFirewallChain(chain);
|
||||||
match = getMatchByFirewallChain(chain);
|
} catch (ServiceSpecificException e) {
|
||||||
} catch (ServiceSpecificException e) {
|
// Throws IllegalArgumentException to keep the behavior of
|
||||||
// Throws IllegalArgumentException to keep the behavior of
|
// ConnectivityManager#replaceFirewallChain API
|
||||||
// ConnectivityManager#replaceFirewallChain API
|
throw new IllegalArgumentException("Invalid firewall chain: " + chain);
|
||||||
throw new IllegalArgumentException("Invalid firewall chain: " + chain);
|
}
|
||||||
}
|
final Set<Integer> uidSet = asSet(uids);
|
||||||
final Set<Integer> uidSet = asSet(uids);
|
final Set<Integer> uidSetToRemoveRule = new ArraySet<>();
|
||||||
final Set<Integer> uidSetToRemoveRule = new ArraySet<>();
|
try {
|
||||||
try {
|
synchronized (sUidOwnerMap) {
|
||||||
synchronized (sUidOwnerMap) {
|
sUidOwnerMap.forEach((uid, config) -> {
|
||||||
sUidOwnerMap.forEach((uid, config) -> {
|
// config could be null if there is a concurrent entry deletion.
|
||||||
// config could be null if there is a concurrent entry deletion.
|
// http://b/220084230. But sUidOwnerMap update must be done while holding a
|
||||||
// http://b/220084230. But sUidOwnerMap update must be done while holding a
|
// lock, so this should not happen.
|
||||||
// lock, so this should not happen.
|
if (config == null) {
|
||||||
if (config == null) {
|
Log.wtf(TAG, "sUidOwnerMap entry was deleted while holding a lock");
|
||||||
Log.wtf(TAG, "sUidOwnerMap entry was deleted while holding a lock");
|
} else if (!uidSet.contains((int) uid.val) && (config.rule & match) != 0) {
|
||||||
} else if (!uidSet.contains((int) uid.val) && (config.rule & match) != 0) {
|
uidSetToRemoveRule.add((int) uid.val);
|
||||||
uidSetToRemoveRule.add((int) uid.val);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
for (final int uid : uidSetToRemoveRule) {
|
for (final int uid : uidSetToRemoveRule) {
|
||||||
removeRule(uid, match, "replaceUidChain");
|
removeRule(uid, match, "replaceUidChain");
|
||||||
}
|
}
|
||||||
for (final int uid : uids) {
|
for (final int uid : uids) {
|
||||||
addRule(uid, match, "replaceUidChain");
|
addRule(uid, match, "replaceUidChain");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (ErrnoException | ServiceSpecificException e) {
|
|
||||||
Log.e(TAG, "replaceUidChain failed: " + e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final int err;
|
|
||||||
switch (chain) {
|
|
||||||
case FIREWALL_CHAIN_DOZABLE:
|
|
||||||
err = native_replaceUidChain("fw_dozable", true /* isAllowList */, uids);
|
|
||||||
break;
|
|
||||||
case FIREWALL_CHAIN_STANDBY:
|
|
||||||
err = native_replaceUidChain("fw_standby", false /* isAllowList */, uids);
|
|
||||||
break;
|
|
||||||
case FIREWALL_CHAIN_POWERSAVE:
|
|
||||||
err = native_replaceUidChain("fw_powersave", true /* isAllowList */, uids);
|
|
||||||
break;
|
|
||||||
case FIREWALL_CHAIN_RESTRICTED:
|
|
||||||
err = native_replaceUidChain("fw_restricted", true /* isAllowList */, uids);
|
|
||||||
break;
|
|
||||||
case FIREWALL_CHAIN_LOW_POWER_STANDBY:
|
|
||||||
err = native_replaceUidChain(
|
|
||||||
"fw_low_power_standby", true /* isAllowList */, uids);
|
|
||||||
break;
|
|
||||||
case FIREWALL_CHAIN_OEM_DENY_1:
|
|
||||||
err = native_replaceUidChain("fw_oem_deny_1", false /* isAllowList */, uids);
|
|
||||||
break;
|
|
||||||
case FIREWALL_CHAIN_OEM_DENY_2:
|
|
||||||
err = native_replaceUidChain("fw_oem_deny_2", false /* isAllowList */, uids);
|
|
||||||
break;
|
|
||||||
case FIREWALL_CHAIN_OEM_DENY_3:
|
|
||||||
err = native_replaceUidChain("fw_oem_deny_3", false /* isAllowList */, uids);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("replaceFirewallChain with invalid chain: "
|
|
||||||
+ chain);
|
|
||||||
}
|
|
||||||
if (err != 0) {
|
|
||||||
Log.e(TAG, "replaceUidChain failed: " + Os.strerror(-err));
|
|
||||||
}
|
}
|
||||||
|
} catch (ErrnoException | ServiceSpecificException e) {
|
||||||
|
Log.e(TAG, "replaceUidChain failed: " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,20 +568,15 @@ public class BpfNetMaps {
|
|||||||
public void setUidRule(final int childChain, final int uid, final int firewallRule) {
|
public void setUidRule(final int childChain, final int uid, final int firewallRule) {
|
||||||
throwIfPreT("setUidRule is not available on pre-T devices");
|
throwIfPreT("setUidRule is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
final long match = getMatchByFirewallChain(childChain);
|
||||||
final long match = getMatchByFirewallChain(childChain);
|
final boolean isAllowList = isFirewallAllowList(childChain);
|
||||||
final boolean isAllowList = isFirewallAllowList(childChain);
|
final boolean add = (firewallRule == FIREWALL_RULE_ALLOW && isAllowList)
|
||||||
final boolean add = (firewallRule == FIREWALL_RULE_ALLOW && isAllowList)
|
|| (firewallRule == FIREWALL_RULE_DENY && !isAllowList);
|
||||||
|| (firewallRule == FIREWALL_RULE_DENY && !isAllowList);
|
|
||||||
|
|
||||||
if (add) {
|
if (add) {
|
||||||
addRule(uid, match, "setUidRule");
|
addRule(uid, match, "setUidRule");
|
||||||
} else {
|
|
||||||
removeRule(uid, match, "setUidRule");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
final int err = native_setUidRule(childChain, uid, firewallRule);
|
removeRule(uid, match, "setUidRule");
|
||||||
maybeThrow(err, "Unable to set uid rule");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,29 +679,24 @@ public class BpfNetMaps {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
// Null ifName is a wildcard to allow apps to receive packets on all interfaces and
|
||||||
// Null ifName is a wildcard to allow apps to receive packets on all interfaces and
|
// ifIndex is set to 0.
|
||||||
// ifIndex is set to 0.
|
final int ifIndex;
|
||||||
final int ifIndex;
|
if (ifName == null) {
|
||||||
if (ifName == null) {
|
ifIndex = 0;
|
||||||
ifIndex = 0;
|
|
||||||
} else {
|
|
||||||
ifIndex = mDeps.getIfIndex(ifName);
|
|
||||||
if (ifIndex == 0) {
|
|
||||||
throw new ServiceSpecificException(ENODEV,
|
|
||||||
"Failed to get index of interface " + ifName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (final int uid : uids) {
|
|
||||||
try {
|
|
||||||
addRule(uid, IIF_MATCH, ifIndex, "addUidInterfaceRules");
|
|
||||||
} catch (ServiceSpecificException e) {
|
|
||||||
Log.e(TAG, "addRule failed uid=" + uid + " ifName=" + ifName + ", " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
final int err = native_addUidInterfaceRules(ifName, uids);
|
ifIndex = mDeps.getIfIndex(ifName);
|
||||||
maybeThrow(err, "Unable to add uid interface rules");
|
if (ifIndex == 0) {
|
||||||
|
throw new ServiceSpecificException(ENODEV,
|
||||||
|
"Failed to get index of interface " + ifName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final int uid : uids) {
|
||||||
|
try {
|
||||||
|
addRule(uid, IIF_MATCH, ifIndex, "addUidInterfaceRules");
|
||||||
|
} catch (ServiceSpecificException e) {
|
||||||
|
Log.e(TAG, "addRule failed uid=" + uid + " ifName=" + ifName + ", " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -816,17 +717,12 @@ public class BpfNetMaps {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
for (final int uid : uids) {
|
||||||
for (final int uid : uids) {
|
try {
|
||||||
try {
|
removeRule(uid, IIF_MATCH, "removeUidInterfaceRules");
|
||||||
removeRule(uid, IIF_MATCH, "removeUidInterfaceRules");
|
} catch (ServiceSpecificException e) {
|
||||||
} catch (ServiceSpecificException e) {
|
Log.e(TAG, "removeRule failed uid=" + uid + ", " + e);
|
||||||
Log.e(TAG, "removeRule failed uid=" + uid + ", " + e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
final int err = native_removeUidInterfaceRules(uids);
|
|
||||||
maybeThrow(err, "Unable to remove uid interface rules");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -842,15 +738,10 @@ public class BpfNetMaps {
|
|||||||
public void updateUidLockdownRule(final int uid, final boolean add) {
|
public void updateUidLockdownRule(final int uid, final boolean add) {
|
||||||
throwIfPreT("updateUidLockdownRule is not available on pre-T devices");
|
throwIfPreT("updateUidLockdownRule is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
if (add) {
|
||||||
if (add) {
|
addRule(uid, LOCKDOWN_VPN_MATCH, "updateUidLockdownRule");
|
||||||
addRule(uid, LOCKDOWN_VPN_MATCH, "updateUidLockdownRule");
|
|
||||||
} else {
|
|
||||||
removeRule(uid, LOCKDOWN_VPN_MATCH, "updateUidLockdownRule");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
final int err = native_updateUidLockdownRule(uid, add);
|
removeRule(uid, LOCKDOWN_VPN_MATCH, "updateUidLockdownRule");
|
||||||
maybeThrow(err, "Unable to update lockdown rule");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -865,33 +756,28 @@ public class BpfNetMaps {
|
|||||||
public void swapActiveStatsMap() {
|
public void swapActiveStatsMap() {
|
||||||
throwIfPreT("swapActiveStatsMap is not available on pre-T devices");
|
throwIfPreT("swapActiveStatsMap is not available on pre-T devices");
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
try {
|
||||||
try {
|
synchronized (sCurrentStatsMapConfigLock) {
|
||||||
synchronized (sCurrentStatsMapConfigLock) {
|
final long config = sConfigurationMap.getValue(
|
||||||
final long config = sConfigurationMap.getValue(
|
CURRENT_STATS_MAP_CONFIGURATION_KEY).val;
|
||||||
CURRENT_STATS_MAP_CONFIGURATION_KEY).val;
|
final long newConfig = (config == STATS_SELECT_MAP_A)
|
||||||
final long newConfig = (config == STATS_SELECT_MAP_A)
|
? STATS_SELECT_MAP_B : STATS_SELECT_MAP_A;
|
||||||
? STATS_SELECT_MAP_B : STATS_SELECT_MAP_A;
|
sConfigurationMap.updateEntry(CURRENT_STATS_MAP_CONFIGURATION_KEY,
|
||||||
sConfigurationMap.updateEntry(CURRENT_STATS_MAP_CONFIGURATION_KEY,
|
new U32(newConfig));
|
||||||
new U32(newConfig));
|
|
||||||
}
|
|
||||||
} catch (ErrnoException e) {
|
|
||||||
throw new ServiceSpecificException(e.errno, "Failed to swap active stats map");
|
|
||||||
}
|
}
|
||||||
|
} catch (ErrnoException e) {
|
||||||
// After changing the config, it's needed to make sure all the current running eBPF
|
throw new ServiceSpecificException(e.errno, "Failed to swap active stats map");
|
||||||
// programs are finished and all the CPUs are aware of this config change before the old
|
|
||||||
// map is modified. So special hack is needed here to wait for the kernel to do a
|
|
||||||
// synchronize_rcu(). Once the kernel called synchronize_rcu(), the updated config will
|
|
||||||
// be available to all cores and the next eBPF programs triggered inside the kernel will
|
|
||||||
// use the new map configuration. So once this function returns it is safe to modify the
|
|
||||||
// old stats map without concerning about race between the kernel and userspace.
|
|
||||||
final int err = mDeps.synchronizeKernelRCU();
|
|
||||||
maybeThrow(err, "synchronizeKernelRCU failed");
|
|
||||||
} else {
|
|
||||||
final int err = native_swapActiveStatsMap();
|
|
||||||
maybeThrow(err, "Unable to swap active stats map");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// After changing the config, it's needed to make sure all the current running eBPF
|
||||||
|
// programs are finished and all the CPUs are aware of this config change before the old
|
||||||
|
// map is modified. So special hack is needed here to wait for the kernel to do a
|
||||||
|
// synchronize_rcu(). Once the kernel called synchronize_rcu(), the updated config will
|
||||||
|
// be available to all cores and the next eBPF programs triggered inside the kernel will
|
||||||
|
// use the new map configuration. So once this function returns it is safe to modify the
|
||||||
|
// old stats map without concerning about race between the kernel and userspace.
|
||||||
|
final int err = mDeps.synchronizeKernelRCU();
|
||||||
|
maybeThrow(err, "synchronizeKernelRCU failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -910,29 +796,25 @@ public class BpfNetMaps {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sEnableJavaBpfMap) {
|
// Remove the entry if package is uninstalled or uid has only INTERNET permission.
|
||||||
// Remove the entry if package is uninstalled or uid has only INTERNET permission.
|
if (permissions == PERMISSION_UNINSTALLED || permissions == PERMISSION_INTERNET) {
|
||||||
if (permissions == PERMISSION_UNINSTALLED || permissions == PERMISSION_INTERNET) {
|
|
||||||
for (final int uid : uids) {
|
|
||||||
try {
|
|
||||||
sUidPermissionMap.deleteEntry(new S32(uid));
|
|
||||||
} catch (ErrnoException e) {
|
|
||||||
Log.e(TAG, "Failed to remove uid " + uid + " from permission map: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final int uid : uids) {
|
for (final int uid : uids) {
|
||||||
try {
|
try {
|
||||||
sUidPermissionMap.updateEntry(new S32(uid), new U8((short) permissions));
|
sUidPermissionMap.deleteEntry(new S32(uid));
|
||||||
} catch (ErrnoException e) {
|
} catch (ErrnoException e) {
|
||||||
Log.e(TAG, "Failed to set permission "
|
Log.e(TAG, "Failed to remove uid " + uid + " from permission map: " + e);
|
||||||
+ permissions + " to uid " + uid + ": " + e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
return;
|
||||||
native_setPermissionForUids(permissions, uids);
|
}
|
||||||
|
|
||||||
|
for (final int uid : uids) {
|
||||||
|
try {
|
||||||
|
sUidPermissionMap.updateEntry(new S32(uid), new U8((short) permissions));
|
||||||
|
} catch (ErrnoException e) {
|
||||||
|
Log.e(TAG, "Failed to set permission "
|
||||||
|
+ permissions + " to uid " + uid + ": " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,7 +951,6 @@ public class BpfNetMaps {
|
|||||||
pw.println("TrafficController"); // required by CTS testDumpBpfNetMaps
|
pw.println("TrafficController"); // required by CTS testDumpBpfNetMaps
|
||||||
|
|
||||||
pw.println();
|
pw.println();
|
||||||
pw.println("sEnableJavaBpfMap: " + sEnableJavaBpfMap);
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
pw.println();
|
pw.println();
|
||||||
pw.println("BPF map content:");
|
pw.println("BPF map content:");
|
||||||
@@ -1104,45 +985,6 @@ public class BpfNetMaps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private static native void native_init(boolean startSkDestroyListener);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_addNaughtyApp(int uid);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_removeNaughtyApp(int uid);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_addNiceApp(int uid);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_removeNiceApp(int uid);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_setChildChain(int childChain, boolean enable);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_replaceUidChain(String name, boolean isAllowlist, int[] uids);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_setUidRule(int childChain, int uid, int firewallRule);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_addUidInterfaceRules(String ifName, int[] uids);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_removeUidInterfaceRules(int[] uids);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_updateUidLockdownRule(int uid, boolean add);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native int native_swapActiveStatsMap();
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
|
||||||
private native void native_setPermissionForUids(int permissions, int[] uids);
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||||
private static native int native_synchronizeKernelRCU();
|
private static native int native_synchronizeKernelRCU();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,6 @@ public final class BpfNetMapsTest {
|
|||||||
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);
|
||||||
doReturn(0).when(mDeps).synchronizeKernelRCU();
|
doReturn(0).when(mDeps).synchronizeKernelRCU();
|
||||||
BpfNetMaps.setEnableJavaBpfMapForTest(true /* enable */);
|
|
||||||
BpfNetMaps.setConfigurationMapForTest(mConfigurationMap);
|
BpfNetMaps.setConfigurationMapForTest(mConfigurationMap);
|
||||||
mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
|
mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
|
||||||
mConfigurationMap.updateEntry(
|
mConfigurationMap.updateEntry(
|
||||||
|
|||||||
Reference in New Issue
Block a user