Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
64 changes: 48 additions & 16 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 @@ -193,8 +197,8 @@ void RoutingTable::ModifyLoopbackRouteImpl(const Route& route, int operation, in

GNS_LOG_INFO(
"SendMessage Route (to {}, via {}), operation ({}), netLinkflags ({})",
route.to.has_value() ? route.to.value().Addr().c_str() : "[empty]",
route.via.has_value() ? route.via.value().Addr().c_str() : "[empty]",
route.to.value().Addr().c_str(),
route.via.value().Addr().c_str(),
RouteOperationToString(operation),
NetLinkFormatFlagsToString(flags).c_str());

Expand Down Expand Up @@ -222,14 +226,33 @@ 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)
Comment thread
FetoiuCatalin marked this conversation as resolved.
{
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 @@ -246,15 +269,15 @@ void RoutingTable::ModifyDefaultRouteImpl(const Route& route, int operation, int

GNS_LOG_INFO(
"SendMessage Route (to {}, via {}), operation ({}), netLinkflags ({})",
route.to.has_value() ? route.to.value().Addr().c_str() : "[empty]",
route.via.has_value() ? route.via.value().Addr().c_str() : "[empty]",
"[empty]",
Comment thread
keith-horton marked this conversation as resolved.
route.via.value().Addr().c_str(),
RouteOperationToString(operation),
NetLinkFormatFlagsToString(flags).c_str());

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);
Comment thread
keith-horton marked this conversation as resolved.
utils::InitializeIntegerAttribute(message.metric, route.metric, RTA_PRIORITY);
Expand All @@ -264,6 +287,11 @@ void RoutingTable::ModifyDefaultRouteImpl(const Route& route, int operation, int
template <typename TAddr>
void RoutingTable::ModifyLinkLocalRouteImpl(const Route& route, int operation, int flags)
{
if (!route.to.has_value())
{
throw RuntimeErrorWithSourceLocation("Link-local route is missing its destination address");
}

struct Message : RouteMessage
{
utils::AddressAttribute<TAddr> to;
Expand All @@ -272,15 +300,15 @@ void RoutingTable::ModifyLinkLocalRouteImpl(const Route& route, int operation, i

GNS_LOG_INFO(
"SendMessage Route (to {}, via {}), operation ({}), netLinkflags ({})",
route.to.has_value() ? route.to.value().Addr().c_str() : "[empty]",
route.via.has_value() ? route.via.value().Addr().c_str() : "[empty]",
route.to.value().Addr().c_str(),
"[empty]",
Comment thread
keith-horton marked this conversation as resolved.
RouteOperationToString(operation),
NetLinkFormatFlagsToString(flags).c_str());

SendMessage<Message>(route, operation, flags, [&](Message& message) {
GNS_LOG_INFO(
"InitializeAddressAttribute RTA_DST ({}) RTA_GATEWAY ([not set]), RTA_PRIORITY ({})",
route.to.has_value() ? route.to.value().Addr().c_str() : "[empty]",
"Netlink message configuration: RTA_DST ({}) RTA_GATEWAY ([not set]), RTA_PRIORITY ({})",
route.to.value().Addr().c_str(),
route.metric);
utils::InitializeAddressAttribute<TAddr>(message.to, route.to.value(), RTA_DST);
utils::InitializeIntegerAttribute(message.metric, route.metric, RTA_PRIORITY);
Expand All @@ -294,6 +322,10 @@ void RoutingTable::ModifyOfflinkRouteImpl(const Route& route, int operation, int
{
throw RuntimeErrorWithSourceLocation("Offlink route is missing its next hop");
}
if (!route.to.has_value())
Comment thread
FetoiuCatalin marked this conversation as resolved.
{
throw RuntimeErrorWithSourceLocation("Offlink route is missing its destination address");
}

struct Message : RouteMessage
{
Expand All @@ -304,16 +336,16 @@ void RoutingTable::ModifyOfflinkRouteImpl(const Route& route, int operation, int

GNS_LOG_INFO(
"SendMessage Route (to {}, via {}), operation ({}), netLinkflags ({})",
route.to.has_value() ? route.to.value().Addr().c_str() : "[empty]",
route.via.has_value() ? route.via.value().Addr().c_str() : "[empty]",
route.to.value().Addr().c_str(),
route.via.value().Addr().c_str(),
RouteOperationToString(operation),
NetLinkFormatFlagsToString(flags).c_str());

SendMessage<Message>(route, operation, flags, [&](Message& message) {
GNS_LOG_INFO(
"InitializeAddressAttribute 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]",
"Netlink message configuration: RTA_DST ({}) RTA_GATEWAY ({}), RTA_PRIORITY ({})",
route.to.value().Addr().c_str(),
route.via.value().Addr().c_str(),
route.metric);
utils::InitializeAddressAttribute<TAddr>(message.to, route.to.value(), RTA_DST);
utils::InitializeAddressAttribute<TAddr>(message.via, route.via.value(), RTA_GATEWAY);
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
37 changes: 37 additions & 0 deletions test/windows/NetworkTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,43 @@ class NetworkTests
VERIFY_ARE_EQUAL(v6State.DefaultRoute->Device, L"eth0");
}

TEST_METHOD(AddRemoveDefaultOnlinkRoutes)
{
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;
Comment thread
keith-horton marked this conversation as resolved.
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;
Comment thread
FetoiuCatalin marked this conversation as resolved.
SendDeviceSettingsRequest(L"eth0", defaultRouteV6, ModifyRequestType::Add, GuestEndpointResourceType::Route);
Comment thread
FetoiuCatalin marked this conversation as resolved.

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

SendDeviceSettingsRequest(L"eth0", defaultRouteV4, ModifyRequestType::Remove, GuestEndpointResourceType::Route);
SendDeviceSettingsRequest(L"eth0", defaultRouteV6, ModifyRequestType::Remove, GuestEndpointResourceType::Route);
Comment thread
FetoiuCatalin marked this conversation as resolved.

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

VERIFY_IS_TRUE(defaultV4RouteExists);
VERIFY_IS_TRUE(defaultV6RouteExists);
VERIFY_IS_TRUE(defaultV4RouteRemoved);
VERIFY_IS_TRUE(defaultV6RouteRemoved);
}

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