Linux STP介绍
1. 介绍
STP(Spanning Tree Protocol)即生成树协议,标准为IEEE802.1D-1998
STP是一种二层冗余技术,利用STA算法构建一个逻辑上没有环路的树形网络拓扑结构,并且可以通过一定的方法实现路径冗余
2. 概念
2.1 角色
生成数有如下角色
- 根桥(Root Bridge) RB, 桥ID最小的桥
- 根端口(Root Port) RP, 该端口到达根桥的路径是该端口所在网桥到达根桥的最佳路径
- 指定端口(Designated Port)DP, 每一个网段选择到根桥最近的网桥作为指定网桥, 该网桥到这一网段的端口为指定端口
- 可选端口(Alternated Port)AP, 即阻塞端口, 既不是指定端口, 也不是根端口的端口
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
2.2 端口状态
STP端口状态有如下几种
- 断开(Disable): 不收发任何报文
- 阻塞(Blocking): 不接收或转发数据, 接收但不发送BPDU, 不进行地址学习
- 监听(Listening): 不接收或转发数据, 接收并发送BPDU, 不进行地址学习
- 学习(Learning): 不接收或转发数据, 接收并发送BPDU, 开始地址学习
- 转发(Forwarding): 接收并转发数据, 接收并发送BPDU, 进行地址学习
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
一个网桥开启STP后,端口会经历如下过程:
Blocking(20s) –> Listening(15s) –> Learning(15s) –> Forwarding
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
这样大约50秒的时间非根端口转变成为根端口或指定端口
2.3 相关参数
2.3.1 网桥参数
Bridge Identifier: 标识本网桥, 由网桥的优先级(2 bytes)和网桥的MAC(6 bytes)组成
Root Path Cost: 从非根桥到根桥的路径开销的总和
Root Port: 根端口, RP
Max Age: 在协议的配置信息被丢弃之前收到的配置信息保留的时间(默认20s)
Hello Time: 对一个想变成桥或者是根桥的桥在固定的时间发送的配置BPDU信息(默认2s)
Forward Delay: 从Listening到Learning和从Learning到Forwarding花费的时间(默认15s)
Bridge Max Age: 桥作为根或想成为根桥的桥标识的它作为根桥的最大年龄
Bridge Hello Time: 非根桥向根桥发送TCN BPDU的时间间隔
Bridge Forward Delay: 和上面介绍的Forward Delay值一样
Topology Change Detected: 用来标识网络拓扑结构改变的布尔变量
Topology Change: 参数设置表示拓扑改变
Topology Change Time: 根桥产生配置消息指明拓扑改变的时间间隔
Hold Time: 在这个时间间隔至少应该收到一个配置BPDU信息
2.3.2 网桥时间参数
Hello Timer: 根桥定时传输配置BPDU信息的时间间隔
Topology Change Notification Timer: 如果没收到拓扑改变回应消息便会定时发送拓扑改变通知
Topology Change Time: 定时发送拓扑改变通知来通知桥进行重配
2.3.3 端口参数
Port Identifier: 桥的端口ID, 由优先级和端口号组成
Port State: 端口状态
Path Cost: 本端口的路径开销(see tips below)
Designated Root: 根桥的桥ID
Designated Cost: 从这个端口到根桥的路径开销
Designated Bridge: 指定桥的桥ID
Designated Port: 指定桥中和它交互的端口ID
Topology Change Acknowledge: 设置来回应拓扑改变通知
Configuration Pending: 设置表示在Holdtimer超时后应该传输配置BPDU信息
Change Detection Enabled: 表示是否理会拓扑改变通知
2.3.4 端口时间参数
Message Age Timer: 表示超时丢弃协议信息的时间
Forward Delay Timer: 和端口状态改变的时间值有关
Hold Timer: 在这个时间间隔至少应该收到一个配置BPDU信息
tips: 关于路径开销,可参考<IEEE802.1t路径开销列表>
通常根据端口的带宽不同,Path Cost值也不同:
• 10 Mb/s: 100
• 100 Mb/s: 19
• 1000 Mb/s: 4
• 10000 Mb/s: 2
2.4 BPDU
2.4.1 介绍
STP的数据单元称为BPDU(Bridge Protocol Data Unit)
BPDU是网桥间信息交流的报文,目标MAC地址为:01-80-C2-00-00-00
网桥之间定期发送BPDU包,交换STP配置信息,以便能够对网络的拓扑、花费或优先级的变化做出及时的响应
BPDU报文在直连的两个网桥或多个网桥内交换,不能被转发
没有运行STP协议的网桥将把BPDU报文当作普通业务报文转发
BPDU被封装在LLC的Payload中
下面是一个C BPDU
2.4.2 类型
BPDU有三种类型
- Configuration BPDU: 即C BPDU, 包含配置信息的BPDU包
- Topology Change Notification BPDU: 即TCN BPDU, 当检测到网络拓扑结构变化时发送拓扑变化通知BPDU
- Topology Change Notification Acknowledgment: 即TCA BPDU(TCA flag置1的C BPDU)
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
BPDU报文格式如下
2.4.3 发送与接收
C BPDU:
只有RB发送C BPDU,它有一个Hello Timer,当这个定时器expire的时候产生一个BPDU的包
而其他的non-RB在他们的RP中收到这些包之后进行中继,中继的过程中对BPDU中的各项值根据自身的情况进行更新
TCN BPDU:
当某个non-RB检测到拓扑变化后,该br会通过RP向RB方向发送TCN BPDU,其他br从它的DP接收到TCN BPDU时,首先从该DP上回应一个TCA BPDU,然后将该TCN BPDU从RP向RB方向发送, 这样TCN BPDU最后会到达RB
RB则会发出一个C BPDU(topology change置1),表示发现拓扑变化,这个包会被所有br转发,传遍全网,这样所有br都得知拓扑变化,然后做出相应的动作(修改ageing timer: 5m->15s)
该过程如下图所示:
TIP: C BPDU是从RB往树的各个方向传送;TCN BPDU则是从树的某个br上行直至RB
2.5 选举
2.5.1 根桥的选举
网桥初始化以后,都认为自己是Root Bridge,在它认为的指定端口上,周期性的发送C BPDU直到收到BridgeID更小的网桥信息,才直到自己不是根网桥
或者由于配置管理(端口使能,设置网桥优先级等),端口状态改变,也会引起Root Bridge的重新选举
2.5.2 根端口的选择
非根桥的其他网桥将各自选择一条到Root Bridge代价最小的路径,相应端口的角色就成为根端口
2.5.3 指定端口的选择
根端口选择以后,选择到根桥路径开销最小的端口作为指定端口
2.5.4 可选端口的选择
端口enable,参与选举的拓扑计算,既不是根端口,也不是指定端口,那就是可选端口了
2.5.5 选择过程
选举过程如下所示
选举根桥 -> 根端口 -> 指定端口 -> 其余为阻塞端口
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
生成树经过一段时间(默认值是30秒左右)稳定之后,所有端口要么进入转发状态,要么进入阻塞状态
STP BPDU仍然会定时从各个网桥的指定端口发出,以维护链路的状态
如果网络拓扑发生变化,生成树就会重新计算,端口状态也会随之改变
TIP:
网桥接受BPDU时开销值增加,发送BPDU时开销值不变
只有根桥是没有根端口的,根桥的所有端口都是指定端口
选举根端口,比较接收的BPDU;
选举指定端口,比较发送的BPDU.
3. 实现
3.1 数据结构
net_bridge: 网桥STP相关参数
struct net_bridge
{
...
/* STP */
bridge_id designated_root; /* RB ID */
bridge_id bridge_id; /* ID */
u32 root_path_cost; /* 路径开销 */
unsigned long max_age; /* 配置信息保留时间 */
unsigned long hello_time;
unsigned long forward_delay;
unsigned long bridge_max_age;
unsigned long ageing_time;
unsigned long bridge_hello_time;
unsigned long bridge_forward_delay; u8 group_addr[ETH_ALEN];
u16 root_port; /* 本网桥的根端口 */ enum {
BR_NO_STP, /* no spanning tree */
BR_KERNEL_STP, /* old STP in kernel */
BR_USER_STP, /* new RSTP in userspace */
} stp_enabled; unsigned char topology_change;
unsigned char topology_change_detected; struct timer_list hello_timer;
struct timer_list tcn_timer;
struct timer_list topology_change_timer;
struct timer_list gc_timer;
};
net_bridge_port: 网桥端口STP相关参数
struct net_bridge_port
{
/* STP */
u8 priority;
u8 state;
u16 port_no;
unsigned char topology_change_ack;
unsigned char config_pending;
port_id port_id; /* 本端口的端口ID */
port_id designated_port; /* 发送当前BPDU包的端口ID */
bridge_id designated_root; /* 根桥的网桥ID */
bridge_id designated_bridge; /* 发送当前BPDU包的网桥ID */
u32 path_cost; /* 本端口的路径开销 */
u32 designated_cost; /* 到根桥的路径开销 */
unsigned long designated_age; struct timer_list forward_delay_timer;
struct timer_list hold_timer;
struct timer_list message_age_timer;
};
br_config_bpdu: BPDU包
struct br_config_bpdu {
unsigned int topology_change:1;
unsigned int topology_change_ack:1;
bridge_id root;
int root_path_cost;
bridge_id bridge_id;
port_id port_id;
int message_age;
int max_age;
int hello_time;
int forward_delay;
};
可以发现,br_config_bpdu和C BPDU报文格式对照可以发现,缺少 Protocol ID、Version、Message Type和Flags
因为Message Type基本在使用的时候可以确定,而Flags则可由topology_change和topology_change_ack来确定
具体可参考函数br_send_config_bpdu()的实现
3.2 STP模块
3.2.1 基本使用
/*
* 新增网桥
* br_dev_setup()
*/
# brctl addbr br0 /*
* 向网桥新增端口
* br_add_if() -> new_nbp() -> br_init_port()
*/
# brctl addif br0 eth0 /*
* 启用和禁用STP
* on -> br_stp_start() -> br_port_state_selection()
* off -> br_stp_stop()
*/
# brctl stp br0 <on|off>
3.2.2 数据通路
static const struct stp_proto br_stp_proto = {
.rcv = br_stp_rcv,
};
static int __init br_init(void)
{
stp_proto_register(&br_stp_proto);
......
}
参考:
<Linux Bridge STP HOWTO>
<Spanning Tree Protocol (STP)>
<Linux的网桥中的STP的实现分析初步>
Linux STP介绍的更多相关文章
- 01 Linux入门介绍
一.Linux 初步介绍 Linux的优点 免费的,开源的 支持多线程,多用户 安全性好 对内存和文件管理优越 系统稳定 消耗资源少 Linux的缺点 操作相对困难 一些专业软件以及游戏支持度不足 L ...
- Linux Epoll介绍和程序实例
Linux Epoll介绍和程序实例 1. Epoll是何方神圣? Epoll但是当前在Linux下开发大规模并发网络程序的热门人选,Epoll 在Linux2.6内核中正式引入,和select类似, ...
- Linux入门介绍
Linux入门介绍 一.Linux 初步介绍 Linux的优点 免费的,开源的 支持多线程,多用户 安全性好 对内存和文件管理优越 系统稳定 消耗资源少 Linux的缺点 操作相对困难 一些专业软件以 ...
- Linux 系统目录介绍
bin : bin 是Binary 二进制的缩写,就是可执行文件了.Bin目录下是用户常用的命令. sbin: 此目录下也是二进制文件 ,不过这里的命令是 超级用户如 root 这样的用户使用的. e ...
- Linux命令介绍
资料链接:(Linux基本命令介绍)http://note.youdao.com/share/?id=36c07917f8d3e6437c1e764c3516a3f2&type=note#/ ...
- 1.Linux入门介绍
1.1 Linux概述 1.1.1 Linux简要介绍 Linux的由来: Linux的内核最初是由芬兰人李纳斯·托瓦茨在上大学的时候编写的一个内核,它是基于Unix操作系统编写的 大多服务器使用的是 ...
- Linux SELinux 介绍详解
Linux SELinux 介绍详解 SElinux 简介 SElinux (Security Enhanced Linux)是由美国国家安全局(NSA)开发的.它已被植入到了Linux系统的内核当中 ...
- Linux文件介绍
Linux文件介绍 Linux 文件属性 可以通过命令ll+文件名,查看文件的具体属性 例如:ll syz.gz 1736706 -rw-r--r--. 1 root root 28 Oct 27 1 ...
- 尚学linux课程---6、linux命令介绍
尚学linux课程---6.linux命令介绍 一.总结 一句话总结: linux中命令的一般格式:命令关键字 选项 参数1 参数2 1.linux基本原则? 一切皆文件 配置文件保存为纯文本格式 2 ...
随机推荐
- 本地已经存在的项目如何跟github发生关联
切换到本地项目地址 git init 初始化项目.该步骤会创建一个 .git文件夹是附属于该仓库的工作树. git add . git commit -am 'initial commit' git ...
- 深入解析AJAX的原理
AJAX:Asynchronous JavaScript And Xml(异步的JS和XML) 同步:客户端发起请求>服务端的处理和响应>客户端重新载入页面(循环) 异步:客户端实时请求& ...
- 微信小程序第3课 目录结构及小知识点
目录 目录结构 安装包下载地址 一.pages目录介绍 二.index目录介绍 index.js(相当JavaScript文件,必不可少的) index.json(可以不需要) index.wxml( ...
- P1309 瑞士轮
题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分 ...
- Linux命令之---cat
命令简介 cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. 命令格式 cat [选项] [文 ...
- python之返回状态commands模块
需要得到命令执行的状态则需要判断$?的值, 在Python中有一个模块commands很容易做到以上的效果. commands.getstatusoutput(cmd) 返回一个元组(status, ...
- OpenCV学习笔记(八) 边缘、线与圆的检测
边缘检测 对图像进行边缘检测之前,一般都需要先进行降噪(可调用GaussianBlur函数). Sobel算子 与 Scharr算子 都是一个离散微分算子 (discrete differentiat ...
- IOS开发---菜鸟学习之路--(十四)-将BASE64图片转换成Image
本文基本全部都是代码 首先是.H文件 #import <Foundation/Foundation.h> @interface Base64AndImageHelp : NSObject ...
- MySQL出现错误1045,用户无法连接
1.root用户可以登陆进去 假设新建了个sqlin用户,但是无法用此用户连接MySQL 这个时候root用户可以登录吧,root用户登录进去,重新修改该用户的密码,执行语句 use mysql; u ...
- csu-2018年11月月赛Round2-div2题解
csu-2018年11月月赛Round2-div2题解 A(2193):昆虫繁殖 Description 科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强.每对成虫过x个月产y对卵,每对 ...