diff --git a/bpf_progs/bpf_shared.h b/bpf_progs/bpf_shared.h index f0df97baf2..2ddc7b86e3 100644 --- a/bpf_progs/bpf_shared.h +++ b/bpf_progs/bpf_shared.h @@ -130,7 +130,8 @@ enum UidOwnerMatchType { STANDBY_MATCH = (1 << 3), POWERSAVE_MATCH = (1 << 4), RESTRICTED_MATCH = (1 << 5), - IIF_MATCH = (1 << 6), + LOW_POWER_STANDBY_MATCH = (1 << 6), + IIF_MATCH = (1 << 7), }; enum BpfPermissionMatch { diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c index f0af8b4112..c1a74e735c 100644 --- a/bpf_progs/netd.c +++ b/bpf_progs/netd.c @@ -210,6 +210,9 @@ static inline int bpf_owner_match(struct __sk_buff* skb, uint32_t uid, int direc if ((enabledRules & RESTRICTED_MATCH) && !(uidRules & RESTRICTED_MATCH)) { return BPF_DROP; } + if ((enabledRules & LOW_POWER_STANDBY_MATCH) && !(uidRules & LOW_POWER_STANDBY_MATCH)) { + return BPF_DROP; + } } if (direction == BPF_INGRESS && (uidRules & IIF_MATCH)) { // Drops packets not coming from lo nor the allowlisted interface diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index 92ede91a8b..524662336c 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -941,6 +941,7 @@ public class ConnectivityManager { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) private final IConnectivityManager mService; + // LINT.IfChange(firewall_chain) /** * Firewall chain for device idle (doze mode). * Allowlist of apps that have network access in device idle. @@ -991,6 +992,7 @@ public class ConnectivityManager { FIREWALL_CHAIN_LOW_POWER_STANDBY }) public @interface FirewallChain {} + // LINT.ThenChange(packages/modules/Connectivity/service/native/include/Common.h) /** * A kludge to facilitate static access where a Context pointer isn't available, like in the diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp index 51dd502b21..5981906fc3 100644 --- a/service/native/TrafficController.cpp +++ b/service/native/TrafficController.cpp @@ -75,6 +75,7 @@ const char* TrafficController::LOCAL_DOZABLE = "fw_dozable"; const char* TrafficController::LOCAL_STANDBY = "fw_standby"; const char* TrafficController::LOCAL_POWERSAVE = "fw_powersave"; const char* TrafficController::LOCAL_RESTRICTED = "fw_restricted"; +const char* TrafficController::LOCAL_LOW_POWER_STANDBY = "fw_low_power_standby"; static_assert(BPF_PERMISSION_INTERNET == INetd::PERMISSION_INTERNET, "Mismatch between BPF and AIDL permissions: PERMISSION_INTERNET"); @@ -97,6 +98,7 @@ const std::string uidMatchTypeToString(uint8_t match) { FLAG_MSG_TRANS(matchType, STANDBY_MATCH, match); FLAG_MSG_TRANS(matchType, POWERSAVE_MATCH, match); FLAG_MSG_TRANS(matchType, RESTRICTED_MATCH, match); + FLAG_MSG_TRANS(matchType, LOW_POWER_STANDBY_MATCH, match); FLAG_MSG_TRANS(matchType, IIF_MATCH, match); if (match) { return StringPrintf("Unknown match: %u", match); @@ -426,6 +428,8 @@ FirewallType TrafficController::getFirewallType(ChildChain chain) { return ALLOWLIST; case RESTRICTED: return ALLOWLIST; + case LOW_POWER_STANDBY: + return ALLOWLIST; case NONE: default: return DENYLIST; @@ -448,6 +452,9 @@ int TrafficController::changeUidOwnerRule(ChildChain chain, uid_t uid, FirewallR case RESTRICTED: res = updateOwnerMapEntry(RESTRICTED_MATCH, uid, rule, type); break; + case LOW_POWER_STANDBY: + res = updateOwnerMapEntry(LOW_POWER_STANDBY_MATCH, uid, rule, type); + break; case NONE: default: ALOGW("Unknown child chain: %d", chain); @@ -526,6 +533,8 @@ int TrafficController::replaceUidOwnerMap(const std::string& name, bool isAllowl res = replaceRulesInMap(POWERSAVE_MATCH, uids); } else if (!name.compare(LOCAL_RESTRICTED)) { res = replaceRulesInMap(RESTRICTED_MATCH, uids); + } else if (!name.compare(LOCAL_LOW_POWER_STANDBY)) { + res = replaceRulesInMap(LOW_POWER_STANDBY_MATCH, uids); } else { ALOGE("unknown chain name: %s", name.c_str()); return -EINVAL; @@ -562,6 +571,9 @@ int TrafficController::toggleUidOwnerMap(ChildChain chain, bool enable) { case RESTRICTED: match = RESTRICTED_MATCH; break; + case LOW_POWER_STANDBY: + match = LOW_POWER_STANDBY_MATCH; + break; default: return -EINVAL; } diff --git a/service/native/TrafficControllerTest.cpp b/service/native/TrafficControllerTest.cpp index 39f33658bd..d0eca34e24 100644 --- a/service/native/TrafficControllerTest.cpp +++ b/service/native/TrafficControllerTest.cpp @@ -470,6 +470,7 @@ TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) { checkUidOwnerRuleForChain(STANDBY, STANDBY_MATCH); checkUidOwnerRuleForChain(POWERSAVE, POWERSAVE_MATCH); checkUidOwnerRuleForChain(RESTRICTED, RESTRICTED_MATCH); + checkUidOwnerRuleForChain(LOW_POWER_STANDBY, LOW_POWER_STANDBY_MATCH); ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, ALLOWLIST)); ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, ALLOWLIST)); } @@ -480,6 +481,7 @@ TEST_F(TrafficControllerTest, TestReplaceUidOwnerMap) { checkUidMapReplace("fw_standby", uids, STANDBY_MATCH); checkUidMapReplace("fw_powersave", uids, POWERSAVE_MATCH); checkUidMapReplace("fw_restricted", uids, RESTRICTED_MATCH); + checkUidMapReplace("fw_low_power_standby", uids, LOW_POWER_STANDBY_MATCH); ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids)); } diff --git a/service/native/include/Common.h b/service/native/include/Common.h index 7c0b797f78..dc448450a6 100644 --- a/service/native/include/Common.h +++ b/service/native/include/Common.h @@ -27,11 +27,14 @@ enum FirewallRule { ALLOW = INetd::FIREWALL_RULE_ALLOW, DENY = INetd::FIREWALL_R enum FirewallType { ALLOWLIST = INetd::FIREWALL_ALLOWLIST, DENYLIST = INetd::FIREWALL_DENYLIST }; +// LINT.IfChange(firewall_chain) enum ChildChain { - NONE = INetd::FIREWALL_CHAIN_NONE, - DOZABLE = INetd::FIREWALL_CHAIN_DOZABLE, - STANDBY = INetd::FIREWALL_CHAIN_STANDBY, - POWERSAVE = INetd::FIREWALL_CHAIN_POWERSAVE, - RESTRICTED = INetd::FIREWALL_CHAIN_RESTRICTED, + NONE = 0, + DOZABLE = 1, + STANDBY = 2, + POWERSAVE = 3, + RESTRICTED = 4, + LOW_POWER_STANDBY = 5, INVALID_CHAIN }; +// LINT.ThenChange(packages/modules/Connectivity/framework/src/android/net/ConnectivityManager.java) diff --git a/service/native/include/TrafficController.h b/service/native/include/TrafficController.h index ddcf4459fb..e741dd6f22 100644 --- a/service/native/include/TrafficController.h +++ b/service/native/include/TrafficController.h @@ -99,6 +99,7 @@ class TrafficController { static const char* LOCAL_STANDBY; static const char* LOCAL_POWERSAVE; static const char* LOCAL_RESTRICTED; + static const char* LOCAL_LOW_POWER_STANDBY; private: /* @@ -160,7 +161,7 @@ class TrafficController { * the map right now: * - Entry with UID_RULES_CONFIGURATION_KEY: * Store the configuration for the current uid rules. It indicates the device - * is in doze/powersave/standby/restricted mode. + * is in doze/powersave/standby/restricted/low power standby mode. * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY: * Stores the current live stats map that kernel program is writing to. * Userspace can do scraping and cleaning job on the other one depending on the diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index a9a06e46a5..198190a545 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -10912,6 +10912,10 @@ public class ConnectivityService extends IConnectivityManager.Stub case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED: mBpfNetMaps.replaceUidChain("fw_restricted", true /* isAllowList */, uids); break; + case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY: + mBpfNetMaps.replaceUidChain("fw_low_power_standby", true /* isAllowList */, + uids); + break; default: throw new IllegalArgumentException("replaceFirewallChain with invalid chain: " + chain);