14

TLDR: Is there a way to use "ip route" to add multicast routes for multiple NICs?

We have software that uses two multicast groups to communicate with two different groups of devices on two separate physical networks. With the exception of this application, devices on one network do not need to communicate across our device to communicate with devices on the other network.

Multicast groups

To do this the software creates two sockets. Each one is bound to the one of the ip addresses of the separate NICS. That socket is then joined to the multicast group that exists on that network, eg socket 1 is bound to 192.168.0.2 and joined to multicast group 233.255.10.1 while socket 2 is bound to 10.57.31.2 and joined to multicast group 239.255.100.1.

We are currently using a bash script (Linux kernel 3.14.39) to set multicast routes on the two network interfaces using route, eg

route add -net 224.0.0.0 netmask 240.0.0.0 eth0
route add -net 224.0.0.0 netmask 240.0.0.0 eth1

and verified via route -n

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
224.0.0.0       0.0.0.0         240.0.0.0       U     0      0        0 eth0
224.0.0.0       0.0.0.0         240.0.0.0       U     0      0        0 eth1

I recently read that route was deprecated/obsolete and that we should be using ip route instead, eg

ip route add 224.0.0.0/4 dev eth0
ip route add 224.0.0.0/4 dev eth1

Unfortunately, the second call fails with "RTNETLINK answers: File exists" and of course the second route doesn't show up after these calls.

Is there a way to use ip route to add multicast routes to multiple NICs?

I can use /8 as a netmask? eg

ip route add 233.0.0.0/8 dev eth0

and

ip route add 239.0.0.0/8 dev eth1

but this is problematic as the script that does this is not aware of what multicast address is associated with which device and its not always guaranteed to be the same depending on system configuration. Using my first example of route add makes this a non issue.

UPDATES Thanks to an extended discussion with @Ron Maupin, I realized the error was in our code. We were not setting the interface to use for multicasting with IP_MULTICAST_IF. Once I added the setsockopt call to set IP_MULTICAST_IF, I no longer needed to add the routing tables.

struct in_addr multicastInterface = {};
multicastInterface.s_addr = interfaceAddressNetworkOrder;

// Set which outgoing interface to use
int result = setsockopt(m_socket, IPPROTO_IP, IP_MULTICAST_IF, (char*)&multicastInterface, sizeof(struct in_addr));
6
  • 1
    Multicast isn't routed the same way unicast is. Multicast routing involves PIM, and you need to software to help you do it correctly.
    – Ron Maupin
    Nov 10, 2016 at 17:33
  • @Ron Maupin, What specific software are you referring to? route and iproute are software programs after all.
    – gnac
    Nov 10, 2016 at 18:03
  • You need to use something like mrouted or pimd. Multicast routing is very different than unicast routing, and it needs to respond to IGMP requests.
    – Ron Maupin
    Nov 10, 2016 at 18:43
  • How is it that our system works using route ... without using mrouted/pimd?
    – gnac
    Nov 10, 2016 at 19:14
  • You got lucky. Linux doesn't normally handle multicast correctly, but to do it right, you need to understand multicast and configure multicast routing. The router should respond to IGMP.
    – Ron Maupin
    Nov 10, 2016 at 19:18

2 Answers 2

15

That you have multicast going through your Linux box by using unicast routing is a combination of a couple of lucky circumstances.

Multicast routing is not the same as unicast routing. Unicast routing is based on the face that traffic is sent to a single address, but multicast traffic is sent to a group address that represents hosts which want to subscribe to the multicast group.

Hosts use IGMP to tell a multicast router that they want to join a multicast group, and the multicast router will then start sending multicast traffic for that group to the network of the hosts requesting this.

Modern switches will use IGMP Snooping to determine which switch ports have hosts requesting to join a particular multicast group, and they will only send traffic for that multicast group to the switch ports where the hosts have requested to join the multicast group.

Linux, by itself, doesn't support multicast routing, and you need to add something to the Linux device to support multicast routing. Refer to the diagram below:

enter image description here

When the multicast source starts to send multicast traffic for a multicast group, the switch probably has not seen any IGMP requests to join the multicast group, so the multicast traffic for that group goes nowhere.

When one of the PCs on the same switch wants to join the multicast group, it will send an IGMP Join message, and the switch will snoop on that and send the multicast traffic to the port where the requesting PC is connected.

If a PC on the other side of the Linux router wants to join the multicast group, it is out of luck because the multicast traffic is not flowing to that side of the Linux Router. The Linux Router has not even joined the multicast group, so the switch never sends the multicast traffic to it.

When you run multicast routing on a router, the router will respond to the host IGMP request, and the switch will know that it is a multicast router, and it will send multicast traffic to the switch port where the multicast router is connected. Simplistically, the router will not send the multicast traffic to another interface unless there is an active receiver on another interface (this depends on the multicast version, for instance, PIM-DM will start sending, but back off if no IGMP requests are seen).

With multicast routing enabled on the router, a PC connected to the other interface will send an IGMP Join message, and the Linux Router will begin sending the multicast traffic for the requested group to the interface. The switch will snoop on the request, and it will send multicast traffic to the switch port where the PC that requested to join the multicast group is connected.

It gets more complicated if you need to route throgh multiple routers. IGMP is used between the hosts and the local multicast router. PIM (or some other multicast routing protocol) is used between multicast routers.

This all prevents multicast traffic from going where it is not wanted.

There are add-ons to Linux to aid it in properly handling IGMP and multicast routing.

8
  • Thanks for the detailed response. I'm going to update my question to ensure it is clear. Namely, I have a linux device/application that is communicating on two different networks via multicast. It itself is not attempting to route multicast data from one network to the other, but rather publishing and receiving multicast data on two different multicast networks over two different physical interfaces.
    – gnac
    Nov 10, 2016 at 22:13
  • As I explained, if you end up with a switch that does IGMP snooping, your box that connects the two networks may never even get the multicast in order to route it to the other network. It is not correctly configured, and you are lucky it works, but a simple change can break it. Multicast, like broadcast, is limited to a single broadcast domain (network). Moving traffic from one network to another network is routing , and you are trying to route multicast traffic.
    – Ron Maupin
    Nov 10, 2016 at 22:15
  • I am not trying to route multicast traffic across my device. I am trying to ensure that the application on my device can communicate with other devices in a multicast group on a specific physical network. If I take away the fact that I'm connecting to two networks, I still need the route add statements or else no multicast traffic is sent of received from my device.
    – gnac
    Nov 10, 2016 at 22:40
  • Yes, you are routing. That is the very definition of sending traffic from one network to another network. If you had bridged these networks then you would not need to use a route or ip route command because the traffic would be bridged from one interface to another interface.
    – Ron Maupin
    Nov 10, 2016 at 22:41
  • but you need to use route even if you are only using one network/interface.
    – gnac
    Nov 10, 2016 at 22:55
2

To add multiple routes for a target, you can add the first as you have done, by using ip route add <address> dev <interface>. To add the second you then use ip route append <address> dev <interface2>.

For ipv4 you will need something to manage the IGMP or whichever multicast management protocol you are using. For ipv6 this is baked into the icmpv6 protocol so my understanding is that linux should handle this out of the box for you.

1
  • Thanks for this. It was exactly what i was looking for at the time. Yeah, we've both resurected zombie threads, but I ran into a similar issue recently and came across my old post with your "new" response, which was what I really needed.
    – gnac
    Dec 15, 2022 at 15:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .