以BGP为代表的路由协议,从设计之初,就关注路由表的正确性,因为这是确保整个网络系统正常工作的最基本要求。因此每个BGP路由器,总是会以最快的速度收敛到整个网络最新的状态上。当一个BGP peer的BGP连接断开时,当前BGP路由器会认为BGP peer已经不能工作,进而会以最快的速度删除之前从这个BGP peer收到的路由。

但这里其实有一些问题。首先,BGP连接断开了不一定代表路由器不能工作了。可能只是BGP所基于的TCP连接有问题,也可能是BGP keepalive消息丢了,但是路由器还是具备正常转发的能力。如果仅以BGP断连来判断路由器不能工作有时候会误伤。其次,路由器上的BGP进程可能正在重启,所以BGP连接只是短暂的断开,马上又能重连回来。如果一断开就删路由,重新建连又添加路由,会造成BGP路由器上路由反转,进而产生短时间的路由环路或者黑洞路由。这样一个路由反转可能会传递到整个数据中心,不仅消耗了路由器控制平面的计算能力,甚至会引起整个网络的抖动。

这在之前的硬件BGP设备中不是严重的问题,因为硬件设备设计就是一直运行,不需要重启。但是对于软件BGP来说,软件维护需要经常的重启BGP进程。为了解决这个问题,RFC4724为BGP(包括传统的BGP-4和MP-BGP)增加了一种新的能力,也就是Graceful Restart,它能在BGP短时间断连的时候,不删除相应的路由信息,从而确保网络的稳定性。从协议上来看,Graceful Restart在BGP协议的基础上增加了两个部分:End-of-RIB和Graceful Restart Capability。

End-of-RIB

BGP协议是由4类消息组成的。End-of-RIB从格式上看就是一种特殊的Update消息,它没有可达的Network Layer Reachability Information(NLRI),同时带的撤回NLRI也是空的。End-of-RIB就是一个空的Update消息,按照正常的处理逻辑是没有意义,并且不会产生任何影响。BGP路由器在启动的时候,会计算本地路由并发布到与之相连的BGP peer。这个过程结束之后,BGP路由器就是断断续续的接收一些更新事件,再将路由redistribute到BGP peer。所以,BGP路由器启动之后,过程可以分为两个部分,一个是初始化路由发布,另一个是正常工作时的路由发布。对于一个支持Graceful Restart的路由器来说,End-of-RIB的作用就是区分这两个部分,它会在初始化路由发布完之后,正常工作之前发布。

Graceful Restart Capability

Graceful Restart新增了一个BGP capability(RFC5492),就叫做Graceful Restart Capability。它在BGP建立连接的时候,随着OPEN message进行发布。BGP Capability的格式如下:




bgp路由汇总加null bgp路由无效是什么原因_路由选择算法


对应于Graceful Restart Capability,code是64;length一个字节,最大为255;value的组成如下:


bgp路由汇总加null bgp路由无效是什么原因_路由选择算法_02


其中:

  • Restart Flags


bgp路由汇总加null bgp路由无效是什么原因_路由选择算法_03


第1bit表明当前BGP是不是刚刚经历了重启。

  • Restart Time

重启超时时间,12bit长,所以最多是4095秒。Restart Time建议是不超过在Open Message中的HOLDTIME。

  • <AFI, SAFI, Flags for Address Family>

说明哪些BGP Address Family,支持Graceful Restart。AFI和SAFI由MP-BGP(RFC4760)定义用来标识BGP地址族。Flags for Address Family的第1bit表明,在刚才的BGP重启过程中,当前的BGP Address Family对应的路由,是否被保留了。受限于BGP Capability的长度,<AFI, SAFI, Flags for Address Family>可以是0到63个。如果是0个,说明当前路由器不能在BGP重启过程中保留任何BGP路由,但是可以配合支持Graceful Restart的对端路由器。

如果一个BGP路由器发布了Graceful Restart Capability,那就意味着它有两个能力:

  • 它在重启的时候,能保留BGP路由(取决于<AFI, SAFI, Flags for Address Family>)。
  • 它在初始的路由计算发布完成之后,会发布一个End-of-RIB。

支持Graceful Restart的路由器重启流程

  1. BGP路由器重启,BGP连接断开。
  2. 存储在RIB中的之前的BGP route标为stale状态,仅此而已。在生成实际路由表时,stale状态的BGP route不应该区别对待。
  3. BGP路由器启动,重新建立BGP连接,发送OPEN Message,在其中的Graceful Restart Capability中,Restart Flags中第1bit置1,表明刚刚经历了重启。
  4. 对于每个BGP Address Family,如果在重启过程中,BGP route保留了,那么相应的<AFI, SAFI, Flags for Address Family>中,Flags for Address Family的第1bit置1,表明本地仍然有之前的路由。
  5. 重新建立BGP连接,接收对端发来的BGP路由。但是当前路由器并不立即进行路由选择算法来更新本地路由表。
  6. 等到下面两个条件之一满足时再进行路由选择算法:
  1. 从所有的BGP peer都收到了End-of-RIB。但是这里要排除在Open Message中,将Restart Flag设置为1的peer,因为它们也在等当前路由器的End-of-RIB,而当前路由器只有在收完BGP peer的End-of-RIB并且进行完本地的路由选择算法之后才会发送自己的End-of-RIB,所以如果这里互相等待的话就会死锁。
  2. 路由选择算法等待时间超时了。为了避免当前路由器无尽的等待而不进行路由选择算法,支持Graceful Restart的BGP路由器,必须支持配置这个超时时间(Selection_Deferral_Timer)。
  1. 进行完路由选择算法之后,如果本地标为stale的BGP 路由没有从任何一个BGP peer收到更新,那么说明这条路由真的不存在了,必须被删除。
  2. 发布计算之后的路由到BGP peer。
  3. 发布End-of-RIB。

支持Graceful Restart的路由器,最主要的能力就是在BGP重启的过程中,保留之前的BGP route,同时保留自身的转发能力。在BGP 重新建立连接之后,再更新相应的BGP route。

支持Graceful Restart的路由器发现peer重启的处理流程

  1. 识别之前已经发送了Graceful Restart Capability的路由器,如果是支持Graceful Restart的路由器断开连接,那么执行下面的操作。
  2. 保留从peer路由器接收的BGP route,并标记成stale状态。仅此而已。在生成实际路由表时,stale状态的BGP route不应该区别对待。如果在这一步中,BGP route已经是stale,那么BGP route会被删除。也就是对端连续重启可能会造成本地相应的路由删除。
  3. 对端重新建立BGP连接,在当前BGP 路由器发送的Open Message中,其中Graceful Restart Capability中,Restart Flags中第1bit置0,除非当前BGP路由器也刚刚重启。如果在之前的Graceful Restart Capability中“Restart Time”到达之后,BGP还没有重新建连,那么stale状态的BGP route必须删除。所以,最多为对端保留路由4095秒。
  4. 对于每个BGP Address Family,如果在peer重启过程中,BGP route保留了,那么相应的<AFI, SAFI, Flags for Address Family>中,Flags for Address Family的第1bit置1,表明本地仍然有之前的路由。
  5. 但是在从peer BGP路由器收到的Graceful Restart Capability中,如果满足下面三个条件之一,表明peer BGP在重启过程中没有保留BGP route,那么需要立即删除相应的stale 状态的BGP route。
  1. 对应的Address Family中的Flags for Address Family第1bit为0;
  2. 没有相应的Address Family;
  3. 根本就没有Graceful Restart Capability
  1. 当前BGP 路由器发送End-of-RIB
  2. 在收到peer BGP重新发送过来的BGP route时,更新本地的stale状态BGP route。
  3. 当收到peer BGP发送的End-of-RIB时,删除相应Address Family中仍然为stale的BGP route。

支持Graceful Restart的路由器,在同样支持Graceful Restart的peer BGP路由器重启过程中,会保留之前的BGP route,仍然相信peer BGP具备转发能力。在BGP 重新建立连接之后,再更新相应的BGP route。

BGP优雅重启,实际上就是将作为控制平面的BGP和转发平面解耦开。这样,就算控制面BGP断开了,也不影响数据面的转发能力。