diff options
| author | Chiachang Wang <chiachangwang@google.com> | 2022-01-15 13:31:04 +0800 |
|---|---|---|
| committer | Chiachang Wang <chiachangwang@google.com> | 2022-01-25 13:21:30 +0800 |
| commit | f79e35692e5b08b5ee95226cd48228ec52a4bba7 (patch) | |
| tree | f3788c2701b5e82ba4221081232687190947795d /server/RouteControllerTest.cpp | |
| parent | 77d0ff62dfd6b76dcbdf731c03c560cafead6ff7 (diff) | |
[ELR#3] Create <iface>_local table to place the local routes
The new local exclusion rules for the VPN networks will be in
the new set of rules above BYPASSABLE_VPN_LOCAL_EXCLUSION for
the local exclusion VPN network. The rules for the local IP
rules will need to be in new tables separated from the existing
interfaces tables. Create <iface>_local table based on the
existing interfaces.
The new routing table will only be written in the rt_tables
instead of open a new device in /dev since it's only required
for supporting routing, such as legacy_network or legacy_system
tables. The new <iface>_local tables share the same life time
of the specific interface tables which means these new tables
will also be removed when the specific interfaces tables are
gone.
These new tables are unfunctional now but only created in the
rt_tables for the mapping between interface name and the index.
Sample content in rt_table before the patch:
255 local
254 main
97 local_network
98 legacy_network
99 legacy_system
1003 dummy0
1010 rmnet_data0
Sample content in the rt_table after the patch:
255 local
254 main
97 local_network
98 legacy_network
99 legacy_system
1003 dummy0
1000000003 dummy0_local
1010 rmnet_data0
1000000010 rmnet_data0_local
Bug: 184750836
Test: cd system/netd ; atest
Change-Id: I13e1efa73a7145c22970880d8b72cbbd7366276c
Diffstat (limited to 'server/RouteControllerTest.cpp')
| -rw-r--r-- | server/RouteControllerTest.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/server/RouteControllerTest.cpp b/server/RouteControllerTest.cpp index 4d1da06f..8bdc8797 100644 --- a/server/RouteControllerTest.cpp +++ b/server/RouteControllerTest.cpp @@ -17,6 +17,7 @@ */ #include <gtest/gtest.h> +#include <fstream> #include "Fwmark.h" #include "IptablesBaseTest.h" @@ -27,6 +28,13 @@ using android::base::StringPrintf; +static const char* TEST_IFACE1 = "netdtest1"; +static const char* TEST_IFACE2 = "netdtest2"; +static const uint32_t TEST_IFACE1_INDEX = 901; +static const uint32_t TEST_IFACE2_INDEX = 902; +// See Linux kernel source in include/net/flow.h +#define LOOPBACK_IFINDEX 1 + namespace android { namespace net { @@ -34,11 +42,20 @@ class RouteControllerTest : public IptablesBaseTest { public: RouteControllerTest() { RouteController::iptablesRestoreCommandFunction = fakeExecIptablesRestoreCommand; + RouteController::ifNameToIndexFunction = fakeIfaceNameToIndexFunction; } int flushRoutes(uint32_t a) { return RouteController::flushRoutes(a); } + + uint32_t static fakeIfaceNameToIndexFunction(const char* iface) { + // "lo" is the same as the real one + if (!strcmp(iface, "lo")) return LOOPBACK_IFINDEX; + if (!strcmp(iface, TEST_IFACE1)) return TEST_IFACE1_INDEX; + if (!strcmp(iface, TEST_IFACE2)) return TEST_IFACE2_INDEX; + return 0; + } }; TEST_F(RouteControllerTest, TestGetRulePriority) { @@ -115,5 +132,46 @@ TEST_F(RouteControllerTest, TestModifyIncomingPacketMark) { mask)}); } +bool hasLocalInterfaceInRouteTable(const char* iface) { + // Calculate the table index from interface index + std::string index = std::to_string(RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL + + RouteController::ifNameToIndexFunction(iface)); + std::string localIface = + index + " " + std::string(iface) + std::string(RouteController::INTERFACE_LOCAL_SUFFIX); + std::string line; + + std::ifstream input(RouteController::RT_TABLES_PATH); + while (std::getline(input, line)) { + if (line.find(localIface) != std::string::npos) { + return true; + } + } + + return false; +} + +TEST_F(RouteControllerTest, TestCreateVirtualLocalInterfaceTable) { + static constexpr int TEST_NETID = 65500; + std::map<int32_t, UidRanges> uidRangeMap; + EXPECT_EQ(0, RouteController::addInterfaceToVirtualNetwork(TEST_NETID, TEST_IFACE1, false, + uidRangeMap, false)); + // Expect to create <iface>_local in the routing table + EXPECT_TRUE(hasLocalInterfaceInRouteTable(TEST_IFACE1)); + // Add another interface, <TEST_IFACE2>_local should also be created + EXPECT_EQ(0, RouteController::addInterfaceToVirtualNetwork(TEST_NETID, TEST_IFACE2, false, + uidRangeMap, false)); + EXPECT_TRUE(hasLocalInterfaceInRouteTable(TEST_IFACE2)); + // Remove TEST_IFACE1 + EXPECT_EQ(0, RouteController::removeInterfaceFromVirtualNetwork(TEST_NETID, TEST_IFACE1, false, + uidRangeMap, false)); + // Interface remove should also remove the virtual local interface for routing table + EXPECT_FALSE(hasLocalInterfaceInRouteTable(TEST_IFACE1)); + // <TEST_IFACE2> should still in the routing table + EXPECT_TRUE(hasLocalInterfaceInRouteTable(TEST_IFACE2)); + EXPECT_EQ(0, RouteController::removeInterfaceFromVirtualNetwork(TEST_NETID, TEST_IFACE2, false, + uidRangeMap, false)); + EXPECT_FALSE(hasLocalInterfaceInRouteTable(TEST_IFACE2)); +} + } // namespace net } // namespace android |
