Skip to content

Commit 218b71b

Browse files
benhillisBen Hillis
andauthored
Resolve and pass gateway MAC address to virtio net device (#14386)
Use ResolveIpNetEntry2 to look up the host gateway's MAC address and pass it as the gateway_mac device option to the virtio net adapter. This allows the guest to see the real gateway MAC instead of the default consomme address. Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
1 parent f3024dc commit 218b71b

File tree

3 files changed

+46
-21
lines changed

3 files changed

+46
-21
lines changed

src/windows/common/VirtioNetworking.cpp

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -172,32 +172,20 @@ try
172172
// Query current networking information before acquiring the lock.
173173
auto networkSettings = GetHostEndpointSettings();
174174

175-
// TODO: Determine gateway MAC address
176175
std::wstring device_options;
177-
auto client_ip = networkSettings->PreferredIpAddress.AddressString;
178-
if (!client_ip.empty())
179-
{
180-
device_options += L"client_ip=" + client_ip;
181-
}
182-
183-
if (!networkSettings->MacAddress.empty())
184-
{
185-
if (!device_options.empty())
176+
auto appendOption = [&device_options](std::wstring_view key, std::wstring_view value) {
177+
if (!value.empty())
186178
{
187-
device_options += L';';
179+
std::format_to(std::back_inserter(device_options), L"{}{}={}", device_options.empty() ? L"" : L";", key, value);
188180
}
189-
device_options += L"client_mac=" + networkSettings->MacAddress;
190-
}
181+
};
182+
183+
appendOption(L"client_ip", networkSettings->PreferredIpAddress.AddressString);
184+
appendOption(L"client_mac", networkSettings->MacAddress);
191185

192186
std::wstring default_route = networkSettings->GetBestGatewayAddressString();
193-
if (!default_route.empty())
194-
{
195-
if (!device_options.empty())
196-
{
197-
device_options += L';';
198-
}
199-
device_options += L"gateway_ip=" + default_route;
200-
}
187+
appendOption(L"gateway_ip", default_route);
188+
appendOption(L"gateway_mac", networkSettings->GetBestGatewayMacAddress());
201189

202190
networking::DnsInfo currentDns{};
203191
if (WI_IsFlagSet(m_flags, VirtioNetworkingFlags::DnsTunneling))

src/windows/common/WslCoreNetworkEndpointSettings.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,38 @@ std::shared_ptr<wsl::core::networking::NetworkSettings> wsl::core::networking::G
9494
return std::make_shared<NetworkSettings>(
9595
bestInterface->NetworkGuid, address, route, macAddress, bestInterface->IfIndex, bestInterface->IfType);
9696
}
97+
98+
std::wstring wsl::core::networking::NetworkSettings::GetBestGatewayMacAddress() const
99+
{
100+
auto gatewayAddress = GetBestGatewayAddress();
101+
if (gatewayAddress.si_family != AF_INET)
102+
{
103+
return {};
104+
}
105+
106+
MIB_IPNET_ROW2 ipNetRow{};
107+
ipNetRow.Address = gatewayAddress;
108+
ipNetRow.InterfaceIndex = InterfaceIndex;
109+
110+
const auto result = ResolveIpNetEntry2(&ipNetRow, nullptr);
111+
if (result != NO_ERROR)
112+
{
113+
LOG_HR_MSG(HRESULT_FROM_WIN32(result), "Failed to resolve gateway MAC address");
114+
return {};
115+
}
116+
117+
if (ipNetRow.PhysicalAddressLength != 6)
118+
{
119+
return {};
120+
}
121+
122+
return wsl::shared::string::FormatMacAddress(
123+
wsl::shared::string::MacAddress{
124+
ipNetRow.PhysicalAddress[0],
125+
ipNetRow.PhysicalAddress[1],
126+
ipNetRow.PhysicalAddress[2],
127+
ipNetRow.PhysicalAddress[3],
128+
ipNetRow.PhysicalAddress[4],
129+
ipNetRow.PhysicalAddress[5]},
130+
L'-');
131+
}

src/windows/common/WslCoreNetworkEndpointSettings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ struct NetworkSettings
318318
return {};
319319
}
320320

321+
std::wstring GetBestGatewayMacAddress() const;
322+
321323
std::wstring IpAddressesString() const
322324
{
323325
return std::accumulate(std::begin(IpAddresses), std::end(IpAddresses), std::wstring{}, [](const std::wstring& prev, const auto& addr) {

0 commit comments

Comments
 (0)