Skip to main content
RunBook Academy

VyOSX · Bonding and Link AggregationBonding

Bond validation — /proc/net/bonding, show bonding, throughput testing

Advanced⏱ ~18 mincat /proc/net/bondingshow bondingip -s link show bond0ethtool -S eth0iperf3

What you'll learn

  • Run the canonical validation command set for a bond
  • Read the kernel driver state from /proc/net/bonding
  • Cross-check the host and switch counters
  • Run a throughput test that proves the aggregate is working
  • Build a validation script that runs the full set on demand

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 validation — /proc/net/bonding, show bonding, throughput testing

A bond that is “up” is not necessarily a bond that is working. The bond may be up but the aggregation may be broken, the slave may be silently degraded, or the switch-side may not match the host-side. The validation command set is what proves the bond is doing what the configuration says. This lesson walks through the canonical commands, the cross-check with the switch, and the throughput test that proves the aggregate.

The validation command set

flowchart TD
  A[Bond validation] --> B[Host side]
  A --> C[Switch side]
  B --> B1[cat /proc/net/bonding/bond0]
  B --> B2[show bonding]
  B --> B3[ip -s link show bond0]
  B --> B4[ip -s link show eth0]
  B --> B5[ip -s link show eth1]
  B --> B6[ethtool eth0]
  B --> B7[ethtool eth1]
  B --> B8[iperf3 to peer]
  C --> C1[show etherchannel summary]
  C --> C2[show etherchannel detail]
  C --> C3[show interfaces counters]
  C --> C4[show spanning-tree]

The host side has six commands. The switch side has four. The host-side set is the canonical truth; the switch-side is the cross-check.

Command 1 — cat /proc/net/bonding/bond0

This is the canonical source of truth. The kernel driver writes its state to this file on every state change.

vyos@vyos:~$ sudo 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
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0

Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0

What to check:

  • Bonding Mode: — must match the configuration.
  • LACP active: — must be on for 802.3ad.
  • MII Status: on each slave — must be up.
  • Speed: on each slave — must match.
  • Link Failure Count: — should be 0 in steady state.
  • Aggregator ID: on each slave — must be the same non-zero number.

Command 2 — show bonding

The VyOS-level wrapper around /proc/net/bonding:

vyos@vyos:~$ show bonding
Interface   Mode        Slaves  Speed
bond0       802.3ad     2       2000

This is the summary. The full state is via show bonding detail:

vyos@vyos:~$ show bonding detail

What to check:

  • Mode: matches the configuration.
  • Slaves: matches the number of configured members.
  • Speed: is the aggregate of the slaves.

The kernel-level interface counters:

vyos@vyos:~$ ip -s link show bond0
3: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 9000 ...
    RX:  bytes  packets errors dropped  missed   mcast
         123456  1234    0      0       0       0
    TX:  bytes  packets errors dropped  carrier collsns
         234567  2345    0      0       0       0

What to check:

  • errors and dropped should be 0 in steady state.
  • carrier should be 0 — the bond is not losing carrier.
  • The bytes counter should grow at the expected rate during a throughput test.

The slave-level counters:

vyos@vyos:~$ ip -s link show eth0
4: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 9000 ...
    RX:  bytes  packets errors dropped  missed   mcast
         61728   617     0      0       0       0
    TX:  bytes  packets errors dropped  carrier collsns
         117283  1172    0      0       0       0

The slave counters should be roughly half of the bond counters (for a 2-slave bond). The ratio is the proof that both slaves are carrying traffic.

Command 5 — ethtool eth0 and eth1

The physical link state:

vyos@vyos:~$ ethtool eth0
Settings for eth0:
    Supported ports: [ TP ]
    Supported link modes:   1000baseT/Full
    Speed: 1000Mb/s
    Duplex: Full
    Port: Twisted Pair
    PHYAD: 0
    Link detected: yes

What to check:

  • Speed: — must match the configuration.
  • Duplex: — must be Full.
  • Link detected: — must be yes.

Command 6 — iperf3

The throughput test:

vyos@vyos:~$ iperf3 -c <peer> -t 30 -i 5
Connecting to host <peer>, port 5201
[  5]   0.00-5.00   sec   550 MBytes   922 Mbits/sec
[  5]   5.00-10.00  sec   549 MBytes   921 Mbits/sec
[  5]  10.00-15.00  sec   550 MBytes   922 Mbits/sec
[  5]  15.00-20.00  sec   549 MBytes   921 Mbits/sec
[  5]  20.00-25.00  sec   550 MBytes   922 Mbits/sec
[  5]  25.00-30.00  sec   549 MBytes   921 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  5]   0.00-30.00  sec  3.22 GBytes   921 Mbits/sec
sender
[  5]   0.00-30.00  sec  3.22 GBytes   921 Mbits/sec
receiver

What to check:

  • Single-stream throughput should be near the speed of one slave (since TCP is single-streamed).
  • Multi-stream throughput (iperf3 -P 4) should reach the aggregate.
  • For a 2-slave 1 Gbps bond, the expected aggregate is ~1.8 Gbps (some overhead).

The switch-side cross-check

The host sees the bond. The switch sees the channel. The two must agree:

Cisco IOS
Switch# show etherchannel summary
Group  Port-channel  Protocol    Ports
------+-------------+-----------+---------------------
10     Po10(SU)       LACP       Eth1/1(P)  Eth1/2(P)

What to check:

  • The port-channel is SU (up, in layer-2 state).
  • The protocol is LACP.
  • The ports are P (bundled).
Arista EOS
Switch# show etherchannel summary
Group  Port-channel  Protocol    Ports
------+-------------+-----------+---------------------
10     Port-Channel10 LACP       Eth1(P)  Eth2(P)

Same layout, different syntax.

Switch# show interfaces counters

The interface counters on the switch must match the host-side counters within the normal asymmetric margin (different counter rollover timing, different MTU overhead calculation).

The validation script

The full validation runs the host-side and switch-side commands and reports the result:

#!/bin/bash
# validate-bond.sh — run the canonical validation command set
set -euo pipefail

BOND=${1:-bond0}
HOST=$(hostname)

echo "=== Host: $HOST ==="
echo ""
echo "--- /proc/net/bonding/$BOND ---"
sudo cat /proc/net/bonding/$BOND
echo ""
echo "--- show bonding ---"
show bonding
echo ""
echo "--- ip -s link show $BOND ---"
ip -s link show $BOND
echo ""
echo "--- ip -s link show eth0 ---"
ip -s link show eth0
echo ""
echo "--- ip -s link show eth1 ---"
ip -s link show eth1
echo ""
echo "--- ethtool eth0 ---"
ethtool eth0
echo ""
echo "--- ethtool eth1 ---"
ethtool eth1
echo ""
echo "--- Partner MAC consistency check ---"
PARTNER0=$(sudo grep -A2 "Slave Interface: eth0" /proc/net/bonding/$BOND | grep "Partner MAC" | awk '{print $3}')
PARTNER1=$(sudo grep -A2 "Slave Interface: eth1" /proc/net/bonding/$BOND | grep "Partner MAC" | awk '{print $3}')
if [ "$PARTNER0" = "$PARTNER1" ]; then
  echo "Both slaves peer with the same switch ($PARTNER0)"
else
  echo "Slaves peer with different switches ($PARTNER0 vs $PARTNER1) — MLAG case"
fi
echo ""
echo "=== End of validation ==="

The script writes the full output to a file, which the operator can attach to the change record. The change-control process always includes the validation output.

Throughput test methodology

The throughput test is the proof that the aggregate is working. The methodology:

  1. Baseline — run iperf3 -c <peer> -t 60 -P 1 between the host and a known peer. Record the throughput.
  2. Parallel streams — run iperf3 -c <peer> -t 60 -P 4. The throughput should be roughly 4x the single-stream.
  3. Reverse direction — run iperf3 -c <peer> -t 60 -R to test the return direction.
  4. Compare — the throughput should be near the aggregate of the slaves. For a 2-slave 1 Gbps bond, expect ~1.8 Gbps.
vyos@vyos:~$ iperf3 -c <peer> -t 60 -P 4

The -P 4 runs four parallel streams. For a 2-slave bond, the four streams should distribute across the two slaves per the hash policy.

How it fails

The production validation failure modes the engineer must recognise:

  • /proc says up but throughput is half. The bond is up but only one slave is carrying traffic. The hash policy is likely misconfigured.
  • Switch P flag missing. The port-channel is up but one port is not bundled. The LACP negotiation is failing.
  • MTU mismatch on validation. The ping -M do -s 8972 fails. The MTU chain is broken.
  • Speed mismatch. One slave is 100 Mbps and another is 1 Gbps. The aggregation is at the lowest speed.
  • Counter mismatch. The host counter and switch counter differ by more than the expected margin. The bridge is dropping frames.

Rollback

The recovery from a failed validation:

  • Re-run the validation to confirm the failure mode.
  • Identify which command output is wrong.
  • Apply the remediation for that mode:
    • Wrong mode: set interfaces bonding bond0 mode '...'; commit; save.
    • Wrong hash policy: set interfaces bonding bond0 hash-policy '...'; commit; save.
    • Wrong MTU: set interfaces bonding bond0 mtu '...'; commit; save.
  • Re-run the validation to confirm the fix.

Production discipline

Cross-course references

The Linux course’s XXII-Linux-NetTroubleshoot covers the counter and diagnostic discipline. The Observability course’s XLIX-Observability-NetMetrics covers the dashboard and alerting side. The Ansible course’s XLII-Ansible-BeyondLinux covers the script automation and CI integration.

Quiz

Knowledge check · 4 questions

  1. Q1. What is the canonical source of truth for the bond state on a VyOS host?

  2. Q2. A bond of two 1 Gbps slaves carries a single TCP stream at roughly 1 Gbps, not 2 Gbps.

  3. Q3. The bond is up per `/proc/net/bonding/bond0`. The throughput test shows 940 Mbps on a single stream but only 1.1 Gbps on four parallel streams. What is the issue?

    The single-stream throughput is 940 Mbps, which is near the speed of one slave. The parallel-stream throughput is 1.1 Gbps, which is barely above the speed of one slave. The expected aggregate is ~1.8 Gbps.

  4. Q4. The validation script shows the bond is up with both slaves up. The throughput test shows the expected aggregate. After one monitoring cycle, the post-validation output shows one slave went down. What is the next step?

    The post-change validation was clean. After one monitoring cycle, the post-validation shows one slave down. The bond is degraded but the other slave is still up.

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