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.) --- docs/formatdomain.html.in | 40 +++++++ docs/formatnetwork.html.in | 50 +++++++++ docs/schemas/domaincommon.rng | 3 + docs/schemas/network.rng | 6 + docs/schemas/networkcommon.rng | 19 ++++ po/POTFILES.in | 1 + src/Makefile.am | 3 +- src/conf/domain_conf.c | 31 ++++- src/conf/domain_conf.h | 4 + src/conf/netdev_vlan_conf.c | 125 +++++++++++++++++++++ src/conf/netdev_vlan_conf.h | 33 ++++++ src/conf/network_conf.c | 18 ++- src/conf/network_conf.h | 3 + src/libvirt_private.syms | 6 + tests/networkxml2xmlin/8021Qbh-net.xml | 3 + tests/networkxml2xmlin/openvswitch-net.xml | 8 ++ tests/networkxml2xmlout/8021Qbh-net.xml | 3 + tests/networkxml2xmlout/openvswitch-net.xml | 8 ++ .../qemuxml2argvdata/qemuxml2argv-net-hostdev.xml | 3 + .../qemuxml2argv-net-openvswitch.xml | 38 +++++++ .../qemuxml2argv-net-virtio-network-portgroup.xml | 3 + tests/qemuxml2xmltest.c | 1 + 22 files changed, 404 insertions(+), 5 deletions(-) create mode 100644 src/conf/netdev_vlan_conf.c create mode 100644 src/conf/netdev_vlan_conf.h create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-openvswitch.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f3b3fa8..a81100c 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2855,6 +2855,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> + ... + <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> <pre> ... diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 0ba4d2d..612c9de 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -290,6 +290,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> + ... + <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> <pre> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 238e57e..6f333e9 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1712,6 +1712,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 30c5a31..eac599c 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -130,6 +130,9 @@ <optional> <ref name="bandwidth"/> </optional> + <optional> + <ref name="vlan"/> + </optional> </interleave> </element> </zeroOrMore> @@ -178,6 +181,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 f2c3330..1700c22 100644 --- a/docs/schemas/networkcommon.rng +++ b/docs/schemas/networkcommon.rng @@ -184,4 +184,23 @@ <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> + </element> + </oneOrMore> + </element> + </define> </grammar> diff --git a/po/POTFILES.in b/po/POTFILES.in index e617952..6424726 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 840bb82..979ce2f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -143,7 +143,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 0cda374..ae95d81 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" #include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN @@ -1031,7 +1032,7 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def) VIR_FREE(def->virtPortProfile); virNetDevBandwidthFree(def->bandwidth); - + virNetDevVlanClear(&def->vlan); VIR_FREE(def); } @@ -1092,6 +1093,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def) virNWFilterHashTableFree(def->filterparams); virNetDevBandwidthFree(def->bandwidth); + virNetDevVlanClear(&def->vlan); VIR_FREE(def); } @@ -4366,6 +4368,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; @@ -4463,6 +4466,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; @@ -4640,6 +4647,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; @@ -11618,8 +11628,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; @@ -11720,8 +11732,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 && @@ -15078,6 +15092,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 f36f7d6..eea81d5 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 0000000..66adb17 --- /dev/null +++ b/src/conf/netdev_vlan_conf.c @@ -0,0 +1,125 @@ +/* + * 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@xxxxxxxxxx> + */ + +#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; + + 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 (nTags > 0) { + int ii; + + 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 (nTags > 1 && !def->trunk) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid \"trunk='%s'\" in <vlan> - trunk='yes' " + "is required for more than one vlan tag"), 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 0000000..1453dcd --- /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@xxxxxxxxxx> + */ + +#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 45f8e69..db8c62f 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 32fc765..a029f70 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 d20f9e3..689377e 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 2d779dc..3aaab61 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 8aa1897..a3d82b1 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 d4d5b4b..281466a 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 8aa1897..a3d82b1 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 51b09e9..81f70d0 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 0000000..ff09844 --- /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 6d379a0..c84ed3f 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 dcdba4f..da298b7 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"); -- 1.7.11.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list