Blame SOURCES/libvirt-qemu-add-remove-bridge-fdb-entries-as-guest-CPUs-are-started-stopped.patch

9119d9
From 585d2ac01d34da0ce729ac889eae0a56608f86be Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <585d2ac01d34da0ce729ac889eae0a56608f86be@dist-git>
9119d9
From: Laine Stump <laine@laine.org>
9119d9
Date: Mon, 15 Dec 2014 10:51:32 -0500
9119d9
Subject: [PATCH] qemu: add/remove bridge fdb entries as guest CPUs are
9119d9
 started/stopped
9119d9
9119d9
This is part of the fix for:
9119d9
9119d9
  https://bugzilla.redhat.com/show_bug.cgi?id=1099210
9119d9
9119d9
When libvirt is managing a bridge's forwarding database (FDB)
9119d9
(macTableManager='libvirt'), if we add FDB entries for a new guest
9119d9
interface even before the qemu process is created, then in the case of
9119d9
a migration any other guest attached to the "destination" bridge will
9119d9
have its traffic immediately sent to the destination of the migration
9119d9
even while the source domain is still running (and the destination, of
9119d9
course, isn't). To make sure that traffic from other guests on the new
9119d9
host continues flowing to the old guest until the new one is ready, we
9119d9
have to wait until the new guest CPUs are started to add the FDB
9119d9
entries.
9119d9
9119d9
Conversely, we need to remove the FDB entries from the bridge any time
9119d9
the guest CPUs are stopped; among other things, this will assure
9119d9
proper operation during a post-copy migration (which is just the
9119d9
opposite of the problem described in the previous paragraph).
9119d9
9119d9
(cherry picked from commit 44292e48a0ffa76badf84d42ad33f885e67d30e9)
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_command.c   | 10 +++-------
9119d9
 src/qemu/qemu_interface.c | 26 ++++++++++++++++++++++++++
9119d9
 2 files changed, 29 insertions(+), 7 deletions(-)
9119d9
9119d9
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
9119d9
index a9c4271..ed66cea 100644
9119d9
--- a/src/qemu/qemu_command.c
9119d9
+++ b/src/qemu/qemu_command.c
9119d9
@@ -355,18 +355,14 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
9119d9
             /* libvirt is managing the FDB of the bridge this device
9119d9
              * is attaching to, so we need to turn off learning and
9119d9
              * unicast_flood on the device to prevent the kernel from
9119d9
-             * adding any FDB entries for it, then add an fdb entry
9119d9
-             * outselves, using the MAC address from the interface
9119d9
-             * config.
9119d9
+             * adding any FDB entries for it. We will add add an fdb
9119d9
+             * entry ourselves (during qemuInterfaceStartDevices(),
9119d9
+             * using the MAC address from the interface config.
9119d9
              */
9119d9
             if (virNetDevBridgePortSetLearning(brname, net->ifname, false) < 0)
9119d9
                 goto cleanup;
9119d9
             if (virNetDevBridgePortSetUnicastFlood(brname, net->ifname, false) < 0)
9119d9
                 goto cleanup;
9119d9
-            if (virNetDevBridgeFDBAdd(&net->mac, net->ifname,
9119d9
-                                      VIR_NETDEVBRIDGE_FDB_FLAG_MASTER |
9119d9
-                                      VIR_NETDEVBRIDGE_FDB_FLAG_TEMP) < 0)
9119d9
-                goto cleanup;
9119d9
         }
9119d9
     } else {
9119d9
         if (qemuCreateInBridgePortWithHelper(cfg, brname,
9119d9
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
9119d9
index 2d33075..201a7dd 100644
9119d9
--- a/src/qemu/qemu_interface.c
9119d9
+++ b/src/qemu/qemu_interface.c
9119d9
@@ -23,10 +23,12 @@
9119d9
 
9119d9
 #include <config.h>
9119d9
 
9119d9
+#include "network_conf.h"
9119d9
 #include "qemu_interface.h"
9119d9
 #include "virnetdev.h"
9119d9
 #include "virnetdevtap.h"
9119d9
 #include "virnetdevmacvlan.h"
9119d9
+#include "virnetdevbridge.h"
9119d9
 #include "virnetdevvportprofile.h"
9119d9
 
9119d9
 /**
9119d9
@@ -46,6 +48,20 @@ qemuInterfaceStartDevice(virDomainNetDefPtr net)
9119d9
     switch (actualType) {
9119d9
     case VIR_DOMAIN_NET_TYPE_BRIDGE:
9119d9
     case VIR_DOMAIN_NET_TYPE_NETWORK:
9119d9
+        if (virDomainNetGetActualBridgeMACTableManager(net)
9119d9
+            == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
9119d9
+            /* libvirt is managing the FDB of the bridge this device
9119d9
+             * is attaching to, so we have turned off learning and
9119d9
+             * unicast_flood on the device to prevent the kernel from
9119d9
+             * adding any FDB entries for it. This means we need to
9119d9
+             * add an fdb entry ourselves, using the MAC address from
9119d9
+             * the interface config.
9119d9
+             */
9119d9
+            if (virNetDevBridgeFDBAdd(&net->mac, net->ifname,
9119d9
+                                      VIR_NETDEVBRIDGE_FDB_FLAG_MASTER |
9119d9
+                                      VIR_NETDEVBRIDGE_FDB_FLAG_TEMP) < 0)
9119d9
+                goto cleanup;
9119d9
+        }
9119d9
         break;
9119d9
     case VIR_DOMAIN_NET_TYPE_DIRECT:
9119d9
         /* macvtap devices share their MAC address with the guest
9119d9
@@ -118,6 +134,16 @@ qemuInterfaceStopDevice(virDomainNetDefPtr net)
9119d9
     switch (actualType) {
9119d9
     case VIR_DOMAIN_NET_TYPE_BRIDGE:
9119d9
     case VIR_DOMAIN_NET_TYPE_NETWORK:
9119d9
+        if (virDomainNetGetActualBridgeMACTableManager(net)
9119d9
+            == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
9119d9
+            /* remove the FDB entries that were added during
9119d9
+             * qemuInterfaceStartDevices()
9119d9
+             */
9119d9
+            if (virNetDevBridgeFDBDel(&net->mac, net->ifname,
9119d9
+                                      VIR_NETDEVBRIDGE_FDB_FLAG_MASTER |
9119d9
+                                      VIR_NETDEVBRIDGE_FDB_FLAG_TEMP) < 0)
9119d9
+                goto cleanup;
9119d9
+        }
9119d9
         break;
9119d9
 
9119d9
     case VIR_DOMAIN_NET_TYPE_DIRECT:
9119d9
-- 
9119d9
2.2.0
9119d9