blob: fee5ee45a3a144e103f54b344f213aa104ab742d [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
43using namespace android::bpf;
44
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) {
137 int sock = socket(protocol, SOCK_STREAM, 0);
138 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 expectTagMapEmpty() { EXPECT_FALSE(isOk(mFakeCookieTagMap.getFirstKey())); }
Chenbo Fenged37fea2017-12-13 19:35:01 -0800155
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700156 void populateFakeStats(uint64_t cookie, uint32_t uid, uint32_t tag, StatsKey* key) {
Chenbo Fenged37fea2017-12-13 19:35:01 -0800157 UidTag cookieMapkey = {.uid = (uint32_t)uid, .tag = tag};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700158 EXPECT_TRUE(isOk(mFakeCookieTagMap.writeValue(cookie, cookieMapkey, BPF_ANY)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800159 *key = {.uid = uid, .tag = tag, .counterSet = TEST_COUNTERSET, .ifaceIndex = 1};
Chenbo Fengeac6c472018-02-05 15:06:23 -0800160 StatsValue statsMapValue = {.rxPackets = 1, .rxBytes = 100};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700161 uint8_t counterSet = TEST_COUNTERSET;
162 EXPECT_TRUE(isOk(mFakeUidCounterSetMap.writeValue(uid, counterSet, BPF_ANY)));
163 EXPECT_TRUE(isOk(mFakeTagStatsMap.writeValue(*key, statsMapValue, BPF_ANY)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800164 key->tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700165 EXPECT_TRUE(isOk(mFakeUidStatsMap.writeValue(*key, statsMapValue, BPF_ANY)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700166 EXPECT_TRUE(isOk(mFakeAppUidStatsMap.writeValue(uid, statsMapValue, BPF_ANY)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800167 // put tag information back to statsKey
168 key->tag = tag;
Chenbo Fenged37fea2017-12-13 19:35:01 -0800169 }
170
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700171 void checkUidOwnerRuleForChain(ChildChain chain, BpfMap<uint32_t, uint8_t>& targetMap) {
Chenbo Feng89c12f12018-03-21 10:29:18 -0700172 uint32_t uid = TEST_UID;
173 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, BLACKLIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700174 StatusOr<uint8_t> value = targetMap.readValue(uid);
175 EXPECT_TRUE(isOk(value));
176 EXPECT_EQ(BPF_DROP, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700177
178 uid = TEST_UID2;
179 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, WHITELIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700180 value = targetMap.readValue(uid);
181 EXPECT_TRUE(isOk(value));
182 EXPECT_EQ(BPF_PASS, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700183
184 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, WHITELIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700185 value = targetMap.readValue(uid);
186 EXPECT_FALSE(isOk(value));
187 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700188
189 uid = TEST_UID;
190 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, BLACKLIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700191 value = targetMap.readValue(uid);
192 EXPECT_FALSE(isOk(value));
193 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700194
195 uid = TEST_UID3;
196 EXPECT_EQ(-ENOENT, mTc.changeUidOwnerRule(chain, uid, ALLOW, BLACKLIST));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700197 value = targetMap.readValue(uid);
198 EXPECT_FALSE(isOk(value));
199 EXPECT_EQ(ENOENT, value.status().code());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700200 }
201
202 void checkEachUidValue(const std::vector<int32_t>& uids, const uint8_t expectValue,
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700203 BpfMap<uint32_t, uint8_t>& targetMap) {
204 for (uint32_t uid : uids) {
205 StatusOr<uint8_t> value = targetMap.readValue(uid);
206 EXPECT_TRUE(isOk(value));
207 EXPECT_EQ(expectValue, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700208 }
209 std::set<uint32_t> uidSet(uids.begin(), uids.end());
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700210 const auto checkNoOtherUid = [&uidSet](const int32_t& key,
211 const BpfMap<uint32_t, uint8_t>&) {
212 EXPECT_NE(uidSet.end(), uidSet.find(key));
213 return netdutils::status::ok;
Chenbo Feng89c12f12018-03-21 10:29:18 -0700214 };
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700215 EXPECT_TRUE(isOk(targetMap.iterate(checkNoOtherUid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700216 }
217
218 void checkUidMapReplace(const std::string& name, const std::vector<int32_t>& uids,
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700219 BpfMap<uint32_t, uint8_t>& targetMap) {
Chenbo Feng89c12f12018-03-21 10:29:18 -0700220 bool isWhitelist = true;
221 EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isWhitelist, uids));
222 checkEachUidValue(uids, BPF_PASS, targetMap);
223
224 isWhitelist = false;
225 EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isWhitelist, uids));
226 checkEachUidValue(uids, BPF_DROP, targetMap);
227 }
228
Chenbo Feng95892f32018-06-07 14:52:02 -0700229 void expectBandwidthMapValues(const std::vector<std::string>& appStrUids,
230 uint8_t expectedValue) {
231 for (std::string strUid : appStrUids) {
232 uint32_t uid = stoi(strUid);
233 StatusOr<uint8_t> value = mFakeBandwidthUidMap.readValue(uid);
234 EXPECT_TRUE(isOk(value));
235 EXPECT_EQ(expectedValue, value.value()) <<
236 "Expected value for UID " << uid << " to be " << expectedValue <<
237 ", but was " << value.value();
238 }
239 }
240
Chenbo Fenged37fea2017-12-13 19:35:01 -0800241 void TearDown() {
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700242 std::lock_guard<std::mutex> ownerGuard(mTc.mOwnerMatchMutex);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800243 mFakeCookieTagMap.reset();
244 mFakeUidCounterSetMap.reset();
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700245 mFakeAppUidStatsMap.reset();
Chenbo Fenged37fea2017-12-13 19:35:01 -0800246 mFakeUidStatsMap.reset();
247 mFakeTagStatsMap.reset();
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700248 mTc.mDozableUidMap.reset();
249 mTc.mStandbyUidMap.reset();
250 mTc.mPowerSaveUidMap.reset();
Chenbo Fenged37fea2017-12-13 19:35:01 -0800251 }
252};
253
254TEST_F(TrafficControllerTest, TestTagSocketV4) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900255 SKIP_IF_BPF_NOT_SUPPORTED;
256
Chenbo Fenged37fea2017-12-13 19:35:01 -0800257 uint64_t sockCookie;
258 int v4socket = setUpSocketAndTag(AF_INET, &sockCookie, TEST_TAG, TEST_UID);
259 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
260 ASSERT_EQ(0, mTc.untagSocket(v4socket));
261 expectNoTag(sockCookie);
262 expectTagMapEmpty();
263}
264
265TEST_F(TrafficControllerTest, TestReTagSocket) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900266 SKIP_IF_BPF_NOT_SUPPORTED;
267
Chenbo Fenged37fea2017-12-13 19:35:01 -0800268 uint64_t sockCookie;
269 int v4socket = setUpSocketAndTag(AF_INET, &sockCookie, TEST_TAG, TEST_UID);
270 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
271 ASSERT_EQ(0, mTc.tagSocket(v4socket, TEST_TAG + 1, TEST_UID + 1));
272 expectUidTag(sockCookie, TEST_UID + 1, TEST_TAG + 1);
273}
274
275TEST_F(TrafficControllerTest, TestTagTwoSockets) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900276 SKIP_IF_BPF_NOT_SUPPORTED;
277
Chenbo Fenged37fea2017-12-13 19:35:01 -0800278 uint64_t sockCookie1;
279 uint64_t sockCookie2;
280 int v4socket1 = setUpSocketAndTag(AF_INET, &sockCookie1, TEST_TAG, TEST_UID);
281 setUpSocketAndTag(AF_INET, &sockCookie2, TEST_TAG, TEST_UID);
282 expectUidTag(sockCookie1, TEST_UID, TEST_TAG);
283 expectUidTag(sockCookie2, TEST_UID, TEST_TAG);
284 ASSERT_EQ(0, mTc.untagSocket(v4socket1));
285 expectNoTag(sockCookie1);
286 expectUidTag(sockCookie2, TEST_UID, TEST_TAG);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700287 ASSERT_FALSE(isOk(mFakeCookieTagMap.getNextKey(sockCookie2)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800288}
289
290TEST_F(TrafficControllerTest, TestTagSocketV6) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900291 SKIP_IF_BPF_NOT_SUPPORTED;
292
Chenbo Fenged37fea2017-12-13 19:35:01 -0800293 uint64_t sockCookie;
294 int v6socket = setUpSocketAndTag(AF_INET6, &sockCookie, TEST_TAG, TEST_UID);
295 expectUidTag(sockCookie, TEST_UID, TEST_TAG);
296 ASSERT_EQ(0, mTc.untagSocket(v6socket));
297 expectNoTag(sockCookie);
298 expectTagMapEmpty();
299}
300
301TEST_F(TrafficControllerTest, TestTagInvalidSocket) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900302 SKIP_IF_BPF_NOT_SUPPORTED;
303
Chenbo Fenged37fea2017-12-13 19:35:01 -0800304 int invalidSocket = -1;
305 ASSERT_GT(0, mTc.tagSocket(invalidSocket, TEST_TAG, TEST_UID));
306 expectTagMapEmpty();
307}
308
309TEST_F(TrafficControllerTest, TestUntagInvalidSocket) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900310 SKIP_IF_BPF_NOT_SUPPORTED;
311
Chenbo Fenged37fea2017-12-13 19:35:01 -0800312 int invalidSocket = -1;
313 ASSERT_GT(0, mTc.untagSocket(invalidSocket));
314 int v4socket = socket(AF_INET, SOCK_STREAM, 0);
315 ASSERT_GT(0, mTc.untagSocket(v4socket));
316 expectTagMapEmpty();
317}
318
319TEST_F(TrafficControllerTest, TestSetCounterSet) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900320 SKIP_IF_BPF_NOT_SUPPORTED;
321
Chenbo Fenged37fea2017-12-13 19:35:01 -0800322 ASSERT_EQ(0, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID));
323 uid_t uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700324 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
325 ASSERT_TRUE(isOk(counterSetResult));
326 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
Chenbo Fenged37fea2017-12-13 19:35:01 -0800327 ASSERT_EQ(0, mTc.setCounterSet(DEFAULT_COUNTERSET, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700328 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
329 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.getFirstKey()));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800330}
331
332TEST_F(TrafficControllerTest, TestSetInvalidCounterSet) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900333 SKIP_IF_BPF_NOT_SUPPORTED;
334
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700335 ASSERT_GT(0, mTc.setCounterSet(OVERFLOW_COUNTERSET, TEST_UID));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800336 uid_t uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700337 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
338 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.getFirstKey()));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800339}
340
341TEST_F(TrafficControllerTest, TestDeleteTagData) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900342 SKIP_IF_BPF_NOT_SUPPORTED;
343
Chenbo Fenged37fea2017-12-13 19:35:01 -0800344 uint64_t cookie = 1;
345 uid_t uid = TEST_UID;
346 uint32_t tag = TEST_TAG;
347 StatsKey tagStatsMapKey;
348 populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
349 ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700350 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie)));
351 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
352 ASSERT_TRUE(isOk(counterSetResult));
353 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
354 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800355 tagStatsMapKey.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700356 StatusOr<StatsValue> statsMapResult = mFakeUidStatsMap.readValue(tagStatsMapKey);
357 ASSERT_TRUE(isOk(statsMapResult));
358 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
359 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700360 auto appStatsResult = mFakeAppUidStatsMap.readValue(TEST_UID);
361 ASSERT_TRUE(isOk(appStatsResult));
362 ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
363 ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800364}
365
366TEST_F(TrafficControllerTest, TestDeleteAllUidData) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900367 SKIP_IF_BPF_NOT_SUPPORTED;
368
Chenbo Fenged37fea2017-12-13 19:35:01 -0800369 uint64_t cookie = 1;
370 uid_t uid = TEST_UID;
371 uint32_t tag = TEST_TAG;
372 StatsKey tagStatsMapKey;
373 populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
374 ASSERT_EQ(0, mTc.deleteTagData(0, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700375 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie)));
376 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid)));
377 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey)));
378 tagStatsMapKey.tag = 0;
379 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700380 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(TEST_UID)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800381}
382
383TEST_F(TrafficControllerTest, TestDeleteDataWithTwoTags) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900384 SKIP_IF_BPF_NOT_SUPPORTED;
385
Chenbo Fenged37fea2017-12-13 19:35:01 -0800386 uint64_t cookie1 = 1;
387 uint64_t cookie2 = 2;
388 uid_t uid = TEST_UID;
389 uint32_t tag1 = TEST_TAG;
390 uint32_t tag2 = TEST_TAG + 1;
391 StatsKey tagStatsMapKey1;
392 StatsKey tagStatsMapKey2;
393 populateFakeStats(cookie1, uid, tag1, &tagStatsMapKey1);
394 populateFakeStats(cookie2, uid, tag2, &tagStatsMapKey2);
395 ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700396 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie1)));
397 StatusOr<UidTag> cookieMapResult = mFakeCookieTagMap.readValue(cookie2);
398 ASSERT_TRUE(isOk(cookieMapResult));
399 ASSERT_EQ(TEST_UID, cookieMapResult.value().uid);
400 ASSERT_EQ(TEST_TAG + 1, cookieMapResult.value().tag);
401 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
402 ASSERT_TRUE(isOk(counterSetResult));
403 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
404 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey1)));
405 StatusOr<StatsValue> statsMapResult = mFakeTagStatsMap.readValue(tagStatsMapKey2);
406 ASSERT_TRUE(isOk(statsMapResult));
407 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
408 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800409}
410
411TEST_F(TrafficControllerTest, TestDeleteDataWithTwoUids) {
Lorenzo Colitti23e5c7f2018-01-12 17:55:59 +0900412 SKIP_IF_BPF_NOT_SUPPORTED;
413
Chenbo Fenged37fea2017-12-13 19:35:01 -0800414 uint64_t cookie1 = 1;
415 uint64_t cookie2 = 2;
416 uid_t uid1 = TEST_UID;
417 uid_t uid2 = TEST_UID + 1;
418 uint32_t tag = TEST_TAG;
419 StatsKey tagStatsMapKey1;
420 StatsKey tagStatsMapKey2;
421 populateFakeStats(cookie1, uid1, tag, &tagStatsMapKey1);
422 populateFakeStats(cookie2, uid2, tag, &tagStatsMapKey2);
423
424 // Delete the stats of one of the uid. Check if it is properly collected by
425 // removedStats.
426 ASSERT_EQ(0, mTc.deleteTagData(0, uid2));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700427 ASSERT_FALSE(isOk(mFakeCookieTagMap.readValue(cookie2)));
428 StatusOr<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid1);
429 ASSERT_TRUE(isOk(counterSetResult));
430 ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
431 ASSERT_FALSE(isOk(mFakeUidCounterSetMap.readValue(uid2)));
432 ASSERT_FALSE(isOk(mFakeTagStatsMap.readValue(tagStatsMapKey2)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800433 tagStatsMapKey2.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700434 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey2)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700435 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(uid2)));
Chenbo Feng63ad5592018-01-22 23:14:12 -0800436 tagStatsMapKey1.tag = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700437 StatusOr<StatsValue> statsMapResult = mFakeUidStatsMap.readValue(tagStatsMapKey1);
438 ASSERT_TRUE(isOk(statsMapResult));
439 ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
440 ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700441 auto appStatsResult = mFakeAppUidStatsMap.readValue(uid1);
442 ASSERT_TRUE(isOk(appStatsResult));
443 ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
444 ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
Chenbo Fenged37fea2017-12-13 19:35:01 -0800445
Chenbo Fengef1cab32018-04-13 19:50:49 -0700446 // Delete the stats of the other uid.
Chenbo Fenged37fea2017-12-13 19:35:01 -0800447 ASSERT_EQ(0, mTc.deleteTagData(0, uid1));
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700448 ASSERT_FALSE(isOk(mFakeUidStatsMap.readValue(tagStatsMapKey1)));
Chenbo Fengbc4a15f2018-05-11 19:15:15 -0700449 ASSERT_FALSE(isOk(mFakeAppUidStatsMap.readValue(uid1)));
Chenbo Fenged37fea2017-12-13 19:35:01 -0800450}
451
Chenbo Feng89c12f12018-03-21 10:29:18 -0700452TEST_F(TrafficControllerTest, TestUpdateOwnerMapEntry) {
453 SKIP_IF_BPF_NOT_SUPPORTED;
454
455 uint32_t uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700456 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, DENY, BLACKLIST)));
457 StatusOr<uint8_t> value = mFakeDozableUidMap.readValue(uid);
458 ASSERT_TRUE(isOk(value));
459 ASSERT_EQ(BPF_DROP, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700460
461 uid = TEST_UID2;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700462 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, WHITELIST)));
463 value = mFakeDozableUidMap.readValue(uid);
464 ASSERT_TRUE(isOk(value));
465 ASSERT_EQ(BPF_PASS, value.value());
Chenbo Feng89c12f12018-03-21 10:29:18 -0700466
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700467 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, DENY, WHITELIST)));
468 ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700469
470 uid = TEST_UID;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700471 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, BLACKLIST)));
472 ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700473
474 uid = TEST_UID3;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700475 ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(mFakeDozableUidMap, uid, ALLOW, BLACKLIST)));
476 ASSERT_FALSE(isOk(mFakeDozableUidMap.readValue(uid)));
Chenbo Feng89c12f12018-03-21 10:29:18 -0700477}
478
479TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) {
480 SKIP_IF_BPF_NOT_SUPPORTED;
481
482 checkUidOwnerRuleForChain(DOZABLE, mFakeDozableUidMap);
483 checkUidOwnerRuleForChain(STANDBY, mFakeStandbyUidMap);
484 checkUidOwnerRuleForChain(POWERSAVE, mFakePowerSaveUidMap);
485 ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, WHITELIST));
486 ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, WHITELIST));
487}
488
489TEST_F(TrafficControllerTest, TestReplaceUidOwnerMap) {
490 SKIP_IF_BPF_NOT_SUPPORTED;
491
492 std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
493 checkUidMapReplace("fw_dozable", uids, mFakeDozableUidMap);
494 checkUidMapReplace("fw_standby", uids, mFakeStandbyUidMap);
495 checkUidMapReplace("fw_powersave", uids, mFakePowerSaveUidMap);
496 ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
497}
498
Chenbo Feng95892f32018-06-07 14:52:02 -0700499TEST_F(TrafficControllerTest, TestBlacklistUidMatch) {
500 SKIP_IF_BPF_NOT_SUPPORTED;
501
502 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
503 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
504 BandwidthController::IptOpInsert)));
505 expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
506 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
507 BandwidthController::IptOpDelete)));
508 ASSERT_FALSE(isOk(mFakeBandwidthUidMap.getFirstKey()));
509}
510
511TEST_F(TrafficControllerTest, TestWhitelistUidMatch) {
512 SKIP_IF_BPF_NOT_SUPPORTED;
513
514 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
515 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
516 BandwidthController::IptOpInsert)));
517 expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
518 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
519 BandwidthController::IptOpDelete)));
520 ASSERT_FALSE(isOk(mFakeBandwidthUidMap.getFirstKey()));
521}
522
523TEST_F(TrafficControllerTest, TestReplaceMatchUid) {
524 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
525 // Add appStrUids to the blacklist and expect that their values are all BLACKLISTMATCH.
526 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
527 BandwidthController::IptOpInsert)));
528 expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
529
530 // Add the same UIDs to the whitelist and expect that we get BLACKLISTMATCH | WHITELISTMATCH.
531 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
532 BandwidthController::IptOpInsert)));
533 expectBandwidthMapValues(appStrUids, WHITELISTMATCH | BLACKLISTMATCH);
534
535 // Remove the same UIDs from the whitelist and check the BLACKLISTMATCH is still there.
536 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
537 BandwidthController::IptOpDelete)));
538 expectBandwidthMapValues(appStrUids, BLACKLISTMATCH);
539
540 // Remove the same UIDs from the blacklist and check the map is empty.
541 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
542 BandwidthController::IptOpDelete)));
543 ASSERT_FALSE(isOk(mFakeBandwidthUidMap.getFirstKey()));
544}
545
546TEST_F(TrafficControllerTest, TestDeleteWrongMatchSilentlyFails) {
547 std::vector<std::string> appStrUids = {"1000", "1001", "10012"};
548 // If the uid does not exist in the map, trying to delete a rule about it will fail.
549 ASSERT_FALSE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
550 BandwidthController::IptOpDelete)));
551 ASSERT_FALSE(isOk(mFakeBandwidthUidMap.getFirstKey()));
552
553 // Add blacklist rules for appStrUids.
554 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReturn,
555 BandwidthController::IptOpInsert)));
556 expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
557
558 // Delete (non-existent) blacklist rules for appStrUids, and check that this silently does
559 // nothing if the uid is in the map but does not have blacklist match. This is required because
560 // NetworkManagementService will try to remove a uid from blacklist after adding it to the
561 // whitelist and if the remove fails it will not update the uid status.
562 ASSERT_TRUE(isOk(mTc.updateBandwidthUidMap(appStrUids, BandwidthController::IptJumpReject,
563 BandwidthController::IptOpDelete)));
564 expectBandwidthMapValues(appStrUids, WHITELISTMATCH);
565}
Chenbo Fenged37fea2017-12-13 19:35:01 -0800566} // namespace net
567} // namespace android