[PATCH 0/2] Couple of domain <interface/> fixes

The first one fixes a bug that was reported on the list: https://listman.redhat.com/archives/libvir-list/2022-November/235922.html The second one - I've noticed while investigating the first one. Michal Prívozník (2): conf: Make VIR_DOMAIN_NET_TYPE_ETHERNET not share 'host view' virnetdevbandwidth: Unbreak tc filter update on Linux-4.20+ src/conf/domain_conf.c | 2 +- src/util/virnetdevbandwidth.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) -- 2.37.4

When setting up QoS for a domain <interface/>, or when reporting its statistics we may need to swap TX/RX values. This is all explained in comment to virDomainNetTypeSharesHostView(). However, this function claims that VIR_DOMAIN_NET_TYPE_ETHERNET also shares the 'host view', meaning the TX/RX values must be swapped. But that's not true. An easy reproducer is to start a domain with two <interface/>-s: one type of network, the other of type ethernet and configure the same <bandwidth/> for both. Reversed setting can then be observed (e.g. via tc). Reported-by: Oleg Vasilev <oleg.vasilev@virtuozzo.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3790121cf7..ef930b1687 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -29106,9 +29106,9 @@ virDomainNetTypeSharesHostView(const virDomainNetDef *net) virDomainNetType actualType = virDomainNetGetActualType(net); switch (actualType) { case VIR_DOMAIN_NET_TYPE_DIRECT: - case VIR_DOMAIN_NET_TYPE_ETHERNET: return true; case VIR_DOMAIN_NET_TYPE_USER: + case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT: -- 2.37.4

On 24.11.2022 18:10, Michal Privoznik wrote:
When setting up QoS for a domain <interface/>, or when reporting its statistics we may need to swap TX/RX values. This is all explained in comment to virDomainNetTypeSharesHostView(). However, this function claims that VIR_DOMAIN_NET_TYPE_ETHERNET also shares the 'host view', meaning the TX/RX values must be swapped. But that's not true.
An easy reproducer is to start a domain with two <interface/>-s: one type of network, the other of type ethernet and configure the same <bandwidth/> for both. Reversed setting can then be observed (e.g. via tc).
Reported-by: Oleg Vasilev <oleg.vasilev@virtuozzo.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3790121cf7..ef930b1687 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -29106,9 +29106,9 @@ virDomainNetTypeSharesHostView(const virDomainNetDef *net) virDomainNetType actualType = virDomainNetGetActualType(net); switch (actualType) { case VIR_DOMAIN_NET_TYPE_DIRECT: - case VIR_DOMAIN_NET_TYPE_ETHERNET: return true; case VIR_DOMAIN_NET_TYPE_USER: + case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT:
Not sure this is much needed, but Tested-by: Oleg Vasilev <oleg.vasilev@virtuozzo.com> :)

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> --- src/util/virnetdevbandwidth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c index d816bcbf06..e67cbd164d 100644 --- a/src/util/virnetdevbandwidth.c +++ b/src/util/virnetdevbandwidth.c @@ -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); -- 2.37.4

On Thu, Nov 24, 2022 at 13:10:15 +0100, Michal Privoznik wrote:
The first one fixes a bug that was reported on the list:
https://listman.redhat.com/archives/libvir-list/2022-November/235922.html
The second one - I've noticed while investigating the first one.
Michal Prívozník (2): conf: Make VIR_DOMAIN_NET_TYPE_ETHERNET not share 'host view' virnetdevbandwidth: Unbreak tc filter update on Linux-4.20+
src/conf/domain_conf.c | 2 +- src/util/virnetdevbandwidth.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
participants (3)
-
Jiri Denemark
-
Michal Privoznik
-
Oleg Vasilev