为什么MA网络上需要进行DR和BDR的选举?如果每个路由器都发送自己的LSDB数据库的话,网络中会有大量LSA流量,而且这些lsa中很大一部分都是重复的.所以为了减少LSA数据包占用的带宽,选举DR和BDR来代表大家发送LSA.
从上图可以很容易的看出来,如果所有路由器形成邻接关系之后,那么需要25条LSA通告全网.
选举DR之后,DR负责的任务是:
- 代表该MA网络,以及MA网络中其他attach上的路由器.
- 管理广播流量
简单来说,DR及背后的网段可以看做一个伪节点,从attach到该伪节点的路由器到伪节点的出向cost为正常的接口cost,但是从伪节点到所attach的路由器的cost为0.(没太理解这段话啥意思.)
DR代表一个特定网段的伪节点,DR和BDR都是接口的概念而不是路由器的概念.
从上图可以看出来所有路由器都是与DR建立邻接关系.相互之间并不是常规的邻接.
上面的设计有个问题,如果DR挂了,那么就需要重新选举DR,这个过程中网络是不可达的.所以,为了避免单点故障,ospf的设计是,启用一个BDR.所有路由器同时与DR和BDR建立邻接关系.而且DR和BDR之间也有完全的邻接关系.这样DR挂的时候,可以迅速切换到BDR上去,防止出现网络不可用的情况.
DR/BDR选举的必要条件:
- 使用一个8bit的priority. 思科默认的priority为1,并且可以通过接口命令ip ospf priority来修改.0代表不参与选举
- hello数据包中带有priority及自己认为的DR和BDR的接口地址的字段.
- 一个接口在MA网络中激活时,初始化DR和BDR字段为0.0.0.0,并且设置一个与dead timer相同长度的wait timer
- DR和BDR的信息会被记录到接口表中.
DR和BDR的选举过程:
step1.After two-way communication has been established with one or more neighbors, examine the Priority, DR, and BDR fields of each neighbor’s Hello. List all routers eligible for election (that is, routers with priority greater than 0 and whose neighbor state is at least two-way); all routers declaring themselves to be the DR (their own interface address is in the DR field of the Hello packet); and all routers declaring themselves to be the BDR (their own interface address is in the BDR field of the Hello packet). The calculating router will include itself on this list unless it is ineligible.
在广播链路上,ospf路由器之间进入到2-way状态之后,开始进行DR/BDR的选举.首先,为什么是2-way状态开始进行选举,因为在2-way状态下,所有路由器的邻居ID字段里都已经有了所有其他路由器的RID,保证了选举的公平.
在初始化选举的时候(注意,是初始化选举),所有具有选举条件的路由器都将自己的RID写入hello包的DR和BDR字段中.
step2.From the list of eligible routers, create a subset of all routers not claiming to be the DR (routers declaring themselves to be the DR cannot be elected BDR).
第二步很让人困惑,因为第一步中所有路由器都已经将自己的RID写入DR字段,那么不生成自己是DR的子集一定为空.这一步看上去是与step1冲突的.这里要注意的是,选举的过程是在ospf进程启动后一直存在的,也就是说这个过程是一直有效的,不仅仅是用于初始化的选举.
换句话说,这个子集里的所有路由器的DR字段里写的不是自己的RID,所以,这一步其实是在为BDR做准备.
再来分析一下,现在有很多说法是ospf实际是先选举BDR再将BDR推举为DR,个人认为这种说法是错误的.从下面的步骤中我们可以看到,在初始化的状态下,所有路由器都声称自己是DR和BDR,step2中的子集为空,应该跳转到step5中进行DR的选举.DR选举出来之后,所有路由器的DR字段写的是DR的RID而非自己的RID,这时候就符合进入该子集的条件了.除DR外所有路由器都会进入该子集,开始进行BDR的选举.
step3.If one or more neighbors in this subset include its own interface address in the BDR field, the neighbor with the highest priority will be declared the BDR. In a tie, the neighbor with the highest Router ID will be chosen.
step3比较明确,初始化的过程中所有路由器BDR写的都是自己,在选举完成后,只有BDR写的是自己.其他都写的是BDR的RID.
step4.If no router in the subset claims to be the BDR, the neighbor with the highest priority will become the BDR. In a tie, the neighbor with the highest Router ID will be chosen.
step4说的是,如果没人声称自己是BDR,那么就意味着BDR死了,那么BDR将会重新选举.(死人是不会说话的,同理可得,死掉的BDR也不会说话…所以,BDR不说自己是BDR了,那么就意味着BDR挂了.)
step5.If one or more of the eligible routers include their own address in the DR field, the neighbor with the highest priority will be declared the DR. In a tie, the neighbor with the highest Router ID will be chosen.
这一步是DR的选举.如果很多人说自己是DR,那么优先级大的选作DR,优先级一样,RID大的是DR.(如果RID一样呢,那么你想多了,邻居关系都起不来)
step6.If no router has declared itself the DR, the newly elected BDR will become the DR.
这一步和step4的概念差不多,主要就是如何判定DR挂了.DR不说话了就以为着DR挂了.这时候BDR自动成为DR.如果这时候DR还没有选举出来,那么会先进行BDR的选举,为什么呢,因为大家的DR字段里还是写的那个挂掉的DR,不符合step5的条件,所以step5没有办法执行.
step7.If the router performing the calculation is the newly elected DR or BDR, or if it is no longer the DR or BDR, repeat steps 2 through 6.
step7印证了一个问题,这个过程不是仅仅给初始化的时候用的.
这里有几个问题需要注意:
- 选举是路由器内部的一个过程,所以抓包是看不到太多信息的.
- DR和BDR一旦决定,在新路由器加入的时候不会有变化,那么这种非抢占特性是如何实现的?一个新上线的路由器不会知道自己到底是处在一个新启动的网络环境还是已经有了DR/BDR的环境.所以,正常情况应该是一视同仁.但是,注意,选举过程引入了一个wait time,一个新上线的路由器并不是立即开始选举过程,而是先等待一个wait time,这个时间的引入是为了学习已有DR和BDR.这个时间DR和BDR字段全部为0.
- 关于DR和BDR到底谁是先选举,网络上现在很多人说是BDR先选举出来.之后发现没有DR,BDR自动当选DR.个人感觉这是对RFC文档的误解读.RFC给出的过程并不是一个严格的顺序化过程,而应该是一个状态的触发机制.从debug吐出来的时间来看,两者是同时的.但是很有可能是因为debug时间的粒度远小于实际处理时间间隔.
从抓包来看,感觉是符合文档描述,先选举DR的.(纠结这个问题好像没有太大意义,厂商的具体实现并不一定完全遵循RFC文档)
参考资料:http://blog.sina.com.cn/s/blog_995092640101b4zx.html