# HOWTO: Seamless Wired <-> Wireless networking

## trazillion

Situation:

You use your laptop in many places with wired and wireless and you'd like to be able to:

1) Go from Wired to Wireless to move around a bit.

2) Go from Wireless to Wired to pick up some speed.

Solution:

NOTES:  The following is known to work with the ipw2200 driver.  I beleive it should also work with the hostap and other drivers.  It will likely NOT work with ndis_wrapper drivers (at least the last time I tried, those drivers didn't support being slaved into a bonding device).

 I'm using ifconfig/route for configuring the interfaces.  If you're using iproute2's 'ip' command, you'll have to change something

 The Blue Socket login script does use the iproute2 'ip' command since it provides cleaner output that's easier to parse.

Kernel configuration:

Compile the bonding driver:

```

Symbol: BONDING [=m]

  Prompt: Bonding driver support

    Defined at drivers/net/Kconfig:49

    Depends on: NETDEVICES && INET

    Location:

      -> Device Drivers

        -> Network device support

          -> Network device support (NETDEVICES [=y])

```

I recommend using it as a module as that is easier to work with, although you should be able to compile into the kernel (just note that you then have to configure it via grub/lilo instead of as below).

To get the module to load at startup, you need the following in /etc/modules.autoload.d/kernel-2.6:

```
bonding mode=1 miimon=100 primary=eth0
```

You should read /usr/src/linux/Documentation/networking/bonding.txt for more information about miimon and alternatives if you are having trouble with getting it to recognize when each interface goes up or down.  The above setting should work in most cases, though.

Also don't forget to run:

```
#modules-update
```

Other software:

You'll need to have ifenslave installed in order to configure network devices in to a bonding device.  If you are following these instructions on a non-Gentoo system, you can find ifenslave.c in the Documentation/networking directory of the kernel sources.

```
emerge ifenslave
```

Gentoo-specific configuration:

Although /etc/conf.d/wireless doesn't need any modifications, here's a good tip for wireless in general.  Try playing with the command "iwlist eth1 txpower".  Even if it doesn't list any values, you can try something like "iwconfig eth1 txpower 20", and see what it says.  If you get something like:

```
Error for wireless request "Set Tx Power" (8B26) :

    SET failed on device eth1 ; Invalid argument.
```

then you're probably too high.  Try a lower number until it stops complaining.  If it doesn't accept any value, then skip this step:

In /etc/conf.d/wireless, add:

```
preassociate() {

    # Note this value should work with the ipw2200 driver

    iwconfig eth1 txpower 20

}
```

The more interesting configuration changes are in /etc/conf.d/net.  Gentoo's supplied net.example has support for the bonding driver, but we need to tweak it a bit for our purposes:

```

# Set all the config_ESSID and routes_ESSID variables as normal

# Normal Bonding configuration:

slaves_bond0="eth0 eth1"

# Note that normally Gentoo wants us to configure the values

#  for this manually, but we want to do it based on our ESSID,

#  so we'll tell it to skip this step.

config_bond0=( "null" ) # I'll configure this later

# the slaves_ line above would force it to bring up net.eth0 and 

# net.eth1, but we don't want to waste time configuring the

# wired network, since we won't use it anyways

depend_bond0() {

       need net.eth1

}

postup() {

    # Calling this function registers some variables for us.  

    #  Unfortunately this isn't meant to be a public API and 

    #  there for might break in a later baselayout ( this is 

    #  known to work in sys-apps/baselayout-1.11.14-r3 )

    essidnet_pre_start

    # Test if we are bringing up the bonding interface

    if [ "${IFACE}" == "bond0" ] ; then

        # This should show the user what they are connected to

        echo "ESSID: ${ESSID}"

        # See if there is a wireless config for this ESSID, if not revert to dhcp

        if [ -z "$(eval echo \${config_${ESSID}})" ] ||

           [ "$(eval echo \${config_${ESSID}})" == "dhcp" ] ; then

            # You might try checking if dhcp_ESSID is set here, too, 

            #  instead of hard coding it

            dhcpcd -t 5 ${IFACE}

        else

            # Use the configuration of the wireless card for the bond interface

            # Show the user what we are planning

            echo $(eval echo "\${config_${ESSID}}")

            # Perhaps there is some gentoo function that could be called here:

            ifconfig ${IFACE} $(eval echo "\${config_${ESSID}}")

            # Sometimes a default route is left that we don't want, so remove it

            (route -n | grep -q "^0.0.0.0") && route del default

            route add $(eval echo "\${routes_${ESSID}}")

        fi

    # Here's another neat trick for blue socket login:

    elif [ "${IFACE}" == "eth1" ] && [ "${ESSID}" == "BlueSocket" ] ; then

        # You might want to check the IP range first:

        if ifconfig | grep -q "172\."  ; then

            /usr/local/bin/bs_login.pl username password server_ip

        fi

    fi

    return 0

}

```

Here's the Blue Socket login script, bs_login.pl

```

#!/usr/bin/perl -w

#Usage: ./bs_login.pl username password server_ip

use strict;

use warnings;

use LWP 5.64;

my $browser = LWP::UserAgent->new;

my $username = '$1';

my $password = '$2';

my $url = 'https://$3/login.pl';

my $ip;

my $iface = 'eth1';

my $ifline = `ip -o addr`;

($ip) = ($ifline =~ /$iface *inet ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})/);

my $response = $browser->post( $url,

  [ 'bs_name' => $username,

    'bs_password' => $password,

    '_FORM_SUBMIT' => 1,

    'which_form' => "reg",

    'destination' => "",

    'source' => $ip,

  ]

);

die "$url error: ", $response->status_line

 unless $response->is_success;

die "Weird content type at $url -- ", $response->content_type

 unless $response->content_type eq 'text/html';

```

----------

## Darknight

Can you provide a bit more background on this? I'm lost  :Smile: 

What do you exactly accomplish with these changes? Does the wireless connection come up as soon as the wired one goes down for example?

----------

## tubs

When you bond two physical devices, (eth0 and eth1 in this example) you create a virtual device (bond0) which will access either eth1 or eth0 (depending on your settings) and when one of them is unavailable, it will access the other. You do not always need to assign IPs and other config to the physical devices either (but I believe you can if you choose to), only the virtual device. 

Please correct me if anything I have written above is wrong, as I am still new to bondage myself :D

Nice first post, trazillion. I like it.

----------

## trazillion

tubs, that's essentially correct.  The exact usage of the enslaved devices in the bond device is dependent on the mode.  Here I'm using it in active-backup mode, which means it will choose which ever interface is up.  Note that I'm also specifying the primary interface as the Wired network, which means it gets preference when both are up (since it's usually the fastest).  Most of the other uses for the bonding driver are for load balancing or a more primtive fault tolerance that broadcasts on all slave interfaces.  I've never tried that mode, though it seems slower and less desirable for this purpose (and might confuse AP/routers as the same MAC would come from different interfaces).

----------

## Darknight

This is going in my bookmarks for later trial  :Cool: 

----------

## XenoTerraCide

yes I was thinking about trying something like this. although I'm not sure how well it will work with mine. currently using ndiswrapper, but I have an atheros pcmcia card, and should probably try madwifi.

----------

## scoobydu

 *Darknight wrote:*   

> This is going in my bookmarks for later trial 

 

Definately.

Thanks for the howto, sounds useful.

----------

## XenoTerraCide

Ok now I've come back to it. I've one concern I like this Idea but my wireless card is a pcmcia card will bonding have problem's if my second nic isn't present at all.

----------

## trazillion

 *XenoTerraCide wrote:*   

> Ok now I've come back to it. I've one concern I like this Idea but my wireless card is a pcmcia card will bonding have problem's if my second nic isn't present at all.

 

The scripts should default to dhcp on the wired connection, in that case.  ifenslave will generate a warning message about not being able to add the wireless card to the bond, but it will add the wired, anyway.

----------

## vicaya

Yeah, tried with ndiswrapper, can't make it work. Until the new bcm43xx driver is usable without additional kernel patches, the new baselayout (>= 1.12) with netplug and wpa_supplicant is an acceptable alternative (using the usual routing metric trick,) i.e., it's not seemless for a ssh session, but works fine with web and torrents  :Smile: 

----------

## maiku

I should also like to add that adding options to a module in /etc/modules.autoload.d/kernel-2.6 will be ignored by modprobe, and idiots like me are going to modprobe bonding in without adding the options at the end.

This was very useful, thanks.

----------

## maiku

I should also like you add that you don't have to add it all to /etc/modules.autoload.d/kernel-2.6

One can simply edit /etc/modules.d/bond *Quote:*   

> alias bond0 bonding
> 
> options bonding mode=1 miimon=100 primary=eth0
> 
> #options bond0 mode=1 miimon=100 primary=eth0

 Now I commented out the line under it because the line under it won't work.  I'm not sure why.  Either way, editing your config in that fashion works, too, and it'll edit both /etc/modprobe.conf and /etc/modules.conf when you run modules-update so even "modprobe bonding" will set the driver up with the proper options.

----------

## Chacabaou

Did anybody try that with wpa_supplicant (ipw2200)?

I found many howtos on channel bonding particularly mentioning the use seamlessly switch between wired and wireless with wpa_supplicant. But for me, everytime I tried to enslave wlan0 (`ifenslave bond0 wlan0`), wpa_cli immediately reported a disconnect-event, followed by an reassociation attempt which fails in an infinite loop until I detach wlan0 from bond0 and restart wpa_supplicant.

Without bonding, wireless lan works perfectly for me, so I don't suppose it to be a general configuration fault with wpa_supplicant.

Thankful for any suggestions,

Daniel

----------

## cables69

 *Chacabaou wrote:*   

> Did anybody try that with wpa_supplicant (ipw2200)?
> 
> I found many howtos on channel bonding particularly mentioning the use seamlessly switch between wired and wireless with wpa_supplicant. But for me, everytime I tried to enslave wlan0 (`ifenslave bond0 wlan0`), wpa_cli immediately reported a disconnect-event, followed by an reassociation attempt which fails in an infinite loop until I detach wlan0 from bond0 and restart wpa_supplicant.
> 
> Without bonding, wireless lan works perfectly for me, so I don't suppose it to be a general configuration fault with wpa_supplicant.
> ...

 

same problem here, wpa_supplicant using the madwifi driver. bonding works on the wired connection.

some dmesg:

```
ath_hal: module license 'Proprietary' taints kernel.

ath_hal: 0.9.16.16 (AR5210, AR5211, AR5212, RF5111, RF5112, RF2413, RF5413)

wlan: 0.8.4.2 (svn 1502)

ath_rate_sample: 1.2 (svn 1502)

PCI: Enabling device 0000:00:1f.6 (0000 -> 0001)

ACPI: PCI Interrupt 0000:00:1f.6[B] -> GSI 17 (level, low) -> IRQ 18

ACPI: PCI interrupt for device 0000:00:1f.6 disabled

ath_pci: 0.9.4.5 (svn 1502)

acpi_bus-0201 [01] bus_set_power         : Device is not power manageable

ACPI: PCI Interrupt 0000:01:05.0[A] -> GSI 22 (level, low) -> IRQ 19

e100: Intel(R) PRO/100 Network Driver, 3.5.10-k2-NAPI

e100: Copyright(c) 1999-2005 Intel Corporation

wifi0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps

wifi0: 11g rates: 1Mbps 2Mbps 5.5Mbps 11Mbps 6Mbps 9Mbps 12Mbps 18Mbps 24Mbps 36

Mbps 48Mbps 54Mbps

wifi0: H/W encryption support: WEP AES AES_CCM TKIP

wifi0: mac 5.6 phy 4.1 radio 1.7

wifi0: Use hw queue 1 for WME_AC_BE traffic

wifi0: Use hw queue 0 for WME_AC_BK traffic

wifi0: Use hw queue 2 for WME_AC_VI traffic

wifi0: Use hw queue 3 for WME_AC_VO traffic

wifi0: Use hw queue 8 for CAB traffic

wifi0: Use hw queue 9 for beacons

wifi0: Atheros 5212: mem=0xcfff0000, irq=19

acpi_bus-0201 [01] bus_set_power         : Device is not power manageable

wlan: mac acl policy registered

Ethernet Channel Bonding Driver: v3.0.1 (January 9, 2006)

bonding: MII link monitoring set to 100 ms

e100: eth0: e100_watchdog: link up, 100Mbps, full-duplex

bonding: bond0: making interface eth0 the new active one.

bonding: bond0: enslaving eth0 as an active interface with an up link.

bonding: bond0: Warning: failed to get speed and duplex from ath0, assumed to be

 100Mb/sec and Full.

bonding: bond0: enslaving ath0 as a backup interface with an up link.

NET: Registered protocol family 5

bonding: bond0: link status definitely down for interface ath0, disabling it

bonding: bond0: link status definitely up for interface ath0.

bonding: bond0: link status definitely down for interface ath0, disabling it

bonding: bond0: Warning: the permanent HWaddr of eth0 - 00:08:0D:B5:CD:DB - is s

till in use by bond0. Set the HWaddr of eth0 to a different address to avoid con

flicts.

bonding: bond0: releasing active interface eth0

bonding: bond0: enslaving ath0 as a backup interface with a down link.

bonding: bond0: link status definitely up for interface ath0.

bonding: bond0: making interface ath0 the new active one.

bonding: bond0: link status definitely down for interface ath0, disabling it

```

last 3 lines repeated on a loop. i'm running with wpa_supplicant 0.5.3,

maybe there's some interesting debug output on wpa_supplicant that 

can say more about the problem. any ideas?

----------

## MikeDougherty

This is very interesting, thanks for posting the info. Think it will work with a ppp0 connection as at third option? I usually connect to a wired network, hotspot, and (finally) to Verizon's EVDO network if the other two are not available. Of course on my current laptop that is done via a PCMCIA card so it may not work if I haven't inserted the card yet. But on my soon-to-be new laptop the EVDO card will be integrated so it would be a more reliable option.

----------

## dmartinsca

I'd like to share my configuration. As of writing this i'm using baselayout-1.12-0-r1. My wireless card is an intel 3945ABG using the intel ipw3945 driver version 1.0.5. My ethernet card is eth0 and my wireless is eth1. The wireless drivers never seem to load the daemon when they are loaded by udev so I'm using a init-script to start the daemon, i'll include that as well. The one thing i'm not happy with so far is that if the radio is turned off on the wireless card via the switch when net.bond0 starts then it will fail because eth1 doesn't exist. Reloading the ipw3945 module and trying to start net.bond0 again seems to fix things. Once net.bond0 has started i can turn on and off the wireless switch and it still works fine.

I haven't had much chance to test this setup yet. I don't know what will happen if there is no wireless network available, does net.eth1 fail in this case?

I have the bonding module set up as previously described, what differs is my /etc/conf.d/net file:

```
config_eth0=( "null" )

config_eth1=( "null" )

slaves_bond0="eth0 eth1"

config_bond0=( "dhcp" )

depend_bond0() {

       need net.eth0 net.eth1

}
```

Here's the init-script to load ipw3945d, courtesy of agnitio:

```
#!/sbin/runscript

depend() {

     before net.eth1

}

start() {

     ebegin "Starting ipw3945d"

     start-stop-daemon --start --quiet --exec /sbin/ipw3945d

     eend $?

}

stop() {

     ebegin "Stopping ipw3945d"

     start-stop-daemon --stop --quiet --pidfile /var/run/ipw3945d.pid

     eend $?

}
```

I added this script to the default runlevel, i don't know if that's required but it works  :Smile: 

----------

## dmartinsca

The setup in my previous post no longer works with recent versions of baselayout (currently 1.12.4-r2). If the wireless card is on at boot then eth1 is brought up but doesn't connect to a network. This means bond0 is brought up but unless a wired connection is available dhcp times out. It also means i need to restart net.eth1 on every boot if I want to switch to using it later. I have a feeling it has to do with the config_eth1=( "null" ) line but i'm not sure what else to change that to.

----------

## maiku

I am experiencing the same problem, however mine complains when wlan0 starts up saying that there is something else already has the same IP.  I am at a loss as to what is wrong.

----------

## maiku

I think the problem is that eth0 and wlan0 are being started before bond.  They aren't even in any run-level, so they have no business being started.  I'm a little bit confused.

----------

## UberLord

 *maiku wrote:*   

> I think the problem is that eth0 and wlan0 are being started before bond.  They aren't even in any run-level, so they have no business being started.  I'm a little bit confused.

 

Look into RC_COLDPLUG in /etc/conf.d/rc

----------

## maiku

Thanks for the tip, changed the file to: *Quote:*   

> # Dynamic /dev managers can trigger coldplug events which cause services to
> 
> # start before we are ready for them. If this happens, we can defer these
> 
> # services to start in the boot runlevel. Set RC_COLDPLUG="no" if you don't
> ...

 It starts as expected in the correct order, however now the internet just doesn't work on boot.  That should have made it work...

----------

## UberLord

 *maiku wrote:*   

> It starts as expected in the correct order, however now the internet just doesn't work on boot.  That should have made it work...

 

Dammit my crystal ball is broken!

Could you post the error  :Smile: 

----------

## maiku

Well, that's the thing.  There are no errors.  The best I have is this: *Quote:*   

> eth0: Media Link Off
> 
> bonding: bond0: enslaving eth0 as a backup interface with a down link.
> 
> wlan0: Setting MAC to 00:03:0d:25:xx:xx
> ...

 The mac addresses are changed because I have  *Quote:*   

> mac_bond0="00:0E:35:BD:xx:xx"

 in /etc/conf.d/net to correct an error it was causing before.

Here is the startup jazz *Quote:*   

>  * Starting wlan0
> 
>  *   Configuring wireless network for wlan0
> 
>  *     wlan0 connected to ESSID "homenetwork" at 00:0F:3D:69:xx:xx
> ...

 as per the config: *Quote:*   

> # To bond interfaces together
> 
> slaves_bond0="eth0 wlan0"
> 
> config_bond0=( "10.0.0.2 netmask 255.255.255.0 broadcast 10.0.0.255" ) # You may not want to assign an IP the the bond
> ...

 in /etc/modules.conf it is set correctly *Quote:*   

> alias bond0 bonding
> 
> options bonding mode=1 miimon=100 primary=eth0

 However, when I run ifconfig I see that nothing is enslaved anymore: *Quote:*   

> bond0     Link encap:Ethernet  HWaddr 00:0E:35:BD:xx:xx  
> 
>           inet addr:10.0.0.2  Bcast:10.0.0.255  Mask:255.255.255.0
> 
>           UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
> ...

 

----------

## UberLord

ifconfig doesn't show any bonding information - and your setup and output looks correct.

cat /proc/net/bonding

should show more.

What make you think there's a config error?

----------

## maiku

Well, if the error isn't in the config files then I'm confused already :D .  Just double checking myself.

cat /proc/net/bonding/bond0 *Quote:*   

> Ethernet Channel Bonding Driver: v2.6.5 (November 4, 2005)
> 
> Bonding Mode: fault-tolerance (active-backup)
> 
> Primary Slave: eth0
> ...

 Shows nothing special?  Is my baselayout version mis-matched with the kernel driver?

----------

## UberLord

OK, let's start over. This thread is a good how to so lets keep it that way.

Start a new thread by posting your problem, your config and our setup results (ie output of starting interfaces)

----------

