[libvirt] [PATCH 3/4] conf: add <vlan> element to network and domain interface elements

Laine Stump laine at laine.org
Mon Aug 13 04:54:14 UTC 2012


The following config elements now support multiple <vlan> subelements:

within a domain: <interface>, and the <actual> subelement of <interface>
within a network: the toplevel, as well as any <portgroup>

If multiple vlan elements are given, 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.

Some examples:

  <interface type='hostdev'/>
    <vlan tag='42'/>
    <mac address='52:54:00:12:34:56'/>
    ...
  </interface>

  <network>
    <name>vlan-net</name>
    <vlan tag='30' trunk='yes'/>
    <virtualport type='openvswitch'/>
  </network>

  <interface type='network'/>
    <source network='vlan-net'/>
    ...
  </interface>

  <network>
    <name>trunk-vlan</name>
    <vlan tag='42'/>
    <vlan tag='43'/>
    ...
  </network>

  <network>
    <name>multi</name>
    ...
    <portgroup name='production'/>
      <vlan tag='42'/>
    </portgroup>
    <portgroup name='test'/>
      <vlan tag='666'/>
    </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.)
---

In a couple of places I noticed mis-indented code in the context of
this patch, so I fixed it.

 docs/formatdomain.html.in                          |  35 +++++++
 docs/formatnetwork.html.in                         |  48 +++++++++
 docs/schemas/domaincommon.rng                      |   3 +
 docs/schemas/network.rng                           |   6 ++
 docs/schemas/networkcommon.rng                     |  15 +++
 po/POTFILES.in                                     |   1 +
 src/Makefile.am                                    |   3 +-
 src/conf/domain_conf.c                             |  29 +++++-
 src/conf/domain_conf.h                             |   4 +
 src/conf/netdev_vlan_conf.c                        | 111 +++++++++++++++++++++
 src/conf/netdev_vlan_conf.h                        |  33 ++++++
 src/conf/network_conf.c                            |  14 ++-
 src/conf/network_conf.h                            |   3 +
 src/libvirt_private.syms                           |   6 ++
 tests/networkxml2xmlin/8021Qbh-net.xml             |   1 +
 tests/networkxml2xmlin/openvswitch-net.xml         |   4 +
 tests/networkxml2xmlout/8021Qbh-net.xml            |   1 +
 tests/networkxml2xmlout/openvswitch-net.xml        |   4 +
 .../qemuxml2argvdata/qemuxml2argv-net-hostdev.xml  |   1 +
 .../qemuxml2argv-net-openvswitch.xml               |  36 +++++++
 .../qemuxml2argv-net-virtio-network-portgroup.xml  |   1 +
 tests/qemuxml2xmltest.c                            |   1 +
 22 files changed, 355 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..618710c 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2855,6 +2855,41 @@ 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 tag='42'/></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.) As expected, the <code>tag</code>
+      attribute specifies which vlan tag to use. 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 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..e5fcaa5 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -290,6 +290,54 @@
         <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 tag='42'/></b>
+      <b><vlan tag='47'/></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..7bd53d7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1712,6 +1712,9 @@
       <optional>
         <ref name="bandwidth"/>
       </optional>
+      <zeroOrMore>
+        <ref name="vlan"/>
+      </zeroOrMore>
     </interleave>
   </define>
   <!--
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 30c5a31..0f59b3c 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -130,6 +130,9 @@
               <optional>
                 <ref name="bandwidth"/>
               </optional>
+            <zeroOrMore>
+              <ref name="vlan"/>
+            </zeroOrMore>
             </interleave>
           </element>
         </zeroOrMore>
@@ -177,6 +180,9 @@
        <optional>
          <ref name="bandwidth"/>
        </optional>
+       <zeroOrMore>
+         <ref name="vlan"/>
+       </zeroOrMore>
        <optional>
          <element name="link">
            <attribute name="state">
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index f2c3330..10644b1 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -184,4 +184,19 @@
       <param name="pattern">(ipv4)|(ipv6)</param>
     </data>
   </define>
+
+  <define name="vlan">
+    <element name="vlan">
+      <attribute name="tag">
+        <data type="unsignedInt">
+          <param name="maxInclusive">4095</param>
+        </data>
+      </attribute>
+      <optional>
+        <attribute name="trunk">
+          <value>yes</value>
+        </attribute>
+      </optional>
+    </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 ff16d6f..5748fd2 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..55679d2 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);
 }
@@ -4463,6 +4465,9 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
         !(actual->bandwidth = virNetDevBandwidthParse(bandwidth_node)))
         goto error;
 
+    if (virNetDevVlanParse(ctxt, &actual->vlan) < 0)
+       goto error;
+
     *def = actual;
     actual = NULL;
     ret = 0;
@@ -4933,6 +4938,9 @@ virDomainNetDefParseXML(virCapsPtr caps,
         goto error;
     }
 
+    if (virNetDevVlanParse(ctxt, &def->vlan) < 0)
+       goto error;
+
 cleanup:
     ctxt->node = oldnode;
     VIR_FREE(macaddr);
@@ -11618,8 +11626,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 +11730,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 +15090,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..3ff50b7
--- /dev/null
+++ b/src/conf/netdev_vlan_conf.c
@@ -0,0 +1,111 @@
+/*
+ * 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 at 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(xmlXPathContextPtr ctxt, virNetDevVlanPtr def)
+{
+    int ret = -1;
+    xmlNodePtr save = ctxt->node;
+    xmlNodePtr *vlanNodes = NULL;
+    int nVlans = virXPathNodeSet("./vlan", ctxt, &vlanNodes);
+
+    if (nVlans < 0)
+        goto error;
+
+    if (nVlans > 0) {
+        int ii;
+
+        if (VIR_ALLOC_N(def->tag, nVlans) < 0) {
+            virReportOOMError();
+            goto error;
+        }
+
+        if (nVlans > 1)
+            def->trunk = true;
+
+        for (ii = 0; ii < nVlans; ii++) {
+            unsigned long tag;
+            char *trunk = NULL;
+
+            ctxt->node = vlanNodes[ii];
+            if (virXPathULong("string(./@tag)", ctxt, &tag) < 0) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("missing or invalid vlan tag"));
+                goto error;
+            }
+            if (tag > 4095) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("vlan tag %lu too large (maximum 4095)"), tag);
+                goto error;
+            }
+            def->tag[ii] = tag;
+            if ((trunk = virXPathString("string(./@trunk)", ctxt)) != NULL) {
+                def->trunk = STRCASEEQ(trunk, "yes");
+                if (nVlans > 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;
+                }
+            }
+        }
+    }
+
+    def->nTags = nVlans;
+    ret = 0;
+error:
+    ctxt->node = save;
+    VIR_FREE(vlanNodes);
+    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;
+    }
+
+    for (ii = 0; ii < def->nTags; ii++) {
+        virBufferAsprintf(buf, "<vlan tag='%u'%s/>\n",
+                          def->tag[ii],
+                          (def->nTags == 1 && def->trunk) ? " trunk='yes'" : "");
+    }
+    return 0;
+}
diff --git a/src/conf/netdev_vlan_conf.h b/src/conf/netdev_vlan_conf.h
new file mode 100644
index 0000000..b96f887
--- /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 at 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(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..6545857 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);
 }
 
@@ -915,6 +917,9 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
         goto error;
     }
 
+    if (virNetDevVlanParse(ctxt, &def->vlan) < 0)
+        goto error;
+
     result = 0;
 error:
     if (result < 0) {
@@ -982,6 +987,9 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
         (def->bandwidth = virNetDevBandwidthParse(bandwidthNode)) == NULL)
         goto error;
 
+    if (virNetDevVlanParse(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 +1456,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 +1552,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..02d7278 100644
--- a/tests/networkxml2xmlin/8021Qbh-net.xml
+++ b/tests/networkxml2xmlin/8021Qbh-net.xml
@@ -8,6 +8,7 @@
     <interface dev="eth4"/>
     <interface dev="eth5"/>
   </forward>
+  <vlan tag='549'/>
   <virtualport type="802.1Qbh">
     <parameters profileid="spongebob24"/>
   </virtualport>
diff --git a/tests/networkxml2xmlin/openvswitch-net.xml b/tests/networkxml2xmlin/openvswitch-net.xml
index 8aa1897..46d0f01 100644
--- a/tests/networkxml2xmlin/openvswitch-net.xml
+++ b/tests/networkxml2xmlin/openvswitch-net.xml
@@ -4,11 +4,15 @@
   <forward mode='bridge'/>
   <virtualport type='openvswitch'/>
   <portgroup name='bob' default='yes'>
+    <vlan tag='666' trunk='yes'/>
     <virtualport>
       <parameters profileid='bob-profile'/>
     </virtualport>
   </portgroup>
   <portgroup name='alice'>
+    <vlan tag='777'/>
+    <vlan tag='888'/>
+    <vlan tag='999'/>
     <virtualport>
       <parameters profileid='alice-profile'/>
     </virtualport>
diff --git a/tests/networkxml2xmlout/8021Qbh-net.xml b/tests/networkxml2xmlout/8021Qbh-net.xml
index d4d5b4b..9385240 100644
--- a/tests/networkxml2xmlout/8021Qbh-net.xml
+++ b/tests/networkxml2xmlout/8021Qbh-net.xml
@@ -8,6 +8,7 @@
     <interface dev='eth4'/>
     <interface dev='eth5'/>
   </forward>
+  <vlan tag='549'/>
   <virtualport type='802.1Qbh'>
     <parameters profileid='spongebob24'/>
   </virtualport>
diff --git a/tests/networkxml2xmlout/openvswitch-net.xml b/tests/networkxml2xmlout/openvswitch-net.xml
index 8aa1897..46d0f01 100644
--- a/tests/networkxml2xmlout/openvswitch-net.xml
+++ b/tests/networkxml2xmlout/openvswitch-net.xml
@@ -4,11 +4,15 @@
   <forward mode='bridge'/>
   <virtualport type='openvswitch'/>
   <portgroup name='bob' default='yes'>
+    <vlan tag='666' trunk='yes'/>
     <virtualport>
       <parameters profileid='bob-profile'/>
     </virtualport>
   </portgroup>
   <portgroup name='alice'>
+    <vlan tag='777'/>
+    <vlan tag='888'/>
+    <vlan tag='999'/>
     <virtualport>
       <parameters profileid='alice-profile'/>
     </virtualport>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
index 51b09e9..43384b3 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
@@ -26,6 +26,7 @@
       <source>
         <address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/>
       </source>
+      <vlan tag='42'/>
       <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..a2753eb
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-openvswitch.xml
@@ -0,0 +1,36 @@
+<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 tag='42'/>
+      <vlan tag='48'/>
+      <vlan tag='456'/>
+      <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..829be52 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml
@@ -24,6 +24,7 @@
     <interface type='network'>
       <mac address='00:11:22:33:44:55'/>
       <source network='rednet' portgroup='bob'/>
+      <vlan tag='4095'/>
       <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




More information about the libvir-list mailing list