summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorLaine Stump <laine@laine.org>2017-03-21 11:24:08 -0400
committerLaine Stump <laine@laine.org>2017-03-22 12:18:27 -0400
commit85bcc0220fcdc33452421256ef26d6e0080278b7 (patch)
treebc796ca8f115cd4cb70191c53dea36e3a4fc94f5 /src/network
parenta4541349516b5aff2da6c5309eda86dcbe6f8233 (diff)
downloadlibvirt-85bcc0220fcdc33452421256ef26d6e0080278b7.tar.gz
network: reconnect tap devices during networkNotifyActualDevice
If a network is destroyed and restarted, or its bridge is changed, any tap devices that had previously been connected to the bridge will no longer be connected. As a first step in automating a reconnection of all tap devices when this happens, this patch modifies networkNotifyActualDevice() (which is called once for every <interface> of every active domain whenever libvirtd is restarted) to reconnect any tap devices that it finds disconnected. With this patch in place, you will need to restart libvirtd to reconnect all the taps to their proper bridges. A future patch will add a callback that hypervisor drivers can register with the network driver to that the network driver can trigger this behavior automatically whenever a network is started.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/bridge_driver.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index a753cd78b0..0336ece35c 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4612,7 +4612,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
* Called to notify the network driver when libvirtd is restarted and
* finds an already running domain. If appropriate it will force an
* allocation of the actual->direct.linkdev to get everything back in
- * order.
+ * order, or re-attach the interface's tap device to the network's
+ * bridge.
*
* Returns 0 on success, -1 on failure.
*/
@@ -4627,6 +4628,7 @@ networkNotifyActualDevice(virDomainDefPtr dom,
virNetworkForwardIfDefPtr dev = NULL;
size_t i;
int ret = -1;
+ char *master = NULL;
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
return 0;
@@ -4651,6 +4653,31 @@ networkNotifyActualDevice(virDomainDefPtr dom,
netdef->bridge) < 0))
goto error;
+ /* see if we're connected to the correct bridge */
+ if (netdef->bridge) {
+ if (virNetDevGetMaster(iface->ifname, &master) < 0)
+ goto error;
+
+ if (STRNEQ_NULLABLE(netdef->bridge, master)) {
+ /* disconnect from current (incorrect) bridge */
+ if (master)
+ ignore_value(virNetDevBridgeRemovePort(master, iface->ifname));
+
+ /* attach/reattach to correct bridge.
+ * NB: we can't notify the guest of any MTU change anyway,
+ * so there is no point in trying to learn the actualMTU
+ * (final arg to virNetDevTapAttachBridge())
+ */
+ if (virNetDevTapAttachBridge(iface->ifname, netdef->bridge,
+ &iface->mac, dom->uuid,
+ virDomainNetGetActualVirtPortProfile(iface),
+ virDomainNetGetActualVlan(iface),
+ iface->mtu, NULL) < 0) {
+ goto error;
+ }
+ }
+ }
+
if (!iface->data.network.actual ||
(actualType != VIR_DOMAIN_NET_TYPE_DIRECT &&
actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
@@ -4783,6 +4810,7 @@ networkNotifyActualDevice(virDomainDefPtr dom,
ret = 0;
cleanup:
virNetworkObjEndAPI(&network);
+ VIR_FREE(master);
return ret;
error: