@samitouri / QOSAMI-WSL / commits / bf791e06

virtionet: send runtime updates to network device (#41263)

* net: virtionet: send runtime updates to network device * remove BOM * Avoid redundant virtio-net updates Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Brian Perkins <bperkins@ntdev.microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Brian Perkins committed Aug 6, 2026 at 09:41 UTC bf791e06661bf2ad56fe8c5d8cd7c5f56154205f
3 files changed +39 -5
packages.config
+1 -1
@@ -19,7 +19,7 @@
19 <package id="Microsoft.WSL.bsdtar" version="0.0.2-2" />
20 <package id="Microsoft.WSL.Dependencies.amd64fre" version="10.0.27820.1000-250318-1700.rs-base2-hyp" targetFramework="native" />
21 <package id="Microsoft.WSL.Dependencies.arm64fre" version="10.0.27820.1000-250318-1700.rs-base2-hyp" targetFramework="native" />
22 - <package id="Microsoft.WSL.DeviceHost" version="1.2.54-0" />
22 + <package id="Microsoft.WSL.DeviceHost" version="1.2.56-0" />
23 <package id="Microsoft.WSL.Kernel" version="6.18.35.2-1" targetFramework="native" />
24 <package id="Microsoft.WSL.LinuxSdk" version="1.23.0" targetFramework="native" />
25 <package id="Microsoft.WSL.TestData" version="0.5.0" />
src/windows/common/ConsommeNetworking.cpp
+36 -4
@@ -67,6 +67,28 @@ IpAddress ToIpAddress(const SOCKADDR_INET& address)
67 return result;
68 }
69
70 +bool AreEqual(const IpAddress& left, const IpAddress& right)
71 +{
72 + return left.family == right.family && std::equal(std::begin(left.bytes), std::end(left.bytes), std::begin(right.bytes));
73 +}
74 +
75 +bool AreEqual(const std::vector<IpAddress>& left, const std::vector<IpAddress>& right)
76 +{
77 + return std::ranges::equal(
78 + left, right, [](const auto& leftAddress, const auto& rightAddress) { return AreEqual(leftAddress, rightAddress); });
79 +}
80 +
81 +bool AreEqual(const WslVirtioNetConfig& left, const WslVirtioNetConfig& right)
82 +{
83 + return left.clientIp.value == right.clientIp.value && left.hasClientIpv6 == right.hasClientIpv6 &&
84 + std::equal(std::begin(left.clientIpv6.bytes), std::end(left.clientIpv6.bytes), std::begin(right.clientIpv6.bytes)) &&
85 + std::equal(std::begin(left.clientMac.bytes), std::end(left.clientMac.bytes), std::begin(right.clientMac.bytes)) &&
86 + left.gatewayIp.value == right.gatewayIp.value &&
87 + std::equal(std::begin(left.gatewayMac.bytes), std::end(left.gatewayMac.bytes), std::begin(right.gatewayMac.bytes)) &&
88 + std::equal(std::begin(left.gatewayMacIpv6.bytes), std::end(left.gatewayMacIpv6.bytes), std::begin(right.gatewayMacIpv6.bytes)) &&
89 + left.netmask.value == right.netmask.value;
90 +}
91 +
92 std::vector<IpAddress> ToIpAddresses(const DnsInfo& dns)
93 {
94 std::vector<IpAddress> result;
@@ -316,12 +338,13 @@ void ConsommeNetworking::RefreshGuestConnection()
338 }
339
340 const auto minMtu = GetMinimumConnectedInterfaceMtu();
319 - const auto virtioNetConfig = BuildVirtioNetConfig(networkSettings, WI_IsFlagSet(m_flags, ConsommeNetworkingFlags::Ipv6));
341 + auto virtioNetConfig = BuildVirtioNetConfig(networkSettings, WI_IsFlagSet(m_flags, ConsommeNetworkingFlags::Ipv6));
342 + auto nameservers = ToIpAddresses(currentDns);
343
344 // Acquire the lock and perform device updates.
345 auto lock = m_lock.lock_exclusive();
346
324 - // Add virtio net adapter to guest. Subsequent address/route/DNS changes are sent through GNS notifications below.
347 + // Add the virtio net adapter to the guest, or update its runtime configuration.
348 if (!m_adapterId.has_value())
349 {
350 WSL_LOG(
@@ -330,9 +353,18 @@ void ConsommeNetworking::RefreshGuestConnection()
353 TraceLoggingValue(networkSettings->PreferredIpAddress.PrefixLength, "PrefixLength"),
354 TraceLoggingValue(default_route.c_str(), "GatewayIp"),
355 TraceLoggingValue(networkSettings->PreferredIpv6Address.AddressString.c_str(), "ClientIpv6"));
333 - m_adapterId =
334 - m_guestDeviceManager->AddVirtioNetDevice(c_eth0DeviceName, virtioNetConfig, ToIpAddresses(currentDns), m_userToken.get());
356 + m_adapterId = m_guestDeviceManager->AddVirtioNetDevice(c_eth0DeviceName, virtioNetConfig, nameservers, m_userToken.get());
357 }
358 + else if (!m_virtioNetConfig.has_value() || !AreEqual(m_virtioNetConfig.value(), virtioNetConfig) || !AreEqual(m_virtioNetNameservers, nameservers))
359 + {
360 + IpAddress emptyNameserver{};
361 + auto* nameserversData = nameservers.empty() ? &emptyNameserver : nameservers.data();
362 + const auto device = m_guestDeviceManager->GetVirtioNetDevice(c_eth0DeviceName);
363 + THROW_IF_FAILED(device->Update(&virtioNetConfig, gsl::narrow_cast<UINT32>(nameservers.size()), nameserversData));
364 + }
365 +
366 + m_virtioNetConfig = virtioNetConfig;
367 + m_virtioNetNameservers = std::move(nameservers);
368
369 UpdateIpv4Address(networkSettings->PreferredIpAddress);
370 if (WI_IsFlagSet(m_flags, ConsommeNetworkingFlags::Ipv6))
src/windows/common/ConsommeNetworking.h
+2
@@ -70,6 +70,8 @@ private:
70 LPCWSTR m_dnsOptions = nullptr;
71 std::optional<GUID> m_localhostAdapterId;
72 std::optional<GUID> m_adapterId;
73 + std::optional<WslVirtioNetConfig> m_virtioNetConfig;
74 + std::vector<IpAddress> m_virtioNetNameservers;
75
76 ULONG m_networkMtu = 0;
77 networking::EndpointIpAddress m_trackedIpv4Address{};