0

On Fedora 30, I'm trying to see multicast packets in another process on the same host. Using netstat, iperf, and tcpdump, I've verified that the group is joined and packets are sent to the multicast address, but the server-mode iperf never receives anything.

When I try this on another machine (CentOS 7) on a different network (that I didn't set up), I see the packets leave, but I don't see packets coming back but the server iperf does print out received packets. I'm guessing this is a kernel thing, but how to I enable this?

Here is some of the terminal session:

 jnordwick@jnkde ~ iperf -s -u -B 226.94.1.1 -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Binding to local address 226.94.1.1
Joining multicast group  226.94.1.1
Receiving 1470 byte datagrams
UDP buffer size:  208 KByte (default)
------------------------------------------------------------

and the other terminal

 jnordwick@jnkde ~ netstat -g
IPv6/IPv4 Group Memberships
Interface       RefCnt Group
--------------- ------ ---------------------
lo              1      all-systems.mcast.net
eno1            1      226.94.1.1

now sending packets

 jnordwick@jnkde ~ iperf -c 226.94.1.1 -u -T 32 -t 3 -i 1
------------------------------------------------------------
Client connecting to 226.94.1.1, UDP port 5001
Sending 1470 byte datagrams, IPG target: 11215.21 us (kalman adjust)
Setting multicast TTL to 32
UDP buffer size:  208 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.155 port 47755 connected with 226.94.1.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 1.0 sec   131 KBytes  1.07 Mbits/sec
[  3]  1.0- 2.0 sec   128 KBytes  1.05 Mbits/sec
[  3]  0.0- 3.0 sec   385 KBytes  1.05 Mbits/sec
[  3] Sent 268 datagrams

Nothing appears in the server side perf, but if I run the exact same command on another network, I can see:

[jnordwick@network2 ~]$ iperf -s -u -B 226.94.1.1 -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Binding to local address 226.94.1.1
Joining multicast group  226.94.1.1
Receiving 1470 byte datagrams
UDP buffer size:  208 KByte (default)
------------------------------------------------------------
[  3] local 226.94.1.1 port 5001 connected with 204.2.57.7 port 58971
[ ID] Interval       Transfer     Bandwidth        Jitter   Lost/Total Datagrams
[  3]  0.0- 1.0 sec   129 KBytes  1.06 Mbits/sec   0.000 ms    0/   90 (0%)
[  3]  1.0- 2.0 sec   128 KBytes  1.05 Mbits/sec   0.001 ms    0/   89 (0%)
[  3]  2.0- 3.0 sec   128 KBytes  1.05 Mbits/sec   0.001 ms    0/   89 (0%)
[  3]  0.0- 3.0 sec   385 KBytes  1.05 Mbits/sec   0.001 ms    0/  268 (0%)

tcpdump confirms the igmp joins and that packets are sent. I've dumped every interface possible (including the bonded and its slaves), and I can see the one interface the multicast packets leave from, but nothing comes back on any of them. I assume this is a kernel thing, since I don't think switches usually send multicast/broadcast traffic back to the sending host.

JasonN
  • 111
  • 4
  • You seem to be using a RESERVED (`225.0.0.0` to `231.255.255.255`) multicast group, and this is a very bad idea because it could have a bad conflict at some point. The Organization-Local scope (`239.0.0.0` to `239.255.255.255`) is set aside for such things. – Ron Maupin Nov 04 '19 at 21:54
  • Also, you do not assign a multicast group as the address of an interface. Interfaces are assigned unicast addresses, and joining a multicast group on the interface tells the network stack for that interface to allow traffic destined to that multicast group up the network stack. If you assume that sending a multicast packet out an interface will also result in the multicast packet coming back into the same interface, then you are incorrect. IPv4 multicast does not have a way to loop back into the host, but that was added for IPv6 multicast (Interface-Local scope). – Ron Maupin Nov 04 '19 at 21:59
  • @RonMaupin I don't understand you're second comment (don't worry about the address - this is just testing). What are you saying is the difference between the two setups? From what I've read (and seems to be what you are saying), I shouldn't expect the packet back over the interface. So the kernel needs to handle it in some way. Why does the CentOS machine handle it fine, but the Fedora one doesn't. Is there some kernel parameter I need to turn on? – JasonN Nov 04 '19 at 22:39
  • The thing about Linux, and the different variants is that they do not always follow the RFCs. For example, you simply do not set an interface address to a multicast group address. Multicast addresses are only used in packets as a destination address. Multicast is very different than unicast, but I have seen some Linux variants able to route it as unicast, and that violates the standards, and you should not do that because it can cause you trouble. There are proper methods for IPC inside a host, but using the network stack is pretty inefficient. – Ron Maupin Nov 04 '19 at 22:43
  • @JasonN [IP Multicasting with Socat](http://www.dest-unreach.org/socat/doc/socat-multicast.html). If you don't want to emit any ipv4 multicast, just create a dummy interface and route it over it. (eg: `ip route add multicast 239.255.255.0/24 dev dummy0` ). Running the server and client of example 1 on the same host works. – A.B Nov 04 '19 at 22:44
  • I don't get to control any of this. I'm using other software that uses multicast for a discovery protocol. This runs on the CentOS machine but not my development Fedora machine. Trying to find out why. My current workaround is a centos docker image. Don't worry about efficiency or anything, this is just for discovery, and I can't change the way it does this and I still need it to go out to the network. – JasonN Nov 04 '19 at 23:07
  • 1
    @JasonN well the same socat example, when the client is added the option ip-multicast-loop=0 fails (and works with ip-multicast-loop=1 which is default here): this controls looping back the multicast packet on the same host. You could strace iperf and see if there's something similar to `setsockopt(5, SOL_IP, IP_MULTICAST_LOOP, "\0", 1) = 0`. There's also the firewall to check. you could be dropping those looped back packets.(for this case the best way to accept them is to mark them on output and accept marks on input). – A.B Nov 04 '19 at 23:21
  • also looping back multicast on IPv4 has nothing linux specific. For example: https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE , https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/commprogramming/skt_multicast.html . – A.B Nov 04 '19 at 23:42
  • This seems to be Fedora specific. Both straces (from the working machine and non-working machine) show essentially the same strace. They both only set TTL to 32 and that is about it. Not sure why CentOS happily forwards the packets locally and Fedora doesn't. – JasonN Nov 05 '19 at 00:46
  • @A.B F---, it was firewalld. I'm not very good at the sysadmin stuff. I stopped firewalld service and it worked fine. What oh why would Fedora do that? Now I just need to figure out how to change the firewall rules for that. If you want to copy that comment into an answer, I'll accept it. Thank you. – JasonN Nov 05 '19 at 00:54
  • I'm not good at using firewalld. I can only tell that kernel's conntrack can't really track correctly multicast because for it there's no relation with the multicast ip and the (unicast source ip of the) sender. As I told, for the loopback case, marking packets (-j MARK ... / -m mark ) solves it , but with firewalld, might be more difficult. I leave it to you or anybody else to write an answer ("disable firewall" is probably not a good answer). ipset can also help: [Stateful matching of multicast responses in iptables](https://serverfault.com/a/911286/217515) – A.B Nov 05 '19 at 01:23

1 Answers1

1

This appears to be a firewalld issue, and any ipchains stuff I tried didn't work, but this did.

firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 \
             -m pkttype --pkt-type multicast -j ACCEPT

also, just turning off firewalld works too:

systemctl stop firewalld

Taken from: https://www.centos.org/forums/viewtopic.php?t=60395

JasonN
  • 111
  • 4