TCP/IP协议-IP 选路
文章目录
[TOC]
IP 选路
IP
层进行的选路实际上是一种选路机制,它搜索路由表并决定向哪个网络接口发送分组。这区别于选路策略,它只是一组决定把哪些路由放入路由表的规则。IP
执行选路机制,而路由守护程序则一般提供选路策略。
路由表
执行netstat -rn
命令列出路由表如下:
$ netstat -rn
routing tables
Destination Gateway Flags Iface
default 192.168.1.1 UG en0
127.0.0.1 127.0.0.1 UH lo0
192.168.1.30 192.168.1.35 UGH en0
如果目的地是Destination
字段中的值,那么网关(路由器)将把分组转发到Gateway
所对应的地址。
Flags
标志字段:
- U 该路由可以使用。
- G 该路由是一个网关(路由器)。如果没有设置该标志,说明目的地是直接相连的。
- H 该路由是到一个主机,即目的地是一个完整的主机地址。如果没有设置该标志,说明该路由是到一个网络,而目地地址是一个网络地址(一个网络号,或网络号与子网号的组合)。
- D 该路由是重定向报文创建的。
- M 该路由已被重定向报文修改。
deafult
表示默认路由,Host Requirements RFC
文档中特别说明,IP
层必须支持多个默认路由。但是,许多实现系统并不支持这一点。
主机路由表的复杂性取决于主机所在网络的拓扑结构:
- 最简单的情况是主机未与任何网络相连。
TCP/IP
协议仍然能用于这样的主机,但是只能与自己本身通信,路由表只包含环回接口一项。 - 第二种情况是主机连接在一个局域网上,只能访问局域网上的主机。这时路由表包含两项分别是环回接口和局域网(以太网)。
- 如果主机能够通过单个路由器访问其他网络(如
Internet
)时,那么就进行下一步。一般情况下增加一个默认表指向该路由器。 - 如果要新增其他的特定的主机或网络路由,那么就进行最后一步。
如果路由表中没有默认项,而又没找到匹配项时,会有两种情况:
1)如果数据报是由本机产生的,那么就给发送该数据报的应用程序返回一个差错(主机不可达或网络不可达差错)。
2)如果是被转发的数据报,那么就给原始发送端发送一份
ICMP
主机不可达差错报文。
ICMP 重定向差错
当IP
数据报应该被发送到另一个路由器时,收到数据报的路由器就要发送ICMP
重定向差错报文给IP
数据报的发送端。只有当主机可以选择路由器发送分组的情况下,我们才可能看到ICMP
重定向报文,如下图:
- 主机发送一份数据报给
R2
,主机的默认路由表是R1
,所以数据报先到达R1
。 R1
收到数据报并检查它的路由表,发现R2
是该数据报的下一站。当它把数据报发送给R2
时,R1
检测到它正在发送的接口与数据报到达的接口相同(即主机与两台路由所连接的LAN
)。这样就给路由器发送重定向报文给原始发送端提供了线索。R1
发送一份ICMP
重定向报文给主机,告诉它以后把数据报发送给R2
而不是R1
。

ICMP
重定向允许TCP/IP
主机在进行选路时不需要具备智能特性,而把所有的智能特性放在路由器端。主机启动时路由表中可以只有一个默认表项,通过接收重定向报文来逐步学习。
ICMP 重定向报文

代码 字段:
0
网络重定向1
主机重定向2
服务类型和网络重定向3
服务类型和主机重定向
ICMP
重定向报文的接收者必须查看三个IP
地址:1)导致重定向的
IP
地址(即ICMP
重定向报文的数据,位于IP
数据报首部);2)发送重定向报文的路由器的
IP
地址(包含重定向信息的IP
数据报中的源地址);3)应该采用的路由器
IP
地址(在ICMP
报文中的4
~7
字节)。
ICMP
只能由路由器生成,而不能由主机生成,重定向报文是为主机而不是为路由器使用的。
假定多个路由共同参与一个共同参与一种选路协议,则该协议应该消除重定向需求(这就意味着路由表应该被路由守护进程或重定向修改,但不能同时修改。 没读懂???
当一个BSD
主机作为路由器生成ICMP
重定向报文前必须通过下面检查:
-
出接口必须等于入接口
-
用于传出的数据报的路由不能是已经被
ICMP
重定向创建或修改的,并且不能是路由器的默认路由。 -
数据报不能是源路由
-
内核必须被配置成可以发送重定向
内核变量通常被命名为
ip_sendredirects
或类似名字来配置,大多数现代系统(BSD
、SunOS4.1
、Solaris 2.x
、和AIX 3.2.2
)默认都启用了这个变量,其他系统如SVR4
默认禁用该变量。
当一个BSD
主机接收一个ICMP
重定向更新路由表之前必须通过下面检查:
- 新的路由器必须直接与网络相连接
- 重定向的目的地必须是当前路由器(即当前主机)
- 重定向不能让主机本身作为路由器
- 被修改的路由必须是一个间接路由
这是为了防止路由器或主机的误操作,以及恶意用户的破坏,导致错误地修改系统路由表。
路由器应该发送的只是对主机的重定向(代码
1
或3
),而不是对网络的重定向。
ICMP 路由器发现报文
到达主机或网络的路由如果不直接相连,那么必须加入路由表。常用的方法是在系统被引导启动时使用route
命令。但是几乎没有系统愿意在初始化文件中包含route
命令。
一些系统允许在某个文件中指定默认的路由器,如/etc/defaultrouter
。于是在每次重新启动系统时都要在路由表中加入该默认项。
另一种新的方法是使用ICMP
路由器通告和请求报文,允许每个正在监听的主机相应地更新它们的路由表。

地址数 字段,报文中所含地址的数量(路由器在一份报文中可以通告多个地址)。
地址项大小 字段,每个路由器地址32bit
字的数目,始终为2
(MAC
地址64bit
除以32bit
等于2
)。
生存时间 字段,通告地址的有效时间(秒)。
路由器地址 字段,发送路由器的某个IP
地址。
优先级 字段,是一个32bit
有符号整数,指出该IP
地址作为默认路由器地址的优先级,这是相对于子网上的其他路由器地址而言。值越大优先级越高,值为0x80000000
表示该地址不能作为默认路由器地址使用,默认值一般为0
。
当路由器启动时,它不定期随机在所有广播或多播传送接口上发送通告报文。随机传送的目的是为了减小与子网上其他路由器发生冲突的概率。一般每两次通告间隔
450
秒和600
秒。一份给定的通告报文默认生命周期是30
分钟。是当路由器上的某个接口被关闭时,路由器可以在该接口上发送最后一份通告报文,并把生命周期值设为
0
。除了定期发送主动提供的通告报文以外,路由器还要监听来自主机的请求报文,并发送路由器通告报文以响应这些请求报文。
主机在引导期间一般发送三份路由器请求报文,每三秒钟发送一次。一旦接收到一个有效的通告报文,就停止发送请求报文。主机也监听来自相邻路由器的请求报文。这些通告报文可以改变主机的默认路由器。另外,如果没有接收到来自当前默认路由器的通告报文,那么默认路由器会超时。
只要有一般的默认路由器,该路由器就会每隔10
分钟发送通告报文,报文的生命周期是30
分钟。这说明主机的默认表项是不会超时的,即使错过一份或两份通告报文。
动态选路协议
上面的静态选路在配置接口时以默认方式生成路由表项(对于直接连接的接口),并通过route
命令增加表项(通常从系统自引导程序文件),或是通过ICMP
重定向方式生成表项(通常是在默认方式出错的情况下)。
在网络很小且与其他网络只有单个连接点且没有多余路由时(若主路由失败,可以使用备用路由),采用这种方法是可行的。如果上述三种方法均无法满足,通常使用 动态选路。
动态选路

当相邻路由器之间进行通信,以告知对方每个路由器当前所连接的网络,这时就出现了动态选路。路由器上有一个 路由守护进程(routing daemon) 它运行选路协议,并与其相邻的一些路由器进行通信。路由守护程序根据它从相邻路由器接收的信息,更新内核中的路由表。
动态路由并不改变内核在IP
层选路方式(内核搜索路由表,查找主机路由、风格路由以及默认路由的方式并没有改变),仅仅是放置路由表中的信息改变了,路由是由动态路由守护程序动态的增加或删除,而不再来自于引导程序中的route命令。
路由守护程序将 选路策略(routing policy) 加入到系统中,选择路由并加入内核路由表中。如果守护程序发现前往同一信宿存在多条路由,那么它(以某种方法)将选择最佳路由并加入内核路由表中。如果路由守护程序发现一条链路已经断开(可能是路由器崩溃或电话线路不好),它可以删除受影响的路由或增加另一条路由以绕过该问题。
Internet
系统中采用了许多不同的选路协议,以一组 自治系统(Autonomous System,AS) 方式组织,每个自治系统由单个实体管理。如一个公司或大学校园都可以定义为自治系统。
每个自治系统可以选择该自治系统中各个路由器之间的选路协议。这种协议我们称之为 内部网关协议(Interior Gateway Protocol,IGP) 或 域内选路协议(intradomain routing protocol) 。
常见的IGP
协议:
RIP(Routing Information Protoco)
路由信息协议,最常用的选路协议。OSPF(Open Shortest Path First)
一种新的选路协议,开放最短路径优先协议,意图取代 RIP。HELLO
NSFNET 骨干网上使用的较早的协议,现在已经不用了。
RFC [Almquist 1993]
规定,实现任何动态选路协议的路由器必须同时支持RIP
和OSPE
,还可以支持其他 IGP
协议
外部网关协议(Exterier Gateway Protocol,EGP) 或 域内选路协议 是用于不同自治系统之间路由器的独立路由协议。
常见的EGP
协议:
EGP
与它同名的协议。BGP(Border Gateway Protocol,BGP)
新的外部网关协议是当前在 NSFNET 骨干网和一些连接到骨干网的区域性网络上使用的是 边界网关协议。意在取代 EGP 协议。
RIP
路由信息协议(Routing Information Protoco,RIP) ,它是最广为使用(也是最受攻击)的选路协议。对于 RIP
的正式描述文件是RFC 1058 [Hedrick 1988a]
,是该RFC
是在该协议实现数年后才出现的。

RIP
报文包含在UDP
数据报中,如上图:
命令 字段,1
表示请求;2
表示应答;3
和4
是两个舍弃不用的命令;最后两个是非正式命令,5
表示轮询6
表示轮询表项。
请求命令表示要求其他系统发送全部或部分路由表。应答命令表示包含发送者的全部或部分路由表。
版本 字段,通常为1
。第二版本 RIP 将此字段设置为 2
接下来是20
字节的路由表项,其中 地址系列 字段值为2
表示IP
协议; 32位 IP 地址 字段值是该路由的目的IP
地址(可以是子网地址和主机地址); 度量 字段是以跳计数的路由开销值。
一个
RIP
报文中最多可以有25
个路由表项,上限25
是为了保证RIP
总报文长度为20*25+4=504
,小于512
字节。由于此限制,所以为了发送整个路由表,经常需要发送多个报文。
RIP
正常运行流程如下:
-
初始化 ,在启动一个路由守护程序时,先判断启动哪些接口,并在每个接口上发送一个请求报文,要求其他路由器发送完整路由表。在点对点链路中,该请求是发送给其他终点。如果网络支持广播,请求则以广播方式发送。目的端口号是
520
(其他路由器守护程序的端口号)。请求报文命令字段值为
1
,地址系列字段值为0
,度量字段值为16
。这是一种要求另一端完整路由表的特殊请求报文。 -
接收到请求 ,如果请求是上面的特殊请求,那么路由器将完整路由表发送给请求者。否则,处理请求表中的每一个表项:如果有连接到指明地址的路由,则将度量设置成我们的值,否则将度量值设置为
16
(度量为16
是一种称为“无穷大”的特殊值,它意味着没有到达目的路由),然后发回响应。 -
接收到响应 ,使响应生效,可能会更新路由表。可能会增加新表项,对已有表项进行修改,或是将已有表项删除。
-
定期选路更新 ,每过
30
秒所有或部分路由器会将完整路由表发送给相邻路由器。发送路由表可以是广播形式,或是发送点对点链路的其他终点。 -
触发更新 ,每当一条路由度量发生变化时,就对它进行更新。不需要发送完整路由表,只需要发送变化的路由表项。
每条路由都有与之相关的定时器。如果运行
RIP
的系统发现一条路由在3
分钟内未更新,就将该路由的度量设置成无穷大(16
),并标注为删除。这意味着已经在6
个30
秒更新时间里没收到通告该路由的路由器的更新了。再过60
秒,将从本地路由表中删除该路由,以保证该路由的失效已被传播开。
度量
RIP
的度量是以跳(hop
)计算的,直接相连的接口跳数为1
。如下图,路由器R1
通过发送广播到N1
通告它与N2
之间的跳数是1
(发送给N1
的广播中通告它与N1
之间的路由是无用的)。同时也发送广播给N2
通告它与N1
之间的跳数为1
。同样R2
通告它与N2
的度量为1
,与N3
的度量为1
。

如果相邻的路由器通告它与其他网络的跳数为1
,那么我们就与那个网络的度量就是2
,原因在于发送报文到达该网络必须经过那个路由器。如上图,R1
到N3
和R2
到N1
的度量均为2
。
由于每个路由器都发送其路由表给邻站,因此,可以判断在同一个自治系统
AS
内到每个网络的路由。如果在该AS
内从一个路由器到一个网络有多条路由,那么路由器将选择跳数最小的路由,而忽略其他路由。跳数的最大值是
15
,这意味着RIP
只能用在主机间最大跳数值为15
的AS
内。度量为16
表示到无路由到达该IP
地址。
RIP 缺陷
RIP
没有子网地址概念。如果标准B
类主机地址主机号不为0
,那么RIP
无法区分非零部分是一个子网号,还是一个主机号。有一些实现通过接收到的RIP
信息,来使用接口的网络掩码,但这有可能出错。
其次,在路由器或链路发生故障后,通常需要几分钟甚至更长一的时间稳定下来。在这段时间里可能发生路由环路,在实现RIP
时必须很多微妙的措施来防止路由环路的出现,使其尽快建立。
路由环路,就是数据包不断在这个网络传输,始终到达不了目的地,导致掉线或者网络瘫痪。
在维护路由表信息的时候,如果在拓扑发生改变后,网络收敛缓慢产生了不协调或者矛盾的路由选择条目,就会发生路由环路的问题,这种条件下,路由器对无法到达的网络路由不予理睬,导致用户的数据包不停在网络上循环发送,最终造成网络资源的严重浪费。
采用跳数作为路由度量忽略了一些其他考虑的因素。并且度量最大值是15
,则限制了可以使用RIP
网络的大小。
RIP-2
RIP
的第二版只是对第一版进行扩充,并不改变协议本身,而是利用一些“必须为0”字段来传递一些额外信息。如果RIP
忽略了这些“必须为0”字段,那么RIP
和RIP-2
可以交互操作。

路由域 字段,是这个数据报所属的路由守护程序的标识符。在Unix
实现中,它可以是一个路由守护程序的进程号。这个字段允许管理者在一个路由器上运行多个RIP
实例,每个实例在一个路由域内运行。
路由标记 字段,是为了支持外部的网关协议而存在的,它携带一个EGP
和BGP
的自治系统号。
子网掩码 字段,每个表项的子网掩码应该用于相应的IP
地址上。
下一站IP地址 字段,指明发往目的IP
地址的报文该发往哪里。该字段为0
表示发往目的地址的报文应该发给发送RIP
报文的系统。
RIP-2
提供了一种简单的鉴别机制,指定RIP
报文前20
字节表项地址系列为0xffff
,路由标记为2
,表项中其余16
字节包含一个明文口令。
RIP-2
除了广播外,还支持多播,可以减少不收听RIP-2
报文的主机负载。
OSPF
开放最短路径优先协议是除了RIP
外另一个内部网关协议,它克服了RIP
的所有限制,随着大部分厂商支持OSPF
,在很多网络中OSPF
将逐步取代RIP
。
与采用距离向量(跳数)的RIP
不同,OSPF
是一个链路状态协议。每个路由器都根据它所收到邻站的这些距离向量来更新自己的路由表。
在一个链路协议中,路由器并不与邻站交换路由信息。它采用的是每个路由器主动的测试与其邻站相连链路的状态,将这些信息发送给它的其他邻站,而邻站将这些信息在自治系统中传播出去。每个路由器接收这些链路状态信息,并建立起完整的路由表。
链路状态协议总是比距离向量协议收敛(路由发生变化后,稳定下来)更快。
OSPF
不使用UDP
而是直接使用IP
,在IP
首部协议字段有自己的值。
特点:
1)可以对每个IP
服务类型(TOS
)计算各自路由集。这意味着对于任何目的,可以有多个路由表项,每个表项对应着一个IP
服务类型。
2)每个接口被分配一个 无量纲 成本,可以通过吞吐率、往返时间、可靠性或其他性能来进行分配。可以给每个IP
服务类型单独分配成本。
3)当对同一个目的地址存在多个相同成本的路由时,在这些路由上平均分配流量,称之为流量平衡。
4)支持子网,子网掩码与每个通告路由相连。这样就允许将一个任何类型的IP
地址分割成多个不同大小的子网。到一个主机的路由是通过全1
子网掩码进行通告的。默认路由是以IP
地址为0.0.0.0
网络掩码为全0
进行通告的。
5)路由器之间点对点链路不需要每端都有一个IP
地址,称之为无记号网络。这样可以节省IP
地址。
6)采用一种简单鉴别机制。可以采用类似于RIP-2
机制的方法指定一个明文口令。
7)采用多播,而不是广播形式,以减少不参与OSPF
系统的负载。
BGP
边界网关协议,是一种不同自治系统的路由器之间进行通信的外部网关协议。BGP
是ARPANET
所使用的老EGP
的取代品。
BGP
系统与其他BGP
系统之间交换网络可到达信息包括数据到达这些网络所必须经过的自治系统AS
中的所有路径。这些信息足以构造一幅自治系统连接图。然后,可以根据连接图删除选路环,制订选路策略。
将一个自治系统中的IP
数据报分为本地流量和通过流量。其中,本地流量是起始或终止于该自治系统的流量(即信源IP
地址或宿信IP
地址所指定的主机位于该自治系统中),其他流量则称为通过流量。在Internet
中使用BGP
的一个目的就是减少通过流量。
自治系统分类:
残桩自治系统(stub AS)
,与其他自治系统只有单个连接,因此只有本地流量。多接口自治系统(multihomed AS)
,与其他自治系统有多个连接,但拒绝传送通过流量。传送自治系统(transit AS)
,与其他自治系统有多个连接,在一些策略准则下,可以传送本地流量和通过流量。
可以将
Internet
的总拓扑结构看成是由一些残桩自治系统、多接口自治系统以及传送自治系统的任意互连。残桩自治系统和多接口自治系统不需要使用
BGP
,它们通过运行EGP
在自治系统之间交换可到达信息。
BGP
允许使用基于策略的选路。由自治系统管理员制订策略,并通过配置文件将策略指定给BGP
。制订策略并不是协议的一部分,但指定策略允许BGP
实现在存在多个可选路径时选择路径,并控制信息的重发送。选路策略与政治、安全或经济因素有关。
BGP
使用TCP
作为其传输层协议,两个运行BGP
的系统之间建立一条TCP
连接,然后交换整个BGP
路由表。从这个时候开始,在路由表发生变化时,再发送更新信号。
BGP
是一个距离向量协议,但是与(通告到目的地址跳数的)RIP
不同的是,BGP
列举了到每个目的地址的路由(自治系统到达目的地址的序列号)。这样就排除了一些距离向量协议的问题。采用16 bit
数字表示自治系统标识。
BGP
通过定期发送keepalive
报文给其邻站来检测TCP
连接对端的链路或主机失败。两个报文之间的时间间隔建议值为30
秒。应用层的keepalive
报文与TCP
的keepalive
选项是独立的。