blob: fd2d0d5e134066514bc31370b36fcf95bf733fef [file] [log] [blame]
Lorenzo Colitti89faa342016-02-26 11:38:47 +09001/*
2 * Copyright 2016 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 * binder_test.cpp - unit tests for netd binder RPCs.
17 */
18
Robin Leeb8087362016-03-30 18:43:08 +010019#include <cerrno>
20#include <cinttypes>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090021#include <cstdint>
Lorenzo Colittidedd2712016-03-22 12:36:29 +090022#include <cstdio>
23#include <cstdlib>
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090024#include <set>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090025#include <vector>
26
Lorenzo Colitti755faa92016-07-27 22:10:49 +090027#include <fcntl.h>
Erik Klinecc4f2732016-08-03 11:24:27 +090028#include <ifaddrs.h>
Lorenzo Colitti755faa92016-07-27 22:10:49 +090029#include <netdb.h>
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090030#include <sys/socket.h>
Lorenzo Colitti755faa92016-07-27 22:10:49 +090031#include <sys/types.h>
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090032#include <netinet/in.h>
Lorenzo Colitti755faa92016-07-27 22:10:49 +090033#include <linux/if.h>
34#include <linux/if_tun.h>
Ben Schwartze7601812017-04-28 16:38:29 -040035#include <openssl/base64.h>
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090036
Erik Klinecc4f2732016-08-03 11:24:27 +090037#include <android-base/macros.h>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090038#include <android-base/stringprintf.h>
Lorenzo Colittidedd2712016-03-22 12:36:29 +090039#include <android-base/strings.h>
Robin Leeb8087362016-03-30 18:43:08 +010040#include <cutils/multiuser.h>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090041#include <gtest/gtest.h>
42#include <logwrap/logwrap.h>
Lorenzo Colitti755faa92016-07-27 22:10:49 +090043#include <netutils/ifc.h>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090044
45#include "NetdConstants.h"
Robin Lee7e05cc92016-09-21 16:31:33 +090046#include "Stopwatch.h"
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090047#include "tun_interface.h"
Lorenzo Colitti89faa342016-02-26 11:38:47 +090048#include "android/net/INetd.h"
Robin Leeb8087362016-03-30 18:43:08 +010049#include "android/net/UidRange.h"
Lorenzo Colitti89faa342016-02-26 11:38:47 +090050#include "binder/IServiceManager.h"
51
Lorenzo Colitti5c68b9c2017-08-10 18:50:10 +090052#define IP_PATH "/system/bin/ip"
53#define IP6TABLES_PATH "/system/bin/ip6tables"
54#define IPTABLES_PATH "/system/bin/iptables"
Lorenzo Colitti755faa92016-07-27 22:10:49 +090055#define TUN_DEV "/dev/tun"
56
Lorenzo Colitti89faa342016-02-26 11:38:47 +090057using namespace android;
58using namespace android::base;
59using namespace android::binder;
Lorenzo Colittiaff28792017-09-26 17:46:18 +090060using android::base::StartsWith;
Lorenzo Colitti89faa342016-02-26 11:38:47 +090061using android::net::INetd;
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090062using android::net::TunInterface;
Robin Leeb8087362016-03-30 18:43:08 +010063using android::net::UidRange;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +090064using android::os::PersistableBundle;
Robin Leeb8087362016-03-30 18:43:08 +010065
66static const char* IP_RULE_V4 = "-4";
67static const char* IP_RULE_V6 = "-6";
Lorenzo Colittid33e96d2016-12-15 23:59:01 +090068static const int TEST_NETID1 = 65501;
69static const int TEST_NETID2 = 65502;
70constexpr int BASE_UID = AID_USER_OFFSET * 5;
Lorenzo Colitti89faa342016-02-26 11:38:47 +090071
Benedict Wongb2daefb2017-12-06 22:05:46 -080072static const std::string NO_SOCKET_ALLOW_RULE("! owner UID match 0-4294967294");
73static const std::string ESP_ALLOW_RULE("esp");
74
Lorenzo Colitti89faa342016-02-26 11:38:47 +090075class BinderTest : public ::testing::Test {
76
77public:
78 BinderTest() {
79 sp<IServiceManager> sm = defaultServiceManager();
80 sp<IBinder> binder = sm->getService(String16("netd"));
81 if (binder != nullptr) {
82 mNetd = interface_cast<INetd>(binder);
83 }
84 }
85
Lorenzo Colitti755faa92016-07-27 22:10:49 +090086 void SetUp() override {
Lorenzo Colitti89faa342016-02-26 11:38:47 +090087 ASSERT_NE(nullptr, mNetd.get());
88 }
89
Lorenzo Colittid33e96d2016-12-15 23:59:01 +090090 void TearDown() override {
91 mNetd->networkDestroy(TEST_NETID1);
92 mNetd->networkDestroy(TEST_NETID2);
93 }
94
Lorenzo Colitti755faa92016-07-27 22:10:49 +090095 // Static because setting up the tun interface takes about 40ms.
96 static void SetUpTestCase() {
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090097 ASSERT_EQ(0, sTun.init());
98 ASSERT_LE(sTun.name().size(), static_cast<size_t>(IFNAMSIZ));
Lorenzo Colitti755faa92016-07-27 22:10:49 +090099 }
100
101 static void TearDownTestCase() {
102 // Closing the socket removes the interface and IP addresses.
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900103 sTun.destroy();
Lorenzo Colitti755faa92016-07-27 22:10:49 +0900104 }
105
106 static void fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket);
Lorenzo Colitti755faa92016-07-27 22:10:49 +0900107
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900108protected:
109 sp<INetd> mNetd;
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900110 static TunInterface sTun;
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900111};
112
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900113TunInterface BinderTest::sTun;
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900114
Lorenzo Colitti699aa992016-04-15 10:22:37 +0900115class TimedOperation : public Stopwatch {
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900116public:
Chih-Hung Hsieh18051052016-05-06 10:36:13 -0700117 explicit TimedOperation(const std::string &name): mName(name) {}
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900118 virtual ~TimedOperation() {
Lorenzo Colitti699aa992016-04-15 10:22:37 +0900119 fprintf(stderr, " %s: %6.1f ms\n", mName.c_str(), timeTaken());
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900120 }
121
122private:
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900123 std::string mName;
124};
125
126TEST_F(BinderTest, TestIsAlive) {
127 TimedOperation t("isAlive RPC");
128 bool isAlive = false;
129 mNetd->isAlive(&isAlive);
130 ASSERT_TRUE(isAlive);
131}
132
133static int randomUid() {
134 return 100000 * arc4random_uniform(7) + 10000 + arc4random_uniform(5000);
135}
136
Robin Leeb8087362016-03-30 18:43:08 +0100137static std::vector<std::string> runCommand(const std::string& command) {
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900138 std::vector<std::string> lines;
139 FILE *f;
140
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900141 if ((f = popen(command.c_str(), "r")) == nullptr) {
142 perror("popen");
143 return lines;
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900144 }
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900145
146 char *line = nullptr;
Robin Leeb8087362016-03-30 18:43:08 +0100147 size_t bufsize = 0;
148 ssize_t linelen = 0;
149 while ((linelen = getline(&line, &bufsize, f)) >= 0) {
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900150 lines.push_back(std::string(line, linelen));
151 free(line);
152 line = nullptr;
153 }
154
155 pclose(f);
156 return lines;
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900157}
158
Robin Leeb8087362016-03-30 18:43:08 +0100159static std::vector<std::string> listIpRules(const char *ipVersion) {
160 std::string command = StringPrintf("%s %s rule list", IP_PATH, ipVersion);
161 return runCommand(command);
162}
163
164static std::vector<std::string> listIptablesRule(const char *binary, const char *chainName) {
Lorenzo Colitti80545772016-06-09 14:20:08 +0900165 std::string command = StringPrintf("%s -w -n -L %s", binary, chainName);
Robin Leeb8087362016-03-30 18:43:08 +0100166 return runCommand(command);
167}
168
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900169static int iptablesRuleLineLength(const char *binary, const char *chainName) {
170 return listIptablesRule(binary, chainName).size();
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900171}
172
Benedict Wongb2daefb2017-12-06 22:05:46 -0800173static bool iptablesRuleExists(const char *binary,
174 const char *chainName,
175 const std::string expectedRule) {
176 std::vector<std::string> rules = listIptablesRule(binary, chainName);
177 for(std::string &rule: rules) {
178 if(rule.find(expectedRule) != std::string::npos) {
179 return true;
180 }
181 }
182 return false;
183}
184
185static bool iptablesNoSocketAllowRuleExists(const char *chainName){
186 return iptablesRuleExists(IPTABLES_PATH, chainName, NO_SOCKET_ALLOW_RULE) &&
187 iptablesRuleExists(IP6TABLES_PATH, chainName, NO_SOCKET_ALLOW_RULE);
188}
189
190static bool iptablesEspAllowRuleExists(const char *chainName){
191 return iptablesRuleExists(IPTABLES_PATH, chainName, ESP_ALLOW_RULE) &&
192 iptablesRuleExists(IP6TABLES_PATH, chainName, ESP_ALLOW_RULE);
193}
194
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900195TEST_F(BinderTest, TestFirewallReplaceUidChain) {
196 std::string chainName = StringPrintf("netd_binder_test_%u", arc4random_uniform(10000));
197 const int kNumUids = 500;
198 std::vector<int32_t> noUids(0);
199 std::vector<int32_t> uids(kNumUids);
200 for (int i = 0; i < kNumUids; i++) {
201 uids[i] = randomUid();
202 }
203
204 bool ret;
205 {
206 TimedOperation op(StringPrintf("Programming %d-UID whitelist chain", kNumUids));
207 mNetd->firewallReplaceUidChain(String16(chainName.c_str()), true, uids, &ret);
208 }
209 EXPECT_EQ(true, ret);
Benedict Wongb2daefb2017-12-06 22:05:46 -0800210 EXPECT_EQ((int) uids.size() + 9, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
211 EXPECT_EQ((int) uids.size() + 15, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
212 EXPECT_EQ(true, iptablesNoSocketAllowRuleExists(chainName.c_str()));
213 EXPECT_EQ(true, iptablesEspAllowRuleExists(chainName.c_str()));
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900214 {
215 TimedOperation op("Clearing whitelist chain");
216 mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
217 }
218 EXPECT_EQ(true, ret);
Lorenzo Colitti50b198a2017-03-30 02:50:09 +0900219 EXPECT_EQ(5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
220 EXPECT_EQ(5, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900221
222 {
223 TimedOperation op(StringPrintf("Programming %d-UID blacklist chain", kNumUids));
224 mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, uids, &ret);
225 }
226 EXPECT_EQ(true, ret);
Lorenzo Colitti50b198a2017-03-30 02:50:09 +0900227 EXPECT_EQ((int) uids.size() + 5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
228 EXPECT_EQ((int) uids.size() + 5, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
Benedict Wongb2daefb2017-12-06 22:05:46 -0800229 EXPECT_EQ(false, iptablesNoSocketAllowRuleExists(chainName.c_str()));
230 EXPECT_EQ(false, iptablesEspAllowRuleExists(chainName.c_str()));
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900231
232 {
233 TimedOperation op("Clearing blacklist chain");
234 mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
235 }
236 EXPECT_EQ(true, ret);
Lorenzo Colitti50b198a2017-03-30 02:50:09 +0900237 EXPECT_EQ(5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
238 EXPECT_EQ(5, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900239
240 // Check that the call fails if iptables returns an error.
241 std::string veryLongStringName = "netd_binder_test_UnacceptablyLongIptablesChainName";
242 mNetd->firewallReplaceUidChain(String16(veryLongStringName.c_str()), true, noUids, &ret);
243 EXPECT_EQ(false, ret);
244}
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900245
246static int bandwidthDataSaverEnabled(const char *binary) {
Lorenzo Colitti464eabe2016-03-25 13:38:19 +0900247 std::vector<std::string> lines = listIptablesRule(binary, "bw_data_saver");
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900248
249 // Output looks like this:
250 //
Lorenzo Colitti464eabe2016-03-25 13:38:19 +0900251 // Chain bw_data_saver (1 references)
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900252 // target prot opt source destination
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900253 // RETURN all -- 0.0.0.0/0 0.0.0.0/0
Lorenzo Colittiaff28792017-09-26 17:46:18 +0900254 //
255 // or:
256 //
257 // Chain bw_data_saver (1 references)
258 // target prot opt source destination
259 // ... possibly connectivity critical packet rules here ...
260 // REJECT all -- ::/0 ::/0
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900261
Lorenzo Colittiaff28792017-09-26 17:46:18 +0900262 EXPECT_GE(lines.size(), 3U);
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900263
Lorenzo Colittiaff28792017-09-26 17:46:18 +0900264 if (lines.size() == 3 && StartsWith(lines[2], "RETURN ")) {
265 // Data saver disabled.
266 return 0;
267 }
268
269 size_t minSize = (std::string(binary) == IPTABLES_PATH) ? 3 : 9;
270
271 if (lines.size() >= minSize && StartsWith(lines[lines.size() -1], "REJECT ")) {
272 // Data saver enabled.
273 return 1;
274 }
275
276 return -1;
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900277}
278
279bool enableDataSaver(sp<INetd>& netd, bool enable) {
280 TimedOperation op(enable ? " Enabling data saver" : "Disabling data saver");
281 bool ret;
282 netd->bandwidthEnableDataSaver(enable, &ret);
283 return ret;
284}
285
286int getDataSaverState() {
287 const int enabled4 = bandwidthDataSaverEnabled(IPTABLES_PATH);
288 const int enabled6 = bandwidthDataSaverEnabled(IP6TABLES_PATH);
289 EXPECT_EQ(enabled4, enabled6);
290 EXPECT_NE(-1, enabled4);
291 EXPECT_NE(-1, enabled6);
292 if (enabled4 != enabled6 || (enabled6 != 0 && enabled6 != 1)) {
293 return -1;
294 }
295 return enabled6;
296}
297
298TEST_F(BinderTest, TestBandwidthEnableDataSaver) {
299 const int wasEnabled = getDataSaverState();
300 ASSERT_NE(-1, wasEnabled);
301
302 if (wasEnabled) {
303 ASSERT_TRUE(enableDataSaver(mNetd, false));
304 EXPECT_EQ(0, getDataSaverState());
305 }
306
307 ASSERT_TRUE(enableDataSaver(mNetd, false));
308 EXPECT_EQ(0, getDataSaverState());
309
310 ASSERT_TRUE(enableDataSaver(mNetd, true));
311 EXPECT_EQ(1, getDataSaverState());
312
313 ASSERT_TRUE(enableDataSaver(mNetd, true));
314 EXPECT_EQ(1, getDataSaverState());
315
316 if (!wasEnabled) {
317 ASSERT_TRUE(enableDataSaver(mNetd, false));
318 EXPECT_EQ(0, getDataSaverState());
319 }
320}
Robin Leeb8087362016-03-30 18:43:08 +0100321
322static bool ipRuleExistsForRange(const uint32_t priority, const UidRange& range,
323 const std::string& action, const char* ipVersion) {
324 // Output looks like this:
Robin Lee6c84ef62016-05-03 13:17:58 +0100325 // "12500:\tfrom all fwmark 0x0/0x20000 iif lo uidrange 1000-2000 prohibit"
Robin Leeb8087362016-03-30 18:43:08 +0100326 std::vector<std::string> rules = listIpRules(ipVersion);
327
328 std::string prefix = StringPrintf("%" PRIu32 ":", priority);
329 std::string suffix = StringPrintf(" iif lo uidrange %d-%d %s\n",
330 range.getStart(), range.getStop(), action.c_str());
331 for (std::string line : rules) {
Elliott Hughes2f445082017-12-20 12:39:35 -0800332 if (android::base::StartsWith(line, prefix) && android::base::EndsWith(line, suffix)) {
Robin Leeb8087362016-03-30 18:43:08 +0100333 return true;
334 }
335 }
336 return false;
337}
338
339static bool ipRuleExistsForRange(const uint32_t priority, const UidRange& range,
340 const std::string& action) {
341 bool existsIp4 = ipRuleExistsForRange(priority, range, action, IP_RULE_V4);
342 bool existsIp6 = ipRuleExistsForRange(priority, range, action, IP_RULE_V6);
343 EXPECT_EQ(existsIp4, existsIp6);
344 return existsIp4;
345}
346
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900347TEST_F(BinderTest, TestNetworkInterfaces) {
348 EXPECT_TRUE(mNetd->networkCreatePhysical(TEST_NETID1, "").isOk());
349 EXPECT_EQ(EEXIST, mNetd->networkCreatePhysical(TEST_NETID1, "").serviceSpecificErrorCode());
350 EXPECT_EQ(EEXIST, mNetd->networkCreateVpn(TEST_NETID1, false, true).serviceSpecificErrorCode());
351 EXPECT_TRUE(mNetd->networkCreateVpn(TEST_NETID2, false, true).isOk());
352
353 EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
354 EXPECT_EQ(EBUSY,
355 mNetd->networkAddInterface(TEST_NETID2, sTun.name()).serviceSpecificErrorCode());
356
357 EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
358 EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID2, sTun.name()).isOk());
359 EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID2).isOk());
360}
361
362TEST_F(BinderTest, TestNetworkUidRules) {
363 const uint32_t RULE_PRIORITY_SECURE_VPN = 12000;
364
365 EXPECT_TRUE(mNetd->networkCreateVpn(TEST_NETID1, false, true).isOk());
366 EXPECT_EQ(EEXIST, mNetd->networkCreateVpn(TEST_NETID1, false, true).serviceSpecificErrorCode());
367 EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
368
369 std::vector<UidRange> uidRanges = {
370 {BASE_UID + 8005, BASE_UID + 8012},
371 {BASE_UID + 8090, BASE_UID + 8099}
372 };
373 UidRange otherRange(BASE_UID + 8190, BASE_UID + 8299);
374 std::string suffix = StringPrintf("lookup %s ", sTun.name().c_str());
375
376 EXPECT_TRUE(mNetd->networkAddUidRanges(TEST_NETID1, uidRanges).isOk());
377
378 EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, uidRanges[0], suffix));
379 EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, otherRange, suffix));
380 EXPECT_TRUE(mNetd->networkRemoveUidRanges(TEST_NETID1, uidRanges).isOk());
381 EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, uidRanges[0], suffix));
382
383 EXPECT_TRUE(mNetd->networkAddUidRanges(TEST_NETID1, uidRanges).isOk());
384 EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, uidRanges[1], suffix));
385 EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
386 EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY_SECURE_VPN, uidRanges[1], suffix));
387
388 EXPECT_EQ(ENONET, mNetd->networkDestroy(TEST_NETID1).serviceSpecificErrorCode());
389}
390
Robin Leeb8087362016-03-30 18:43:08 +0100391TEST_F(BinderTest, TestNetworkRejectNonSecureVpn) {
Robin Lee6c84ef62016-05-03 13:17:58 +0100392 constexpr uint32_t RULE_PRIORITY = 12500;
Robin Leeb8087362016-03-30 18:43:08 +0100393
Robin Leeb8087362016-03-30 18:43:08 +0100394 std::vector<UidRange> uidRanges = {
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900395 {BASE_UID + 150, BASE_UID + 224},
396 {BASE_UID + 226, BASE_UID + 300}
Robin Leeb8087362016-03-30 18:43:08 +0100397 };
398
399 const std::vector<std::string> initialRulesV4 = listIpRules(IP_RULE_V4);
400 const std::vector<std::string> initialRulesV6 = listIpRules(IP_RULE_V6);
401
402 // Create two valid rules.
403 ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(true, uidRanges).isOk());
404 EXPECT_EQ(initialRulesV4.size() + 2, listIpRules(IP_RULE_V4).size());
405 EXPECT_EQ(initialRulesV6.size() + 2, listIpRules(IP_RULE_V6).size());
406 for (auto const& range : uidRanges) {
407 EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
408 }
409
410 // Remove the rules.
411 ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(false, uidRanges).isOk());
412 EXPECT_EQ(initialRulesV4.size(), listIpRules(IP_RULE_V4).size());
413 EXPECT_EQ(initialRulesV6.size(), listIpRules(IP_RULE_V6).size());
414 for (auto const& range : uidRanges) {
415 EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
416 }
417
418 // Fail to remove the rules a second time after they are already deleted.
419 binder::Status status = mNetd->networkRejectNonSecureVpn(false, uidRanges);
420 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
421 EXPECT_EQ(ENOENT, status.serviceSpecificErrorCode());
422
423 // All rules should be the same as before.
424 EXPECT_EQ(initialRulesV4, listIpRules(IP_RULE_V4));
425 EXPECT_EQ(initialRulesV6, listIpRules(IP_RULE_V6));
426}
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900427
Lorenzo Colitti755faa92016-07-27 22:10:49 +0900428// Create a socket pair that isLoopbackSocket won't think is local.
429void BinderTest::fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket) {
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900430 *serverSocket = socket(AF_INET6, SOCK_STREAM, 0);
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900431 struct sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.dstAddr() };
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900432 ASSERT_EQ(0, bind(*serverSocket, (struct sockaddr *) &server6, sizeof(server6)));
433
434 socklen_t addrlen = sizeof(server6);
435 ASSERT_EQ(0, getsockname(*serverSocket, (struct sockaddr *) &server6, &addrlen));
436 ASSERT_EQ(0, listen(*serverSocket, 10));
437
438 *clientSocket = socket(AF_INET6, SOCK_STREAM, 0);
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900439 struct sockaddr_in6 client6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.srcAddr() };
Lorenzo Colitti755faa92016-07-27 22:10:49 +0900440 ASSERT_EQ(0, bind(*clientSocket, (struct sockaddr *) &client6, sizeof(client6)));
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900441 ASSERT_EQ(0, connect(*clientSocket, (struct sockaddr *) &server6, sizeof(server6)));
442 ASSERT_EQ(0, getsockname(*clientSocket, (struct sockaddr *) &client6, &addrlen));
443
444 *acceptedSocket = accept(*serverSocket, (struct sockaddr *) &server6, &addrlen);
445 ASSERT_NE(-1, *acceptedSocket);
446
447 ASSERT_EQ(0, memcmp(&client6, &server6, sizeof(client6)));
448}
449
450void checkSocketpairOpen(int clientSocket, int acceptedSocket) {
451 char buf[4096];
452 EXPECT_EQ(4, write(clientSocket, "foo", sizeof("foo")));
453 EXPECT_EQ(4, read(acceptedSocket, buf, sizeof(buf)));
454 EXPECT_EQ(0, memcmp(buf, "foo", sizeof("foo")));
455}
456
457void checkSocketpairClosed(int clientSocket, int acceptedSocket) {
458 // Check that the client socket was closed with ECONNABORTED.
459 int ret = write(clientSocket, "foo", sizeof("foo"));
460 int err = errno;
461 EXPECT_EQ(-1, ret);
462 EXPECT_EQ(ECONNABORTED, err);
463
464 // Check that it sent a RST to the server.
465 ret = write(acceptedSocket, "foo", sizeof("foo"));
466 err = errno;
467 EXPECT_EQ(-1, ret);
468 EXPECT_EQ(ECONNRESET, err);
469}
470
471TEST_F(BinderTest, TestSocketDestroy) {
472 int clientSocket, serverSocket, acceptedSocket;
Lorenzo Colitti755faa92016-07-27 22:10:49 +0900473 ASSERT_NO_FATAL_FAILURE(fakeRemoteSocketPair(&clientSocket, &serverSocket, &acceptedSocket));
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900474
475 // Pick a random UID in the system UID range.
476 constexpr int baseUid = AID_APP - 2000;
477 static_assert(baseUid > 0, "Not enough UIDs? Please fix this test.");
478 int uid = baseUid + 500 + arc4random_uniform(1000);
479 EXPECT_EQ(0, fchown(clientSocket, uid, -1));
480
481 // UID ranges that don't contain uid.
482 std::vector<UidRange> uidRanges = {
483 {baseUid + 42, baseUid + 449},
484 {baseUid + 1536, AID_APP - 4},
485 {baseUid + 498, uid - 1},
486 {uid + 1, baseUid + 1520},
487 };
488 // A skip list that doesn't contain UID.
489 std::vector<int32_t> skipUids { baseUid + 123, baseUid + 1600 };
490
491 // Close sockets. Our test socket should be intact.
492 EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
493 checkSocketpairOpen(clientSocket, acceptedSocket);
494
495 // UID ranges that do contain uid.
496 uidRanges = {
497 {baseUid + 42, baseUid + 449},
498 {baseUid + 1536, AID_APP - 4},
499 {baseUid + 498, baseUid + 1520},
500 };
501 // Add uid to the skip list.
502 skipUids.push_back(uid);
503
504 // Close sockets. Our test socket should still be intact because it's in the skip list.
505 EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
506 checkSocketpairOpen(clientSocket, acceptedSocket);
507
508 // Now remove uid from skipUids, and close sockets. Our test socket should have been closed.
509 skipUids.resize(skipUids.size() - 1);
510 EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
511 checkSocketpairClosed(clientSocket, acceptedSocket);
512
513 close(clientSocket);
514 close(serverSocket);
515 close(acceptedSocket);
516}
Erik Klinecc4f2732016-08-03 11:24:27 +0900517
518namespace {
519
520int netmaskToPrefixLength(const uint8_t *buf, size_t buflen) {
521 if (buf == nullptr) return -1;
522
523 int prefixLength = 0;
524 bool endOfContiguousBits = false;
525 for (unsigned int i = 0; i < buflen; i++) {
526 const uint8_t value = buf[i];
527
528 // Bad bit sequence: check for a contiguous set of bits from the high
529 // end by verifying that the inverted value + 1 is a power of 2
530 // (power of 2 iff. (v & (v - 1)) == 0).
531 const uint8_t inverse = ~value + 1;
532 if ((inverse & (inverse - 1)) != 0) return -1;
533
534 prefixLength += (value == 0) ? 0 : CHAR_BIT - ffs(value) + 1;
535
536 // Bogus netmask.
537 if (endOfContiguousBits && value != 0) return -1;
538
539 if (value != 0xff) endOfContiguousBits = true;
540 }
541
542 return prefixLength;
543}
544
545template<typename T>
546int netmaskToPrefixLength(const T *p) {
547 return netmaskToPrefixLength(reinterpret_cast<const uint8_t*>(p), sizeof(T));
548}
549
550
551static bool interfaceHasAddress(
552 const std::string &ifname, const char *addrString, int prefixLength) {
553 struct addrinfo *addrinfoList = nullptr;
554 ScopedAddrinfo addrinfoCleanup(addrinfoList);
555
556 const struct addrinfo hints = {
557 .ai_flags = AI_NUMERICHOST,
558 .ai_family = AF_UNSPEC,
559 .ai_socktype = SOCK_DGRAM,
560 };
561 if (getaddrinfo(addrString, nullptr, &hints, &addrinfoList) != 0 ||
562 addrinfoList == nullptr || addrinfoList->ai_addr == nullptr) {
563 return false;
564 }
565
566 struct ifaddrs *ifaddrsList = nullptr;
567 ScopedIfaddrs ifaddrsCleanup(ifaddrsList);
568
569 if (getifaddrs(&ifaddrsList) != 0) {
570 return false;
571 }
572
573 for (struct ifaddrs *addr = ifaddrsList; addr != nullptr; addr = addr->ifa_next) {
574 if (std::string(addr->ifa_name) != ifname ||
575 addr->ifa_addr == nullptr ||
576 addr->ifa_addr->sa_family != addrinfoList->ai_addr->sa_family) {
577 continue;
578 }
579
580 switch (addr->ifa_addr->sa_family) {
581 case AF_INET: {
582 auto *addr4 = reinterpret_cast<const struct sockaddr_in*>(addr->ifa_addr);
583 auto *want = reinterpret_cast<const struct sockaddr_in*>(addrinfoList->ai_addr);
584 if (memcmp(&addr4->sin_addr, &want->sin_addr, sizeof(want->sin_addr)) != 0) {
585 continue;
586 }
587
588 if (prefixLength < 0) return true; // not checking prefix lengths
589
590 if (addr->ifa_netmask == nullptr) return false;
591 auto *nm = reinterpret_cast<const struct sockaddr_in*>(addr->ifa_netmask);
592 EXPECT_EQ(prefixLength, netmaskToPrefixLength(&nm->sin_addr));
593 return (prefixLength == netmaskToPrefixLength(&nm->sin_addr));
594 }
595 case AF_INET6: {
596 auto *addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr->ifa_addr);
597 auto *want = reinterpret_cast<const struct sockaddr_in6*>(addrinfoList->ai_addr);
598 if (memcmp(&addr6->sin6_addr, &want->sin6_addr, sizeof(want->sin6_addr)) != 0) {
599 continue;
600 }
601
602 if (prefixLength < 0) return true; // not checking prefix lengths
603
604 if (addr->ifa_netmask == nullptr) return false;
605 auto *nm = reinterpret_cast<const struct sockaddr_in6*>(addr->ifa_netmask);
606 EXPECT_EQ(prefixLength, netmaskToPrefixLength(&nm->sin6_addr));
607 return (prefixLength == netmaskToPrefixLength(&nm->sin6_addr));
608 }
609 default:
610 // Cannot happen because we have already screened for matching
611 // address families at the top of each iteration.
612 continue;
613 }
614 }
615
616 return false;
617}
618
619} // namespace
620
621TEST_F(BinderTest, TestInterfaceAddRemoveAddress) {
622 static const struct TestData {
623 const char *addrString;
624 const int prefixLength;
625 const bool expectSuccess;
626 } kTestData[] = {
627 { "192.0.2.1", 24, true },
628 { "192.0.2.2", 25, true },
629 { "192.0.2.3", 32, true },
630 { "192.0.2.4", 33, false },
631 { "192.not.an.ip", 24, false },
632 { "2001:db8::1", 64, true },
633 { "2001:db8::2", 65, true },
634 { "2001:db8::3", 128, true },
635 { "2001:db8::4", 129, false },
636 { "foo:bar::bad", 64, false },
637 };
638
639 for (unsigned int i = 0; i < arraysize(kTestData); i++) {
640 const auto &td = kTestData[i];
641
642 // [1.a] Add the address.
643 binder::Status status = mNetd->interfaceAddAddress(
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900644 sTun.name(), td.addrString, td.prefixLength);
Erik Klinecc4f2732016-08-03 11:24:27 +0900645 if (td.expectSuccess) {
646 EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
647 } else {
648 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
649 ASSERT_NE(0, status.serviceSpecificErrorCode());
650 }
651
652 // [1.b] Verify the addition meets the expectation.
653 if (td.expectSuccess) {
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900654 EXPECT_TRUE(interfaceHasAddress(sTun.name(), td.addrString, td.prefixLength));
Erik Klinecc4f2732016-08-03 11:24:27 +0900655 } else {
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900656 EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
Erik Klinecc4f2732016-08-03 11:24:27 +0900657 }
658
659 // [2.a] Try to remove the address. If it was not previously added, removing it fails.
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900660 status = mNetd->interfaceDelAddress(sTun.name(), td.addrString, td.prefixLength);
Erik Klinecc4f2732016-08-03 11:24:27 +0900661 if (td.expectSuccess) {
662 EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
663 } else {
664 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
665 ASSERT_NE(0, status.serviceSpecificErrorCode());
666 }
667
668 // [2.b] No matter what, the address should not be present.
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900669 EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
Erik Klinecc4f2732016-08-03 11:24:27 +0900670 }
671}
Erik Kline55b06f82016-07-04 09:57:18 +0900672
673TEST_F(BinderTest, TestSetProcSysNet) {
674 static const struct TestData {
675 const int family;
676 const int which;
677 const char *ifname;
678 const char *parameter;
679 const char *value;
680 const int expectedReturnCode;
681 } kTestData[] = {
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900682 { INetd::IPV4, INetd::CONF, sTun.name().c_str(), "arp_ignore", "1", 0 },
683 { -1, INetd::CONF, sTun.name().c_str(), "arp_ignore", "1", EAFNOSUPPORT },
684 { INetd::IPV4, -1, sTun.name().c_str(), "arp_ignore", "1", EINVAL },
Erik Kline55b06f82016-07-04 09:57:18 +0900685 { INetd::IPV4, INetd::CONF, "..", "conf/lo/arp_ignore", "1", EINVAL },
686 { INetd::IPV4, INetd::CONF, ".", "lo/arp_ignore", "1", EINVAL },
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900687 { INetd::IPV4, INetd::CONF, sTun.name().c_str(), "../all/arp_ignore", "1", EINVAL },
688 { INetd::IPV6, INetd::NEIGH, sTun.name().c_str(), "ucast_solicit", "7", 0 },
Erik Kline55b06f82016-07-04 09:57:18 +0900689 };
690
691 for (unsigned int i = 0; i < arraysize(kTestData); i++) {
692 const auto &td = kTestData[i];
693
694 const binder::Status status = mNetd->setProcSysNet(
695 td.family, td.which, td.ifname, td.parameter,
696 td.value);
697
698 if (td.expectedReturnCode == 0) {
699 SCOPED_TRACE(String8::format("test case %d should have passed", i));
700 EXPECT_EQ(0, status.exceptionCode());
701 EXPECT_EQ(0, status.serviceSpecificErrorCode());
702 } else {
703 SCOPED_TRACE(String8::format("test case %d should have failed", i));
704 EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
705 EXPECT_EQ(td.expectedReturnCode, status.serviceSpecificErrorCode());
706 }
707 }
708}
Ben Schwartze7601812017-04-28 16:38:29 -0400709
710static std::string base64Encode(const std::vector<uint8_t>& input) {
711 size_t out_len;
712 EXPECT_EQ(1, EVP_EncodedLength(&out_len, input.size()));
713 // out_len includes the trailing NULL.
714 uint8_t output_bytes[out_len];
715 EXPECT_EQ(out_len - 1, EVP_EncodeBlock(output_bytes, input.data(), input.size()));
716 return std::string(reinterpret_cast<char*>(output_bytes));
717}
718
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400719TEST_F(BinderTest, TestSetResolverConfiguration_Tls) {
Ben Schwartze7601812017-04-28 16:38:29 -0400720 std::vector<uint8_t> fp(SHA256_SIZE);
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400721 std::vector<uint8_t> short_fp(1);
722 std::vector<uint8_t> long_fp(SHA256_SIZE + 1);
723 std::vector<std::string> test_domains;
724 std::vector<int> test_params = { 300, 25, 8, 8 };
725 unsigned test_netid = 0;
Ben Schwartze7601812017-04-28 16:38:29 -0400726 static const struct TestData {
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400727 const std::vector<std::string> servers;
728 const std::string tlsName;
729 const std::vector<std::vector<uint8_t>> tlsFingerprints;
Ben Schwartze7601812017-04-28 16:38:29 -0400730 const int expectedReturnCode;
731 } kTestData[] = {
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400732 { {"192.0.2.1"}, "", {}, 0 },
733 { {"2001:db8::2"}, "host.name", {}, 0 },
734 { {"192.0.2.3"}, "@@@@", { fp }, 0 },
735 { {"2001:db8::4"}, "", { fp }, 0 },
736 { {"192.0.*.5"}, "", {}, EINVAL },
737 { {""}, "", {}, EINVAL },
738 { {"2001:dg8::6"}, "", {}, EINVAL },
739 { {"2001:db8::c"}, "", { short_fp }, EINVAL },
740 { {"192.0.2.12"}, "", { long_fp }, EINVAL },
741 { {"2001:db8::e"}, "", { fp, fp, fp }, 0 },
742 { {"192.0.2.14"}, "", { fp, short_fp }, EINVAL },
Ben Schwartze7601812017-04-28 16:38:29 -0400743 };
744
745 for (unsigned int i = 0; i < arraysize(kTestData); i++) {
746 const auto &td = kTestData[i];
747
748 std::vector<std::string> fingerprints;
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400749 for (const auto& fingerprint : td.tlsFingerprints) {
Ben Schwartze7601812017-04-28 16:38:29 -0400750 fingerprints.push_back(base64Encode(fingerprint));
751 }
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400752 binder::Status status = mNetd->setResolverConfiguration(
753 test_netid, td.servers, test_domains, test_params,
754 true, td.tlsName, fingerprints);
Ben Schwartze7601812017-04-28 16:38:29 -0400755
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400756 if (td.expectedReturnCode == 0) {
Ben Schwartze7601812017-04-28 16:38:29 -0400757 SCOPED_TRACE(String8::format("test case %d should have passed", i));
758 SCOPED_TRACE(status.toString8());
759 EXPECT_EQ(0, status.exceptionCode());
760 } else {
761 SCOPED_TRACE(String8::format("test case %d should have failed", i));
762 EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400763 EXPECT_EQ(td.expectedReturnCode, status.serviceSpecificErrorCode());
Ben Schwartze7601812017-04-28 16:38:29 -0400764 }
Ben Schwartze7601812017-04-28 16:38:29 -0400765 }
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400766 // Ensure TLS is disabled before the start of the next test.
767 mNetd->setResolverConfiguration(
768 test_netid, kTestData[0].servers, test_domains, test_params,
769 false, "", {});
Ben Schwartze7601812017-04-28 16:38:29 -0400770}
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900771
772void expectNoTestCounterRules() {
773 for (const auto& binary : { IPTABLES_PATH, IP6TABLES_PATH }) {
774 std::string command = StringPrintf("%s -w -nvL tetherctrl_counters", binary);
775 std::string allRules = Join(runCommand(command), "\n");
776 EXPECT_EQ(std::string::npos, allRules.find("netdtest_"));
777 }
778}
779
780void addTetherCounterValues(const char *path, std::string if1, std::string if2, int byte, int pkt) {
781 runCommand(StringPrintf("%s -w -A tetherctrl_counters -i %s -o %s -j RETURN -c %d %d",
782 path, if1.c_str(), if2.c_str(), pkt, byte));
783}
784
785void delTetherCounterValues(const char *path, std::string if1, std::string if2) {
786 runCommand(StringPrintf("%s -w -D tetherctrl_counters -i %s -o %s -j RETURN",
787 path, if1.c_str(), if2.c_str()));
788 runCommand(StringPrintf("%s -w -D tetherctrl_counters -i %s -o %s -j RETURN",
789 path, if2.c_str(), if1.c_str()));
790}
791
792TEST_F(BinderTest, TestTetherGetStats) {
793 expectNoTestCounterRules();
794
795 // TODO: fold this into more comprehensive tests once we have binder RPCs for enabling and
796 // disabling tethering. We don't check the return value because these commands will fail if
797 // tethering is already enabled.
798 runCommand(StringPrintf("%s -w -N tetherctrl_counters", IPTABLES_PATH));
799 runCommand(StringPrintf("%s -w -N tetherctrl_counters", IP6TABLES_PATH));
800
801 std::string intIface1 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
802 std::string intIface2 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
803 std::string intIface3 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
804 std::string extIface1 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
805 std::string extIface2 = StringPrintf("netdtest_%u", arc4random_uniform(10000));
806
807 addTetherCounterValues(IPTABLES_PATH, intIface1, extIface1, 123, 111);
808 addTetherCounterValues(IP6TABLES_PATH, intIface1, extIface1, 456, 10);
809 addTetherCounterValues(IPTABLES_PATH, extIface1, intIface1, 321, 222);
810 addTetherCounterValues(IP6TABLES_PATH, extIface1, intIface1, 654, 20);
811 // RX is from external to internal, and TX is from internal to external.
812 // So rxBytes is 321 + 654 = 975, txBytes is 123 + 456 = 579, etc.
813 std::vector<int64_t> expected1 = { 975, 242, 579, 121 };
814
815 addTetherCounterValues(IPTABLES_PATH, intIface2, extIface2, 1000, 333);
816 addTetherCounterValues(IP6TABLES_PATH, intIface2, extIface2, 3000, 30);
817
818 addTetherCounterValues(IPTABLES_PATH, extIface2, intIface2, 2000, 444);
819 addTetherCounterValues(IP6TABLES_PATH, extIface2, intIface2, 4000, 40);
820
821 addTetherCounterValues(IP6TABLES_PATH, intIface3, extIface2, 1000, 25);
822 addTetherCounterValues(IP6TABLES_PATH, extIface2, intIface3, 2000, 35);
823 std::vector<int64_t> expected2 = { 8000, 519, 5000, 388 };
824
825 PersistableBundle stats;
826 binder::Status status = mNetd->tetherGetStats(&stats);
827 EXPECT_TRUE(status.isOk()) << "Getting tethering stats failed: " << status;
828
829 std::vector<int64_t> actual1;
830 EXPECT_TRUE(stats.getLongVector(String16(extIface1.c_str()), &actual1));
831 EXPECT_EQ(expected1, actual1);
832
833 std::vector<int64_t> actual2;
834 EXPECT_TRUE(stats.getLongVector(String16(extIface2.c_str()), &actual2));
835 EXPECT_EQ(expected2, actual2);
836
837 for (const auto& path : { IPTABLES_PATH, IP6TABLES_PATH }) {
838 delTetherCounterValues(path, intIface1, extIface1);
839 delTetherCounterValues(path, intIface2, extIface2);
840 if (path == IP6TABLES_PATH) {
841 delTetherCounterValues(path, intIface3, extIface2);
842 }
843 }
844
845 expectNoTestCounterRules();
846}