Ospf中路由器之间存在两种连接关系:邻居关系和邻接关系。本博文将详细介绍这2种关系建立及工作原理。

如果两台路由器之间共享一条公共数据链路(两台路由器中间没有其它路由器,或者两台路由器之间存在虚连接),并且成功协商了hello包中所指定的参数,那么它们就成为邻居。如果两个邻居之间需要同步LSDB,那么它们之间需要建立邻接关系。如果两个路由器之间建立了邻接关系,那么它们的LSDB一定是同步的。LSA只在存在邻接关系的路由器之间传递。

那么邻居关系和邻接关系怎么建立呢?邻居关系通过hello报文来建立。Hello报文中包含如下一些内容:

1、始发路由器的router-id

2、始发路由器接口的area-id

3、始发路由器接口的地址掩码

4、始发路由器接口的authentication type和authentication message

5、始发路由器接口的hello-interval

6、始发路由器接口的router dead-interval

7、路由器优先级

8、指定DR和BDR

9、标识可选性能的5个标志位

10、始发路由器的所有有效neighbor router-id(始发路由器接收到了它们的hello报文)

以两台路由器之间建立邻居关系为例:

1、R1发送hello报文(组播或者单播,链路层类型来定),neighbor字段为空

2、R2收到hello报文,为R1建立一个邻居数据结构,并把R1的邻居状态置为init,然后向R1发送hello报文,neighbor字段中包含R1的rougerID,表示自己收到了R1的hello报文。

3、R1收到R2的hello报文之后,为R2建立一个邻居数据结构,并把邻居状态置为2way,然后向R2发送hello报文,报文的neighbor字段中包含R2的routerID。

4、R2收到R1的hello报文后,把R1的邻居状态置为2way

至此,邻居关系就建立起来了,邻居路由器之间会按时发送hello报文进行保活,如果hello报文超时,那么该路由器就会宣告这里邻居失效。

所有路由器之间都达到2way状态后,它们会根据网络类型判断是否需要选举DR和BDR,如果需要的话就开始选举DR和BDR。

邻居路由器之间会判断是否需要建立邻接关系,怎么判断呢?

1、 如果是point-to-point链路,需要建立邻接关系

2、 如果是point-to-multipoint链路,需要建立邻接关系

3、 如果网络类型是虚链路,需要建立邻接关系

4、 本地路由器是网段上的DR,需要建立邻接关系

5、 本地路由器是网段上的BDR,需要建立邻接关系

6、 邻居路由器是网段上的DR,需要建立邻接关系

7、 邻居路由器是网段上的BDR,需要建立邻接关系

如何建立邻接关系呢?

其实邻接关系的建立过程中就顺带把LSDB同步了。过程如下:

建立邻接关系使用下面三种协议报文:

Hello报文type1、数据库描述数据包type2、链路状态请求报文type3、链路状态更新报文type4、链路状态确认报文type5

1、RT1的一个连接到广播类型网络的接口上激活了OSPF协议,并发送了一个HELLO报文(使用组播地址224.0.0.5)。由于此时RT1在该网段中还未发现任何邻居,所以HELLO报文中的Neighbor字段为空。

2、RT2收到RT1发送的HELLO报文后,为RT1创建一个邻居的数据结构,并且将RT1的邻居状态机置为Init。RT2发送一个HELLO报文回应RT1,并且在报文中的Neighbor字段中填入RT1的Router id,表示已收到RT1的HELLO报文。

3、RT1收到RT2回应的HELLO报文后,为RT2创建一个邻居的数据结构,并将邻居状态机置为Exstart状态。下一步双方开始发送各自的链路状态数据库。

为了提高发送的效率,双方需先了解一下对端数据库中那些LSA是自己所需要的(如果某一条LSA自己已经有了,就不再需要请求了)。方法是先发送DD报文,DD报文中包含了对本地数据库中LSA的摘要描述(每一条摘要可以惟一标识一条LSA,但所占的空间要少得多)。由于OSPF直接用IP报文来封装自己的协议报文,所以在传输的过程中必须考虑到报文传输的可靠性。

为了做到这一点,在DD报文的发送过程中需要确定双方的主从关系。作为Master的一方定义一个序列号seq,每发送一个新的DD报文将seq加一。作为Slave的一方,每次发送DD报文时使用接收到的上一个Master的DD报文中的seq。实际上这种序列号机制是一种隐含的确认方法。如果再加上每个报文都有超时重传,就可以保证这种传输是可靠的。

RT1首先发送一个DD报文,宣称自己是Master(MS=1),并规定序列号为x。I=1表示这是第一个DD报文,报文中并不包含LSA的摘要,只是为了协商主从关系。M=1说明这不是最后一个报文。

4. RT2在收到RT1的DD报文后,将RT1的邻居状态机改为Exstart,并且回应了一个DD报文(该报文中同样不包含LSA的摘要信息)。由于RT2的RouterID较大,所以在报文中RT2认为自己是Master,并且重新规定了序列号为y。

5. RT1收到报文后,同意了RT2为Master,并将RT2的邻居状态机改为Exchange。RT1使用RT2的序列号y来发送新的DD报文,该报文开始正式地传送LSA的摘要。在报文中RT1将MS=0,说明自己是Slave。

6. RT2收到报文后,将RT1的邻居状态机改为Exchange,并发送新的DD报文来描述自己的LSA摘要,需要注意的是:此时RT2已将报文的序列号改为y+1了。

7. 上述过程持续进行,RT1通过重复RT2的序列号来确认已收到RT2的报文。RT2通过将序列号+1来确认已收到RT1的报文。当RT2发送最后一个DD报文时,将报文中的M=0,表示这是最后一个DD报文了

8. RT1收到最后一个DD报文后,发现RT2的数据库中有许多LSA是自己没有的,将邻居状态机改为Loading状态。此时RT2也收到了RT1的最后一个DD报文,但RT1的LSA,RT2都已经有了,不需要再请求,所以直接将RT1的邻居状态机改为Full状态。

9. RT1发送LS Request报文向RT2请求所需要的LSA。RT2用LS Update报文来回应RT1的请求。RT1收到之后,需要发送LS Ack报文来确认。上述过程持续到RT1中的LSA与RT2的LSA完全同步为止。此时RT1将RT2的邻居状态机改为Full状态。

注:

以上过程是两台路由器由相互没有发现对方的存在到建立邻接关系的过程。或者可以理解为网络中新加入一台路由器时的处理情况。当两台路由器之间的状态机都已经达到Full状态之后,如果此时网络中再有路由变化时,就无须重复以上的所有步骤。只由一方发送LS Update报文通知需要更新的内容,另一方发送LS Ack报文予以回应即可。双方的邻居状态机在此过程中不再发生变化。

转自:http://blog.csdn.net/yiluyangguang1234/article/details/50571910

OSPF建立邻居、邻接关系 学习笔记的更多相关文章

  1. HCNA Routing&Switching之动态路由协议OSPF建立邻居的条件

    前文我们了解了OSPF的router id.数据包结构.类型.不同类型的数据包作用以及OSPF状态机制,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15027 ...

  2. 基于 OSPF 路由的邻居邻接关系发现实践

    1.实验目的 理解 OSPF 邻居关系和 OSPF 邻接关系的含义及差别 观察 OSPF 邻居邻接关系的建立过程 观察 OSPF 链路状态数据库的同步过程 2.实验原理 OSPF 网络中,路由器在发送 ...

  3. Sparse Filtering 学习笔记(三)目标函数的建立和求解

      Sparse Filtering 是一个用于提取特征的无监督学习算法,与通常特征学习算法试图建模训练数据的分布的做法不同,Sparse Filtering 直接对训练数据的特征分布进行分析,在所谓 ...

  4. Solr学习笔记之3、Solr dataimport - 从SQLServer导入数据建立索引

    Solr学习笔记之3.Solr导入SQLServer数据建立索引 一.下载MSSQLServer的JDBC驱动 下载:Microsoft JDBC Driver 4.0 for SQL Server ...

  5. SQL反模式学习笔记4 建立主键规范【需要ID】

    目标:建立主键规范 反模式:每个数据库中的表都需要一个伪主键Id 在表中,需要引入一个对于表的域模型无意义的新列来存储一个伪值,这一列被用作这张表的主键, 从而通过它来确定表中的一条记录,即便其他的列 ...

  6. Ruby学习笔记4: 动态web app的建立

    Ruby学习笔记4: 动态web app的建立 We will first build the Categories page. This page contains topics like Art, ...

  7. Django学习笔记(二):使用Template让HTML、CSS参与网页建立

    Django学习笔记(二):使用Template让HTML.CSS参与网页建立 通过本文章实现: 了解Django中Template的使用 让HTML.CSS等参与网页建立 利用静态文件应用网页样式 ...

  8. python学习笔记:建立一个自己的搜索引擎

    写学习笔记是我学习python以来养成的一个习惯,每学习一个知识点,便整理成文字记录下来.搜索引擎大家经常都有在使用,国内外也很很多搜索引擎平台. Google搜索引擎建立至今已经快20年了,之后全球 ...

  9. C++学习笔记之由文本文件读取数据到vector模板建立的二维数组 并存储为新的文本文件

    阅读本文可首先参考: C++学习笔记之输入.输出和文件 测试数据: /*读取txt文件到二维数组*/ #include <iostream> #include <fstream> ...

随机推荐

  1. Unity创建一个简易的弹簧(弹动)效果

    参考文章:http://www.cnblogs.com/SkyD/archive/2008/09/05/1284778.html 主要依据胡克公式F=-k·x.这里k是倔度系数,可以理解为k值越大弹性 ...

  2. [svc]linux内核参数

    内核参数 说明 net.ipv4.tcp_max_syn_backlog = 2048 增大队列SYN最大半连接数; 对于那些依然还未获得客户端确认的连接请求,需要保存在队列中最大数目.默认值是102 ...

  3. 【Unity】3.6 导入图片资源

    分类:Unity.C#.VS2015 创建日期:2016-04-05 一.简介 Unity支持的图像文件格式非常多,包括TIF.PSD.TCA.JPC.PNG.GlF.BMP.IFF.PICT.DDS ...

  4. 正确使用 Volatile 变量

    Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少, ...

  5. Java map双括号初始化方式的问题

    关于Java双括号的初始化凡是确实很方便,特别是在常量文件中,无可替代.如下所示: Map map = new HashMap() { { put("Name", "Un ...

  6. vim学习日志(8):linux查看和修改文件编码

    查看文件的编码 方法一: 1.在Vim中可以直接查看文件编码:set fileencoding即可显示文件编码格式.注:如果你只是想查看其它编码格式的文件或者想解决用Vim查看文件乱码的问题,那么你可 ...

  7. node的http请求

    //node的http服务 'use strict' var http = require('http') var server = http.createServer(function (reque ...

  8. 【Tensorflow】设置显存自适应,显存比例

    用惯了theano.再用tensoflow发现一运行显存就满载了,吓得我吃了一个苹果. 用天朝搜索引擎毛都搜不到,于是FQ找了下问题的解决方法,原来有两种 按比例 config = tf.Config ...

  9. [转]Oracle存储过程总结

    原文地址:https://www.cnblogs.com/tingbogiu/p/5641000.html 1.存储过程结构 1.1 第一个存储过程 create or replace procedu ...

  10. android 中使用jwt token(json web token)--java

    http://blog.csdn.net/mingzhnglei/article/details/51119836 下面贴上自己项目中的一个小小的example import com.nimbusds ...