]> xenbits.xensource.com Git - libvirt.git/commitdiff
virnetdevbandwidth: Unbreak tc filter update on Linux-4.20+
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 24 Nov 2022 11:34:56 +0000 (12:34 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 24 Nov 2022 14:51:42 +0000 (15:51 +0100)
Guests are allowed to change their MAC addresses. Subsequently,
we may respond to that with tweaking that part of host side
configuration that depends on it. In this particular case: QoS.

Some parts of QoS are in fact set on corresponding bridge, where
overall view on traffic can be seen. Here, TC filters are used to
place incoming packets into qdiscs. These filters match source
MAC address. Therefore, upon guest changing its MAC address, the
corresponding TC filter needs to be updated too. This is done by
simply removing the old one and instantiating a new one, with new
MAC address.

Now, u32 filters (which we use) use a hash table for matching,
internally. And when deleting the old filter, we used to remove
the hash table (ID = 800::) and let the new filter instantiate
new hash table. This used to work, until kernel release 4.20
(specifically commit v4.20-rc1~27^2~131^2~11 and its friends)
where this practice was turned into error.

But that's okay - we can delete the specific filter we are after
and not touch the hash table at all.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
src/util/virnetdevbandwidth.c

index d816bcbf06999c09758058162473547d6fb5151b..e67cbd164d49480c7fcf9c4ef7ad70c2ba5ec2ea 100644 (file)
@@ -114,8 +114,10 @@ virNetDevBandwidthManipulateFilter(const char *ifname,
         goto cleanup;
     }
 
-    /* u32 filters must have 800:: prefix. Don't ask. */
-    filter_id = g_strdup_printf("800::%u", id);
+    /* u32 filters must have 800:: prefix. Don't ask. Furthermore, handles
+     * start at 800. Therefore, we want the filter ID to look like this:
+     *   800::(800 + id) */
+    filter_id = g_strdup_printf("800::%u", 800 + id);
 
     if (remove_old) {
         g_autoptr(virCommand) cmd = virCommandNew(TC);