diff --git a/src/Makefile.am b/src/Makefile.am
index b6c1701381..550362cca3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -733,7 +733,8 @@ QEMU_DRIVER_SOURCES = \
qemu/qemu_monitor_text.h \
qemu/qemu_monitor_json.c \
qemu/qemu_monitor_json.h \
- qemu/qemu_driver.c qemu/qemu_driver.h
+ qemu/qemu_driver.c qemu/qemu_driver.h \
+ qemu/qemu_interface.c qemu/qemu_interface.h
XENAPI_DRIVER_SOURCES = \
xenapi/xenapi_driver.c xenapi/xenapi_driver.h \
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 632fc17ac6..1c0d4e5bf1 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -297,6 +297,7 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
virNetDevVPortProfilePtr prof;
virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
const char *linkdev = virDomainNetGetActualDirectDev(net);
+ unsigned int macvlan_create_flags = VIR_NETDEV_MACVLAN_CREATE_IFUP;
/* XXX how todo bandwidth controls ?
* Since the 'net-ifname' is about to be moved to a different
@@ -332,7 +333,8 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
prof,
&res_ifname,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
- cfg->stateDir, 0) < 0)
+ cfg->stateDir,
+ macvlan_create_flags) < 0)
goto cleanup;
ret = res_ifname;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 95304517af..8c0642e424 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -30,6 +30,7 @@
#include "qemu_domain.h"
#include "qemu_command.h"
#include "qemu_hostdev.h"
+#include "qemu_interface.h"
#include "domain_audit.h"
#include "netdev_bandwidth_conf.h"
#include "domain_nwfilter.h"
@@ -943,6 +944,10 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
goto cleanup;
}
+ /* Set device online immediately */
+ if (qemuInterfaceStartDevice(net) < 0)
+ goto cleanup;
+
/* Set Bandwidth */
if (virNetDevSupportBandwidth(actualType) &&
virNetDevBandwidthSet(net->ifname,
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
new file mode 100644
index 0000000000..b0f0c5df9f
--- /dev/null
+++ b/src/qemu/qemu_interface.c
@@ -0,0 +1,100 @@
+/*
+ * qemu_interface.c: QEMU interface management
+ *
+ * Copyright IBM Corp. 2014
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * .
+ *
+ * Authors:
+ * Matthew J. Rosato
+ */
+
+#include
+
+#include "qemu_interface.h"
+#include "virnetdev.h"
+#include "virnetdevtap.h"
+#include "virnetdevmacvlan.h"
+#include "virnetdevvportprofile.h"
+
+/**
+ * qemuInterfaceStartDevice:
+ * @net: net device to start
+ *
+ * Based upon the type of device provided, perform the appropriate
+ * work to completely activate the device and make it reachable from
+ * the rest of the network.
+ */
+int
+qemuInterfaceStartDevice(virDomainNetDefPtr net)
+{
+ int ret = -1;
+
+ switch (virDomainNetGetActualType(net)) {
+ case VIR_DOMAIN_NET_TYPE_BRIDGE:
+ case VIR_DOMAIN_NET_TYPE_NETWORK:
+ break;
+ case VIR_DOMAIN_NET_TYPE_DIRECT:
+ /* macvtap devices share their MAC address with the guest
+ * domain, and if they are set online prior to the domain CPUs
+ * being started, the host may send out traffic from this
+ * device that could confuse other entities on the network (in
+ * particular, if this new domain is the destination of a
+ * migration, and the source domain is still running, another
+ * host may mistakenly direct traffic for the guest to the
+ * destination domain rather than source domain). To prevent
+ * this, we create the macvtap device with IFF_UP false
+ * (i.e. "offline") then wait to bring it online until just as
+ * we are starting the domain CPUs.
+ */
+ if (virNetDevSetOnline(net->ifname, true) < 0)
+ goto cleanup;
+ break;
+
+ case VIR_DOMAIN_NET_TYPE_USER:
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+ case VIR_DOMAIN_NET_TYPE_SERVER:
+ case VIR_DOMAIN_NET_TYPE_CLIENT:
+ case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_INTERNAL:
+ case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+ case VIR_DOMAIN_NET_TYPE_LAST:
+ /* these types all require no action */
+ break;
+ }
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+/**
+ * qemuInterfaceStartDevices:
+ * @def: domain definition
+ *
+ * Set all ifaces associated with this domain to the online state.
+ */
+int
+qemuInterfaceStartDevices(virDomainDefPtr def)
+{
+ size_t i;
+
+ for (i = 0; i < def->nnets; i++) {
+ if (qemuInterfaceStartDevice(def->nets[i]) < 0)
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
new file mode 100644
index 0000000000..d040f52611
--- /dev/null
+++ b/src/qemu/qemu_interface.h
@@ -0,0 +1,32 @@
+/*
+ * qemu_interface.h: QEMU interface management
+ *
+ * Copyright IBM Corp. 2014
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * .
+ *
+ * Authors:
+ * Matthew J. Rosato
+ */
+
+#ifndef __QEMU_INTERFACE_H__
+# define __QEMU_INTERFACE_H__
+
+# include "domain_conf.h"
+
+int qemuInterfaceStartDevice(virDomainNetDefPtr net);
+int qemuInterfaceStartDevices(virDomainDefPtr def);
+
+#endif /* __QEMU_INTERFACE_H__ */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a14b6f7fe0..ab4df9bce5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -42,6 +42,7 @@
#include "qemu_hostdev.h"
#include "qemu_hotplug.h"
#include "qemu_migration.h"
+#include "qemu_interface.h"
#include "cpu/cpu.h"
#include "datatypes.h"
@@ -3124,6 +3125,12 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
qemuDomainObjPrivatePtr priv = vm->privateData;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ /* Bring up netdevs before starting CPUs */
+ if (reason != VIR_DOMAIN_RUNNING_UNPAUSED &&
+ reason != VIR_DOMAIN_RUNNING_SAVE_CANCELED &&
+ qemuInterfaceStartDevices(vm->def) < 0)
+ goto cleanup;
+
VIR_DEBUG("Using lock state '%s'", NULLSTR(priv->lockState));
if (virDomainLockProcessResume(driver->lockManager, cfg->uri,
vm, priv->lockState) < 0) {
diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
index 2ff24b1f90..f2eae06115 100644
--- a/src/util/virnetdevmacvlan.c
+++ b/src/util/virnetdevmacvlan.c
@@ -899,9 +899,11 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
goto link_del_exit;
}
- if (virNetDevSetOnline(cr_ifname, true) < 0) {
- rc = -1;
- goto disassociate_exit;
+ if (flags & VIR_NETDEV_MACVLAN_CREATE_IFUP) {
+ if (virNetDevSetOnline(cr_ifname, true) < 0) {
+ rc = -1;
+ goto disassociate_exit;
+ }
}
if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) {
diff --git a/src/util/virnetdevmacvlan.h b/src/util/virnetdevmacvlan.h
index f08d32bf5d..298e52240e 100644
--- a/src/util/virnetdevmacvlan.h
+++ b/src/util/virnetdevmacvlan.h
@@ -44,6 +44,8 @@ typedef enum {
VIR_NETDEV_MACVLAN_CREATE_NONE = 0,
/* Create with a tap device */
VIR_NETDEV_MACVLAN_CREATE_WITH_TAP = 1 << 0,
+ /* Bring the interface up */
+ VIR_NETDEV_MACVLAN_CREATE_IFUP = 1 << 1,
} virNetDevMacVLanCreateFlags;
int virNetDevMacVLanCreate(const char *ifname,