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@xxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list