When libvirt is managing the forwarding database (fdb) of a bridge, it
must turn off learning and unicast_flood for each tap device attached
to that bridge, then add an FDB entry for the tap device using the MAC
address from the domain interface config.
If there is only one device on the bridge with learning/unicast_flood
enabled, then that device has promiscuous mode disabled. If there are
*no* devices with learning/unicast_flood enabled (e.g. for a libvirt
"route", "nat", or isolated network that has no physical device
attached), then all devices will have promiscuous mode disabled.
Once we have disabled learning and flooding, any packet that has a
destination MAC address not present in the forwarding database (fdb)
will be dropped by the bridge. This, along with the opportunistic
disabling of promiscuous mode, can result in enhanced network
performance. and a potential security improvement.
None of this has any effect for kernels prior to 3.15 (upstream kernel
commit 2796d0c648c940b4796f84384fbcfb0a2399db84 "bridge: Automatically
manage port promiscuous mode"). Even after that, until kernel 3.17
(upstream commit 5be5a2df40f005ea7fb7e280e87bbbcfcf1c2fc0 "bridge: Add
filtering support for default_pvid") traffic will not be properly
forwarded without manually adding vlan table entries. Unfortunately,
there is no reliable way to query whether or not the system's kernel
has the appropriate patches installed, the only thing that can be done
is to try the setting and see if traffic continues to pass.
---
Changes from V1: only attribute name/value
To reiterate what I said in my response to John's original review -
vlan_filtering is a property of the bridge, while learning and
unicast_flood are properties of each port of the bridge, so there is
no vlan_filtering knob to set for each port.
src/qemu/qemu_command.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4ed6506..0007bb5 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -35,6 +35,7 @@
#include "virerror.h"
#include "virfile.h"
#include "virnetdev.h"
+#include "virnetdevbridge.h"
#include "virstring.h"
#include "virtime.h"
#include "viruuid.h"
@@ -350,6 +351,23 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
virDomainAuditNetDevice(def, net, tunpath, false);
goto cleanup;
}
+ if (virDomainNetGetActualFDB(net) == VIR_NETWORK_BRIDGE_FDB_MANAGED) {
+ /* libvirt is managing the FDB of the bridge this device
+ * is attaching to, so we need to turn off learning and
+ * unicast_flood on the device to prevent the kernel from
+ * adding any FDB entries for it, then add an fdb entry
+ * outselves, using the MAC address from the interface
+ * config.
+ */
+ if (virNetDevBridgePortSetLearning(brname, net->ifname, false) < 0)
+ goto cleanup;
+ if (virNetDevBridgePortSetUnicastFlood(brname, net->ifname, false) <
0)
+ goto cleanup;
+ if (virNetDevBridgeFDBAdd(&net->mac, net->ifname,
+ VIR_NETDEVBRIDGE_FDB_FLAG_MASTER |
+ VIR_NETDEVBRIDGE_FDB_FLAG_TEMP) < 0)
+ goto cleanup;
+ }
} else {
if (qemuCreateInBridgePortWithHelper(cfg, brname,
&net->ifname,
--
1.9.3