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