virtio networking: fix two minor issues (#13810)

* virtio networking: fix two minor issues

* Update src/windows/common/VirtioNetworking.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Ben Hillis 2025-12-01 21:18:09 -08:00 committed by GitHub
parent 0f6f3c1e02
commit 4637f3758f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 32 deletions

View File

@ -506,23 +506,12 @@ CATCH_LOG()
void NatNetworking::UpdateMtu() void NatNetworking::UpdateMtu()
{ {
unique_interface_table interfaceTable{}; const auto minMtu = GetMinimumConnectedInterfaceMtu();
THROW_IF_WIN32_ERROR(::GetIpInterfaceTable(AF_UNSPEC, &interfaceTable));
ULONG minMtu = ULONG_MAX;
for (ULONG index = 0; index < interfaceTable.get()->NumEntries; index++)
{
const auto& ipInterface = interfaceTable.get()->Table[index];
if (ipInterface.Connected)
{
minMtu = std::min(ipInterface.NlMtu, minMtu);
}
}
// Only send the update if the MTU changed. // Only send the update if the MTU changed.
if (minMtu != ULONG_MAX && minMtu != m_networkMtu) if (minMtu && minMtu.value() != m_networkMtu)
{ {
m_networkMtu = minMtu; m_networkMtu = minMtu.value();
hns::ModifyGuestEndpointSettingRequest<hns::NetworkInterface> notification{}; hns::ModifyGuestEndpointSettingRequest<hns::NetworkInterface> notification{};
notification.ResourceType = hns::GuestEndpointResourceType::Interface; notification.ResourceType = hns::GuestEndpointResourceType::Interface;

View File

@ -22,6 +22,14 @@ VirtioNetworking::VirtioNetworking(
{ {
} }
VirtioNetworking::~VirtioNetworking()
{
// Unregister the network notification callback to prevent it from using the GNS channel.
m_networkNotifyHandle.reset();
// Stop the GNS channel to unblock any stuck communications with the guest.
m_gnsChannel.Stop();
}
void VirtioNetworking::Initialize() void VirtioNetworking::Initialize()
try try
{ {
@ -271,32 +279,25 @@ void VirtioNetworking::UpdateDns(hns::DNS&& dnsSettings)
void VirtioNetworking::UpdateMtu() void VirtioNetworking::UpdateMtu()
{ {
unique_interface_table interfaceTable{}; const auto minMtu = GetMinimumConnectedInterfaceMtu();
THROW_IF_WIN32_ERROR(::GetIpInterfaceTable(AF_UNSPEC, &interfaceTable));
ULONG minMtu = ULONG_MAX;
for (ULONG index = 0; index < interfaceTable.get()->NumEntries; index++)
{
const auto& ipInterface = interfaceTable.get()->Table[index];
if (ipInterface.Connected)
{
minMtu = std::min(ipInterface.NlMtu, minMtu);
}
}
// Only send the update if the MTU changed. // Only send the update if the MTU changed.
if (minMtu != ULONG_MAX && minMtu != m_networkMtu) if (minMtu && minMtu.value() != m_networkMtu)
{ {
m_networkMtu = minMtu.value();
hns::ModifyGuestEndpointSettingRequest<hns::NetworkInterface> notification{}; hns::ModifyGuestEndpointSettingRequest<hns::NetworkInterface> notification{};
notification.ResourceType = hns::GuestEndpointResourceType::Interface; notification.ResourceType = hns::GuestEndpointResourceType::Interface;
notification.RequestType = hns::ModifyRequestType::Update; notification.RequestType = hns::ModifyRequestType::Update;
notification.Settings.NlMtu = m_networkMtu;
notification.Settings.Connected = true; notification.Settings.Connected = true;
notification.Settings.NlMtu = m_networkMtu;
WSL_LOG("VirtioNetworking::UpdateMtu", TraceLoggingValue(m_networkMtu, "VirtioMtu")); WSL_LOG(
"VirtioNetworking::UpdateMtu",
TraceLoggingValue(m_adapterId, "endpointId"),
TraceLoggingValue(m_networkMtu, "virtioMtu"));
// TODO: Why was this commented ? m_gnsChannel.SendHnsNotification(ToJsonW(notification).c_str(), m_adapterId);
// m_gnsChannel.SendHnsNotification(ToJsonW(notification).c_str(), m_endpointId);
} }
} }

View File

@ -14,7 +14,7 @@ class VirtioNetworking : public INetworkingEngine
{ {
public: public:
VirtioNetworking(GnsChannel&& gnsChannel, bool enableLocalhostRelay, std::shared_ptr<GuestDeviceManager> guestDeviceManager, wil::shared_handle userToken); VirtioNetworking(GnsChannel&& gnsChannel, bool enableLocalhostRelay, std::shared_ptr<GuestDeviceManager> guestDeviceManager, wil::shared_handle userToken);
~VirtioNetworking() = default; ~VirtioNetworking();
// Note: This class cannot be moved because m_networkNotifyHandle captures a 'this' pointer. // Note: This class cannot be moved because m_networkNotifyHandle captures a 'this' pointer.
VirtioNetworking(const VirtioNetworking&) = delete; VirtioNetworking(const VirtioNetworking&) = delete;

View File

@ -248,3 +248,25 @@ wsl::core::networking::EphemeralHcnEndpoint wsl::core::networking::CreateEphemer
return endpoint; return endpoint;
} }
std::optional<ULONG> wsl::core::networking::GetMinimumConnectedInterfaceMtu() noexcept
{
std::optional<ULONG> minMtu{};
try
{
unique_interface_table interfaceTable{};
THROW_IF_WIN32_ERROR(::GetIpInterfaceTable(AF_UNSPEC, &interfaceTable));
for (ULONG index = 0; index < interfaceTable.get()->NumEntries; index++)
{
const auto& ipInterface = interfaceTable.get()->Table[index];
if (ipInterface.Connected)
{
minMtu = std::min(minMtu.value_or(ipInterface.NlMtu), ipInterface.NlMtu);
}
}
}
CATCH_LOG()
return minMtu;
}

View File

@ -456,6 +456,11 @@ std::vector<wsl::core::networking::CurrentInterfaceInformation> EnumerateConnect
bool IsMetered(ABI::Windows::Networking::Connectivity::NetworkCostType cost) noexcept; bool IsMetered(ABI::Windows::Networking::Connectivity::NetworkCostType cost) noexcept;
/// <summary>
/// Gets the minimum MTU across all connected network interfaces.
/// </summary>
std::optional<ULONG> GetMinimumConnectedInterfaceMtu() noexcept;
/// <summary> /// <summary>
/// This instance acts as an IP_ADAPTER_ADDRESS pointer. /// This instance acts as an IP_ADAPTER_ADDRESS pointer.
/// </summary> /// </summary>