mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
conf: add <vlan> element to network and domain interface elements
The following config elements now support a <vlan> subelements: within a domain: <interface>, and the <actual> subelement of <interface> within a network: the toplevel, as well as any <portgroup> Each vlan element must have one or more <tag id='n'/> subelements. If there is more than one tag, it is assumed that vlan trunking is being requested. If trunking is required with only a single tag, the attribute "trunk='yes'" should be added to the toplevel <vlan> element. Some examples: <interface type='hostdev'/> <vlan> <tag id='42'/> </vlan> <mac address='52:54:00:12:34:56'/> ... </interface> <network> <name>vlan-net</name> <vlan trunk='yes'> <tag id='30'/> </vlan> <virtualport type='openvswitch'/> </network> <interface type='network'/> <source network='vlan-net'/> ... </interface> <network> <name>trunk-vlan</name> <vlan> <tag id='42'/> <tag id='43'/> </vlan> ... </network> <network> <name>multi</name> ... <portgroup name='production'/> <vlan> <tag id='42'/> </vlan> </portgroup> <portgroup name='test'/> <vlan> <tag id='666'/> </vlan> </portgroup> </network> <interface type='network'/> <source network='multi' portgroup='test'/> ... </interface> IMPORTANT NOTE: As of this patch there is no backend support for the vlan element for *any* network device type. When support is added in later patches, it will only be for those select network types that support setting up a vlan on the host side, without the guest's involvement. (For example, it will be possible to configure a vlan for a guest connected to an openvswitch bridge, but it won't be possible to do that for one that is connected to a standard Linux host bridge.)
This commit is contained in:
parent
cfbdd005e9
commit
3f9274a524
@ -2857,6 +2857,46 @@ qemu-kvm -net nic,model=? /dev/null
|
|||||||
<span class="since">Since 0.9.4</span>
|
<span class="since">Since 0.9.4</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h5><a name="elementVlanTag">Setting VLAN tag (on supported network types only)</a></h5>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
...
|
||||||
|
<devices>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<b><vlan></b>
|
||||||
|
<b><tag id='42'/></b>
|
||||||
|
<b></vlan></b>
|
||||||
|
<source bridge='ovsbr0'/>
|
||||||
|
<virtualport type='openvswitch'>
|
||||||
|
<parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
||||||
|
</virtualport>
|
||||||
|
</interface>
|
||||||
|
<devices>
|
||||||
|
...</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If (and only if) the network connection used by the guest
|
||||||
|
supports vlan tagging transparent to the guest, an
|
||||||
|
optional <code><vlan></code> element can specify one or
|
||||||
|
more vlan tags to apply to the guest's network
|
||||||
|
traffic <span class="since">Since 0.10.0</span>. (openvswitch
|
||||||
|
and type='hostdev' SR-IOV interfaces do support transparent vlan
|
||||||
|
tagging of guest traffic; everything else, including standard
|
||||||
|
linux bridges and libvirt's own virtual networks, <b>do not</b>
|
||||||
|
support it. 802.1Qbh (vn-link) and 802.1Qbg (VEPA) switches
|
||||||
|
provide their own way (outside of libvirt) to tag guest traffic
|
||||||
|
onto specific vlans.) To allow for specification of multiple
|
||||||
|
tags (in the case of vlan trunking), a
|
||||||
|
subelement, <code><tag%gt;</code>, specifies which vlan tag
|
||||||
|
to use (for example: <code><tag id='42'/></code>. If an
|
||||||
|
interface has more than one <code><vlan></code> element
|
||||||
|
defined, it is assumed that the user wants to do VLAN trunking
|
||||||
|
using all the specified tags. In the case that vlan trunking
|
||||||
|
with a single tag is desired, the optional
|
||||||
|
attribute <code>trunk='yes'</code> can be added to the toplevel
|
||||||
|
vlan element.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h5><a name="elementLink">Modifying virtual link state</a></h5>
|
<h5><a name="elementLink">Modifying virtual link state</a></h5>
|
||||||
<pre>
|
<pre>
|
||||||
...
|
...
|
||||||
|
@ -306,6 +306,56 @@
|
|||||||
<span class="since">Since 0.9.4</span>
|
<span class="since">Since 0.9.4</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h5><a name="elementVlanTag">Setting VLAN tag (on supported network types only)</a></h5>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
...
|
||||||
|
<devices>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<b><vlan trunk='yes'></b>
|
||||||
|
<b><tag id='42'/></b>
|
||||||
|
<b><tag id='47'/></b>
|
||||||
|
<b></vlan></b>
|
||||||
|
<source bridge='ovsbr0'/>
|
||||||
|
<virtualport type='openvswitch'>
|
||||||
|
<parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
||||||
|
</virtualport>
|
||||||
|
</interface>
|
||||||
|
<devices>
|
||||||
|
...</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If (and only if) the network type supports vlan tagging
|
||||||
|
transparent to the guest, an optional <code><vlan></code>
|
||||||
|
element can specify one or more vlan tags to apply to the
|
||||||
|
traffic of all guests using this
|
||||||
|
network <span class="since">Since 0.10.0</span>. (openvswitch
|
||||||
|
and type='hostdev' SR-IOV networks do support transparent vlan
|
||||||
|
tagging of guest traffic; everything else, including standard
|
||||||
|
linux bridges and libvirt's own virtual networks, <b>do not</b>
|
||||||
|
support it. 802.1Qbh (vn-link) and 802.1Qbg (VEPA) switches
|
||||||
|
provide their own way (outside of libvirt) to tag guest traffic
|
||||||
|
onto specific vlans.) As expected, the <code>tag</code>
|
||||||
|
attribute specifies which vlan tag to use. If a network has more
|
||||||
|
than one <code><vlan></code> element defined, it is
|
||||||
|
assumed that the user wants to do VLAN trunking using all the
|
||||||
|
specified tags. In the case that vlan trunking with a single tag
|
||||||
|
is desired, the optional attribute <code>trunk='yes'</code> can
|
||||||
|
be added to the vlan element.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code><vlan></code> elements can also be specified in
|
||||||
|
a <code><portgroup></code> element, as well as directly in
|
||||||
|
a domain's <code><interface></code> element. In the case
|
||||||
|
that a vlan tag is specified in multiple locations, the setting
|
||||||
|
in <code><interface></code> takes precedence, followed by
|
||||||
|
the setting in the <code><portgroup></code> selected by
|
||||||
|
the interface config. The <code><vlan></code>
|
||||||
|
in <code><network></code> will be selected only if none is
|
||||||
|
given in <code><portgroup></code>
|
||||||
|
or <code><interface></code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h5><a name="elementsPortgroup">Portgroups</a></h5>
|
<h5><a name="elementsPortgroup">Portgroups</a></h5>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
@ -1713,6 +1713,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="bandwidth"/>
|
<ref name="bandwidth"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name="vlan"/>
|
||||||
|
</optional>
|
||||||
</interleave>
|
</interleave>
|
||||||
</define>
|
</define>
|
||||||
<!--
|
<!--
|
||||||
|
@ -140,6 +140,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="bandwidth"/>
|
<ref name="bandwidth"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name="vlan"/>
|
||||||
|
</optional>
|
||||||
</interleave>
|
</interleave>
|
||||||
</element>
|
</element>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
@ -187,6 +190,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="bandwidth"/>
|
<ref name="bandwidth"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name="vlan"/>
|
||||||
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
<element name="link">
|
<element name="link">
|
||||||
<attribute name="state">
|
<attribute name="state">
|
||||||
|
@ -184,4 +184,24 @@
|
|||||||
<param name="pattern">(ipv4)|(ipv6)</param>
|
<param name="pattern">(ipv4)|(ipv6)</param>
|
||||||
</data>
|
</data>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<define name="vlan">
|
||||||
|
<element name="vlan">
|
||||||
|
<optional>
|
||||||
|
<attribute name="trunk">
|
||||||
|
<value>yes</value>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<oneOrMore>
|
||||||
|
<element name="tag">
|
||||||
|
<attribute name="id">
|
||||||
|
<data type="unsignedInt">
|
||||||
|
<param name="maxInclusive">4095</param>
|
||||||
|
</data>
|
||||||
|
</attribute>
|
||||||
|
<empty/>
|
||||||
|
</element>
|
||||||
|
</oneOrMore>
|
||||||
|
</element>
|
||||||
|
</define>
|
||||||
</grammar>
|
</grammar>
|
||||||
|
@ -11,6 +11,7 @@ src/conf/domain_conf.c
|
|||||||
src/conf/domain_event.c
|
src/conf/domain_event.c
|
||||||
src/conf/interface_conf.c
|
src/conf/interface_conf.c
|
||||||
src/conf/netdev_bandwidth_conf.c
|
src/conf/netdev_bandwidth_conf.c
|
||||||
|
src/conf/netdev_vlan_conf.c
|
||||||
src/conf/netdev_vport_profile_conf.c
|
src/conf/netdev_vport_profile_conf.c
|
||||||
src/conf/network_conf.c
|
src/conf/network_conf.c
|
||||||
src/conf/node_device_conf.c
|
src/conf/node_device_conf.c
|
||||||
|
@ -144,7 +144,8 @@ LOCK_DRIVER_SANLOCK_SOURCES = \
|
|||||||
|
|
||||||
NETDEV_CONF_SOURCES = \
|
NETDEV_CONF_SOURCES = \
|
||||||
conf/netdev_bandwidth_conf.h conf/netdev_bandwidth_conf.c \
|
conf/netdev_bandwidth_conf.h conf/netdev_bandwidth_conf.c \
|
||||||
conf/netdev_vport_profile_conf.h conf/netdev_vport_profile_conf.c
|
conf/netdev_vport_profile_conf.h conf/netdev_vport_profile_conf.c \
|
||||||
|
conf/netdev_vlan_conf.h conf/netdev_vlan_conf.c
|
||||||
|
|
||||||
# XML configuration format handling sources
|
# XML configuration format handling sources
|
||||||
# Domain driver generic impl APIs
|
# Domain driver generic impl APIs
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "secret_conf.h"
|
#include "secret_conf.h"
|
||||||
#include "netdev_vport_profile_conf.h"
|
#include "netdev_vport_profile_conf.h"
|
||||||
#include "netdev_bandwidth_conf.h"
|
#include "netdev_bandwidth_conf.h"
|
||||||
|
#include "netdev_vlan_conf.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
||||||
|
|
||||||
@ -1030,7 +1031,7 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def)
|
|||||||
|
|
||||||
VIR_FREE(def->virtPortProfile);
|
VIR_FREE(def->virtPortProfile);
|
||||||
virNetDevBandwidthFree(def->bandwidth);
|
virNetDevBandwidthFree(def->bandwidth);
|
||||||
|
virNetDevVlanClear(&def->vlan);
|
||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1091,6 +1092,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
|
|||||||
virNWFilterHashTableFree(def->filterparams);
|
virNWFilterHashTableFree(def->filterparams);
|
||||||
|
|
||||||
virNetDevBandwidthFree(def->bandwidth);
|
virNetDevBandwidthFree(def->bandwidth);
|
||||||
|
virNetDevVlanClear(&def->vlan);
|
||||||
|
|
||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
@ -4365,6 +4367,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
xmlNodePtr save_ctxt = ctxt->node;
|
xmlNodePtr save_ctxt = ctxt->node;
|
||||||
xmlNodePtr bandwidth_node = NULL;
|
xmlNodePtr bandwidth_node = NULL;
|
||||||
|
xmlNodePtr vlanNode;
|
||||||
xmlNodePtr virtPortNode;
|
xmlNodePtr virtPortNode;
|
||||||
char *type = NULL;
|
char *type = NULL;
|
||||||
char *mode = NULL;
|
char *mode = NULL;
|
||||||
@ -4462,6 +4465,10 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
|
|||||||
!(actual->bandwidth = virNetDevBandwidthParse(bandwidth_node)))
|
!(actual->bandwidth = virNetDevBandwidthParse(bandwidth_node)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
vlanNode = virXPathNode("./vlan", ctxt);
|
||||||
|
if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &actual->vlan) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
*def = actual;
|
*def = actual;
|
||||||
actual = NULL;
|
actual = NULL;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -4645,6 +4652,9 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "bandwidth")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "bandwidth")) {
|
||||||
if (!(def->bandwidth = virNetDevBandwidthParse(cur)))
|
if (!(def->bandwidth = virNetDevBandwidthParse(cur)))
|
||||||
goto error;
|
goto error;
|
||||||
|
} else if (xmlStrEqual(cur->name, BAD_CAST "vlan")) {
|
||||||
|
if (virNetDevVlanParse(cur, ctxt, &def->vlan) < 0)
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
@ -11623,8 +11633,10 @@ virDomainActualNetDefFormat(virBufferPtr buf,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
|
||||||
|
return -1;
|
||||||
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
|
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0)
|
if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -11725,8 +11737,10 @@ virDomainNetDefFormat(virBufferPtr buf,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
|
||||||
|
return -1;
|
||||||
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
|
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
virBufferEscapeString(buf, "<script path='%s'/>\n",
|
virBufferEscapeString(buf, "<script path='%s'/>\n",
|
||||||
def->script);
|
def->script);
|
||||||
if (def->ifname &&
|
if (def->ifname &&
|
||||||
@ -15083,6 +15097,17 @@ virDomainNetGetActualBandwidth(virDomainNetDefPtr iface)
|
|||||||
return iface->bandwidth;
|
return iface->bandwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virNetDevVlanPtr
|
||||||
|
virDomainNetGetActualVlan(virDomainNetDefPtr iface)
|
||||||
|
{
|
||||||
|
if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
|
||||||
|
iface->data.network.actual &&
|
||||||
|
iface->data.network.actual->vlan.nTags > 0)
|
||||||
|
return &iface->data.network.actual->vlan;
|
||||||
|
if (iface->vlan.nTags > 0)
|
||||||
|
return &iface->vlan;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return listens[ii] from the appropriate union for the graphics
|
/* Return listens[ii] from the appropriate union for the graphics
|
||||||
* type, or NULL if this is an unsuitable type, or the index is out of
|
* type, or NULL if this is an unsuitable type, or the index is out of
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
# include "virnetdevvportprofile.h"
|
# include "virnetdevvportprofile.h"
|
||||||
# include "virnetdevopenvswitch.h"
|
# include "virnetdevopenvswitch.h"
|
||||||
# include "virnetdevbandwidth.h"
|
# include "virnetdevbandwidth.h"
|
||||||
|
# include "virnetdevvlan.h"
|
||||||
# include "virobject.h"
|
# include "virobject.h"
|
||||||
|
|
||||||
/* forward declarations of all device types, required by
|
/* forward declarations of all device types, required by
|
||||||
@ -781,6 +782,7 @@ struct _virDomainActualNetDef {
|
|||||||
} data;
|
} data;
|
||||||
virNetDevVPortProfilePtr virtPortProfile;
|
virNetDevVPortProfilePtr virtPortProfile;
|
||||||
virNetDevBandwidthPtr bandwidth;
|
virNetDevBandwidthPtr bandwidth;
|
||||||
|
virNetDevVlan vlan;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Stores the virtual network interface configuration */
|
/* Stores the virtual network interface configuration */
|
||||||
@ -845,6 +847,7 @@ struct _virDomainNetDef {
|
|||||||
char *filter;
|
char *filter;
|
||||||
virNWFilterHashTablePtr filterparams;
|
virNWFilterHashTablePtr filterparams;
|
||||||
virNetDevBandwidthPtr bandwidth;
|
virNetDevBandwidthPtr bandwidth;
|
||||||
|
virNetDevVlan vlan;
|
||||||
int linkstate;
|
int linkstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2039,6 +2042,7 @@ virNetDevVPortProfilePtr
|
|||||||
virDomainNetGetActualVirtPortProfile(virDomainNetDefPtr iface);
|
virDomainNetGetActualVirtPortProfile(virDomainNetDefPtr iface);
|
||||||
virNetDevBandwidthPtr
|
virNetDevBandwidthPtr
|
||||||
virDomainNetGetActualBandwidth(virDomainNetDefPtr iface);
|
virDomainNetGetActualBandwidth(virDomainNetDefPtr iface);
|
||||||
|
virNetDevVlanPtr virDomainNetGetActualVlan(virDomainNetDefPtr iface);
|
||||||
|
|
||||||
int virDomainControllerInsert(virDomainDefPtr def,
|
int virDomainControllerInsert(virDomainDefPtr def,
|
||||||
virDomainControllerDefPtr controller);
|
virDomainControllerDefPtr controller);
|
||||||
|
131
src/conf/netdev_vlan_conf.c
Normal file
131
src/conf/netdev_vlan_conf.c
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2012 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Laine Stump <laine@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "netdev_vlan_conf.h"
|
||||||
|
#include "virterror_internal.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr def)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
xmlNodePtr save = ctxt->node;
|
||||||
|
const char *trunk;
|
||||||
|
xmlNodePtr *tagNodes = NULL;
|
||||||
|
int nTags, ii;
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
nTags = virXPathNodeSet("./tag", ctxt, &tagNodes);
|
||||||
|
if (nTags < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (nTags == 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("missing tag id - each <vlan> must have "
|
||||||
|
"at least one <tag id='n'/> subelement"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(def->tag, nTags) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ii = 0; ii < nTags; ii++) {
|
||||||
|
unsigned long id;
|
||||||
|
|
||||||
|
ctxt->node = tagNodes[ii];
|
||||||
|
if (virXPathULong("string(./@id)", ctxt, &id) < 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("missing or invalid vlan tag id attribute"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (id > 4095) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("vlan tag id %lu too large (maximum 4095)"), id);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
def->tag[ii] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
def->nTags = nTags;
|
||||||
|
|
||||||
|
/* now that we know how many tags there are, look for an explicit
|
||||||
|
* trunk setting.
|
||||||
|
*/
|
||||||
|
if (nTags > 1)
|
||||||
|
def->trunk = true;
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
if ((trunk = virXPathString("string(./@trunk)", ctxt)) != NULL) {
|
||||||
|
def->trunk = STRCASEEQ(trunk, "yes");
|
||||||
|
if (!def->trunk) {
|
||||||
|
if (nTags > 1) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid \"trunk='%s'\" in <vlan> - trunk='yes' "
|
||||||
|
"is required for more than one vlan tag"), trunk);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
/* allow (but discard) "trunk='no' if there is a single tag */
|
||||||
|
if (STRCASENEQ(trunk, "no")) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid \"trunk='%s'\" in <vlan> "
|
||||||
|
"- must be yes or no"), trunk);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
error:
|
||||||
|
ctxt->node = save;
|
||||||
|
VIR_FREE(tagNodes);
|
||||||
|
if (ret < 0)
|
||||||
|
virNetDevVlanClear(def);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDevVlanFormat(virNetDevVlanPtr def, virBufferPtr buf)
|
||||||
|
{
|
||||||
|
int ii;
|
||||||
|
|
||||||
|
if (def->nTags == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!def->tag) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("missing vlan tag data"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<vlan%s>\n", def->trunk ? " trunk='yes'" : "");
|
||||||
|
for (ii = 0; ii < def->nTags; ii++) {
|
||||||
|
virBufferAsprintf(buf, " <tag id='%u'/>\n", def->tag[ii]);
|
||||||
|
}
|
||||||
|
virBufferAddLit(buf, "</vlan>\n");
|
||||||
|
return 0;
|
||||||
|
}
|
33
src/conf/netdev_vlan_conf.h
Normal file
33
src/conf/netdev_vlan_conf.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2012 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Laine Stump <laine@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VIR_NETDEV_VLAN_CONF_H__
|
||||||
|
# define __VIR_NETDEV_VLAN_CONF_H__
|
||||||
|
|
||||||
|
# include "internal.h"
|
||||||
|
# include "virnetdevvlan.h"
|
||||||
|
# include "buf.h"
|
||||||
|
# include "xml.h"
|
||||||
|
|
||||||
|
int virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr def);
|
||||||
|
int virNetDevVlanFormat(virNetDevVlanPtr def, virBufferPtr buf);
|
||||||
|
|
||||||
|
#endif /* __VIR_NETDEV_VPORT_PROFILE_CONF_H__ */
|
@ -36,6 +36,7 @@
|
|||||||
#include "network_conf.h"
|
#include "network_conf.h"
|
||||||
#include "netdev_vport_profile_conf.h"
|
#include "netdev_vport_profile_conf.h"
|
||||||
#include "netdev_bandwidth_conf.h"
|
#include "netdev_bandwidth_conf.h"
|
||||||
|
#include "netdev_vlan_conf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
@ -88,6 +89,7 @@ virPortGroupDefClear(virPortGroupDefPtr def)
|
|||||||
VIR_FREE(def->name);
|
VIR_FREE(def->name);
|
||||||
VIR_FREE(def->virtPortProfile);
|
VIR_FREE(def->virtPortProfile);
|
||||||
virNetDevBandwidthFree(def->bandwidth);
|
virNetDevBandwidthFree(def->bandwidth);
|
||||||
|
virNetDevVlanClear(&def->vlan);
|
||||||
def->bandwidth = NULL;
|
def->bandwidth = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +189,7 @@ void virNetworkDefFree(virNetworkDefPtr def)
|
|||||||
VIR_FREE(def->virtPortProfile);
|
VIR_FREE(def->virtPortProfile);
|
||||||
|
|
||||||
virNetDevBandwidthFree(def->bandwidth);
|
virNetDevBandwidthFree(def->bandwidth);
|
||||||
|
virNetDevVlanClear(&def->vlan);
|
||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,6 +892,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
|
|||||||
|
|
||||||
xmlNodePtr save;
|
xmlNodePtr save;
|
||||||
xmlNodePtr virtPortNode;
|
xmlNodePtr virtPortNode;
|
||||||
|
xmlNodePtr vlanNode;
|
||||||
xmlNodePtr bandwidth_node;
|
xmlNodePtr bandwidth_node;
|
||||||
char *isDefault = NULL;
|
char *isDefault = NULL;
|
||||||
|
|
||||||
@ -915,6 +918,10 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vlanNode = virXPathNode("./vlan", ctxt);
|
||||||
|
if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
error:
|
error:
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
@ -943,6 +950,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
|||||||
char *forwardDev = NULL;
|
char *forwardDev = NULL;
|
||||||
xmlNodePtr save = ctxt->node;
|
xmlNodePtr save = ctxt->node;
|
||||||
xmlNodePtr bandwidthNode = NULL;
|
xmlNodePtr bandwidthNode = NULL;
|
||||||
|
xmlNodePtr vlanNode;
|
||||||
|
|
||||||
if (VIR_ALLOC(def) < 0) {
|
if (VIR_ALLOC(def) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
@ -982,6 +990,10 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
|||||||
(def->bandwidth = virNetDevBandwidthParse(bandwidthNode)) == NULL)
|
(def->bandwidth = virNetDevBandwidthParse(bandwidthNode)) == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
vlanNode = virXPathNode("./vlan", ctxt);
|
||||||
|
if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* Parse bridge information */
|
/* Parse bridge information */
|
||||||
def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
|
def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
|
||||||
stp = virXPathString("string(./bridge[1]/@stp)", ctxt);
|
stp = virXPathString("string(./bridge[1]/@stp)", ctxt);
|
||||||
@ -1448,6 +1460,8 @@ virPortGroupDefFormat(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
virBufferAddLit(buf, ">\n");
|
virBufferAddLit(buf, ">\n");
|
||||||
virBufferAdjustIndent(buf, 4);
|
virBufferAdjustIndent(buf, 4);
|
||||||
|
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
|
||||||
|
return -1;
|
||||||
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
|
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
virNetDevBandwidthFormat(def->bandwidth, buf);
|
virNetDevBandwidthFormat(def->bandwidth, buf);
|
||||||
@ -1542,6 +1556,8 @@ char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags)
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
virBufferAdjustIndent(&buf, 2);
|
virBufferAdjustIndent(&buf, 2);
|
||||||
|
if (virNetDevVlanFormat(&def->vlan, &buf) < 0)
|
||||||
|
goto error;
|
||||||
if (virNetDevBandwidthFormat(def->bandwidth, &buf) < 0)
|
if (virNetDevBandwidthFormat(def->bandwidth, &buf) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
virBufferAdjustIndent(&buf, -2);
|
virBufferAdjustIndent(&buf, -2);
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
# include "virsocketaddr.h"
|
# include "virsocketaddr.h"
|
||||||
# include "virnetdevbandwidth.h"
|
# include "virnetdevbandwidth.h"
|
||||||
# include "virnetdevvportprofile.h"
|
# include "virnetdevvportprofile.h"
|
||||||
|
# include "virnetdevvlan.h"
|
||||||
# include "virmacaddr.h"
|
# include "virmacaddr.h"
|
||||||
|
|
||||||
enum virNetworkForwardType {
|
enum virNetworkForwardType {
|
||||||
@ -148,6 +149,7 @@ struct _virPortGroupDef {
|
|||||||
bool isDefault;
|
bool isDefault;
|
||||||
virNetDevVPortProfilePtr virtPortProfile;
|
virNetDevVPortProfilePtr virtPortProfile;
|
||||||
virNetDevBandwidthPtr bandwidth;
|
virNetDevBandwidthPtr bandwidth;
|
||||||
|
virNetDevVlan vlan;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virNetworkDef virNetworkDef;
|
typedef struct _virNetworkDef virNetworkDef;
|
||||||
@ -185,6 +187,7 @@ struct _virNetworkDef {
|
|||||||
size_t nPortGroups;
|
size_t nPortGroups;
|
||||||
virPortGroupDefPtr portGroups;
|
virPortGroupDefPtr portGroups;
|
||||||
virNetDevBandwidthPtr bandwidth;
|
virNetDevBandwidthPtr bandwidth;
|
||||||
|
virNetDevVlan vlan;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virNetworkObj virNetworkObj;
|
typedef struct _virNetworkObj virNetworkObj;
|
||||||
|
@ -406,6 +406,7 @@ virDomainNetGetActualDirectMode;
|
|||||||
virDomainNetGetActualHostdev;
|
virDomainNetGetActualHostdev;
|
||||||
virDomainNetGetActualType;
|
virDomainNetGetActualType;
|
||||||
virDomainNetGetActualVirtPortProfile;
|
virDomainNetGetActualVirtPortProfile;
|
||||||
|
virDomainNetGetActualVlan;
|
||||||
virDomainNetIndexByMac;
|
virDomainNetIndexByMac;
|
||||||
virDomainNetInsert;
|
virDomainNetInsert;
|
||||||
virDomainNetRemove;
|
virDomainNetRemove;
|
||||||
@ -787,6 +788,11 @@ virNetDevBandwidthFormat;
|
|||||||
virNetDevBandwidthParse;
|
virNetDevBandwidthParse;
|
||||||
|
|
||||||
|
|
||||||
|
#netdev_vlan_conf.h
|
||||||
|
virNetDevVlanFormat;
|
||||||
|
virNetDevVlanParse;
|
||||||
|
|
||||||
|
|
||||||
# netdev_vportprofile_conf.h
|
# netdev_vportprofile_conf.h
|
||||||
virNetDevVPortProfileFormat;
|
virNetDevVPortProfileFormat;
|
||||||
virNetDevVPortProfileParse;
|
virNetDevVPortProfileParse;
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
<interface dev="eth4"/>
|
<interface dev="eth4"/>
|
||||||
<interface dev="eth5"/>
|
<interface dev="eth5"/>
|
||||||
</forward>
|
</forward>
|
||||||
|
<vlan>
|
||||||
|
<tag id='549'/>
|
||||||
|
</vlan>
|
||||||
<virtualport type="802.1Qbh">
|
<virtualport type="802.1Qbh">
|
||||||
<parameters profileid="spongebob24"/>
|
<parameters profileid="spongebob24"/>
|
||||||
</virtualport>
|
</virtualport>
|
||||||
|
@ -4,11 +4,19 @@
|
|||||||
<forward mode='bridge'/>
|
<forward mode='bridge'/>
|
||||||
<virtualport type='openvswitch'/>
|
<virtualport type='openvswitch'/>
|
||||||
<portgroup name='bob' default='yes'>
|
<portgroup name='bob' default='yes'>
|
||||||
|
<vlan trunk='yes'>
|
||||||
|
<tag id='666'/>
|
||||||
|
</vlan>
|
||||||
<virtualport>
|
<virtualport>
|
||||||
<parameters profileid='bob-profile'/>
|
<parameters profileid='bob-profile'/>
|
||||||
</virtualport>
|
</virtualport>
|
||||||
</portgroup>
|
</portgroup>
|
||||||
<portgroup name='alice'>
|
<portgroup name='alice'>
|
||||||
|
<vlan trunk='yes'>
|
||||||
|
<tag id='777'/>
|
||||||
|
<tag id='888'/>
|
||||||
|
<tag id='999'/>
|
||||||
|
</vlan>
|
||||||
<virtualport>
|
<virtualport>
|
||||||
<parameters profileid='alice-profile'/>
|
<parameters profileid='alice-profile'/>
|
||||||
</virtualport>
|
</virtualport>
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
<interface dev='eth4'/>
|
<interface dev='eth4'/>
|
||||||
<interface dev='eth5'/>
|
<interface dev='eth5'/>
|
||||||
</forward>
|
</forward>
|
||||||
|
<vlan>
|
||||||
|
<tag id='549'/>
|
||||||
|
</vlan>
|
||||||
<virtualport type='802.1Qbh'>
|
<virtualport type='802.1Qbh'>
|
||||||
<parameters profileid='spongebob24'/>
|
<parameters profileid='spongebob24'/>
|
||||||
</virtualport>
|
</virtualport>
|
||||||
|
@ -4,11 +4,19 @@
|
|||||||
<forward mode='bridge'/>
|
<forward mode='bridge'/>
|
||||||
<virtualport type='openvswitch'/>
|
<virtualport type='openvswitch'/>
|
||||||
<portgroup name='bob' default='yes'>
|
<portgroup name='bob' default='yes'>
|
||||||
|
<vlan trunk='yes'>
|
||||||
|
<tag id='666'/>
|
||||||
|
</vlan>
|
||||||
<virtualport>
|
<virtualport>
|
||||||
<parameters profileid='bob-profile'/>
|
<parameters profileid='bob-profile'/>
|
||||||
</virtualport>
|
</virtualport>
|
||||||
</portgroup>
|
</portgroup>
|
||||||
<portgroup name='alice'>
|
<portgroup name='alice'>
|
||||||
|
<vlan trunk='yes'>
|
||||||
|
<tag id='777'/>
|
||||||
|
<tag id='888'/>
|
||||||
|
<tag id='999'/>
|
||||||
|
</vlan>
|
||||||
<virtualport>
|
<virtualport>
|
||||||
<parameters profileid='alice-profile'/>
|
<parameters profileid='alice-profile'/>
|
||||||
</virtualport>
|
</virtualport>
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
<source>
|
<source>
|
||||||
<address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/>
|
<address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/>
|
||||||
</source>
|
</source>
|
||||||
|
<vlan>
|
||||||
|
<tag id='42'/>
|
||||||
|
</vlan>
|
||||||
<virtualport type='802.1Qbg'>
|
<virtualport type='802.1Qbg'>
|
||||||
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
||||||
</virtualport>
|
</virtualport>
|
||||||
|
38
tests/qemuxml2argvdata/qemuxml2argv-net-openvswitch.xml
Normal file
38
tests/qemuxml2argvdata/qemuxml2argv-net-openvswitch.xml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory unit='KiB'>219136</memory>
|
||||||
|
<currentMemory unit='KiB'>219136</currentMemory>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='usb' index='0'/>
|
||||||
|
<controller type='ide' index='0'/>
|
||||||
|
<interface type='network'>
|
||||||
|
<mac address='00:11:22:33:44:55'/>
|
||||||
|
<source network='ovs-net'/>
|
||||||
|
<vlan trunk='yes'>
|
||||||
|
<tag id='42'/>
|
||||||
|
<tag id='48'/>
|
||||||
|
<tag id='456'/>
|
||||||
|
</vlan>
|
||||||
|
<virtualport type='openvswitch'>
|
||||||
|
<parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f' profileid='bob'/>
|
||||||
|
</virtualport>
|
||||||
|
</interface>
|
||||||
|
<memballoon model='virtio'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -24,6 +24,9 @@
|
|||||||
<interface type='network'>
|
<interface type='network'>
|
||||||
<mac address='00:11:22:33:44:55'/>
|
<mac address='00:11:22:33:44:55'/>
|
||||||
<source network='rednet' portgroup='bob'/>
|
<source network='rednet' portgroup='bob'/>
|
||||||
|
<vlan>
|
||||||
|
<tag id='4095'/>
|
||||||
|
</vlan>
|
||||||
<virtualport type='802.1Qbg'>
|
<virtualport type='802.1Qbg'>
|
||||||
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
||||||
</virtualport>
|
</virtualport>
|
||||||
|
@ -178,6 +178,7 @@ mymain(void)
|
|||||||
DO_TEST("net-eth-ifname");
|
DO_TEST("net-eth-ifname");
|
||||||
DO_TEST("net-virtio-network-portgroup");
|
DO_TEST("net-virtio-network-portgroup");
|
||||||
DO_TEST("net-hostdev");
|
DO_TEST("net-hostdev");
|
||||||
|
DO_TEST("net-openvswitch");
|
||||||
DO_TEST("sound");
|
DO_TEST("sound");
|
||||||
DO_TEST("sound-device");
|
DO_TEST("sound-device");
|
||||||
DO_TEST("net-bandwidth");
|
DO_TEST("net-bandwidth");
|
||||||
|
Loading…
Reference in New Issue
Block a user