January 10, 2018
How to aggregate multiple network interfaces into a single logical interface?
If you haven’t heard about network bonding - it’s a network setup that allows you to use two or more network devices to act as one interface, giving you expanded bandwidth and some redundancy. Basically you can turn a 1 GiB link into a 2 GiB link for the one virtual interface.
Usually it’s used to bond ethernet devices, but let’s try to mix wifi and ethernet.
As long as the network cable is connected, its interface (e.g. eth0) is used for the network traffic.
The goal is to switch over to the wireless interface transparently, without any loss of network packages when you pull the RJ45-plug. After reconnecting the network cable, it switches back to ethernet.
These steps were tested on Linux Mint 18.3 which is a Ubuntu based distribution.
I assume you have at least two network devices (one wifi, one eth), let’s list them:
ip -br addr show
The result on my laptop is:
lo UNKNOWN 127.0.0.1/8 ::1/128
enp3s0 DOWN
wlp2s0 UP 192.168.1.19/24 ff70::957f:4ecd:d256:43c1/64
docker0 DOWN 172.17.0.1/16
As you can see I’m on my wifi at the moment as wlp2s0 is UP end I’m not using my ethernet ensp3s0 (it’s unplugged) connection right now.
If you don’t know which interface represents which device you can also use NetworkManager:
sudo nmcli device status
DEVICE TYPE STATE CONNECTION
docker0 bridge connected docker0
wlp2s0 wifi connected xxxxxxxxxxxx
enp3s0 ethernet unavailable --
lo loopback unmanaged --
I replaced my real wifi name with “xxxxxxxxxxxx”, so you will see there a wifi network name you’re currently connected.
Tell the kernel to load the bonding module
If you want to check to see if your bonding module is already loaded in the kernel just run:
lsmod |grep bonding
and you should see something like this:
bonding 163840 0
If not, install neccecary packages:
sudo apt install ifenslave
And insert the module to the kernel:
sudo modprobe bonding
A default content of this file should be similar to:
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
This is a standard loopback interface configuration which informs the kernel to bring the adapter up automatically on start-up. iface lo inet loopback tells the system that this interface is the system’s loop-back interface or more commonly referenced as 127.0.0.1.
Let’s start by adding two existing interfaces to the list:
auto enp3s0
iface enp3s0 inet manual
bond-master bond0
bond-primary enp3s0 wlp2s0
auto wlp2s0
iface wlp2s0 inet manual
bond-master bond0
bond-primary enp3s0 wlp2s0
wpa-ssid xxxxxxxxxxxx
wpa-bssid XX:XX:XX:XX:XX:XX
wpa-psk xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-
bond-master bond0 is fairly straightforward, it indicates which interface is master (we will create bond0 interface further)
-
bond-primary enp3s0 wlp2s0 is specifying which slave is the primary device. The specified device will always be the active slave while it is available. Only when the primary is off-line will alternate devices be used.
wpa-ssid is your wifi network broadcasted name, wpa-bssid is a mac of your wifi router, wpa-psk is your wifi password (don’t keep it as a plain text, use wpa_passphrase [passphrase]).
New interface (bond0)
The interface bond0 can be set a static one or as dhcp:
auto bond0
iface bond0 inet static
address 192.168.1.10
netmask 255.255.255.0
network 192.168.1.0
gateway 192.168.1.1
These settings are down to individual congiguration settings of your network but very likely these will work for you as well but you may prefer dhcp, in this replace inet static with inet dhcp and remove everything below.
Time for bonding settings:
# Bonding
bond-slaves none
bond-mode active-backup
bond-miimon 100
bond-downdelay 200
bond-updelay 200
-
bond-slaves none this one is very hard to find in any documentation but based on my understanding it instructs to not proceed with slaves interfaces before bond0 is started. Ping me if you find a better explaination.
-
bond-mode active-backup means that when the active interface fails, the other takes over. There are different options available here like broadcast which transmits everything to all slave devices, or balance-tld (adaptive load balancing), or balance-xor (selectable hashing algorithm) and a few more
-
bond-miimon 100 determines how often the link state of each slave is inspected for link failures. A value of zero disables MII link monitoring
-
bond-downdelay 200 means that the system will wait 200 ms before concluding that the currently active interface is indeed down.
-
bond-updelay 200 is used to tell the system to wait on using the new active interface until 200 ms after the link is brought up.
updelay and downdelay - both of these values must be multiples of the miimon value otherwise the system will round down
The completed setup should look like this:
auto enp3s0
iface enp3s0 inet manual
bond-master bond0
bond-primary enp3s0 wlp2s0
auto wlp2s0
iface wlp2s0 inet manual
bond-master bond0
bond-primary enp3s0 wlp2s0
wpa-scan-ssid 1
wpa-ssid xxxxxxxxxxxx
wpa-bssid XX:XX:XX:XX:XX:XX
wpa-psk xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
auto bond0
iface bond0 inet dhcp
bond-slaves none
bond-mode active-backup
bond-miimon 100
bond-downdelay 200
bond-updelay 200
Testing the Bond Configuration
Enslave interfaces and restart network:
sudo ifenslave bond0 enp3s0 wlp2s0
sudo /etc/init.d/networking restart
Checkout the output:
cat /proc/net/bonding/bond0
Output:
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
Bonding Mode: fault-tolerance (active-backup)
Primary Slave: enp3s0 (primary_reselect always)
Currently Active Slave: enp3s0
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 200
Down Delay (ms): 200
Slave Interface: enp3s0
MII Status: up
Speed: 100 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: XX:XX:XX:XX:XX:XX
Slave queue ID: 0
Slave Interface: wlp2s0
MII Status: up
Speed: Unknown
Duplex: Unknown
Link Failure Count: 0
Permanent HW addr: XX:XX:XX:XX:XX:XX
Slave queue ID: 0
You can also check:
dmesg | grep -i bond0
[ 1708.596284] IPv6: ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
[ 1708.714483] bond0: Enslaving wlp2s0 as a backup interface with a down link
[ 1712.352020] bond0: link status up for interface wlp2s0, enabling it in 200 ms
[ 1712.560172] bond0: link status definitely up for interface wlp2s0, 0 Mbps full duplex
[ 1823.200935] bond0: link status down for active interface enp3s0, disabling it in 200 ms
[ 1823.409140] bond0: link status definitely down for interface enp3s0, disabling it
[ 1823.409146] bond0: making interface wlp2s0 the new active one
[ 1855.865317] bond0: link status up for interface enp3s0, enabling it in 200 ms
[ 1856.073355] bond0: link status definitely up for interface enp3s0, 100 Mbps full duplex
[ 1856.073358] bond0: making interface enp3s0 the new active one
[ 3032.576211] bond0: link status down for active interface enp3s0, disabling it in 200 ms
[ 3032.784299] bond0: link status definitely down for interface enp3s0, disabling it
[ 3032.784304] bond0: making interface wlp2s0 the new active one
If you run sudo nmcli device status you probably notice that NetworkManager didn’t pick up bond0, you can safely disable it:
sudo systemctl stop NetworkManager.service
sudo systemctl disable NetworkManager.service
Use ip -br addr show instead:
ip -br addr show
lo UNKNOWN 127.0.0.1/8 ::1/128
enp3s0 UP
wlp2s0 UP
docker0 DOWN 172.17.0.1/16
bond0 UP 192.168.1.29/24 ff50::4fdd:6aff:fedc:fddc/64
Now you should enjoy packetless switching between network devices, which in practice means your video streaming or VPN connection won’t be frozen when unplugging RJ45 cable :)
Source:
[1] Kernel Docs