# Bonding wireless (wpa_supplicant) + ethernet the Gentoo way

## VinzC

Hi.

I'd like to bond my wireless (wlan0, iwl3945 driver) and my ethernet interfaces. I've tried to setup bonding manually first (ip link set bond0 up && ifenslave bond0 wlan0 && ifenslave bond0 eth0 && dhcpcd bond0). Unfortunately I get no network connection with the wireless interface alone (i.e. if the ethernet device is not plugged in).

I'm using wpa_supplicant and WPA/PSK at home. Are there some recommendations for bonding wireless devices?

EDIT:The following link gave me an answer on what I did wrong the manual way.

This code works:

```
VIF=bond0

[ -d /proc/net/bonding ] || modprobe bonding

ip link set $VIF up

ifenslave $VIF eth0 wlan0 || exit 1

wpa_supplicant -Dwext -c /etc/wpa_supplicant/wpa_supplicant.conf -W -B -i wlan0 -b $VIF -P /var/run/wpa_supplicant-wlan0.pid

wpa_cli -a /etc/wpa_supplicant/wpa_cli.sh -p /var/run/wpa_supplicant -i wlan0 -P /var/run/wpa_cli-wlan0.pid -B

dhcpcd -F both -A -L -m 2004 bond0
```

The trick is to provide interface bond0 with -b. What's the Gentoo way to chain these instructions?

EDIT: I've read net.lo thoroughly and here are my conclusions.I can't use a preup() function for bond0 to start wpa_supplicant because the slaves must be added to interface bond0 first. Slaves get added only when bonding_pre_start() is executed, which occurs *after* preup().

I can't use a postup function for bond0 because it happens too late (i.e. after adding the IP addresses or running dhcpcd and wpa_supplicant must start beforehand).

I can't use a preup() function for wlan0 to start net.bond0 because interface bond0 would get its IP *before* wpa_supplicant starts.

So I need a script to do something but I don't know what nor where to start it.

In all cases it turns up I'd need to completely rewrite either a) the code to start wpa_supplicant or b) the code to start bonding, which would mean Gentoo network init scripts are not of much use as soon as wireless is involved... There must be a better way! I'd like not to have to write my own network scripts again...

----------

## VinzC

Well? No candidate?  :Crying or Very sad: 

----------

## ppurka

I don't know anything about bonding, but /usr/share/doc/openrc/net.example says *Quote:*   

> #-----------------------------------------------------------------------------
> 
> # Bonding
> 
> # For link bonding/trunking on 2.4 kernels, or kernels without sysfs
> ...

 

----------

## VinzC

Yes, I know about bonding and how to bind two Ethernet interfaces together in general. The issue comes with wpa_supplicant. It *must* take an additional argument -b <controlling_interface_name> that is up before wpa_supplicant is called. In this case, it's -b bond0. The issue is all about the sequence of operations:set bond0 up (but don't get an IP address yet  :Exclamation:  ) and add the wireless and wired interfaces

start and associate the wireless interface, wlan0 and wait till it's associated

when and only when the slave interfaces are up and ready, get an IP address for bond0So you see: bond0 must be available and bonding be ready before wpa_supplicant uses it to associate wlan0 through bond0.

If I use the described method, net.bond0 fails because it attempts to set an IP address, which fails because the slave interfaces are not ready yet. At most the sequence is as follows with Gentoo net scripts:start bond0, add the slaves and get an IP address

start and associate wlan0

optionally start eth0

This is bound to fail already at the first step because no IP address can be set. Next I fear that the script for wireless interface wlan0 fails to start because the interface is already brought up beforehand, having the whole process fail to start.

Hence my initial post...

----------

## VinzC

I've finally found a hack -- at least that's what I think it is. Here's the related network configuration.

```
#

# Link aggregation (eth0, wlan0)

#

wpa_supplicant_wlan0="-Dwext -b bond0"

config_wlan0="null"

config_eth0="null"

# First slave MAC address will be used for bond0

slaves_bond0="wlan0 eth0"

config_bond0="null"

depend_wlan0()

{

        need net.bond0

}

postup()

{

        # Start DHCP against bond0 when wlan0 gets up

        [ "$IFACE" == "wlan0" ] && (IFACE="bond0"; IFVAR="bond0"; dhcpcd_start)

}
```

Setting config_bond0 to null prevents the network script from assigning an IP address, which is now deferred and must be done "manually". The IP address however must be assigned only after wlan0 started, hence the postup function and the test against $IFACE. Since /lib/rc/net/dhcpcd.sh uses $IFACE and $IFVAR internally as an argument to dhcpcd, both variables must be overriden for dhcpcd to run against bond0 instead of wlan0.

The only remaining issue is this one:

```
net.bond0          |/lib64/rc/net/bonding.sh: line 48: echo: write error: Operation not permitted
```

It occurs as /lib/rc/net/bonding.sh tries to add slaves. But I don't know what slave produces that error.

----------

## VinzC

Geez! This trick didn't even survive a reboot... [Worked perfectly at home, fails miserably at work...]

Bonding sucks!

----------

## UberLord

I'm not entirely sure you can do this, even with OpenRC as it stands.

Future OpenRC versions will at least make it possible, mainly by removing the whole net.foo concept and replacing it with a much simpler script just to assign addresses and routes for ALL configured interfaces and run a custom script per interface (like to say setup bonding). Then each daemon component (wpa_supplicant, dhcpcd, etc) can be moved into a generic init script.

----------

## VinzC

Thanks for your lights, Roy. In fact I'm just surprised it doesn't work here at work in fact though it seemed to work perfectly well at home -- meaning it should be possible with OpenRC. At least I succeeded in having my “custom” configuration work once. Just that the interface configuration must be done manually later on, calling dhcp_start(), for instance, which makes it a “hard runtime” dependency towards dhcp but since it's the default with Gentoo.

BTW, if we're expecting to see something simpler, I love this:

```
#!/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
```

```
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
```

It's from Debian and also assumes there is such a line in Gentoo module configuration

```
option bonding mode=active-backup miimon=100 primary=eth0
```

but it gives a good idea on how simple it is to setup the network. Of course, there is the binary (Lord knows I hate) "network-manager" but simple scripts are possible too. Also note the above example lacks -a /path/to/wpa/action.script, which would have made the endless loop pointless.

I wrote my own network scripts at the time I was using baselayout-1 -- I remember I sent you a copy BTW. My goal was to make them faster (even with bash) than Gentoo network script library, which looked overly complex to me. Another goal was to have only one script for network called... network. Since I also had to bridge several virtual tap interfaces, I took care to simplify it as much as possible, requiring only one line (instead of three) to configure a tap interface. I used it for a couple of months and it was pretty stable... Then came baselayout-2, which was even faster  :Very Happy:  .

I'm tempted to port them to baselayout-2/OpenRC. I'd be glad to submit them as a contribution...

----------

## UberLord

http://roy.marples.name/projects/openrc/browser/trunk/init.d/network.in

The new simple script  :Smile: 

Here's a bonded interface config for it

```
# Create a bonded interface

interfaces="bond0"

ifup_bond0="modprobe bonding; ifconfig bond0 up; ifenslave bond0 bge0"

ifconfig_bond0="192.168.0.10/24"

ifdown_bond0="rmmod bonding"

```

----------

## VinzC

 *UberLord wrote:*   

> http://roy.marples.name/projects/openrc/browser/trunk/init.d/network.in
> 
> The new simple script 
> 
> Here's a bonded interface config for it

 

```
# Create a bonded interface

interfaces="bond0"

ifup_bond0="modprobe bonding; ifconfig bond0 up; ifenslave bond0 bge0"

ifconfig_bond0="192.168.0.10/24"

ifdown_bond0="rmmod bonding"
```

Uh  :Shocked:  ? I know Gentoo users are^Wshould be aware of using the command line but don't you fear this is too technical? This furiously looks like what we type on the command line to start network interfaces.

I'm aware that using configuration files to abstract most of the commands we type is indeed a tough job but isn't there a smarter compromise between usability (for users) and simplicity (for developers)? It's no offence, just a first impression.

----------

## UberLord

 *VinzC wrote:*   

> Uh  ? I know Gentoo users are^Wshould be aware of using the command line but don't you fear this is too technical? This furiously looks like what we type on the command line to start network interfaces.
> 
> I'm aware that using configuration files to abstract most of the commands we type is indeed a tough job but isn't there a smarter compromise between usability (for users) and simplicity (for developers)? It's no offence, just a first impression.

 

After using NetBSD for some time now (I'm a NetBSD developer - heh) I've come to the conclusion that the reason why network configuration is perceived to be hard is due to the quality of the tools.

Here's how a bonded interface is done on NetBSD.

```

interfaces="agr0"

ifconfig_agr0="create; agrport sip0; agrport sip1; 192.168.0.10/24"
```

How much easier is that? A lot - for the user and for the distro maintainers. And the beauty is that it's all in the ifconfig man page.

All it needs is someone to step-up and bring linux ifconfig into the modern age.

----------

## VinzC

I see  :Laughing:  ...

----------

