Merge "Merge all uid owner match map into one"
diff --git a/bpfloader/BpfLoader.cpp b/bpfloader/BpfLoader.cpp
index 0329be3..1a41d3d 100644
--- a/bpfloader/BpfLoader.cpp
+++ b/bpfloader/BpfLoader.cpp
@@ -54,6 +54,7 @@
#define BPF_PROG_PATH "/system/etc/bpf"
#define BPF_PROG_SRC BPF_PROG_PATH "/bpf_kern.o"
#define MAP_LD_CMD_HEAD 0x18
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
#define FAIL(...) \
do { \
@@ -229,61 +230,19 @@
return bpfProgLoad(type, prog, "Apache 2.0", 0, bpfLog);
}
-int loadAndAttachProgram(bpf_attach_type type, const char* path, const char* name,
- const std::vector<ReplacePattern>& mapPatterns) {
- unique_fd fd;
- if (type == BPF_CGROUP_INET_INGRESS) {
- fd.reset(loadProg(cgroupIngressProg, BPF_PROG_TYPE_CGROUP_SKB, mapPatterns));
- } else if (type == BPF_CGROUP_INET_EGRESS) {
- fd.reset(loadProg(cgroupEgressProg, BPF_PROG_TYPE_CGROUP_SKB, mapPatterns));
- } else if (!strcmp(name, XT_BPF_INGRESS_PROG_NAME)) {
- fd.reset(loadProg(xtIngressProg, BPF_PROG_TYPE_SOCKET_FILTER, mapPatterns));
- } else if (!strcmp(name, XT_BPF_EGRESS_PROG_NAME)) {
- fd.reset(loadProg(xtEgressProg, BPF_PROG_TYPE_SOCKET_FILTER, mapPatterns));
- } else if (!strcmp(name, XT_BPF_WHITELIST_PROG_NAME)) {
- fd.reset(loadProg(xtWhiteListProg, BPF_PROG_TYPE_SOCKET_FILTER, mapPatterns));
- } else if (!strcmp(name, XT_BPF_BLACKLIST_PROG_NAME)) {
- fd.reset(loadProg(xtBlackListProg, BPF_PROG_TYPE_SOCKET_FILTER, mapPatterns));
- } else {
- FAIL("Unrecognized program type: %s", name);
- }
-
- if (fd < 0) {
- FAIL("load %s failed: %s", name, strerror(errno));
- }
- int ret = 0;
- if (type == BPF_CGROUP_INET_EGRESS || type == BPF_CGROUP_INET_INGRESS) {
- unique_fd cg_fd(open(CGROUP_ROOT_PATH, O_DIRECTORY | O_RDONLY | O_CLOEXEC));
- if (cg_fd < 0) {
- FAIL("Failed to open the cgroup directory");
- }
- ret = attachProgram(type, fd, cg_fd);
- if (ret) {
- FAIL("%s attach failed: %s", name, strerror(errno));
- }
- }
-
- ret = mapPin(fd, path);
- if (ret) {
- FAIL("Pin %s as file %s failed: %s", name, path, strerror(errno));
- }
- return 0;
-}
-
} // namespace bpf
} // namespace android
using android::bpf::APP_UID_STATS_MAP_PATH;
-using android::bpf::BANDWIDTH_UID_MAP_PATH;
using android::bpf::BPF_EGRESS_PROG_PATH;
using android::bpf::BPF_INGRESS_PROG_PATH;
+using android::bpf::CGROUP_ROOT_PATH;
+using android::bpf::CONFIGURATION_MAP_PATH;
using android::bpf::COOKIE_TAG_MAP_PATH;
-using android::bpf::DOZABLE_UID_MAP_PATH;
using android::bpf::IFACE_STATS_MAP_PATH;
-using android::bpf::POWERSAVE_UID_MAP_PATH;
-using android::bpf::STANDBY_UID_MAP_PATH;
using android::bpf::TAG_STATS_MAP_PATH;
using android::bpf::UID_COUNTERSET_MAP_PATH;
+using android::bpf::UID_OWNER_MAP_PATH;
using android::bpf::UID_STATS_MAP_PATH;
using android::bpf::XT_BPF_BLACKLIST_PROG_PATH;
using android::bpf::XT_BPF_EGRESS_PROG_PATH;
@@ -291,20 +250,15 @@
using android::bpf::XT_BPF_WHITELIST_PROG_PATH;
using android::bpf::ReplacePattern;
-using android::bpf::loadAndAttachProgram;
-static void usage(void) {
- ALOGE(
- "Usage: ./bpfloader [-i] [-e]\n"
- " -i load ingress bpf program\n"
- " -e load egress bpf program\n"
- " -p load prerouting xt_bpf program\n"
- " -m load mangle xt_bpf program\n"
- " -w load bandwidth whitelist program\n"
- " -b load bandwidth blacklist program\n");
-}
+using android::bpf::cgroupEgressProg;
+using android::bpf::cgroupIngressProg;
+using android::bpf::xtBlackListProg;
+using android::bpf::xtEgressProg;
+using android::bpf::xtIngressProg;
+using android::bpf::xtWhiteListProg;
-int main(int argc, char** argv) {
+int main() {
int ret = 0;
DECLARE_MAP(cookieTagMap, COOKIE_TAG_MAP_PATH);
DECLARE_MAP(uidCounterSetMap, UID_COUNTERSET_MAP_PATH);
@@ -312,94 +266,66 @@
DECLARE_MAP(uidStatsMap, UID_STATS_MAP_PATH);
DECLARE_MAP(tagStatsMap, TAG_STATS_MAP_PATH);
DECLARE_MAP(ifaceStatsMap, IFACE_STATS_MAP_PATH);
- DECLARE_MAP(dozableUidMap, DOZABLE_UID_MAP_PATH);
- DECLARE_MAP(standbyUidMap, STANDBY_UID_MAP_PATH);
- DECLARE_MAP(powerSaveUidMap, POWERSAVE_UID_MAP_PATH);
- DECLARE_MAP(bandwidthUidMap, BANDWIDTH_UID_MAP_PATH);
+ DECLARE_MAP(configurationMap, CONFIGURATION_MAP_PATH);
+ DECLARE_MAP(uidOwnerMap, UID_OWNER_MAP_PATH);
const std::vector<ReplacePattern> mapPatterns = {
- ReplacePattern(COOKIE_TAG_MAP, cookieTagMap.get()),
- ReplacePattern(UID_COUNTERSET_MAP, uidCounterSetMap.get()),
- ReplacePattern(APP_UID_STATS_MAP, appUidStatsMap.get()),
- ReplacePattern(UID_STATS_MAP, uidStatsMap.get()),
- ReplacePattern(TAG_STATS_MAP, tagStatsMap.get()),
- ReplacePattern(IFACE_STATS_MAP, ifaceStatsMap.get()),
- ReplacePattern(DOZABLE_UID_MAP, dozableUidMap.get()),
- ReplacePattern(STANDBY_UID_MAP, standbyUidMap.get()),
- ReplacePattern(POWERSAVE_UID_MAP, powerSaveUidMap.get()),
- ReplacePattern(BANDWIDTH_UID_MAP, bandwidthUidMap.get()),
+ ReplacePattern(COOKIE_TAG_MAP, cookieTagMap.get()),
+ ReplacePattern(UID_COUNTERSET_MAP, uidCounterSetMap.get()),
+ ReplacePattern(APP_UID_STATS_MAP, appUidStatsMap.get()),
+ ReplacePattern(UID_STATS_MAP, uidStatsMap.get()),
+ ReplacePattern(TAG_STATS_MAP, tagStatsMap.get()),
+ ReplacePattern(IFACE_STATS_MAP, ifaceStatsMap.get()),
+ ReplacePattern(CONFIGURATION_MAP, configurationMap.get()),
+ ReplacePattern(UID_OWNER_MAP, uidOwnerMap.get()),
};
-
- int opt;
- bool doIngress = false, doEgress = false, doPrerouting = false, doMangle = false;
- bool doWhitelist = false, doBlacklist = false;
- while ((opt = getopt(argc, argv, "iepmwb")) != -1) {
- switch (opt) {
- case 'i':
- doIngress = true;
- break;
- case 'e':
- doEgress = true;
- break;
- case 'p':
- doPrerouting = true;
- break;
- case 'm':
- doMangle = true;
- break;
- case 'w':
- doWhitelist = true;
- break;
- case 'b':
- doBlacklist = true;
- break;
- default:
- usage();
- FAIL("unknown argument %c", opt);
- }
- }
android::bpf::parseProgramsFromFile(BPF_PROG_SRC);
- if (doIngress) {
- ret = loadAndAttachProgram(BPF_CGROUP_INET_INGRESS, BPF_INGRESS_PROG_PATH,
- BPF_CGROUP_INGRESS_PROG_NAME, mapPatterns);
- if (ret) {
- FAIL("Failed to set up ingress program");
- }
- }
- if (doEgress) {
- ret = loadAndAttachProgram(BPF_CGROUP_INET_EGRESS, BPF_EGRESS_PROG_PATH,
- BPF_CGROUP_EGRESS_PROG_NAME, mapPatterns);
- if (ret) {
- FAIL("Failed to set up ingress program");
- }
- }
- if (doPrerouting) {
- ret = loadAndAttachProgram(MAX_BPF_ATTACH_TYPE, XT_BPF_INGRESS_PROG_PATH,
- XT_BPF_INGRESS_PROG_NAME, mapPatterns);
- if (ret) {
- FAIL("Failed to set up xt_bpf program");
- }
- }
- if (doMangle) {
- ret = loadAndAttachProgram(MAX_BPF_ATTACH_TYPE, XT_BPF_EGRESS_PROG_PATH,
- XT_BPF_EGRESS_PROG_NAME, mapPatterns);
- if (ret) {
- FAIL("Failed to set up xt_bpf program");
- }
- }
- if (doWhitelist) {
- ret = loadAndAttachProgram(MAX_BPF_ATTACH_TYPE, XT_BPF_WHITELIST_PROG_PATH,
- XT_BPF_WHITELIST_PROG_NAME, mapPatterns);
- if (ret) {
- FAIL("Failed to set up xt_bpf Whitelist program");
- }
- }
- if (doBlacklist) {
- ret = loadAndAttachProgram(MAX_BPF_ATTACH_TYPE, XT_BPF_BLACKLIST_PROG_PATH,
- XT_BPF_BLACKLIST_PROG_NAME, mapPatterns);
- if (ret) {
- FAIL("Failed to set up xt_bpf blacklist program");
+ struct BpfProgInfo {
+ bpf_attach_type attachType;
+ const char* path;
+ const char* name;
+ bpf_prog_type loadType;
+ Slice progBlock;
+ } programs[] = {{BPF_CGROUP_INET_INGRESS, BPF_INGRESS_PROG_PATH, BPF_CGROUP_INGRESS_PROG_NAME,
+ BPF_PROG_TYPE_CGROUP_SKB, cgroupIngressProg},
+ {BPF_CGROUP_INET_EGRESS, BPF_EGRESS_PROG_PATH, BPF_CGROUP_EGRESS_PROG_NAME,
+ BPF_PROG_TYPE_CGROUP_SKB, cgroupEgressProg},
+ {MAX_BPF_ATTACH_TYPE, XT_BPF_INGRESS_PROG_PATH, XT_BPF_INGRESS_PROG_NAME,
+ BPF_PROG_TYPE_SOCKET_FILTER, xtIngressProg},
+ {MAX_BPF_ATTACH_TYPE, XT_BPF_EGRESS_PROG_PATH, XT_BPF_EGRESS_PROG_NAME,
+ BPF_PROG_TYPE_SOCKET_FILTER, xtEgressProg},
+ {MAX_BPF_ATTACH_TYPE, XT_BPF_WHITELIST_PROG_PATH, XT_BPF_WHITELIST_PROG_NAME,
+ BPF_PROG_TYPE_SOCKET_FILTER, xtWhiteListProg},
+ {MAX_BPF_ATTACH_TYPE, XT_BPF_BLACKLIST_PROG_PATH, XT_BPF_BLACKLIST_PROG_NAME,
+ BPF_PROG_TYPE_SOCKET_FILTER, xtBlackListProg}};
+
+ for (size_t i = 0; i < ARRAY_SIZE(programs); i++) {
+ BpfProgInfo* prog = programs + i;
+ if (access(prog->path, R_OK) == -1) {
+ // Program doesn't exist. Try to load it.
+ unique_fd fd;
+ fd.reset(loadProg(prog->progBlock, prog->loadType, mapPatterns));
+ if (fd < 0) {
+ FAIL("load %s failed: %s", prog->name, strerror(errno));
+ }
+ int ret = 0;
+ if (prog->attachType == BPF_CGROUP_INET_EGRESS ||
+ prog->attachType == BPF_CGROUP_INET_INGRESS) {
+ unique_fd cg_fd(open(CGROUP_ROOT_PATH, O_DIRECTORY | O_RDONLY | O_CLOEXEC));
+ if (cg_fd < 0) {
+ FAIL("Failed to open the cgroup directory");
+ }
+ ret = android::bpf::attachProgram(prog->attachType, fd, cg_fd);
+ if (ret) {
+ FAIL("%s attach failed: %s", prog->name, strerror(errno));
+ }
+ }
+
+ ret = android::bpf::mapPin(fd, prog->path);
+ if (ret) {
+ FAIL("Pin %s as file %s failed: %s", prog->name, prog->path, strerror(errno));
+ }
}
}
return ret;
diff --git a/bpfloader/bpf_kern.c b/bpfloader/bpf_kern.c
index 1d04cda..4fe8140 100644
--- a/bpfloader/bpf_kern.c
+++ b/bpfloader/bpf_kern.c
@@ -46,15 +46,15 @@
int xt_bpf_whitelist_prog(struct __sk_buff* skb) {
uint32_t sock_uid = get_socket_uid(skb);
if (is_system_uid(sock_uid)) return BPF_MATCH;
- uint8_t* whitelistMatch = find_map_entry(BANDWIDTH_UID_MAP, &sock_uid);
- if (whitelistMatch) return *whitelistMatch & WHITELISTMATCH;
+ uint8_t* whitelistMatch = find_map_entry(UID_OWNER_MAP, &sock_uid);
+ if (whitelistMatch) return *whitelistMatch & HAPPY_BOX_MATCH;
return BPF_NOMATCH;
}
ELF_SEC(XT_BPF_BLACKLIST_PROG_NAME)
int xt_bpf_blacklist_prog(struct __sk_buff* skb) {
uint32_t sock_uid = get_socket_uid(skb);
- uint8_t* blacklistMatch = find_map_entry(BANDWIDTH_UID_MAP, &sock_uid);
- if (blacklistMatch) return *blacklistMatch & BLACKLISTMATCH;
+ uint8_t* blacklistMatch = find_map_entry(UID_OWNER_MAP, &sock_uid);
+ if (blacklistMatch) return *blacklistMatch & PENALTY_BOX_MATCH;
return BPF_NOMATCH;
}
diff --git a/bpfloader/bpf_kern.h b/bpfloader/bpf_kern.h
index b0efe77..e56033d 100644
--- a/bpfloader/bpf_kern.h
+++ b/bpfloader/bpf_kern.h
@@ -35,6 +35,7 @@
#include <linux/in6.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
+#include <stdbool.h>
#include <stdint.h>
#include "bpf/bpf_shared.h"
@@ -110,7 +111,7 @@
}
}
-static inline int bpf_owner_match(struct __sk_buff* skb, uint32_t uid) {
+static inline bool skip_owner_match(struct __sk_buff* skb) {
int offset = -1;
int ret = 0;
if (skb->protocol == ETH_P_IP) {
@@ -120,13 +121,13 @@
ret = bpf_skb_load_bytes(skb, offset, &proto, 1);
if (!ret) {
if (proto == IPPROTO_ESP) {
- return 1;
+ return true;
} else if (proto == IPPROTO_TCP) {
ret = bpf_skb_load_bytes(skb, IPPROTO_IHL_OFF, &ihl, 1);
ihl = ihl & 0x0F;
ret = bpf_skb_load_bytes(skb, ihl * 4 + TCP_FLAG_OFF, &flag, 1);
if (ret == 0 && (flag >> RST_OFFSET & 1)) {
- return BPF_PASS;
+ return true;
}
}
}
@@ -136,40 +137,48 @@
ret = bpf_skb_load_bytes(skb, offset, &proto, 1);
if (!ret) {
if (proto == IPPROTO_ESP) {
- return BPF_PASS;
+ return true;
} else if (proto == IPPROTO_TCP) {
uint16_t flag;
ret = bpf_skb_load_bytes(skb, sizeof(struct ipv6hdr) + TCP_FLAG_OFF, &flag, 1);
if (ret == 0 && (flag >> RST_OFFSET & 1)) {
- return BPF_PASS;
+ return true;
}
}
}
}
+ return false;
+}
+
+static __always_inline BpfConfig getConfig() {
+ uint32_t mapSettingKey = CONFIGURATION_KEY;
+ BpfConfig* config = find_map_entry(CONFIGURATION_MAP, &mapSettingKey);
+ if (!config) {
+ // Couldn't read configuration entry. Assume everything is disabled.
+ return DEFAULT_CONFIG;
+ }
+ return *config;
+}
+
+static inline int bpf_owner_match(struct __sk_buff* skb, uint32_t uid) {
+ if (skip_owner_match(skb)) return BPF_PASS;
if ((uid <= MAX_SYSTEM_UID) && (uid >= MIN_SYSTEM_UID)) return BPF_PASS;
- // In each of these maps, the entry with key UID_MAP_ENABLED tells us whether that
- // map is enabled or not.
- // TODO: replace this with a map of size one that contains a config structure defined in
- // bpf_shared.h that can be written by userspace and read here.
- uint32_t mapSettingKey = UID_MAP_ENABLED;
- uint8_t* ownerMatch;
- uint8_t* mapEnabled = find_map_entry(DOZABLE_UID_MAP, &mapSettingKey);
- if (mapEnabled && *mapEnabled) {
- ownerMatch = find_map_entry(DOZABLE_UID_MAP, &uid);
- if (ownerMatch) return *ownerMatch;
+ BpfConfig enabledRules = getConfig();
+ if (!enabledRules) {
+ return BPF_PASS;
+ }
+
+ uint8_t* uidEntry = find_map_entry(UID_OWNER_MAP, &uid);
+ uint8_t uidRules = uidEntry ? *uidEntry : 0;
+ if ((enabledRules & DOZABLE_MATCH) && !(uidRules & DOZABLE_MATCH)) {
return BPF_DROP;
}
- mapEnabled = find_map_entry(STANDBY_UID_MAP, &mapSettingKey);
- if (mapEnabled && *mapEnabled) {
- ownerMatch = find_map_entry(STANDBY_UID_MAP, &uid);
- if (ownerMatch) return *ownerMatch;
+ if ((enabledRules & STANDBY_MATCH) && (uidRules & STANDBY_MATCH)) {
+ return BPF_DROP;
}
- mapEnabled = find_map_entry(POWERSAVE_UID_MAP, &mapSettingKey);
- if (mapEnabled && *mapEnabled) {
- ownerMatch = find_map_entry(POWERSAVE_UID_MAP, &uid);
- if (ownerMatch) return *ownerMatch;
+ if ((enabledRules & POWERSAVE_MATCH) && !(uidRules & POWERSAVE_MATCH)) {
return BPF_DROP;
}
return BPF_PASS;
diff --git a/libbpf/BpfUtils.cpp b/libbpf/BpfUtils.cpp
index 9a587fb..9502af6 100644
--- a/libbpf/BpfUtils.cpp
+++ b/libbpf/BpfUtils.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "BpfUtils"
+
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/in.h>
diff --git a/libbpf/include/bpf/BpfMap.h b/libbpf/include/bpf/BpfMap.h
index 51459f1..2e26d7a 100644
--- a/libbpf/include/bpf/BpfMap.h
+++ b/libbpf/include/bpf/BpfMap.h
@@ -165,7 +165,7 @@
const auto deleteAllEntries = [](const Key& key, BpfMap<Key, Value>& map) {
netdutils::Status res = map.deleteValue(key);
if (!isOk(res) && (res.code() != ENOENT)) {
- ALOGE("Failed to delete data(uid=%u): %s\n", key, strerror(res.code()));
+ ALOGE("Failed to delete data %s\n", strerror(res.code()));
}
return netdutils::status::ok;
};
diff --git a/libbpf/include/bpf/BpfUtils.h b/libbpf/include/bpf/BpfUtils.h
index b13f6ac..5d0f248 100644
--- a/libbpf/include/bpf/BpfUtils.h
+++ b/libbpf/include/bpf/BpfUtils.h
@@ -104,6 +104,7 @@
constexpr const int TAG_STATS_MAP_SIZE = 10000;
constexpr const int IFACE_INDEX_NAME_MAP_SIZE = 1000;
constexpr const int IFACE_STATS_MAP_SIZE = 1000;
+constexpr const int CONFIGURATION_MAP_SIZE = 1;
constexpr const int UID_OWNER_MAP_SIZE = 2000;
constexpr const char* BPF_EGRESS_PROG_PATH = BPF_PATH "/egress_prog";
@@ -122,10 +123,8 @@
constexpr const char* TAG_STATS_MAP_PATH = BPF_PATH "/traffic_tag_stats_map";
constexpr const char* IFACE_INDEX_NAME_MAP_PATH = BPF_PATH "/traffic_iface_index_name_map";
constexpr const char* IFACE_STATS_MAP_PATH = BPF_PATH "/traffic_iface_stats_map";
-constexpr const char* DOZABLE_UID_MAP_PATH = BPF_PATH "/traffic_dozable_uid_map";
-constexpr const char* STANDBY_UID_MAP_PATH = BPF_PATH "/traffic_standby_uid_map";
-constexpr const char* POWERSAVE_UID_MAP_PATH = BPF_PATH "/traffic_powersave_uid_map";
-constexpr const char* BANDWIDTH_UID_MAP_PATH = BPF_PATH "/traffic_bandwidth_uid_map";
+constexpr const char* CONFIGURATION_MAP_PATH = BPF_PATH "/traffic_configuration_map";
+constexpr const char* UID_OWNER_MAP_PATH = BPF_PATH "/traffic_uid_owner_map";
constexpr const int OVERFLOW_COUNTERSET = 2;
diff --git a/libbpf/include/bpf/bpf_shared.h b/libbpf/include/bpf/bpf_shared.h
index f76820e..66aaac4 100644
--- a/libbpf/include/bpf/bpf_shared.h
+++ b/libbpf/include/bpf/bpf_shared.h
@@ -29,12 +29,22 @@
#define UID_STATS_MAP 0xbfdaafffffffffff
#define TAG_STATS_MAP 0xbfaaafffffffffff
#define IFACE_STATS_MAP 0xbf1faceaafffffff
-#define DOZABLE_UID_MAP 0Xbfd0ab1e1dafffff
-#define STANDBY_UID_MAP 0Xbfadb1daffffffff
-#define POWERSAVE_UID_MAP 0Xbf0eae1dafffffff
-#define BANDWIDTH_UID_MAP 0xbfbad1d1daffffff
+#define CONFIGURATION_MAP 0Xbfc0fa0affffffff
+#define UID_OWNER_MAP 0xbfbad1d1daffffff
-enum BandwithMatchType { NO_MATCH, WHITELISTMATCH, BLACKLISTMATCH };
+enum UidOwnerMatchType {
+ NO_MATCH,
+ HAPPY_BOX_MATCH = (1 << 0),
+ PENALTY_BOX_MATCH = (1 << 1),
+ DOZABLE_MATCH = (1 << 2),
+ STANDBY_MATCH = (1 << 3),
+ POWERSAVE_MATCH = (1 << 4),
+};
+
+// TODO: change the configuration object from an 8-bit bitmask to an object with clearer
+// semantics, like a struct.
+typedef uint8_t BpfConfig;
+const BpfConfig DEFAULT_CONFIG = 0;
// These are also defined in NetdConstants.h, but we want to minimize the number of headers
// included by the BPF kernel program.
@@ -42,4 +52,4 @@
// NetdConstants.h can also include it from there.
#define MIN_SYSTEM_UID 0
#define MAX_SYSTEM_UID 9999
-#define UID_MAP_ENABLED UINT32_MAX
+#define CONFIGURATION_KEY 1
diff --git a/server/BandwidthController.cpp b/server/BandwidthController.cpp
index a01ad41..fcbe266 100644
--- a/server/BandwidthController.cpp
+++ b/server/BandwidthController.cpp
@@ -152,13 +152,12 @@
*/
const std::string COMMIT_AND_CLOSE = "COMMIT\n";
-const std::string HAPPY_BOX_WHITELIST_COMMAND = StringPrintf(
- "-I bw_happy_box -m owner --uid-owner %d-%d --jump RETURN", 0, MAX_SYSTEM_UID);
-const std::string BPF_HAPPY_BOX_WHITELIST_COMMAND =
- StringPrintf("-I bw_happy_box -m bpf --object-pinned %s -j RETURN", XT_BPF_WHITELIST_PROG_PATH);
-const std::string BPF_PENALTY_BOX_BLACKLIST_COMMAND =
- StringPrintf("-I bw_penalty_box -m bpf --object-pinned %s -j REJECT",
- XT_BPF_BLACKLIST_PROG_PATH);
+const std::string HAPPY_BOX_MATCH_WHITELIST_COMMAND =
+ StringPrintf("-I bw_happy_box -m owner --uid-owner %d-%d --jump RETURN", 0, MAX_SYSTEM_UID);
+const std::string BPF_HAPPY_BOX_MATCH_WHITELIST_COMMAND = StringPrintf(
+ "-I bw_happy_box -m bpf --object-pinned %s -j RETURN", XT_BPF_WHITELIST_PROG_PATH);
+const std::string BPF_PENALTY_BOX_MATCH_BLACKLIST_COMMAND = StringPrintf(
+ "-I bw_penalty_box -m bpf --object-pinned %s -j REJECT", XT_BPF_BLACKLIST_PROG_PATH);
static const std::vector<std::string> IPT_FLUSH_COMMANDS = {
/*
@@ -218,50 +217,50 @@
const std::vector<std::string> getBasicAccountingCommands(const bool useBpf) {
const std::vector<std::string> ipt_basic_accounting_commands = {
- "*filter",
- // Prevents IPSec double counting (ESP and UDP-encap-ESP respectively)
- "-A bw_INPUT -p esp -j RETURN",
- StringPrintf("-A bw_INPUT -m mark --mark 0x%x/0x%x -j RETURN",
- uidBillingMask, uidBillingMask),
- "-A bw_INPUT -m owner --socket-exists", /* This is a tracking rule. */
- StringPrintf("-A bw_INPUT -j MARK --or-mark 0x%x", uidBillingMask),
+ "*filter",
+ // Prevents IPSec double counting (ESP and UDP-encap-ESP respectively)
+ "-A bw_INPUT -p esp -j RETURN",
+ StringPrintf("-A bw_INPUT -m mark --mark 0x%x/0x%x -j RETURN", uidBillingMask,
+ uidBillingMask),
+ "-A bw_INPUT -m owner --socket-exists", /* This is a tracking rule. */
+ StringPrintf("-A bw_INPUT -j MARK --or-mark 0x%x", uidBillingMask),
- // Prevents IPSec double counting (Tunnel mode and Transport mode,
- // respectively)
- "-A bw_OUTPUT -o " IPSEC_IFACE_PREFIX "+ -j RETURN",
- "-A bw_OUTPUT -m policy --pol ipsec --dir out -j RETURN",
- "-A bw_OUTPUT -m owner --socket-exists", /* This is a tracking rule. */
+ // Prevents IPSec double counting (Tunnel mode and Transport mode,
+ // respectively)
+ "-A bw_OUTPUT -o " IPSEC_IFACE_PREFIX "+ -j RETURN",
+ "-A bw_OUTPUT -m policy --pol ipsec --dir out -j RETURN",
+ "-A bw_OUTPUT -m owner --socket-exists", /* This is a tracking rule. */
- "-A bw_costly_shared --jump bw_penalty_box",
- useBpf ? BPF_PENALTY_BOX_BLACKLIST_COMMAND : "",
- "-A bw_penalty_box --jump bw_happy_box",
- "-A bw_happy_box --jump bw_data_saver",
- "-A bw_data_saver -j RETURN",
- useBpf ? BPF_HAPPY_BOX_WHITELIST_COMMAND : HAPPY_BOX_WHITELIST_COMMAND,
- "COMMIT",
+ "-A bw_costly_shared --jump bw_penalty_box",
+ useBpf ? BPF_PENALTY_BOX_MATCH_BLACKLIST_COMMAND : "",
+ "-A bw_penalty_box --jump bw_happy_box", "-A bw_happy_box --jump bw_data_saver",
+ "-A bw_data_saver -j RETURN",
+ useBpf ? BPF_HAPPY_BOX_MATCH_WHITELIST_COMMAND : HAPPY_BOX_MATCH_WHITELIST_COMMAND,
+ "COMMIT",
- "*raw",
- // Prevents IPSec double counting (Tunnel mode and Transport mode,
- // respectively)
- "-A bw_raw_PREROUTING -i " IPSEC_IFACE_PREFIX "+ -j RETURN",
- "-A bw_raw_PREROUTING -m policy --pol ipsec --dir in -j RETURN",
- "-A bw_raw_PREROUTING -m owner --socket-exists", /* This is a tracking rule. */
- useBpf ? StringPrintf("-A bw_raw_PREROUTING -m bpf --object-pinned %s",
- XT_BPF_INGRESS_PROG_PATH) : "",
- "COMMIT",
+ "*raw",
+ // Prevents IPSec double counting (Tunnel mode and Transport mode,
+ // respectively)
+ "-A bw_raw_PREROUTING -i " IPSEC_IFACE_PREFIX "+ -j RETURN",
+ "-A bw_raw_PREROUTING -m policy --pol ipsec --dir in -j RETURN",
+ "-A bw_raw_PREROUTING -m owner --socket-exists", /* This is a tracking rule. */
+ useBpf ? StringPrintf("-A bw_raw_PREROUTING -m bpf --object-pinned %s",
+ XT_BPF_INGRESS_PROG_PATH)
+ : "",
+ "COMMIT",
- "*mangle",
- // Prevents IPSec double counting (Tunnel mode and Transport mode,
- // respectively)
- "-A bw_mangle_POSTROUTING -o " IPSEC_IFACE_PREFIX "+ -j RETURN",
- "-A bw_mangle_POSTROUTING -m policy --pol ipsec --dir out -j RETURN",
- "-A bw_mangle_POSTROUTING -m owner --socket-exists", /* This is a tracking rule. */
- StringPrintf("-A bw_mangle_POSTROUTING -j MARK --set-mark 0x0/0x%x",
- uidBillingMask), // Clear the mark before sending this packet
- useBpf ? StringPrintf("-A bw_mangle_POSTROUTING -m bpf --object-pinned %s",
- XT_BPF_EGRESS_PROG_PATH) : "",
- COMMIT_AND_CLOSE
- };
+ "*mangle",
+ // Prevents IPSec double counting (Tunnel mode and Transport mode,
+ // respectively)
+ "-A bw_mangle_POSTROUTING -o " IPSEC_IFACE_PREFIX "+ -j RETURN",
+ "-A bw_mangle_POSTROUTING -m policy --pol ipsec --dir out -j RETURN",
+ "-A bw_mangle_POSTROUTING -m owner --socket-exists", /* This is a tracking rule. */
+ StringPrintf("-A bw_mangle_POSTROUTING -j MARK --set-mark 0x0/0x%x",
+ uidBillingMask), // Clear the mark before sending this packet
+ useBpf ? StringPrintf("-A bw_mangle_POSTROUTING -m bpf --object-pinned %s",
+ XT_BPF_EGRESS_PROG_PATH)
+ : "",
+ COMMIT_AND_CLOSE};
return ipt_basic_accounting_commands;
}
@@ -370,9 +369,9 @@
const std::string& chain, IptJumpOp jumpHandling,
IptOp op) {
if (mBpfSupported) {
- Status status = gCtls->trafficCtrl.updateBandwidthUidMap(appStrUids, jumpHandling, op);
- if (!isOk(status)) {
- ALOGE("unable to update the Bandwidth Uid Map: %s", toString(status).c_str());
+ Status status = gCtls->trafficCtrl.updateUidOwnerMap(appStrUids, jumpHandling, op);
+ if (!isOk(status)) {
+ ALOGE("unable to update the Bandwidth Uid Map: %s", toString(status).c_str());
}
return status.code();
}
diff --git a/server/FirewallController.cpp b/server/FirewallController.cpp
index ff1f19d..4e5e3e5 100644
--- a/server/FirewallController.cpp
+++ b/server/FirewallController.cpp
@@ -41,9 +41,6 @@
using android::base::Split;
using android::base::StringAppendF;
using android::base::StringPrintf;
-using android::bpf::DOZABLE_UID_MAP_PATH;
-using android::bpf::POWERSAVE_UID_MAP_PATH;
-using android::bpf::STANDBY_UID_MAP_PATH;
using android::net::gCtls;
namespace {
diff --git a/server/IptablesRestoreControllerTest.cpp b/server/IptablesRestoreControllerTest.cpp
index 7ccb1ce..e34f644 100644
--- a/server/IptablesRestoreControllerTest.cpp
+++ b/server/IptablesRestoreControllerTest.cpp
@@ -40,9 +40,6 @@
using android::base::Join;
using android::base::StringPrintf;
-using android::bpf::DOZABLE_UID_MAP_PATH;
-using android::bpf::STANDBY_UID_MAP_PATH;
-using android::bpf::POWERSAVE_UID_MAP_PATH;
using android::netdutils::ScopedMockSyscalls;
using testing::Return;
using testing::StrictMock;
diff --git a/server/TrafficController.cpp b/server/TrafficController.cpp
index 4426e58..bb7a0ad 100644
--- a/server/TrafficController.cpp
+++ b/server/TrafficController.cpp
@@ -71,6 +71,27 @@
constexpr int kSockDiagMsgType = SOCK_DIAG_BY_FAMILY;
constexpr int kSockDiagDoneMsgType = NLMSG_DONE;
+#define UID_MATCH_MSG_TRANS(result, target, match) \
+ do { \
+ if (match & target) { \
+ result.append(StringPrintf(" %s", #target)); \
+ match &= ~target; \
+ } \
+ } while (0)
+
+const std::string uidMatchTypeToString(uint8_t match) {
+ std::string matchType;
+ UID_MATCH_MSG_TRANS(matchType, HAPPY_BOX_MATCH, match);
+ UID_MATCH_MSG_TRANS(matchType, PENALTY_BOX_MATCH, match);
+ UID_MATCH_MSG_TRANS(matchType, DOZABLE_MATCH, match);
+ UID_MATCH_MSG_TRANS(matchType, STANDBY_MATCH, match);
+ UID_MATCH_MSG_TRANS(matchType, POWERSAVE_MATCH, match);
+ if (match) {
+ return StringPrintf("Unknown match: %u", match);
+ }
+ return matchType;
+}
+
StatusOr<std::unique_ptr<NetlinkListenerInterface>> makeSkDestroyListener() {
const auto& sys = sSyscalls.get();
ASSIGN_OR_RETURN(auto event, sys.eventfd(0, EFD_CLOEXEC));
@@ -117,7 +138,7 @@
Status initialOwnerMap(BpfMap<uint32_t, uint8_t>& map) {
map.clear();
- uint32_t mapSettingKey = UID_MAP_ENABLED;
+ uint32_t mapSettingKey = CONFIGURATION_KEY;
uint8_t defaultMapState = 0;
return map.writeValue(mapSettingKey, defaultMapState, BPF_NOEXIST);
}
@@ -156,29 +177,22 @@
"IfaceIndexNameMap", false));
RETURN_IF_NOT_OK(
- mDozableUidMap.getOrCreate(UID_OWNER_MAP_SIZE, DOZABLE_UID_MAP_PATH, BPF_MAP_TYPE_HASH));
- RETURN_IF_NOT_OK(changeOwnerAndMode(DOZABLE_UID_MAP_PATH, AID_ROOT, "DozableUidMap", true));
- RETURN_IF_NOT_OK(initialOwnerMap(mDozableUidMap));
-
- RETURN_IF_NOT_OK(
- mStandbyUidMap.getOrCreate(UID_OWNER_MAP_SIZE, STANDBY_UID_MAP_PATH, BPF_MAP_TYPE_HASH));
- RETURN_IF_NOT_OK(changeOwnerAndMode(STANDBY_UID_MAP_PATH, AID_ROOT, "StandbyUidMap", true));
- RETURN_IF_NOT_OK(initialOwnerMap(mStandbyUidMap));
-
- RETURN_IF_NOT_OK(mPowerSaveUidMap.getOrCreate(UID_OWNER_MAP_SIZE, POWERSAVE_UID_MAP_PATH,
- BPF_MAP_TYPE_HASH));
- RETURN_IF_NOT_OK(changeOwnerAndMode(POWERSAVE_UID_MAP_PATH, AID_ROOT, "PowerSaveUidMap", true));
- RETURN_IF_NOT_OK(initialOwnerMap(mPowerSaveUidMap));
-
- RETURN_IF_NOT_OK(
mIfaceStatsMap.getOrCreate(IFACE_STATS_MAP_SIZE, IFACE_STATS_MAP_PATH, BPF_MAP_TYPE_HASH));
RETURN_IF_NOT_OK(changeOwnerAndMode(IFACE_STATS_MAP_PATH, AID_NET_BW_STATS, "IfaceStatsMap",
false));
- RETURN_IF_NOT_OK(mBandwidthUidMap.getOrCreate(UID_OWNER_MAP_SIZE, BANDWIDTH_UID_MAP_PATH,
- BPF_MAP_TYPE_HASH));
- RETURN_IF_NOT_OK(changeOwnerAndMode(BANDWIDTH_UID_MAP_PATH, AID_ROOT, "BandwidthUidMap", true));
- mBandwidthUidMap.clear();
+ RETURN_IF_NOT_OK(mConfigurationMap.getOrCreate(CONFIGURATION_MAP_SIZE, CONFIGURATION_MAP_PATH,
+ BPF_MAP_TYPE_HASH));
+ RETURN_IF_NOT_OK(
+ changeOwnerAndMode(CONFIGURATION_MAP_PATH, AID_ROOT, "ConfigurationMap", true));
+ uint32_t key = CONFIGURATION_KEY;
+ uint8_t initialConfiguration = DEFAULT_CONFIG;
+ RETURN_IF_NOT_OK(mConfigurationMap.writeValue(key, initialConfiguration, BPF_ANY));
+
+ RETURN_IF_NOT_OK(
+ mUidOwnerMap.getOrCreate(UID_OWNER_MAP_SIZE, UID_OWNER_MAP_PATH, BPF_MAP_TYPE_HASH));
+ RETURN_IF_NOT_OK(changeOwnerAndMode(UID_OWNER_MAP_PATH, AID_ROOT, "UidOwnerMap", true));
+ mUidOwnerMap.clear();
return netdutils::status::ok;
}
@@ -241,38 +255,9 @@
std::vector<const char*> prog_args{
"/system/bin/bpfloader",
};
- int ret = access(BPF_INGRESS_PROG_PATH, R_OK);
- if (ret != 0 && errno == ENOENT) {
- prog_args.push_back((char*)"-i");
- }
- ret = access(BPF_EGRESS_PROG_PATH, R_OK);
- if (ret != 0 && errno == ENOENT) {
- prog_args.push_back((char*)"-e");
- }
- ret = access(XT_BPF_INGRESS_PROG_PATH, R_OK);
- if (ret != 0 && errno == ENOENT) {
- prog_args.push_back((char*)"-p");
- }
- ret = access(XT_BPF_EGRESS_PROG_PATH, R_OK);
- if (ret != 0 && errno == ENOENT) {
- prog_args.push_back((char*)"-m");
- }
- ret = access(XT_BPF_WHITELIST_PROG_PATH, R_OK);
- if (ret != 0 && errno == ENOENT) {
- prog_args.push_back((char*)"-w");
- }
- ret = access(XT_BPF_BLACKLIST_PROG_PATH, R_OK);
- if (ret != 0 && errno == ENOENT) {
- prog_args.push_back((char*)"-b");
- }
-
- if (prog_args.size() == 1) {
- // all program are loaded already.
- return netdutils::status::ok;
- }
prog_args.push_back(nullptr);
- ret = android_fork_execvp(prog_args.size(), (char**)prog_args.data(), status, false, true);
+ int ret = android_fork_execvp(prog_args.size(), (char**) prog_args.data(), status, false, true);
if (ret) {
ret = errno;
ALOGE("failed to execute %s: %s", prog_args[0], strerror(errno));
@@ -429,17 +414,13 @@
return 0;
}
-Status TrafficController::updateOwnerMapEntry(BpfMap<uint32_t, uint8_t>& map, uid_t uid,
- FirewallRule rule, FirewallType type) {
- if (uid == UID_MAP_ENABLED) {
- return statusFromErrno(-EINVAL, "This uid is reserved for map state");
- }
-
+Status TrafficController::updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
+ FirewallType type) {
+ std::lock_guard<std::mutex> guard(mOwnerMatchMutex);
if ((rule == ALLOW && type == WHITELIST) || (rule == DENY && type == BLACKLIST)) {
- uint8_t flag = (type == WHITELIST) ? BPF_PASS : BPF_DROP;
- RETURN_IF_NOT_OK(map.writeValue(uid, flag, BPF_ANY));
+ RETURN_IF_NOT_OK(addMatch(mUidOwnerMap, uid, match));
} else if ((rule == ALLOW && type == BLACKLIST) || (rule == DENY && type == WHITELIST)) {
- RETURN_IF_NOT_OK(map.deleteValue(uid));
+ RETURN_IF_NOT_OK(removeMatch(mUidOwnerMap, uid, match));
} else {
//Cannot happen.
return statusFromErrno(-EINVAL, "");
@@ -447,24 +428,53 @@
return netdutils::status::ok;
}
-BandwithMatchType TrafficController::jumpOpToMatch(BandwidthController::IptJumpOp jumpHandling) {
+UidOwnerMatchType TrafficController::jumpOpToMatch(BandwidthController::IptJumpOp jumpHandling) {
switch (jumpHandling) {
case BandwidthController::IptJumpReject:
- return BLACKLISTMATCH;
+ return PENALTY_BOX_MATCH;
case BandwidthController::IptJumpReturn:
- return WHITELISTMATCH;
+ return HAPPY_BOX_MATCH;
case BandwidthController::IptJumpNoAdd:
return NO_MATCH;
}
}
-Status TrafficController::updateBandwidthUidMap(const std::vector<std::string>& appStrUids,
- BandwidthController::IptJumpOp jumpHandling,
- BandwidthController::IptOp op) {
- uint8_t command = jumpOpToMatch(jumpHandling);
- if (command == NO_MATCH) {
- return statusFromErrno(EINVAL, StringPrintf("invalid IptJumpOp: %d, command: %d",
- jumpHandling, command));
+Status TrafficController::removeMatch(BpfMap<uint32_t, uint8_t>& map, uint32_t uid,
+ UidOwnerMatchType match) {
+ auto oldMatch = map.readValue(uid);
+ if (isOk(oldMatch)) {
+ uint8_t newMatch = oldMatch.value() & ~match;
+ if (newMatch == 0) {
+ RETURN_IF_NOT_OK(map.deleteValue(uid));
+ } else {
+ RETURN_IF_NOT_OK(map.writeValue(uid, newMatch, BPF_ANY));
+ }
+ } else {
+ return statusFromErrno(ENOENT, StringPrintf("uid: %u does not exist in map", uid));
+ }
+ return netdutils::status::ok;
+}
+
+Status TrafficController::addMatch(BpfMap<uint32_t, uint8_t>& map, uint32_t uid,
+ UidOwnerMatchType match) {
+ auto oldMatch = map.readValue(uid);
+ if (isOk(oldMatch)) {
+ uint8_t newMatch = oldMatch.value() | match;
+ map.writeValue((uint32_t) uid, newMatch, BPF_ANY);
+ } else {
+ RETURN_IF_NOT_OK(map.writeValue(uid, match, BPF_ANY));
+ }
+ return netdutils::status::ok;
+}
+
+Status TrafficController::updateUidOwnerMap(const std::vector<std::string>& appStrUids,
+ BandwidthController::IptJumpOp jumpHandling,
+ BandwidthController::IptOp op) {
+ std::lock_guard<std::mutex> guard(mOwnerMatchMutex);
+ UidOwnerMatchType match = jumpOpToMatch(jumpHandling);
+ if (match == NO_MATCH) {
+ return statusFromErrno(
+ EINVAL, StringPrintf("invalid IptJumpOp: %d, command: %d", jumpHandling, match));
}
for (const auto& appStrUid : appStrUids) {
char* endPtr;
@@ -474,27 +484,13 @@
return statusFromErrno(errno, "invalid uid string:" + appStrUid);
}
- auto match = mBandwidthUidMap.readValue(uid);
if (op == BandwidthController::IptOpDelete) {
- if(!isOk(match)) {
- return statusFromErrno(EINVAL, StringPrintf("uid(%ld): %s does not exist in map",
- uid, appStrUid.c_str()));
- }
- uint8_t newValue = match.value() & ~command;
- if (newValue == 0) {
- RETURN_IF_NOT_OK(mBandwidthUidMap.deleteValue((uint32_t)uid));
- } else {
- RETURN_IF_NOT_OK(mBandwidthUidMap.writeValue((uint32_t)uid, newValue, BPF_ANY));
- }
+ RETURN_IF_NOT_OK(removeMatch(mUidOwnerMap, uid, match));
} else if (op == BandwidthController::IptOpInsert) {
- uint8_t newValue = command;
- if (isOk(match)) {
- newValue |= match.value();
- }
- RETURN_IF_NOT_OK(mBandwidthUidMap.writeValue((uint32_t)uid, newValue, BPF_ANY));
+ RETURN_IF_NOT_OK(addMatch(mUidOwnerMap, uid, match));
} else {
// Cannot happen.
- return statusFromErrno(EINVAL, StringPrintf("invalid IptOp: %d, %d", op, command));
+ return statusFromErrno(EINVAL, StringPrintf("invalid IptOp: %d, %d", op, match));
}
}
return netdutils::status::ok;
@@ -502,7 +498,6 @@
int TrafficController::changeUidOwnerRule(ChildChain chain, uid_t uid, FirewallRule rule,
FirewallType type) {
- std::lock_guard<std::mutex> guard(mOwnerMatchMutex);
if (!ebpfSupported) {
ALOGE("bpf is not set up, should use iptables rule");
return -ENOSYS;
@@ -510,13 +505,13 @@
Status res;
switch (chain) {
case DOZABLE:
- res = updateOwnerMapEntry(mDozableUidMap, uid, rule, type);
+ res = updateOwnerMapEntry(DOZABLE_MATCH, uid, rule, type);
break;
case STANDBY:
- res = updateOwnerMapEntry(mStandbyUidMap, uid, rule, type);
+ res = updateOwnerMapEntry(STANDBY_MATCH, uid, rule, type);
break;
case POWERSAVE:
- res = updateOwnerMapEntry(mPowerSaveUidMap, uid, rule, type);
+ res = updateOwnerMapEntry(POWERSAVE_MATCH, uid, rule, type);
break;
case NONE:
default:
@@ -530,33 +525,32 @@
return 0;
}
-Status TrafficController::replaceUidsInMap(BpfMap<uint32_t, uint8_t>& map,
- const std::vector<int32_t>& uids, FirewallRule rule,
- FirewallType type) {
+Status TrafficController::replaceUidsInMap(const UidOwnerMatchType match,
+ const std::vector<int32_t>& uids) {
+ std::lock_guard<std::mutex> guard(mOwnerMatchMutex);
std::set<int32_t> uidSet(uids.begin(), uids.end());
std::vector<uint32_t> uidsToDelete;
auto getUidsToDelete = [&uidsToDelete, &uidSet](const uint32_t& key,
const BpfMap<uint32_t, uint8_t>&) {
- if (key != UID_MAP_ENABLED && uidSet.find((int32_t)key) == uidSet.end()) {
+ if (uidSet.find((int32_t) key) == uidSet.end()) {
uidsToDelete.push_back(key);
}
return netdutils::status::ok;
};
- RETURN_IF_NOT_OK(map.iterate(getUidsToDelete));
+ RETURN_IF_NOT_OK(mUidOwnerMap.iterate(getUidsToDelete));
for(auto uid : uidsToDelete) {
- RETURN_IF_NOT_OK(map.deleteValue(uid));
+ RETURN_IF_NOT_OK(removeMatch(mUidOwnerMap, uid, match));
}
for (auto uid : uids) {
- RETURN_IF_NOT_OK(updateOwnerMapEntry(map, uid, rule, type));
+ RETURN_IF_NOT_OK(addMatch(mUidOwnerMap, uid, match));
}
return netdutils::status::ok;
}
int TrafficController::replaceUidOwnerMap(const std::string& name, bool isWhitelist,
const std::vector<int32_t>& uids) {
- std::lock_guard<std::mutex> guard(mOwnerMatchMutex);
FirewallRule rule;
FirewallType type;
if (isWhitelist) {
@@ -568,11 +562,11 @@
}
Status res;
if (!name.compare(FirewallController::LOCAL_DOZABLE)) {
- res = replaceUidsInMap(mDozableUidMap, uids, rule, type);
+ res = replaceUidsInMap(DOZABLE_MATCH, uids);
} else if (!name.compare(FirewallController::LOCAL_STANDBY)) {
- res = replaceUidsInMap(mStandbyUidMap, uids, rule, type);
+ res = replaceUidsInMap(STANDBY_MATCH, uids);
} else if (!name.compare(FirewallController::LOCAL_POWERSAVE)) {
- res = replaceUidsInMap(mPowerSaveUidMap, uids, rule, type);
+ res = replaceUidsInMap(POWERSAVE_MATCH, uids);
} else {
ALOGE("unknown chain name: %s", name.c_str());
return -EINVAL;
@@ -586,22 +580,32 @@
int TrafficController::toggleUidOwnerMap(ChildChain chain, bool enable) {
std::lock_guard<std::mutex> guard(mOwnerMatchMutex);
- uint32_t keyUid = UID_MAP_ENABLED;
- uint8_t mapState = enable ? 1 : 0;
+ uint32_t key = CONFIGURATION_KEY;
+ auto oldConfiguration = mConfigurationMap.readValue(key);
+ if (!isOk(oldConfiguration)) {
+ ALOGE("Cannot read the old configuration from map: %s",
+ oldConfiguration.status().msg().c_str());
+ return -oldConfiguration.status().code();
+ }
Status res;
+ BpfConfig newConfiguration;
+ uint8_t match;
switch (chain) {
case DOZABLE:
- res = mDozableUidMap.writeValue(keyUid, mapState, BPF_EXIST);
+ match = DOZABLE_MATCH;
break;
case STANDBY:
- res = mStandbyUidMap.writeValue(keyUid, mapState, BPF_EXIST);
+ match = STANDBY_MATCH;
break;
case POWERSAVE:
- res = mPowerSaveUidMap.writeValue(keyUid, mapState, BPF_EXIST);
+ match = POWERSAVE_MATCH;
break;
default:
return -EINVAL;
}
+ newConfiguration =
+ enable ? (oldConfiguration.value() | match) : (oldConfiguration.value() & (~match));
+ res = mConfigurationMap.writeValue(key, newConfiguration, BPF_EXIST);
if (!isOk(res)) {
ALOGE("Failed to toggleUidOwnerMap(%d): %s", chain, res.msg().c_str());
}
@@ -670,14 +674,10 @@
getMapStatus(mIfaceIndexNameMap.getMap(), IFACE_INDEX_NAME_MAP_PATH).c_str());
dw.println("mIfaceStatsMap status: %s",
getMapStatus(mIfaceStatsMap.getMap(), IFACE_STATS_MAP_PATH).c_str());
- dw.println("mDozableUidMap status: %s",
- getMapStatus(mDozableUidMap.getMap(), DOZABLE_UID_MAP_PATH).c_str());
- dw.println("mStandbyUidMap status: %s",
- getMapStatus(mStandbyUidMap.getMap(), STANDBY_UID_MAP_PATH).c_str());
- dw.println("mPowerSaveUidMap status: %s",
- getMapStatus(mPowerSaveUidMap.getMap(), POWERSAVE_UID_MAP_PATH).c_str());
- dw.println("mBandwidthUidMap status: %s",
- getMapStatus(mBandwidthUidMap.getMap(), BANDWIDTH_UID_MAP_PATH).c_str());
+ dw.println("mConfigurationMap status: %s",
+ getMapStatus(mConfigurationMap.getMap(), CONFIGURATION_MAP_PATH).c_str());
+ dw.println("mUidOwnerMap status: %s",
+ getMapStatus(mUidOwnerMap.getMap(), UID_OWNER_MAP_PATH).c_str());
dw.blankline();
dw.println("Cgroup ingress program status: %s",
@@ -799,29 +799,24 @@
dw.println("mIfaceStatsMap print end with error: %s", res.msg().c_str());
}
- // Print owner match uid maps
- dumpBpfMap("mDozableUidMap", dw, "");
- res = mDozableUidMap.iterateWithValue(printUidInfo);
- if (!isOk(res)) {
- dw.println("mDozableUidMap print end with error: %s", res.msg().c_str());
- }
+ dw.blankline();
- dumpBpfMap("mStandbyUidMap", dw, "");
- res = mStandbyUidMap.iterateWithValue(printUidInfo);
- if (!isOk(res)) {
- dw.println("mDozableUidMap print end with error: %s", res.msg().c_str());
+ uint32_t key = CONFIGURATION_KEY;
+ auto configuration = mConfigurationMap.readValue(key);
+ if (isOk(configuration)) {
+ dw.println("current configuration: %d", configuration.value());
+ } else {
+ dw.println("mConfigurationMap read with error: %s", configuration.status().msg().c_str());
}
-
- dumpBpfMap("mPowerSaveUidMap", dw, "");
- res = mPowerSaveUidMap.iterateWithValue(printUidInfo);
+ dumpBpfMap("mUidOwnerMap", dw, "");
+ const auto printUidMatchInfo = [&dw](const uint32_t& key, const uint8_t& value,
+ const BpfMap<uint32_t, uint8_t>&) {
+ dw.println("%u %s", key, uidMatchTypeToString(value).c_str());
+ return netdutils::status::ok;
+ };
+ res = mUidOwnerMap.iterateWithValue(printUidMatchInfo);
if (!isOk(res)) {
- dw.println("mDozableUidMap print end with error: %s", res.msg().c_str());
- }
-
- dumpBpfMap("mBandwidthUidMap", dw, "");
- res = mBandwidthUidMap.iterateWithValue(printUidInfo);
- if (!isOk(res)) {
- dw.println("mBandwidthUidMap print end with error: %s", res.msg().c_str());
+ dw.println("mUidOwnerMap print end with error: %s", res.msg().c_str());
}
}
diff --git a/server/TrafficController.h b/server/TrafficController.h
index e4e32f4..afc78a5 100644
--- a/server/TrafficController.h
+++ b/server/TrafficController.h
@@ -99,18 +99,16 @@
int replaceUidOwnerMap(const std::string& name, bool isWhitelist,
const std::vector<int32_t>& uids);
- netdutils::Status updateOwnerMapEntry(BpfMap<uint32_t, uint8_t>& map, uid_t uid,
- FirewallRule rule, FirewallType type);
+ netdutils::Status updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
+ FirewallType type);
void dump(DumpWriter& dw, bool verbose);
- netdutils::Status replaceUidsInMap(BpfMap<uint32_t, uint8_t>& map,
- const std::vector<int32_t>& uids, FirewallRule rule,
- FirewallType type);
+ netdutils::Status replaceUidsInMap(UidOwnerMatchType match, const std::vector<int32_t>& uids);
- netdutils::Status updateBandwidthUidMap(const std::vector<std::string>& appStrUids,
- BandwidthController::IptJumpOp jumpHandling,
- BandwidthController::IptOp op);
+ netdutils::Status updateUidOwnerMap(const std::vector<std::string>& appStrUids,
+ BandwidthController::IptJumpOp jumpHandling,
+ BandwidthController::IptOp op);
static const String16 DUMP_KEYWORD;
int toggleUidOwnerMap(ChildChain chain, bool enable);
@@ -180,30 +178,24 @@
BpfMap<uint32_t, StatsValue> mIfaceStatsMap;
/*
- * mDozableUidMap: Store uids that have related rules in dozable mode owner match
- * chain.
- */
- BpfMap<uint32_t, uint8_t> mDozableUidMap GUARDED_BY(mOwnerMatchMutex);
-
- /*
- * mStandbyUidMap: Store uids that have related rules in standby mode owner match
- * chain.
- */
- BpfMap<uint32_t, uint8_t> mStandbyUidMap GUARDED_BY(mOwnerMatchMutex);
-
- /*
* mPowerSaveUidMap: Store uids that have related rules in power save mode owner match
* chain.
*/
- BpfMap<uint32_t, uint8_t> mPowerSaveUidMap GUARDED_BY(mOwnerMatchMutex);
+ BpfMap<uint32_t, uint8_t> mConfigurationMap GUARDED_BY(mOwnerMatchMutex);
/*
- * mBandwidthUidMap: Store uids that are used for bandwidth control uid match.
+ * mUidOwnerMap: Store uids that are used for bandwidth control uid match.
*/
- BpfMap<uint32_t, uint8_t> mBandwidthUidMap;
+ BpfMap<uint32_t, uint8_t> mUidOwnerMap GUARDED_BY(mOwnerMatchMutex);
std::unique_ptr<NetlinkListenerInterface> mSkDestroyListener;
+ netdutils::Status removeMatch(BpfMap<uint32_t, uint8_t>& map, uint32_t uid,
+ UidOwnerMatchType match) REQUIRES(mOwnerMatchMutex);
+
+ netdutils::Status addMatch(BpfMap<uint32_t, uint8_t>& map, uint32_t uid,
+ UidOwnerMatchType match) REQUIRES(mOwnerMatchMutex);
+
bool ebpfSupported;
std::mutex mOwnerMatchMutex;
@@ -213,7 +205,7 @@
netdutils::Status initMaps();
- BandwithMatchType jumpOpToMatch(BandwidthController::IptJumpOp jumpHandling);
+ UidOwnerMatchType jumpOpToMatch(BandwidthController::IptJumpOp jumpHandling);
// For testing
friend class TrafficControllerTest;
};
diff --git a/server/TrafficControllerTest.cpp b/server/TrafficControllerTest.cpp
index 359ea8a..c3b6a6e 100644
--- a/server/TrafficControllerTest.cpp
+++ b/server/TrafficControllerTest.cpp
@@ -75,10 +75,8 @@
BpfMap<uint32_t, StatsValue> mFakeAppUidStatsMap;
BpfMap<StatsKey, StatsValue> mFakeUidStatsMap;
BpfMap<StatsKey, StatsValue> mFakeTagStatsMap;
- BpfMap<uint32_t, uint8_t> mFakeDozableUidMap;
- BpfMap<uint32_t, uint8_t> mFakeStandbyUidMap;
- BpfMap<uint32_t, uint8_t> mFakePowerSaveUidMap;
- BpfMap<uint32_t, uint8_t> mFakeBandwidthUidMap;
+ BpfMap<uint32_t, uint8_t> mFakeConfigurationMap;
+ BpfMap<uint32_t, uint8_t> mFakeUidOwnerMap;
void SetUp() {
std::lock_guard<std::mutex> ownerGuard(mTc.mOwnerMatchMutex);
@@ -104,21 +102,13 @@
sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
ASSERT_LE(0, mFakeTagStatsMap.getMap());
- mFakeDozableUidMap.reset(
- createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
- ASSERT_LE(0, mFakeDozableUidMap.getMap());
+ mFakeConfigurationMap.reset(
+ createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), 1, 0));
+ ASSERT_LE(0, mFakeConfigurationMap.getMap());
- mFakeStandbyUidMap.reset(
- createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
- ASSERT_LE(0, mFakeStandbyUidMap.getMap());
-
- mFakePowerSaveUidMap.reset(
- createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
- ASSERT_LE(0, mFakePowerSaveUidMap.getMap());
-
- mFakeBandwidthUidMap.reset(
- createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
- ASSERT_LE(0, mFakeBandwidthUidMap.getMap());
+ mFakeUidOwnerMap.reset(
+ createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
+ ASSERT_LE(0, mFakeUidOwnerMap.getMap());
// Make sure trafficController use the eBPF code path.
mTc.ebpfSupported = true;
@@ -127,10 +117,8 @@
mTc.mAppUidStatsMap.reset(mFakeAppUidStatsMap.getMap());
mTc.mUidStatsMap.reset(mFakeUidStatsMap.getMap());
mTc.mTagStatsMap.reset(mFakeTagStatsMap.getMap());
- mTc.mDozableUidMap.reset(mFakeDozableUidMap.getMap());
- mTc.mStandbyUidMap.reset(mFakeStandbyUidMap.getMap());
- mTc.mPowerSaveUidMap.reset(mFakePowerSaveUidMap.getMap());
- mTc.mBandwidthUidMap.reset(mFakeBandwidthUidMap.getMap());
+ mTc.mConfigurationMap.reset(mFakeConfigurationMap.getMap());
+ mTc.mUidOwnerMap.reset(mFakeUidOwnerMap.getMap());
}
int setUpSocketAndTag(int protocol, uint64_t* cookie, uint32_t tag, uid_t uid) {
@@ -166,43 +154,42 @@
key->tag = tag;
}
- void checkUidOwnerRuleForChain(ChildChain chain, BpfMap<uint32_t, uint8_t>& targetMap) {
+ void checkUidOwnerRuleForChain(ChildChain chain, UidOwnerMatchType match) {
uint32_t uid = TEST_UID;
EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, BLACKLIST));
- StatusOr<uint8_t> value = targetMap.readValue(uid);
+ StatusOr<uint8_t> value = mFakeUidOwnerMap.readValue(uid);
EXPECT_TRUE(isOk(value));
- EXPECT_EQ(BPF_DROP, value.value());
+ EXPECT_TRUE(value.value() & match);
uid = TEST_UID2;
EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, WHITELIST));
- value = targetMap.readValue(uid);
+ value = mFakeUidOwnerMap.readValue(uid);
EXPECT_TRUE(isOk(value));
- EXPECT_EQ(BPF_PASS, value.value());
+ EXPECT_TRUE(value.value() & match);
EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, WHITELIST));
- value = targetMap.readValue(uid);
+ value = mFakeUidOwnerMap.readValue(uid);
EXPECT_FALSE(isOk(value));
EXPECT_EQ(ENOENT, value.status().code());
uid = TEST_UID;
EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, BLACKLIST));
- value = targetMap.readValue(uid);
+ value = mFakeUidOwnerMap.readValue(uid);
EXPECT_FALSE(isOk(value));
EXPECT_EQ(ENOENT, value.status().code());
uid = TEST_UID3;
EXPECT_EQ(-ENOENT, mTc.changeUidOwnerRule(chain, uid, ALLOW, BLACKLIST));
- value = targetMap.readValue(uid);
+ value = mFakeUidOwnerMap.readValue(uid);
EXPECT_FALSE(isOk(value));
EXPECT_EQ(ENOENT, value.status().code());
}
- void checkEachUidValue(const std::vector<int32_t>& uids, const uint8_t expectValue,
- BpfMap<uint32_t, uint8_t>& targetMap) {
+ void checkEachUidValue(const std::vector<int32_t>& uids, UidOwnerMatchType match) {
for (uint32_t uid : uids) {
- StatusOr<uint8_t> value = targetMap.readValue(uid);
+ StatusOr<uint8_t> value = mFakeUidOwnerMap.readValue(uid);
EXPECT_TRUE(isOk(value));
- EXPECT_EQ(expectValue, value.value());
+ EXPECT_TRUE(value.value() & match);
}
std::set<uint32_t> uidSet(uids.begin(), uids.end());
const auto checkNoOtherUid = [&uidSet](const int32_t& key,
@@ -210,25 +197,24 @@
EXPECT_NE(uidSet.end(), uidSet.find(key));
return netdutils::status::ok;
};
- EXPECT_TRUE(isOk(targetMap.iterate(checkNoOtherUid)));
+ EXPECT_TRUE(isOk(mFakeUidOwnerMap.iterate(checkNoOtherUid)));
}
void checkUidMapReplace(const std::string& name, const std::vector<int32_t>& uids,
- BpfMap<uint32_t, uint8_t>& targetMap) {
+ UidOwnerMatchType match) {
bool isWhitelist = true;
EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isWhitelist, uids));
- checkEachUidValue(uids, BPF_PASS, targetMap);
+ checkEachUidValue(uids, match);
isWhitelist = false;
EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isWhitelist, uids));
- checkEachUidValue(uids, BPF_DROP, targetMap);
+ checkEachUidValue(uids, match);
}
-
- void expectBandwidthMapValues(const std::vector<std::string>& appStrUids,
- uint8_t expectedValue) {
+ void expectUidOwnerMapValues(const std::vector<std::string>& appStrUids,
+ uint8_t expectedValue) {
for (const std::string& strUid : appStrUids) {
uint32_t uid = stoi(strUid);
- StatusOr<uint8_t> value = mFakeBandwidthUidMap.readValue(uid);
+ StatusOr<uint8_t> value = mFakeUidOwnerMap.readValue(uid);
EXPECT_TRUE(isOk(value));
EXPECT_EQ(expectedValue, value.value()) <<
"Expected value for UID " << uid << " to be " << expectedValue <<
@@ -248,17 +234,6 @@
ASSERT_TRUE(isEmpty.value());
}
- void TearDown() {
- std::lock_guard<std::mutex> ownerGuard(mTc.mOwnerMatchMutex);
- mFakeCookieTagMap.reset();
- mFakeUidCounterSetMap.reset();
- mFakeAppUidStatsMap.reset();
- mFakeUidStatsMap.reset();
- mFakeTagStatsMap.reset();
- mTc.mDozableUidMap.reset();
- mTc.mStandbyUidMap.reset();
- mTc.mPowerSaveUidMap.reset();
- }
};
TEST_F(TrafficControllerTest, TestTagSocketV4) {
@@ -463,35 +438,35 @@
SKIP_IF_BPF_NOT_SUPPORTED;
uint32_t uid = TEST_UID;
- ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, DENY, BLACKLIST)));
- StatusOr<uint8_t> value = mFakeDozableUidMap.readValue(uid);
+ ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, DENY, BLACKLIST)));
+ StatusOr<uint8_t> value = mFakeUidOwnerMap.readValue(uid);
ASSERT_TRUE(isOk(value));
- ASSERT_EQ(BPF_DROP, value.value());
+ ASSERT_TRUE(value.value() & STANDBY_MATCH);
+
+ ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, ALLOW, WHITELIST)));
+ value = mFakeUidOwnerMap.readValue(uid);
+ ASSERT_TRUE(isOk(value));
+ ASSERT_TRUE(value.value() & DOZABLE_MATCH);
+
+ ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, DENY, WHITELIST)));
+ value = mFakeUidOwnerMap.readValue(uid);
+ ASSERT_TRUE(isOk(value));
+ ASSERT_FALSE(value.value() & DOZABLE_MATCH);
+
+ ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, BLACKLIST)));
+ ASSERT_FALSE(isOk(mFakeUidOwnerMap.readValue(uid)));
uid = TEST_UID2;
- ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, WHITELIST)));
- value = mFakeDozableUidMap.readValue(uid);
- ASSERT_TRUE(isOk(value));
- ASSERT_EQ(BPF_PASS, value.value());
-
- ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, DENY, WHITELIST)));
- ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
-
- uid = TEST_UID;
- ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, BLACKLIST)));
- ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
-
- uid = TEST_UID3;
- ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, BLACKLIST)));
- ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
+ ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, BLACKLIST)));
+ ASSERT_FALSE(isOk(mFakeUidOwnerMap.readValue(uid)));
}
TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) {
SKIP_IF_BPF_NOT_SUPPORTED;
- checkUidOwnerRuleForChain(DOZABLE, mFakeDozableUidMap);
- checkUidOwnerRuleForChain(STANDBY, mFakeStandbyUidMap);
- checkUidOwnerRuleForChain(POWERSAVE, mFakePowerSaveUidMap);
+ checkUidOwnerRuleForChain(DOZABLE, DOZABLE_MATCH);
+ checkUidOwnerRuleForChain(STANDBY, STANDBY_MATCH);
+ checkUidOwnerRuleForChain(POWERSAVE, POWERSAVE_MATCH);
ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, WHITELIST));
ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, WHITELIST));
}
@@ -500,59 +475,69 @@
SKIP_IF_BPF_NOT_SUPPORTED;
std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
- checkUidMapReplace("fw_dozable", uids, mFakeDozableUidMap);
- checkUidMapReplace("fw_standby", uids, mFakeStandbyUidMap);
- checkUidMapReplace("fw_powersave", uids, mFakePowerSaveUidMap);
+ checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
+ checkUidMapReplace("fw_standby", uids, STANDBY_MATCH);
+ checkUidMapReplace("fw_powersave", uids, POWERSAVE_MATCH);
ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
}
+TEST_F(TrafficControllerTest, TestReplaceSameChain) {
+ SKIP_IF_BPF_NOT_SUPPORTED;
+
+ std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
+ checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
+ std::vector<int32_t> newUids = {TEST_UID2, TEST_UID3};
+ checkUidMapReplace("fw_dozable", newUids, DOZABLE_MATCH);
+}
+
TEST_F(TrafficControllerTest, TestBlacklistUidMatch) {
SKIP_IF_BPF_NOT_SUPPORTED;
std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
- BandwidthController::IptOpInsert)));
- expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
- BandwidthController::IptOpDelete)));
- expectMapEmpty(mFakeBandwidthUidMap);
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
+ BandwidthController::IptOpInsert)));
+ expectUidOwnerMapValues(appStrUids, PENALTY_BOX_MATCH);
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
+ BandwidthController::IptOpDelete)));
+ expectMapEmpty(mFakeUidOwnerMap);
}
TEST_F(TrafficControllerTest, TestWhitelistUidMatch) {
SKIP_IF_BPF_NOT_SUPPORTED;
std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
- BandwidthController::IptOpInsert)));
- expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
- BandwidthController::IptOpDelete)));
- expectMapEmpty(mFakeBandwidthUidMap);
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
+ BandwidthController::IptOpInsert)));
+ expectUidOwnerMapValues(appStrUids, HAPPY_BOX_MATCH);
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
+ BandwidthController::IptOpDelete)));
+ expectMapEmpty(mFakeUidOwnerMap);
}
TEST_F(TrafficControllerTest, TestReplaceMatchUid) {
SKIP_IF_BPF_NOT_SUPPORTED;
std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
- // Add appStrUids to the blacklist and expect that their values are all BLACKLISTMATCH.
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
- BandwidthController::IptOpInsert)));
- expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
+ // Add appStrUids to the blacklist and expect that their values are all PENALTY_BOX_MATCH.
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
+ BandwidthController::IptOpInsert)));
+ expectUidOwnerMapValues(appStrUids, PENALTY_BOX_MATCH);
- // Add the same UIDs to the whitelist and expect that we get BLACKLISTMATCH | WHITELISTMATCH.
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
- BandwidthController::IptOpInsert)));
- expectBandwidthMapValues(appStrUids, WHITELISTMATCH | BLACKLISTMATCH);
+ // Add the same UIDs to the whitelist and expect that we get PENALTY_BOX_MATCH |
+ // HAPPY_BOX_MATCH.
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
+ BandwidthController::IptOpInsert)));
+ expectUidOwnerMapValues(appStrUids, HAPPY_BOX_MATCH | PENALTY_BOX_MATCH);
- // Remove the same UIDs from the whitelist and check the BLACKLISTMATCH is still there.
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
- BandwidthController::IptOpDelete)));
- expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
+ // Remove the same UIDs from the whitelist and check the PENALTY_BOX_MATCH is still there.
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
+ BandwidthController::IptOpDelete)));
+ expectUidOwnerMapValues(appStrUids, PENALTY_BOX_MATCH);
// Remove the same UIDs from the blacklist and check the map is empty.
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
- BandwidthController::IptOpDelete)));
- ASSERT_FALSE(isOk(mFakeBandwidthUidMap.getFirstKey()));
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
+ BandwidthController::IptOpDelete)));
+ ASSERT_FALSE(isOk(mFakeUidOwnerMap.getFirstKey()));
}
TEST_F(TrafficControllerTest, TestDeleteWrongMatchSilentlyFails) {
@@ -560,22 +545,22 @@
std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
// If the uid does not exist in the map, trying to delete a rule about it will fail.
- ASSERT_FALSE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
- BandwidthController::IptOpDelete)));
- expectMapEmpty(mFakeBandwidthUidMap);
+ ASSERT_FALSE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
+ BandwidthController::IptOpDelete)));
+ expectMapEmpty(mFakeUidOwnerMap);
// Add blacklist rules for appStrUids.
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
- BandwidthController::IptOpInsert)));
- expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
+ BandwidthController::IptOpInsert)));
+ expectUidOwnerMapValues(appStrUids, HAPPY_BOX_MATCH);
// Delete (non-existent) blacklist rules for appStrUids, and check that this silently does
// nothing if the uid is in the map but does not have blacklist match. This is required because
// NetworkManagementService will try to remove a uid from blacklist after adding it to the
// whitelist and if the remove fails it will not update the uid status.
- ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
- BandwidthController::IptOpDelete)));
- expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
+ ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
+ BandwidthController::IptOpDelete)));
+ expectUidOwnerMapValues(appStrUids, HAPPY_BOX_MATCH);
}
} // namespace net
} // namespace android
diff --git a/tests/bpf_base_test.cpp b/tests/bpf_base_test.cpp
index 76c5bd8..ead06bd 100644
--- a/tests/bpf_base_test.cpp
+++ b/tests/bpf_base_test.cpp
@@ -77,9 +77,8 @@
ASSERT_EQ(0, access(TAG_STATS_MAP_PATH, R_OK));
ASSERT_EQ(0, access(IFACE_INDEX_NAME_MAP_PATH, R_OK));
ASSERT_EQ(0, access(IFACE_STATS_MAP_PATH, R_OK));
- ASSERT_EQ(0, access(DOZABLE_UID_MAP_PATH, R_OK));
- ASSERT_EQ(0, access(STANDBY_UID_MAP_PATH, R_OK));
- ASSERT_EQ(0, access(POWERSAVE_UID_MAP_PATH, R_OK));
+ ASSERT_EQ(0, access(CONFIGURATION_MAP_PATH, R_OK));
+ ASSERT_EQ(0, access(UID_OWNER_MAP_PATH, R_OK));
}
TEST_F(BpfBasicTest, TestTagSocket) {