0

I'm trying to join an IGMP multicast stream from a Centos 8 machine but after sending a JOIN, there is no traffic coming from the switch.

Simple connection:

MUX <-----------> cisco3850 <--------> Centos8
192.168.117.13                         192.168.117.21

The upstream switch (cisco catalyst 3850) is fed an MPEG-TS to 239.1.1.1:4000 from the MUX.

I've tried both socat and my own program to open a socket, join the stream, and hold the socket open. Both send the same IGMP join message as confirmed by wireshark:

Internet Group Management Protocol
    [IGMP Version: 3]
    Type: Membership Report (0x22)
    Reserved: 00
    Checksum: 0xe9fb [correct]
    [Checksum Status: Good]
    Reserved: 0000
    Num Group Records: 1
    Group Record : 239.1.1.1  Change To Exclude Mode
        Record Type: Change To Exclude Mode (4)
        Aux Data Len: 0
        Num Src: 0
        Multicast Address: 239.1.1.1

Using ip route add I created routes for multicast groups to the interface:

224.0.0.0/4 dev eth1 scope link
225.0.0.0/8 dev eth1 scope link
239.0.0.0/8 dev eth1 scope link

and cat /proc/net/igmp shows the group has been joined:

cat /proc/net/igmp
Idx     Device    : Count Querier       Group    Users Timer    Reporter
3       eth1      :     2      V3
                                030101E1     1 0:00000000               0
                                010000E0     1 0:00000000               0

I suspect this is a problem with the switch rather than a Linux problem, but the customer (who owns the switch) says everything is fine.

What else can I do on the Linux side to investigate/fix this issue?

If it is an issue on the switch then what? What needs to be configured there? (need to explain to customer)


For reference, my program which joins and holds the socket open looks like:

// Error checking omitted for brevity
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes);

memset(&saddr, 0, sizeof(saddr));
saddr.sin_family      = PF_INET;
saddr.sin_addr.s_addr = mcastAddr;
saddr.sin_port        = htons(port);

bind(fd, (struct sockaddr *)&saddr, sizeof(saddr);

struct ip_mreq mcastReq;
mcastReq.imr_multiaddr.s_addr = mcastAddr;
&mcastReq.imr_interface.s_addr = interfaceAddr;

setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcastReq, sizeof(mcastReq);
Danny
  • 235
  • 2
  • 10

1 Answers1

0

In the end, the customer switch could not/would not activate IGMPv3, so we set our machine to use IGMP v2 by creating a file under /etc/sysctl.d.

The JOIN then worked, but Linux did not respond to multicast membership queries so the switch dropped the stream after 1-2 minutes (even though we had net.ipv4.conf.default.rp_filter set to zero.

It turns out to fully disable return path validation, we needed to set all of the rp_filter settings to zero (including explicitly listing the interface)

# Set IGMP Version for eth1
# Set to '2' or '3' depending on what is enabled in the switch
net.ipv4.conf.eth1.force_igmp_version = 2

# Disable source route verification
# In addition to 90-torque.conf, also explicitly set eth1 to ignore
# return path validation
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.eth1.rp_filter = 0
Danny
  • 235
  • 2
  • 10