From 861d40565e9a53fdf127b8b3a2fe4029dcb6219f Mon Sep 17 00:00:00 2001
From: james robson
Date: Thu, 23 May 2013 18:12:10 +0100
Subject: [PATCH] Configure native vlan modes on Open vSwitch ports
This patch adds functionality to allow libvirt to configure the
'native-tagged' and 'native-untagged' modes on openvswitch networks.
Signed-off-by: Laine Stump
---
docs/formatdomain.html.in | 16 ++++++++
docs/formatnetwork.html.in | 15 +++++++
docs/schemas/networkcommon.rng | 8 ++++
src/conf/netdev_vlan_conf.c | 43 ++++++++++++++++++++-
src/util/virnetdevopenvswitch.c | 14 +++++++
src/util/virnetdevvlan.c | 8 +++-
src/util/virnetdevvlan.h | 15 ++++++-
tests/networkxml2xmlin/openvswitch-net.xml | 9 +++++
tests/networkxml2xmlout/openvswitch-net.xml | 9 +++++
9 files changed, 134 insertions(+), 3 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 77126a56fe..17ea9c2486 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3523,6 +3523,13 @@ qemu-kvm -net nic,model=? /dev/null
<parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
</virtualport>
</interface>
+ <interface type='bridge'>
+ <vlan trunk='yes'>
+ <tag id='42'/>
+ <tag id='123' nativeMode='untagged'/>
+ </vlan>
+ ...
+ </interface>
<devices>
...
@@ -3549,6 +3556,15 @@ qemu-kvm -net nic,model=? /dev/null
vlan element.
+
+ For network connections using openvswitch it is possible to
+ configure the 'native-tagged' and 'native-untagged' vlan modes
+ Since 1.0.7. This uses the optional
+ nativeMode
attribute on the <tag>
+ element: nativeMode
may be set to 'tagged' or
+ 'untagged'. The id atribute of the element sets the native vlan.
+
+
...
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index a1198ce6be..6a4b36df2a 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -446,6 +446,13 @@
<parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
</virtualport>
</interface>
+ <interface type='bridge'>
+ <vlan trunk='yes'>
+ <tag id='42'/>
+ <tag id='123' nativeMode='untagged'/>
+ </vlan>
+ ...
+ </interface>
<devices>
...
@@ -468,6 +475,14 @@
is desired, the optional attribute trunk='yes'
can
be added to the vlan element.
+
+ For network connections using openvswitch it is possible to
+ configure the 'native-tagged' and 'native-untagged' vlan modes
+ Since 1.0.7. This uses the optional
+ nativeMode
attribute on the <tag>
+ element: nativeMode
may be set to 'tagged' or
+ 'untagged'. The id atribute of the element sets the native vlan.
+
<vlan>
elements can also be specified in
a <portgroup>
element, as well as directly in
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index 51ff7592ea..e60f1fc99d 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -204,6 +204,14 @@
4095
+
+
+
+ tagged
+ untagged
+
+
+
diff --git a/src/conf/netdev_vlan_conf.c b/src/conf/netdev_vlan_conf.c
index 13ba8c6ab8..82ff9e8b65 100644
--- a/src/conf/netdev_vlan_conf.c
+++ b/src/conf/netdev_vlan_conf.c
@@ -17,6 +17,7 @@
*
* Authors:
* Laine Stump
+ * James Robson
*/
#include
@@ -27,12 +28,16 @@
#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 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 - \"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, "\n", def->trunk ? " trunk='yes'" : "");
for (ii = 0; ii < def->nTags; ii++) {
- virBufferAsprintf(buf, " \n", def->tag[ii]);
+ if (def->nativeMode != VIR_NATIVE_VLAN_MODE_DEFAULT &&
+ def->nativeTag == def->tag[ii]) {
+ /* check the nativeMode in case we get */
+ const char *mode = virNativeVlanModeTypeToString(def->nativeMode);
+ if (!mode) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Bad value for nativeMode"));
+ }
+ virBufferAsprintf(buf, " \n",
+ def->tag[ii], mode);
+ } else {
+ virBufferAsprintf(buf, " \n", def->tag[ii]);
+ }
}
virBufferAddLit(buf, "\n");
return 0;
diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c
index 2aee445a58..5834e4e413 100644
--- a/src/util/virnetdevopenvswitch.c
+++ b/src/util/virnetdevopenvswitch.c
@@ -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);
diff --git a/src/util/virnetdevvlan.c b/src/util/virnetdevvlan.c
index 2fe2017b58..eed32f75ab 100644
--- a/src/util/virnetdevvlan.c
+++ b/src/util/virnetdevvlan.c
@@ -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;
}
diff --git a/src/util/virnetdevvlan.h b/src/util/virnetdevvlan.h
index c6b16efd2e..fd1762a266 100644
--- a/src/util/virnetdevvlan.h
+++ b/src/util/virnetdevvlan.h
@@ -18,16 +18,29 @@
* Authors:
* Laine Stump
*/
-
#ifndef __VIR_NETDEV_VLAN_H__
# define __VIR_NETDEV_VLAN_H__
+# include
+
+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);
diff --git a/tests/networkxml2xmlin/openvswitch-net.xml b/tests/networkxml2xmlin/openvswitch-net.xml
index a3d82b165e..2f6084d690 100644
--- a/tests/networkxml2xmlin/openvswitch-net.xml
+++ b/tests/networkxml2xmlin/openvswitch-net.xml
@@ -21,4 +21,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/tests/networkxml2xmlout/openvswitch-net.xml b/tests/networkxml2xmlout/openvswitch-net.xml
index a3d82b165e..2f6084d690 100644
--- a/tests/networkxml2xmlout/openvswitch-net.xml
+++ b/tests/networkxml2xmlout/openvswitch-net.xml
@@ -21,4 +21,13 @@
+
+
+
+
+
+
+
+
+