aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaine Stump <laine@laine.org>2012-08-12 03:51:30 -0400
committerLaine Stump <laine@laine.org>2012-08-15 13:10:57 -0400
commit3f9274a524804f8aa59c811932dba56550c120a1 (patch)
tree348bf52bf88261864e7a4bcb1450d62f50d7b5c7
parentutil: add virNetDevVlanType (diff)
downloadlibvirt-3f9274a524804f8aa59c811932dba56550c120a1.tar.gz
libvirt-3f9274a524804f8aa59c811932dba56550c120a1.tar.bz2
libvirt-3f9274a524804f8aa59c811932dba56550c120a1.zip
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.)
-rw-r--r--docs/formatdomain.html.in40
-rw-r--r--docs/formatnetwork.html.in50
-rw-r--r--docs/schemas/domaincommon.rng3
-rw-r--r--docs/schemas/network.rng6
-rw-r--r--docs/schemas/networkcommon.rng20
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/Makefile.am3
-rw-r--r--src/conf/domain_conf.c31
-rw-r--r--src/conf/domain_conf.h4
-rw-r--r--src/conf/netdev_vlan_conf.c131
-rw-r--r--src/conf/netdev_vlan_conf.h33
-rw-r--r--src/conf/network_conf.c18
-rw-r--r--src/conf/network_conf.h3
-rw-r--r--src/libvirt_private.syms6
-rw-r--r--tests/networkxml2xmlin/8021Qbh-net.xml3
-rw-r--r--tests/networkxml2xmlin/openvswitch-net.xml8
-rw-r--r--tests/networkxml2xmlout/8021Qbh-net.xml3
-rw-r--r--tests/networkxml2xmlout/openvswitch-net.xml8
-rw-r--r--tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml3
-rw-r--r--tests/qemuxml2argvdata/qemuxml2argv-net-openvswitch.xml38
-rw-r--r--tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml3
-rw-r--r--tests/qemuxml2xmltest.c1
22 files changed, 411 insertions, 5 deletions
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index fb25cb838..2c5c45632 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2857,6 +2857,46 @@ qemu-kvm -net nic,model=? /dev/null
<span class="since">Since 0.9.4</span>
</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>
<pre>
...
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index a010cbd21..ed9f7a9db 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -306,6 +306,56 @@
<span class="since">Since 0.9.4</span>
</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>
<pre>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 767fccda0..4903ca69e 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1713,6 +1713,9 @@
<optional>
<ref name="bandwidth"/>
</optional>
+ <optional>
+ <ref name="vlan"/>
+ </optional>
</interleave>
</define>
<!--
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 124c9f982..e55105a14 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -140,6 +140,9 @@
<optional>
<ref name="bandwidth"/>
</optional>
+ <optional>
+ <ref name="vlan"/>
+ </optional>
</interleave>
</element>
</zeroOrMore>
@@ -188,6 +191,9 @@
<ref name="bandwidth"/>
</optional>
<optional>
+ <ref name="vlan"/>
+ </optional>
+ <optional>
<element name="link">
<attribute name="state">
<choice>
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index f2c333074..c7749e718 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -184,4 +184,24 @@
<param name="pattern">(ipv4)|(ipv6)</param>
</data>
</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>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e61795292..642472682 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -11,6 +11,7 @@ src/conf/domain_conf.c
src/conf/domain_event.c
src/conf/interface_conf.c
src/conf/netdev_bandwidth_conf.c
+src/conf/netdev_vlan_conf.c
src/conf/netdev_vport_profile_conf.c
src/conf/network_conf.c
src/conf/node_device_conf.c
diff --git a/src/Makefile.am b/src/Makefile.am
index fef391724..b5f8056d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -144,7 +144,8 @@ LOCK_DRIVER_SANLOCK_SOURCES = \
NETDEV_CONF_SOURCES = \
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
# Domain driver generic impl APIs
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 62f5f5b08..a2e73c69a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -51,6 +51,7 @@
#include "secret_conf.h"
#include "netdev_vport_profile_conf.h"
#include "netdev_bandwidth_conf.h"
+#include "netdev_vlan_conf.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@@ -1030,7 +1031,7 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def)
VIR_FREE(def->virtPortProfile);
virNetDevBandwidthFree(def->bandwidth);
-
+ virNetDevVlanClear(&def->vlan);
VIR_FREE(def);
}
@@ -1091,6 +1092,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
virNWFilterHashTableFree(def->filterparams);
virNetDevBandwidthFree(def->bandwidth);
+ virNetDevVlanClear(&def->vlan);
VIR_FREE(def);
}
@@ -4365,6 +4367,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
int ret = -1;
xmlNodePtr save_ctxt = ctxt->node;
xmlNodePtr bandwidth_node = NULL;
+ xmlNodePtr vlanNode;
xmlNodePtr virtPortNode;
char *type = NULL;
char *mode = NULL;
@@ -4462,6 +4465,10 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
!(actual->bandwidth = virNetDevBandwidthParse(bandwidth_node)))
goto error;
+ vlanNode = virXPathNode("./vlan", ctxt);
+ if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &actual->vlan) < 0)
+ goto error;
+
*def = actual;
actual = NULL;
ret = 0;
@@ -4645,6 +4652,9 @@ virDomainNetDefParseXML(virCapsPtr caps,
} else if (xmlStrEqual(cur->name, BAD_CAST "bandwidth")) {
if (!(def->bandwidth = virNetDevBandwidthParse(cur)))
goto error;
+ } else if (xmlStrEqual(cur->name, BAD_CAST "vlan")) {
+ if (virNetDevVlanParse(cur, ctxt, &def->vlan) < 0)
+ goto error;
}
}
cur = cur->next;
@@ -11623,8 +11633,10 @@ virDomainActualNetDefFormat(virBufferPtr buf,
return -1;
}
+ if (virNetDevVlanFormat(&def->vlan, buf) < 0)
+ return -1;
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
- return -1;
+ return -1;
if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0)
return -1;
@@ -11725,8 +11737,10 @@ virDomainNetDefFormat(virBufferPtr buf,
break;
}
+ if (virNetDevVlanFormat(&def->vlan, buf) < 0)
+ return -1;
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
- return -1;
+ return -1;
virBufferEscapeString(buf, "<script path='%s'/>\n",
def->script);
if (def->ifname &&
@@ -15083,6 +15097,17 @@ virDomainNetGetActualBandwidth(virDomainNetDefPtr iface)
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
* type, or NULL if this is an unsuitable type, or the index is out of
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8d024b375..fae77922f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -43,6 +43,7 @@
# include "virnetdevvportprofile.h"
# include "virnetdevopenvswitch.h"
# include "virnetdevbandwidth.h"
+# include "virnetdevvlan.h"
# include "virobject.h"
/* forward declarations of all device types, required by
@@ -781,6 +782,7 @@ struct _virDomainActualNetDef {
} data;
virNetDevVPortProfilePtr virtPortProfile;
virNetDevBandwidthPtr bandwidth;
+ virNetDevVlan vlan;
};
/* Stores the virtual network interface configuration */
@@ -845,6 +847,7 @@ struct _virDomainNetDef {
char *filter;
virNWFilterHashTablePtr filterparams;
virNetDevBandwidthPtr bandwidth;
+ virNetDevVlan vlan;
int linkstate;
};
@@ -2039,6 +2042,7 @@ virNetDevVPortProfilePtr
virDomainNetGetActualVirtPortProfile(virDomainNetDefPtr iface);
virNetDevBandwidthPtr
virDomainNetGetActualBandwidth(virDomainNetDefPtr iface);
+virNetDevVlanPtr virDomainNetGetActualVlan(virDomainNetDefPtr iface);
int virDomainControllerInsert(virDomainDefPtr def,
virDomainControllerDefPtr controller);
diff --git a/src/conf/netdev_vlan_conf.c b/src/conf/netdev_vlan_conf.c
new file mode 100644
index 000000000..f3a987fa2
--- /dev/null
+++ b/src/conf/netdev_vlan_conf.c
@@ -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;
+}
diff --git a/src/conf/netdev_vlan_conf.h b/src/conf/netdev_vlan_conf.h
new file mode 100644
index 000000000..1453dcdc4
--- /dev/null
+++ b/src/conf/netdev_vlan_conf.h
@@ -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__ */
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 45f8e698e..db8c62f4e 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -36,6 +36,7 @@
#include "network_conf.h"
#include "netdev_vport_profile_conf.h"
#include "netdev_bandwidth_conf.h"
+#include "netdev_vlan_conf.h"
#include "memory.h"
#include "xml.h"
#include "uuid.h"
@@ -88,6 +89,7 @@ virPortGroupDefClear(virPortGroupDefPtr def)
VIR_FREE(def->name);
VIR_FREE(def->virtPortProfile);
virNetDevBandwidthFree(def->bandwidth);
+ virNetDevVlanClear(&def->vlan);
def->bandwidth = NULL;
}
@@ -187,7 +189,7 @@ void virNetworkDefFree(virNetworkDefPtr def)
VIR_FREE(def->virtPortProfile);
virNetDevBandwidthFree(def->bandwidth);
-
+ virNetDevVlanClear(&def->vlan);
VIR_FREE(def);
}
@@ -890,6 +892,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
xmlNodePtr save;
xmlNodePtr virtPortNode;
+ xmlNodePtr vlanNode;
xmlNodePtr bandwidth_node;
char *isDefault = NULL;
@@ -915,6 +918,10 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
goto error;
}
+ vlanNode = virXPathNode("./vlan", ctxt);
+ if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
+ goto error;
+
result = 0;
error:
if (result < 0) {
@@ -943,6 +950,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
char *forwardDev = NULL;
xmlNodePtr save = ctxt->node;
xmlNodePtr bandwidthNode = NULL;
+ xmlNodePtr vlanNode;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -982,6 +990,10 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
(def->bandwidth = virNetDevBandwidthParse(bandwidthNode)) == NULL)
goto error;
+ vlanNode = virXPathNode("./vlan", ctxt);
+ if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
+ goto error;
+
/* Parse bridge information */
def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
stp = virXPathString("string(./bridge[1]/@stp)", ctxt);
@@ -1448,6 +1460,8 @@ virPortGroupDefFormat(virBufferPtr buf,
}
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 4);
+ if (virNetDevVlanFormat(&def->vlan, buf) < 0)
+ return -1;
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
return -1;
virNetDevBandwidthFormat(def->bandwidth, buf);
@@ -1542,6 +1556,8 @@ char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags)
goto error;
virBufferAdjustIndent(&buf, 2);
+ if (virNetDevVlanFormat(&def->vlan, &buf) < 0)
+ goto error;
if (virNetDevBandwidthFormat(def->bandwidth, &buf) < 0)
goto error;
virBufferAdjustIndent(&buf, -2);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 32fc76502..a029f7070 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -35,6 +35,7 @@
# include "virsocketaddr.h"
# include "virnetdevbandwidth.h"
# include "virnetdevvportprofile.h"
+# include "virnetdevvlan.h"
# include "virmacaddr.h"
enum virNetworkForwardType {
@@ -148,6 +149,7 @@ struct _virPortGroupDef {
bool isDefault;
virNetDevVPortProfilePtr virtPortProfile;
virNetDevBandwidthPtr bandwidth;
+ virNetDevVlan vlan;
};
typedef struct _virNetworkDef virNetworkDef;
@@ -185,6 +187,7 @@ struct _virNetworkDef {
size_t nPortGroups;
virPortGroupDefPtr portGroups;
virNetDevBandwidthPtr bandwidth;
+ virNetDevVlan vlan;
};
typedef struct _virNetworkObj virNetworkObj;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2c95f943f..d5912ed0c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -406,6 +406,7 @@ virDomainNetGetActualDirectMode;
virDomainNetGetActualHostdev;
virDomainNetGetActualType;
virDomainNetGetActualVirtPortProfile;
+virDomainNetGetActualVlan;
virDomainNetIndexByMac;
virDomainNetInsert;
virDomainNetRemove;
@@ -787,6 +788,11 @@ virNetDevBandwidthFormat;
virNetDevBandwidthParse;
+#netdev_vlan_conf.h
+virNetDevVlanFormat;
+virNetDevVlanParse;
+
+
# netdev_vportprofile_conf.h
virNetDevVPortProfileFormat;
virNetDevVPortProfileParse;
diff --git a/tests/networkxml2xmlin/8021Qbh-net.xml b/tests/networkxml2xmlin/8021Qbh-net.xml
index 2d779dcac..3aaab61db 100644
--- a/tests/networkxml2xmlin/8021Qbh-net.xml
+++ b/tests/networkxml2xmlin/8021Qbh-net.xml
@@ -8,6 +8,9 @@
<interface dev="eth4"/>
<interface dev="eth5"/>
</forward>
+ <vlan>
+ <tag id='549'/>
+ </vlan>
<virtualport type="802.1Qbh">
<parameters profileid="spongebob24"/>
</virtualport>
diff --git a/tests/networkxml2xmlin/openvswitch-net.xml b/tests/networkxml2xmlin/openvswitch-net.xml
index 8aa1897ab..a3d82b165 100644
--- a/tests/networkxml2xmlin/openvswitch-net.xml
+++ b/tests/networkxml2xmlin/openvswitch-net.xml
@@ -4,11 +4,19 @@
<forward mode='bridge'/>
<virtualport type='openvswitch'/>
<portgroup name='bob' default='yes'>
+ <vlan trunk='yes'>
+ <tag id='666'/>
+ </vlan>
<virtualport>
<parameters profileid='bob-profile'/>
</virtualport>
</portgroup>
<portgroup name='alice'>
+ <vlan trunk='yes'>
+ <tag id='777'/>
+ <tag id='888'/>
+ <tag id='999'/>
+ </vlan>
<virtualport>
<parameters profileid='alice-profile'/>
</virtualport>
diff --git a/tests/networkxml2xmlout/8021Qbh-net.xml b/tests/networkxml2xmlout/8021Qbh-net.xml
index d4d5b4b44..281466a9f 100644
--- a/tests/networkxml2xmlout/8021Qbh-net.xml
+++ b/tests/networkxml2xmlout/8021Qbh-net.xml
@@ -8,6 +8,9 @@
<interface dev='eth4'/>
<interface dev='eth5'/>
</forward>
+ <vlan>
+ <tag id='549'/>
+ </vlan>
<virtualport type='802.1Qbh'>
<parameters profileid='spongebob24'/>
</virtualport>
diff --git a/tests/networkxml2xmlout/openvswitch-net.xml b/tests/networkxml2xmlout/openvswitch-net.xml
index 8aa1897ab..a3d82b165 100644
--- a/tests/networkxml2xmlout/openvswitch-net.xml
+++ b/tests/networkxml2xmlout/openvswitch-net.xml
@@ -4,11 +4,19 @@
<forward mode='bridge'/>
<virtualport type='openvswitch'/>
<portgroup name='bob' default='yes'>
+ <vlan trunk='yes'>
+ <tag id='666'/>
+ </vlan>
<virtualport>
<parameters profileid='bob-profile'/>
</virtualport>
</portgroup>
<portgroup name='alice'>
+ <vlan trunk='yes'>
+ <tag id='777'/>
+ <tag id='888'/>
+ <tag id='999'/>
+ </vlan>
<virtualport>
<parameters profileid='alice-profile'/>
</virtualport>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
index 51b09e914..81f70d0d4 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
@@ -26,6 +26,9 @@
<source>
<address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/>
</source>
+ <vlan>
+ <tag id='42'/>
+ </vlan>
<virtualport type='802.1Qbg'>
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
</virtualport>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-openvswitch.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-openvswitch.xml
new file mode 100644
index 000000000..ff098448d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-openvswitch.xml
@@ -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>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml
index 6d379a044..c84ed3f35 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml
@@ -24,6 +24,9 @@
<interface type='network'>
<mac address='00:11:22:33:44:55'/>
<source network='rednet' portgroup='bob'/>
+ <vlan>
+ <tag id='4095'/>
+ </vlan>
<virtualport type='802.1Qbg'>
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
</virtualport>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index dcdba4fc6..da298b7aa 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -178,6 +178,7 @@ mymain(void)
DO_TEST("net-eth-ifname");
DO_TEST("net-virtio-network-portgroup");
DO_TEST("net-hostdev");
+ DO_TEST("net-openvswitch");
DO_TEST("sound");
DO_TEST("sound-device");
DO_TEST("net-bandwidth");