1
0
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:
Laine Stump 2012-08-12 03:51:30 -04:00
parent cfbdd005e9
commit 3f9274a524
22 changed files with 411 additions and 5 deletions

View File

@ -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>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
<b>&lt;vlan&gt;</b>
<b>&lt;tag id='42'/&gt;</b>
<b>&lt;/vlan&gt;</b>
&lt;source bridge='ovsbr0'/&gt;
&lt;virtualport type='openvswitch'&gt;
&lt;parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/&gt;
&lt;/virtualport&gt;
&lt;/interface&gt;
&lt;devices&gt;
...</pre>
<p>
If (and only if) the network connection used by the guest
supports vlan tagging transparent to the guest, an
optional <code>&lt;vlan&gt;</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>&lt;tag%gt;</code>, specifies which vlan tag
to use (for example: <code>&lt;tag id='42'/&gt;</code>. If an
interface has more than one <code>&lt;vlan&gt;</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>
... ...

View File

@ -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>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
<b>&lt;vlan trunk='yes'&gt;</b>
<b>&lt;tag id='42'/&gt;</b>
<b>&lt;tag id='47'/&gt;</b>
<b>&lt;/vlan&gt;</b>
&lt;source bridge='ovsbr0'/&gt;
&lt;virtualport type='openvswitch'&gt;
&lt;parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/&gt;
&lt;/virtualport&gt;
&lt;/interface&gt;
&lt;devices&gt;
...</pre>
<p>
If (and only if) the network type supports vlan tagging
transparent to the guest, an optional <code>&lt;vlan&gt;</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>&lt;vlan&gt;</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>&lt;vlan&gt;</code> elements can also be specified in
a <code>&lt;portgroup&gt;</code> element, as well as directly in
a domain's <code>&lt;interface&gt;</code> element. In the case
that a vlan tag is specified in multiple locations, the setting
in <code>&lt;interface&gt;</code> takes precedence, followed by
the setting in the <code>&lt;portgroup&gt;</code> selected by
the interface config. The <code>&lt;vlan&gt;</code>
in <code>&lt;network&gt;</code> will be selected only if none is
given in <code>&lt;portgroup&gt;</code>
or <code>&lt;interface&gt;</code>.
</p>
<h5><a name="elementsPortgroup">Portgroups</a></h5> <h5><a name="elementsPortgroup">Portgroups</a></h5>
<pre> <pre>

View File

@ -1713,6 +1713,9 @@
<optional> <optional>
<ref name="bandwidth"/> <ref name="bandwidth"/>
</optional> </optional>
<optional>
<ref name="vlan"/>
</optional>
</interleave> </interleave>
</define> </define>
<!-- <!--

View File

@ -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">

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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;
}

View 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__ */

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View 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>

View File

@ -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>

View File

@ -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");