I got annoyed at my cable modem being down between 8pm-10pm for a few days in a row, so I got a DSL connection. I wanted to setup both my DSL and cable in a way I could use them at the same time.
These connections both use regular DHCP, which gives me an IP, the DNS servers to use, and a default gateway. I started out by changing the interface setup script that DHCP calls to just apply the IP and ignore the DNS servers for the secondary broadband connection. With this setup, I can use one or the other by changing where my routing table sends my packets. By changing the DHCP script to add the default route to a second routing table, and using policy routing to switch between routing tables, I can have both connections active at the same time. But the problem with that not many applications support choosing the source IP (which is what the policy uses to determine what routing table to use).
One way to do this is to force applications to use a specific IP by messing with the libraries it calls, or through a kernel interface.
Another choice is to have different machines handle the two connections. So I created a virtual machine in qemu-kvm and gave it a virtual network interface. The virtual network interface hands off ethernet packets to the kernel via a tap interface. I then took the physical interface, put it into a bridge group with brctl, and added the virtual interface to the bridge group. My qemu-kvm command line looked like:
qemu-kvm -net nic,vlan=0,macaddr=00:16:3e:76:ab:4a -net tap,vlan=0,ifname=cable0,script=/etc/qemu-ifup.eth1 -hda /root/vm/cable.disk -boot c -m 384
and /etc/qemu-ifup.eth1 (eth1 being the bridge group and peth1 being the physical interface):
#!/bin/sh
/sbin/ifconfig $1 0.0.0.0 promisc up
/usr/sbin/brctl addif eth1 $1
The real machine only had the DSL connection up, and with this setup I was able to bring up the virtual machine and do a network install of Fedora 7 off the cable connection. So the next thing I wanted to do was connect the virtual machine to my home network. I tried adding a second virtual network card (-net nic...) and kernel tap connection (-net tap...). This showed up properly, except the MAC addresses were the same between both cards and the first interface would never receive any packets, and it would discard anything transmitted. So I tried using 802.1q tagging, but there seems to be something wrong with using 802.1q and tap. I went looking on the net, and found someone who had a similar virtual machine setup, so I know this has to work somehow. I found someone else using a parameter to change the type of virtual network card. I try that out, and it works. Apparently using more than one virtual network card of a specific type fails because of sub-page sized IO resources (which the developers of qemu already know about and fixed in a development version). So now my startup command looks like:
#!/bin/sh
NET1="-net nic,vlan=0,macaddr=00:16:3e:76:ab:4a,model=ne2k_pci -net tap,vlan=0,ifname=cable0,script=/etc/qemu-ifup.eth1"
NET2="-net nic,vlan=1,macaddr=00:16:3e:76:ab:4b,model=ne2k_pci -net tap,vlan=1,ifname=cable1,script=/etc/qemu-ifup.eth2"
qemu-kvm $NET1 $NET2 -hda /root/vm/cable.disk -boot c -m 384
So now if I run things on my virtual machine, they use the cablemodem and if I run things on my real machine they use DSL. The machines on my home LAN are all routed through the DSL connection.
Next step is to make it so that I can change where the machines on the LAN go manually. I setup an IP alias on the real machine, change my local DHCP server to hand out that IP alias as the default gateway and DNS resolver. So now all I have to do is move that alias from the real machine to the virtual to change where the LAN goes.
Next is to make it so I can easily switch connections my web browser uses. So I setup a socks 5 proxy on the virtual machine (package name ss5). I then downloaded the FoxyProxy addon to mozilla, and created a "dsl" profile with no proxy, and a "cable" profile with the virtual machine as the proxy. Then I can switch between profiles with a click (or define rules to have it automatically choose). I tested this all out by downloading one file, switching the proxy, and downloading another. The DSL file capped out at 600k/s and the cable file capped at 800k/s.
ss5.conf:
auth 10.1.2.0/24 - -
permit - 10.1.2.0/24 - 0.0.0.0/0 - - - -