blob: 359ea8a5633e060aa37be8078136aacfb911bdba [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;
78 BpfMap<uint32_t, uint8_t> mFakeDozableUidMap;
79 BpfMap<uint32_t, uint8_t> mFakeStandbyUidMap;
80 BpfMap<uint32_t, uint8_t> mFakePowerSaveUidMap;
Chenbo Feng95892f32018-06-07 14:52:02 -070081 BpfMap<uint32_t, uint8_t> mFakeBandwidthUidMap;
Chenbo Fenged37fea2017-12-13 19:35:01 -080082
83 void SetUp() {
Chenbo Fengef1cab32018-04-13 19:50:49 -070084 std::lock_guard<std::mutex> ownerGuard(mTc.mOwnerMatchMutex);
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +090085 SKIP_IF_BPF_NOT_SUPPORTED;
86
Chenbo Feng4f6c2372018-04-26 10:37:55 -070087 mFakeCookieTagMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint64_t),
88 sizeof(struct UidTag), TEST_MAP_SIZE, 0));
89 ASSERT_LE(0, mFakeCookieTagMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -080090
Chenbo Feng4f6c2372018-04-26 10:37:55 -070091 mFakeUidCounterSetMap.reset(
92 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
93 ASSERT_LE(0, mFakeUidCounterSetMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -080094
Chenbo Fengbc4a15f2018-05-11 19:15:15 -070095 mFakeAppUidStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t),
96 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
97 ASSERT_LE(0, mFakeAppUidStatsMap.getMap());
98
Chenbo Feng4f6c2372018-04-26 10:37:55 -070099 mFakeUidStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(struct StatsKey),
100 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
101 ASSERT_LE(0, mFakeUidStatsMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800102
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700103 mFakeTagStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(struct StatsKey),
104 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
105 ASSERT_LE(0, mFakeTagStatsMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800106
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700107 mFakeDozableUidMap.reset(
108 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
109 ASSERT_LE(0, mFakeDozableUidMap.getMap());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700110
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700111 mFakeStandbyUidMap.reset(
112 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
113 ASSERT_LE(0, mFakeStandbyUidMap.getMap());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700114
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700115 mFakePowerSaveUidMap.reset(
116 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
117 ASSERT_LE(0, mFakePowerSaveUidMap.getMap());
Chenbo Feng95892f32018-06-07 14:52:02 -0700118
119 mFakeBandwidthUidMap.reset(
120 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
121 ASSERT_LE(0, mFakeBandwidthUidMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800122 // Make sure trafficController use the eBPF code path.
123 mTc.ebpfSupported = true;
124
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700125 mTc.mCookieTagMap.reset(mFakeCookieTagMap.getMap());
126 mTc.mUidCounterSetMap.reset(mFakeUidCounterSetMap.getMap());
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700127 mTc.mAppUidStatsMap.reset(mFakeAppUidStatsMap.getMap());
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700128 mTc.mUidStatsMap.reset(mFakeUidStatsMap.getMap());
129 mTc.mTagStatsMap.reset(mFakeTagStatsMap.getMap());
130 mTc.mDozableUidMap.reset(mFakeDozableUidMap.getMap());
131 mTc.mStandbyUidMap.reset(mFakeStandbyUidMap.getMap());
132 mTc.mPowerSaveUidMap.reset(mFakePowerSaveUidMap.getMap());
Chenbo Feng95892f32018-06-07 14:52:02 -0700133 mTc.mBandwidthUidMap.reset(mFakeBandwidthUidMap.getMap());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800134 }
135
136 int setUpSocketAndTag(int protocol, uint64_t* cookie, uint32_t tag, uid_t uid) {
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900137 int sock = socket(protocol, SOCK_STREAM | SOCK_CLOEXEC, 0);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800138 EXPECT_LE(0, sock);
139 *cookie = getSocketCookie(sock);
Chenbo Fengef1cab32018-04-13 19:50:49 -0700140 EXPECT_NE(NONEXISTENT_COOKIE, *cookie);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800141 EXPECT_EQ(0, mTc.tagSocket(sock, tag, uid));
142 return sock;
143 }
144
145 void expectUidTag(uint64_t cookie, uid_t uid, uint32_t tag) {
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700146 StatusOr<UidTag> tagResult = mFakeCookieTagMap.readValue(cookie);
147 EXPECT_TRUE(isOk(tagResult));
148 EXPECT_EQ(uid, tagResult.value().uid);
149 EXPECT_EQ(tag, tagResult.value().tag);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800150 }
151
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700152 void expectNoTag(uint64_t cookie) { EXPECT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie))); }
Chenbo Fenged37fea2017-12-13 19:35:01 -0800153
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700154 void populateFakeStats(uint64_t cookie, uint32_t uid, uint32_t tag, StatsKey* key) {
Chenbo Fenged37fea2017-12-13 19:35:01 -0800155 UidTag cookieMapkey = {.uid = (uint32_t)uid, .tag = tag};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700156 EXPECT_TRUE(isOk(mFakeCookieTagMap.writeValue(cookie, cookieMapkey, BPF_ANY)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800157 *key = {.uid = uid, .tag = tag, .counterSet = TEST_COUNTERSET, .ifaceIndex = 1};
Chenbo Fengeac6c472018-02-05 15:06:23 -0800158 StatsValue statsMapValue = {.rxPackets = 1, .rxBytes = 100};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700159 uint8_t counterSet = TEST_COUNTERSET;
160 EXPECT_TRUE(isOk(mFakeUidCounterSetMap.writeValue(uid, counterSet, BPF_ANY)));
161 EXPECT_TRUE(isOk(mFakeTagStatsMap.writeValue(*key, statsMapValue, BPF_ANY)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800162 key->tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700163 EXPECT_TRUE(isOk(mFakeUidStatsMap.writeValue(*key, statsMapValue, BPF_ANY)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700164 EXPECT_TRUE(isOk(mFakeAppUidStatsMap.writeValue(uid, statsMapValue, BPF_ANY)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800165 // put tag information back to statsKey
166 key->tag = tag;
Chenbo Fenged37fea2017-12-13 19:35:01 -0800167 }
168
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700169 void checkUidOwnerRuleForChain(ChildChain chain, BpfMap<uint32_t, uint8_t>& targetMap) {
Chenbo Feng89c12f12018-03-21 10:29:18 -0700170 uint32_t uid = TEST_UID;
171 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, BLACKLIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700172 StatusOr<uint8_t> value = targetMap.readValue(uid);
173 EXPECT_TRUE(isOk(value));
174 EXPECT_EQ(BPF_DROP, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700175
176 uid = TEST_UID2;
177 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, WHITELIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700178 value = targetMap.readValue(uid);
179 EXPECT_TRUE(isOk(value));
180 EXPECT_EQ(BPF_PASS, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700181
182 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, WHITELIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700183 value = targetMap.readValue(uid);
184 EXPECT_FALSE(isOk(value));
185 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700186
187 uid = TEST_UID;
188 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, BLACKLIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700189 value = targetMap.readValue(uid);
190 EXPECT_FALSE(isOk(value));
191 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700192
193 uid = TEST_UID3;
194 EXPECT_EQ(-ENOENT, mTc.changeUidOwnerRule(chain, uid, ALLOW, BLACKLIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700195 value = targetMap.readValue(uid);
196 EXPECT_FALSE(isOk(value));
197 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700198 }
199
200 void checkEachUidValue(const std::vector<int32_t>& uids, const uint8_t expectValue,
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700201 BpfMap<uint32_t, uint8_t>& targetMap) {
202 for (uint32_t uid : uids) {
203 StatusOr<uint8_t> value = targetMap.readValue(uid);
204 EXPECT_TRUE(isOk(value));
205 EXPECT_EQ(expectValue, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700206 }
207 std::set<uint32_t> uidSet(uids.begin(), uids.end());
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700208 const auto checkNoOtherUid = [&uidSet](const int32_t& key,
209 const BpfMap<uint32_t, uint8_t>&) {
210 EXPECT_NE(uidSet.end(), uidSet.find(key));
211 return netdutils::status::ok;
Chenbo Feng89c12f12018-03-21 10:29:18 -0700212 };
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700213 EXPECT_TRUE(isOk(targetMap.iterate(checkNoOtherUid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700214 }
215
216 void checkUidMapReplace(const std::string& name, const std::vector<int32_t>& uids,
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700217 BpfMap<uint32_t, uint8_t>& targetMap) {
Chenbo Feng89c12f12018-03-21 10:29:18 -0700218 bool isWhitelist = true;
219 EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isWhitelist, uids));
220 checkEachUidValue(uids, BPF_PASS, targetMap);
221
222 isWhitelist = false;
223 EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isWhitelist, uids));
224 checkEachUidValue(uids, BPF_DROP, targetMap);
225 }
226
Chenbo Feng95892f32018-06-07 14:52:02 -0700227 void expectBandwidthMapValues(const std::vector<std::string>& appStrUids,
228 uint8_t expectedValue) {
Bernie Innocenti7e25ec02018-07-02 19:32:17 +0900229 for (const std::string& strUid : appStrUids) {
Chenbo Feng95892f32018-06-07 14:52:02 -0700230 uint32_t uid = stoi(strUid);
231 StatusOr<uint8_t> value = mFakeBandwidthUidMap.readValue(uid);
232 EXPECT_TRUE(isOk(value));
233 EXPECT_EQ(expectedValue, value.value()) <<
234 "Expected value for UID " << uid << " to be " << expectedValue <<
235 ", but was " << value.value();
236 }
237 }
238
Chenbo Fengc16827b2018-06-08 15:58:11 -0700239 void expectMapEmpty(BpfMap<uint64_t, UidTag>& map) {
240 auto isEmpty = map.isEmpty();
241 EXPECT_TRUE(isOk(isEmpty));
242 EXPECT_TRUE(isEmpty.value());
243 }
244
245 void expectMapEmpty(BpfMap<uint32_t, uint8_t>& map) {
246 auto isEmpty = map.isEmpty();
247 ASSERT_TRUE(isOk(isEmpty));
248 ASSERT_TRUE(isEmpty.value());
249 }
250
Chenbo Fenged37fea2017-12-13 19:35:01 -0800251 void TearDown() {
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700252 std::lock_guard<std::mutex> ownerGuard(mTc.mOwnerMatchMutex);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800253 mFakeCookieTagMap.reset();
254 mFakeUidCounterSetMap.reset();
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700255 mFakeAppUidStatsMap.reset();
Chenbo Fenged37fea2017-12-13 19:35:01 -0800256 mFakeUidStatsMap.reset();
257 mFakeTagStatsMap.reset();
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700258 mTc.mDozableUidMap.reset();
259 mTc.mStandbyUidMap.reset();
260 mTc.mPowerSaveUidMap.reset();
Chenbo Fenged37fea2017-12-13 19:35:01 -0800261 }
262};
263
264TEST_F(TrafficControllerTest, TestTagSocketV4) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900265 SKIP_IF_BPF_NOT_SUPPORTED;
266
Chenbo Fenged37fea2017-12-13 19:35:01 -0800267 uint64_t sockCookie;
268 int v4socket = setUpSocketAndTag(AF_INET, &sockCookie, TEST_TAG, TEST_UID);
269 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
270 ASSERT_EQ(0, mTc.untagSocket(v4socket));
271 expectNoTag(sockCookie);
Chenbo Fengc16827b2018-06-08 15:58:11 -0700272 expectMapEmpty(mFakeCookieTagMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800273}
274
275TEST_F(TrafficControllerTest, TestReTagSocket) {
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 v4socket = setUpSocketAndTag(AF_INET, &sockCookie, TEST_TAG, TEST_UID);
280 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
281 ASSERT_EQ(0, mTc.tagSocket(v4socket, TEST_TAG + 1, TEST_UID + 1));
282 expectUidTag(sockCookie, TEST_UID + 1, TEST_TAG + 1);
283}
284
285TEST_F(TrafficControllerTest, TestTagTwoSockets) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900286 SKIP_IF_BPF_NOT_SUPPORTED;
287
Chenbo Fenged37fea2017-12-13 19:35:01 -0800288 uint64_t sockCookie1;
289 uint64_t sockCookie2;
290 int v4socket1 = setUpSocketAndTag(AF_INET, &sockCookie1, TEST_TAG, TEST_UID);
291 setUpSocketAndTag(AF_INET, &sockCookie2, TEST_TAG, TEST_UID);
292 expectUidTag(sockCookie1, TEST_UID, TEST_TAG);
293 expectUidTag(sockCookie2, TEST_UID, TEST_TAG);
294 ASSERT_EQ(0, mTc.untagSocket(v4socket1));
295 expectNoTag(sockCookie1);
296 expectUidTag(sockCookie2, TEST_UID, TEST_TAG);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700297 ASSERT_FALSE(isOk(mFakeCookieTagMap.getNextKey(sockCookie2)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800298}
299
300TEST_F(TrafficControllerTest, TestTagSocketV6) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900301 SKIP_IF_BPF_NOT_SUPPORTED;
302
Chenbo Fenged37fea2017-12-13 19:35:01 -0800303 uint64_t sockCookie;
304 int v6socket = setUpSocketAndTag(AF_INET6, &sockCookie, TEST_TAG, TEST_UID);
305 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
306 ASSERT_EQ(0, mTc.untagSocket(v6socket));
307 expectNoTag(sockCookie);
Chenbo Fengc16827b2018-06-08 15:58:11 -0700308 expectMapEmpty(mFakeCookieTagMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800309}
310
311TEST_F(TrafficControllerTest, TestTagInvalidSocket) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900312 SKIP_IF_BPF_NOT_SUPPORTED;
313
Chenbo Fenged37fea2017-12-13 19:35:01 -0800314 int invalidSocket = -1;
315 ASSERT_GT(0, mTc.tagSocket(invalidSocket, TEST_TAG, TEST_UID));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700316 expectMapEmpty(mFakeCookieTagMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800317}
318
319TEST_F(TrafficControllerTest, TestUntagInvalidSocket) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900320 SKIP_IF_BPF_NOT_SUPPORTED;
321
Chenbo Fenged37fea2017-12-13 19:35:01 -0800322 int invalidSocket = -1;
323 ASSERT_GT(0, mTc.untagSocket(invalidSocket));
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900324 int v4socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800325 ASSERT_GT(0, mTc.untagSocket(v4socket));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700326 expectMapEmpty(mFakeCookieTagMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800327}
328
329TEST_F(TrafficControllerTest, TestSetCounterSet) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900330 SKIP_IF_BPF_NOT_SUPPORTED;
331
Chenbo Fenged37fea2017-12-13 19:35:01 -0800332 ASSERT_EQ(0, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID));
333 uid_t uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700334 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
335 ASSERT_TRUE(isOk(counterSetResult));
336 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800337 ASSERT_EQ(0, mTc.setCounterSet(DEFAULT_COUNTERSET, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700338 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700339 expectMapEmpty(mFakeUidCounterSetMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800340}
341
342TEST_F(TrafficControllerTest, TestSetInvalidCounterSet) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900343 SKIP_IF_BPF_NOT_SUPPORTED;
344
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700345 ASSERT_GT(0, mTc.setCounterSet(OVERFLOW_COUNTERSET, TEST_UID));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800346 uid_t uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700347 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700348 expectMapEmpty(mFakeUidCounterSetMap);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800349}
350
351TEST_F(TrafficControllerTest, TestDeleteTagData) {
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(TEST_TAG, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700360 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie)));
361 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
362 ASSERT_TRUE(isOk(counterSetResult));
363 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
364 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800365 tagStatsMapKey.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700366 StatusOr<StatsValue> statsMapResult = mFakeUidStatsMap.readValue(tagStatsMapKey);
367 ASSERT_TRUE(isOk(statsMapResult));
368 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
369 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700370 auto appStatsResult = mFakeAppUidStatsMap.readValue(TEST_UID);
371 ASSERT_TRUE(isOk(appStatsResult));
372 ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
373 ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800374}
375
376TEST_F(TrafficControllerTest, TestDeleteAllUidData) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900377 SKIP_IF_BPF_NOT_SUPPORTED;
378
Chenbo Fenged37fea2017-12-13 19:35:01 -0800379 uint64_t cookie = 1;
380 uid_t uid = TEST_UID;
381 uint32_t tag = TEST_TAG;
382 StatsKey tagStatsMapKey;
383 populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
384 ASSERT_EQ(0, mTc.deleteTagData(0, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700385 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie)));
386 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
387 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey)));
388 tagStatsMapKey.tag = 0;
389 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700390 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(TEST_UID)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800391}
392
393TEST_F(TrafficControllerTest, TestDeleteDataWithTwoTags) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900394 SKIP_IF_BPF_NOT_SUPPORTED;
395
Chenbo Fenged37fea2017-12-13 19:35:01 -0800396 uint64_t cookie1 = 1;
397 uint64_t cookie2 = 2;
398 uid_t uid = TEST_UID;
399 uint32_t tag1 = TEST_TAG;
400 uint32_t tag2 = TEST_TAG + 1;
401 StatsKey tagStatsMapKey1;
402 StatsKey tagStatsMapKey2;
403 populateFakeStats(cookie1, uid, tag1, &tagStatsMapKey1);
404 populateFakeStats(cookie2, uid, tag2, &tagStatsMapKey2);
405 ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700406 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie1)));
407 StatusOr<UidTag> cookieMapResult = mFakeCookieTagMap.readValue(cookie2);
408 ASSERT_TRUE(isOk(cookieMapResult));
409 ASSERT_EQ(TEST_UID, cookieMapResult.value().uid);
410 ASSERT_EQ(TEST_TAG + 1, cookieMapResult.value().tag);
411 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
412 ASSERT_TRUE(isOk(counterSetResult));
413 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
414 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey1)));
415 StatusOr<StatsValue> statsMapResult = mFakeTagStatsMap.readValue(tagStatsMapKey2);
416 ASSERT_TRUE(isOk(statsMapResult));
417 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
418 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800419}
420
421TEST_F(TrafficControllerTest, TestDeleteDataWithTwoUids) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900422 SKIP_IF_BPF_NOT_SUPPORTED;
423
Chenbo Fenged37fea2017-12-13 19:35:01 -0800424 uint64_t cookie1 = 1;
425 uint64_t cookie2 = 2;
426 uid_t uid1 = TEST_UID;
427 uid_t uid2 = TEST_UID + 1;
428 uint32_t tag = TEST_TAG;
429 StatsKey tagStatsMapKey1;
430 StatsKey tagStatsMapKey2;
431 populateFakeStats(cookie1, uid1, tag, &tagStatsMapKey1);
432 populateFakeStats(cookie2, uid2, tag, &tagStatsMapKey2);
433
434 // Delete the stats of one of the uid. Check if it is properly collected by
435 // removedStats.
436 ASSERT_EQ(0, mTc.deleteTagData(0, uid2));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700437 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie2)));
438 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid1);
439 ASSERT_TRUE(isOk(counterSetResult));
440 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
441 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid2)));
442 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey2)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800443 tagStatsMapKey2.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700444 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey2)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700445 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(uid2)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800446 tagStatsMapKey1.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700447 StatusOr<StatsValue> statsMapResult = mFakeUidStatsMap.readValue(tagStatsMapKey1);
448 ASSERT_TRUE(isOk(statsMapResult));
449 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
450 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700451 auto appStatsResult = mFakeAppUidStatsMap.readValue(uid1);
452 ASSERT_TRUE(isOk(appStatsResult));
453 ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
454 ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800455
Chenbo Fengef1cab32018-04-13 19:50:49 -0700456 // Delete the stats of the other uid.
Chenbo Fenged37fea2017-12-13 19:35:01 -0800457 ASSERT_EQ(0, mTc.deleteTagData(0, uid1));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700458 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey1)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700459 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(uid1)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800460}
461
Chenbo Feng89c12f12018-03-21 10:29:18 -0700462TEST_F(TrafficControllerTest, TestUpdateOwnerMapEntry) {
463 SKIP_IF_BPF_NOT_SUPPORTED;
464
465 uint32_t uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700466 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, DENY, BLACKLIST)));
467 StatusOr<uint8_t> value = mFakeDozableUidMap.readValue(uid);
468 ASSERT_TRUE(isOk(value));
469 ASSERT_EQ(BPF_DROP, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700470
471 uid = TEST_UID2;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700472 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, WHITELIST)));
473 value = mFakeDozableUidMap.readValue(uid);
474 ASSERT_TRUE(isOk(value));
475 ASSERT_EQ(BPF_PASS, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700476
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700477 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, DENY, WHITELIST)));
478 ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700479
480 uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700481 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, BLACKLIST)));
482 ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700483
484 uid = TEST_UID3;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700485 ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, BLACKLIST)));
486 ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700487}
488
489TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) {
490 SKIP_IF_BPF_NOT_SUPPORTED;
491
492 checkUidOwnerRuleForChain(DOZABLE, mFakeDozableUidMap);
493 checkUidOwnerRuleForChain(STANDBY, mFakeStandbyUidMap);
494 checkUidOwnerRuleForChain(POWERSAVE, mFakePowerSaveUidMap);
495 ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, WHITELIST));
496 ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, WHITELIST));
497}
498
499TEST_F(TrafficControllerTest, TestReplaceUidOwnerMap) {
500 SKIP_IF_BPF_NOT_SUPPORTED;
501
502 std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
503 checkUidMapReplace("fw_dozable", uids, mFakeDozableUidMap);
504 checkUidMapReplace("fw_standby", uids, mFakeStandbyUidMap);
505 checkUidMapReplace("fw_powersave", uids, mFakePowerSaveUidMap);
506 ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
507}
508
Chenbo Feng95892f32018-06-07 14:52:02 -0700509TEST_F(TrafficControllerTest, TestBlacklistUidMatch) {
510 SKIP_IF_BPF_NOT_SUPPORTED;
511
512 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
513 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
514 BandwidthController::IptOpInsert)));
515 expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
516 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
517 BandwidthController::IptOpDelete)));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700518 expectMapEmpty(mFakeBandwidthUidMap);
Chenbo Feng95892f32018-06-07 14:52:02 -0700519}
520
521TEST_F(TrafficControllerTest, TestWhitelistUidMatch) {
522 SKIP_IF_BPF_NOT_SUPPORTED;
523
524 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
525 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
526 BandwidthController::IptOpInsert)));
527 expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
528 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
529 BandwidthController::IptOpDelete)));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700530 expectMapEmpty(mFakeBandwidthUidMap);
Chenbo Feng95892f32018-06-07 14:52:02 -0700531}
532
533TEST_F(TrafficControllerTest, TestReplaceMatchUid) {
Bernie Innocenti093d6622018-07-09 20:52:48 +0900534 SKIP_IF_BPF_NOT_SUPPORTED;
535
Chenbo Feng95892f32018-06-07 14:52:02 -0700536 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
537 // Add appStrUids to the blacklist and expect that their values are all BLACKLISTMATCH.
538 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
539 BandwidthController::IptOpInsert)));
540 expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
541
542 // Add the same UIDs to the whitelist and expect that we get BLACKLISTMATCH | WHITELISTMATCH.
543 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
544 BandwidthController::IptOpInsert)));
545 expectBandwidthMapValues(appStrUids, WHITELISTMATCH | BLACKLISTMATCH);
546
547 // Remove the same UIDs from the whitelist and check the BLACKLISTMATCH is still there.
548 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
549 BandwidthController::IptOpDelete)));
550 expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
551
552 // Remove the same UIDs from the blacklist and check the map is empty.
553 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
554 BandwidthController::IptOpDelete)));
555 ASSERT_FALSE(isOk(mFakeBandwidthUidMap.getFirstKey()));
556}
557
558TEST_F(TrafficControllerTest, TestDeleteWrongMatchSilentlyFails) {
Bernie Innocenti093d6622018-07-09 20:52:48 +0900559 SKIP_IF_BPF_NOT_SUPPORTED;
560
Chenbo Feng95892f32018-06-07 14:52:02 -0700561 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
562 // If the uid does not exist in the map, trying to delete a rule about it will fail.
563 ASSERT_FALSE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
564 BandwidthController::IptOpDelete)));
Chenbo Fengc16827b2018-06-08 15:58:11 -0700565 expectMapEmpty(mFakeBandwidthUidMap);
Chenbo Feng95892f32018-06-07 14:52:02 -0700566
567 // Add blacklist rules for appStrUids.
568 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
569 BandwidthController::IptOpInsert)));
570 expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
571
572 // Delete (non-existent) blacklist rules for appStrUids, and check that this silently does
573 // nothing if the uid is in the map but does not have blacklist match. This is required because
574 // NetworkManagementService will try to remove a uid from blacklist after adding it to the
575 // whitelist and if the remove fails it will not update the uid status.
576 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
577 BandwidthController::IptOpDelete)));
578 expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
579}
Chenbo Fenged37fea2017-12-13 19:35:01 -0800580} // namespace net
581} // namespace android