Co-authored-by: Sri Ramanujam <sramanujam(a)datto.com>
Signed-off-by: Matt Coleman <matt(a)datto.com>
---
src/hyperv/hyperv_driver.c | 113 ++++++++++++++++++++++++++
src/hyperv/hyperv_wmi.c | 20 +++++
src/hyperv/hyperv_wmi.h | 8 ++
src/hyperv/hyperv_wmi_classes.h | 12 +++
src/hyperv/hyperv_wmi_generator.input | 109 +++++++++++++++++++++++++
5 files changed, 262 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 9394794c8f..ca75de98a9 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1388,6 +1388,107 @@ hypervDomainDefParseSerial(virDomainDefPtr def,
Msvm_ResourceAllocationSettingDa
}
+static int
+hypervDomainDefParseEthernetAdapter(virDomainDefPtr def,
+ Msvm_EthernetPortAllocationSettingData *net,
+ hypervPrivate *priv)
+{
+ virDomainNetDefPtr ndef = NULL;
+ g_autoptr(Msvm_SyntheticEthernetPortSettingData) sepsd = NULL;
+ g_autoptr(Msvm_VirtualEthernetSwitch) vSwitch = NULL;
+ char **switchConnection = NULL;
+ g_autofree char *switchConnectionEscaped = NULL;
+ char *sepsdPATH = NULL;
+ g_autofree char *sepsdEscaped = NULL;
+ g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER;
+
+ VIR_DEBUG("Parsing ethernet adapter '%s'",
net->data->InstanceID);
+
+ ndef = g_new0(virDomainNetDef, 1);
+
+ ndef->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
+
+ /*
+ * If there's no switch port connection or the EnabledState is disabled,
+ * then the adapter isn't hooked up to anything and we don't have to
+ * do anything more.
+ */
+ switchConnection = net->data->HostResource.data;
+ if (net->data->HostResource.count < 1 || !*switchConnection ||
+ net->data->EnabledState ==
MSVM_ETHERNETPORTALLOCATIONSETTINGDATA_ENABLEDSTATE_DISABLED) {
+ VIR_DEBUG("Adapter not connected to switch");
+ return 0;
+ }
+
+ /*
+ * Now we retrieve the associated Msvm_SyntheticEthernetPortSettingData and
+ * Msvm_VirtualEthernetSwitch objects and use them to build the XML definition.
+ */
+
+ /* begin by getting the Msvm_SyntheticEthernetPortSettingData object */
+ sepsdPATH = net->data->Parent;
+ sepsdEscaped = virStringReplace(sepsdPATH, "\\", "\\\\");
+ virBufferAsprintf(&query,
+ MSVM_SYNTHETICETHERNETPORTSETTINGDATA_WQL_SELECT "WHERE __PATH
= '%s'",
+ sepsdEscaped);
+
+ if (hypervGetWmiClass(Msvm_SyntheticEthernetPortSettingData, &sepsd) < 0)
+ return -1;
+
+ if (!sepsd) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not retrieve
NIC settings"));
+ return -1;
+ }
+
+ /* set mac address */
+ if (virMacAddrParseHex(sepsd->data->Address, &ndef->mac) < 0)
+ return -1;
+
+ /* now we get the Msvm_VirtualEthernetSwitch */
+ virBufferFreeAndReset(&query);
+ switchConnectionEscaped = virStringReplace(*switchConnection, "\\",
"\\\\");
+ virBufferAsprintf(&query,
+ MSVM_VIRTUALETHERNETSWITCH_WQL_SELECT "WHERE __PATH =
'%s'",
+ switchConnectionEscaped);
+
+ if (hypervGetWmiClass(Msvm_VirtualEthernetSwitch, &vSwitch) < 0)
+ return -1;
+
+ if (!vSwitch) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not retrieve
virtual switch"));
+ return -1;
+ }
+
+ /* get bridge name */
+ ndef->data.bridge.brname = g_strdup(vSwitch->data->Name);
+
+ if (VIR_APPEND_ELEMENT(def->nets, def->nnets, ndef) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not append
definition to domain"));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+hypervDomainDefParseEthernet(virDomainPtr domain,
+ virDomainDefPtr def,
+ Msvm_EthernetPortAllocationSettingData *nets)
+{
+ Msvm_EthernetPortAllocationSettingData *entry = nets;
+ hypervPrivate *priv = domain->conn->privateData;
+
+ while (entry) {
+ if (hypervDomainDefParseEthernetAdapter(def, entry, priv) < 0)
+ return -1;
+
+ entry = entry->next;
+ }
+
+ return 0;
+}
+
+
/*
* Driver functions
*/
@@ -2249,6 +2350,7 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
g_autoptr(Msvm_StorageAllocationSettingData) sasd = NULL;
g_autoptr(Msvm_SerialPortSettingData) spsd = NULL;
Msvm_ResourceAllocationSettingData *serialDevices = NULL;
+ g_autoptr(Msvm_EthernetPortAllocationSettingData) nets = NULL;
virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL);
@@ -2290,6 +2392,10 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
if (hypervGetSerialPortSD(priv, virtualSystemSettingData->data->InstanceID,
&spsd) < 0)
return NULL;
+ if (hypervGetEthernetPortAllocationSD(priv,
+
virtualSystemSettingData->data->InstanceID, &nets) < 0)
+ return NULL;
+
/* Fill struct */
def->virtType = VIR_DOMAIN_VIRT_HYPERV;
@@ -2351,6 +2457,10 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
def->controllers = g_new0(virDomainControllerDefPtr, 5);
def->ncontrollers = 0;
+ /* 8 synthetic + 4 legacy NICs */
+ def->nets = g_new0(virDomainNetDefPtr, 12);
+ def->nnets = 0;
+
if (hypervDomainDefParseStorage(priv, def, rasd, sasd) < 0)
return NULL;
@@ -2362,6 +2472,9 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
if (hypervDomainDefParseSerial(def, serialDevices) < 0)
return NULL;
+ if (hypervDomainDefParseEthernet(domain, def, nets) < 0)
+ return NULL;
+
/* XXX xmlopts must be non-NULL */
return virDomainDefFormat(def, NULL, virDomainDefFormatConvertXMLFlags(flags));
}
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index f5f0797605..4c1bd5e0d2 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -1498,6 +1498,26 @@ hypervGetSerialPortSD(hypervPrivate *priv,
}
+int
+hypervGetSyntheticEthernetPortSD(hypervPrivate *priv,
+ const char *id,
+ Msvm_SyntheticEthernetPortSettingData **data)
+{
+ hypervGetSettingData(Msvm_SyntheticEthernetPortSettingData, id, data);
+ return 0;
+}
+
+
+int
+hypervGetEthernetPortAllocationSD(hypervPrivate *priv,
+ const char *id,
+ Msvm_EthernetPortAllocationSettingData **data)
+{
+ hypervGetSettingData(Msvm_EthernetPortAllocationSettingData, id, data);
+ return 0;
+}
+
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Msvm_VirtualSystemManagementService
*/
diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h
index 2b0d0e4a3f..6021a46f3e 100644
--- a/src/hyperv/hyperv_wmi.h
+++ b/src/hyperv/hyperv_wmi.h
@@ -258,6 +258,14 @@ int hypervGetSerialPortSD(hypervPrivate *priv,
const char *id,
Msvm_SerialPortSettingData **data);
+int hypervGetSyntheticEthernetPortSD(hypervPrivate *priv,
+ const char *id,
+ Msvm_SyntheticEthernetPortSettingData **data);
+
+int hypervGetEthernetPortAllocationSD(hypervPrivate *priv,
+ const char *id,
+ Msvm_EthernetPortAllocationSettingData **data);
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Msvm_VirtualSystemManagementService
*/
diff --git a/src/hyperv/hyperv_wmi_classes.h b/src/hyperv/hyperv_wmi_classes.h
index 2f813bedb3..eea24235a5 100644
--- a/src/hyperv/hyperv_wmi_classes.h
+++ b/src/hyperv/hyperv_wmi_classes.h
@@ -119,6 +119,18 @@ enum _Msvm_ResourceAllocationSettingData_ResourceType {
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_EthernetPortAllocationSettingData
+ */
+
+/*
https://docs.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-ethernetpor...
*/
+enum _Msvm_EthernetPortAllocationSettingData_EnabledState {
+ MSVM_ETHERNETPORTALLOCATIONSETTINGDATA_ENABLEDSTATE_ENABLED = 2,
+ MSVM_ETHERNETPORTALLOCATIONSETTINGDATA_ENABLEDSTATE_DISABLED = 3,
+};
+
+
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* WMI
*/
diff --git a/src/hyperv/hyperv_wmi_generator.input
b/src/hyperv/hyperv_wmi_generator.input
index 765ffba169..df240361e6 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -827,3 +827,112 @@ class Msvm_StorageAllocationSettingData
string IOPSAllocationUnits
boolean PersistentReservationsSupported
end
+
+
+class Msvm_SyntheticEthernetPortSettingData
+ string InstanceID
+ string Caption
+ string Description
+ string ElementName
+ uint16 ResourceType
+ string OtherResourceType
+ string ResourceSubType
+ string PoolID
+ uint16 ConsumerVisibility
+ string HostResource[]
+ string AllocationUnits
+ uint64 VirtualQuantity
+ uint64 Reservation
+ uint64 Limit
+ uint32 Weight
+ boolean AutomaticAllocation
+ boolean AutomaticDeallocation
+ string Parent
+ string Connection[]
+ string Address
+ uint16 MappingBehavior
+ string AddressOnParent
+ string VirtualQuantityUnits
+ uint16 DesiredVLANEndpointMode
+ string OtherEndpointMode
+ string VirtualSystemIdentifiers[]
+# DeviceNamingEnabled and AllowPacketDirect are not present in Windows Server 2012R2.
+# They were added in Windows 10 and Windows Server 2016.
+# They have been omitted to retain compatibility with Windows Server 2012R2.
+# boolean DeviceNamingEnabled
+# boolean AllowPacketDirect
+ boolean StaticMacAddress
+ boolean ClusterMonitored
+end
+
+
+class Msvm_EthernetPortAllocationSettingData
+ string InstanceID
+ string Caption
+ string Description
+ string ElementName
+ uint16 ResourceType
+ string OtherResourceType
+ string ResourceSubType
+ string PoolID
+ uint16 ConsumerVisibility
+ string HostResource[]
+ string AllocationUnits
+ uint64 VirtualQuantity
+ uint64 Reservation
+ uint64 Limit
+ uint32 Weight
+ boolean AutomaticAllocation
+ boolean AutomaticDeallocation
+ string Parent
+ string Connection[]
+ string Address
+ uint16 MappingBehavior
+ string AddressOnParent
+ string VirtualQuantityUnits
+ uint16 DesiredVLANEndpointMode
+ string OtherEndpointMode
+ uint16 EnabledState
+ string RequiredFeatures[]
+ string RequiredFeatureHints[]
+ string TestReplicaPoolID
+ string TestReplicaSwitchName
+end
+
+
+class Msvm_VirtualEthernetSwitch
+ string InstanceID
+ string Caption
+ string Description
+ string ElementName
+ datetime InstallDate
+ uint16 OperationalStatus[]
+ string StatusDescriptions[]
+ string Status
+ uint16 HealthState
+ uint16 CommunicationStatus
+ uint16 DetailedStatus
+ uint16 OperatingStatus
+ uint16 PrimaryStatus
+ uint16 EnabledState
+ string OtherEnabledState
+ uint16 RequestedState
+ uint16 EnabledDefault
+ datetime TimeOfLastStateChange
+ uint16 AvailableRequestedStates[]
+ uint16 TransitioningToState
+ string CreationClassName
+ string Name
+ string PrimaryOwnerName
+ string PrimaryOwnerContact
+ string Roles[]
+ string NameFormat
+ string OtherIdentifyingInfo[]
+ string IdentifyingDescriptions[]
+ uint16 Dedicated[]
+ string OtherDedicatedDescriptions[]
+ uint16 ResetCapability
+ uint16 PowerManagementCapabilities[]
+ uint32 MaxVMQOffloads
+ uint32 MaxIOVOffloads
+end
--
2.30.0