2.1 BFD
网络可靠性的一项重要标准在于这个网络是否能够快速复原,有些技术资料称之为网络的弹性(Resilience)。快速复原能力一般是指网络不借助技术人员的干预就自动恢复的能力,因此网络要想具备快速复原能力,就必须首先拥有一种能够检测出网络中故障的机制,否则恢复也就无从谈起,而2.1节要介绍的双向转发检测(Bidirectional Forwarding Detection,BFD)就是这样一项技术。
2.1.1 BFD概述
根据2.1.1节引入部分的介绍,读者应该己经大致了解了BFD的作用。部署BFD就像给网络安装了故障自检系统,让网络设备能够更快地发现相邻设备之间的通信己经中断,以便尽快采取有针对性的措施来促进网络快速复原。
不过,通过《网络基础》和《路由交换技术》的学习,读者也应该知道很多人在搭建网络时采用的介质和技术自身就提供了错误检测机制,譬如很多协议中引入的Hello/Keepalive(保活)数据包与老化计时器机制,就可以让这种协议能够在通信出现故障时发现问题。然而,并不是通过所有方式建立的通信都具备这样的通信故障检测机制,比如对于管理员手动配置的静态路由条目,路由器就没有配套机制可以了解它们对应的下一跳设备是否仍然可达。除了不具备统一的检错机制会显著降低网络的快速复原能力之外,很多技术自带的检错机制效率很低,常常无法满足某些应用的需求。BFD 同时解决了这两大问题,它不仅检错效率高,而且适用于广泛的介质,能够给大量的协议提供错误检测服务,这是读者在设计网络时应该部署这项技术的原因。
BFD提供的服务很容易理解,下面我们来介绍一下BFD提供这种服务的机制。
2.1.2 BFD的工作机制
BFD采取的通信故障检测方式与Hello消息采用的方式十分类似,这个以UDP作为传输层协议的协议可以算是一种轻量级的Hello协议。具体来说,在检测通信故障之前,BFD对等体之间也需要首先建立会话,然后再通过这条对等体之间建立的会话来周期性地发送故障检测消息。如果一台 BFD设备在指定时间内没有接收到 BFD对等体发送过来的检测消息,那么它就会认为自己与对等体之间的通信出现了故障,如图2-1所示。
为了建立BFD会话,对等体之间需要首先完成3次握手,3次握手的会话建立过程同时也是参数协商过程。如果对等体之间完成了BFD 3次握手,那么它们也就完成了状态迁移并进入BFD UP状态。
既然涉及状态迁移,就有对应的状态机。作为一种轻量级Hello协议,(如果不考虑因为管理员没有在设备上启用BFD协议而导致BFD处于管理DOWN的状态)BFD共有3种状态,它们是DOWN、INIT和UP。BFD的状态迁移过程相当简单,下面我们来简单介绍一下BFD对等体之间的状态迁移过程。
图2-1 BFD的工作方式
首先,当管理员在两台设备上启用BFD之后,它们的初始状态都是DOWN。此时,BFD设备会向对端发送BFD消息,BFD消息中会携带始发设备当前的状态,如图2-2所示。
图2-2 BFD的DOWN状态
当一台处于DOWN状态的BFD设备接收到状态为DOWN的BFD消息之后,它就会进入INIT状态,状态为INIT的设备发送的BFD消息状态也会变为INIT,如图2-3所示。
图2-3 BFD的INIT状态
在图2-3中,图2-2的AR2接收到了AR1发送的DOWN消息,因此AR2进行了状态迁移,并开始向AR1发送状态为INIT的BFD消息。同时,由于AR1此时还没有接收到AR2发送的DOWN消息,因此AR1仍然在周期性地向AR2发送状态为DOWN的消息。对于状态为INIT的BFD设备,它会忽略后续状态为DOWN的消息。因此,在图2-3的下一个状态中,AR1会接收到AR2发送的DOWN消息并切换为INIT状态,但AR2由于己经进入了INIT状态,因此它不会处理AR1发来的DOWN消息。这个过程十分简单,我们不再通过图示进行说明。
同理,当处于三种状态(DOWN/INIT/UP)中任何一种状态的设备接收到状态为INIT的BFD消息之后,它都会进入UP状态,状态为UP的设备发送的BFD消息状态也会变为UP,如图2-4所示。
图2-4 BFD的UP状态
在图2-4中,由于图2-3中AR2首先迁移到了INIT状态并开始向AR1发送状态为INIT的BFD消息,因此AR1首先接收到了AR2发送的INIT消息,AR1迁移到了UP状态后开始向AR2发送状态为UP的BFD消息。同时,由于AR1迁移到INIT状态的时间比较晚,因此AR2还没有接收到AR1发送的INIT消息。
当一台BFD设备的状态由DOWN迁移到INIT之后,它就会开始启动超时计时器,只要超时计时器过期之前它仍然没有接收到对端发送过来的BFD消息,那么无论此时该设备的状态为INIT还是UP,它都会直接进入DOWN状态;如果它接收到的BFD消息状态为DOWN,它也会直接进入DOWN状态。这也就是说,UP状态不会回退到INIT状态,它只会直接回到DOWN状态。
注释:
如果一台处于DOWN状态的设备直接接收到了状态为UP的BFD消息,它会忽略这个消息,而不会直接过渡到INIT状态或者UP状态。
BFD的接口状态机逻辑十分简单,我们在2.1.2节中己经充分介绍了触发BFD接口状态机的几种情况。在这里,我们在章末练习题之外先给读者留下一道画图题:请读者能够根据2.1.2节中的文字描述,画出BFD状态机的迁移流程,图中包含BFD状态机迁移的触发条件。
在介绍了BFD的状态之后,2.1.3节将介绍BFD的报文格式。
2.1.3 BFD的报文格式
在《网络基础》和《路由与交换技术》中我们也曾经提到过,一项协议提供的服务需要通过定义这个协议的头部字段来落实。既然这样,我们可以分析一下BFD的协议报文,了解BFD是如何实现协议功能的。
BFD的头部封装格式如图2-5所示。
下面,我们结合图2-5介绍BFD头部封装格式中各个字段的表意。
·版本:版本字段与 IPv4 数据包头部的作用类似,用来标识这个数据包的 BFD版本。目前这个字段的取值固定为“1”。
·诊断字:这个字段的作用是标识本地设备最近一次BFD状态发生变化的原因。
图2-5 BFD头部封装格式
·状态:如果有心,学习了2.1.2节的读者应该在看到图2-5时就开始主动寻找这个字段,因为我们2.1.2节的内容实际上都是围绕着这个字段展开的。这个字段的长度为2比特,因此可以取4个值:这个字段取值为“0”表示本地设备管理关闭了BFD;取值为“1”表示本地设备当前BFD状态为DOWN;取值为“2”表示当前BFD状态为INIT;取值为“3”表示当前状态为UP。
·超时检测倍数:在默认模式下,BFD设备会周期性地发送BFD消息向对端通告自己的存在。如果一台BFD设备在超时时间周期内都没有接收到对端发送的BFD消息,那么这台设备就会认为与对方设备的通信出现了故障。这个字段的作用是标识本地设备的超时时间周期,是发送周期的多少倍。
·长度:长度字段的作用与IP数据包头部的作用类似,用来表示这个BFD头部所封装的数据长度。
·本地鉴别符:一对BFD对等体之间未必彼此通过介质直连。因此,BFD消息中需要有专门的字段用来告知对端这是来自哪个BFD会话的消息,本地鉴别符的作用就在于此。如果BFD会话是动态建立的,那么系统会给每个会话的BFD消息自动分配一个本地鉴别符值。如果BFD会话是静态建立的,那么本地鉴别值则是管理员静态配置的数值。
·对端鉴别符:如果BFD会话是动态建立的,那么当BFD设备接收到对端发送的BFD 消息时,它会用该消息中本地鉴别符字段中封装的数值,作为自己在这段会话中给对等体发送BFD消息时使用的对端鉴别符字段的值。如果BFD会话是静态建立的,那么本地鉴别值和对端鉴别值则都需要由管理员进行静态配置。
·支持最小发送间隔:这个字段的作用顾名思义,它标识了这台BFD设备支持的最小BFD消息发送间隔。
·支持最小接收间隔:这个字段标识了这台BFD设备支持的最小BFD消息接收间隔。
·支持最小回声接收间隔:这个字段的作用是标识这台BFD设备支持的最小回声(Echo)消息接收间隔。
·认证类型:认证类型字段是可选字段。如果管理员启用了BFD认证,那么BFD消息中就会携带这个字段来标识管理员指定的认证类型。BFD支持5种类型的认证,包括明文密码认证(类型字段取值为“1”)和加密MD5认证(类型字段取值为“2”)等。
·认证长度:既然认证类型是可选字段,认证长度当然也是可选字段。如果管理员启用了BFD认证,那么BFD消息中就会携带这个字段来标识认证类型字段、认证长度字段和认证数据字段这3个字段的总长度。
·认证数据:这一部分顾名思义就是认证的数据部分。显然,这个字段的长度不是固定的。
通过上面3节的介绍,读者己经基本了解了BFD的工作方式。下面我们简单说明一下动态建立的BFD会话是如何通过检测故障来影响通信的。
图2-6所示为管理员在OSPF进程下启用了BFD,让BFD来检测OSPF的通信故障。
图2-6 BFD会话的建立
图2-6展示了BFD开始检测故障之前经历的3个步骤:
步骤1 OSPF建立了邻居关系;
步骤2 OSPF将邻居信息通告给了BFD;
步骤3 BFD 则利用这些信息建立了会话,并且通过这段会话周期性地相互发送消息来检测故障。
此时,如果AR1和AR2之间的通信因为链路故障而中断,那么BFD就会迅速检测出通信中断的情况,如图2-7所示。
图2-7 BFD向OSPF通告链路故障
图2-7展示了BFD检测到故障发生并通告链路故障时经历的3个步骤:
步骤1 BFD因在指定时间内没有接收到对端的BFD消息而迅速检测出了AR1与AR2之间的通信故障,同时BFD的状态也由UP变为了DOWN;
步骤2 BFD向OSPF通告邻居己经不可达的信息;
步骤3 OSPF断开邻居关系,OSPF网络也会开始重新收敛。
静态建立的BFD会话检测通信故障的方式也是类似的,比如管理员就可以使用BFD来检测本地路由器上某条静态路由条目的下一跳路由器是否仍然可达。当然,静态路由并不会向BFD通告邻居信息,因此当管理员希望使用BFD来检测静态路由通信故障时,就需要通过手动配置本地鉴别符和对端鉴别符的方式,让双方设备之间建立静态BFD会话。另外,静态路由也不会重新收敛,如果BFD检测到某条静态路由条目的下一跳己经变为不可达,那么BFD就会将这条路由设置为“非激活”状态,此后路由器不能再使用这条路由来进行转发;直到BFD重新建立会话之后,BFD才会将这条路由条目重新恢复为“激活”状态。
在2.1节中,我们简单地介绍了BFD的工作原理。