From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
When the network interface is of "user" type, and QEMU has the "-net
socket,fd=" datagram support, call qemuInterfacePrepareSlirp() to
probe and associate a slirp-helper with the interface.
The usage of automated slirp-helper can be prevented with
VIR_QEMU_PROCESS_START_NO_SLIRP (in particular when resuming a
VM that didn't start with slirp-helper before).
Signed-off-by: Marc-André Lureau <marcandre.lureau(a)redhat.com>
---
src/qemu/qemu_interface.c | 27 +++++++++++++++++++++++++++
src/qemu/qemu_interface.h | 4 ++++
src/qemu/qemu_process.c | 17 ++++++++++++++---
3 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index c8effa68f4..e58f464d87 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -603,6 +603,33 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def,
}
+qemuSlirpPtr
+qemuInterfacePrepareSlirp(virQEMUDriverPtr driver,
+ virDomainNetDefPtr net)
+{
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ VIR_AUTOPTR(qemuSlirp) slirp = NULL;
+ size_t i;
+
+ if (!(slirp = qemuSlirpNewForHelper(cfg->slirpHelperName)))
+ return NULL;
+
+ for (i = 0; i < net->guestIP.nips; i++) {
+ const virNetDevIPAddr *ip = net->guestIP.ips[i];
+
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET) &&
+ !qemuSlirpHasFeature(slirp, QEMU_SLIRP_FEATURE_IPV4))
+ return NULL;
+
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6) &&
+ !qemuSlirpHasFeature(slirp, QEMU_SLIRP_FEATURE_IPV6))
+ return NULL;
+ }
+
+ VIR_RETURN_PTR(slirp);
+}
+
+
/**
* qemuInterfaceOpenVhostNet:
* @def: domain definition
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index 5a2f87e532..0464b903d7 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -24,6 +24,7 @@
#include "domain_conf.h"
#include "qemu_conf.h"
#include "qemu_domain.h"
+#include "qemu_slirp.h"
int qemuInterfaceStartDevice(virDomainNetDefPtr net);
int qemuInterfaceStartDevices(virDomainDefPtr def);
@@ -54,3 +55,6 @@ int qemuInterfaceOpenVhostNet(virDomainDefPtr def,
virDomainNetDefPtr net,
int *vhostfd,
size_t *vhostfdSize);
+
+qemuSlirpPtr qemuInterfacePrepareSlirp(virQEMUDriverPtr driver,
+ virDomainNetDefPtr net);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d067223a0e..856460f0b6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5619,8 +5619,12 @@ qemuProcessInit(virQEMUDriverPtr driver,
* qemuProcessNetworkPrepareDevices
*/
static int
-qemuProcessNetworkPrepareDevices(virDomainDefPtr def)
+qemuProcessNetworkPrepareDevices(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ unsigned int flags)
{
+ virDomainDefPtr def = vm->def;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
size_t i;
virConnectPtr conn = NULL;
@@ -5665,7 +5669,14 @@ qemuProcessNetworkPrepareDevices(virDomainDefPtr def)
}
if (virDomainHostdevInsert(def, hostdev) < 0)
goto cleanup;
- }
+ } else if (actualType == VIR_DOMAIN_NET_TYPE_USER &&
+ !(flags & VIR_QEMU_PROCESS_START_NO_SLIRP) &&
+ virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NET_SOCKET_DGRAM)) {
+ qemuSlirpPtr slirp = qemuInterfacePrepareSlirp(driver, net);
+
+ QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;
+ }
+
}
ret = 0;
cleanup:
@@ -6468,7 +6479,7 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver,
* will need to be setup.
*/
VIR_DEBUG("Preparing network devices");
- if (qemuProcessNetworkPrepareDevices(vm->def) < 0)
+ if (qemuProcessNetworkPrepareDevices(driver, vm, flags) < 0)
goto cleanup;
/* Must be run before security labelling */
--
2.22.0.214.g8dca754b1e