So, as partly explained in previous commit, there is an issue
with NATed networks on a guest originated MAC change. When user
sets @floor in <inbound/> under <bandwidth/> it results in a QoS
hierarchy being built on the corresponding bridge (yes, this
feature is type='network' only). The reason is we can make
shaping decisions only there, where the whole traffic can be
seen. In case of bridged networks it's bridge. But, on the
bridge, in egress qdiscs (outgoing traffic, after routing
decision), due to some Linux kernel internal implementation, we
are not able to see the device packet came from. So we have a set
of filters that place the packet into correct qdisc based on the
MAC recorded in the packet. But with recent changes, this is not
working as expected. We taught libvirt to listen to MAC change
events from guests. However, the QoS hierarchy is not updated
accordingly resulting in applying incorrect shaping rules on a
vNIC that changed the MAC address.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f5a3ef9..6aab1d0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4382,6 +4382,28 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
syncNicRxFilterDeviceOptions(def->ifname, guestFilter, hostFilter);
}
+ if (virDomainNetGetActualType(def) == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ const char *brname = virDomainNetGetActualBridgeName(def);
+
+ 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 TUN/TAP connections, set the following macvtap network device
+ * attributes to match those of the guest network device:
+ * - MAC address
+ * - QoS filters (which are based on MAC address)
+ */
+ syncNicRxFilterMacAddr(def->ifname, guestFilter, hostFilter);
+
+ if (virNetDevBandwidthUpdateFilter(brname, &guestFilter->mac,
+ def->data.network.actual->class_id) <
0)
+ goto endjob;
+ }
+
endjob:
qemuDomainObjEndJob(driver, vm);
--
2.0.5