]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: handle multicast overflow on macvtap NIC_RX_FILTER_CHANGED
authorJason Baron <jbaron@akamai.com>
Fri, 30 Nov 2018 17:50:26 +0000 (12:50 -0500)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 3 Dec 2018 13:35:10 +0000 (14:35 +0100)
Guest network devices can set 'overflow' when there are a number of multicast
ips configured. For virtio_net, the limit is only 64. In this case, the list
of mac addresses is empty and the 'overflow' condition is set. Thus, the guest
will currently receive no multicast traffic in this state.

When 'overflow' is set in the guest, let's turn this into ALLMULTI on the host.

Signed-off-by: Jason Baron <jbaron@akamai.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_driver.c

index 7d9e17e72c71ea8aa7089fc43e1b934da7f22432..8403492ec125480f4f58d7d7016fac4e3e45f34e 100644 (file)
@@ -4443,11 +4443,12 @@ static void
 syncNicRxFilterMultiMode(char *ifname, virNetDevRxFilterPtr guestFilter,
                          virNetDevRxFilterPtr hostFilter)
 {
-    if (hostFilter->multicast.mode != guestFilter->multicast.mode) {
+    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)) {
-
                     VIR_WARN("Couldn't set allmulticast flag to 'on' for "
                              "device %s while responding to "
                              "NIC_RX_FILTER_CHANGED", ifname);
@@ -4455,17 +4456,24 @@ syncNicRxFilterMultiMode(char *ifname, virNetDevRxFilterPtr guestFilter,
                 break;
 
             case VIR_NETDEV_RX_FILTER_MODE_NORMAL:
-                if (virNetDevSetRcvMulti(ifname, true)) {
+                if (guestFilter->multicast.overflow &&
+                    (hostFilter->multicast.mode == VIR_NETDEV_RX_FILTER_MODE_ALL)) {
+                    break;
+                }
 
+                if (virNetDevSetRcvMulti(ifname, true)) {
                     VIR_WARN("Couldn't set multicast flag to 'on' for "
                              "device %s while responding to "
                              "NIC_RX_FILTER_CHANGED", ifname);
                 }
 
-                if (virNetDevSetRcvAllMulti(ifname, false)) {
-                    VIR_WARN("Couldn't set allmulticast flag to 'off' 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;