Blame SOURCES/libvirt-qemu-change-macvtap-device-MAC-address-in-response-to-NIC_RX_FILTER_CHANGED.patch

9119d9
From 68e16ab92310206b28471434ff80f90b4fcf987b Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <68e16ab92310206b28471434ff80f90b4fcf987b@dist-git>
9119d9
From: Laine Stump <laine@laine.org>
9119d9
Date: Mon, 3 Nov 2014 10:00:21 -0500
9119d9
Subject: [PATCH] qemu: change macvtap device MAC address in response to
9119d9
 NIC_RX_FILTER_CHANGED
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=848199
9119d9
9119d9
This patch fills in the functionality of
9119d9
processNicRxFilterChangedEvent().  It now checks if it is appropriate
9119d9
to respond to the NIC_RX_FILTER_CHANGED event (based on device type
9119d9
and configuration) and takes appropriate action. Currently it checks
9119d9
if the guest interface has been configured with
9119d9
trustGuestRxFilters='yes', and if the host side device is macvtap. If
9119d9
so, and the MAC address on the guest has changed, the MAC address of
9119d9
the macvtap device is changed to match.
9119d9
9119d9
The result of this is that networking from the guest will continue to
9119d9
work if the mac address of a macvtap-connected network device is
9119d9
changed from within the guest, as long as trustGuestRxFilters='yes'
9119d9
(previously changing the MAC address in the guest would break
9119d9
networking).
9119d9
9119d9
(cherry picked from commit db6b738dde047c9b38ed41add5d00bbbdb7c5daa)
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_driver.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
9119d9
 1 file changed, 50 insertions(+)
9119d9
9119d9
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
9119d9
index 29deb76..229836f 100644
9119d9
--- a/src/qemu/qemu_driver.c
9119d9
+++ b/src/qemu/qemu_driver.c
9119d9
@@ -4153,8 +4153,13 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
9119d9
                                char *devAlias)
9119d9
 {
9119d9
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
9119d9
+    qemuDomainObjPrivatePtr priv = vm->privateData;
9119d9
     virDomainDeviceDef dev;
9119d9
     virDomainNetDefPtr def;
9119d9
+    virNetDevRxFilterPtr filter = NULL;
9119d9
+    virMacAddr oldMAC;
9119d9
+    char newMacStr[VIR_MAC_STRING_BUFLEN];
9119d9
+    int ret;
9119d9
 
9119d9
     VIR_DEBUG("Received NIC_RX_FILTER_CHANGED event for device %s "
9119d9
               "from domain %p %s",
9119d9
@@ -4182,11 +4187,55 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
9119d9
     }
9119d9
     def = dev.data.net;
9119d9
 
9119d9
+    if (!virDomainNetGetActualTrustGuestRxFilters(def)) {
9119d9
+        VIR_WARN("ignore NIC_RX_FILTER_CHANGED event for network "
9119d9
+                  "device %s in domain %s",
9119d9
+                  def->info.alias, vm->def->name);
9119d9
+        /* not sending "query-rx-filter" will also suppress any
9119d9
+         * further NIC_RX_FILTER_CHANGED events for this device
9119d9
+         */
9119d9
+        goto endjob;
9119d9
+    }
9119d9
+
9119d9
     /* handle the event - send query-rx-filter and respond to it. */
9119d9
 
9119d9
     VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network "
9119d9
               "device %s in domain %s", def->info.alias, vm->def->name);
9119d9
 
9119d9
+    qemuDomainObjEnterMonitor(driver, vm);
9119d9
+    ret = qemuMonitorQueryRxFilter(priv->mon, devAlias, &filter);
9119d9
+    qemuDomainObjExitMonitor(driver, vm);
9119d9
+    if (ret < 0)
9119d9
+        goto endjob;
9119d9
+
9119d9
+    virMacAddrFormat(&filter->mac, newMacStr);
9119d9
+
9119d9
+    if (virDomainNetGetActualType(def) == VIR_DOMAIN_NET_TYPE_DIRECT) {
9119d9
+
9119d9
+        /* For macvtap connections, set the macvtap device's MAC
9119d9
+         * address to match that of the guest device.
9119d9
+         */
9119d9
+
9119d9
+        if (virNetDevGetMAC(def->ifname, &oldMAC) < 0) {
9119d9
+            VIR_WARN("Couldn't get current MAC address of device %s "
9119d9
+                     "while responding to NIC_RX_FILTER_CHANGED",
9119d9
+                     def->ifname);
9119d9
+            goto endjob;
9119d9
+        }
9119d9
+
9119d9
+        if (virMacAddrCmp(&oldMAC, &filter->mac)) {
9119d9
+            /* set new MAC address from guest to associated macvtap device */
9119d9
+            if (virNetDevSetMAC(def->ifname, &filter->mac) < 0) {
9119d9
+                VIR_WARN("Couldn't set new MAC address %s to device %s "
9119d9
+                         "while responding to NIC_RX_FILTER_CHANGED",
9119d9
+                         newMacStr, def->ifname);
9119d9
+            } else {
9119d9
+                VIR_DEBUG("device %s MAC address set to %s",
9119d9
+                          def->ifname, newMacStr);
9119d9
+            }
9119d9
+        }
9119d9
+    }
9119d9
+
9119d9
  endjob:
9119d9
     /* We had an extra reference to vm before starting a new job so ending the
9119d9
      * job is guaranteed not to remove the last reference.
9119d9
@@ -4194,6 +4243,7 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
9119d9
     ignore_value(qemuDomainObjEndJob(driver, vm));
9119d9
 
9119d9
  cleanup:
9119d9
+    virNetDevRxFilterFree(filter);
9119d9
     VIR_FREE(devAlias);
9119d9
     virObjectUnref(cfg);
9119d9
 }
9119d9
-- 
9119d9
2.1.3
9119d9