Skip to content

feat: Add NIC link aggregation (bonding) with 802.3ad LACP support#254

Open
kcirtapfromspace wants to merge 5 commits intoturing-machines:masterfrom
kcirtapfromspace:feature/nic-link-aggregation
Open

feat: Add NIC link aggregation (bonding) with 802.3ad LACP support#254
kcirtapfromspace wants to merge 5 commits intoturing-machines:masterfrom
kcirtapfromspace:feature/nic-link-aggregation

Conversation

@kcirtapfromspace
Copy link

@kcirtapfromspace kcirtapfromspace commented Jan 12, 2026

Summary

  • Enables 2Gbps link aggregation by bonding ge0 and ge1 NICs
  • Supports 802.3ad LACP for true aggregate bandwidth with compatible switches
  • Persists across reboots via S45bonding init script
  • Configurable via /etc/bonding.conf or web UI integration

Changes

Backend

  • S45bonding: New init script that configures bonding after network init
  • S00dsa: Removed hardcoded mode=balance-alb from modprobe to allow any mode
  • bonding.conf: Configuration file for bonding mode selection (default: active-backup)
  • bonding.enabled: Marker file to enable/disable bonding
  • Fixed: DSA ports ge0/ge1 share same MAC by default - now sets unique MAC on ge1

Web UI / API Integration

  • network_config.rs: Rust module providing REST API endpoints
    • GET /api/bmc?opt=get&type=network_config - Returns current bonding status
    • GET /api/bmc?opt=set&type=network_config&enabled=1&mode=802.3ad&apply=1 - Configure bonding
  • add_network_config.py: Build script to patch bmcd with API handlers
  • BMC-UI: Custom build with Network Settings page
  • Web UI: Accessible at https://turingpi → Network tab

API Response

{
  "bonding_enabled": true,
  "bonding_mode": "802.3ad",
  "bonding_active": true,
  "slaves": ["ge0", "ge1"],
  "miimon": 100
}

Supported Bonding Modes

Mode Name Switch Config Required
0 balance-rr Yes (aggregate)
1 active-backup No
2 balance-xor Yes (aggregate)
3 broadcast No
4 802.3ad Yes (LACP)
5 balance-tlb No
6 balance-alb No

Usage

Bonding is enabled by default with active-backup mode (safe default). To change mode:

echo "802.3ad" > /etc/bonding.conf
/etc/init.d/S45bonding restart

To disable bonding:

rm /etc/bonding.enabled
reboot

Test Plan

  • Tested active-backup mode (failover)
  • Tested balance-alb mode (adaptive load balancing)
  • Tested 802.3ad LACP with UniFi USW Pro Max 24 PoE
  • Verified reboot persistence
  • Verified flashing to internal storage via UBI
  • Verified Web UI Network tab loads and displays bonding status
  • Verified Web UI can change bonding mode and apply changes

Related PRs

🤖 Generated with Claude Code

kcirtapfromspace and others added 5 commits January 10, 2026 21:08
Enable 2Gbps aggregate link using both ge0 and ge1 NICs via Linux bonding.

Changes:
- Add CONFIG_BONDING=m to kernel defconfig
- Add bonding module to /etc/modules for auto-load
- Configure bond0 interface with balance-alb mode (no switch config required)
- Update br0 bridge to use bond0 as uplink instead of individual ge0/ge1
- Add setup_bonding() function to S00dsa init script
- Add migration helper for legacy configs

The bond0 interface aggregates ge0 and ge1, providing:
- Automatic failover if one link fails
- Load balancing for outbound traffic (balance-alb mode)
- No upstream switch configuration required

Alternative modes can be configured in /etc/network/interfaces:
- active-backup: failover only
- 802.3ad: LACP (requires switch support for true 2Gbps)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement 2Gbps link aggregation by bonding ge0 and ge1 NICs with support
for multiple bonding modes including 802.3ad LACP.

Backend Changes:
- Add S45bonding init script for proper bonding setup after network init
- Remove hardcoded balance-alb mode from S00dsa modprobe command
- Add /etc/bonding.conf for runtime mode configuration
- Add /etc/bonding.enabled marker file to enable/disable bonding
- Fix DSA port MAC address conflict (ge1 gets unique MAC)

Web UI/API Integration:
- Add network_config.rs Rust module with REST API endpoints:
  - GET /api/network_config - Retrieve current bonding status
  - POST /api/network_config - Set bonding mode and apply
- Add add_network_config.py to patch bmcd with API handlers
- API returns: bonding_enabled, bonding_mode, bonding_active, slaves, miimon
- Web UI accessible at System > Network Settings

Supported Bonding Modes:
  - balance-rr (0): Round-robin - requires switch support
  - active-backup (1): Failover only - works with single cable
  - balance-xor (2): XOR hashing - requires switch support
  - broadcast (3): All slaves transmit
  - 802.3ad (4): LACP - requires switch LACP support
  - balance-tlb (5): Transmit load balancing
  - balance-alb (6): Adaptive load balancing - no switch config

Architecture:
  Web Browser → BMC-UI (http://turingpi) → REST API → bmcd daemon
    → network_config.rs → /etc/bonding.conf → S45bonding → bond0

The default mode is 802.3ad LACP which provides true 2Gbps aggregate
bandwidth when paired with a switch configured for LACP.

Tested with UniFi USW Pro Max 24 PoE switch.
Flashed to internal storage via UBI and verified persistence.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Active-backup is safer as it works without any switch configuration.
Users can switch to 802.3ad once their switch is configured for LACP.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Include pre-built BMC-UI assets with the Network tab for configuring
link aggregation (bonding) between ge0 and ge1.

UI Features:
- Network tab in navigation bar
- Enable/disable bonding toggle
- Bonding mode selector (7 modes: active-backup, balance-rr,
  balance-xor, broadcast, 802.3ad, balance-tlb, balance-alb)
- Current status display (active/inactive, mode, slave interfaces)
- Mode descriptions with switch requirement indicators
- Translations for en, de, es, nl, pl, zh-Hans

The UI calls the REST API endpoints:
- GET /api?cmd=network_config - Retrieve current config
- GET /api?cmd=network_config&enabled=X&mode=X&apply=X - Set config

Based on BMC-UI v3.3.6 with network bonding additions.
Source: https://github.com/kcirtapfromspace/BMC-UI/tree/feature/network-bonding-ui

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rebuild BMC-UI with corrected API endpoint format for network config.
The network bonding configuration page now properly communicates with
bmcd using the standard /api/bmc?opt=get&type=network_config format.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hungerf3
Copy link

hungerf3 commented Jan 18, 2026

I did some testing of this pull request.

The Good News: LACP negotiation was successful, and when testing from the BMC, the other modes seemed to work.
The Bad News: Only the BMC network worked; the nodes couldn't talk to the outside world. I saw the links come up, but they were unable to reach the DHCP server. As far as I could tell, they were unable to talk to anything off of the board.

Is there any special configuration needed on the nodes when link aggregation is enabled?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the bonding config be done before we configure the network?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this patch is mixing up functionalitiy which would actually be in ifupdown-ng. If you have template-able split files like shown in #196 , then you would only need init.d/network, and could kill dsa and bonding init scripts.
The way it is implemented it is needed, as it splits out ge0/1 into a seperate interfaces, might work but not nice. IMHO

@j0ju
Copy link

j0ju commented Jan 26, 2026

This patch assumes, that in kernel DSA is working with VLAN and link-aggregation support from the switch driver.
In the current state it does not work. I just isolates ge0/ge1 from the node ports. So you have no connectivity at all.
I am curious dd you test it? and how was your test config? @kcirtapfromspace

@svenrademakers
Copy link
Collaborator

Fyi, Im able to approve this PR as soon as its working on main. Let me know of you require some testing as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants