Port Triggering with OpenWRT

OpenWRT seems to be lacking the ability to do port triggering, even though port triggering is available in other GPL firmware, and also in the Linksys GPL source. So I did some work to build the relevant files into patches for the Whiterussian 0.9 OpenWRT source. It may also work with Kamikaze or later variants, but I have not been able to test. I doubt that it's much trouble to get it working. Here's how to do it. I stress that you undertake this at your own risk, of course. I am not responsible for any bricked routers.

First, grab the latest (RC6) Whiterussian 0.9 source from OpenWRT.org and unpack it:

$ tar -jxf whiterussian-0.9.tar.bz2
Next, download these two patches for port triggering:

The iptables patch. This provides the trigger module for iptables 1.3.3.

$ cp 06-ipt_trigger.patch whiterussian-0.9/package/iptables/patches
The kernel patch. This provides the trigger kernel module.
$ cp 123-netfilter_trigger.patch whiterussian-0.9/target/linux/linux-2.4/patches/generic
Next, follow the instructions to build the toolchain and kernel. If you already have a working installation and just want to add the port trigger modules, you can just do:
$ cd whiterussian-0.9; make
Everything should build (it may take a little while). During the build process you may be asked whether to build ipt_TRIGGER in the kernel. Choose 'm' to build it as a module. After building, you will have your firmware image with the trigger modules therein. If you're installing fresh, follow the OpenWRT documentation and stop reading here; if you're just wanting to add the modules to your existing install, first copy the correct files to your box (substitute your router IP address for
$ scp build_mipsel/iptables-1.3.3/extensions/libipt_TRIGGER.so root@
$ scp build_mipsel/linux/net/ipv4/netfilter/ipt_TRIGGER.o root@
Next, log in to your router.
$ ssh -l root
You will probably need to alter the permissions on the .so file you just copied over.
# chmod 755 /usr/lib/iptables/libipt_TRIGGER.so
To finish up the hookup, you'll need to load the kernel module, and arrange for it to get autoloaded on boot. Don't worry if you get a warning about tainting the kernel; it'll still work.
# insmod ipt_TRIGGER
# echo ipt_TRIGGER >> /etc/modules
At this stage, you should be ready to use the port triggering with iptables. There is very little documentation on the web about how exactly to do this. You will need 3 lines in the config file (/etc/firewall.user):
#iptables -t nat -A prerouting_wan -p tcp --dport 6881:6889 -j TRIGGER --trigger-type dnat
#iptables -A forwarding_wan -p tcp --dport 6881:6889 -j TRIGGER --trigger-type in
#iptables -t nat -A prerouting_rule -i br0 -p tcp --dport 6969 -j TRIGGER --trigger-type out --trigger-proto all --trigger-match 6881-6889 --trigger-relate 6881-6889
This example is for setting up Bittorrent with port triggering on a WRT54GS. The first two lines route incoming WAN packets to the LAN. The third line here sets up the trigger when it sees the outgoing packet from the LAN. Taken together, these three lines allow incoming traffic on ports 6881 through 6889 after seeing an outgoing packet on port 6969. I'm sure you can figure out your own required iptables commands using these as a guideline. The only thing left to do is restart iptables:
# /etc/init.d/S35firewall
Happy port triggering!