On Thu, Feb 12, 2026 at 14:36:37 +0100, Michal Prívozník wrote:
On 2/10/26 18:40, Peter Krempa wrote:
On Fri, Feb 06, 2026 at 14:52:37 +0100, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
The virDomainInterfaceAddresses() API accepts @source argument, but since this is hyperv, we can't really use _SRC_LEASE (we didn't spawn any dnsmasq there), not _SRC_ARP. The only source that's more or less usable is _SRC_AGENT. Okay, there's no QEMU guest agent running, but hyperv has its own guest agent. In my testing (with Linux guest) I had to install 'hyperv' package and then enable 'hv_kvp_daemon.service'. After that, Msvm_GuestNetworkAdapterConfiguration struct [1] contained guest IP addresses.
There's one caveat though: the interface name (virDomainInterface::name). We don't fetch that one even for hypervDomainGetXMLDesc() case. And there's no <target dev=''/> either nor device alias (v12.0.0-43-g4009126f17). So just put InstanceID there for now, which is this long path, with some UUIDs, e.g.:
Microsoft:5C58E5F2-946E-490F-B81D-6E2A7328640D\C85554E0-2B3B-487C-A557-D230BFF5F9E6\
But hey, at least it's unique.
1: https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-guestnetworka... Resolves: https://issues.redhat.com/browse/RHEL-145306 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> ---
Admittedly, the 'virsh domifaddr' output is misaligned after this, but I'll post a separate patch for that.
Disclaimer: I have absolutely no idea about the hyperv specific bits.
src/hyperv/hyperv_driver.c | 169 ++++++++++++++++++++++++++ src/hyperv/hyperv_wmi_generator.input | 12 ++ 2 files changed, 181 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index fbc76544df..c25cb91c13 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -3654,6 +3654,174 @@ hypervDomainSendKey(virDomainPtr domain, unsigned int codeset, }
+static int +hypervDomainInterfaceAddressesParseOne(hypervPrivate *priv, + Msvm_EthernetPortAllocationSettingData *net, + virDomainInterfacePtr *oneIfaceRet) +{ + g_autoptr(virDomainInterface) iface = NULL; + g_autoptr(Msvm_SyntheticEthernetPortSettingData) sepsd = NULL; + g_autoptr(Msvm_GuestNetworkAdapterConfiguration) aConfig = NULL; + g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER; + virMacAddr macAddr = { 0 }; + char macAddrStr[VIR_MAC_STRING_BUFLEN] = { 0 }; + + VIR_DEBUG("Parsing ethernet adapter '%s'", net->data->InstanceID); + + iface = g_new0(virDomainInterface, 1); + iface->name = g_strdup(net->data->InstanceID); + + if (hypervDomainDefParseEthernetAdapterMAC(priv, net, &macAddr) < 0) + return -1; + + iface->hwaddr = g_strdup(virMacAddrFormat(&macAddr, macAddrStr)); + + virBufferAsprintf(&query, + "ASSOCIATORS OF {%s} " + "WHERE AssocClass=Msvm_SettingDataComponent " + "ResultClass=Msvm_GuestNetworkAdapterConfiguration", + net->data->Parent);
'query' is unused after this.
It's not.
+ + if (hypervGetWmiClass(Msvm_GuestNetworkAdapterConfiguration, &aConfig) < 0)
This ^^ is actually a macro:
#define hypervGetWmiClass(type, class) \ hypervGetWmiClassList(priv, type ## _WmiInfo, &query, (hypervObject **)class)
Ewwww.
+ return -1;
[...]
+ while (entry) { + virDomainInterfacePtr oneIface = NULL; + + if (hypervDomainInterfaceAddressesParseOne(priv, entry, &oneIface) < 0) + return -1;
If this fails ....
+ + if (oneIface) + VIR_APPEND_ELEMENT(*ifaces, nifaces, oneIface);
... after this was partially filled, the caller has no way of figuring out how many entries to free. This function should cleanup after itself internally.
Ah, okay. Will post v2.
No need to; just fix it and use Reviewed-by: Peter Krempa <pkrempa@redhat.com>