Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive multicast data on a multihomed server's non-default interface

I have a linux server with two NICs (eth0 and eth1), and have set eth0 as default in "ip route." Now I would like to receive multicast packets on eth1. I have added "224.0.20.0/24 dev eth1 proto static scope link" to the routing table, and I connect as follows:

sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);

// port 12345, adress INADDR_ANY
bind(sock, &bind_addr, sizeof(bind_addr));

// multicast address 224.0.20.100, interface address 10.13.0.7 (=eth1)
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imreq, sizeof(imreq));

According to ip maddr it connects to that group on the right interface, and tshark -i eth1 shows that I am actually getting multicast packets.

However, I don't get any packets when calling recvfrom(sock). If I set "ip route default" to eth1 (instead of eth0), I do get packets via recvfrom. Is this an issue with my code or with my network setup, and what is the correct way of doing this?

(update) solution: caf hinted that this might be the same problem; indeed: after doing echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter I can now receive multicast packets!

like image 620
hrr Avatar asked Apr 04 '11 14:04

hrr


3 Answers

caf's comment that this is a duplicate of receiving multicast on a server with multiple interfaces (linux) answered this! (And I post this as an answer for clarity.) Namely, an echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter resolves my issue.

like image 153
hrr Avatar answered Nov 16 '22 12:11

hrr


Try adding a netmask and specifying 10.13.0.7 as the gateway in your routing table entry.

like image 27
Steve Emmerson Avatar answered Nov 16 '22 10:11

Steve Emmerson


Correct, assuming you had two NICs with a default gw on only one of them.

Multicast uses unicast routes to determine path back to the source. It means, if multicast path is different from unicast path, then a multicast path will exit. It's a loop prevention mechanism called RPF check.

In this case the application bound to a NIC effectively was forced to join the IGMP over where as the unicast routes were learned from the other NIC with default gateway. So the check was failing. Thus no data.

You don't need to add any static routes. It should just work when you change the rp_filter value to 0.

like image 30
Lamiv Avatar answered Nov 16 '22 12:11

Lamiv