Display detected IP addresses in the domain XML using the
IP_LEASE variable name. This variable name now becomes
a reserved variable name that can be read only but not set
by the user.
The format of the value is: <ip address>,<lease timeout in seconds>
An example of a displayed XML may then be:
<interface type='bridge'>
<mac address='52:54:00:68:e3:90'/>
<source bridge='virbr0'/>
<target dev='vnet1'/>
<model type='virtio'/>
<filterref filter='clean-traffic'>
<parameter name='CTRL_IP_LEARNING' value='dhcp'/>
<parameter name='IP_LEASE' value='192.168.122.210,100'/>
</filterref>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x04' function='0x0'/>
</interface>
This patch now also offers a better (libvirt-internal) API for accessing
the detected IP addresses. The function virDomainConfNWFilterGetLeases can
be used to retrieve a list of IP leases associated with a given interface.
This function will then either retrieve the data from the DHCP snooping or
IP learning subsystems, depending on which detection algorithm has been
activated. If none is active, a NULL pointer for the array of leases will
be returned.
---
PS: This is the last remaining patch of the DHCP snooping series. I am
submitting it now as a stand-alone patch restarting the version counting.
---
docs/formatnwfilter.html.in | 27 +++++++++++
src/conf/domain_conf.c | 16 +++++--
src/conf/domain_nwfilter.c | 13 +++++
src/conf/domain_nwfilter.h | 15 ++++++
src/conf/nwfilter_conf.c | 3 -
src/conf/nwfilter_ipaddrmap.c | 51 ++++++++++++++++++++++
src/conf/nwfilter_ipaddrmap.h | 5 ++
src/conf/nwfilter_params.c | 75 ++++++++++++++++++++++++++++++++-
src/conf/nwfilter_params.h | 9 +++
src/libvirt_private.syms | 5 +-
src/nwfilter/nwfilter_dhcpsnoop.c | 59 +++++++++++++++++++++++++
src/nwfilter/nwfilter_dhcpsnoop.h | 4 +
src/nwfilter/nwfilter_driver.c | 10 ++++
src/nwfilter/nwfilter_gentech_driver.c | 26 +++++++++++
src/nwfilter/nwfilter_gentech_driver.h | 8 +++
src/nwfilter/nwfilter_learnipaddr.c | 9 +++
src/nwfilter/nwfilter_learnipaddr.h | 2
src/util/viriplease.h | 18 +++++++
18 files changed, 345 insertions(+), 10 deletions(-)
Index: libvirt-acl/src/conf/nwfilter_params.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_params.h
+++ libvirt-acl/src/conf/nwfilter_params.h
@@ -72,7 +72,10 @@ struct _virNWFilterHashTable {
virNWFilterHashTablePtr virNWFilterParseParamAttributes(xmlNodePtr cur);
int virNWFilterFormatParamAttributes(virBufferPtr buf,
virNWFilterHashTablePtr table,
- const char *filterref);
+ const char *filterref,
+ const unsigned char *vmuuid,
+ const unsigned char *mac,
+ const char *ifname);
virNWFilterHashTablePtr virNWFilterHashTableCreate(int n);
void virNWFilterHashTableFree(virNWFilterHashTablePtr table);
@@ -89,12 +92,14 @@ int virNWFilterHashTablePutAll(virNWFilt
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
# define VALID_VARVALUE \
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:,"
# define NWFILTER_VARNAME_IP "IP"
# define NWFILTER_VARNAME_MAC "MAC"
# define NWFILTER_VARNAME_CTRL_IP_LEARNING "CTRL_IP_LEARNING"
# define NWFILTER_VARNAME_DHCPSERVER "DHCPSERVER"
+# define NWFILTER_VARNAME_IP_LEASE "IP_LEASE"
+# define NWFILTER_VARNAME_IPV6_LEASE "IPV6_LEASE" /* future */
enum virNWFilterVarAccessType {
VIR_NWFILTER_VAR_ACCESS_ELEMENT = 0,
Index: libvirt-acl/src/conf/domain_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/domain_conf.c
+++ libvirt-acl/src/conf/domain_conf.c
@@ -43,6 +43,7 @@
#include "buf.h"
#include "c-ctype.h"
#include "logging.h"
+#include "nwfilter_params.h"
#include "nwfilter_conf.h"
#include "ignore-value.h"
#include "storage_file.h"
@@ -11500,7 +11501,8 @@ error:
static int
virDomainNetDefFormat(virBufferPtr buf,
virDomainNetDefPtr def,
- unsigned int flags)
+ unsigned int flags,
+ const unsigned char *vmuuid)
{
const char *type = virDomainNetTypeToString(def->type);
@@ -11641,9 +11643,15 @@ virDomainNetDefFormat(virBufferPtr buf,
}
}
if (def->filter) {
+ const char *ifname = NULL;
+
+ if (!(flags & VIR_DOMAIN_XML_INACTIVE))
+ ifname = def->ifname;
+
virBufferAdjustIndent(buf, 6);
if (virNWFilterFormatParamAttributes(buf, def->filterparams,
- def->filter) < 0)
+ def->filter, vmuuid, def->mac,
+ ifname) < 0)
return -1;
virBufferAdjustIndent(buf, -6);
}
@@ -12969,7 +12977,7 @@ virDomainDefFormatInternal(virDomainDefP
for (n = 0 ; n < def->nnets ; n++)
- if (virDomainNetDefFormat(buf, def->nets[n], flags) < 0)
+ if (virDomainNetDefFormat(buf, def->nets[n], flags, def->uuid) < 0)
goto cleanup;
for (n = 0 ; n < def->nsmartcards ; n++)
@@ -15222,7 +15230,7 @@ virDomainDeviceDefCopy(virCapsPtr caps,
rc = virDomainFSDefFormat(&buf, src->data.fs, flags);
break;
case VIR_DOMAIN_DEVICE_NET:
- rc = virDomainNetDefFormat(&buf,
src->data.net, flags);
+ rc = virDomainNetDefFormat(&buf,
src->data.net, flags, def->uuid);
break;
case VIR_DOMAIN_DEVICE_INPUT:
rc = virDomainInputDefFormat(&buf, src->data.input, flags);
Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -3406,7 +3406,8 @@ virNWFilterIncludeDefFormat(virNWFilterI
virBufferAdjustIndent(&buf, 2);
if (virNWFilterFormatParamAttributes(&buf, inc->params,
- inc->filterref) < 0) {
+ inc->filterref,
+ NULL, NULL, NULL) < 0) {
virBufferFreeAndReset(&buf);
return NULL;
}
Index: libvirt-acl/src/libvirt_private.syms
===================================================================
--- libvirt-acl.orig/src/libvirt_private.syms
+++ libvirt-acl/src/libvirt_private.syms
@@ -552,6 +552,7 @@ virDomainLockLeaseDetach;
# domain_nwfilter.h
+virDomainConfNWFiltetGetLeases;
virDomainConfNWFilterInstantiate;
virDomainConfNWFilterRegister;
virDomainConfNWFilterTeardown;
@@ -873,15 +874,17 @@ virNWFilterTestUnassignDef;
virNWFilterUnlockFilterUpdates;
-# nwfilter_ipaddrmap
+# nwfilter_ipaddrmap.h
virNWFilterIPAddrMapAddIPAddr;
virNWFilterIPAddrMapDelIPAddr;
virNWFilterIPAddrMapGetIPAddr;
+virNWFilterIPAddrMapGetIPLeases;
virNWFilterIPAddrMapInit;
virNWFilterIPAddrMapShutdown;
# nwfilter_params.h
+virNWFilterFormatParamAttributes;
virNWFilterHashTableCreate;
virNWFilterHashTableFree;
virNWFilterHashTablePut;
Index: libvirt-acl/src/conf/nwfilter_params.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_params.c
+++ libvirt-acl/src/conf/nwfilter_params.c
@@ -31,9 +31,16 @@
#include "nwfilter_params.h"
#include "domain_conf.h"
#include "logging.h"
+#include "domain_nwfilter.h"
+#include "nwfilter_ipaddrmap.h"
#define VIR_FROM_THIS VIR_FROM_NWFILTER
+static const char *virNWFilterReservedVarnames[] = {
+ NWFILTER_VARNAME_IP_LEASE,
+ NWFILTER_VARNAME_IPV6_LEASE,
+};
+
static bool isValidVarValue(const char *value);
static void virNWFilterVarAccessSetIntIterId(virNWFilterVarAccessPtr,
unsigned int);
@@ -784,6 +791,19 @@ virNWFilterParseVarValue(const char *val
return virNWFilterVarValueCreateSimpleCopyValue(val);
}
+static void
+virNWFilterDelReservedVarnames(virNWFilterHashTablePtr ht)
+{
+ unsigned int i;
+ virNWFilterVarValuePtr val;
+
+ for (i = 0; i < ARRAY_CARDINALITY(virNWFilterReservedVarnames); i++) {
+ val = virNWFilterHashTableRemoveEntry(ht,
+ virNWFilterReservedVarnames[i]);
+ virNWFilterVarValueFree(val);
+ }
+}
+
virNWFilterHashTablePtr
virNWFilterParseParamAttributes(xmlNodePtr cur)
{
@@ -834,6 +854,15 @@ skip_entry:
}
cur = cur->next;
}
+
+ /*
+ * read-only variables that may be usable in an incoming
+ * migration could be wired up here.
+ */
+
+ /* remove all reserved varnames from the table */
+ virNWFilterDelReservedVarnames(table);
+
return table;
err_exit:
@@ -855,10 +884,16 @@ virNWFilterFormatParameterNameSorter(con
int
virNWFilterFormatParamAttributes(virBufferPtr buf,
virNWFilterHashTablePtr table,
- const char *filterref)
+ const char *filterref,
+ const unsigned char *vmuuid,
+ const unsigned char *mac,
+ const char *ifname)
{
virHashKeyValuePairPtr items;
+ virIPLeasePtr leases = NULL;
+ size_t nLeases = 0;
int i, j, card, numKeys;
+ int ret = 0;
numKeys = virHashSize(table->hashTable);
@@ -889,14 +924,50 @@ virNWFilterFormatParamAttributes(virBuff
virNWFilterVarValueGetNthValue(value, j));
}
+ if (ifname) {
+ time_t now = time(0);
+ /* also display the IP addresses being used */
+ if (virDomainConfNWFilterGetLeases(&leases, &nLeases,
+ table,
+ ifname,
+ vmuuid,
+ mac) < 0) {
+ ret = -1;
+ goto cleanup;
+ }
+
+ for (i = 0; i < nLeases; i++) {
+ int64_t to;
+ char *ipbuf = virSocketAddrFormat(&leases[i].addr);
+
+ if (!ipbuf) {
+ virReportOOMError();
+ ret = -1;
+ goto cleanup;
+ }
+
+ to = (leases[i].timeout != VIR_IPLEASE_TIMEOUT_NONE)
+ ? (int64_t)(leases[i].timeout - now)
+ : -1;
+
+ virBufferAsprintf(buf,
+ " <parameter name='"
+ NWFILTER_VARNAME_IP_LEASE
+ "' value='%s,%ld'/>\n",
+ ipbuf, to);
+ VIR_FREE(ipbuf);
+ }
+ }
virBufferAddLit(buf, "</filterref>\n");
} else {
virBufferAddLit(buf, "/>\n");
}
+cleanup:
VIR_FREE(items);
+ VIR_FREE(leases);
- return 0;
+ return ret;
}
void
Index: libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_dhcpsnoop.c
+++ libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -1987,6 +1987,57 @@ virNWFilterSnoopLeaseFileLoad(void)
}
/*
+ * Get the detected IP addresses along with their absolute lease timeout.
+ */
+int
+virNWFilterSnoopGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ const unsigned char *vmuuid,
+ const unsigned char *macaddr)
+{
+ int ret = 0;
+ char ifkey[VIR_IFKEY_LEN];
+ virNWFilterSnoopReqPtr req;
+ virNWFilterSnoopIPLeasePtr ipl;
+ size_t ctr = 0;
+ virIPLeasePtr myleases = NULL;
+
+ *leases = NULL;
+
+ virNWFilterSnoopIFKeyFMT(ifkey, vmuuid, macaddr);
+
+ req = virNWFilterSnoopReqGetByIFKey(ifkey);
+ if (req) {
+ time_t now = time(0);
+
+ /* protect req->start */
+ virNWFilterSnoopReqLock(req);
+
+ for (ipl = req->start; ipl; ipl = ipl->next) {
+ if (ipl->timeout <= now)
+ continue;
+
+ if (VIR_EXPAND_N(myleases, ctr, 1) < 0) {
+ VIR_FREE(myleases);
+ ret = -1;
+ goto cleanup;
+ }
+
+ myleases[ctr-1].addr = ipl->ipAddress;
+ myleases[ctr-1].timeout = ipl->timeout;
+ }
+
+ *leases = myleases;
+ *nLeases = ctr;
+
+cleanup:
+ virNWFilterSnoopReqUnlock(req);
+
+ virNWFilterSnoopReqPut(req);
+ }
+ return ret;
+}
+
+/*
* Wait until all threads have ended.
*/
static void
@@ -2174,6 +2225,14 @@ virNWFilterDHCPSnoopShutdown(void)
#else /* HAVE_LIBPCAP */
int
+virNWFilterSnoopGetLeases(virIPLeasePtr *leases ATTRIBUTE_UNUSED,
+ size_t *nLeases ATTRIBUTE_UNUSED,
+ const unsigned char *vmuuid ATTRIBUTE_UNUSED,
+ const unsigned char *macaddr ATTRIBUTE_UNUSED)
+{
+}
+
+int
virNWFilterDHCPSnoopInit(void)
{
return -1;
Index: libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_dhcpsnoop.h
+++ libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.h
@@ -36,4 +36,8 @@ int virNWFilterDHCPSnoopReq(virNWFilterT
virNWFilterHashTablePtr filterparams,
virNWFilterDriverStatePtr driver);
void virNWFilterDHCPSnoopEnd(const char *ifname);
+int virNWFilterSnoopGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ const unsigned char *vmuuid,
+ const unsigned char *macaddr);
+
#endif /* __NWFILTER_DHCPSNOOP_H */
Index: libvirt-acl/src/conf/domain_nwfilter.c
===================================================================
--- libvirt-acl.orig/src/conf/domain_nwfilter.c
+++ libvirt-acl/src/conf/domain_nwfilter.c
@@ -60,3 +60,16 @@ virDomainConfVMNWFilterTeardown(virDomai
virDomainConfNWFilterTeardown(vm->def->nets[i]);
}
}
+
+int
+virDomainConfNWFilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr table,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac)
+{
+ if (nwfilterDriver != NULL)
+ return nwfilterDriver->getLeases(leases, nLeases, table, ifname,
+ vmuuid, mac);
+ return 0;
+}
Index: libvirt-acl/src/conf/domain_nwfilter.h
===================================================================
--- libvirt-acl.orig/src/conf/domain_nwfilter.h
+++ libvirt-acl/src/conf/domain_nwfilter.h
@@ -23,14 +23,24 @@
#ifndef DOMAIN_NWFILTER_H
# define DOMAIN_NWFILTER_H
+# include "viriplease.h"
+
typedef int (*virDomainConfInstantiateNWFilter)(virConnectPtr conn,
const unsigned char *vmuuid,
virDomainNetDefPtr net);
typedef void (*virDomainConfTeardownNWFilter)(virDomainNetDefPtr net);
+typedef int (*virDomainConfGetLeases)(virIPLeasePtr *leases,
+ size_t *nLeases,
+ virNWFilterHashTablePtr table,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac);
+
typedef struct {
virDomainConfInstantiateNWFilter instantiateFilter;
virDomainConfTeardownNWFilter teardownFilter;
+ virDomainConfGetLeases getLeases;
} virDomainConfNWFilterDriver;
typedef virDomainConfNWFilterDriver *virDomainConfNWFilterDriverPtr;
@@ -41,5 +51,10 @@ int virDomainConfNWFilterInstantiate(vir
virDomainNetDefPtr net);
void virDomainConfNWFilterTeardown(virDomainNetDefPtr net);
void virDomainConfVMNWFilterTeardown(virDomainObjPtr vm);
+int virDomainConfNWFilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr table,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac);
#endif /* DOMAIN_NWFILTER_H */
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
@@ -1209,3 +1209,29 @@ virNWFilterDomainFWUpdateCB(void *payloa
virDomainObjUnlock(obj);
}
+
+int
+virNWFilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr vars,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac)
+{
+ virNWFilterVarValuePtr lv;
+ const char *learning = NULL;
+ int ret = 0;
+
+ if (!vars)
+ return 0;
+
+ lv = virHashLookup(vars->hashTable, NWFILTER_VARNAME_CTRL_IP_LEARNING);
+ if (lv)
+ learning = virNWFilterVarValueGetNthValue(lv, 0);
+
+ if (!learning || STRCASEEQ(learning, "any")) {
+ ret = virNWFilterLearnGetLeases(leases, nLeases, ifname);
+ } else if (STRCASEEQ(learning, "dhcp")) {
+ ret = virNWFilterSnoopGetLeases(leases, nLeases, vmuuid, mac);
+ }
+ return ret;
+}
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.h
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
@@ -23,6 +23,8 @@
#ifndef __NWFILTER_GENTECH_DRIVER_H
# define __NWFILTER_GENTECH_DRIVER_H
+# include "viriplease.h"
+
virNWFilterTechDriverPtr virNWFilterTechDriverForName(const char *name);
int virNWFilterRuleInstAddData(virNWFilterRuleInstPtr res,
@@ -64,4 +66,10 @@ void virNWFilterDomainFWUpdateCB(void *p
const void *name,
void *data);
+int virNWFilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr vars,
+ const char *ifname,
+ const unsigned char *vmmuid,
+ const unsigned char *mac);
+
#endif
Index: libvirt-acl/src/nwfilter/nwfilter_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_driver.c
@@ -463,6 +463,15 @@ nwfilterTeardownFilter(virDomainNetDefPt
virNWFilterTeardownFilter(net);
}
+static int
+nwfilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr vars,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac)
+{
+ return virNWFilterGetLeases(leases, nLeases, vars, ifname, vmuuid, mac);
+}
static virNWFilterDriver nwfilterDriver = {
.name = "nwfilter",
@@ -490,6 +499,7 @@ static virStateDriver stateDriver = {
static virDomainConfNWFilterDriver domainNWFilterDriver = {
.instantiateFilter = nwfilterInstantiateFilter,
.teardownFilter = nwfilterTeardownFilter,
+ .getLeases = nwfilterGetLeases,
};
Index: libvirt-acl/src/conf/nwfilter_ipaddrmap.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_ipaddrmap.h
+++ libvirt-acl/src/conf/nwfilter_ipaddrmap.h
@@ -26,6 +26,9 @@
#ifndef __VIR_NWFILTER_IPADDRMAP_H
# define __VIR_NWFILTER_IPADDRMAP_H
+# include "buf.h"
+# include "viriplease.h"
+
int virNWFilterIPAddrMapInit(void);
void virNWFilterIPAddrMapShutdown(void);
@@ -33,5 +36,7 @@ int virNWFilterIPAddrMapAddIPAddr(const
int virNWFilterIPAddrMapDelIPAddr(const char *ifname,
const char *ipaddr);
virNWFilterVarValuePtr virNWFilterIPAddrMapGetIPAddr(const char *ifname);
+int virNWFilterIPAddrMapGetIPLeases(const char *ifname,
+ virIPLeasePtr *leases, size_t *nLeases);
#endif /* __VIR_NWFILTER_IPADDRMAP_H */
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
@@ -771,6 +771,15 @@ virNWFilterLearnIPAddress(virNWFilterTec
}
#endif /* HAVE_LIBPCAP */
+/*
+ * Get the detected IP addresses along with their absolute lease timeout
+ */
+int
+virNWFilterLearnGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ const char *ifname)
+{
+ return virNWFilterIPAddrMapGetIPLeases(ifname, leases, nLeases);
+}
/**
* virNWFilterLearnInit
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.h
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
@@ -71,5 +71,7 @@ void virNWFilterUnlockIface(const char *
int virNWFilterLearnInit(void);
void virNWFilterLearnShutdown(void);
void virNWFilterLearnThreadsTerminate(bool allowNewThreads);
+int virNWFilterLearnGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ const char *ifname);
#endif /* __NWFILTER_LEARNIPADDR_H */
Index: libvirt-acl/docs/formatnwfilter.html.in
===================================================================
--- libvirt-acl.orig/docs/formatnwfilter.html.in
+++ libvirt-acl/docs/formatnwfilter.html.in
@@ -446,6 +446,22 @@
</interface>
</pre>
+ <p>
+ Once an IP address has been detected, the domain's interface XML
+ will display the detected IP address and its lease expiration time
+ in seconds. Note that the <code>IP_LEASE</code> variable is read-only
+ and cannot be set by the user.
+ </p>
+<pre>
+ <interface type='bridge'>
+ <source bridge='virbr0'/>
+ <filterref filter='clean-traffic'>
+ <parameter name='CTRL_IP_LEARNING' value='dhcp'/>
+ <parameter name='IP_LEASE'
value='192.168.122.100,200'/>
+ </filterref>
+ </interface>
+</pre>
+
<h3><a name="nwfelemsReservedVars">Reserved
Variables</a></h3>
<p>
The following table lists reserved variables in use by libvirt.
@@ -481,6 +497,17 @@
<td> CTRL_IP_LEARNING </td>
<td> The choice of the IP address detection mode </td>
</tr>
+ <tr>
+ <td> IP_LEASE (<span class="since">Since
0.9.13</span>)</td>
+ <td> Read-only variable displaying the detected IP lease in the
+ format IP address,lease expiration time in seconds </td>
+ </tr>
+ <tr>
+ <td> IPV6_LEASE </td>
+ <td> Not currently implemented:
+ Read-only variable displaying the detected IPV6 lease in the
+ format IPV6 address,lease expiration time in seconds </td>
+ </tr>
</table>
<h2><a name="nwfelems">Element and attribute
overview</a></h2>
Index: libvirt-acl/src/util/viriplease.h
===================================================================
--- /dev/null
+++ libvirt-acl/src/util/viriplease.h
@@ -0,0 +1,18 @@
+#ifndef __VIR_IPLEASE_H__
+# define __VIR_IPLEASE_H__
+
+# include <time.h>
+
+# include "virsocketaddr.h"
+
+typedef struct _virIPLease virIPLease;
+typedef virIPLease *virIPLeasePtr;
+
+struct _virIPLease {
+ virSocketAddr addr;
+ time_t timeout;
+};
+
+#define VIR_IPLEASE_TIMEOUT_NONE (-1)
+
+#endif /* __VIR_IP_LEASE_H__ */
Index: libvirt-acl/src/conf/nwfilter_ipaddrmap.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_ipaddrmap.c
+++ libvirt-acl/src/conf/nwfilter_ipaddrmap.c
@@ -28,6 +28,7 @@
#include "virterror_internal.h"
#include "datatypes.h"
+#include "memory.h"
#include "nwfilter_params.h"
#include "nwfilter_ipaddrmap.h"
@@ -142,6 +143,56 @@ virNWFilterIPAddrMapGetIPAddr(const char
return res;
}
+/*
+ * Get the IP addresses associated with the interface as an array
+ * of virIPLease. Since we don't know about lease timeouts here, we
+ * set the lease timeout to VIR_IPLEASE_TIMEOUT_NONE.
+ */
+int
+virNWFilterIPAddrMapGetIPLeases(const char *ifname,
+ virIPLeasePtr *leases, size_t *nLeases)
+{
+ int ret = 0;
+ virNWFilterVarValuePtr val;
+ virIPLeasePtr myleases = NULL;
+
+ *leases = NULL;
+
+ virMutexLock(&ipAddressMapLock);
+
+ val = virHashLookup(ipAddressMap->hashTable, ifname);
+
+ if (val) {
+ size_t card = virNWFilterVarValueGetCardinality(val);
+ unsigned int i;
+
+ if (VIR_ALLOC_N(myleases, card) < 0) {
+ virReportOOMError();
+ ret = -1;
+ goto cleanup;
+ }
+
+ for (i = 0; i < card; i++) {
+ const char *value = virNWFilterVarValueGetNthValue(val, i);
+
+ if (virSocketAddrParse(&myleases[i].addr, value, AF_UNSPEC) < 0) {
+ VIR_FREE(myleases);
+ ret = -1;
+ goto cleanup;
+ }
+ myleases[i].timeout = VIR_IPLEASE_TIMEOUT_NONE;
+ }
+
+ *leases = myleases;
+ *nLeases = card;
+ }
+
+cleanup:
+ virMutexUnlock(&ipAddressMapLock);
+
+ return ret;
+}
+
int
virNWFilterIPAddrMapInit(void)
{