diff options
-rw-r--r-- | server/RouteController.cpp | 22 | ||||
-rw-r--r-- | server/RouteController.h | 1 | ||||
-rw-r--r-- | tests/binder_test.cpp | 63 |
3 files changed, 68 insertions, 18 deletions
diff --git a/server/RouteController.cpp b/server/RouteController.cpp index 465e5b90..d2af9a37 100644 --- a/server/RouteController.cpp +++ b/server/RouteController.cpp @@ -64,6 +64,14 @@ const char* const ROUTE_TABLE_NAME_MAIN = "main"; const char* const RouteController::LOCAL_MANGLE_INPUT = "routectrl_mangle_INPUT"; +const IPPrefix V4_LOCAL_ADDR[] = { + IPPrefix::forString("169.254.0.0/16"), // Link Local + IPPrefix::forString("100.64.0.0/10"), // CGNAT + IPPrefix::forString("10.0.0.0/8"), // RFC1918 + IPPrefix::forString("172.16.0.0/12"), // RFC1918 + IPPrefix::forString("192.168.0.0/16") // RFC1918 +}; + const uint8_t AF_FAMILIES[] = {AF_INET, AF_INET6}; const uid_t UID_ROOT = 0; @@ -1384,13 +1392,23 @@ int RouteController::removeInterfaceFromDefaultNetwork(const char* interface, return modifyDefaultNetwork(RTM_DELRULE, interface, permission); } +bool RouteController::isTargetV4LocalRange(const char* dst) { + for (IPPrefix addr : V4_LOCAL_ADDR) { + if (addr.contains(IPPrefix::forString(dst))) { + return true; + } + } + return false; +} + bool RouteController::isLocalAddress(TableType tableType, const char* destination, const char* nexthop) { IPPrefix prefix = IPPrefix::forString(destination); - // TODO: Intersect with RFC1918/CGNAT/LINK LOCAL range. return nexthop == nullptr && tableType == RouteController::INTERFACE && // Skip default route to prevent network being modeled as point-to-point interfaces. - (prefix.family() == AF_INET6 && prefix != IPPrefix::forString("::/0")); + ((prefix.family() == AF_INET6 && prefix != IPPrefix::forString("::/0")) || + // Skip adding non-target local network range. + (prefix.family() == AF_INET && isTargetV4LocalRange(destination))); } int RouteController::addRoute(const char* interface, const char* destination, const char* nexthop, diff --git a/server/RouteController.h b/server/RouteController.h index 74d005ac..ff41678d 100644 --- a/server/RouteController.h +++ b/server/RouteController.h @@ -231,6 +231,7 @@ public: static int modifyUidLocalNetworkRule(const char* interface, uid_t uidStart, uid_t uidEnd, bool add); static bool isLocalAddress(TableType tableType, const char* destination, const char* nexthop); + static bool isTargetV4LocalRange(const char* addrstr); }; // Public because they are called by by RouteControllerTest.cpp. diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp index 2133e1da..f423ea38 100644 --- a/tests/binder_test.cpp +++ b/tests/binder_test.cpp @@ -1633,21 +1633,51 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) { const char* testDest; const char* testNextHop; const bool expectInLocalTable; - } kTestData[] = { - {IP_RULE_V6, "::/0", "fe80::", false}, - {IP_RULE_V6, "::/0", "", false}, - {IP_RULE_V6, "2001:db8:cafe::/64", "fe80::", false}, - {IP_RULE_V6, "fe80::/64", "", true}, - {IP_RULE_V6, "2001:db8:cafe::/48", "", true}, - {IP_RULE_V6, "2001:db8:cafe::/64", "unreachable", false}, - {IP_RULE_V6, "2001:db8:ca00::/40", "", true}, - }; - + } kTestData[] = {{IP_RULE_V6, "::/0", "fe80::", false}, + {IP_RULE_V6, "::/0", "", false}, + {IP_RULE_V6, "2001:db8:cafe::/64", "fe80::", false}, + {IP_RULE_V6, "fe80::/64", "", true}, + {IP_RULE_V6, "2001:db8:cafe::/48", "", true}, + {IP_RULE_V6, "2001:db8:cafe::/64", "unreachable", false}, + {IP_RULE_V6, "2001:db8:ca00::/40", "", true}, + {IP_RULE_V4, "0.0.0.0/0", "10.251.10.1", false}, + {IP_RULE_V4, "192.1.0.0/16", "", false}, + {IP_RULE_V4, "192.168.0.0/15", "", false}, + {IP_RULE_V4, "192.168.0.0/16", "", true}, + {IP_RULE_V4, "192.168.0.0/24", "", true}, + {IP_RULE_V4, "100.1.0.0/16", "", false}, + {IP_RULE_V4, "100.0.0.0/8", "", false}, + {IP_RULE_V4, "100.64.0.0/10", "", true}, + {IP_RULE_V4, "100.64.0.0/16", "", true}, + {IP_RULE_V4, "100.64.0.0/10", "throw", false}, + {IP_RULE_V4, "172.0.0.0/8", "", false}, + {IP_RULE_V4, "172.16.0.0/12", "", true}, + {IP_RULE_V4, "172.16.0.0/16", "", true}, + {IP_RULE_V4, "172.16.0.0/12", "unreachable", false}, + {IP_RULE_V4, "172.32.0.0/12", "", false}, + {IP_RULE_V4, "169.0.0.0/8", "", false}, + {IP_RULE_V4, "169.254.0.0/16", "", true}, + {IP_RULE_V4, "169.254.0.0/20", "", true}, + {IP_RULE_V4, "169.254.3.0/24", "", true}, + {IP_RULE_V4, "170.254.0.0/16", "", false}, + {IP_RULE_V4, "10.0.0.0/8", "", true}, + {IP_RULE_V4, "10.0.0.0/7", "", false}, + {IP_RULE_V4, "10.0.0.0/16", "", true}, + {IP_RULE_V4, "10.251.0.0/16", "", true}, + {IP_RULE_V4, "10.251.250.0/24", "", true}, + {IP_RULE_V4, "10.251.10.2/31", "throw", false}, + {IP_RULE_V4, "10.251.10.2/31", "unreachable", false}}; + + // To ensure that the nexthops for the above are reachable. + // Otherwise, the routes can't be created. static const struct { const char* ipVersion; const char* testDest; const char* testNextHop; - } kLinkLocalRoutes[] = {{IP_RULE_V6, "2001:db8::/32", ""}}; + } kDirectlyConnectedRoutes[] = { + {IP_RULE_V4, "10.251.10.0/30", ""}, + {IP_RULE_V6, "2001:db8::/32", ""}, + }; // Add test physical network const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL, @@ -1664,8 +1694,8 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) { std::string localTableName = std::string(sTun.name() + "_local"); // Set up link-local routes for connectivity to the "gateway" - for (size_t i = 0; i < std::size(kLinkLocalRoutes); i++) { - const auto& td = kLinkLocalRoutes[i]; + for (size_t i = 0; i < std::size(kDirectlyConnectedRoutes); i++) { + const auto& td = kDirectlyConnectedRoutes[i]; binder::Status status = mNetd->networkAddRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop); @@ -1679,7 +1709,8 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) { for (size_t i = 0; i < std::size(kTestData); i++) { const auto& td = kTestData[i]; - + SCOPED_TRACE(StringPrintf("case ip:%s, dest:%s, nexHop:%s, expect:%d", td.ipVersion, + td.testDest, td.testNextHop, td.expectInLocalTable)); binder::Status status = mNetd->networkAddRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop); EXPECT_TRUE(status.isOk()) << status.exceptionMessage(); @@ -1698,8 +1729,8 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) { localTableName.c_str()); } - for (size_t i = 0; i < std::size(kLinkLocalRoutes); i++) { - const auto& td = kLinkLocalRoutes[i]; + for (size_t i = 0; i < std::size(kDirectlyConnectedRoutes); i++) { + const auto& td = kDirectlyConnectedRoutes[i]; status = mNetd->networkRemoveRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop); EXPECT_TRUE(status.isOk()) << status.exceptionMessage(); } |