TechInfoDepot:DD-WRT/Dual / Triple WAN How To

From TechInfoDepot
Jump to navigationJump to search

Source: jbarbieri

Introduction

This setup is working for me, so I will post down what my router looks like.

My setup: I have 2 cable modems from the same ISP. I also have 2 static IPs, but in DIFFERENT RANGES (not sure how much this helps, but I did not try with IPs in the same range). I also am not sure on how to get this to work with DHCP or PPPoE. As usual, YMMV. I can try to help you out as best as I can, but.....if it involves DHCP or PPPoE, I wont be able to help.

VLANs

First, we have to put port 4 onto its own VLAN. I am using a WRT54GS V2, and the port numbering was switched with a newer version, so your numbering might be different. In the web gui, set port 4 to vlan 2. Then login into the router, and run these commands:

nvram set vlan0ports="1 2 3 5*"
nvram set vlan2ports="4 5"
nvram set vlan2hwname=et0
nvram commit
reboot

scripts

After many trials and errors, there is a good working baseline. Here are the current scripts....3 in all. 2 of them are loaded under startup, the other is the firewall. You can download them from this post: http://www.dd-wrt.com/phpBB2/viewtopic.php?p=169172#169172

dhcp on vlan2

The first piece of code, I put on JFFS and called udhcpc-wan2.script:

#!/bin/sh
# udhcpc script edited by Tim Riker <Tim@Rikers.org>
[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1

ifconfig $interface up

RESOLV_CONF="/etc/resolv.conf"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"

case "$1" in
   deconfig)
     # /sbin/ifconfig $interface 0.0.0.0
     ;;

  renew|bound)
    # /sbin/ifconfig $interface $ip $BROADCAST $NETMASK
    echo "$ip $BROADCAST $NETMASK"

  if [ -n "$router" ] ; then
    echo "deleting routers"
    # while route del default gw 0.0.0.0 dev $interface ; do
    #  :
    # done

    # for i in $router ; do
    #   route add default gw $i dev $interface
    # done
    echo "$router"
  fi

  echo -n > $RESOLV_CONF
  [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF
  for i in $dns ; do
    echo adding dns $i
    echo nameserver $i >> $RESOLV_CONF
  done
  nvram set wan2_ifname=$interface
  nvram set wan2_gateway=$router
  nvram set wan2_ipaddr=$ip
  nvram set wan2_netmask=$subnet
  nvram set wan2_broadcast=$broadcast
  nvram commit
  ifconfig $(nvram get wan2_ifname) $(nvram get wan2_ipaddr) netmask $(nvram get wan2_netmask) up
  ;;
esac

exit 0

This script does dhcp on vlan2, and stores the values into NVRAM to be used in later scripts.

routes

The second piece of code, I called routes.firewall:

#!/bin/sh

ip rule flush

ip rule add lookup main prio 32766
ip rule add lookup default prio 32767

ip rule add from $(nvram get wan_ipaddr) table 100 prio 100
ip rule add fwmark 0x100 table 100 prio 101

ip rule add from $(nvram get wan2_ipaddr) table 200 prio 200
ip rule add fwmark 0x200 table 200 prio 201

ip route flush table 100
ip route flush table 200

for TABLE in 100 200
do
   ip route | grep link | while read ROUTE
   do
     ip route add table $TABLE to $ROUTE
   done
done

ip route add table 100 default via $(nvram get wan_gateway)
ip route add table 200 default via $(nvram get wan2_gateway)
ip route delete default
ip route add default scope global equalize nexthop via $(nvram get wan_gateway) dev  $(nvram get wan_ifname) nexthop via $(nvram get wan2_gateway) dev $(nvram get wan2_ifname)

This sets up the routing tables.

firewall

For bellow V24RC4

The last piece, I called firewall.firewall...the tricky part here is, depending on what version of firmware you are running, this will be different. For V23 and V24RC4 and below, use this code:

#!/bin/sh
IPTABLES="/usr/sbin/iptables"

#DD-WRT firewall rules #BEGIN

#apply simple forward rules

for RULE in $(nvram get forward_spec)
do
   FROM=`echo $RULE | cut -d '>' -f 1`
   TO=`echo $RULE | cut -d '>' -f 2`
   STATE=`echo $FROM | cut -d ':' -f 2`
   PROTO=`echo $FROM | cut -d ':' -f 3`
   SPORT=`echo $FROM | cut -d ':' -f 4`
   DEST=`echo $TO | cut -d ':' -f 1`
   DPORT=`echo $TO | cut -d ':' -f 2`

   if [ "$STATE" = "on" ]; then
      if [ "$PROTO" = "both" ]; then
        #udp
        iptables -A PREROUTING -t nat -p udp -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
        #tcp
        iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
      else
        iptables -A PREROUTING -t nat -p $PROTO -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
      fi
   fi
done

#apply range forward rules
for RULE in $(nvram get forward_port)
do
  FROM=`echo $RULE | cut -d '>' -f 1`
  TO=`echo $RULE | cut -d '>' -f 2`
  STATE=`echo $FROM | cut -d ':' -f 2`
  PROTO=`echo $FROM | cut -d ':' -f 3`
  SPORT=`echo $FROM | cut -d ':' -f 4`
  EPORT=`echo $FROM | cut -d ':' -f 5`

  if [ "$STATE" = "on" ]; then
    if [ "$PROTO" = "both" ]; then
      #udp
      iptables -A PREROUTING -t nat -p udp -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
      #tcp
      iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
    else
      iptables -A PREROUTING -t nat -p $PROTO -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
    fi
  fi
done

iptables -A PREROUTING -t nat -p icmp -d $(nvram get wan2_ipaddr) -j DNAT --to $(nvram get lan_ipaddr)

if [ $(nvram get remote_management) -eq 1 ]; then
        iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $(nvram get http_wanport) -j DNAT --to $(nvram get lan_ipaddr):$(nvram get http_lanport)
fi

if [ $(nvram get dmz_enable) -eq 1 ]; then
        DMZ_IP=$(nvram get lan_ipaddr | sed -r 's/[0-9]+$//')$(nvram get dmz_ipaddr)
        iptables -A PREROUTING -t nat -d $(nvram get wan2_ipaddr) -j DNAT --to $DMZ_IP
fi

iptables -A PREROUTING -t nat --dest $(nvram get wan2_ipaddr) -j TRIGGER --trigger-type dnat
iptables -A FORWARD -i $(nvram get wan2_ifname) -o $(nvram get lan_ifname) -j TRIGGER --trigger-type in

#DD-WRT END

$IPTABLES -t mangle -F PREROUTING
$IPTABLES -t mangle -F OUTPUT

$IPTABLES -F POSTROUTING -t nat

$IPTABLES -t mangle -N ETH1
$IPTABLES -t mangle -F ETH1
#$IPTABLES -t mangle -A ETH1 -p tcp -j LOG --log-prefix " MANGLE_TCP_ETH1 "
#$IPTABLES -t mangle -A ETH1 -p icmp -j LOG --log-prefix " MANGLE_ICMP_ETH1 "
$IPTABLES -t mangle -A ETH1 -j MARK --set-mark 0x100
$IPTABLES -t mangle -A ETH1 -j CONNMARK --save-mark

$IPTABLES -t mangle -N ETH2
$IPTABLES -t mangle -F ETH2
#$IPTABLES -t mangle -A ETH2 -p tcp -j LOG --log-prefix " MANGLE_TCP_ETH2 "
#$IPTABLES -t mangle -A ETH2 -p icmp -j LOG --log-prefix " MANGLE_ICMP_ETH2 "
$IPTABLES -t mangle -A ETH2 -j MARK --set-mark 0x200
$IPTABLES -t mangle -A ETH2 -j CONNMARK --save-mark

$IPTABLES -t mangle -N RANDOM
$IPTABLES -t mangle -F RANDOM
$IPTABLES -t mangle -A RANDOM -m random --average 50 -j ETH1
$IPTABLES -t mangle -A RANDOM -m random --average 50 -j ETH2

$IPTABLES -t nat -N SPOOF_ETH1
$IPTABLES -t nat -F SPOOF_ETH1
#$IPTABLES -t nat -A SPOOF_ETH1 -j LOG --log-prefix " SPOOF_ETH1 "
$IPTABLES -t nat -A SPOOF_ETH1 -j SNAT --to $(nvram get wan_ipaddr)

$IPTABLES -t nat -N SPOOF_ETH2
$IPTABLES -t nat -F SPOOF_ETH2
#$IPTABLES -t nat -A SPOOF_ETH2 -j LOG --log-prefix " SPOOF_ETH2 "
$IPTABLES -t nat -A SPOOF_ETH2 -j SNAT --to $(nvram get wan2_ipaddr)

$IPTABLES -t nat -A POSTROUTING -o $(nvram get wan_ifname) -j SPOOF_ETH1
$IPTABLES -t nat -A POSTROUTING -o $(nvram get wan2_ifname) -j SPOOF_ETH2

$IPTABLES -t mangle -A OUTPUT -o ! br0 -m state --state NEW -j RANDOM
$IPTABLES -t mangle -A OUTPUT -j CONNMARK --restore-mark
$IPTABLES -t mangle -A OUTPUT --match mark --mark 0x100 -j ACCEPT
$IPTABLES -t mangle -A OUTPUT --match mark --mark 0x200 -j ACCEPT

$IPTABLES -t mangle -A PREROUTING -i br0 -m state --state NEW -j RANDOM
$IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark
$IPTABLES -t mangle -A PREROUTING --match mark --mark 0x100 -j ACCEPT
$IPTABLES -t mangle -A PREROUTING --match mark --mark 0x200 -j ACCEPT
$IPTABLES -t mangle -A PREROUTING -i vlan1 -j ETH1
$IPTABLES -t mangle -A PREROUTING -i vlan2 -j ETH2

RP_PATH=/proc/sys/net/ipv4/conf
for IFACE in `ls $RP_PATH`; do
    echo 0 > $RP_PATH/$IFACE/rp_filter
done
iptables -I INPUT -p icmp -j ACCEPT

echo "`date` firewall.firewall is now completed" >> /var/log/messages

For above V24RC4

#!/bin/sh
insmod ipt_CONNMARK
IPTABLES="/usr/sbin/iptables"

#DD-WRT firewall rules #BEGIN

#apply simple forward rules

for RULE in $(nvram get forward_spec)
do
   FROM=`echo $RULE | cut -d '>' -f 1`
   TO=`echo $RULE | cut -d '>' -f 2`
   STATE=`echo $FROM | cut -d ':' -f 2`
   PROTO=`echo $FROM | cut -d ':' -f 3`
   SPORT=`echo $FROM | cut -d ':' -f 4`
   DEST=`echo $TO | cut -d ':' -f 1`
   DPORT=`echo $TO | cut -d ':' -f 2`

   if [ "$STATE" = "on" ]; then
      if [ "$PROTO" = "both" ]; then
        #udp
        #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p udp --dport $SPORT -j ACCEPT
        iptables -A PREROUTING -t nat -p udp -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
        #tcp
        #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p tcp --dport $SPORT -j ACCEPT
        iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
      else
        #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p $PROTO --dport $SPORT -j ACCEPT
        iptables -A PREROUTING -t nat -p $PROTO -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
      fi
   fi
done

#apply range forward rules
for RULE in $(nvram get forward_port)
do
  FROM=`echo $RULE | cut -d '>' -f 1`
  TO=`echo $RULE | cut -d '>' -f 2`
  STATE=`echo $FROM | cut -d ':' -f 2`
  PROTO=`echo $FROM | cut -d ':' -f 3`
  SPORT=`echo $FROM | cut -d ':' -f 4`
  EPORT=`echo $FROM | cut -d ':' -f 5`

  if [ "$STATE" = "on" ]; then
    if [ "$PROTO" = "both" ]; then
      #udp
      #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p udp --dport $SPORT:$EPORT -j ACCEPT
      iptables -A PREROUTING -t nat -p udp -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
      #tcp
      #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p tcp --dport $SPORT:$EPORT -j ACCEPT
      iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
    else
      #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p $PROTO --dport $SPORT:$EPORT -j ACCEPT
      iptables -A PREROUTING -t nat -p $PROTO -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
    fi
  fi
done

iptables -A PREROUTING -t nat -p icmp -d $(nvram get wan2_ipaddr) -j DNAT --to $(nvram get lan_ipaddr)

if [ $(nvram get remote_management) -eq 1 ]; then
        iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $(nvram get http_wanport) -j DNAT --to $(nvram get lan_ipaddr):$(nvram get http_lanport)
fi

if [ $(nvram get dmz_enable) -eq 1 ]; then
        DMZ_IP=$(nvram get lan_ipaddr | sed -r 's/[0-9]+$//')$(nvram get dmz_ipaddr)
        iptables -A PREROUTING -t nat -d $(nvram get wan2_ipaddr) -j DNAT --to $DMZ_IP
fi

iptables -A PREROUTING -t nat --dest $(nvram get wan2_ipaddr) -j TRIGGER --trigger-type dnat
iptables -A FORWARD -i $(nvram get wan2_ifname) -o $(nvram get lan_ifname) -j TRIGGER --trigger-type in

#iptables -A PREROUTING -t mangle -i $(nvram get wan2_ifname) -j IMQ --todev 0
#iptables -A PREROUTING -t mangle -i $(nvram get wan2_ifname) -j SVQOS_IN
#iptables -A POSTROUTING -t mangle -o $(nvram get wan2_ifname) -j SVQOS_OUT

#DD-WRT END

$IPTABLES -F POSTROUTING -t nat
$IPTABLES -t mangle -N ETH1
$IPTABLES -t mangle -F ETH1
#$IPTABLES -t mangle -A ETH1 -p tcp -j LOG --log-prefix " MANGLE_TCP_ETH1 "
#$IPTABLES -t mangle -A ETH1 -p icmp -j LOG --log-prefix " MANGLE_ICMP_ETH1 "
$IPTABLES -t mangle -A ETH1 -j MARK --set-mark 0x100
$IPTABLES -t mangle -N ETH2
$IPTABLES -t mangle -F ETH2
#$IPTABLES -t mangle -A ETH2 -p tcp -j LOG --log-prefix " MANGLE_TCP_ETH2 "
#$IPTABLES -t mangle -A ETH2 -p icmp -j LOG --log-prefix " MANGLE_ICMP_ETH2 "
$IPTABLES -t mangle -A ETH2 -j MARK --set-mark 0x200
$IPTABLES -t nat -N SPOOF_ETH1
$IPTABLES -t nat -F SPOOF_ETH1
$IPTABLES -t nat -A SPOOF_ETH1 -j LOG --log-prefix " SPOOF_ETH1 "
$IPTABLES -t nat -A SPOOF_ETH1 -j SNAT --to $(nvram get wan_ipaddr)
#$IPTABLES -t nat -A SPOOF_ETH1 -j MASQUERADE
$IPTABLES -t nat -N SPOOF_ETH2
$IPTABLES -t nat -F SPOOF_ETH2
$IPTABLES -t nat -A SPOOF_ETH2 -j LOG --log-prefix " SPOOF_ETH2 "
$IPTABLES -t nat -A SPOOF_ETH2 -j SNAT --to $(nvram get wan2_ipaddr)
#$IPTABLES -t nat -A SPOOF_ETH2 -j MASQUERADE
$IPTABLES -A INPUT -p icmp -s 192.168.1.0/24 -d 192.168.1.1 -j ACCEPT
#Save the gateway in the connection mark for new incoming connections
$IPTABLES -t mangle -A PREROUTING -i $(nvram get wan_ifname) -m conntrack --ctstate NEW -j CONNMARK --set-mark 0x100
$IPTABLES -t mangle -A PREROUTING -i $(nvram get wan2_ifname) -m conntrack --ctstate NEW -j CONNMARK --set-mark 0x200
$IPTABLES -A POSTROUTING -t mangle -o $(nvram get wan_ifname) -j MARK --set-mark 0x100
$IPTABLES -A POSTROUTING -t mangle -o $(nvram get wan2_ifname) -j MARK --set-mark 0x200
$IPTABLES -t nat -A POSTROUTING -o $(nvram get wan_ifname) -j SPOOF_ETH1
$IPTABLES -t nat -A POSTROUTING -o $(nvram get wan2_ifname) -j SPOOF_ETH2
$IPTABLES -t mangle -A POSTROUTING -j CONNMARK --save-mark
$IPTABLES -t mangle -A PREROUTING -i br0 -m state --state RELATED,ESTABLISHED -j CONNMARK --restore-mark
# Use the correct gateway for reply packets from local connections
$IPTABLES -t mangle -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark

RP_PATH=/proc/sys/net/ipv4/conf
for IFACE in `ls $RP_PATH`; do
    echo 0 > $RP_PATH/$IFACE/rp_filter
done

Save the file.

Finishing up

Next, goto Admin>commands, and put the following in the box:

udhcpc -s /jffs/scripts/udhcpc-wan2.script  -i vlan2
/jffs/scripts/routes.firewall

and click save startup.

Then in the box again, put this in:

/jffs/scripts/firewall.firewall


And click save firewall.

After that, everything SHOULD be up and running. That is all I did to get it working. I was pinging an external server that I had root on, and was doing a tcpdump icmp to see where my pings where coming from, and they were swapping from one interface to the other. It wasnt 1 for 1, but it was close (sometimes it would repeat 2 or 3 times on an interface).

This round robins your outbound traffic, and the servers will reply to the IP you sent it from. This will NOT double download speeds of SINGLE FILES. However, with a program (like download accelerator plus, which makes multiple connections per download), this will work. This works with V23...the newer stuff, you have to use different servers since routes are cached.

Here are my MRTG graphs after implementing and downloading a large file (Fedora Core DVD ISO) with Download Accelerator Plus:

Traffic Analysis for VLAN0 (LAN Traffic): Vlan0.png

Traffic Analysis for VLAN1 (WAN1 Traffic): Wan1.png

Traffic Analysis for VLAN2 (WAN2 Traffic): Wan2.png


My ISP's speeds are 6mbit/384 k, and as you can see, I was close to max on both cable modems.


If you have questions/comments/problems post here or shoot me an IM, and I will try to help you.

Regards,

John

Page 5 Scripts from thread

Alright, I was able to do this @ home, and it is working for me Very Happy I am doing this on a WRT54GS V2.

For the first WAN, just plug it into the WAN port like normal, and leave alone, setting DD-wrt to do auto config (DHCP).


For the second WAN, first, goto the VLAN page and set port 4 up to VLAN 2. Then, log into the router using telnet/ssh, and set up VLAN2 for port 4:

nvram set vlan0ports="1 2 3 5*"
nvram set vlan2ports="4 5"
nvram set vlan2hwname=et0
nvram commit
reboot	


Then, for the rest of config, I use 3 different scripts that I put into JFFS. (I am unsure at the moment how to get this to work if you dont have room in JFFS). All the scripts are located in /jffs/scripts


First script, I named "udhcpc-vlan2.script"

#!/bin/sh
# udhcpc script edited by Tim Riker <Tim@Rikers.org>
[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1

ifconfig $interface up

RESOLV_CONF="/etc/resolv.conf"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"

case "$1" in
   deconfig)
     # /sbin/ifconfig $interface 0.0.0.0
     ;;

  renew|bound)
    # /sbin/ifconfig $interface $ip $BROADCAST $NETMASK
    echo "$ip $BROADCAST $NETMASK"

  if [ -n "$router" ] ; then
    echo "deleting routers"
    # while route del default gw 0.0.0.0 dev $interface ; do
    #  :
    # done

    # for i in $router ; do
    #   route add default gw $i dev $interface
    # done
    echo "$router"
  fi

  echo -n > $RESOLV_CONF
  [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF
  for i in $dns ; do
    echo adding dns $i
    echo nameserver $i >> $RESOLV_CONF
  done
  nvram set wan2_ifname=$interface
  #nvram set wan2_ifname=vlan3
  nvram set wan2_gateway=$router
  nvram set wan2_ipaddr=$ip
  nvram set wan2_netmask=$subnet
  nvram set wan2_broadcast=$broadcast
  nvram commit
  ifconfig $(nvram get wan2_ifname) $(nvram get wan2_ipaddr) netmask $(nvram get wan2_netmask) up
  ;;
esac

exit 0

Save the script, and

	
chmod 755 udhcpc-vlan2.script

What this does is a DHCP request, gets the IP address, and sets the values in NVRAM (IP, Netmask, gateway) which are needed for the other scripts.


The second script I named "routes.firewall"

#!/bin/sh

ip rule flush

ip rule add lookup main prio 32766
ip rule add lookup default prio 32767

ip rule add from $(nvram get wan_ipaddr) table 100 prio 100
ip rule add fwmark 0x100 table 100 prio 101

ip rule add from $(nvram get wan2_ipaddr) table 200 prio 200
ip rule add fwmark 0x200 table 200 prio 201

ip route flush table 100
ip route flush table 200

for TABLE in 100 200
do
   ip route | grep link | while read ROUTE
   do
     ip route add table $TABLE to $ROUTE
   done
done

ip route add table 100 default via $(nvram get wan_gateway)
ip route add table 200 default via $(nvram get wan2_gateway)
ip route delete default
ip route add default scope global equalize nexthop via $(nvram get wan_gateway) dev  $(nvram get wan_ifname) nexthop via $(nvram get wan2_gateway) dev $(nvram get wan2_ifname)

This sets up the routing tables for both interfaces, and throws in the equalize command.

Set it to executable:

chmod 755 routes.firewall	

The last script, I named "firewall.firewall"

#!/bin/sh
IPTABLES="/usr/sbin/iptables"

#DD-WRT firewall rules #BEGIN

#apply simple forward rules

for RULE in $(nvram get forward_spec)
do
   FROM=`echo $RULE | cut -d '>' -f 1`
   TO=`echo $RULE | cut -d '>' -f 2`
   STATE=`echo $FROM | cut -d ':' -f 2`
   PROTO=`echo $FROM | cut -d ':' -f 3`
   SPORT=`echo $FROM | cut -d ':' -f 4`
   DEST=`echo $TO | cut -d ':' -f 1`
   DPORT=`echo $TO | cut -d ':' -f 2`

   if [ "$STATE" = "on" ]; then
      if [ "$PROTO" = "both" ]; then
        #udp
        #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p udp --dport $SPORT -j ACCEPT
        iptables -A PREROUTING -t nat -p udp -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
        #tcp
        #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p tcp --dport $SPORT -j ACCEPT
        iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
      else
        #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p $PROTO --dport $SPORT -j ACCEPT
        iptables -A PREROUTING -t nat -p $PROTO -d $(nvram get wan2_ipaddr) --dport $SPORT -j DNAT --to $DEST:$DPORT
      fi
   fi
done

#apply range forward rules
for RULE in $(nvram get forward_port)
do
  FROM=`echo $RULE | cut -d '>' -f 1`
  TO=`echo $RULE | cut -d '>' -f 2`
  STATE=`echo $FROM | cut -d ':' -f 2`
  PROTO=`echo $FROM | cut -d ':' -f 3`
  SPORT=`echo $FROM | cut -d ':' -f 4`
  EPORT=`echo $FROM | cut -d ':' -f 5`

  if [ "$STATE" = "on" ]; then
    if [ "$PROTO" = "both" ]; then
      #udp
      #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p udp --dport $SPORT:$EPORT -j ACCEPT
      iptables -A PREROUTING -t nat -p udp -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
      #tcp
      #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p tcp --dport $SPORT:$EPORT -j ACCEPT
      iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
    else
      #iptables -A FORWARD -d $(nvram get wan2_ipaddr) -p $PROTO --dport $SPORT:$EPORT -j ACCEPT
      iptables -A PREROUTING -t nat -p $PROTO -d $(nvram get wan2_ipaddr) --dport $SPORT:$EPORT -j DNAT --to $TO
    fi
  fi
done

iptables -A PREROUTING -t nat -p icmp -d $(nvram get wan2_ipaddr) -j DNAT --to $(nvram get lan_ipaddr)

if [ $(nvram get remote_management) -eq 1 ]; then
        iptables -A PREROUTING -t nat -p tcp -d $(nvram get wan2_ipaddr) --dport $(nvram get http_wanport) -j DNAT --to $(nvram get lan_ipaddr):$(nvram get http_lanport)
fi

if [ $(nvram get dmz_enable) -eq 1 ]; then
        DMZ_IP=$(nvram get lan_ipaddr | sed -r 's/[0-9]+$//')$(nvram get dmz_ipaddr)
        iptables -A PREROUTING -t nat -d $(nvram get wan2_ipaddr) -j DNAT --to $DMZ_IP
fi

iptables -A PREROUTING -t nat --dest $(nvram get wan2_ipaddr) -j TRIGGER --trigger-type dnat
iptables -A FORWARD -i $(nvram get wan2_ifname) -o $(nvram get lan_ifname) -j TRIGGER --trigger-type in

#iptables -A PREROUTING -t mangle -i $(nvram get wan2_ifname) -j IMQ --todev 0
iptables -A PREROUTING -t mangle -i $(nvram get wan2_ifname) -j SVQOS_IN
iptables -A POSTROUTING -t mangle -o $(nvram get wan2_ifname) -j SVQOS_OUT

#DD-WRT END

$IPTABLES -F POSTROUTING -t nat
$IPTABLES -t mangle -N ETH1
$IPTABLES -t mangle -F ETH1
#$IPTABLES -t mangle -A ETH1 -p tcp -j LOG --log-prefix " MANGLE_TCP_ETH1 "
#$IPTABLES -t mangle -A ETH1 -p icmp -j LOG --log-prefix " MANGLE_ICMP_ETH1 "
$IPTABLES -t mangle -A ETH1 -j MARK --set-mark 0x100
$IPTABLES -t mangle -N ETH2
$IPTABLES -t mangle -F ETH2
#$IPTABLES -t mangle -A ETH2 -p tcp -j LOG --log-prefix " MANGLE_TCP_ETH2 "
#$IPTABLES -t mangle -A ETH2 -p icmp -j LOG --log-prefix " MANGLE_ICMP_ETH2 "
$IPTABLES -t mangle -A ETH2 -j MARK --set-mark 0x200
$IPTABLES -t nat -N SPOOF_ETH1
$IPTABLES -t nat -F SPOOF_ETH1
#$IPTABLES -t nat -A SPOOF_ETH1 -j LOG --log-prefix " SPOOF_ETH1 "
$IPTABLES -t nat -A SPOOF_ETH1 -j SNAT --to $(nvram get wan_ipaddr)
$IPTABLES -t nat -N SPOOF_ETH2
$IPTABLES -t nat -F SPOOF_ETH2
#$IPTABLES -t nat -A SPOOF_ETH2 -j LOG --log-prefix " SPOOF_ETH2 "
$IPTABLES -t nat -A SPOOF_ETH2 -j SNAT --to $(nvram get wan2_ipaddr)
$IPTABLES -t mangle -A OUTPUT -o ! br0 -m random --average 50 -j ETH1
$IPTABLES -t mangle -A PREROUTING -i br0 -m random --average 50 -j ETH1
$IPTABLES -t mangle -A OUTPUT -o ! br0 -m random --average 50 -j ETH2
$IPTABLES -t mangle -A PREROUTING -i br0 -m random --average 50 -j ETH2
$IPTABLES -t nat -A POSTROUTING -o $(nvram get wan_ifname) -j SPOOF_ETH1
$IPTABLES -t nat -A POSTROUTING -o $(nvram get wan2_ifname) -j SPOOF_ETH2

RP_PATH=/proc/sys/net/ipv4/conf
for IFACE in `ls $RP_PATH`; do
    echo 0 > $RP_PATH/$IFACE/rp_filter
done

This does the iptables magic, which randomizes the outgoing connections, using SNAT, and sends them out the different interfaces. Dont forget to

chmod 755 firewall.firewall	

The last step, is to set these scripts to run.

In the webgui, goto Administration>Commands, and put the following in for startup:

udhcpc -s /jffs/scripts/udhcpc-vlan2.script  -i vlan2
/jffs/scripts/routes.firewall

And click save startup.

Next, do the same thing for the firewall:

/jffs/scripts/firewall.firewall

And click save firewall.


After all of that, everything *should* work. It did for me, I got rid of my static IPs, and now things are working great. The only problem I still see, and others might too, is if both IPs happen to be in the same network, it breaks the dual wan...unsure why.


Give those scripts a shot. The good thing is, there is no more editing of the scripts to your liking, they should just work.


--John