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