#!/usr/bin/env bash # Teardown bridge and restore interfaces # # Removes the transparent bridge, flushes ebtables rules, and restores # the original interface state. Safe to call even if the bridge is # already down or partially broken. set -uo pipefail # Note: no -e — we want all cleanup steps to run even if some fail BRIDGE="br0" echo "Tearing down bridge $BRIDGE" # -------------------------------------------------------------------------- # Identify bridge members before removal # -------------------------------------------------------------------------- MEMBERS=() if ip link show "$BRIDGE" &>/dev/null; then while IFS= read -r line; do iface=$(echo "$line" | awk '{print $2}' | tr -d ':') if [[ -n "$iface" ]]; then MEMBERS+=("$iface") fi done < <(bridge link show master "$BRIDGE" 2>/dev/null | grep -oP '^\d+:\s+\K\S+') fi # -------------------------------------------------------------------------- # Remove ebtables rules # -------------------------------------------------------------------------- if command -v ebtables &>/dev/null; then echo "Flushing ebtables rules" ebtables -F 2>/dev/null || true ebtables -X 2>/dev/null || true fi # -------------------------------------------------------------------------- # Bring bridge down # -------------------------------------------------------------------------- ip link set down dev "$BRIDGE" 2>/dev/null || true # -------------------------------------------------------------------------- # Remove interfaces from bridge and restore state # -------------------------------------------------------------------------- for iface in "${MEMBERS[@]}"; do echo "Restoring interface: $iface" # Remove from bridge ip link set "$iface" nomaster 2>/dev/null || true # Disable promiscuous mode ip link set "$iface" promisc off 2>/dev/null || true # Re-enable IPv6 sysctl -qw "net.ipv6.conf.${iface}.disable_ipv6=0" 2>/dev/null || true # Bring interface up (in case it was downed) ip link set up dev "$iface" 2>/dev/null || true done # -------------------------------------------------------------------------- # Delete bridge device # -------------------------------------------------------------------------- if ip link show "$BRIDGE" &>/dev/null; then ip link del "$BRIDGE" 2>/dev/null || true echo "Bridge $BRIDGE deleted" else echo "Bridge $BRIDGE already removed" fi # -------------------------------------------------------------------------- # Re-enable IPv6 globally on bridge name (cleanup) # -------------------------------------------------------------------------- sysctl -qw "net.ipv6.conf.${BRIDGE}.disable_ipv6=0" 2>/dev/null || true # -------------------------------------------------------------------------- # Verify cleanup # -------------------------------------------------------------------------- if ip link show "$BRIDGE" &>/dev/null; then echo "Warning: bridge $BRIDGE still exists after teardown" >&2 exit 1 else echo "Bridge teardown complete" exit 0 fi