Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions src/linux/netlinkutil/RoutingTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ void RoutingTable::ModifyRouteImpl(const Route& route, Operation action)
{
ModifyLoopbackRouteImpl<TAddr>(route, operation, flags);
}
else if (route.defaultRoute && route.IsOnlink())
{
ModifyDefaultLinkLocalRouteImpl<TAddr>(route, operation, flags);
}
else if (route.defaultRoute)
{
ModifyDefaultRouteImpl<TAddr>(route, operation, flags);
Expand Down Expand Up @@ -222,14 +226,35 @@ void RoutingTable::ModifyLoopbackRouteImpl(const Route& route, int operation, in

message.route.rtm_flags |= RTNH_F_ONLINK;
GNS_LOG_INFO(
"InitializeAddressAttribute RTA_DST ({}) RTA_GATEWAY ({}) RTA_PRIORITY ([not set])",
"Netlink message configuration: RTA_DST ({}) RTA_GATEWAY ({}) RTA_PRIORITY ([not set])",
route.to.value().Addr().c_str(),
route.via.value().Addr().c_str());
utils::InitializeAddressAttribute<TAddr>(message.to, route.to.value(), RTA_DST);
utils::InitializeAddressAttribute<TAddr>(message.via, route.via.value(), RTA_GATEWAY);
});
}

template <typename TAddr>
void RoutingTable::ModifyDefaultLinkLocalRouteImpl(const Route& route, int operation, int flags)
{
struct Message : RouteMessage
{
utils::IntegerAttribute metric;
} __attribute__((packed));

GNS_LOG_INFO(
"SendMessage Route (default onlink), operation ({}), netLinkflags ({})",
RouteOperationToString(operation),
NetLinkFormatFlagsToString(flags).c_str());

SendMessage<Message>(route, operation, flags, [&](Message& message) {
GNS_LOG_INFO(
"Netlink message configuration: RTA_DST ([not set]) RTA_GATEWAY ([not set]), RTA_PRIORITY ({})",
route.metric);
utils::InitializeIntegerAttribute(message.metric, route.metric, RTA_PRIORITY);
});
}

template <typename TAddr>
void RoutingTable::ModifyDefaultRouteImpl(const Route& route, int operation, int flags)
{
Expand All @@ -253,8 +278,8 @@ void RoutingTable::ModifyDefaultRouteImpl(const Route& route, int operation, int

SendMessage<Message>(route, operation, flags, [&](Message& message) {
GNS_LOG_INFO(
"InitializeAddressAttribute RTA_DST ([not set]) RTA_GATEWAY ({}), RTA_PRIORITY ({})",
route.to.has_value() ? route.to.value().Addr().c_str() : "[empty]",
"Netlink message configuration: RTA_DST ([not set]) RTA_GATEWAY ({}), RTA_PRIORITY ({})",
route.via.value().Addr().c_str(),
route.metric);
utils::InitializeAddressAttribute<TAddr>(message.via, route.via.value(), RTA_GATEWAY);
utils::InitializeIntegerAttribute(message.metric, route.metric, RTA_PRIORITY);
Expand All @@ -279,7 +304,7 @@ void RoutingTable::ModifyLinkLocalRouteImpl(const Route& route, int operation, i

SendMessage<Message>(route, operation, flags, [&](Message& message) {
GNS_LOG_INFO(
"InitializeAddressAttribute RTA_DST ({}) RTA_GATEWAY ([not set]), RTA_PRIORITY ({})",
"Netlink message configuration: RTA_DST ({}) RTA_GATEWAY ([not set]), RTA_PRIORITY ({})",
route.to.has_value() ? route.to.value().Addr().c_str() : "[empty]",
route.metric);
utils::InitializeAddressAttribute<TAddr>(message.to, route.to.value(), RTA_DST);
Expand Down Expand Up @@ -311,7 +336,7 @@ void RoutingTable::ModifyOfflinkRouteImpl(const Route& route, int operation, int

SendMessage<Message>(route, operation, flags, [&](Message& message) {
GNS_LOG_INFO(
"InitializeAddressAttribute RTA_DST ({}) RTA_GATEWAY ({}), RTA_PRIORITY ({})",
"Netlink message configuration: RTA_DST ({}) RTA_GATEWAY ({}), RTA_PRIORITY ({})",
route.to.has_value() ? route.to.value().Addr().c_str() : "[empty]",
route.via.has_value() ? route.via.value().Addr().c_str() : "[empty]",
route.metric);
Expand Down
3 changes: 3 additions & 0 deletions src/linux/netlinkutil/RoutingTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class RoutingTable
template <typename TAddr>
void ModifyDefaultRouteImpl(const Route& route, int operation, int flags);

template <typename TAddr>
void ModifyDefaultLinkLocalRouteImpl(const Route& route, int operation, int flags);

template <typename TAddr>
void ModifyLinkLocalRouteImpl(const Route& route, int operation, int flags);

Expand Down
9 changes: 9 additions & 0 deletions src/windows/service/exe/WslMirroredNetworking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,15 @@ void wsl::core::networking::WslMirroredNetworkManager::ProcessRouteChange()
{
endpointRoute.Metric = UINT16_MAX;
}

// Some Windows interfaces (like VPNs) can have metric 0 and routes over that interface with metric also 0, adding up to 0.
// Linux treats metric 0 as unspecified and will default to a 1024 metric. The highest priority metric in Linux is 1
// instead so we need to switch the metric from 0 to 1.
if (endpointRoute.Metric == 0)
{
endpointRoute.Metric = 1;
}

endpoint.Network->Routes.insert(endpointRoute);
}
}
Expand Down
27 changes: 27 additions & 0 deletions test/windows/NetworkTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,33 @@ class NetworkTests
VERIFY_ARE_EQUAL(v6State.DefaultRoute->Device, L"eth0");
}

TEST_METHOD(DefaultOnlinkRoutes)
{
WSL2_TEST_ONLY();

wsl::shared::hns::Route defaultRouteV4;
defaultRouteV4.NextHop = L"0.0.0.0";
defaultRouteV4.DestinationPrefix = LX_INIT_DEFAULT_ROUTE_PREFIX;
defaultRouteV4.Family = AF_INET;
defaultRouteV4.Metric = 1;
SendDeviceSettingsRequest(L"eth0", defaultRouteV4, ModifyRequestType::Add, GuestEndpointResourceType::Route);

wsl::shared::hns::Route defaultRouteV6;
defaultRouteV6.NextHop = L"::";
defaultRouteV6.DestinationPrefix = LX_INIT_DEFAULT_ROUTE_V6_PREFIX;
defaultRouteV6.Family = AF_INET6;
defaultRouteV6.Metric = 1;
SendDeviceSettingsRequest(L"eth0", defaultRouteV6, ModifyRequestType::Add, GuestEndpointResourceType::Route);

const bool defaultV4RouteExists =
LxsstuLaunchWsl(L"ip -4 route show | grep \"default dev eth0\" | grep \"metric 1\"") == (DWORD)0;
const bool defaultV6RouteExists =
LxsstuLaunchWsl(L"ip -6 route show | grep \"default dev eth0\" | grep \"metric 1\"") == (DWORD)0;

VERIFY_IS_TRUE(defaultV4RouteExists);
VERIFY_IS_TRUE(defaultV6RouteExists);
}

TEST_METHOD(SetInterfaceDownAndUp)
{
WSL2_TEST_ONLY();
Expand Down
Loading