scripts/network-reset.sh

#!/usr/bin/env bash
# scripts/network-reset.sh
# Unstick a flaky wifi/ethernet link without rebooting. Tries, in
# order: nmcli device reapply, down/up of the primary connection, then
# a NetworkManager restart. Never dumps interface names to stdout
# unless -v is given.

set -euo pipefail

HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=/dev/null
. "${HERE}/lib/log.sh"

VERBOSE=0
while getopts ":v" opt; do
    case "${opt}" in
        v) VERBOSE=1 ;;
        *) ;;
    esac
done

conn=$(nmcli -t -f NAME,STATE,DEVICE connection show --active \
    | awk -F: '$2=="activated" {print $1; exit}')
if [[ -z "${conn}" ]]; then
    log_err "no active connection found"
    exit 1
fi

(( VERBOSE )) && log_info "active connection: ${conn}"

log_info "nmcli device reapply"
nmcli device reapply "$(nmcli -t -g GENERAL.DEVICES connection show "${conn}")" \
    || true

if ping -c1 -W2 1.1.1.1 >/dev/null 2>&1; then
    log_info "reapply fixed it"
    exit 0
fi

log_warn "bouncing ${conn}"
nmcli connection down "${conn}" || true
sleep 2
nmcli connection up "${conn}" || true

if ping -c1 -W2 1.1.1.1 >/dev/null 2>&1; then
    log_info "bounce fixed it"
    exit 0
fi

log_err "restarting NetworkManager"
systemctl restart NetworkManager