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