生成树机制实验(2)原理说明
生成树拓扑
生成树机制:
通过禁止(block)设备的相关端口,在有环路的网络中构造出一个总体开销最小的生成树拓扑,使得网络在连通的前提下,避免广播风暴
如何构建开销最小的生成树拓扑?
实际上:
-
具有相同开销的生成树拓扑可能并不唯一
如何消除歧义性,构建唯一确定的生成树拓扑
-
网络中的节点没有全局视图
如何定义通信协议,分布式的构建生成树拓扑?
-
网络中的节点收发消息的时序不确定
如何设计生成树运行机制,保证最终结果与消息收发时序无关?
生成树的唯一性
- 具有相同开销的生成树可能并不唯一
- 唯一生成树: 选择开销最小的生成树 (×) 优先级最高的生成树(√)
- 节点ID最小的点作为生成树的根节点
- 每个节点选择到树的根结点优先级最高的路径
- 优先级顺序:路径开销 > 所连接的节点ID大小 > 所连接的端口ID大小 > …
节点ID和端口ID
-
节点ID是一个64位整数
- 前2字节为优先级,每个节点可以独立设置优先级,默认为32768
- 后6字节为节点第一个端口的MAC地址
Bridge Identifier: 32768/ 100 / 00:1c:0e:87:85:00 Bridge Priority: 32768 Bridge System ID Extension: 100 Bridge System ID: Cisco_87:85:00 (00:1c:0e:87:85:00)
-
端口ID是一个16位整数
- 前1字节为优先级,可独立设置,默认为 128
- 后1字节标识该端口序列号
- 例如,0x8001为第一个端口,优先级是0x80(128)
路径开销
- 路径开销用于衡量节点间路径的优劣
- 每条链路都具有开销值
- 路径开销等于路径上全部链路开销之和
- 链路开销与链路带宽相关,带宽越高,开销越小
配置消息(BPDU Config): Bridge Protoc0l Data Unit,网桥协议数据单元
-
节点通过交换Config消息获取路径及优先级等信息
-
每个端口独立生成Config消息
- 表示本网段(Segment,可以理解为链路)到根结点的路径和开销,而不是本节点的
- 包括自己的节点ID、发送端口ID、自己认为的根结点ID,以及到根结点的路径和开销
-
Config消息的发送
- 根结点周期发送,发送周期为 Hello Time(2 秒)
- 其它节点收到的 Config后可能触发发送
-
Config消息基于二层组播方式发送
- 目的地址为 01-80-c2-00-00-01
生成树机制的基本原理
- 经过有限次的收发Config消息,网络中能选举出唯一的根结点,即ID最小的结点
- 除根结点外,每个结点选择通过自己的某端口连接到根结点,使得到根结点的路径开销最小,该端口叫做根端口
- 为了保证新的Config消息能够扩散到其它结点,每个结点会通过某些端口发送Config消息,这些端口叫做指定端口
1) 每个交换网络选举一个根桥(Root Bridge)
2) 每个非根桥上选举一个根端口(Root Port)
3) 每个段选举一个指定端口(Designated Port)
4) 阻塞非指定端口(NonDesignated Port)
生成树中的术语
-
根节点(Root Switch)
- 一个网络中只有一个根节点
- ID最小的节点作为根节点
-
根端口(Root Port,RP)
- 除根节点以外,每个节点有一个根端口
- 节点通过根端口连接到根节点,根端口是一个节点到根节点路径开销最小的端口
-
指定端口(Designated Port,DP)
- 每个网段(Segment,一跳可达,本实验中等同于链路)有且只有一个指定端口
- 指定端口为网段(Segment)内优先级最高的端口,即可以发送Config的端口
-
其余端口(Alternate Port,AP)
- 剩余的端口为其他端口,不参与构建生成树拓扑
生成树机制中端口的数据结构
-
每个端口存储本网段的通过开销(port->path_cost)
- 本实验中所有链路的通过开销均为1
-
每个端口记录本网段到根节点最小开销路径的配置(Config)
- 自己认为的根节点 designated_root
- 本网段到根节点的路径开销 designated_cost
- 本网段到根节点的上一跳节点ID designated_switch(是本节点还是本网段中其他节点)
- 本网段到根节点的上一跳端口 designated_port(是本端口还是本网段中的其他端口)
-
生成树机制收敛后,每个网段内所有端口存储的配置都相同
-
每个节点记录本节点到根节点开销最小的路径
-
自己认为的根节点 designated_root
-
根端口 root_port
-
到根节点的路径开销 root_path_cost
生成树机制收敛后,所有节点认为的根节点都相同
-
-
节点到根节点的路径开销,等于根端口所在网段到根节点的路径开销与根端口所在网段的通过开销之和
stp ->root_path_cost = root_port->designated_cost + root_port->path_cost
生成树运行机制 - 初始化
-
节点认为自己是根节点
stp -> designated_root = stp->switch_id
-
将每个端口设置为指定端口,即端口所在网段应该通过本节点连接到根节点
p -> designated_root = stp -> switch_id
// 自己认为的根节点
p -> designated_cost = 0
// 本网段到根节点的路径开销
p -> designated_switch = stp -> switch_id
// 本网段到根节点的上一跳节点ID(就是根节点的id)
p -> designated_port = p -> port_id
// 本网段到根节点的上一跳端口(就是本端口)
-
当节点认为自己是根节点时,周期性主动发送Config消息
- 每个端口发送的Config消息中,只有端口ID字段不同
-
节点通过hello定时器(2秒)周期发送Config消息,直到该节点不再认为自己是根节点为止
收到Config消息后,将其与本端口Config进行优先级比较
-
如果收到的Config优先级高,说明该网段应该通过对方端口连接根节点
- 将本端口的Config替换为收到的Config消息,本端口为非指定端口
- 更新节点状态
- 更新其余端口的Config
- 如果节点由根节点变为非根节点,停止hello定时器
- 将更新后的Config从每个指定端口转发出去
-
否则,说明该网段应该通过本端口连接根节点
- 该端口是指定端口,发送Config消息
Config之间的优先级比较
根节点ID小 > 开销小 > 到根节点的上一跳ID小 > 上一跳端口ID 小
什么时候进行Config优先级比较?
- 端口收到Config消息之后(端口Config与收到的Config消息的比较)
- 节点更新状态,从所有非指定端口中选取根端口时(端口间的比较)
更新节点状态
-
遍历所有端口,满足如下条件的为根端口(root_port)
- 该端口是非指定端口
- 该端口的优先级要高于所有其余非指定端口
-
更新节点状态,选择通过root_port连接到根节点:
stp -> root_port = root_port stp -> designate_root = root_port -> designated_root stp -> root_path_cost = root_port -> designated_cost + root_port->path_cost
更新端口的Config
-
节点在更新自己的状态后,哪些端口的Config需要更新?
1.非指定 -> 非指定 (不需要处理)
2.指定 -> 指定 (需要)
3.指定 -> 非指定(只有收到Config时可能,已处理)
4.非指定 -> 指定(可能)
-
如果一个端口为非指定,且其较网段内其他端口优先级更高,那么该端口成为指定端口:
p -> designated_switch = stp -> switch_id
p -> designated_port = p->port_id
- 对于所有指定端口,更新其认为的根节点和路径开销
p -> designated_root = stp -> designated_root
p -> designated_cost = stp -> root_path_cost
处理Config消息的例子
更新其余端口Config的例子
-
节点b3 先收到 b2-eth0的Config消息
1.1 b3-eth0变为根端口
1.2 更新其余端口,b3-eth1仍为指定端口,更新其认为的根节点和路径开销
-
节点 b3 再收到 b1-eth0的Config消息
2.1 b3-eth1 更新为根端口
2.2 更新其余端口: b3-eth0 的 Config 比网段内(b2 - eth0端口)的Config优先级更高,由非指定端口更新为指定端口
非指定端口更新为指定端口的例子
-
更新b3-eth0 的Config: 先假设其可以从非指定端口更新为指定端口,构造其Config
- 其认为的根节点: b1(stp -> designated_root)
- 其认为到根节点的路径开销: 1(stp->root_path_cost)
- 到根节点的上一跳节点: b3(stp->switch_id)
- 到根节点的上一跳端口: b3-eth0(p->port_id)
-
当前本网段内优先级最高的Config:(b3-eth0存储的相应字段)
-
如果前者优先级高于后者,则端口由非指定端口更新为指定端口,即将前者存储为本端口的Config;如果不高于后者,则保持不变