This API returns dynamically allocated XML document
showing IP addresses for all domain interfaces.
---
docs/schemas/interfaces.rng | 57 ++++++++++++++++++++++++++++++++++++++++++
include/libvirt/libvirt.h.in | 2 +
src/driver.h | 4 +++
src/libvirt.c | 49 ++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1 +
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 12 ++++++++-
src/remote_protocol-structs | 8 ++++++
8 files changed, 133 insertions(+), 1 deletions(-)
create mode 100644 docs/schemas/interfaces.rng
diff --git a/docs/schemas/interfaces.rng b/docs/schemas/interfaces.rng
new file mode 100644
index 0000000..95c939e
--- /dev/null
+++ b/docs/schemas/interfaces.rng
@@ -0,0 +1,57 @@
+<!-- A Relax NG schema for the libvirt interfaces (return of
+ virDomainGetInterfacesAddresses) XML format -->
+<grammar
xmlns="http://relaxng.org/ns/structure/1.0"
+
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <include href='basictypes.rng'/>
+ <start>
+ <ref name='interfaces'/>
+ </start>
+
+
+ <define name='interfaces'>
+ <element name='interfaces'>
+ <zeroOrMore>
+ <ref name='interface'/>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name='interface'>
+ <element name='interface'>
+ <element name='name'>
+ <text/>
+ </element>
+ <optional>
+ <element name='hwaddr'>
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <ref name='addresses'/>
+ </optional>
+ </element>
+ </define>
+
+ <define name='addresses'>
+ <element name='addresses'>
+ <zeroOrMore>
+ <ref name='ip'/>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name='ip'>
+ <element name='ip'>
+ <attribute name='type'>
+ <choice>
+ <value>ipv4</value>
+ <value>ipv6</value>
+ </choice>
+ </attribute>
+ <attribute name='prefix'>
+ <ref name='unsignedInt'/>
+ </attribute>
+ <text/>
+ </element>
+ </define>
+</grammar>
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 024c4ec..90660d1 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1659,6 +1659,8 @@ int virDomainGetInterfaceParameters
(virDomainPtr dom,
const char *device,
virTypedParameterPtr params,
int *nparams, unsigned int
flags);
+char * virDomainGetInterfacesAddresses (virDomainPtr dom,
+ unsigned int flags);
/* Management of domain block devices */
diff --git a/src/driver.h b/src/driver.h
index b3c1740..b2ed4b0 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -398,6 +398,9 @@ typedef int
const char *device,
virTypedParameterPtr params,
int *nparams, unsigned int flags);
+typedef char *
+ (*virDrvDomainGetInterfacesAddresses) (virDomainPtr dom,
+ unsigned int flags);
typedef int
(*virDrvDomainMemoryStats)
@@ -966,6 +969,7 @@ struct _virDriver {
virDrvDomainInterfaceStats domainInterfaceStats;
virDrvDomainSetInterfaceParameters domainSetInterfaceParameters;
virDrvDomainGetInterfaceParameters domainGetInterfaceParameters;
+ virDrvDomainGetInterfacesAddresses domainGetInterfacesAddresses;
virDrvDomainMemoryStats domainMemoryStats;
virDrvDomainBlockPeek domainBlockPeek;
virDrvDomainMemoryPeek domainMemoryPeek;
diff --git a/src/libvirt.c b/src/libvirt.c
index 0aa50cb..2dadd6f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -7357,6 +7357,55 @@ error:
}
/**
+ * virDomainGetInterfacesAddresses:
+ * @domain: domain object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Return an XML document representing domain interfaces among with their IP
+ * addresses assigned. It's worth noticing that one interface can have multiple
+ * addresses or even none.
+ *
+ * For some hypervisors (e.g. qemu) a configured guest agent is needed. If
+ * guest agent is used, then the interface name will be the as seen by guest
+ * OS. To match such interface with the one from @domain XML us HW address or
+ * IP range.
+ *
+ * Returns an XML document or NULL on error.
+ * Callers *must* free returned pointer.
+ */
+char *
+virDomainGetInterfacesAddresses(virDomainPtr domain,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetInterfacesAddresses) {
+ char *ret;
+ ret = conn->driver->domainGetInterfacesAddresses(domain, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(domain ? domain->conn : NULL);
+ return NULL;
+}
+
+/**
* 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 2913a81..20dd08d 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -542,6 +542,7 @@ LIBVIRT_0.9.13 {
virDomainSnapshotIsCurrent;
virDomainSnapshotListAllChildren;
virDomainSnapshotRef;
+ virDomainGetInterfacesAddresses;
} LIBVIRT_0.9.11;
# .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 6f53264..40a7a9c 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -5226,6 +5226,7 @@ static virDriver remote_driver = {
.domainInterfaceStats = remoteDomainInterfaceStats, /* 0.3.2 */
.domainSetInterfaceParameters = remoteDomainSetInterfaceParameters, /* 0.9.9 */
.domainGetInterfaceParameters = remoteDomainGetInterfaceParameters, /* 0.9.9 */
+ .domainGetInterfacesAddresses = remoteDomainGetInterfacesAddresses, /* 0.9.13 */
.domainMemoryStats = remoteDomainMemoryStats, /* 0.7.5 */
.domainBlockPeek = remoteDomainBlockPeek, /* 0.4.2 */
.domainMemoryPeek = remoteDomainMemoryPeek, /* 0.4.2 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 1da9f3e..ea37270 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -653,6 +653,15 @@ struct remote_domain_get_interface_parameters_ret {
int nparams;
};
+struct remote_domain_get_interfaces_addresses_args {
+ remote_nonnull_domain dom;
+ unsigned int flags;
+};
+
+struct remote_domain_get_interfaces_addresses_ret {
+ remote_nonnull_string xml;
+};
+
struct remote_domain_memory_stats_args {
remote_nonnull_domain dom;
unsigned int maxStats;
@@ -2838,7 +2847,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SNAPSHOT_HAS_METADATA = 272, /* autogen autogen */
REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS = 273, /* skipgen skipgen priority:high */
REMOTE_PROC_DOMAIN_LIST_ALL_SNAPSHOTS = 274, /* skipgen skipgen priority:high */
- REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN = 275 /* skipgen skipgen priority:high
*/
+ REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN = 275, /* skipgen skipgen priority:high
*/
+ REMOTE_PROC_DOMAIN_GET_INTERFACES_ADDRESSES = 276 /* autogen autogen */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index b667527..fadff38 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -354,6 +354,13 @@ struct remote_domain_get_interface_parameters_ret {
} params;
int nparams;
};
+struct remote_domain_get_interfaces_addresses_args {
+ remote_nonnull_domain dom;
+ u_int flags;
+};
+struct remote_domain_get_interfaces_addresses_ret {
+ remote_nonnull_string xml;
+};
struct remote_domain_memory_stats_args {
remote_nonnull_domain dom;
u_int maxStats;
@@ -2246,4 +2253,5 @@ enum remote_procedure {
REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS = 273,
REMOTE_PROC_DOMAIN_LIST_ALL_SNAPSHOTS = 274,
REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN = 275,
+ REMOTE_PROC_DOMAIN_GET_INTERFACES_ADDRESSES = 276,
};
--
1.7.8.5