Last active
September 14, 2026 15:07
-
-
Save wudi/083c0be0286b5da300021dba727bf586 to your computer and use it in GitHub Desktop.
Netgear R8500 路由器 OpenWRT 5G信号 看门狗
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # Restart R8500 5 GHz APs after brcmfmac firmware crash. | |
| # radio0 = NETGEAR_5G-2 (phy0), radio2 = NETGEAR_5G-1 (phy2) | |
| LOCK=/var/run/wifi5-watchdog.lock | |
| STATE_DIR=/tmp/wifi5-watchdog | |
| RESTART_LOG=$STATE_DIR/restarts | |
| MAX_RESTARTS_PER_HOUR=6 | |
| MISS_NEEDED=2 | |
| COOLDOWN_SEC=90 | |
| TAG=wifi5-watchdog | |
| mkdir -p "$STATE_DIR" | |
| if ! lock -n "$LOCK" 2>/dev/null; then | |
| exit 0 | |
| fi | |
| trap 'lock -u "$LOCK" 2>/dev/null' EXIT | |
| now=$(date +%s) | |
| if [ -f "$STATE_DIR/cooldown" ]; then | |
| cool=$(cat "$STATE_DIR/cooldown" 2>/dev/null) | |
| if [ -n "$cool" ] && [ $((now - cool)) -lt "$COOLDOWN_SEC" ]; then | |
| exit 0 | |
| fi | |
| fi | |
| iface_is_ap() { | |
| iw dev "$1" info 2>/dev/null | grep -q "type AP" | |
| } | |
| radio_enabled() { | |
| [ "$(uci -q get "wireless.${1}.disabled")" != "1" ] | |
| } | |
| prune_restarts() { | |
| [ -f "$RESTART_LOG" ] || return 0 | |
| awk -v now="$now" '$1 >= now-3600 { print }' "$RESTART_LOG" > "$RESTART_LOG.tmp" | |
| mv "$RESTART_LOG.tmp" "$RESTART_LOG" | |
| } | |
| too_many_restarts() { | |
| prune_restarts | |
| count=$(wc -l < "$RESTART_LOG" 2>/dev/null || echo 0) | |
| [ "$count" -ge "$MAX_RESTARTS_PER_HOUR" ] | |
| } | |
| record_restart() { | |
| echo "$now" >> "$RESTART_LOG" | |
| echo "$now" > "$STATE_DIR/cooldown" | |
| } | |
| restart_radio() { | |
| radio=$1 | |
| sta_guess=$2 | |
| if too_many_restarts; then | |
| logger -t "$TAG" "skip $radio: more than $MAX_RESTARTS_PER_HOUR restarts in 1h" | |
| return 1 | |
| fi | |
| logger -t "$TAG" "restarting $radio (5 GHz AP missing after firmware crash)" | |
| ip link del "$sta_guess" 2>/dev/null | |
| wifi down "$radio" | |
| sleep 2 | |
| wifi up "$radio" | |
| record_restart | |
| } | |
| check_radio() { | |
| radio=$1 | |
| expect_if=$2 | |
| sta_guess=$3 | |
| miss_file="$STATE_DIR/${radio}.miss" | |
| radio_enabled "$radio" || { | |
| rm -f "$miss_file" | |
| return 0 | |
| } | |
| ifname=$(ubus call network.wireless status 2>/dev/null | jsonfilter -e "@.${radio}.interfaces[0].ifname") | |
| [ -n "$ifname" ] || ifname=$expect_if | |
| if iface_is_ap "$ifname" || iface_is_ap "$expect_if"; then | |
| rm -f "$miss_file" | |
| return 0 | |
| fi | |
| miss=$(cat "$miss_file" 2>/dev/null || echo 0) | |
| miss=$((miss + 1)) | |
| echo "$miss" > "$miss_file" | |
| logger -t "$TAG" "$radio AP down ($ifname missing), miss=$miss/$MISS_NEEDED" | |
| if [ "$miss" -ge "$MISS_NEEDED" ]; then | |
| restart_radio "$radio" "$sta_guess" | |
| rm -f "$miss_file" | |
| fi | |
| } | |
| check_radio radio0 phy0-ap0 wlan0 | |
| check_radio radio2 phy2-ap0 wlan1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment