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
disableSlirp (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 | 16 +++++++++++++---
3 files changed, 44 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 d41ee0f25b..d1d73d55c7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5688,8 +5688,11 @@ qemuProcessInit(virQEMUDriverPtr driver,
* qemuProcessNetworkPrepareDevices
*/
static int
-qemuProcessNetworkPrepareDevices(virDomainDefPtr def)
+qemuProcessNetworkPrepareDevices(virQEMUDriverPtr driver,
+ virDomainObjPtr vm)
{
+ virDomainDefPtr def = vm->def;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
size_t i;
virConnectPtr conn = NULL;
@@ -5734,7 +5737,14 @@ qemuProcessNetworkPrepareDevices(virDomainDefPtr def)
}
if (virDomainHostdevInsert(def, hostdev) < 0)
goto cleanup;
- }
+ } else if (actualType == VIR_DOMAIN_NET_TYPE_USER &&
+ !priv->disableSlirp &&
+ virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NET_SOCKET_DGRAM)) {
+ qemuSlirpPtr slirp = qemuInterfacePrepareSlirp(driver, net);
+
+ QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;
+ }
+
}
ret = 0;
cleanup:
@@ -6535,7 +6545,7 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver,
* will need to be setup.
*/
VIR_DEBUG("Preparing network devices");
- if (qemuProcessNetworkPrepareDevices(vm->def) < 0)
+ if (qemuProcessNetworkPrepareDevices(driver, vm) < 0)
goto cleanup;
/* Must be run before security labelling */
--
2.23.0.rc1