]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Move parts of NIC_RX_FILTER_CHANGED event handling into a function
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 30 Sep 2022 14:01:38 +0000 (16:01 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 20 Oct 2022 06:47:31 +0000 (08:47 +0200)
Parts of the code that responds to the NIC_RX_FILTER_CHANGED
event are going to be re-used. Separate them into a function
(qemuDomainSyncRxFilter()) and move the code into qemu_domain.c
so that it can be re-used from other places of the driver.

There's one slight change though: instead of passing device alias
from the just received event to qemuMonitorQueryRxFilter(), I've
switched to using the alias stored in our domain definition. But
these two are guaranteed to be equal. virDomainDefFindDevice()
made sure about that, if nothing else.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_driver.c

index 429a53872fe1a79fa6b982cfb14047552583d55d..3ad01d7199ebfe3978a4afb56da97c339f75c50d 100644 (file)
@@ -11816,3 +11816,254 @@ qemuDomainRefreshStatsSchema(virDomainObj *dom)
 
     return 0;
 }
+
+
+static void
+syncNicRxFilterMacAddr(char *ifname, virNetDevRxFilter *guestFilter,
+                       virNetDevRxFilter *hostFilter)
+{
+    char newMacStr[VIR_MAC_STRING_BUFLEN];
+
+    if (virMacAddrCmp(&hostFilter->mac, &guestFilter->mac)) {
+        virMacAddrFormat(&guestFilter->mac, newMacStr);
+
+        /* set new MAC address from guest to associated macvtap device */
+        if (virNetDevSetMAC(ifname, &guestFilter->mac) < 0) {
+            VIR_WARN("Couldn't set new MAC address %s to device %s "
+                     "while responding to NIC_RX_FILTER_CHANGED",
+                     newMacStr, ifname);
+        } else {
+            VIR_DEBUG("device %s MAC address set to %s", ifname, newMacStr);
+        }
+    }
+}
+
+
+static void
+syncNicRxFilterGuestMulticast(char *ifname, virNetDevRxFilter *guestFilter,
+                              virNetDevRxFilter *hostFilter)
+{
+    size_t i, j;
+    bool found;
+    char macstr[VIR_MAC_STRING_BUFLEN];
+
+    for (i = 0; i < guestFilter->multicast.nTable; i++) {
+        found = false;
+
+        for (j = 0; j < hostFilter->multicast.nTable; j++) {
+            if (virMacAddrCmp(&guestFilter->multicast.table[i],
+                              &hostFilter->multicast.table[j]) == 0) {
+                found = true;
+                break;
+            }
+        }
+
+        if (!found) {
+            virMacAddrFormat(&guestFilter->multicast.table[i], macstr);
+
+            if (virNetDevAddMulti(ifname, &guestFilter->multicast.table[i]) < 0) {
+                VIR_WARN("Couldn't add new multicast MAC address %s to "
+                         "device %s while responding to NIC_RX_FILTER_CHANGED",
+                         macstr, ifname);
+            } else {
+                VIR_DEBUG("Added multicast MAC %s to %s interface",
+                          macstr, ifname);
+            }
+        }
+    }
+}
+
+
+static void
+syncNicRxFilterHostMulticast(char *ifname, virNetDevRxFilter *guestFilter,
+                             virNetDevRxFilter *hostFilter)
+{
+    size_t i, j;
+    bool found;
+    char macstr[VIR_MAC_STRING_BUFLEN];
+
+    for (i = 0; i < hostFilter->multicast.nTable; i++) {
+        found = false;
+
+        for (j = 0; j < guestFilter->multicast.nTable; j++) {
+            if (virMacAddrCmp(&hostFilter->multicast.table[i],
+                              &guestFilter->multicast.table[j]) == 0) {
+                found = true;
+                break;
+            }
+        }
+
+        if (!found) {
+            virMacAddrFormat(&hostFilter->multicast.table[i], macstr);
+
+            if (virNetDevDelMulti(ifname, &hostFilter->multicast.table[i]) < 0) {
+                VIR_WARN("Couldn't delete multicast MAC address %s from "
+                         "device %s while responding to NIC_RX_FILTER_CHANGED",
+                         macstr, ifname);
+            } else {
+                VIR_DEBUG("Deleted multicast MAC %s from %s interface",
+                          macstr, ifname);
+            }
+        }
+    }
+}
+
+
+static void
+syncNicRxFilterPromiscMode(char *ifname,
+                           virNetDevRxFilter *guestFilter,
+                           virNetDevRxFilter *hostFilter)
+{
+    bool promisc;
+    bool setpromisc = false;
+
+    /* Set macvtap promisc mode to true if the guest has vlans defined */
+    /* or synchronize the macvtap promisc mode if different from guest */
+    if (guestFilter->vlan.nTable > 0) {
+        if (!hostFilter->promiscuous) {
+            setpromisc = true;
+            promisc = true;
+        }
+    } else if (hostFilter->promiscuous != guestFilter->promiscuous) {
+        setpromisc = true;
+        promisc = guestFilter->promiscuous;
+    }
+
+    if (setpromisc) {
+        if (virNetDevSetPromiscuous(ifname, promisc) < 0) {
+            VIR_WARN("Couldn't set PROMISC flag to %s for device %s "
+                     "while responding to NIC_RX_FILTER_CHANGED",
+                     promisc ? "true" : "false", ifname);
+        }
+    }
+}
+
+
+static void
+syncNicRxFilterMultiMode(char *ifname, virNetDevRxFilter *guestFilter,
+                         virNetDevRxFilter *hostFilter)
+{
+    if (hostFilter->multicast.mode != guestFilter->multicast.mode ||
+        (guestFilter->multicast.overflow &&
+         guestFilter->multicast.mode == VIR_NETDEV_RX_FILTER_MODE_NORMAL)) {
+        switch (guestFilter->multicast.mode) {
+        case VIR_NETDEV_RX_FILTER_MODE_ALL:
+            if (virNetDevSetRcvAllMulti(ifname, true) < 0) {
+                VIR_WARN("Couldn't set allmulticast flag to 'on' for "
+                         "device %s while responding to "
+                         "NIC_RX_FILTER_CHANGED", ifname);
+            }
+            break;
+
+        case VIR_NETDEV_RX_FILTER_MODE_NORMAL:
+            if (guestFilter->multicast.overflow &&
+                (hostFilter->multicast.mode == VIR_NETDEV_RX_FILTER_MODE_ALL)) {
+                break;
+            }
+
+            if (virNetDevSetRcvMulti(ifname, true) < 0) {
+                VIR_WARN("Couldn't set multicast flag to 'on' for "
+                         "device %s while responding to "
+                         "NIC_RX_FILTER_CHANGED", ifname);
+            }
+
+            if (virNetDevSetRcvAllMulti(ifname,
+                                        guestFilter->multicast.overflow) < 0) {
+                VIR_WARN("Couldn't set allmulticast flag to '%s' for "
+                         "device %s while responding to "
+                         "NIC_RX_FILTER_CHANGED",
+                         virTristateSwitchTypeToString(virTristateSwitchFromBool(guestFilter->multicast.overflow)),
+                         ifname);
+            }
+            break;
+
+        case VIR_NETDEV_RX_FILTER_MODE_NONE:
+            if (virNetDevSetRcvAllMulti(ifname, false) < 0) {
+                VIR_WARN("Couldn't set allmulticast flag to 'off' for "
+                         "device %s while responding to "
+                         "NIC_RX_FILTER_CHANGED", ifname);
+            }
+
+            if (virNetDevSetRcvMulti(ifname, false) < 0) {
+                VIR_WARN("Couldn't set multicast flag to 'off' for "
+                         "device %s while responding to "
+                         "NIC_RX_FILTER_CHANGED",
+                         ifname);
+            }
+            break;
+        }
+    }
+}
+
+
+static void
+syncNicRxFilterDeviceOptions(char *ifname, virNetDevRxFilter *guestFilter,
+                           virNetDevRxFilter *hostFilter)
+{
+    syncNicRxFilterPromiscMode(ifname, guestFilter, hostFilter);
+    syncNicRxFilterMultiMode(ifname, guestFilter, hostFilter);
+}
+
+
+static void
+syncNicRxFilterMulticast(char *ifname,
+                         virNetDevRxFilter *guestFilter,
+                         virNetDevRxFilter *hostFilter)
+{
+    syncNicRxFilterGuestMulticast(ifname, guestFilter, hostFilter);
+    syncNicRxFilterHostMulticast(ifname, guestFilter, hostFilter);
+}
+
+
+int
+qemuDomainSyncRxFilter(virDomainObj *vm,
+                       virDomainNetDef *def)
+{
+    qemuDomainObjPrivate *priv = vm->privateData;
+    g_autoptr(virNetDevRxFilter) guestFilter = NULL;
+    g_autoptr(virNetDevRxFilter) hostFilter = NULL;
+    int rc;
+
+    qemuDomainObjEnterMonitor(vm);
+    rc = qemuMonitorQueryRxFilter(priv->mon, def->info.alias, &guestFilter);
+    qemuDomainObjExitMonitor(vm);
+    if (rc < 0)
+        return -1;
+
+    if (virDomainNetGetActualType(def) == VIR_DOMAIN_NET_TYPE_DIRECT) {
+        if (virNetDevGetRxFilter(def->ifname, &hostFilter)) {
+            VIR_WARN("Couldn't get current RX filter for device %s while responding to NIC_RX_FILTER_CHANGED",
+                     def->ifname);
+            return -1;
+        }
+
+        /* For macvtap connections, set the following macvtap network device
+         * attributes to match those of the guest network device:
+         * - MAC address
+         * - Multicast MAC address table
+         * - Device options:
+         *   - PROMISC
+         *   - MULTICAST
+         *   - ALLMULTI
+         */
+        syncNicRxFilterMacAddr(def->ifname, guestFilter, hostFilter);
+        syncNicRxFilterMulticast(def->ifname, guestFilter, hostFilter);
+        syncNicRxFilterDeviceOptions(def->ifname, guestFilter, hostFilter);
+    }
+
+    if (virDomainNetGetActualType(def) == VIR_DOMAIN_NET_TYPE_NETWORK) {
+        const char *brname = virDomainNetGetActualBridgeName(def);
+
+        /* For libivrt network connections, set the following TUN/TAP network
+         * device attributes to match those of the guest network device:
+         * - QoS filters (which are based on MAC address)
+         */
+        if (virDomainNetGetActualBandwidth(def) &&
+            def->data.network.actual &&
+            virNetDevBandwidthUpdateFilter(brname, &guestFilter->mac,
+                                           def->data.network.actual->class_id) < 0)
+            return -1;
+    }
+
+    return 0;
+}
index 975fa99cca91b280413e467e46b36c317f0ac83e..d5509d7e5f2e0a87b5bc0009c817bee742147efb 100644 (file)
@@ -1103,3 +1103,7 @@ qemuDomainObjWait(virDomainObj *vm);
 
 int
 qemuDomainRefreshStatsSchema(virDomainObj *dom);
+
+int
+qemuDomainSyncRxFilter(virDomainObj *vm,
+                       virDomainNetDef *def);
index 673d582cbe99ec59fd335b254e7358f9a97604c5..3c3894f5685c63c6efc517691ac83e673223e2b6 100644 (file)
@@ -3614,212 +3614,12 @@ processDeviceDeletedEvent(virQEMUDriver *driver,
 }
 
 
-static void
-syncNicRxFilterMacAddr(char *ifname, virNetDevRxFilter *guestFilter,
-                       virNetDevRxFilter *hostFilter)
-{
-    char newMacStr[VIR_MAC_STRING_BUFLEN];
-
-    if (virMacAddrCmp(&hostFilter->mac, &guestFilter->mac)) {
-        virMacAddrFormat(&guestFilter->mac, newMacStr);
-
-        /* set new MAC address from guest to associated macvtap device */
-        if (virNetDevSetMAC(ifname, &guestFilter->mac) < 0) {
-            VIR_WARN("Couldn't set new MAC address %s to device %s "
-                     "while responding to NIC_RX_FILTER_CHANGED",
-                     newMacStr, ifname);
-        } else {
-            VIR_DEBUG("device %s MAC address set to %s", ifname, newMacStr);
-        }
-    }
-}
-
-
-static void
-syncNicRxFilterGuestMulticast(char *ifname, virNetDevRxFilter *guestFilter,
-                              virNetDevRxFilter *hostFilter)
-{
-    size_t i, j;
-    bool found;
-    char macstr[VIR_MAC_STRING_BUFLEN];
-
-    for (i = 0; i < guestFilter->multicast.nTable; i++) {
-        found = false;
-
-        for (j = 0; j < hostFilter->multicast.nTable; j++) {
-            if (virMacAddrCmp(&guestFilter->multicast.table[i],
-                              &hostFilter->multicast.table[j]) == 0) {
-                found = true;
-                break;
-            }
-        }
-
-        if (!found) {
-            virMacAddrFormat(&guestFilter->multicast.table[i], macstr);
-
-            if (virNetDevAddMulti(ifname, &guestFilter->multicast.table[i]) < 0) {
-                VIR_WARN("Couldn't add new multicast MAC address %s to "
-                         "device %s while responding to NIC_RX_FILTER_CHANGED",
-                         macstr, ifname);
-            } else {
-                VIR_DEBUG("Added multicast MAC %s to %s interface",
-                          macstr, ifname);
-            }
-        }
-    }
-}
-
-
-static void
-syncNicRxFilterHostMulticast(char *ifname, virNetDevRxFilter *guestFilter,
-                             virNetDevRxFilter *hostFilter)
-{
-    size_t i, j;
-    bool found;
-    char macstr[VIR_MAC_STRING_BUFLEN];
-
-    for (i = 0; i < hostFilter->multicast.nTable; i++) {
-        found = false;
-
-        for (j = 0; j < guestFilter->multicast.nTable; j++) {
-            if (virMacAddrCmp(&hostFilter->multicast.table[i],
-                              &guestFilter->multicast.table[j]) == 0) {
-                found = true;
-                break;
-            }
-        }
-
-        if (!found) {
-            virMacAddrFormat(&hostFilter->multicast.table[i], macstr);
-
-            if (virNetDevDelMulti(ifname, &hostFilter->multicast.table[i]) < 0) {
-                VIR_WARN("Couldn't delete multicast MAC address %s from "
-                         "device %s while responding to NIC_RX_FILTER_CHANGED",
-                         macstr, ifname);
-            } else {
-                VIR_DEBUG("Deleted multicast MAC %s from %s interface",
-                          macstr, ifname);
-            }
-        }
-    }
-}
-
-
-static void
-syncNicRxFilterPromiscMode(char *ifname,
-                           virNetDevRxFilter *guestFilter,
-                           virNetDevRxFilter *hostFilter)
-{
-    bool promisc;
-    bool setpromisc = false;
-
-    /* Set macvtap promisc mode to true if the guest has vlans defined */
-    /* or synchronize the macvtap promisc mode if different from guest */
-    if (guestFilter->vlan.nTable > 0) {
-        if (!hostFilter->promiscuous) {
-            setpromisc = true;
-            promisc = true;
-        }
-    } else if (hostFilter->promiscuous != guestFilter->promiscuous) {
-        setpromisc = true;
-        promisc = guestFilter->promiscuous;
-    }
-
-    if (setpromisc) {
-        if (virNetDevSetPromiscuous(ifname, promisc) < 0) {
-            VIR_WARN("Couldn't set PROMISC flag to %s for device %s "
-                     "while responding to NIC_RX_FILTER_CHANGED",
-                     promisc ? "true" : "false", ifname);
-        }
-    }
-}
-
-
-static void
-syncNicRxFilterMultiMode(char *ifname, virNetDevRxFilter *guestFilter,
-                         virNetDevRxFilter *hostFilter)
-{
-    if (hostFilter->multicast.mode != guestFilter->multicast.mode ||
-        (guestFilter->multicast.overflow &&
-         guestFilter->multicast.mode == VIR_NETDEV_RX_FILTER_MODE_NORMAL)) {
-        switch (guestFilter->multicast.mode) {
-        case VIR_NETDEV_RX_FILTER_MODE_ALL:
-            if (virNetDevSetRcvAllMulti(ifname, true) < 0) {
-                VIR_WARN("Couldn't set allmulticast flag to 'on' for "
-                         "device %s while responding to "
-                         "NIC_RX_FILTER_CHANGED", ifname);
-            }
-            break;
-
-        case VIR_NETDEV_RX_FILTER_MODE_NORMAL:
-            if (guestFilter->multicast.overflow &&
-                (hostFilter->multicast.mode == VIR_NETDEV_RX_FILTER_MODE_ALL)) {
-                break;
-            }
-
-            if (virNetDevSetRcvMulti(ifname, true) < 0) {
-                VIR_WARN("Couldn't set multicast flag to 'on' for "
-                         "device %s while responding to "
-                         "NIC_RX_FILTER_CHANGED", ifname);
-            }
-
-            if (virNetDevSetRcvAllMulti(ifname,
-                                        guestFilter->multicast.overflow) < 0) {
-                VIR_WARN("Couldn't set allmulticast flag to '%s' for "
-                         "device %s while responding to "
-                         "NIC_RX_FILTER_CHANGED",
-                         virTristateSwitchTypeToString(virTristateSwitchFromBool(guestFilter->multicast.overflow)),
-                         ifname);
-            }
-            break;
-
-        case VIR_NETDEV_RX_FILTER_MODE_NONE:
-            if (virNetDevSetRcvAllMulti(ifname, false) < 0) {
-                VIR_WARN("Couldn't set allmulticast flag to 'off' for "
-                         "device %s while responding to "
-                         "NIC_RX_FILTER_CHANGED", ifname);
-            }
-
-            if (virNetDevSetRcvMulti(ifname, false) < 0) {
-                VIR_WARN("Couldn't set multicast flag to 'off' for "
-                         "device %s while responding to "
-                         "NIC_RX_FILTER_CHANGED",
-                         ifname);
-            }
-            break;
-        }
-    }
-}
-
-
-static void
-syncNicRxFilterDeviceOptions(char *ifname, virNetDevRxFilter *guestFilter,
-                           virNetDevRxFilter *hostFilter)
-{
-    syncNicRxFilterPromiscMode(ifname, guestFilter, hostFilter);
-    syncNicRxFilterMultiMode(ifname, guestFilter, hostFilter);
-}
-
-
-static void
-syncNicRxFilterMulticast(char *ifname,
-                         virNetDevRxFilter *guestFilter,
-                         virNetDevRxFilter *hostFilter)
-{
-    syncNicRxFilterGuestMulticast(ifname, guestFilter, hostFilter);
-    syncNicRxFilterHostMulticast(ifname, guestFilter, hostFilter);
-}
-
 static void
 processNicRxFilterChangedEvent(virDomainObj *vm,
                                const char *devAlias)
 {
-    qemuDomainObjPrivate *priv = vm->privateData;
     virDomainDeviceDef dev;
     virDomainNetDef *def;
-    g_autoptr(virNetDevRxFilter) guestFilter = NULL;
-    g_autoptr(virNetDevRxFilter) hostFilter = NULL;
-    int ret;
 
     VIR_DEBUG("Received NIC_RX_FILTER_CHANGED event for device %s "
               "from domain %p %s",
@@ -3862,49 +3662,9 @@ processNicRxFilterChangedEvent(virDomainObj *vm,
     VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network "
               "device %s in domain %s", def->info.alias, vm->def->name);
 
-    qemuDomainObjEnterMonitor(vm);
-    ret = qemuMonitorQueryRxFilter(priv->mon, devAlias, &guestFilter);
-    qemuDomainObjExitMonitor(vm);
-    if (ret < 0)
+    if (qemuDomainSyncRxFilter(vm, def) < 0)
         goto endjob;
 
-    if (virDomainNetGetActualType(def) == VIR_DOMAIN_NET_TYPE_DIRECT) {
-
-        if (virNetDevGetRxFilter(def->ifname, &hostFilter)) {
-            VIR_WARN("Couldn't get current RX filter for device %s "
-                     "while responding to NIC_RX_FILTER_CHANGED",
-                     def->ifname);
-            goto endjob;
-        }
-
-        /* For macvtap connections, set the following macvtap network device
-         * attributes to match those of the guest network device:
-         * - MAC address
-         * - Multicast MAC address table
-         * - Device options:
-         *   - PROMISC
-         *   - MULTICAST
-         *   - ALLMULTI
-         */
-        syncNicRxFilterMacAddr(def->ifname, guestFilter, hostFilter);
-        syncNicRxFilterMulticast(def->ifname, guestFilter, hostFilter);
-        syncNicRxFilterDeviceOptions(def->ifname, guestFilter, hostFilter);
-    }
-
-    if (virDomainNetGetActualType(def) == VIR_DOMAIN_NET_TYPE_NETWORK) {
-        const char *brname = virDomainNetGetActualBridgeName(def);
-
-        /* For libivrt network connections, set the following TUN/TAP network
-         * device attributes to match those of the guest network device:
-         * - QoS filters (which are based on MAC address)
-         */
-        if (virDomainNetGetActualBandwidth(def) &&
-            def->data.network.actual &&
-            virNetDevBandwidthUpdateFilter(brname, &guestFilter->mac,
-                                           def->data.network.actual->class_id) < 0)
-            goto endjob;
-    }
-
  endjob:
     virDomainObjEndJob(vm);
 }