diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f795f2e987fc2e810b02b39c12e5c0cf85ab395f..2acae3bf3317355dd445d47ae14f6e7badce1226 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8352,50 +8352,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, if (!bootindex) bootindex = net->info.bootIndex; - /* Currently nothing besides TAP devices supports multiqueue. */ - if (net->driver.virtio.queues > 0 && - !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK || - actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || - actualType == VIR_DOMAIN_NET_TYPE_DIRECT || - actualType == VIR_DOMAIN_NET_TYPE_ETHERNET || - actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Multiqueue network is not supported for: %s"), - virDomainNetTypeToString(actualType)); + if (qemuDomainValidateActualNetDef(net, qemuCaps) < 0) return -1; - } - - /* and only TAP devices support nwfilter rules */ - if (net->filter) { - virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(net); - if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK || - actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || - actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("filterref is not supported for " - "network interfaces of type %s"), - virDomainNetTypeToString(actualType)); - return -1; - } - if (vport && vport->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) { - /* currently none of the defined virtualport types support iptables */ - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("filterref is not supported for " - "network interfaces with virtualport type %s"), - virNetDevVPortTypeToString(vport->virtPortType)); - return -1; - } - } - - if (net->backend.tap && - !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK || - actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || - actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Custom tap device path is not supported for: %s"), - virDomainNetTypeToString(actualType)); - return -1; - } switch (actualType) { case VIR_DOMAIN_NET_TYPE_NETWORK: @@ -8458,14 +8416,6 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, case VIR_DOMAIN_NET_TYPE_VHOSTUSER: requireNicdev = true; - if (net->driver.virtio.queues > 1 && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("multi-queue is not supported for vhost-user " - "with this QEMU binary")); - goto cleanup; - } - if (qemuInterfaceVhostuserConnect(driver, logManager, secManager, cmd, def, net, qemuCaps, &chardev) < 0) goto cleanup; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index bd247628cb3cdbfef4cce388dbc03261cda7c684..ad4db7e8811838d703f7d09ab3044d15a5100ddc 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5300,6 +5300,86 @@ qemuDomainWatchdogDefValidate(const virDomainWatchdogDef *dev, } +int +qemuDomainValidateActualNetDef(const virDomainNetDef *net, + virQEMUCapsPtr qemuCaps) +{ + /* + * Validations that can only be properly checked at runtime (after + * an has been resolved to its actual + * type. + * + * (In its current form this function can still be called before + * the actual type has been resolved (e.g. at domain definition + * time), but only if the validations would SUCCEED for + * type='network'.) + */ + virDomainNetType actualType = virDomainNetGetActualType(net); + + /* Only tap/macvtap devices support multiqueue. */ + if (net->driver.virtio.queues > 0) { + + if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK || + actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || + actualType == VIR_DOMAIN_NET_TYPE_DIRECT || + actualType == VIR_DOMAIN_NET_TYPE_ETHERNET || + actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("multiqueue network is not supported for: %s"), + virDomainNetTypeToString(actualType)); + return -1; + } + + if (net->driver.virtio.queues > 1 && + actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("multiqueue network is not supported for vhost-user " + "with this QEMU binary")); + return -1; + } + } + + /* + * Only standard tap devices support nwfilter rules, and even then only + * when *not* connected to an OVS bridge or midonet (indicated by having + * a element in the config) + */ + if (net->filter) { + virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(net); + if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK || + actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || + actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("filterref is not supported for " + "network interfaces of type %s"), + virDomainNetTypeToString(actualType)); + return -1; + } + if (vport && vport->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) { + /* currently none of the defined virtualport types support iptables */ + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("filterref is not supported for " + "network interfaces with virtualport type %s"), + virNetDevVPortTypeToString(vport->virtPortType)); + return -1; + } + } + + if (net->backend.tap && + !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK || + actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || + actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Custom tap device path is not supported for: %s"), + virDomainNetTypeToString(actualType)); + return -1; + } + + return 0; +} + + static int qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 3e87e75c3a46be2d7c4819779d5e49022856b4af..f53ea146e18b7ad4d8494cd1f1c308e431f34474 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -1215,3 +1215,7 @@ qemuDomainNVRAMPathGenerate(virQEMUDriverConfigPtr cfg, virDomainEventSuspendedDetailType qemuDomainPausedReasonToSuspendedEvent(virDomainPausedReason reason); + +int +qemuDomainValidateActualNetDef(const virDomainNetDef *net, + virQEMUCapsPtr qemuCaps);