Add firewall chains for HAPPY_BOX and user/admin PENALTY_BOX

Follow up CLs will update CS to generate blocked reason from bpf map
instead of asking NPMS.

However, one issue is NPMS set PENALTY_BOX for
BLOCKED_METERED_REASON_USER_RESTRICTED and
BLOCKED_METERED_REASON_ADMIN_DISABLED without telling the reason.
So, CS can not know the reason of PENALTY_BOX.

This CL add new firewall chain and match to distinguish reasons.
NPMS must call setUidFirewallRule with
FIREWALL_CHAIN_METERED_DENY_USER or FIREWALL_CHAIN_METERED_DENY_ADMIN
based on the reason so that CS can know the reason of restriction.

Bug: 332628891
Test: atest com.android.cts.net.HostsideRestrictBackgroundNetworkTests
Change-Id: Ia4ad4bdb345abc22c782630e828edfad2452db36
This commit is contained in:
Motomu Utsumi 2024-04-02 18:29:08 +09:00
commit 11d3345daa

View file

@ -128,6 +128,8 @@ public class ConnectivityManager {
"com.android.net.flags.support_is_uid_networking_blocked";
static final String BASIC_BACKGROUND_RESTRICTIONS_ENABLED =
"com.android.net.flags.basic_background_restrictions_enabled";
static final String METERED_NETWORK_FIREWALL_CHAINS =
"com.android.net.flags.metered_network_firewall_chains";
}
/**
@ -1068,6 +1070,61 @@ public class ConnectivityManager {
@SystemApi(client = MODULE_LIBRARIES)
public static final int FIREWALL_CHAIN_OEM_DENY_3 = 9;
/**
* Firewall chain for allow list on metered networks
*
* UIDs added to this chain have access to metered networks, unless they're also in one of the
* denylist, {@link #FIREWALL_CHAIN_METERED_DENY_USER},
* {@link #FIREWALL_CHAIN_METERED_DENY_ADMIN}
*
* Note that this chain is used from a separate bpf program that is triggered by iptables and
* can not be controlled by {@link ConnectivityManager#setFirewallChainEnabled}.
*
* @hide
*/
// TODO: Merge this chain with data saver and support setFirewallChainEnabled
@FlaggedApi(Flags.METERED_NETWORK_FIREWALL_CHAINS)
@SystemApi(client = MODULE_LIBRARIES)
public static final int FIREWALL_CHAIN_METERED_ALLOW = 10;
/**
* Firewall chain for user-set restrictions on metered networks
*
* UIDs added to this chain do not have access to metered networks.
* UIDs should be added to this chain based on user settings.
* To restrict metered network based on admin configuration (e.g. enterprise policies),
* {@link #FIREWALL_CHAIN_METERED_DENY_ADMIN} should be used.
* This chain corresponds to {@link #BLOCKED_METERED_REASON_USER_RESTRICTED}
*
* Note that this chain is used from a separate bpf program that is triggered by iptables and
* can not be controlled by {@link ConnectivityManager#setFirewallChainEnabled}.
*
* @hide
*/
// TODO: Support setFirewallChainEnabled to control this chain
@FlaggedApi(Flags.METERED_NETWORK_FIREWALL_CHAINS)
@SystemApi(client = MODULE_LIBRARIES)
public static final int FIREWALL_CHAIN_METERED_DENY_USER = 11;
/**
* Firewall chain for admin-set restrictions on metered networks
*
* UIDs added to this chain do not have access to metered networks.
* UIDs should be added to this chain based on admin configuration (e.g. enterprise policies).
* To restrict metered network based on user settings, {@link #FIREWALL_CHAIN_METERED_DENY_USER}
* should be used.
* This chain corresponds to {@link #BLOCKED_METERED_REASON_ADMIN_DISABLED}
*
* Note that this chain is used from a separate bpf program that is triggered by iptables and
* can not be controlled by {@link ConnectivityManager#setFirewallChainEnabled}.
*
* @hide
*/
// TODO: Support setFirewallChainEnabled to control this chain
@FlaggedApi(Flags.METERED_NETWORK_FIREWALL_CHAINS)
@SystemApi(client = MODULE_LIBRARIES)
public static final int FIREWALL_CHAIN_METERED_DENY_ADMIN = 12;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = false, prefix = "FIREWALL_CHAIN_", value = {
@ -1079,7 +1136,10 @@ public class ConnectivityManager {
FIREWALL_CHAIN_BACKGROUND,
FIREWALL_CHAIN_OEM_DENY_1,
FIREWALL_CHAIN_OEM_DENY_2,
FIREWALL_CHAIN_OEM_DENY_3
FIREWALL_CHAIN_OEM_DENY_3,
FIREWALL_CHAIN_METERED_ALLOW,
FIREWALL_CHAIN_METERED_DENY_USER,
FIREWALL_CHAIN_METERED_DENY_ADMIN
})
public @interface FirewallChain {}
@ -6065,7 +6125,7 @@ public class ConnectivityManager {
})
public void addUidToMeteredNetworkAllowList(final int uid) {
try {
mService.updateMeteredNetworkAllowList(uid, true /* add */);
mService.setUidFirewallRule(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_ALLOW);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@ -6088,7 +6148,7 @@ public class ConnectivityManager {
})
public void removeUidFromMeteredNetworkAllowList(final int uid) {
try {
mService.updateMeteredNetworkAllowList(uid, false /* remove */);
mService.setUidFirewallRule(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_DENY);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@ -6098,10 +6158,17 @@ public class ConnectivityManager {
* Adds the specified UID to the list of UIDs that are not allowed to use background data on
* metered networks. Takes precedence over {@link #addUidToMeteredNetworkAllowList}.
*
* On V+, {@link #setUidFirewallRule} should be used with
* {@link #FIREWALL_CHAIN_METERED_DENY_USER} or {@link #FIREWALL_CHAIN_METERED_DENY_ADMIN}
* based on the reason so that users can receive {@link #BLOCKED_METERED_REASON_USER_RESTRICTED}
* or {@link #BLOCKED_METERED_REASON_ADMIN_DISABLED}, respectively.
* This API always uses {@link #FIREWALL_CHAIN_METERED_DENY_USER}.
*
* @param uid uid of target app
* @throws IllegalStateException if updating deny list failed.
* @hide
*/
// TODO(b/332649177): Deprecate this API after V
@SystemApi(client = MODULE_LIBRARIES)
@RequiresPermission(anyOf = {
android.Manifest.permission.NETWORK_SETTINGS,
@ -6110,7 +6177,7 @@ public class ConnectivityManager {
})
public void addUidToMeteredNetworkDenyList(final int uid) {
try {
mService.updateMeteredNetworkDenyList(uid, true /* add */);
mService.setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_DENY);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@ -6121,10 +6188,17 @@ public class ConnectivityManager {
* networks if background data is not restricted. The deny list takes precedence over the
* allow list.
*
* On V+, {@link #setUidFirewallRule} should be used with
* {@link #FIREWALL_CHAIN_METERED_DENY_USER} or {@link #FIREWALL_CHAIN_METERED_DENY_ADMIN}
* based on the reason so that users can receive {@link #BLOCKED_METERED_REASON_USER_RESTRICTED}
* or {@link #BLOCKED_METERED_REASON_ADMIN_DISABLED}, respectively.
* This API always uses {@link #FIREWALL_CHAIN_METERED_DENY_USER}.
*
* @param uid uid of target app
* @throws IllegalStateException if updating deny list failed.
* @hide
*/
// TODO(b/332649177): Deprecate this API after V
@SystemApi(client = MODULE_LIBRARIES)
@RequiresPermission(anyOf = {
android.Manifest.permission.NETWORK_SETTINGS,
@ -6133,7 +6207,7 @@ public class ConnectivityManager {
})
public void removeUidFromMeteredNetworkDenyList(final int uid) {
try {
mService.updateMeteredNetworkDenyList(uid, false /* remove */);
mService.setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_ALLOW);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@ -6191,6 +6265,10 @@ public class ConnectivityManager {
/**
* Enables or disables the specified firewall chain.
*
* Note that metered firewall chains can not be controlled by this API.
* See {@link #FIREWALL_CHAIN_METERED_ALLOW}, {@link #FIREWALL_CHAIN_METERED_DENY_USER}, and
* {@link #FIREWALL_CHAIN_METERED_DENY_ADMIN} for more detail.
*
* @param chain target chain.
* @param enable whether the chain should be enabled.
* @throws UnsupportedOperationException if called on pre-T devices.