openwrt 网络故障自动切换脚本

首页 / 默认分类 / 正文
#!/bin/bash

# Configuration
LOG_FILE="/var/log/network_failover.log"
PING_TARGET="223.5.5.5"
CHECK_INTERVAL=5
FAILURE_THRESHOLD=3
PRIMARY_IF="wan"
BACKUP_IF="wwan"
PRIMARY_CHECK_INTERVAL=30

# Initialize
failure_count=0
using_backup=0
last_primary_check=$(date +%s)

# Logger
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE"
}

# Primary interface check
check_primary() {
    if ping -I $PRIMARY_IF -c 2 -W 3 "$PING_TARGET" >/dev/null 2>&1; then
        log "Primary interface test PASSED"
        return 0
    else
        log "Primary interface test FAILED"
        return 1
    fi
}

# Normal network check
check_network() {
    if ping -c 1 -W 2 "$PING_TARGET" >/dev/null 2>&1; then
        return 0
    else
        return 1
    fi
}

switch_network() {
    case "$1" in
        "backup")
            log "Switching to backup network..."
            uci set network.$PRIMARY_IF.metric=100
            uci set network.$BACKUP_IF.metric=10
            ;;
        "primary")
            log "Reverting to primary network..."
            uci set network.$PRIMARY_IF.metric=10
            uci set network.$BACKUP_IF.metric=100
            ;;
    esac

    if uci commit network && /etc/init.d/network reload; then
        log "Switch successful"
        return 0
    else
        log "Switch failed!"
        return 1
    fi
}

# Main loop
log "Failover system started (Primary: $PRIMARY_IF, Backup: $BACKUP_IF)"
while true; do
    current_time=$(date +%s)
    
    if [ "$using_backup" -eq 1 ]; then
        # Backup mode: check primary interface periodically
        if [ $((current_time - last_primary_check)) -ge $PRIMARY_CHECK_INTERVAL ]; then
            if check_primary; then
                if switch_network "primary"; then
                    using_backup=0
                    failure_count=0
                fi
            fi
            last_primary_check=$current_time
        fi
    else
        # Primary mode: normal network check
        if ! check_network; then
            failure_count=$((failure_count + 1))
            log "Failure detected ($failure_count/$FAILURE_THRESHOLD)"
            
            if [ "$failure_count" -ge "$FAILURE_THRESHOLD" ]; then
                if switch_network "backup"; then
                    using_backup=1
                    failure_count=0
                    last_primary_check=$current_time
                fi
            fi
        else
            [ "$failure_count" -gt 0 ] && log "Network restored"
            failure_count=0
        fi
    fi
    
    sleep $CHECK_INTERVAL
done
无标签
评论区
头像