I’m working on an application to capture and display 4 multicast streams. The video
processing is done with a gstreamer pipeline, using udpsrc to capture multicast.
The problem is that the first time the application starts, the gstreamer pipeline does
not receive any of the multicast datagram packets. If I stop and restart the application,
the data is received and the video is displayed.
I am waiting until the ethernet interface is up, I make sure it will ping.
I know the packets are on the ethernet port, I am using a managed switch with
port mirroring (more below) and I see all four packet streams. I also see the
expected igmp join messages.
netstat -gn shows the group memberships.
Interestingly “ethtool -S eth0 | egrep ‘rx_multi|rx_broad’” shows some broadcast
traffic, but not the volume I expect (see below). Note that this is when I can
see all the streams on the port from the monitor port. The Ethernet packets
are there.
# ethtool -S eth0 | egrep 'rx_multi|rx_broad'
mmc_rx_broadcastframe_g: 8380
mmc_rx_multicastframe_g: 6
# ethtool -S eth0 | egrep 'rx_multi|rx_broad'
mmc_rx_broadcastframe_g: 8405
mmc_rx_multicastframe_g: 6
The most confusing part in debugging is that if I run tcpdump, it shows
all the packet streams and all the streams start almost instantly. That’s
why I set up the managed switch with port mirroring.
Interstingly, if I don’t run tcpdump in promiscious mode, the video streams
don’t start.
Even more interestingly, after running tcpdump in promiscous mode, ethtool
shows that the multicast frames are being received at the expected rate.
# tcpdump -n -i eth0
[ 596.822526] Unsupported IOCTL call
[ 596.846401] Unsupported IOCTL call
[ 596.865935] device eth0 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
15:50:26.682731 IP 10.3.15.12.36250 > 239.3.15.1.4001: UDP, length 1316
15:50:26.682911 IP 10.3.15.12.36250 > 239.3.15.1.4001: UDP, length 1316
15:50:26.682961 IP 10.3.15.12.36250 > 239.3.15.1.4001: UDP, length 1316
...
# ethtool -S eth0 | egrep 'rx_multi|rx_broad'
mmc_rx_broadcastframe_g: 10456
mmc_rx_multicastframe_g: 55855
# ethtool -S eth0 | egrep 'rx_multi|rx_broad'
mmc_rx_broadcastframe_g: 10490
mmc_rx_multicastframe_g: 57772
Note many more multicast frames.
It seems as if somehow running tcpdump kicks the system into properly categorizing
the streams as multicast.
This situation can also be cleared by stopping ALL the multicast rx streams and
restarting them.
No clue where “Unsupported IOCTL call” comes from.
I can probably fix the problem by detecting video loss and restarting the gstreamer
pipelines, but this will slow startup, which is not desirable in some of the
expected use cases. I could also probably fix the problem by periodically running
tcpdump, but that’s a path rather than a fix. I’d rather have a solid understanding
of the problem and the best fix.
Note currently all the streams are on the same multicast group. The problem is also
observed when they are on different multicast groups.
Ideas? Suggestions?
Thanks, Cary