关于DR/BDR的选举似乎一直没有定论,卷一中所写的选举过程实为引用的RFC2328,而其内容用“过程”来定义似乎是不太容易理解的,准确来说,应该是状态的触发,我们想想可知,OSPF协议选举DR/BDR过程的代码不会是这些步骤的顺序实现,所以我们在分析的时候要找到每一个步骤的触发点,下面我具体分析一下,事先声明这不是翻译
 
1.  After two-way communication has been established with .e 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 . this list unless it is ineligible.
 
在广播型链路上,所有OSPF路由器之间进入Two-Way状态后开始触发选举过程,这个状态下,每一台路由器的邻居ID字段都包含其他所有的路由器的ID,这是选举公平的保证。
 
下一个关键点是,选举初始化时,所有的路由器在一开始都宣称自己是DR和BDR,这里涉及到RFC中的两个英文单词 declare 和 claim,很多人认为这上面有文章,其实这两个单词都有宣称的意思,只不过declare用于更为正式的场合,试想一台OSPF路由器会有这等人性的思考?所以用词我觉得作者可能都没有怎么考虑,因为在路由器上实现所谓的“宣称自己是DR/BDR”就是将自己的路由器ID写入Hello包中DR ID字段中和BDR ID字段中

2.  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).
 
第2步很有意思,似乎与第1步冲突,既然都声称自己是DR,那么不声称自己是DR的子集一定为空啊? 其实这是思维定势,因为一个选举的代码是要始终有效的,而不是仅仅用于初始化的选举。
 
注:个人认为将子集替换为字段会较容易理解些。)
 
关键点就一句话:能进入这个子集的条件是,这台路由器的DR ID字段里写的不是自己的ID,这第2步是为下一步选举BDR做准备的!
 
具体我们分析一下:在初始化状态下,即网络中没有DR,所有人都宣称自己是DR,也宣称自己是BDR,根据原则,这个子集为空,这时会直接跳到第5步,先去选举DR,在DR选举出以后,也就是网络中存在DR,现象是这样:除了DR在DR ID字段的写的是自己的ID以外,别的路由器都不是写的自己,而是选举出的那个DR的ID,那么这时就符合进入子集的条件了,除DR外的所有路由器都会进入这个子集,进行下一步,即BDR的选举。

3.  If .e 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.
 
第3步,在选举BDR的时候,大家都在BDR ID字段写的自己的ID,选举结果明确后,只有BDR发的Hello包中写的是自己的ID,子集里其余的路由器都不是写的自己ID,而是选举出来的BDR的ID。

4.  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.
 
第4步应该这样理解:如果这个子集没有路由器说自己是BDR,那就意味着BDR死掉了(本来就他一个说自己是BDR,死了就说不出来了),BDR会重新选举。

5.  If .e 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.
 
第5步是DR的选举过程,没有所谓的子集概念,也不是第2步以后的步骤,而是不满足第2步的条件直接跳到这一步。选举DR的资格是:在DR ID字段中写的是自己的ID

6.  If no router has declared itself the DR, the newly elected BDR will become the DR.
 
第6步中说到的如果没有人宣称自己是DR对应的情景是这样,别人都说A是DR,A也应该说自己是DR,可是他死了,死人是不会说话的,所以BDR成为DR,其实这一条就是说,如果DR当掉,BDR会成为新的DR。而如果这时BDR还没有选出来,还是会先进行BDR的选举,然后BDR成为DR,为什么,因为大家的DR字段里还是写的那个死了的DR,不符合选举DR的条件,第5步无法执行。

7.  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.
 
其实这一步就是说明了这个程序不仅仅是为初始化的选举用的,当稳定的角色分配出现问题时,依然能通过这些原则使角色重新定义。
 
总结:
 
其实DR/BDR选举就是“字段游戏”,DR的选举资格:在Hello包中的DR ID写的是自己的ID,BDR的选举资格:在Hello包中的BDR ID写的是自己的ID 且在 DR ID字段写的不是自己的ID,具体选举还要看接口优先级和最高Router-id。