Add the ability to specify a "vlantag" parameter for bridge
networks with a virtualport type of openvswitch. This
allows for specifying the port is on a single VLAN, and
should receive untagged traffic (e.g. vlantag=10), or that
a port should receive tagged traffic and is a trunk port
(e.g. vlantag=10,11).
Signed-off-by: Kyle Mestery <kmestery(a)cisco.com>
---
src/conf/netdev_vport_profile_conf.c | 34 ++++++++++++++++++++++++++++++----
src/util/virnetdevopenvswitch.c | 23 +++++++++++++++++++++--
src/util/virnetdevvportprofile.h | 2 ++
3 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/src/conf/netdev_vport_profile_conf.c b/src/conf/netdev_vport_profile_conf.c
index d008042..5a4e894 100644
--- a/src/conf/netdev_vport_profile_conf.c
+++ b/src/conf/netdev_vport_profile_conf.c
@@ -46,6 +46,7 @@ virNetDevVPortProfileParse(xmlNodePtr node)
char *virtPortInstanceID = NULL;
char *virtPortProfileID = NULL;
char *virtPortInterfaceID = NULL;
+ char *virtPortVlanTag = NULL;
virNetDevVPortProfilePtr virtPort = NULL;
xmlNodePtr cur = node->children;
@@ -76,6 +77,7 @@ virNetDevVPortProfileParse(xmlNodePtr node)
virtPortInstanceID = virXMLPropString(cur, "instanceid");
virtPortProfileID = virXMLPropString(cur, "profileid");
virtPortInterfaceID = virXMLPropString(cur, "interfaceid");
+ virtPortVlanTag = virXMLPropString(cur, "vlantag");
break;
}
@@ -196,6 +198,18 @@ virNetDevVPortProfileParse(xmlNodePtr node)
} else {
virtPort->u.openvswitch.profileID[0] = '\0';
}
+ /* vlantag is not mandatory for Open vSwitch */
+ if (virtPortVlanTag != NULL) {
+
+ if (virStrcpyStatic(virtPort->u.openvswitch.vlantag,
+ virtPortVlanTag) == NULL) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("vlantag parameter too long"));
+ goto error;
+ }
+ } else {
+ virtPort->u.openvswitch.vlantag[0] = '\0';
+ }
break;
default:
@@ -254,13 +268,25 @@ virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort,
case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH:
virUUIDFormat(virtPort->u.openvswitch.interfaceID,
uuidstr);
- if (virtPort->u.openvswitch.profileID[0] == '\0') {
+ if (virtPort->u.openvswitch.profileID[0] == '\0' &&
+ virtPort->u.openvswitch.vlantag[0] == '\0') {
virBufferAsprintf(buf, " <parameters
interfaceid='%s'/>\n",
uuidstr);
} else {
- virBufferAsprintf(buf, " <parameters interfaceid='%s'
"
- "profileid='%s'/>\n", uuidstr,
- virtPort->u.openvswitch.profileID);
+ if (virtPort->u.openvswitch.vlantag[0] == '\0') {
+ virBufferAsprintf(buf, " <parameters interfaceid='%s'
"
+ "profileid='%s'/>\n", uuidstr,
+ virtPort->u.openvswitch.profileID);
+ } else if (virtPort->u.openvswitch.profileID[0] == '\0') {
+ virBufferAsprintf(buf, " <parameters interfaceid='%s'
"
+ "vlantag='%s'/>\n", uuidstr,
+ virtPort->u.openvswitch.vlantag);
+ } else {
+ virBufferAsprintf(buf, " <parameters interfaceid='%s'
"
+ "profileid='%s'
vlantag='%s'/>\n", uuidstr,
+ virtPort->u.openvswitch.profileID,
+ virtPort->u.openvswitch.vlantag);
+ }
}
break;
diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c
index 7e0beef..ea71dd1 100644
--- a/src/util/virnetdevopenvswitch.c
+++ b/src/util/virnetdevopenvswitch.c
@@ -57,6 +57,7 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname,
char *ifaceid_ex_id = NULL;
char *profile_ex_id = NULL;
char *vmid_ex_id = NULL;
+ char *vlantag = NULL;
virMacAddrFormat(macaddr, macaddrstr);
virUUIDFormat(ovsport->u.openvswitch.interfaceID, ifuuidstr);
@@ -76,11 +77,29 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char
*ifname,
ovsport->u.openvswitch.profileID) < 0)
goto out_of_memory;
}
+ if (ovsport->u.openvswitch.vlantag[0] != '\0') {
+ int i = 0;
+ const char *ovsvlan = "tag";
+
+ /* Parse this. It's either a single entry, or multiple */
+ while (ovsport->u.openvswitch.vlantag[i] != '\0') {
+ if (ovsport->u.openvswitch.vlantag[i] == ',') {
+ ovsvlan = "trunks";
+ break;
+ }
+
+ i++;
+ }
+
+ if (virAsprintf(&vlantag, "%s=%s", ovsvlan,
+ ovsport->u.openvswitch.vlantag) < 0)
+ goto out_of_memory;
+ }
cmd = virCommandNew(OVSVSCTL);
if (ovsport->u.openvswitch.profileID[0] == '\0') {
virCommandAddArgList(cmd, "--", "--may-exist",
"add-port",
- brname, ifname,
+ brname, ifname, vlantag,
"--", "set", "Interface", ifname,
attachedmac_ex_id,
"--", "set", "Interface", ifname,
ifaceid_ex_id,
"--", "set", "Interface", ifname,
vmid_ex_id,
@@ -89,7 +108,7 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char
*ifname,
NULL);
} else {
virCommandAddArgList(cmd, "--", "--may-exist",
"add-port",
- brname, ifname,
+ brname, ifname, vlantag,
"--", "set", "Interface", ifname,
attachedmac_ex_id,
"--", "set", "Interface", ifname,
ifaceid_ex_id,
"--", "set", "Interface", ifname,
vmid_ex_id,
diff --git a/src/util/virnetdevvportprofile.h b/src/util/virnetdevvportprofile.h
index 6cce1bb..7cacd4f 100644
--- a/src/util/virnetdevvportprofile.h
+++ b/src/util/virnetdevvportprofile.h
@@ -31,6 +31,7 @@
# include "virmacaddr.h"
# define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40
+# define LIBVIRT_VLANTAG_MAX 128
enum virNetDevVPortProfile {
VIR_NETDEV_VPORT_PROFILE_NONE,
@@ -74,6 +75,7 @@ struct _virNetDevVPortProfile {
struct {
unsigned char interfaceID[VIR_UUID_BUFLEN];
char profileID[LIBVIRT_IFLA_VF_PORT_PROFILE_MAX];
+ char vlantag[LIBVIRT_VLANTAG_MAX];
} openvswitch;
} u;
};
--
1.7.11.2