This API returns dynamically allocated array of IP addresses for all domain interfaces. --- include/libvirt/libvirt.h.in | 32 +++++++++++++ python/generator.py | 1 + src/driver.h | 6 +++ src/libvirt.c | 101 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++ 5 files changed, 145 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index da3ce29..604e598 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1659,6 +1659,38 @@ int virDomainGetInterfaceParameters (virDomainPtr dom, virTypedParameterPtr params, int *nparams, unsigned int flags); +typedef enum { + VIR_IP_ADDR_TYPE_IPV4, + VIR_IP_ADDR_TYPE_IPV6, + +#ifdef VIR_ENUM_SENTINELS + VIR_IP_ADDR_TYPE_LAST +#endif +} virIPAddrType; + + +typedef struct _virDomainInterfaceIPAddress virDomainIPAddress; +typedef virDomainIPAddress *virDomainIPAddressPtr; +struct _virDomainInterfaceIPAddress { + int type; /* virIPAddrType */ + char *addr; /* IP address */ + int prefix; /* IP address prefix */ +}; + +typedef struct _virDomainInterface virDomainInterface; +typedef virDomainInterface *virDomainInterfacePtr; +struct _virDomainInterface { + char *name; /* interface name */ + char *hwaddr; /* hardware address */ + unsigned int ip_addrs_count; /* number of items in @ip_addr */ + virDomainIPAddressPtr ip_addrs; /* array of IP addresses */ +}; + +int virDomainInterfacesAddresses (virDomainPtr dom, + virDomainInterfacePtr *ifaces, + unsigned int *ifaces_count, + unsigned int flags); + /* Management of domain block devices */ int virDomainBlockPeek (virDomainPtr dom, diff --git a/python/generator.py b/python/generator.py index 9530867..747d1a8 100755 --- a/python/generator.py +++ b/python/generator.py @@ -425,6 +425,7 @@ skip_impl = ( 'virDomainGetInterfaceParameters', 'virDomainGetCPUStats', 'virDomainGetDiskErrors', + 'virDomainInterfacesAddresses', ) qemu_skip_impl = ( diff --git a/src/driver.h b/src/driver.h index aa7a377..336ad31 100644 --- a/src/driver.h +++ b/src/driver.h @@ -394,6 +394,11 @@ typedef int const char *device, virTypedParameterPtr params, int *nparams, unsigned int flags); +typedef int + (*virDrvDomainInterfacesAddresses) (virDomainPtr dom, + virDomainInterfacePtr *ifaces, + unsigned int *ifaces_count, + unsigned int flags); typedef int (*virDrvDomainMemoryStats) @@ -943,6 +948,7 @@ struct _virDriver { virDrvDomainInterfaceStats domainInterfaceStats; virDrvDomainSetInterfaceParameters domainSetInterfaceParameters; virDrvDomainGetInterfaceParameters domainGetInterfaceParameters; + virDrvDomainInterfacesAddresses domainInterfacesAddresses; virDrvDomainMemoryStats domainMemoryStats; virDrvDomainBlockPeek domainBlockPeek; virDrvDomainMemoryPeek domainMemoryPeek; diff --git a/src/libvirt.c b/src/libvirt.c index 6386ed4..2e30a14 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -7347,6 +7347,107 @@ error: } /** + * virDomainInterfacesAddresses: + * @dom: domain object + * @ifaces: array of @dom interfaces + * @ifaces_count: number of items in @ifaces + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Return an array of interfaces presented in given domain + * among with their IP and HW addresses. Note, that single + * interface can have multiple or even none IP address. + * + * This API dynamically allocates the virDomainInterfacePtr + * struct based on how much interfaces domain @dom has, + * usually there's 1:1 correlation. The count of elements + * allocated is stored in @ifaces_count. + * + * Note that for some hypervisors a configured guest agent + * is needed for successful return from this API. + * Moreover, if guest agent is used then the interface name + * is the one seen by guest OS. To match such interface with + * the one from @dom XML use HW address or IP range. + * + * @ifaces->name is never NULL, @ifaces->hwaddr might be NULL, + * + * The caller *must* free @ifaces when no longer needed. + * Usual use case looks like this: + * + * virDomainInterfacePtr ifaces = NULL; + * unsigned int ifaces_count = 0; + * unsigned int i, j; + * virDomainPtr dom = ... obtain a domain here ...; + * + * if (virDomainInterfacesAddresses(dom, &ifaces, &ifaces_count, 0) < 0) + * goto cleanup; + * + * ... do something with returned values, for example: + * for (i = 0; i < ifaces_count; i++) { + * printf("name: %s", ifaces[i].name); + * if (ifaces[i].hwaddr) + * printf(" hwaddr: %s", ifaces[i].hwaddr); + * + * for (j = 0; j < ifaces[i].ip_addrs_count; j++) { + * virDomainIPAddressPtr ip_addr = ifaces[i].ip_addrs + j; + * printf("[addr: %s prefix: %d type: %d]", + * ip_addr->addr, ip_addr->prefix, ip_addr->type); + * } + * printf("\n"); + * } + * + * cleanup: + * for (i = 0; i < ifaces_count; i++) { + * free(ifaces[i].name); + * free(ifaces[i].hwaddr); + * for (j = 0; j < ifaces[i].ip_addrs_count; j++) + * free(ifaces[i].ip_addrs[j].addr); + * free(ifaces[i].ip_addrs); + * } + * free(ifaces); + * + * Returns 0 on success, + * -1 in case of error + */ +int +virDomainInterfacesAddresses (virDomainPtr dom, + virDomainInterfacePtr *ifaces, + unsigned int *ifaces_count, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(dom, "ifaces=%p, ifaces_count=%p, flags=%x", + ifaces, ifaces_count, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(dom)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + goto error; + } + + conn = dom->conn; + + virCheckNonNullArgGoto(ifaces, error); + virCheckNonNullArgGoto(ifaces_count, error); + + if (conn->driver->domainInterfacesAddresses) { + int ret; + ret = conn->driver->domainInterfacesAddresses(dom, ifaces, + ifaces_count, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(dom ? dom->conn : NULL); + return -1; +} + +/** * virDomainMemoryStats: * @dom: pointer to the domain object * @stats: nr_stats-sized array of stat structures (returned) diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 46c13fb..54b094e 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -534,4 +534,9 @@ LIBVIRT_0.9.11 { virDomainPMWakeup; } LIBVIRT_0.9.10; +LIBVIRT_0.9.13 { + global: + virDomainInterfacesAddresses; +} LIBVIRT_0.9.11; + # .... define new API here using predicted next version number .... -- 1.7.8.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list