路由
路由概述
路由算法
疑问:路由表是怎么维护的?路由表中的下一跳IP地址是怎么确定的?
网络拓扑中,每个点都是一个设备,每条线都是一条网络路径
路由算法可以理解为图论算法,因网络环境的复杂性,路由算法实际上比图论算法更为复杂
理想路由算法的要求:
- 算法是正确的、完整的
- 算法在计算上应该尽可能的简单
- 算法可以适应网络中的变化
- 算法是稳定的和公平的
自治系统(Autonomous System)
- 一个自治系统(AS)是处于一个管理机构下的网络设备群
- AS内部网络自行管理,AS对外提供一个或多个出(入)口,这些出入口就是后面会说到的BGP Speaker
- 每个自治系统都有一个AS号
- 公司AS、家庭AS、校园AS。。。
- 自治系统内部路由的协议称为:内部网关协议(RIP、OSPF)也统称为IGP
- 自治系统外部路由的协议称为:外部网关协议(BGP)
内部网关路由协议-RIP
距离矢量(DV)算法
- **Bellman-Ford(BFA)**算法
D i = m i n j ∈ N ( i ) ( d i j + D j ) D_i = min_{j \in N(i)}(d_{ij} + D_j) Di=minj∈N(i)(dij+Dj)
D i D_i Di:节点i到达其他节点最短路径集合
N(i):节点i相邻节点的集合
d i j d_{ij} dij:节点i和相邻节点j的距离,该值当前节点是已知的
该式中
D
i
D_i
Di和
D
j
D_j
Dj是要同时计算出来的,这在网络中意味着i
节点的所有相邻节点N(i)需同时向i
节点发送自己的
D
j
∈
N
(
i
)
D_{j \in N(i)}
Dj∈N(i),这在网络的复杂环境中是很难办到的
于是基于BFA算法优化,有了异步BF算法(Asynchronous Bellman-Ford)
- Asynchronous Bellman-Ford(ABF)
D i = m i n j ∈ N ( i ) ( d i j + D j i ) D_i = min_{j \in N(i)}(d_{ij} + D_j^i) Di=minj∈N(i)(dij+Dji)
D j i D_j^i Dji:
i
节点最近一次接收到的 D j D_j Dj
异步BF算法中不需要所有相邻节点同时同步自己的最短路径集合,N(i)可以分别同步到 i 节点不需要同时同步
-
计算两节点i和y间最短路径 D i ( y ) D_i(y) Di(y)
d i y = D i ( y ) = m i n j ∈ N ( i ) [ d i j + D j i ( y ) ] d_{iy} = D_i(y) = min_{j \in N(i)} [d_{ij} + D_j^i(y)] diy=Di(y)=minj∈N(i)[dij+Dji(y)]简单解释就是:
i
到目的节点的最小距离,等于i
到邻居距离与邻居到目的地最小距离之和(邻居存在多个,这个和就存在多个) 的最小值; 注意: D i ( i ) = 0 D_i(i) = 0 Di(i)=0 -
距离矢量算法特点(基于ABF)
- 异步:算法不要求所有节点之间同时进行同步计算,各节点可以各自进行单独计算
- 分布式:每个节点都只维护一张局部路由表,每次从邻居节点获得邻居的路由信息后进行计算,计算后将结果分发给邻居
- 迭代:周期性进行路由信息交换计算,持续到邻居无更多信息交换。
- 收敛性:从开始交换信息计算,在有限次数内路由表收敛到一个固定状态时,终止交换计算
-
DV算法伪代码(假设当前节点为x):
Initialization(初始化):
for y in N:
/* if y is not a neigbor then D x ( y ) D_x(y) Dx(y) = ∞ 该初始化方式为SBF/∞,还有另一种方式为SBF/-1 */
D x ( y ) = { 0 y = x d x y y ∈ N ( x ) ∞ y ∉ N ( x ) D_x(y) = \begin{cases} 0 &y=x \\ d_{xy} &y \in N(x) \\ ∞ &y \notin N(x) \end{cases} Dx(y)=⎩⎪⎨⎪⎧0dxy∞y=xy∈N(x)y∈/N(x)
for w in N ( x ) N(x) N(x):
/* 邻居到y的距离,我不知道呀,只能先预估一个 */
D w D_w Dw(y) = ? for all destinations y in N
for w in N ( x ) N(x) N(x):
/* x节点按上述逻辑初始化的所有节点距离矢量表发给每个邻居 */
send D x = [ D x ( y ) : y ∈ N ] D_x = [D_x(y) : y \in N] Dx=[Dx(y):y∈N] to w
loop(循环):
wait (until I see a link cost change to some neighbor w or until I reseive a distance vector from some neighbor w)
/* 观察到或收到邻居w发送的距离矢量表有变动,更新本地记录*/
D w x = D w D_w^x = D_w Dwx=Dw
for each y in N:
D x ( y ) = m i n v ∈ N ( x ) [ d x v + D v x ( y ) ] D_x(y) = min_{v \in N(x)} [d_{xv} + D_v^x(y)] Dx(y)=minv∈N(x)[dxv+Dvx(y)]
if D x ( y ) D_x(y) Dx(y) changed for any destination y:
send distance vector D x D_x Dx = [ D x D_x Dx(y) : y in N] to all neighbors
forever
思考:上述算法描述中, D i D_i Di的计算是收敛到最小值的,那如果链路中两个节点之间的距离增加了,这时怎么同步自己真实增长的链路距离??
- 补充另一个要素
S
i
S_i
Si
- 在每个节点除了用 D i D_i Di表示当前节点到其他节点的距离,还有 S i S_i Si,表示当前节点到其他节点最短距离链路上的下一节点;
- 在上述DV算法更新当前节点 D i D_i Di时,同时确认到当前目标节点的下一节点更新 S i S_i Si
案例拓扑图如下:
我们以节点a作为当前节点进行分析
如图a节点已知自己和邻居节点之间的距离,a节点和其他节点间的距离需要使用其他邻居节点送过来的距离矢量表进行推算, 下表为假设a节点某时刻获得b、c、d、f节点的路由信息(其他节点表可能不是最新同步的,所以可能会和当前拓扑状态不一致)后的路由信息状态
上表
D
a
D_a
Da的值根据d、c、d、f的距离表使用DV算法计算,并产出
S
a
S_a
Sa
例:
D
a
(
e
)
D_a(e)
Da(e)计算:
D
a
(
e
)
D_a(e)
Da(e) = min((
d
a
b
+
d
b
e
d_{ab} + d_{be}
dab+dbe), (
d
a
c
+
d
c
e
d_{ac} + d_{ce}
dac+dce), (
d
a
d
+
d
d
e
d_{ad} + d_{de}
dad+dde), (
d
a
f
+
d
f
e
d_{af} + d_{fe}
daf+dfe))=19 对应下一节点为d
RIP协议
距离:
- 从一个路由器到直接连接的网络的距离定义为1。
- 从一个路由器到非直接连接的网络的距离为所经过的路由数加1。
RIP(Routing Information Protocol)协议是基于DV算法的一种内部网关路由选择协议;
- RIP协议把网络的跳数(hop)作为DV算法的距离;
- RIP协议每隔30秒交换一次路由信息
- RIP协议将超过15跳(是否可设置??)的路由当为不可达路由
缺陷:
- RIP原则是最短路由,路由策略中不会考虑链路的时延快慢,只考虑跳数大小(如网线和光纤等快慢不影响路由选择);
- 网络规模被限制,RIP最大跳数为15,只允许一条路径中有15个路由器,因此RIP只适用于小型网络;
- 网络故障信息传递慢,网络中某节点故障,其他节点需等3分钟接收不到故障节点报文,将其置为不可达;
- 无条件相信相邻节点的信息,自己节点只能看到自己到邻居间的信息;
- 网络信息更新,收敛时间过长
具体过程和上面DV算法伪代码类似
- 路由器(使用RIP协议)初始化 D i D_i Di和 S i S_i Si;
- 获得相邻路由器(假设为x)发来的信息后(本质就是DV算法的过程):
- 对信息内容进行修改,下一跳地址设置为x,所有距离加1;
- 检索本地路由,将修改内容后的路由信息插入或更新到本地路由表里;
- 检索本地路由,对下一跳为x的记录更新为修改后的信息;
- 检索本地路由,对比相同目的的距离,新信息距离小,则真正更新本地路由表;
- 如果3分钟没有收到相邻路由信息,则将相邻路由设置为不可达(16跳)
报文格式:
RIPv1报文:
暂无
RIPv2报文:
网络资料(相当透彻):
距离向量(DV)协议
RIP详解
RIP报文格式
Dijkstra(迪杰斯特拉)算法
上面介绍了Bellman-Ford算法,主要在RIP路由协议中使用;这里介绍的算法是后面介绍的OSPF路由协议的基础???TODO
Dijkstra算法是一个图算法,使用广度优先搜索,来解决一个节点到其他节点的最短路径问题;只能用于边权为正的图中;算法特点是以起始点为中心,向外层层扩展。
算法逻辑简述:
- 初始化两个集合(S, U)(S为只有初始顶点点a的集合,U为其他a到其他顶点集合)
- 如果U不为空, 对U集合顶点进行距离的排序(使用优先队列),并取出距离a最近的一个顶点b
i. 将顶点b纳入S集合
ii.更新通过顶点b到达U集合所有点的距离(如果距离更小则更新,否则不更新)
iii. 重复2步骤 - 直到U集合为空,算法完成
下图我们以a节点为起始节点来演示
- 初始化S和U集合
S = ( a : a → a = 0 ) S = \begin{pmatrix} a:a \rightarrow a = 0 \end{pmatrix} S=(a:a→a=0)
U = ( b : a → b = 6 f : a → f = 7 d : a → d = 8 c : a → c = 9 − : a → e = ∞ ) U = \begin{pmatrix} b:a \rightarrow b = 6\\f:a \rightarrow f = 7\\d:a \rightarrow d = 8\\c:a \rightarrow c = 9\\-:a \rightarrow e = ∞ \end{pmatrix} U=⎝⎜⎜⎜⎜⎛b:a→b=6f:a→f=7d:a→d=8c:a→c=9−:a→e=∞⎠⎟⎟⎟⎟⎞
注:该表格是路由表,此处我们用来补充一下该算法中路由表落地细节目标节点 a b c d e f D a D_a Da 0 6 9 8 ∞ 7 S a S_a Sa - b c d - f - 移动U集合中离a距离最短节点b到S集合中
i. 将顶点b纳入S集合
S = ( a : a → a = 0 b : a → b = 6 ) S = \begin{pmatrix} a:a \rightarrow a = 0\\b:a \rightarrow b = 6 \end{pmatrix} S=(a:a→a=0b:a→b=6)
ii.更新通过顶点b到达U集合所有点的距离(如果距离更小则更新,否则不更新)
通过b计算到链路上到达c的距离a=>c:a->b->c(6+2=8) < a->c(9) 更新U中a->c的最短距离
U = ( f : a → f = 7 b : a → c = ( 6 + 2 ) d : a → d = 8 − : a → e = ∞ ) U = \begin{pmatrix} f:a \rightarrow f = 7\\b:a \rightarrow c = (6+2)\\d:a \rightarrow d = 8\\-:a \rightarrow e = ∞ \end{pmatrix} U=⎝⎜⎜⎛f:a→f=7b:a→c=(6+2)d:a→d=8−:a→e=∞⎠⎟⎟⎞目标节点 a b c d e f D a D_a Da 0 6 9 8 ∞ 7 S a S_a Sa - b c d - f - 移动U集合中离a距离最短节点f到S集合中
S = ( a : a → a = 0 b : a → b = 6 f : a → f = 7 ) S = \begin{pmatrix} a:a \rightarrow a = 0\\b:a \rightarrow b = 6\\f:a \rightarrow f = 7 \end{pmatrix} S=⎝⎛a:a→a=0b:a→b=6f:a→f=7⎠⎞
U = ( b : a → c = 8 d : a → d = 8 f : a → e = ( d a f ( 7 ) + 3 ) ) U = \begin{pmatrix} b:a \rightarrow c = 8\\d:a \rightarrow d = 8\\f:a \rightarrow e = (d_{af}(7)+3) \end{pmatrix} U=⎝⎛b:a→c=8d:a→d=8f:a→e=(daf(7)+3)⎠⎞目标节点 a b c d e f D a D_a Da 0 6 9 8 ∞ 7 S a S_a Sa - b c d - f - 移动U集合中离a距离最短节点c到S集合中
S = ( a : a → a = 0 b : a → b = 6 f : a → f = 7 b : a → c = 8 ) S = \begin{pmatrix} a:a \rightarrow a = 0\\b:a \rightarrow b = 6\\f:a \rightarrow f = 7\\b:a \rightarrow c = 8 \end{pmatrix} S=⎝⎜⎜⎛a:a→a=0b:a→b=6f:a→f=7b:a→c=8⎠⎟⎟⎞
U = ( d : a → d = 8 f : a → e = 10 ) U = \begin{pmatrix} d:a \rightarrow d = 8\\f:a \rightarrow e = 10 \end{pmatrix} U=(d:a→d=8f:a→e=10)目标节点 a b c d e f D a D_a Da 0 6 8 8 ∞ 7 S a S_a Sa - b b d - f - 移动U集合中离a距离最短节点d到S集合中
S = ( a : a → a = 0 b : a → b = 6 f : a → f = 7 b : a → c = 8 d : a → d = 8 ) S = \begin{pmatrix} a:a \rightarrow a = 0\\b:a \rightarrow b = 6\\f:a \rightarrow f = 7\\b:a \rightarrow c = 8\\d:a \rightarrow d = 8 \end{pmatrix} S=⎝⎜⎜⎜⎜⎛a:a→a=0b:a→b=6f:a→f=7b:a→c=8d:a→d=8⎠⎟⎟⎟⎟⎞
U = ( d : a → e = ( d a d ( 8 ) + 1 ) ) U = \begin{pmatrix} d:a \rightarrow e = (d_{ad}(8)+1) \end{pmatrix} U=(d:a→e=(dad(8)+1))目标节点 a b c d e f D a D_a Da 0 6 8 8 ∞ 7 S a S_a Sa - b b d - f - 移动U集合中最后一个节点e到S集合中
S = ( a : a → a = 0 b : a → b = 6 f : a → f = 7 b : a → c = 8 d : a → d = 8 d : a → e = 9 ) S = \begin{pmatrix} a:a \rightarrow a = 0\\b:a \rightarrow b = 6\\f:a \rightarrow f = 7\\b:a \rightarrow c = 8\\d:a \rightarrow d = 8\\d:a \rightarrow e = 9 \end{pmatrix} S=⎝⎜⎜⎜⎜⎜⎜⎛a:a→a=0b:a→b=6f:a→f=7b:a→c=8d:a→d=8d:a→e=9⎠⎟⎟⎟⎟⎟⎟⎞
U = ( ) U = \begin{pmatrix} \end{pmatrix} U=()目标节点 a b c d e f D a D_a Da 0 6 8 8 9 7 S a S_a Sa - b b d d f - U集合为空,结束
网络资料:
Dijkstra算法
Dijkstra算法图文详解 该文章算法描述未使用堆优化(堆优化使用优先队列)
内部网关路由协议-OSPF
OSPF(Open Shortest Path First:开放最短路径优先),协议的核心是Dijkstra算法。
上面已经介绍了Dijkstra算法,我们在描述算法逻辑时,其实是假设a节点已经知道其他节点间的距离(即图中每条边的长度),这些信息称为链路状态数据库,在路由器刚接入到网络时,链路状态数据库是有个收集过程的,下面我们再完整了解一下OSPF。
链路状态(LS)协议
LS协议作用是保持“链路状态数据库”是全网一至的;
- 只有邻居路由器之间才会交换LSA,每隔30S交换一次
- 路由器向所有路由器发送消息
- 发送的消息是描述该路由器与相邻路由器的链路状态(LSA)
- 只有链路状态发生变化时,才发送更新信息
链路状态数据库(LSDB)
链路状态数据库保存当前网络所有LSA记录,整个网络节点中相互交流保持LSDB一致;
链路状态LSA描述的是路由器与相邻路由器之间的链路状态,此链路状态不仅仅是跳数,还包括距离、时延、带宽等因素;
以Dijkstra算法描述案例来看,该拓扑中的链路状态数据库简略描述如下
- | a | b | c | d | e | f |
---|---|---|---|---|---|---|
a | 0 | 6 | 9 | 8 | ∞ | 7 |
b | 6 | 0 | 2 | ∞ | ∞ | ∞ |
c | 9 | 2 | 0 | 3 | ∞ | 2 |
d | 8 | ∞ | 3 | 0 | 1 | ∞ |
e | ∞ | ∞ | 2 | 1 | 0 | 3 |
f | 7 | ∞ | ∞ | ∞ | 3 | 0 |
OSPF报文
OSPF用IP报文直接封装协议报文,IP报文首部的协议类型为89的报文数据部分即为OSPF报文;
OSPF报文分五种,五种报文报文头格式一样,都为24字节,详细格式见OSPF报文类型
- Hello
Hello包是用来建立和维护OSPF邻居的,要交换LSA,必须先通过Hello包建立OSPF邻居。
邻接(Adjacency)
两台OSPF路由器能够形成邻居,但并不一定能相互交换LSA,只要能交换LSA,关系则称为邻接(Adjacency)。邻居之间只交换Hello包,而邻接(Adjacency)之间不仅交换Hello包,还要交换LSA
- Database Description Packets(DBD)
DBD报文内容包括**LSDB(链路状态数据库)中每一条LSA(链路状态)**的Header(LSA的Header可以唯一标识一条LSA),是LSDB的描述信息;
邻居建立之后,并不会立刻就将自己链路状态数据库中所有的LSA全部发给邻居,而是将LSA的基本描述信息(DBD)发给邻居,是LSA的目录信息,相当于书的目录,邻居在看完DBD之后,就能知道哪些LSA是需要邻居发送给自己的。 - Link State Request Packet(LSR)
邻居在看完发来的DBD之后,就知道哪些LSA是需要邻居发送给自己的,自己就会向邻居发送LSA请求(LSR),告诉邻居自己需要哪些LSA - Link State Update Packet(LSU)
当邻居收到其它路由器发来的LSA请求(LSR)之后,就知道对方需要哪些LSA,然后根据LSR,将完整的LSA内容全部发给邻居,以供计算路由表。 - Link State Acknowledgment Packet(LSAck)
邻居收到请求的LSU回应后,需返回确认报文即LSAck,报文内容是待确认LSA的Header集合
OSPF过程
路由器接入网络 => 路由器向邻居发出问候信息 => 与邻居交流并收敛链路状态数据库 => 广播和更新位置路由
网络资料:
OSPF报文类型
OSPF协议介绍及配置
OSPF协议介绍
外部网关路由协议-BGP
BGP(Border Gateway Protocol 边际网关协议)是运行在自治系统(AS)之间的协议
**??**有了RIP和OSPF为什么还需要BGP
网络规模很大,整个使用OSPF等协议的话,路由信息将会非常巨大,路由交换时会消耗大量网络资源。
不同的自治网络之间的交互涉及到政策、宗教、信息安全等各个方面的因素,自治网络间需要个性化访问策略
概念
- BGP发言人(BGP Speaker)
BGP发言人是AS中的一个边界路由器,BGP协议不关注AS内部网络是什么样,两个AS之间通过BGP发言人交流信息;发言人可以自定义配置策略;说白了发送BGP消息的路由器就是BGP发言者 - Router ID(RID)
Router ID为32位比特的无符号整数,自治系统中使用RID唯一标识一台路由器,RID可以手动配置也可以由路由协议自动选举 - BGP对等体(BGP Peer)
相互交换信息的BGP Speaker之间互称对等体 - IBGP对等体(Internal BGP Peer)
BGP对等体处于同一自治系统时,称为IBGP对等体,两对等体可以是直连的也可以不是直连的; - EBGP对等体(External BGP Peer)
BGP对等体处于不同自治系统时,称为EBGP对等体,一般情况下EBGP对等体是直连的 - AS号
每个自治系统都有个号码,BGP中AS号标识路由器属于哪个AS系统,AS号也能确定两个对等体之间是IBGP还是EBGP关系
工作原理
-
对等体路由信息交互
- BGP Speaker从IBGP处获得的路由信息,只发布给EBPG
- 从EBGP处获得的路由信息,发布给所有的IBGP和EBGP邻居
- 不发送全量路由信息,只发送最优BGP路由
- 路由有变化时,只发送需要更新的路由信息
-
BGP有关数据库:
-
IP-RIB(IP路由表)
全局路由信息库,包括所有IP路由信息
-
Loc-RIB(BGP路由表):
BGP路由信息库,包括本地BGP Speakr选择的路由信息
-
邻居表:
对等体邻居清单列表
-
Adj-RIB-In:
对等体宣告给本地BGP Speaker的未处理的路由信息库
-
Adj-RIB-Out:
本地BGP Speaker宣告给指定对等体的路由信息库
-
-
信息处理过程:
图片引自:https://www.cnblogs.com/good-study/p/Network_Wei.html
BGP报文
BGP报文有五种类型:
- OPEN
- UPDATE
- NOTIFICATION
- KEEPALIVE
- REFRESH(RFC2918)
具体格式参见下面资料
网络资料:
BGP(边界网关协议)简述
BGP报文类型
RIP、OSPD、BGP对比
协议 | RIP | OSPF | BGP |
---|---|---|---|
类型 | AS内部 | AS内部 | AS外部 |
算法 | DV算法 | Dijkstra | ?? |
上层报文协议 | UDP | IP | TCP |
交互对象 | 邻居路由器 | 拓扑中所有路由器 | 对等体(使用BGP的路由器) |
交互内容 | 当前节点到其他节点的所有自己计算出的路由信息 | 拓扑中所有节点和其邻居的链路信息 | ?? |