1 /*
2 * Copyright (C) 2022 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
17 #define LOG_TAG "tetheroffload_aidl_hal_test"
18
19 #include <aidl/Gtest.h>
20 #include <aidl/Vintf.h>
21 #include <aidl/android/hardware/tetheroffload/BnOffload.h>
22 #include <aidl/android/hardware/tetheroffload/BnTetheringOffloadCallback.h>
23 #include <android-base/logging.h>
24 #include <android-base/unique_fd.h>
25 #include <android/binder_manager.h>
26 #include <android/binder_process.h>
27 #include <gmock/gmock.h>
28 #include <gtest/gtest.h>
29 #include <linux/netfilter/nfnetlink.h>
30 #include <linux/netlink.h>
31 #include <linux/rtnetlink.h>
32 #include <log/log.h>
33 #include <net/if.h>
34 #include <sys/socket.h>
35
36 namespace aidl::android::hardware::tetheroffload {
37
38 namespace {
39
40 using ::android::base::unique_fd;
41 using android::hardware::tetheroffload::ForwardedStats;
42 using android::hardware::tetheroffload::IOffload;
43 using android::hardware::tetheroffload::NatTimeoutUpdate;
44 using android::hardware::tetheroffload::OffloadCallbackEvent;
45 using ::testing::AnyOf;
46 using ::testing::Eq;
47
48 const std::string TEST_IFACE = "rmnet_data0";
49 const unsigned kFd1Groups = NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY;
50 const unsigned kFd2Groups = NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY;
51
52 enum class ExpectBoolean {
53 Ignored = -1,
54 False = 0,
55 True = 1,
56 };
57
asSockaddr(const sockaddr_nl * nladdr)58 inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
59 return reinterpret_cast<const sockaddr*>(nladdr);
60 }
61
netlinkSocket(int protocol,unsigned groups)62 int netlinkSocket(int protocol, unsigned groups) {
63 unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, protocol));
64 if (s.get() < 0) {
65 return -errno;
66 }
67
68 const struct sockaddr_nl bind_addr = {
69 .nl_family = AF_NETLINK,
70 .nl_pad = 0,
71 .nl_pid = 0,
72 .nl_groups = groups,
73 };
74 if (bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
75 return -errno;
76 }
77
78 const struct sockaddr_nl kernel_addr = {
79 .nl_family = AF_NETLINK,
80 .nl_pad = 0,
81 .nl_pid = 0,
82 .nl_groups = groups,
83 };
84 if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
85 return -errno;
86 }
87
88 return s.release();
89 }
90
netlinkSocket(unsigned groups)91 int netlinkSocket(unsigned groups) {
92 return netlinkSocket(NETLINK_NETFILTER, groups);
93 }
94
95 // Check whether the specified interface is up.
interfaceIsUp(const std::string name)96 bool interfaceIsUp(const std::string name) {
97 struct ifreq ifr = {};
98 strlcpy(ifr.ifr_name, name.c_str(), sizeof(ifr.ifr_name));
99 int sock = socket(AF_INET6, SOCK_DGRAM, 0);
100 if (sock == -1) return false;
101 int ret = ioctl(sock, SIOCGIFFLAGS, &ifr, sizeof(ifr));
102 close(sock);
103 return (ret == 0) && (ifr.ifr_flags & IFF_UP);
104 }
105
106 // Callback class for both events and NAT timeout updates.
107 class TetheringOffloadCallback : public BnTetheringOffloadCallback {
108 public:
onEvent(OffloadCallbackEvent in_event)109 ndk::ScopedAStatus onEvent(OffloadCallbackEvent in_event) override {
110 auto lock = std::lock_guard{mMutex};
111 mOnEventInvoked = true;
112 mLastEvent = in_event;
113 mNotifyCv.notify_all();
114 return ndk::ScopedAStatus::ok();
115 }
116
updateTimeout(const NatTimeoutUpdate & in_params)117 ndk::ScopedAStatus updateTimeout(const NatTimeoutUpdate& in_params) override {
118 auto lock = std::lock_guard{mMutex};
119 mOnUpdateTimeoutInvoked = true;
120 mNatTimeout = in_params;
121 mNotifyCv.notify_all();
122 return ndk::ScopedAStatus::ok();
123 }
124
125 private:
126 std::mutex mMutex;
127 std::condition_variable mNotifyCv;
128 OffloadCallbackEvent mLastEvent;
129 NatTimeoutUpdate mNatTimeout;
130 bool mOnEventInvoked = false;
131 bool mOnUpdateTimeoutInvoked = false;
132 };
133
134 // The common base class for tetheroffload AIDL HAL tests.
135 class TetheroffloadAidlTestBase : public testing::TestWithParam<std::string> {
136 public:
SetUp()137 virtual void SetUp() override { getService(); }
TearDown()138 virtual void TearDown() override {
139 // For good measure, the teardown should try stopOffload() once more, since
140 // different HAL call test cycles might enter this function. Also the
141 // return code cannot be actually expected for all cases, hence ignore it.
142 stopOffload(ExpectBoolean::Ignored);
143 };
144
145 protected:
getService()146 void getService() {
147 AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
148 ASSERT_NE(binder, nullptr);
149 mOffload = IOffload::fromBinder(ndk::SpAIBinder(binder));
150 }
151
initOffload(const bool expectedResult)152 void initOffload(const bool expectedResult) {
153 unique_fd ufd1(netlinkSocket(kFd1Groups));
154 if (ufd1.get() < 0) {
155 FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
156 }
157 ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(ufd1.release());
158
159 unique_fd ufd2(netlinkSocket(kFd2Groups));
160 if (ufd2.get() < 0) {
161 FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
162 }
163 ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(ufd2.release());
164
165 mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
166 ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
167
168 ASSERT_EQ(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
169 expectedResult ? EX_NONE : EX_ILLEGAL_STATE);
170 }
171
stopOffload(const ExpectBoolean expectedResult)172 void stopOffload(const ExpectBoolean expectedResult) {
173 ndk::ScopedAStatus status = mOffload->stopOffload();
174 if (expectedResult == ExpectBoolean::Ignored) return;
175 ASSERT_EQ(status.getExceptionCode(),
176 expectedResult == ExpectBoolean::True ? EX_NONE : EX_ILLEGAL_STATE);
177 }
178
179 std::shared_ptr<IOffload> mOffload;
180 std::shared_ptr<TetheringOffloadCallback> mTetheringOffloadCallback;
181 };
182
183 // The test class for tetheroffload before initialization.
184 class TetheroffloadAidlPreInitTest : public TetheroffloadAidlTestBase {
185 public:
SetUp()186 virtual void SetUp() override { getService(); }
187 };
188
189 // The main test class for tetheroffload AIDL HAL.
190 class TetheroffloadAidlGeneralTest : public TetheroffloadAidlTestBase {
191 public:
SetUp()192 virtual void SetUp() override {
193 getService();
194 initOffload(true);
195 }
196 };
197
198 // Passing invalid file descriptor to initOffload() should return an error.
199 // Check that this occurs when both FDs are empty.
TEST_P(TetheroffloadAidlPreInitTest,TestInitOffloadInvalidFdsReturnsError)200 TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFdsReturnsError) {
201 ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(-1);
202 ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(-1);
203 mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
204 ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
205 EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
206 AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
207 }
208
209 // Passing invalid file descriptor to initOffload() should return an error.
210 // Check that this occurs when FD1 is empty.
TEST_P(TetheroffloadAidlPreInitTest,TestInitOffloadInvalidFd1ReturnsError)211 TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFd1ReturnsError) {
212 ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(-1);
213 unique_fd ufd2(netlinkSocket(kFd2Groups));
214 if (ufd2.get() < 0) {
215 FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
216 }
217 ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(ufd2.release());
218 mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
219 ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
220 EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
221 AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
222 }
223
224 // Passing invalid file descriptor to initOffload() should return an error.
225 // Check that this occurs when FD2 is empty.
TEST_P(TetheroffloadAidlPreInitTest,TestInitOffloadInvalidFd2ReturnsError)226 TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFd2ReturnsError) {
227 unique_fd ufd1(netlinkSocket(kFd1Groups));
228 if (ufd1.get() < 0) {
229 FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
230 }
231 ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(ufd1.release());
232 ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(-1);
233 mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
234 ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
235 EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
236 AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
237 }
238
239 // Call initOffload() multiple times. Check that non-first initOffload() calls return error.
TEST_P(TetheroffloadAidlPreInitTest,AdditionalInitsWithoutStopReturnError)240 TEST_P(TetheroffloadAidlPreInitTest, AdditionalInitsWithoutStopReturnError) {
241 initOffload(true);
242 initOffload(false);
243 initOffload(false);
244 initOffload(false);
245 }
246
247 // Check that calling stopOffload() without first having called initOffload() returns error.
TEST_P(TetheroffloadAidlPreInitTest,MultipleStopsWithoutInitReturnError)248 TEST_P(TetheroffloadAidlPreInitTest, MultipleStopsWithoutInitReturnError) {
249 stopOffload(ExpectBoolean::False);
250 stopOffload(ExpectBoolean::False);
251 stopOffload(ExpectBoolean::False);
252 }
253
254 // Check that calling stopOffload() after a complete init/stop cycle returns error.
TEST_P(TetheroffloadAidlPreInitTest,AdditionalStopsWithInitReturnError)255 TEST_P(TetheroffloadAidlPreInitTest, AdditionalStopsWithInitReturnError) {
256 initOffload(true);
257 // Call setUpstreamParameters() so that "offload" can be reasonably said
258 // to be both requested and operational.
259 const std::string iface(TEST_IFACE);
260 const std::string v4Addr("192.0.0.2");
261 const std::string v4Gw("192.0.0.1");
262 const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
263 auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
264 EXPECT_TRUE(ret.isOk()) << ret;
265 if (!interfaceIsUp(TEST_IFACE)) {
266 return;
267 }
268 SCOPED_TRACE("Expecting stopOffload to succeed");
269 stopOffload(ExpectBoolean::True); // balance out initOffload(true)
270 SCOPED_TRACE("Expecting stopOffload to fail the first time");
271 stopOffload(ExpectBoolean::False);
272 SCOPED_TRACE("Expecting stopOffload to fail the second time");
273 stopOffload(ExpectBoolean::False);
274 }
275
276 // Check that calling setLocalPrefixes() without first having called initOffload() returns error.
TEST_P(TetheroffloadAidlPreInitTest,SetLocalPrefixesWithoutInitReturnsError)277 TEST_P(TetheroffloadAidlPreInitTest, SetLocalPrefixesWithoutInitReturnsError) {
278 const std::vector<std::string> prefixes{std::string("2001:db8::/64")};
279 EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
280 }
281
282 // Check that calling getForwardedStats() without first having called initOffload()
283 // returns zero bytes statistics.
TEST_P(TetheroffloadAidlPreInitTest,GetForwardedStatsWithoutInitReturnsZeroValues)284 TEST_P(TetheroffloadAidlPreInitTest, GetForwardedStatsWithoutInitReturnsZeroValues) {
285 const std::string upstream(TEST_IFACE);
286 ForwardedStats stats;
287 auto ret = mOffload->getForwardedStats(upstream, &stats);
288 EXPECT_TRUE(ret.isOk()) << ret;
289 EXPECT_EQ(0ULL, stats.rxBytes);
290 EXPECT_EQ(0ULL, stats.txBytes);
291 }
292
293 // Check that calling setDataWarningAndLimit() without first having called initOffload() returns
294 // error.
TEST_P(TetheroffloadAidlPreInitTest,SetDataWarningAndLimitWithoutInitReturnsError)295 TEST_P(TetheroffloadAidlPreInitTest, SetDataWarningAndLimitWithoutInitReturnsError) {
296 const std::string upstream(TEST_IFACE);
297 const int64_t warning = 5000LL;
298 const int64_t limit = 5000LL;
299 EXPECT_EQ(EX_ILLEGAL_STATE,
300 mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
301 }
302
303 // Check that calling setUpstreamParameters() without first having called initOffload()
304 // returns error.
TEST_P(TetheroffloadAidlPreInitTest,SetUpstreamParametersWithoutInitReturnsError)305 TEST_P(TetheroffloadAidlPreInitTest, SetUpstreamParametersWithoutInitReturnsError) {
306 const std::string iface(TEST_IFACE);
307 const std::string v4Addr("192.0.2.0/24");
308 const std::string v4Gw("192.0.2.1");
309 const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
310 EXPECT_EQ(EX_ILLEGAL_STATE,
311 mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
312 }
313
314 // Check that calling addDownstream() with an IPv4 prefix without first having called
315 // initOffload() returns error.
TEST_P(TetheroffloadAidlPreInitTest,AddIPv4DownstreamWithoutInitReturnsError)316 TEST_P(TetheroffloadAidlPreInitTest, AddIPv4DownstreamWithoutInitReturnsError) {
317 const std::string iface(TEST_IFACE);
318 const std::string prefix("192.0.2.0/24");
319 EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->addDownstream(iface, prefix).getExceptionCode());
320 }
321
322 // Check that calling addDownstream() with an IPv6 prefix without first having called
323 // initOffload() returns error.
TEST_P(TetheroffloadAidlPreInitTest,AddIPv6DownstreamWithoutInitReturnsError)324 TEST_P(TetheroffloadAidlPreInitTest, AddIPv6DownstreamWithoutInitReturnsError) {
325 const std::string iface(TEST_IFACE);
326 const std::string prefix("2001:db8::/64");
327 EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->addDownstream(iface, prefix).getExceptionCode());
328 }
329
330 // Check that calling removeDownstream() with an IPv4 prefix without first having called
331 // initOffload() returns error.
TEST_P(TetheroffloadAidlPreInitTest,RemoveIPv4DownstreamWithoutInitReturnsError)332 TEST_P(TetheroffloadAidlPreInitTest, RemoveIPv4DownstreamWithoutInitReturnsError) {
333 const std::string iface(TEST_IFACE);
334 const std::string prefix("192.0.2.0/24");
335 EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->removeDownstream(iface, prefix).getExceptionCode());
336 }
337
338 // Check that calling removeDownstream() with an IPv6 prefix without first having called
339 // initOffload() returns error.
TEST_P(TetheroffloadAidlPreInitTest,RemoveIPv6DownstreamWithoutInitReturnsError)340 TEST_P(TetheroffloadAidlPreInitTest, RemoveIPv6DownstreamWithoutInitReturnsError) {
341 const std::string iface(TEST_IFACE);
342 const std::string prefix("2001:db8::/64");
343 EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->removeDownstream(iface, prefix).getExceptionCode());
344 }
345
346 /*
347 * Tests for IOffload::setLocalPrefixes().
348 */
349
350 // Test setLocalPrefixes() rejects an IPv4 address.
TEST_P(TetheroffloadAidlGeneralTest,SetLocalPrefixesIPv4AddressFails)351 TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv4AddressFails) {
352 const std::vector<std::string> prefixes{std::string("192.0.2.1")};
353 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
354 }
355
356 // Test setLocalPrefixes() rejects an IPv6 address.
TEST_P(TetheroffloadAidlGeneralTest,SetLocalPrefixesIPv6AddressFails)357 TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv6AddressFails) {
358 const std::vector<std::string> prefixes{std::string("fe80::1")};
359 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
360 }
361
362 // Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
TEST_P(TetheroffloadAidlGeneralTest,SetLocalPrefixesIPv4v6PrefixesOk)363 TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv4v6PrefixesOk) {
364 const std::vector<std::string> prefixes{std::string("192.0.2.0/24"), std::string("fe80::/64")};
365 auto ret = mOffload->setLocalPrefixes(prefixes);
366 EXPECT_TRUE(ret.isOk()) << ret;
367 }
368
369 // Test that setLocalPrefixes() fails given empty input. There is always
370 // a non-empty set of local prefixes; when all networking interfaces are down
371 // we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
TEST_P(TetheroffloadAidlGeneralTest,SetLocalPrefixesEmptyFails)372 TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesEmptyFails) {
373 const std::vector<std::string> prefixes{};
374 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
375 }
376
377 // Test setLocalPrefixes() fails on incorrectly formed input strings.
TEST_P(TetheroffloadAidlGeneralTest,SetLocalPrefixesInvalidFails)378 TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesInvalidFails) {
379 const std::vector<std::string> prefixes{std::string("192.0.2.0/24"), std::string("invalid")};
380 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
381 }
382
383 /*
384 * Tests for IOffload::getForwardedStats().
385 */
386
387 // Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
TEST_P(TetheroffloadAidlGeneralTest,GetForwardedStatsInvalidUpstreamIface)388 TEST_P(TetheroffloadAidlGeneralTest, GetForwardedStatsInvalidUpstreamIface) {
389 const std::string upstream("invalid");
390 ForwardedStats stats;
391 auto ret = mOffload->getForwardedStats(upstream, &stats);
392 EXPECT_TRUE(ret.isOk()) << ret;
393 EXPECT_EQ(0ULL, stats.rxBytes);
394 EXPECT_EQ(0ULL, stats.txBytes);
395 }
396
397 // TEST_IFACE is presumed to exist on the device and be up. No packets
398 // are ever actually caused to be forwarded.
TEST_P(TetheroffloadAidlGeneralTest,GetForwardedStatsDummyIface)399 TEST_P(TetheroffloadAidlGeneralTest, GetForwardedStatsDummyIface) {
400 const std::string upstream(TEST_IFACE);
401 ForwardedStats stats;
402 auto ret = mOffload->getForwardedStats(upstream, &stats);
403 EXPECT_TRUE(ret.isOk()) << ret;
404 EXPECT_EQ(0ULL, stats.rxBytes);
405 EXPECT_EQ(0ULL, stats.txBytes);
406 }
407
408 /*
409 * Tests for IOffload::setDataWarningAndLimit().
410 */
411
412 // Test that setDataWarningAndLimit() for an empty interface name fails.
TEST_P(TetheroffloadAidlGeneralTest,SetDataWarningAndLimitEmptyUpstreamIfaceFails)413 TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitEmptyUpstreamIfaceFails) {
414 const std::string upstream("");
415 const int64_t warning = 12345LL;
416 const int64_t limit = 67890LL;
417 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
418 mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
419 }
420
421 // TEST_IFACE is presumed to exist on the device and be up. No packets
422 // are ever actually caused to be forwarded.
TEST_P(TetheroffloadAidlGeneralTest,SetDataWarningAndLimitNonZeroOk)423 TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitNonZeroOk) {
424 const std::string upstream(TEST_IFACE);
425 const int64_t warning = 4000LL;
426 const int64_t limit = 5000LL;
427 auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
428 EXPECT_TRUE(ret.isOk()) << ret;
429 }
430
431 // TEST_IFACE is presumed to exist on the device and be up. No packets
432 // are ever actually caused to be forwarded.
TEST_P(TetheroffloadAidlGeneralTest,SetDataWarningAndLimitZeroOk)433 TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitZeroOk) {
434 const std::string upstream(TEST_IFACE);
435 const int64_t warning = 0LL;
436 const int64_t limit = 0LL;
437 auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
438 EXPECT_TRUE(ret.isOk()) << ret;
439 }
440
441 // TEST_IFACE is presumed to exist on the device and be up. No packets
442 // are ever actually caused to be forwarded.
TEST_P(TetheroffloadAidlGeneralTest,SetDataWarningAndLimitUnlimitedWarningOk)443 TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitUnlimitedWarningOk) {
444 const std::string upstream(TEST_IFACE);
445 const int64_t warning = LLONG_MAX;
446 const int64_t limit = 5000LL;
447 auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
448 EXPECT_TRUE(ret.isOk()) << ret;
449 }
450
451 // Test that setDataWarningAndLimit() with negative thresholds fails.
TEST_P(TetheroffloadAidlGeneralTest,SetDataWarningAndLimitNegativeFails)452 TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitNegativeFails) {
453 const std::string upstream(TEST_IFACE);
454 const int64_t warning = -1LL;
455 const int64_t limit = -1LL;
456 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
457 mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
458 }
459
460 /*
461 * Tests for IOffload::setUpstreamParameters().
462 */
463
464 // TEST_IFACE is presumed to exist on the device and be up. No packets
465 // are ever actually caused to be forwarded.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersIPv6OnlyOk)466 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv6OnlyOk) {
467 const std::string iface(TEST_IFACE);
468 const std::string v4Addr("");
469 const std::string v4Gw("");
470 const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
471 auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
472 EXPECT_TRUE(ret.isOk()) << ret;
473 }
474
475 // TEST_IFACE is presumed to exist on the device and be up. No packets
476 // are ever actually caused to be forwarded.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersAlternateIPv6OnlyOk)477 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
478 const std::string iface(TEST_IFACE);
479 const std::string v4Addr("");
480 const std::string v4Gw("");
481 const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:3")};
482 auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
483 EXPECT_TRUE(ret.isOk()) << ret;
484 }
485
486 // TEST_IFACE is presumed to exist on the device and be up. No packets
487 // are ever actually caused to be forwarded.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersIPv4OnlyOk)488 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv4OnlyOk) {
489 const std::string iface(TEST_IFACE);
490 const std::string v4Addr("192.0.2.2");
491 const std::string v4Gw("192.0.2.1");
492 const std::vector<std::string> v6Gws{};
493 auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
494 EXPECT_TRUE(ret.isOk()) << ret;
495 }
496
497 // TEST_IFACE is presumed to exist on the device and be up. No packets
498 // are ever actually caused to be forwarded.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersIPv4v6Ok)499 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv4v6Ok) {
500 const std::string iface(TEST_IFACE);
501 const std::string v4Addr("192.0.2.2");
502 const std::string v4Gw("192.0.2.1");
503 const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
504 auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
505 EXPECT_TRUE(ret.isOk()) << ret;
506 }
507
508 // Test that setUpstreamParameters() fails when all parameters are empty.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersEmptyFails)509 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersEmptyFails) {
510 const std::string iface("");
511 const std::string v4Addr("");
512 const std::string v4Gw("");
513 const std::vector<std::string> v6Gws{};
514 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
515 mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
516 }
517
518 // Test that setUpstreamParameters() fails when given empty or non-existent interface names.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersBogusIfaceFails)519 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersBogusIfaceFails) {
520 const std::string v4Addr("192.0.2.2");
521 const std::string v4Gw("192.0.2.1");
522 const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
523 for (const auto& bogus : {"", "invalid"}) {
524 SCOPED_TRACE(testing::Message() << "upstream: " << bogus);
525 const std::string iface(bogus);
526 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
527 mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
528 }
529 }
530
531 // Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersInvalidIPv4AddrFails)532 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersInvalidIPv4AddrFails) {
533 const std::string iface(TEST_IFACE);
534 const std::string v4Gw("192.0.2.1");
535 const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
536 for (const auto& bogus : {"invalid", "192.0.2"}) {
537 SCOPED_TRACE(testing::Message() << "v4addr: " << bogus);
538 const std::string v4Addr(bogus);
539 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
540 mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
541 }
542 }
543
544 // Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersInvalidIPv4GatewayFails)545 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
546 const std::string iface(TEST_IFACE);
547 const std::string v4Addr("192.0.2.2");
548 const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
549 for (const auto& bogus : {"invalid", "192.0.2"}) {
550 SCOPED_TRACE(testing::Message() << "v4gateway: " << bogus);
551 const std::string v4Gw(bogus);
552 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
553 mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
554 }
555 }
556
557 // Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
TEST_P(TetheroffloadAidlGeneralTest,SetUpstreamParametersBadIPv6GatewaysFail)558 TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersBadIPv6GatewaysFail) {
559 const std::string iface(TEST_IFACE);
560 const std::string v4Addr("192.0.2.2");
561 const std::string v4Gw("192.0.2.1");
562 for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
563 SCOPED_TRACE(testing::Message() << "v6gateway: " << bogus);
564 const std::vector<std::string> v6Gws{std::string("fe80::1"), std::string(bogus)};
565 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
566 mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
567 }
568 }
569
570 /*
571 * Tests for IOffload::addDownstream().
572 */
573
574 // Test addDownstream() works given an IPv4 prefix.
TEST_P(TetheroffloadAidlGeneralTest,AddDownstreamIPv4)575 TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamIPv4) {
576 const std::string iface("dummy0");
577 const std::string prefix("192.0.2.0/24");
578 auto ret = mOffload->addDownstream(iface, prefix);
579 EXPECT_TRUE(ret.isOk()) << ret;
580 }
581
582 // Test addDownstream() works given an IPv6 prefix.
TEST_P(TetheroffloadAidlGeneralTest,AddDownstreamIPv6)583 TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamIPv6) {
584 const std::string iface("dummy0");
585 const std::string prefix("2001:db8::/64");
586 auto ret = mOffload->addDownstream(iface, prefix);
587 EXPECT_TRUE(ret.isOk()) << ret;
588 }
589
590 // Test addDownstream() fails given all empty parameters.
TEST_P(TetheroffloadAidlGeneralTest,AddDownstreamEmptyFails)591 TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamEmptyFails) {
592 const std::string iface("");
593 const std::string prefix("");
594 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
595 }
596
597 // Test addDownstream() fails given empty or non-existent interface names.
TEST_P(TetheroffloadAidlGeneralTest,AddDownstreamInvalidIfaceFails)598 TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamInvalidIfaceFails) {
599 const std::string prefix("192.0.2.0/24");
600 for (const auto& bogus : {"", "invalid"}) {
601 SCOPED_TRACE(testing::Message() << "iface: " << bogus);
602 const std::string iface(bogus);
603 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
604 }
605 }
606
607 // Test addDownstream() fails given unparseable prefix arguments.
TEST_P(TetheroffloadAidlGeneralTest,AddDownstreamBogusPrefixFails)608 TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamBogusPrefixFails) {
609 const std::string iface("dummy0");
610 for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
611 SCOPED_TRACE(testing::Message() << "prefix: " << bogus);
612 const std::string prefix(bogus);
613 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
614 }
615 }
616
617 /*
618 * Tests for IOffload::removeDownstream().
619 */
620
621 // Test removeDownstream() works given an IPv4 prefix.
TEST_P(TetheroffloadAidlGeneralTest,RemoveDownstreamIPv4)622 TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamIPv4) {
623 const std::string iface("dummy0");
624 const std::string prefix("192.0.2.0/24");
625 // First add the downstream, otherwise removeDownstream logic can reasonably
626 // return error for downstreams not previously added.
627 auto ret = mOffload->addDownstream(iface, prefix);
628 EXPECT_TRUE(ret.isOk()) << ret;
629 ret = mOffload->removeDownstream(iface, prefix);
630 EXPECT_TRUE(ret.isOk()) << ret;
631 }
632
633 // Test removeDownstream() works given an IPv6 prefix.
TEST_P(TetheroffloadAidlGeneralTest,RemoveDownstreamIPv6)634 TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamIPv6) {
635 const std::string iface("dummy0");
636 const std::string prefix("2001:db8::/64");
637 // First add the downstream, otherwise removeDownstream logic can reasonably
638 // return error for downstreams not previously added.
639 auto ret = mOffload->addDownstream(iface, prefix);
640 EXPECT_TRUE(ret.isOk()) << ret;
641 ret = mOffload->removeDownstream(iface, prefix);
642 EXPECT_TRUE(ret.isOk()) << ret;
643 }
644
645 // Test removeDownstream() fails given all empty parameters.
TEST_P(TetheroffloadAidlGeneralTest,RemoveDownstreamEmptyFails)646 TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamEmptyFails) {
647 const std::string iface("");
648 const std::string prefix("");
649 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->removeDownstream(iface, prefix).getExceptionCode());
650 }
651
652 // Test removeDownstream() fails given empty or non-existent interface names.
TEST_P(TetheroffloadAidlGeneralTest,RemoveDownstreamBogusIfaceFails)653 TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamBogusIfaceFails) {
654 const std::string prefix("192.0.2.0/24");
655 for (const auto& bogus : {"", "invalid"}) {
656 SCOPED_TRACE(testing::Message() << "iface: " << bogus);
657 const std::string iface(bogus);
658 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
659 mOffload->removeDownstream(iface, prefix).getExceptionCode());
660 }
661 }
662
663 // Test removeDownstream() fails given unparseable prefix arguments.
TEST_P(TetheroffloadAidlGeneralTest,RemoveDownstreamBogusPrefixFails)664 TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamBogusPrefixFails) {
665 const std::string iface("dummy0");
666 for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
667 SCOPED_TRACE(testing::Message() << "prefix: " << bogus);
668 const std::string prefix(bogus);
669 EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
670 mOffload->removeDownstream(iface, prefix).getExceptionCode());
671 }
672 }
673
674 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlTestBase);
675 INSTANTIATE_TEST_SUITE_P(
676 IOffload, TetheroffloadAidlTestBase,
677 testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
678 ::android::PrintInstanceNameToString);
679
680 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlPreInitTest);
681 INSTANTIATE_TEST_SUITE_P(
682 IOffload, TetheroffloadAidlPreInitTest,
683 testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
684 ::android::PrintInstanceNameToString);
685
686 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlGeneralTest);
687 INSTANTIATE_TEST_SUITE_P(
688 IOffload, TetheroffloadAidlGeneralTest,
689 testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
690 ::android::PrintInstanceNameToString);
691
692 } // namespace
693 } // namespace aidl::android::hardware::tetheroffload
694
main(int argc,char ** argv)695 int main(int argc, char** argv) {
696 ::testing::InitGoogleTest(&argc, argv);
697 ABinderProcess_setThreadPoolMaxThreadCount(1);
698 ABinderProcess_startThreadPool();
699 return RUN_ALL_TESTS();
700 }
701