Splitting international and local traffic on a Linksys WRT54G

Gatecrasher

Executive Member
Joined
Jan 11, 2005
Messages
6,278
#1
Splitting international and local traffic with DD-WRT

Had to abandon Route Sentry. It was running on my machine with DDProxy which was acting as a proxy for my home network.

It did the basic stuff fine, but email (with large attachments), ftp, and most web based apps that required open ports on the firewall caused endless hassles. There was also the drawback of the internet going down whenever I rebooted or switched off my pc.

Looking for an alternative I figured I would rather set up traffic splitting with IPCOP on an old PC. But unfortunately (or fortunately) after putting an old box together I found that the graphics card was shot.

Having read this thread though I twigged that my Linksys WRT54GS router also runs under linux and the broad methodology in the thread could possibly be applied to the router.

Many thanks to contributers of the IPcop thread and particularly Bernie for the scripts and ArminM for providing the local routes.

So after endless messing about with the script it finally works. And is totally transparent to the entire network. With minimum maintenance too. Heaven, really.

I have a Linksys WRT54GS v4 with HyperWRT Thibor 15c firmware. The firmware allows for a non-volatile startup script. Very handy for the job in hand. I use this script to create another executable script in the volatile /tmp folder on boot up. This script runs every two minutes to check that the local pppoe connection is running. If necessary it will connect the local connection and create the necessary routing table entries.

Just set the router to dial a pppoe connection to your international account. Go to the routers Web GUI under Administration, Management. Edit Start Up Script. Then paste and copy the following script into the editor. Edit the username and password for your local account. Save the script. Reboot. And after several minutes you'll be enjoying a more cost effective internet experience.

That's all there is too it, really.

If you are using a later version of the WRT54G/S you may struggle getting 3rd party firmware to work. If you are using different firmware the script may still be useful to you, but program paths will possibly require editing.

I particularly like the HyperWRT Thibor firmware because it is incredibly clean and stable. My router can run for months without a reboot.

Here is the script. Remember to provide your MyUserName and MyPassWord for your local only account.

Code:
echo "INTS=`/sbin/ifconfig|grep ppp0|awk '{print $1}'`
   echo "INTS=" >> /tmp/splitlog 
      LOCS=`/sbin/ifconfig|grep ppp1|awk '{print $1}'`
   echo "LOCS=" >> /tmp/splitlog
if [ "" == "ppp0" ]; then
   if [ "" != "ppp1" ]; then
     /usr/sbin/pppd pty '/usr/sbin/pppoecd vlan1 -u MyUserName -p MyPassWord -i 0 -I 30 -T 5 -t 1492 -k' noipdefault nodefaultroute ipcp-accept-local ipcp-accept-remote passive noccp nopcomp novjccomp lcp-echo-interval 20 lcp-echo-failure 3 lcp-max-configure 50 maxfail 5
     sleep 15
     LOCUP=`/sbin/ifconfig|grep ppp1|awk '{print $1}'`
      if [ "" == "ppp1" ]; then
         echo "Local connect succeeded. Routing..." >> /tmp/splitlog
         /usr/bin/wget http://alm.za.net/ip/localroutes4.txt -O /tmp/localroutes4.txt
         for IP in `cat /tmp/localroutes4.txt | awk '{print $4}'`
         do
             /sbin/route add -net  ppp1
         done
         /sbin/route add default dev ppp0 metric 0
         sleep 2
         /usr/sbin/iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE
         sleep 2
      else
         echo "Local connect failed" >> /tmp/splitlog
      fi
   fi
fi" > /tmp/splitter
chmod +x /tmp/splitter
echo "*/2 * * * * root /tmp/splitter" > /tmp/cron.d/check_split
I'm a complete Linux noob. The code could certainly be improved and made more robust, so feel free.

However, I take no responsibility for your actions. Don't pin any bricked routers on me.

The following commands can be run in Hyperwrt's Web GUI "Run Command" screen (or I guess you could do the same via telnet/putty etc):

ifconfig {will show whether ppp0 (International) and ppp1 (Local) are connected and the amount of traffic that they have each generated since connecting.}

route -n {will show the routing table. If the script is working there should be a large number of entries directing traffic to ppp1.}

cat /tmp/splitlog {debugging generated by the script - at some point best to remove debugging from the script. Memory is capped, ie not unlimited.}

cat /tmp/localroutes4.txt {shows the downloaded routing table}

That's it. Have fun.

EDIT: Due to the unreliability of HyperWrt's pppoecd connections, I have since changed firmware to use rp-pppoe under DD-WRT. Script has been revised in later posts. Latest Version is here
 
Last edited:

Gatecrasher

Executive Member
Joined
Jan 11, 2005
Messages
6,278
#3
Will have to give this a try. Will it run on DD-WRT?
Probably, but you may have to make sure that the paths to the commands are consistant with the dd-wrt firmware.

I put paths to most of the commands since scripts executed by the cron on Hyperwrt seems to lose its environments paths. I don't why it does this, but it is something which caused me hours of bafflement when nothing I tried seemed to work.

I still have to work on the connection command since ppp1 often drops shortly after connecting with the result that it can sometimes takes several iterations of the script for everything to be working properly.

It might be that pppoecd needs to be replaced with another dialer, like rp-pppoe, but I haven't had time try that yet and rp-pppoe does not come with the firmware.
 

milomak

Honorary Master
Joined
May 23, 2007
Messages
12,016
#4
I take it the international connection is the one that is setup "normally" on the webgui and the local one is setup by the script.
 

Gatecrasher

Executive Member
Joined
Jan 11, 2005
Messages
6,278
#5
I take it the international connection is the one that is setup "normally" on the webgui and the local one is setup by the script.
Correct.

I have some good news and some bad news.

The bad news is that my solution above is just too hit and miss. And more often miss than hit. No matter what I did it would often not hold onto the second connection for more than a few seconds. The probable cause for this was that the discovery packets of the two connections were interfering with each other. And there was really no fix that that I could find using HyperWRT's pppoecd.

The good news is that I now have the process working perfectly with rock solid results on DD-WRT firmware with the rp-pppoe protocol. There are still some tweaks to the scrip required, but I will post it as soon as I'm happy with it.

The only drawback is that DD-WRT's pppoe default options are incompatible with multiple connections, so the startup script has to kill the default connection and its processes before it can set up the new connections. It uses the rp-pppoe host-unique tag which does allow for multiple connection daemons. Both international and local login details need to be included in the script, but the great thing is that it is now completely reliable.

I'm using DD-WRT Ver 23 SP2, and a recent discussion on the DD-WRT forum suggests that there may soon be a way in the firmware for the user to change the rp-pppoe default options.
 

CodeMaster

Expert Member
Joined
Dec 4, 2003
Messages
3,234
#6
That is really GREAT news. Glad to hear that you are trying to get it sorted on DD-WRT, my F/W of choice. It will be great to having the routing done by the router, then my Wi-Fi devices will be able to use my internet connection, and I won't need to setup RouteSentry on all the Pc's.

Please keep us up to date with your progress.
 

Gatecrasher

Executive Member
Joined
Jan 11, 2005
Messages
6,278
#7
There's much more I would like to do with this script, but I have no time to play around with it until the weekend at least.

For now, though, it does the job exceptionally well.

First it kills the default pppd daemon (because the default does not support multiple connections.) Then it sets up your international and local connections. Finally, it creates a script that monitors and establishes the local routing.

If either connection goes down the respective pppd daemon automatically brings it back up. The cron script detects whether the local routing is in place or not and reinstates it as necessary.

All you have to do is paste the script into the DD-WRT GUI's command shell, edit your user names and passwords and click "Save Startup".

And that's it.

Code:
sleep 5
killall pppd
sleep 2
killall redial
sleep 2
/usr/sbin/pppd pty '/usr/sbin/pppoe -U -I vlan1' noipdefault noauth defaultroute noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp nomppe nomppc usepeerdns user 'myIntUserName' password 'myIntPassWord' default-asyncmap mtu 1492 mru 1492 persist lcp-echo-interval 5 lcp-echo-failure 10 holdoff 60 unit 0
sleep 10
/usr/sbin/pppd pty '/usr/sbin/pppoe -U -I vlan1' noipdefault noauth nodefaultroute noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp nomppe nomppc user 'myLocUserName' password 'myLocPassword' default-asyncmap mtu 1492 mru 1492 persist lcp-echo-interval 5 lcp-echo-failure 10 holdoff 60 unit 1
sleep 10
echo "LOCS=\`/sbin/ifconfig|grep ppp1|awk '{print \$1}'\`
   if [ \"\$LOCS\" == \"ppp1\" ]; then
      LCRT =\`/sbin/route -n|grep '32.106.152.0'|awk '{print \$8}'\`  
      if [ \"\$LCRT\" != \"ppp1\" ]; then
        /usr/bin/wget http://alm.za.net/ip/localroutes4.txt -O /tmp/localroutes4.txt
        for IP in \`cat /tmp/localroutes4.txt | awk '{print \$4}'\`
        do
            /sbin/route add -net \$IP ppp1
        done
        /sbin/route add default dev ppp0 metric 0
        /sbin/route del default dev ppp1 metric 0
        sleep 2
        /usr/sbin/iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE
        sleep 2
      fi
   fi" >> /tmp/splitter
chmod +x /tmp/splitter
echo "*/2 * * * * root /tmp/splitter" > /tmp/cron.d/check_split
Good luck.
 

milomak

Honorary Master
Joined
May 23, 2007
Messages
12,016
#8
I wonder if that script might be a step to far for a WRT54Gv5 with DD-WRT micro. I'll give it a bash when I am not feeling lazy.
 

mancombseepgood

Executive Member
Joined
Jun 1, 2004
Messages
9,352
#9
Hi, I have just upgraded the stock fw on my Linksys WRT54GL 1.1 to DD-WRT 23 sp2 standard. All went well and the web interface is functioning nicely. I tried the startup script and it appears to work... I get the following from the ifconfig command:
ppp0 Link encap:point-to-Point Protocol
inet addr:41.195.76.48 P-t-P:41.195.76.1 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1492 Metric:1
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:130 (130.0 B) TX bytes:282 (282.0 B)
ppp1 Link encap:point-to-Point Protocol
inet addr:196.210.88.211 P-t-P:196.210.88.1 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1492 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:594 (594.0 B) TX bytes:30 (30.0 B)
However, there is no routing for some reason. I use DHCP and the router is the default gateway and DNS server... that much is working, beyond the router be dragons however... any help on what I am missing would be greatly appreciated.
Thanks
 

mancombseepgood

Executive Member
Joined
Jun 1, 2004
Messages
9,352
#10
Do I need my international PPPoE connection set up in the GUI? I had nothing there to start with (I think it may default to DHCP) and all is well (except of course that it wasn't routing!), for some reason though, when I put the PPPoE login details in, the router loses it's web interface and I can't ping it. Strange. I reset to default and started again, this time I setup PPPoE first using the GUI and no go - still can't get in after a reboot. I will try recycling the power...

UPDATE: OK, got it working... dunno what it means, but this time I put the "Use RP PPPoE" to Enable. I am now connecting fine using the router and my international account... about to try the script thingy.
 
Last edited:

mancombseepgood

Executive Member
Joined
Jun 1, 2004
Messages
9,352
#11
OK!
It appears to be sorted. This is what I did (starting at the top):
I have Linksys WRT55GL 1.1

1) I downloaded the mini generic dd-wrt as well as dd-wrt 23 SP2
2) I flashed with the mini generic firmware using the standard linksys web interface
3) I flashed using the standard generic v23 SP2 firmware using the new dd-wrt web interface
4) I reset the router using the reset button at the back (I didn't pull the power).
5) I set up the standard PPPoE connection with my international login details and set the "Use RP PPPoE" to Enable (whatever that's for).
6) I went to the Admin - command page and entered the script above, substituting the login details for the local and international with my own local and intl. account details.

That's it.

Initially I had speed issues with this site, although I'm not convinced it was related - it may just have been that IS or Myadsl were experiencing problems... so far it works like a charm...

THANK YOU Gatecrasher!

p.s. I see the startup script is set to d/l the latest routing details from http://alm.za.net/ip/localroutes4.txt
I assume there is no reason routing should fail should this site be unavailable at startup?
What if the d/l is half way through and conks out?
Just wondering if it may be better to d/l to a temp file, then if success copy over the original...
Anyway, thanks again!
 
Last edited:

Gatecrasher

Executive Member
Joined
Jan 11, 2005
Messages
6,278
#12
Hi Groundnut,

Yes, you have to enter the default pppoe details and set to use rp-pppoe

I've made a few enhancements to the script since I posted above. I'll post my latest when I get home this evening.

There is an issue sometimes when the default routing makes the localroutes site invisible, and you end up with an empty file.

Also there is an issue with upnp and port forwards, which work on the assumption that ppp1 (the last pppd process) is your default route. So p2p apps report a firewall, and perform poorly.

But the latest script sorts all this out and make everything much more robust.... and faster.
 

Gatecrasher

Executive Member
Joined
Jan 11, 2005
Messages
6,278
#14
The username(s) and password(s) are now accessed from nvram, i.e. they are set to the pppoe username and password that you supply in the GUI.

You should have "keep alive" set to an appropriate redial period, say 30 secs. You must have RP PPPoE set.

When you want to split international and local, enter both usernames separated by a space, ie: [int@myisp loc@myotherisp ]
Do the same the with the passwords (it helps to unmask while editing). Enter international first, local last.

This makes things much more user friendly. Sometimes you wont want to split the traffic, so you can just enter a single name and password and the startup script is bypassed on reboot.

So once the script is entered it should never have to be removed or edited.

To overcome the default wan being set to the last activated pppoe connection (and the knock on problems with the firewall, port forwarding and upnp), ppp0 is now set to local, and ppp1 to international.

If grabbing the local route file fails, it will retry with each cron iteration.

Code:
#!/bin/sh
user0=`nvram get pppoe_username|awk '{ print $2 }'`
if [ "$user0" != "" ]; then
   user1=`nvram get pppoe_username|awk '{ print $1 }'` 
   pass0=`nvram get pppoe_passwd|awk '{ print $2 }'`
   pass1=`nvram get pppoe_passwd|awk '{ print $1 }'`
   sleep 5
   killall pppd
   killall redial
   sleep 5
   /usr/sbin/pppd pty '/usr/sbin/pppoe -U -I vlan1' noipdefault noauth nodefaultroute noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp nomppe nomppc usepeerdns user $user0 password $pass0 default-asyncmap mtu 1492 mru 1492 persist lcp-echo-interval 5 lcp-echo-failure 10 holdoff 30 unit 0
   sleep 5
   /usr/sbin/pppd pty '/usr/sbin/pppoe -U -I vlan1' noipdefault noauth defaultroute noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp nomppe nomppc usepeerdns user $user1 password $pass1 default-asyncmap mtu 1492 mru 1492 persist lcp-echo-interval 5 lcp-echo-failure 10 holdoff 30 unit 1
   sleep 5
   echo "#!/bin/sh
   intppp=\`/sbin/ifconfig|grep ppp1|awk '{print \$1}'\`
   if [ \"\$intppp\" == \"ppp1\" ]; then
      locppp=\`/sbin/ifconfig|grep ppp0|awk '{print \$1}'\`
      if [ \"\$locppp\" == \"ppp0\" ]; then
         isrouted=\`/sbin/route -n|grep '196.26.0.0'|awk '{print \$8}'\`  
         if [ \"\$isrouted\" != \"ppp0\" ]; then
            /sbin/route add default dev ppp1 metric 0
            /sbin/route del default dev ppp0 metric 0
            if [ -f /tmp/localroutes4.txt ]; then
               isfound=\`cat /tmp/localroutes4.txt|grep '196.26.0.0/16'|awk '{print \$1}'\`
               if [ \"\$isfound\" != \"route\" ]; then
                  /usr/bin/wget http://alm.za.net/ip/localroutes4.txt -O /tmp/localroutes4.txt
               fi
            else
               /usr/bin/wget http://alm.za.net/ip/localroutes4.txt -O /tmp/localroutes4.txt   
            fi
            for IP in \`cat /tmp/localroutes4.txt | awk '{print \$4}'\`
            do
                /sbin/route add -net \$IP ppp0
            done
            /sbin/route add default dev ppp1 metric 0
            /sbin/route del default dev ppp0 metric 0
            /usr/sbin/iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE
         fi
      fi
   fi" > /tmp/splitter
   chmod +x /tmp/splitter
   echo "*/2 * * * * root /tmp/splitter" > /tmp/cron.d/check_split
   /tmp/splitter
fi
If you have any problems let me know.
 
Last edited:

mancombseepgood

Executive Member
Joined
Jun 1, 2004
Messages
9,352
#15
Hey Gatecrasher... thanks for the update!
It all seemed fine after rebooting, but it seems it's not routing properly. I d/l a file from ftp.is.co.za - 125 Mb and did an ifconfig to confirm but all that traffic went over international. Then I tried this:
cat /tmp/localroutes4.txt
And get nothing. I assume the file is missing / didn't download. Any suggestions?

UPDATE: I manually d/l the file to the router and all is well with routing...
Then after reboot, the file is missing again. It seems to possibly be an issue with timing... maybe we need a pause before the d/l of the file... after the first connect (or something).

I'll see if I can potter around with puttytel this morning some time...
I am sooo keen to get this working. Awesome solution!
 
Last edited:

Gatecrasher

Executive Member
Joined
Jan 11, 2005
Messages
6,278
#16
The reason for using the start-up script is that it is stored in non-volatile ram, so it will survive a reboot. Everything else is lost when the router reboots, until it is recreated by the start-up script.

You can experiment with incrasing the sleep times. I'm not currently having the same problem that you are having.

If the routes file is missing that fact should be picked up and the file should be downloaded during the cron, which runs every 2 minutes. I have a test to check that the file is not empty, maybe that part of the script isn't working as it should. Will check later.

Another solution would be to keep a copy of localroutes4.txt on your pc and have the script load that file instead. It may prove more reliable.

I'm thinkng of programming an LED on the router to show when the local routing is in place. Because at the moment it is quite messy to check that all is well.
 

mancombseepgood

Executive Member
Joined
Jun 1, 2004
Messages
9,352
#17
Another solution would be to keep a copy of localroutes4.txt on your pc and have the script load that file instead. It may prove more reliable.

I'm thinkng of programming an LED on the router to show when the local routing is in place. Because at the moment it is quite messy to check that all is well.
I love that last idea...

Is there any place to store the routes file elsewhere... in NVRAM? Maybe we can release our own dd-wrt image ;)
Just wondering in my noob mind.
Cheers
 
Last edited:

mancombseepgood

Executive Member
Joined
Jun 1, 2004
Messages
9,352
#19
You've done an awesome job! Anyways.. if I had time, I would add a dual login and routing page to the admin screens.... For those who want to configure it with the gui - specify a file name and server to d/l the tables from or have a manual list to be edited on screen (e.g. for those with shaped and unshaped accounts for gaming / browsing). I may look at this weekend... then again, I may not - time permitting! :D
 

mancombseepgood

Executive Member
Joined
Jun 1, 2004
Messages
9,352
#20
Hey Gatecrasher... I was wondering about that LED issue to check on both routes being up...
What about a tray app that polls the router for this info somehow... wonder how easy that would be... does the dd-wrt do FTP by default? Maybe a smb share mount on the local machine and push a small file to that share using cron on the router... then check for the presence of that file for the up or down status in the tray app. there are probably cleaner ways of doing it...
 
Top