Skip to main content
RunBook Academy

VyOSX · Bonding and Link AggregationBonding

Bond modes — balance-rr, active-backup, balance-xor, 802.3ad, balance-tlb, balance-alb

Intermediate⏱ ~18 minset interfaces bondingshow bondingcat /proc/net/bondingip link show bond0

What you'll learn

  • List the six Linux bonding modes and the trade-off each one makes
  • Choose the right mode for a given switch and use case
  • Configure balance-rr, active-backup, balance-xor, 802.3ad, balance-tlb, and balance-alb in VyOS
  • Recognise the failure modes each mode hides and exposes

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15

Not yet marked complete on this device.

Bond modes — balance-rr, active-backup, balance-xor, 802.3ad, balance-tlb, balance-alb

A bond is a Linux kernel driver that presents two or more physical Ethernet interfaces as a single logical device. The driver chooses how to use the slaves — round-robin, active-backup, hash-based, LACP-negotiated, transmit-load-balanced, or adaptive-load-balanced — and the choice has consequences the operator cannot see until a specific failure mode hits. This lesson walks through the six modes the Linux driver supports, the trade-off each one makes, and how VyOS 1.5 LTS exposes them through set interfaces bonding syntax.

The mode trade-off

The bond driver offers six modes. The choice between them is a trade-off between three orthogonal properties:

  1. Bandwidth — does the mode aggregate throughput across slaves, or only one at a time?
  2. Switch dependency — does the mode require the peer switch to be configured (LACP, static LAG), or does it work against any switch?
  3. Failover behaviour — does the mode detect and react to a slave failure, and how quickly?
flowchart TD
  A[Bond mode?] --> B{Need aggregation?}
  B -- No --> C[active-backup]
  B -- Yes --> D{Switch supports LACP?}
  D -- Yes --> E[802.3ad]
  D -- No --> F{Need only TX load balance?}
  F -- Yes --> G[balance-tlb]
  F -- No --> H{Static LAG on switch?}
  H -- Yes --> I[balance-xor]
  H -- No --> J[balance-rr]

The decision is rarely “which is best”; it is “which three constraints am I willing to accept on this link”.

Mode 0 — balance-rr (round-robin)

flowchart LR
  A[Packet 1] --> B[bond0]
  C[Packet 2] --> B
  D[Packet 3] --> B
  B --> E[eth0: tx pkt 1]
  B --> F[eth1: tx pkt 2]
  B --> G[eth0: tx pkt 3]

Transmits packets in round-robin order across slaves. Slaves alternate strictly: packet 1 on eth0, packet 2 on eth1, packet 3 on eth0, and so on. This is the only mode that can increase throughput for a single TCP flow at the slave level, but the switch must not enforce a LAG on the receiving ports for this to be useful for ingress.

PropertyValue
BandwidthSum of slaves, both directions in theory
Switch dependencyNone — works against any switch
FailoverPer-packet; one slave dies, rest of traffic continues
Cisco interopOften fails — Cisco switches expect all frames in a flow from the same port
Frame orderingOut-of-order between slaves — breaks some TCP receivers

The TCP-reordering problem is the deal-breaker for most production use. Some receivers re-order aggressively and lose throughput; some drop out-of-order frames entirely. balance-rr is rare in production except for very specific custom switch setups.

Mode 1 — active-backup

flowchart LR
  A[All traffic] --> B[bond0]
  B --> C[eth0: active]
  B -. failover .-> D[eth1: backup]
  E[eth0 dies] --> F[eth1 becomes active]

Only one slave is active at a time. The other slaves are hot-standby. If the active slave fails, the bond fails over to the next available slave. No switch configuration is required.

PropertyValue
BandwidthOne slave — no aggregation
Switch dependencyNone — works against any switch
FailoverSub-second with MII monitoring
Use caseHA pair where bandwidth is not the constraint

This is the default mode when you do not specify one. Production users who do not need bandwidth but want failover pick this mode. It is the most boring mode, and boring is good.

Mode 2 — balance-xor

flowchart LR
  A[Src+dst MAC<br/>XOR hash] --> B[bond0]
  B --> C[eth0: conversation 1]
  B --> D[eth1: conversation 2]
  B --> E[eth0: conversation 3]

Selects a slave for each frame based on the XOR of source and destination MAC addresses. The same source+destination pair always goes to the same slave. The switch must not enforce LAG behaviour that requires aggregation, but it can be configured statically.

PropertyValue
BandwidthSum of slaves, but only across multiple conversations
Switch dependencyStatic LAG on the switch works
FailoverThe slave for a conversation dies; conversations rebalance
Frame orderingPreserved within a conversation

This is essentially a static LAG without LACP. The switch is configured to put the ports in a channel group, but no protocol runs between the two ends. It is what you use when the switch does not support LACP but does support static LAG.

Mode 3 — broadcast

flowchart LR
  A[Frame] --> B[bond0]
  B --> C[eth0: copy]
  B --> D[eth1: copy]
  B --> E[eth2: copy]

Every frame is sent on every slave. Used for specific scenarios where redundancy is more important than bandwidth, like a heartbeat link between two high-availability nodes. It is rare and not on the standard menu, but the kernel driver supports it.

Mode 4 — 802.3ad (LACP)

sequenceDiagram
  participant VyOS as VyOS bond0
  participant SW as Switch LAG
  VyOS->>SW: LACPDU (active)
  SW->>VyOS: LACPDU (active)
  VyOS->>SW: LACPDU (slow: 30s)
  Note over VyOS,SW: Aggregated.<br/>Hash selects slave per flow.
  SW->>VyOS: Slave eth0 down
  VyOS->>VyOS: Re-hash flows<br/>across remaining slaves

The IEEE 802.3ad / 802.1AX standard. The two ends exchange LACP Data Units (LACPDU) every second (fast) or 30 seconds (slow). The switch and the host agree on the aggregation, and frames for a given conversation always go to the same slave per the hash policy. This is the most common production mode.

PropertyValue
BandwidthSum of slaves, across multiple conversations
Switch dependencyLACP must be configured on the switch
FailoverLACP detects slave death in ~1s (fast) or up to 30s (slow)
Frame orderingPreserved within a conversation

Mode 5 — balance-tlb (transmit load balancing)

flowchart LR
  A[TX frames] --> B[bond0]
  B --> C[eth0: speed 1000<br/>load 0.4]
  B --> D[eth1: speed 1000<br/>load 0.6]
  B --> E[Re-balance: more frames to eth0]

The driver distributes outbound traffic based on the current load on each slave. Each slave is assigned a percentage of outgoing frames based on its speed and counters. The switch does not need to know it is a bond — the slaves appear as independent ports. Receive is on a single slave (typically the first one).

PropertyValue
BandwidthSum of slaves for TX, one slave for RX
Switch dependencyNone
FailoverDriver detects via MII; failover sub-second
CaveatAsymmetric: TX aggregated, RX not

This mode is useful when the switch does not support LACP but the operator wants more TX bandwidth than active-backup provides. Receivers see all traffic from the same MAC, so the switch does not need to know the ports are related.

Mode 6 — balance-alb (adaptive load balancing)

flowchart LR
  A[TX frames] --> B[bond0]
  B --> C[eth0: tx]
  B --> D[eth1: tx]
  E[RX frames] --> F[bond0]
  F --> G[eth0: rx]
  F --> H[eth1: rx via ARP negotiation]

Extends balance-tlb by also load-balancing receive. The driver does this by sending ARP replies with different source MAC addresses to different peers, so the switch learns different MACs on different ports. The driver monitors ARP traffic and adapts.

PropertyValue
BandwidthSum of slaves for both TX and RX
Switch dependencyNone
FailoverMII monitoring; sub-second
CaveatARP manipulation breaks on some routers and firewalls

balance-alb is rare in 2026 because the assumption “the switch does not support LACP” is increasingly false. Modern switches — including the cheap ones — support LACP. The use case for balance-alb has shrunk to legacy networks where the switch is indeed an unmanaged Layer 2 hub.

Mode summary table

ModeBond nameBWSwitchFailoverUse case
0balance-rrsumanyyesSpecial; rarely used
1active-backuponeanyyesHA without bandwidth need
2balance-xorsumstatic LAGyesSwitch without LACP
3broadcastoneanyyesHeartbeat
4802.3adsumLACPyesProduction default
5balance-tlbsum TXanyyesTX aggregation only
6balance-albsumanyyesLegacy, no LACP

Configuration in VyOS 1.5 LTS

The mode is set with set interfaces bonding bondN mode '...':

[edit]
vyos@vyos# set interfaces bonding bond0 mode '802.3ad'
[edit]
vyos@vyos# set interfaces bonding bond0 lacp-rate 'fast'
[edit]
vyos@vyos# set interfaces bonding bond0 hash-policy 'layer3+4'
[edit]
vyos@vyos# set interfaces bonding bond0 member interface eth0
[edit]
vyos@vyos# set interfaces bonding bond0 member interface eth1
[edit]
vyos@vyos# set interfaces bonding bond0 address '192.0.2.1/24'
[edit]
vyos@vyos# commit
[edit]
vyos@vyos# save

The mode value is the literal string the kernel driver expects (balance-rr, active-backup, balance-xor, 802.3ad, balance-tlb, balance-alb, broadcast). The lacp-rate only applies to mode 4. The hash-policy controls the conversation hash and applies to modes that use hashing.

[edit]
vyos@vyos# set interfaces bonding bond0 mode 'active-backup'
[edit]
vyos@vyos# set interfaces bonding bond0 primary 'eth0'
[edit]
vyos@vyos# commit
[edit]
vyos@vyos# save

For active-backup, the primary directive sets the preferred active slave. On commit, the primary is made active; on failure the next available slave takes over; on primary recovery, the bond does NOT automatically revert unless primary is configured with primary-reselect 'always'.

Validation

vyos@vyos:~$ show bonding

The first command shows the VyOS-level view of the bond. The mode is reported, the slave count, and the aggregate speed.

vyos@vyos:~$ cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v6.6

Bonding Mode: IEEE 802.3ad Dynamic Link Aggregation
LACP rate: fast
LACP active: on
...
Slave Interface: eth0
MII Status: up
...
Slave Interface: eth1
MII Status: up
...

The second command shows the kernel driver state. The mode and the slave status are visible. This is the canonical source of truth.

How it fails

The production failure modes the engineer must recognise:

  • Wrong mode for the switch. 802.3ad configured on the host but the switch ports are access — LACP never converges.
  • balance-rr on a switch that does not accept frame-by-frame distribution. Frames dropped or flagged as errors on the switch.
  • balance-alb with ARP-inspecting firewall. The constant ARP-source-shifting breaks stateful inspection rules.
  • Mode change without reloading the driver. Changing the mode from active-backup to 802.3ad requires reloading the bonding driver. VyOS does this on commit, but misordered commits can leave the bond in the wrong mode.
  • Primary slave configured but the primary is the one that fails. The primary directive is a preference, not a forced active state. The driver will still fail over if the primary goes down.

Rollback

The recovery from a bad mode configuration:

  • Wrong mode: set interfaces bonding bond0 mode 'active-backup'; commit; save.
  • Driver not reloaded: sudo ifdown bond0; sudo ifup bond0 or reboot.
  • Slave in wrong state: bring the slave down with set interfaces ethernet ethN disable; commit; save, then investigate.

Production discipline

Cross-course references

The Linux course’s XIX-Linux-NetFoundations covers the kernel bonding driver in detail. The Proxmox course’s XXIX-Proxmox-Networking covers host-side bonding for hypervisor bridges. The Ansible course’s XLII-Ansible-BeyondLinux covers configuration management of bonds across fleets.

Quiz

Knowledge check · 4 questions

  1. Q1. Which bond mode requires the switch to be configured for LACP?

  2. Q2. balance-rr can deliver the frames of a single TCP conversation out of order across slaves.

  3. Q3. An operator configures a bond with mode 802.3ad and the switch as access ports. The bond never converges. What is the issue and how is it fixed?

    The host is sending LACPDU but the switch is treating the ports as access. The switch never engages LACP. The bond stays in the no-aggregation state.

  4. Q4. A bond is configured as balance-tlb. Outbound throughput is aggregated, but inbound throughput is limited to one slave. The operator wants full bidirectional aggregation. What are the options?

    balance-tlb aggregates TX only. RX is on a single slave. The operator wants symmetric aggregation but the switch does not support LACP.

Passing score: 75%. Answers are checked in this browser.