Years ago, I built a script that used a patched version of miitool and would watch for the presence or absence of link-beat on the wired connection on my laptop to detect when an Ethernet cable was plugged into it. It would re-configure the network when this happened such that my packets would go out over either the wired network (very fast) or the wireless (very portable). It's nice to be able to just plug in the network cable and within a few seconds be getting 100mbps performance.
I used that for about 6 months, once in a while I would make use of it when copying large file if I was by an Ethernet cable. Then I did an upgrade and just didn't bother to re-install it. About a year ago, I thought it would be neat if I could use bridging of the wired and wireless network interfaces to accomplish the same thing, but bridging with a wireless interface has some issues unless you are in access point mode.
Tonight I realized that what I really wanted was to use (or some may say abuse) the bonding driver. It was only a few months ago that I found out how useful the bonding driver is. For years I was under the mistaken impression that it was for bonding low-speed serial devices. More recently I found it can be used for all sorts of useful high availability and bandwidth increasing uses.
Tonight I decided to see if it was flexible enough to be used for setting up the wired and wireless interfaces such that the system would prefer the wired interface if available, but would seamlessly switch to wireless when wired was not available.
The short answer is that it definitely is. The magic is in using active-backup mode and specifying a primary interface. In other words, with DHCP shut down and both interfaces up but without IP addresses, you set up a bonding interface with eth0 and eth1 enslaved using:
modprobe bonding arp_interval=300 arp_ip_target=<router IP address> mode=active-backup primary=eth0 ifenslave bond0 eth0 ifenslave bond0 eth1
Now you can use the bond0 interface just as you would have used the regular interface. Perhaps you want to set up an IP address using “ifconfig” or get a dynamic address via dhclient. These both should work.
The bonding driver configuration above requests that the system send out ARP packets 3 times a second to determine if the router is available. Yes, this generates some traffic on the interface at all times. One could increase this if a quick transition is less important to you than a few hundred bytes per second. It also specifies that whenever eth0 is up, it should be used. eth1 will only be used when eth0 is unavailable.
With this setup it's possible to start a copy and plug in the wired interface. With 0 packet loss, it will seamlessly convert over to using the wired network link. You can pull the wired interface and within some time period around what “arp_interval” is set to the traffic will switch to the wireless interface. This does experience some packet loss, because the Ethernet interface is down until the fail-over occurs. Luckily, TCP/IP can deal with this. In my testing at 300ms, copies didn't have any problems at all, not even a hiccup.
My previous setup where I'd detect the plugin of the Ethernet using a daemon which then ran a script was a bit ham-handed, but did work. It would result in 10 to 20 seconds of network down-time while the traffic was switched to the other interface and things figured out that the MAC address had changed, etc. I don't recall if I pushed out a promiscuous ARP or not.
The bonding driver wins hands down for this use though. I've now included it as a standard part of my network startup scripts when it detects I'm at home.comments powered by Disqus