Alan, thanks for this great discussion. I took the time to discuss this with the libvirt guy that implemented parts of the trustGuestRxFilter stuff. In addition I did some testing. This is how I think it works with trust rx filter set to yes : Libvirt receives an event if there was a change from within the guest. It queries qemu for the actual state. More details see [1]. Now libvirt does the following - adds the guests multicasts macs to the macvtaps multicast rx filter list - if one or more vlans are enabled in the guest, it sets the macvtap into promisc mode - snychronises the following flags: promisc, multicast, allmulti - changes the macvtaps mac to the primary mac What it NOT does is doing anything with the unicast mac list (as far as I understood). This one is being ignored. What I could NOT verify is the use case of running a bridge in a macvtap attached vm - I mean it works as long as the bridge uses the same mac as the vms eth nic. But as soon as you change that mac - you won't get any inbound traffic for this mac anymore. I was using the bridge mode and tested vm-vm traffic as well as outside-vm traffic. If that's right the big problems I see are the following: # Having trustGuest set to NO - no multicast - no arbitrary ipv6 addresses (which require special multicast groups for neighbour discovery) - mac spoofing (and therfore packet sniffing) is not possible, however you can sent out faked packets and confuse the switches in the datacenter # having trustGuest set to YES - Guest can change the mac and therefore the mac of the macvtap (this is a big problem, as the mac address will be used for identifying a device in this proposal) - Guest can mac spoof unicast and therefore do packet sniffing. But this works only for one mac address at the same time as only one can be set - (i know this doesn't make things better...) Spoofing does NOT work if the target mac is already used on the same host by another libvirt manged guest (if there is already a libvirt configured macvtap with this mac, libvirt does not change the mac of the macvtap device - however if it is not libvirt managed, it will result in a duplicated mac on the host; if a new instance appears on the same host that wants to use this mac, libvirt returns an error) [1] Show rx-filter information. Returns a json-array of rx-filter information for all NICs (or for the given NIC), returning an error if the given NIC doesn't exist, or given NIC doesn't support rx-filter querying, or given net client isn't a NIC. The query will clear the event notification flag of each NIC, then qemu will start to emit event to QMP monitor. Each array entry contains the following: - "name": net client name (json-string) - "promiscuous": promiscuous mode is enabled (json-bool) - "multicast": multicast receive state (one of 'normal', 'none', 'all') - "unicast": unicast receive state (one of 'normal', 'none', 'all') - "vlan": vlan receive state (one of 'normal', 'none', 'all') (Since 2.0) - "broadcast-allowed": allow to receive broadcast (json-bool) - "multicast-overflow": multicast table is overflowed (json-bool) - "unicast-overflow": unicast table is overflowed (json-bool) - "main-mac": main macaddr string (json-string) - "vlan-table": a json-array of active vlan id - "unicast-table": a json-array of unicast macaddr string - "multicast-table": a json-array of multicast macaddr string Example: -> { "execute": "query-rx-filter", "arguments": { "name": "vnet0" } } <- { "return": [ { "promiscuous": true, "name": "vnet0", "main-mac": "52:54:00:12:34:56", "unicast": "normal", "vlan": "normal", "vlan-table": [ 4, 0 ], "unicast-table": [ ], "multicast": "normal", "multicast-overflow": false, "unicast-overflow": false, "multicast-table": [ "01:00:5e:00:00:01", "33:33:00:00:00:01", "33:33:ff:12:34:56" ], "broadcast-allowed": false } ] }