How to Setup LACP Bonding on Ubuntu

By

Network bonding or teaming refers to a process of combining two or more network interfaces into one. Network bonding can enhance performance and capacity by increasing throughput and bandwidth, and provide network redundancy and load balancing.

This guide will show how to connect multiple network interfaces into a single bond interface on Ubuntu 20.04.

Requirements

This guide requires the system to be running networkd instead of NetworkManager. To check if you’re running networkd or NetworkManager, see our other post here.

To change from NetworkManager to networkd, see our guide here.

Sudo Privileges

It’s convenient to be root while configuring the network. To become root on Ubuntu:

sudo su

Install Kernel Bonding Module

The Linux kernel provides us with modules to perform network bonding. Before you can configure the network cards you need to ensure that the kernel module called bonding is present and loaded.

sudo lsmod | grep bonding

If the module is not loaded, use the following command to load it:

modprobe bonding

To ensure that the bonding module is loaded during boot, edit the /etc/modules file:

nano /etc/modules

Add the following line:

bonding

Then, install the ifenslave dependency if it’s not already on your system:

apt install ifenslave

Find Member Interfaces for Bonding

Run the command ip link to see a list of your interfaces:

root@localsharespace:~# ip link

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 3c:a8:2a:24:f0:90 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.5/24 brd 192.168.2.255 scope global 
3: enp3s0: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 3c:a8:2a:24:f0:94 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.6/24 brd 192.168.2.255 scope global 

You can ignore the lo interface. That only leaves two interfaces that have to be configured. If you have more than two interfaces, LACP is usually configured on the first two interfaces.

You could also try to find the active network interface by using the following command:

clear && echo $(ip -o -4 route get 8.8.8.8 | sed -nr 's/.*dev ([^\ ]+).*/\1/p')

The output of the above command should give you the network interface that is currently active. You should use that interface name for the bond. In our case, this is enp2s0, and the second interface is enp3s0.

Configure Network Interfaces for Bonding

On Ubuntu 20.04 using networkd, the network configuration file will be located in /etc/netplan/ and the file name ends in .yaml. In our case, it was config.yaml.

Use your preferred editor to edit the configuration file:

nano /etc/netplan/config.yaml

Use the following example for your configuration:

# /etc/netplan/config.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp2s0:
      dhcp4: no
    enp3s0:
      dhcp4: no
  bonds:
    bond0:
      interfaces: [enp2s0, enp3s0]
      addresses: [192.168.2.2/24]
      gateway4: 192.168.2.1
      parameters:
        mode: 802.3ad
        lacp-rate: fast
        transmit-hash-policy: layer3+4
        mii-monitor-interval: 1
      nameservers:
        addresses:
          - "1.1.1.1"
          - "8.8.8.8"

Replace enp2s0 and enp3s0 with the interfaces that you want to use as the members of the bond. You can also define more interfaces to have more than two members in the bond.

dhcp4 needs to be “no” for all interfaces that are members of the bond. If your bond isn’t working, see the Troubleshooting section in this guide for instructions on how to remove any IP address assigned to a member interface.

For the bond, replace the IP address and gateway with your own information.

YAML is sensitive to spacing and indentation. We recommend using 2 spaces for each indent level (do not use the tab key).

Replace the addresses of the nameservers (1.1.1.1, 8.8.8.8) with your preferred DNS resolvers.

For optimal performance, include transmit-hash-policy: layer3+4 in the configuration file. This setting affects load-balancing. By default, the transmit-hash-policy is set to layer2. The algorithm for layer2 places all traffic to a particular network peer on the same member interface, which means all traffic to the same MAC-address (which our router will always have) will egress over the same interface and therefore potentially limit the bond’s performance.

By setting transmit-hash-policy to layer3+4, traffic will be split based on the src/dst IP and src/dst port, which can result in better load-balancing. layer3+4 uses upper layer protocol information, when available, to generate the hash, allowing traffic to a particular network peer to span multiple member interfaces, although a single connection will not span multiple member interfaces. The L4 hashing allows load-balancing to be more evenly distributed. Consider, for example, a server with multiple connections to a SAN device that uses L3 hashing, in which all of those connections would utilize only one link. L4 hashing would allow the connections to be spread out across the LAG.

LAG hashing generally does not need to match on the two sides of a LAG so long as both sides behave according to standards. A LAG will accept traffic on any port and use the hash algorithm to determine the outgoing port. The LAG hashing algorithm is used for load-balancing, not for authentication.

Apply Bond Configuration

To apply the configuration we just created, simply run:

netplan apply

Then reboot your system:

reboot

Verify Network Configuration

If everything went well, you should have a working bonding interface.

To verify your configuration was applied, run the ip link command:

ip link

The output should now show the bond0 interface.

To confirm the bond’s IP address matches the configuration file, run ip address:

root@localsharespace:~# ip address

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master bond0 state UP group default qlen 1000
    link/ether 72:d6:bf:b4:18:8c brd ff:ff:ff:ff:ff:ff
3: enp3s0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master bond0 state UP group default qlen 1000
    link/ether 72:d6:bf:b4:18:8c brd ff:ff:ff:ff:ff:ff
4: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 72:d6:bf:b4:18:8c brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.2/24 brd 192.168.2.255 scope global bond0
       valid_lft forever preferred_lft forever
    inet6 fe80::70d6:bfff:feb4:188c/64 scope link 
       valid_lft forever preferred_lft forever

Run cat /proc/net/bonding/bond0 to show more information about the bond0 interface, such as the following: ​

  • Bonding Mode: IEEE 802.3ad Dynamic link aggregation – Shows the bond is configured with 802.3ad (LACP), this way it negotiates with our switch.
  • Transmit Hash Policy: layer3+4 (1) – Shows the bond hashing mode is set to layer3+4, which is what we want in our case.

You can also check the interface using ethtool bond0, which will show the speed of the interface. The speed of bond0 should equal the sum of the two member interfaces, e.g. 20000Mb/s for two members with gigabit interfaces:

root@localsharespace:~# ethtool bond0

Settings for bond0:
        Supported ports: [ ]
        Supported link modes:   Not reported
        Supported pause frame use: No
        Supports auto-negotiation: No
        Supported FEC modes: Not reported
        Advertised link modes:  Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 2000Mb/s
        Duplex: Full
        Port: Other
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: off
        Link detected: yes

Ping to confirm internet connectivity. By default, the firewall will allow this type of outbound traffic. If you notice missing icmp_seq numbers, there may be packet loss.

ping 8.8.8.8

Configure LACP on the Switch

For link aggregation control protocol (LACP) to fully work, a link aggregation group (LAG) and LACP will need to be configured on your network switch. See our other post about setting up a LAG and LACP on the TP-Link Jetstream T2600G-28TS.

Troubleshooting

Remove IP Addresses from Member Interfaces

Only the bond0 interface should have an IP address. The members of the bond (e.g., enp2s0 and enp3s0) should not have any IP addresses assigned to their interfaces. Run ip addr del for each member interface that has an IP address assigned to it. For example, in our case, we would run:

ip addr del 192.168.2.5/24 dev enp2s0
ip addr del 192.168.2.6/24 dev enp3s0

Then, make sure the interfaces are configured to not automatically be assigned an IP address. Check the configuration file to confirm dhcp4 is set to no for each of the member interfaces:

nano /etc/netplan/config.yaml

Reboot and check to see if an IP address is still automatically being assigned to the interfaces:

ip address

If the interfaces are still receiving an IP address, then check to see if dhcpcd is running:

systemctl status dhcpcd

To disable dhcpcd:

systemctl stop dhcpcd
systemctl disable dhcpcd

Reboot and then check the ip address again:

reboot
ip address

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.