1. 背景
双向转发检测bfd(bidirectional forwarding detection)是一种全网统一的检测机制,用于快速检测、监控网络中链路或者ip路由的转发连通状况。
为了保护关键应用,网络中会设计有一定的冗余备份链路,网络发生故障时就要求网络设备能够快速检测出故障并将流量切换至备份链路以加快网络收敛速度。目前有些链路具备硬件检测机制来快速故障检测,但某些链路(如以太网链路)不具备这样的检测功能。这种情况下就需要上层协议自身的机制来进行故障检测。但大部分协议如ospf,bgp等检测链路故障的速度都很慢,最快也需要1s的时间,而且这些功能只针对本协议有效,无法为其他的协议或者应用提供快速检测机制。这对于某些实时性较高的上层应用如音频,视频等是不能接受的。
bfd就是在这种背景下产生的,它提供了一个通用的标准化的介质无关和协议无关的检测机制。
2. 工作原理
bfd在两台网络设备上建立会话,用来检测网络设备间的双向转发路径,为上层应用服务。会话建立后会周期性地快速发送bfd报文,如果在检测时间内没有收到bfd报文则认为该双向转发路径发生了故障,通知被服务的上层应用进行相应的处理。
bfd协议本身没有邻居发现机制,bfd邻居的创建依赖于上层的应用。根据bfd会话建立过程可以将其分为动态bfd和静态bfd。
动态bfd:是通过上层应用(例如ospf)的邻居发现机制,有上层应用将邻居信息发送到bfd模块,bfd则根据接收到的邻居信息创建会话并建立自己的邻居。
静态bfd:是通过静态配置手动添加对端的邻居信息来创建会话,静态bfd配置完后,会定时发送bfd控制报文。只有对端接口也开启bfd的情况下并对本端的bfd报文做出正确应答后,双方建立邻居信息。
3. bfd报文结构
3.1bfd控制报文
bfd控制报文包括两部分:强制部分和可选认证部分。
强制部分的报文格式是固定的,如下图所示:
可选认证部分根据认证的类型的不同而异,如下图所示:
bfd控制协议各字段代表的意义如下:
3.2bfd echo报文
bfd
echo报文提供了一种不依赖于bfd控制报文的故障检测方法。本端发送本端接收,远端不对报文进行处理,而只是将此此报文在反向通道上返回。因此bfd协议并没有对bfd
echo报文的格式进行定义,唯一的要求是发送方能够通过报文内容区分会话。bfd
echo报文采用udp封装,目的端口号为3785,目的ip地址为发送接口的地址,源ip地址由配置产生(配置的源ip地址要避免产生icmp重定向)。
4 bfd会话建立过程
bfd共有4种类型的控制报文维持bfd状态,分别为:
#define bsm_admindown 0
#define bsm_down 1
#define bsm_init 2
#define bsm_up 3
bfd控制报文交互及其状态切换图如下所示:
5. bfd系统架构
这个系统架构包括有四部分组成(实际使用过程中,而不是纯bfd协议)。架构图如下:
…[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g4tzcbd5-1600689737899)(.https://img-blog.csdnimg.cn/20191019004058806.png?x-oss-process=image/watermark,type_zmfuz3pozw5nagvpdgk,shadow_10,text_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3mynjazodk4mjyw,size_16,color_ffffff,t_70#pic_center)]
6.应用层bfdd数据结构
…[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kwb3ubvk-1600689759907)(.https://img-blog.csdnimg.cn/20191019004340145.png?x-oss-process=image/watermark,type_zmfuz3pozw5nagvpdgk,shadow_10,text_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3mynjazodk4mjyw,size_16,color_ffffff,t_70#pic_center)]
7.内核态kbfd数据结构
kbfd是开源代码,因此内核框架部分是通用的
kbfd维护两个哈希表的原因:
1)down状态:发送bfd报文无法知道对端鉴别值,只知道对端的ip,因此只能根据ip进行查表;
2)其他状态:已经进行了初步交互,既有对端的ip也有对端鉴别值,对端可以根据发来的鉴别值进行查表
实际是同一个哈希表,只是有两种查找方式。
8.内核态kbfd处理流程
内核态处理使用到的知识:
1)netlink套接字通信: 用来和应用层进行通信;
2)工作队列和工作这线程:用来定时发送报文,一个用来超时检测;
3)状态机:用来维护不同bfd会话的工作状态。
4)哈希表存储会话信息。
kbfd开源源码中的状态机代码实现个人感觉比较经典,属于常用的那种,我是在这里才正式接触到状态机的,并更新了一篇《c语言实现状态机》的博客。
8.内核态kbfd状态机流程图
9. bfd联动ospf动态路由
9.1 bfd会话建立过程
上图所示是一个简单的网络组网,两台设备上同时配置了ospf与bfd,bfd会话建立过程如下所示:
- 动态配置流程:
(1) ospf通过自己的hello机制发现邻居并建立连接。
(2) ospf在建立了新的邻居关系后,将邻居信息(包括目的地址和源地址等)通告给bfd。
(3) bfd根据收到的邻居信息建立会话。
(4) 会话建立以后,bfd开始快速发送bfd控制报文,检测链路故障,并做出快速反应。 - 静态配置流程:
(1) 通过手动配置,直接将邻居信息(包括目的地址和源地址)通告给bfd
(2) bfd根据收到的邻居信息建立会话。
(3) 会话建立以后,bfd开始快速发送bfd控制报文,检测链路故障,并做出快速反应。
目前与ha的联动采用的是静态配置方式。
9.2 bfd故障发现过程
(1) 被检测链路出现故障。
(2) bfd快速检测到链路故障,bfd拆除邻居会话,会话状态变为down。
(3) bfd通知本地ospf进程bfd邻居不可达。
(4) 本地ospf进程中断ospf邻居关系并根据需求切换到备用链路。