This API returns dynamically allocated array of IP addresses for all domain interfaces. --- include/libvirt/libvirt.h.in | 49 ++++++++++++++++++++++++++++++ python/generator.py | 2 ++ src/driver.h | 6 ++++ src/libvirt.c | 71 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 ++++ 5 files changed, 134 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index cc3fe13..3ee6688 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4563,6 +4563,55 @@ int virDomainFSTrim(virDomainPtr dom, unsigned long long minimum, unsigned int flags); +typedef enum { + VIR_INTERFACE_BROADCAST = (1 << 0), /* Broadcast address valid. */ + VIR_INTERFACE_PPP = (1 << 1), /* Interface is point-to-point. */ + /* we can add new flags here */ +} virDomainInterfaceType; + +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 */ + char *dstaddr; /* Broadcast address (if @flags & VIR_INTERFACE_BROADCAST), + PPP destination address (if @flags & VIR_INTERFACE_PPP) */ +}; + +typedef struct _virDomainInterface virDomainInterface; +typedef virDomainInterface *virDomainInterfacePtr; +struct _virDomainInterface { + char *name; /* interface name */ + unsigned int flags; /* virDomainInterfaceType */ + char *hwaddr; /* hardware address */ + unsigned int ip_addrs_count; /* number of items in @ip_addr */ + virDomainIPAddressPtr ip_addrs; /* array of IP addresses */ +}; + +typedef enum { + VIR_DOMAIN_INTERFACE_ADDRS_DEFAULT = 0, /* hypervisor choice */ + VIR_DOMAIN_INTERFACE_ADDRS_GUEST_AGENT = 1, /* use guest agent */ + VIR_DOMAIN_INTERFACE_ADDRS_NWFILTER = 2, /* use nwfilter learning code */ + /* etc ... */ +} virDomainInterfacesAddressesMethod; + + +int virDomainInterfacesAddresses(virDomainPtr domain, + virDomainInterfacePtr **ifaces, + unsigned int method, + unsigned int flags); + /** * virSchedParameterType: * diff --git a/python/generator.py b/python/generator.py index bae4edc..ee39e51 100755 --- a/python/generator.py +++ b/python/generator.py @@ -243,6 +243,7 @@ skipped_types = { 'virEventHandleCallback': "No function types in python", 'virEventTimeoutCallback': "No function types in python", 'virDomainBlockJobInfoPtr': "Not implemented yet", + 'virDomainInterfacePtr': "Not implemented yet", } ####################################################################### @@ -428,6 +429,7 @@ skip_impl = ( 'virNodeGetMemoryParameters', 'virNodeSetMemoryParameters', 'virNodeGetCPUMap', + 'virDomainInterfacesAddresses', ) qemu_skip_impl = ( diff --git a/src/driver.h b/src/driver.h index 64d652f..dc93ffb 100644 --- a/src/driver.h +++ b/src/driver.h @@ -914,6 +914,11 @@ typedef int const char *mountPoint, unsigned long long minimum, unsigned int flags); +typedef int + (*virDrvDomainInterfacesAddresses)(virDomainPtr domain, + virDomainInterfacePtr **ifaces, + unsigned int method, + unsigned int flags); /** * _virDriver: @@ -1107,6 +1112,7 @@ struct _virDriver { virDrvNodeGetCPUMap nodeGetCPUMap; virDrvDomainFSTrim domainFSTrim; virDrvDomainSendProcessSignal domainSendProcessSignal; + virDrvDomainInterfacesAddresses domainInterfacesAddresses; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index bf674d1..6f0de36 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -20424,3 +20424,74 @@ error: virDispatchError(dom->conn); return -1; } + +/** + * virDomainInterfacesAddresses: + * @domain: domain object + * @ifaces: array of @domain interfaces + * @method: which method use, one of virDomainInterfacesAddressesMethod + * @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. Single interface can have multiple or even + * none IP address. + * + * This API dynamically allocates the virDomainInterfacePtr struct based on + * how much interfaces domain has, usually there's 1:1 correlation between + * interfaces seen from the host and interfaces seen from the guest. The + * count of elements allocated is then returned. + * + * Depending on selected @method, guest agent or NWFilter can be used. The + * guest agent method communicates with a running agent within guest and + * dumps all interfaces within their addresses. This, obviously requires + * guest agent to be configured and running and will fail otherwise. + * However, this gives interfaces from guest point of view, that is, names + * and HW addresses are those as seen from the guest. When the NWFilter + * method is used, libvirt starts snooping on guests interfaces and try to + * gather as much info as possible. This returns interface name and HW + * address as seen from the host perspective. + * + * @ifaces->name is never NULL, other pointers MIGHT be NULL. + * + * The caller *must* free @ifaces when no longer needed. + * + * Returns -1 on failure + * otherwise the count of items stored into @ifaces. + */ +int +virDomainInterfacesAddresses(virDomainPtr domain, + virDomainInterfacePtr **ifaces, + unsigned int method, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "ifaces=%p, methd=%d, flags=%x", + ifaces, method, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + goto error; + } + + conn = domain->conn; + + virCheckNonNullArgGoto(ifaces, error); + + if (conn->driver->domainInterfacesAddresses) { + int ret; + ret = conn->driver->domainInterfacesAddresses(domain, ifaces, + method, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index e3d63d3..8e7c5d2 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -580,4 +580,10 @@ LIBVIRT_1.0.1 { virDomainSendProcessSignal; } LIBVIRT_1.0.0; +LIBVIRT_1.0.2 { + global: + virDomainInterfacesAddresses; +} LIBVIRT_1.0.1; + + # .... define new API here using predicted next version number .... -- 1.8.0.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list