]> xenbits.xensource.com Git - people/dariof/libvirt.git/commitdiff
Configure native vlan modes on Open vSwitch ports
authorjames robson <jrobson@websense.com>
Thu, 23 May 2013 17:12:10 +0000 (18:12 +0100)
committerLaine Stump <laine@laine.org>
Tue, 25 Jun 2013 04:22:36 +0000 (00:22 -0400)
This patch adds functionality to allow libvirt to configure the
'native-tagged' and 'native-untagged' modes on openvswitch networks.

Signed-off-by: Laine Stump <laine@redhat.com>
docs/formatdomain.html.in
docs/formatnetwork.html.in
docs/schemas/networkcommon.rng
src/conf/netdev_vlan_conf.c
src/util/virnetdevopenvswitch.c
src/util/virnetdevvlan.c
src/util/virnetdevvlan.h
tests/networkxml2xmlin/openvswitch-net.xml
tests/networkxml2xmlout/openvswitch-net.xml

index 77126a56fec3f8edc4e46d1d930e9c0487231609..17ea9c24866b32196e9ad9ab3336b3964b431478 100644 (file)
@@ -3523,6 +3523,13 @@ qemu-kvm -net nic,model=? /dev/null
         &lt;parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/&gt;
       &lt;/virtualport&gt;
     &lt;/interface&gt;
+    &lt;interface type='bridge'&gt;
+      <b>&lt;vlan trunk='yes'&gt;</b>
+        <b>&lt;tag id='42'/&gt;</b>
+        <b>&lt;tag id='123' nativeMode='untagged'/&gt;</b>
+      <b>&lt;/vlan&gt;</b>
+      ...
+    &lt;/interface&gt;
   &lt;devices&gt;
   ...</pre>
 
@@ -3549,6 +3556,15 @@ qemu-kvm -net nic,model=? /dev/null
       vlan element.
     </p>
 
+    <p>
+      For network connections using openvswitch it is possible to
+      configure the 'native-tagged' and 'native-untagged' vlan modes
+      <span class="since">Since 1.0.7.</span> This uses the optional
+      <code>nativeMode</code> attribute on the <code>&lt;tag&gt;</code>
+      element: <code>nativeMode</code> may be set to 'tagged' or
+      'untagged'. The id atribute of the element sets the native vlan.
+    </p>
+
     <h5><a name="elementLink">Modifying virtual link state</a></h5>
 <pre>
   ...
index a1198ce6beecadc65e35d512c1c92ed5c6d6e04a..6a4b36df2a8bd55ed16e92998c216f7d8a4922b9 100644 (file)
         &lt;parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/&gt;
       &lt;/virtualport&gt;
     &lt;/interface&gt;
+    &lt;interface type='bridge'&gt;
+      <b>&lt;vlan trunk='yes'&gt;</b>
+        <b>&lt;tag id='42'/&gt;</b>
+        <b>&lt;tag id='123' nativeMode='untagged'/&gt;</b>
+      <b>&lt;/vlan&gt;</b>
+      ...
+    &lt;/interface&gt;
   &lt;devices&gt;
   ...</pre>
 
       is desired, the optional attribute <code>trunk='yes'</code> can
       be added to the vlan element.
     </p>
+    <p>
+      For network connections using openvswitch it is possible to
+      configure the 'native-tagged' and 'native-untagged' vlan modes
+      <span class="since">Since 1.0.7</span>. This uses the optional
+      <code>nativeMode</code> attribute on the <code>&lt;tag&gt;</code>
+      element: <code>nativeMode</code> may be set to 'tagged' or
+      'untagged'. The id atribute of the element sets the native vlan.
+    </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
index 51ff7592ea0e6eb97ca203df75d505a4b7db0a76..e60f1fc99d84eb5c0457efe8867660f03bb529e2 100644 (file)
               <param name="maxInclusive">4095</param>
             </data>
           </attribute>
+          <optional>
+            <attribute name="nativeMode">
+              <choice>
+                <value>tagged</value>
+                <value>untagged</value>
+              </choice>
+            </attribute>
+          </optional>
           <empty/>
         </element>
       </oneOrMore>
index 13ba8c6ab84404cc3762731a608b7fcb56e9c43f..82ff9e8b658961e9fd5a7be0c7c25e3be459d232 100644 (file)
@@ -17,6 +17,7 @@
  *
  * Authors:
  *     Laine Stump <laine@redhat.com>
+ *     James Robson <jrobson@websense.com>
  */
 
 #include <config.h>
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
+VIR_ENUM_IMPL(virNativeVlanMode, VIR_NATIVE_VLAN_MODE_LAST,
+              "default", "tagged", "untagged")
+
 int
 virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr def)
 {
     int ret = -1;
     xmlNodePtr save = ctxt->node;
     const char *trunk = NULL;
+    const char *nativeMode = NULL;
     xmlNodePtr *tagNodes = NULL;
     int nTags, ii;
 
@@ -54,6 +59,8 @@ virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr de
         goto error;
     }
 
+    def->nativeMode = 0;
+    def->nativeTag = 0;
     for (ii = 0; ii < nTags; ii++) {
         unsigned long id;
 
@@ -68,6 +75,22 @@ virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr de
                            _("vlan tag id %lu too large (maximum 4095)"), id);
             goto error;
         }
+        if ((nativeMode = virXPathString("string(./@nativeMode)", ctxt))) {
+            if (def->nativeMode != 0) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("duplicate native vlan setting"));
+                goto error;
+            }
+            if ((def->nativeMode
+                 = virNativeVlanModeTypeFromString(nativeMode)) <= 0) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("Invalid \"nativeMode='%s'\" "
+                                 "in vlan <tag> element"),
+                               nativeMode);
+                goto error;
+            }
+            def->nativeTag = id;
+        }
         def->tag[ii] = id;
     }
 
@@ -89,6 +112,12 @@ virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr de
                                  "is required for more than one vlan tag"), trunk);
                 goto error;
             }
+            if (def->nativeMode != 0) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("invalid configuration in <vlan> - \"trunk='no'\" is "
+                                 "not allowed with a native vlan id"));
+                goto error;
+            }
             /* allow (but discard) "trunk='no' if there is a single tag */
             if (STRCASENEQ(trunk, "no")) {
                 virReportError(VIR_ERR_XML_ERROR,
@@ -125,7 +154,19 @@ virNetDevVlanFormat(virNetDevVlanPtr def, virBufferPtr buf)
 
     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]);
+        if (def->nativeMode != VIR_NATIVE_VLAN_MODE_DEFAULT &&
+            def->nativeTag == def->tag[ii]) {
+            /* check the nativeMode in case we get <tag id='0'/>*/
+            const char *mode = virNativeVlanModeTypeToString(def->nativeMode);
+            if (!mode) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("Bad value for nativeMode"));
+            }
+            virBufferAsprintf(buf, "  <tag id='%u' nativeMode='%s'/>\n",
+                              def->tag[ii], mode);
+        } else {
+            virBufferAsprintf(buf, "  <tag id='%u'/>\n", def->tag[ii]);
+        }
     }
     virBufferAddLit(buf, "</vlan>\n");
     return 0;
index 2aee445a5844071a0e39bc4367988f11c7cd29a1..5834e4e413404df47ca125ee5a75b51027e807e9 100644 (file)
@@ -109,6 +109,20 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname,
     virCommandAddArgList(cmd, "--timeout=5", "--", "--may-exist", "add-port",
                         brname, ifname, NULL);
 
+    switch (virtVlan->nativeMode) {
+    case VIR_NATIVE_VLAN_MODE_TAGGED:
+        virCommandAddArg(cmd, "vlan_mode=native-tagged");
+        virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag);
+        break;
+    case VIR_NATIVE_VLAN_MODE_UNTAGGED:
+        virCommandAddArg(cmd, "vlan_mode=native-untagged");
+        virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag);
+        break;
+    case VIR_NATIVE_VLAN_MODE_DEFAULT:
+    default:
+        break;
+    }
+
     if (virBufferUse(&buf) != 0)
         virCommandAddArgList(cmd, virBufferCurrentContent(&buf), NULL);
 
index 2fe2017b580723ca198ba8a837d820ec0244b8bd..eed32f75ab91aa39074c6bf389a9e06bc4e0b978 100644 (file)
@@ -33,6 +33,8 @@ virNetDevVlanClear(virNetDevVlanPtr vlan)
 {
     VIR_FREE(vlan->tag);
     vlan->nTags = 0;
+    vlan->nativeMode = 0;
+    vlan->nativeTag = 0;
 }
 
 void
@@ -54,7 +56,9 @@ virNetDevVlanEqual(const virNetDevVlanPtr a, const virNetDevVlanPtr b)
         return false;
 
     if (a->trunk != b->trunk ||
-        a->nTags != b->nTags) {
+        a->nTags != b->nTags ||
+        a->nativeMode != b->nativeMode ||
+        a->nativeTag != b->nativeTag) {
         return false;
     }
 
@@ -89,6 +93,8 @@ virNetDevVlanCopy(virNetDevVlanPtr dst, const virNetDevVlanPtr src)
 
     dst->trunk = src->trunk;
     dst->nTags = src->nTags;
+    dst->nativeMode = src->nativeMode;
+    dst->nativeTag = src->nativeTag;
     memcpy(dst->tag, src->tag, src->nTags * sizeof(*src->tag));
     return 0;
 }
index c6b16efd2e68af66a19c029cabe5fc4dba2baa05..fd1762a2669b339b46311cacd2e5916e85cbf1f6 100644 (file)
  * Authors:
  *      Laine Stump <laine@redhat.com>
  */
-
 #ifndef __VIR_NETDEV_VLAN_H__
 # define __VIR_NETDEV_VLAN_H__
 
+# include <virutil.h>
+
+typedef enum {
+    VIR_NATIVE_VLAN_MODE_DEFAULT = 0,
+    VIR_NATIVE_VLAN_MODE_TAGGED,
+    VIR_NATIVE_VLAN_MODE_UNTAGGED,
+
+    VIR_NATIVE_VLAN_MODE_LAST
+} virNativeVlanMode;
+
+VIR_ENUM_DECL(virNativeVlanMode)
+
 typedef struct _virNetDevVlan virNetDevVlan;
 typedef virNetDevVlan *virNetDevVlanPtr;
 struct _virNetDevVlan {
     bool trunk;        /* true if this is a trunk */
     int nTags;          /* number of tags in array */
     unsigned int *tag; /* pointer to array of tags */
+    int nativeMode;    /* enum virNativeVlanMode */
+    unsigned int nativeTag;
 };
 
 void virNetDevVlanClear(virNetDevVlanPtr vlan);
index a3d82b165e098c098fd79dbeaccf9b3af59391b8..2f6084d690408b84784837e555f0e9a327846b80 100644 (file)
       <parameters profileid='alice-profile'/>
     </virtualport>
   </portgroup>
+  <portgroup name='native'>
+    <vlan trunk='yes'>
+      <tag id='123' nativeMode='tagged'/>
+      <tag id='444'/>
+    </vlan>
+    <virtualport>
+      <parameters profileid='native-profile'/>
+    </virtualport>
+  </portgroup>
 </network>
index a3d82b165e098c098fd79dbeaccf9b3af59391b8..2f6084d690408b84784837e555f0e9a327846b80 100644 (file)
       <parameters profileid='alice-profile'/>
     </virtualport>
   </portgroup>
+  <portgroup name='native'>
+    <vlan trunk='yes'>
+      <tag id='123' nativeMode='tagged'/>
+      <tag id='444'/>
+    </vlan>
+    <virtualport>
+      <parameters profileid='native-profile'/>
+    </virtualport>
+  </portgroup>
 </network>