diff options
author | chiachangwang <chiachangwang@google.com> | 2022-08-25 06:55:19 +0000 |
---|---|---|
committer | Cherrypicker Worker <android-build-cherrypicker-worker@google.com> | 2022-09-21 00:55:06 +0000 |
commit | b7a6099aff35e8b2f7a88272e67a7feeb2b9f0c0 (patch) | |
tree | c4cf801c637d63ff48569fd3a3997ecf571522f5 | |
parent | 9542a1e63336cb094afb54ae2cac16279210b2ef (diff) | |
download | netd-b7a6099aff35e8b2f7a88272e67a7feeb2b9f0c0.tar.gz |
Add IPv4 link-local multicast range to local routing tablesandroid-13.0.0_r82android-13.0.0_r81android-13.0.0_r80android-13.0.0_r74android-13.0.0_r73android-13.0.0_r72android-13.0.0_r66android-13.0.0_r65android-13.0.0_r64android-13.0.0_r60android-13.0.0_r59android-13.0.0_r58android13-qpr3-c-s8-releaseandroid13-qpr3-c-s7-releaseandroid13-qpr3-c-s6-releaseandroid13-qpr3-c-s5-releaseandroid13-qpr3-c-s4-releaseandroid13-qpr3-c-s3-releaseandroid13-qpr3-c-s2-releaseandroid13-qpr3-c-s12-releaseandroid13-qpr3-c-s11-releaseandroid13-qpr3-c-s10-releaseandroid13-qpr3-c-s1-release
This commit allows local multicast traffic to be sent locally
instead of being sent through VPN when using a VPN automatic
bypass for local traffic.
Currently, the local network that is considered in VPN local
exclusion mode is the same subnet of the network assigned
address. If apps try to make some traffic to multicast range,
it may be routed to VPN and block the traffic. E.g. If app
connect a UDP socket to multicast range(224.0.0.x) and sends
from the socket, or app send to 224.0.0.x from an unconnected
socket. The traffic will send from VPN network. This traffic
may not be well-routed in VPN network. So the case should be
also considered to make the function work in the VPN bypass
mode because it usually won't be the network assigned subnet
range. Add the multicast range as a fixed range in the local
exclusion table.
The multicast range is 224.0.0.0/4 but only limit it to
224.0.0.0/24 since the IPv4 definitions are not as precise as
for IPv6, it is the only range that the standards (RFC 2365
and RFC 5771) specify is link-local and must not be forwarded.
Bug: 243200566
Test: cd system/netd ; atest
Test: connect to Wifi or cellular network and check the routing
Test: manually test with chromecast with local routes exclusion
enabled
Change-Id: I79fe499fb02a88ec687fadf3fad461c204fe3e47
(cherry picked from commit 5308c041c712b8cd2ecee04335c10d0aeb97d610)
Merged-In: I79fe499fb02a88ec687fadf3fad461c204fe3e47
-rw-r--r-- | server/RouteController.cpp | 18 | ||||
-rw-r--r-- | server/RouteController.h | 8 | ||||
-rw-r--r-- | tests/binder_test.cpp | 8 |
3 files changed, 34 insertions, 0 deletions
diff --git a/server/RouteController.cpp b/server/RouteController.cpp index dca6bd98..86b23b6d 100644 --- a/server/RouteController.cpp +++ b/server/RouteController.cpp @@ -667,6 +667,19 @@ int RouteController::modifyVpnLocalExclusionRule(bool add, const char* physicalI INVALID_UID); } +int RouteController::addFixedLocalRoutes(const char* interface) { + for (size_t i = 0; i < ARRAY_SIZE(V4_FIXED_LOCAL_PREFIXES); ++i) { + if (int ret = modifyRoute(RTM_NEWROUTE, NETLINK_ROUTE_CREATE_FLAGS, interface, + V4_FIXED_LOCAL_PREFIXES[i], nullptr /* nexthop */, + RouteController::INTERFACE, 0 /* mtu */, 0 /* priority */, + true /* isLocal */)) { + return ret; + } + } + + return 0; +} + // A rule to enable split tunnel VPNs. // // If a packet with a VPN's netId doesn't find a route in the VPN's routing table, it's allowed to @@ -1297,6 +1310,11 @@ int RouteController::addInterfaceToPhysicalNetwork(unsigned netId, const char* i maybeModifyQdiscClsact(interface, ACTION_ADD); updateTableNamesFile(); + + if (int ret = addFixedLocalRoutes(interface)) { + return ret; + } + return 0; } diff --git a/server/RouteController.h b/server/RouteController.h index f57bc242..1b3a093a 100644 --- a/server/RouteController.h +++ b/server/RouteController.h @@ -85,6 +85,13 @@ constexpr int32_t RULE_PRIORITY_DEFAULT_NETWORK = 31000; constexpr int32_t RULE_PRIORITY_UNREACHABLE = 32000; // clang-format on +static const char* V4_FIXED_LOCAL_PREFIXES[] = { + // The multicast range is 224.0.0.0/4 but only limit it to 224.0.0.0/24 since the IPv4 + // definitions are not as precise as for IPv6, it is the only range that the standards + // (RFC 2365 and RFC 5771) specify is link-local and must not be forwarded. + "224.0.0.0/24" // Link-local multicast; non-internet routable +}; + class UidRanges; class RouteController { @@ -232,6 +239,7 @@ public: bool add); static bool isLocalRoute(TableType tableType, const char* destination, const char* nexthop); static bool isWithinIpv4LocalPrefix(const char* addrstr); + static int addFixedLocalRoutes(const char* interface); }; // Public because they are called by by RouteControllerTest.cpp. diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp index d9d7cecc..02a750d2 100644 --- a/tests/binder_test.cpp +++ b/tests/binder_test.cpp @@ -136,6 +136,7 @@ using android::net::TetherStatsParcel; using android::net::TunInterface; using android::net::UidRangeParcel; using android::net::UidRanges; +using android::net::V4_FIXED_LOCAL_PREFIXES; using android::net::mdns::aidl::DiscoveryInfo; using android::net::mdns::aidl::GetAddressInfo; using android::net::mdns::aidl::IMDns; @@ -1700,6 +1701,13 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) { EXPECT_TRUE(mNetd->networkSetDefault(TEST_NETID1).isOk()); std::string localTableName = std::string(sTun.name() + "_local"); + + // Verify the fixed routes exist in the local table. + for (size_t i = 0; i < std::size(V4_FIXED_LOCAL_PREFIXES); i++) { + expectNetworkRouteExists(IP_RULE_V4, sTun.name(), V4_FIXED_LOCAL_PREFIXES[i], "", + localTableName.c_str()); + } + // Set up link-local routes for connectivity to the "gateway" for (size_t i = 0; i < std::size(kDirectlyConnectedRoutes); i++) { const auto& td = kDirectlyConnectedRoutes[i]; |