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>

Ben Hillis committed Dec 1, 2025 at 21:18 UTC 4637f3758f300d932a6f3659867603a3ddec8559
5 files changed +49 -32
src/windows/common/NatNetworking.cpp
+3 -14
@@ -506,23 +506,12 @@ CATCH_LOG()
506
507 void NatNetworking::UpdateMtu()
508 {
509 - unique_interface_table interfaceTable{};
510 - THROW_IF_WIN32_ERROR(::GetIpInterfaceTable(AF_UNSPEC, &interfaceTable));
511 -
512 - ULONG minMtu = ULONG_MAX;
513 - for (ULONG index = 0; index < interfaceTable.get()->NumEntries; index++)
514 - {
515 - const auto& ipInterface = interfaceTable.get()->Table[index];
516 - if (ipInterface.Connected)
517 - {
518 - minMtu = std::min(ipInterface.NlMtu, minMtu);
519 - }
520 - }
509 + const auto minMtu = GetMinimumConnectedInterfaceMtu();
510
511 // Only send the update if the MTU changed.
523 - if (minMtu != ULONG_MAX && minMtu != m_networkMtu)
512 + if (minMtu && minMtu.value() != m_networkMtu)
513 {
525 - m_networkMtu = minMtu;
514 + m_networkMtu = minMtu.value();
515
516 hns::ModifyGuestEndpointSettingRequest<hns::NetworkInterface> notification{};
517 notification.ResourceType = hns::GuestEndpointResourceType::Interface;
src/windows/common/VirtioNetworking.cpp
+18 -17
@@ -22,6 +22,14 @@ VirtioNetworking::VirtioNetworking(
22 {
23 }
24
25 +VirtioNetworking::~VirtioNetworking()
26 +{
27 + // Unregister the network notification callback to prevent it from using the GNS channel.
28 + m_networkNotifyHandle.reset();
29 + // Stop the GNS channel to unblock any stuck communications with the guest.
30 + m_gnsChannel.Stop();
31 +}
32 +
33 void VirtioNetworking::Initialize()
34 try
35 {
@@ -271,32 +279,25 @@ void VirtioNetworking::UpdateDns(hns::DNS&& dnsSettings)
279
280 void VirtioNetworking::UpdateMtu()
281 {
274 - unique_interface_table interfaceTable{};
275 - THROW_IF_WIN32_ERROR(::GetIpInterfaceTable(AF_UNSPEC, &interfaceTable));
276 -
277 - ULONG minMtu = ULONG_MAX;
278 - for (ULONG index = 0; index < interfaceTable.get()->NumEntries; index++)
279 - {
280 - const auto& ipInterface = interfaceTable.get()->Table[index];
281 - if (ipInterface.Connected)
282 - {
283 - minMtu = std::min(ipInterface.NlMtu, minMtu);
284 - }
285 - }
282 + const auto minMtu = GetMinimumConnectedInterfaceMtu();
283
284 // Only send the update if the MTU changed.
288 - if (minMtu != ULONG_MAX && minMtu != m_networkMtu)
285 + if (minMtu && minMtu.value() != m_networkMtu)
286 {
287 + m_networkMtu = minMtu.value();
288 +
289 hns::ModifyGuestEndpointSettingRequest<hns::NetworkInterface> notification{};
290 notification.ResourceType = hns::GuestEndpointResourceType::Interface;
291 notification.RequestType = hns::ModifyRequestType::Update;
293 - notification.Settings.NlMtu = m_networkMtu;
292 notification.Settings.Connected = true;
293 + notification.Settings.NlMtu = m_networkMtu;
294
296 - WSL_LOG("VirtioNetworking::UpdateMtu", TraceLoggingValue(m_networkMtu, "VirtioMtu"));
295 + WSL_LOG(
296 + "VirtioNetworking::UpdateMtu",
297 + TraceLoggingValue(m_adapterId, "endpointId"),
298 + TraceLoggingValue(m_networkMtu, "virtioMtu"));
299
298 - // TODO: Why was this commented ?
299 - // m_gnsChannel.SendHnsNotification(ToJsonW(notification).c_str(), m_endpointId);
300 + m_gnsChannel.SendHnsNotification(ToJsonW(notification).c_str(), m_adapterId);
301 }
302 }
303
src/windows/common/VirtioNetworking.h
+1 -1
@@ -14,7 +14,7 @@ class VirtioNetworking : public INetworkingEngine
14 {
15 public:
16 VirtioNetworking(GnsChannel&& gnsChannel, bool enableLocalhostRelay, std::shared_ptr<GuestDeviceManager> guestDeviceManager, wil::shared_handle userToken);
17 - ~VirtioNetworking() = default;
17 + ~VirtioNetworking();
18
19 // Note: This class cannot be moved because m_networkNotifyHandle captures a 'this' pointer.
20 VirtioNetworking(const VirtioNetworking&) = delete;
src/windows/common/WslCoreNetworkingSupport.cpp
+22
@@ -248,3 +248,25 @@ wsl::core::networking::EphemeralHcnEndpoint wsl::core::networking::CreateEphemer
248
249 return endpoint;
250 }
251 +
252 +std::optional<ULONG> wsl::core::networking::GetMinimumConnectedInterfaceMtu() noexcept
253 +{
254 + std::optional<ULONG> minMtu{};
255 + try
256 + {
257 + unique_interface_table interfaceTable{};
258 + THROW_IF_WIN32_ERROR(::GetIpInterfaceTable(AF_UNSPEC, &interfaceTable));
259 +
260 + for (ULONG index = 0; index < interfaceTable.get()->NumEntries; index++)
261 + {
262 + const auto& ipInterface = interfaceTable.get()->Table[index];
263 + if (ipInterface.Connected)
264 + {
265 + minMtu = std::min(minMtu.value_or(ipInterface.NlMtu), ipInterface.NlMtu);
266 + }
267 + }
268 + }
269 + CATCH_LOG()
270 +
271 + return minMtu;
272 +}
src/windows/common/WslCoreNetworkingSupport.h
+5
@@ -456,6 +456,11 @@ std::vector<wsl::core::networking::CurrentInterfaceInformation> EnumerateConnect
456
457 bool IsMetered(ABI::Windows::Networking::Connectivity::NetworkCostType cost) noexcept;
458
459 +/// <summary>
460 +/// Gets the minimum MTU across all connected network interfaces.
461 +/// </summary>
462 +std::optional<ULONG> GetMinimumConnectedInterfaceMtu() noexcept;
463 +
464 /// <summary>
465 /// This instance acts as an IP_ADAPTER_ADDRESS pointer.
466 /// </summary>