LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General > LinuxQuestions.org Member Success Stories
User Name
Password
LinuxQuestions.org Member Success Stories Just spent four hours configuring your favorite program? Just figured out a Linux problem that has been stumping you for months?
Post your Linux Success Stories here.

Notices

Reply
 
Search this Thread
Old 10-23-2008, 07:48 PM   #1
jonaskoelker
Senior Member
 
Registered: Jul 2004
Location: Denmark
Distribution: Ubuntu, Debian
Posts: 1,524

Rep: Reputation: 46
NIC bonding between eth0 and wifi


Hi all.

Here's a success story, mixed with my theory of why what I did works.

My underlying philosophy to computers is that if the hardware makes it physically possible and reasonably feasible, it should be easy to do. If two machines are networked, I want to plug my joystick into one and use it on the other (damn laptops don't come with joystick ports these days). And I want to use the keyboard and mouse too (synergy does 33% of what I want, which is what I do 95% of the time).

This story is not about peripherals though, but one of networking itself. My laptop, as most laptops, has an ethernet card and a wireless interface. What I want is that whenever the cable is in, my laptop uses that (since it's faster). Whenever I unplug, it seamlessly switches to using the wireless.

Seamlessly here means that nothing except my laptop and my AP/switch sees any difference; in particular, I'm still reachable at the same IP address(es) and no TCP connections are closed. In terms of applications, any files I'm wget'ing will keep on coming down, my ssh and sshfs connection won't close and I can continue watching that youtube video of cute cats eating cheezburgr.

How might we go about that? The quick-and-dirty idea is to configure the two interfaces to have the same IP address. That's fairly easy; you edit /etc/network/interfaces (I'm on ubuntu) to make eth0 manually configured, grab an IP address for eth1 with your favorite dhcp client (network manager does this for you). Then you ifconfig eth0 {the-address-of-eth1}. That'll kinda' sorta' work. You probably need to write a shell script that detects the plugging and unplugging of cables, and invoke `ip route' just the right way when it happens to switch from using one interface to the other.

But there's this cute thing called arp that routers use to know the connection between mac addresses and ip addresses, such that it knows on which port it should send its traffic to reach the right box. If I start announcing "69.555.123.45 is at 00:13:37:d0:0d:00" and "69.555.123.45 is at 00:ca:fe:ba:be:00", the poor router will get mightily confused. Okay, so could one work around this with macchanger? Yeah, maybe, but you still need the homegrown script, and there's an easier solution to that. Also, not all NICs can change their mac address.

Besides, I'm no hardcore networking expert. I've read the IP, TCP and UDP RFCs (somewhat cursorily) and kinda' grok the ascii packet diagrams, but I've never implemented any networking code more complicated than {create socket, listen, put the client socket on a list, do a select call every now and then, do something to the data}. I'd trust the people who write networking stacks to know more about the lower levels of networking stacks than I do (and I really like networking).

Which leads to... the "bonding" kernel module. We can do away with the homegrown ip-route-invoking script and not worry about changing mac addresses, because all the smart people have already thought about that for us

What the module does is create an interface, bond0, that you can enslave other interfaces to, meaning that data routed to bond0 will be sent via one of the those devices. The bond0 device has an IP address, not the slave devices. How does it choose which slave interface to use? There are six different policies you can choose from, depending on whether you want high availability (AKA instant failover) or more bandwidth, based on an assumption of satisfactorily high availability as is.

For today's scenario, we want high availability. Sure, we might want to do something really fancy and use both interfaces at the same time, but by the figures I did the math on, you can at most increase your bandwidth by 5% by also using the wireless NIC when the cable is plugged in. So we choose to just have the box automatically switch to using eth1 when eth0 becomes down.

And here's how you do it: add to /etc/modules a line saying "bonding mode=active-backup miimon=100 primary=eth0"

If you use WPA to encrypt, you need to run wpa_supplicant to authenticate with the access point (network manager does this for you). But the nasty trick is this: when you do that, you need to use the mac address of the interface you want to authenticate with. That means you either have to unplug eth0 when you do it, or write a little script. But you need to reauthenticate every so often, and I know me: I couldn't remember to unplug and replug eth0 every n minutes, and I don't want to do that. So script it is.

It's actually not so bad, as wpa_supplicant has a command-line interface that lets you talk to it. Here it is, in its full glory; for future reference, I've chosen to store it in /root/wpa_bonding_supplicant.

Code:
#!/bin/sh
cd /
bond=/sys/class/net/bond0/bonding/
while sleep 1s; do
	pgrep wpa_supplicant > /dev/null || exit
	wpa_cli status | grep -q 'COMPLETED'
	primary=eth$?
	echo $primary | diff - $bond/active_slave > /dev/null || \
		echo $primary > $bond/primary
done
It checks whether we have completed the authentication with the AP. If so, it says to the bonding module "please use eth0 if possible"; otherwise, "please use eth1 if possible". That way, you only use eth1 when you authenticate or when eth0 is unplugged.

What's left is putting all this into motion. Here's the bond0 stanza from my /etc/network/interfaces:
Code:
noauto bond0
iface bond0 inet dhcp
	pre-up ifconfig bond0 up
	pre-up ifenslave bond0 eth0 eth1
	pre-up wpa_supplicant -i eth1 -b bond0 -c /root/wpa.conf &
	pre-up /root/wpa_bonding_supplicant &
	down wpa_cli terminate
	down pkill wpa_bonding
	post-down ifconfig bond0 up
	post-down ifenslave -d bond0 eth0 eth1
	post-down ifconfig bond0 down
I've forgotten exactly what "-b bond0" makes wpa_supplicant do differently, but I seem to recall that it makes wpa_supplicant talk to the AP over bond0 instead of eth1, meaning you use the IP and mac address of bond0 (which is kind of important).

I've put this as "noauto" beacuse I don't trust my own code (a sign that I was born to be a sysadmin ). You can put it as auto if you like, but be sure to have stanzas for eth0 and eth1 that say "manual" instead of "dhcp"; only this, and nothing more.

And there you go. Boot up. Become root. Run "ifup bond0". Start a long-lasting connection (download a big file, or ssh into one of your other machines). Plug and unplug the cable. Observe how the physically possible actually happens. And that, boy and girls, concludes today's lesson

Happy hacking.


[should this not work for you, please create a new thread instead of replying to this one; it probably belongs in Linux - Networking. Feel free to post a link to it here, though, and we can all look at it]
 
Old 10-29-2008, 08:58 AM   #2
harry2006
Member
 
Registered: Aug 2006
Location: /hawaii/honolulu/downtown
Distribution: Fedora 10[Cambridge] and Ubuntu 9.04[Jaunty]
Posts: 201

Rep: Reputation: 30
thank you very much for this tut of nice/cool way of doing things that looks a bit difficult in the first place!
 
Old 11-02-2008, 04:32 PM   #3
olly_cat
LQ Newbie
 
Registered: Nov 2008
Location: Saint-Petersburg
Posts: 1

Rep: Reputation: 0
You can try ifplugd for switching between interfaces. This daemon created special for looking state of interface (plug/unplug) and do something in this case.

Good lack!
 
Old 11-03-2008, 09:41 AM   #4
jonaskoelker
Senior Member
 
Registered: Jul 2004
Location: Denmark
Distribution: Ubuntu, Debian
Posts: 1,524

Original Poster
Rep: Reputation: 46
Quote:
You can try ifplugd for switching between interfaces.
I've looked at the package description. It sounds inferior to a good bonding setup.

As I understand it, ifplugd detects which interfaces are available, and invokes ifup/-down to give the interfaces IP addresses and set up the routing table.

Bonding will also look at when interfaces are available, and use exactly those which are. As a bonus, which ifplugd doesn't do, bonding will keep all existing connections alive since you never change your IP address(es).
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Nic Bonding mstjohn1974 Slackware 9 06-15-2012 11:26 PM
NIC Bonding: Does not failover successfully. Only one NIC is active Akhran Debian 2 02-18-2011 08:26 PM
NIC Bonding zimm247 Red Hat 1 06-28-2008 08:22 PM
bonding-problem, eth0,1,2 changes nic's max_mad Linux - Networking 5 09-13-2005 05:33 PM
NIC Bonding Problem jon3k Linux - Networking 4 08-31-2004 03:36 PM


All times are GMT -5. The time now is 09:51 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration