#!/usr/bin/env bash # # JbTecWiz Support Centre -- generated fix script # # Fault : Bonded or teamed interfaces will not come up, or run at one link's speed # Fix : Get both ends agreeing # Source: https://jbtecwiz.com/support/lnx-net-bonding # # Run as : Root shell and the switch # Expect : 40 minutes # Risk : high # Reversible : yes # # WHEN THIS IS THE RIGHT FIX # The bond is down or only one link is active. # # HOW TO UNDO IT # nmcli connection delete removes the bond and its slaves, returning the # interfaces to standalone. # # Walks the fix one step at a time and asks before each. Steps with no # command are yours to do -- it prints those and waits. DRYRUN=1 prints # without executing; UNATTENDED=1 does not ask. # # -------------------------------------------------------------------- # NO WARRANTY - USE AT YOUR OWN RISK # # This script is provided by JbTecWiz as-is and with no warranty of any # kind, express or implied. You run it entirely at your own risk. # # JbTecWiz accepts no liability for any loss or damage arising from its # use, including but not limited to data loss, downtime, or configuration # changes that turn out to be wrong for your system. # # You are responsible for reading this script before running it, for # satisfying yourself that it suits the machine in front of you, and for # having a working backup first. Some steps cannot be undone. # -------------------------------------------------------------------- set -uo pipefail DRYRUN="${DRYRUN:-0}" UNATTENDED="${UNATTENDED:-0}" failed=0 if [ "$(id -u)" -ne 0 ]; then echo " This fix is documented as needing root. Re-run with sudo." >&2 exit 3 fi rule() { printf "\n%s\n" "$(printf '-%.0s' $(seq 1 70))"; if [ $# -gt 0 ]; then echo "$1"; fi; } prose() { echo "$1" | fold -s -w 74 | sed "s/^/ /"; } # Returns 0 when the caller should run the command, 1 when it should not. # A manual step always returns 1 -- there is nothing for the caller to run. step() { # step [command lines...] local n="$1" dotext="$2" why="$3" mode="$4"; shift 4 rule " Step $n of 5" prose "$dotext" if [ -n "$why" ]; then echo; prose "$why"; fi if [ "$mode" = "manual" ]; then echo; echo " -> Do this yourself, then press Enter to carry on." if [ "$UNATTENDED" = "0" ] && [ "$DRYRUN" = "0" ]; then read -r _; fi return 1 fi echo; printf " %s\n" "$@"; echo if [ "$DRYRUN" = "1" ]; then echo " (dry run -- not executed)"; return 1; fi if [ "$UNATTENDED" = "0" ]; then read -r -p " Run this step? [Y]es / [S]kip / [Q]uit " a case "$a" in [Qq]*) echo " Stopped at your request."; exit 0 ;; [Ss]*) echo " Skipped."; return 1 ;; esac fi return 0 } rule echo " Bonded or teamed interfaces will not come up, or run at one link'\''s speed" echo " Get both ends agreeing" echo echo " Risk: high Reversible 40 minutes" echo prose 'No warranty. Use at your own risk - JbTecWiz accepts no liability. Read it before you run it, and have a backup.' rule echo if [ "$UNATTENDED" = "0" ] && [ "$DRYRUN" = "0" ]; then read -r -p " Ready? [y/N] " go case "$go" in [Yy]*) ;; *) echo " Nothing was changed."; exit 0;; esac fi if step 1 'Read the bond'\''s own status file, which states exactly what the switch is or is not saying.' 'The partner MAC and partner key fields are the answer. All zeros means the switch is not speaking LACP on those ports at all, which is a switch configuration job, not a Linux one.' cmd 'cat /proc/net/bonding/bond0'; then cat /proc/net/bonding/bond0 if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 1 failed. The rest of the fix may depend on it." >&2 fi fi step 2 'Check the mode. Mode 4 (802.3ad) requires the switch to be configured with a matching port-channel; modes 1 (active-backup) and 6 (balance-alb) do not.' '' manual || true if step 3 'If the switch cannot be configured, use active-backup, which needs nothing from the switch and gives redundancy without extra throughput.' '' cmd 'sudo nmcli connection add type bond con-name bond0 ifname bond0 bond.options '\''mode=active-backup,miimon=100'\'''; then sudo nmcli connection add type bond con-name bond0 ifname bond0 bond.options 'mode=active-backup,miimon=100' if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 3 failed. The rest of the fix may depend on it." >&2 fi fi step 4 'For LACP, configure the switch ports into a channel group first, then bring the bond up -- bringing up an unconfigured bond against a switch can create a loop.' '' manual || true if step 5 'Add the slaves.' '' cmd 'sudo nmcli connection add type ethernet slave-type bond con-name bond0-p1 ifname enp1s0 master bond0' 'sudo nmcli connection add type ethernet slave-type bond con-name bond0-p2 ifname enp2s0 master bond0' 'sudo nmcli connection up bond0'; then sudo nmcli connection add type ethernet slave-type bond con-name bond0-p1 ifname enp1s0 master bond0 sudo nmcli connection add type ethernet slave-type bond con-name bond0-p2 ifname enp2s0 master bond0 sudo nmcli connection up bond0 if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 5 failed. The rest of the fix may depend on it." >&2 fi fi rule " Confirm it worked" prose 'Both slaves report active and the partner details are populated.' if [ "$DRYRUN" = "0" ]; then cat /proc/net/bonding/bond0 | grep -E 'Slave Interface|MII Status|Partner Mac' fi rule if [ "$failed" -gt 0 ]; then echo " Finished with $failed failed step(s)." echo " Read the full write-up at https://jbtecwiz.com/support/lnx-net-bonding" else echo " Finished." fi echo prose 'To undo: nmcli connection delete removes the bond and its slaves, returning the interfaces to standalone.' rule