Finally figured out dual wan routing rules

N/A

Occasional Visitor
For a long long time, people said the routing rules weren't working at all. I used to believe that top rule has priority because that's how it worked in my case. My top rule was 192.168.1.56 to all via primary wan and bottom rule was 192.168.1.0/24 to all via secondary wan. It worked flawlessly for me across multiple firmware versions.

Yesterday I tried to switch 192.168.1.56 to secondary and everything else to primary because I believe currently you can only get IPv6 from primary wan. To my surprise, 192.168.1.56 was still going through primary. Switching the top and bottom rules' position didn't fix it either.

Finally I realized that the priority wasn't determined by the order of rules but instead whether it's going through primary or secondary. Rules with primary wan have priority over rules with secondary wan.

So without static IP or DHCP reservation, simply set 192.168.1.0/24 to secondary wan and few specific clients to primary wan. If you want most clients through primary wan, then you can't use the cidr trick to combine multiple rules.

Let's hope ASUS can open source this part of code or improve it themselves. Really want to see 1. sticky connections for destination port 80/443 and 2. ability to set a rule through both wan.

If anyone can confirm my observations then I can add this part to Github wiki.
 

Yota

Senior Member
When we were testing how iptables order affects priority, we ignored the order of physical WAN ports. :eek:
 

FernandoF

Occasional Visitor
Rules with primary wan have priority over rules with secondary wan.
The above statement is correct. Regardless of the order that Dual WAN routing rules are entered via the GUI, the router will internally sort, list, and follow Primary WAN rules prior to Secondary WAN. Of course, those rules can be tailored over SSH, for example to give higher priority to Secondary WAN rules, but that will eventually require a wan-event script (which is actually what I do).

If you want to check the actual order of the Dual WAN routing rules:
Code:
ip rule
 

N/A

Occasional Visitor
The above statement is correct. Regardless of the order that Dual WAN routing rules are entered via the GUI, the router will internally sort, list, and follow Primary WAN rules prior to Secondary WAN. Of course, those rules can be tailored over SSH, for example to give higher priority to Secondary WAN rules, but that will eventually require a wan-event script (which is actually what I do).

If you want to check the actual order of the Dual WAN routing rules:
Code:
ip rule
Would you mind share your script please? Thanks in advance.
 

FernandoF

Occasional Visitor
@N/A, here's a slightly streamlined version of my /jffs/scripts/wan-event script. However, please keep in mind:
  • I'm a beginner with limited scripting skills
  • The script has only been tested with my particular equipment and settings (Router, ONT, Cable Modem)
  • Even though the core portion of the script is very simple, you'll notice lots of "if's" to account for several corner cases I've identified over time
  • Any comments will be very welcome

Code:
#!/bin/sh

# Exits if this is not a "connected" event
if [ "$2" != "connected" ]; then
    exit
fi

# Checks whether Dual WAN is enabled (at least initially)
if [ "$(nvram get wan0_enable)" = "1" ] && [ "$(nvram get wan1_enable)" = "1" ]; then

    # Pauses to wait for the WAN connections to be fully established
    sleep 10

    # Generates a numeric code as an indication of the current Dual WAN state (typically 11212 - may be useful while reading syslog.log)
    A=$(nvram get 'wan_enable'); B=$(nvram get 'wan0_enable'); C=$(nvram get 'wan0_state_t'); D=$(nvram get 'wan1_enable'); E=$(nvram get 'wan1_state_t')
    wancodes="($A$B$C$D$E)"

    # Checks whether Dual WAN is still enabled (after the pause)
    if [ "$B$D" = "11" ]; then

        # Checks whether both WAN's are connected
        if [ "$C$E" = "22" ]; then

            # Checks whether standard Dual WAN rules are present
            if [ "$(ip rule | grep '100:')" != "" ] && [ "$(ip rule | grep '150:')" != "" ] && [ "$(ip rule | grep '200:')" != "" ] && [ "$(ip rule | grep '400:')" != "" ]; then

                # Cleans up any existing custom Dual WAN rules (to avoid any potential duplication)
                while [ "$(ip rule | grep '90:')" != "" ]; do
                    ip rule delete priority 90 > /dev/null
                done

                # Creates custom Dual WAN rules with higher priority (90) than the standard Dual WAN rules (100)
                # Add your custom Dual WAN rules here, in the desired order, for example:
                ip rule add from xxx.xxx.xxx.xxx lookup wan1 priority 90
                ip rule add from yyy.yyy.yyy.yyy lookup wan0 priority 90
                ip rule add from all to zzz.zzz.zzz.zzz lookup wan0 priority 90
                ip rule add from all to www.www.www.www lookup wan1 priority 90

                logger -t "   $(basename $0)" "Script executed with parameters [$1 $2]: Custom Dual WAN rules configured" $wancodes

            else
                # Exits and presumes that another wan-event script will run later, when standard rules are present. This can happen on a router reboot or after a power failure
                logger -t "   $(basename $0)" "Script NOT executed with parameters [$1 $2]: Dual WAN is enabled, but standard rules are missing!!!" $wancodes
            fi

        else
            # Exits and presumes that another wan-event script will run later, when Dual WAN is ready (both modems fully connected). This can happen on a router reboot or after a power failure
            logger -t "   $(basename $0)" "Script NOT executed with parameters [$1 $2]: Dual WAN connections are not ready!!!" $wancodes
        fi

    else
        # Exits as Dual WAN was initially enabled but changed to disabled sometime during the execution of the script
        logger -t "   $(basename $0)" "Script NOT executed with parameters [$1 $2]: Dual WAN is no longer enabled!!!" $wancodes
    fi

fi
 
  • Like
Reactions: N/A

FernandoF

Occasional Visitor
To complement my previous post, I'd recommend that you play with manually adding/deleting priority 90 ip rules over SSH to get acquainted with how those interact with the standard priority 100 rules. Please just keep in mind ip rules are automatically rebuilt whenever there's a relevant change to the WAN connections, which means your manual rules will be deleted.

Once you're happy with the results, then you can proceed to automate and make your priority 90 rules persistent by using a wan-event script similar to the one above. That will ensure your custom Dual WAN rules are also rebuilt along with the standard Dual WAN rules.

I hope this helps!
 
Last edited:

gorstj

Occasional Visitor
When doing requests from the router itself the alternate between going from Primary and Secondary WAN

This is problematic if you only want to use secondary WAN for specific things.

e.g. run the following command and the IP address will alternative roughly 1:1 (if you have load balance 1:1 on)

curl icanhazip.com

I have tried adding a rule for my routers IP (192.168.1.1) to only go via the Primary WAN.
Do I need to add 127.0.0.1 ?

I am only wanting to use the Secondary WAN for one device on my network.

Would it be better to use failover and add IP rules for all IP addresses to use Primary WAN (and then add a higher priority rule for the single IP address to use Secondary WAN?)
 

gorstj

Occasional Visitor
When doing requests from the router itself the alternate between going from Primary and Secondary WAN

This is problematic if you only want to use secondary WAN for specific things.

e.g. run the following command and the IP address will alternative roughly 1:1 (if you have load balance 1:1 on)

curl icanhazip.com

I have tried adding a rule for my routers IP (192.168.1.1) to only go via the Primary WAN.
Do I need to add 127.0.0.1 ?

I am only wanting to use the Secondary WAN for one device on my network.

Would it be better to use failover and add IP rules for all IP addresses to use Primary WAN (and then add a higher priority rule for the single IP address to use Secondary WAN?)

I have figured out how to stop the router using Secondary Wan.


Code:
ip route
default
        nexthop via Wan1-Gateway dev ppp0 weight 9
        nexthop via Wan2-Gateway dev eth0 weight 1

If I delete the default route and just add the Wan1-agteway PPP0 route back then Wan2 is never used (except for IP addresses told to explicitly use that link in the GUI)

What I don't have the knowhow is how to script deleting eth0 from the routing table?

I think I need to delete the default route (ip route del default)
Then I need to re-create the default route using the ppp0 interface/gateway.
But I don't know how to script this and at what point to initiate it.

Any ideas?
 

gorstj

Occasional Visitor
I have figured out how to stop the router using Secondary Wan.


Code:
ip route
default
        nexthop via Wan1-Gateway dev ppp0 weight 9
        nexthop via Wan2-Gateway dev eth0 weight 1

If I delete the default route and just add the Wan1-agteway PPP0 route back then Wan2 is never used (except for IP addresses told to explicitly use that link in the GUI)

What I don't have the knowhow is how to script deleting eth0 from the routing table?

I think I need to delete the default route (ip route del default)
Then I need to re-create the default route using the ppp0 interface/gateway.
But I don't know how to script this and at what point to initiate it.

Any ideas?

If anyone else is looking for a solution to disabling the secondary WAN default connection in load balancing mode here is the script I have put in /jffs/script/wan-event

It means no traffic goes via secondary WAN except if an IP address rule is explicitly set in the load balancing routing rules GUI

You will need to ensure wan0_gateway is the route you want to keep and that it is on ppp0 (it could be on eth0 if it is not a PPPoE)

Code:
#!/bin/sh

# Checks whether Dual WAN is enabled (at least initially)
if [ "$(nvram get wan0_enable)" = "1" ] && [ "$(nvram get wan1_enable)" = "1" ]; then

    # Pauses to wait for the WAN connections to be fully established
    sleep 10

        ip route del default
        ip route add default via $(nvram get wan0_gateway) dev ppp0

    logger -t "   $(basename $0)" "wan-event script completed - secondary WAN routes deleted"
fi

An upgrade could be to change 'ppp0' to '$(nvram get wan0_gw_ifname)'

Very new to scripts so any corrections or suggestions gladly accepted
(I note it runs multiple times on disabling/enabling the secondary WAN connection and haven't fully checked it in all fault conditions e.g. wan0 disconnect/re-connect)
 

Ranger802004

Senior Member
I have figured out how to stop the router using Secondary Wan.


Code:
ip route
default
        nexthop via Wan1-Gateway dev ppp0 weight 9
        nexthop via Wan2-Gateway dev eth0 weight 1

If I delete the default route and just add the Wan1-agteway PPP0 route back then Wan2 is never used (except for IP addresses told to explicitly use that link in the GUI)

What I don't have the knowhow is how to script deleting eth0 from the routing table?

I think I need to delete the default route (ip route del default)
Then I need to re-create the default route using the ppp0 interface/gateway.
But I don't know how to script this and at what point to initiate it.

Any ideas?
See my reply in this thread, in my script there is a command that will help you in particular.

These 2 commands will create default route based on WAN 0 or WAN 1.

Code:
ip route add default via $(nvram get wan1_gateway) dev $(nvram get wan1_ifname)

ip route add default via $(nvram get wan0_gateway) dev $(nvram get wan0_ifname)
 

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top