#!/bin/bash

# 检查是否提供了足够的参数
if [ "$#" -ne 2 ]; then
    echo "Usage: $0 <interface_name> <gateway_address>"
    exit 1
fi

# 获取参数
INTERFACE_NAME="$1"
GATEWAY="$2"

# 检查网关的可达性
echo "正在检查网关 $GATEWAY 的可达性..."
if ! ping -c 4 "$GATEWAY" > /dev/null 2>&1; then
    echo "Error: 无法访问网关 $GATEWAY,请确保网关地址正确并可达"
    exit 1
fi

# 检查网卡类型和成员数量
if ! [[ "$INTERFACE_NAME" =~ ^(team|bond)[0-9]+$ ]]; then
    echo "Error: 提供的网卡名称不合规,请使用类似 'teamX' 或 'bondX' 的格式"
    exit 1
fi

# 检查网卡是否存在
if ! ip link show "$INTERFACE_NAME" > /dev/null 2>&1; then
    echo "Error: 提供的网卡 $INTERFACE_NAME 在主机上不存在"
    exit 1
fi

# 获取网卡成员数量
INTERFACE_MEMBERS_COUNT=0
if [ "${INTERFACE_NAME:0:4}" == "team" ]; then
    INTERFACE_TYPE="team"
    INTERFACE_MEMBERS_COUNT=$(sudo teamdctl "$INTERFACE_NAME" state dump | grep -oP 'port ifname.*' | wc -l)
elif [ "${INTERFACE_NAME:0:4}" == "bond" ]; then
    INTERFACE_TYPE="bond"
    INTERFACE_MEMBERS_COUNT=$(cat "/proc/net/bonding/$INTERFACE_NAME" | grep -oP 'Slave Interface:' | wc -l)
else
    echo "Error: 不支持的接口类型"
    exit 1
fi

if [ $INTERFACE_MEMBERS_COUNT -ne 2 ]; then
    echo "Error: 提供的 $INTERFACE_TYPE 网卡 $INTERFACE_NAME 不是由两块网卡绑定而成"
    exit 1
fi

# 定义日志文件路径
LOG_FILE="/var/log/network_test.log"

# 函数:检查命令执行结果
check_command_result() {
    if [ $? -ne 0 ]; then
        echo "Error: 命令执行失败"
        exit 1
    fi
}

# 函数:获取当前活跃的接口成员
get_active_member() {
    if [ "$INTERFACE_TYPE" == "team" ]; then
        ACTIVE_MEMBER=$(sudo teamdctl "$INTERFACE_NAME" state dump | grep -oP 'active ifname.*\K\w+')
    elif [ "$INTERFACE_TYPE" == "bond" ]; then
        ACTIVE_MEMBER=$(cat "/proc/net/bonding/$INTERFACE_NAME" | grep -oP 'Currently Active Slave:.*\K\w+')
    else
        echo "Error: 不支持的接口类型"
        exit 1
    fi

    echo "$ACTIVE_MEMBER"
}

# 函数:down指定的接口成员
down_active_interface() {
    ACTIVE_MEMBER=$(get_active_member)
    if [ -n "$ACTIVE_MEMBER" ]; then
        echo "当前活跃的接口成员为 $ACTIVE_MEMBER"
        down_interface "$ACTIVE_MEMBER"
    else
        echo "Error: 无法获取当前活跃的接口成员"
        exit 1
    fi
}

# 函数:up指定的接口成员
up_interface() {
    echo "正在将接口 $1 启用..."
    ip link set dev "$1" up
    check_command_result
}

# 函数:测试接口成员,down后ping测试
test_interface() {
    down_active_interface
    sleep 5  # 可根据实际情况调整等待时间
    up_interface "$(get_active_member)"

    # Ping测试
    echo "正在进行 $(get_active_member) 的ping测试..."
    ping -c 4 "$GATEWAY" > /dev/null 2>&1  # 可根据实际情况调整ping的次数
    if [ $? -ne 0 ]; then
        echo "$(date): $(get_active_member) ping测试失败,无法访问网关 $GATEWAY" >> "$LOG_FILE"
        echo "恢复 $(get_active_member) ..."
        up_interface "$(get_active_member)"
        exit 1
    fi
}

# 主程序

# 执行测试任务,并将输出追加到日志文件
for ((i=0; i<5; i++)); do  # 这里执行5次,你可以根据实际情况调整
    test_interface
    echo "$INTERFACE_TYPE 网卡冗余性测试完成" | tee -a "$LOG_FILE"
done