diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fd1e5cdb47..f795f2e987 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -28,6 +28,7 @@ #include "qemu_alias.h" #include "qemu_security.h" #include "qemu_dbus.h" +#include "qemu_slirp.h" #include "qemu_block.h" #include "cpu/cpu.h" #include "dirname.h" @@ -3909,7 +3910,8 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, char **tapfd, size_t tapfdSize, char **vhostfd, - size_t vhostfdSize) + size_t vhostfdSize, + const char *slirpfd) { bool is_tap = false; VIR_AUTOCLEAN(virBuffer) buf = VIR_BUFFER_INITIALIZER; @@ -3979,24 +3981,28 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, break; case VIR_DOMAIN_NET_TYPE_USER: - virBufferAddLit(&buf, "user,"); - for (i = 0; i < net->guestIP.nips; i++) { - const virNetDevIPAddr *ip = net->guestIP.ips[i]; - VIR_AUTOFREE(char *) addr = NULL; - const char *prefix = ""; + if (slirpfd) { + virBufferAsprintf(&buf, "socket,fd=%s,", slirpfd); + } else { + virBufferAddLit(&buf, "user,"); + for (i = 0; i < net->guestIP.nips; i++) { + const virNetDevIPAddr *ip = net->guestIP.ips[i]; + VIR_AUTOFREE(char *) addr = NULL; + const char *prefix = ""; - if (!(addr = virSocketAddrFormat(&ip->address))) - goto cleanup; + if (!(addr = virSocketAddrFormat(&ip->address))) + goto cleanup; - if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET)) - prefix = "net="; - if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6)) - prefix = "ipv6-net="; + if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET)) + prefix = "net="; + if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6)) + prefix = "ipv6-net="; - virBufferAsprintf(&buf, "%s%s", prefix, addr); - if (ip->prefix) - virBufferAsprintf(&buf, "/%u", ip->prefix); - virBufferAddChar(&buf, ','); + virBufferAsprintf(&buf, "%s%s", prefix, addr); + if (ip->prefix) + virBufferAsprintf(&buf, "/%u", ip->prefix); + virBufferAddChar(&buf, ','); + } } break; @@ -8312,10 +8318,10 @@ qemuInterfaceVhostuserConnect(virQEMUDriverPtr driver, static int qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, + virDomainObjPtr vm, virLogManagerPtr logManager, virSecurityManagerPtr secManager, virCommandPtr cmd, - virDomainDefPtr def, virDomainNetDefPtr net, virQEMUCapsPtr qemuCaps, unsigned int bootindex, @@ -8324,6 +8330,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, size_t *nnicindexes, int **nicindexes) { + virDomainDefPtr def = vm->def; int ret = -1; VIR_AUTOFREE(char *) nic = NULL; VIR_AUTOFREE(char *) host = NULL; @@ -8334,9 +8341,11 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, size_t vhostfdSize = 0; char **tapfdName = NULL; char **vhostfdName = NULL; + VIR_AUTOFREE(char *) slirpfdName = NULL; virDomainNetType actualType = virDomainNetGetActualType(net); virNetDevBandwidthPtr actualBandwidth; bool requireNicdev = false; + qemuSlirpPtr slirp; size_t i; @@ -8562,6 +8571,16 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, goto cleanup; } + slirp = QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp; + if (slirp && !standalone) { + int slirpfd = qemuSlirpGetFD(slirp); + virCommandPassFD(cmd, slirpfd, + VIR_COMMAND_PASS_FD_CLOSE_PARENT); + if (virAsprintf(&slirpfdName, "%d", slirpfd) < 0) + goto cleanup; + } + + for (i = 0; i < tapfdSize; i++) { if (qemuSecuritySetTapFDLabel(driver->securityManager, def, tapfd[i]) < 0) @@ -8586,7 +8605,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, if (!(host = qemuBuildHostNetStr(net, driver, tapfdName, tapfdSize, - vhostfdName, vhostfdSize))) + vhostfdName, vhostfdSize, + slirpfdName))) goto cleanup; virCommandAddArgList(cmd, "-netdev", host, NULL); @@ -8651,10 +8671,10 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, */ static int qemuBuildNetCommandLine(virQEMUDriverPtr driver, + virDomainObjPtr vm, virLogManagerPtr logManager, virSecurityManagerPtr secManager, virCommandPtr cmd, - virDomainDefPtr def, virQEMUCapsPtr qemuCaps, virNetDevVPortProfileOp vmop, bool standalone, @@ -8665,6 +8685,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver, size_t i; int last_good_net = -1; virErrorPtr originalError = NULL; + virDomainDefPtr def = vm->def; if (def->nnets) { unsigned int bootNet = 0; @@ -8680,7 +8701,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver, for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; - if (qemuBuildInterfaceCommandLine(driver, logManager, secManager, cmd, def, net, + if (qemuBuildInterfaceCommandLine(driver, vm, logManager, secManager, cmd, net, qemuCaps, bootNet, vmop, standalone, nnicindexes, nicindexes) < 0) @@ -10402,7 +10423,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildFilesystemCommandLine(cmd, def, qemuCaps) < 0) return NULL; - if (qemuBuildNetCommandLine(driver, logManager, secManager, cmd, def, + if (qemuBuildNetCommandLine(driver, vm, logManager, secManager, cmd, qemuCaps, vmop, standalone, nnicindexes, nicindexes, &bootHostdevNet) < 0) return NULL; diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 74cb1e76d6..ec8e43ace1 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -90,7 +90,8 @@ char *qemuBuildHostNetStr(virDomainNetDefPtr net, char **tapfd, size_t tapfdSize, char **vhostfd, - size_t vhostfdSize); + size_t vhostfdSize, + const char *slirpfd); /* Current, best practice */ char *qemuBuildNicDevStr(virDomainDefPtr def, diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 71c4afb4a5..69eeb50a2d 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1385,7 +1385,8 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, if (!(netstr = qemuBuildHostNetStr(net, driver, tapfdName, tapfdSize, - vhostfdName, vhostfdSize))) + vhostfdName, vhostfdSize, + NULL))) goto cleanup; qemuDomainObjEnterMonitor(driver, vm);