1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "VtsOffloadControlV1_0TargetTest"
18 
19 #include <VtsHalHidlTargetCallbackBase.h>
20 #include <android-base/stringprintf.h>
21 #include <android-base/unique_fd.h>
22 #include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
23 #include <android/hardware/tetheroffload/control/1.0/IOffloadControl.h>
24 #include <android/hardware/tetheroffload/control/1.0/types.h>
25 #include <gtest/gtest.h>
26 #include <hidl/GtestPrinter.h>
27 #include <hidl/ServiceManagement.h>
28 #include <linux/netfilter/nfnetlink.h>
29 #include <linux/netlink.h>
30 #include <log/log.h>
31 #include <net/if.h>
32 #include <sys/socket.h>
33 #include <unistd.h>
34 #include <set>
35 
36 using android::base::StringPrintf;
37 using android::base::unique_fd;
38 using android::hardware::hidl_handle;
39 using android::hardware::hidl_string;
40 using android::hardware::hidl_vec;
41 using android::hardware::Return;
42 using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
43 using android::hardware::tetheroffload::control::V1_0::IOffloadControl;
44 using android::hardware::tetheroffload::control::V1_0::IPv4AddrPortPair;
45 using android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
46 using android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent;
47 using android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate;
48 using android::hardware::tetheroffload::control::V1_0::NetworkProtocol;
49 using android::hardware::Void;
50 using android::sp;
51 
52 enum class ExpectBoolean {
53     Ignored = -1,
54     False = 0,
55     True = 1,
56 };
57 
58 constexpr const char* TEST_IFACE = "rmnet_data0";
59 
60 // We use #defines here so as to get local lamba captures and error message line numbers
61 #define ASSERT_TRUE_CALLBACK                                                    \
62     [&](bool success, std::string errMsg) {                                     \
63         std::string msg = StringPrintf("unexpected error: %s", errMsg.c_str()); \
64         ASSERT_TRUE(success) << msg;                                            \
65     }
66 
67 #define ASSERT_FALSE_CALLBACK                                                 \
68     [&](bool success, std::string errMsg) {                                   \
69         std::string msg = StringPrintf("expected error: %s", errMsg.c_str()); \
70         ASSERT_FALSE(success) << msg;                                         \
71     }
72 
73 #define ASSERT_ZERO_BYTES_CALLBACK            \
74     [&](uint64_t rxBytes, uint64_t txBytes) { \
75         EXPECT_EQ(0ULL, rxBytes);             \
76         EXPECT_EQ(0ULL, txBytes);             \
77     }
78 
asSockaddr(const sockaddr_nl * nladdr)79 inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
80     return reinterpret_cast<const sockaddr*>(nladdr);
81 }
82 
conntrackSocket(unsigned groups)83 int conntrackSocket(unsigned groups) {
84     unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER));
85     if (s.get() < 0) {
86         return -errno;
87     }
88 
89     const struct sockaddr_nl bind_addr = {
90         .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
91     };
92     if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) < 0) {
93         return -errno;
94     }
95 
96     const struct sockaddr_nl kernel_addr = {
97         .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
98     };
99     if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
100         return -errno;
101     }
102 
103     return s.release();
104 }
105 
106 constexpr char kCallbackOnEvent[] = "onEvent";
107 constexpr char kCallbackUpdateTimeout[] = "updateTimeout";
108 
109 class TetheringOffloadCallbackArgs {
110    public:
111     OffloadCallbackEvent last_event;
112     NatTimeoutUpdate last_params;
113 };
114 
115 class OffloadControlHidlTestBase
116     : public testing::TestWithParam<std::tuple<std::string, std::string>> {
117    public:
SetUp()118     virtual void SetUp() override {
119         setupConfigHal();
120         prepareControlHal();
121     }
122 
TearDown()123     virtual void TearDown() override {
124         // For good measure, we should try stopOffload() once more. Since we
125         // don't know where we are in HAL call test cycle we don't know what
126         // return code to actually expect, so we just ignore it.
127         stopOffload(ExpectBoolean::Ignored);
128     }
129 
130     // The IOffloadConfig HAL is tested more thoroughly elsewhere. He we just
131     // setup everything correctly and verify basic readiness.
setupConfigHal()132     void setupConfigHal() {
133         config = IOffloadConfig::getService(std::get<0>(GetParam()));
134         ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
135 
136         unique_fd fd1(conntrackSocket(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY));
137         if (fd1.get() < 0) {
138             ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
139             FAIL();
140         }
141         native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
142         nativeHandle1->data[0] = fd1.release();
143         hidl_handle h1;
144         h1.setTo(nativeHandle1, true);
145 
146         unique_fd fd2(conntrackSocket(NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY));
147         if (fd2.get() < 0) {
148             ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
149             FAIL();
150         }
151         native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
152         nativeHandle2->data[0] = fd2.release();
153         hidl_handle h2;
154         h2.setTo(nativeHandle2, true);
155 
156         const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
157         ASSERT_TRUE(ret.isOk());
158     }
159 
prepareControlHal()160     void prepareControlHal() {
161         control = IOffloadControl::getService(std::get<1>(GetParam()));
162         ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
163 
164         control_cb = new TetheringOffloadCallback();
165         ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback";
166     }
167 
initOffload(const bool expected_result)168     void initOffload(const bool expected_result) {
169         auto init_cb = [&](bool success, std::string errMsg) {
170             std::string msg = StringPrintf("Unexpectedly %s to init offload: %s",
171                                            success ? "succeeded" : "failed", errMsg.c_str());
172             ASSERT_EQ(expected_result, success) << msg;
173         };
174         const Return<void> ret = control->initOffload(control_cb, init_cb);
175         ASSERT_TRUE(ret.isOk());
176     }
177 
setupControlHal()178     void setupControlHal() {
179         prepareControlHal();
180         initOffload(true);
181     }
182 
stopOffload(const ExpectBoolean value)183     void stopOffload(const ExpectBoolean value) {
184         auto cb = [&](bool success, const hidl_string& errMsg) {
185             switch (value) {
186                 case ExpectBoolean::False:
187                     ASSERT_EQ(false, success) << "Unexpectedly able to stop offload: " << errMsg;
188                     break;
189                 case ExpectBoolean::True:
190                     ASSERT_EQ(true, success) << "Unexpectedly failed to stop offload: " << errMsg;
191                     break;
192                 case ExpectBoolean::Ignored:
193                     break;
194             }
195         };
196         const Return<void> ret = control->stopOffload(cb);
197         ASSERT_TRUE(ret.isOk());
198     }
199 
200     // Callback class for both events and NAT timeout updates.
201     class TetheringOffloadCallback
202         : public testing::VtsHalHidlTargetCallbackBase<TetheringOffloadCallbackArgs>,
203           public ITetheringOffloadCallback {
204        public:
205         TetheringOffloadCallback() = default;
206         virtual ~TetheringOffloadCallback() = default;
207 
onEvent(OffloadCallbackEvent event)208         Return<void> onEvent(OffloadCallbackEvent event) override {
209             const TetheringOffloadCallbackArgs args{.last_event = event};
210             NotifyFromCallback(kCallbackOnEvent, args);
211             return Void();
212         };
213 
updateTimeout(const NatTimeoutUpdate & params)214         Return<void> updateTimeout(const NatTimeoutUpdate& params) override {
215             const TetheringOffloadCallbackArgs args{.last_params = params};
216             NotifyFromCallback(kCallbackUpdateTimeout, args);
217             return Void();
218         };
219     };
220 
221     sp<IOffloadConfig> config;
222     sp<IOffloadControl> control;
223     sp<TetheringOffloadCallback> control_cb;
224 };
225 
226 // Call initOffload() multiple times. Check that non-first initOffload() calls return false.
TEST_P(OffloadControlHidlTestBase,AdditionalInitsWithoutStopReturnFalse)227 TEST_P(OffloadControlHidlTestBase, AdditionalInitsWithoutStopReturnFalse) {
228     initOffload(true);
229     initOffload(false);
230     initOffload(false);
231     initOffload(false);
232 }
233 
234 // Check that calling stopOffload() without first having called initOffload() returns false.
TEST_P(OffloadControlHidlTestBase,MultipleStopsWithoutInitReturnFalse)235 TEST_P(OffloadControlHidlTestBase, MultipleStopsWithoutInitReturnFalse) {
236     stopOffload(ExpectBoolean::False);
237     stopOffload(ExpectBoolean::False);
238     stopOffload(ExpectBoolean::False);
239 }
240 
241 // Check whether the specified interface is up.
interfaceIsUp(const char * name)242 bool interfaceIsUp(const char* name) {
243     if (name == nullptr) return false;
244     struct ifreq ifr = {};
245     strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
246     int sock = socket(AF_INET6, SOCK_DGRAM, 0);
247     if (sock == -1) return false;
248     int ret = ioctl(sock, SIOCGIFFLAGS, &ifr, sizeof(ifr));
249     close(sock);
250     return (ret == 0) && (ifr.ifr_flags & IFF_UP);
251 }
252 
253 // Check that calling stopOffload() after a complete init/stop cycle returns false.
TEST_P(OffloadControlHidlTestBase,AdditionalStopsWithInitReturnFalse)254 TEST_P(OffloadControlHidlTestBase, AdditionalStopsWithInitReturnFalse) {
255     initOffload(true);
256     // Call setUpstreamParameters() so that "offload" can be reasonably said
257     // to be both requested and operational.
258     const hidl_string v4Addr("192.0.0.2");
259     const hidl_string v4Gw("192.0.0.1");
260     const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
261     const Return<void> upstream =
262         control->setUpstreamParameters(TEST_IFACE, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
263     EXPECT_TRUE(upstream.isOk());
264     if (!interfaceIsUp(TEST_IFACE)) {
265         return;
266     }
267     SCOPED_TRACE("Expecting stopOffload to succeed");
268     stopOffload(ExpectBoolean::Ignored);  // balance out initOffload(true)
269     SCOPED_TRACE("Expecting stopOffload to fail the first time");
270     stopOffload(ExpectBoolean::False);
271     SCOPED_TRACE("Expecting stopOffload to fail the second time");
272     stopOffload(ExpectBoolean::False);
273 }
274 
275 // Check that calling setLocalPrefixes() without first having called initOffload() returns false.
TEST_P(OffloadControlHidlTestBase,SetLocalPrefixesWithoutInitReturnsFalse)276 TEST_P(OffloadControlHidlTestBase, SetLocalPrefixesWithoutInitReturnsFalse) {
277     const vector<hidl_string> prefixes{hidl_string("2001:db8::/64")};
278     const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
279     EXPECT_TRUE(ret.isOk());
280 }
281 
282 // Check that calling getForwardedStats() without first having called initOffload()
283 // returns zero bytes statistics.
TEST_P(OffloadControlHidlTestBase,GetForwardedStatsWithoutInitReturnsZeroValues)284 TEST_P(OffloadControlHidlTestBase, GetForwardedStatsWithoutInitReturnsZeroValues) {
285     const hidl_string upstream(TEST_IFACE);
286     const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
287     EXPECT_TRUE(ret.isOk());
288 }
289 
290 // Check that calling setDataLimit() without first having called initOffload() returns false.
TEST_P(OffloadControlHidlTestBase,SetDataLimitWithoutInitReturnsFalse)291 TEST_P(OffloadControlHidlTestBase, SetDataLimitWithoutInitReturnsFalse) {
292     const hidl_string upstream(TEST_IFACE);
293     const uint64_t limit = 5000ULL;
294     const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
295     EXPECT_TRUE(ret.isOk());
296 }
297 
298 // Check that calling setUpstreamParameters() without first having called initOffload()
299 // returns false.
TEST_P(OffloadControlHidlTestBase,SetUpstreamParametersWithoutInitReturnsFalse)300 TEST_P(OffloadControlHidlTestBase, SetUpstreamParametersWithoutInitReturnsFalse) {
301     const hidl_string iface(TEST_IFACE);
302     const hidl_string v4Addr("192.0.2.0/24");
303     const hidl_string v4Gw("192.0.2.1");
304     const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
305     const Return<void> ret =
306         control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
307     EXPECT_TRUE(ret.isOk());
308 }
309 
310 // Check that calling addDownstream() with an IPv4 prefix without first having called
311 // initOffload() returns false.
TEST_P(OffloadControlHidlTestBase,AddIPv4DownstreamWithoutInitReturnsFalse)312 TEST_P(OffloadControlHidlTestBase, AddIPv4DownstreamWithoutInitReturnsFalse) {
313     const hidl_string iface(TEST_IFACE);
314     const hidl_string prefix("192.0.2.0/24");
315     const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
316     EXPECT_TRUE(ret.isOk());
317 }
318 
319 // Check that calling addDownstream() with an IPv6 prefix without first having called
320 // initOffload() returns false.
TEST_P(OffloadControlHidlTestBase,AddIPv6DownstreamWithoutInitReturnsFalse)321 TEST_P(OffloadControlHidlTestBase, AddIPv6DownstreamWithoutInitReturnsFalse) {
322     const hidl_string iface(TEST_IFACE);
323     const hidl_string prefix("2001:db8::/64");
324     const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
325     EXPECT_TRUE(ret.isOk());
326 }
327 
328 // Check that calling removeDownstream() with an IPv4 prefix without first having called
329 // initOffload() returns false.
TEST_P(OffloadControlHidlTestBase,RemoveIPv4DownstreamWithoutInitReturnsFalse)330 TEST_P(OffloadControlHidlTestBase, RemoveIPv4DownstreamWithoutInitReturnsFalse) {
331     const hidl_string iface(TEST_IFACE);
332     const hidl_string prefix("192.0.2.0/24");
333     const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
334     EXPECT_TRUE(ret.isOk());
335 }
336 
337 // Check that calling removeDownstream() with an IPv6 prefix without first having called
338 // initOffload() returns false.
TEST_P(OffloadControlHidlTestBase,RemoveIPv6DownstreamWithoutInitReturnsFalse)339 TEST_P(OffloadControlHidlTestBase, RemoveIPv6DownstreamWithoutInitReturnsFalse) {
340     const hidl_string iface(TEST_IFACE);
341     const hidl_string prefix("2001:db8::/64");
342     const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
343     EXPECT_TRUE(ret.isOk());
344 }
345 
346 class OffloadControlHidlTest : public OffloadControlHidlTestBase {
347    public:
SetUp()348     virtual void SetUp() override {
349         setupConfigHal();
350         setupControlHal();
351     }
352 
TearDown()353     virtual void TearDown() override {
354         // For good measure, we should try stopOffload() once more. Since we
355         // don't know where we are in HAL call test cycle we don't know what
356         // return code to actually expect, so we just ignore it.
357         stopOffload(ExpectBoolean::Ignored);
358     }
359 };
360 
361 /*
362  * Tests for IOffloadControl::setLocalPrefixes().
363  */
364 
365 // Test setLocalPrefixes() accepts an IPv4 address.
TEST_P(OffloadControlHidlTest,SetLocalPrefixesIPv4AddressOk)366 TEST_P(OffloadControlHidlTest, SetLocalPrefixesIPv4AddressOk) {
367     const vector<hidl_string> prefixes{hidl_string("192.0.2.1")};
368     const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
369     EXPECT_TRUE(ret.isOk());
370 }
371 
372 // Test setLocalPrefixes() accepts an IPv6 address.
TEST_P(OffloadControlHidlTest,SetLocalPrefixesIPv6AddressOk)373 TEST_P(OffloadControlHidlTest, SetLocalPrefixesIPv6AddressOk) {
374     const vector<hidl_string> prefixes{hidl_string("fe80::1")};
375     const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
376     EXPECT_TRUE(ret.isOk());
377 }
378 
379 // Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
TEST_P(OffloadControlHidlTest,SetLocalPrefixesIPv4v6PrefixesOk)380 TEST_P(OffloadControlHidlTest, SetLocalPrefixesIPv4v6PrefixesOk) {
381     const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("fe80::/64")};
382     const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
383     EXPECT_TRUE(ret.isOk());
384 }
385 
386 // Test that setLocalPrefixes() fails given empty input. There is always
387 // a non-empty set of local prefixes; when all networking interfaces are down
388 // we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
TEST_P(OffloadControlHidlTest,SetLocalPrefixesEmptyFails)389 TEST_P(OffloadControlHidlTest, SetLocalPrefixesEmptyFails) {
390     const vector<hidl_string> prefixes{};
391     const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
392     EXPECT_TRUE(ret.isOk());
393 }
394 
395 // Test setLocalPrefixes() fails on incorrectly formed input strings.
TEST_P(OffloadControlHidlTest,SetLocalPrefixesInvalidFails)396 TEST_P(OffloadControlHidlTest, SetLocalPrefixesInvalidFails) {
397     const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("invalid")};
398     const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
399     EXPECT_TRUE(ret.isOk());
400 }
401 
402 /*
403  * Tests for IOffloadControl::getForwardedStats().
404  */
405 
406 // Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
TEST_P(OffloadControlHidlTest,GetForwardedStatsInvalidUpstreamIface)407 TEST_P(OffloadControlHidlTest, GetForwardedStatsInvalidUpstreamIface) {
408     const hidl_string upstream("invalid");
409     const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
410     EXPECT_TRUE(ret.isOk());
411 }
412 
413 // TEST_IFACE is presumed to exist on the device and be up. No packets
414 // are ever actually caused to be forwarded.
TEST_P(OffloadControlHidlTest,GetForwardedStatsDummyIface)415 TEST_P(OffloadControlHidlTest, GetForwardedStatsDummyIface) {
416     const hidl_string upstream(TEST_IFACE);
417     const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
418     EXPECT_TRUE(ret.isOk());
419 }
420 
421 /*
422  * Tests for IOffloadControl::setDataLimit().
423  */
424 
425 // Test that setDataLimit() for an empty interface name fails.
TEST_P(OffloadControlHidlTest,SetDataLimitEmptyUpstreamIfaceFails)426 TEST_P(OffloadControlHidlTest, SetDataLimitEmptyUpstreamIfaceFails) {
427     const hidl_string upstream("");
428     const uint64_t limit = 5000ULL;
429     const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
430     EXPECT_TRUE(ret.isOk());
431 }
432 
433 // TEST_IFACE is presumed to exist on the device and be up. No packets
434 // are ever actually caused to be forwarded.
TEST_P(OffloadControlHidlTest,SetDataLimitNonZeroOk)435 TEST_P(OffloadControlHidlTest, SetDataLimitNonZeroOk) {
436     const hidl_string upstream(TEST_IFACE);
437     const uint64_t limit = 5000ULL;
438     const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
439     EXPECT_TRUE(ret.isOk());
440 }
441 
442 // TEST_IFACE is presumed to exist on the device and be up. No packets
443 // are ever actually caused to be forwarded.
TEST_P(OffloadControlHidlTest,SetDataLimitZeroOk)444 TEST_P(OffloadControlHidlTest, SetDataLimitZeroOk) {
445     const hidl_string upstream(TEST_IFACE);
446     const uint64_t limit = 0ULL;
447     const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
448     EXPECT_TRUE(ret.isOk());
449 }
450 
451 /*
452  * Tests for IOffloadControl::setUpstreamParameters().
453  */
454 
455 // TEST_IFACE is presumed to exist on the device and be up. No packets
456 // are ever actually caused to be forwarded.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersIPv6OnlyOk)457 TEST_P(OffloadControlHidlTest, SetUpstreamParametersIPv6OnlyOk) {
458     const hidl_string iface(TEST_IFACE);
459     const hidl_string v4Addr("");
460     const hidl_string v4Gw("");
461     const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
462     const Return<void> ret =
463         control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
464     EXPECT_TRUE(ret.isOk());
465 }
466 
467 // TEST_IFACE is presumed to exist on the device and be up. No packets
468 // are ever actually caused to be forwarded.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersAlternateIPv6OnlyOk)469 TEST_P(OffloadControlHidlTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
470     const hidl_string iface(TEST_IFACE);
471     const hidl_string v4Addr;
472     const hidl_string v4Gw;
473     const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:3")};
474     const Return<void> ret =
475         control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
476     EXPECT_TRUE(ret.isOk());
477 }
478 
479 // TEST_IFACE is presumed to exist on the device and be up. No packets
480 // are ever actually caused to be forwarded.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersIPv4OnlyOk)481 TEST_P(OffloadControlHidlTest, SetUpstreamParametersIPv4OnlyOk) {
482     const hidl_string iface(TEST_IFACE);
483     const hidl_string v4Addr("192.0.2.2");
484     const hidl_string v4Gw("192.0.2.1");
485     const vector<hidl_string> v6Gws{};
486     const Return<void> ret =
487         control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
488     EXPECT_TRUE(ret.isOk());
489 }
490 
491 // TEST_IFACE is presumed to exist on the device and be up. No packets
492 // are ever actually caused to be forwarded.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersIPv4v6Ok)493 TEST_P(OffloadControlHidlTest, SetUpstreamParametersIPv4v6Ok) {
494     const hidl_string iface(TEST_IFACE);
495     const hidl_string v4Addr("192.0.2.2");
496     const hidl_string v4Gw("192.0.2.1");
497     const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
498     const Return<void> ret =
499         control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
500     EXPECT_TRUE(ret.isOk());
501 }
502 
503 // Test that setUpstreamParameters() fails when all parameters are empty.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersEmptyFails)504 TEST_P(OffloadControlHidlTest, SetUpstreamParametersEmptyFails) {
505     const hidl_string iface("");
506     const hidl_string v4Addr("");
507     const hidl_string v4Gw("");
508     const vector<hidl_string> v6Gws{};
509     const Return<void> ret =
510         control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
511     EXPECT_TRUE(ret.isOk());
512 }
513 
514 // Test that setUpstreamParameters() fails when given empty or non-existent interface names.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersBogusIfaceFails)515 TEST_P(OffloadControlHidlTest, SetUpstreamParametersBogusIfaceFails) {
516     const hidl_string v4Addr("192.0.2.2");
517     const hidl_string v4Gw("192.0.2.1");
518     const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
519     for (const auto& bogus : {"", "invalid"}) {
520         SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
521         const hidl_string iface(bogus);
522         const Return<void> ret =
523             control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
524         EXPECT_TRUE(ret.isOk());
525     }
526 }
527 
528 // Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersInvalidIPv4AddrFails)529 TEST_P(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4AddrFails) {
530     const hidl_string iface(TEST_IFACE);
531     const hidl_string v4Gw("192.0.2.1");
532     const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
533     for (const auto& bogus : {"invalid", "192.0.2"}) {
534         SCOPED_TRACE(StringPrintf("v4addr='%s'", bogus));
535         const hidl_string v4Addr(bogus);
536         const Return<void> ret =
537             control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
538         EXPECT_TRUE(ret.isOk());
539     }
540 }
541 
542 // Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersInvalidIPv4GatewayFails)543 TEST_P(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
544     const hidl_string iface(TEST_IFACE);
545     const hidl_string v4Addr("192.0.2.2");
546     const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
547     for (const auto& bogus : {"invalid", "192.0.2"}) {
548         SCOPED_TRACE(StringPrintf("v4gateway='%s'", bogus));
549         const hidl_string v4Gw(bogus);
550         const Return<void> ret =
551             control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
552         EXPECT_TRUE(ret.isOk());
553     }
554 }
555 
556 // Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
TEST_P(OffloadControlHidlTest,SetUpstreamParametersBadIPv6GatewaysFail)557 TEST_P(OffloadControlHidlTest, SetUpstreamParametersBadIPv6GatewaysFail) {
558     const hidl_string iface(TEST_IFACE);
559     const hidl_string v4Addr("192.0.2.2");
560     const hidl_string v4Gw("192.0.2.1");
561     for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
562         SCOPED_TRACE(StringPrintf("v6gateway='%s'", bogus));
563         const vector<hidl_string> v6Gws{hidl_string("fe80::1"), hidl_string(bogus)};
564         const Return<void> ret =
565             control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
566         EXPECT_TRUE(ret.isOk());
567     }
568 }
569 
570 /*
571  * Tests for IOffloadControl::addDownstream().
572  */
573 
574 // Test addDownstream() works given an IPv4 prefix.
TEST_P(OffloadControlHidlTest,AddDownstreamIPv4)575 TEST_P(OffloadControlHidlTest, AddDownstreamIPv4) {
576     const hidl_string iface("dummy0");
577     const hidl_string prefix("192.0.2.0/24");
578     const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
579     EXPECT_TRUE(ret.isOk());
580 }
581 
582 // Test addDownstream() works given an IPv6 prefix.
TEST_P(OffloadControlHidlTest,AddDownstreamIPv6)583 TEST_P(OffloadControlHidlTest, AddDownstreamIPv6) {
584     const hidl_string iface("dummy0");
585     const hidl_string prefix("2001:db8::/64");
586     const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
587     EXPECT_TRUE(ret.isOk());
588 }
589 
590 // Test addDownstream() fails given all empty parameters.
TEST_P(OffloadControlHidlTest,AddDownstreamEmptyFails)591 TEST_P(OffloadControlHidlTest, AddDownstreamEmptyFails) {
592     const hidl_string iface("");
593     const hidl_string prefix("");
594     const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
595     EXPECT_TRUE(ret.isOk());
596 }
597 
598 // Test addDownstream() fails given empty or non-existent interface names.
TEST_P(OffloadControlHidlTest,AddDownstreamInvalidIfaceFails)599 TEST_P(OffloadControlHidlTest, AddDownstreamInvalidIfaceFails) {
600     const hidl_string prefix("192.0.2.0/24");
601     for (const auto& bogus : {"", "invalid"}) {
602         SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
603         const hidl_string iface(bogus);
604         const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
605         EXPECT_TRUE(ret.isOk());
606     }
607 }
608 
609 // Test addDownstream() fails given unparseable prefix arguments.
TEST_P(OffloadControlHidlTest,AddDownstreamBogusPrefixFails)610 TEST_P(OffloadControlHidlTest, AddDownstreamBogusPrefixFails) {
611     const hidl_string iface("dummy0");
612     for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
613         SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
614         const hidl_string prefix(bogus);
615         const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
616         EXPECT_TRUE(ret.isOk());
617     }
618 }
619 
620 /*
621  * Tests for IOffloadControl::removeDownstream().
622  */
623 
624 // Test removeDownstream() works given an IPv4 prefix.
TEST_P(OffloadControlHidlTest,RemoveDownstreamIPv4)625 TEST_P(OffloadControlHidlTest, RemoveDownstreamIPv4) {
626     const hidl_string iface("dummy0");
627     const hidl_string prefix("192.0.2.0/24");
628     // First add the downstream, otherwise removeDownstream logic can reasonably
629     // return false for downstreams not previously added.
630     const Return<void> add = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
631     EXPECT_TRUE(add.isOk());
632     const Return<void> del = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
633     EXPECT_TRUE(del.isOk());
634 }
635 
636 // Test removeDownstream() works given an IPv6 prefix.
TEST_P(OffloadControlHidlTest,RemoveDownstreamIPv6)637 TEST_P(OffloadControlHidlTest, RemoveDownstreamIPv6) {
638     const hidl_string iface("dummy0");
639     const hidl_string prefix("2001:db8::/64");
640     // First add the downstream, otherwise removeDownstream logic can reasonably
641     // return false for downstreams not previously added.
642     const Return<void> add = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
643     EXPECT_TRUE(add.isOk());
644     const Return<void> del = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
645     EXPECT_TRUE(del.isOk());
646 }
647 
648 // Test removeDownstream() fails given all empty parameters.
TEST_P(OffloadControlHidlTest,RemoveDownstreamEmptyFails)649 TEST_P(OffloadControlHidlTest, RemoveDownstreamEmptyFails) {
650     const hidl_string iface("");
651     const hidl_string prefix("");
652     const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
653     EXPECT_TRUE(ret.isOk());
654 }
655 
656 // Test removeDownstream() fails given empty or non-existent interface names.
TEST_P(OffloadControlHidlTest,RemoveDownstreamBogusIfaceFails)657 TEST_P(OffloadControlHidlTest, RemoveDownstreamBogusIfaceFails) {
658     const hidl_string prefix("192.0.2.0/24");
659     for (const auto& bogus : {"", "invalid"}) {
660         SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
661         const hidl_string iface(bogus);
662         const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
663         EXPECT_TRUE(ret.isOk());
664     }
665 }
666 
667 // Test removeDownstream() fails given unparseable prefix arguments.
TEST_P(OffloadControlHidlTest,RemoveDownstreamBogusPrefixFails)668 TEST_P(OffloadControlHidlTest, RemoveDownstreamBogusPrefixFails) {
669     const hidl_string iface("dummy0");
670     for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
671         SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
672         const hidl_string prefix(bogus);
673         const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
674         EXPECT_TRUE(ret.isOk());
675     }
676 }
677 
678 INSTANTIATE_TEST_CASE_P(
679     PerInstance, OffloadControlHidlTestBase,
680     testing::Combine(
681         testing::ValuesIn(
682             android::hardware::getAllHalInstanceNames(IOffloadConfig::descriptor)),
683         testing::ValuesIn(
684             android::hardware::getAllHalInstanceNames(IOffloadControl::descriptor))),
685     android::hardware::PrintInstanceTupleNameToString<>);
686 
687 INSTANTIATE_TEST_CASE_P(
688     PerInstance, OffloadControlHidlTest,
689     testing::Combine(
690         testing::ValuesIn(
691             android::hardware::getAllHalInstanceNames(IOffloadConfig::descriptor)),
692         testing::ValuesIn(
693             android::hardware::getAllHalInstanceNames(IOffloadControl::descriptor))),
694     android::hardware::PrintInstanceTupleNameToString<>);
695 
696