summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchiachangwang <chiachangwang@google.com>2022-08-25 06:55:19 +0000
committerCherrypicker Worker <android-build-cherrypicker-worker@google.com>2022-09-21 00:55:06 +0000
commitb7a6099aff35e8b2f7a88272e67a7feeb2b9f0c0 (patch)
treec4cf801c637d63ff48569fd3a3997ecf571522f5
parent9542a1e63336cb094afb54ae2cac16279210b2ef (diff)
downloadnetd-b7a6099aff35e8b2f7a88272e67a7feeb2b9f0c0.tar.gz
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.cpp18
-rw-r--r--server/RouteController.h8
-rw-r--r--tests/binder_test.cpp8
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];