2008-07-11 10:48:34 +00:00
|
|
|
/*
|
|
|
|
* network_conf.c: network XML handling
|
|
|
|
*
|
2016-04-18 19:07:26 +00:00
|
|
|
* Copyright (C) 2006-2016 Red Hat, Inc.
|
2008-07-11 10:48:34 +00:00
|
|
|
* 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
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2008-07-11 10:48:34 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2009-12-22 02:06:57 +00:00
|
|
|
#include <unistd.h>
|
2008-07-11 10:48:34 +00:00
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <sys/types.h>
|
2008-08-12 08:25:48 +00:00
|
|
|
#include <sys/stat.h>
|
2008-07-11 10:48:34 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2008-11-04 23:22:06 +00:00
|
|
|
#include "datatypes.h"
|
2008-07-11 10:48:34 +00:00
|
|
|
#include "network_conf.h"
|
Split src/util/network.{c,h} into 5 pieces
The src/util/network.c file is a dumping ground for many different
APIs. Split it up into 5 pieces, along functional lines
- src/util/virnetdevbandwidth.c: virNetDevBandwidth type & helper APIs
- src/util/virnetdevvportprofile.c: virNetDevVPortProfile type & helper APIs
- src/util/virsocketaddr.c: virSocketAddr and APIs
- src/conf/netdev_bandwidth_conf.c: XML parsing / formatting
for virNetDevBandwidth
- src/conf/netdev_vport_profile_conf.c: XML parsing / formatting
for virNetDevVPortProfile
* src/util/network.c, src/util/network.h: Split into 5 pieces
* src/conf/netdev_bandwidth_conf.c, src/conf/netdev_bandwidth_conf.h,
src/conf/netdev_vport_profile_conf.c, src/conf/netdev_vport_profile_conf.h,
src/util/virnetdevbandwidth.c, src/util/virnetdevbandwidth.h,
src/util/virnetdevvportprofile.c, src/util/virnetdevvportprofile.h,
src/util/virsocketaddr.c, src/util/virsocketaddr.h: New pieces
* daemon/libvirtd.h, daemon/remote.c, src/conf/domain_conf.c,
src/conf/domain_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/conf/nwfilter_conf.h,
src/esx/esx_util.h, src/network/bridge_driver.c,
src/qemu/qemu_conf.c, src/rpc/virnetsocket.c,
src/rpc/virnetsocket.h, src/util/dnsmasq.h, src/util/interface.h,
src/util/iptables.h, src/util/macvtap.c, src/util/macvtap.h,
src/util/virnetdev.h, src/util/virnetdevtap.c,
tools/virsh.c: Update include files
2011-11-02 15:40:08 +00:00
|
|
|
#include "netdev_vport_profile_conf.h"
|
|
|
|
#include "netdev_bandwidth_conf.h"
|
2012-08-12 07:51:30 +00:00
|
|
|
#include "netdev_vlan_conf.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-13 18:13:21 +00:00
|
|
|
#include "virxml.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
2012-12-04 12:04:07 +00:00
|
|
|
#include "virbuffer.h"
|
2008-08-20 12:50:29 +00:00
|
|
|
#include "c-ctype.h"
|
2011-07-19 18:32:58 +00:00
|
|
|
#include "virfile.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
2015-02-24 12:48:50 +00:00
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
VIR_ENUM_IMPL(virNetworkForward,
|
|
|
|
VIR_NETWORK_FORWARD_LAST,
|
2016-08-10 23:09:55 +00:00
|
|
|
"none", "nat", "route", "open",
|
|
|
|
"bridge", "private", "vepa", "passthrough",
|
2019-01-20 16:30:15 +00:00
|
|
|
"hostdev",
|
|
|
|
);
|
2012-08-16 15:41:41 +00:00
|
|
|
|
conf: new network bridge device attribute macTableManager
The macTableManager attribute of a network's bridge subelement tells
libvirt how the bridge's MAC address table (used to determine the
egress port for packets) is managed. In the default mode, "kernel",
management is left to the kernel, which usually determines entries in
part by turning on promiscuous mode on all ports of the bridge,
flooding packets to all ports when the correct destination is unknown,
and adding/removing entries to the fdb as it sees incoming traffic
from particular MAC addresses. In "libvirt" mode, libvirt turns off
learning and flooding on all the bridge ports connected to guest
domain interfaces, and adds/removes entries according to the MAC
addresses in the domain interface configurations. A side effect of
turning off learning and unicast_flood on the ports of a bridge is
that (with Linux kernel 3.17 and newer), the kernel can automatically
turn off promiscuous mode on one or more of the bridge's ports
(usually only the one interface that is used to connect the bridge to
the physical network). The result is better performance (because
packets aren't being flooded to all ports, and can be dropped earlier
when they are of no interest) and slightly better security (a guest
can still send out packets with a spoofed source MAC address, but will
only receive traffic intended for the guest interface's configured MAC
address).
The attribute looks like this in the configuration:
<network>
<name>test</name>
<bridge name='br0' macTableManager='libvirt'/>
...
This patch only adds the config knob, documentation, and test
cases. The functionality behind this knob is added in later patches.
2014-11-20 17:40:33 +00:00
|
|
|
VIR_ENUM_IMPL(virNetworkBridgeMACTableManager,
|
|
|
|
VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LAST,
|
2019-01-20 16:30:15 +00:00
|
|
|
"default", "kernel", "libvirt",
|
|
|
|
);
|
conf: new network bridge device attribute macTableManager
The macTableManager attribute of a network's bridge subelement tells
libvirt how the bridge's MAC address table (used to determine the
egress port for packets) is managed. In the default mode, "kernel",
management is left to the kernel, which usually determines entries in
part by turning on promiscuous mode on all ports of the bridge,
flooding packets to all ports when the correct destination is unknown,
and adding/removing entries to the fdb as it sees incoming traffic
from particular MAC addresses. In "libvirt" mode, libvirt turns off
learning and flooding on all the bridge ports connected to guest
domain interfaces, and adds/removes entries according to the MAC
addresses in the domain interface configurations. A side effect of
turning off learning and unicast_flood on the ports of a bridge is
that (with Linux kernel 3.17 and newer), the kernel can automatically
turn off promiscuous mode on one or more of the bridge's ports
(usually only the one interface that is used to connect the bridge to
the physical network). The result is better performance (because
packets aren't being flooded to all ports, and can be dropped earlier
when they are of no interest) and slightly better security (a guest
can still send out packets with a spoofed source MAC address, but will
only receive traffic intended for the guest interface's configured MAC
address).
The attribute looks like this in the configuration:
<network>
<name>test</name>
<bridge name='br0' macTableManager='libvirt'/>
...
This patch only adds the config knob, documentation, and test
cases. The functionality behind this knob is added in later patches.
2014-11-20 17:40:33 +00:00
|
|
|
|
2019-01-20 16:04:56 +00:00
|
|
|
VIR_ENUM_DECL(virNetworkForwardHostdevDevice);
|
2012-08-16 15:41:41 +00:00
|
|
|
VIR_ENUM_IMPL(virNetworkForwardHostdevDevice,
|
|
|
|
VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_LAST,
|
2019-01-20 16:30:15 +00:00
|
|
|
"none", "pci", "netdev",
|
|
|
|
);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2013-04-26 20:23:27 +00:00
|
|
|
VIR_ENUM_IMPL(virNetworkForwardDriverName,
|
|
|
|
VIR_NETWORK_FORWARD_DRIVER_NAME_LAST,
|
|
|
|
"default",
|
|
|
|
"kvm",
|
2019-01-20 16:30:15 +00:00
|
|
|
"vfio",
|
|
|
|
);
|
2013-04-26 20:23:27 +00:00
|
|
|
|
2019-03-16 18:20:32 +00:00
|
|
|
VIR_ENUM_IMPL(virNetworkTaint,
|
|
|
|
VIR_NETWORK_TAINT_LAST,
|
2019-01-20 16:30:15 +00:00
|
|
|
"hook-script",
|
|
|
|
);
|
2014-02-04 16:36:54 +00:00
|
|
|
|
2019-07-14 16:11:06 +00:00
|
|
|
static virClassPtr virNetworkXMLOptionClass;
|
|
|
|
|
|
|
|
static void
|
|
|
|
virNetworkXMLOptionDispose(void *obj ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
virNetworkXMLOnceInit(void)
|
|
|
|
{
|
|
|
|
if (!VIR_CLASS_NEW(virNetworkXMLOption, virClassForObject()))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_ONCE_GLOBAL_INIT(virNetworkXML);
|
|
|
|
|
|
|
|
virNetworkXMLOptionPtr
|
|
|
|
virNetworkXMLOptionNew(void)
|
|
|
|
{
|
|
|
|
virNetworkXMLOptionPtr xmlopt;
|
|
|
|
|
|
|
|
if (virNetworkXMLInitialize() < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!(xmlopt = virObjectNew(virNetworkXMLOptionClass)))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return xmlopt;
|
|
|
|
}
|
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
static void
|
|
|
|
virPortGroupDefClear(virPortGroupDefPtr def)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->name);
|
|
|
|
VIR_FREE(def->virtPortProfile);
|
Adjust naming of network device bandwidth management APIs
Rename virBandwidth to virNetDevBandwidth, and virRate to
virNetDevBandwidthRate.
* src/util/network.c, src/util/network.h: Rename bandwidth
structs and APIs
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/conf/network_conf.c, src/conf/network_conf.h,
src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/qemu/qemu_command.c, src/util/macvtap.c,
src/util/macvtap.h, tools/virsh.c: Update for API changes.
2011-11-02 14:29:05 +00:00
|
|
|
virNetDevBandwidthFree(def->bandwidth);
|
2012-08-12 07:51:30 +00:00
|
|
|
virNetDevVlanClear(&def->vlan);
|
2011-07-26 12:42:37 +00:00
|
|
|
def->bandwidth = NULL;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
static void
|
|
|
|
virNetworkForwardIfDefClear(virNetworkForwardIfDefPtr def)
|
|
|
|
{
|
2012-08-16 15:41:41 +00:00
|
|
|
if (def->type == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV)
|
|
|
|
VIR_FREE(def->device.dev);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-08-05 06:32:49 +00:00
|
|
|
static void
|
|
|
|
virNetworkForwardPfDefClear(virNetworkForwardPfDefPtr def)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->dev);
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 18:57:34 +00:00
|
|
|
static void
|
|
|
|
virNetworkDHCPHostDefClear(virNetworkDHCPHostDefPtr def)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->mac);
|
2013-02-15 19:02:26 +00:00
|
|
|
VIR_FREE(def->id);
|
2012-09-14 18:57:34 +00:00
|
|
|
VIR_FREE(def->name);
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-11-11 15:27:55 +00:00
|
|
|
static void
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefClear(virNetworkIPDefPtr def)
|
2010-11-17 18:36:19 +00:00
|
|
|
{
|
|
|
|
VIR_FREE(def->family);
|
|
|
|
VIR_FREE(def->ranges);
|
|
|
|
|
2013-07-26 10:04:32 +00:00
|
|
|
while (def->nhosts)
|
|
|
|
virNetworkDHCPHostDefClear(&def->hosts[--def->nhosts]);
|
2010-11-17 18:36:19 +00:00
|
|
|
|
|
|
|
VIR_FREE(def->hosts);
|
|
|
|
VIR_FREE(def->tftproot);
|
|
|
|
VIR_FREE(def->bootfile);
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
static void
|
|
|
|
virNetworkDNSTxtDefClear(virNetworkDNSTxtDefPtr def)
|
2011-06-24 10:04:36 +00:00
|
|
|
{
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
VIR_FREE(def->name);
|
|
|
|
VIR_FREE(def->value);
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
static void
|
|
|
|
virNetworkDNSHostDefClear(virNetworkDNSHostDefPtr def)
|
|
|
|
{
|
2013-07-26 10:04:32 +00:00
|
|
|
while (def->nnames)
|
|
|
|
VIR_FREE(def->names[--def->nnames]);
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
VIR_FREE(def->names);
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
static void
|
|
|
|
virNetworkDNSSrvDefClear(virNetworkDNSSrvDefPtr def)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->domain);
|
|
|
|
VIR_FREE(def->service);
|
|
|
|
VIR_FREE(def->protocol);
|
|
|
|
VIR_FREE(def->target);
|
|
|
|
}
|
|
|
|
|
2016-08-12 02:28:27 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
virNetworkDNSForwarderClear(virNetworkDNSForwarderPtr def)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->domain);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
static void
|
|
|
|
virNetworkDNSDefClear(virNetworkDNSDefPtr def)
|
|
|
|
{
|
2013-09-13 16:31:07 +00:00
|
|
|
if (def->forwarders) {
|
|
|
|
while (def->nfwds)
|
2016-08-12 02:28:27 +00:00
|
|
|
virNetworkDNSForwarderClear(&def->forwarders[--def->nfwds]);
|
2013-09-13 16:31:07 +00:00
|
|
|
VIR_FREE(def->forwarders);
|
|
|
|
}
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (def->txts) {
|
2013-07-26 10:04:32 +00:00
|
|
|
while (def->ntxts)
|
|
|
|
virNetworkDNSTxtDefClear(&def->txts[--def->ntxts]);
|
2012-11-11 23:59:28 +00:00
|
|
|
VIR_FREE(def->txts);
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
}
|
|
|
|
if (def->hosts) {
|
2013-07-26 10:04:32 +00:00
|
|
|
while (def->nhosts)
|
|
|
|
virNetworkDNSHostDefClear(&def->hosts[--def->nhosts]);
|
2011-08-11 03:28:05 +00:00
|
|
|
VIR_FREE(def->hosts);
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
}
|
|
|
|
if (def->srvs) {
|
2013-07-26 10:04:32 +00:00
|
|
|
while (def->nsrvs)
|
|
|
|
virNetworkDNSSrvDefClear(&def->srvs[--def->nsrvs]);
|
2012-11-11 23:59:28 +00:00
|
|
|
VIR_FREE(def->srvs);
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
static void
|
|
|
|
virNetworkForwardDefClear(virNetworkForwardDefPtr def)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-11-11 22:57:16 +00:00
|
|
|
|
2014-11-13 14:23:27 +00:00
|
|
|
for (i = 0; i < def->npfs && def->pfs; i++)
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virNetworkForwardPfDefClear(&def->pfs[i]);
|
2012-11-11 22:57:16 +00:00
|
|
|
VIR_FREE(def->pfs);
|
|
|
|
|
2014-11-13 14:23:27 +00:00
|
|
|
for (i = 0; i < def->nifs && def->ifs; i++)
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virNetworkForwardIfDefClear(&def->ifs[i]);
|
2012-11-11 22:57:16 +00:00
|
|
|
VIR_FREE(def->ifs);
|
2013-07-26 10:04:32 +00:00
|
|
|
def->nifs = def->npfs = 0;
|
2012-11-11 22:57:16 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
void
|
|
|
|
virNetworkDefFree(virNetworkDefPtr def)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
if (!def)
|
|
|
|
return;
|
|
|
|
|
|
|
|
VIR_FREE(def->name);
|
|
|
|
VIR_FREE(def->bridge);
|
2019-01-09 21:51:31 +00:00
|
|
|
VIR_FREE(def->bridgeZone);
|
2008-09-08 12:45:29 +00:00
|
|
|
VIR_FREE(def->domain);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
virNetworkForwardDefClear(&def->forward);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
2014-11-13 14:23:27 +00:00
|
|
|
for (i = 0; i < def->nips && def->ips; i++)
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefClear(&def->ips[i]);
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(def->ips);
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2014-11-13 14:23:27 +00:00
|
|
|
for (i = 0; i < def->nroutes && def->routes; i++)
|
2016-06-14 17:40:04 +00:00
|
|
|
virNetDevIPRouteFree(def->routes[i]);
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
VIR_FREE(def->routes);
|
|
|
|
|
2014-11-13 14:23:27 +00:00
|
|
|
for (i = 0; i < def->nPortGroups && def->portGroups; i++)
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virPortGroupDefClear(&def->portGroups[i]);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
VIR_FREE(def->portGroups);
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virNetworkDNSDefClear(&def->dns);
|
2011-06-24 10:04:36 +00:00
|
|
|
|
2011-08-01 08:06:59 +00:00
|
|
|
VIR_FREE(def->virtPortProfile);
|
|
|
|
|
Adjust naming of network device bandwidth management APIs
Rename virBandwidth to virNetDevBandwidth, and virRate to
virNetDevBandwidthRate.
* src/util/network.c, src/util/network.h: Rename bandwidth
structs and APIs
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/conf/network_conf.c, src/conf/network_conf.h,
src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/qemu/qemu_command.c, src/util/macvtap.c,
src/util/macvtap.h, tools/virsh.c: Update for API changes.
2011-11-02 14:29:05 +00:00
|
|
|
virNetDevBandwidthFree(def->bandwidth);
|
2012-08-12 07:51:30 +00:00
|
|
|
virNetDevVlanClear(&def->vlan);
|
2016-06-22 22:05:50 +00:00
|
|
|
|
|
|
|
xmlFreeNode(def->metadata);
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
VIR_FREE(def);
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 15:35:35 +00:00
|
|
|
/*
|
|
|
|
* virNetworkDefCopy:
|
|
|
|
* @def: NetworkDef to copy
|
|
|
|
* @flags: VIR_NETWORK_XML_INACTIVE if appropriate
|
|
|
|
*
|
|
|
|
* make a deep copy of the given NetworkDef
|
|
|
|
*
|
|
|
|
* Returns a new NetworkDef on success, or NULL on failure.
|
|
|
|
*/
|
|
|
|
virNetworkDefPtr
|
2019-07-14 16:15:12 +00:00
|
|
|
virNetworkDefCopy(virNetworkDefPtr def,
|
|
|
|
virNetworkXMLOptionPtr xmlopt,
|
|
|
|
unsigned int flags)
|
2012-09-14 15:35:35 +00:00
|
|
|
{
|
|
|
|
char *xml = NULL;
|
|
|
|
virNetworkDefPtr newDef = NULL;
|
|
|
|
|
|
|
|
if (!def) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("NULL NetworkDef"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* deep copy with a format/parse cycle */
|
2019-07-14 16:15:12 +00:00
|
|
|
if (!(xml = virNetworkDefFormat(def, xmlopt, flags)))
|
2012-09-14 15:35:35 +00:00
|
|
|
goto cleanup;
|
2019-07-14 16:15:12 +00:00
|
|
|
newDef = virNetworkDefParseString(xml, xmlopt);
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2012-09-14 15:35:35 +00:00
|
|
|
VIR_FREE(xml);
|
|
|
|
return newDef;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
/* return ips[index], or NULL if there aren't enough ips */
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr
|
|
|
|
virNetworkDefGetIPByIndex(const virNetworkDef *def,
|
2017-03-08 15:41:57 +00:00
|
|
|
int family,
|
|
|
|
size_t n)
|
2010-11-17 18:36:19 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-11-17 18:36:19 +00:00
|
|
|
|
|
|
|
if (!def->ips || n >= def->nips)
|
|
|
|
return NULL;
|
|
|
|
|
2014-11-13 14:23:27 +00:00
|
|
|
if (family == AF_UNSPEC)
|
2010-11-17 18:36:19 +00:00
|
|
|
return &def->ips[n];
|
|
|
|
|
|
|
|
/* find the nth ip of type "family" */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->nips; i++) {
|
|
|
|
if (VIR_SOCKET_ADDR_IS_FAMILY(&def->ips[i].address, family)
|
2010-11-17 18:36:19 +00:00
|
|
|
&& (n-- <= 0)) {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
return &def->ips[i];
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* failed to find enough of the right family */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2015-07-09 13:50:41 +00:00
|
|
|
/* return routes[index], or NULL if there aren't enough routes */
|
2016-06-14 17:40:04 +00:00
|
|
|
virNetDevIPRoutePtr
|
2015-07-09 13:50:41 +00:00
|
|
|
virNetworkDefGetRouteByIndex(const virNetworkDef *def,
|
2017-03-08 15:41:57 +00:00
|
|
|
int family,
|
|
|
|
size_t n)
|
2015-07-09 13:50:41 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (!def->routes || n >= def->nroutes)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (family == AF_UNSPEC)
|
|
|
|
return def->routes[n];
|
|
|
|
|
|
|
|
/* find the nth route of type "family" */
|
|
|
|
for (i = 0; i < def->nroutes; i++) {
|
2016-06-14 17:40:04 +00:00
|
|
|
virSocketAddrPtr addr = virNetDevIPRouteGetAddress(def->routes[i]);
|
2015-07-09 13:50:41 +00:00
|
|
|
if (VIR_SOCKET_ADDR_IS_FAMILY(addr, family)
|
|
|
|
&& (n-- <= 0)) {
|
|
|
|
return def->routes[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* failed to find enough of the right family */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2010-11-26 22:20:37 +00:00
|
|
|
/* return number of 1 bits in netmask for the network's ipAddress,
|
|
|
|
* or -1 on error
|
|
|
|
*/
|
2017-03-08 15:41:57 +00:00
|
|
|
int
|
|
|
|
virNetworkIPDefPrefix(const virNetworkIPDef *def)
|
2010-11-26 22:20:37 +00:00
|
|
|
{
|
2016-06-08 16:48:50 +00:00
|
|
|
return virSocketAddrGetIPPrefix(&def->address,
|
2013-04-20 19:45:46 +00:00
|
|
|
&def->netmask,
|
|
|
|
def->prefix);
|
2010-11-26 22:20:37 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2010-11-26 22:20:37 +00:00
|
|
|
/* Fill in a virSocketAddr with the proper netmask for this
|
|
|
|
* definition, based on either the definition's netmask, or its
|
|
|
|
* prefix. Return -1 on error (and set the netmask family to AF_UNSPEC)
|
|
|
|
*/
|
2016-06-08 16:48:50 +00:00
|
|
|
int virNetworkIPDefNetmask(const virNetworkIPDef *def,
|
2010-11-17 18:36:19 +00:00
|
|
|
virSocketAddrPtr netmask)
|
2010-11-26 22:20:37 +00:00
|
|
|
{
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) {
|
2010-11-26 22:20:37 +00:00
|
|
|
*netmask = def->netmask;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-08 16:48:50 +00:00
|
|
|
return virSocketAddrPrefixToNetmask(virNetworkIPDefPrefix(def), netmask,
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
VIR_SOCKET_ADDR_FAMILY(&def->address));
|
2010-11-26 22:20:37 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
static int
|
2013-02-19 10:44:16 +00:00
|
|
|
virSocketAddrRangeParseXML(const char *networkName,
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr ipdef,
|
2015-05-22 21:32:02 +00:00
|
|
|
xmlNodePtr node,
|
|
|
|
virSocketAddrRangePtr range)
|
2012-09-14 18:57:34 +00:00
|
|
|
{
|
|
|
|
char *start = NULL, *end = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (!(start = virXMLPropString(node, "start"))) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing 'start' attribute in dhcp range for network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (virSocketAddrParse(&range->start, start, AF_UNSPEC) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(end = virXMLPropString(node, "end"))) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing 'end' attribute in dhcp range for network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (virSocketAddrParse(&range->end, end, AF_UNSPEC) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* do a sanity check of the range */
|
2015-05-22 21:32:02 +00:00
|
|
|
if (virSocketAddrGetRange(&range->start, &range->end, &ipdef->address,
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPrefix(ipdef)) < 0)
|
2012-09-14 18:57:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2012-09-14 18:57:34 +00:00
|
|
|
VIR_FREE(start);
|
|
|
|
VIR_FREE(end);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 18:57:34 +00:00
|
|
|
static int
|
2012-11-11 23:55:12 +00:00
|
|
|
virNetworkDHCPHostDefParseXML(const char *networkName,
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr def,
|
2012-11-11 23:55:12 +00:00
|
|
|
xmlNodePtr node,
|
|
|
|
virNetworkDHCPHostDefPtr host,
|
|
|
|
bool partialOkay)
|
2012-09-14 18:57:34 +00:00
|
|
|
{
|
2013-02-15 19:02:26 +00:00
|
|
|
char *mac = NULL, *name = NULL, *ip = NULL, *id = NULL;
|
2012-09-14 18:57:34 +00:00
|
|
|
virMacAddr addr;
|
|
|
|
virSocketAddr inaddr;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
mac = virXMLPropString(node, "mac");
|
|
|
|
if (mac != NULL) {
|
2012-12-06 17:20:38 +00:00
|
|
|
if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid to specify MAC address '%s' "
|
|
|
|
"in network '%s' IPv6 static host definition"),
|
|
|
|
mac, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-09-14 18:57:34 +00:00
|
|
|
if (virMacAddrParse(mac, &addr) < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Cannot parse MAC address '%s' in network '%s'"),
|
|
|
|
mac, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (virMacAddrIsMulticast(&addr)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("expected unicast mac address, found "
|
|
|
|
"multicast '%s' in network '%s'"),
|
|
|
|
(const char *)mac, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-15 19:02:26 +00:00
|
|
|
id = virXMLPropString(node, "id");
|
|
|
|
if (id) {
|
|
|
|
char *cp = id + strspn(id, "0123456789abcdefABCDEF:");
|
|
|
|
if (*cp) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid character '%c' in id '%s' of network '%s'"),
|
|
|
|
*cp, id, networkName);
|
2015-02-26 06:14:20 +00:00
|
|
|
goto cleanup;
|
2013-02-15 19:02:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-14 18:57:34 +00:00
|
|
|
name = virXMLPropString(node, "name");
|
|
|
|
if (name && (!c_isalpha(name[0]))) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
2013-02-15 19:02:26 +00:00
|
|
|
_("Cannot use host name '%s' in network '%s'"),
|
2012-09-14 18:57:34 +00:00
|
|
|
name, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ip = virXMLPropString(node, "ip");
|
|
|
|
if (ip && (virSocketAddrParse(&inaddr, ip, AF_UNSPEC) < 0)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid IP address in static host definition "
|
|
|
|
"for network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (partialOkay) {
|
|
|
|
/* for search/match, you just need one of the three */
|
|
|
|
if (!(mac || name || ip)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("At least one of name, mac, or ip attribute "
|
|
|
|
"must be specified for static host definition "
|
|
|
|
"in network '%s' "),
|
|
|
|
networkName);
|
2015-02-26 08:03:09 +00:00
|
|
|
goto cleanup;
|
2012-09-14 18:57:34 +00:00
|
|
|
}
|
|
|
|
} else {
|
2012-12-06 17:20:38 +00:00
|
|
|
/* normal usage - you need at least name (IPv6) or one of MAC
|
|
|
|
* address or name (IPv4)
|
|
|
|
*/
|
|
|
|
if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
|
2013-02-15 19:02:26 +00:00
|
|
|
if (!(id || name)) {
|
2012-12-06 17:20:38 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Static host definition in IPv6 network '%s' "
|
2013-02-15 19:02:26 +00:00
|
|
|
"must have id or name attribute"),
|
2012-12-06 17:20:38 +00:00
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else if (!(mac || name)) {
|
2012-09-14 18:57:34 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
2012-12-06 17:20:38 +00:00
|
|
|
_("Static host definition in IPv4 network '%s' "
|
2012-09-14 18:57:34 +00:00
|
|
|
"must have mac or name attribute"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!ip) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing IP address in static host definition "
|
|
|
|
"for network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
host->mac = mac;
|
|
|
|
mac = NULL;
|
2013-02-15 19:02:26 +00:00
|
|
|
host->id = id;
|
|
|
|
id = NULL;
|
2012-09-14 18:57:34 +00:00
|
|
|
host->name = name;
|
|
|
|
name = NULL;
|
|
|
|
if (ip)
|
|
|
|
host->ip = inaddr;
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2012-09-14 18:57:34 +00:00
|
|
|
VIR_FREE(mac);
|
2013-02-15 19:02:26 +00:00
|
|
|
VIR_FREE(id);
|
2012-09-14 18:57:34 +00:00
|
|
|
VIR_FREE(name);
|
|
|
|
VIR_FREE(ip);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 18:57:34 +00:00
|
|
|
static int
|
2012-11-11 23:55:12 +00:00
|
|
|
virNetworkDHCPDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr def)
|
2010-11-17 18:36:19 +00:00
|
|
|
{
|
2015-05-21 19:51:02 +00:00
|
|
|
int ret = -1;
|
2008-07-11 10:48:34 +00:00
|
|
|
xmlNodePtr cur;
|
2015-05-21 19:51:02 +00:00
|
|
|
virSocketAddrRange range;
|
|
|
|
virNetworkDHCPHostDef host;
|
|
|
|
|
|
|
|
memset(&range, 0, sizeof(range));
|
|
|
|
memset(&host, 0, sizeof(host));
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
2008-08-20 12:50:29 +00:00
|
|
|
if (cur->type == XML_ELEMENT_NODE &&
|
2017-08-14 12:31:52 +00:00
|
|
|
virXMLNodeNameEqual(cur, "range")) {
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2015-05-21 19:51:02 +00:00
|
|
|
if (virSocketAddrRangeParseXML(networkName, def, cur, &range) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (VIR_APPEND_ELEMENT(def->ranges, def->nranges, range) < 0)
|
|
|
|
goto cleanup;
|
2012-09-14 18:57:34 +00:00
|
|
|
|
2008-08-20 12:50:29 +00:00
|
|
|
} else if (cur->type == XML_ELEMENT_NODE &&
|
2017-08-14 12:31:52 +00:00
|
|
|
virXMLNodeNameEqual(cur, "host")) {
|
2008-08-20 12:50:29 +00:00
|
|
|
|
2012-12-06 17:20:38 +00:00
|
|
|
if (virNetworkDHCPHostDefParseXML(networkName, def, cur,
|
2015-05-21 19:51:02 +00:00
|
|
|
&host, false) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (VIR_APPEND_ELEMENT(def->hosts, def->nhosts, host) < 0)
|
|
|
|
goto cleanup;
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2012-12-06 17:20:38 +00:00
|
|
|
} else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) &&
|
|
|
|
cur->type == XML_ELEMENT_NODE &&
|
2017-08-14 12:31:52 +00:00
|
|
|
virXMLNodeNameEqual(cur, "bootp")) {
|
2010-11-24 20:08:55 +00:00
|
|
|
char *file;
|
|
|
|
char *server;
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
virSocketAddr inaddr;
|
2010-10-22 12:28:04 +00:00
|
|
|
memset(&inaddr, 0, sizeof(inaddr));
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2010-11-24 20:08:55 +00:00
|
|
|
if (!(file = virXMLPropString(cur, "file"))) {
|
2009-09-21 20:50:25 +00:00
|
|
|
cur = cur->next;
|
|
|
|
continue;
|
|
|
|
}
|
2010-11-24 20:08:55 +00:00
|
|
|
server = virXMLPropString(cur, "server");
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
|
2010-10-22 12:28:04 +00:00
|
|
|
if (server &&
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
virSocketAddrParse(&inaddr, server, AF_UNSPEC) < 0) {
|
2010-11-24 20:29:38 +00:00
|
|
|
VIR_FREE(file);
|
|
|
|
VIR_FREE(server);
|
2015-05-21 19:51:02 +00:00
|
|
|
goto cleanup;
|
2010-11-24 20:29:38 +00:00
|
|
|
}
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2010-11-24 20:08:55 +00:00
|
|
|
def->bootfile = file;
|
Convert virNetwork to use virSocketAddr everywhere
Instead of storing the IP address string in virNetwork related
structs, store the parsed virSocketAddr. This will make it
easier to add IPv6 support in the future, by letting driver
code directly check what address family is present
* src/conf/network_conf.c, src/conf/network_conf.h,
src/network/bridge_driver.c: Convert to use virSocketAddr
in virNetwork, instead of char *.
* src/util/bridge.c, src/util/bridge.h,
src/util/dnsmasq.c, src/util/dnsmasq.h,
src/util/iptables.c, src/util/iptables.h: Convert to
take a virSocketAddr instead of char * for any IP
address parameters
* src/util/network.h: Add macros to determine if an address
is set, and what address family is set.
2010-10-21 12:14:33 +00:00
|
|
|
def->bootserver = inaddr;
|
2010-11-24 20:29:38 +00:00
|
|
|
VIR_FREE(server);
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
2015-05-21 19:51:02 +00:00
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
virNetworkDHCPHostDefClear(&host);
|
|
|
|
return ret;
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2011-06-24 10:04:40 +00:00
|
|
|
static int
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virNetworkDNSHostDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
virNetworkDNSHostDefPtr def,
|
|
|
|
bool partialOkay)
|
2011-06-24 10:04:40 +00:00
|
|
|
{
|
|
|
|
xmlNodePtr cur;
|
|
|
|
char *ip;
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (!(ip = virXMLPropString(node, "ip")) && !partialOkay) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing IP address in network '%s' DNS HOST record"),
|
|
|
|
networkName);
|
2011-06-24 10:04:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (ip && (virSocketAddrParse(&def->ip, ip, AF_UNSPEC) < 0)) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Invalid IP address in network '%s' DNS HOST record"),
|
|
|
|
networkName);
|
|
|
|
VIR_FREE(ip);
|
2011-06-24 10:04:40 +00:00
|
|
|
goto error;
|
|
|
|
}
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
VIR_FREE(ip);
|
2011-06-24 10:04:40 +00:00
|
|
|
|
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
|
|
|
if (cur->type == XML_ELEMENT_NODE &&
|
2017-08-14 12:31:52 +00:00
|
|
|
virXMLNodeNameEqual(cur, "hostname")) {
|
2011-06-24 10:04:40 +00:00
|
|
|
if (cur->children != NULL) {
|
2014-03-07 08:33:31 +00:00
|
|
|
char *name = (char *) xmlNodeGetContent(cur);
|
|
|
|
|
|
|
|
if (!name) {
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing hostname in network '%s' DNS HOST record"),
|
|
|
|
networkName);
|
2014-03-07 08:33:31 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (VIR_APPEND_ELEMENT(def->names, def->nnames, name) < 0) {
|
|
|
|
VIR_FREE(name);
|
|
|
|
goto error;
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
}
|
2011-06-24 10:04:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (def->nnames == 0 && !partialOkay) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing hostname in network '%s' DNS HOST record"),
|
|
|
|
networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2011-06-24 10:04:40 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (!VIR_SOCKET_ADDR_VALID(&def->ip) && def->nnames == 0) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing ip and hostname in network '%s' DNS HOST record"),
|
|
|
|
networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2011-06-24 10:04:40 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
return 0;
|
2011-06-24 10:04:40 +00:00
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
error:
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virNetworkDNSHostDefClear(def);
|
|
|
|
return -1;
|
2011-06-24 10:04:40 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
/* This includes all characters used in the names of current
|
|
|
|
* /etc/services and /etc/protocols files (on Fedora 20), except ".",
|
|
|
|
* which we can't allow because it would conflict with the use of "."
|
|
|
|
* as a field separator in the SRV record, there appears to be no way
|
|
|
|
* to escape it in, and the protocols/services that use "." in the
|
|
|
|
* name are obscure and unlikely to be used anyway.
|
|
|
|
*/
|
|
|
|
#define PROTOCOL_CHARS \
|
|
|
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" \
|
|
|
|
"-+/"
|
|
|
|
|
|
|
|
#define SERVICE_CHARS \
|
|
|
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" \
|
|
|
|
"_-+/*"
|
|
|
|
|
2012-01-02 14:23:54 +00:00
|
|
|
static int
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virNetworkDNSSrvDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
virNetworkDNSSrvDefPtr def,
|
|
|
|
bool partialOkay)
|
2012-01-02 14:23:54 +00:00
|
|
|
{
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
int ret;
|
|
|
|
xmlNodePtr save_ctxt = ctxt->node;
|
|
|
|
|
|
|
|
ctxt->node = node;
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (!(def->service = virXMLPropString(node, "service")) && !partialOkay) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
_("missing required service attribute in DNS SRV record "
|
|
|
|
"of network '%s'"), networkName);
|
2012-01-02 14:23:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
if (def->service) {
|
|
|
|
if (strlen(def->service) > DNS_RECORD_LENGTH_SRV) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("service attribute '%s' in network '%s' is too long, "
|
|
|
|
"limit is %d bytes"),
|
|
|
|
def->service, networkName, DNS_RECORD_LENGTH_SRV);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (strspn(def->service, SERVICE_CHARS) < strlen(def->service)) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("invalid character in service attribute '%s' "
|
|
|
|
"in DNS SRV record of network '%s'"),
|
|
|
|
def->service, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2012-01-02 14:23:54 +00:00
|
|
|
}
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (!(def->protocol = virXMLPropString(node, "protocol")) && !partialOkay) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
_("missing required protocol attribute "
|
|
|
|
"in DNS SRV record '%s' of network '%s'"),
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
def->service, networkName);
|
2012-01-02 14:23:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
if (def->protocol &&
|
|
|
|
strspn(def->protocol, PROTOCOL_CHARS) < strlen(def->protocol)) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
_("invalid character in protocol attribute '%s' "
|
|
|
|
"in DNS SRV record of network '%s'"),
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
def->protocol, networkName);
|
2012-01-02 14:23:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
/* Following attributes are optional */
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
def->domain = virXMLPropString(node, "domain");
|
|
|
|
def->target = virXMLPropString(node, "target");
|
2012-01-02 14:23:54 +00:00
|
|
|
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
ret = virXPathUInt("string(./@port)", ctxt, &def->port);
|
|
|
|
if (ret >= 0 && !def->target) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("DNS SRV port attribute not permitted without "
|
|
|
|
"target for service '%s' in network '%s'"),
|
|
|
|
def->service, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (ret == -2 || (ret >= 0 && (def->port < 1 || def->port > 65535))) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("invalid DNS SRV port attribute "
|
|
|
|
"for service '%s' in network '%s'"),
|
|
|
|
def->service, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2012-01-02 14:23:54 +00:00
|
|
|
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
ret = virXPathUInt("string(./@priority)", ctxt, &def->priority);
|
|
|
|
if (ret >= 0 && !def->target) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("DNS SRV priority attribute not permitted without "
|
|
|
|
"target for service '%s' in network '%s'"),
|
|
|
|
def->service, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (ret == -2 || (ret >= 0 && def->priority > 65535)) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Invalid DNS SRV priority attribute "
|
|
|
|
"for service '%s' in network '%s'"),
|
|
|
|
def->service, networkName);
|
|
|
|
goto error;
|
2012-01-02 14:23:54 +00:00
|
|
|
}
|
|
|
|
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
ret = virXPathUInt("string(./@weight)", ctxt, &def->weight);
|
|
|
|
if (ret >= 0 && !def->target) {
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
_("DNS SRV weight attribute not permitted without "
|
|
|
|
"target for service '%s' in network '%s'"),
|
|
|
|
def->service, networkName);
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
goto error;
|
|
|
|
}
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
if (ret == -2 || (ret >= 0 && def->weight > 65535)) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("invalid DNS SRV weight attribute "
|
|
|
|
"for service '%s' in network '%s'"),
|
|
|
|
def->service, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxt->node = save_ctxt;
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
return 0;
|
2012-01-02 14:23:54 +00:00
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
error:
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virNetworkDNSSrvDefClear(def);
|
network: fix problems with SRV records
A patch submitted by Steven Malin last week pointed out a problem with
libvirt's DNS SRV record configuration:
https://www.redhat.com/archives/libvir-list/2014-March/msg00536.html
When searching for that message later, I found another series that had
been posted by Guannan Ren back in 2012 that somehow slipped between
the cracks:
https://www.redhat.com/archives/libvir-list/2012-July/msg00236.html
That patch was very much out of date, but also pointed out some real
problems.
This patch fixes all the noted problems by refactoring
virNetworkDNSSrvDefParseXML() and networkDnsmasqConfContents(), then
verifies those fixes by added several new records to the test case.
Problems fixed:
* both service and protocol now have an underscore ("_") prepended on
the commandline, as required by RFC2782.
<srv service='sip' protocol='udp' domain='example.com'
target='tests.example.com' port='5060' priority='10'
weight='150'/>
before: srv-host=sip.udp.example.com,tests.example.com,5060,10,150
after: srv-host=_sip._udp.example.com,tests.example.com,5060,10,150
* if "domain" wasn't specified in the <srv> element, the extra
trailing "." will no longer be added to the dnsmasq commandline.
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060' priority='10' weight='150'/>
before: srv-host=sip.udp.,tests.example.com,5060,10,150
after: srv-host=_sip._udp,tests.example.com,5060,10,150
* when optional attributes aren't specified, the separating comma is
also now not placed on the dnsmasq commandline. If optional
attributes in the middle of the line are not specified, they are
replaced with a default value in the commandline (1 for port, 0 for
priority and weight).
<srv service='sip' protocol='udp' target='tests.example.com'
port='5060'/>
before: srv-host=sip.udp.,tests.example.com,5060,,
after: srv-host=_sip._udp,tests.example.com,5060
(actually the would have generated an error, because "optional"
attributes weren't really optional.)
* The allowed characters for both service and protocol are now limited
to alphanumerics, plus a few special characters that are found in
existing names in /etc/services and /etc/protocols. (One exception
is that both of these files contain names with an embedded ".", but
"." can't be used in these fields of an SRV record because it is
used as a field separator and there is no method to escape a "."
into a field.) (Previously only the strings "tcp" and "udp" were
allowed for protocol, but this restriction has been removed, since
RFC2782 specifically says that it isn't limited to those, and that
anyway it is case insensitive.)
* the "domain" attribute is no longer required in order to recognize
the port, priority, and weight attributes during parsing. Only
"target" is required for this.
* if "target" isn't specified, port, priority, and weight are not
allowed (since they are meaningless - an empty target means "this
service is *not available* for this domain").
* port, priority, and weight are now truly optional, as the comments
originally suggested, but which was not actually true.
2014-03-18 01:16:38 +00:00
|
|
|
ctxt->node = save_ctxt;
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
static int
|
|
|
|
virNetworkDNSTxtDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
virNetworkDNSTxtDefPtr def,
|
|
|
|
bool partialOkay)
|
|
|
|
{
|
2015-02-23 12:19:16 +00:00
|
|
|
const char *bad = " ,";
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (!(def->name = virXMLPropString(node, "name"))) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("missing required name attribute in DNS TXT record "
|
|
|
|
"of network %s"), networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2015-02-23 12:19:16 +00:00
|
|
|
if (strcspn(def->name, bad) != strlen(def->name)) {
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
2015-02-23 12:19:16 +00:00
|
|
|
_("prohibited character in DNS TXT record "
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
"name '%s' of network %s"), def->name, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (!(def->value = virXMLPropString(node, "value")) && !partialOkay) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("missing required value attribute in DNS TXT record "
|
|
|
|
"named '%s' of network %s"), def->name, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2012-01-02 14:23:54 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (!(def->name || def->value)) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing required name or value "
|
|
|
|
"in DNS TXT record of network %s"), networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
return 0;
|
2012-01-02 14:23:54 +00:00
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
error:
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virNetworkDNSTxtDefClear(def);
|
|
|
|
return -1;
|
2012-01-02 14:23:54 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
static int
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
virNetworkDNSDefParseXML(const char *networkName,
|
2012-01-02 14:23:54 +00:00
|
|
|
xmlNodePtr node,
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
virNetworkDNSDefPtr def)
|
2011-06-24 10:04:36 +00:00
|
|
|
{
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
xmlNodePtr *hostNodes = NULL;
|
|
|
|
xmlNodePtr *srvNodes = NULL;
|
|
|
|
xmlNodePtr *txtNodes = NULL;
|
2013-09-13 16:31:07 +00:00
|
|
|
xmlNodePtr *fwdNodes = NULL;
|
2013-08-13 22:56:38 +00:00
|
|
|
char *forwardPlainNames = NULL;
|
2016-08-11 21:29:43 +00:00
|
|
|
char *enable = NULL;
|
2013-09-13 16:31:07 +00:00
|
|
|
int nhosts, nsrvs, ntxts, nfwds;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int ret = -1;
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
xmlNodePtr save = ctxt->node;
|
2011-06-24 10:04:36 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
ctxt->node = node;
|
|
|
|
|
2016-08-11 21:29:43 +00:00
|
|
|
enable = virXPathString("string(./@enable)", ctxt);
|
|
|
|
if (enable) {
|
|
|
|
def->enable = virTristateBoolTypeFromString(enable);
|
|
|
|
if (def->enable <= 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid dns enable setting '%s' "
|
|
|
|
"in network '%s'"),
|
|
|
|
enable, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-13 22:56:38 +00:00
|
|
|
forwardPlainNames = virXPathString("string(./@forwardPlainNames)", ctxt);
|
|
|
|
if (forwardPlainNames) {
|
2014-06-27 15:16:54 +00:00
|
|
|
def->forwardPlainNames = virTristateBoolTypeFromString(forwardPlainNames);
|
2014-01-31 13:50:16 +00:00
|
|
|
if (def->forwardPlainNames <= 0) {
|
2013-08-13 22:56:38 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid dns forwardPlainNames setting '%s' "
|
|
|
|
"in network '%s'"),
|
|
|
|
forwardPlainNames, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-13 16:31:07 +00:00
|
|
|
nfwds = virXPathNodeSet("./forwarder", ctxt, &fwdNodes);
|
|
|
|
if (nfwds < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <forwarder> element found in <dns> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (nfwds > 0) {
|
|
|
|
if (VIR_ALLOC_N(def->forwarders, nfwds) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < nfwds; i++) {
|
2016-08-12 02:28:27 +00:00
|
|
|
char *addr = virXMLPropString(fwdNodes[i], "addr");
|
|
|
|
|
|
|
|
if (addr && virSocketAddrParse(&def->forwarders[i].addr,
|
|
|
|
addr, AF_UNSPEC) < 0) {
|
2013-09-13 16:31:07 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
2016-08-12 02:28:27 +00:00
|
|
|
_("Invalid forwarder IP address '%s' "
|
|
|
|
"in network '%s'"),
|
|
|
|
addr, networkName);
|
|
|
|
VIR_FREE(addr);
|
2013-09-13 16:31:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2016-08-12 02:28:27 +00:00
|
|
|
def->forwarders[i].domain = virXMLPropString(fwdNodes[i], "domain");
|
|
|
|
if (!(addr || def->forwarders[i].domain)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
|
_("Invalid forwarder element, must contain "
|
|
|
|
"at least one of addr or domain"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VIR_FREE(addr);
|
2013-09-13 16:31:07 +00:00
|
|
|
def->nfwds++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
nhosts = virXPathNodeSet("./host", ctxt, &hostNodes);
|
|
|
|
if (nhosts < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <host> element found in <dns> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (nhosts > 0) {
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC_N(def->hosts, nhosts) < 0)
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
goto cleanup;
|
2011-06-24 10:04:36 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < nhosts; i++) {
|
|
|
|
if (virNetworkDNSHostDefParseXML(networkName, hostNodes[i],
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
&def->hosts[def->nhosts], false) < 0) {
|
|
|
|
goto cleanup;
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
def->nhosts++;
|
|
|
|
}
|
|
|
|
}
|
2011-06-24 10:04:36 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
nsrvs = virXPathNodeSet("./srv", ctxt, &srvNodes);
|
|
|
|
if (nsrvs < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <srv> element found in <dns> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (nsrvs > 0) {
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC_N(def->srvs, nsrvs) < 0)
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
goto cleanup;
|
2011-06-24 10:04:36 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < nsrvs; i++) {
|
|
|
|
if (virNetworkDNSSrvDefParseXML(networkName, srvNodes[i], ctxt,
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
&def->srvs[def->nsrvs], false) < 0) {
|
|
|
|
goto cleanup;
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
def->nsrvs++;
|
|
|
|
}
|
|
|
|
}
|
2011-06-24 10:04:36 +00:00
|
|
|
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
ntxts = virXPathNodeSet("./txt", ctxt, &txtNodes);
|
|
|
|
if (ntxts < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <txt> element found in <dns> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (ntxts > 0) {
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC_N(def->txts, ntxts) < 0)
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
goto cleanup;
|
2011-06-24 10:04:36 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < ntxts; i++) {
|
|
|
|
if (virNetworkDNSTxtDefParseXML(networkName, txtNodes[i],
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
&def->txts[def->ntxts], false) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
def->ntxts++;
|
|
|
|
}
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
|
|
|
|
2016-08-11 21:29:43 +00:00
|
|
|
if (def->enable == VIR_TRISTATE_BOOL_NO &&
|
|
|
|
(nfwds || nhosts || nsrvs || ntxts)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Extra data in disabled network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2016-08-11 21:29:43 +00:00
|
|
|
VIR_FREE(enable);
|
2013-08-13 22:56:38 +00:00
|
|
|
VIR_FREE(forwardPlainNames);
|
2013-09-13 16:31:07 +00:00
|
|
|
VIR_FREE(fwdNodes);
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
VIR_FREE(hostNodes);
|
|
|
|
VIR_FREE(srvNodes);
|
|
|
|
VIR_FREE(txtNodes);
|
|
|
|
ctxt->node = save;
|
2011-06-24 10:04:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2009-09-21 20:50:25 +00:00
|
|
|
static int
|
2012-11-11 23:55:12 +00:00
|
|
|
virNetworkIPDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt,
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr def)
|
2010-11-17 18:36:19 +00:00
|
|
|
{
|
|
|
|
/*
|
2016-06-08 16:48:50 +00:00
|
|
|
* virNetworkIPDef object is already allocated as part of an array.
|
2010-11-17 18:36:19 +00:00
|
|
|
* On failure clear it out, but don't free it.
|
|
|
|
*/
|
|
|
|
|
2016-12-08 13:05:16 +00:00
|
|
|
xmlNodePtr save;
|
|
|
|
xmlNodePtr dhcp;
|
2010-11-17 18:36:19 +00:00
|
|
|
char *address = NULL, *netmask = NULL;
|
2013-04-21 14:34:40 +00:00
|
|
|
unsigned long prefix = 0;
|
|
|
|
int prefixRc;
|
2010-11-17 18:36:19 +00:00
|
|
|
int result = -1;
|
2016-12-08 21:23:09 +00:00
|
|
|
char *localPtr = NULL;
|
2010-11-17 18:36:19 +00:00
|
|
|
|
|
|
|
save = ctxt->node;
|
|
|
|
ctxt->node = node;
|
|
|
|
|
|
|
|
/* grab raw data from XML */
|
|
|
|
def->family = virXPathString("string(./@family)", ctxt);
|
2013-04-21 14:34:40 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
address = virXPathString("string(./@address)", ctxt);
|
2013-04-21 14:34:40 +00:00
|
|
|
if (!address) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing required address attribute in network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid address '%s' in network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-11-17 18:36:19 +00:00
|
|
|
|
|
|
|
netmask = virXPathString("string(./@netmask)", ctxt);
|
2013-04-21 14:34:40 +00:00
|
|
|
if (netmask &&
|
|
|
|
(virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid netmask '%s' in network '%s'"),
|
|
|
|
netmask, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-11-17 18:36:19 +00:00
|
|
|
|
2013-04-21 14:34:40 +00:00
|
|
|
prefixRc = virXPathULong("string(./@prefix)", ctxt, &prefix);
|
|
|
|
if (prefixRc == -2) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid ULong value specified for prefix in definition of network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
2013-04-21 14:34:40 +00:00
|
|
|
if (prefixRc < 0)
|
|
|
|
def->prefix = 0;
|
|
|
|
else
|
|
|
|
def->prefix = prefix;
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2016-12-08 21:23:09 +00:00
|
|
|
localPtr = virXPathString("string(./@localPtr)", ctxt);
|
|
|
|
if (localPtr) {
|
|
|
|
def->localPTR = virTristateBoolTypeFromString(localPtr);
|
|
|
|
if (def->localPTR <= 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid localPtr value '%s' in network '%s'"),
|
|
|
|
localPtr, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-21 14:34:40 +00:00
|
|
|
/* validate address, etc. for each family */
|
|
|
|
if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) {
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) ||
|
|
|
|
VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2013-04-21 14:34:40 +00:00
|
|
|
_("%s family specified for non-IPv4 address '%s' in network '%s'"),
|
|
|
|
def->family == NULL? "no" : "ipv4", address, networkName);
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
2013-04-21 14:34:40 +00:00
|
|
|
if (netmask) {
|
|
|
|
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("Invalid netmask '%s' for address '%s' "
|
|
|
|
"in network '%s' (both must be IPv4)"),
|
|
|
|
netmask, address, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (def->prefix > 0) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("Network '%s' IP address cannot have "
|
|
|
|
"both a prefix and a netmask"), networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else if (def->prefix > 32) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2013-04-21 14:34:40 +00:00
|
|
|
_("Invalid IPv4 prefix '%lu' in network '%s'"),
|
|
|
|
prefix, networkName);
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
|
|
|
} else if (STREQ(def->family, "ipv6")) {
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2013-04-21 14:34:40 +00:00
|
|
|
_("Family 'ipv6' specified for non-IPv6 address '%s' in network '%s'"),
|
2012-07-18 10:50:44 +00:00
|
|
|
address, networkName);
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
2013-04-21 14:34:40 +00:00
|
|
|
if (netmask) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2013-04-21 14:34:40 +00:00
|
|
|
_("netmask not allowed for IPv6 address '%s' in network '%s'"),
|
2012-07-18 10:50:44 +00:00
|
|
|
address, networkName);
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
2013-04-21 14:34:40 +00:00
|
|
|
if (def->prefix > 128) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2013-04-21 14:34:40 +00:00
|
|
|
_("Invalid IPv6 prefix '%lu' in network '%s'"),
|
|
|
|
prefix, networkName);
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
2013-04-21 14:34:40 +00:00
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Unrecognized family '%s' in network '%s'"),
|
|
|
|
def->family, networkName);
|
|
|
|
goto cleanup;
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
|
|
|
|
2016-12-08 13:05:16 +00:00
|
|
|
if ((dhcp = virXPathNode("./dhcp[1]", ctxt)) &&
|
|
|
|
virNetworkDHCPDefParseXML(networkName, dhcp, def) < 0)
|
|
|
|
goto cleanup;
|
2010-11-17 18:36:19 +00:00
|
|
|
|
2016-12-08 13:05:16 +00:00
|
|
|
if (virXPathNode("./tftp[1]", ctxt)) {
|
|
|
|
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("Unsupported <tftp> element in an IPv6 element "
|
|
|
|
"in network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
2009-09-21 20:50:25 +00:00
|
|
|
}
|
2016-12-08 13:05:16 +00:00
|
|
|
|
|
|
|
def->tftproot = virXPathString("string(./tftp[1]/@root)", ctxt);
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
result = 0;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2014-11-13 14:23:27 +00:00
|
|
|
if (result < 0)
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefClear(def);
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(address);
|
|
|
|
VIR_FREE(netmask);
|
2016-12-08 21:23:09 +00:00
|
|
|
VIR_FREE(localPtr);
|
2010-11-17 18:36:19 +00:00
|
|
|
|
|
|
|
ctxt->node = save;
|
|
|
|
return result;
|
2009-09-21 20:50:25 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
static int
|
|
|
|
virNetworkPortGroupParseXML(virPortGroupDefPtr def,
|
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* virPortGroupDef object is already allocated as part of an array.
|
|
|
|
* On failure clear it out, but don't free it.
|
|
|
|
*/
|
|
|
|
|
|
|
|
xmlNodePtr save;
|
|
|
|
xmlNodePtr virtPortNode;
|
2012-08-12 07:51:30 +00:00
|
|
|
xmlNodePtr vlanNode;
|
2011-07-26 12:42:37 +00:00
|
|
|
xmlNodePtr bandwidth_node;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
char *isDefault = NULL;
|
2014-09-23 18:19:08 +00:00
|
|
|
char *trustGuestRxFilters = NULL;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
|
|
|
int result = -1;
|
|
|
|
|
|
|
|
save = ctxt->node;
|
|
|
|
ctxt->node = node;
|
|
|
|
|
|
|
|
/* grab raw data from XML */
|
|
|
|
def->name = virXPathString("string(./@name)", ctxt);
|
2012-11-28 04:59:17 +00:00
|
|
|
if (!def->name) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
|
_("Missing required name attribute in portgroup"));
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
2012-11-28 04:59:17 +00:00
|
|
|
}
|
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
isDefault = virXPathString("string(./@default)", ctxt);
|
|
|
|
def->isDefault = isDefault && STRCASEEQ(isDefault, "yes");
|
|
|
|
|
2014-09-23 18:19:08 +00:00
|
|
|
trustGuestRxFilters
|
|
|
|
= virXPathString("string(./@trustGuestRxFilters)", ctxt);
|
|
|
|
if (trustGuestRxFilters) {
|
|
|
|
if ((def->trustGuestRxFilters
|
|
|
|
= virTristateBoolTypeFromString(trustGuestRxFilters)) <= 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid trustGuestRxFilters setting '%s' "
|
|
|
|
"in portgroup"), trustGuestRxFilters);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
virtPortNode = virXPathNode("./virtualport", ctxt);
|
|
|
|
if (virtPortNode &&
|
conf: support partially-specified <virtualport> in parser and formatter
Until now, all attributes in a <virtualport> parameter list that were
acceptable for a particular type, were also required. There were no
optional attributes.
One of the aims of supporting <virtualport> in libvirt's virtual
networks and portgroups is to allow specifying the group-wide
parameters in the network's virtualport, and merge that with the
interface's virtualport, which will have the instance-specific info
(i.e. the interfaceid or instanceid).
Additionally, the guest's interface XML shouldn't need to know what
type of network connection will be used prior to runtime - it could be
openvswitch, 802.1Qbh, 802.1Qbg, or none of the above - but should
still be able to specify instance-specific info just in case it turns
out to be applicable.
Finally, up to now, the parser for virtualport has always generated a
random instanceid/interfaceid when appropriate, making it impossible
to leave it blank (which is what's required for virtualports within a
network/portprofile definition).
This patch modifies the parser and formatter of the <virtualport>
element in the following ways:
* because most of the attributes in a virNetDevVPortProfile are fixed
size binary data with no reserved values, there is no way to embed a
"this value wasn't specified" sentinel into the existing data. To
solve this problem, the new *_specified fields in the
virNetDevVPortProfile object that were added in a previous patch of
this series are now set when the corresponding attribute is present
during the parse.
* allow parsing/formatting a <virtualport> that has no type set. In
this case, all fields are settable, but all are also optional.
* add a GENERATE_MISSING_DEFAULTS flag to the parser - if this flag is
set and an instanceid/interfaceid is expected but not provided, a
random one will be generated. This was previously the default
behavior, but is now done only for virtualports inside an
<interface> definition, not for those in <network> or <portgroup>.
* add a REQUIRE_ALL_ATTRIBUTES flag to the parser - if this flag is
set the parser will call the new
virNetDevVPortProfileCheckComplete() functions at the end of the
parser to check for any missing attributes (based on type), and
return failure if anything is missing. This used to be default
behavior. Now it is only used for the virtualport defined inside an
interface's <actual> element (by the time you've figured out the
contents of <actual>, you should have all the necessary data to fill
in the entire virtualport)
* add a REQUIRE_TYPE flag to the parser - if this flag is set, the
parser will return an error if the virtualport has no type
attribute. This also was previously the default behavior, but isn't
needed in the case of the virtualport for a type='network' interface
(i.e. the exact type isn't yet known), or the virtualport of a
portgroup (i.e. the portgroup just has modifiers for the network's
virtualport, which *does* require a type) - in those cases, the
check will be done at domain startup, once the final virtualport is
assembled (this is handled in the next patch).
2012-07-31 18:36:51 +00:00
|
|
|
(!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode, 0)))) {
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
conf: support partially-specified <virtualport> in parser and formatter
Until now, all attributes in a <virtualport> parameter list that were
acceptable for a particular type, were also required. There were no
optional attributes.
One of the aims of supporting <virtualport> in libvirt's virtual
networks and portgroups is to allow specifying the group-wide
parameters in the network's virtualport, and merge that with the
interface's virtualport, which will have the instance-specific info
(i.e. the interfaceid or instanceid).
Additionally, the guest's interface XML shouldn't need to know what
type of network connection will be used prior to runtime - it could be
openvswitch, 802.1Qbh, 802.1Qbg, or none of the above - but should
still be able to specify instance-specific info just in case it turns
out to be applicable.
Finally, up to now, the parser for virtualport has always generated a
random instanceid/interfaceid when appropriate, making it impossible
to leave it blank (which is what's required for virtualports within a
network/portprofile definition).
This patch modifies the parser and formatter of the <virtualport>
element in the following ways:
* because most of the attributes in a virNetDevVPortProfile are fixed
size binary data with no reserved values, there is no way to embed a
"this value wasn't specified" sentinel into the existing data. To
solve this problem, the new *_specified fields in the
virNetDevVPortProfile object that were added in a previous patch of
this series are now set when the corresponding attribute is present
during the parse.
* allow parsing/formatting a <virtualport> that has no type set. In
this case, all fields are settable, but all are also optional.
* add a GENERATE_MISSING_DEFAULTS flag to the parser - if this flag is
set and an instanceid/interfaceid is expected but not provided, a
random one will be generated. This was previously the default
behavior, but is now done only for virtualports inside an
<interface> definition, not for those in <network> or <portgroup>.
* add a REQUIRE_ALL_ATTRIBUTES flag to the parser - if this flag is
set the parser will call the new
virNetDevVPortProfileCheckComplete() functions at the end of the
parser to check for any missing attributes (based on type), and
return failure if anything is missing. This used to be default
behavior. Now it is only used for the virtualport defined inside an
interface's <actual> element (by the time you've figured out the
contents of <actual>, you should have all the necessary data to fill
in the entire virtualport)
* add a REQUIRE_TYPE flag to the parser - if this flag is set, the
parser will return an error if the virtualport has no type
attribute. This also was previously the default behavior, but isn't
needed in the case of the virtualport for a type='network' interface
(i.e. the exact type isn't yet known), or the virtualport of a
portgroup (i.e. the portgroup just has modifiers for the network's
virtualport, which *does* require a type) - in those cases, the
check will be done at domain startup, once the final virtualport is
assembled (this is handled in the next patch).
2012-07-31 18:36:51 +00:00
|
|
|
}
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
2011-07-26 12:42:37 +00:00
|
|
|
bandwidth_node = virXPathNode("./bandwidth", ctxt);
|
|
|
|
if (bandwidth_node &&
|
2019-05-14 14:44:55 +00:00
|
|
|
virNetDevBandwidthParse(&def->bandwidth, NULL, bandwidth_node, false) < 0)
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
2011-07-26 12:42:37 +00:00
|
|
|
|
2012-08-12 07:51:30 +00:00
|
|
|
vlanNode = virXPathNode("./vlan", ctxt);
|
|
|
|
if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
|
2012-11-11 23:55:12 +00:00
|
|
|
goto cleanup;
|
2012-08-12 07:51:30 +00:00
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
result = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2014-11-13 14:23:27 +00:00
|
|
|
if (result < 0)
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
virPortGroupDefClear(def);
|
|
|
|
VIR_FREE(isDefault);
|
2014-09-23 18:19:08 +00:00
|
|
|
VIR_FREE(trustGuestRxFilters);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
|
|
|
ctxt->node = save;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2013-02-19 10:44:14 +00:00
|
|
|
static int
|
|
|
|
virNetworkForwardNatDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
virNetworkForwardDefPtr def)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
xmlNodePtr *natAddrNodes = NULL;
|
2013-02-19 10:44:15 +00:00
|
|
|
xmlNodePtr *natPortNodes = NULL;
|
|
|
|
int nNatAddrs, nNatPorts;
|
2013-02-19 10:44:14 +00:00
|
|
|
char *addrStart = NULL;
|
|
|
|
char *addrEnd = NULL;
|
|
|
|
xmlNodePtr save = ctxt->node;
|
|
|
|
|
|
|
|
ctxt->node = node;
|
|
|
|
|
|
|
|
if (def->type != VIR_NETWORK_FORWARD_NAT) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("The <nat> element can only be used when <forward> 'mode' is 'nat' in network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* addresses for SNAT */
|
|
|
|
nNatAddrs = virXPathNodeSet("./address", ctxt, &natAddrNodes);
|
|
|
|
if (nNatAddrs < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <address> element found in <forward> of "
|
|
|
|
"network %s"), networkName);
|
|
|
|
goto cleanup;
|
|
|
|
} else if (nNatAddrs > 1) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Only one <address> element is allowed in <nat> in "
|
|
|
|
"<forward> in network %s"), networkName);
|
|
|
|
goto cleanup;
|
|
|
|
} else if (nNatAddrs == 1) {
|
|
|
|
addrStart = virXMLPropString(*natAddrNodes, "start");
|
|
|
|
if (addrStart == NULL) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("missing 'start' attribute in <address> element in <nat> in "
|
|
|
|
"<forward> in network %s"), networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
addrEnd = virXMLPropString(*natAddrNodes, "end");
|
|
|
|
if (addrEnd == NULL) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("missing 'end' attribute in <address> element in <nat> in "
|
|
|
|
"<forward> in network %s"), networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-19 10:44:16 +00:00
|
|
|
if (addrStart && virSocketAddrParse(&def->addr.start, addrStart, AF_INET) < 0) {
|
2013-02-19 10:44:14 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Bad ipv4 start address '%s' in <nat> in <forward> in "
|
|
|
|
"network '%s'"), addrStart, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-19 10:44:16 +00:00
|
|
|
if (addrEnd && virSocketAddrParse(&def->addr.end, addrEnd, AF_INET) < 0) {
|
2013-02-19 10:44:14 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Bad ipv4 end address '%s' in <nat> in <forward> in "
|
|
|
|
"network '%s'"), addrEnd, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2015-08-11 13:09:29 +00:00
|
|
|
if (addrStart && addrEnd) {
|
|
|
|
/* verify that start <= end */
|
|
|
|
if (virSocketAddrGetRange(&def->addr.start, &def->addr.end, NULL, 0) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else {
|
|
|
|
if (addrStart) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Only start address '%s' specified in <nat> in "
|
|
|
|
"<forward> in network '%s'"),
|
|
|
|
addrStart, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (addrEnd) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Only end address '%s' specified in <nat> in "
|
|
|
|
"<forward> in network '%s'"),
|
|
|
|
addrEnd, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2015-08-08 21:46:41 +00:00
|
|
|
|
2013-02-19 10:44:15 +00:00
|
|
|
/* ports for SNAT and MASQUERADE */
|
|
|
|
nNatPorts = virXPathNodeSet("./port", ctxt, &natPortNodes);
|
|
|
|
if (nNatPorts < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <port> element found in <forward> of "
|
|
|
|
"network %s"), networkName);
|
|
|
|
goto cleanup;
|
|
|
|
} else if (nNatPorts > 1) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Only one <port> element is allowed in <nat> in "
|
|
|
|
"<forward> in network %s"), networkName);
|
|
|
|
goto cleanup;
|
|
|
|
} else if (nNatPorts == 1) {
|
2013-02-19 10:44:16 +00:00
|
|
|
if (virXPathUInt("string(./port[1]/@start)", ctxt, &def->port.start) < 0
|
|
|
|
|| def->port.start > 65535) {
|
2013-02-19 10:44:15 +00:00
|
|
|
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing or invalid 'start' attribute in <port> "
|
|
|
|
"in <nat> in <forward> in network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2013-02-19 10:44:16 +00:00
|
|
|
if (virXPathUInt("string(./port[1]/@end)", ctxt, &def->port.end) < 0
|
|
|
|
|| def->port.end > 65535 || def->port.end < def->port.start) {
|
2013-02-19 10:44:15 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing or invalid 'end' attribute in <port> in "
|
|
|
|
"<nat> in <forward> in network %s"), networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2013-02-19 10:44:14 +00:00
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2013-02-19 10:44:14 +00:00
|
|
|
VIR_FREE(addrStart);
|
|
|
|
VIR_FREE(addrEnd);
|
|
|
|
VIR_FREE(natAddrNodes);
|
2013-04-10 09:38:07 +00:00
|
|
|
VIR_FREE(natPortNodes);
|
2013-02-19 10:44:14 +00:00
|
|
|
ctxt->node = save;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
static int
|
|
|
|
virNetworkForwardDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
virNetworkForwardDefPtr def)
|
|
|
|
{
|
2016-04-18 19:07:26 +00:00
|
|
|
size_t i, j;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int ret = -1;
|
2012-11-11 22:57:16 +00:00
|
|
|
xmlNodePtr *forwardIfNodes = NULL;
|
|
|
|
xmlNodePtr *forwardPfNodes = NULL;
|
|
|
|
xmlNodePtr *forwardAddrNodes = NULL;
|
2013-02-19 10:44:14 +00:00
|
|
|
xmlNodePtr *forwardNatNodes = NULL;
|
|
|
|
int nForwardIfs, nForwardAddrs, nForwardPfs, nForwardNats;
|
2012-11-11 22:57:16 +00:00
|
|
|
char *forwardDev = NULL;
|
|
|
|
char *forwardManaged = NULL;
|
2013-04-26 20:23:27 +00:00
|
|
|
char *forwardDriverName = NULL;
|
2012-11-11 22:57:16 +00:00
|
|
|
char *type = NULL;
|
|
|
|
xmlNodePtr save = ctxt->node;
|
|
|
|
|
|
|
|
ctxt->node = node;
|
|
|
|
|
|
|
|
if (!(type = virXPathString("string(./@mode)", ctxt))) {
|
|
|
|
def->type = VIR_NETWORK_FORWARD_NAT;
|
|
|
|
} else {
|
|
|
|
if ((def->type = virNetworkForwardTypeFromString(type)) < 0) {
|
2014-01-10 16:41:33 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2012-11-11 22:57:16 +00:00
|
|
|
_("unknown forwarding type '%s'"), type);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VIR_FREE(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
forwardManaged = virXPathString("string(./@managed)", ctxt);
|
|
|
|
if (forwardManaged != NULL &&
|
|
|
|
STRCASEEQ(forwardManaged, "yes")) {
|
|
|
|
def->managed = true;
|
|
|
|
}
|
|
|
|
|
2013-04-26 20:23:27 +00:00
|
|
|
forwardDriverName = virXPathString("string(./driver/@name)", ctxt);
|
|
|
|
if (forwardDriverName) {
|
|
|
|
int driverName
|
|
|
|
= virNetworkForwardDriverNameTypeFromString(forwardDriverName);
|
|
|
|
|
|
|
|
if (driverName <= 0) {
|
2014-01-10 16:41:33 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2013-04-26 20:23:27 +00:00
|
|
|
_("Unknown forward <driver name='%s'/> "
|
|
|
|
"in network %s"),
|
|
|
|
forwardDriverName, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
def->driverName = driverName;
|
|
|
|
}
|
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
/* bridge and hostdev modes can use a pool of physical interfaces */
|
|
|
|
nForwardIfs = virXPathNodeSet("./interface", ctxt, &forwardIfNodes);
|
|
|
|
if (nForwardIfs < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <interface> element found in <forward> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
nForwardAddrs = virXPathNodeSet("./address", ctxt, &forwardAddrNodes);
|
|
|
|
if (nForwardAddrs < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <address> element found in <forward> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
nForwardPfs = virXPathNodeSet("./pf", ctxt, &forwardPfNodes);
|
|
|
|
if (nForwardPfs < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <pf> element found in <forward> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-19 10:44:14 +00:00
|
|
|
nForwardNats = virXPathNodeSet("./nat", ctxt, &forwardNatNodes);
|
|
|
|
if (nForwardNats < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("invalid <nat> element found in <forward> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
} else if (nForwardNats > 1) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Only one <nat> element is allowed in <forward> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
} else if (nForwardNats == 1) {
|
|
|
|
if (virNetworkForwardNatDefParseXML(networkName,
|
|
|
|
*forwardNatNodes,
|
|
|
|
ctxt, def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
forwardDev = virXPathString("string(./@dev)", ctxt);
|
|
|
|
if (forwardDev && (nForwardAddrs > 0 || nForwardPfs > 0)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
|
_("the <forward> 'dev' attribute cannot be used when "
|
|
|
|
"<address> or <pf> sub-elements are present "
|
|
|
|
"in network %s"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nForwardIfs > 0 || forwardDev) {
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC_N(def->ifs, MAX(nForwardIfs, 1)) < 0)
|
2012-11-11 22:57:16 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (forwardDev) {
|
|
|
|
def->ifs[0].device.dev = forwardDev;
|
|
|
|
def->ifs[0].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
|
|
|
|
forwardDev = NULL;
|
|
|
|
def->nifs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* parse each <interface> */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < nForwardIfs; i++) {
|
|
|
|
forwardDev = virXMLPropString(forwardIfNodes[i], "dev");
|
2012-11-11 22:57:16 +00:00
|
|
|
if (!forwardDev) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing required dev attribute in "
|
|
|
|
"<forward> <interface> element of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if ((i == 0) && (def->nifs == 1)) {
|
2012-11-11 22:57:16 +00:00
|
|
|
/* both <forward dev='x'> and <interface dev='x'/> are
|
|
|
|
* present. If they don't match, it's an error.
|
|
|
|
*/
|
|
|
|
if (STRNEQ(forwardDev, def->ifs[0].device.dev)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("<forward dev='%s'> must match first "
|
|
|
|
"<interface dev='%s'/> in network %s"),
|
|
|
|
def->ifs[0].device.dev,
|
|
|
|
forwardDev, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VIR_FREE(forwardDev);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-04-18 19:07:26 +00:00
|
|
|
for (j = 0; j < i; j++) {
|
|
|
|
if (STREQ_NULLABLE(def->ifs[j].device.dev, forwardDev)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("interface '%s' can only be "
|
|
|
|
"listed once in network %s"),
|
|
|
|
forwardDev, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
def->ifs[i].device.dev = forwardDev;
|
2012-11-11 22:57:16 +00:00
|
|
|
forwardDev = NULL;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
def->ifs[i].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
|
2012-11-11 22:57:16 +00:00
|
|
|
def->nifs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (nForwardAddrs > 0) {
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC_N(def->ifs, nForwardAddrs) < 0)
|
2012-11-11 22:57:16 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < nForwardAddrs; i++) {
|
|
|
|
if (!(type = virXMLPropString(forwardAddrNodes[i], "type"))) {
|
2012-11-11 22:57:16 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("missing address type in network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if ((def->ifs[i].type = virNetworkForwardHostdevDeviceTypeFromString(type)) < 0) {
|
2014-01-10 16:41:33 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2012-11-11 22:57:16 +00:00
|
|
|
_("unknown address type '%s' in network %s"),
|
|
|
|
type, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
switch (def->ifs[i].type) {
|
2012-11-11 22:57:16 +00:00
|
|
|
case VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI:
|
2016-04-18 19:07:26 +00:00
|
|
|
{
|
2016-04-03 18:16:51 +00:00
|
|
|
virPCIDeviceAddressPtr addr = &def->ifs[i].device.pci;
|
2016-04-18 19:07:26 +00:00
|
|
|
|
2016-04-03 18:16:51 +00:00
|
|
|
if (virPCIDeviceAddressParseXML(forwardAddrNodes[i], addr) < 0)
|
2012-11-11 22:57:16 +00:00
|
|
|
goto cleanup;
|
2016-04-18 19:07:26 +00:00
|
|
|
|
|
|
|
for (j = 0; j < i; j++) {
|
2016-04-03 18:16:51 +00:00
|
|
|
if (virPCIDeviceAddressEqual(addr, &def->ifs[j].device.pci)) {
|
2016-04-18 19:07:26 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("PCI device '%04x:%02x:%02x.%x' can "
|
|
|
|
"only be listed once in network %s"),
|
|
|
|
addr->domain, addr->bus,
|
|
|
|
addr->slot, addr->function,
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-11-11 22:57:16 +00:00
|
|
|
}
|
|
|
|
break;
|
2016-04-18 19:07:26 +00:00
|
|
|
}
|
2012-11-11 22:57:16 +00:00
|
|
|
/* Add USB case here if we ever find a reason to support it */
|
|
|
|
|
|
|
|
default:
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("unsupported address type '%s' in network %s"),
|
|
|
|
type, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VIR_FREE(type);
|
|
|
|
def->nifs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (nForwardPfs > 1) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Only one <pf> element is allowed in <forward> of network %s"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
} else if (nForwardPfs == 1) {
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC_N(def->pfs, nForwardPfs) < 0)
|
2012-11-11 22:57:16 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
forwardDev = virXMLPropString(*forwardPfNodes, "dev");
|
|
|
|
if (!forwardDev) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing required dev attribute "
|
|
|
|
"in <pf> element of network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->pfs->dev = forwardDev;
|
|
|
|
forwardDev = NULL;
|
|
|
|
def->npfs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2012-11-11 22:57:16 +00:00
|
|
|
VIR_FREE(type);
|
|
|
|
VIR_FREE(forwardDev);
|
|
|
|
VIR_FREE(forwardManaged);
|
2013-04-26 20:23:27 +00:00
|
|
|
VIR_FREE(forwardDriverName);
|
2012-11-11 22:57:16 +00:00
|
|
|
VIR_FREE(forwardPfNodes);
|
|
|
|
VIR_FREE(forwardIfNodes);
|
|
|
|
VIR_FREE(forwardAddrNodes);
|
2013-02-19 10:44:14 +00:00
|
|
|
VIR_FREE(forwardNatNodes);
|
2012-11-11 22:57:16 +00:00
|
|
|
ctxt->node = save;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2017-03-08 15:25:24 +00:00
|
|
|
virNetworkDefPtr
|
2019-07-14 16:15:12 +00:00
|
|
|
virNetworkDefParseXML(xmlXPathContextPtr ctxt,
|
|
|
|
virNetworkXMLOptionPtr xmlopt ATTRIBUTE_UNUSED)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
|
|
|
virNetworkDefPtr def;
|
2014-09-15 08:42:15 +00:00
|
|
|
char *tmp = NULL;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
char *stp = NULL;
|
2010-11-17 18:36:19 +00:00
|
|
|
xmlNodePtr *ipNodes = NULL;
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
xmlNodePtr *routeNodes = NULL;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
xmlNodePtr *portGroupNodes = NULL;
|
2016-06-08 16:48:50 +00:00
|
|
|
int nips, nPortGroups, nRoutes;
|
2011-06-24 10:04:36 +00:00
|
|
|
xmlNodePtr dnsNode = NULL;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
xmlNodePtr virtPortNode = NULL;
|
|
|
|
xmlNodePtr forwardNode = NULL;
|
2012-12-03 16:13:36 +00:00
|
|
|
char *ipv6nogwStr = NULL;
|
2014-09-23 18:19:08 +00:00
|
|
|
char *trustGuestRxFilters = NULL;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
xmlNodePtr save = ctxt->node;
|
2011-07-22 14:07:25 +00:00
|
|
|
xmlNodePtr bandwidthNode = NULL;
|
2012-08-12 07:51:30 +00:00
|
|
|
xmlNodePtr vlanNode;
|
2016-06-22 22:05:50 +00:00
|
|
|
xmlNodePtr metadataNode = NULL;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC(def) < 0)
|
2008-07-11 10:48:34 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Extract network name */
|
2010-02-04 21:52:34 +00:00
|
|
|
def->name = virXPathString("string(./name[1])", ctxt);
|
2008-07-11 10:48:34 +00:00
|
|
|
if (!def->name) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_NO_NAME, NULL);
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2016-10-19 20:57:47 +00:00
|
|
|
if (virXMLCheckIllegalChars("name", def->name, "/") < 0)
|
2016-04-26 16:47:42 +00:00
|
|
|
goto error;
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
/* Extract network uuid */
|
2010-02-04 21:52:34 +00:00
|
|
|
tmp = virXPathString("string(./uuid[1])", ctxt);
|
2008-07-11 10:48:34 +00:00
|
|
|
if (!tmp) {
|
2018-04-09 20:30:10 +00:00
|
|
|
if (virUUIDGenerate(def->uuid) < 0) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Failed to generate UUID"));
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (virUUIDParse(tmp, def->uuid) < 0) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("malformed uuid element"));
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
2012-08-05 20:11:50 +00:00
|
|
|
def->uuid_specified = true;
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
2012-12-03 16:13:36 +00:00
|
|
|
/* check if definitions with no IPv6 gateway addresses is to
|
|
|
|
* allow guest-to-guest communications.
|
|
|
|
*/
|
|
|
|
ipv6nogwStr = virXPathString("string(./@ipv6)", ctxt);
|
|
|
|
if (ipv6nogwStr) {
|
|
|
|
if (STREQ(ipv6nogwStr, "yes")) {
|
|
|
|
def->ipv6nogw = true;
|
|
|
|
} else if (STRNEQ(ipv6nogwStr, "no")) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid ipv6 setting '%s' in network '%s'"),
|
|
|
|
ipv6nogwStr, def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(ipv6nogwStr);
|
|
|
|
}
|
|
|
|
|
2014-09-23 18:19:08 +00:00
|
|
|
trustGuestRxFilters
|
|
|
|
= virXPathString("string(./@trustGuestRxFilters)", ctxt);
|
|
|
|
if (trustGuestRxFilters) {
|
|
|
|
if ((def->trustGuestRxFilters
|
|
|
|
= virTristateBoolTypeFromString(trustGuestRxFilters)) <= 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid trustGuestRxFilters setting '%s' "
|
|
|
|
"in network '%s'"),
|
|
|
|
trustGuestRxFilters, def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(trustGuestRxFilters);
|
|
|
|
}
|
|
|
|
|
2008-09-08 12:45:29 +00:00
|
|
|
/* Parse network domain information */
|
2010-02-04 21:52:34 +00:00
|
|
|
def->domain = virXPathString("string(./domain[1]/@name)", ctxt);
|
2014-12-04 00:01:33 +00:00
|
|
|
tmp = virXPathString("string(./domain[1]/@localOnly)", ctxt);
|
|
|
|
if (tmp) {
|
|
|
|
def->domainLocalOnly = virTristateBoolTypeFromString(tmp);
|
|
|
|
if (def->domainLocalOnly <= 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid domain localOnly setting '%s' "
|
|
|
|
"in network '%s'"),
|
|
|
|
tmp, def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
}
|
2008-09-08 12:45:29 +00:00
|
|
|
|
2015-01-07 16:53:04 +00:00
|
|
|
if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) &&
|
2019-05-14 14:44:55 +00:00
|
|
|
virNetDevBandwidthParse(&def->bandwidth, NULL, bandwidthNode, false) < 0)
|
2011-07-22 14:07:25 +00:00
|
|
|
goto error;
|
|
|
|
|
2012-08-12 07:51:30 +00:00
|
|
|
vlanNode = virXPathNode("./vlan", ctxt);
|
|
|
|
if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
/* Parse bridge information */
|
2010-02-04 21:52:34 +00:00
|
|
|
def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
|
2019-01-09 21:51:31 +00:00
|
|
|
def->bridgeZone = virXPathString("string(./bridge[1]/@zone)", ctxt);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
stp = virXPathString("string(./bridge[1]/@stp)", ctxt);
|
2013-04-12 09:08:59 +00:00
|
|
|
def->stp = (stp && STREQ(stp, "off")) ? false : true;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2014-09-15 08:42:15 +00:00
|
|
|
tmp = virXPathString("string(./bridge[1]/@delay)", ctxt);
|
|
|
|
if (tmp) {
|
|
|
|
if (virStrToLong_ulp(tmp, NULL, 10, &def->delay) < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid delay value in network '%s'"),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
conf: new network bridge device attribute macTableManager
The macTableManager attribute of a network's bridge subelement tells
libvirt how the bridge's MAC address table (used to determine the
egress port for packets) is managed. In the default mode, "kernel",
management is left to the kernel, which usually determines entries in
part by turning on promiscuous mode on all ports of the bridge,
flooding packets to all ports when the correct destination is unknown,
and adding/removing entries to the fdb as it sees incoming traffic
from particular MAC addresses. In "libvirt" mode, libvirt turns off
learning and flooding on all the bridge ports connected to guest
domain interfaces, and adds/removes entries according to the MAC
addresses in the domain interface configurations. A side effect of
turning off learning and unicast_flood on the ports of a bridge is
that (with Linux kernel 3.17 and newer), the kernel can automatically
turn off promiscuous mode on one or more of the bridge's ports
(usually only the one interface that is used to connect the bridge to
the physical network). The result is better performance (because
packets aren't being flooded to all ports, and can be dropped earlier
when they are of no interest) and slightly better security (a guest
can still send out packets with a spoofed source MAC address, but will
only receive traffic intended for the guest interface's configured MAC
address).
The attribute looks like this in the configuration:
<network>
<name>test</name>
<bridge name='br0' macTableManager='libvirt'/>
...
This patch only adds the config knob, documentation, and test
cases. The functionality behind this knob is added in later patches.
2014-11-20 17:40:33 +00:00
|
|
|
tmp = virXPathString("string(./bridge[1]/@macTableManager)", ctxt);
|
|
|
|
if (tmp) {
|
|
|
|
if ((def->macTableManager
|
|
|
|
= virNetworkBridgeMACTableManagerTypeFromString(tmp)) <= 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid macTableManager setting '%s' "
|
|
|
|
"in network '%s'"), tmp, def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
}
|
|
|
|
|
Give each virtual network bridge its own fixed MAC address
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=609463
The problem was that, since a bridge always acquires the MAC address
of the connected interface with the numerically lowest MAC, as guests
are started and stopped, it was possible for the MAC address to change
over time, and this change in the network was being detected by
Windows 7 (it sees the MAC of the default route change), so on each
reboot it would bring up a dialog box asking about this "new network".
The solution is to create a dummy tap interface with a MAC guaranteed
to be lower than any guest interface's MAC, and attach that tap to the
bridge as soon as it's created. Since all guest MAC addresses start
with 0xFE, we can just generate a MAC with the standard "0x52, 0x54,
0" prefix, and it's guaranteed to always win (physical interfaces are
never connected to these bridges, so we don't need to worry about
competing numerically with them).
Note that the dummy tap is never set to IFF_UP state - that's not
necessary in order for the bridge to take its MAC, and not setting it
to UP eliminates the clutter of having an (eg) "virbr0-nic" displayed
in the output of the ifconfig command.
I chose to not auto-generate the MAC address in the network XML
parser, as there are likely to be consumers of that API that don't
need or want to have a MAC address associated with the
bridge.
Instead, in bridge_driver.c when the network is being defined, if
there is no MAC, one is generated. To account for virtual network
configs that already exist when upgrading from an older version of
libvirt, I've added a %post script to the specfile that searches for
all network definitions in both the config directory
(/etc/libvirt/qemu/networks) and the state directory
(/var/lib/libvirt/network) that are missing a mac address, generates a
random address, and adds it to the config (and a matching address to
the state file, if there is one).
docs/formatnetwork.html.in: document <mac address.../>
docs/schemas/network.rng: add nac address to schema
libvirt.spec.in: %post script to update existing networks
src/conf/network_conf.[ch]: parse and format <mac address.../>
src/libvirt_private.syms: export a couple private symbols we need
src/network/bridge_driver.c:
auto-generate mac address when needed,
create dummy interface if mac address is present.
tests/networkxml2xmlin/isolated-network.xml
tests/networkxml2xmlin/routed-network.xml
tests/networkxml2xmlout/isolated-network.xml
tests/networkxml2xmlout/routed-network.xml: add mac address to some tests
2011-02-09 08:28:12 +00:00
|
|
|
tmp = virXPathString("string(./mac[1]/@address)", ctxt);
|
|
|
|
if (tmp) {
|
2012-07-17 12:07:59 +00:00
|
|
|
if (virMacAddrParse(tmp, &def->mac) < 0) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid bridge mac address '%s' in network '%s'"),
|
|
|
|
tmp, def->name);
|
Give each virtual network bridge its own fixed MAC address
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=609463
The problem was that, since a bridge always acquires the MAC address
of the connected interface with the numerically lowest MAC, as guests
are started and stopped, it was possible for the MAC address to change
over time, and this change in the network was being detected by
Windows 7 (it sees the MAC of the default route change), so on each
reboot it would bring up a dialog box asking about this "new network".
The solution is to create a dummy tap interface with a MAC guaranteed
to be lower than any guest interface's MAC, and attach that tap to the
bridge as soon as it's created. Since all guest MAC addresses start
with 0xFE, we can just generate a MAC with the standard "0x52, 0x54,
0" prefix, and it's guaranteed to always win (physical interfaces are
never connected to these bridges, so we don't need to worry about
competing numerically with them).
Note that the dummy tap is never set to IFF_UP state - that's not
necessary in order for the bridge to take its MAC, and not setting it
to UP eliminates the clutter of having an (eg) "virbr0-nic" displayed
in the output of the ifconfig command.
I chose to not auto-generate the MAC address in the network XML
parser, as there are likely to be consumers of that API that don't
need or want to have a MAC address associated with the
bridge.
Instead, in bridge_driver.c when the network is being defined, if
there is no MAC, one is generated. To account for virtual network
configs that already exist when upgrading from an older version of
libvirt, I've added a %post script to the specfile that searches for
all network definitions in both the config directory
(/etc/libvirt/qemu/networks) and the state directory
(/var/lib/libvirt/network) that are missing a mac address, generates a
random address, and adds it to the config (and a matching address to
the state file, if there is one).
docs/formatnetwork.html.in: document <mac address.../>
docs/schemas/network.rng: add nac address to schema
libvirt.spec.in: %post script to update existing networks
src/conf/network_conf.[ch]: parse and format <mac address.../>
src/libvirt_private.syms: export a couple private symbols we need
src/network/bridge_driver.c:
auto-generate mac address when needed,
create dummy interface if mac address is present.
tests/networkxml2xmlin/isolated-network.xml
tests/networkxml2xmlin/routed-network.xml
tests/networkxml2xmlout/isolated-network.xml
tests/networkxml2xmlout/routed-network.xml: add mac address to some tests
2011-02-09 08:28:12 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2012-07-17 12:07:59 +00:00
|
|
|
if (virMacAddrIsMulticast(&def->mac)) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid multicast bridge mac address '%s' in network '%s'"),
|
|
|
|
tmp, def->name);
|
2012-03-19 16:49:17 +00:00
|
|
|
goto error;
|
|
|
|
}
|
Give each virtual network bridge its own fixed MAC address
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=609463
The problem was that, since a bridge always acquires the MAC address
of the connected interface with the numerically lowest MAC, as guests
are started and stopped, it was possible for the MAC address to change
over time, and this change in the network was being detected by
Windows 7 (it sees the MAC of the default route change), so on each
reboot it would bring up a dialog box asking about this "new network".
The solution is to create a dummy tap interface with a MAC guaranteed
to be lower than any guest interface's MAC, and attach that tap to the
bridge as soon as it's created. Since all guest MAC addresses start
with 0xFE, we can just generate a MAC with the standard "0x52, 0x54,
0" prefix, and it's guaranteed to always win (physical interfaces are
never connected to these bridges, so we don't need to worry about
competing numerically with them).
Note that the dummy tap is never set to IFF_UP state - that's not
necessary in order for the bridge to take its MAC, and not setting it
to UP eliminates the clutter of having an (eg) "virbr0-nic" displayed
in the output of the ifconfig command.
I chose to not auto-generate the MAC address in the network XML
parser, as there are likely to be consumers of that API that don't
need or want to have a MAC address associated with the
bridge.
Instead, in bridge_driver.c when the network is being defined, if
there is no MAC, one is generated. To account for virtual network
configs that already exist when upgrading from an older version of
libvirt, I've added a %post script to the specfile that searches for
all network definitions in both the config directory
(/etc/libvirt/qemu/networks) and the state directory
(/var/lib/libvirt/network) that are missing a mac address, generates a
random address, and adds it to the config (and a matching address to
the state file, if there is one).
docs/formatnetwork.html.in: document <mac address.../>
docs/schemas/network.rng: add nac address to schema
libvirt.spec.in: %post script to update existing networks
src/conf/network_conf.[ch]: parse and format <mac address.../>
src/libvirt_private.syms: export a couple private symbols we need
src/network/bridge_driver.c:
auto-generate mac address when needed,
create dummy interface if mac address is present.
tests/networkxml2xmlin/isolated-network.xml
tests/networkxml2xmlin/routed-network.xml
tests/networkxml2xmlout/isolated-network.xml
tests/networkxml2xmlout/routed-network.xml: add mac address to some tests
2011-02-09 08:28:12 +00:00
|
|
|
VIR_FREE(tmp);
|
|
|
|
def->mac_specified = true;
|
|
|
|
}
|
|
|
|
|
2017-01-23 02:23:48 +00:00
|
|
|
tmp = virXPathString("string(./mtu/@size)", ctxt);
|
|
|
|
if (tmp) {
|
|
|
|
if (virStrToLong_ui(tmp, NULL, 10, &def->mtu) < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid mtu size '%s' in network '%s'"),
|
|
|
|
tmp, def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
dnsNode = virXPathNode("./dns", ctxt);
|
conf: clear and parse functions for dns host/srv/txt records
Since there is only a single virNetworkDNSDef for any virNetworkDef,
and it's trivial to determine whether or not it contains any real
data, it's much simpler (and fits more uniformly with the parse
function calling sequence of the parsers for many other objects that
are subordinates of virNetworkDef) if virNetworkDef *contains* an
virNetworkDNSDef rather than pointing to one.
Since it is now just a part of another object rather than its own
object, it no longer makes sense to have a *Free() function, so that
is changed to a *Clear() function.
More importantly though, ParseXML and Clear functions are needed for
the individual items contained in a virNetworkDNSDef (srv, txt, and
host records), but none of them have a *Clear(), and only two of the
three had *ParseXML() functions (both of which used a non-uniform
arglist). Those problems are cleared up by this patch - it splits the
higher-level Clear function into separate functions for each of the
three, creates a parse for txt records, and cleans up the srv and host
parsers, so we now have all the utility functions necessary to
implement virNetworkDefUpdateDNS(Host|Srv|Txt).
2012-11-12 00:00:22 +00:00
|
|
|
if (dnsNode != NULL &&
|
|
|
|
virNetworkDNSDefParseXML(def->name, dnsNode, ctxt, &def->dns) < 0) {
|
|
|
|
goto error;
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
virtPortNode = virXPathNode("./virtualport", ctxt);
|
|
|
|
if (virtPortNode &&
|
conf: support partially-specified <virtualport> in parser and formatter
Until now, all attributes in a <virtualport> parameter list that were
acceptable for a particular type, were also required. There were no
optional attributes.
One of the aims of supporting <virtualport> in libvirt's virtual
networks and portgroups is to allow specifying the group-wide
parameters in the network's virtualport, and merge that with the
interface's virtualport, which will have the instance-specific info
(i.e. the interfaceid or instanceid).
Additionally, the guest's interface XML shouldn't need to know what
type of network connection will be used prior to runtime - it could be
openvswitch, 802.1Qbh, 802.1Qbg, or none of the above - but should
still be able to specify instance-specific info just in case it turns
out to be applicable.
Finally, up to now, the parser for virtualport has always generated a
random instanceid/interfaceid when appropriate, making it impossible
to leave it blank (which is what's required for virtualports within a
network/portprofile definition).
This patch modifies the parser and formatter of the <virtualport>
element in the following ways:
* because most of the attributes in a virNetDevVPortProfile are fixed
size binary data with no reserved values, there is no way to embed a
"this value wasn't specified" sentinel into the existing data. To
solve this problem, the new *_specified fields in the
virNetDevVPortProfile object that were added in a previous patch of
this series are now set when the corresponding attribute is present
during the parse.
* allow parsing/formatting a <virtualport> that has no type set. In
this case, all fields are settable, but all are also optional.
* add a GENERATE_MISSING_DEFAULTS flag to the parser - if this flag is
set and an instanceid/interfaceid is expected but not provided, a
random one will be generated. This was previously the default
behavior, but is now done only for virtualports inside an
<interface> definition, not for those in <network> or <portgroup>.
* add a REQUIRE_ALL_ATTRIBUTES flag to the parser - if this flag is
set the parser will call the new
virNetDevVPortProfileCheckComplete() functions at the end of the
parser to check for any missing attributes (based on type), and
return failure if anything is missing. This used to be default
behavior. Now it is only used for the virtualport defined inside an
interface's <actual> element (by the time you've figured out the
contents of <actual>, you should have all the necessary data to fill
in the entire virtualport)
* add a REQUIRE_TYPE flag to the parser - if this flag is set, the
parser will return an error if the virtualport has no type
attribute. This also was previously the default behavior, but isn't
needed in the case of the virtualport for a type='network' interface
(i.e. the exact type isn't yet known), or the virtualport of a
portgroup (i.e. the portgroup just has modifiers for the network's
virtualport, which *does* require a type) - in those cases, the
check will be done at domain startup, once the final virtualport is
assembled (this is handled in the next patch).
2012-07-31 18:36:51 +00:00
|
|
|
(!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode,
|
|
|
|
VIR_VPORT_XML_REQUIRE_TYPE)))) {
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
goto error;
|
conf: support partially-specified <virtualport> in parser and formatter
Until now, all attributes in a <virtualport> parameter list that were
acceptable for a particular type, were also required. There were no
optional attributes.
One of the aims of supporting <virtualport> in libvirt's virtual
networks and portgroups is to allow specifying the group-wide
parameters in the network's virtualport, and merge that with the
interface's virtualport, which will have the instance-specific info
(i.e. the interfaceid or instanceid).
Additionally, the guest's interface XML shouldn't need to know what
type of network connection will be used prior to runtime - it could be
openvswitch, 802.1Qbh, 802.1Qbg, or none of the above - but should
still be able to specify instance-specific info just in case it turns
out to be applicable.
Finally, up to now, the parser for virtualport has always generated a
random instanceid/interfaceid when appropriate, making it impossible
to leave it blank (which is what's required for virtualports within a
network/portprofile definition).
This patch modifies the parser and formatter of the <virtualport>
element in the following ways:
* because most of the attributes in a virNetDevVPortProfile are fixed
size binary data with no reserved values, there is no way to embed a
"this value wasn't specified" sentinel into the existing data. To
solve this problem, the new *_specified fields in the
virNetDevVPortProfile object that were added in a previous patch of
this series are now set when the corresponding attribute is present
during the parse.
* allow parsing/formatting a <virtualport> that has no type set. In
this case, all fields are settable, but all are also optional.
* add a GENERATE_MISSING_DEFAULTS flag to the parser - if this flag is
set and an instanceid/interfaceid is expected but not provided, a
random one will be generated. This was previously the default
behavior, but is now done only for virtualports inside an
<interface> definition, not for those in <network> or <portgroup>.
* add a REQUIRE_ALL_ATTRIBUTES flag to the parser - if this flag is
set the parser will call the new
virNetDevVPortProfileCheckComplete() functions at the end of the
parser to check for any missing attributes (based on type), and
return failure if anything is missing. This used to be default
behavior. Now it is only used for the virtualport defined inside an
interface's <actual> element (by the time you've figured out the
contents of <actual>, you should have all the necessary data to fill
in the entire virtualport)
* add a REQUIRE_TYPE flag to the parser - if this flag is set, the
parser will return an error if the virtualport has no type
attribute. This also was previously the default behavior, but isn't
needed in the case of the virtualport for a type='network' interface
(i.e. the exact type isn't yet known), or the virtualport of a
portgroup (i.e. the portgroup just has modifiers for the network's
virtualport, which *does* require a type) - in those cases, the
check will be done at domain startup, once the final virtualport is
assembled (this is handled in the next patch).
2012-07-31 18:36:51 +00:00
|
|
|
}
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
|
|
|
nPortGroups = virXPathNodeSet("./portgroup", ctxt, &portGroupNodes);
|
|
|
|
if (nPortGroups < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (nPortGroups > 0) {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
|
|
|
/* allocate array to hold all the portgroups */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC_N(def->portGroups, nPortGroups) < 0)
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
goto error;
|
|
|
|
/* parse each portgroup */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < nPortGroups; i++) {
|
2014-09-15 08:42:15 +00:00
|
|
|
if (virNetworkPortGroupParseXML(&def->portGroups[i],
|
|
|
|
portGroupNodes[i],
|
|
|
|
ctxt) < 0)
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
goto error;
|
|
|
|
def->nPortGroups++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(portGroupNodes);
|
|
|
|
|
2016-06-08 16:48:50 +00:00
|
|
|
nips = virXPathNodeSet("./ip", ctxt, &ipNodes);
|
|
|
|
if (nips < 0)
|
2011-05-12 19:45:22 +00:00
|
|
|
goto error;
|
|
|
|
|
2016-06-08 16:48:50 +00:00
|
|
|
if (nips > 0) {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
/* allocate array to hold all the addrs */
|
2016-06-08 16:48:50 +00:00
|
|
|
if (VIR_ALLOC_N(def->ips, nips) < 0)
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
2010-11-17 18:36:19 +00:00
|
|
|
/* parse each addr */
|
2016-06-08 16:48:50 +00:00
|
|
|
for (i = 0; i < nips; i++) {
|
2014-09-15 08:42:15 +00:00
|
|
|
if (virNetworkIPDefParseXML(def->name,
|
|
|
|
ipNodes[i],
|
|
|
|
ctxt,
|
|
|
|
&def->ips[i]) < 0)
|
2010-11-17 18:36:19 +00:00
|
|
|
goto error;
|
|
|
|
def->nips++;
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
2010-11-30 20:53:17 +00:00
|
|
|
}
|
2011-01-10 22:35:37 +00:00
|
|
|
VIR_FREE(ipNodes);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
nRoutes = virXPathNodeSet("./route", ctxt, &routeNodes);
|
|
|
|
if (nRoutes < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (nRoutes > 0) {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
|
|
|
|
/* allocate array to hold all the route definitions */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC_N(def->routes, nRoutes) < 0)
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
goto error;
|
|
|
|
/* parse each definition */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < nRoutes; i++) {
|
2016-06-14 17:40:04 +00:00
|
|
|
virNetDevIPRoutePtr route = NULL;
|
2015-01-14 13:21:10 +00:00
|
|
|
|
2016-06-14 17:40:04 +00:00
|
|
|
if (!(route = virNetDevIPRouteParseXML(def->name,
|
|
|
|
routeNodes[i],
|
|
|
|
ctxt)))
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
goto error;
|
2015-01-14 13:21:10 +00:00
|
|
|
def->routes[i] = route;
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
def->nroutes++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now validate the correctness of any static route gateways specified
|
|
|
|
*
|
|
|
|
* note: the parameters within each definition are verified/assumed valid;
|
|
|
|
* the question being asked and answered here is if the specified gateway
|
|
|
|
* is directly reachable from this bridge.
|
|
|
|
*/
|
|
|
|
nRoutes = def->nroutes;
|
2016-06-08 16:48:50 +00:00
|
|
|
nips = def->nips;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < nRoutes; i++) {
|
|
|
|
size_t j;
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
virSocketAddr testAddr, testGw;
|
|
|
|
bool addrMatch;
|
2016-06-14 17:40:04 +00:00
|
|
|
virNetDevIPRoutePtr gwdef = def->routes[i];
|
|
|
|
virSocketAddrPtr gateway = virNetDevIPRouteGetGateway(gwdef);
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
addrMatch = false;
|
2016-06-08 16:48:50 +00:00
|
|
|
for (j = 0; j < nips; j++) {
|
|
|
|
virNetworkIPDefPtr def2 = &def->ips[j];
|
2015-01-14 13:21:10 +00:00
|
|
|
if (VIR_SOCKET_ADDR_FAMILY(gateway)
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
!= VIR_SOCKET_ADDR_FAMILY(&def2->address)) {
|
|
|
|
continue;
|
|
|
|
}
|
2016-06-08 16:48:50 +00:00
|
|
|
int prefix = virNetworkIPDefPrefix(def2);
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
virSocketAddrMaskByPrefix(&def2->address, prefix, &testAddr);
|
2015-01-14 13:21:10 +00:00
|
|
|
virSocketAddrMaskByPrefix(gateway, prefix, &testGw);
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
if (VIR_SOCKET_ADDR_VALID(&testAddr) &&
|
|
|
|
VIR_SOCKET_ADDR_VALID(&testGw) &&
|
|
|
|
virSocketAddrEqual(&testAddr, &testGw)) {
|
|
|
|
addrMatch = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!addrMatch) {
|
2015-01-14 13:21:10 +00:00
|
|
|
char *gw = virSocketAddrFormat(gateway);
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("unreachable static route gateway '%s' specified for network '%s'"),
|
|
|
|
gw, def->name);
|
|
|
|
VIR_FREE(gw);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(routeNodes);
|
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
forwardNode = virXPathNode("./forward", ctxt);
|
2012-11-11 22:57:16 +00:00
|
|
|
if (forwardNode &&
|
|
|
|
virNetworkForwardDefParseXML(def->name, forwardNode, ctxt, &def->forward) < 0) {
|
|
|
|
goto error;
|
|
|
|
}
|
2011-12-14 10:50:23 +00:00
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
/* Validate some items in the main NetworkDef that need to align
|
|
|
|
* with the chosen forward mode.
|
|
|
|
*/
|
2018-07-24 03:49:48 +00:00
|
|
|
switch ((virNetworkForwardType) def->forward.type) {
|
2012-11-11 22:57:16 +00:00
|
|
|
case VIR_NETWORK_FORWARD_NONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_NETWORK_FORWARD_ROUTE:
|
|
|
|
case VIR_NETWORK_FORWARD_NAT:
|
2016-08-10 23:09:55 +00:00
|
|
|
case VIR_NETWORK_FORWARD_OPEN:
|
2012-11-11 22:57:16 +00:00
|
|
|
/* It's pointless to specify L3 forwarding without specifying
|
|
|
|
* the network we're on.
|
|
|
|
*/
|
|
|
|
if (def->nips == 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("%s forwarding requested, "
|
|
|
|
"but no IP address provided for network '%s'"),
|
|
|
|
virNetworkForwardTypeToString(def->forward.type),
|
|
|
|
def->name);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
goto error;
|
2011-12-14 10:50:23 +00:00
|
|
|
}
|
2012-11-11 22:57:16 +00:00
|
|
|
if (def->forward.nifs > 1) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("multiple forwarding interfaces specified "
|
|
|
|
"for network '%s', only one is supported"),
|
|
|
|
def->name);
|
2012-08-16 15:41:41 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2016-08-10 23:09:55 +00:00
|
|
|
|
|
|
|
if (def->forward.type == VIR_NETWORK_FORWARD_OPEN && def->forward.nifs) {
|
|
|
|
/* an open network by definition can't place any restrictions
|
|
|
|
* on what traffic is allowed or where it goes, so specifying
|
|
|
|
* a forwarding device is nonsensical.
|
|
|
|
*/
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("forward dev not allowed for "
|
|
|
|
"network '%s' with forward mode='%s'"),
|
|
|
|
def->name,
|
|
|
|
virNetworkForwardTypeToString(def->forward.type));
|
|
|
|
goto error;
|
|
|
|
}
|
2012-11-11 22:57:16 +00:00
|
|
|
break;
|
2012-08-16 15:41:41 +00:00
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
case VIR_NETWORK_FORWARD_PRIVATE:
|
|
|
|
case VIR_NETWORK_FORWARD_VEPA:
|
|
|
|
case VIR_NETWORK_FORWARD_PASSTHROUGH:
|
|
|
|
case VIR_NETWORK_FORWARD_HOSTDEV:
|
|
|
|
if (def->bridge) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("bridge name not allowed in %s mode (network '%s')"),
|
|
|
|
virNetworkForwardTypeToString(def->forward.type),
|
|
|
|
def->name);
|
2012-08-16 15:41:41 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2019-01-09 21:51:31 +00:00
|
|
|
if (def->bridgeZone) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("bridge zone not allowed in %s mode (network '%s')"),
|
|
|
|
virNetworkForwardTypeToString(def->forward.type),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
conf: new network bridge device attribute macTableManager
The macTableManager attribute of a network's bridge subelement tells
libvirt how the bridge's MAC address table (used to determine the
egress port for packets) is managed. In the default mode, "kernel",
management is left to the kernel, which usually determines entries in
part by turning on promiscuous mode on all ports of the bridge,
flooding packets to all ports when the correct destination is unknown,
and adding/removing entries to the fdb as it sees incoming traffic
from particular MAC addresses. In "libvirt" mode, libvirt turns off
learning and flooding on all the bridge ports connected to guest
domain interfaces, and adds/removes entries according to the MAC
addresses in the domain interface configurations. A side effect of
turning off learning and unicast_flood on the ports of a bridge is
that (with Linux kernel 3.17 and newer), the kernel can automatically
turn off promiscuous mode on one or more of the bridge's ports
(usually only the one interface that is used to connect the bridge to
the physical network). The result is better performance (because
packets aren't being flooded to all ports, and can be dropped earlier
when they are of no interest) and slightly better security (a guest
can still send out packets with a spoofed source MAC address, but will
only receive traffic intended for the guest interface's configured MAC
address).
The attribute looks like this in the configuration:
<network>
<name>test</name>
<bridge name='br0' macTableManager='libvirt'/>
...
This patch only adds the config knob, documentation, and test
cases. The functionality behind this knob is added in later patches.
2014-11-20 17:40:33 +00:00
|
|
|
if (def->macTableManager) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("bridge macTableManager setting not allowed "
|
|
|
|
"in %s mode (network '%s')"),
|
|
|
|
virNetworkForwardTypeToString(def->forward.type),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
2017-02-22 17:37:09 +00:00
|
|
|
ATTRIBUTE_FALLTHROUGH;
|
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
case VIR_NETWORK_FORWARD_BRIDGE:
|
2019-01-09 21:51:31 +00:00
|
|
|
if (def->delay || stp || def->bridgeZone) {
|
2012-11-11 22:57:16 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
2019-01-09 21:51:31 +00:00
|
|
|
_("bridge delay/stp/zone options only allowed in "
|
2017-01-23 02:23:48 +00:00
|
|
|
"route, nat, and isolated mode, not in %s "
|
|
|
|
"(network '%s')"),
|
2012-11-11 22:57:16 +00:00
|
|
|
virNetworkForwardTypeToString(def->forward.type),
|
|
|
|
def->name);
|
2011-12-14 10:50:23 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2012-11-11 22:57:16 +00:00
|
|
|
if (def->bridge && (def->forward.nifs || def->forward.npfs)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("A network with forward mode='%s' can specify "
|
|
|
|
"a bridge name or a forward dev, but not "
|
|
|
|
"both (network '%s')"),
|
|
|
|
virNetworkForwardTypeToString(def->forward.type),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
}
|
2012-11-11 22:57:16 +00:00
|
|
|
break;
|
2018-07-24 03:49:48 +00:00
|
|
|
|
|
|
|
case VIR_NETWORK_FORWARD_LAST:
|
|
|
|
default:
|
|
|
|
virReportEnumRangeError(virNetworkForwardType, def->forward.type);
|
|
|
|
goto error;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
}
|
2012-11-11 22:57:16 +00:00
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
VIR_FREE(stp);
|
2016-06-22 22:05:50 +00:00
|
|
|
|
2018-07-24 03:49:48 +00:00
|
|
|
if (def->mtu) {
|
|
|
|
switch ((virNetworkForwardType) def->forward.type) {
|
|
|
|
case VIR_NETWORK_FORWARD_NONE:
|
|
|
|
case VIR_NETWORK_FORWARD_NAT:
|
|
|
|
case VIR_NETWORK_FORWARD_ROUTE:
|
|
|
|
case VIR_NETWORK_FORWARD_OPEN:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_NETWORK_FORWARD_BRIDGE:
|
|
|
|
case VIR_NETWORK_FORWARD_PRIVATE:
|
|
|
|
case VIR_NETWORK_FORWARD_VEPA:
|
|
|
|
case VIR_NETWORK_FORWARD_PASSTHROUGH:
|
|
|
|
case VIR_NETWORK_FORWARD_HOSTDEV:
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("mtu size only allowed in open, route, nat, "
|
|
|
|
"and isolated mode, not in %s (network '%s')"),
|
|
|
|
virNetworkForwardTypeToString(def->forward.type),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
case VIR_NETWORK_FORWARD_LAST:
|
|
|
|
default:
|
|
|
|
virReportEnumRangeError(virNetworkForwardType, def->forward.type);
|
|
|
|
goto error;
|
|
|
|
}
|
2017-01-23 02:23:48 +00:00
|
|
|
}
|
|
|
|
|
2016-06-22 22:05:50 +00:00
|
|
|
/* Extract custom metadata */
|
|
|
|
if ((metadataNode = virXPathNode("./metadata[1]", ctxt)) != NULL) {
|
|
|
|
def->metadata = xmlCopyNode(metadataNode, 1);
|
|
|
|
virXMLNodeSanitizeNamespaces(def->metadata);
|
|
|
|
}
|
|
|
|
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
ctxt->node = save;
|
2008-07-11 10:48:34 +00:00
|
|
|
return def;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
error:
|
2014-09-15 08:42:15 +00:00
|
|
|
VIR_FREE(tmp);
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
VIR_FREE(routeNodes);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
VIR_FREE(stp);
|
2008-07-11 10:48:34 +00:00
|
|
|
virNetworkDefFree(def);
|
2011-01-10 22:35:37 +00:00
|
|
|
VIR_FREE(ipNodes);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
VIR_FREE(portGroupNodes);
|
2012-12-03 16:13:36 +00:00
|
|
|
VIR_FREE(ipv6nogwStr);
|
2014-09-23 18:19:08 +00:00
|
|
|
VIR_FREE(trustGuestRxFilters);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
ctxt->node = save;
|
2008-07-11 10:48:34 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2010-02-24 20:53:16 +00:00
|
|
|
static virNetworkDefPtr
|
|
|
|
virNetworkDefParse(const char *xmlStr,
|
2019-07-14 16:15:12 +00:00
|
|
|
const char *filename,
|
|
|
|
virNetworkXMLOptionPtr xmlopt)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
2010-02-24 20:53:16 +00:00
|
|
|
xmlDocPtr xml;
|
2008-08-01 09:39:44 +00:00
|
|
|
virNetworkDefPtr def = NULL;
|
2016-06-22 22:05:50 +00:00
|
|
|
int keepBlanksDefault = xmlKeepBlanksDefault(0);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2011-09-14 14:17:57 +00:00
|
|
|
if ((xml = virXMLParse(filename, xmlStr, _("(network_definition)")))) {
|
2019-07-14 16:15:12 +00:00
|
|
|
def = virNetworkDefParseNode(xml, xmlDocGetRootElement(xml), xmlopt);
|
2010-02-24 20:53:16 +00:00
|
|
|
xmlFreeDoc(xml);
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
2016-06-22 22:05:50 +00:00
|
|
|
xmlKeepBlanksDefault(keepBlanksDefault);
|
2008-07-11 10:48:34 +00:00
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
|
|
|
virNetworkDefPtr
|
2019-07-14 16:15:12 +00:00
|
|
|
virNetworkDefParseString(const char *xmlStr,
|
|
|
|
virNetworkXMLOptionPtr xmlopt)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
2019-07-14 16:15:12 +00:00
|
|
|
return virNetworkDefParse(xmlStr, NULL, xmlopt);
|
2010-02-24 20:53:16 +00:00
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
|
|
|
virNetworkDefPtr
|
2019-07-14 16:15:12 +00:00
|
|
|
virNetworkDefParseFile(const char *filename,
|
|
|
|
virNetworkXMLOptionPtr xmlopt)
|
2010-02-24 20:53:16 +00:00
|
|
|
{
|
2019-07-14 16:15:12 +00:00
|
|
|
return virNetworkDefParse(NULL, filename, xmlopt);
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
virNetworkDefPtr
|
|
|
|
virNetworkDefParseNode(xmlDocPtr xml,
|
2019-07-14 16:15:12 +00:00
|
|
|
xmlNodePtr root,
|
|
|
|
virNetworkXMLOptionPtr xmlopt)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
virNetworkDefPtr def = NULL;
|
|
|
|
|
2017-08-14 12:31:52 +00:00
|
|
|
if (!virXMLNodeNameEqual(root, "network")) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("unexpected root element <%s>, "
|
|
|
|
"expecting <network>"),
|
|
|
|
root->name);
|
2008-07-11 10:48:34 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxt = xmlXPathNewContext(xml);
|
|
|
|
if (ctxt == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-07-11 10:48:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxt->node = root;
|
2019-07-14 16:15:12 +00:00
|
|
|
def = virNetworkDefParseXML(ctxt, xmlopt);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2008-07-11 10:48:34 +00:00
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
static int
|
|
|
|
virNetworkDNSDefFormat(virBufferPtr buf,
|
maint: avoid 'const fooPtr' in conf
'const fooPtr' is the same as 'foo * const' (the pointer won't
change, but it's contents can). But in general, if an interface
is trying to be const-correct, it should be using 'const foo *'
(the pointer is to data that can't be changed).
Fix up remaining offenders in src/conf, and their fallout.
* src/conf/snapshot_conf.h (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Drop attempt at const.
* src/conf/interface_conf.h (virInterfaceObjIsActive)
(virInterfaceDefFormat): Use intended type.
(virInterfaceFindByMACString, virInterfaceFindByName)
(virInterfaceAssignDef, virInterfaceRemove): Drop attempt at
const.
* src/conf/network_conf.h (virNetworkObjIsActive)
(virNetworkDefFormat, virNetworkDefForwardIf)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask): Use intended type.
(virNetworkFindByUUID, virNetworkFindByName, virNetworkAssignDef)
(virNetworkObjAssignDef, virNetworkRemoveInactive)
(virNetworkBridgeInUse, virNetworkSetBridgeName)
(virNetworkAllocateBridge): Drop attempt at const.
* src/conf/netdev_vlan_conf.h (virNetDevVlanFormat): Make
const-correct.
* src/conf/node_device_conf.h (virNodeDeviceHasCap)
(virNodeDeviceDefFormat): Use intended type.
(virNodeDeviceFindByName, virNodeDeviceFindBySysfsPath)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceGetParentHost): Drop attempt at const.
* src/conf/secret_conf.h (virSecretDefFormat): Use intended type.
* src/conf/snapshot_conf.c (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Fix fallout.
* src/conf/interface_conf.c (virInterfaceBridgeDefFormat)
(virInterfaceBondDefFormat, virInterfaceVlanDefFormat)
(virInterfaceProtocolDefFormat, virInterfaceDefDevFormat)
(virInterfaceDefFormat, virInterfaceFindByMACString)
(virInterfaceFindByName, virInterfaceAssignDef)
(virInterfaceRemove): Likewise.
* src/conf/network_conf.c
(VIR_ENUM_IMPL, virNetworkFindByName, virNetworkObjAssignDef)
(virNetworkAssignDef, virNetworkRemoveInactive)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask, virNetworkDHCPHostDefParseXML)
(virNetworkIpDefFormat, virNetworkRouteDefFormat)
(virPortGroupDefFormat, virNetworkForwardNatDefFormat)
(virNetworkDefFormatInternal, virNetworkBridgeInUse)
(virNetworkAllocateBridge, virNetworkSetBridgeName)
(virNetworkDNSDefFormat, virNetworkDefFormat): Likewise.
* src/conf/netdev_vlan_conf.c (virNetDevVlanFormat): Likewise.
* src/conf/node_device_conf.c (virNodeDeviceHasCap)
(virNodeDeviceFindBySysfsPath, virNodeDeviceFindByName)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceDefFormat, virNodeDeviceGetParentHost): Likewise.
* src/conf/secret_conf.c (virSecretDefFormatUsage)
(virSecretDefFormat): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-10-08 16:36:37 +00:00
|
|
|
const virNetworkDNSDef *def)
|
2011-06-24 10:04:36 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i, j;
|
2011-06-24 10:04:36 +00:00
|
|
|
|
2016-08-11 21:29:43 +00:00
|
|
|
if (!(def->enable || def->forwardPlainNames || def->nfwds || def->nhosts ||
|
2013-09-13 16:31:07 +00:00
|
|
|
def->nsrvs || def->ntxts))
|
2014-01-31 13:50:16 +00:00
|
|
|
return 0;
|
2011-06-24 10:04:36 +00:00
|
|
|
|
2013-08-13 22:56:38 +00:00
|
|
|
virBufferAddLit(buf, "<dns");
|
2016-08-11 21:29:43 +00:00
|
|
|
if (def->enable) {
|
|
|
|
const char *fwd = virTristateBoolTypeToString(def->enable);
|
|
|
|
|
|
|
|
if (!fwd) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unknown enable type %d in network"),
|
|
|
|
def->enable);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
virBufferAsprintf(buf, " enable='%s'", fwd);
|
|
|
|
}
|
2013-08-13 22:56:38 +00:00
|
|
|
if (def->forwardPlainNames) {
|
2014-06-27 15:16:54 +00:00
|
|
|
const char *fwd = virTristateBoolTypeToString(def->forwardPlainNames);
|
2014-01-31 13:50:16 +00:00
|
|
|
|
|
|
|
if (!fwd) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unknown forwardPlainNames type %d in network"),
|
|
|
|
def->forwardPlainNames);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
virBufferAsprintf(buf, " forwardPlainNames='%s'", fwd);
|
2016-08-11 21:29:43 +00:00
|
|
|
}
|
|
|
|
if (!(def->nfwds || def->nhosts || def->nsrvs || def->ntxts)) {
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
|
|
|
return 0;
|
2013-08-13 22:56:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virBufferAddLit(buf, ">\n");
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(buf, 2);
|
2011-06-24 10:04:36 +00:00
|
|
|
|
2013-09-13 16:31:07 +00:00
|
|
|
for (i = 0; i < def->nfwds; i++) {
|
2016-08-12 02:28:27 +00:00
|
|
|
|
|
|
|
virBufferAddLit(buf, "<forwarder");
|
|
|
|
if (def->forwarders[i].domain) {
|
|
|
|
virBufferEscapeString(buf, " domain='%s'",
|
|
|
|
def->forwarders[i].domain);
|
|
|
|
}
|
|
|
|
if (VIR_SOCKET_ADDR_VALID(&def->forwarders[i].addr)) {
|
|
|
|
char *addr = virSocketAddrFormat(&def->forwarders[i].addr);
|
|
|
|
|
|
|
|
if (!addr)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
virBufferAsprintf(buf, " addr='%s'", addr);
|
|
|
|
VIR_FREE(addr);
|
|
|
|
}
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
2013-09-13 16:31:07 +00:00
|
|
|
}
|
|
|
|
|
2013-05-21 07:21:17 +00:00
|
|
|
for (i = 0; i < def->ntxts; i++) {
|
2015-05-05 14:52:46 +00:00
|
|
|
virBufferEscapeString(buf, "<txt name='%s' ", def->txts[i].name);
|
|
|
|
virBufferEscapeString(buf, "value='%s'/>\n", def->txts[i].value);
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
|
|
|
|
2013-05-21 07:21:17 +00:00
|
|
|
for (i = 0; i < def->nsrvs; i++) {
|
2012-11-11 23:59:28 +00:00
|
|
|
if (def->srvs[i].service && def->srvs[i].protocol) {
|
2015-05-05 14:52:46 +00:00
|
|
|
virBufferEscapeString(buf, "<srv service='%s' ",
|
|
|
|
def->srvs[i].service);
|
|
|
|
virBufferEscapeString(buf, "protocol='%s'", def->srvs[i].protocol);
|
2012-11-11 23:59:28 +00:00
|
|
|
|
|
|
|
if (def->srvs[i].domain)
|
2015-05-05 14:52:46 +00:00
|
|
|
virBufferEscapeString(buf, " domain='%s'", def->srvs[i].domain);
|
2012-11-11 23:59:28 +00:00
|
|
|
if (def->srvs[i].target)
|
2015-05-05 14:52:46 +00:00
|
|
|
virBufferEscapeString(buf, " target='%s'", def->srvs[i].target);
|
2012-11-11 23:59:28 +00:00
|
|
|
if (def->srvs[i].port)
|
|
|
|
virBufferAsprintf(buf, " port='%d'", def->srvs[i].port);
|
|
|
|
if (def->srvs[i].priority)
|
|
|
|
virBufferAsprintf(buf, " priority='%d'", def->srvs[i].priority);
|
|
|
|
if (def->srvs[i].weight)
|
|
|
|
virBufferAsprintf(buf, " weight='%d'", def->srvs[i].weight);
|
2012-01-02 14:23:54 +00:00
|
|
|
|
2013-05-07 10:28:50 +00:00
|
|
|
virBufferAddLit(buf, "/>\n");
|
2012-01-02 14:23:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-24 10:04:40 +00:00
|
|
|
if (def->nhosts) {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->nhosts; i++) {
|
|
|
|
char *ip = virSocketAddrFormat(&def->hosts[i].ip);
|
2011-06-24 10:04:40 +00:00
|
|
|
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAsprintf(buf, "<host ip='%s'>\n", ip);
|
|
|
|
virBufferAdjustIndent(buf, 2);
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (j = 0; j < def->hosts[i].nnames; j++)
|
2015-05-05 14:52:46 +00:00
|
|
|
virBufferEscapeString(buf, "<hostname>%s</hostname>\n",
|
|
|
|
def->hosts[i].names[j]);
|
2011-06-24 10:04:40 +00:00
|
|
|
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(buf, -2);
|
2013-05-07 10:28:50 +00:00
|
|
|
virBufferAddLit(buf, "</host>\n");
|
2011-06-29 02:45:01 +00:00
|
|
|
VIR_FREE(ip);
|
2011-06-24 10:04:40 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(buf, -2);
|
|
|
|
virBufferAddLit(buf, "</dns>\n");
|
2014-01-31 13:50:16 +00:00
|
|
|
return 0;
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
static int
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefFormat(virBufferPtr buf,
|
|
|
|
const virNetworkIPDef *def)
|
2010-11-17 18:36:19 +00:00
|
|
|
{
|
|
|
|
int result = -1;
|
|
|
|
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAddLit(buf, "<ip");
|
2010-11-17 18:36:19 +00:00
|
|
|
|
2014-11-13 14:23:27 +00:00
|
|
|
if (def->family)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(buf, " family='%s'", def->family);
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (VIR_SOCKET_ADDR_VALID(&def->address)) {
|
|
|
|
char *addr = virSocketAddrFormat(&def->address);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (!addr)
|
|
|
|
goto error;
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(buf, " address='%s'", addr);
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(addr);
|
|
|
|
}
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (VIR_SOCKET_ADDR_VALID(&def->netmask)) {
|
|
|
|
char *addr = virSocketAddrFormat(&def->netmask);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (!addr)
|
|
|
|
goto error;
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(buf, " netmask='%s'", addr);
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(addr);
|
|
|
|
}
|
2014-11-13 14:23:27 +00:00
|
|
|
if (def->prefix > 0)
|
2013-11-19 22:21:40 +00:00
|
|
|
virBufferAsprintf(buf, " prefix='%u'", def->prefix);
|
2016-12-08 21:23:09 +00:00
|
|
|
|
|
|
|
if (def->localPTR) {
|
|
|
|
virBufferAsprintf(buf, " localPtr='%s'",
|
|
|
|
virTristateBoolTypeToString(def->localPTR));
|
|
|
|
}
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
virBufferAddLit(buf, ">\n");
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(buf, 2);
|
2010-11-17 18:36:19 +00:00
|
|
|
|
|
|
|
if (def->tftproot) {
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferEscapeString(buf, "<tftp root='%s'/>\n",
|
2010-11-17 18:36:19 +00:00
|
|
|
def->tftproot);
|
|
|
|
}
|
|
|
|
if ((def->nranges || def->nhosts)) {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAddLit(buf, "<dhcp>\n");
|
|
|
|
virBufferAdjustIndent(buf, 2);
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->nranges; i++) {
|
|
|
|
char *saddr = virSocketAddrFormat(&def->ranges[i].start);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (!saddr)
|
|
|
|
goto error;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
char *eaddr = virSocketAddrFormat(&def->ranges[i].end);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (!eaddr) {
|
|
|
|
VIR_FREE(saddr);
|
|
|
|
goto error;
|
|
|
|
}
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferAsprintf(buf, "<range start='%s' end='%s'/>\n",
|
2010-11-17 18:36:19 +00:00
|
|
|
saddr, eaddr);
|
|
|
|
VIR_FREE(saddr);
|
|
|
|
VIR_FREE(eaddr);
|
|
|
|
}
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->nhosts; i++) {
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferAddLit(buf, "<host");
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (def->hosts[i].mac)
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferAsprintf(buf, " mac='%s'", def->hosts[i].mac);
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (def->hosts[i].id)
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferAsprintf(buf, " id='%s'", def->hosts[i].id);
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (def->hosts[i].name)
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferAsprintf(buf, " name='%s'", def->hosts[i].name);
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (VIR_SOCKET_ADDR_VALID(&def->hosts[i].ip)) {
|
|
|
|
char *ipaddr = virSocketAddrFormat(&def->hosts[i].ip);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (!ipaddr)
|
|
|
|
goto error;
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferAsprintf(buf, " ip='%s'", ipaddr);
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(ipaddr);
|
|
|
|
}
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
|
|
|
}
|
|
|
|
if (def->bootfile) {
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferEscapeString(buf, "<bootp file='%s'",
|
2010-11-17 18:36:19 +00:00
|
|
|
def->bootfile);
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (VIR_SOCKET_ADDR_VALID(&def->bootserver)) {
|
|
|
|
char *ipaddr = virSocketAddrFormat(&def->bootserver);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (!ipaddr)
|
|
|
|
goto error;
|
2013-07-30 12:36:08 +00:00
|
|
|
virBufferEscapeString(buf, " server='%s'", ipaddr);
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(ipaddr);
|
|
|
|
}
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
2012-08-16 15:41:41 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
|
|
|
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(buf, -2);
|
|
|
|
virBufferAddLit(buf, "</dhcp>\n");
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
|
|
|
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(buf, -2);
|
|
|
|
virBufferAddLit(buf, "</ip>\n");
|
2010-11-17 18:36:19 +00:00
|
|
|
|
|
|
|
result = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
error:
|
2010-11-17 18:36:19 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2011-11-02 14:53:35 +00:00
|
|
|
static int
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
virPortGroupDefFormat(virBufferPtr buf,
|
maint: avoid 'const fooPtr' in conf
'const fooPtr' is the same as 'foo * const' (the pointer won't
change, but it's contents can). But in general, if an interface
is trying to be const-correct, it should be using 'const foo *'
(the pointer is to data that can't be changed).
Fix up remaining offenders in src/conf, and their fallout.
* src/conf/snapshot_conf.h (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Drop attempt at const.
* src/conf/interface_conf.h (virInterfaceObjIsActive)
(virInterfaceDefFormat): Use intended type.
(virInterfaceFindByMACString, virInterfaceFindByName)
(virInterfaceAssignDef, virInterfaceRemove): Drop attempt at
const.
* src/conf/network_conf.h (virNetworkObjIsActive)
(virNetworkDefFormat, virNetworkDefForwardIf)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask): Use intended type.
(virNetworkFindByUUID, virNetworkFindByName, virNetworkAssignDef)
(virNetworkObjAssignDef, virNetworkRemoveInactive)
(virNetworkBridgeInUse, virNetworkSetBridgeName)
(virNetworkAllocateBridge): Drop attempt at const.
* src/conf/netdev_vlan_conf.h (virNetDevVlanFormat): Make
const-correct.
* src/conf/node_device_conf.h (virNodeDeviceHasCap)
(virNodeDeviceDefFormat): Use intended type.
(virNodeDeviceFindByName, virNodeDeviceFindBySysfsPath)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceGetParentHost): Drop attempt at const.
* src/conf/secret_conf.h (virSecretDefFormat): Use intended type.
* src/conf/snapshot_conf.c (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Fix fallout.
* src/conf/interface_conf.c (virInterfaceBridgeDefFormat)
(virInterfaceBondDefFormat, virInterfaceVlanDefFormat)
(virInterfaceProtocolDefFormat, virInterfaceDefDevFormat)
(virInterfaceDefFormat, virInterfaceFindByMACString)
(virInterfaceFindByName, virInterfaceAssignDef)
(virInterfaceRemove): Likewise.
* src/conf/network_conf.c
(VIR_ENUM_IMPL, virNetworkFindByName, virNetworkObjAssignDef)
(virNetworkAssignDef, virNetworkRemoveInactive)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask, virNetworkDHCPHostDefParseXML)
(virNetworkIpDefFormat, virNetworkRouteDefFormat)
(virPortGroupDefFormat, virNetworkForwardNatDefFormat)
(virNetworkDefFormatInternal, virNetworkBridgeInUse)
(virNetworkAllocateBridge, virNetworkSetBridgeName)
(virNetworkDNSDefFormat, virNetworkDefFormat): Likewise.
* src/conf/netdev_vlan_conf.c (virNetDevVlanFormat): Likewise.
* src/conf/node_device_conf.c (virNodeDeviceHasCap)
(virNodeDeviceFindBySysfsPath, virNodeDeviceFindByName)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceDefFormat, virNodeDeviceGetParentHost): Likewise.
* src/conf/secret_conf.c (virSecretDefFormatUsage)
(virSecretDefFormat): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-10-08 16:36:37 +00:00
|
|
|
const virPortGroupDef *def)
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
{
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAsprintf(buf, "<portgroup name='%s'", def->name);
|
2014-11-13 14:23:27 +00:00
|
|
|
if (def->isDefault)
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
virBufferAddLit(buf, " default='yes'");
|
2014-09-23 18:19:08 +00:00
|
|
|
if (def->trustGuestRxFilters)
|
|
|
|
virBufferAsprintf(buf, " trustGuestRxFilters='%s'",
|
|
|
|
virTristateBoolTypeToString(def->trustGuestRxFilters));
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
virBufferAddLit(buf, ">\n");
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(buf, 2);
|
2012-08-12 07:51:30 +00:00
|
|
|
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
|
|
|
|
return -1;
|
2011-11-02 14:53:35 +00:00
|
|
|
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
|
|
|
|
return -1;
|
2019-05-14 14:44:55 +00:00
|
|
|
virNetDevBandwidthFormat(def->bandwidth, 0, buf);
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(buf, -2);
|
|
|
|
virBufferAddLit(buf, "</portgroup>\n");
|
2011-11-02 14:53:35 +00:00
|
|
|
return 0;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2013-02-19 10:44:14 +00:00
|
|
|
static int
|
|
|
|
virNetworkForwardNatDefFormat(virBufferPtr buf,
|
maint: avoid 'const fooPtr' in conf
'const fooPtr' is the same as 'foo * const' (the pointer won't
change, but it's contents can). But in general, if an interface
is trying to be const-correct, it should be using 'const foo *'
(the pointer is to data that can't be changed).
Fix up remaining offenders in src/conf, and their fallout.
* src/conf/snapshot_conf.h (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Drop attempt at const.
* src/conf/interface_conf.h (virInterfaceObjIsActive)
(virInterfaceDefFormat): Use intended type.
(virInterfaceFindByMACString, virInterfaceFindByName)
(virInterfaceAssignDef, virInterfaceRemove): Drop attempt at
const.
* src/conf/network_conf.h (virNetworkObjIsActive)
(virNetworkDefFormat, virNetworkDefForwardIf)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask): Use intended type.
(virNetworkFindByUUID, virNetworkFindByName, virNetworkAssignDef)
(virNetworkObjAssignDef, virNetworkRemoveInactive)
(virNetworkBridgeInUse, virNetworkSetBridgeName)
(virNetworkAllocateBridge): Drop attempt at const.
* src/conf/netdev_vlan_conf.h (virNetDevVlanFormat): Make
const-correct.
* src/conf/node_device_conf.h (virNodeDeviceHasCap)
(virNodeDeviceDefFormat): Use intended type.
(virNodeDeviceFindByName, virNodeDeviceFindBySysfsPath)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceGetParentHost): Drop attempt at const.
* src/conf/secret_conf.h (virSecretDefFormat): Use intended type.
* src/conf/snapshot_conf.c (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Fix fallout.
* src/conf/interface_conf.c (virInterfaceBridgeDefFormat)
(virInterfaceBondDefFormat, virInterfaceVlanDefFormat)
(virInterfaceProtocolDefFormat, virInterfaceDefDevFormat)
(virInterfaceDefFormat, virInterfaceFindByMACString)
(virInterfaceFindByName, virInterfaceAssignDef)
(virInterfaceRemove): Likewise.
* src/conf/network_conf.c
(VIR_ENUM_IMPL, virNetworkFindByName, virNetworkObjAssignDef)
(virNetworkAssignDef, virNetworkRemoveInactive)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask, virNetworkDHCPHostDefParseXML)
(virNetworkIpDefFormat, virNetworkRouteDefFormat)
(virPortGroupDefFormat, virNetworkForwardNatDefFormat)
(virNetworkDefFormatInternal, virNetworkBridgeInUse)
(virNetworkAllocateBridge, virNetworkSetBridgeName)
(virNetworkDNSDefFormat, virNetworkDefFormat): Likewise.
* src/conf/netdev_vlan_conf.c (virNetDevVlanFormat): Likewise.
* src/conf/node_device_conf.c (virNodeDeviceHasCap)
(virNodeDeviceFindBySysfsPath, virNodeDeviceFindByName)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceDefFormat, virNodeDeviceGetParentHost): Likewise.
* src/conf/secret_conf.c (virSecretDefFormatUsage)
(virSecretDefFormat): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-10-08 16:36:37 +00:00
|
|
|
const virNetworkForwardDef *fwd)
|
2013-02-19 10:44:14 +00:00
|
|
|
{
|
|
|
|
char *addrStart = NULL;
|
|
|
|
char *addrEnd = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
2013-02-19 10:44:16 +00:00
|
|
|
if (VIR_SOCKET_ADDR_VALID(&fwd->addr.start)) {
|
|
|
|
addrStart = virSocketAddrFormat(&fwd->addr.start);
|
2013-02-19 10:44:14 +00:00
|
|
|
if (!addrStart)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-19 10:44:16 +00:00
|
|
|
if (VIR_SOCKET_ADDR_VALID(&fwd->addr.end)) {
|
|
|
|
addrEnd = virSocketAddrFormat(&fwd->addr.end);
|
2013-02-19 10:44:14 +00:00
|
|
|
if (!addrEnd)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-19 10:44:16 +00:00
|
|
|
if (!addrEnd && !addrStart && !fwd->port.start && !fwd->port.end)
|
2013-02-19 10:44:14 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
virBufferAddLit(buf, "<nat>\n");
|
|
|
|
virBufferAdjustIndent(buf, 2);
|
|
|
|
|
2013-02-19 10:44:15 +00:00
|
|
|
if (addrStart) {
|
|
|
|
virBufferAsprintf(buf, "<address start='%s'", addrStart);
|
|
|
|
if (addrEnd)
|
|
|
|
virBufferAsprintf(buf, " end='%s'", addrEnd);
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
|
|
|
}
|
|
|
|
|
2013-02-19 10:44:16 +00:00
|
|
|
if (fwd->port.start || fwd->port.end) {
|
|
|
|
virBufferAsprintf(buf, "<port start='%d'", fwd->port.start);
|
|
|
|
if (fwd->port.end)
|
|
|
|
virBufferAsprintf(buf, " end='%d'", fwd->port.end);
|
2013-02-19 10:44:15 +00:00
|
|
|
virBufferAddLit(buf, "/>\n");
|
|
|
|
}
|
2013-02-19 10:44:14 +00:00
|
|
|
|
|
|
|
virBufferAdjustIndent(buf, -2);
|
|
|
|
virBufferAddLit(buf, "</nat>\n");
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2013-02-19 10:44:14 +00:00
|
|
|
VIR_FREE(addrStart);
|
|
|
|
VIR_FREE(addrEnd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2014-02-12 16:36:35 +00:00
|
|
|
int
|
|
|
|
virNetworkDefFormatBuf(virBufferPtr buf,
|
|
|
|
const virNetworkDef *def,
|
2019-07-14 16:15:12 +00:00
|
|
|
virNetworkXMLOptionPtr xmlopt ATTRIBUTE_UNUSED,
|
2014-02-12 16:36:35 +00:00
|
|
|
unsigned int flags)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
maint: avoid 'const fooPtr' in conf
'const fooPtr' is the same as 'foo * const' (the pointer won't
change, but it's contents can). But in general, if an interface
is trying to be const-correct, it should be using 'const foo *'
(the pointer is to data that can't be changed).
Fix up remaining offenders in src/conf, and their fallout.
* src/conf/snapshot_conf.h (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Drop attempt at const.
* src/conf/interface_conf.h (virInterfaceObjIsActive)
(virInterfaceDefFormat): Use intended type.
(virInterfaceFindByMACString, virInterfaceFindByName)
(virInterfaceAssignDef, virInterfaceRemove): Drop attempt at
const.
* src/conf/network_conf.h (virNetworkObjIsActive)
(virNetworkDefFormat, virNetworkDefForwardIf)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask): Use intended type.
(virNetworkFindByUUID, virNetworkFindByName, virNetworkAssignDef)
(virNetworkObjAssignDef, virNetworkRemoveInactive)
(virNetworkBridgeInUse, virNetworkSetBridgeName)
(virNetworkAllocateBridge): Drop attempt at const.
* src/conf/netdev_vlan_conf.h (virNetDevVlanFormat): Make
const-correct.
* src/conf/node_device_conf.h (virNodeDeviceHasCap)
(virNodeDeviceDefFormat): Use intended type.
(virNodeDeviceFindByName, virNodeDeviceFindBySysfsPath)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceGetParentHost): Drop attempt at const.
* src/conf/secret_conf.h (virSecretDefFormat): Use intended type.
* src/conf/snapshot_conf.c (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Fix fallout.
* src/conf/interface_conf.c (virInterfaceBridgeDefFormat)
(virInterfaceBondDefFormat, virInterfaceVlanDefFormat)
(virInterfaceProtocolDefFormat, virInterfaceDefDevFormat)
(virInterfaceDefFormat, virInterfaceFindByMACString)
(virInterfaceFindByName, virInterfaceAssignDef)
(virInterfaceRemove): Likewise.
* src/conf/network_conf.c
(VIR_ENUM_IMPL, virNetworkFindByName, virNetworkObjAssignDef)
(virNetworkAssignDef, virNetworkRemoveInactive)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask, virNetworkDHCPHostDefParseXML)
(virNetworkIpDefFormat, virNetworkRouteDefFormat)
(virPortGroupDefFormat, virNetworkForwardNatDefFormat)
(virNetworkDefFormatInternal, virNetworkBridgeInUse)
(virNetworkAllocateBridge, virNetworkSetBridgeName)
(virNetworkDNSDefFormat, virNetworkDefFormat): Likewise.
* src/conf/netdev_vlan_conf.c (virNetDevVlanFormat): Likewise.
* src/conf/node_device_conf.c (virNodeDeviceHasCap)
(virNodeDeviceFindBySysfsPath, virNodeDeviceFindByName)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceDefFormat, virNodeDeviceGetParentHost): Likewise.
* src/conf/secret_conf.c (virSecretDefFormatUsage)
(virSecretDefFormat): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-10-08 16:36:37 +00:00
|
|
|
const unsigned char *uuid;
|
2008-07-11 10:48:34 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2013-09-05 09:27:36 +00:00
|
|
|
bool shortforward;
|
2018-07-24 03:49:48 +00:00
|
|
|
bool hasbridge = false;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, "<network");
|
2014-11-13 14:23:27 +00:00
|
|
|
if (!(flags & VIR_NETWORK_XML_INACTIVE) && (def->connections > 0))
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAsprintf(buf, " connections='%d'", def->connections);
|
2012-12-03 16:13:36 +00:00
|
|
|
if (def->ipv6nogw)
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, " ipv6='yes'");
|
2014-09-23 18:19:08 +00:00
|
|
|
if (def->trustGuestRxFilters)
|
|
|
|
virBufferAsprintf(buf, " trustGuestRxFilters='%s'",
|
|
|
|
virTristateBoolTypeToString(def->trustGuestRxFilters));
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, ">\n");
|
|
|
|
virBufferAdjustIndent(buf, 2);
|
|
|
|
virBufferEscapeString(buf, "<name>%s</name>\n", def->name);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
uuid = def->uuid;
|
|
|
|
virUUIDFormat(uuid, uuidstr);
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAsprintf(buf, "<uuid>%s</uuid>\n", uuidstr);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2016-06-22 22:05:50 +00:00
|
|
|
if (def->metadata) {
|
|
|
|
xmlBufferPtr xmlbuf;
|
|
|
|
int oldIndentTreeOutput = xmlIndentTreeOutput;
|
|
|
|
|
|
|
|
/* Indentation on output requires that we previously set
|
|
|
|
* xmlKeepBlanksDefault to 0 when parsing; also, libxml does 2
|
|
|
|
* spaces per level of indentation of intermediate elements,
|
|
|
|
* but no leading indentation before the starting element.
|
|
|
|
* Thankfully, libxml maps what looks like globals into
|
|
|
|
* thread-local uses, so we are thread-safe. */
|
|
|
|
xmlIndentTreeOutput = 1;
|
|
|
|
xmlbuf = xmlBufferCreate();
|
|
|
|
if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata,
|
|
|
|
virBufferGetIndent(buf, false) / 2, 1) < 0) {
|
|
|
|
xmlBufferFree(xmlbuf);
|
|
|
|
xmlIndentTreeOutput = oldIndentTreeOutput;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
virBufferAsprintf(buf, "%s\n", (char *) xmlBufferContent(xmlbuf));
|
|
|
|
xmlBufferFree(xmlbuf);
|
|
|
|
xmlIndentTreeOutput = oldIndentTreeOutput;
|
|
|
|
}
|
|
|
|
|
2012-11-08 02:16:17 +00:00
|
|
|
if (def->forward.type != VIR_NETWORK_FORWARD_NONE) {
|
2011-12-14 10:50:23 +00:00
|
|
|
const char *dev = NULL;
|
2012-11-08 02:16:17 +00:00
|
|
|
if (!def->forward.npfs)
|
2011-12-14 10:50:23 +00:00
|
|
|
dev = virNetworkDefForwardIf(def, 0);
|
2012-11-08 02:16:17 +00:00
|
|
|
const char *mode = virNetworkForwardTypeToString(def->forward.type);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
|
|
|
if (!mode) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unknown forward type %d in network '%s'"),
|
2012-11-08 02:16:17 +00:00
|
|
|
def->forward.type, def->name);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, "<forward");
|
|
|
|
virBufferEscapeString(buf, " dev='%s'", dev);
|
|
|
|
virBufferAsprintf(buf, " mode='%s'", mode);
|
2012-11-08 02:16:17 +00:00
|
|
|
if (def->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
|
|
|
|
if (def->forward.managed)
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, " managed='yes'");
|
2012-08-16 15:41:41 +00:00
|
|
|
else
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, " managed='no'");
|
2012-08-16 15:41:41 +00:00
|
|
|
}
|
2013-02-19 10:44:14 +00:00
|
|
|
shortforward = !(def->forward.nifs || def->forward.npfs
|
2013-02-19 10:44:16 +00:00
|
|
|
|| VIR_SOCKET_ADDR_VALID(&def->forward.addr.start)
|
|
|
|
|| VIR_SOCKET_ADDR_VALID(&def->forward.addr.end)
|
|
|
|
|| def->forward.port.start
|
2013-04-26 20:23:27 +00:00
|
|
|
|| def->forward.port.end
|
|
|
|
|| (def->forward.driverName
|
|
|
|
!= VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT));
|
2013-02-19 10:44:14 +00:00
|
|
|
virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : "");
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAdjustIndent(buf, 2);
|
2011-12-14 10:50:23 +00:00
|
|
|
|
2013-04-26 20:23:27 +00:00
|
|
|
if (def->forward.driverName
|
|
|
|
!= VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT) {
|
|
|
|
const char *driverName
|
|
|
|
= virNetworkForwardDriverNameTypeToString(def->forward.driverName);
|
|
|
|
if (!driverName) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected hostdev driver name type %d "),
|
|
|
|
def->forward.driverName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
virBufferAsprintf(buf, "<driver name='%s'/>\n", driverName);
|
|
|
|
}
|
2013-02-19 10:44:14 +00:00
|
|
|
if (def->forward.type == VIR_NETWORK_FORWARD_NAT) {
|
|
|
|
if (virNetworkForwardNatDefFormat(buf, &def->forward) < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2012-11-08 02:16:17 +00:00
|
|
|
/* For now, hard-coded to at most 1 forward.pfs */
|
|
|
|
if (def->forward.npfs)
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferEscapeString(buf, "<pf dev='%s'/>\n",
|
2012-11-08 02:16:17 +00:00
|
|
|
def->forward.pfs[0].dev);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
2012-11-08 02:16:17 +00:00
|
|
|
if (def->forward.nifs &&
|
|
|
|
(!def->forward.npfs || !(flags & VIR_NETWORK_XML_INACTIVE))) {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->forward.nifs; i++) {
|
2014-08-21 09:06:37 +00:00
|
|
|
if (def->forward.ifs[i].type == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV) {
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferEscapeString(buf, "<interface dev='%s'",
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
def->forward.ifs[i].device.dev);
|
2012-08-16 15:41:41 +00:00
|
|
|
if (!(flags & VIR_NETWORK_XML_INACTIVE) &&
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
(def->forward.ifs[i].connections > 0)) {
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAsprintf(buf, " connections='%d'",
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
def->forward.ifs[i].connections);
|
2012-08-16 15:41:41 +00:00
|
|
|
}
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, "/>\n");
|
2014-08-21 09:06:37 +00:00
|
|
|
} else {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (def->forward.ifs[i].type == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI) {
|
2018-12-19 11:58:42 +00:00
|
|
|
virPCIDeviceAddressFormat(buf,
|
|
|
|
def->forward.ifs[i].device.pci,
|
|
|
|
true);
|
2012-08-16 15:41:41 +00:00
|
|
|
}
|
2012-08-05 06:59:55 +00:00
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
}
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAdjustIndent(buf, -2);
|
2013-02-19 10:44:14 +00:00
|
|
|
if (!shortforward)
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, "</forward>\n");
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
2018-07-24 03:49:48 +00:00
|
|
|
switch ((virNetworkForwardType) def->forward.type) {
|
|
|
|
case VIR_NETWORK_FORWARD_NONE:
|
|
|
|
case VIR_NETWORK_FORWARD_NAT:
|
|
|
|
case VIR_NETWORK_FORWARD_ROUTE:
|
|
|
|
case VIR_NETWORK_FORWARD_OPEN:
|
|
|
|
hasbridge = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_NETWORK_FORWARD_BRIDGE:
|
|
|
|
case VIR_NETWORK_FORWARD_PRIVATE:
|
|
|
|
case VIR_NETWORK_FORWARD_VEPA:
|
|
|
|
case VIR_NETWORK_FORWARD_PASSTHROUGH:
|
|
|
|
case VIR_NETWORK_FORWARD_HOSTDEV:
|
|
|
|
break;
|
conf: new network bridge device attribute macTableManager
The macTableManager attribute of a network's bridge subelement tells
libvirt how the bridge's MAC address table (used to determine the
egress port for packets) is managed. In the default mode, "kernel",
management is left to the kernel, which usually determines entries in
part by turning on promiscuous mode on all ports of the bridge,
flooding packets to all ports when the correct destination is unknown,
and adding/removing entries to the fdb as it sees incoming traffic
from particular MAC addresses. In "libvirt" mode, libvirt turns off
learning and flooding on all the bridge ports connected to guest
domain interfaces, and adds/removes entries according to the MAC
addresses in the domain interface configurations. A side effect of
turning off learning and unicast_flood on the ports of a bridge is
that (with Linux kernel 3.17 and newer), the kernel can automatically
turn off promiscuous mode on one or more of the bridge's ports
(usually only the one interface that is used to connect the bridge to
the physical network). The result is better performance (because
packets aren't being flooded to all ports, and can be dropped earlier
when they are of no interest) and slightly better security (a guest
can still send out packets with a spoofed source MAC address, but will
only receive traffic intended for the guest interface's configured MAC
address).
The attribute looks like this in the configuration:
<network>
<name>test</name>
<bridge name='br0' macTableManager='libvirt'/>
...
This patch only adds the config knob, documentation, and test
cases. The functionality behind this knob is added in later patches.
2014-11-20 17:40:33 +00:00
|
|
|
|
2018-07-24 03:49:48 +00:00
|
|
|
case VIR_NETWORK_FORWARD_LAST:
|
|
|
|
default:
|
|
|
|
virReportEnumRangeError(virNetworkForwardType, def->forward.type);
|
|
|
|
goto error;
|
|
|
|
}
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
2018-07-24 03:49:48 +00:00
|
|
|
if (hasbridge || def->bridge || def->macTableManager) {
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, "<bridge");
|
conf: new network bridge device attribute macTableManager
The macTableManager attribute of a network's bridge subelement tells
libvirt how the bridge's MAC address table (used to determine the
egress port for packets) is managed. In the default mode, "kernel",
management is left to the kernel, which usually determines entries in
part by turning on promiscuous mode on all ports of the bridge,
flooding packets to all ports when the correct destination is unknown,
and adding/removing entries to the fdb as it sees incoming traffic
from particular MAC addresses. In "libvirt" mode, libvirt turns off
learning and flooding on all the bridge ports connected to guest
domain interfaces, and adds/removes entries according to the MAC
addresses in the domain interface configurations. A side effect of
turning off learning and unicast_flood on the ports of a bridge is
that (with Linux kernel 3.17 and newer), the kernel can automatically
turn off promiscuous mode on one or more of the bridge's ports
(usually only the one interface that is used to connect the bridge to
the physical network). The result is better performance (because
packets aren't being flooded to all ports, and can be dropped earlier
when they are of no interest) and slightly better security (a guest
can still send out packets with a spoofed source MAC address, but will
only receive traffic intended for the guest interface's configured MAC
address).
The attribute looks like this in the configuration:
<network>
<name>test</name>
<bridge name='br0' macTableManager='libvirt'/>
...
This patch only adds the config knob, documentation, and test
cases. The functionality behind this knob is added in later patches.
2014-11-20 17:40:33 +00:00
|
|
|
virBufferEscapeString(buf, " name='%s'", def->bridge);
|
2019-01-09 21:51:31 +00:00
|
|
|
virBufferEscapeString(buf, " zone='%s'", def->bridgeZone);
|
2018-07-24 03:49:48 +00:00
|
|
|
if (hasbridge)
|
conf: new network bridge device attribute macTableManager
The macTableManager attribute of a network's bridge subelement tells
libvirt how the bridge's MAC address table (used to determine the
egress port for packets) is managed. In the default mode, "kernel",
management is left to the kernel, which usually determines entries in
part by turning on promiscuous mode on all ports of the bridge,
flooding packets to all ports when the correct destination is unknown,
and adding/removing entries to the fdb as it sees incoming traffic
from particular MAC addresses. In "libvirt" mode, libvirt turns off
learning and flooding on all the bridge ports connected to guest
domain interfaces, and adds/removes entries according to the MAC
addresses in the domain interface configurations. A side effect of
turning off learning and unicast_flood on the ports of a bridge is
that (with Linux kernel 3.17 and newer), the kernel can automatically
turn off promiscuous mode on one or more of the bridge's ports
(usually only the one interface that is used to connect the bridge to
the physical network). The result is better performance (because
packets aren't being flooded to all ports, and can be dropped earlier
when they are of no interest) and slightly better security (a guest
can still send out packets with a spoofed source MAC address, but will
only receive traffic intended for the guest interface's configured MAC
address).
The attribute looks like this in the configuration:
<network>
<name>test</name>
<bridge name='br0' macTableManager='libvirt'/>
...
This patch only adds the config knob, documentation, and test
cases. The functionality behind this knob is added in later patches.
2014-11-20 17:40:33 +00:00
|
|
|
virBufferAsprintf(buf, " stp='%s' delay='%ld'",
|
|
|
|
def->stp ? "on" : "off", def->delay);
|
|
|
|
if (def->macTableManager) {
|
|
|
|
virBufferAsprintf(buf, " macTableManager='%s'",
|
|
|
|
virNetworkBridgeMACTableManagerTypeToString(def->macTableManager));
|
|
|
|
}
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
}
|
|
|
|
|
2017-01-23 02:23:48 +00:00
|
|
|
if (def->mtu)
|
|
|
|
virBufferAsprintf(buf, "<mtu size='%u'/>\n", def->mtu);
|
|
|
|
|
Give each virtual network bridge its own fixed MAC address
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=609463
The problem was that, since a bridge always acquires the MAC address
of the connected interface with the numerically lowest MAC, as guests
are started and stopped, it was possible for the MAC address to change
over time, and this change in the network was being detected by
Windows 7 (it sees the MAC of the default route change), so on each
reboot it would bring up a dialog box asking about this "new network".
The solution is to create a dummy tap interface with a MAC guaranteed
to be lower than any guest interface's MAC, and attach that tap to the
bridge as soon as it's created. Since all guest MAC addresses start
with 0xFE, we can just generate a MAC with the standard "0x52, 0x54,
0" prefix, and it's guaranteed to always win (physical interfaces are
never connected to these bridges, so we don't need to worry about
competing numerically with them).
Note that the dummy tap is never set to IFF_UP state - that's not
necessary in order for the bridge to take its MAC, and not setting it
to UP eliminates the clutter of having an (eg) "virbr0-nic" displayed
in the output of the ifconfig command.
I chose to not auto-generate the MAC address in the network XML
parser, as there are likely to be consumers of that API that don't
need or want to have a MAC address associated with the
bridge.
Instead, in bridge_driver.c when the network is being defined, if
there is no MAC, one is generated. To account for virtual network
configs that already exist when upgrading from an older version of
libvirt, I've added a %post script to the specfile that searches for
all network definitions in both the config directory
(/etc/libvirt/qemu/networks) and the state directory
(/var/lib/libvirt/network) that are missing a mac address, generates a
random address, and adds it to the config (and a matching address to
the state file, if there is one).
docs/formatnetwork.html.in: document <mac address.../>
docs/schemas/network.rng: add nac address to schema
libvirt.spec.in: %post script to update existing networks
src/conf/network_conf.[ch]: parse and format <mac address.../>
src/libvirt_private.syms: export a couple private symbols we need
src/network/bridge_driver.c:
auto-generate mac address when needed,
create dummy interface if mac address is present.
tests/networkxml2xmlin/isolated-network.xml
tests/networkxml2xmlin/routed-network.xml
tests/networkxml2xmlout/isolated-network.xml
tests/networkxml2xmlout/routed-network.xml: add mac address to some tests
2011-02-09 08:28:12 +00:00
|
|
|
if (def->mac_specified) {
|
|
|
|
char macaddr[VIR_MAC_STRING_BUFLEN];
|
2012-07-17 12:07:59 +00:00
|
|
|
virMacAddrFormat(&def->mac, macaddr);
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAsprintf(buf, "<mac address='%s'/>\n", macaddr);
|
Give each virtual network bridge its own fixed MAC address
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=609463
The problem was that, since a bridge always acquires the MAC address
of the connected interface with the numerically lowest MAC, as guests
are started and stopped, it was possible for the MAC address to change
over time, and this change in the network was being detected by
Windows 7 (it sees the MAC of the default route change), so on each
reboot it would bring up a dialog box asking about this "new network".
The solution is to create a dummy tap interface with a MAC guaranteed
to be lower than any guest interface's MAC, and attach that tap to the
bridge as soon as it's created. Since all guest MAC addresses start
with 0xFE, we can just generate a MAC with the standard "0x52, 0x54,
0" prefix, and it's guaranteed to always win (physical interfaces are
never connected to these bridges, so we don't need to worry about
competing numerically with them).
Note that the dummy tap is never set to IFF_UP state - that's not
necessary in order for the bridge to take its MAC, and not setting it
to UP eliminates the clutter of having an (eg) "virbr0-nic" displayed
in the output of the ifconfig command.
I chose to not auto-generate the MAC address in the network XML
parser, as there are likely to be consumers of that API that don't
need or want to have a MAC address associated with the
bridge.
Instead, in bridge_driver.c when the network is being defined, if
there is no MAC, one is generated. To account for virtual network
configs that already exist when upgrading from an older version of
libvirt, I've added a %post script to the specfile that searches for
all network definitions in both the config directory
(/etc/libvirt/qemu/networks) and the state directory
(/var/lib/libvirt/network) that are missing a mac address, generates a
random address, and adds it to the config (and a matching address to
the state file, if there is one).
docs/formatnetwork.html.in: document <mac address.../>
docs/schemas/network.rng: add nac address to schema
libvirt.spec.in: %post script to update existing networks
src/conf/network_conf.[ch]: parse and format <mac address.../>
src/libvirt_private.syms: export a couple private symbols we need
src/network/bridge_driver.c:
auto-generate mac address when needed,
create dummy interface if mac address is present.
tests/networkxml2xmlin/isolated-network.xml
tests/networkxml2xmlin/routed-network.xml
tests/networkxml2xmlout/isolated-network.xml
tests/networkxml2xmlout/routed-network.xml: add mac address to some tests
2011-02-09 08:28:12 +00:00
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2014-12-04 00:01:33 +00:00
|
|
|
if (def->domain) {
|
|
|
|
virBufferAsprintf(buf, "<domain name='%s'", def->domain);
|
|
|
|
|
|
|
|
/* default to "no", but don't format it in the XML */
|
|
|
|
if (def->domainLocalOnly) {
|
|
|
|
const char *local = virTristateBoolTypeToString(def->domainLocalOnly);
|
|
|
|
|
|
|
|
if (!local) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unknown localOnly type %d in network"),
|
|
|
|
def->domainLocalOnly);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
virBufferAsprintf(buf, " localOnly='%s'", local);
|
|
|
|
}
|
|
|
|
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
|
|
|
}
|
2009-07-02 14:02:18 +00:00
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
if (virNetworkDNSDefFormat(buf, &def->dns) < 0)
|
2011-06-24 10:04:36 +00:00
|
|
|
goto error;
|
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
|
2012-08-12 07:51:30 +00:00
|
|
|
goto error;
|
2019-05-14 14:44:55 +00:00
|
|
|
if (virNetDevBandwidthFormat(def->bandwidth, 0, buf) < 0)
|
2011-07-22 14:07:26 +00:00
|
|
|
goto error;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->nips; i++) {
|
2016-06-08 16:48:50 +00:00
|
|
|
if (virNetworkIPDefFormat(buf, &def->ips[i]) < 0)
|
2010-11-17 18:36:19 +00:00
|
|
|
goto error;
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->nroutes; i++) {
|
2016-06-14 17:40:04 +00:00
|
|
|
if (virNetDevIPRouteFormat(buf, def->routes[i]) < 0)
|
Support for static routes on a virtual bridge
network: static route support for <network>
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
These attributes are translated into an "ip route add" command that is
executed when the network is started. The command used is of the
following form:
ip route add <address>/<prefix> via <gateway> \
dev <virbr-bridge> proto static metric <metric>
Tests are done to validate that the input data are correct. For
example, for a static route ip definition, the address must be a
network address and not a host address. Additional checks are added
to ensure that the specified gateway is directly reachable via this
network (i.e. that the gateway IP address is in the same subnet as one
of the IP's defined for the network).
prefix='0' is supported for both family='ipv4' address='0.0.0.0'
netmask='0.0.0.0' or prefix='0', and for family='ipv6' address='::',
prefix=0', although care should be taken to not override a desired
system default route.
Anytime an attempt is made to define a static route which *exactly*
duplicates an existing static route (for example, address=::,
prefix=0, metric=1), the following error message will be sent to
syslog:
RTNETLINK answers: File exists
This can be overridden by decreasing the metric value for the route
that should be preferred, or increasing the metric for the route that
shouldn't be preferred (and is thus in place only in anticipation that
the preferred route may be removed in the future). Caution should be
used when manipulating route metrics, especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exercise for another day.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
Signed-off-by: Laine Stump <laine@laine.org>
2013-05-07 17:42:55 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
|
2011-11-02 14:53:35 +00:00
|
|
|
goto error;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->nPortGroups; i++)
|
|
|
|
if (virPortGroupDefFormat(buf, &def->portGroups[i]) < 0)
|
2011-11-02 14:53:35 +00:00
|
|
|
goto error;
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAdjustIndent(buf, -2);
|
|
|
|
virBufferAddLit(buf, "</network>\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
error:
|
2012-11-18 15:59:21 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
char *
|
maint: avoid 'const fooPtr' in conf
'const fooPtr' is the same as 'foo * const' (the pointer won't
change, but it's contents can). But in general, if an interface
is trying to be const-correct, it should be using 'const foo *'
(the pointer is to data that can't be changed).
Fix up remaining offenders in src/conf, and their fallout.
* src/conf/snapshot_conf.h (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Drop attempt at const.
* src/conf/interface_conf.h (virInterfaceObjIsActive)
(virInterfaceDefFormat): Use intended type.
(virInterfaceFindByMACString, virInterfaceFindByName)
(virInterfaceAssignDef, virInterfaceRemove): Drop attempt at
const.
* src/conf/network_conf.h (virNetworkObjIsActive)
(virNetworkDefFormat, virNetworkDefForwardIf)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask): Use intended type.
(virNetworkFindByUUID, virNetworkFindByName, virNetworkAssignDef)
(virNetworkObjAssignDef, virNetworkRemoveInactive)
(virNetworkBridgeInUse, virNetworkSetBridgeName)
(virNetworkAllocateBridge): Drop attempt at const.
* src/conf/netdev_vlan_conf.h (virNetDevVlanFormat): Make
const-correct.
* src/conf/node_device_conf.h (virNodeDeviceHasCap)
(virNodeDeviceDefFormat): Use intended type.
(virNodeDeviceFindByName, virNodeDeviceFindBySysfsPath)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceGetParentHost): Drop attempt at const.
* src/conf/secret_conf.h (virSecretDefFormat): Use intended type.
* src/conf/snapshot_conf.c (virDomainSnapshotAssignDef)
(virDomainSnapshotFindByName): Fix fallout.
* src/conf/interface_conf.c (virInterfaceBridgeDefFormat)
(virInterfaceBondDefFormat, virInterfaceVlanDefFormat)
(virInterfaceProtocolDefFormat, virInterfaceDefDevFormat)
(virInterfaceDefFormat, virInterfaceFindByMACString)
(virInterfaceFindByName, virInterfaceAssignDef)
(virInterfaceRemove): Likewise.
* src/conf/network_conf.c
(VIR_ENUM_IMPL, virNetworkFindByName, virNetworkObjAssignDef)
(virNetworkAssignDef, virNetworkRemoveInactive)
(virNetworkDefGetIpByIndex, virNetworkIpDefPrefix)
(virNetworkIpDefNetmask, virNetworkDHCPHostDefParseXML)
(virNetworkIpDefFormat, virNetworkRouteDefFormat)
(virPortGroupDefFormat, virNetworkForwardNatDefFormat)
(virNetworkDefFormatInternal, virNetworkBridgeInUse)
(virNetworkAllocateBridge, virNetworkSetBridgeName)
(virNetworkDNSDefFormat, virNetworkDefFormat): Likewise.
* src/conf/netdev_vlan_conf.c (virNetDevVlanFormat): Likewise.
* src/conf/node_device_conf.c (virNodeDeviceHasCap)
(virNodeDeviceFindBySysfsPath, virNodeDeviceFindByName)
(virNodeDeviceAssignDef, virNodeDeviceObjRemove)
(virNodeDeviceDefFormat, virNodeDeviceGetParentHost): Likewise.
* src/conf/secret_conf.c (virSecretDefFormatUsage)
(virSecretDefFormat): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-10-08 16:36:37 +00:00
|
|
|
virNetworkDefFormat(const virNetworkDef *def,
|
2019-07-14 16:15:12 +00:00
|
|
|
virNetworkXMLOptionPtr xmlopt,
|
2012-11-18 15:59:21 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
|
2019-07-14 16:15:12 +00:00
|
|
|
if (virNetworkDefFormatBuf(&buf, def, xmlopt, flags) < 0)
|
2012-11-18 15:59:21 +00:00
|
|
|
goto error;
|
|
|
|
|
2014-06-27 08:40:15 +00:00
|
|
|
if (virBufferCheckError(&buf) < 0)
|
|
|
|
goto error;
|
2012-11-18 15:59:21 +00:00
|
|
|
|
|
|
|
return virBufferContentAndReset(&buf);
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
error:
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferFreeAndReset(&buf);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2016-03-03 07:14:37 +00:00
|
|
|
const char *
|
2017-03-08 15:41:57 +00:00
|
|
|
virNetworkDefForwardIf(const virNetworkDef *def,
|
|
|
|
size_t n)
|
2016-03-03 07:14:37 +00:00
|
|
|
{
|
|
|
|
return ((def->forward.ifs && (def->forward.nifs > n) &&
|
|
|
|
def->forward.ifs[n].type == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV)
|
|
|
|
? def->forward.ifs[n].device.dev : NULL);
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
|
|
|
virPortGroupDefPtr
|
|
|
|
virPortGroupFindByName(virNetworkDefPtr net,
|
|
|
|
const char *portgroup)
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
for (i = 0; i < net->nPortGroups; i++) {
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
if (portgroup) {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (STREQ(portgroup, net->portGroups[i].name))
|
|
|
|
return &net->portGroups[i];
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
} else {
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (net->portGroups[i].isDefault)
|
|
|
|
return &net->portGroups[i];
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
virNetworkSaveXML(const char *configDir,
|
|
|
|
virNetworkDefPtr def,
|
|
|
|
const char *xml)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
2012-10-29 12:15:55 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
2009-01-20 22:36:10 +00:00
|
|
|
char *configFile = NULL;
|
2011-10-27 16:55:47 +00:00
|
|
|
int ret = -1;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
if ((configFile = virNetworkConfigFile(configDir, def->name)) == NULL)
|
2008-07-11 10:48:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2011-07-05 21:02:53 +00:00
|
|
|
if (virFileMakePath(configDir) < 0) {
|
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("cannot create config directory '%s'"),
|
|
|
|
configDir);
|
2008-07-11 10:48:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-10-29 12:15:55 +00:00
|
|
|
virUUIDFormat(def->uuid, uuidstr);
|
|
|
|
ret = virXMLSaveFile(configFile,
|
|
|
|
virXMLPickShellSafeComment(def->name, uuidstr),
|
|
|
|
"net-edit", xml);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
cleanup:
|
2009-01-20 22:36:10 +00:00
|
|
|
VIR_FREE(configFile);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
virNetworkSaveConfig(const char *configDir,
|
2019-07-14 16:15:12 +00:00
|
|
|
virNetworkDefPtr def,
|
|
|
|
virNetworkXMLOptionPtr xmlopt)
|
2009-01-20 22:36:10 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
char *xml;
|
|
|
|
|
2019-07-14 16:15:12 +00:00
|
|
|
if (!(xml = virNetworkDefFormat(def, xmlopt, VIR_NETWORK_XML_INACTIVE)))
|
2009-01-20 22:36:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
if (virNetworkSaveXML(configDir, def, xml))
|
2009-01-20 22:36:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2009-01-20 22:36:10 +00:00
|
|
|
VIR_FREE(xml);
|
2008-07-11 10:48:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
|
|
|
char *
|
|
|
|
virNetworkConfigFile(const char *dir,
|
|
|
|
const char *name)
|
2012-09-14 15:35:35 +00:00
|
|
|
{
|
2017-03-08 15:25:24 +00:00
|
|
|
char *ret = NULL;
|
2009-01-20 22:36:10 +00:00
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
ignore_value(virAsprintf(&ret, "%s/%s.xml", dir, name));
|
2009-01-20 22:36:10 +00:00
|
|
|
return ret;
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
2008-12-04 20:53:20 +00:00
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
virNetworkSetBridgeMacAddr(virNetworkDefPtr def)
|
Give each virtual network bridge its own fixed MAC address
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=609463
The problem was that, since a bridge always acquires the MAC address
of the connected interface with the numerically lowest MAC, as guests
are started and stopped, it was possible for the MAC address to change
over time, and this change in the network was being detected by
Windows 7 (it sees the MAC of the default route change), so on each
reboot it would bring up a dialog box asking about this "new network".
The solution is to create a dummy tap interface with a MAC guaranteed
to be lower than any guest interface's MAC, and attach that tap to the
bridge as soon as it's created. Since all guest MAC addresses start
with 0xFE, we can just generate a MAC with the standard "0x52, 0x54,
0" prefix, and it's guaranteed to always win (physical interfaces are
never connected to these bridges, so we don't need to worry about
competing numerically with them).
Note that the dummy tap is never set to IFF_UP state - that's not
necessary in order for the bridge to take its MAC, and not setting it
to UP eliminates the clutter of having an (eg) "virbr0-nic" displayed
in the output of the ifconfig command.
I chose to not auto-generate the MAC address in the network XML
parser, as there are likely to be consumers of that API that don't
need or want to have a MAC address associated with the
bridge.
Instead, in bridge_driver.c when the network is being defined, if
there is no MAC, one is generated. To account for virtual network
configs that already exist when upgrading from an older version of
libvirt, I've added a %post script to the specfile that searches for
all network definitions in both the config directory
(/etc/libvirt/qemu/networks) and the state directory
(/var/lib/libvirt/network) that are missing a mac address, generates a
random address, and adds it to the config (and a matching address to
the state file, if there is one).
docs/formatnetwork.html.in: document <mac address.../>
docs/schemas/network.rng: add nac address to schema
libvirt.spec.in: %post script to update existing networks
src/conf/network_conf.[ch]: parse and format <mac address.../>
src/libvirt_private.syms: export a couple private symbols we need
src/network/bridge_driver.c:
auto-generate mac address when needed,
create dummy interface if mac address is present.
tests/networkxml2xmlin/isolated-network.xml
tests/networkxml2xmlin/routed-network.xml
tests/networkxml2xmlout/isolated-network.xml
tests/networkxml2xmlout/routed-network.xml: add mac address to some tests
2011-02-09 08:28:12 +00:00
|
|
|
{
|
|
|
|
if (!def->mac_specified) {
|
|
|
|
/* if the bridge doesn't have a mac address explicitly defined,
|
|
|
|
* autogenerate a random one.
|
|
|
|
*/
|
2012-01-27 16:48:38 +00:00
|
|
|
virMacAddrGenerate((unsigned char[]){ 0x52, 0x54, 0 },
|
2012-07-17 12:07:59 +00:00
|
|
|
&def->mac);
|
Give each virtual network bridge its own fixed MAC address
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=609463
The problem was that, since a bridge always acquires the MAC address
of the connected interface with the numerically lowest MAC, as guests
are started and stopped, it was possible for the MAC address to change
over time, and this change in the network was being detected by
Windows 7 (it sees the MAC of the default route change), so on each
reboot it would bring up a dialog box asking about this "new network".
The solution is to create a dummy tap interface with a MAC guaranteed
to be lower than any guest interface's MAC, and attach that tap to the
bridge as soon as it's created. Since all guest MAC addresses start
with 0xFE, we can just generate a MAC with the standard "0x52, 0x54,
0" prefix, and it's guaranteed to always win (physical interfaces are
never connected to these bridges, so we don't need to worry about
competing numerically with them).
Note that the dummy tap is never set to IFF_UP state - that's not
necessary in order for the bridge to take its MAC, and not setting it
to UP eliminates the clutter of having an (eg) "virbr0-nic" displayed
in the output of the ifconfig command.
I chose to not auto-generate the MAC address in the network XML
parser, as there are likely to be consumers of that API that don't
need or want to have a MAC address associated with the
bridge.
Instead, in bridge_driver.c when the network is being defined, if
there is no MAC, one is generated. To account for virtual network
configs that already exist when upgrading from an older version of
libvirt, I've added a %post script to the specfile that searches for
all network definitions in both the config directory
(/etc/libvirt/qemu/networks) and the state directory
(/var/lib/libvirt/network) that are missing a mac address, generates a
random address, and adds it to the config (and a matching address to
the state file, if there is one).
docs/formatnetwork.html.in: document <mac address.../>
docs/schemas/network.rng: add nac address to schema
libvirt.spec.in: %post script to update existing networks
src/conf/network_conf.[ch]: parse and format <mac address.../>
src/libvirt_private.syms: export a couple private symbols we need
src/network/bridge_driver.c:
auto-generate mac address when needed,
create dummy interface if mac address is present.
tests/networkxml2xmlin/isolated-network.xml
tests/networkxml2xmlin/routed-network.xml
tests/networkxml2xmlout/isolated-network.xml
tests/networkxml2xmlout/routed-network.xml: add mac address to some tests
2011-02-09 08:28:12 +00:00
|
|
|
def->mac_specified = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
/* NetworkObj backend of the virNetworkUpdate API */
|
|
|
|
|
|
|
|
static void
|
|
|
|
virNetworkDefUpdateNoSupport(virNetworkDefPtr def, const char *section)
|
|
|
|
{
|
2016-04-19 18:48:30 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
2012-09-14 19:14:57 +00:00
|
|
|
_("can't update '%s' section of network '%s'"),
|
|
|
|
section, def->name);
|
|
|
|
}
|
2017-03-08 15:25:24 +00:00
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-21 16:11:51 +00:00
|
|
|
static void
|
|
|
|
virNetworkDefUpdateUnknownCommand(unsigned int command)
|
|
|
|
{
|
2016-04-19 18:48:30 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
2012-09-21 16:11:51 +00:00
|
|
|
_("unrecognized network update command code %d"), command);
|
|
|
|
}
|
2012-09-14 19:14:57 +00:00
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateCheckElementName(virNetworkDefPtr def,
|
|
|
|
xmlNodePtr node,
|
|
|
|
const char *section)
|
|
|
|
{
|
2017-08-14 12:31:52 +00:00
|
|
|
if (!virXMLNodeNameEqual(node, section)) {
|
2012-09-14 19:14:57 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("unexpected element <%s>, expecting <%s>, "
|
|
|
|
"while updating network '%s'"),
|
|
|
|
node->name, section, def->name);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateBridge(virNetworkDefPtr def,
|
|
|
|
unsigned int command ATTRIBUTE_UNUSED,
|
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
|
|
|
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virNetworkDefUpdateNoSupport(def, "bridge");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateDomain(virNetworkDefPtr def,
|
|
|
|
unsigned int command ATTRIBUTE_UNUSED,
|
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
|
|
|
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virNetworkDefUpdateNoSupport(def, "domain");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateIP(virNetworkDefPtr def,
|
|
|
|
unsigned int command ATTRIBUTE_UNUSED,
|
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
|
|
|
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virNetworkDefUpdateNoSupport(def, "ip");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2016-06-08 16:48:50 +00:00
|
|
|
static virNetworkIPDefPtr
|
|
|
|
virNetworkIPDefByIndex(virNetworkDefPtr def, int parentIndex)
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
{
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr ipdef = NULL;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
|
|
|
|
/* first find which ip element's dhcp host list to work on */
|
|
|
|
if (parentIndex >= 0) {
|
2016-06-08 16:48:50 +00:00
|
|
|
ipdef = virNetworkDefGetIPByIndex(def, AF_UNSPEC, parentIndex);
|
2012-12-06 17:20:38 +00:00
|
|
|
if (!(ipdef)) {
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
2012-12-06 17:20:38 +00:00
|
|
|
_("couldn't update dhcp host entry - no <ip> "
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
"element found at index %d in network '%s'"),
|
|
|
|
parentIndex, def->name);
|
|
|
|
}
|
|
|
|
return ipdef;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* -1 means "find the most appropriate", which in this case
|
|
|
|
* means the one and only <ip> that has <dhcp> element
|
|
|
|
*/
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0;
|
2016-06-08 16:48:50 +00:00
|
|
|
(ipdef = virNetworkDefGetIPByIndex(def, AF_UNSPEC, i));
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
i++) {
|
2012-12-06 17:20:38 +00:00
|
|
|
if (ipdef->nranges || ipdef->nhosts)
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-12-06 17:20:38 +00:00
|
|
|
if (!ipdef) {
|
2016-06-08 16:48:50 +00:00
|
|
|
ipdef = virNetworkDefGetIPByIndex(def, AF_INET, 0);
|
2012-12-06 17:20:38 +00:00
|
|
|
if (!ipdef)
|
2016-06-08 16:48:50 +00:00
|
|
|
ipdef = virNetworkDefGetIPByIndex(def, AF_INET6, 0);
|
2012-12-06 17:20:38 +00:00
|
|
|
}
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
if (!ipdef) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
2012-12-06 17:20:38 +00:00
|
|
|
_("couldn't update dhcp host entry - no <ip> "
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
"element found in network '%s'"), def->name);
|
|
|
|
}
|
|
|
|
return ipdef;
|
|
|
|
}
|
|
|
|
|
2014-12-04 21:07:36 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
virNetworkDefUpdateCheckMultiDHCP(virNetworkDefPtr def,
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr ipdef)
|
2014-12-04 21:07:36 +00:00
|
|
|
{
|
|
|
|
int family = VIR_SOCKET_ADDR_FAMILY(&ipdef->address);
|
|
|
|
size_t i;
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr ip;
|
2014-12-04 21:07:36 +00:00
|
|
|
|
2016-06-08 16:48:50 +00:00
|
|
|
for (i = 0; (ip = virNetworkDefGetIPByIndex(def, family, i)); i++) {
|
2014-12-04 21:07:36 +00:00
|
|
|
if (ip != ipdef) {
|
|
|
|
if (ip->nranges || ip->nhosts) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("dhcp is supported only for a "
|
|
|
|
"single %s address on each network"),
|
|
|
|
(family == AF_INET) ? "IPv4" : "IPv6");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def,
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
unsigned int command,
|
|
|
|
int parentIndex,
|
|
|
|
xmlXPathContextPtr ctxt,
|
2012-09-14 19:14:57 +00:00
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int ret = -1;
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr ipdef = virNetworkIPDefByIndex(def, parentIndex);
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
virNetworkDHCPHostDef host;
|
2013-07-31 11:25:59 +00:00
|
|
|
bool partialOkay = (command == VIR_NETWORK_UPDATE_COMMAND_DELETE);
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
|
|
|
|
memset(&host, 0, sizeof(host));
|
|
|
|
|
|
|
|
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* ipdef is the ip element that needs its host array updated */
|
|
|
|
if (!ipdef)
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-31 11:25:59 +00:00
|
|
|
if (virNetworkDHCPHostDefParseXML(def->name, ipdef, ctxt->node,
|
|
|
|
&host, partialOkay) < 0)
|
|
|
|
goto cleanup;
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
|
2015-01-19 22:04:01 +00:00
|
|
|
if (!partialOkay &&
|
|
|
|
VIR_SOCKET_ADDR_FAMILY(&ipdef->address)
|
|
|
|
!= VIR_SOCKET_ADDR_FAMILY(&host.ip)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("the address family of a host entry IP must match "
|
|
|
|
"the address family of the dhcp element's parent"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-07-31 11:25:59 +00:00
|
|
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
|
2014-07-08 16:27:55 +00:00
|
|
|
/* search for the entry with this (ip|mac|name),
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
* and update the IP+(mac|name) */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < ipdef->nhosts; i++) {
|
2015-01-15 14:42:04 +00:00
|
|
|
if ((host.mac && ipdef->hosts[i].mac &&
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
!virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
|
2014-07-08 16:27:55 +00:00
|
|
|
(VIR_SOCKET_ADDR_VALID(&host.ip) &&
|
|
|
|
virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
(host.name &&
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (i == ipdef->nhosts) {
|
2014-07-08 16:27:55 +00:00
|
|
|
char *ip = virSocketAddrFormat(&host.ip);
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("couldn't locate an existing dhcp host entry with "
|
2014-07-08 16:27:55 +00:00
|
|
|
"\"mac='%s'\" \"name='%s'\" \"ip='%s'\" in"
|
|
|
|
" network '%s'"),
|
|
|
|
host.mac ? host.mac : _("unknown"), host.name,
|
|
|
|
ip ? ip : _("unknown"), def->name);
|
|
|
|
VIR_FREE(ip);
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear the existing hosts entry, move the new one in its place,
|
|
|
|
* then clear out the extra copy to get rid of the duplicate pointers
|
|
|
|
* to its data (mac and name strings).
|
|
|
|
*/
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virNetworkDHCPHostDefClear(&ipdef->hosts[i]);
|
|
|
|
ipdef->hosts[i] = host;
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
memset(&host, 0, sizeof(host));
|
|
|
|
|
|
|
|
} else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
|
|
|
|
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) {
|
|
|
|
|
2014-12-04 21:07:36 +00:00
|
|
|
if (virNetworkDefUpdateCheckMultiDHCP(def, ipdef) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
/* log error if an entry with same name/address/ip already exists */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < ipdef->nhosts; i++) {
|
2015-01-15 14:42:04 +00:00
|
|
|
if ((host.mac && ipdef->hosts[i].mac &&
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
!virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
(host.name &&
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) ||
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
(VIR_SOCKET_ADDR_VALID(&host.ip) &&
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
char *ip = virSocketAddrFormat(&host.ip);
|
|
|
|
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("there is an existing dhcp host entry in "
|
|
|
|
"network '%s' that matches "
|
|
|
|
"\"<host mac='%s' name='%s' ip='%s'/>\""),
|
2014-07-08 16:27:55 +00:00
|
|
|
def->name, host.mac ? host.mac : _("unknown"),
|
|
|
|
host.name, ip ? ip : _("unknown"));
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
VIR_FREE(ip);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2012-10-08 17:42:21 +00:00
|
|
|
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
/* add to beginning/end of list */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_INSERT_ELEMENT(ipdef->hosts,
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
|
|
|
|
? 0 : ipdef->nhosts,
|
|
|
|
ipdef->nhosts, host) < 0)
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
|
|
|
|
|
|
|
|
/* find matching entry - all specified attributes must match */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < ipdef->nhosts; i++) {
|
2015-01-15 14:42:04 +00:00
|
|
|
if ((!host.mac || !ipdef->hosts[i].mac ||
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
!virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
(!host.name ||
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
(!VIR_SOCKET_ADDR_VALID(&host.ip) ||
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (i == ipdef->nhosts) {
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("couldn't locate a matching dhcp host entry "
|
|
|
|
"in network '%s'"), def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove it */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virNetworkDHCPHostDefClear(&ipdef->hosts[i]);
|
|
|
|
VIR_DELETE_ELEMENT(ipdef->hosts, i, ipdef->nhosts);
|
2012-10-08 17:42:21 +00:00
|
|
|
|
2012-09-21 16:11:51 +00:00
|
|
|
} else {
|
|
|
|
virNetworkDefUpdateUnknownCommand(command);
|
|
|
|
goto cleanup;
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
network: implement backend of virNetworkUpdate(IP_DHCP_HOST)
This patch fills in the first implementation for one of the
virNetworkUpdate sections. With this code, you can now add/delete/edit
<host> entries in a network's <ip> address <dhcp> element (by
specifying a section of VIR_NETWORK_SECTION_IP_DHCP_HOST).
If you pass in a parentIndex of -1, the code will automatically find
the one ip element that has a <dhcp> section and make the updates
there. Otherwise, you can specify an index >= 0, and libvirt will look
for that particular instance of <ip> in the network, and modify its
<dhcp> element. (This currently isn't very useful, because libvirt
only supports having dhcp information on a single IP address, but that
could change in the future).
When adding a new host entry
(VIR_NETWORK_UPDATE_COMMAND_ADD_(FIRST|LAST)), the existing entries
will be compared to the new entry, and if any non-empty attribute
matches, the add will fail. When updating an existing entry
(VIR_NETWORK_UPDATE_COMMAND_MODIFY), the mac address or name will be
used to find the existing entry, and other fields will only be updated
(note there is some potential for ambiguity here if you specify the
mac address from one entry and the name from another). When deleting
an existing entry (VIR_NETWORK_UPDATE_COMMAND_DELETE), all non-empty
attributes in the supplied xml arg will be compared - all of them must
match before libvirt will delete the host.
The xml should be a fully formed <host> element as it would appear in
a network definition, e.g. "<host mac=00:11:22:33:44:55 ip=10.1.23.22
name='testbox'/>" (when adding/updating, ip and one of mac|name is
required; when deleting, you can specify any one, two, or all
attributes, but they all must match the target element).
As with the update of any other section, you can choose to affect the
live config (with flag VIR_NETWORK_UPDATE_AFFECT_LIVE), the persistent
config (VIR_NETWORK_UPDATE_AFFECT_CONFIG), or both. If you've chosen
to affect the live config, those changes will take effect immediately,
with no need to destroy/restart the network.
An example of adding a host entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_ADD_LAST,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
To delete that same entry:
virNetworkUpdate(net, VIR_NETWORK_UPDATE_COMMAND_DELETE,
VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
"<host mac='00:11:22:33:44:55'/>",
VIR_NETWORK_UPDATE_AFFECT_LIVE
| VIR_NETWORK_UPDATE_AFFECT_CONFIG);
(you could also delete it by replacing "mac='00:11:22:33:44:55'" with
"ip='192.168.122.5'".)
2012-09-17 21:03:11 +00:00
|
|
|
virNetworkDHCPHostDefClear(&host);
|
|
|
|
return ret;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
unsigned int command,
|
2013-07-31 07:42:58 +00:00
|
|
|
int parentIndex,
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
2012-09-14 19:14:57 +00:00
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int ret = -1;
|
2016-06-08 16:48:50 +00:00
|
|
|
virNetworkIPDefPtr ipdef = virNetworkIPDefByIndex(def, parentIndex);
|
2013-02-19 10:44:16 +00:00
|
|
|
virSocketAddrRange range;
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
|
|
|
|
memset(&range, 0, sizeof(range));
|
|
|
|
|
|
|
|
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "range") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* ipdef is the ip element that needs its range array updated */
|
|
|
|
if (!ipdef)
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-02-19 10:44:16 +00:00
|
|
|
/* parse the xml into a virSocketAddrRange */
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
|
|
|
|
2016-04-19 18:48:30 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
_("dhcp ranges cannot be modified, "
|
|
|
|
"only added or deleted"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2015-05-22 21:32:02 +00:00
|
|
|
if (virSocketAddrRangeParseXML(def->name, ipdef, ctxt->node, &range) < 0)
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2015-01-19 22:04:01 +00:00
|
|
|
if (VIR_SOCKET_ADDR_FAMILY(&ipdef->address)
|
|
|
|
!= VIR_SOCKET_ADDR_FAMILY(&range.start)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("the address family of a dhcp range must match "
|
|
|
|
"the address family of the dhcp element's parent"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
/* check if an entry with same name/address/ip already exists */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < ipdef->nranges; i++) {
|
|
|
|
if (virSocketAddrEqual(&range.start, &ipdef->ranges[i].start) &&
|
|
|
|
virSocketAddrEqual(&range.end, &ipdef->ranges[i].end)) {
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
|
|
|
|
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) {
|
|
|
|
|
2014-12-04 21:07:36 +00:00
|
|
|
if (virNetworkDefUpdateCheckMultiDHCP(def, ipdef) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (i < ipdef->nranges) {
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
char *startip = virSocketAddrFormat(&range.start);
|
|
|
|
char *endip = virSocketAddrFormat(&range.end);
|
|
|
|
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("there is an existing dhcp range entry in "
|
|
|
|
"network '%s' that matches "
|
|
|
|
"\"<range start='%s' end='%s'/>\""),
|
|
|
|
def->name,
|
|
|
|
startip ? startip : "unknown",
|
|
|
|
endip ? endip : "unknown");
|
2014-08-27 18:57:53 +00:00
|
|
|
VIR_FREE(startip);
|
|
|
|
VIR_FREE(endip);
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add to beginning/end of list */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_INSERT_ELEMENT(ipdef->ranges,
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
|
|
|
|
? 0 : ipdef->nranges,
|
|
|
|
ipdef->nranges, range) < 0)
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (i == ipdef->nranges) {
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("couldn't locate a matching dhcp range entry "
|
|
|
|
"in network '%s'"), def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove it */
|
|
|
|
/* NB: nothing to clear from a RangeDef that's being freed */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DELETE_ELEMENT(ipdef->ranges, i, ipdef->nranges);
|
2012-10-08 17:42:21 +00:00
|
|
|
|
2012-09-21 16:11:51 +00:00
|
|
|
} else {
|
|
|
|
virNetworkDefUpdateUnknownCommand(command);
|
|
|
|
goto cleanup;
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a
network's <ip> elements. There can be multiple <range>
elements. Because there are only two attributes (start and end), and
those are exactly what you would use to identify a particular range,
it doesn't really make sense to modify an existing element, so
VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section,
only ADD_FIRST, ADD_LAST, and DELETE.
Since virsh already has support for understanding all the defined
sections, this new backend is automatically supported by virsh. You
would use it like this:
virsh net-update mynet add ip-dhcp-range \
"<range start='1.2.3.4' end='1.2.3.20'/>" --live --config
The bridge driver also already supports all sections, so it's doing
the correct thing in this case as well - since the dhcp range is
placed on the dnsmasq commandline, the bridge driver recreates the
dnsmasq commandline, and re-runs dnsmasq whenever a range is
added/deleted (and AFFECT_LIVE is specified in the flags).
2012-09-21 02:25:40 +00:00
|
|
|
return ret;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateForward(virNetworkDefPtr def,
|
|
|
|
unsigned int command ATTRIBUTE_UNUSED,
|
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
|
|
|
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virNetworkDefUpdateNoSupport(def, "forward");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateForwardInterface(virNetworkDefPtr def,
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
unsigned int command,
|
2012-09-14 19:14:57 +00:00
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
2012-09-14 19:14:57 +00:00
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int ret = -1;
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
virNetworkForwardIfDef iface;
|
|
|
|
|
|
|
|
memset(&iface, 0, sizeof(iface));
|
|
|
|
|
|
|
|
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "interface") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
2016-04-19 18:48:30 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
_("forward interface entries cannot be modified, "
|
|
|
|
"only added or deleted"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* parsing this is so simple that it doesn't have its own function */
|
|
|
|
iface.type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
|
|
|
|
if (!(iface.device.dev = virXMLPropString(ctxt->node, "dev"))) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
|
_("missing dev attribute in <interface> element"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check if an <interface> with same dev name already exists */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->forward.nifs; i++) {
|
|
|
|
if (def->forward.ifs[i].type
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
== VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV &&
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
STREQ(iface.device.dev, def->forward.ifs[i].device.dev))
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
|
|
|
|
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) {
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (i < def->forward.nifs) {
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("there is an existing interface entry "
|
|
|
|
"in network '%s' that matches "
|
|
|
|
"\"<interface dev='%s'>\""),
|
|
|
|
def->name, iface.device.dev);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add to beginning/end of list */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_INSERT_ELEMENT(def->forward.ifs,
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
|
|
|
|
? 0 : def->forward.nifs,
|
|
|
|
def->forward.nifs, iface) < 0)
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (i == def->forward.nifs) {
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("couldn't find an interface entry "
|
|
|
|
"in network '%s' matching <interface dev='%s'>"),
|
|
|
|
def->name, iface.device.dev);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fail if the interface is being used */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (def->forward.ifs[i].connections > 0) {
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("unable to delete interface '%s' "
|
|
|
|
"in network '%s'. It is currently being used "
|
|
|
|
" by %d domains."),
|
|
|
|
iface.device.dev, def->name,
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
def->forward.ifs[i].connections);
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove it */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virNetworkForwardIfDefClear(&def->forward.ifs[i]);
|
|
|
|
VIR_DELETE_ELEMENT(def->forward.ifs, i, def->forward.nifs);
|
2012-10-08 17:42:21 +00:00
|
|
|
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
} else {
|
|
|
|
virNetworkDefUpdateUnknownCommand(command);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
network: backend for virNetworkUpdate of interface list
<interface> elements are location inside the <forward> element of a
network. There is only one <forward> element in any network, but it
might have many <interface> elements. This element only contains a
single attribute, "dev", which is the name of a network device
(e.g. "eth0").
Since there is only a single attribute, the modify operation isn't
supported for this "section", only add-first, add-last, and
delete. Also, note that it's not permitted to delete an interface from
the list while any guest is using it. We may later decide this is safe
(because removing it from the list really only excludes it from
consideration in future guest allocations of interfaces, but doesn't
affect any guests currently connected), but for now this limitation
seems prudent (of course when changing the persistent config, this
limitation doesn't apply, because the persistent config doesn't
support the concept of "in used").
Another limitation - it is also possible for the interfraces in this
list to be described by PCI address rather than netdev name. However,
I noticed while writing this function that we currently don't support
defining interfaces that way in config - the only method of getting
interfaces specified as <adress type='pci' ..../> instead of
<interface dev='xx'/> is to provide a <pf dev='yy'/> element under
forward, and let the entries in the interface list be automatically
populated with the virtual functions (VF) of the physical function
device given in <pg>.
As with the other virNetworkUpdate section backends, support for this
section is completely contained within a single static function, no
other changes were required, and only functions already called from
elsewhere within the same file are used in the new content for this
existing function (i.e., adding this code should not cause a new build
problem on any platform).
2012-09-21 16:50:53 +00:00
|
|
|
virNetworkForwardIfDefClear(&iface);
|
|
|
|
return ret;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateForwardPF(virNetworkDefPtr def,
|
|
|
|
unsigned int command ATTRIBUTE_UNUSED,
|
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
|
|
|
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virNetworkDefUpdateNoSupport(def, "forward pf");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
virNetworkDefUpdatePortGroup(virNetworkDefPtr def,
|
|
|
|
unsigned int command,
|
2012-09-14 19:14:57 +00:00
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
2012-09-14 19:14:57 +00:00
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int foundName = -1, foundDefault = -1;
|
2012-10-20 08:39:18 +00:00
|
|
|
int ret = -1;
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
virPortGroupDef portgroup;
|
|
|
|
|
|
|
|
memset(&portgroup, 0, sizeof(portgroup));
|
|
|
|
|
|
|
|
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "portgroup") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virNetworkPortGroupParseXML(&portgroup, ctxt->node, ctxt) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* check if a portgroup with same name already exists */
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < def->nPortGroups; i++) {
|
|
|
|
if (STREQ(portgroup.name, def->portGroups[i].name))
|
|
|
|
foundName = i;
|
|
|
|
if (def->portGroups[i].isDefault)
|
|
|
|
foundDefault = i;
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
}
|
2012-10-20 08:39:18 +00:00
|
|
|
if (foundName == -1 &&
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
((command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) ||
|
|
|
|
(command == VIR_NETWORK_UPDATE_COMMAND_DELETE))) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("couldn't find a portgroup entry "
|
|
|
|
"in network '%s' matching <portgroup name='%s'>"),
|
|
|
|
def->name, portgroup.name);
|
|
|
|
goto cleanup;
|
2012-10-20 08:39:18 +00:00
|
|
|
} else if (foundName >= 0 &&
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
|
|
|
|
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST))) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("there is an existing portgroup entry in "
|
|
|
|
"network '%s' that matches "
|
|
|
|
"\"<portgroup name='%s'>\""),
|
|
|
|
def->name, portgroup.name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-10-20 08:39:18 +00:00
|
|
|
/* if there is already a different default, we can't make this
|
|
|
|
* one the default.
|
|
|
|
*/
|
|
|
|
if (command != VIR_NETWORK_UPDATE_COMMAND_DELETE &&
|
|
|
|
portgroup.isDefault &&
|
|
|
|
foundDefault >= 0 && foundDefault != foundName) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("a different portgroup entry in "
|
|
|
|
"network '%s' is already set as the default. "
|
|
|
|
"Only one default is allowed."),
|
|
|
|
def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
|
|
|
|
|
|
|
/* replace existing entry */
|
2012-10-20 08:39:18 +00:00
|
|
|
virPortGroupDefClear(&def->portGroups[foundName]);
|
|
|
|
def->portGroups[foundName] = portgroup;
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
memset(&portgroup, 0, sizeof(portgroup));
|
|
|
|
|
|
|
|
} else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
|
|
|
|
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) {
|
|
|
|
|
|
|
|
/* add to beginning/end of list */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_INSERT_ELEMENT(def->portGroups,
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
|
|
|
|
? 0 : def->nPortGroups,
|
|
|
|
def->nPortGroups, portgroup) < 0)
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
|
|
|
|
|
|
|
|
/* remove it */
|
2012-10-20 08:39:18 +00:00
|
|
|
virPortGroupDefClear(&def->portGroups[foundName]);
|
2012-10-08 17:42:21 +00:00
|
|
|
VIR_DELETE_ELEMENT(def->portGroups, foundName, def->nPortGroups);
|
|
|
|
|
2012-09-21 16:11:51 +00:00
|
|
|
} else {
|
|
|
|
virNetworkDefUpdateUnknownCommand(command);
|
|
|
|
goto cleanup;
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
virPortGroupDefClear(&portgroup);
|
|
|
|
return ret;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefUpdateDNSHost(virNetworkDefPtr def,
|
|
|
|
unsigned int command ATTRIBUTE_UNUSED,
|
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
|
|
|
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i, j, k;
|
|
|
|
int foundIdx = -1, ret = -1;
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
virNetworkDNSDefPtr dns = &def->dns;
|
|
|
|
virNetworkDNSHostDef host;
|
|
|
|
bool isAdd = (command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST ||
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST);
|
2013-01-04 22:02:42 +00:00
|
|
|
int foundCt = 0;
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
|
|
|
|
memset(&host, 0, sizeof(host));
|
|
|
|
|
|
|
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
2016-04-19 18:48:30 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
_("DNS HOST records cannot be modified, "
|
|
|
|
"only added or deleted"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virNetworkDNSHostDefParseXML(def->name, ctxt->node, &host, !isAdd) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < dns->nhosts; i++) {
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
bool foundThisTime = false;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (virSocketAddrEqual(&host.ip, &dns->hosts[i].ip))
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
foundThisTime = true;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (j = 0; j < host.nnames && !foundThisTime; j++) {
|
|
|
|
for (k = 0; k < dns->hosts[i].nnames && !foundThisTime; k++) {
|
|
|
|
if (STREQ(host.names[j], dns->hosts[i].names[k]))
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
foundThisTime = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (foundThisTime) {
|
|
|
|
foundCt++;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
foundIdx = i;
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isAdd) {
|
|
|
|
|
|
|
|
if (foundCt > 0) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("there is already at least one DNS HOST "
|
|
|
|
"record with a matching field in network %s"),
|
|
|
|
def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add to beginning/end of list */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_INSERT_ELEMENT(dns->hosts,
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
|
|
|
|
? 0 : dns->nhosts, dns->nhosts, host) < 0)
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
|
|
|
|
|
|
|
|
if (foundCt == 0) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("couldn't locate a matching DNS HOST "
|
|
|
|
"record in network %s"), def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (foundCt > 1) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("multiple matching DNS HOST records were "
|
|
|
|
"found in network %s"), def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove it */
|
|
|
|
virNetworkDNSHostDefClear(&dns->hosts[foundIdx]);
|
|
|
|
VIR_DELETE_ELEMENT(dns->hosts, foundIdx, dns->nhosts);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
virNetworkDefUpdateUnknownCommand(command);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
virNetworkDNSHostDefClear(&host);
|
|
|
|
return ret;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
virNetworkDefUpdateDNSSrv(virNetworkDefPtr def,
|
2012-09-14 19:14:57 +00:00
|
|
|
unsigned int command ATTRIBUTE_UNUSED,
|
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
|
|
|
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int foundIdx = -1, ret = -1;
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
virNetworkDNSDefPtr dns = &def->dns;
|
|
|
|
virNetworkDNSSrvDef srv;
|
|
|
|
bool isAdd = (command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST ||
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST);
|
2013-01-04 22:02:42 +00:00
|
|
|
int foundCt = 0;
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
|
|
|
|
memset(&srv, 0, sizeof(srv));
|
|
|
|
|
|
|
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
2016-04-19 18:48:30 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
_("DNS SRV records cannot be modified, "
|
|
|
|
"only added or deleted"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "srv") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virNetworkDNSSrvDefParseXML(def->name, ctxt->node, ctxt, &srv, !isAdd) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (i = 0; i < dns->nsrvs; i++) {
|
|
|
|
if ((!srv.domain || STREQ_NULLABLE(srv.domain, dns->srvs[i].domain)) &&
|
|
|
|
(!srv.service || STREQ_NULLABLE(srv.service, dns->srvs[i].service)) &&
|
|
|
|
(!srv.protocol || STREQ_NULLABLE(srv.protocol, dns->srvs[i].protocol)) &&
|
|
|
|
(!srv.target || STREQ_NULLABLE(srv.target, dns->srvs[i].target))) {
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
foundCt++;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
foundIdx = i;
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isAdd) {
|
|
|
|
|
|
|
|
if (foundCt > 0) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("there is already at least one DNS SRV "
|
|
|
|
"record matching all specified fields in network %s"),
|
|
|
|
def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add to beginning/end of list */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_INSERT_ELEMENT(dns->srvs,
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
|
|
|
|
? 0 : dns->nsrvs, dns->nsrvs, srv) < 0)
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
|
|
|
|
|
|
|
|
if (foundCt == 0) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("couldn't locate a matching DNS SRV "
|
|
|
|
"record in network %s"), def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (foundCt > 1) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("multiple DNS SRV records matching all specified "
|
|
|
|
"fields were found in network %s"), def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove it */
|
|
|
|
virNetworkDNSSrvDefClear(&dns->srvs[foundIdx]);
|
|
|
|
VIR_DELETE_ELEMENT(dns->srvs, foundIdx, dns->nsrvs);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
virNetworkDefUpdateUnknownCommand(command);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
virNetworkDNSSrvDefClear(&srv);
|
|
|
|
return ret;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
static int
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
virNetworkDefUpdateDNSTxt(virNetworkDefPtr def,
|
2012-09-14 19:14:57 +00:00
|
|
|
unsigned int command ATTRIBUTE_UNUSED,
|
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
|
|
|
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
|
/* virNetworkUpdateFlags */
|
|
|
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
int foundIdx, ret = -1;
|
|
|
|
virNetworkDNSDefPtr dns = &def->dns;
|
|
|
|
virNetworkDNSTxtDef txt;
|
|
|
|
bool isAdd = (command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST ||
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST);
|
|
|
|
|
|
|
|
memset(&txt, 0, sizeof(txt));
|
|
|
|
|
|
|
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
2016-04-19 18:48:30 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
_("DNS TXT records cannot be modified, "
|
|
|
|
"only added or deleted"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "txt") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virNetworkDNSTxtDefParseXML(def->name, ctxt->node, &txt, !isAdd) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (foundIdx = 0; foundIdx < dns->ntxts; foundIdx++) {
|
|
|
|
if (STREQ(txt.name, dns->txts[foundIdx].name))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isAdd) {
|
|
|
|
|
|
|
|
if (foundIdx < dns->ntxts) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("there is already a DNS TXT record "
|
|
|
|
"with name '%s' in network %s"),
|
|
|
|
txt.name, def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add to beginning/end of list */
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_INSERT_ELEMENT(dns->txts,
|
|
|
|
command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
|
|
|
|
? 0 : dns->ntxts, dns->ntxts, txt) < 0)
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
|
|
|
|
|
|
|
|
if (foundIdx == dns->ntxts) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("couldn't locate a matching DNS TXT "
|
|
|
|
"record in network %s"), def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove it */
|
|
|
|
virNetworkDNSTxtDefClear(&dns->txts[foundIdx]);
|
|
|
|
VIR_DELETE_ELEMENT(dns->txts, foundIdx, dns->ntxts);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
virNetworkDefUpdateUnknownCommand(command);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
network: backend functions for updating network dns host/srv/txt
These three functions are very similar - none allow a MODIFY
operation; you can only add or delete.
The biggest difference between them (other than the data itself) is in
the criteria for determining a match, and whether or not multiple
matches are possible:
1) for HOST records, it's considered a match if the IP address or any
of the hostnames of an existing record matches.
2) for SRV records, it's a match if all of
domain+service+protocol+target *which have been specified* are
matched.
3) for TXT records, there is only a single field to match - name
(value can be the same for multiple records, and isn't considered a
search term), so by definition there can be no ambiguous matches.
In all three cases, if any matches are found, ADD will fail; if
multiple matches are found, it means the search term was ambiguous,
and a DELETE will fail.
The upper level code in bridge_driver.c is already implemented for
these functions - appropriate conf files will be re-written, and
dnsmasq will be SIGHUPed or restarted as appropriate.
2012-11-12 21:18:02 +00:00
|
|
|
virNetworkDNSTxtDefClear(&txt);
|
|
|
|
return ret;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 15:41:57 +00:00
|
|
|
|
2013-07-29 15:17:47 +00:00
|
|
|
int
|
2012-09-14 19:14:57 +00:00
|
|
|
virNetworkDefUpdateSection(virNetworkDefPtr def,
|
|
|
|
unsigned int command, /* virNetworkUpdateCommand */
|
|
|
|
unsigned int section, /* virNetworkUpdateSection */
|
|
|
|
int parentIndex,
|
|
|
|
const char *xml,
|
|
|
|
unsigned int flags) /* virNetworkUpdateFlags */
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
xmlDocPtr doc;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
|
|
|
|
if (!(doc = virXMLParseStringCtxt(xml, _("network_update_xml"), &ctxt)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
switch (section) {
|
|
|
|
case VIR_NETWORK_SECTION_BRIDGE:
|
|
|
|
ret = virNetworkDefUpdateBridge(def, command, parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_NETWORK_SECTION_DOMAIN:
|
|
|
|
ret = virNetworkDefUpdateDomain(def, command, parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_IP:
|
|
|
|
ret = virNetworkDefUpdateIP(def, command, parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_IP_DHCP_HOST:
|
|
|
|
ret = virNetworkDefUpdateIPDHCPHost(def, command,
|
|
|
|
parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_IP_DHCP_RANGE:
|
|
|
|
ret = virNetworkDefUpdateIPDHCPRange(def, command,
|
|
|
|
parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_FORWARD:
|
|
|
|
ret = virNetworkDefUpdateForward(def, command,
|
|
|
|
parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_FORWARD_INTERFACE:
|
|
|
|
ret = virNetworkDefUpdateForwardInterface(def, command,
|
|
|
|
parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_FORWARD_PF:
|
|
|
|
ret = virNetworkDefUpdateForwardPF(def, command,
|
|
|
|
parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_PORTGROUP:
|
network: backend for virNetworkUpdate of portgroups
portgroup elements are located in the toplevel of <network>
objects. There can be multiple <portgroup> elements, and they each
have a unique name attribute.
Add, delete, and modify are all supported for portgroup. When deleting
a portgroup, only the name must be specified in the provided xml - all
other attributes and subelements are ignored for the purposes of
matching and existing portgroup.
The bridge driver and virsh already know about the portgroup element,
so providing this backend should cause the entire stack to work. Note
that in the case of portgroup, there is no external daemon based on
the portgroup config, so nothing must be restarted.
It is important to note that guests make a copy of the appropriate
network's portgroup data when they are started, so although an updated
portgroup's configuration will have an affect on new guests started
after the cahange, existing guests won't magically have their
bandwidth changed, for example. If something like that is desired, it
will take a lot of redesign work in the way network devices are setup
(there is currently no link from the network back to the individual
interfaces using it, much less from a portgroup within a network back
to the individual interfaces).
2012-09-21 02:25:41 +00:00
|
|
|
ret = virNetworkDefUpdatePortGroup(def, command,
|
2012-09-14 19:14:57 +00:00
|
|
|
parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_DNS_HOST:
|
|
|
|
ret = virNetworkDefUpdateDNSHost(def, command,
|
|
|
|
parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_DNS_TXT:
|
|
|
|
ret = virNetworkDefUpdateDNSTxt(def, command, parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_SECTION_DNS_SRV:
|
|
|
|
ret = virNetworkDefUpdateDNSSrv(def, command, parentIndex, ctxt, flags);
|
|
|
|
break;
|
|
|
|
default:
|
2016-04-19 18:48:30 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
2012-09-14 19:14:57 +00:00
|
|
|
_("can't update unrecognized section of network"));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2012-09-14 19:14:57 +00:00
|
|
|
xmlFreeDoc(doc);
|
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
return ret;
|
|
|
|
}
|