How can I make my libvirt/KVM guest see all IPv4/UDP multicast traffic?

I have an issue with IPv4/UDP multicast traffic not being fully visible from within a KVM guest.

The guest has a dedicated NIC which is attached using MacVTap. Both the host OS and the OS in the guest are Ubuntu 18.04. This is the VM’s network configuration:

 <interface type='direct' trustGuestRxFilters='yes'>
   <mac address='XX:XX:XX:XX:XX:XX'/>
   <source dev='enp1s0f1' mode='passthrough'/>
   <model type='virtio'/>
   <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
 </interface>

(Note that I obfuscated the actual MAC address.)

Since I’ve enabled trustGuestRxFilters, mDNS is working fine. However, there is still certain multicast traffic that I cannot see.

This is the command the generates the problematic UDP multicast traffic:

raspivid -ae 40,0xff -a 1036 -t 0 -w 1280 -h 720 -ih -fps 30 -mm spot \
  -o udp://239.255.0.1:5000

This creates a constant video stream of approximately 400 KB/s. I’m deliberately using multicast here, so multiple hosts on the network can play or record the stream (without requiring the source computer, which is connected via WiFi, to send multiple streams). The host in the KVM guest is supposed to analyze the stream and record it whenever there is movement in the video.

Here’s the problem: All hosts that are directly connected to the network (= not a KVM guest) can receive the UDP traffic, even the KVM host itself. However, the KVM guest cannot—it only sees very few packages:

sudo timeout 20 tcpdump -i ens3 host 239.255.0.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens3, link-type EN10MB (Ethernet), capture size 262144 bytes
20:53:10.361355 IP vogelhaus.internal.example.com.48146 > 239.255.0.1.5000: UDP, length 4096
#
# omitted 5 lines
#
20:53:12.081881 IP vogelhaus.internal.example.com.48146 > 239.255.0.1.5000: UDP, length 4096

7 packets captured
16 packets received by filter
9 packets dropped by kernel

These are definitely not enough packets for a 400 KB/s video stream running for 20 seconds. When I do the same on another host that is directly connected I do get the expected results:

sudo timeout 20 tcpdump -i enp1s0f0 host 239.255.0.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp1s0f0, link-type EN10MB (Ethernet), capture size 262144 bytes
20:54:41.264709 IP vogelhaus.internal.example.com > 239.255.0.1: udp
#
# ... many, many more! ...
#
20:55:00.912257 IP vogelhaus.internal.example.com > 239.255.0.1: udp
20:55:00.912446 IP vogelhaus.internal.example.com.48146 > 239.255.0.1.5000: UDP, bad length 4096 > 1472

7205 packets captured
7231 packets received by filter
26 packets dropped by kernel

The OS on the KVM host is Ubuntu 18.04. QEMU version:

QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.21)

Any idea what’s preventing the KVM guest from seeing all the traffic?


Solution 1:

Maybe rnxrx' answer could help?

ip link set dev macvtap*n* allmulticast on