计算机网络课程总结 --RIP 与 OSPF
本文主要讲述内部网关协议中两个著名的协议 RIP 和 OSPF。
路由器的基本功能是路由 (Routing) 和转发 (Forwarding)。其中路由指的是通过路由选择协议将路由信息注入到路由表中,转发指的是依据路由表和分组携带的信息将分组从入口转到正确的出口的过程。
分组转发的技术有以下几种
- Source routing(源路由):分组携带路径
- Table of virtual circuits(虚电路):穿越网络建立链接及状态,使用链接转发分组
- Table of global addresses (IP,数据报交换):路由器维持到目的地的下一条,分组需要携带目的地地址
本文主要涉及到的是第三种。
静态路由
配置命令 Ip route prefix mask {address|interface} [distance]
使用地址 (address) 和使用接口 (interface) 的差别
- 使用接口,路由器知道从哪里转发出去,更高效
- 使用地址需要第二次查找,以确定转发接口
距离 (distance) 的特定
- 直连网络的管理距离为 0
- 静态路由的管理距离为 1
- 值越小,优先级越高
- 到达某个网络出现多条路由的情况下,可以依据管理距离进行选择
还可以通过管理距离配置备份路由(也称为浮动静态路由),如下图所示
动态路由
动态路由就是通过协议动态地学习到路由信息,据其作用域的不同,又可分为内部网管协议 (IGP) 和边界网络协议 (BGP);内部网关协议有 RIP,OSPF,IGRP,EIGRP 等,其在网络中的位置入下
这里主要讲述内部网络协议中的 RIP 和 OSPF。
RIP
RIP 是典型 DV (Distance Vector, 距离矢量) 协议,其工作原理如下:
- 每个路由器维护两个向量 \(D_i\) 和 \(S_i\) 来表示该点到网上所有节点的路径距离及其下一个节点
- 相邻路由器之间交换路径信息
- 各节点根据路径信息更新路由表
向量 \(D_i\) 和 \(S_i\) 的含义如下: \(d_{i1}\):从节点 i 到节点 1 的时延向量 \(S_{i1}\):从节点 i 到节点 1 的一条最小时延路径上的下一个节点 n :网络中的节点数
RIP 使用跳数作为路由选择的度量,当到达目的网络的跳数超过 15 跳,数据包将被丢掉。 RIP 路由更新广播默认周期为 30 秒。
下图是 RIP 的一个简单例子
RIP 在 ipv4 中的协议版本有 RIPv1 和 RIPv2, 其中 RIPv1 只支持传输自然网段的地址 (也就是 ABC 三类网络),而 RIPv2 修复了这个缺陷,增加了一个子网掩码的段,支持所有长度的子网掩码,也支持 CIDR 和 VLSM。
路由环路
RIP 协议可能会导致路由环路,下图为一个路由环路的例子,图中初始状态是正常状态,但是当 40.0.0.0 的网络挂掉后,C 不会修改到网络 40.0.0.0 的距离不可达,而是相信 B 传过来的关于 40.0.0.0 网路的距离为 1 的消息,从而导致错误信息不断在网络中传输,每个路由器到 40.0.0.0 的距离不断增大,直到距离超过 15 才将网络 40.0.0.0 标记为不可达。
虽然上面的例子中距离增大到 16 的时候会将网络 40.0.0.0 标记为不可达,但是这样的话收敛的速度会非常慢。为了提高收敛的速度,常常会有以下方法
- 水平分割(Split Horizon)
- 毒性逆转(Poison Reverse)
- 抑制定时器(Hold-Down Timers)
- 触发更新(Triggered Updates)
水平分割(Split Horizon) 分析上面的例子中路径环产生的原因,就是 B 向 C 提供了一条过时的、错误的路由信息。
但是分析可知,B 必须经由 C 方可到达网络 40.0.0.0,所以 B 不可能向 C 提供任何有价值的路由信息。因此可以修改 B 对 C 提供的路由,禁止 B 向 C 提供关于此信宿的路由信息,具体操作就是 B 告诉 C 一条在正常情况下不真实的消息:网络 40.0.0.0 不可达(距离为无穷大,实际中记为 16 即可)。
通过水平分割可以使得上面的情况的收敛速度加快,如下所示
毒性逆转(Poison Reverse) 分析上面的例子,当网络 40.0.0.0 挂掉的时候,路由器 C 并没有采取任何措施,而是利用了 B 的信息更新。
而毒性逆转的方法就是指当 C 发现网络 40.0.0.0 发生故障时,主动将到达信宿的距离改为无穷大(实际中改为 16 即可),收敛过程如下图所示
抑制定时器(Hold-Down Timers) 当 C 发现网络 40.0.0.0 发生故障时,启动抑制计时器。
在抑制计时期间内,有三种可能 1. 如果网络状态转变,即 down→up
,则关闭计时器,保留原有路由信息 2. 如果收到来自 B 的关于信宿的路由信息,且路径比原有路径短,则关闭计时器,更新路由信息 3. 如果无上述两种情况发生,计时器到时,更新路由为信宿不可达。
触发更新(Triggered Updates) 当 C 发现网络 40.0.0.0 发生故障时,不等下一刷新周期到来,立刻更改路由为 “信宿不可达”,引起全网的连锁反映,迅速刷新
类似于 RIP 这种 DV 类协议的优点是算法简单,但是缺点有:
- 交换的路径信息量大
- 路径信息传播慢,使得路径信息可能不一致。
- 收敛速度慢,存在无穷计算问题。
- 不适合大型网络
RIPng
RIPng 是 IPV6 中使用的 RIP 协议,保留了原来 RIP 协议的一些特性,也增加了一些新的特点。
RIPng 有以下特点
- UDP 端口号:使用 521 端口收、发报文(RIPv2 用 520 端口)
- 组播地址:
FF02::9
作为链路本地范围的路由器组播地址 - 源地址:使用链路本地地址
FE80::/10
作为源地址发送 RIPng 路由信息报文 - 下一跳地址:使用 128 位的 IPv6 地址
’ RIPng 和 RIPv2 的报文对比如下 其中 RIPng 的一个报文种可包含多条路由信息,而 RIPv2 一个报文只含有一条路由信息。
RIPng 的报文格式为
RIPv2 的报文格式为
RIPng 中有 Request 和 Response 两种报文,其作用分别如下 Request 报文:当路由器启动或更新时,发该类报文(组播),用于请求其他路由器的路由信息 Response 报文:对 Request 的回应,通常包含全部的路由信息。除了收到 Request 的时候会发送,路由器还会周期性地发送。
配置
RIP 的配置的主要工作就是启动 RIP 进程并声明路由器所连接的网络。如下图所示
默认是 RIPv1,如果要配置 RIPv2, 需要 version 2
的命令,如下图所示
RIPng 的配置过程入下
OSPF
OSPF 时典型的 LS (Link State, 链路状态) 协议,其思想是通过邻居的 LSA (Link-state advertisement, 链路转态通告) 构建整个网络的拓扑并构建最小生成树,然后通过 dijkstra 计算最短路径,并根据最短路径修改路由表。
OSPF 有以下特点
- 无路由自环
- 支持 VLSM、CIDR
- 使用带宽作为度量值(108/BW)
- 收敛速度快
- 通过分区实现高效的网络管理
- 支持帧中继,X2.5, Ethernet, ppp 等网络
- 可以在大型网络中使用
OSPF 协议的一些基本概念如下;
- 协议号 = 89:IP 头中代表 OSPF 报文的协议号是 89
- RouterID:一个 32 位的无符号整数,是一台路由器的唯一标识,在整个自治系统内唯一
- 路由器间的关系:邻居 (Neighbor)、邻接 (Adjacent)、未知 (Unknown)
- TTL=1:通常 OSPF 报文不转发,只被传递一条,即在 IP 报头的 TTL 值被设为 1,
- DR (Designated Router) 和 BDR (Backup Designated Router): DR 是由所有路由器选举出来的,目的是减少路由器间同步的次数,所有路由器只需要和选举出来的 DR 进行同步即可,原理如下图所示,BDR 是 DR 的备份路由器。
这里需要注意的是,DR 是路由器选出来的,选举规则根据其 priority 值的大小,若 priority 相同则比较 router id;DR 一旦当选,除非路由器故障,否则不会更换;DR 选出的同时,也选出 BDR,DR 故障后,由 BDR 接替 DR 成为新的 DR
报文类型
OSPF 的分组有五种,分别如下所示
OSPF 报文类型 | 作用 |
---|---|
Type = 1, Hello 报文 | 建立和维护连接,报文中包含自己的 RouterID 和区域 ID |
Type = 2,DD (数据库描述) 报文 | 描述一个 OSPF 路由器的链路状态数据库内容,传输 LSA 摘要 |
Type = 3,LSR (链路状态请求) 报文 | 请求对方发送自己没有的 LSA |
Type = 4,LSU (链路状态更新) 报文 | LSR 的应答,可回传多条 LSA |
Type = 3,LSAck (链路状态确认) 报文 | 确认收到 LSA |
建立毗邻关系
OSPF 运行的步骤为 1. 建立路由器毗邻关系 2. 选举 DR 和 BDR 3. 发现路由 4. 选择最佳路由 5. 维护路由信息
OSPF 中,一个路由器的的状态可能为
- Down
- Init(初始)
- Two-way(双向)
- ExStart(准启动)
- Exchange(交换)
- Loading(加载)
- Full adjacency(全毗邻)
结合路由器的状态,OSPF 建立毗邻关系的步骤如下
1)RT1,RT2 在某个接口激活了 OSPF 后,都会开始在这个接口上去发组播的 Hello 报文,目的是发现 OSPF 邻居,此时双方都处于 Down
状态。
2)当 RT2 收到 RT1 发来的 Hello 包(Neighbors Seen 为空),此时 RT2 的状态变为 init
,然后将 RT1 的 Router-ID 存储放在 Hello 报文中 (Neighbors Seen = RT1) 发送出去,当 RT1 收到这个 hello 报文并从中找到自己的 Router-ID,RT1 会认为与 RT2 已经完成了双边关系的建立,此时 RT1 的状态变为 Two-way
,而 RT1 会发送 Neighbors Seen = RT2 的 hello 包让 RT2 的状态也变为 Two-way
。
3)接下来 RT1 和 RT2 会进入 ExStart
状态并开始进行 Master、Slave 的协商。协商 M/S 的目的是为了决定在后续的 LSA 交互中,谁来决定 DD(Database Description)报文的序列号(Sequence Number),而 Router-ID 大的那个 OSPF 路由器的接口将会成为 Master(注意这里的 Master 不是 DR). 协商过程通过 DD 报文实现,有三个关键的字段:I、M、MS,其含义如下
字段 | 含义 |
---|---|
I(Init) | 如果是第一个 DD 报文则置 1,其它的均置 0 |
M(More) | 如果是最后一个 DD 报文则置 0,否则均置 1 |
M/S | 设置进行 DD 报文双方的主从关系,如果本端是 Master 角色,则置 1,否则置 0 |
Sequence Number | 指定所发送的 DD 报文序列号。主从双方利用序列号来确保 DD 报文传输的可靠性和完整性 |
4)确认了 M/S 关系后,两个路由器就进入了 Exchange
状态, 主路由器首先开始和从路由器共享链路状态信息。如果将链路状态数据库比喻成一本书,那么 DD 报文相当于这本书的目录,通过 DD 报文,可以发现自己所没有的信息。
5)当所有的 DD 报文传输完后,假如从路由器通过 DD 报文发现了自己所没有的信息后,会发送 LSR 报文给主路由器,随后主路由器会发送 LSU 报文给从路由器。从路由器将该信息合并到它的本地链路状态数据库中。从路由器会回应一个 LSAck 包给主路由器。此时两者处于 loading
状态。
6)两者的链路数据库一致,达到了 full
状态。
其状态转移图如下所示,图中的稳态有三种 (Down
,Two-way
,Full
)
其他概念
克服路由自环 OSPF 能够克服路由自环的原因有以下几个
- 每一条 LSA 都标记了生成者(用生成该 LSA 的路由器的 RouterID 标记),其他路由器只负责传输,这样不会在传输的过程中发生对该信息的改变和错误理解。
- 路由计算的算法是 SPF,计算的结果是一棵树,路由是树上的叶子节点,从根节点到叶子节点是单向不可回复的路径。
- 区域则通过规定骨干区域避免
大型网络中存在的问题及对策
在大型网络中,OSPF 存在着以下问题
- 链路状态数据库 (LSDB) 非常庞大,占用大量存储空间
- 计算最小生成树耗时增加,CPU 负担很重,一点变化都会引发从头重新计算
- 网络拓扑结构经常发生变化,网络经常处于 “动荡” 之中
针对该问题,常用的解决方法是对 OSPF 划分区域
OSPF 路由器的类型 根据位置不同,OSPF 路由器可以被被划分为不同类型
- 内部路由器 --- 路由器所有接口都在一个区
- 主干路由器 --- 所有接口都在主干区域的路由器
- 区域边界路由器 (ABR) --- 路由器接口分属不同区域 (Area)
- 自治域边界路由器 (ASBR) --- 路由器至少有一个接口不属于本自治域 (AS).
OSPFv3
OSPFv3 保留了 OSPFv2 的基本机制
- 网络类型和接口类型
- 邻居发现和邻接(毗邻)建立机制
- 接口状态机和邻居状态机
- 基于 LSDB 计算路由
- LSA 老化更新机制
- 泛洪机制 (Flooding mechanism)
- 共五种协议报文: Hello, DD, LSR, LSU, LSAck
但是 OSPFv3 在 OSPFv2 的基础上做出的变化为:
1)基于链路运行
在 OSPFv2 中,协议的运行是基于子网的,邻居之间形成邻接关系的条件之一就是两端的 IP 地址属于同一网段而且掩码相同。
而在 OSPFv3 中,协议基于链路运行,与具体的 IPv6 地址、前缀分离开来,即使同一链路上的不同节点具有不同的 IPv6 地址时,协议也可以正常运行。
2)取消了编址语义
在 OSPFv2 中,协议分组和 LSA 中的许多字段都是来自于网络上的某个 IP 地址,或掩码,或某个 IP 子网号。严重依赖 IPv4。
在 OSPFv3 中,取消了上述编址性语义,而只保留协议运行必须的核心内容。ID 依然保留 32 位,但只是一个编号,不再包含地址信息。
3)链路本地地址的使用
在 OSPFv2 中,每一个运行 OSPF 的接口都必须有一个全局的 IPv4 地址,协议的运行和路由的计算都依赖于它。
在 IPv6 中,每个接口都会分配本地链路地址(link-local address),OSPFv3 使用了这个本地链路地址作为协议分组发送的源地址(虚连接除外),而且使用它作为路由的下一跳。
这样可以节省大量的全局地址,同时可以说协议的运行独立于 IPv6,可以方便的扩展用于多种协议的路由
4)使用专门的 LSA 来发布路由前缀信息
新增加了 Intra-Area-Prefix-LSA
,用于传递区域内路由前缀 新增加了 Link-LSA
,用于传递链路范围内的 IPv6 前缀。
5)明确的 LSA 泛滥范围
泛滥的范围分为:本地链路范围(Link-local scope),区域范围(Area scope),AS 范围(AS scope)
6)提供了对多实例的支持
在 OSPFv2 中,不同的实例必须运行在不同的链路上;在 OSPFv3 中,明确的提供了对多实例的支持,同一链路也可以运行多个 OSPF 实例了,而且互相独立运行不会影响。
配置
单区域配置
配置 Routert-ID
router-id 是一个可选的配置,其获取方式依次为 1)手动配置 2)使用环回地址作为 router ID 3)如果没有,选择路由器的最高逻辑地址作为 routerID
注意:IOS 的某些早期版本无法识别 router-id 命令;因此,为这些路由器设置路由器 ID 的最佳方法是使用环回接口
配置优先级 优先级的取值范围为 0~255,优先级为 0 的路由器不能被选举为 DR
配置计时器
广播型 OSPF 网络,缺省 hello 包间隔为 10 秒,down 机判断间隔为 40 秒 非广播型 OSPF 网络,缺省 hello 包间隔为 30 秒,down 机判断间隔为 120 秒
实际配置的例子如下1
2Router(config-if)#ip ospf hello-interval 5
Router(config-if)#ip ospf dead-interval 10