数据链路层/物理层提供跨物理路径的通信服务,当沿着物理路径进行通信时,必须获得有关数据链路标识和数据封装的信息,并且这些信息要保存在数据库中,例如 ARP 高速缓存。而网络层则提供跨越由一连串的数据链路组成的逻辑路径或虚拟路径的通信服务,其也需要获取和保存所涉及到的相关信息。有区别的是,这些信息被保存在路由表中,路由表又叫做路有选择信息库(RIB)。
路由表
当数据包达到路由器接口时,路由器首先会检查数据帧目标地址字段中的数据链路标识,如果它包含了路由器接口标识符或广播标识符,那么路由器将从帧中剥离出数据包并传递给网络层。在网络层,路由器将检查数据包的目标地址,如果目标地址是路由器接口的 IP 地址或者所有主机的广播地址,那么需要进一步检查数据包的协议字段,然后再把被封装的数据发送给适当的内部进程。
除此之外,所有其他的目标地址都需要进行路由选择。这里的目标地址可能是另一个网络上的主机地址,该网络或者与路由器直接相连(路由器的某个接口可以直达该网络),或者不直接连接到路由器上。也可能是一个定向的广播地址(这种地址有明确的网络地址或子网地址,并且主机位全部为 1)。
如果数据包是可以被路由的,那么路由器将会查找路由表获得一个正确的路径。在数据库中的每一个路由表项至少包括下面两个项目:
- 目标地址:这是路由器可以到达的网络地址
- 指向目标的指针:指针要么是指向路由器的直连目标网络,要么是指向路由器直连目标网络内的另一台路由器地址(或者是到这个链路的本地接口)。更接近目标网络一跳的路由器叫下一跳路由器
路由器将会尽量地执行最精确的匹配。按精确程度递减的顺序,可选地址排列如下:
- 主机地址(主机路径)
- 子网
- 一组子网(一条汇总路由)
- 主网号
- 一组主网号(超网)
- 缺省地址
如果数据包的目标地址不能匹配到任何一条路由表项,那么数据包将被丢弃,同时一个 目标网络不可达
的 ICMP 消息将会发送给源地址。
下图展示了该路由转发的过程:
- 路由器 Carrol 收到源地址为 10.1.1.97,目标地址为 10.1.7.35 的数据包,查询其路由器表后,目标地址的最优匹配是子网 10.1.7.0,可以从 S0 接口出站经下一跳地址 10.1.2.2 去往目的地
- 数据包到达 Dahl 后,继续查找其路由器,发现数据表应该从 S1 接口出站经下一跳 10.1.4.2 去往目标网络 10.1.7.0
- 该过程一直持续,直到数据包到达路由器 Baum,其发现目的地是连接在端口 E0 的一个直连网络
- 最终结束路由选择过程,数据包被传递给以太网链路上的主机 10.1.7.35
这里说明的路由选择过程是假设路由器可以将下一跳地址同它的接口进行匹配。例如,路由器 Dahl 必须知道通过接口 S1 可以到达 Lewis 的地址 10.1.4.2。Dahl 从分配给 S1 的 IP 地址和子网掩码就可以知道 10.1.4.0 直接连接在接口 S1 上,那么由于 10.1.4.2 是该子网的成员,因此一定被连接到该子网上。
注意,为了正确地进行数据包交换,每台路由器都必须保持信息的一致性和准确性。在 Cisco 路由器中查看路由表的 IOS 命令是 show ip route。
- 表最上方的关键字是对路由表左侧的一列字母的解释。这些字母指明了每个路由表项是如何学习到的
- 表头有有一句声明主网络 10.0.0.0 有 7 个已知子网,掩码为 24 位,在 7 个路由表项中,每一个都给出了目标子网
- 对于不是直连网络的表项,即数据包必须转发到下一跳路由器,置于括号内的元祖指明了路由的管理距离/度量
- 度量是通过优先权评价路由的一种手段,度量越低,路径越短,也就是该路径越理想
- 路由表还给出了下一跳路由器的接口地址或连接直连目标网络的接口
配置静态路由
路由表可以用下面 3 种方式之一获取信息:
- 基于路由器的直连子网
- 以静态路由表项的方式手工输入信息
- 通过某种自动信息发现和共享系统(动态路由协议)自动地获取信息
在某些场合,人们宁愿选用静态路由选择,而不是动态路由选择。对于任何过程而言,自动化程度越高,可控程度就越差。虽然动态路由选择要求更少的人为干涉,但是静态路由选择允许在网络的路由选择行为上实施非常精确的控制,但是每当网络拓扑结构发生变化时都需要重新进行手工配置。
静态路由具有两个特性:
- 如果网络拓扑结构发生变化,那么这些变化的路由器必须被重新配置
- 可以用静态路由建立非常精确的路由选择行为
案例研究:简单 IPv4 静态路由
网络的静态路由选择过程共有 3 步:
- 为网络中的每台数据链路确定一个子网或网络地址
- 为每台路由器标识所有非直连的数据链路
- 为每台路由器写出关于每个非直连地址的路由语句
没有必要为路由器写出直连数据链路的路由描述,因为在路由器接口上配置的地址和掩码使得这些直连网络会自动记录在路由表中。
如下所示,图中的 6 个子网是:
为了在路由器 Piglet 上配置静态路由器,将那些非直连的子网标识如下:
- 192.168.1.0/27
- 192.168.1.64/27
- 10.4.6.0/24
- 10.4.7.0/24
在路由器 Piglet 上配置静态路由的命令如下,对其他 3 台路由器也执行类似的步骤。
- ip route 192.168.1.0 255.255.255.224 192.168.1.193
- ip route 192.168.1.64 255.255.255.224 192.168.1.193
- ip route 10.4.6.0 255.255.255.0 192.168.1.193
- ip route 10.4.7.0 255.255.255.0 192.168.1.193
路由配置命令本身是很容易阅读的,命令 ip route 用于 IPv4,它后面跟着的是:
- 将要被输入到路由表中的地址
- 确定地址网络号的掩码
- 下一跳路由器的接口地址
配置 IPv4 静态路由还可以选择另一种命令,这种命令用出站接口代替下一跳路由器的接口地址,其中出站接口可以到达目标网路。需要注意,所有静态路由指明的网络,如果静态路由参照出站接口,那么它们将被作为直连网络输入到路由表中。
在配置静态路由时,必须满足以下条件:
- IP 路由选择必须启动(默认开启)
- 如果使用下一跳地址,那么该地址必须可达
- 出站接口必须配置 IP 地址,接口必须正常工作
配置静态路由的第 3 种选择是联合使用出站接口和下一跳地址。如果出站接口失败,即使下一跳地址通过替代路由递归可达,路由依然会被删除。这样可以把与下一跳地址相关联的出站接口查询减到最小,同时使相应的路由表项不再是直连网络,而是距离为 1 的静态路由。
如果直接把静态路由指向一个广播型的出站接口(例如以太网),而不使用下一跳地址,可能会导致广播网络上出现过多的流量,而且还可能耗尽路由器的内存。因为此时路由器会认为该静态路由到达的网络是一个直连网络,因此当路由器向该网络内的目标主机转发数据包时,路由器将发送 ARP 请求,而广播网络上的下一跳路由器由于配置了代理 ARP 功能,将代表目标网络回复 ARP 响应。因此不管数据包的目标地址是否有效,每次到达都会触发一个 ARP 请求和响应,并需要路由器配备大容量的 ARP 高速缓存。
指定出站接口和下一跳地址可以最小化与下一跳地址相关联的出站接口查询,并且把广播网络上的流量减到最小。
案例研究:简单 IPv6 静态路由
IPv6 静态路由的配置方法和 IPv4 基本相同,唯一不同的是 IPv4 网络掩码使用点分十进制形式,而 IPv6 使用目标网络的前缀长度。IPv6 路由选择缺省情况下是关闭的,所以在输入 IPv6 静态路由前,必须使用命令 ipv6 unicast-routing
启动 IPv6 路由选择。
创建静态 IPv6 路由的命令是 ipv6 route
,该命令后面跟随的参数是目标网络、前缀长度和下一跳路由器地址或去往目标网络的出站接口。
当我们需要确定静态路由表项中下一跳地址时,为了标识邻接路由器的 128 位 IPv6 地址,可以使用 Cisco 发现协议(CDP)的统计信息。CDP 可以给出关于邻接路由器的信息。另一种确定 IPv6 地址的方法是使用 show ipv6 interface
命令,该命令可以显示相关接口的 IPv6 信息。
与 IPv4 一样,IPv6 静态路由也可以使用出站接口代替下一跳地址。一种选择是在接口后面输入地址,可是输入链路本地地址后者一个配置的地址。当出站接口是广播接口时,应该使用下一跳地址。
使用 show ipv6 route
命令可以查看 IPv6 路由表。
如果静态路由是使用下一跳 IPv6 地址建立的,同 IPv4 一样,路由器必须递归查找与该 IPv6 地址相关联的出站接口。而且,使用下一跳 IPv6 地址建立的静态路由的管理距离是 1,路由测量为 0,这和 IPv4 是相同的。
和 IPv4 静态路由不同,使用出站接口配置 IPv6 静态路由,路有表中显示目标网络不是直接连接的。除非同时指定出站接口和下一跳地址,否则在输入出站接口时下一跳地址是不确定的,路由表中显示下一跳地址为 ::,即下一跳没有指定。对于点对点的串行接口,这不会有问题,因为在点对点网络的另一端仅会有一台设备,所有出站接口发出的数据包一定能到达设备,但是在广播网络接口上,路由器必须找到邻居才能发送数据包。
因此,在广播网络上使用出站接口配置静态路由时,必须指定下一跳地址。这里建议采用本地链路地址作为下一跳地址,这是因为:
- 除非网卡或路由器被替换,否则本地链路地址不会改变,即使使用不同的 IPv6 全局前缀重新编号站点也是这样
- 可以与路由器通告信息中的地址保持一致,使用这些地址的进程可以按要求运行
路由器向广播网络上的所有设备通告自己的存在及本地链路地址。主机使用这些通告信息建立路由列表,并使用这些列表确定如何向网络转发数据包。如果主机把一个数据包转发给路由器,并且该路由器知道一个更适合转发该数据包的路由器,那么路由器将向主机发送重定向信息。重定向信息包括另一台路由器的 IPv6 本地链路地址。主机在收到重定向信息后,如果路由器列表中包含这台更合适的路由器,那么主机将向它转发数据包,否则主机将丢弃数据包。
案例研究:汇总路由
汇总路由(Summary Route)是一个包含路由表中几个更精确地址的地址。正是由于路由表项与地址掩码联合使用,使得静态路由的使用非常灵活。通过使用合适的子网掩码,有时可以为多个目标地址生成一条单一的汇总路由。
例如,在前面例子中,对于路由器 Piglet 来说,可以使用经路由器 Tigger 可达 10.4.0.0/16
的单一表项来完成对子网 10.4.6.0/24
和 10.4.7.0/24
的说明,同样地,也可以用指向 192.168.1.0/24
的单一表项替代路由表中的子网 192.168.1.0/27
和 192.168.1.64/27
。这里 10.4.0.0/16
和 192.168.1.0/24
两个路由表项就是汇总路由。
使用汇总路由技术后,路由器 Piglet 的静态路由配置如下:
1 | ip route 192.168.1.0 255.255.255.0 192.168.1.193 |
汇总路由也可以应用到 IPv6 中。通过对一组子网甚至主网汇总(用小于特定类别地址标准掩码长度的掩码汇总一组主网地址的方法叫做超网化),可以使静态路由项的数目迅速减少。但是,对地址进行汇总时需要小心,当汇总不正确时,可能会有意想不到的路由行为发生。
案例研究:浮动静态路由
浮动路由与其他静态路由不同,路由表中的其他路由总是优选于浮动静态路由,仅在一种特殊的情况下:即在一条首选路由发生失败时,浮动路由才会出现在路由表中。
如下所示,新路由器 Rabbit 通过两条并行链路连接到 Piglet 上,添加第二条链路主要是考虑到线路冗余。如果主链路 10.1.10.0 发生故障,浮动静态路由将会指引流量流经备份链路 10.1.20.0。
为了建立浮动路由,分别在 Piglet 和 Rabit 上配置如下静态路由表项:
1 | ip route 192.168.1.0 255.255.255.0 192.168.1.193 |
1 | ip route 10.4.0.0 255.255.0.0 10.1.10.1 |
在 Piglet 上有两条路由指向 Rabbit 的网络 10.1.30.0:一条指定 Rabbit 接口 S0 的地址作为下一跳地址,另一条指定 Rabbit 接口 S1 的地址作为下一跳地址。在 Rabbit 上,对每个目标网络都有类似的双重表项。
注意,在所有使用子网 10.1.20.0 的静态路由后面都跟有 50。该数字指定了管理距离。管理距离是一种优选度量。当存在两条路径到达相同的网络时,路由器将会选择管理距离较低的路径。这种思想听上去有点像度量,但是度量指明了路径的优先权,而管理距离指明了发现路由方式的优先权。
例如,指向下一跳地址的 IPv4 静态路由的管理距离为 1,而指向出站接口的静态路由的管理距离为 0。如果有两条静态路由指向相同的目标网络,一条指向下一跳地址,一条指向出站接口,那么后一条路由被选择(管理距离值更低的路由)。
在这个例子中,通过将经过子网 10.1.20.0
的静态路由的管理距离提高到 50
,可以使经过子网 10.1.10.0 的静态路由成为首选路由。
使用 show ip route
命令时可以显示路由表项的管理距离和度量值。对于静态路由,其度量值为 0(没有度量),默认管理距离为 1。动态路由选择协议的管理距离远远大于 1,因此对于相同的目标网络,缺省情况下,到相同目标网络的静态路由总是优于动态路由。
IPv6 浮动静态路由的工作方式和 IPv4 一样。但是不管是使用出站接口还是下一跳地址,IPv6 静态路由管理距离的缺省值都为 1。使用这两种方式指定的静态路由是等价的,并且会均分负载。
案例研究:均分负载
上面的例子存在一个缺点,即正常情况下备份链路不能被利用,备份链路的可用带宽资源被浪费了。均分负载(Load Sharing),又叫负载均衡,允许路由器利用多路径的优点,在所有可用的路径上发送数据包。
均分负载可以是等价的或非等价的,这里代价是一个通用术语,指与路由相关联的度量:
- 等价均分负载:将流量均匀地分布到多条度量相同的路径上,这种情况又叫负载均衡
- 非等价均分负载:将数据包分布到度量不同的多跳路径上。各条路径上分布的流量与路由代价成反比。也就是说代价越低的路径分配的流量越多,代价越高的路径分配的流量越少
一些路由选择协议可以支持等价和非等价负载均衡两种方式,而其他一些路由选择协议仅支持等价方式。静态路由没有度量,所以仅支持等价负载均衡。
在静态路由中实现负载均衡,除了链路使用缺省的管理距离 1 以外,其他和浮动静态路由没有什么区别。在配置静态路由负载均衡后,路由表中对于相应的目标网络存在多条路由。IPv6 和 IPv4 的工作方式一致。
负载均衡有两种方式:基于目标网络和基于数据包。
负载均衡和 Cisco 急速转发
基于目标网络的负载均衡是根据目标地址分配负载。假设到一个网路存在两条路径,那么发往该网络中第一个目标的数据包从第一条路径通过,发往该网络中的第二个目标的数据包通过第二条路径,发往此网络第三个目标的所有数据包还通过第一条路径,以此类推。这就是 Cisco 急速转发(CEF)使用的缺省负载均衡方式。在大部分平台,IPv4 的缺省交换模式是 CEF,但是 IPv6 不是。
CEF 是一种非常有效的交换方法,它实现从路由表获取信息并把信息存储在转发信息库(FIB)中,当任何数据包需要这些信息时可以立即使用。FIB 包括路由表中的所有目标网络,如果路由表稳定且不发生改变,那么 FIB 也不会变化。
CEF 使用一个单独的数据表—邻接关系表,为 FIB 的每个表项维护第二层转发信息。邻接关系表由第二层信息构成,例如这些信息可以通过 IP ARP 或 IPv6 邻居发现协议学习到。FIB 和邻接关系表是在数据包转发之前建立的。
CEF 在缺省情况下是按照源/目的地址对进行负载均衡。因此所有发往特定目标地址的流量只要源地址相同都会从相同的接口出站,而不同源/目的地址对的流量可能会从下一个接口出站。
基于数据包的负载均衡是交换 IPv4 数据包的另一种方式。对于 IPv6,CEF 仅支持基于目标网络的负载方式。基于数据包的负载均衡方式意味着在不同的链路上发送数据包,即使在路径等价、目标相同的情况下也是这样。如果路径代价不同,那么可能会在高、低代价路径上按照代价比率进行分流。
基于数据包的负载均衡方式可以更加均匀地分布流量,但是数据包选择不同的路径去往目标网络会引起非顺序到达,对于某些应用来说,这是不能接受的。
为了确定 CEF 功能是否在路由器上被全局打开,可以使用命令 show ip cef
和 show ipv6 cef
。如果 CEF 没有被打开,对于 IPv4 可以使用命令 ip cef,对于 IPv6 来说,则需要先打开 IPv4 的 CEF,然后使用命令 ipv6 cef 打开该功能。
在 IPv4 下,命令 ip load-sharing per-destination
命令可以打开基于目标地址的负载均衡,命令 ip load-sharing per-packet
可以打开基于数据包的负载均衡功能。使用 命令 show cef interface
可以查看接口上配置的 CEF 信息。
路由器通常根据入站接口和源/目的地址类型确定是否使用 CEF 交换。对于考虑使用 CEF 交换的路由器来说,出站接口必须配置为 CEF 交换模式,如果接口上配置了 CEF,那么将尝试使用 CEF 交换数据包。否则,CEF 将会把数据包交付给次优的交换方法去处理,对于 IPv4 是快速交换,在 IPv6 中是过程交换(process switching)。
基于目标网路的负载均衡和快速交换
IOS 在配置了快速交换的出站接口上执行基于目标网络的负载均衡,在一些路由路由器上,IOS 的缺省交换模式是快速交换。快速交换的工作方式如下:
- 当路由器为第一个去往特定目标的数据包进行交换处理时,路由器将执行路由表查询并选择出站接口
- 然后获取有关被选接口的数据链路信息(例如从 ARP 表),这些信息对数据包成帧是必须的,最后封装数据包并发送
- 前面获取的路由和数据链路信息被输入到快速交换的高速缓存内
- 一旦去往相同目的地的后续数据包进入路由器,高速缓存中的信息使路由器不必查找路由表和 ARP 高速缓冲,就可以立即交换数据包
快速交换意味着所有去往指定目的地的数据包都从相同的接口被发送出去。因此交换时间和处理器的占用率会大大降低。当去往相同网络内不同主机的数据包进入路由器且还存在一条可选路由时,路由器会在另一条路径上发送数据包到目的地。因此路由器能够做的最好的就是基于目标网络的负载均衡。
基于数据包的负载均衡和过程交换
过程交换(process switching)就是对于每个数据包,路由器都要进行路由表查询和接口选择,然后再查询数据链路信息。因为每一次为数据包确定路由的过程都是独立的,所以不会强制去往目标网络的所有数据包使用相同的接口。为了在接口上打开过程过程交换,在 IPv4 下使用·no ip route-cache
命令,对于 IPv6 缺省情况下该功能打开。
在使用 debug ip packet 命令时,允许查看过程交换的数据包,快速交换的数据包将不被显示出来。
基于数据包的均分负载虽然使流量的分布比快速交换更均匀,但是其没有快速交换的较低交换时间和处理器占优的优点。
哪一种交换方法会被用到
IOS 首先基于入站接口的配置来决定交换模式。如果接口上配置了 CEF,不管出站接口的配置是什么,数据包都会被 CEF 交换。如果入站接口上没有配置 CEF,那么 IOS 会处理并转发数据包,并根据出站接口的配置,后继的数据包或者被快速交换,或者被过程交换。如下列出了交换方法与出/入站接口配置的对应关系表:
案例研究:递归表查询
所有的路由表项不一定要指向下一跳路由器。在如下网络中,假设 Pooh 的静态路由配置如下:
- 如果 Pooh 需要向主机 10.1.30.25 发送数据包,Pooh 将查找路由表并发现经过 10.1.10.2 可以到达该子网
- 但是这个地址不在直连网络中,所以 Pooh 必须再次查找路由表并发现去往 10.1.10.0 要经过 192.168.194
- 同样这个地址也不在直连网络中,因此需要继续查找路由表,发现途径 192.168.1.66 可以到达 192.168.1.192
- 192.168.1.66 在路由器 Pooh 的直连网络中,于是现在可以转发数据包了
因为每次路由表查找都会花费处理器的时间,所以正常情况下强制路由器进行多次路由表查找是不好的设计。快速交换对递归查询进行了限制,仅对去往每个目标网络的第 1 个进行递归查询,从而有效地降低了这些不利的影响。但是通过使用路由表的递归查询机制,有时可以简化静态路由的配置和修改。
静态路由故障诊断
当排除路由故障时,第一步就是检查路由表。为了顺利地排除网络故障,了解如何跟踪路由是十分必要的。
- 当你跟踪路由时,必须考虑完整的通信过程。不仅要验证去往目标网络的路由是正确的,还要验证返回的路径也是正确的
- 通过查看路由表,可以确认路由器是否具有经过某条逻辑路径到达目标网络的正确信息,通过检查 ARP 高速缓存,可以确定路由器是否具有经过某条物理路径达到某台主机的正确信息
- 代理 ARP 有时可能会导致意想不到的结果。可以使用 no ip proxy-arp 命令在接口上关闭代理 ARP 功能,或者配置静态 ARP
- 每当路由器或接口卡被替换时,一定要记得修改使用了旧路由器 EUI-64 格式 IPv6 地址的路由表项
- 如果一个数据包从串行接口入站,又从该串行接口出站,就表明存在路由环路。在两个或多个目标网络之间流量的持续循环为路由选择环路
总结
对于精确地控制网络的路由选择行为来说,静态路由是一个强有力的工具。但是,如果经常发生网络拓扑变化,那么手动配置方式导致静态路由的管理工作根本无法进行下去,而动态路由选择协议能够迅速并自动地响应网络拓扑的变化。