Open vSwitch STP
本文主要介绍 Open vSwitch 中 STP 的应用。
我的新书《LangChain编程从入门到实践》 已经开售!推荐正在学习AI应用开发的朋友购买阅读!
STP 生成树协议
STP 协议通过在逻辑上将特定的端口进行阻塞,从而解决网络中存在的二层环路问题同时使网络在二层物理链路中存在冗余;
二层交换机的转发机制
交换机对于从一个 port N 上 incoming frame,学习其 source MAC X,生成 MAC Address Table,比如MAC X <------> Port N
生成 MAC 地址和 Port 的映射表。如果收到下一个 frame ,就会查询 frame 的 MAC 与 MAC Address Table 进行匹配,匹配到了就从对应的 Port 发送出去。如果没有匹配到,就认为是 unknown unicast 或 broadcast,没有办法只好把它从所有 Port ( 除了接收到 frame 的接口)发送出去,到了另外一台交换机也是这么处理,于是这个 frame 就一直在封闭的环路里无限的循环。
生成树 Spanning Tree
用一种逻辑的方法将物理的环路斩断,斩成一个发散的树状架构,解决 frame 无限循环下去的问题,如果把树的拓扑结构用于二层交换网络,在二层网络里选择一个根(root bridge),其它交换机当作树的树杈,每个树杈自然有一个根末梢(root port),这个就是交换机的上游接口,其它的接口都是下游接口,至于下游接口是畅通的、还是阻断的,取决于到根的路径成本 cost,谁更接近根,谁就畅通(forwarding) ,即 designated port;谁远离根,谁就需要被阻断(blocked), 即常说的 non designated Port。通过这种仿生的机制,可以有效地避免网络环路。
每个广播域中选举一个根桥(Root)
每个非根桥选举一个根端口(Root Port)
每一段链路选举一个指定端口(Designated Port)
非指定端口会被阻塞(Blocking)
环路问题确定
网络环路可分为网络二层和三层环路,首先看 IP 头中的 IPID 标识,如果数据包中的 IPID 都一样,可判断存在网络环路。再看 IP 头中的 TTL 值,若数据包中的 TTL 值逐渐减 1,可判断存在网络三层环路,即网络路由环路,需检查网络中的路由。若 TTL 值一直没变,可判断存在网络二层环路,需检查网络中的二层设备。
OvS STP
创建网络拓扑
1 | ip netns add ns1 |
连通测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18$ ip netns exec ns1 ping -c 3 1.1.1.2
PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.
64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=1.35 ms
64 bytes from 1.1.1.2: icmp_seq=2 ttl=64 time=0.120 ms
64 bytes from 1.1.1.2: icmp_seq=3 ttl=64 time=0.111 ms
--- 1.1.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 0.111/0.529/1.358/0.586 ms
$ ip netns exec ns1 ping -c 3 1.1.1.3
PING 1.1.1.3 (1.1.1.3) 56(84) bytes of data.
64 bytes from 1.1.1.3: icmp_seq=1 ttl=64 time=1.43 ms
64 bytes from 1.1.1.3: icmp_seq=2 ttl=64 time=0.121 ms
64 bytes from 1.1.1.3: icmp_seq=3 ttl=64 time=0.150 ms
--- 1.1.1.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 0.121/0.569/1.436/0.613 msbr2 和 br3 连通组成二层环路
ovs-vsctl add-port br3 br3-br2
环路后进行连通性测试,结果时通时不通
1
2
3
4
5
6
7$ ip netns exec ns1 ping -c 3 1.1.1.2
PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.
64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=1.21 ms
--- 1.1.1.2 ping statistics ---
3 packets transmitted, 1 received, 66% packet loss, time 2002ms
rtt min/avg/max/mdev = 1.211/1.211/1.211/0.000 ms
环路情况下分析
查询端口名称和索引的对应关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14$ ovs-ofctl show br1
1(tap1): addr:00:00:00:00:00:00
2(br1-br2): addr:16:ea:56:83:dc:bb
3(br1-br3): addr:96:53:db:b9:6d:7d
$ ovs-ofctl show br2
1(tap2): addr:00:00:00:00:00:00
2(br2-br1): addr:22:22:47:4f:ce:cb
3(br2-br3): addr:16:65:81:9b:d1:c7
$ ovs-ofctl show br3
1(tap3): addr:00:00:00:00:00:00
2(br3-br1): addr:ce:ef:8d:5f:a6:e2
3(br3-br2): addr:16:9a:85:2e:07:76查看 ns1 的 arp 表项,发现已经无法学习到 1.1.1.3 MAC 地址
1
2
3
4ip netns exec ns1 arp -n
地址 类型 硬件地址 标志 Mask 接口
1.1.1.3 (incomplete) tap1
1.1.1.2 ether 5e:d8:35:40:0e:a5 C tap1分别查看 br1、br2、br3 的 MAC 转发表均发生错乱,br1 连接 ns1 的 tap1,br2 连接 ns2 的 tap2,br3 连接 ns3 的 tap3 本应该分别从各自的接口 1 学习到
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21$ ovs-appctl fdb/show br1
port VLAN MAC Age
...
3 0 5e:d8:35:40:0e:a5 0
3 0 1a:0d:61:8b:4c:5d 0
2 0 ca:d4:37:41:f5:c5 0
$ ovs-appctl fdb/show br2
port VLAN MAC Age
...
3 0 1a:0d:61:8b:4c:5d 0
3 0 5e:d8:35:40:0e:a5 0
3 0 ca:d4:37:41:f5:c5 0
$ ovs-appctl fdb/show br3
port VLAN MAC Age
...
2 0 5e:d8:35:40:0e:a5 0
2 0 1a:0d:61:8b:4c:5d 0
3 0 ca:d4:37:41:f5:c5 0
开启 ovs stp
开启 stp
1
2
3ovs-vsctl set Bridge br1 stp_enable=true
ovs-vsctl set Bridge br2 stp_enable=true
ovs-vsctl set Bridge br3 stp_enable=truestp 研究
1
2
3
4$ ovs-vsctl list bridge
br1: stp_root_path_cost="2"
br2: stp_root_path_cost="0"
br3: stp_root_path_cost="2"由
stp_root_path_cost
可知,已经被逻辑修剪为如下拓扑图令
ns2 ping ns3
,并在 br1-br3 处抓包1
2
3
4
5$ ip netns exec ns2 ping -c 2 1.1.1.3
PING 1.1.1.3 (1.1.1.3) 56(84) bytes of data.
64 bytes from 1.1.1.3: icmp_seq=1 ttl=64 time=1.48 ms
64 bytes from 1.1.1.3: icmp_seq=2 ttl=64 time=0.160 ms
...1
2
3
4
5
6$ tcpdump -i br1-br3
...
21:24:44.806469 IP 1.1.1.2 > 1.1.1.3: ICMP echo request, id 20724, seq 1, length 64
21:24:44.806531 IP 1.1.1.3 > 1.1.1.2: ICMP echo reply, id 20724, seq 1, length 64
21:24:45.807056 IP 1.1.1.2 > 1.1.1.3: ICMP echo request, id 20724, seq 2, length 64
21:24:45.807104 IP 1.1.1.3 > 1.1.1.2: ICMP echo reply, id 20724, seq 2, length 64由抓取结果可知,报文流量经过了 br1,可确定 ovs 二层环路问题已解决。
清除实验环境
1 | ip link del br1-br2 type veth peer name br2-br1 |
stp 相关命令
1 | # 开启 br1 stp |
参考链接
Open vSwitch STP