[libvirt] [PATCHv2 00/14] Fix vmdef usage after ExitMonitor
by Ján Tomko
Patches 3-8 fix possible crash/invalid memory access if QEMU crashes
while we're in the monitor.
Patches 9-13 change all other callers of qemuDomainObjExitMonitor
to exit early in that case, but should not fix any real issues.
They are necessary to turn on ATTRIBUTE_RETURN_CHECK for the ExitMonitor
call.
https://bugzilla.redhat.com/show_bug.cgi?id=1161024
Ján Tomko (14):
Check for domain liveness in qemuDomainObjExitMonitor
Mark the domain as active in qemuhotplugtest
Fix vmdef usage after domain crash in monitor on device removal
Fix vmdef usage after domain crash in monitor on device detach
Fix vmdef usage after domain crash in monitor on device attach
Fix vmdef usage while in monitor in qemuDomainHotplugVcpus
Fix vmdef usage while in monitor in BlockStat* APIs
Fix vmdef usage while in monitor in qemu process
Exit early after domain crash in monitor on device hotplug
Exit early after domain crash in monitor on migration
Exit early after domain crash in monitor in qemu_process
Exit early after domain crash in monitor in qemu_driver
Exit early after domain crash in monitor on snapshots
Add ATTRIBUTE_RETURN_CHECK to qemuDomainObjExitMonitor
src/qemu/THREADS.txt | 5 ++
src/qemu/qemu_domain.c | 27 +++++--
src/qemu/qemu_domain.h | 7 +-
src/qemu/qemu_driver.c | 196 +++++++++++++++++++++++++++++-----------------
src/qemu/qemu_hotplug.c | 183 ++++++++++++++++++++++++++-----------------
src/qemu/qemu_hotplug.h | 6 +-
src/qemu/qemu_migration.c | 137 ++++++++++++++++----------------
src/qemu/qemu_process.c | 128 +++++++++++++++++-------------
tests/qemuhotplugtest.c | 6 ++
9 files changed, 410 insertions(+), 285 deletions(-)
--
2.0.4
9 years, 10 months
[libvirt] [PATCH 0/2] check IOMMU group devices usage during vfio device passthrough
by Shivaprasad G Bhat
Problem:
====================================================================
If a device in the same iommu group is in use by a different vm, the guest boot
fails with the below error during vfio passthrough.
bash-4.2$ virsh start demo
error: Failed to start domain demo
error: internal error: process exited while connecting to monitor:
2014-12-02T13:43:52.020136Z qemu-system-x86_64: -device vfio-pci,host=00:1c.3,id=hostdev0,bus=pci.0,addr=0x5: vfio: error opening /dev/vfio/7: Device or resource busy
Solution:
=====================================================================
The patch iterates through the iommu group devices and errors out cleanly
mentioning the device and the guest which is using the device.
With Patch
bash-4.2$ virsh start demo
error: Failed to start domain demo
error: Requested operation is not valid: PCI device 0000:0d:00.0 is in use by driver QEMU, domain vm10
---
Shivaprasad G Bhat (2):
Move struct _virPCIDevice definition from virpci.c to virpci.h
check IOMMU group devices usage when preparing device for vfio passthrough
src/util/virhostdev.c | 87 +++++++++++++++++++++++++++++--------------------
src/util/virpci.c | 29 ----------------
src/util/virpci.h | 30 +++++++++++++++++
3 files changed, 82 insertions(+), 64 deletions(-)
--
Signature
9 years, 10 months
[libvirt] [PATCH v3 0/2] Fix migration to older libvirt
by Pavel Hrdina
Recently I've implemented new feature that we can set "vgamem_mb" for QXL device
and also I've fixed libvirt to honor the 'vram' attribute and pass that value to
QEMU process. But with this change the migration to older libvirt stopped
working because QEMU silently updates the video memory size if the value is too
low or there are some dependencies (for example QXL device has to have 'ram'
size twice as 'vgamem').
To fix the migration we need to load the updated values from QEMU and store them
into the status XML.
v2:
- don't fail if JSON monitor isn't available
v1:
- removed unnecessary movement of qemuMonitorJSONObjectProperty
- completely rewritten the second patch
Pavel Hrdina (2):
qemu_monitor: introduce new function to get QOM path
qemu_process: detect updated video ram size values from QEMU
src/qemu/qemu_monitor.c | 206 ++++++++++++++++++++++++++++---------------
src/qemu/qemu_monitor.h | 4 +
src/qemu/qemu_monitor_json.c | 69 +++++++++++++++
src/qemu/qemu_monitor_json.h | 3 +
src/qemu/qemu_process.c | 67 ++++++++++++++
5 files changed, 279 insertions(+), 70 deletions(-)
--
2.0.5
9 years, 10 months
[libvirt] [PATCH] qemu_driver: fix setting vcpus for offline domain
by Pavel Hrdina
Commit e3435caf fixed hot-plugging of vcpus with strict memory pinning
on NUMA hosts, but unfortunately it also broke updating number of vcpus
for offline guests using our API.
The issue is that we try to create a cpu cgroup for non-running guest
which fails as there are no cgroups for that domain. We should create
cgroups and update cpuset.mems only if we are hot-plugging.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/qemu/qemu_driver.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index cdf4173..3a343d0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4576,21 +4576,23 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
priv = vm->privateData;
- if (virCgroupNewEmulator(priv->cgroup, false, &cgroup_temp) < 0)
- goto cleanup;
-
- if (!(all_nodes = virNumaGetHostNodeset()))
- goto cleanup;
-
- if (!(all_nodes_str = virBitmapFormat(all_nodes)))
- goto cleanup;
-
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
- if (virCgroupGetCpusetMems(cgroup_temp, &mem_mask) < 0 ||
- virCgroupSetCpusetMems(cgroup_temp, all_nodes_str) < 0)
- goto endjob;
+ if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+ if (virCgroupNewEmulator(priv->cgroup, false, &cgroup_temp) < 0)
+ goto cleanup;
+
+ if (!(all_nodes = virNumaGetHostNodeset()))
+ goto cleanup;
+
+ if (!(all_nodes_str = virBitmapFormat(all_nodes)))
+ goto cleanup;
+
+ if (virCgroupGetCpusetMems(cgroup_temp, &mem_mask) < 0 ||
+ virCgroupSetCpusetMems(cgroup_temp, all_nodes_str) < 0)
+ goto endjob;
+ }
maximum = (flags & VIR_DOMAIN_VCPU_MAXIMUM) != 0;
flags &= ~VIR_DOMAIN_VCPU_MAXIMUM;
--
2.0.5
9 years, 10 months
[libvirt] [PATCH v2 0/4] UEFI and NVRAM store file format
by Michal Privoznik
diff to v1:
-Laszlo's review worked in (notably, even UEFI can have a different format than raw)
Michal Privoznik (4):
conf: Make virDomainLoaderDefParseXML parse <nvram/> too
conf: Allow UEFI and NVRAM format selection
qemu: Adapt to UEFI and NVRAM store file format change
domaincaps: Expose UEFI and NVRAM store file format capabilities
docs/formatdomain.html.in | 18 +++++--
docs/formatdomaincaps.html.in | 26 ++++++++++
docs/schemas/domaincaps.rng | 13 +++++
docs/schemas/domaincommon.rng | 16 ++++++
src/conf/domain_capabilities.c | 18 +++++++
src/conf/domain_capabilities.h | 2 +
src/conf/domain_conf.c | 57 +++++++++++++++++-----
src/conf/domain_conf.h | 11 +++++
src/libvirt_private.syms | 2 +
src/qemu/qemu_capabilities.c | 10 +++-
src/qemu/qemu_command.c | 12 +++--
tests/domaincapsschemadata/domaincaps-full.xml | 10 ++++
.../domaincaps-qemu_1.6.50-1.xml | 10 ++++
tests/domaincapstest.c | 2 +
.../qemuxml2argv-bios-nvram-qcow2.args | 10 ++++
.../qemuxml2argv-bios-nvram-qcow2.xml | 40 +++++++++++++++
tests/qemuxml2argvtest.c | 2 +
.../qemuxml2xmlout-bios-nvram.xml | 40 +++++++++++++++
tests/qemuxml2xmltest.c | 2 +-
19 files changed, 279 insertions(+), 22 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-qcow2.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-qcow2.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-nvram.xml
--
2.0.5
9 years, 10 months
[libvirt] [PATCH v2] qemu, lxc: Warn if setting QoS on unsupported vNIC types
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1165993
So, there are still plenty of vNIC types that we don't know how to set
bandwidth on. Let's warn explicitly in case user has requested it
instead of pretending everything was set.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
Diff to v1:
-switch from virReportError(); goto error; to VIR_WARN().
src/lxc/lxc_driver.c | 18 +++++++++++++-----
src/lxc/lxc_process.c | 18 +++++++++++++-----
src/qemu/qemu_command.c | 19 +++++++++++++------
src/qemu/qemu_hotplug.c | 18 +++++++++++++-----
4 files changed, 52 insertions(+), 21 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index f503fcf..07ddce3 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -4148,6 +4148,7 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
virLXCDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
int actualType;
+ virNetDevBandwidthPtr actualBandwidth;
char *veth = NULL;
if (!priv->initpid) {
@@ -4195,11 +4196,18 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
_("Network device type is not supported"));
goto cleanup;
}
- /* set network bandwidth */
- if (virNetDevSupportBandwidth(actualType) &&
- virNetDevBandwidthSet(net->ifname,
- virDomainNetGetActualBandwidth(net), false) < 0)
- goto cleanup;
+ /* Set bandwidth or warn if requested and not supported. */
+ actualBandwidth = virDomainNetGetActualBandwidth(net);
+ if (actualBandwidth) {
+ if (virNetDevSupportBandwidth(actualType)) {
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false) < 0)
+ goto cleanup;
+ } else {
+ VIR_WARN("setting bandwidth on interfaces of "
+ "type '%s' is not implemented yet",
+ virDomainNetTypeToString(actualType));
+ }
+ }
if (virNetDevSetNamespace(veth, priv->initpid) < 0) {
virDomainAuditNet(vm, NULL, net, "attach", false);
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index af08de9..89e9249 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -369,6 +369,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
for (i = 0; i < def->nnets; i++) {
char *veth = NULL;
+ virNetDevBandwidthPtr actualBandwidth;
/* If appropriate, grab a physical device from the configured
* network's pool of devices, or resolve bridge device name
* to the one defined in the network definition.
@@ -422,11 +423,18 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
}
- /* set network bandwidth */
- if (virNetDevSupportBandwidth(type) &&
- virNetDevBandwidthSet(net->ifname,
- virDomainNetGetActualBandwidth(net), false) < 0)
- goto cleanup;
+ /* Set bandwidth or warn if requested and not supported. */
+ actualBandwidth = virDomainNetGetActualBandwidth(net);
+ if (actualBandwidth) {
+ if (virNetDevSupportBandwidth(type)) {
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false) < 0)
+ goto cleanup;
+ } else {
+ VIR_WARN("setting bandwidth on interfaces of "
+ "type '%s' is not implemented yet",
+ virDomainNetTypeToString(type));
+ }
+ }
(*veths)[(*nveths)-1] = veth;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3346e95..3cafbfb 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7365,6 +7365,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
char **tapfdName = NULL;
char **vhostfdName = NULL;
int actualType = virDomainNetGetActualType(net);
+ virNetDevBandwidthPtr actualBandwidth;
size_t i;
if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)
@@ -7415,12 +7416,18 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
goto cleanup;
}
- /* Set Bandwidth */
- if (virNetDevSupportBandwidth(actualType) &&
- virNetDevBandwidthSet(net->ifname,
- virDomainNetGetActualBandwidth(net),
- false) < 0)
- goto cleanup;
+ /* Set bandwidth or warn if requested and not supported. */
+ actualBandwidth = virDomainNetGetActualBandwidth(net);
+ if (actualBandwidth) {
+ if (virNetDevSupportBandwidth(actualType)) {
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false) < 0)
+ goto cleanup;
+ } else {
+ VIR_WARN("setting bandwidth on interfaces of "
+ "type '%s' is not implemented yet",
+ virDomainNetTypeToString(actualType));
+ }
+ }
if ((actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1714341..bf1f69a 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -838,6 +838,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
bool releaseaddr = false;
bool iface_connected = false;
int actualType;
+ virNetDevBandwidthPtr actualBandwidth;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
size_t i;
@@ -926,11 +927,18 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (qemuInterfaceStartDevice(net) < 0)
goto cleanup;
- /* Set Bandwidth */
- if (virNetDevSupportBandwidth(actualType) &&
- virNetDevBandwidthSet(net->ifname,
- virDomainNetGetActualBandwidth(net), false) < 0)
- goto cleanup;
+ /* Set bandwidth or warn if requested and not supported. */
+ actualBandwidth = virDomainNetGetActualBandwidth(net);
+ if (actualBandwidth) {
+ if (virNetDevSupportBandwidth(actualType)) {
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false) < 0)
+ goto cleanup;
+ } else {
+ VIR_WARN("setting bandwidth on interfaces of "
+ "type '%s' is not implemented yet",
+ virDomainNetTypeToString(actualType));
+ }
+ }
for (i = 0; i < tapfdSize; i++) {
if (virSecurityManagerSetTapFDLabel(driver->securityManager,
--
2.0.5
9 years, 10 months
[libvirt] [PATCH 0/2] Forbid starting VMs with bandwidth on unsupported vNIC type
by Michal Privoznik
The patch 1/2 is trivial.
The patch 2/2 is controversial and I expect heavy discussion on
it :-) Thing is, there might be somebody misusing our XML to
store the QoS setting, and do the actual setting themselves in
startup hook. Now with this patch, we will forbid such usage
scenario.
Michal Privoznik (2):
conf: Increase virNetDevBandwidthParse intelligence
qemu, lxc: Fail explicitly if setting QoS on unsupported vNIC types
src/conf/domain_conf.c | 10 ++++++----
src/conf/netdev_bandwidth_conf.c | 38 +++++++++++++++++++++++---------------
src/conf/netdev_bandwidth_conf.h | 7 ++++---
src/conf/network_conf.c | 7 +++----
src/lxc/lxc_driver.c | 20 +++++++++++++++-----
src/lxc/lxc_process.c | 20 +++++++++++++++-----
src/qemu/qemu_command.c | 21 +++++++++++++++------
src/qemu/qemu_hotplug.c | 20 +++++++++++++++-----
tests/virnetdevbandwidthtest.c | 12 ++++++------
9 files changed, 102 insertions(+), 53 deletions(-)
--
2.0.5
9 years, 10 months
[libvirt] It does not support hot-plugging VHOST-USER networkcard in libvirt?
by zhang bo
It works well if we use qmp command to directly interact with qemu 2.1 to hot-add vhost-user network card. However, libvirt seems not support hotplugging well.
Steps to use qmp commands to directly(without libvirtd) interact with qemu 2.1 :
1 (qemu) chardev-add backend=socket,id=charnet1,path=/var/run/vhost-user/tap1
2 (qemu) netdev_add vhost-user,id=hostnet1,chardev=charnet1
3 (qemu) device_add virtio-net-pci,netdev=hostnet1,id=net1
In libvirt, we found that, Hot-plug is finished with a success result, but the network card doesn't work afterwards, it could not send/receive IOs.
As we further digged into the problem, the 1st step of qmp commands is missing if we use libvirt to do the hot-plug job.
1 (qemu) chardev-add backend=socket,id=charnet1,path=/var/run/vhost-user/tap1
After looking into the function qemuDomainAttachNetDevice(), we found that it does have
1) qemuMonitorAddNetdev()
2) qemuMonitorAddDevice()
except for *ChardevAdd*()
The question is : why does qemuDomainAttachNetDevice() not do the *ChardevAdd*() work? It seems necessary to add chardev to add a vhost-user network card.
9 years, 10 months
[libvirt] [PATCH] Share the code and schemas for domain and network route definitions
by Cédric Bosdonnat
Made the network configuration schemas and codes for the route element reusable.
Created networkcommon_conf.[ch] files containing pieces to be used in both domain
and network configurations.
Replaced the brand new domain route configuration by the network one. Note that it
now forces the destination address to be defined, even if the user wants to define
the default gateway.
---
docs/formatdomain.html.in | 14 +-
docs/schemas/basictypes.rng | 2 +-
docs/schemas/domaincommon.rng | 29 +-
docs/schemas/network.rng | 20 +-
docs/schemas/networkcommon.rng | 22 ++
po/POTFILES.in | 1 +
src/Makefile.am | 3 +-
src/conf/domain_conf.c | 117 ++------
src/conf/domain_conf.h | 14 +-
src/conf/network_conf.c | 284 +-----------------
src/conf/network_conf.h | 20 +-
src/conf/networkcommon_conf.c | 337 ++++++++++++++++++++++
src/conf/networkcommon_conf.h | 76 +++++
src/libvirt_private.syms | 7 +
src/lxc/lxc_container.c | 22 +-
src/lxc/lxc_native.c | 26 +-
tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml | 4 +-
tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 4 +-
tests/lxcxml2xmldata/lxc-hostdev.xml | 4 +-
tests/lxcxml2xmldata/lxc-idmap.xml | 4 +-
20 files changed, 542 insertions(+), 468 deletions(-)
create mode 100644 src/conf/networkcommon_conf.c
create mode 100644 src/conf/networkcommon_conf.h
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 499879e..292c8c2 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4329,8 +4329,8 @@ qemu-kvm -net nic,model=? /dev/null
<source network='default'/>
<target dev='vnet0'/>
<b><ip address='192.168.122.5' prefix='24'/></b>
- <b><route family='ipv4' address='192.168.122.0' prefix='24' via='192.168.122.1'/></b>
- <b><route family='ipv4' via='192.168.122.1'/></b>
+ <b><route family='ipv4' address='192.168.122.0' prefix='24' gateway='192.168.122.1'/></b>
+ <b><route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/></b>
</interface>
...
<hostdev mode='capabilities' type='net'>
@@ -4338,8 +4338,8 @@ qemu-kvm -net nic,model=? /dev/null
<interface>eth0</interface>
</source>
<b><ip address='192.168.122.6' prefix='24'/></b>
- <b><route family='ipv4' address='192.168.122.0' prefix='24' via='192.168.122.1'/></b>
- <b><route family='ipv4' via='192.168.122.1'/></b>
+ <b><route family='ipv4' address='192.168.122.0' prefix='24' gateway='192.168.122.1'/></b>
+ <b><route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/></b>
</hostdev>
</devices>
@@ -4359,11 +4359,7 @@ qemu-kvm -net nic,model=? /dev/null
<p>
<span class="since">Since 1.2.12</span> route elements can also be added
to define the network routes to use for the network device. This element
- has a <code>family</code> attribute set either to <code>ipv4</code> or
- <code>ipv6</code>, a mandatory <code>via</code> attribute defining the
- IP address to route throught and optional <code>address</code> and <code>prefix</code>
- attributes defining the target network range. If those aren't given, then
- a default route will be set.
+ has the same attributes than its equivalent for network definitions.
This is only used by the LXC driver.
</p>
diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
index 9ddd92b..efc9da4 100644
--- a/docs/schemas/basictypes.rng
+++ b/docs/schemas/basictypes.rng
@@ -174,7 +174,7 @@
<define name="ipv6Addr">
<data type="string">
<!-- To understand this better, take apart the toplevel "|"s -->
-<param name="pattern">(([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|(([0-9A-Fa-f]{1,4}:){0,5}:(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|(::([0-9A-Fa-f]{1,4}:){0,5}(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:)</param>
+<param name="pattern">(([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|(([0-9A-Fa-f]{1,4}:){0,5}:(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|(::([0-9A-Fa-f]{1,4}:){0,5}(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:)|(::)</param>
</data>
</define>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 879e064..548cd15 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2330,9 +2330,7 @@
</element>
</zeroOrMore>
<zeroOrMore>
- <element name="route">
- <ref name="route"/>
- </element>
+ <ref name="route"/>
</zeroOrMore>
<optional>
<element name="script">
@@ -3602,27 +3600,6 @@
</element>
</define>
- <define name="route">
- <interleave>
- <attribute name="family">
- <ref name="addr-family"/>
- </attribute>
- <attribute name="via">
- <ref name="ipAddr"/>
- </attribute>
- <optional>
- <attribute name="address">
- <ref name="ipAddr"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="prefix">
- <ref name="ipPrefix"/>
- </attribute>
- </optional>
- </interleave>
- </define>
-
<define name="hostdev">
<element name="hostdev">
<interleave>
@@ -3859,9 +3836,7 @@
</element>
</zeroOrMore>
<zeroOrMore>
- <element name="route">
- <ref name="route"/>
- </element>
+ <ref name="route"/>
</zeroOrMore>
</interleave>
</define>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 9a7d156..a8814e7 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -371,25 +371,7 @@
</zeroOrMore>
<!-- <route> element -->
<zeroOrMore>
- <!-- The (static) route element specifies a network address and gateway
- address to access that network. Both the network address and
- the gateway address must be specified. -->
- <element name="route">
- <optional>
- <attribute name="family"><ref name="addr-family"/></attribute>
- </optional>
- <attribute name="address"><ref name="ipAddr"/></attribute>
- <optional>
- <choice>
- <attribute name="netmask"><ref name="ipv4Addr"/></attribute>
- <attribute name="prefix"><ref name="ipPrefix"/></attribute>
- </choice>
- </optional>
- <attribute name="gateway"><ref name="ipAddr"/></attribute>
- <optional>
- <attribute name="metric"><ref name="unsignedInt"/></attribute>
- </optional>
- </element>
+ <ref name='route'/>
</zeroOrMore>
</interleave>
</element>
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index e26b7f3..162ea3d 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -224,4 +224,26 @@
<param name='maxInclusive'>65535</param>
</data>
</define>
+
+ <!-- The (static) route element specifies a network address and gateway
+ address to access that network. Both the network address and
+ the gateway address must be specified. -->
+ <define name='route'>
+ <element name="route">
+ <optional>
+ <attribute name="family"><ref name="addr-family"/></attribute>
+ </optional>
+ <attribute name="address"><ref name="ipAddr"/></attribute>
+ <optional>
+ <choice>
+ <attribute name="netmask"><ref name="ipv4Addr"/></attribute>
+ <attribute name="prefix"><ref name="ipPrefix"/></attribute>
+ </choice>
+ </optional>
+ <attribute name="gateway"><ref name="ipAddr"/></attribute>
+ <optional>
+ <attribute name="metric"><ref name="unsignedInt"/></attribute>
+ </optional>
+ </element>
+ </define>
</grammar>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 094c8e3..3064037 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -25,6 +25,7 @@ src/conf/netdev_bandwidth_conf.c
src/conf/netdev_vlan_conf.c
src/conf/netdev_vport_profile_conf.c
src/conf/network_conf.c
+src/conf/networkcommon_conf.c
src/conf/node_device_conf.c
src/conf/numatune_conf.c
src/conf/nwfilter_conf.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 2eaaf11..ba4c6ef 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -287,7 +287,8 @@ NETWORK_EVENT_SOURCES = \
# Network driver generic impl APIs
NETWORK_CONF_SOURCES = \
- conf/network_conf.c conf/network_conf.h
+ conf/network_conf.c conf/network_conf.h \
+ conf/networkcommon_conf.c conf/networkcommon_conf.h
# Network filter driver generic impl APIs
NWFILTER_PARAM_CONF_SOURCES = \
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 57e99e6..8e34fd6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2006-2014 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1475,11 +1476,13 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
VIR_FREE(def->ips[i]);
VIR_FREE(def->ips);
- for (i = 0; i < def->nroutes; i++)
+ for (i = 0; i < def->nroutes; i++) {
+ virNetworkRouteDefClear(def->routes[i]);
VIR_FREE(def->routes[i]);
+ }
VIR_FREE(def->routes);
- virDomainDeviceInfoClear(&def->info);
+ virDomainDeviceInfoClear(&def->info);
VIR_FREE(def->filter);
virNWFilterHashTableFree(def->filterparams);
@@ -4838,64 +4841,6 @@ virDomainNetIpParseXML(xmlNodePtr node)
return NULL;
}
-static virDomainNetRouteDefPtr
-virDomainNetRouteParse(xmlNodePtr node)
-{
- virDomainNetRouteDefPtr route = NULL;
- char *familyStr = NULL;
- int family = AF_UNSPEC;
- char *via = NULL;
- char *to = NULL;
- char *prefixStr = NULL;
-
- to = virXMLPropString(node, "address");
- if (!(via = virXMLPropString(node, "via"))) {
- virReportError(VIR_ERR_INVALID_ARG, "%s",
- _("Missing route address"));
- goto error;
- }
-
- familyStr = virXMLPropString(node, "family");
- if (familyStr && STREQ(familyStr, "ipv4"))
- family = AF_INET;
- else if (familyStr && STREQ(familyStr, "ipv6"))
- family = AF_INET6;
- else
- family = virSocketAddrNumericFamily(via);
-
- if (VIR_ALLOC(route) < 0)
- goto error;
-
- if (virSocketAddrParse(&route->via, via, family) < 0) {
- virReportError(VIR_ERR_INVALID_ARG,
- _("Failed to parse IP address: '%s'"),
- via);
- goto error;
- }
-
- if (to && virSocketAddrParse(&route->to, to, family) < 0) {
- virReportError(VIR_ERR_INVALID_ARG,
- _("Failed to parse IP address: '%s'"),
- to);
- goto error;
- }
-
- if (!(prefixStr = virXMLPropString(node, "prefix")) ||
- (virStrToLong_ui(prefixStr, NULL, 10, &route->prefix) < 0)) {
- }
-
- return route;
-
- error:
- VIR_FREE(familyStr);
- VIR_FREE(via);
- VIR_FREE(to);
- VIR_FREE(prefixStr);
- VIR_FREE(route);
-
- return NULL;
-}
-
static int
virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
xmlXPathContextPtr ctxt,
@@ -4989,13 +4934,20 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
if (nroutenodes) {
size_t i;
for (i = 0; i < nroutenodes; i++) {
- virDomainNetRouteDefPtr route = virDomainNetRouteParse(routenodes[i]);
+ virNetworkRouteDefPtr route = NULL;
- if (!route)
+ if (VIR_ALLOC(route) < 0)
goto error;
+ if (virNetworkRouteDefParseXML(_("Domain hostdev device"), routenodes[i],
+ ctxt, route) < 0) {
+ VIR_FREE(route);
+ goto error;
+ }
+
if (VIR_APPEND_ELEMENT(def->source.caps.u.net.routes,
def->source.caps.u.net.nroutes, route) < 0) {
+ virNetworkRouteDefClear(route);
VIR_FREE(route);
goto error;
}
@@ -7456,7 +7408,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
size_t nips = 0;
virDomainNetIpDefPtr *ips = NULL;
size_t nroutes = 0;
- virDomainNetRouteDefPtr *routes = NULL;
+ virNetworkRouteDefPtr *routes = NULL;
if (VIR_ALLOC(def) < 0)
return NULL;
@@ -7554,12 +7506,21 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
if (VIR_APPEND_ELEMENT(ips, nips, ip) < 0)
goto error;
} else if (xmlStrEqual(cur->name, BAD_CAST "route")) {
- virDomainNetRouteDefPtr route = NULL;
- if (!(route = virDomainNetRouteParse(cur)))
+ virNetworkRouteDefPtr route = NULL;
+
+ if (VIR_ALLOC(route) < 0)
goto error;
- if (VIR_APPEND_ELEMENT(routes, nroutes, route) < 0)
+ if (virNetworkRouteDefParseXML(_("Domain interface"), cur, ctxt, route) < 0) {
+ VIR_FREE(route);
+ goto error;
+ }
+
+ if (VIR_APPEND_ELEMENT(routes, nroutes, route) < 0) {
+ virNetworkRouteDefClear(route);
+ VIR_FREE(route);
goto error;
+ }
} else if (!ifname &&
xmlStrEqual(cur->name, BAD_CAST "target")) {
ifname = virXMLPropString(cur, "dev");
@@ -17285,32 +17246,14 @@ virDomainNetIpsFormat(virBufferPtr buf, virDomainNetIpDefPtr *ips, size_t nips)
static void
virDomainNetRoutesFormat(virBufferPtr buf,
- virDomainNetRouteDefPtr *routes,
+ virNetworkRouteDefPtr *routes,
size_t nroutes)
{
size_t i;
for (i = 0; i < nroutes; i++) {
- virDomainNetRouteDefPtr route = routes[i];
- const char *familyStr = NULL;
- char *via = virSocketAddrFormat(&route->via);
- char *to = NULL;
-
- if (VIR_SOCKET_ADDR_IS_FAMILY(&route->via, AF_INET6))
- familyStr = "ipv6";
- else if (VIR_SOCKET_ADDR_IS_FAMILY(&route->via, AF_INET))
- familyStr = "ipv4";
- virBufferAsprintf(buf, "<route family='%s' via='%s'", familyStr, via);
-
- if (VIR_SOCKET_ADDR_VALID(&route->to)) {
- to = virSocketAddrFormat(&route->to);
- virBufferAsprintf(buf, " address='%s'", to);
- }
-
- if (route->prefix > 0)
- virBufferAsprintf(buf, " prefix='%d'", route->prefix);
-
- virBufferAddLit(buf, "/>\n");
+ virNetworkRouteDefPtr route = routes[i];
+ virNetworkRouteDefFormat(buf, route);
}
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ac1f4f8..0828d07 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3,6 +3,7 @@
*
* Copyright (C) 2006-2014 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -35,6 +36,7 @@
# include "virthread.h"
# include "virhash.h"
# include "virsocketaddr.h"
+# include "networkcommon_conf.h"
# include "nwfilter_params.h"
# include "numatune_conf.h"
# include "virnetdevmacvlan.h"
@@ -485,14 +487,6 @@ struct _virDomainNetIpDef {
unsigned int prefix; /* number of 1 bits in the net mask */
};
-typedef struct _virDomainNetRouteDef virDomainNetRouteDef;
-typedef virDomainNetRouteDef *virDomainNetRouteDefPtr;
-struct _virDomainNetRouteDef {
- virSocketAddr via;
- virSocketAddr to;
- unsigned int prefix;
-};
-
typedef struct _virDomainHostdevCaps virDomainHostdevCaps;
typedef virDomainHostdevCaps *virDomainHostdevCapsPtr;
struct _virDomainHostdevCaps {
@@ -509,7 +503,7 @@ struct _virDomainHostdevCaps {
size_t nips;
virDomainNetIpDefPtr *ips;
size_t nroutes;
- virDomainNetRouteDefPtr *routes;
+ virNetworkRouteDefPtr *routes;
} net;
} u;
};
@@ -1013,7 +1007,7 @@ struct _virDomainNetDef {
size_t nips;
virDomainNetIpDefPtr *ips;
size_t nroutes;
- virDomainNetRouteDefPtr *routes;
+ virNetworkRouteDefPtr *routes;
};
/* Used for prefix of ifname of any network name generated dynamically
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index ddb5c07..33392a7 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -163,12 +163,6 @@ virNetworkIpDefClear(virNetworkIpDefPtr def)
}
static void
-virNetworkRouteDefClear(virNetworkRouteDefPtr def)
-{
- VIR_FREE(def->family);
-}
-
-static void
virNetworkDNSTxtDefClear(virNetworkDNSTxtDefPtr def)
{
VIR_FREE(def->name);
@@ -1371,232 +1365,6 @@ virNetworkIPDefParseXML(const char *networkName,
}
static int
-virNetworkRouteDefParseXML(const char *networkName,
- xmlNodePtr node,
- xmlXPathContextPtr ctxt,
- virNetworkRouteDefPtr def)
-{
- /*
- * virNetworkRouteDef object is already allocated as part
- * of an array. On failure clear: it out, but don't free it.
- */
-
- xmlNodePtr save;
- char *address = NULL, *netmask = NULL;
- char *gateway = NULL;
- unsigned long prefix = 0, metric = 0;
- int result = -1;
- int prefixRc, metricRc;
- virSocketAddr testAddr;
-
- save = ctxt->node;
- ctxt->node = node;
-
- /* grab raw data from XML */
- def->family = virXPathString("string(./@family)", ctxt);
- address = virXPathString("string(./@address)", ctxt);
- netmask = virXPathString("string(./@netmask)", ctxt);
- gateway = virXPathString("string(./@gateway)", ctxt);
- prefixRc = virXPathULong("string(./@prefix)", ctxt, &prefix);
- if (prefixRc == -2) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Invalid prefix specified "
- "in route definition of network '%s'"),
- networkName);
- goto cleanup;
- }
- def->has_prefix = (prefixRc == 0);
- def->prefix = prefix;
- metricRc = virXPathULong("string(./@metric)", ctxt, &metric);
- if (metricRc == -2) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Invalid metric specified "
- "in route definition of network '%s'"),
- networkName);
- goto cleanup;
- }
- if (metricRc == 0) {
- def->has_metric = true;
- if (metric == 0) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Invalid metric value, must be > 0 "
- "in route definition of network '%s'"),
- networkName);
- goto cleanup;
- }
- }
- def->metric = metric;
-
- /* Note: both network and gateway addresses must be specified */
-
- if (!address) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Missing required address attribute "
- "in route definition of network '%s'"),
- networkName);
- goto cleanup;
- }
-
- if (!gateway) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Missing required gateway attribute "
- "in route definition of network '%s'"),
- networkName);
- goto cleanup;
- }
-
- if (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Bad network address '%s' "
- "in route definition of network '%s'"),
- address, networkName);
- goto cleanup;
- }
-
- if (virSocketAddrParse(&def->gateway, gateway, AF_UNSPEC) < 0) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Bad gateway address '%s' "
- "in route definition of network '%s'"),
- gateway, networkName);
- goto cleanup;
- }
-
- /* validate network address, etc. for each family */
- if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) {
- if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) ||
- VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) {
- virReportError(VIR_ERR_XML_ERROR,
- def->family == NULL ?
- _("No family specified for non-IPv4 address '%s' "
- "in route definition of network '%s'") :
- _("IPv4 family specified for non-IPv4 address '%s' "
- "in route definition of network '%s'"),
- address, networkName);
- goto cleanup;
- }
- if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET)) {
- virReportError(VIR_ERR_XML_ERROR,
- def->family == NULL ?
- _("No family specified for non-IPv4 gateway '%s' "
- "in route definition of network '%s'") :
- _("IPv4 family specified for non-IPv4 gateway '%s' "
- "in route definition of network '%s'"),
- address, networkName);
- goto cleanup;
- }
- if (netmask) {
- if (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Bad netmask address '%s' "
- "in route definition of network '%s'"),
- netmask, networkName);
- goto cleanup;
- }
- if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Network '%s' has invalid netmask '%s' "
- "for address '%s' (both must be IPv4)"),
- networkName, netmask, address);
- goto cleanup;
- }
- if (def->has_prefix) {
- /* can't have both netmask and prefix at the same time */
- virReportError(VIR_ERR_XML_ERROR,
- _("Route definition '%s' cannot have both "
- "a prefix and a netmask"),
- networkName);
- goto cleanup;
- }
- }
- if (def->prefix > 32) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Invalid prefix %u specified "
- "in route definition of network '%s', "
- "must be 0 - 32"),
- def->prefix, networkName);
- goto cleanup;
- }
- } else if (STREQ(def->family, "ipv6")) {
- if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
- virReportError(VIR_ERR_XML_ERROR,
- _("ipv6 family specified for non-IPv6 address '%s' "
- "in route definition of network '%s'"),
- address, networkName);
- goto cleanup;
- }
- if (netmask) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Specifying netmask invalid for IPv6 address '%s' "
- "in route definition of network '%s'"),
- address, networkName);
- goto cleanup;
- }
- if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET6)) {
- virReportError(VIR_ERR_XML_ERROR,
- _("ipv6 specified for non-IPv6 gateway address '%s' "
- "in route definition of network '%s'"),
- gateway, networkName);
- goto cleanup;
- }
- if (def->prefix > 128) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Invalid prefix %u specified "
- "in route definition of network '%s', "
- "must be 0 - 128"),
- def->prefix, networkName);
- goto cleanup;
- }
- } else {
- virReportError(VIR_ERR_XML_ERROR,
- _("Unrecognized family '%s' "
- "in route definition of network'%s'"),
- def->family, networkName);
- goto cleanup;
- }
-
- /* make sure the address is a network address */
- if (netmask) {
- if (virSocketAddrMask(&def->address, &def->netmask, &testAddr) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("error converting address '%s' with netmask '%s' "
- "to network-address "
- "in route definition of network '%s'"),
- address, netmask, networkName);
- goto cleanup;
- }
- } else {
- if (virSocketAddrMaskByPrefix(&def->address,
- def->prefix, &testAddr) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("error converting address '%s' with prefix %u "
- "to network-address "
- "in route definition of network '%s'"),
- address, def->prefix, networkName);
- goto cleanup;
- }
- }
- if (!virSocketAddrEqual(&def->address, &testAddr)) {
- virReportError(VIR_ERR_XML_ERROR,
- _("address '%s' in route definition of network '%s' "
- "is not a network address"),
- address, networkName);
- goto cleanup;
- }
-
- result = 0;
-
- cleanup:
- if (result < 0)
- virNetworkRouteDefClear(def);
- VIR_FREE(address);
- VIR_FREE(netmask);
- VIR_FREE(gateway);
-
- ctxt->node = save;
- return result;
-}
-
-static int
virNetworkPortGroupParseXML(virPortGroupDefPtr def,
xmlNodePtr node,
xmlXPathContextPtr ctxt)
@@ -2026,6 +1794,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
xmlNodePtr save = ctxt->node;
xmlNodePtr bandwidthNode = NULL;
xmlNodePtr vlanNode;
+ char *errorDetail = NULL;
if (VIR_ALLOC(def) < 0)
return NULL;
@@ -2037,6 +1806,9 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
goto error;
}
+ if (virAsprintf(&errorDetail, _("Network '%s'"), def->name) < 0)
+ goto error;
+
/* Extract network uuid */
tmp = virXPathString("string(./uuid[1])", ctxt);
if (!tmp) {
@@ -2210,7 +1982,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
goto error;
/* parse each definition */
for (i = 0; i < nRoutes; i++) {
- if (virNetworkRouteDefParseXML(def->name,
+ if (virNetworkRouteDefParseXML(errorDetail,
routeNodes[i],
ctxt,
&def->routes[i]) < 0)
@@ -2336,6 +2108,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
}
VIR_FREE(stp);
+ VIR_FREE(errorDetail);
ctxt->node = save;
return def;
@@ -2349,6 +2122,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
VIR_FREE(ipv6nogwStr);
VIR_FREE(trustGuestRxFilters);
ctxt->node = save;
+ VIR_FREE(errorDetail);
return NULL;
}
@@ -2586,50 +2360,6 @@ virNetworkIpDefFormat(virBufferPtr buf,
}
static int
-virNetworkRouteDefFormat(virBufferPtr buf,
- const virNetworkRouteDef *def)
-{
- int result = -1;
-
- virBufferAddLit(buf, "<route");
-
- if (def->family)
- virBufferAsprintf(buf, " family='%s'", def->family);
- if (VIR_SOCKET_ADDR_VALID(&def->address)) {
- char *addr = virSocketAddrFormat(&def->address);
-
- if (!addr)
- goto error;
- virBufferAsprintf(buf, " address='%s'", addr);
- VIR_FREE(addr);
- }
- if (VIR_SOCKET_ADDR_VALID(&def->netmask)) {
- char *addr = virSocketAddrFormat(&def->netmask);
-
- if (!addr)
- goto error;
- virBufferAsprintf(buf, " netmask='%s'", addr);
- VIR_FREE(addr);
- }
- if (def->has_prefix)
- virBufferAsprintf(buf, " prefix='%u'", def->prefix);
- if (VIR_SOCKET_ADDR_VALID(&def->gateway)) {
- char *addr = virSocketAddrFormat(&def->gateway);
- if (!addr)
- goto error;
- virBufferAsprintf(buf, " gateway='%s'", addr);
- VIR_FREE(addr);
- }
- if (def->has_metric && def->metric > 0)
- virBufferAsprintf(buf, " metric='%u'", def->metric);
- virBufferAddLit(buf, "/>\n");
-
- result = 0;
- error:
- return result;
-}
-
-static int
virPortGroupDefFormat(virBufferPtr buf,
const virPortGroupDef *def)
{
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 8110028..8cce28a 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -38,6 +38,7 @@
# include "virnetdevvlan.h"
# include "virmacaddr.h"
# include "device_conf.h"
+# include "networkcommon_conf.h"
# include "virbitmap.h"
typedef enum {
@@ -162,25 +163,6 @@ struct _virNetworkIpDef {
virSocketAddr bootserver;
};
-typedef struct _virNetworkRouteDef virNetworkRouteDef;
-typedef virNetworkRouteDef *virNetworkRouteDefPtr;
-struct _virNetworkRouteDef {
- char *family; /* ipv4 or ipv6 - default is ipv4 */
- virSocketAddr address; /* Routed Network IP address */
-
- /* One or the other of the following two will be used for a given
- * Network address, but never both. The parser guarantees this.
- * The virSocketAddrGetIpPrefix() can be used to get a
- * valid prefix.
- */
- virSocketAddr netmask; /* ipv4 - either netmask or prefix specified */
- unsigned int prefix; /* ipv6 - only prefix allowed */
- bool has_prefix; /* prefix= was specified */
- unsigned int metric; /* value for metric (defaults to 1) */
- bool has_metric; /* metric= was specified */
- virSocketAddr gateway; /* gateway IP address for ip-route */
- };
-
typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef;
typedef virNetworkForwardIfDef *virNetworkForwardIfDefPtr;
struct _virNetworkForwardIfDef {
diff --git a/src/conf/networkcommon_conf.c b/src/conf/networkcommon_conf.c
new file mode 100644
index 0000000..da80c0f
--- /dev/null
+++ b/src/conf/networkcommon_conf.c
@@ -0,0 +1,337 @@
+/*
+ * networkcommon_conf.c: network XML handling
+ *
+ * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "virerror.h"
+#include "datatypes.h"
+#include "networkcommon_conf.h"
+#include "viralloc.h"
+#include "virxml.h"
+
+#define VIR_FROM_THIS VIR_FROM_NETWORK
+
+void
+virNetworkRouteDefClear(virNetworkRouteDefPtr def)
+{
+ VIR_FREE(def->family);
+}
+
+int
+virNetworkRouteDefCreate(const char *errorDetail,
+ char *family,
+ char *address,
+ char *netmask,
+ char *gateway,
+ unsigned int prefix,
+ bool hasPrefix,
+ unsigned int metric,
+ bool hasMetric,
+ virNetworkRouteDefPtr def)
+{
+ virSocketAddr testAddr;
+ int result = -1;
+
+ def->family = family;
+ def->prefix = prefix;
+ def->has_prefix = hasPrefix;
+ def->metric = metric;
+ def->has_metric = hasMetric;
+
+ /* Note: both network and gateway addresses must be specified */
+
+ if (!address) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Missing required address attribute "
+ "in route definition"),
+ errorDetail);
+ goto cleanup;
+ }
+
+ if (!gateway) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Missing required gateway attribute "
+ "in route definition"),
+ errorDetail);
+ goto cleanup;
+ }
+
+ if (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Bad network address '%s' "
+ "in route definition"),
+ errorDetail, address);
+ goto cleanup;
+ }
+
+ if (virSocketAddrParse(&def->gateway, gateway, AF_UNSPEC) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Bad gateway address '%s' "
+ "in route definition"),
+ errorDetail, gateway);
+ goto cleanup;
+ }
+
+ /* validate network address, etc. for each family */
+ if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) {
+ if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) ||
+ VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) {
+ virReportError(VIR_ERR_XML_ERROR,
+ def->family == NULL ?
+ _("%s: No family specified for non-IPv4 address '%s' "
+ "in route definition") :
+ _("%s: IPv4 family specified for non-IPv4 address '%s' "
+ "in route definition"),
+ errorDetail, address);
+ goto cleanup;
+ }
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ def->family == NULL ?
+ _("%s: No family specified for non-IPv4 gateway '%s' "
+ "in route definition") :
+ _("%s: IPv4 family specified for non-IPv4 gateway '%s' "
+ "in route definition"),
+ errorDetail, address);
+ goto cleanup;
+ }
+ if (netmask) {
+ if (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Bad netmask address '%s' "
+ "in route definition"),
+ errorDetail, netmask);
+ goto cleanup;
+ }
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Invalid netmask '%s' "
+ "for address '%s' (both must be IPv4)"),
+ errorDetail, netmask, address);
+ goto cleanup;
+ }
+ if (def->has_prefix) {
+ /* can't have both netmask and prefix at the same time */
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Route definition cannot have both "
+ "a prefix and a netmask"),
+ errorDetail);
+ goto cleanup;
+ }
+ }
+ if (def->prefix > 32) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Invalid prefix %u specified "
+ "in route definition, "
+ "must be 0 - 32"),
+ errorDetail, def->prefix);
+ goto cleanup;
+ }
+ } else if (STREQ(def->family, "ipv6")) {
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: ipv6 family specified for non-IPv6 address '%s' "
+ "in route definition"),
+ errorDetail, address);
+ goto cleanup;
+ }
+ if (netmask) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Specifying netmask invalid for IPv6 address '%s' "
+ "in route definition"),
+ errorDetail, address);
+ goto cleanup;
+ }
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET6)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: ipv6 specified for non-IPv6 gateway address '%s' "
+ "in route definition"),
+ errorDetail, gateway);
+ goto cleanup;
+ }
+ if (def->prefix > 128) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Invalid prefix %u specified "
+ "in route definition, "
+ "must be 0 - 128"),
+ errorDetail, def->prefix);
+ goto cleanup;
+ }
+ } else {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Unrecognized family '%s' "
+ "in route definition"),
+ errorDetail, def->family);
+ goto cleanup;
+ }
+
+ /* make sure the address is a network address */
+ if (netmask) {
+ if (virSocketAddrMask(&def->address, &def->netmask, &testAddr) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("%s: Error converting address '%s' with netmask '%s' "
+ "to network-address "
+ "in route definition"),
+ errorDetail, address, netmask);
+ goto cleanup;
+ }
+ } else {
+ if (virSocketAddrMaskByPrefix(&def->address,
+ def->prefix, &testAddr) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("%s: Error converting address '%s' with prefix %u "
+ "to network-address "
+ "in route definition"),
+ errorDetail, address, def->prefix);
+ goto cleanup;
+ }
+ }
+ if (!virSocketAddrEqual(&def->address, &testAddr)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Address '%s' in route definition "
+ "is not a network address"),
+ errorDetail, address);
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ if (result < 0)
+ virNetworkRouteDefClear(def);
+ VIR_FREE(address);
+ VIR_FREE(netmask);
+ VIR_FREE(gateway);
+
+ return result;
+}
+
+int
+virNetworkRouteDefParseXML(const char *errorDetail,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ virNetworkRouteDefPtr def)
+{
+ /*
+ * virNetworkRouteDef object is already allocated as part
+ * of an array. On failure clear: it out, but don't free it.
+ */
+
+ xmlNodePtr save;
+ char *family = NULL;
+ char *address = NULL, *netmask = NULL;
+ char *gateway = NULL;
+ unsigned long prefix = 0, metric = 0;
+ int result = -1;
+ int prefixRc, metricRc;
+ bool hasPrefix = false;
+ bool hasMetric = false;
+
+ save = ctxt->node;
+ ctxt->node = node;
+
+ /* grab raw data from XML */
+ family = virXPathString("string(./@family)", ctxt);
+ address = virXPathString("string(./@address)", ctxt);
+ netmask = virXPathString("string(./@netmask)", ctxt);
+ gateway = virXPathString("string(./@gateway)", ctxt);
+ prefixRc = virXPathULong("string(./@prefix)", ctxt, &prefix);
+ if (prefixRc == -2) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Invalid prefix specified "
+ "in route definition"),
+ errorDetail);
+ goto cleanup;
+ }
+ hasPrefix = (prefixRc == 0);
+ metricRc = virXPathULong("string(./@metric)", ctxt, &metric);
+ if (metricRc == -2) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Invalid metric specified "
+ "in route definition"),
+ errorDetail);
+ goto cleanup;
+ }
+ if (metricRc == 0) {
+ hasMetric = true;
+ if (metric == 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("%s: Invalid metric value, must be > 0 "
+ "in route definition"),
+ errorDetail);
+ goto cleanup;
+ }
+ }
+
+ result = virNetworkRouteDefCreate(errorDetail, family, address, netmask,
+ gateway, prefix, hasPrefix, metric,
+ hasMetric, def);
+
+ cleanup:
+ ctxt->node = save;
+ return result;
+}
+
+int
+virNetworkRouteDefFormat(virBufferPtr buf,
+ const virNetworkRouteDef *def)
+{
+ int result = -1;
+
+ virBufferAddLit(buf, "<route");
+
+ if (def->family)
+ virBufferAsprintf(buf, " family='%s'", def->family);
+ if (VIR_SOCKET_ADDR_VALID(&def->address)) {
+ char *addr = virSocketAddrFormat(&def->address);
+
+ if (!addr)
+ goto error;
+ virBufferAsprintf(buf, " address='%s'", addr);
+ VIR_FREE(addr);
+ }
+ if (VIR_SOCKET_ADDR_VALID(&def->netmask)) {
+ char *addr = virSocketAddrFormat(&def->netmask);
+
+ if (!addr)
+ goto error;
+ virBufferAsprintf(buf, " netmask='%s'", addr);
+ VIR_FREE(addr);
+ }
+ if (def->has_prefix)
+ virBufferAsprintf(buf, " prefix='%u'", def->prefix);
+ if (VIR_SOCKET_ADDR_VALID(&def->gateway)) {
+ char *addr = virSocketAddrFormat(&def->gateway);
+ if (!addr)
+ goto error;
+ virBufferAsprintf(buf, " gateway='%s'", addr);
+ VIR_FREE(addr);
+ }
+ if (def->has_metric && def->metric > 0)
+ virBufferAsprintf(buf, " metric='%u'", def->metric);
+ virBufferAddLit(buf, "/>\n");
+
+ result = 0;
+ error:
+ return result;
+}
diff --git a/src/conf/networkcommon_conf.h b/src/conf/networkcommon_conf.h
new file mode 100644
index 0000000..a42bb21
--- /dev/null
+++ b/src/conf/networkcommon_conf.h
@@ -0,0 +1,76 @@
+/*
+ * networkcommon_conf.h: network XML handling
+ *
+ * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __NETWORKCOMMON_CONF_H__
+# define __NETWORKCOMMON_CONF_H__
+
+# include <libxml/tree.h>
+# include <libxml/xpath.h>
+
+# include "internal.h"
+# include "virbuffer.h"
+# include "virsocketaddr.h"
+
+typedef struct _virNetworkRouteDef virNetworkRouteDef;
+typedef virNetworkRouteDef *virNetworkRouteDefPtr;
+struct _virNetworkRouteDef {
+ char *family; /* ipv4 or ipv6 - default is ipv4 */
+ virSocketAddr address; /* Routed Network IP address */
+
+ /* One or the other of the following two will be used for a given
+ * Network address, but never both. The parser guarantees this.
+ * The virSocketAddrGetIpPrefix() can be used to get a
+ * valid prefix.
+ */
+ virSocketAddr netmask; /* ipv4 - either netmask or prefix specified */
+ unsigned int prefix; /* ipv6 - only prefix allowed */
+ bool has_prefix; /* prefix= was specified */
+ unsigned int metric; /* value for metric (defaults to 1) */
+ bool has_metric; /* metric= was specified */
+ virSocketAddr gateway; /* gateway IP address for ip-route */
+ };
+
+void
+virNetworkRouteDefClear(virNetworkRouteDefPtr def);
+int
+virNetworkRouteDefCreate(const char *networkName,
+ char *family,
+ char *address,
+ char *netmask,
+ char *gateway,
+ unsigned int prefix,
+ bool hasPrefix,
+ unsigned int metric,
+ bool hasMetric,
+ virNetworkRouteDefPtr def);
+int
+virNetworkRouteDefParseXML(const char *networkName,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ virNetworkRouteDefPtr def);
+int
+virNetworkRouteDefFormat(virBufferPtr buf,
+ const virNetworkRouteDef *def);
+
+#endif /* __NETWORKCOMMON_CONF_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fb5d003..d0c2a2d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -581,6 +581,13 @@ virNetworkEventLifecycleNew;
virNetworkEventStateRegisterID;
+# conf/networkcommon_conf.h
+virNetworkRouteDefClear;
+virNetworkRouteDefCreate;
+virNetworkRouteDefFormat;
+virNetworkRouteDefParseXML;
+
+
# conf/node_device_conf.h
virNodeDevCapsDefFree;
virNodeDevCapTypeFromString;
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 380d136..c792f17 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -544,17 +544,27 @@ static int lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef,
/* Set the routes */
for (j = 0; j < netDef->nroutes; j++) {
- virDomainNetRouteDefPtr route = netDef->routes[j];
- if (VIR_SOCKET_ADDR_VALID(&route->to))
- toStr = virSocketAddrFormat(&route->to);
+ virNetworkRouteDefPtr route = netDef->routes[j];
+ int prefix = 0;
+
+ if (VIR_SOCKET_ADDR_VALID(&route->address))
+ toStr = virSocketAddrFormat(&route->address);
else
if (VIR_STRDUP(toStr, "default") < 0)
goto error_out;
- viaStr = virSocketAddrFormat(&route->via);
+ viaStr = virSocketAddrFormat(&route->gateway);
VIR_DEBUG("Adding route %s/%d via %s", toStr, route->prefix, viaStr);
- if (virNetDevAddRoute(newname, &route->to, route->prefix,
- &route->via, 0) < 0) {
+ if ((prefix = virSocketAddrGetIpPrefix(&route->address,
+ &route->netmask,
+ prefix)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Invalid netmask or IP address in route definition"));
+ goto error_out;
+ }
+
+ if (virNetDevAddRoute(newname, &route->address, prefix,
+ &route->gateway, route->metric) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("Failed to add route %s/%d via %s"),
toStr, route->prefix, viaStr);
diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c
index d7cd1d5..dd99bbb 100644
--- a/src/lxc/lxc_native.c
+++ b/src/lxc/lxc_native.c
@@ -2,7 +2,7 @@
* lxc_native.c: LXC native configuration import
*
* Copyright (c) 2014 Red Hat, Inc.
- * Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ * Copyright (c) 2013-2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -433,15 +433,32 @@ typedef struct {
static int
lxcAddNetworkRouteDefinition(const char *address,
int family,
- virDomainNetRouteDefPtr **routes,
+ virNetworkRouteDefPtr **routes,
size_t *nroutes)
{
- virDomainNetRouteDefPtr route = NULL;
+ virNetworkRouteDefPtr route = NULL;
+ char *familyStr = NULL;
+ char *zero = NULL;
+ char *gateway = NULL;
+
+ if (VIR_STRDUP(zero, family == AF_INET ? VIR_SOCKET_ADDR_IPV4_ALL
+ : VIR_SOCKET_ADDR_IPV6_ALL) < 0)
+ goto error;
if (VIR_ALLOC(route) < 0)
goto error;
- if (virSocketAddrParse(&route->via, address, family) < 0)
+ if (virSocketAddrParse(&route->gateway, address, family) < 0)
+ goto error;
+
+ if (VIR_STRDUP(familyStr, family == AF_INET ? "ipv4" : "ipv6") < 0)
+ goto error;
+
+ if (VIR_STRDUP(gateway, address) < 0)
+ goto error;
+
+ if (virNetworkRouteDefCreate(_("Domain interface"), familyStr, zero, NULL, gateway,
+ 0, false, 0, false, route) < 0)
goto error;
if (VIR_APPEND_ELEMENT(*routes, *nroutes, route) < 0)
@@ -450,6 +467,7 @@ lxcAddNetworkRouteDefinition(const char *address,
return 0;
error:
+ virNetworkRouteDefClear(route);
VIR_FREE(route);
return -1;
}
diff --git a/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml b/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml
index d2cec8f..79bcfa0 100644
--- a/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml
+++ b/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml
@@ -27,8 +27,8 @@
</source>
<ip address='192.168.122.2' family='ipv4' prefix='24'/>
<ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='64'/>
- <route family='ipv4' via='192.168.122.1'/>
- <route family='ipv6' via='2003:db8:1:0:214:1234:fe0b:3595'/>
+ <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
+ <route family='ipv6' address='::' gateway='2003:db8:1:0:214:1234:fe0b:3595'/>
</hostdev>
</devices>
</domain>
diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml
index b1210e5..45a2012 100644
--- a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml
+++ b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml
@@ -39,8 +39,8 @@
<source bridge='virbr0'/>
<ip address='192.168.122.2' family='ipv4' prefix='24'/>
<ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='64'/>
- <route family='ipv4' via='192.168.122.1'/>
- <route family='ipv6' via='2003:db8:1:0:214:1234:fe0b:3595'/>
+ <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
+ <route family='ipv6' address='::' gateway='2003:db8:1:0:214:1234:fe0b:3595'/>
<guest dev='eth0'/>
<link state='up'/>
</interface>
diff --git a/tests/lxcxml2xmldata/lxc-hostdev.xml b/tests/lxcxml2xmldata/lxc-hostdev.xml
index 61e8655..3972594 100644
--- a/tests/lxcxml2xmldata/lxc-hostdev.xml
+++ b/tests/lxcxml2xmldata/lxc-hostdev.xml
@@ -37,8 +37,8 @@
</source>
<ip address='192.168.122.2' family='ipv4'/>
<ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='24'/>
- <route family='ipv4' via='192.168.122.1'/>
- <route family='ipv6' via='2003:db8:1:0:214:1234:fe0b:3595'/>
+ <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
+ <route family='ipv6' address='::' gateway='2003:db8:1:0:214:1234:fe0b:3595'/>
</hostdev>
</devices>
</domain>
diff --git a/tests/lxcxml2xmldata/lxc-idmap.xml b/tests/lxcxml2xmldata/lxc-idmap.xml
index 2b04a65..b477636 100644
--- a/tests/lxcxml2xmldata/lxc-idmap.xml
+++ b/tests/lxcxml2xmldata/lxc-idmap.xml
@@ -30,8 +30,8 @@
<source bridge='bri0'/>
<ip address='192.168.122.12' family='ipv4' prefix='24'/>
<ip address='192.168.122.13' family='ipv4' prefix='24'/>
- <route family='ipv4' via='192.168.122.1'/>
- <route family='ipv4' via='192.168.124.1' address='192.168.124.0' prefix='24'/>
+ <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
+ <route family='ipv4' address='192.168.124.0' prefix='24' gateway='192.168.124.1'/>
<target dev='veth0'/>
<guest dev='eth2'/>
</interface>
--
2.1.2
9 years, 10 months
[libvirt] [PATCH 0/4] NVRAM store file format
by Michal Privoznik
The first patch is in fact unrelated, but trivial.
The interesting work is done in the rest of the patches.
Michal Privoznik (4):
formatdomaincaps: Correctly format API reference
conf: Allow UEFI NVRAM format selection
qemu: Adapt to NVRAM store file format change
domaincaps: Expose NVRAM store file format capabilities
docs/formatdomain.html.in | 8 +++--
docs/formatdomaincaps.html.in | 20 +++++++++--
docs/schemas/domaincaps.rng | 13 +++++++
docs/schemas/domaincommon.rng | 8 +++++
src/conf/domain_capabilities.c | 17 +++++++++
src/conf/domain_capabilities.h | 1 +
src/conf/domain_conf.c | 40 +++++++++++++++++-----
src/conf/domain_conf.h | 10 ++++++
src/libvirt_private.syms | 2 ++
src/qemu/qemu_capabilities.c | 7 ++--
src/qemu/qemu_command.c | 6 ++--
tests/domaincapsschemadata/domaincaps-full.xml | 6 ++++
.../domaincaps-qemu_1.6.50-1.xml | 6 ++++
tests/domaincapstest.c | 1 +
.../qemuxml2argv-bios-nvram-qcow2.args | 10 ++++++
.../qemuxml2argv-bios-nvram-qcow2.xml | 40 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 ++
.../qemuxml2xmlout-bios-nvram.xml | 40 ++++++++++++++++++++++
tests/qemuxml2xmltest.c | 2 +-
19 files changed, 220 insertions(+), 19 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-qcow2.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-qcow2.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-nvram.xml
--
2.0.5
9 years, 10 months