I thought the last part would actually be my last part. But shortly after I wrote up the initial draft of my complete Adventures with DD-WRT, I encountered an application that was having trouble with the UPnP/NAT-PMP that I had set up. Strangely, this particular application worked with the built-in UPnP of DD-WRT, but failed with my MiniUPnP bypass. I didn't really believe that MiniUPnP was the problem because both NAT-PMP and UPnP would have to fail separately. More likely that this app was doing something different than my other apps and there was a flaw in my iptables rules.
So this became the straw that broke the camel's back. I actually did come up with a workaround that used MiniUPnP for NAT-PMP and then used the built-in UPnP as the fallback. But I didn't really like this solution, so I decided I would abandon DD-WRT and try Tomato. I found various statements and documentation claiming that switching is easy. Well, they were right. It was very easy.
I encountered different guides on how to switch, but my favorite was this one. I like it because it is pretty short. Living dangerously, I actually skipped the first 4 steps myself.
The most important step is Step 5: Run nvram get http_passwd
to retrieve the password for Tomato. Do not forget to do this step before flashing your router. DD-WRT's password storage scheme is different than Tomato's. You need to run this to get the password that Tomato expects so you can log into the device. Write this password down. (If you forget, don't worry. You can always do a 30-30-30 hard reset which will reset Tomato back to its default settings including its default login and password.)
Choosing a Firmware
Other than that, it was a straight-foward process of downloading the Tomato firmware and using DD-WRT's firmware upgrade tool in the web gui to flash the router. For my Asus WL-520gU, a variation of Tomato called TomatoUSB seems to be the best option. As implied by the name, this variation has USB support which I need for my USB flash drive.
TomatoUSB actually has 6 variations itself: standard, extras, lite, no CIFS, VPN, and no USB. These are pretty well described on the linked page. Unlike DD-WRT, I didn't feel lost and overwhelmed by having too many choices. TomatoUSB also comes in Linux 2.4 and 2.6 variations, but my device isn't supported in the 2.6 flavor which makes things simpler.
I chose the VPN version because I am curious about setting OpenVPN up some day. I was pleasantly surprised to see they had an OpenVPN variation, and that it would fit on my 4MB router. DD-WRT didn't seem to have a variation that would give me both USB and OpenVPN and I figured I would have to resort to Optware. There will be no JFFS space for me using this variation, but since I've already established that Optware is too big for me to fit on the device and I need external storage anyway, it doesn't seem like a big loss any more. In addition, Tomato has explicit startup/shutdown/firewall/wanup script access in the web GUI, so I no longer will need to write these scripts directly on the local file system.
And while on the subject of Tomato features and variations, while there seem to be fewer than DD-WRT, I didn't feel overly frustrated that a variation was left out. I like the trade-offs Tomato (or more precisely, TomatoUSB) made much more than DD-WRT. Tomato seemed to cram in a lot more useful things into a 4MB footprint than DD-WRT and I didn't feel like I was giving up something of near equal importance. (In fact, I didn't really feel like I was giving up anything.) I think home users and small businesses (not running public access points) will find the Tomato feature set more more useful and sensible. DD-WRT makes me scratch my head in puzzlement. I can only assume that DD-WRT's paying client base is a very different demographic.
First Impressions
The very first thing I notice is that Tomato feels very fast and snappy. Page load times are usually about a second, whereas DD-WRT was several seconds.
The second thing I noticed is that all my configuration options that I set in DD-WRT like IP address, DHCP range, wireless settings, etc. continued to be properly set in Tomato. That was kind of a pleasant surprise. However, given previous bad experiences where tools seem to work but are actually silently failing (like ipkg force-overwrite), I decided to erase all the settings and reconfigure from scratch anyway.
Tomato's organization is different than DD-WRT's. I'm not sure which I actually like more. DD-WRT uses tabs more heavily which gives an extra dimension to navigate the settings matrix. While this can sometimes obscure options, when used appropriately, this can help keep logical groups together and make things in fact easier to find. Tomato uses tabs in a few places like the initialization scripts page and the OpenVPN page, but for the most part, they use vertical space to list more options.
Tomato has pretty graphs that get a lot of acclaim from users. I haven't used them enough to really know if they will be helpful to me. But they are pretty.
Unlike DD-WRT, Tomato includes https as an option in all the firmwares. (Yea.) But I did come across a bug where after enabling http, https, telnet, and ssh, if you tried to log into telnet or ssh, the login attempts would hang. When I disabled https again or disabled telnet instead, the problem went away. I would like to see automatic http to https redirection as a future option. (Ruckus has this option and I find it really convenient.)
No surprise here since this is why I switched, but Tomato includes MiniUPnP and a GUI interface to it. So for the common options, I no longer need to manually tweak the .conf file. And yes, the built-in MiniUPnP had no problems with that one particular application so I do believe my problem in DD-WRT was likely the firewall rules.
Tomato includes an FTP and Samba server in my firmware. I probably won't be using these, but I do see the mass appeal of these features and understand why they are included. This is in contrast to my DD-WRT firmware which lacked both of these. (Though in fairness, DD-WRT does have a mini-usb-ftp variant.)
The Tomato firmware also seems to provide me FAT, NTFS, ext3, and ext2 support. I thought DD-WRT was very confusing how they omitted different ones depending on which firmware you used. Tomato managed to get all of them in the firmware which is very convenient.
I keep seeing a lot of acclaim for Tomato's QoS feature. I haven't tried it, but it does look interesting.
I can't find a CPU load monitor in Tomato like in DD-WRT. I thought I read that Tomato has one, but I can't find it. But it's not a big deal to me since I can run top on the command line.
Migrating Optware and Avahi (Zeroconf) to Tomato
I've already done a ton of work to setup Optware and Avahi in DD-WRT. It would be nice to have this in Tomato. And it would be nice to not have to start from scratch. So good news...I was able to migrate everything already on my USB flash drive to work with Tomato.
A few changes are needed. First, Tomato automounts the partition to /tmp/mnt/ddwrt for me and there doesn't seem to be a way to specify /opt as the mount point through the web gui. This will have to be changed by providing a script to the Scripts portion of the web gui.
In the Init script, we will do two things. First we will change the mount point for the partition to go to /opt since I assume many things in Optware are going to assume this location. (Plus my scripts also assume this location.) Second, we will run the same initialization code that we introduced in Part 5 to start up all the S* scripts in /opt/etc/init.d. This will start up Avahi so we can get our Zeroconf services. The script is as follows:
#!/bin/sh # Need to wait for file system, USB, automounter to come online first so wait for some period. sleep 6 # Remount to /opt because Tomato doesn't automount there umount -f /tmp/mnt/ddwrt mount -r -o noatime,nodev -t ext3 /dev/discs/disc0/part1 /opt sleep 1 # note that /tmp/etc seems to go directly to /etc echo "netdev:x:1:" >> /tmp/etc/group echo "avahi:x:2:" >> /tmp/etc/group echo "avahi:x:2:2:avahi daemon:/opt/sbin/avahi-daemon:/bin/false" >> /tmp/etc/passwd for f in /opt/etc/init.d/S* ; do [ -x $f ] && $f start done
An important hack to notice is that I add a sleep at the top of the script before changing the mount point. It appears that the Init script will be run as other processes are still booting up. So if you try remounting the partition too early, the operation has no effect because nothing has been mounted yet. The workaround seems to be to sleep for at least 5 seconds (determined experimentally). I made it 6 seconds just to be extra paranoid. I also added another 1 second sleep after the partition has been mounted for extra paranoia, though I don't think this is necessary. (And again, remember to only invoke the read-only switch after we are completely done making changes.)
In Tomato, the device name has changed from DD-WRT. So other people migrating from DD-WRT, take notice that the device is different and you will need to adjust your script to reflect the device name on your router. For me it is /dev/discs/disc0/part1.
The remaining code is just a straight copy from the startup code in Part 5. I'm not sure if the user and group stuff is completely correct, due to another fact I will mention shortly, but it seems to work well enough.
No Avahi Runaway CPU Problem
Now those who read my Part 5 may remember the Avahi runaway CPU problem. Another really pleasing fact I discovered with Tomato is that the Avahi runaway CPU problem on DD-WRT doesn't occur here. So no more ugly hacks to kill and restart Avahi in the wanup script are needed. This is another big win for Tomato.
Fixes to the Optware Scripts
So next, we need to make a few changes to the scripts on the file system. For convenience in this article, I will refer to locations using the /opt mount point even though you may have not rebooted the router yet. You will need to adjust the mount point to where it actually is on your system (/tmp/mnt/ddwrt on mine). The first thing I did was to make sure that /opt/var map to /tmp/var with a symlink like we did in Part 5.
Second, the S20dbus script in /opt/etc/init.d needs two lines removed.
# chown $DAEMONUSER $PIDDIR # chgrp $DAEMONUSER $PIDDIR
It seems that chown and chgrp are not available in Tomato. So the script fails if these lines are in the script. I just commented them out and things seem to work. But it makes me think that the user and group stuff might now be meaningless in the Init script a little earlier above. But I didn't see Tomato complaining so I left it alone.
Finally, as a cosmetic fix, in the /opt/etc/avahi/services files, I also replaced all the text I had that said DD-WRT with Tomato.
So now if you restart the router, Zeroconf should just work using all the Optware stuff we had setup before.
Conclusions
Avahi works better on Tomato than DD-WRT. MiniUPnP is built-in on Tomato and just works and I get NAT-PMP as an option. The web gui for scripts is much nicer than dealing with startup scripts on JFFS. I get https and all the mainstream partition types with Tomato. I can get OpenVPN in the firmware for my 4MB router. Samba is also an available built-in option. Tomato's user response time is much faster than DD-WRT.
I would say that Tomato is a huge win for me over DD-WRT. No contest.
In addition, it looks like compiling things yourself is easier with Tomato than DD-WRT. I've read about DD-WRT having a multi-gigabyte SVN download you have to do which is kind of a deterrent.
I think DD-WRT still wins in documentation and online forum, but I suppose Tomato is simple enough that the community hasn't put priority in these things. And Tomato only supports Broadcom based chipsets.
But I think for most users, Tomato is the better choice.
Future Directions
Like I said in my previous parts, I would still be interested to see Avahi and Bonjour compiled directly for the firmware to remove the Optware dependencies and make Zeroconf a built-in feature. And I would really interested in seeing if Bonjour Sleep Proxy works.
Links:
Part 1: Introduction (The Beginning)
Part 9: Conclusions (Previous Part)