Iptables – Unicast to multicast via iptables

iptablesmulticast

Note: While there is an accepted answer now, it is only part; check the final iptables rule below.

I'm receiving a unicast RTP stream on one interface and wish to send it out via multicast on a second interface. The system in question is an embedded processor running Linux, but I'm finding it equally difficult to set up on my Ubuntu 10.10 host. The simple, obvious answer, based on http://lists.netfilter.org/pipermail/netfilter/2002-October/038890.html and other sources, seems to be:

iptables -t nat -A PREROUTING -i [unicast-interface] -p udp --dport [unicast-incoming-port] -j DNAT --to-destination [multicast-addr]:[multicast-port]

A bit of additional research resulted in this pairing:

iptables -t nat -A PREROUTING -i [unicast-interface] -p udp --dport [unicast-incoming-port] -j DNAT --to-destination [multicast-addr]:[multicast-port]
iptables -A FORWARD -i [unicast-interface] -o [multicast-interface] -p udp --dport [unicast-incoming-port] -j ACCEPT

Though the rules show up when listed, and tcpdump shows the unicast packets coming in, Wireshark on a separate machine showed no packets coming out.

I looked at How to translate unicast to broadcast via DNAT with iptables? but that seems concerned with the specifics of the broadcast case.

Note: there are no other iptables rules that have been set. I've double-checked using iptables -L (and -t nat -L) and iptables –flush.

(I realize there are other options, like socat — but before I switch to them I'd like to make sure I'm not missing something.)

Edit: I do have ip_forward enabled.

~ # sysctl -a 2>&1 |grep ip_forward
net.ipv4.ip_forward = 1

Edit: It looks like I'm getting increasing packet counts in my NAT table (iptables -t nat -L -v -n) but not in the main/filter table (iptables -L -v -n)

Edit: Having caught up on trying things, I have had no success. I have seen some people get a similar process to work with Cisco, such as on this site: http://www.penrod.cc/?p=527

It did seem that this worked at one point in time but I have been unable to make it work since, either on the original embedded host or on a Linux workstation.

Edit: As it turns out, this issue came up again.

Final solution that worked in full:

Get smcroute (static multicast route daemon running). If you're in an embedded system you might need to use smcroute -d

smcroute -a [unicast-interface] [source-ip] [multicast-addr] [multicast-interface]
iptables -t nat -A PREROUTING -p UDP -d [unicast-interface-ip] -j NETMAP --to [multicast-addr]

For example:

smcroute -a eth0 192.168.0.101 239.1.1.1 eth0
iptables -t nat -A PREROUTING -p UDP -d 192.168.0.1 -j NETMAP --to 239.1.1.1

Note that you might need to refine the iptables rule to ensure you don't catch packets you don't intend — this is just a simplified example.

Best Answer

Do you have ip forward enabled on kernel ?

# sysctl -a 2>&1 | grep ip_forward
net.ipv4.ip_forward=1

You need it to pass traffic from one interface to another (a.k.a. the FORWARD table rules).

Edit:

There is other sysctl setting, that I suspect that will be related:

net.ipv4.conf.all.mc_forwarding

and per interface, and for ipv6.

That "mc" really sounds to multicast, but I do not have kernel docs at hand to be 100% sure.

Try setting to 1, if doesn't work always you can return to the default 0.

Edit:

from networking/ip-sysctl.txt:

conf/all/mc_forwarding must also be set to TRUE to enable multicast routing