Handle offlink default gateways in GNS (#41130)

Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com> Copilot-Session: a404d085-142f-448f-b7fa-7ccc6528e844

Ben Hillis committed Jul 23, 2026 at 13:48 UTC 4b1eeb831b532f50cb9aa2d1f8ee60ee20c560fb
2 files changed +8 -1
src/linux/netlinkutil/RoutingTable.cpp
+3 -1
@@ -139,7 +139,9 @@ void RoutingTable::SendMessage(const Route& route, int operation, int flags, con
139 message.route.rtm_type = route.IsMulticast() ? RTN_MULTICAST : RTN_UNICAST;
140 message.route.rtm_scope = route.IsOnlink() ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE;
141 message.route.rtm_flags = RTM_F_NOTIFY;
142 - if (route.via.has_value() && route.via.value().IsLinkLocal())
142 + // Default gateways received from the host are directly reachable through the specified interface,
143 + // even when a VPN exposes the interface as a host route and the gateway is outside that prefix.
144 + if (route.via.has_value() && (route.defaultRoute || route.via.value().IsLinkLocal()))
145 {
146 message.route.rtm_flags |= RTNH_F_ONLINK;
147 }
test/windows/NetworkTests.cpp
+5
@@ -345,6 +345,11 @@ class NetworkTests
345 VERIFY_ARE_EQUAL(v6State.DefaultRoute->Device, L"eth0");
346 }
347
348 + WSL2_TEST_METHOD(AddDefaultRouteWithOfflinkGateway)
349 + {
350 + TestCase({{L"eth0", {{L"100.96.5.160", 32}}, L"100.96.5.161"}});
351 + }
352 +
353 WSL2_TEST_METHOD(AddRemoveDefaultOnlinkRoutes)
354 {
355 wsl::shared::hns::Route defaultRouteV4;