1 /*
2 * Copyright 2018 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 "netd_hidl_test"
18
19 #include <linux/if.h>
20
21 #include <android-base/stringprintf.h>
22 #include <android/system/net/netd/1.1/INetd.h>
23 #include <gtest/gtest.h>
24 #include <hidl/GtestPrinter.h>
25 #include <hidl/ServiceManagement.h>
26 #include <log/log.h>
27 #include <netutils/ifc.h>
28
29 #include "VtsHalNetNetdTestUtils.h"
30 #include "tun_interface.h"
31
32 using android::sp;
33 using android::base::StringPrintf;
34 using android::hardware::Return;
35 using android::net::TunInterface;
36 using android::system::net::netd::V1_1::INetd;
37
38 namespace {
39 const net_handle_t INVALID_NET_HANDLE = 0x6600FACADE;
40
41 constexpr const char* IPV4_ROUTER = "192.0.2.1";
42 constexpr const char* IPV4_CONNECTED = "192.0.2.0/25";
43 constexpr const char* IPV4_SUBNET_1 = "192.0.2.192/28";
44 constexpr const char* IPV4_HOST_1 = "192.0.2.195";
45 constexpr const char* IPV4_SUBNET_2 = "192.0.2.240/28";
46 constexpr const char* IPV4_HOST_2 = "192.0.2.245";
47 constexpr const char* IPV4_UNREACHABLE = "192.0.2.239";
48
49 constexpr const char* IPV6_ROUTER = "2001:db8::cafe";
50 constexpr const char* IPV6_CONNECTED = "2001:db8::/64";
51 constexpr const char* IPV6_SUBNET_1 = "2001:db8:babe::/48";
52 constexpr const char* IPV6_HOST_1 = "2001:db8:babe::1";
53 constexpr const char* IPV6_SUBNET_2 = "2001:db8:d00d::/48";
54 constexpr const char* IPV6_HOST_2 = "2001:db8:d00d::1";
55 constexpr const char* IPV6_UNREACHABLE = "2001:db8:d0a::";
56
57 std::vector<const char*> REACHABLE = {
58 IPV4_ROUTER, IPV4_HOST_1, IPV4_HOST_2, IPV6_ROUTER, IPV6_HOST_1, IPV6_HOST_2,
59 };
60
checkAllReachable(net_handle_t handle)61 void checkAllReachable(net_handle_t handle) {
62 int ret;
63 for (const auto& dst : REACHABLE) {
64 ret = checkReachability(handle, dst);
65 EXPECT_EQ(0, ret) << "Expected reachability to " << dst << " but got %s" << strerror(-ret);
66 }
67 for (const auto& dst : {IPV4_UNREACHABLE, IPV6_UNREACHABLE}) {
68 EXPECT_EQ(-ENETUNREACH, checkReachability(handle, dst))
69 << "Expected " << dst << " to be unreachable, but was reachable";
70 }
71 }
72
checkAllUnreachable(net_handle_t handle)73 void checkAllUnreachable(net_handle_t handle) {
74 for (const auto& dst : REACHABLE) {
75 EXPECT_EQ(-ENETUNREACH, checkReachability(handle, dst));
76 }
77 for (const auto& dst : {IPV4_UNREACHABLE, IPV6_UNREACHABLE}) {
78 EXPECT_EQ(-ENETUNREACH, checkReachability(handle, dst));
79 }
80 }
81 } // namespace
82
83 class NetdHidlTest : public ::testing::TestWithParam<std::string> {
84 public:
85 // Netd HAL instance.
86 sp<INetd> netd;
87
88 // The nethandle of our test network, and its packet mark.
89 net_handle_t mNetHandle;
90 uint32_t mPacketMark;
91
92 // Two interfaces that we can add and remove from our test network.
93 static TunInterface sTun1;
94 static TunInterface sTun2;
95
96 // The interface name of sTun1, for convenience.
97 static const char* sIfaceName;
98
SetUpTestCase()99 static void SetUpTestCase() {
100 ASSERT_EQ(0, sTun1.init());
101 ASSERT_EQ(0, sTun2.init());
102 ASSERT_LE(sTun1.name().size(), static_cast<size_t>(IFNAMSIZ));
103 ASSERT_LE(sTun2.name().size(), static_cast<size_t>(IFNAMSIZ));
104 ifc_init();
105 ASSERT_EQ(0, ifc_up(sTun1.name().c_str()));
106 ASSERT_EQ(0, ifc_up(sTun2.name().c_str()));
107 sIfaceName = sTun1.name().c_str();
108 }
109
TearDownTestCase()110 static void TearDownTestCase() {
111 sTun1.destroy();
112 sTun2.destroy();
113 ifc_close();
114 }
115
SetUp()116 virtual void SetUp() override {
117 netd = INetd::getService(GetParam());
118
119 ASSERT_NE(netd, nullptr) << "Could not get HIDL instance";
120
121 // Set up an OEM network.
122 INetd::StatusCode status;
123 Return<void> ret =
124 netd->createOemNetwork([&](net_handle_t n, uint32_t p, INetd::StatusCode s) {
125 status = s;
126 mNetHandle = n;
127 mPacketMark = p;
128 });
129 ASSERT_TRUE(ret.isOk());
130 ASSERT_EQ(INetd::StatusCode::OK, status);
131 ASSERT_NE(NETWORK_UNSPECIFIED, mNetHandle);
132 ASSERT_NE((uint32_t)0, mPacketMark);
133 }
134
TearDown()135 virtual void TearDown() override { netd->destroyOemNetwork(mNetHandle); }
136
expectAddRoute(INetd::StatusCode expectedStatus,net_handle_t handle,const char * iface,const char * destination,const char * nexthop)137 void expectAddRoute(INetd::StatusCode expectedStatus, net_handle_t handle, const char* iface,
138 const char* destination, const char* nexthop) {
139 Return<INetd::StatusCode> retStatus =
140 netd->addRouteToOemNetwork(handle, iface, destination, nexthop);
141 EXPECT_STATUS(expectedStatus, retStatus);
142 }
143
expectAddRouteSuccess(net_handle_t h,const char * i,const char * d,const char * n)144 void expectAddRouteSuccess(net_handle_t h, const char* i, const char* d, const char* n) {
145 expectAddRoute(INetd::StatusCode::OK, h, i, d, n);
146 }
147
expectRemoveRoute(INetd::StatusCode expectedStatus,net_handle_t handle,const char * iface,const char * destination,const char * nexthop)148 void expectRemoveRoute(INetd::StatusCode expectedStatus, net_handle_t handle, const char* iface,
149 const char* destination, const char* nexthop) {
150 Return<INetd::StatusCode> retStatus =
151 netd->removeRouteFromOemNetwork(handle, iface, destination, nexthop);
152 EXPECT_STATUS(expectedStatus, retStatus);
153 }
154
expectRemoveRouteSuccess(net_handle_t h,const char * i,const char * d,const char * n)155 void expectRemoveRouteSuccess(net_handle_t h, const char* i, const char* d, const char* n) {
156 expectRemoveRoute(INetd::StatusCode::OK, h, i, d, n);
157 }
158 };
159
160 TunInterface NetdHidlTest::sTun1;
161 TunInterface NetdHidlTest::sTun2;
162 const char* NetdHidlTest::sIfaceName;
163
164 // Tests adding and removing interfaces from the OEM network.
TEST_P(NetdHidlTest,TestAddRemoveInterfaces)165 TEST_P(NetdHidlTest, TestAddRemoveInterfaces) {
166 // HACK: mark out permissions bits.
167 uint32_t packetMark = mPacketMark & 0xffff;
168
169 EXPECT_EQ(0, checkNetworkExists(mNetHandle));
170 EXPECT_EQ(0, countRulesForFwmark(packetMark));
171
172 // Adding an interface creates the routing rules.
173 Return<INetd::StatusCode> retStatus = netd->addInterfaceToOemNetwork(mNetHandle, sIfaceName);
174 EXPECT_TRUE(retStatus.isOk());
175 EXPECT_EQ(0, checkNetworkExists(mNetHandle));
176 EXPECT_EQ(2, countRulesForFwmark(packetMark));
177
178 // Adding an interface again silently succeeds.
179 retStatus = netd->addInterfaceToOemNetwork(mNetHandle, sIfaceName);
180 EXPECT_TRUE(retStatus.isOk());
181 EXPECT_EQ(0, checkNetworkExists(mNetHandle));
182 EXPECT_EQ(2, countRulesForFwmark(packetMark));
183
184 // More than one network can be created.
185 net_handle_t netHandle2;
186 uint32_t packetMark2;
187
188 Return<void> ret = netd->createOemNetwork([&](net_handle_t n, uint32_t p, INetd::StatusCode) {
189 netHandle2 = n;
190 packetMark2 = p & 0xffff;
191 });
192 EXPECT_TRUE(ret.isOk());
193 EXPECT_NE(mNetHandle, netHandle2);
194 EXPECT_NE(packetMark, packetMark2);
195 EXPECT_EQ(0, checkNetworkExists(netHandle2));
196 EXPECT_EQ(0, countRulesForFwmark(packetMark2));
197
198 // An interface can only be in one network.
199 retStatus = netd->addInterfaceToOemNetwork(netHandle2, sIfaceName);
200 EXPECT_STATUS(INetd::StatusCode::UNKNOWN_ERROR, retStatus);
201
202 // Removing the interface removes the rules.
203 retStatus = netd->removeInterfaceFromOemNetwork(mNetHandle, sIfaceName);
204 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
205 EXPECT_EQ(0, countRulesForFwmark(packetMark));
206
207 retStatus = netd->addInterfaceToOemNetwork(netHandle2, sIfaceName);
208 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
209 EXPECT_EQ(2, countRulesForFwmark(packetMark2));
210
211 // When a network is removed the interfaces are deleted.
212 retStatus = netd->destroyOemNetwork(netHandle2);
213 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
214 EXPECT_EQ(-ENONET, checkNetworkExists(netHandle2));
215 EXPECT_EQ(0, countRulesForFwmark(packetMark2));
216
217 // Adding an interface to a non-existent network fails.
218 retStatus = netd->addInterfaceToOemNetwork(INVALID_NET_HANDLE, sIfaceName);
219 EXPECT_STATUS(INetd::StatusCode::INVALID_ARGUMENTS, retStatus);
220 retStatus = netd->removeInterfaceFromOemNetwork(INVALID_NET_HANDLE, sIfaceName);
221 EXPECT_STATUS(INetd::StatusCode::INVALID_ARGUMENTS, retStatus);
222 }
223
224 // Tests adding and removing routes from the OEM network.
TEST_P(NetdHidlTest,TestAddRemoveRoutes)225 TEST_P(NetdHidlTest, TestAddRemoveRoutes) {
226 Return<INetd::StatusCode> retStatus = netd->addInterfaceToOemNetwork(mNetHandle, sIfaceName);
227 ASSERT_TRUE(retStatus.isOk());
228
229 // Network exists, but has no routes and no connectivity.
230 EXPECT_EQ(0, checkNetworkExists(mNetHandle));
231 checkAllUnreachable(mNetHandle);
232
233 // Add a directly-connected route and two gatewayed routes through it.
234 expectAddRouteSuccess(mNetHandle, sIfaceName, IPV4_CONNECTED, "");
235 expectAddRouteSuccess(mNetHandle, sIfaceName, IPV4_SUBNET_1, IPV4_ROUTER);
236 expectAddRouteSuccess(mNetHandle, sIfaceName, IPV4_SUBNET_2, IPV4_ROUTER);
237 expectAddRouteSuccess(mNetHandle, sIfaceName, IPV6_CONNECTED, "");
238 expectAddRouteSuccess(mNetHandle, sIfaceName, IPV6_SUBNET_1, IPV6_ROUTER);
239 expectAddRouteSuccess(mNetHandle, sIfaceName, IPV6_SUBNET_2, IPV6_ROUTER);
240
241 // Test some destinations.
242 checkAllReachable(mNetHandle);
243
244 // Remove the directly-connected routes and everything is unreachable again.
245 expectRemoveRouteSuccess(mNetHandle, sIfaceName, IPV4_CONNECTED, "");
246 expectRemoveRouteSuccess(mNetHandle, sIfaceName, IPV6_CONNECTED, "");
247 expectRemoveRouteSuccess(mNetHandle, sIfaceName, IPV4_SUBNET_1, IPV4_ROUTER);
248 expectRemoveRouteSuccess(mNetHandle, sIfaceName, IPV4_SUBNET_2, IPV4_ROUTER);
249 expectRemoveRouteSuccess(mNetHandle, sIfaceName, IPV6_SUBNET_1, IPV6_ROUTER);
250 expectRemoveRouteSuccess(mNetHandle, sIfaceName, IPV6_SUBNET_2, IPV6_ROUTER);
251
252 checkAllUnreachable(mNetHandle);
253
254 // Invalid: route doesn't exist so can't be deleted.
255 expectRemoveRoute(INetd::StatusCode::UNKNOWN_ERROR, mNetHandle, sIfaceName, IPV4_CONNECTED, "");
256
257 // Invalid: IP address instead of prefix.
258 expectAddRoute(INetd::StatusCode::INVALID_ARGUMENTS, mNetHandle, sIfaceName, IPV4_HOST_1, "");
259 expectAddRoute(INetd::StatusCode::INVALID_ARGUMENTS, mNetHandle, sIfaceName, IPV6_HOST_1, "");
260
261 // Invalid: both nexthop and interface are empty.
262 expectAddRoute(INetd::StatusCode::UNKNOWN_ERROR, mNetHandle, "", IPV4_SUBNET_1, "");
263 expectAddRoute(INetd::StatusCode::UNKNOWN_ERROR, mNetHandle, "", IPV6_SUBNET_1, "");
264
265 // The kernel deletes the routes when the interfaces go away.
266 }
267
268 // Tests enabling and disabling forwarding between interfaces.
TEST_P(NetdHidlTest,TestForwarding)269 TEST_P(NetdHidlTest, TestForwarding) {
270 Return<INetd::StatusCode> retStatus =
271 netd->addInterfaceToOemNetwork(mNetHandle, sTun1.name().c_str());
272 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
273 retStatus = netd->addInterfaceToOemNetwork(mNetHandle, sTun2.name().c_str());
274 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
275
276 // TODO: move this test to netd and use ROUTE_TABLE_OFFSET_FROM_INDEX directly.
277 uint32_t table1 = 1000 + sTun1.ifindex();
278 uint32_t table2 = 1000 + sTun1.ifindex();
279 const char* regexTemplate = "from all iif %s .*lookup (%s|%d)";
280 std::string regex1 =
281 StringPrintf(regexTemplate, sTun1.name().c_str(), sTun2.name().c_str(), table2);
282 std::string regex2 =
283 StringPrintf(regexTemplate, sTun2.name().c_str(), sTun1.name().c_str(), table1);
284
285 EXPECT_EQ(0, countMatchingIpRules(regex1));
286 EXPECT_EQ(0, countMatchingIpRules(regex2));
287
288 retStatus = netd->setForwardingBetweenInterfaces(sTun1.name(), sTun2.name(), true);
289 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
290 EXPECT_EQ(2, countMatchingIpRules(regex1));
291 EXPECT_EQ(0, countMatchingIpRules(regex2));
292
293 // No attempt at deduplicating rules is made.
294 retStatus = netd->setForwardingBetweenInterfaces(sTun1.name(), sTun2.name(), true);
295 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
296 EXPECT_EQ(4, countMatchingIpRules(regex1));
297
298 retStatus = netd->setForwardingBetweenInterfaces(sTun1.name(), sTun2.name(), false);
299 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
300 EXPECT_EQ(2, countMatchingIpRules(regex1));
301
302 retStatus = netd->setForwardingBetweenInterfaces(sTun2.name(), sTun1.name(), true);
303 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
304 EXPECT_EQ(2, countMatchingIpRules(regex1));
305 EXPECT_EQ(2, countMatchingIpRules(regex2));
306
307 retStatus = netd->setForwardingBetweenInterfaces(sTun1.name(), sTun2.name(), false);
308 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
309 EXPECT_EQ(0, countMatchingIpRules(regex1));
310 EXPECT_EQ(2, countMatchingIpRules(regex2));
311
312 retStatus = netd->setForwardingBetweenInterfaces(sTun2.name(), sTun1.name(), false);
313 EXPECT_STATUS(INetd::StatusCode::OK, retStatus);
314 EXPECT_EQ(0, countMatchingIpRules(regex1));
315 EXPECT_EQ(0, countMatchingIpRules(regex2));
316
317 // Deleting rules that don't exist fails.
318 retStatus = netd->setForwardingBetweenInterfaces(sTun1.name(), sTun2.name(), false);
319 EXPECT_STATUS(INetd::StatusCode::UNKNOWN_ERROR, retStatus);
320 EXPECT_EQ(0, countMatchingIpRules(regex1));
321 EXPECT_EQ(0, countMatchingIpRules(regex2));
322 }
323
324 INSTANTIATE_TEST_SUITE_P(
325 PerInstance, NetdHidlTest,
326 testing::ValuesIn(android::hardware::getAllHalInstanceNames(INetd::descriptor)),
327 android::hardware::PrintInstanceNameToString);
328