2008-07-11 10:48:34 +00:00
|
|
|
/*
|
|
|
|
* network_conf.c: network XML handling
|
|
|
|
*
|
2013-01-04 22:02:42 +00:00
|
|
|
* Copyright (C) 2006-2013 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
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#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>
|
2008-10-28 17:45:41 +00:00
|
|
|
#include <string.h>
|
2008-07-11 10:48:34 +00:00
|
|
|
#include <dirent.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-03-02 17:37:03 +00:00
|
|
|
#define MAX_BRIDGE_ID 256
|
2009-01-20 17:13:33 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
2012-11-16 13:29:01 +00:00
|
|
|
#define NEXT_FREE_CLASS_ID 3
|
|
|
|
/* currently, /sbin/tc implementation allows up to 16 bits for minor class size */
|
|
|
|
#define CLASS_ID_BITMAP_SIZE (1<<16)
|
2009-01-20 17:13:33 +00:00
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
VIR_ENUM_IMPL(virNetworkForward,
|
|
|
|
VIR_NETWORK_FORWARD_LAST,
|
2012-08-16 15:41:41 +00:00
|
|
|
"none", "nat", "route", "bridge", "private", "vepa", "passthrough", "hostdev")
|
|
|
|
|
|
|
|
VIR_ENUM_DECL(virNetworkForwardHostdevDevice)
|
|
|
|
VIR_ENUM_IMPL(virNetworkForwardHostdevDevice,
|
|
|
|
VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_LAST,
|
|
|
|
"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",
|
|
|
|
"vfio")
|
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjListPtr nets,
|
2008-07-11 10:48:34 +00:00
|
|
|
const unsigned char *uuid)
|
|
|
|
{
|
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-10-10 14:50:26 +00:00
|
|
|
|
2013-05-21 07:21:17 +00:00
|
|
|
for (i = 0; i < nets->count; i++) {
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjLock(nets->objs[i]);
|
2008-10-10 14:50:26 +00:00
|
|
|
if (!memcmp(nets->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
|
|
|
|
return nets->objs[i];
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjUnlock(nets->objs[i]);
|
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
virNetworkObjPtr virNetworkFindByName(const virNetworkObjListPtr nets,
|
2008-07-11 10:48:34 +00:00
|
|
|
const char *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
|
|
|
size_t i;
|
2008-10-10 14:50:26 +00:00
|
|
|
|
2013-05-21 07:21:17 +00:00
|
|
|
for (i = 0; i < nets->count; i++) {
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjLock(nets->objs[i]);
|
2008-10-10 14:50:26 +00:00
|
|
|
if (STREQ(nets->objs[i]->def->name, name))
|
|
|
|
return nets->objs[i];
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjUnlock(nets->objs[i]);
|
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
return 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
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2012-08-05 06:32:49 +00:00
|
|
|
static void
|
|
|
|
virNetworkForwardPfDefClear(virNetworkForwardPfDefPtr def)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->dev);
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2012-11-11 15:27:55 +00:00
|
|
|
static void
|
|
|
|
virNetworkIpDefClear(virNetworkIpDefPtr def)
|
2010-11-17 18:36:19 +00:00
|
|
|
{
|
|
|
|
VIR_FREE(def->family);
|
|
|
|
VIR_FREE(def->ranges);
|
|
|
|
|
2012-11-11 15:27:55 +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);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
static void
|
|
|
|
virNetworkRouteDefClear(virNetworkRouteDefPtr def)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->family);
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
virNetworkDNSHostDefClear(virNetworkDNSHostDefPtr def)
|
|
|
|
{
|
|
|
|
while (def->nnames--)
|
|
|
|
VIR_FREE(def->names[def->nnames]);
|
|
|
|
VIR_FREE(def->names);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
virNetworkDNSSrvDefClear(virNetworkDNSSrvDefPtr def)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->domain);
|
|
|
|
VIR_FREE(def->service);
|
|
|
|
VIR_FREE(def->protocol);
|
|
|
|
VIR_FREE(def->target);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
virNetworkDNSDefClear(virNetworkDNSDefPtr def)
|
|
|
|
{
|
|
|
|
if (def->txts) {
|
|
|
|
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) {
|
|
|
|
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) {
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
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->npfs && def->pfs; i++) {
|
|
|
|
virNetworkForwardPfDefClear(&def->pfs[i]);
|
2012-11-11 22:57:16 +00:00
|
|
|
}
|
|
|
|
VIR_FREE(def->pfs);
|
|
|
|
|
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->nifs && def->ifs; i++) {
|
|
|
|
virNetworkForwardIfDefClear(&def->ifs[i]);
|
2012-11-11 22:57:16 +00:00
|
|
|
}
|
|
|
|
VIR_FREE(def->ifs);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
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
|
|
|
|
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 && def->ips; i++) {
|
|
|
|
virNetworkIpDefClear(&def->ips[i]);
|
2008-08-20 12:50:29 +00:00
|
|
|
}
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(def->ips);
|
2009-09-21 20:50:25 +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 && def->routes; i++) {
|
|
|
|
virNetworkRouteDefClear(&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);
|
|
|
|
|
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 && def->portGroups; i++) {
|
|
|
|
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);
|
2008-07-11 10:48:34 +00:00
|
|
|
VIR_FREE(def);
|
|
|
|
}
|
|
|
|
|
|
|
|
void virNetworkObjFree(virNetworkObjPtr net)
|
|
|
|
{
|
|
|
|
if (!net)
|
|
|
|
return;
|
|
|
|
|
|
|
|
virNetworkDefFree(net->def);
|
|
|
|
virNetworkDefFree(net->newDef);
|
2013-01-15 14:20:02 +00:00
|
|
|
virBitmapFree(net->class_id);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexDestroy(&net->lock);
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
VIR_FREE(net);
|
|
|
|
}
|
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
void virNetworkObjListFree(virNetworkObjListPtr nets)
|
|
|
|
{
|
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-10-10 14:50:26 +00:00
|
|
|
|
2013-05-21 07:21:17 +00:00
|
|
|
for (i = 0; i < nets->count; i++)
|
2008-10-10 14:50:26 +00:00
|
|
|
virNetworkObjFree(nets->objs[i]);
|
|
|
|
|
|
|
|
VIR_FREE(nets->objs);
|
|
|
|
nets->count = 0;
|
|
|
|
}
|
|
|
|
|
2012-09-14 15:35:35 +00:00
|
|
|
/*
|
|
|
|
* virNetworkObjAssignDef:
|
|
|
|
* @network: the network object to update
|
|
|
|
* @def: the new NetworkDef (will be consumed by this function iff successful)
|
|
|
|
* @live: is this new def the "live" version, or the "persistent" version
|
|
|
|
*
|
|
|
|
* Replace the appropriate copy of the given network's NetworkDef
|
|
|
|
* with def. Use "live" and current state of the network to determine
|
|
|
|
* which to replace.
|
|
|
|
*
|
|
|
|
* Returns 0 on success, -1 on failure.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virNetworkObjAssignDef(virNetworkObjPtr network,
|
|
|
|
const virNetworkDefPtr def,
|
|
|
|
bool live)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
2012-09-14 15:35:35 +00:00
|
|
|
if (virNetworkObjIsActive(network)) {
|
|
|
|
if (live) {
|
2008-07-11 10:48:34 +00:00
|
|
|
virNetworkDefFree(network->def);
|
|
|
|
network->def = def;
|
2012-09-14 15:35:35 +00:00
|
|
|
} else if (network->persistent) {
|
|
|
|
/* save current configuration to be restored on network shutdown */
|
2010-05-17 20:38:59 +00:00
|
|
|
virNetworkDefFree(network->newDef);
|
2008-07-11 10:48:34 +00:00
|
|
|
network->newDef = def;
|
2012-09-14 15:35:35 +00:00
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("cannot save persistent config of transient "
|
|
|
|
"network '%s'"), network->def->name);
|
|
|
|
return -1;
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
2012-09-14 15:35:35 +00:00
|
|
|
} else if (!live) {
|
2012-10-18 14:28:35 +00:00
|
|
|
virNetworkDefFree(network->newDef);
|
2012-09-14 15:35:35 +00:00
|
|
|
virNetworkDefFree(network->def);
|
2012-10-18 14:28:35 +00:00
|
|
|
network->newDef = NULL;
|
2012-09-14 15:35:35 +00:00
|
|
|
network->def = def;
|
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("cannot save live config of inactive "
|
|
|
|
"network '%s'"), network->def->name);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2012-09-14 15:35:35 +00:00
|
|
|
/*
|
|
|
|
* virNetworkAssignDef:
|
|
|
|
* @nets: list of all networks
|
|
|
|
* @def: the new NetworkDef (will be consumed by this function iff successful)
|
|
|
|
* @live: is this new def the "live" version, or the "persistent" version
|
|
|
|
*
|
|
|
|
* Either replace the appropriate copy of the NetworkDef with name
|
|
|
|
* matching def->name or, if not found, create a new NetworkObj with
|
|
|
|
* def. For an existing network, use "live" and current state of the
|
|
|
|
* network to determine which to replace.
|
|
|
|
*
|
|
|
|
* Returns -1 on failure, 0 on success.
|
|
|
|
*/
|
|
|
|
virNetworkObjPtr
|
|
|
|
virNetworkAssignDef(virNetworkObjListPtr nets,
|
|
|
|
const virNetworkDefPtr def,
|
|
|
|
bool live)
|
|
|
|
{
|
|
|
|
virNetworkObjPtr network;
|
|
|
|
|
|
|
|
if ((network = virNetworkFindByName(nets, def->name))) {
|
|
|
|
if (virNetworkObjAssignDef(network, def, live) < 0) {
|
2012-10-26 12:33:13 +00:00
|
|
|
virNetworkObjUnlock(network);
|
2012-09-14 15:35:35 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
return network;
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_REALLOC_N(nets->objs, nets->count + 1) < 0)
|
2012-09-14 08:53:54 +00:00
|
|
|
return NULL;
|
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC(network) < 0)
|
2008-07-11 10:48:34 +00:00
|
|
|
return NULL;
|
2009-01-15 19:56:05 +00:00
|
|
|
if (virMutexInit(&network->lock) < 0) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("cannot initialize mutex"));
|
2009-01-15 19:56:05 +00:00
|
|
|
VIR_FREE(network);
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjLock(network);
|
2008-07-11 10:48:34 +00:00
|
|
|
network->def = def;
|
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (!(network->class_id = virBitmapNew(CLASS_ID_BITMAP_SIZE)))
|
2012-11-16 13:29:01 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
/* The first three class IDs are already taken */
|
|
|
|
ignore_value(virBitmapSetBit(network->class_id, 0));
|
|
|
|
ignore_value(virBitmapSetBit(network->class_id, 1));
|
|
|
|
ignore_value(virBitmapSetBit(network->class_id, 2));
|
|
|
|
|
|
|
|
network->def = def;
|
2008-10-10 14:50:26 +00:00
|
|
|
nets->objs[nets->count] = network;
|
|
|
|
nets->count++;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
return network;
|
2012-11-16 13:29:01 +00:00
|
|
|
error:
|
|
|
|
virNetworkObjUnlock(network);
|
|
|
|
virNetworkObjFree(network);
|
|
|
|
return NULL;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-09-14 15:35:35 +00:00
|
|
|
/*
|
|
|
|
* virNetworkObjSetDefTransient:
|
|
|
|
* @network: network object pointer
|
|
|
|
* @live: if true, run this operation even for an inactive network.
|
|
|
|
* this allows freely updated network->def with runtime defaults
|
|
|
|
* before starting the network, which will be discarded on network
|
|
|
|
* shutdown. Any cleanup paths need to be sure to handle newDef if
|
|
|
|
* the network is never started.
|
|
|
|
*
|
|
|
|
* Mark the active network config as transient. Ensures live-only update
|
|
|
|
* operations do not persist past network destroy.
|
|
|
|
*
|
|
|
|
* Returns 0 on success, -1 on failure
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virNetworkObjSetDefTransient(virNetworkObjPtr network, bool live)
|
|
|
|
{
|
|
|
|
if (!virNetworkObjIsActive(network) && !live)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!network->persistent || network->newDef)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
network->newDef = virNetworkDefCopy(network->def, VIR_NETWORK_XML_INACTIVE);
|
|
|
|
return network->newDef ? 0 : -1;
|
|
|
|
}
|
|
|
|
|
network: free/null newDef if network fails to start
https://bugzilla.redhat.com/show_bug.cgi?id=866364
pointed out a crash due to virNetworkObjAssignDef free'ing
network->newDef without NULLing it afterward. A fix for this is in
upstream commit b7e9202401ebaa039b8f05acdefda8c24081537a. While the
NULLing of newDef was a legitimate fix, newDef should have already
been empty (NULL) anyway (as indicated in the comment that was deleted
by that commit).
The reason that newDef had a non-NULL value (i.e. the root cause) was
that networkStartNetwork() had failed after populating
network->newDef, but then neglected to free/NULL newDef in the
cleanup.
(A bit of background here: network->newDef should contain the
persistent config of a network when a network is active (and of course
only when it is persisten), and NULL at all other times. There is also
a network->def which should contain the persistent definition of the
network when it is inactive, and the current live state at all other
times. The idea is that you can make changes to network->newDef which
will take effect the next time the network is restarted, but won't
mess with the current state of the network (virDomainObj has a similar
pair of virDomainDefs that behave in the same fashion). Personally I
think there should be a network->live and network->config, and the
location of the persistent config should *always* be in
network->config, but that's for a later cleanup).
Since I love things to be symmetric, I created a new function called
virNetworkObjUnsetDefTransient(), which reverses the effects of
virNetworkObjSetDefTransient(). I don't really like the name of the
new function, but then I also didn't really like the name of the old
one either (it's just named that way to match a similar function in
the domain conf code).
2012-10-19 16:13:49 +00:00
|
|
|
/* virNetworkObjUnsetDefTransient:
|
|
|
|
*
|
|
|
|
* This *undoes* what virNetworkObjSetDefTransient did.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
virNetworkObjUnsetDefTransient(virNetworkObjPtr network)
|
|
|
|
{
|
2012-10-25 15:06:04 +00:00
|
|
|
if (network->newDef) {
|
network: free/null newDef if network fails to start
https://bugzilla.redhat.com/show_bug.cgi?id=866364
pointed out a crash due to virNetworkObjAssignDef free'ing
network->newDef without NULLing it afterward. A fix for this is in
upstream commit b7e9202401ebaa039b8f05acdefda8c24081537a. While the
NULLing of newDef was a legitimate fix, newDef should have already
been empty (NULL) anyway (as indicated in the comment that was deleted
by that commit).
The reason that newDef had a non-NULL value (i.e. the root cause) was
that networkStartNetwork() had failed after populating
network->newDef, but then neglected to free/NULL newDef in the
cleanup.
(A bit of background here: network->newDef should contain the
persistent config of a network when a network is active (and of course
only when it is persisten), and NULL at all other times. There is also
a network->def which should contain the persistent definition of the
network when it is inactive, and the current live state at all other
times. The idea is that you can make changes to network->newDef which
will take effect the next time the network is restarted, but won't
mess with the current state of the network (virDomainObj has a similar
pair of virDomainDefs that behave in the same fashion). Personally I
think there should be a network->live and network->config, and the
location of the persistent config should *always* be in
network->config, but that's for a later cleanup).
Since I love things to be symmetric, I created a new function called
virNetworkObjUnsetDefTransient(), which reverses the effects of
virNetworkObjSetDefTransient(). I don't really like the name of the
new function, but then I also didn't really like the name of the old
one either (it's just named that way to match a similar function in
the domain conf code).
2012-10-19 16:13:49 +00:00
|
|
|
virNetworkDefFree(network->def);
|
|
|
|
network->def = network->newDef;
|
|
|
|
network->newDef = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-14 15:35:35 +00:00
|
|
|
/*
|
|
|
|
* virNetworkObjGetPersistentDef:
|
|
|
|
* @network: network object pointer
|
|
|
|
*
|
|
|
|
* Return the persistent network configuration. If network is transient,
|
|
|
|
* return the running config.
|
|
|
|
*
|
|
|
|
* Returns NULL on error, virNetworkDefPtr on success.
|
|
|
|
*/
|
|
|
|
virNetworkDefPtr
|
|
|
|
virNetworkObjGetPersistentDef(virNetworkObjPtr network)
|
|
|
|
{
|
|
|
|
if (network->newDef)
|
|
|
|
return network->newDef;
|
|
|
|
else
|
|
|
|
return network->def;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* virNetworkObjReplacePersistentDef:
|
|
|
|
* @network: network object pointer
|
|
|
|
* @def: new virNetworkDef to replace current persistent config
|
|
|
|
*
|
|
|
|
* Replace the "persistent" network configuration with the given new
|
|
|
|
* virNetworkDef. This pays attention to whether or not the network
|
|
|
|
* is active.
|
|
|
|
*
|
|
|
|
* Returns -1 on error, 0 on success
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virNetworkObjReplacePersistentDef(virNetworkObjPtr network,
|
|
|
|
virNetworkDefPtr def)
|
|
|
|
{
|
|
|
|
if (virNetworkObjIsActive(network)) {
|
|
|
|
virNetworkDefFree(network->newDef);
|
|
|
|
network->newDef = def;
|
|
|
|
} else {
|
|
|
|
virNetworkDefFree(network->def);
|
|
|
|
network->def = def;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
virNetworkDefCopy(virNetworkDefPtr def, unsigned int flags)
|
|
|
|
{
|
|
|
|
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 */
|
|
|
|
if (!(xml = virNetworkDefFormat(def, flags)))
|
|
|
|
goto cleanup;
|
|
|
|
newDef = virNetworkDefParseString(xml);
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(xml);
|
|
|
|
return newDef;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* virNetworkConfigChangeSetup:
|
|
|
|
*
|
|
|
|
* 1) checks whether network state is consistent with the requested
|
|
|
|
* type of modification.
|
|
|
|
*
|
|
|
|
* 3) make sure there are separate "def" and "newDef" copies of
|
|
|
|
* networkDef if appropriate.
|
|
|
|
*
|
|
|
|
* Returns 0 on success, -1 on error.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virNetworkConfigChangeSetup(virNetworkObjPtr network, unsigned int flags)
|
|
|
|
{
|
|
|
|
bool isActive;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
isActive = virNetworkObjIsActive(network);
|
|
|
|
|
|
|
|
if (!isActive && (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("network is not running"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
|
|
|
|
if (!network->persistent) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot change persistent config of a "
|
|
|
|
"transient network"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* this should already have been done by the driver, but do it
|
|
|
|
* anyway just in case.
|
|
|
|
*/
|
|
|
|
if (isActive && (virNetworkObjSetDefTransient(network, false) < 0))
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
void virNetworkRemoveInactive(virNetworkObjListPtr nets,
|
2008-07-11 10:48:34 +00:00
|
|
|
const virNetworkObjPtr net)
|
|
|
|
{
|
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
|
|
|
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjUnlock(net);
|
2013-05-21 07:21:17 +00:00
|
|
|
for (i = 0; i < nets->count; i++) {
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjLock(nets->objs[i]);
|
2008-10-10 14:50:26 +00:00
|
|
|
if (nets->objs[i] == net) {
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjUnlock(nets->objs[i]);
|
2008-10-10 14:50:26 +00:00
|
|
|
virNetworkObjFree(nets->objs[i]);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
if (i < (nets->count - 1))
|
|
|
|
memmove(nets->objs + i, nets->objs + i + 1,
|
|
|
|
sizeof(*(nets->objs)) * (nets->count - (i + 1)));
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
if (VIR_REALLOC_N(nets->objs, nets->count - 1) < 0) {
|
|
|
|
; /* Failure to reduce memory allocation isn't fatal */
|
|
|
|
}
|
|
|
|
nets->count--;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjUnlock(nets->objs[i]);
|
2008-10-10 14:50:26 +00:00
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
/* return ips[index], or NULL if there aren't enough ips */
|
|
|
|
virNetworkIpDefPtr
|
|
|
|
virNetworkDefGetIpByIndex(const virNetworkDefPtr def,
|
|
|
|
int family, size_t n)
|
|
|
|
{
|
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;
|
|
|
|
|
|
|
|
if (family == AF_UNSPEC) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-11-26 22:20:37 +00:00
|
|
|
/* return number of 1 bits in netmask for the network's ipAddress,
|
|
|
|
* or -1 on error
|
|
|
|
*/
|
2010-11-17 18:36:19 +00:00
|
|
|
int virNetworkIpDefPrefix(const virNetworkIpDefPtr def)
|
2010-11-26 22:20:37 +00:00
|
|
|
{
|
2013-04-20 19:45:46 +00:00
|
|
|
return virSocketAddrGetIpPrefix(&def->address,
|
|
|
|
&def->netmask,
|
|
|
|
def->prefix);
|
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)
|
|
|
|
*/
|
2010-11-17 18:36:19 +00:00
|
|
|
int virNetworkIpDefNetmask(const virNetworkIpDefPtr def,
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-11-17 18:36:19 +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,
|
2012-11-11 23:55:12 +00:00
|
|
|
xmlNodePtr node,
|
2013-02-19 10:44:16 +00:00
|
|
|
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 */
|
|
|
|
if (virSocketAddrGetRange(&range->start, &range->end) < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid dhcp range '%s' to '%s' in network '%s'"),
|
|
|
|
start, end, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(start);
|
|
|
|
VIR_FREE(end);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-11-11 23:55:12 +00:00
|
|
|
virNetworkDHCPHostDefParseXML(const char *networkName,
|
2012-12-06 17:20:38 +00:00
|
|
|
const 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
} 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;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-11-11 23:55:12 +00:00
|
|
|
virNetworkDHCPDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
virNetworkIpDefPtr def)
|
2010-11-17 18:36:19 +00:00
|
|
|
{
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
xmlNodePtr cur;
|
|
|
|
|
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
2008-08-20 12:50:29 +00:00
|
|
|
if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "range")) {
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0)
|
2008-08-20 12:50:29 +00:00
|
|
|
return -1;
|
2013-02-19 10:44:16 +00:00
|
|
|
if (virSocketAddrRangeParseXML(networkName, cur,
|
2012-11-11 23:55:12 +00:00
|
|
|
&def->ranges[def->nranges]) < 0) {
|
2012-09-14 18:57:34 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-08-20 12:50:29 +00:00
|
|
|
def->nranges++;
|
2012-09-14 18:57:34 +00:00
|
|
|
|
2008-08-20 12:50:29 +00:00
|
|
|
} else if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "host")) {
|
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_REALLOC_N(def->hosts, def->nhosts + 1) < 0)
|
2008-08-20 12:50:29 +00:00
|
|
|
return -1;
|
2012-12-06 17:20:38 +00:00
|
|
|
if (virNetworkDHCPHostDefParseXML(networkName, def, cur,
|
2012-11-11 23:55:12 +00:00
|
|
|
&def->hosts[def->nhosts],
|
|
|
|
false) < 0) {
|
2012-09-14 18:57:34 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-08-20 12:50:29 +00:00
|
|
|
def->nhosts++;
|
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 &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "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);
|
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
|
|
|
return -1;
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
VIR_FREE(ip);
|
|
|
|
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 &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "hostname")) {
|
|
|
|
if (cur->children != NULL) {
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_REALLOC_N(def->names, def->nnames + 1) < 0)
|
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
|
|
|
def->names[def->nnames++] = (char *)xmlNodeGetContent(cur);
|
|
|
|
if (!def->names[def->nnames - 1]) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing hostname in network '%s' DNS HOST record"),
|
|
|
|
networkName);
|
|
|
|
}
|
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
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
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,
|
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
|
|
|
_("Missing required service attribute in DNS SRV record "
|
|
|
|
" of network %s"), 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
|
|
|
if (strlen(def->service) > DNS_RECORD_LENGTH_SRV) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
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
|
|
|
_("Service name '%s' in network %s is too long, limit is %d bytes"),
|
|
|
|
def->service, networkName, DNS_RECORD_LENGTH_SRV);
|
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
|
|
|
if (!(def->protocol = virXMLPropString(node, "protocol")) && !partialOkay) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
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
|
|
|
_("Missing required protocol attribute "
|
|
|
|
"in dns srv record '%s' of network %s"),
|
|
|
|
def->service, networkName);
|
2012-01-02 14:23:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check whether protocol value is the supported one */
|
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 (STRNEQ(def->protocol, "tcp") && (STRNEQ(def->protocol, "udp"))) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
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
|
|
|
_("Invalid protocol attribute value '%s' "
|
|
|
|
" in DNS SRV record of network %s"),
|
|
|
|
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 */
|
|
|
|
if ((def->target = virXMLPropString(node, "target")) &&
|
|
|
|
(def->domain = virXMLPropString(node, "domain"))) {
|
2012-01-02 14:23:54 +00:00
|
|
|
xmlNodePtr save_ctxt = ctxt->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
|
|
|
ctxt->node = node;
|
|
|
|
if (virXPathUInt("string(./@port)", ctxt, &def->port) < 0 ||
|
|
|
|
def->port > 65535) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing or invalid port attribute "
|
|
|
|
"in network %s"), networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virXPathUInt("string(./@priority)", ctxt, &def->priority) < 0 ||
|
|
|
|
def->priority > 65535) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing or invalid priority attribute "
|
|
|
|
"in network %s"), 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 (virXPathUInt("string(./@weight)", ctxt, &def->weight) < 0 ||
|
|
|
|
def->weight > 65535) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing or invalid weight attribute "
|
|
|
|
"in network %s"), networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2012-01-02 14:23:54 +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
|
|
|
if (!(def->service || def->protocol)) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing required service attribute or protocol "
|
|
|
|
"in DNS SRV record of network %s"), networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
return 0;
|
2012-01-02 14:23:54 +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);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
virNetworkDNSTxtDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
virNetworkDNSTxtDefPtr def,
|
|
|
|
bool partialOkay)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
if (strchr(def->name, ' ') != NULL) {
|
|
|
|
virReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("prohibited space character in DNS TXT record "
|
|
|
|
"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
|
|
|
|
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
|
|
|
error:
|
|
|
|
virNetworkDNSTxtDefClear(def);
|
|
|
|
return -1;
|
2012-01-02 14:23:54 +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;
|
|
|
|
int nhosts, nsrvs, ntxts;
|
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;
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
ret = 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
|
|
|
cleanup:
|
|
|
|
VIR_FREE(hostNodes);
|
|
|
|
VIR_FREE(srvNodes);
|
|
|
|
VIR_FREE(txtNodes);
|
|
|
|
ctxt->node = save;
|
2011-06-24 10:04:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
virNetworkIpDefPtr def)
|
2010-11-17 18:36:19 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* virNetworkIpDef object is already allocated as part of an array.
|
|
|
|
* On failure clear it out, but don't free it.
|
|
|
|
*/
|
|
|
|
|
|
|
|
xmlNodePtr cur, save;
|
|
|
|
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;
|
|
|
|
|
|
|
|
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
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2012-12-06 17:20:38 +00:00
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
|
|
|
if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "dhcp")) {
|
|
|
|
if (virNetworkDHCPDefParseXML(networkName, cur, def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "tftp")) {
|
|
|
|
char *root;
|
2010-11-17 18:36:19 +00:00
|
|
|
|
2012-12-06 17:20:38 +00:00
|
|
|
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
|
|
|
}
|
2012-12-06 17:20:38 +00:00
|
|
|
if (!(root = virXMLPropString(cur, "root"))) {
|
|
|
|
cur = cur->next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
def->tftproot = (char *)root;
|
2009-09-21 20:50:25 +00:00
|
|
|
}
|
2012-12-06 17:20:38 +00:00
|
|
|
cur = cur->next;
|
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;
|
|
|
|
|
2012-11-11 23:55:12 +00:00
|
|
|
cleanup:
|
2010-11-17 18:36:19 +00:00
|
|
|
if (result < 0) {
|
|
|
|
virNetworkIpDefClear(def);
|
2009-09-21 20:50:25 +00:00
|
|
|
}
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(address);
|
|
|
|
VIR_FREE(netmask);
|
|
|
|
|
|
|
|
ctxt->node = save;
|
|
|
|
return result;
|
2009-09-21 20:50:25 +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
|
|
|
static int
|
|
|
|
virNetworkRouteDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
virNetworkRouteDefPtr def)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* virNetworkRouteDef object is already allocated as part
|
|
|
|
* of an array. On failure clear: it out, but don't free it.
|
|
|
|
*/
|
|
|
|
|
|
|
|
xmlNodePtr save;
|
|
|
|
char *address = NULL, *netmask = NULL;
|
|
|
|
char *gateway = NULL;
|
|
|
|
unsigned long prefix = 0, metric = 0;
|
|
|
|
int result = -1;
|
|
|
|
int prefixRc, metricRc;
|
|
|
|
virSocketAddr testAddr;
|
|
|
|
|
|
|
|
save = ctxt->node;
|
|
|
|
ctxt->node = node;
|
|
|
|
|
|
|
|
/* grab raw data from XML */
|
|
|
|
def->family = virXPathString("string(./@family)", ctxt);
|
|
|
|
address = virXPathString("string(./@address)", ctxt);
|
|
|
|
netmask = virXPathString("string(./@netmask)", ctxt);
|
|
|
|
gateway = virXPathString("string(./@gateway)", ctxt);
|
|
|
|
prefixRc = virXPathULong("string(./@prefix)", ctxt, &prefix);
|
|
|
|
if (prefixRc == -2) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid prefix specified "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
def->has_prefix = (prefixRc == 0);
|
|
|
|
def->prefix = prefix;
|
|
|
|
metricRc = virXPathULong("string(./@metric)", ctxt, &metric);
|
|
|
|
if (metricRc == -2) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid metric specified "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (metricRc == 0) {
|
|
|
|
def->has_metric = true;
|
|
|
|
if (metric == 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid metric value, must be > 0 "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
def->metric = metric;
|
|
|
|
|
|
|
|
/* Note: both network and gateway addresses must be specified */
|
|
|
|
|
|
|
|
if (!address) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing required address attribute "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!gateway) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing required gateway attribute "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Bad network address '%s' "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virSocketAddrParse(&def->gateway, gateway, AF_UNSPEC) < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Bad gateway address '%s' "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
gateway, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* validate network address, etc. for each family */
|
|
|
|
if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) {
|
|
|
|
if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) ||
|
|
|
|
VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
def->family == NULL ?
|
|
|
|
_("No family specified for non-IPv4 address '%s' "
|
|
|
|
"in route definition of network '%s'") :
|
|
|
|
_("IPv4 family specified for non-IPv4 address '%s' "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
def->family == NULL ?
|
|
|
|
_("No family specified for non-IPv4 gateway '%s' "
|
|
|
|
"in route definition of network '%s'") :
|
|
|
|
_("IPv4 family specified for non-IPv4 gateway '%s' "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (netmask) {
|
|
|
|
if (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Bad netmask address '%s' "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
netmask, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Network '%s' has invalid netmask '%s' "
|
|
|
|
"for address '%s' (both must be IPv4)"),
|
|
|
|
networkName, netmask, address);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (def->has_prefix) {
|
|
|
|
/* can't have both netmask and prefix at the same time */
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Route definition '%s' cannot have both "
|
|
|
|
"a prefix and a netmask"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (def->prefix > 32) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid prefix %u specified "
|
|
|
|
"in route definition of network '%s', "
|
|
|
|
"must be 0 - 32"),
|
|
|
|
def->prefix, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else if (STREQ(def->family, "ipv6")) {
|
|
|
|
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("ipv6 family specified for non-IPv6 address '%s' "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (netmask) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Specifying netmask invalid for IPv6 address '%s' "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET6)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("ipv6 specified for non-IPv6 gateway address '%s' "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
gateway, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (def->prefix > 128) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid prefix %u specified "
|
|
|
|
"in route definition of network '%s', "
|
|
|
|
"must be 0 - 128"),
|
|
|
|
def->prefix, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Unrecognized family '%s' "
|
|
|
|
"in route definition of network'%s'"),
|
|
|
|
def->family, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* make sure the address is a network address */
|
|
|
|
if (netmask) {
|
|
|
|
if (virSocketAddrMask(&def->address, &def->netmask, &testAddr) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("error converting address '%s' with netmask '%s' "
|
|
|
|
"to network-address "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
address, netmask, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (virSocketAddrMaskByPrefix(&def->address,
|
|
|
|
def->prefix, &testAddr) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("error converting address '%s' with prefix %u "
|
|
|
|
"to network-address "
|
|
|
|
"in route definition of network '%s'"),
|
|
|
|
address, def->prefix, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!virSocketAddrEqual(&def->address, &testAddr)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("address '%s' in route definition of network '%s' "
|
|
|
|
"is not a network address"),
|
|
|
|
address, networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (result < 0) {
|
|
|
|
virNetworkRouteDefClear(def);
|
|
|
|
}
|
|
|
|
VIR_FREE(address);
|
|
|
|
VIR_FREE(netmask);
|
|
|
|
VIR_FREE(gateway);
|
|
|
|
|
|
|
|
ctxt->node = save;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
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 &&
|
2012-11-16 09:37:15 +00:00
|
|
|
!(def->bandwidth = virNetDevBandwidthParse(bandwidth_node, -1))) {
|
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;
|
2012-11-11 23:55:12 +00:00
|
|
|
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
|
|
|
if (result < 0) {
|
|
|
|
virPortGroupDefClear(def);
|
|
|
|
}
|
|
|
|
VIR_FREE(isDefault);
|
|
|
|
|
|
|
|
ctxt->node = save;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
static int
|
|
|
|
virNetworkForwardDefParseXML(const char *networkName,
|
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
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;
|
|
|
|
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) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("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) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("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
|
|
|
if (((nForwardIfs > 0) + (nForwardAddrs > 0) + (nForwardPfs > 0)) > 1) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("<address>, <interface>, and <pf> elements in <forward> "
|
|
|
|
"of network %s are mutually exclusive"),
|
|
|
|
networkName);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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) {
|
2012-11-11 22:57:16 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("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:
|
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 (virDevicePCIAddressParseXML(forwardAddrNodes[i],
|
|
|
|
&def->ifs[i].device.pci) < 0) {
|
2012-11-11 22:57:16 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
cleanup:
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
static virNetworkDefPtr
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
|
|
|
virNetworkDefPtr def;
|
|
|
|
char *tmp;
|
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;
|
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
|
|
|
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;
|
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;
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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) {
|
2009-09-04 17:15:51 +00:00
|
|
|
if (virUUIDGenerate(def->uuid)) {
|
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) {
|
|
|
|
VIR_FREE(tmp);
|
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);
|
|
|
|
}
|
|
|
|
|
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);
|
2008-09-08 12:45:29 +00:00
|
|
|
|
2011-07-22 14:07:25 +00:00
|
|
|
if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) != NULL &&
|
2012-11-16 09:37:15 +00:00
|
|
|
(def->bandwidth = virNetDevBandwidthParse(bandwidthNode, -1)) == NULL)
|
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);
|
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
|
|
|
|
2010-02-04 21:52:34 +00:00
|
|
|
if (virXPathULong("string(./bridge[1]/@delay)", ctxt, &def->delay) < 0)
|
2008-07-11 10:48:34 +00:00
|
|
|
def->delay = 0;
|
|
|
|
|
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
|
|
|
VIR_FREE(tmp);
|
|
|
|
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
|
|
|
VIR_FREE(tmp);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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++) {
|
|
|
|
int ret = virNetworkPortGroupParseXML(&def->portGroups[i],
|
|
|
|
portGroupNodes[i], 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
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
def->nPortGroups++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(portGroupNodes);
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
nIps = virXPathNodeSet("./ip", ctxt, &ipNodes);
|
2011-05-12 19:45:22 +00:00
|
|
|
if (nIps < 0)
|
|
|
|
goto error;
|
|
|
|
|
2010-11-17 18:36:19 +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 */
|
2013-07-04 10:02:00 +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 */
|
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 < nIps; i++) {
|
|
|
|
int ret = virNetworkIPDefParseXML(def->name, ipNodes[i],
|
|
|
|
ctxt, &def->ips[i]);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (ret < 0)
|
|
|
|
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++) {
|
|
|
|
int ret = virNetworkRouteDefParseXML(def->name, routeNodes[i],
|
|
|
|
ctxt, &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
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
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;
|
|
|
|
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;
|
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
|
|
|
virNetworkRouteDefPtr gwdef = &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
|
|
|
addrMatch = 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
|
|
|
for (j = 0; j < nIps; j++) {
|
|
|
|
virNetworkIpDefPtr def2 = &def->ips[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
|
|
|
if (VIR_SOCKET_ADDR_FAMILY(&gwdef->gateway)
|
|
|
|
!= VIR_SOCKET_ADDR_FAMILY(&def2->address)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
int prefix = virNetworkIpDefPrefix(def2);
|
|
|
|
virSocketAddrMaskByPrefix(&def2->address, prefix, &testAddr);
|
|
|
|
virSocketAddrMaskByPrefix(&gwdef->gateway, prefix, &testGw);
|
|
|
|
if (VIR_SOCKET_ADDR_VALID(&testAddr) &&
|
|
|
|
VIR_SOCKET_ADDR_VALID(&testGw) &&
|
|
|
|
virSocketAddrEqual(&testAddr, &testGw)) {
|
|
|
|
addrMatch = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!addrMatch) {
|
|
|
|
char *gw = virSocketAddrFormat(&gwdef->gateway);
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
switch (def->forward.type) {
|
|
|
|
case VIR_NETWORK_FORWARD_NONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_NETWORK_FORWARD_ROUTE:
|
|
|
|
case VIR_NETWORK_FORWARD_NAT:
|
|
|
|
/* 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;
|
|
|
|
}
|
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;
|
|
|
|
}
|
2012-11-11 22:57:16 +00:00
|
|
|
/* fall through to next case */
|
|
|
|
case VIR_NETWORK_FORWARD_BRIDGE:
|
|
|
|
if (def->delay || stp) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("bridge delay/stp options only allowed in route, nat, and isolated mode, not in %s (network '%s')"),
|
|
|
|
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;
|
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);
|
|
|
|
ctxt->node = save;
|
2008-07-11 10:48:34 +00:00
|
|
|
return def;
|
|
|
|
|
2012-11-11 22:57:16 +00:00
|
|
|
error:
|
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);
|
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;
|
|
|
|
}
|
|
|
|
|
2010-02-24 20:53:16 +00:00
|
|
|
static virNetworkDefPtr
|
|
|
|
virNetworkDefParse(const char *xmlStr,
|
|
|
|
const char *filename)
|
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;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2011-09-14 14:17:57 +00:00
|
|
|
if ((xml = virXMLParse(filename, xmlStr, _("(network_definition)")))) {
|
2010-02-24 20:53:16 +00:00
|
|
|
def = virNetworkDefParseNode(xml, xmlDocGetRootElement(xml));
|
|
|
|
xmlFreeDoc(xml);
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2010-02-24 20:53:16 +00:00
|
|
|
virNetworkDefPtr virNetworkDefParseString(const char *xmlStr)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
2010-02-24 20:53:16 +00:00
|
|
|
return virNetworkDefParse(xmlStr, NULL);
|
|
|
|
}
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2010-02-24 20:53:16 +00:00
|
|
|
virNetworkDefPtr virNetworkDefParseFile(const char *filename)
|
|
|
|
{
|
|
|
|
return virNetworkDefParse(NULL, filename);
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkDefPtr virNetworkDefParseNode(xmlDocPtr xml,
|
2008-07-11 10:48:34 +00:00
|
|
|
xmlNodePtr root)
|
|
|
|
{
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
virNetworkDefPtr def = NULL;
|
|
|
|
|
|
|
|
if (!xmlStrEqual(root->name, BAD_CAST "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;
|
2010-02-10 10:22:52 +00:00
|
|
|
def = virNetworkDefParseXML(ctxt);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
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,
|
|
|
|
virNetworkDNSDefPtr def)
|
|
|
|
{
|
|
|
|
int result = 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, j;
|
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 (!(def->nhosts || def->nsrvs || def->ntxts))
|
2011-06-24 10:04:36 +00:00
|
|
|
goto out;
|
|
|
|
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAddLit(buf, "<dns>\n");
|
|
|
|
virBufferAdjustIndent(buf, 2);
|
2011-06-24 10:04:36 +00:00
|
|
|
|
2013-05-21 07:21:17 +00:00
|
|
|
for (i = 0; i < def->ntxts; i++) {
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAsprintf(buf, "<txt name='%s' value='%s' />\n",
|
2012-11-11 23:59:28 +00:00
|
|
|
def->txts[i].name,
|
|
|
|
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) {
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAsprintf(buf, "<srv service='%s' protocol='%s'",
|
2012-11-11 23:59:28 +00:00
|
|
|
def->srvs[i].service,
|
|
|
|
def->srvs[i].protocol);
|
|
|
|
|
|
|
|
if (def->srvs[i].domain)
|
|
|
|
virBufferAsprintf(buf, " domain='%s'", def->srvs[i].domain);
|
|
|
|
if (def->srvs[i].target)
|
|
|
|
virBufferAsprintf(buf, " target='%s'", def->srvs[i].target);
|
|
|
|
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++)
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAsprintf(buf, "<hostname>%s</hostname>\n",
|
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->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");
|
2011-06-24 10:04:36 +00:00
|
|
|
out:
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
static int
|
|
|
|
virNetworkIpDefFormat(virBufferPtr buf,
|
|
|
|
const virNetworkIpDefPtr def)
|
|
|
|
{
|
|
|
|
int result = -1;
|
|
|
|
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAddLit(buf, "<ip");
|
2010-11-17 18:36:19 +00:00
|
|
|
|
|
|
|
if (def->family) {
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(buf, " family='%s'", def->family);
|
2010-11-17 18:36:19 +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_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);
|
|
|
|
}
|
|
|
|
if (def->prefix > 0) {
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(buf," prefix='%u'", def->prefix);
|
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) {
|
2012-08-16 15:41:41 +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;
|
|
|
|
}
|
2012-08-16 15:41:41 +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++) {
|
2012-08-16 15:41:41 +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)
|
|
|
|
virBufferAsprintf(buf, "mac='%s' ", def->hosts[i].mac);
|
|
|
|
if (def->hosts[i].id)
|
|
|
|
virBufferAsprintf(buf, "id='%s' ", def->hosts[i].id);
|
|
|
|
if (def->hosts[i].name)
|
|
|
|
virBufferAsprintf(buf, "name='%s' ", def->hosts[i].name);
|
|
|
|
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;
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(buf, "ip='%s' ", ipaddr);
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(ipaddr);
|
|
|
|
}
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
|
|
|
}
|
|
|
|
if (def->bootfile) {
|
2012-08-16 15:41:41 +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;
|
|
|
|
virBufferEscapeString(buf, "server='%s' ", ipaddr);
|
|
|
|
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;
|
|
|
|
error:
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
static int
|
|
|
|
virNetworkRouteDefFormat(virBufferPtr buf,
|
|
|
|
const virNetworkRouteDefPtr def)
|
|
|
|
{
|
|
|
|
int result = -1;
|
|
|
|
|
|
|
|
virBufferAddLit(buf, "<route");
|
|
|
|
|
|
|
|
if (def->family) {
|
|
|
|
virBufferAsprintf(buf, " family='%s'", def->family);
|
|
|
|
}
|
|
|
|
if (VIR_SOCKET_ADDR_VALID(&def->address)) {
|
|
|
|
char *addr = virSocketAddrFormat(&def->address);
|
|
|
|
|
|
|
|
if (!addr)
|
|
|
|
goto error;
|
|
|
|
virBufferAsprintf(buf, " address='%s'", addr);
|
|
|
|
VIR_FREE(addr);
|
|
|
|
}
|
|
|
|
if (VIR_SOCKET_ADDR_VALID(&def->netmask)) {
|
|
|
|
char *addr = virSocketAddrFormat(&def->netmask);
|
|
|
|
|
|
|
|
if (!addr)
|
|
|
|
goto error;
|
|
|
|
virBufferAsprintf(buf, " netmask='%s'", addr);
|
|
|
|
VIR_FREE(addr);
|
|
|
|
}
|
|
|
|
if (def->has_prefix) {
|
|
|
|
virBufferAsprintf(buf," prefix='%u'", def->prefix);
|
|
|
|
}
|
|
|
|
if (VIR_SOCKET_ADDR_VALID(&def->gateway)) {
|
|
|
|
char *addr = virSocketAddrFormat(&def->gateway);
|
|
|
|
if (!addr)
|
|
|
|
goto error;
|
|
|
|
virBufferAsprintf(buf, " gateway='%s'", addr);
|
|
|
|
VIR_FREE(addr);
|
|
|
|
}
|
|
|
|
if (def->has_metric && def->metric > 0) {
|
|
|
|
virBufferAsprintf(buf," metric='%u'", def->metric);
|
|
|
|
}
|
|
|
|
virBufferAddLit(buf, "/>\n");
|
|
|
|
|
|
|
|
result = 0;
|
|
|
|
error:
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
const virPortGroupDefPtr def)
|
|
|
|
{
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAsprintf(buf, "<portgroup name='%s'", 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
|
|
|
if (def->isDefault) {
|
|
|
|
virBufferAddLit(buf, " default='yes'");
|
|
|
|
}
|
|
|
|
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;
|
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
|
|
|
virNetDevBandwidthFormat(def->bandwidth, 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
|
|
|
}
|
|
|
|
|
2013-02-19 10:44:14 +00:00
|
|
|
static int
|
|
|
|
virNetworkForwardNatDefFormat(virBufferPtr buf,
|
|
|
|
const virNetworkForwardDefPtr fwd)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(addrStart);
|
|
|
|
VIR_FREE(addrEnd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
static int
|
|
|
|
virNetworkDefFormatInternal(virBufferPtr buf,
|
|
|
|
const virNetworkDefPtr def,
|
|
|
|
unsigned int flags)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
|
|
|
unsigned char *uuid;
|
|
|
|
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;
|
|
|
|
int shortforward;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, "<network");
|
2012-08-06 20:17:58 +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-08-06 20:17:58 +00:00
|
|
|
}
|
2012-12-03 16:13:36 +00:00
|
|
|
if (def->ipv6nogw)
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(buf, " ipv6='yes'");
|
|
|
|
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
|
|
|
|
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++) {
|
2012-11-08 02:16:17 +00:00
|
|
|
if (def->forward.type != VIR_NETWORK_FORWARD_HOSTDEV) {
|
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");
|
2012-08-16 15:41:41 +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) {
|
2012-11-18 15:59:21 +00:00
|
|
|
if (virDevicePCIAddressFormat(buf,
|
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.pci,
|
2012-08-16 15:41:41 +00:00
|
|
|
true) < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2012-11-08 02:16:17 +00:00
|
|
|
if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
|
|
|
|
def->forward.type == VIR_NETWORK_FORWARD_NAT ||
|
|
|
|
def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
|
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
|
|
|
virBufferAddLit(buf, "<bridge");
|
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 (def->bridge)
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferEscapeString(buf, " name='%s'", def->bridge);
|
|
|
|
virBufferAsprintf(buf, " stp='%s' delay='%ld' />\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
|
|
|
def->stp ? "on" : "off",
|
|
|
|
def->delay);
|
2012-11-08 02:16:17 +00:00
|
|
|
} else if (def->forward.type == VIR_NETWORK_FORWARD_BRIDGE &&
|
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
|
|
|
def->bridge) {
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferEscapeString(buf, "<bridge name='%s' />\n", def->bridge);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
|
2009-07-02 14:02:18 +00:00
|
|
|
if (def->domain)
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAsprintf(buf, "<domain name='%s'/>\n", def->domain);
|
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;
|
2012-11-18 15:59:21 +00:00
|
|
|
if (virNetDevBandwidthFormat(def->bandwidth, 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++) {
|
|
|
|
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++) {
|
|
|
|
if (virNetworkRouteDefFormat(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;
|
|
|
|
|
|
|
|
error:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
virNetworkDefFormat(virNetworkDefPtr def,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
|
|
|
|
if (virNetworkDefFormatInternal(&buf, def, flags) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (virBufferError(&buf))
|
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
return virBufferContentAndReset(&buf);
|
|
|
|
|
|
|
|
no_memory:
|
|
|
|
virReportOOMError();
|
|
|
|
error:
|
|
|
|
virBufferFreeAndReset(&buf);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
virNetworkObjFormat(virNetworkObjPtr net,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
char *class_id = virBitmapFormat(net->class_id);
|
|
|
|
|
|
|
|
if (!class_id)
|
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
virBufferAddLit(&buf, "<networkstatus>\n");
|
|
|
|
virBufferAsprintf(&buf, " <class_id bitmap='%s'/>\n", class_id);
|
|
|
|
virBufferAsprintf(&buf, " <floor sum='%llu'/>\n", net->floor_sum);
|
|
|
|
VIR_FREE(class_id);
|
|
|
|
|
|
|
|
virBufferAdjustIndent(&buf, 2);
|
|
|
|
if (virNetworkDefFormatInternal(&buf, net->def, flags) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2012-08-16 15:41:41 +00:00
|
|
|
virBufferAdjustIndent(&buf, -2);
|
2012-11-18 15:59:21 +00:00
|
|
|
virBufferAddLit(&buf, "</networkstatus>");
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
if (virBufferError(&buf))
|
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
return virBufferContentAndReset(&buf);
|
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
no_memory:
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2012-11-18 15:59:21 +00:00
|
|
|
error:
|
2009-12-09 23:00:50 +00:00
|
|
|
virBufferFreeAndReset(&buf);
|
2008-07-11 10:48:34 +00:00
|
|
|
return 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
|
|
|
virPortGroupDefPtr virPortGroupFindByName(virNetworkDefPtr net,
|
|
|
|
const char *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
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
int virNetworkSaveXML(const char *configDir,
|
2009-01-20 22:36:10 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
int virNetworkSaveConfig(const char *configDir,
|
2009-01-20 22:36:10 +00:00
|
|
|
virNetworkDefPtr def)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
char *xml;
|
|
|
|
|
2012-09-14 15:35:35 +00:00
|
|
|
if (!(xml = virNetworkDefFormat(def, 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;
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(xml);
|
2008-07-11 10:48:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-01-20 22:36:10 +00:00
|
|
|
|
2012-09-14 15:35:35 +00:00
|
|
|
int virNetworkSaveStatus(const char *statusDir,
|
|
|
|
virNetworkObjPtr network)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
2012-11-18 15:59:21 +00:00
|
|
|
int flags = 0;
|
2012-09-14 15:35:35 +00:00
|
|
|
char *xml;
|
|
|
|
|
2012-11-18 15:59:21 +00:00
|
|
|
if (!(xml = virNetworkObjFormat(network, flags)))
|
2012-09-14 15:35:35 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virNetworkSaveXML(statusDir, network->def, xml))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(xml);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-04-16 16:35:59 +00:00
|
|
|
virNetworkObjPtr
|
|
|
|
virNetworkLoadState(virNetworkObjListPtr nets,
|
|
|
|
const char *stateDir,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
char *configFile = NULL;
|
|
|
|
virNetworkDefPtr def = NULL;
|
|
|
|
virNetworkObjPtr net = NULL;
|
|
|
|
xmlDocPtr xml = NULL;
|
|
|
|
xmlNodePtr node = NULL;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
virBitmapPtr class_id_map = NULL;
|
|
|
|
unsigned long long floor_sum_val = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if ((configFile = virNetworkConfigFile(stateDir, name)) == NULL)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(xml = virXMLParseCtxt(configFile, NULL, _("(network status)"), &ctxt)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(node = virXPathNode("//network", ctxt))) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Could not find any 'network' element in status file"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* parse the definition first */
|
|
|
|
ctxt->node = node;
|
|
|
|
if (!(def = virNetworkDefParseXML(ctxt)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!STREQ(name, def->name)) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Network config filename '%s'"
|
|
|
|
" does not match network name '%s'"),
|
|
|
|
configFile, def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now parse possible status data */
|
|
|
|
node = xmlDocGetRootElement(xml);
|
|
|
|
if (xmlStrEqual(node->name, BAD_CAST "networkstatus")) {
|
|
|
|
/* Newer network status file. Contains useful
|
|
|
|
* info which are not to be found in bare config XML */
|
|
|
|
char *class_id = NULL;
|
|
|
|
char *floor_sum = NULL;
|
|
|
|
|
|
|
|
ctxt->node = node;
|
|
|
|
if ((class_id = virXPathString("string(./class_id[1]/@bitmap)", ctxt))) {
|
|
|
|
if (virBitmapParse(class_id, 0, &class_id_map,
|
|
|
|
CLASS_ID_BITMAP_SIZE) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Malformed 'class_id' attribute: %s"),
|
|
|
|
class_id);
|
|
|
|
VIR_FREE(class_id);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(class_id);
|
|
|
|
|
|
|
|
floor_sum = virXPathString("string(./floor[1]/@sum)", ctxt);
|
|
|
|
if (floor_sum &&
|
|
|
|
virStrToLong_ull(floor_sum, NULL, 10, &floor_sum_val) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Malformed 'floor_sum' attribute: %s"),
|
|
|
|
floor_sum);
|
|
|
|
VIR_FREE(floor_sum);
|
|
|
|
}
|
|
|
|
VIR_FREE(floor_sum);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create the object */
|
|
|
|
if (!(net = virNetworkAssignDef(nets, def, true)))
|
|
|
|
goto error;
|
|
|
|
/* do not put any "goto error" below this comment */
|
|
|
|
|
|
|
|
/* assign status data stored in the network object */
|
|
|
|
if (class_id_map) {
|
|
|
|
virBitmapFree(net->class_id);
|
|
|
|
net->class_id = class_id_map;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (floor_sum_val > 0)
|
|
|
|
net->floor_sum = floor_sum_val;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(configFile);
|
|
|
|
xmlFreeDoc(xml);
|
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
return net;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virBitmapFree(class_id_map);
|
|
|
|
virNetworkDefFree(def);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkObjPtr virNetworkLoadConfig(virNetworkObjListPtr nets,
|
2008-07-11 10:48:34 +00:00
|
|
|
const char *configDir,
|
|
|
|
const char *autostartDir,
|
2009-01-20 22:36:10 +00:00
|
|
|
const char *name)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
|
|
|
char *configFile = NULL, *autostartLink = NULL;
|
|
|
|
virNetworkDefPtr def = NULL;
|
|
|
|
virNetworkObjPtr net;
|
|
|
|
int autostart;
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
if ((configFile = virNetworkConfigFile(configDir, name)) == NULL)
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
2010-02-10 10:22:52 +00:00
|
|
|
if ((autostartLink = virNetworkConfigFile(autostartDir, name)) == NULL)
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
if (!(def = virNetworkDefParseFile(configFile)))
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
|
|
|
|
2009-01-20 22:36:10 +00:00
|
|
|
if (!STREQ(name, def->name)) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Network config filename '%s'"
|
|
|
|
" does not match network name '%s'"),
|
|
|
|
configFile, def->name);
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2012-11-08 02:16:17 +00:00
|
|
|
if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
|
|
|
|
def->forward.type == VIR_NETWORK_FORWARD_NAT ||
|
|
|
|
def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
|
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
|
|
|
|
|
|
|
/* Generate a bridge if none is specified, but don't check for collisions
|
|
|
|
* if a bridge is hardcoded, so the network is at least defined.
|
|
|
|
*/
|
|
|
|
if (virNetworkSetBridgeName(nets, def, 0))
|
|
|
|
goto error;
|
|
|
|
}
|
2009-03-02 17:37:03 +00:00
|
|
|
|
2012-09-14 15:35:35 +00:00
|
|
|
if (!(net = virNetworkAssignDef(nets, def, false)))
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
net->autostart = autostart;
|
2009-03-02 17:29:44 +00:00
|
|
|
net->persistent = 1;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2009-01-20 22:36:10 +00:00
|
|
|
VIR_FREE(configFile);
|
|
|
|
VIR_FREE(autostartLink);
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
return net;
|
|
|
|
|
|
|
|
error:
|
|
|
|
VIR_FREE(configFile);
|
|
|
|
VIR_FREE(autostartLink);
|
|
|
|
virNetworkDefFree(def);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-04-16 16:35:59 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
virNetworkLoadAllState(virNetworkObjListPtr nets,
|
|
|
|
const char *stateDir)
|
|
|
|
{
|
|
|
|
DIR *dir;
|
|
|
|
struct dirent *entry;
|
|
|
|
|
|
|
|
if (!(dir = opendir(stateDir))) {
|
|
|
|
if (errno == ENOENT)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
virReportSystemError(errno, _("Failed to open dir '%s'"), stateDir);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((entry = readdir(dir))) {
|
|
|
|
virNetworkObjPtr net;
|
|
|
|
|
|
|
|
if (entry->d_name[0] == '.')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!virFileStripSuffix(entry->d_name, ".xml"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ((net = virNetworkLoadState(nets, stateDir, entry->d_name)))
|
|
|
|
virNetworkObjUnlock(net);
|
|
|
|
}
|
|
|
|
|
|
|
|
closedir(dir);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
int virNetworkLoadAllConfigs(virNetworkObjListPtr nets,
|
2008-07-11 10:48:34 +00:00
|
|
|
const char *configDir,
|
|
|
|
const char *autostartDir)
|
|
|
|
{
|
|
|
|
DIR *dir;
|
|
|
|
struct dirent *entry;
|
|
|
|
|
|
|
|
if (!(dir = opendir(configDir))) {
|
|
|
|
if (errno == ENOENT)
|
|
|
|
return 0;
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("Failed to open dir '%s'"),
|
|
|
|
configDir);
|
2008-07-11 10:48:34 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((entry = readdir(dir))) {
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjPtr net;
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
if (entry->d_name[0] == '.')
|
|
|
|
continue;
|
|
|
|
|
2009-01-20 22:36:10 +00:00
|
|
|
if (!virFileStripSuffix(entry->d_name, ".xml"))
|
2008-07-11 10:48:34 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* NB: ignoring errors, so one malformed config doesn't
|
|
|
|
kill the whole process */
|
2010-02-10 10:22:52 +00:00
|
|
|
net = virNetworkLoadConfig(nets,
|
2008-12-04 22:00:14 +00:00
|
|
|
configDir,
|
|
|
|
autostartDir,
|
|
|
|
entry->d_name);
|
|
|
|
if (net)
|
|
|
|
virNetworkObjUnlock(net);
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
closedir(dir);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
int virNetworkDeleteConfig(const char *configDir,
|
2009-01-20 22:36:10 +00:00
|
|
|
const char *autostartDir,
|
2008-07-11 10:48:34 +00:00
|
|
|
virNetworkObjPtr net)
|
|
|
|
{
|
2009-01-20 22:36:10 +00:00
|
|
|
char *configFile = NULL;
|
|
|
|
char *autostartLink = NULL;
|
2009-09-04 13:56:32 +00:00
|
|
|
int ret = -1;
|
2009-01-20 22:36:10 +00:00
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
if ((configFile = virNetworkConfigFile(configDir, net->def->name)) == NULL)
|
2009-01-20 22:36:10 +00:00
|
|
|
goto error;
|
2010-02-10 10:22:52 +00:00
|
|
|
if ((autostartLink = virNetworkConfigFile(autostartDir, net->def->name)) == NULL)
|
2009-01-20 22:36:10 +00:00
|
|
|
goto error;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
/* Not fatal if this doesn't work */
|
2009-01-20 22:36:10 +00:00
|
|
|
unlink(autostartLink);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2009-01-20 22:36:10 +00:00
|
|
|
if (unlink(configFile) < 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("cannot remove config file '%s'"),
|
2009-01-20 22:36:10 +00:00
|
|
|
configFile);
|
|
|
|
goto error;
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
2009-09-04 13:56:32 +00:00
|
|
|
ret = 0;
|
2009-01-20 22:36:10 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
VIR_FREE(configFile);
|
|
|
|
VIR_FREE(autostartLink);
|
2009-09-04 13:56:32 +00:00
|
|
|
return ret;
|
2009-01-20 22:36:10 +00:00
|
|
|
}
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
char *virNetworkConfigFile(const char *dir,
|
2009-01-20 22:36:10 +00:00
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
char *ret = NULL;
|
|
|
|
|
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
|
|
|
|
2009-03-02 17:37:03 +00:00
|
|
|
int virNetworkBridgeInUse(const virNetworkObjListPtr nets,
|
|
|
|
const char *bridge,
|
|
|
|
const char *skipname)
|
|
|
|
{
|
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;
|
2009-03-02 17:37:03 +00:00
|
|
|
unsigned int ret = 0;
|
|
|
|
|
2013-05-21 07:21:17 +00:00
|
|
|
for (i = 0; i < nets->count; i++) {
|
2009-03-02 17:37:03 +00:00
|
|
|
virNetworkObjLock(nets->objs[i]);
|
|
|
|
if (nets->objs[i]->def->bridge &&
|
|
|
|
STREQ(nets->objs[i]->def->bridge, bridge) &&
|
|
|
|
!(skipname && STREQ(nets->objs[i]->def->name, skipname)))
|
|
|
|
ret = 1;
|
|
|
|
virNetworkObjUnlock(nets->objs[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
char *virNetworkAllocateBridge(const virNetworkObjListPtr nets,
|
2009-04-21 19:00:06 +00:00
|
|
|
const char *template)
|
2009-03-02 17:37:03 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
int id = 0;
|
|
|
|
char *newname;
|
|
|
|
|
2009-04-21 19:00:06 +00:00
|
|
|
if (!template)
|
|
|
|
template = "virbr%d";
|
|
|
|
|
2009-03-02 17:37:03 +00:00
|
|
|
do {
|
2013-07-04 10:02:00 +00:00
|
|
|
if (virAsprintf(&newname, template, id) < 0)
|
2010-08-31 20:25:49 +00:00
|
|
|
return NULL;
|
|
|
|
if (!virNetworkBridgeInUse(nets, newname, NULL)) {
|
2009-03-02 17:37:03 +00:00
|
|
|
return newname;
|
|
|
|
}
|
2010-08-31 20:25:49 +00:00
|
|
|
VIR_FREE(newname);
|
2009-03-02 17:37:03 +00:00
|
|
|
|
|
|
|
id++;
|
2009-03-02 17:56:50 +00:00
|
|
|
} while (id <= MAX_BRIDGE_ID);
|
2009-03-02 17:37:03 +00:00
|
|
|
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Bridge generation exceeded max id %d"),
|
|
|
|
MAX_BRIDGE_ID);
|
2009-03-02 17:37:03 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
int virNetworkSetBridgeName(const virNetworkObjListPtr nets,
|
2009-05-29 14:18:57 +00:00
|
|
|
virNetworkDefPtr def,
|
|
|
|
int check_collision) {
|
2009-03-02 17:37:03 +00:00
|
|
|
|
|
|
|
int ret = -1;
|
|
|
|
|
2009-04-21 19:00:06 +00:00
|
|
|
if (def->bridge && !strstr(def->bridge, "%d")) {
|
2009-05-29 14:18:57 +00:00
|
|
|
/* We may want to skip collision detection in this case (ex. when
|
|
|
|
* loading configs at daemon startup, so the network is at least
|
|
|
|
* defined. */
|
|
|
|
if (check_collision &&
|
|
|
|
virNetworkBridgeInUse(nets, def->bridge, def->name)) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("bridge name '%s' already in use."),
|
|
|
|
def->bridge);
|
2009-03-02 17:37:03 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Allocate a bridge name */
|
2010-02-10 10:22:52 +00:00
|
|
|
if (!(def->bridge = virNetworkAllocateBridge(nets, def->bridge)))
|
2009-03-02 17:37:03 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
error:
|
|
|
|
return ret;
|
|
|
|
}
|
2009-01-20 22:36:10 +00:00
|
|
|
|
2010-05-27 15:44:31 +00:00
|
|
|
|
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
|
|
|
void virNetworkSetBridgeMacAddr(virNetworkDefPtr def)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
/* NetworkObj backend of the virNetworkUpdate API */
|
|
|
|
|
|
|
|
static void
|
|
|
|
virNetworkDefUpdateNoSupport(virNetworkDefPtr def, const char *section)
|
|
|
|
{
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT,
|
|
|
|
_("can't update '%s' section of network '%s'"),
|
|
|
|
section, def->name);
|
|
|
|
}
|
2012-09-21 16:11:51 +00:00
|
|
|
static void
|
|
|
|
virNetworkDefUpdateUnknownCommand(unsigned int command)
|
|
|
|
{
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT,
|
|
|
|
_("unrecognized network update command code %d"), command);
|
|
|
|
}
|
2012-09-14 19:14:57 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
virNetworkDefUpdateCheckElementName(virNetworkDefPtr def,
|
|
|
|
xmlNodePtr node,
|
|
|
|
const char *section)
|
|
|
|
{
|
|
|
|
if (!xmlStrEqual(node->name, BAD_CAST section)) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("unexpected element <%s>, expecting <%s>, "
|
|
|
|
"while updating network '%s'"),
|
|
|
|
node->name, section, def->name);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
static virNetworkIpDefPtr
|
|
|
|
virNetworkIpDefByIndex(virNetworkDefPtr def, int parentIndex)
|
|
|
|
{
|
|
|
|
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) {
|
|
|
|
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;
|
|
|
|
(ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, i));
|
|
|
|
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) {
|
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
|
|
|
ipdef = virNetworkDefGetIpByIndex(def, AF_INET, 0);
|
2012-12-06 17:20:38 +00:00
|
|
|
if (!ipdef)
|
|
|
|
ipdef = virNetworkDefGetIpByIndex(def, AF_INET6, 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
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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;
|
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
|
|
|
virNetworkIpDefPtr ipdef = virNetworkIpDefByIndex(def, parentIndex);
|
|
|
|
virNetworkDHCPHostDef host;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
/* parse the xml into a virNetworkDHCPHostDef */
|
|
|
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
|
|
|
|
2012-12-06 17:20:38 +00:00
|
|
|
if (virNetworkDHCPHostDefParseXML(def->name, ipdef,
|
|
|
|
ctxt->node, &host, false) < 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;
|
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
|
|
|
|
|
|
|
/* search for the entry with this (mac|name),
|
|
|
|
* 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++) {
|
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 ((host.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
|
|
|
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 an existing dhcp host entry with "
|
|
|
|
"\"mac='%s'\" in network '%s'"),
|
|
|
|
host.mac, def->name);
|
|
|
|
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)) {
|
|
|
|
|
2012-12-06 17:20:38 +00:00
|
|
|
if (virNetworkDHCPHostDefParseXML(def->name, ipdef,
|
|
|
|
ctxt->node, &host, true) < 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;
|
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
|
|
|
|
|
|
|
/* 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++) {
|
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 ((host.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'/>\""),
|
|
|
|
def->name, host.mac, host.name,
|
|
|
|
ip ? ip : "unknown");
|
|
|
|
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) {
|
|
|
|
|
2012-12-06 17:20:38 +00:00
|
|
|
if (virNetworkDHCPHostDefParseXML(def->name, ipdef,
|
|
|
|
ctxt->node, &host, false) < 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;
|
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
|
|
|
|
|
|
|
/* 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++) {
|
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 ((!host.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;
|
|
|
|
cleanup:
|
|
|
|
virNetworkDHCPHostDefClear(&host);
|
|
|
|
return ret;
|
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,
|
2012-09-14 19:14:57 +00:00
|
|
|
int parentIndex ATTRIBUTE_UNUSED,
|
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;
|
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
|
|
|
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) {
|
|
|
|
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("dhcp ranges cannot be modified, "
|
|
|
|
"only added or deleted"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-19 10:44:16 +00:00
|
|
|
if (virSocketAddrRangeParseXML(def->name, 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;
|
|
|
|
|
|
|
|
/* 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)) {
|
|
|
|
|
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");
|
|
|
|
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;
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("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;
|
|
|
|
cleanup:
|
|
|
|
virNetworkForwardIfDefClear(&iface);
|
|
|
|
return ret;
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
cleanup:
|
|
|
|
virPortGroupDefClear(&portgroup);
|
|
|
|
return ret;
|
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) {
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("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;
|
|
|
|
cleanup:
|
|
|
|
virNetworkDNSHostDefClear(&host);
|
|
|
|
return ret;
|
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) {
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("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;
|
|
|
|
cleanup:
|
|
|
|
virNetworkDNSSrvDefClear(&srv);
|
|
|
|
return ret;
|
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) {
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("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;
|
|
|
|
cleanup:
|
|
|
|
virNetworkDNSTxtDefClear(&txt);
|
|
|
|
return ret;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
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:
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("can't update unrecognized section of network"));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* virNetworkObjUpdate:
|
|
|
|
*
|
|
|
|
* Apply the supplied update to the given virNetworkObj. Except for
|
|
|
|
* @network pointing to an actual network object rather than the
|
|
|
|
* opaque virNetworkPtr, parameters are identical to the public API
|
|
|
|
* virNetworkUpdate.
|
|
|
|
*
|
|
|
|
* The original virNetworkDefs are copied, and all modifications made
|
|
|
|
* to these copies. The originals are replaced with the copies only
|
|
|
|
* after success has been guaranteed.
|
|
|
|
*
|
|
|
|
* Returns: -1 on error, 0 on success.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virNetworkObjUpdate(virNetworkObjPtr network,
|
|
|
|
unsigned int command, /* virNetworkUpdateCommand */
|
|
|
|
unsigned int section, /* virNetworkUpdateSection */
|
|
|
|
int parentIndex,
|
|
|
|
const char *xml,
|
|
|
|
unsigned int flags) /* virNetworkUpdateFlags */
|
|
|
|
{
|
|
|
|
int ret = -1;
|
2012-09-21 18:48:17 +00:00
|
|
|
virNetworkDefPtr livedef = NULL, configdef = NULL;
|
2012-09-14 19:14:57 +00:00
|
|
|
|
|
|
|
/* normalize config data, and check for common invalid requests. */
|
|
|
|
if (virNetworkConfigChangeSetup(network, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE) {
|
2012-09-21 18:48:17 +00:00
|
|
|
virNetworkDefPtr checkdef;
|
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
/* work on a copy of the def */
|
2012-09-21 18:48:17 +00:00
|
|
|
if (!(livedef = virNetworkDefCopy(network->def, 0)))
|
2012-09-14 19:14:57 +00:00
|
|
|
goto cleanup;
|
2012-09-21 18:48:17 +00:00
|
|
|
if (virNetworkDefUpdateSection(livedef, command, section,
|
2012-09-14 19:14:57 +00:00
|
|
|
parentIndex, xml, flags) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-09-21 18:48:17 +00:00
|
|
|
/* run a final format/parse cycle to make sure we didn't
|
|
|
|
* add anything illegal to the def
|
|
|
|
*/
|
|
|
|
if (!(checkdef = virNetworkDefCopy(livedef, 0)))
|
|
|
|
goto cleanup;
|
|
|
|
virNetworkDefFree(checkdef);
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
|
2012-09-21 18:48:17 +00:00
|
|
|
virNetworkDefPtr checkdef;
|
|
|
|
|
2012-09-14 19:14:57 +00:00
|
|
|
/* work on a copy of the def */
|
2012-09-21 18:48:17 +00:00
|
|
|
if (!(configdef = virNetworkDefCopy(virNetworkObjGetPersistentDef(network),
|
|
|
|
VIR_NETWORK_XML_INACTIVE))) {
|
2012-09-14 19:14:57 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-09-21 18:48:17 +00:00
|
|
|
if (virNetworkDefUpdateSection(configdef, command, section,
|
2012-09-14 19:14:57 +00:00
|
|
|
parentIndex, xml, flags) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-09-21 18:48:17 +00:00
|
|
|
if (!(checkdef = virNetworkDefCopy(configdef,
|
|
|
|
VIR_NETWORK_XML_INACTIVE))) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
virNetworkDefFree(checkdef);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (configdef) {
|
2012-09-14 19:14:57 +00:00
|
|
|
/* successfully modified copy, now replace original */
|
2012-09-21 18:48:17 +00:00
|
|
|
if (virNetworkObjReplacePersistentDef(network, configdef) < 0)
|
2012-09-14 19:14:57 +00:00
|
|
|
goto cleanup;
|
2012-09-21 18:48:17 +00:00
|
|
|
configdef = NULL;
|
|
|
|
}
|
|
|
|
if (livedef) {
|
|
|
|
/* successfully modified copy, now replace original */
|
|
|
|
virNetworkDefFree(network->def);
|
|
|
|
network->def = livedef;
|
|
|
|
livedef = NULL;
|
2012-09-14 19:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
2012-09-21 18:48:17 +00:00
|
|
|
virNetworkDefFree(livedef);
|
|
|
|
virNetworkDefFree(configdef);
|
2012-09-14 19:14:57 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-05-27 15:44:31 +00:00
|
|
|
/*
|
|
|
|
* virNetworkObjIsDuplicate:
|
|
|
|
* @doms : virNetworkObjListPtr to search
|
|
|
|
* @def : virNetworkDefPtr definition of network to lookup
|
|
|
|
* @check_active: If true, ensure that network is not active
|
|
|
|
*
|
|
|
|
* Returns: -1 on error
|
|
|
|
* 0 if network is new
|
|
|
|
* 1 if network is a duplicate
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virNetworkObjIsDuplicate(virNetworkObjListPtr doms,
|
|
|
|
virNetworkDefPtr def,
|
2012-10-25 12:19:59 +00:00
|
|
|
bool check_active)
|
2010-05-27 15:44:31 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
virNetworkObjPtr vm = NULL;
|
|
|
|
|
|
|
|
/* See if a VM with matching UUID already exists */
|
|
|
|
vm = virNetworkFindByUUID(doms, def->uuid);
|
|
|
|
if (vm) {
|
|
|
|
/* UUID matches, but if names don't match, refuse it */
|
|
|
|
if (STRNEQ(vm->def->name, def->name)) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(vm->def->uuid, uuidstr);
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("network '%s' is already defined with uuid %s"),
|
|
|
|
vm->def->name, uuidstr);
|
2010-05-27 15:44:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (check_active) {
|
|
|
|
/* UUID & name match, but if VM is already active, refuse it */
|
|
|
|
if (virNetworkObjIsActive(vm)) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("network is already active as '%s'"),
|
|
|
|
vm->def->name);
|
2010-05-27 15:44:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-24 10:29:28 +00:00
|
|
|
ret = 1;
|
2010-05-27 15:44:31 +00:00
|
|
|
} else {
|
|
|
|
/* UUID does not match, but if a name matches, refuse it */
|
|
|
|
vm = virNetworkFindByName(doms, def->name);
|
|
|
|
if (vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(vm->def->uuid, uuidstr);
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("network '%s' already exists with uuid %s"),
|
|
|
|
def->name, uuidstr);
|
2010-05-27 15:44:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2013-05-24 10:29:28 +00:00
|
|
|
ret = 0;
|
2010-05-27 15:44:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virNetworkObjUnlock(vm);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-04 22:00:14 +00:00
|
|
|
void virNetworkObjLock(virNetworkObjPtr obj)
|
|
|
|
{
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexLock(&obj->lock);
|
2008-12-04 22:00:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void virNetworkObjUnlock(virNetworkObjPtr obj)
|
|
|
|
{
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexUnlock(&obj->lock);
|
2008-12-04 20:53:20 +00:00
|
|
|
}
|
2012-09-04 15:55:17 +00:00
|
|
|
|
|
|
|
#define MATCH(FLAG) (flags & (FLAG))
|
|
|
|
static bool
|
2012-10-17 09:23:12 +00:00
|
|
|
virNetworkMatch(virNetworkObjPtr netobj,
|
|
|
|
unsigned int flags)
|
2012-09-04 15:55:17 +00:00
|
|
|
{
|
|
|
|
/* filter by active state */
|
|
|
|
if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) &&
|
|
|
|
!((MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE) &&
|
|
|
|
virNetworkObjIsActive(netobj)) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_NETWORKS_INACTIVE) &&
|
|
|
|
!virNetworkObjIsActive(netobj))))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* filter by persistence */
|
|
|
|
if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_PERSISTENT) &&
|
|
|
|
!((MATCH(VIR_CONNECT_LIST_NETWORKS_PERSISTENT) &&
|
|
|
|
netobj->persistent) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_NETWORKS_TRANSIENT) &&
|
|
|
|
!netobj->persistent)))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* filter by autostart option */
|
|
|
|
if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_AUTOSTART) &&
|
|
|
|
!((MATCH(VIR_CONNECT_LIST_NETWORKS_AUTOSTART) &&
|
|
|
|
netobj->autostart) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART) &&
|
|
|
|
!netobj->autostart)))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#undef MATCH
|
|
|
|
|
|
|
|
int
|
2013-06-26 15:42:27 +00:00
|
|
|
virNetworkObjListExport(virConnectPtr conn,
|
|
|
|
virNetworkObjList netobjs,
|
|
|
|
virNetworkPtr **nets,
|
|
|
|
virNetworkObjListFilter filter,
|
|
|
|
unsigned int flags)
|
2012-09-04 15:55:17 +00:00
|
|
|
{
|
|
|
|
virNetworkPtr *tmp_nets = NULL;
|
|
|
|
virNetworkPtr net = NULL;
|
|
|
|
int nnets = 0;
|
|
|
|
int ret = -1;
|
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-09-04 15:55:17 +00:00
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (nets && VIR_ALLOC_N(tmp_nets, netobjs.count + 1) < 0)
|
|
|
|
goto cleanup;
|
2012-09-04 15:55:17 +00:00
|
|
|
|
|
|
|
for (i = 0; i < netobjs.count; i++) {
|
|
|
|
virNetworkObjPtr netobj = netobjs.objs[i];
|
|
|
|
virNetworkObjLock(netobj);
|
2013-06-26 15:42:27 +00:00
|
|
|
if ((!filter || filter(conn, netobj->def)) &&
|
|
|
|
virNetworkMatch(netobj, flags)) {
|
2012-09-04 15:55:17 +00:00
|
|
|
if (nets) {
|
|
|
|
if (!(net = virGetNetwork(conn,
|
|
|
|
netobj->def->name,
|
|
|
|
netobj->def->uuid))) {
|
|
|
|
virNetworkObjUnlock(netobj);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
tmp_nets[nnets] = net;
|
|
|
|
}
|
|
|
|
nnets++;
|
|
|
|
}
|
|
|
|
virNetworkObjUnlock(netobj);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tmp_nets) {
|
|
|
|
/* trim the array to the final size */
|
|
|
|
ignore_value(VIR_REALLOC_N(tmp_nets, nnets + 1));
|
|
|
|
*nets = tmp_nets;
|
|
|
|
tmp_nets = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = nnets;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (tmp_nets) {
|
|
|
|
for (i = 0; i < nnets; i++) {
|
|
|
|
if (tmp_nets[i])
|
|
|
|
virNetworkFree(tmp_nets[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(tmp_nets);
|
|
|
|
return ret;
|
|
|
|
}
|