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)

link|improve this question
feedback

3 Answers

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 grep:

networking/ip-sysctl.txt: conf/all/mc_forwarding must also be set to TRUE to enable multicast routing

link|improve this answer
I indeed do have ip_forward enabled -- but good thought, I should have mentioned that. – Arthur Shipkowski Apr 8 '11 at 17:02
1  
Hmm, mc_forwarding is zero and refuses to go to one, so I'd better check my kernel config. – Arthur Shipkowski Apr 8 '11 at 18:02
Right, this is more complete than the grep: "Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE and a multicast routing daemon is required. conf/all/mc_forwarding must also be set to TRUE to enable multicast routing for the interface", in Debian It comes builtin (CONFIG_IP_MROUTE and CONFIG_IPV6_MROUTE). – poisonbit Apr 8 '11 at 18:16
It turns out to be set to "y" in the kernel config. Additional Googling indicates I need to install a multicast routing daemon to get it to go to "1" -- which, given the cross-compilation situation, may mean the simplest solution is to go with my alternate plan. I'll see about double-checking with a multicast routing daemon when I get the chance, and accept your answer if it works. – Arthur Shipkowski Apr 8 '11 at 18:27
feedback

You need to manipulate the routing table so that after NAT-ing the packet, it gets sent out the correct interface.

ip route add to $MULTICAST_ADDR dev $MULTICAST_IFACE

That might cause problems if you send out multicasts through the incoming interface, so we must mark the packets

iptables -t mangle <rules to match the packets you want to multicast> -j MARK --mark <your favorite number>
ip rule add order 10 fwmark <that favorite number> lookup table <another favorite number>
ip route add to <multicast> dev <iface> table <2nd fav number>

Finally, you have to realize that conntrack will not be able to match the return packets; you have to do your own conntrack:

iptables -t nat -A POSTROUTING -d <multicast> -o <iface> -j SNAT <router's IP>:<a port>
iptables -t nat -A PREROUTING -i <router's IP> -p udp --dport <a port> -j DNAT <orig sender>:<orig port>

There, the general way to do what you want. I hope my (limited) explanation can start you on the right path.

link|improve this answer
feedback

It seems that you will have to use special daemon - look at igmpproxy or mrouted - as iptables will simply translate and forward incoming packet to one combination of addresses/ports in the given range.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.