blob: c3b6a6eb50dd2ff518ba0b5da31d59e76af68978 [file] [log] [blame]
Chenbo Fenged37fea2017-12-13 19:35:01 -08001/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * TrafficControllerTest.cpp - unit tests for TrafficController.cpp
17 */
18
19#include <string>
20#include <vector>
21
22#include <fcntl.h>
23#include <inttypes.h>
24#include <linux/inet_diag.h>
25#include <linux/sock_diag.h>
26#include <sys/socket.h>
27#include <sys/types.h>
28#include <unistd.h>
29
30#include <gtest/gtest.h>
31
32#include <android-base/stringprintf.h>
33#include <android-base/strings.h>
34
35#include <netdutils/MockSyscalls.h>
Chenbo Feng4f6c2372018-04-26 10:37:55 -070036#include "netdutils/Status.h"
37#include "netdutils/StatusOr.h"
38
Chenbo Feng89c12f12018-03-21 10:29:18 -070039#include "FirewallController.h"
Chenbo Fenged37fea2017-12-13 19:35:01 -080040#include "TrafficController.h"
41#include "bpf/BpfUtils.h"
42
Bernie Innocenti7e25ec02018-07-02 19:32:17 +090043using namespace android::bpf; // NOLINT(google-build-using-namespace): grandfathered
Chenbo Fenged37fea2017-12-13 19:35:01 -080044
45using ::testing::_;
46using ::testing::ByMove;
47using ::testing::Invoke;
48using ::testing::Return;
49using ::testing::StrictMock;
50using ::testing::Test;
51
52namespace android {
53namespace net {
54
55using base::unique_fd;
Chenbo Feng4f6c2372018-04-26 10:37:55 -070056using netdutils::isOk;
57using netdutils::Status;
Chenbo Fenged37fea2017-12-13 19:35:01 -080058using netdutils::status::ok;
Chenbo Feng4f6c2372018-04-26 10:37:55 -070059using netdutils::StatusOr;
Chenbo Fenged37fea2017-12-13 19:35:01 -080060
61constexpr int TEST_MAP_SIZE = 10;
62constexpr uid_t TEST_UID = 10086;
Chenbo Feng89c12f12018-03-21 10:29:18 -070063constexpr uid_t TEST_UID2 = 54321;
64constexpr uid_t TEST_UID3 = 98765;
Chenbo Fenged37fea2017-12-13 19:35:01 -080065constexpr uint32_t TEST_TAG = 42;
Chenbo Feng4f6c2372018-04-26 10:37:55 -070066constexpr uint32_t TEST_COUNTERSET = 1;
67constexpr uint32_t DEFAULT_COUNTERSET = 0;
Chenbo Fenged37fea2017-12-13 19:35:01 -080068
69class TrafficControllerTest : public ::testing::Test {
70 protected:
71 TrafficControllerTest() {}
72 TrafficController mTc;
Chenbo Feng4f6c2372018-04-26 10:37:55 -070073 BpfMap<uint64_t, UidTag> mFakeCookieTagMap;
74 BpfMap<uint32_t, uint8_t> mFakeUidCounterSetMap;
Chenbo Fengbc4a15f2018-05-11 19:15:15 -070075 BpfMap<uint32_t, StatsValue> mFakeAppUidStatsMap;
Chenbo Feng4f6c2372018-04-26 10:37:55 -070076 BpfMap<StatsKey, StatsValue> mFakeUidStatsMap;
77 BpfMap<StatsKey, StatsValue> mFakeTagStatsMap;
Chenbo Feng703798e2018-06-15 17:07:59 -070078 BpfMap<uint32_t, uint8_t> mFakeConfigurationMap;
79 BpfMap<uint32_t, uint8_t> mFakeUidOwnerMap;
Chenbo Fenged37fea2017-12-13 19:35:01 -080080
81 void SetUp() {
Chenbo Fengef1cab32018-04-13 19:50:49 -070082 std::lock_guard<std::mutex> ownerGuard(mTc.mOwnerMatchMutex);
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +090083 SKIP_IF_BPF_NOT_SUPPORTED;
84
Chenbo Feng4f6c2372018-04-26 10:37:55 -070085 mFakeCookieTagMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint64_t),
86 sizeof(struct UidTag), TEST_MAP_SIZE, 0));
87 ASSERT_LE(0, mFakeCookieTagMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -080088
Chenbo Feng4f6c2372018-04-26 10:37:55 -070089 mFakeUidCounterSetMap.reset(
90 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
91 ASSERT_LE(0, mFakeUidCounterSetMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -080092
Chenbo Fengbc4a15f2018-05-11 19:15:15 -070093 mFakeAppUidStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t),
94 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
95 ASSERT_LE(0, mFakeAppUidStatsMap.getMap());
96
Chenbo Feng4f6c2372018-04-26 10:37:55 -070097 mFakeUidStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(struct StatsKey),
98 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
99 ASSERT_LE(0, mFakeUidStatsMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800100
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700101 mFakeTagStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(struct StatsKey),
102 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
103 ASSERT_LE(0, mFakeTagStatsMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800104
Chenbo Feng703798e2018-06-15 17:07:59 -0700105 mFakeConfigurationMap.reset(
106 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), 1, 0));
107 ASSERT_LE(0, mFakeConfigurationMap.getMap());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700108
Chenbo Feng703798e2018-06-15 17:07:59 -0700109 mFakeUidOwnerMap.reset(
110 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
111 ASSERT_LE(0, mFakeUidOwnerMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800112 // Make sure trafficController use the eBPF code path.
113 mTc.ebpfSupported = true;
114
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700115 mTc.mCookieTagMap.reset(mFakeCookieTagMap.getMap());
116 mTc.mUidCounterSetMap.reset(mFakeUidCounterSetMap.getMap());
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700117 mTc.mAppUidStatsMap.reset(mFakeAppUidStatsMap.getMap());
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700118 mTc.mUidStatsMap.reset(mFakeUidStatsMap.getMap());
119 mTc.mTagStatsMap.reset(mFakeTagStatsMap.getMap());
Chenbo Feng703798e2018-06-15 17:07:59 -0700120 mTc.mConfigurationMap.reset(mFakeConfigurationMap.getMap());
121 mTc.mUidOwnerMap.reset(mFakeUidOwnerMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800122 }
123
124 int setUpSocketAndTag(int protocol, uint64_t* cookie, uint32_t tag, uid_t uid) {
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900125 int sock = socket(protocol, SOCK_STREAM | SOCK_CLOEXEC, 0);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800126 EXPECT_LE(0, sock);
127 *cookie = getSocketCookie(sock);
Chenbo Fengef1cab32018-04-13 19:50:49 -0700128 EXPECT_NE(NONEXISTENT_COOKIE, *cookie);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800129 EXPECT_EQ(0, mTc.tagSocket(sock, tag, uid));
130 return sock;
131 }
132
133 void expectUidTag(uint64_t cookie, uid_t uid, uint32_t tag) {
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700134 StatusOr<UidTag> tagResult = mFakeCookieTagMap.readValue(cookie);
135 EXPECT_TRUE(isOk(tagResult));
136 EXPECT_EQ(uid, tagResult.value().uid);
137 EXPECT_EQ(tag, tagResult.value().tag);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800138 }
139
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700140 void expectNoTag(uint64_t cookie) { EXPECT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie))); }
Chenbo Fenged37fea2017-12-13 19:35:01 -0800141
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700142 void populateFakeStats(uint64_t cookie, uint32_t uid, uint32_t tag, StatsKey* key) {
Chenbo Fenged37fea2017-12-13 19:35:01 -0800143 UidTag cookieMapkey = {.uid = (uint32_t)uid, .tag = tag};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700144 EXPECT_TRUE(isOk(mFakeCookieTagMap.writeValue(cookie, cookieMapkey, BPF_ANY)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800145 *key = {.uid = uid, .tag = tag, .counterSet = TEST_COUNTERSET, .ifaceIndex = 1};
Chenbo Fengeac6c472018-02-05 15:06:23 -0800146 StatsValue statsMapValue = {.rxPackets = 1, .rxBytes = 100};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700147 uint8_t counterSet = TEST_COUNTERSET;
148 EXPECT_TRUE(isOk(mFakeUidCounterSetMap.writeValue(uid, counterSet, BPF_ANY)));
149 EXPECT_TRUE(isOk(mFakeTagStatsMap.writeValue(*key, statsMapValue, BPF_ANY)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800150 key->tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700151 EXPECT_TRUE(isOk(mFakeUidStatsMap.writeValue(*key, statsMapValue, BPF_ANY)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700152 EXPECT_TRUE(isOk(mFakeAppUidStatsMap.writeValue(uid, statsMapValue, BPF_ANY)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800153 // put tag information back to statsKey
154 key->tag = tag;
Chenbo Fenged37fea2017-12-13 19:35:01 -0800155 }
156
Chenbo Feng703798e2018-06-15 17:07:59 -0700157 void checkUidOwnerRuleForChain(ChildChain chain, UidOwnerMatchType match) {
Chenbo Feng89c12f12018-03-21 10:29:18 -0700158 uint32_t uid = TEST_UID;
159 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, BLACKLIST));
Chenbo Feng703798e2018-06-15 17:07:59 -0700160 StatusOr<uint8_t> value = mFakeUidOwnerMap.readValue(uid);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700161 EXPECT_TRUE(isOk(value));
Chenbo Feng703798e2018-06-15 17:07:59 -0700162 EXPECT_TRUE(value.value() & match);
Chenbo Feng89c12f12018-03-21 10:29:18 -0700163
164 uid = TEST_UID2;
165 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, WHITELIST));
Chenbo Feng703798e2018-06-15 17:07:59 -0700166 value = mFakeUidOwnerMap.readValue(uid);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700167 EXPECT_TRUE(isOk(value));
Chenbo Feng703798e2018-06-15 17:07:59 -0700168 EXPECT_TRUE(value.value() & match);
Chenbo Feng89c12f12018-03-21 10:29:18 -0700169
170 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, WHITELIST));
Chenbo Feng703798e2018-06-15 17:07:59 -0700171 value = mFakeUidOwnerMap.readValue(uid);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700172 EXPECT_FALSE(isOk(value));
173 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700174
175 uid = TEST_UID;
176 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, BLACKLIST));
Chenbo Feng703798e2018-06-15 17:07:59 -0700177 value = mFakeUidOwnerMap.readValue(uid);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700178 EXPECT_FALSE(isOk(value));
179 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700180
181 uid = TEST_UID3;
182 EXPECT_EQ(-ENOENT, mTc.changeUidOwnerRule(chain, uid, ALLOW, BLACKLIST));
Chenbo Feng703798e2018-06-15 17:07:59 -0700183 value = mFakeUidOwnerMap.readValue(uid);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700184 EXPECT_FALSE(isOk(value));
185 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700186 }
187
Chenbo Feng703798e2018-06-15 17:07:59 -0700188 void checkEachUidValue(const std::vector<int32_t>& uids, UidOwnerMatchType match) {
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700189 for (uint32_t uid : uids) {
Chenbo Feng703798e2018-06-15 17:07:59 -0700190 StatusOr<uint8_t> value = mFakeUidOwnerMap.readValue(uid);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700191 EXPECT_TRUE(isOk(value));
Chenbo Feng703798e2018-06-15 17:07:59 -0700192 EXPECT_TRUE(value.value() & match);
Chenbo Feng89c12f12018-03-21 10:29:18 -0700193 }
194 std::set<uint32_t> uidSet(uids.begin(), uids.end());
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700195 const auto checkNoOtherUid = [&uidSet](const int32_t& key,
196 const BpfMap<uint32_t, uint8_t>&) {
197 EXPECT_NE(uidSet.end(), uidSet.find(key));
198 return netdutils::status::ok;
Chenbo Feng89c12f12018-03-21 10:29:18 -0700199 };
Chenbo Feng703798e2018-06-15 17:07:59 -0700200 EXPECT_TRUE(isOk(mFakeUidOwnerMap.iterate(checkNoOtherUid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700201 }
202
203 void checkUidMapReplace(const std::string& name, const std::vector<int32_t>& uids,
Chenbo Feng703798e2018-06-15 17:07:59 -0700204 UidOwnerMatchType match) {
Chenbo Feng89c12f12018-03-21 10:29:18 -0700205 bool isWhitelist = true;
206 EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isWhitelist, uids));
Chenbo Feng703798e2018-06-15 17:07:59 -0700207 checkEachUidValue(uids, match);
Chenbo Feng89c12f12018-03-21 10:29:18 -0700208
209 isWhitelist = false;
210 EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isWhitelist, uids));
Chenbo Feng703798e2018-06-15 17:07:59 -0700211 checkEachUidValue(uids, match);
Chenbo Feng89c12f12018-03-21 10:29:18 -0700212 }
Chenbo Feng703798e2018-06-15 17:07:59 -0700213 void expectUidOwnerMapValues(const std::vector<std::string>& appStrUids,
214 uint8_t expectedValue) {
Bernie Innocenti7e25ec02018-07-02 19:32:17 +0900215 for (const std::string& strUid : appStrUids) {
Chenbo Feng95892f32018-06-07 14:52:02 -0700216 uint32_t uid = stoi(strUid);
Chenbo Feng703798e2018-06-15 17:07:59 -0700217 StatusOr<uint8_t> value = mFakeUidOwnerMap.readValue(uid);
Chenbo Feng95892f32018-06-07 14:52:02 -0700218 EXPECT_TRUE(isOk(value));
219 EXPECT_EQ(expectedValue, value.value()) <<
220 "Expected value for UID " << uid << " to be " << expectedValue <<
221 ", but was " << value.value();
222 }
223 }
224
Chenbo Fengc16827b2018-06-08 15:58:11 -0700225 void expectMapEmpty(BpfMap<uint64_t, UidTag>& map) {
226 auto isEmpty = map.isEmpty();
227 EXPECT_TRUE(isOk(isEmpty));
228 EXPECT_TRUE(isEmpty.value());
229 }
230
231 void expectMapEmpty(BpfMap<uint32_t, uint8_t>& map) {
232 auto isEmpty = map.isEmpty();
233 ASSERT_TRUE(isOk(isEmpty));
234 ASSERT_TRUE(isEmpty.value());
235 }
236
Chenbo Fenged37fea2017-12-13 19:35:01 -0800237};
238
239TEST_F(TrafficControllerTest, TestTagSocketV4) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900240 SKIP_IF_BPF_NOT_SUPPORTED;
241
Chenbo Fenged37fea2017-12-13 19:35:01 -0800242 uint64_t sockCookie;
243 int v4socket = setUpSocketAndTag(AF_INET, &sockCookie, TEST_TAG, TEST_UID);
244 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
245 ASSERT_EQ(0, mTc.untagSocket(v4socket));
246 expectNoTag(sockCookie);
Chenbo Fengc16827b2018-06-08 15:58:11 -0700247 expectMapEmpty(mFakeCookieTagMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800248}
249
250TEST_F(TrafficControllerTest, TestReTagSocket) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900251 SKIP_IF_BPF_NOT_SUPPORTED;
252
Chenbo Fenged37fea2017-12-13 19:35:01 -0800253 uint64_t sockCookie;
254 int v4socket = setUpSocketAndTag(AF_INET, &sockCookie, TEST_TAG, TEST_UID);
255 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
256 ASSERT_EQ(0, mTc.tagSocket(v4socket, TEST_TAG + 1, TEST_UID + 1));
257 expectUidTag(sockCookie, TEST_UID + 1, TEST_TAG + 1);
258}
259
260TEST_F(TrafficControllerTest, TestTagTwoSockets) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900261 SKIP_IF_BPF_NOT_SUPPORTED;
262
Chenbo Fenged37fea2017-12-13 19:35:01 -0800263 uint64_t sockCookie1;
264 uint64_t sockCookie2;
265 int v4socket1 = setUpSocketAndTag(AF_INET, &sockCookie1, TEST_TAG, TEST_UID);
266 setUpSocketAndTag(AF_INET, &sockCookie2, TEST_TAG, TEST_UID);
267 expectUidTag(sockCookie1, TEST_UID, TEST_TAG);
268 expectUidTag(sockCookie2, TEST_UID, TEST_TAG);
269 ASSERT_EQ(0, mTc.untagSocket(v4socket1));
270 expectNoTag(sockCookie1);
271 expectUidTag(sockCookie2, TEST_UID, TEST_TAG);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700272 ASSERT_FALSE(isOk(mFakeCookieTagMap.getNextKey(sockCookie2)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800273}
274
275TEST_F(TrafficControllerTest, TestTagSocketV6) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900276 SKIP_IF_BPF_NOT_SUPPORTED;
277
Chenbo Fenged37fea2017-12-13 19:35:01 -0800278 uint64_t sockCookie;
279 int v6socket = setUpSocketAndTag(AF_INET6, &sockCookie, TEST_TAG, TEST_UID);
280 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
281 ASSERT_EQ(0, mTc.untagSocket(v6socket));
282 expectNoTag(sockCookie);
Chenbo Fengc16827b2018-06-08 15:58:11 -0700283 expectMapEmpty(mFakeCookieTagMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800284}
285
286TEST_F(TrafficControllerTest, TestTagInvalidSocket) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900287 SKIP_IF_BPF_NOT_SUPPORTED;
288
Chenbo Fenged37fea2017-12-13 19:35:01 -0800289 int invalidSocket = -1;
290 ASSERT_GT(0, mTc.tagSocket(invalidSocket, TEST_TAG, TEST_UID));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700291 expectMapEmpty(mFakeCookieTagMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800292}
293
294TEST_F(TrafficControllerTest, TestUntagInvalidSocket) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900295 SKIP_IF_BPF_NOT_SUPPORTED;
296
Chenbo Fenged37fea2017-12-13 19:35:01 -0800297 int invalidSocket = -1;
298 ASSERT_GT(0, mTc.untagSocket(invalidSocket));
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900299 int v4socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800300 ASSERT_GT(0, mTc.untagSocket(v4socket));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700301 expectMapEmpty(mFakeCookieTagMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800302}
303
304TEST_F(TrafficControllerTest, TestSetCounterSet) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900305 SKIP_IF_BPF_NOT_SUPPORTED;
306
Chenbo Fenged37fea2017-12-13 19:35:01 -0800307 ASSERT_EQ(0, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID));
308 uid_t uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700309 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
310 ASSERT_TRUE(isOk(counterSetResult));
311 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800312 ASSERT_EQ(0, mTc.setCounterSet(DEFAULT_COUNTERSET, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700313 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700314 expectMapEmpty(mFakeUidCounterSetMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800315}
316
317TEST_F(TrafficControllerTest, TestSetInvalidCounterSet) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900318 SKIP_IF_BPF_NOT_SUPPORTED;
319
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700320 ASSERT_GT(0, mTc.setCounterSet(OVERFLOW_COUNTERSET, TEST_UID));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800321 uid_t uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700322 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700323 expectMapEmpty(mFakeUidCounterSetMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800324}
325
326TEST_F(TrafficControllerTest, TestDeleteTagData) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900327 SKIP_IF_BPF_NOT_SUPPORTED;
328
Chenbo Fenged37fea2017-12-13 19:35:01 -0800329 uint64_t cookie = 1;
330 uid_t uid = TEST_UID;
331 uint32_t tag = TEST_TAG;
332 StatsKey tagStatsMapKey;
333 populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
334 ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700335 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie)));
336 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
337 ASSERT_TRUE(isOk(counterSetResult));
338 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
339 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800340 tagStatsMapKey.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700341 StatusOr<StatsValue> statsMapResult = mFakeUidStatsMap.readValue(tagStatsMapKey);
342 ASSERT_TRUE(isOk(statsMapResult));
343 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
344 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700345 auto appStatsResult = mFakeAppUidStatsMap.readValue(TEST_UID);
346 ASSERT_TRUE(isOk(appStatsResult));
347 ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
348 ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800349}
350
351TEST_F(TrafficControllerTest, TestDeleteAllUidData) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900352 SKIP_IF_BPF_NOT_SUPPORTED;
353
Chenbo Fenged37fea2017-12-13 19:35:01 -0800354 uint64_t cookie = 1;
355 uid_t uid = TEST_UID;
356 uint32_t tag = TEST_TAG;
357 StatsKey tagStatsMapKey;
358 populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
359 ASSERT_EQ(0, mTc.deleteTagData(0, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700360 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie)));
361 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
362 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey)));
363 tagStatsMapKey.tag = 0;
364 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700365 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(TEST_UID)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800366}
367
368TEST_F(TrafficControllerTest, TestDeleteDataWithTwoTags) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900369 SKIP_IF_BPF_NOT_SUPPORTED;
370
Chenbo Fenged37fea2017-12-13 19:35:01 -0800371 uint64_t cookie1 = 1;
372 uint64_t cookie2 = 2;
373 uid_t uid = TEST_UID;
374 uint32_t tag1 = TEST_TAG;
375 uint32_t tag2 = TEST_TAG + 1;
376 StatsKey tagStatsMapKey1;
377 StatsKey tagStatsMapKey2;
378 populateFakeStats(cookie1, uid, tag1, &tagStatsMapKey1);
379 populateFakeStats(cookie2, uid, tag2, &tagStatsMapKey2);
380 ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700381 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie1)));
382 StatusOr<UidTag> cookieMapResult = mFakeCookieTagMap.readValue(cookie2);
383 ASSERT_TRUE(isOk(cookieMapResult));
384 ASSERT_EQ(TEST_UID, cookieMapResult.value().uid);
385 ASSERT_EQ(TEST_TAG + 1, cookieMapResult.value().tag);
386 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
387 ASSERT_TRUE(isOk(counterSetResult));
388 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
389 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey1)));
390 StatusOr<StatsValue> statsMapResult = mFakeTagStatsMap.readValue(tagStatsMapKey2);
391 ASSERT_TRUE(isOk(statsMapResult));
392 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
393 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800394}
395
396TEST_F(TrafficControllerTest, TestDeleteDataWithTwoUids) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900397 SKIP_IF_BPF_NOT_SUPPORTED;
398
Chenbo Fenged37fea2017-12-13 19:35:01 -0800399 uint64_t cookie1 = 1;
400 uint64_t cookie2 = 2;
401 uid_t uid1 = TEST_UID;
402 uid_t uid2 = TEST_UID + 1;
403 uint32_t tag = TEST_TAG;
404 StatsKey tagStatsMapKey1;
405 StatsKey tagStatsMapKey2;
406 populateFakeStats(cookie1, uid1, tag, &tagStatsMapKey1);
407 populateFakeStats(cookie2, uid2, tag, &tagStatsMapKey2);
408
409 // Delete the stats of one of the uid. Check if it is properly collected by
410 // removedStats.
411 ASSERT_EQ(0, mTc.deleteTagData(0, uid2));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700412 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie2)));
413 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid1);
414 ASSERT_TRUE(isOk(counterSetResult));
415 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
416 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid2)));
417 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey2)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800418 tagStatsMapKey2.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700419 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey2)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700420 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(uid2)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800421 tagStatsMapKey1.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700422 StatusOr<StatsValue> statsMapResult = mFakeUidStatsMap.readValue(tagStatsMapKey1);
423 ASSERT_TRUE(isOk(statsMapResult));
424 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
425 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700426 auto appStatsResult = mFakeAppUidStatsMap.readValue(uid1);
427 ASSERT_TRUE(isOk(appStatsResult));
428 ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
429 ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800430
Chenbo Fengef1cab32018-04-13 19:50:49 -0700431 // Delete the stats of the other uid.
Chenbo Fenged37fea2017-12-13 19:35:01 -0800432 ASSERT_EQ(0, mTc.deleteTagData(0, uid1));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700433 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey1)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700434 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(uid1)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800435}
436
Chenbo Feng89c12f12018-03-21 10:29:18 -0700437TEST_F(TrafficControllerTest, TestUpdateOwnerMapEntry) {
438 SKIP_IF_BPF_NOT_SUPPORTED;
439
440 uint32_t uid = TEST_UID;
Chenbo Feng703798e2018-06-15 17:07:59 -0700441 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, DENY, BLACKLIST)));
442 StatusOr<uint8_t> value = mFakeUidOwnerMap.readValue(uid);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700443 ASSERT_TRUE(isOk(value));
Chenbo Feng703798e2018-06-15 17:07:59 -0700444 ASSERT_TRUE(value.value() & STANDBY_MATCH);
445
446 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, ALLOW, WHITELIST)));
447 value = mFakeUidOwnerMap.readValue(uid);
448 ASSERT_TRUE(isOk(value));
449 ASSERT_TRUE(value.value() & DOZABLE_MATCH);
450
451 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, DENY, WHITELIST)));
452 value = mFakeUidOwnerMap.readValue(uid);
453 ASSERT_TRUE(isOk(value));
454 ASSERT_FALSE(value.value() & DOZABLE_MATCH);
455
456 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, BLACKLIST)));
457 ASSERT_FALSE(isOk(mFakeUidOwnerMap.readValue(uid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700458
459 uid = TEST_UID2;
Chenbo Feng703798e2018-06-15 17:07:59 -0700460 ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, BLACKLIST)));
461 ASSERT_FALSE(isOk(mFakeUidOwnerMap.readValue(uid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700462}
463
464TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) {
465 SKIP_IF_BPF_NOT_SUPPORTED;
466
Chenbo Feng703798e2018-06-15 17:07:59 -0700467 checkUidOwnerRuleForChain(DOZABLE, DOZABLE_MATCH);
468 checkUidOwnerRuleForChain(STANDBY, STANDBY_MATCH);
469 checkUidOwnerRuleForChain(POWERSAVE, POWERSAVE_MATCH);
Chenbo Feng89c12f12018-03-21 10:29:18 -0700470 ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, WHITELIST));
471 ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, WHITELIST));
472}
473
474TEST_F(TrafficControllerTest, TestReplaceUidOwnerMap) {
475 SKIP_IF_BPF_NOT_SUPPORTED;
476
477 std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
Chenbo Feng703798e2018-06-15 17:07:59 -0700478 checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
479 checkUidMapReplace("fw_standby", uids, STANDBY_MATCH);
480 checkUidMapReplace("fw_powersave", uids, POWERSAVE_MATCH);
Chenbo Feng89c12f12018-03-21 10:29:18 -0700481 ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
482}
483
Chenbo Feng703798e2018-06-15 17:07:59 -0700484TEST_F(TrafficControllerTest, TestReplaceSameChain) {
485 SKIP_IF_BPF_NOT_SUPPORTED;
486
487 std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
488 checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
489 std::vector<int32_t> newUids = {TEST_UID2, TEST_UID3};
490 checkUidMapReplace("fw_dozable", newUids, DOZABLE_MATCH);
491}
492
Chenbo Feng95892f32018-06-07 14:52:02 -0700493TEST_F(TrafficControllerTest, TestBlacklistUidMatch) {
494 SKIP_IF_BPF_NOT_SUPPORTED;
495
496 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
Chenbo Feng703798e2018-06-15 17:07:59 -0700497 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
498 BandwidthController::IptOpInsert)));
499 expectUidOwnerMapValues(appStrUids, PENALTY_BOX_MATCH);
500 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
501 BandwidthController::IptOpDelete)));
502 expectMapEmpty(mFakeUidOwnerMap);
Chenbo Feng95892f32018-06-07 14:52:02 -0700503}
504
505TEST_F(TrafficControllerTest, TestWhitelistUidMatch) {
506 SKIP_IF_BPF_NOT_SUPPORTED;
507
508 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
Chenbo Feng703798e2018-06-15 17:07:59 -0700509 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
510 BandwidthController::IptOpInsert)));
511 expectUidOwnerMapValues(appStrUids, HAPPY_BOX_MATCH);
512 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
513 BandwidthController::IptOpDelete)));
514 expectMapEmpty(mFakeUidOwnerMap);
Chenbo Feng95892f32018-06-07 14:52:02 -0700515}
516
517TEST_F(TrafficControllerTest, TestReplaceMatchUid) {
Bernie Innocenti093d6622018-07-09 20:52:48 +0900518 SKIP_IF_BPF_NOT_SUPPORTED;
519
Chenbo Feng95892f32018-06-07 14:52:02 -0700520 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
Chenbo Feng703798e2018-06-15 17:07:59 -0700521 // Add appStrUids to the blacklist and expect that their values are all PENALTY_BOX_MATCH.
522 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
523 BandwidthController::IptOpInsert)));
524 expectUidOwnerMapValues(appStrUids, PENALTY_BOX_MATCH);
Chenbo Feng95892f32018-06-07 14:52:02 -0700525
Chenbo Feng703798e2018-06-15 17:07:59 -0700526 // Add the same UIDs to the whitelist and expect that we get PENALTY_BOX_MATCH |
527 // HAPPY_BOX_MATCH.
528 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
529 BandwidthController::IptOpInsert)));
530 expectUidOwnerMapValues(appStrUids, HAPPY_BOX_MATCH | PENALTY_BOX_MATCH);
Chenbo Feng95892f32018-06-07 14:52:02 -0700531
Chenbo Feng703798e2018-06-15 17:07:59 -0700532 // Remove the same UIDs from the whitelist and check the PENALTY_BOX_MATCH is still there.
533 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
534 BandwidthController::IptOpDelete)));
535 expectUidOwnerMapValues(appStrUids, PENALTY_BOX_MATCH);
Chenbo Feng95892f32018-06-07 14:52:02 -0700536
537 // Remove the same UIDs from the blacklist and check the map is empty.
Chenbo Feng703798e2018-06-15 17:07:59 -0700538 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
539 BandwidthController::IptOpDelete)));
540 ASSERT_FALSE(isOk(mFakeUidOwnerMap.getFirstKey()));
Chenbo Feng95892f32018-06-07 14:52:02 -0700541}
542
543TEST_F(TrafficControllerTest, TestDeleteWrongMatchSilentlyFails) {
Bernie Innocenti093d6622018-07-09 20:52:48 +0900544 SKIP_IF_BPF_NOT_SUPPORTED;
545
Chenbo Feng95892f32018-06-07 14:52:02 -0700546 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
547 // If the uid does not exist in the map, trying to delete a rule about it will fail.
Chenbo Feng703798e2018-06-15 17:07:59 -0700548 ASSERT_FALSE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
549 BandwidthController::IptOpDelete)));
550 expectMapEmpty(mFakeUidOwnerMap);
Chenbo Feng95892f32018-06-07 14:52:02 -0700551
552 // Add blacklist rules for appStrUids.
Chenbo Feng703798e2018-06-15 17:07:59 -0700553 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReturn,
554 BandwidthController::IptOpInsert)));
555 expectUidOwnerMapValues(appStrUids, HAPPY_BOX_MATCH);
Chenbo Feng95892f32018-06-07 14:52:02 -0700556
557 // Delete (non-existent) blacklist rules for appStrUids, and check that this silently does
558 // nothing if the uid is in the map but does not have blacklist match. This is required because
559 // NetworkManagementService will try to remove a uid from blacklist after adding it to the
560 // whitelist and if the remove fails it will not update the uid status.
Chenbo Feng703798e2018-06-15 17:07:59 -0700561 ASSERT_TRUE(isOk(mTc.updateUidOwnerMap(appStrUids, BandwidthController::IptJumpReject,
562 BandwidthController::IptOpDelete)));
563 expectUidOwnerMapValues(appStrUids, HAPPY_BOX_MATCH);
Chenbo Feng95892f32018-06-07 14:52:02 -0700564}
Chenbo Fenged37fea2017-12-13 19:35:01 -0800565} // namespace net
566} // namespace android