2008-07-11 10:48:34 +00:00
|
|
|
/*
|
|
|
|
* network_conf.c: network XML handling
|
|
|
|
*
|
2011-12-14 10:50:23 +00:00
|
|
|
* Copyright (C) 2006-2012 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
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
* 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>
|
|
|
|
|
2008-11-04 22:30:33 +00:00
|
|
|
#include "virterror_internal.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"
|
2008-07-11 10:48:34 +00:00
|
|
|
#include "memory.h"
|
|
|
|
#include "xml.h"
|
|
|
|
#include "uuid.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "buf.h"
|
2008-08-20 12:50:29 +00:00
|
|
|
#include "c-ctype.h"
|
2011-07-19 18:32:58 +00:00
|
|
|
#include "virfile.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
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
VIR_ENUM_DECL(virNetworkForward)
|
|
|
|
|
|
|
|
VIR_ENUM_IMPL(virNetworkForward,
|
|
|
|
VIR_NETWORK_FORWARD_LAST,
|
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
|
|
|
"none", "nat", "route", "bridge", "private", "vepa", "passthrough" )
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2010-03-01 23:38:28 +00:00
|
|
|
#define virNetworkReportError(code, ...) \
|
2011-04-16 08:30:22 +00:00
|
|
|
virReportErrorHelper(VIR_FROM_NETWORK, code, __FILE__, \
|
2010-03-01 23:38:28 +00:00
|
|
|
__FUNCTION__, __LINE__, __VA_ARGS__)
|
2008-07-11 10:48:34 +00:00
|
|
|
|
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)
|
|
|
|
{
|
2008-10-10 14:50:26 +00:00
|
|
|
unsigned int i;
|
|
|
|
|
2008-12-04 22:00:14 +00:00
|
|
|
for (i = 0 ; i < nets->count ; i++) {
|
|
|
|
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)
|
|
|
|
{
|
2008-10-10 14:50:26 +00:00
|
|
|
unsigned int i;
|
|
|
|
|
2008-12-04 22:00:14 +00:00
|
|
|
for (i = 0 ; i < nets->count ; i++) {
|
|
|
|
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);
|
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)
|
|
|
|
{
|
|
|
|
VIR_FREE(def->dev);
|
|
|
|
}
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
static void virNetworkIpDefClear(virNetworkIpDefPtr def)
|
|
|
|
{
|
|
|
|
int ii;
|
|
|
|
|
|
|
|
VIR_FREE(def->family);
|
|
|
|
VIR_FREE(def->ranges);
|
|
|
|
|
|
|
|
for (ii = 0 ; ii < def->nhosts && def->hosts ; ii++) {
|
|
|
|
VIR_FREE(def->hosts[ii].mac);
|
|
|
|
VIR_FREE(def->hosts[ii].name);
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(def->hosts);
|
|
|
|
VIR_FREE(def->tftproot);
|
|
|
|
VIR_FREE(def->bootfile);
|
|
|
|
}
|
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
static void virNetworkDNSDefFree(virNetworkDNSDefPtr def)
|
|
|
|
{
|
|
|
|
if (def) {
|
|
|
|
if (def->txtrecords) {
|
|
|
|
while (def->ntxtrecords--) {
|
|
|
|
VIR_FREE(def->txtrecords[def->ntxtrecords].name);
|
|
|
|
VIR_FREE(def->txtrecords[def->ntxtrecords].value);
|
|
|
|
}
|
|
|
|
}
|
2011-08-11 03:28:05 +00:00
|
|
|
VIR_FREE(def->txtrecords);
|
2011-06-24 10:04:40 +00:00
|
|
|
if (def->nhosts) {
|
|
|
|
while (def->nhosts--) {
|
|
|
|
while (def->hosts[def->nhosts].nnames--)
|
|
|
|
VIR_FREE(def->hosts[def->nhosts].names[def->hosts[def->nhosts].nnames]);
|
|
|
|
VIR_FREE(def->hosts[def->nhosts].names);
|
|
|
|
}
|
|
|
|
}
|
2011-08-11 03:28:05 +00:00
|
|
|
VIR_FREE(def->hosts);
|
2012-01-02 14:23:54 +00:00
|
|
|
if (def->nsrvrecords) {
|
|
|
|
while (def->nsrvrecords--) {
|
|
|
|
VIR_FREE(def->srvrecords[def->nsrvrecords].domain);
|
|
|
|
VIR_FREE(def->srvrecords[def->nsrvrecords].service);
|
|
|
|
VIR_FREE(def->srvrecords[def->nsrvrecords].protocol);
|
|
|
|
VIR_FREE(def->srvrecords[def->nsrvrecords].target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(def->srvrecords);
|
2011-06-24 10:04:36 +00:00
|
|
|
VIR_FREE(def);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
void virNetworkDefFree(virNetworkDefPtr def)
|
|
|
|
{
|
2010-11-17 18:36:19 +00:00
|
|
|
int ii;
|
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
|
|
|
|
2011-12-14 10:50:23 +00:00
|
|
|
for (ii = 0 ; ii < def->nForwardPfs && def->forwardPfs ; ii++) {
|
|
|
|
virNetworkForwardIfDefClear(&def->forwardPfs[ii]);
|
|
|
|
}
|
|
|
|
VIR_FREE(def->forwardPfs);
|
|
|
|
|
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
|
|
|
for (ii = 0 ; ii < def->nForwardIfs && def->forwardIfs ; ii++) {
|
|
|
|
virNetworkForwardIfDefClear(&def->forwardIfs[ii]);
|
|
|
|
}
|
|
|
|
VIR_FREE(def->forwardIfs);
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
for (ii = 0 ; ii < def->nips && def->ips ; ii++) {
|
|
|
|
virNetworkIpDefClear(&def->ips[ii]);
|
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
|
|
|
|
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
|
|
|
for (ii = 0; ii < def->nPortGroups && def->portGroups; ii++) {
|
|
|
|
virPortGroupDefClear(&def->portGroups[ii]);
|
|
|
|
}
|
|
|
|
VIR_FREE(def->portGroups);
|
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
virNetworkDNSDefFree(def->dns);
|
|
|
|
|
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);
|
2011-07-22 14:07:25 +00:00
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
VIR_FREE(def);
|
|
|
|
}
|
|
|
|
|
|
|
|
void virNetworkObjFree(virNetworkObjPtr net)
|
|
|
|
{
|
|
|
|
if (!net)
|
|
|
|
return;
|
|
|
|
|
|
|
|
virNetworkDefFree(net->def);
|
|
|
|
virNetworkDefFree(net->newDef);
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0 ; i < nets->count ; i++)
|
|
|
|
virNetworkObjFree(nets->objs[i]);
|
|
|
|
|
|
|
|
VIR_FREE(nets->objs);
|
|
|
|
nets->count = 0;
|
|
|
|
}
|
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkObjPtr virNetworkAssignDef(virNetworkObjListPtr nets,
|
2008-07-11 10:48:34 +00:00
|
|
|
const virNetworkDefPtr def)
|
|
|
|
{
|
|
|
|
virNetworkObjPtr network;
|
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
if ((network = virNetworkFindByName(nets, def->name))) {
|
Rename internal APis
Rename virDomainIsActive to virDomainObjIsActive, and
virInterfaceIsActive to virInterfaceObjIsActive and finally
virNetworkIsActive to virNetworkObjIsActive.
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/conf/interface_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/lxc/lxc_driver.c,
src/network/bridge_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/qemu/qemu_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c: Update for
renamed APIs.
2009-10-20 14:51:03 +00:00
|
|
|
if (!virNetworkObjIsActive(network)) {
|
2008-07-11 10:48:34 +00:00
|
|
|
virNetworkDefFree(network->def);
|
|
|
|
network->def = def;
|
|
|
|
} else {
|
2010-05-17 20:38:59 +00:00
|
|
|
virNetworkDefFree(network->newDef);
|
2008-07-11 10:48:34 +00:00
|
|
|
network->newDef = def;
|
|
|
|
}
|
|
|
|
|
|
|
|
return network;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_ALLOC(network) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-07-11 10:48:34 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-01-15 19:56:05 +00:00
|
|
|
if (virMutexInit(&network->lock) < 0) {
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-01-15 19:56:05 +00:00
|
|
|
"%s", _("cannot initialize mutex"));
|
|
|
|
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;
|
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
if (VIR_REALLOC_N(nets->objs, nets->count + 1) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-10-10 14:50:26 +00:00
|
|
|
VIR_FREE(network);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
nets->objs[nets->count] = network;
|
|
|
|
nets->count++;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
return network;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-10-10 14:50:26 +00:00
|
|
|
void virNetworkRemoveInactive(virNetworkObjListPtr nets,
|
2008-07-11 10:48:34 +00:00
|
|
|
const virNetworkObjPtr net)
|
|
|
|
{
|
2008-10-10 14:50:26 +00:00
|
|
|
unsigned int i;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2008-12-04 22:00:14 +00:00
|
|
|
virNetworkObjUnlock(net);
|
2008-10-10 14:50:26 +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)
|
|
|
|
{
|
|
|
|
int ii;
|
|
|
|
|
|
|
|
if (!def->ips || n >= def->nips)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (family == AF_UNSPEC) {
|
|
|
|
return &def->ips[n];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find the nth ip of type "family" */
|
|
|
|
for (ii = 0; ii < def->nips; ii++) {
|
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->ips[ii].address, family)
|
2010-11-17 18:36:19 +00:00
|
|
|
&& (n-- <= 0)) {
|
|
|
|
return &def->ips[ii];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* 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
|
|
|
{
|
2010-11-17 18:36:19 +00:00
|
|
|
if (def->prefix > 0) {
|
|
|
|
return def->prefix;
|
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
|
|
|
} else if (VIR_SOCKET_ADDR_VALID(&def->netmask)) {
|
|
|
|
return virSocketAddrGetNumNetmaskBits(&def->netmask);
|
|
|
|
} else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) {
|
2010-11-26 22:20:37 +00:00
|
|
|
/* Return the natural prefix for the network's ip address.
|
|
|
|
* On Linux we could use the IN_CLASSx() macros, but those
|
|
|
|
* aren't guaranteed on all platforms, so we just deal with
|
|
|
|
* the bits ourselves.
|
|
|
|
*/
|
|
|
|
unsigned char octet
|
2010-11-17 18:36:19 +00:00
|
|
|
= ntohl(def->address.data.inet4.sin_addr.s_addr) >> 24;
|
2010-11-26 22:20:37 +00:00
|
|
|
if ((octet & 0x80) == 0) {
|
|
|
|
/* Class A network */
|
|
|
|
return 8;
|
|
|
|
} else if ((octet & 0xC0) == 0x80) {
|
|
|
|
/* Class B network */
|
|
|
|
return 16;
|
|
|
|
} else if ((octet & 0xE0) == 0xC0) {
|
|
|
|
/* Class C network */
|
|
|
|
return 24;
|
|
|
|
}
|
|
|
|
return -1;
|
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
|
|
|
} else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
|
2010-11-17 18:36:19 +00:00
|
|
|
return 64;
|
2010-11-26 22:20:37 +00:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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
|
2011-01-03 21:47:17 +00:00
|
|
|
virNetworkDHCPRangeDefParseXML(const char *networkName,
|
|
|
|
virNetworkIpDefPtr def,
|
2010-11-17 18:36:19 +00:00
|
|
|
xmlNodePtr node)
|
|
|
|
{
|
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")) {
|
2009-11-06 16:50:54 +00:00
|
|
|
char *start, *end;
|
|
|
|
virSocketAddr saddr, eaddr;
|
|
|
|
int range;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2010-11-24 20:08:55 +00:00
|
|
|
if (!(start = virXMLPropString(cur, "start"))) {
|
2008-08-20 12:50:29 +00:00
|
|
|
cur = cur->next;
|
|
|
|
continue;
|
|
|
|
}
|
2010-11-24 20:08:55 +00:00
|
|
|
if (!(end = virXMLPropString(cur, "end"))) {
|
|
|
|
VIR_FREE(start);
|
2008-08-20 12:50:29 +00:00
|
|
|
cur = cur->next;
|
2009-11-06 16:50:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
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 (virSocketAddrParse(&saddr, start, AF_UNSPEC) < 0) {
|
2010-11-24 20:08:55 +00:00
|
|
|
VIR_FREE(start);
|
|
|
|
VIR_FREE(end);
|
2010-10-20 14:20:37 +00:00
|
|
|
return -1;
|
2009-11-06 16:50:54 +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 (virSocketAddrParse(&eaddr, end, AF_UNSPEC) < 0) {
|
2010-11-24 20:08:55 +00:00
|
|
|
VIR_FREE(start);
|
|
|
|
VIR_FREE(end);
|
2010-10-20 14:20:37 +00:00
|
|
|
return -1;
|
2009-11-06 16:50:54 +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
|
|
|
range = virSocketAddrGetRange(&saddr, &eaddr);
|
2009-11-06 16:50:54 +00:00
|
|
|
if (range < 0) {
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
2011-01-03 21:47:17 +00:00
|
|
|
_("Invalid dhcp range '%s' to '%s' in network '%s'"),
|
|
|
|
start, end, networkName);
|
2010-11-24 20:08:55 +00:00
|
|
|
VIR_FREE(start);
|
|
|
|
VIR_FREE(end);
|
2010-10-20 14:20:37 +00:00
|
|
|
return -1;
|
2008-08-20 12:50:29 +00:00
|
|
|
}
|
2010-11-24 20:29:38 +00:00
|
|
|
VIR_FREE(start);
|
|
|
|
VIR_FREE(end);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2008-08-20 12:50:29 +00:00
|
|
|
if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-08-20 12:50:29 +00:00
|
|
|
return -1;
|
|
|
|
}
|
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->ranges[def->nranges].start = saddr;
|
|
|
|
def->ranges[def->nranges].end = eaddr;
|
2008-08-20 12:50:29 +00:00
|
|
|
def->nranges++;
|
|
|
|
} else if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "host")) {
|
2010-11-24 20:08:55 +00:00
|
|
|
char *mac, *name, *ip;
|
2008-08-20 12:50:29 +00:00
|
|
|
unsigned char addr[6];
|
2010-10-21 10:13:05 +00:00
|
|
|
virSocketAddr inaddr;
|
2008-08-20 12:50:29 +00:00
|
|
|
|
2010-11-24 20:08:55 +00:00
|
|
|
mac = virXMLPropString(cur, "mac");
|
2008-08-20 12:50:29 +00:00
|
|
|
if ((mac != NULL) &&
|
2010-11-24 20:08:55 +00:00
|
|
|
(virParseMacAddr(mac, &addr[0]) != 0)) {
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
2011-01-03 21:47:17 +00:00
|
|
|
_("Cannot parse MAC address '%s' in network '%s'"),
|
|
|
|
mac, networkName);
|
2008-08-20 12:50:29 +00:00
|
|
|
VIR_FREE(mac);
|
|
|
|
}
|
2010-11-24 20:08:55 +00:00
|
|
|
name = virXMLPropString(cur, "name");
|
2008-08-20 12:50:29 +00:00
|
|
|
if ((name != NULL) && (!c_isalpha(name[0]))) {
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
2011-01-03 21:47:17 +00:00
|
|
|
_("Cannot use name address '%s' in network '%s'"),
|
|
|
|
name, networkName);
|
2008-08-20 12:50:29 +00:00
|
|
|
VIR_FREE(name);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* You need at least one MAC address or one host name
|
|
|
|
*/
|
|
|
|
if ((mac == NULL) && (name == NULL)) {
|
2011-01-03 21:47:17 +00:00
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Static host definition in network '%s' must have mac or name attribute"),
|
|
|
|
networkName);
|
|
|
|
return -1;
|
2008-08-20 12:50:29 +00:00
|
|
|
}
|
2010-11-24 20:08:55 +00:00
|
|
|
ip = virXMLPropString(cur, "ip");
|
2011-01-03 21:47:17 +00:00
|
|
|
if ((ip == NULL) ||
|
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, ip, AF_UNSPEC) < 0)) {
|
2011-01-03 21:47:17 +00:00
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing IP address in static host definition for network '%s'"),
|
|
|
|
networkName);
|
2008-08-20 12:50:29 +00:00
|
|
|
VIR_FREE(ip);
|
|
|
|
VIR_FREE(mac);
|
|
|
|
VIR_FREE(name);
|
2011-01-03 21:47:17 +00:00
|
|
|
return -1;
|
2008-08-20 12:50:29 +00:00
|
|
|
}
|
2010-11-24 20:29:38 +00:00
|
|
|
VIR_FREE(ip);
|
2008-08-20 12:50:29 +00:00
|
|
|
if (VIR_REALLOC_N(def->hosts, def->nhosts + 1) < 0) {
|
|
|
|
VIR_FREE(mac);
|
|
|
|
VIR_FREE(name);
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-08-20 12:50:29 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2010-11-24 20:08:55 +00:00
|
|
|
def->hosts[def->nhosts].mac = mac;
|
|
|
|
def->hosts[def->nhosts].name = name;
|
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->hosts[def->nhosts].ip = inaddr;
|
2008-08-20 12:50:29 +00:00
|
|
|
def->nhosts++;
|
2009-09-21 20:50:25 +00:00
|
|
|
|
|
|
|
} else if (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
|
|
|
|
virNetworkDNSHostsDefParseXML(virNetworkDNSDefPtr def,
|
|
|
|
xmlNodePtr node)
|
|
|
|
{
|
|
|
|
xmlNodePtr cur;
|
|
|
|
char *ip;
|
|
|
|
virSocketAddr inaddr;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (def->hosts == NULL) {
|
|
|
|
if (VIR_ALLOC(def->hosts) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
def->nhosts = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ip = virXMLPropString(node, "ip")) ||
|
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, ip, AF_UNSPEC) < 0)) {
|
2011-06-24 10:04:40 +00:00
|
|
|
virNetworkReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing IP address in DNS host definition"));
|
|
|
|
VIR_FREE(ip);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(ip);
|
|
|
|
|
|
|
|
if (VIR_REALLOC_N(def->hosts, def->nhosts + 1) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->hosts[def->nhosts].ip = inaddr;
|
|
|
|
def->hosts[def->nhosts].nnames = 0;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(def->hosts[def->nhosts].names) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
|
|
|
if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "hostname")) {
|
|
|
|
if (cur->children != NULL) {
|
|
|
|
if (VIR_REALLOC_N(def->hosts[def->nhosts].names, def->hosts[def->nhosts].nnames + 1) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->hosts[def->nhosts].names[def->hosts[def->nhosts].nnames] = strdup((char *)cur->children->content);
|
|
|
|
def->hosts[def->nhosts].nnames++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->nhosts++;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-01-02 14:23:54 +00:00
|
|
|
static int
|
|
|
|
virNetworkDNSSrvDefParseXML(virNetworkDNSDefPtr def,
|
|
|
|
xmlNodePtr cur,
|
|
|
|
xmlXPathContextPtr ctxt)
|
|
|
|
{
|
|
|
|
char *domain;
|
|
|
|
char *service;
|
|
|
|
char *protocol;
|
|
|
|
char *target;
|
|
|
|
int port;
|
|
|
|
int priority;
|
|
|
|
int weight;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (!(service = virXMLPropString(cur, "service"))) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
"%s", _("Missing required service attribute in dns srv record"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strlen(service) > DNS_RECORD_LENGTH_SRV) {
|
|
|
|
char *name = NULL;
|
|
|
|
|
|
|
|
virAsprintf(&name, _("Service name is too long, limit is %d bytes"), DNS_RECORD_LENGTH_SRV);
|
|
|
|
virNetworkReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
"%s", name);
|
|
|
|
free(name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(protocol = virXMLPropString(cur, "protocol"))) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing required protocol attribute in dns srv record '%s'"), service);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check whether protocol value is the supported one */
|
|
|
|
if (STRNEQ(protocol, "tcp") && (STRNEQ(protocol, "udp"))) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Invalid protocol attribute value '%s'"), protocol);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_REALLOC_N(def->srvrecords, def->nsrvrecords + 1) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->srvrecords[def->nsrvrecords].service = service;
|
|
|
|
def->srvrecords[def->nsrvrecords].protocol = protocol;
|
|
|
|
def->srvrecords[def->nsrvrecords].domain = NULL;
|
|
|
|
def->srvrecords[def->nsrvrecords].target = NULL;
|
|
|
|
def->srvrecords[def->nsrvrecords].port = 0;
|
|
|
|
def->srvrecords[def->nsrvrecords].priority = 0;
|
|
|
|
def->srvrecords[def->nsrvrecords].weight = 0;
|
|
|
|
|
|
|
|
/* Following attributes are optional but we had to make sure they're NULL above */
|
|
|
|
if ((target = virXMLPropString(cur, "target")) && (domain = virXMLPropString(cur, "domain"))) {
|
|
|
|
xmlNodePtr save_ctxt = ctxt->node;
|
|
|
|
|
|
|
|
ctxt->node = cur;
|
|
|
|
if (virXPathInt("string(./@port)", ctxt, &port))
|
|
|
|
def->srvrecords[def->nsrvrecords].port = port;
|
|
|
|
|
|
|
|
if (virXPathInt("string(./@priority)", ctxt, &priority))
|
|
|
|
def->srvrecords[def->nsrvrecords].priority = priority;
|
|
|
|
|
|
|
|
if (virXPathInt("string(./@weight)", ctxt, &weight))
|
|
|
|
def->srvrecords[def->nsrvrecords].weight = weight;
|
|
|
|
ctxt->node = save_ctxt;
|
|
|
|
|
|
|
|
def->srvrecords[def->nsrvrecords].domain = domain;
|
|
|
|
def->srvrecords[def->nsrvrecords].target = target;
|
|
|
|
def->srvrecords[def->nsrvrecords].port = port;
|
|
|
|
def->srvrecords[def->nsrvrecords].priority = priority;
|
|
|
|
def->srvrecords[def->nsrvrecords].weight = weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->nsrvrecords++;
|
|
|
|
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
error:
|
|
|
|
VIR_FREE(domain);
|
|
|
|
VIR_FREE(service);
|
|
|
|
VIR_FREE(protocol);
|
|
|
|
VIR_FREE(target);
|
|
|
|
|
|
|
|
ret = -1;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
static int
|
|
|
|
virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
|
2012-01-02 14:23:54 +00:00
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt)
|
2011-06-24 10:04:36 +00:00
|
|
|
{
|
|
|
|
xmlNodePtr cur;
|
|
|
|
int ret = -1;
|
|
|
|
char *name = NULL;
|
|
|
|
char *value = NULL;
|
|
|
|
virNetworkDNSDefPtr def = NULL;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(def) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
|
|
|
if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "txt")) {
|
|
|
|
if (!(name = virXMLPropString(cur, "name"))) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
"%s", _("Missing required name attribute in dns txt record"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (!(value = virXMLPropString(cur, "value"))) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("Missing required value attribute in dns txt record '%s'"), name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strchr(name, ' ') != NULL) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_DETAIL,
|
|
|
|
_("spaces are not allowed in DNS TXT record names (name is '%s')"), name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_REALLOC_N(def->txtrecords, def->ntxtrecords + 1) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->txtrecords[def->ntxtrecords].name = name;
|
|
|
|
def->txtrecords[def->ntxtrecords].value = value;
|
|
|
|
def->ntxtrecords++;
|
|
|
|
name = NULL;
|
|
|
|
value = NULL;
|
2012-01-02 14:23:54 +00:00
|
|
|
} else if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "srv")) {
|
|
|
|
ret = virNetworkDNSSrvDefParseXML(def, cur, ctxt);
|
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
2011-06-24 10:04:40 +00:00
|
|
|
} else if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "host")) {
|
|
|
|
ret = virNetworkDNSHostsDefParseXML(def, cur);
|
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
2011-06-24 10:04:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
error:
|
|
|
|
if (ret < 0) {
|
|
|
|
VIR_FREE(name);
|
|
|
|
VIR_FREE(value);
|
|
|
|
virNetworkDNSDefFree(def);
|
|
|
|
} else {
|
|
|
|
*dnsdef = def;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-21 20:50:25 +00:00
|
|
|
static int
|
2010-11-17 18:36:19 +00:00
|
|
|
virNetworkIPParseXML(const char *networkName,
|
|
|
|
virNetworkIpDefPtr def,
|
|
|
|
xmlNodePtr node,
|
|
|
|
xmlXPathContextPtr ctxt)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
unsigned long prefix;
|
|
|
|
int result = -1;
|
|
|
|
|
|
|
|
save = ctxt->node;
|
|
|
|
ctxt->node = node;
|
|
|
|
|
|
|
|
/* grab raw data from XML */
|
|
|
|
def->family = virXPathString("string(./@family)", ctxt);
|
|
|
|
address = virXPathString("string(./@address)", ctxt);
|
|
|
|
if (virXPathULong("string(./@prefix)", ctxt, &prefix) < 0)
|
|
|
|
def->prefix = 0;
|
|
|
|
else
|
|
|
|
def->prefix = prefix;
|
|
|
|
|
|
|
|
netmask = virXPathString("string(./@netmask)", ctxt);
|
|
|
|
|
|
|
|
if (address) {
|
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 (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) {
|
2010-11-17 18:36:19 +00:00
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Bad address '%s' in definition of network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
}
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
/* validate family vs. address */
|
|
|
|
if (def->family == NULL) {
|
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))) {
|
2010-11-17 18:36:19 +00:00
|
|
|
virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("no family specified for non-IPv4 address address '%s' in network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} else if (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)) {
|
2010-11-17 18:36:19 +00:00
|
|
|
virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("family 'ipv4' specified for non-IPv4 address '%s' in network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} 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)) {
|
2010-11-17 18:36:19 +00:00
|
|
|
virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("family 'ipv6' specified for non-IPv6 address '%s' in network '%s'"),
|
|
|
|
address, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Unrecognized family '%s' in definition of network '%s'"),
|
|
|
|
def->family, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
2009-09-21 20:50:25 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
/* parse/validate netmask */
|
|
|
|
if (netmask) {
|
|
|
|
if (address == NULL) {
|
|
|
|
/* netmask is meaningless without an address */
|
|
|
|
virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("netmask specified without address in network '%s'"),
|
|
|
|
networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
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)) {
|
2010-11-17 18:36:19 +00:00
|
|
|
virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("netmask not supported for address '%s' in network '%s' (IPv4 only)"),
|
|
|
|
address, networkName);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (def->prefix > 0) {
|
|
|
|
/* can't have both netmask and prefix at the same time */
|
|
|
|
virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("network '%s' cannot have both prefix='%u' and a netmask"),
|
|
|
|
networkName, def->prefix);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
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 (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0)
|
2010-11-17 18:36:19 +00:00
|
|
|
goto error;
|
|
|
|
|
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-17 18:36:19 +00:00
|
|
|
virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("network '%s' has invalid netmask '%s' for address '%s' (both must be IPv4)"),
|
|
|
|
networkName, netmask, address);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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)) {
|
2010-11-17 18:36:19 +00:00
|
|
|
/* parse IPv4-related info */
|
|
|
|
cur = node->children;
|
|
|
|
while (cur != NULL) {
|
|
|
|
if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "dhcp")) {
|
2011-01-03 21:47:17 +00:00
|
|
|
result = virNetworkDHCPRangeDefParseXML(networkName, def, cur);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (result)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
} else if (cur->type == XML_ELEMENT_NODE &&
|
|
|
|
xmlStrEqual(cur->name, BAD_CAST "tftp")) {
|
|
|
|
char *root;
|
|
|
|
|
|
|
|
if (!(root = virXMLPropString(cur, "root"))) {
|
|
|
|
cur = cur->next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->tftproot = (char *)root;
|
2009-09-21 20:50:25 +00:00
|
|
|
}
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
cur = cur->next;
|
2009-09-21 20:50:25 +00:00
|
|
|
}
|
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;
|
|
|
|
|
|
|
|
error:
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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;
|
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);
|
|
|
|
isDefault = virXPathString("string(./@default)", ctxt);
|
|
|
|
def->isDefault = isDefault && STRCASEEQ(isDefault, "yes");
|
|
|
|
|
|
|
|
virtPortNode = virXPathNode("./virtualport", ctxt);
|
|
|
|
if (virtPortNode &&
|
2011-11-02 14:53:35 +00:00
|
|
|
(!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode))))
|
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-07-26 12:42:37 +00:00
|
|
|
bandwidth_node = virXPathNode("./bandwidth", ctxt);
|
|
|
|
if (bandwidth_node &&
|
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
|
|
|
!(def->bandwidth = virNetDevBandwidthParse(bandwidth_node))) {
|
2011-07-26 12:42:37 +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
|
|
|
result = 0;
|
|
|
|
error:
|
|
|
|
if (result < 0) {
|
|
|
|
virPortGroupDefClear(def);
|
|
|
|
}
|
|
|
|
VIR_FREE(isDefault);
|
|
|
|
|
|
|
|
ctxt->node = save;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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;
|
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;
|
|
|
|
xmlNodePtr *forwardIfNodes = NULL;
|
2011-12-14 10:50:23 +00:00
|
|
|
xmlNodePtr *forwardPfNodes = NULL;
|
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;
|
2011-12-14 10:50:23 +00:00
|
|
|
int nIps, nPortGroups, nForwardIfs, nForwardPfs;
|
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 *forwardDev = NULL;
|
|
|
|
xmlNodePtr save = ctxt->node;
|
2011-07-22 14:07:25 +00:00
|
|
|
xmlNodePtr bandwidthNode = NULL;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
if (VIR_ALLOC(def) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
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) {
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(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)) {
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-01-20 17:13:33 +00:00
|
|
|
"%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);
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
2008-07-11 10:48:34 +00:00
|
|
|
"%s", _("malformed uuid element"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
}
|
|
|
|
|
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 &&
|
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
|
|
|
(def->bandwidth = virNetDevBandwidthParse(bandwidthNode)) == NULL)
|
2011-07-22 14:07:25 +00:00
|
|
|
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);
|
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) {
|
|
|
|
if (virParseMacAddr(tmp, def->mac) < 0) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid bridge mac address '%s' in network '%s'"),
|
|
|
|
tmp, def->name);
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
def->mac_specified = true;
|
|
|
|
}
|
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
dnsNode = virXPathNode("./dns", ctxt);
|
|
|
|
if (dnsNode != NULL) {
|
2012-01-02 14:23:54 +00:00
|
|
|
if (virNetworkDNSDefParseXML(&def->dns, dnsNode, ctxt) < 0)
|
2011-06-24 10:04:36 +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
|
|
|
virtPortNode = virXPathNode("./virtualport", ctxt);
|
|
|
|
if (virtPortNode &&
|
2011-11-02 14:53:35 +00:00
|
|
|
(!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode))))
|
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;
|
|
|
|
|
|
|
|
nPortGroups = virXPathNodeSet("./portgroup", ctxt, &portGroupNodes);
|
|
|
|
if (nPortGroups < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (nPortGroups > 0) {
|
|
|
|
int ii;
|
|
|
|
|
|
|
|
/* allocate array to hold all the portgroups */
|
|
|
|
if (VIR_ALLOC_N(def->portGroups, nPortGroups) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
/* parse each portgroup */
|
|
|
|
for (ii = 0; ii < nPortGroups; ii++) {
|
|
|
|
int ret = virNetworkPortGroupParseXML(&def->portGroups[ii],
|
|
|
|
portGroupNodes[ii], ctxt);
|
|
|
|
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) {
|
|
|
|
int ii;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
/* allocate array to hold all the addrs */
|
|
|
|
if (VIR_ALLOC_N(def->ips, nIps) < 0) {
|
|
|
|
virReportOOMError();
|
2008-07-11 10:48:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2010-11-17 18:36:19 +00:00
|
|
|
/* parse each addr */
|
|
|
|
for (ii = 0; ii < nIps; ii++) {
|
|
|
|
int ret = virNetworkIPParseXML(def->name, &def->ips[ii],
|
|
|
|
ipNodes[ii], ctxt);
|
|
|
|
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
|
|
|
|
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);
|
|
|
|
if (!forwardNode) {
|
|
|
|
def->forwardType = VIR_NETWORK_FORWARD_NONE;
|
|
|
|
def->stp = (stp && STREQ(stp, "off")) ? 0 : 1;
|
|
|
|
} else {
|
|
|
|
ctxt->node = forwardNode;
|
|
|
|
tmp = virXPathString("string(./@mode)", ctxt);
|
2008-07-11 10:48:34 +00:00
|
|
|
if (tmp) {
|
|
|
|
if ((def->forwardType = virNetworkForwardTypeFromString(tmp)) < 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
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
2008-07-11 10:48:34 +00:00
|
|
|
_("unknown forwarding type '%s'"), tmp);
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
} else {
|
|
|
|
def->forwardType = VIR_NETWORK_FORWARD_NAT;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
forwardDev = virXPathString("string(./@dev)", ctxt);
|
2008-07-11 10:48:34 +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
|
|
|
/* all of these modes can use a pool of physical interfaces */
|
|
|
|
nForwardIfs = virXPathNodeSet("./interface", ctxt, &forwardIfNodes);
|
2011-12-14 10:50:23 +00:00
|
|
|
nForwardPfs = virXPathNodeSet("./pf", ctxt, &forwardPfNodes);
|
|
|
|
|
|
|
|
if (nForwardIfs < 0 || nForwardPfs < 0) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("No interface pool or SRIOV physical device given"));
|
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
|
|
|
}
|
|
|
|
|
|
|
|
if (nForwardPfs == 1) {
|
|
|
|
if (VIR_ALLOC_N(def->forwardPfs, nForwardPfs) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (forwardDev) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("A forward Dev should not be used when using a SRIOV PF"));
|
|
|
|
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
|
|
|
|
2011-12-14 10:50:23 +00:00
|
|
|
forwardDev = virXMLPropString(*forwardPfNodes, "dev");
|
|
|
|
if (!forwardDev) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing required dev attribute in network '%s' pf element"),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->forwardPfs->usageCount = 0;
|
|
|
|
def->forwardPfs->dev = forwardDev;
|
|
|
|
forwardDev = NULL;
|
|
|
|
def->nForwardPfs++;
|
|
|
|
} else if (nForwardPfs > 1) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Use of more than one physical interface is not allowed"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (nForwardIfs > 0 || forwardDev) {
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
int ii;
|
2008-07-11 10:48:34 +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
|
|
|
/* allocate array to hold all the portgroups */
|
|
|
|
if (VIR_ALLOC_N(def->forwardIfs, MAX(nForwardIfs, 1)) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (forwardDev) {
|
|
|
|
def->forwardIfs[0].usageCount = 0;
|
|
|
|
def->forwardIfs[0].dev = forwardDev;
|
|
|
|
forwardDev = NULL;
|
|
|
|
def->nForwardIfs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* parse each forwardIf */
|
|
|
|
for (ii = 0; ii < nForwardIfs; ii++) {
|
|
|
|
forwardDev = virXMLPropString(forwardIfNodes[ii], "dev");
|
|
|
|
if (!forwardDev) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Missing required dev attribute in network '%s' forward interface element"),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ii == 0) && (def->nForwardIfs == 1)) {
|
|
|
|
/* both forwardDev and an interface element are present.
|
|
|
|
* If they don't match, it's an error. */
|
|
|
|
if (STRNEQ(forwardDev, def->forwardIfs[0].dev)) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("forward dev '%s' must match first interface element dev '%s' in network '%s'"),
|
|
|
|
def->forwardIfs[0].dev,
|
|
|
|
forwardDev, def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(forwardDev);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->forwardIfs[ii].dev = forwardDev;
|
|
|
|
forwardDev = NULL;
|
|
|
|
def->forwardIfs[ii].usageCount = 0;
|
|
|
|
def->nForwardIfs++;
|
|
|
|
}
|
|
|
|
}
|
2011-12-14 10:50:23 +00:00
|
|
|
VIR_FREE(forwardDev);
|
|
|
|
VIR_FREE(forwardPfNodes);
|
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(forwardIfNodes);
|
|
|
|
|
|
|
|
switch (def->forwardType) {
|
|
|
|
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) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("%s forwarding requested, but no IP address provided for network '%s'"),
|
|
|
|
virNetworkForwardTypeToString(def->forwardType),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (def->nForwardIfs > 1) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("multiple forwarding interfaces specified for network '%s', only one is supported"),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
def->stp = (stp && STREQ(stp, "off")) ? 0 : 1;
|
|
|
|
break;
|
|
|
|
case VIR_NETWORK_FORWARD_PRIVATE:
|
|
|
|
case VIR_NETWORK_FORWARD_VEPA:
|
|
|
|
case VIR_NETWORK_FORWARD_PASSTHROUGH:
|
|
|
|
if (def->bridge) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("bridge name not allowed in %s mode (network '%s'"),
|
|
|
|
virNetworkForwardTypeToString(def->forwardType),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
/* fall through to next case */
|
|
|
|
case VIR_NETWORK_FORWARD_BRIDGE:
|
|
|
|
if (def->delay || stp) {
|
|
|
|
virNetworkReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("bridge delay/stp options only allowed in route, nat, and isolated mode, not in %s (network '%s')"),
|
|
|
|
virNetworkForwardTypeToString(def->forwardType),
|
|
|
|
def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(stp);
|
|
|
|
ctxt->node = save;
|
2008-07-11 10:48:34 +00:00
|
|
|
return def;
|
|
|
|
|
|
|
|
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
|
|
|
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);
|
|
|
|
VIR_FREE(forwardIfNodes);
|
2011-12-14 10:50:23 +00:00
|
|
|
VIR_FREE(forwardPfNodes);
|
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(forwardDev);
|
|
|
|
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")) {
|
2011-11-25 12:23:03 +00:00
|
|
|
virNetworkReportError(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;
|
|
|
|
}
|
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
static int
|
|
|
|
virNetworkDNSDefFormat(virBufferPtr buf,
|
|
|
|
virNetworkDNSDefPtr def)
|
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (def == NULL)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
virBufferAddLit(buf, " <dns>\n");
|
|
|
|
|
|
|
|
for (i = 0 ; i < def->ntxtrecords ; i++) {
|
|
|
|
virBufferAsprintf(buf, " <txt name='%s' value='%s' />\n",
|
|
|
|
def->txtrecords[i].name,
|
|
|
|
def->txtrecords[i].value);
|
|
|
|
}
|
|
|
|
|
2012-01-02 14:23:54 +00:00
|
|
|
for (i = 0 ; i < def->nsrvrecords ; i++) {
|
|
|
|
if (def->srvrecords[i].service && def->srvrecords[i].protocol) {
|
|
|
|
virBufferAsprintf(buf, " <srv service='%s' protocol='%s'",
|
|
|
|
def->srvrecords[i].service,
|
|
|
|
def->srvrecords[i].protocol);
|
|
|
|
|
|
|
|
if (def->srvrecords[i].domain)
|
|
|
|
virBufferAsprintf(buf, " domain='%s'", def->srvrecords[i].domain);
|
|
|
|
if (def->srvrecords[i].target)
|
|
|
|
virBufferAsprintf(buf, " target='%s'", def->srvrecords[i].target);
|
|
|
|
if (def->srvrecords[i].port)
|
|
|
|
virBufferAsprintf(buf, " port='%d'", def->srvrecords[i].port);
|
|
|
|
if (def->srvrecords[i].priority)
|
|
|
|
virBufferAsprintf(buf, " priority='%d'", def->srvrecords[i].priority);
|
|
|
|
if (def->srvrecords[i].weight)
|
|
|
|
virBufferAsprintf(buf, " weight='%d'", def->srvrecords[i].weight);
|
|
|
|
|
|
|
|
virBufferAsprintf(buf, "/>\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-24 10:04:40 +00:00
|
|
|
if (def->nhosts) {
|
|
|
|
int ii, j;
|
|
|
|
|
|
|
|
for (ii = 0 ; ii < def->nhosts; ii++) {
|
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
|
|
|
char *ip = virSocketAddrFormat(&def->hosts[ii].ip);
|
2011-06-24 10:04:40 +00:00
|
|
|
|
|
|
|
virBufferAsprintf(buf, " <host ip='%s'>\n", ip);
|
|
|
|
|
|
|
|
for (j = 0; j < def->hosts[ii].nnames; j++)
|
|
|
|
virBufferAsprintf(buf, " <hostname>%s</hostname>\n",
|
|
|
|
def->hosts[ii].names[j]);
|
|
|
|
|
|
|
|
virBufferAsprintf(buf, " </host>\n");
|
2011-06-29 02:45:01 +00:00
|
|
|
VIR_FREE(ip);
|
2011-06-24 10:04:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
virBufferAddLit(buf, " </dns>\n");
|
|
|
|
out:
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
static int
|
|
|
|
virNetworkIpDefFormat(virBufferPtr buf,
|
|
|
|
const virNetworkIpDefPtr def)
|
|
|
|
{
|
|
|
|
int result = -1;
|
|
|
|
|
|
|
|
virBufferAddLit(buf, " <ip");
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
if (def->tftproot) {
|
|
|
|
virBufferEscapeString(buf, " <tftp root='%s' />\n",
|
|
|
|
def->tftproot);
|
|
|
|
}
|
|
|
|
if ((def->nranges || def->nhosts)) {
|
|
|
|
int ii;
|
|
|
|
virBufferAddLit(buf, " <dhcp>\n");
|
|
|
|
for (ii = 0 ; ii < def->nranges ; ii++) {
|
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
|
|
|
char *saddr = virSocketAddrFormat(&def->ranges[ii].start);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (!saddr)
|
|
|
|
goto error;
|
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
|
|
|
char *eaddr = virSocketAddrFormat(&def->ranges[ii].end);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (!eaddr) {
|
|
|
|
VIR_FREE(saddr);
|
|
|
|
goto error;
|
|
|
|
}
|
2011-04-30 16:34:49 +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);
|
|
|
|
}
|
|
|
|
for (ii = 0 ; ii < def->nhosts ; ii++) {
|
|
|
|
virBufferAddLit(buf, " <host ");
|
|
|
|
if (def->hosts[ii].mac)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(buf, "mac='%s' ", def->hosts[ii].mac);
|
2010-11-17 18:36:19 +00:00
|
|
|
if (def->hosts[ii].name)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(buf, "name='%s' ", def->hosts[ii].name);
|
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->hosts[ii].ip)) {
|
|
|
|
char *ipaddr = virSocketAddrFormat(&def->hosts[ii].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) {
|
|
|
|
virBufferEscapeString(buf, " <bootp file='%s' ",
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
|
|
|
virBufferAddLit(buf, " </dhcp>\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
virBufferAddLit(buf, " </ip>\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)
|
|
|
|
{
|
|
|
|
virBufferAsprintf(buf, " <portgroup name='%s'", def->name);
|
|
|
|
if (def->isDefault) {
|
|
|
|
virBufferAddLit(buf, " default='yes'");
|
|
|
|
}
|
|
|
|
virBufferAddLit(buf, ">\n");
|
2011-09-22 18:00:45 +00:00
|
|
|
virBufferAdjustIndent(buf, 4);
|
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);
|
2011-09-22 18:00:45 +00:00
|
|
|
virBufferAdjustIndent(buf, -4);
|
conf: support abstracted interface info in network XML
The network XML is updated in the following ways:
1) The <forward> element can now contain a list of forward interfaces:
<forward .... >
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
</forward>
The first of these takes the place of the dev attribute that is
normally in <forward> - when defining a network you can specify
either one, and on output both will be present. If you specify
both on input, they must match.
2) In addition to forward modes of 'nat' and 'route', these new modes
are supported:
private, passthrough, vepa - when this network is referenced by a
domain's interface, it will have the same effect as if the
interface had been defined as type='direct', e.g.:
<interface type='direct'>
<source mode='${mode}' dev='${dev}>
...
</interface>
where ${mode} is one of the three new modes, and ${dev} is an interface
selected from the list given in <forward>.
bridge - if a <forward> dev (or multiple devs) is defined, and
forward mode is 'bridge' this is just like the modes 'private',
'passthrough', and 'vepa' above. If there is no forward dev
specified but a bridge name is given (e.g. "<bridge
name='br0'/>"), then guest interfaces using this network will use
libvirt's "host bridge" mode, equivalent to this:
<interface type='bridge'>
<source bridge='${bridge-name}'/>
...
</interface>
3) A network can have multiple <portgroup> elements, which may be
selected by the guest interface definition (by adding
"portgroup='${name}'" in the <source> element along with the
network name). Currently a portgroup can only contain a
virtportprofile, but the intent is that other configuration items
may be put there int the future (e.g. bandwidth config). When
building a guest's interface, if the <interface> XML itself has no
virtportprofile, and if the requested network has a portgroup with
a name matching the name given in the <interface> (or if one of the
network's portgroups is marked with the "default='yes'" attribute),
the virtportprofile from that portgroup will be used by the
interface.
4) A network can have a virtportprofile defined at the top level,
which will be used by a guest interface when connecting in one of
the 'direct' modes if the guest interface XML itself hasn't
specified any virtportprofile, and if there are also no matching
portgroups on the network.
2011-07-20 03:01:09 +00:00
|
|
|
virBufferAddLit(buf, " </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
|
|
|
}
|
|
|
|
|
2011-12-14 10:50:40 +00:00
|
|
|
char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
unsigned char *uuid;
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
2010-11-17 18:36:19 +00:00
|
|
|
int ii;
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
virBufferAddLit(&buf, "<network>\n");
|
|
|
|
virBufferEscapeString(&buf, " <name>%s</name>\n", def->name);
|
|
|
|
|
|
|
|
uuid = def->uuid;
|
|
|
|
virUUIDFormat(uuid, uuidstr);
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
|
2008-07-11 10:48:34 +00:00
|
|
|
|
|
|
|
if (def->forwardType != VIR_NETWORK_FORWARD_NONE) {
|
2011-12-14 10:50:23 +00:00
|
|
|
const char *dev = NULL;
|
|
|
|
if (!def->nForwardPfs)
|
|
|
|
dev = virNetworkDefForwardIf(def, 0);
|
2008-07-11 10:48:34 +00:00
|
|
|
const char *mode = virNetworkForwardTypeToString(def->forwardType);
|
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) {
|
|
|
|
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unknown forward type %d in network '%s'"),
|
|
|
|
def->forwardType, def->name);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
virBufferAddLit(&buf, " <forward");
|
2011-12-14 10:50:23 +00:00
|
|
|
virBufferEscapeString(&buf, " dev='%s'", 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
|
|
|
virBufferAsprintf(&buf, " mode='%s'%s>\n", mode,
|
2011-12-14 10:50:23 +00:00
|
|
|
(def->nForwardIfs || def->nForwardPfs) ? "" : "/");
|
|
|
|
|
|
|
|
/* For now, hard-coded to at most 1 forwardPfs */
|
|
|
|
if (def->nForwardPfs)
|
|
|
|
virBufferEscapeString(&buf, " <pf dev='%s'/>\n",
|
|
|
|
def->forwardPfs[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
|
|
|
|
2011-12-14 10:50:40 +00:00
|
|
|
if (def->nForwardIfs &&
|
|
|
|
(!def->nForwardPfs || !(flags & VIR_NETWORK_XML_INACTIVE))) {
|
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
|
|
|
for (ii = 0; ii < def->nForwardIfs; ii++) {
|
2011-12-14 10:50:23 +00:00
|
|
|
virBufferEscapeString(&buf, " <interface dev='%s'/>\n",
|
|
|
|
def->forwardIfs[ii].dev);
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
}
|
2011-12-14 10:50:23 +00:00
|
|
|
if (def->nForwardPfs || def->nForwardIfs)
|
|
|
|
virBufferAddLit(&buf, " </forward>\n");
|
2008-07-11 10:48:34 +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
|
|
|
if (def->forwardType == VIR_NETWORK_FORWARD_NONE ||
|
|
|
|
def->forwardType == VIR_NETWORK_FORWARD_NAT ||
|
|
|
|
def->forwardType == VIR_NETWORK_FORWARD_ROUTE) {
|
|
|
|
|
|
|
|
virBufferAddLit(&buf, " <bridge");
|
|
|
|
if (def->bridge)
|
|
|
|
virBufferEscapeString(&buf, " name='%s'", def->bridge);
|
|
|
|
virBufferAsprintf(&buf, " stp='%s' delay='%ld' />\n",
|
|
|
|
def->stp ? "on" : "off",
|
|
|
|
def->delay);
|
|
|
|
} else if (def->forwardType == VIR_NETWORK_FORWARD_BRIDGE &&
|
|
|
|
def->bridge) {
|
|
|
|
virBufferEscapeString(&buf, " <bridge name='%s' />\n", def->bridge);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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];
|
|
|
|
virFormatMacAddr(def->mac, macaddr);
|
2011-04-30 16:34:49 +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)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, " <domain name='%s'/>\n", def->domain);
|
2009-07-02 14:02:18 +00:00
|
|
|
|
2011-06-24 10:04:36 +00:00
|
|
|
if (virNetworkDNSDefFormat(&buf, def->dns) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2011-09-22 18:00:45 +00:00
|
|
|
virBufferAdjustIndent(&buf, 2);
|
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
|
|
|
if (virNetDevBandwidthFormat(def->bandwidth, &buf) < 0)
|
2011-07-22 14:07:26 +00:00
|
|
|
goto error;
|
2011-09-22 18:00:45 +00:00
|
|
|
virBufferAdjustIndent(&buf, -2);
|
2011-07-22 14:07:26 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
for (ii = 0; ii < def->nips; ii++) {
|
|
|
|
if (virNetworkIpDefFormat(&buf, &def->ips[ii]) < 0)
|
|
|
|
goto error;
|
2008-07-11 10:48:34 +00:00
|
|
|
}
|
|
|
|
|
2011-09-22 18:00:45 +00:00
|
|
|
virBufferAdjustIndent(&buf, 2);
|
2011-11-02 14:53:35 +00:00
|
|
|
if (virNetDevVPortProfileFormat(def->virtPortProfile, &buf) < 0)
|
|
|
|
goto error;
|
2011-09-22 18:00:45 +00:00
|
|
|
virBufferAdjustIndent(&buf, -2);
|
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
|
|
|
|
|
|
|
for (ii = 0; ii < def->nPortGroups; ii++)
|
2011-11-02 14:53:35 +00:00
|
|
|
if (virPortGroupDefFormat(&buf, &def->portGroups[ii]) < 0)
|
|
|
|
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
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
virBufferAddLit(&buf, "</network>\n");
|
|
|
|
|
|
|
|
if (virBufferError(&buf))
|
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
return virBufferContentAndReset(&buf);
|
|
|
|
|
|
|
|
no_memory:
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
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
|
|
|
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)
|
|
|
|
{
|
|
|
|
int ii;
|
|
|
|
for (ii = 0; ii < net->nPortGroups; ii++) {
|
|
|
|
if (portgroup) {
|
|
|
|
if (STREQ(portgroup, net->portGroups[ii].name))
|
|
|
|
return &net->portGroups[ii];
|
|
|
|
} else {
|
|
|
|
if (net->portGroups[ii].isDefault)
|
|
|
|
return &net->portGroups[ii];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
{
|
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;
|
|
|
|
}
|
|
|
|
|
2011-10-27 16:55:47 +00:00
|
|
|
ret = virXMLSaveFile(configFile, def->name, "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;
|
|
|
|
|
2011-12-14 10:50:40 +00:00
|
|
|
if (!(xml = virNetworkDefFormat(def, 0)))
|
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
|
|
|
|
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)) {
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
2008-07-11 10:48:34 +00:00
|
|
|
_("Network config filename '%s'"
|
|
|
|
" does not match network name '%s'"),
|
|
|
|
configFile, 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
|
|
|
if (def->forwardType == VIR_NETWORK_FORWARD_NONE ||
|
|
|
|
def->forwardType == VIR_NETWORK_FORWARD_NAT ||
|
|
|
|
def->forwardType == VIR_NETWORK_FORWARD_ROUTE) {
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
if (!(net = virNetworkAssignDef(nets, def)))
|
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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (virAsprintf(&ret, "%s/%s.xml", dir, name) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-01-20 22:36:10 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
unsigned int ret = 0;
|
|
|
|
|
|
|
|
for (i = 0 ; i < nets->count ; i++) {
|
|
|
|
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 {
|
2010-08-31 20:25:49 +00:00
|
|
|
if (virAsprintf(&newname, template, id) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
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
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
|
2009-03-02 17:37:03 +00:00
|
|
|
_("Bridge generation exceeded max id %d"),
|
|
|
|
MAX_BRIDGE_ID);
|
|
|
|
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)) {
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkReportError(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.
|
|
|
|
*/
|
|
|
|
virGenerateMacAddr((unsigned char[]){ 0x52, 0x54, 0 },
|
|
|
|
def->mac);
|
|
|
|
def->mac_specified = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
unsigned int check_active)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int dupVM = 0;
|
|
|
|
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);
|
|
|
|
virNetworkReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("network '%s' is already defined with uuid %s"),
|
|
|
|
vm->def->name, uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (check_active) {
|
|
|
|
/* UUID & name match, but if VM is already active, refuse it */
|
|
|
|
if (virNetworkObjIsActive(vm)) {
|
|
|
|
virNetworkReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("network is already active as '%s'"),
|
|
|
|
vm->def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dupVM = 1;
|
|
|
|
} 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);
|
|
|
|
virNetworkReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("network '%s' already exists with uuid %s"),
|
|
|
|
def->name, uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = dupVM;
|
|
|
|
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
|
|
|
}
|