The underlying function to set the vlan tag of an SR-IOV network
device was already in place (although an extra patch to save/restore
the original vlan tag was needed), and recent patches added the
ability to configure a vlan tag. This patch just ties those two
together.
An SR-IOV device doesn't support vlan trunking, so if anyone tries to
configure more than a single tag, or set the trunk flag, and error is
logged.
---
src/qemu/qemu_hostdev.c | 40 ++++++++++++++++++++++++++++++++++------
1 file changed, 34 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 7619fd0..46c84b5 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -301,6 +301,7 @@ qemuDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
char *stateDir)
{
char *linkdev = NULL;
+ virNetDevVlanPtr vlan;
virNetDevVPortProfilePtr virtPort;
int ret = -1;
int vf = -1;
@@ -319,19 +320,46 @@ qemuDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
if (qemuDomainHostdevNetDevice(hostdev, &linkdev, &vf) < 0)
return ret;
+ vlan = virDomainNetGetActualVlan(hostdev->parent.data.net);
virtPort = virDomainNetGetActualVirtPortProfile(
hostdev->parent.data.net);
- if (virtPort)
+ if (virtPort) {
+ if (vlan) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("direct setting of the vlan tag is not allowed "
+ "for hostdev devices using %s mode"),
+ virNetDevVPortTypeToString(virtPort->virtPortType));
+ goto cleanup;
+ }
ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf,
virtPort, &hostdev->parent.data.net->mac, uuid,
port_profile_associate);
- else
- /* Set only mac */
+ } else {
+ /* Set only mac and vlan */
+ if (vlan) {
+ if (vlan->nTags != 1 || vlan->trunk) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vlan trunking is not supported "
+ "by SR-IOV network devices"));
+ goto cleanup;
+ }
+ if (vf == -1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("vlan can only be set for SR-IOV VFs, but "
+ "%s is not a VF"), linkdev);
+ goto cleanup;
+ }
+ vlanid = vlan->tag[0];
+ } else if (vf >= 0) {
+ vlanid = 0; /* assure any current vlan tag is reset */
+ }
+
ret = virNetDevReplaceNetConfig(linkdev, vf,
- &hostdev->parent.data.net->mac,
vlanid,
- stateDir);
+ &hostdev->parent.data.net->mac,
+ vlanid, stateDir);
+ }
+cleanup:
VIR_FREE(linkdev);
-
return ret;
}
--
1.7.11.4