mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
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 <laine@redhat.com>
This commit is contained in:
parent
1eeab6e6de
commit
861d40565e
@ -3523,6 +3523,13 @@ qemu-kvm -net nic,model=? /dev/null
|
||||
<parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
||||
</virtualport>
|
||||
</interface>
|
||||
<interface type='bridge'>
|
||||
<b><vlan trunk='yes'></b>
|
||||
<b><tag id='42'/></b>
|
||||
<b><tag id='123' nativeMode='untagged'/></b>
|
||||
<b></vlan></b>
|
||||
...
|
||||
</interface>
|
||||
<devices>
|
||||
...</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><tag></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>
|
||||
...
|
||||
|
@ -446,6 +446,13 @@
|
||||
<parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
||||
</virtualport>
|
||||
</interface>
|
||||
<interface type='bridge'>
|
||||
<b><vlan trunk='yes'></b>
|
||||
<b><tag id='42'/></b>
|
||||
<b><tag id='123' nativeMode='untagged'/></b>
|
||||
<b></vlan></b>
|
||||
...
|
||||
</interface>
|
||||
<devices>
|
||||
...</pre>
|
||||
|
||||
@ -468,6 +475,14 @@
|
||||
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><tag></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><vlan></code> elements can also be specified in
|
||||
a <code><portgroup></code> element, as well as directly in
|
||||
|
@ -204,6 +204,14 @@
|
||||
<param name="maxInclusive">4095</param>
|
||||
</data>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="nativeMode">
|
||||
<choice>
|
||||
<value>tagged</value>
|
||||
<value>untagged</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<empty/>
|
||||
</element>
|
||||
</oneOrMore>
|
||||
|
@ -17,6 +17,7 @@
|
||||
*
|
||||
* Authors:
|
||||
* Laine Stump <laine@redhat.com>
|
||||
* James Robson <jrobson@websense.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -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 <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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -18,16 +18,29 @@
|
||||
* 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);
|
||||
|
@ -21,4 +21,13 @@
|
||||
<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>
|
||||
|
@ -21,4 +21,13 @@
|
||||
<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>
|
||||
|
Loading…
Reference in New Issue
Block a user