同步桥接接口的状态

同步桥接接口的状态

我们拥有冗余的 10G 光纤链路,连接到上游互联网提供商,并采用主动/故障转移配置。在我们的路由器和上游路由器之间,我们有一对以透明模式运行 Vyos 的防火墙。我们使用 BGP 进行路由通告,并且我们无法更改大多数参数。

绘画:网络布局图

如果其中一个路由器的链路发生故障(例如,图中带有 的路由器x- 这恰好是我们最常见的故障类型),则整个网络将无法访问,直到 BGP 超时(最多 150 秒)。我已经知道,如果我们强制关闭桥另一侧的链路,我们的路由器将立即开始通过另一条链路转发流量。

如果防火墙桥接器的另一侧出现故障,是否有某种方法可以自动关闭该侧桥接器?

这个解决方案是否存在任何隐藏的陷阱?

答案1

我会在 VyOS 机器上运行一个脚本,检查上游连接的状态,然后根据需要在另一端执行ifdown/ 。ifup

最简单的方法是放入脚本/etc/network/if-down.d(检查关闭的接口是否是更新的一侧,并关闭另一侧)和/etc/network/if-up.d(检查开启的接口是否是更新的一侧,并开启另一侧)。
或者,您可以使用 cron(或 Systemd Timers,或任何类似的调度程序)每分钟运行一次监控脚本,或者您可以将其编写为休眠几秒钟的无限循环,以获得亚分钟级检查。

答案2

我编写了一个脚本,用于检查接口/sys以确定它们是否是桥接成员,然后反弹桥接。VyOS 用于netplugd监控接口,出于某种原因,我的脚本使它感到困惑(我可能会为此写一个单独的问题),但我认为这是一个很好的通用解决方案。

#!/bin/bash

## This script will bounce a br interface if a member interface goes down.
## This will cause router BGP timers to reset, making outages last only seconds instead of minutes.
##
## This script is called by netplug on Vyos:
## /etc/netplug/linkdown.d/my-brdown
##
## Version History
## 1.0 - Initial version
##

LOCKDIR=/var/run/my-bridge-ctl

# Since we only have one br, not going to implement this right now.
#IGNORE_BRIDGES=()

IFACE=$1

#Remove the lock directory
function cleanup {
    if rmdir $LOCKDIR; then
        logger -is -t "my-bridge-ctl" -p "kern.info" "Finished"
    else
        logger -is -t "my-bridge-ctl" -p "kern.error" "Failed to remove lock directory '$LOCKDIR'"
        exit 1
    fi
}

if mkdir $LOCKDIR; then
    #Ensure that if we "grabbed a lock", we release it
    #Works for SIGTERM and SIGINT(Ctrl-C)
    trap "cleanup" EXIT

    logger -is -t "my-bridge-ctl" -p "kern.info" "Acquired lock, running"

    # Processing starts here

    IFACE_DESC=$(<"/sys/class/net/${IFACE}/ifalias")
    IFACE_BR_DIR="/sys/class/net/${IFACE}/brport"

    if [ ! -d "$IFACE_BR_DIR" ]; then
        logger -is -t "my-bridge-ctl" -p "kern.warning" "Interface ${IFACE} (${IFACE_DESC-no desc}) went down. Not a member of a bridge. Skipping."
    else
        IFACE_BR_LINK=$(realpath "/sys/class/net/${IFACE}/master")
        IFACE_BR_NAME=$(basename $IFACE_BR_LINK)
        IFACE_BR_DESC=$(<"${IFACE_BR_LINK}/ifalias")
        logger -is -t "my-bridge-ctl" -p "kern.warning" "Interface ${IFACE} (${IFACE_DESC:-no desc}) went down. Member of bridge ${IFACE_BR_NAME} (${IFACE_BR_DESC:-no desc})."

        # TODO: Insert IGNORE_BRIDGE check here

        find "${IFACE_BR_LINK}/brif" -type l -print0 | while IFS= read -r -d $'\0' IFACE_BR_MEMBER_LINK; do
            IFACE_BR_MEMBER_NAME=$(basename $IFACE_BR_MEMBER_LINK)
            logger -is -t "my-bridge-ctl" -p "kern.info" "Handling ${IFACE_BR_NAME} member interface ${IFACE_BR_MEMBER_NAME} (${IFACE_BR_MEMBER_LINK})."

            # Actually do the bounce
            ip link set dev ${IFACE_BR_MEMBER_NAME} down && sleep 2 && ip link set dev ${IFACE_BR_MEMBER_NAME} up

            logger -is -t "my-bridge-ctl" -p "kern.info" "Interface ${IFACE_BR_MEMBER_NAME} bounced."
        done
    fi

    sleep 5
else
    logger -is -t "my-bridge-ctl" -p "kern.info" "Could not create lock directory '$LOCKDIR'"
    exit 1
fi

相关内容