首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Linux: STP不会在linux容器之间聚合。

Linux: STP不会在linux容器之间聚合。
EN

Server Fault用户
提问于 2023-01-24 19:33:58
回答 1查看 129关注 0票数 4

我正试图在GNS3中创建一个带有码头容器的实验室,以了解有关生成树的更多信息。我的实验室非常简单:有两个具有两个链接的Linux/阿尔卑斯容器:

代码语言:javascript
复制
--------                                          --------
| SW-1 | et2 -------------------------------- et2 | SW-2 |
|      | et3 -------------------------------- et3 |      |
--------                                          --------

每个br0都有一个桥接,配置如下:

代码语言:javascript
复制
ifconfig eth2 down
ifconfig eth3 down
brctl addbr br0
brctl addif br0 eth2
brctl addif br0 eth3
brctl stp br0 on
ifconfig eth2 0.0.0.0 up
ifconfig eth3 0.0.0.0 up
ifconfig br0 up

网桥已启动,模块已加载,stp似乎在每个主机上运行良好,但they不收敛于。所有端口都保持转发,L2 pkts无限期地循环:

代码语言:javascript
复制
# BOTH SW-1 and SW-2:
# lsmod | egrep -i 'bridge|stp'
bridge                352256  1 br_netfilter
stp                    16384  1 bridge
llc                    16384  2 bridge,stp

SW-1:
br0
 bridge id              8000.8615aca70489
 designated root        8000.8615aca70489    <<== SW-1 believes it is the root
 root port                 0                    path cost                  0
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               0.36                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                 116.61
 flags


eth3 (2)
 port id                8002                    state                forwarding
 designated root        8000.8615aca70489       path cost                100
 designated bridge      8000.8615aca70489       message age timer          0.00
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

eth2 (1)
 port id                8001                    state                forwarding
 designated root        8000.8615aca70489       path cost                100
 designated bridge      8000.8615aca70489       message age timer          0.00
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags


SW-2:
br0
 bridge id              8000.16d0f207e210
 designated root        8000.16d0f207e210    <<== SW-2 believes it is the root
 root port                 0                    path cost                  0
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               0.57                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                 116.61
 flags


eth3 (2)
 port id                8002                    state                forwarding
 designated root        8000.16d0f207e210       path cost                100
 designated bridge      8000.16d0f207e210       message age timer          0.00
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

eth2 (1)
 port id                8001                    state                forwarding
 designated root        8000.16d0f207e210       path cost                100
 designated bridge      8000.16d0f207e210       message age timer          0.00
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

当我在eth2上运行D5和在两个设备上运行eth3时,我看到BPDU正在被发送/接收,但很明显,每个设备都忽略了来自另一个设备的BDPU (顺便说一下,负载avg在我的机器中因为循环而上升):

代码语言:javascript
复制
SW-1:
Spanning Tree Protocol
    Protocol Identifier: Spanning Tree Protocol (0x0000)
    Protocol Version Identifier: Spanning Tree (0)
    BPDU Type: Configuration (0x00)
    BPDU flags: 0x00
        0... .... = Topology Change Acknowledgment: No
        .... ...0 = Topology Change: No
    Root Identifier: 32768 / 0 / 86:15:ac:a7:04:89
        Root Bridge Priority: 32768
        Root Bridge System ID Extension: 0
        Root Bridge System ID: 86:15:ac:a7:04:89 (86:15:ac:a7:04:89)
    Root Path Cost: 0
    Bridge Identifier: 32768 / 0 / 86:15:ac:a7:04:89
        Bridge Priority: 32768
        Bridge System ID Extension: 0
        Bridge System ID: 86:15:ac:a7:04:89 (86:15:ac:a7:04:89)
    Port identifier: 0x8002
    Message Age: 0
    Max Age: 20
    Hello Time: 2
    Forward Delay: 15

SW-2:
Spanning Tree Protocol
    Protocol Identifier: Spanning Tree Protocol (0x0000)
    Protocol Version Identifier: Spanning Tree (0)
    BPDU Type: Configuration (0x00)
    BPDU flags: 0x00
        0... .... = Topology Change Acknowledgment: No
        .... ...0 = Topology Change: No
    Root Identifier: 32768 / 0 / 16:d0:f2:07:e2:10
        Root Bridge Priority: 32768
        Root Bridge System ID Extension: 0
        Root Bridge System ID: 16:d0:f2:07:e2:10 (16:d0:f2:07:e2:10)
    Root Path Cost: 0
    Bridge Identifier: 32768 / 0 / 16:d0:f2:07:e2:10
        Bridge Priority: 32768
        Bridge System ID Extension: 0
        Bridge System ID: 16:d0:f2:07:e2:10 (16:d0:f2:07:e2:10)
    Port identifier: 0x8002
    Message Age: 0
    Max Age: 20
    Hello Time: 2
    Forward Delay: 15

每个人都不停地告诉对方,这是根桥。我等几分钟也没关系。dmesg只显示了以下内容:

代码语言:javascript
复制
[37533.507941] br0: received packet on eth2 with own address as source address (addr:86:15:ac:a7:04:89, vlan:0)
[37533.507942] br0: received packet on eth3 with own address as source address (addr:86:15:ac:a7:04:89, vlan:0)

AFAIK,网桥不知道VLAN。无论如何,我都试图将这个桥的default_pvid设置为0,但这并没有什么区别。没有应用ebtable过滤器规则,我也对/proc/sys/net/bridge/上的所有文件进行了归零。我看不出为什么BPDU没有被消耗,设备最终会聚在一起。

我尝试了同样的实验,只使用一个连接网桥(即,没有循环)的链路,以及连接到另一个接口的主机,在主机中配置静态IP地址,并成功地彼此点击,也就是说,桥接器正在交换数据包:

代码语言:javascript
复制
--------                                          --------
| SW-1 | et2 -------------------------------- et2 | SW-2 |
--------                                          --------
   et1                                              et1
    |                                                |
   host1                                            host2

我还尝试用openvswitch和专有映像替换容器,它运行得很好。有什么想法吗?

EN

回答 1

Server Fault用户

回答已采纳

发布于 2023-01-24 22:33:33

这是一个非常有趣的问题,所以我花了一些时间研究这个问题。原来这个问题已经问过了,这个答案描述了这个问题:

根本原因是,从bridge_slaves正确发送的stp消息,但是rcv例程仅限于net/llc/llc_input.c第166行(linux-source-5.15.0.)中的init_ns。

看起来,当前6.1.x内核中存在相同的条件;参见例如这里

您可以通过在全局网络命名空间中保留桥来验证这是问题所在。我不熟悉GNS3,所以我使用命令行设置了一个测试环境;最后我得到了这样的结果:

在这个图中,sw1-br0sw2-br0是桥接设备,sw1sw2是网络名称空间,其他都是veth设备。这在很大程度上等同于您的示例(这两个桥由一对链接连接),但是桥位于全局命名空间中。我们在每个桥上附加一个名称空间接口,这样我们就可以测试端到端的连接。

我用这个脚本设置了所有的东西:

代码语言:javascript
复制
#!/bin/sh

set -ex

for dev in 1 2; do
        ns=sw$dev

        # create namespace
        ip netns add $ns

        # create bridge device
        ip link add $ns-br0 type bridge stp_state 1
        ip link set $ns-br0 up

        # create link from namespace to bridge
        ip link add $ns-int type veth peer name $ns-ext

        # configure internal device
        ip link set netns $ns dev $ns-int
        ip -n $ns link set up dev $ns-int
        ip -n $ns addr add 100.64.10.$(( dev * 10))/24 dev $ns-int

        # add external device to bridge
        ip link set master $ns-br0 dev $ns-ext
        ip link set up dev $ns-ext
done

# create links between bridge devices
for port in port0 port1; do
        ip link add sw1-$port type veth peer name sw2-$port
        ip link set master sw1-br0 sw1-$port
        ip link set master sw2-br0 sw2-$port
done

当这个脚本完成运行时,桥到桥的链接都会被禁用,而命名空间到桥的链接则会被关闭。这使我们:

代码语言:javascript
复制
$ bridge link | grep br0
5090: sw1-ext@if5091:  mtu 1500 master sw1-br0 state forwarding priority 32 cost 2
5093: sw2-ext@if5094:  mtu 1500 master sw2-br0 state forwarding priority 32 cost 2
5095: sw2-port0@sw1-port0:  mtu 1500 master sw2-br0 state disabled priority 32 cost 2
5096: sw1-port0@sw2-port0:  mtu 1500 master sw1-br0 state disabled priority 32 cost 2
5097: sw2-port1@sw1-port1:  mtu 1500 master sw2-br0 state disabled priority 32 cost 2
5098: sw1-port1@sw2-port1:  mtu 1500 master sw1-br0 state disabled priority 32 cost 2

如果我打开port0接口:

代码语言:javascript
复制
ip link set sw1-port0 up
ip link set sw2-port0 up

我们最终看到:

代码语言:javascript
复制
5090: sw1-ext@if5091:  mtu 1500 master sw1-br0 state forwarding priority 32 cost 2
5093: sw2-ext@if5094:  mtu 1500 master sw2-br0 state forwarding priority 32 cost 2
5095: sw2-port0@sw1-port0:  mtu 1500 master sw2-br0 state forwarding priority 32 cost 2
5096: sw1-port0@sw2-port0:  mtu 1500 master sw1-br0 state forwarding priority 32 cost 2
5097: sw2-port1@sw1-port1:  mtu 1500 master sw2-br0 state disabled priority 32 cost 2
5098: sw1-port1@sw2-port1:  mtu 1500 master sw1-br0 state disabled priority 32 cost 2

当我最终打开port1链接并等待stp收敛时:

代码语言:javascript
复制
ip link set sw1-port1 up
ip link set sw2-port1 up

我们看到:

代码语言:javascript
复制
5090: sw1-ext@if5091:  mtu 1500 master sw1-br0 state forwarding priority 32 cost 2
5093: sw2-ext@if5094:  mtu 1500 master sw2-br0 state forwarding priority 32 cost 2
5095: sw2-port0@sw1-port0:  mtu 1500 master sw2-br0 state forwarding priority 32 cost 2
5096: sw1-port0@sw2-port0:  mtu 1500 master sw1-br0 state forwarding priority 32 cost 2
5097: sw2-port1@sw1-port1:  mtu 1500 master sw2-br0 state blocking priority 32 cost 2
5098: sw1-port1@sw2-port1:  mtu 1500 master sw1-br0 state forwarding priority 32 cost 2

在这里,您可以看到桥接器已经成功地检测到一个循环,并将其中一个端口标记为blocking

我们可以验证两个命名空间之间的连接性:

代码语言:javascript
复制
# ip netns exec sw1 ping -c2 100.64.10.20
PING 100.64.10.20 (100.64.10.20) 56(84) bytes of data.
64 bytes from 100.64.10.20: icmp_seq=1 ttl=64 time=0.052 ms
64 bytes from 100.64.10.20: icmp_seq=2 ttl=64 time=0.067 ms

--- 100.64.10.20 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1004ms
rtt min/avg/max/mdev = 0.052/0.059/0.067/0.007 ms

通过在任何链接上运行tcpdump,我们可以验证没有循环。

票数 3
EN
页面原文内容由Server Fault提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://serverfault.com/questions/1121032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档