Implement the .domainInterfaceAddresses hypervisor API, although only
functional for the VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT source.
Signed-off-by: Pino Toscano <ptoscano@redhat.com>
---
docs/drvesx.html.in | 4 ++
src/esx/esx_driver.c | 166 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 170 insertions(+)
diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in
index 465daafc2e..c4a2ae78a8 100644
--- a/docs/drvesx.html.in
+++ b/docs/drvesx.html.in
@@ -792,6 +792,10 @@ Enter administrator password for example-vcenter.com:
<li>
<code>virDomainGetHostname</code>
</li>
+ <li>
+ <code>virDomainInterfaceAddresses</code> (only for the
+ <code>VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT</code> source)
+ </li>
<li>
<code>virDomainReboot</code>
</li>
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 39e3faeb8f..73b8f32f1b 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -5122,6 +5122,171 @@ esxDomainGetHostname(virDomainPtr domain,
}
+static int
+esxParseIPAddress(const char *ipAddress, int prefixLength,
+ virDomainIPAddress *addr)
+{
+ virSocketAddr tmp_addr;
+ virIPAddrType addr_type;
+
+ if (virSocketAddrParseAny(&tmp_addr, ipAddress, AF_UNSPEC, false) <= 0)
+ return 0;
+
+ switch (VIR_SOCKET_ADDR_FAMILY(&tmp_addr)) {
+ case AF_INET:
+ addr_type = VIR_IP_ADDR_TYPE_IPV4;
+ break;
+ case AF_INET6:
+ addr_type = VIR_IP_ADDR_TYPE_IPV6;
+ break;
+ default:
+ return 0;
+ }
+
+ addr->type = addr_type;
+ addr->addr = g_strdup(ipAddress);
+ addr->prefix = prefixLength;
+
+ return 1;
+}
+
+
+static int
+esxDomainInterfaceAddresses(virDomainPtr domain,
+ virDomainInterfacePtr **ifaces,
+ unsigned int source,
+ unsigned int flags)
+{
+ int result = -1;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *virtualMachine = NULL;
+ esxVI_VirtualMachinePowerState powerState;
+ esxVI_DynamicProperty *dynamicProperty;
+ esxVI_GuestNicInfo *guestNicInfoList = NULL;
+ esxVI_GuestNicInfo *guestNicInfo = NULL;
+ virDomainInterfacePtr *ifaces_ret = NULL;
+ size_t ifaces_count = 0;
+ size_t i;
+ int ret;
+
+ virCheckFlags(0, -1);
+ if (source != VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
+ _("Unknown IP address data source %d"),
+ source);
+ return -1;
+ }
+
+ if (esxVI_EnsureSession(priv->primary) < 0)
+ return -1;
+
+ if (esxVI_String_AppendValueListToList(&propertyNameList,
+ "runtime.powerState\0"
+ "guest.net") < 0 ||
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
+ propertyNameList, &virtualMachine,
+ esxVI_Occurrence_RequiredItem) ||
+ esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
+ goto cleanup;
+ }
+
+ if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain is not powered on"));
+ goto cleanup;
+ }
+
+ for (dynamicProperty = virtualMachine->propSet; dynamicProperty;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "guest.net")) {
+ if (esxVI_GuestNicInfo_CastListFromAnyType
+ (dynamicProperty->val, &guestNicInfoList) < 0) {
+ goto cleanup;
+ }
+ }
+ }
+
+ if (!guestNicInfoList)
+ goto cleanup;
+
+ for (guestNicInfo = guestNicInfoList; guestNicInfo;
+ guestNicInfo = guestNicInfo->_next) {
+ virDomainInterfacePtr iface = NULL;
+ size_t addrs_count = 0;
+
+ if (guestNicInfo->connected != esxVI_Boolean_True ||
+ !guestNicInfo->network) {
+ continue;
+ }
+
+ if (VIR_EXPAND_N(ifaces_ret, ifaces_count, 1) < 0)
+ goto cleanup;
+
+ if (VIR_ALLOC(ifaces_ret[ifaces_count - 1]) < 0)
+ goto cleanup;
+
+ iface = ifaces_ret[ifaces_count - 1];
+ iface->naddrs = 0;
+ iface->name = g_strdup(guestNicInfo->network);
+ iface->hwaddr = g_strdup(guestNicInfo->macAddress);
+
+ if (guestNicInfo->ipConfig) {
+ esxVI_NetIpConfigInfoIpAddress *ipAddress;
+ for (ipAddress = guestNicInfo->ipConfig->ipAddress; ipAddress;
+ ipAddress = ipAddress->_next) {
+ virDomainIPAddress ip_addr;
+
+ ret = esxParseIPAddress(ipAddress->ipAddress,
+ ipAddress->prefixLength->value, &ip_addr);
+ if (ret < 0)
+ goto cleanup;
+ else if (ret == 0)
+ continue;
+
+ if (VIR_APPEND_ELEMENT(iface->addrs, addrs_count, ip_addr) < 0)
+ goto cleanup;
+ }
+ } else {
+ esxVI_String *str;
+ for (str = guestNicInfo->ipAddress; str;
+ str = str->_next) {
+ virDomainIPAddress ip_addr;
+
+ /* Not even the netmask seems available... */
+ ret = esxParseIPAddress(str->value, 0, &ip_addr);
+ if (ret < 0)
+ goto cleanup;
+ else if (ret == 0)
+ continue;
+
+ if (VIR_APPEND_ELEMENT(iface->addrs, addrs_count, ip_addr) < 0)
+ goto cleanup;
+
+ }
+ }
+
+ iface->naddrs = addrs_count;
+ }
+
+ *ifaces = ifaces_ret;
+ result = ifaces_count;
+
+ cleanup:
+ if (result < 0) {
+ if (ifaces_ret) {
+ for (i = 0; i < ifaces_count; i++)
+ virDomainInterfaceFree(ifaces_ret[i]);
+ }
+ }
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&virtualMachine);
+ esxVI_GuestNicInfo_Free(&guestNicInfoList);
+
+ return result;
+}
+
+
static virHypervisorDriver esxHypervisorDriver = {
.name = "ESX",
.connectOpen = esxConnectOpen, /* 0.7.0 */
@@ -5203,6 +5368,7 @@ static virHypervisorDriver esxHypervisorDriver = {
.connectIsAlive = esxConnectIsAlive, /* 0.9.8 */
.domainHasManagedSaveImage = esxDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetHostname = esxDomainGetHostname, /* 6.0.0 */
+ .domainInterfaceAddresses = esxDomainInterfaceAddresses, /* 6.0.0 */
};
--
2.24.1
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 12/20/19 3:58 PM, Pino Toscano wrote:
> Implement the .domainInterfaceAddresses hypervisor API, although only
> functional for the VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT source.
>
> Signed-off-by: Pino Toscano <ptoscano@redhat.com>
> ---
> docs/drvesx.html.in | 4 ++
> src/esx/esx_driver.c | 166 +++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 170 insertions(+)
>
> diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in
> index 465daafc2e..c4a2ae78a8 100644
> --- a/docs/drvesx.html.in
> +++ b/docs/drvesx.html.in
> @@ -792,6 +792,10 @@ Enter administrator password for example-vcenter.com:
> <li>
> <code>virDomainGetHostname</code>
> </li>
> + <li>
> + <code>virDomainInterfaceAddresses</code> (only for the
> + <code>VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT</code> source)
> + </li>
> <li>
> <code>virDomainReboot</code>
> </li>
> diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
> index 39e3faeb8f..73b8f32f1b 100644
> --- a/src/esx/esx_driver.c
> +++ b/src/esx/esx_driver.c
> @@ -5122,6 +5122,171 @@ esxDomainGetHostname(virDomainPtr domain,
> }
>
>
> +static int
> +esxParseIPAddress(const char *ipAddress, int prefixLength,
> + virDomainIPAddress *addr)
> +{
> + virSocketAddr tmp_addr;
> + virIPAddrType addr_type;
> +
> + if (virSocketAddrParseAny(&tmp_addr, ipAddress, AF_UNSPEC, false) <= 0)
> + return 0;
> +
> + switch (VIR_SOCKET_ADDR_FAMILY(&tmp_addr)) {
> + case AF_INET:
> + addr_type = VIR_IP_ADDR_TYPE_IPV4;
> + break;
> + case AF_INET6:
> + addr_type = VIR_IP_ADDR_TYPE_IPV6;
> + break;
> + default:
> + return 0;
> + }
> +
> + addr->type = addr_type;
> + addr->addr = g_strdup(ipAddress);
> + addr->prefix = prefixLength;
> +
> + return 1;
> +}
> +
> +
> +static int
> +esxDomainInterfaceAddresses(virDomainPtr domain,
> + virDomainInterfacePtr **ifaces,
> + unsigned int source,
> + unsigned int flags)
> +{
> + int result = -1;
> + esxPrivate *priv = domain->conn->privateData;
> + esxVI_String *propertyNameList = NULL;
> + esxVI_ObjectContent *virtualMachine = NULL;
> + esxVI_VirtualMachinePowerState powerState;
> + esxVI_DynamicProperty *dynamicProperty;
> + esxVI_GuestNicInfo *guestNicInfoList = NULL;
> + esxVI_GuestNicInfo *guestNicInfo = NULL;
> + virDomainInterfacePtr *ifaces_ret = NULL;
> + size_t ifaces_count = 0;
> + size_t i;
> + int ret;
> +
> + virCheckFlags(0, -1);
> + if (source != VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT) {
> + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
> + _("Unknown IP address data source %d"),
> + source);
> + return -1;
> + }
> +
> + if (esxVI_EnsureSession(priv->primary) < 0)
> + return -1;
> +
> + if (esxVI_String_AppendValueListToList(&propertyNameList,
> + "runtime.powerState\0"
> + "guest.net") < 0 ||
> + esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
> + propertyNameList, &virtualMachine,
> + esxVI_Occurrence_RequiredItem) ||
> + esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
> + goto cleanup;
> + }
> +
> + if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
> + virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> + _("Domain is not powered on"));
> + goto cleanup;
> + }
> +
> + for (dynamicProperty = virtualMachine->propSet; dynamicProperty;
> + dynamicProperty = dynamicProperty->_next) {
> + if (STREQ(dynamicProperty->name, "guest.net")) {
> + if (esxVI_GuestNicInfo_CastListFromAnyType
> + (dynamicProperty->val, &guestNicInfoList) < 0) {
> + goto cleanup;
> + }
> + }
> + }
> +
> + if (!guestNicInfoList)
> + goto cleanup;
> +
> + for (guestNicInfo = guestNicInfoList; guestNicInfo;
> + guestNicInfo = guestNicInfo->_next) {
> + virDomainInterfacePtr iface = NULL;
> + size_t addrs_count = 0;
> +
> + if (guestNicInfo->connected != esxVI_Boolean_True ||
> + !guestNicInfo->network) {
> + continue;
> + }
> +
> + if (VIR_EXPAND_N(ifaces_ret, ifaces_count, 1) < 0)
> + goto cleanup;
> +
> + if (VIR_ALLOC(ifaces_ret[ifaces_count - 1]) < 0)
> + goto cleanup;
> +
> + iface = ifaces_ret[ifaces_count - 1];
> + iface->naddrs = 0;
> + iface->name = g_strdup(guestNicInfo->network);
> + iface->hwaddr = g_strdup(guestNicInfo->macAddress);
> +
> + if (guestNicInfo->ipConfig) {
> + esxVI_NetIpConfigInfoIpAddress *ipAddress;
> + for (ipAddress = guestNicInfo->ipConfig->ipAddress; ipAddress;
> + ipAddress = ipAddress->_next) {
> + virDomainIPAddress ip_addr;
> +
> + ret = esxParseIPAddress(ipAddress->ipAddress,
> + ipAddress->prefixLength->value, &ip_addr);
> + if (ret < 0)
> + goto cleanup;
> + else if (ret == 0)
> + continue;
> +
> + if (VIR_APPEND_ELEMENT(iface->addrs, addrs_count, ip_addr) < 0)
> + goto cleanup;
> + }
> + } else {
> + esxVI_String *str;
> + for (str = guestNicInfo->ipAddress; str;
> + str = str->_next) {
> + virDomainIPAddress ip_addr;
> +
> + /* Not even the netmask seems available... */
> + ret = esxParseIPAddress(str->value, 0, &ip_addr);
> + if (ret < 0)
> + goto cleanup;
> + else if (ret == 0)
> + continue;
> +
> + if (VIR_APPEND_ELEMENT(iface->addrs, addrs_count, ip_addr) < 0)
> + goto cleanup;
> +
> + }
> + }
> +
> + iface->naddrs = addrs_count;
> + }
> +
> + *ifaces = ifaces_ret;
> + result = ifaces_count;
> +
> + cleanup:
> + if (result < 0) {
> + if (ifaces_ret) {
> + for (i = 0; i < ifaces_count; i++)
> + virDomainInterfaceFree(ifaces_ret[i]);
> + }
Small nit, ifaces_count can't be anything else than zero without
ifaces_ret being not NULL. So I'd drop the ifces_ret check. I'll also
post a patch to remove it from other places around our code.
Michal
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2026 Red Hat, Inc.