diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1396661ca95d5f652a518ee48dc17f5c2c10a863..0767c66490367bc475878deb6f76b0f5f591ef85 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3555,7 +3555,8 @@ qemuBuildNicDevStr(virDomainDefPtr def, int vlan, unsigned int bootindex, size_t vhostfdSize, - virQEMUCapsPtr qemuCaps) + virQEMUCapsPtr qemuCaps, + unsigned int mtu) { virBuffer buf = VIR_BUFFER_INITIALIZER; const char *nic = net->model; @@ -3679,13 +3680,23 @@ qemuBuildNicDevStr(virDomainDefPtr def, virBufferAsprintf(&buf, ",rx_queue_size=%u", net->driver.virtio.rx_queue_size); } - if (usingVirtio && net->mtu) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("setting MTU is not supported with this QEMU binary")); - goto error; + if (usingVirtio && mtu) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) { + + virBufferAsprintf(&buf, ",host_mtu=%u", mtu); + + } else { + /* log an error if mtu was requested specifically for this + * interface, otherwise, if it's just what was reported by + * the attached network, ignore it. + */ + if (net->mtu) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("setting MTU is not supported with " + "this QEMU binary")); + goto error; + } } - virBufferAsprintf(&buf, ",host_mtu=%u", net->mtu); } if (vlan == -1) @@ -8042,7 +8053,7 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver, VIR_FREE(netdev); if (!(nic = qemuBuildNicDevStr(def, net, -1, bootindex, - queues, qemuCaps))) { + queues, qemuCaps, net->mtu))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Error generating NIC -device string")); goto error; @@ -8088,6 +8099,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, virDomainNetType actualType = virDomainNetGetActualType(net); virNetDevBandwidthPtr actualBandwidth; size_t i; + unsigned int mtu = net->mtu; if (!bootindex) @@ -8142,7 +8154,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, memset(tapfd, -1, tapfdSize * sizeof(tapfd[0])); if (qemuInterfaceBridgeConnect(def, driver, net, - tapfd, &tapfdSize) < 0) + tapfd, &tapfdSize, &mtu) < 0) goto cleanup; break; @@ -8322,7 +8334,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, } if (qemuDomainSupportsNicdev(def, net)) { if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex, - vhostfdSize, qemuCaps))) + vhostfdSize, qemuCaps, mtu))) goto cleanup; virCommandAddArgList(cmd, "-device", nic, NULL); } else { diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 3bcfdc6e4fd252b0333431a67c8c76237d18df04..69fe84613961989923accb11359353d88f798297 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -101,7 +101,8 @@ char *qemuBuildNicDevStr(virDomainDefPtr def, int vlan, unsigned int bootindex, size_t vhostfdSize, - virQEMUCapsPtr qemuCaps); + virQEMUCapsPtr qemuCaps, + unsigned int mtu); char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 8a4d20dba5cdc443694b4726c75b3429165dee87..e272df35607977f50635f36aa7c81adbaedabbd3 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -969,6 +969,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, bool charDevPlugged = false; bool netdevPlugged = false; bool hostPlugged = false; + unsigned int mtu = net->mtu; /* preallocate new slot for device */ if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0) @@ -1025,7 +1026,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, goto cleanup; memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize); if (qemuInterfaceBridgeConnect(vm->def, driver, net, - tapfd, &tapfdSize) < 0) + tapfd, &tapfdSize, &mtu) < 0) goto cleanup; iface_connected = true; if (qemuInterfaceOpenVhostNet(vm->def, net, priv->qemuCaps, @@ -1236,7 +1237,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, VIR_FORCE_CLOSE(vhostfd[i]); if (!(nicstr = qemuBuildNicDevStr(vm->def, net, vlan, 0, - queueSize, priv->qemuCaps))) + queueSize, priv->qemuCaps, mtu))) goto try_remove; qemuDomainObjEnterMonitor(driver, vm); diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c index ce448d24330279a2c9fd85a6f715cf665e6f595c..c5dca60f1f654dfbff2335469f3bce87791f4707 100644 --- a/src/qemu/qemu_interface.c +++ b/src/qemu/qemu_interface.c @@ -503,7 +503,8 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def, virQEMUDriverPtr driver, virDomainNetDefPtr net, int *tapfd, - size_t *tapfdSize) + size_t *tapfdSize, + unsigned int *mtu) { const char *brname; int ret = -1; @@ -544,7 +545,7 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def, def->uuid, tunpath, tapfd, *tapfdSize, virDomainNetGetActualVirtPortProfile(net), virDomainNetGetActualVlan(net), - 0, NULL, + net->mtu, mtu, tap_create_flags) < 0) { virDomainAuditNetDevice(def, net, tunpath, false); goto cleanup; diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h index a7faa0b3da71a9e7c8328c3a2aaf252c91cebf91..ba74ac2cfe4b5fbcfb9e9acae8a722f646b59db5 100644 --- a/src/qemu/qemu_interface.h +++ b/src/qemu/qemu_interface.h @@ -51,7 +51,8 @@ int qemuInterfaceBridgeConnect(virDomainDefPtr def, virQEMUDriverPtr driver, virDomainNetDefPtr net, int *tapfd, - size_t *tapfdSize) + size_t *tapfdSize, + unsigned int *mtu) ATTRIBUTE_NONNULL(2); int qemuInterfaceOpenVhostNet(virDomainDefPtr def,