9.1 引言
选路是IP最重要的功能之一。图9-1是IP层处理过程的简单流程。需要进行选路的数据报可以由本地主机产生,也可以由其他主机产生。在后一种情况下,主机必须配置成一个路由器,否则通过网络接口接收到的数据报,如果目的地址不是本机就要被丢弃(例如,悄无声息地被丢弃)。
在图9-1中,我们还描述了一个路由守护程序(daemon),通常这是一个用户进程。在Unix系统中,大多数普通的守护程序都是路由程序和网关程序(术语daemon指的是运行在后台的进程,它代表整个系统执行某些操作。daemon一般在系统引导时启动,在系统运行期间一直存在)。在某个给定主机上运行何种路由协议,如何在相邻路由器上交换选路信息,以及选路协议是如何工作的,所有这些问题都是非常复杂的,其本身就可以用整本书来加以讨论(有兴趣的读者可以参考文献[Perlman 1992]以获得更详细的信息)。在第10章中,我们将简单讨论动态选路和选路信息协议RIP(Routing Information Protocol)。在本章中,我们主要的目的是了解单个IP层如何作出路由决策。
图9-1所示的路由表经常被IP访问(在一个繁忙的主机上,一秒钟内可能要访问几百次),但是它被路由守护程序更新的频度却要低得多(可能大约30秒种一次)。当接收到ICMP重定向报文时,路由表也要被更新,这一点我们将在9.5节讨论route命令时加以介绍。在本章中,我们还将用netstat命令来显示路由表。
图9-1 IP层工作流程
9.2 选路的原理
开始讨论IP选路之前,首先要理解内核是如何维护路由表的。路由表中包含的信息决定了IP层所做的所有决策。
在3.3节中,我们列出了IP搜索路由表的几个步骤:
- 搜索匹配的主机地址;
- 搜索匹配的网络地址;
- 搜索默认表项(默认表项一般在路由表中被指定为一个网络表项,其网络号为0)。
匹配主机地址步骤始终发生在匹配网络地址步骤之前。
IP层进行的选路实际上是一种选路机制,它搜索路由表并决定向哪个网络接口发送分组。这区别于选路策略,它只是一组决定把哪些路由放入路由表的规则。IP执行选路机制,而路由守护程序则一般提供选路策略。
The routing done by IP, when it searches the routing table and decides which interface to send a packet
out, is a routing mechanism. This differs from a routing policy, which is a set of rules that decides which
routes go into the routing table. IP performs the routing mechanism while a routing daemon normally
provides the routing policy.
中英双译看起来好一些,这表明
ip选路机制:搜索路由表并决定向哪个网络接口发送分组
路由策略:决定把哪些路由放入路由表的规则
9.2.1 简单路由表
里面写了几个例子,结合例子看下概念
1)
假定目的地址是主机sun,140.252.13.33。首先进行主机地址的匹配。路由表中的两个主机地址表项(slip和localhost)均不匹配,接着进行网络地址匹配。这一次匹配成功,找到表项140.252.13.32(网络号和子网号都相同),因此使用emd0接口。这是一个直接路由,因此链路层地址将是目的端的地址。
netstat命令输出的最后一项还隐含了另一个信息,那就是目的地址(140.252.13.32)的子网掩码。如果要把该目的地址与140.252.13.33进行比较,那么在比较之前首先要把它与目的地址掩码(0xffffff e0,3.7节)进行逻辑与。
slip的地址是140.252.13.65,主机地址(主机号)为65,而目的地址是33,明显是不匹配的,同理127.0.0.1也是不匹配的,
33:0010 0001
32:0010 0000
34:0010 0010
e0: 1110 0000
对于一个给定的路由器,可以打印出五种不同的标志(flag):
- U 该路由可以使用。
- G 该路由是到一个网关(路由器)。如果没有设置该标志,说明目的地是直接相连的。
- H 该路由是到一个主机,也就是说,目的地址是一个完整的主机地址。如果没有设置该标志,说明该路由是到一个网络,而目的地址是一个网络地址:一个网络号,或者网络号与子网号的组合。
- D 该路由是由重定向报文创建的(9.5节)。
- M 该路由已被重定向报文修改(9.5节)。
2)
假定目的地址是主机slip,140.252.13.65。首先在路由表搜索主机地址,并找到一个匹配地址。这是一个间接路由,因此目的端的IP地址仍然是140.252.13.65,但是链路层地址必须是网关140.252.13.65的链路层地址,其接口名为emd0。
3)
这一次我们通过Internet给主机aw.com(192.207.11 7.2)发送一份数据报。首先在路由表中搜索主机地址,失败后进行网络地址匹配。最后成功地找到默认表项。该路由是一个间接路由,通过网关140.252.13.33,并使用接口名为emd0
9.2.2 初始化路由表
我们从来没有说过这些路由表是如何被创建的。每当初始化一个接口时(通常是用ifconfig命令设置接口地址),就为接口自动创建一个直接路由。对于点对点链路和环回接口来说,路由是到达主机(例如,设置H标志)。对于广播接口来说,如以太网,路由是到达网络。
到达主机或网络的路由如果不是直接相连的,那么就必须加入路由表。一个常用的方法是在系统引导时显式地在初始化文件中运行route命令。在主机svr4上,我们运行下面两个命令来添加路由表中的表项:
route add default sun 1
route add slip bsdi 1
第3个参数(default和slip)代表目的端,第4个参数代表网关(路由器),最后一个参数代表路由的度量(metric)。route命令在度量值大于0时要为该路由设置G标志,否则,当耗费值为0时就不设置G标志。
9.3 ICMP主机与网络不可达差错
当路由器收到一份IP数据报但又不能转发时,就要发送一份ICMP“主机不可达”差错报文(ICMP主机不可达报文的格式如图6-10所示)。可以很容易发现,在我们的网络上把接在路由器sun上的拨号SLIP链路断开,然后试图通过该SLIP链路发送分组给任何指定sun为默认路由器的主机。
较老版本的BSD产生一个主机不可达或者网络不可达差错,这取决于目的端是否处于一个局域子网上。4.4BSD只产生主机不可达差错。
我们在上一节通过在路由器sun上运行netstat命令可以看到,当接通SLIP链路启动时就要在路由表中增加一项使用SLIP链路的表项,而当断开SLIP链路时则删除该表项。这说明当SLIP链路断开时,sun的路由表中就没有默认项了。但是我们不想改变网络上其他主机的路由表,即同时删除它们的默认路由。相反,对于sun不能转发的分组,我们对它产生的ICMP主机不可达差错报文进行计数。
在主机svr4上运行ping程序就可以看到这一点,它在拨号SLIP链路的另一端(拨号链路已被断开):
在主机bsdi上运行tcpdump命令的输出如图9-2所示。
图9-2 响应ping命令的ICMP主机不可达报文
当路由器sun发现找不到能到达主机gemini的路由时,它就响应一个主机不可达的回显请求报文。
如果把SLIP链路接到Internet上,然后试图ping一个与Internet没有连接的IP地址,那么应该会产生差错。但令人感兴趣的是,我们可以看到在返回差错报文之前,分组要在Internet上传送多远:
从图8-5可以看出,在发现该IP地址是无效的之前,该分组已通过了6个路由器。只有当它到达NSFNET骨干网的边界时才检测到差错。这说明,6个路由器之所以能转发分组是因为路由表中有默认项。只有当分组到达NSFNET骨干网时,路由器才能知道每个连接到Internet上的每个网络的信息。这说明许多路由器只能在局部范围内工作。
9.4 转发或不转发
前面我们已经提过几次,一般都假定主机不转发IP数据报,除非对它们进行特殊配置而作为路由器使用。如何进行这样的配置呢?
大多数伯克利派生出来的系统都有一个内核变量ipforwarding,或其他类似的名字(参见附录E)。一些系统(如BSD/386和SVR4)只有在该变量值不为0的情况下才转发数据报。SunOS 4.1.x允许该变量可以有三个不同的值:-1表示始终不转发并且始终不改变它的值;0表示默认条件下不转发,但是当打开两个或更多个接口时就把该值设为1;1表示始终转发。Solaris 2.x把这三个值改为0(始终不转发)、1(始终转发)和2(在打开两个或更多个接口时才转发)。
较早版本的4.2BSD主机在默认条件下可以转发数据报,这给没有进行正确配置的系统带来了许多问题。这就是内核选项为什么要设成默认的“始终不转发”的原因,除非系统管理员进行特殊设置。
9.5 ICMP重定向差错
当IP数据报应该被发送到另一个路由器时,收到数据报的路由器就要发送ICMP重定向差错报文给IP数据报的发送端。这在概念上是很简单的,正如图9-3所示的那样。只有当主机可以选择路由器发送分组的情况下,我们才可能看到ICMP重定向报文(回忆我们在图7-6中看过的例子)。
- 我们假定主机发送一份IP数据报给R1。这种选路决策经常发生,因为R1是该主机的默认路由。
- R1收到数据报并且检查它的路由表,发现R2是发送该数据报的下一站。当它把数据报发送给R2时,R1检测到它正在发送的接口与数据报到达接口是相同的(即主机和两个路由器所在的LAN)。这样就给路由器发送重定向报文给原始发送端提供了线索。
- R1发送一份ICMP重定向报文给主机,告诉它以后把数据报发送给R2而不是R1。
图9-3 ICMP重定向的例子
重定向一般用来让具有很少选路信息的主机逐渐建立更完善的路由表。主机启动时路由表中可以只有一个默认表项(在图9-3所示的例子中,为R1或R2)。一旦默认路由发生差错,默认路由器将通知它进行重定向,并允许主机对路由表作相应的改动。ICMP重定向允许TCP/IP主机在进行选路时不需要具备智能特性,而把所有的智能特性放在路由器端。显然,在我们的例子中,R1和R2必须知道有关相连网络的更多拓扑结构的信息,但是连在LAN上的所有主机在启动时只需一个默认路由,通过接收重定向报文来逐步学习。
9.6 ICMP路由器发现报文
在本章前面已提到过一种初始化路由表的方法,即在配置文件中指定静态路由。这种方法经常用来设置默认路由。另一种新的方法是利用ICMP路由器通告和请求报文。
一般认为,主机在引导以后要广播或多播传送一份路由器请求报文。一台或更多台路由器响应一份路由器通告报文。另外,路由器定期地广播或多播传送它们的路由器通告报文,允许每个正在监听的主机相应地更新它们的路由表。
RFC 1256 [Deering 1991]确定了这两种ICMP报文的格式。ICMP路由器请求报文的格式如图9-6所示。ICMP路由器通告报文的格式如图9-7所示。
路由器在一份报文中可以通告多个地址。地址数指的是报文中所含的地址数。地址项大小指的是每个路由器地址32 bit字的数目,始终为2。生存期指的是通告地址有效的时间(秒数)。
图9-6 ICMP路由器请求报文格式
图9-7 ICMP路由器通告报文格式
接下来是一对或多对IP地址和优先级。IP地址必须是发送路由器的某个地址。优先级是一个有符号的32 bit整数,指出该IP地址作为默认路由器地址的优先等级,这是与子网上的其他路由器相比较而言的。值越大说明优先级越高。优先级为0x80000000说明对应的地址不能作为默认路由器地址使用,尽管它也被包含在通告报文中。优先级的默认值一般为0。
9.6.1 路由器操作
当路由器启动时,它定期在所有广播或多播传送接口上发送通告报文。准确地说,这些通告报文不是定期发送的,而是随机传送的,以减小与子网上其他路由器发生冲突的概率。一般每两次通告间隔450秒和600秒。一份给定的通告报文默认生命周期是30分钟。
使用生命周期域的另一个时机是当路由器上的某个接口被关闭时。在这种情况下,路由器可以在该接口上发送最后一份通告报文,并把生命周期值设为0。
除了定期发送主动提供的通告报文以外,路由器还要监听来自主机的请求报文,并发送路由器通告报文以响应这些请求报文。
如果子网上有多台路由器,由系统管理员为每个路由器设置优先等级。例如,主默认路由器就要比备份路由器具有更高的优先级。
9.6.2 主机操作
主机在引导期间一般发送三份路由器请求报文,每三秒钟发送一次。一旦接收到一个有效的通告报文,就停止发送请求报文。
主机也监听来自相邻路由器的请求报文。这些通告报文可以改变主机的默认路由器。另外,如果没有接收到来自当前默认路由器的通告报文,那么默认路由器会超时。
只要有一般的默认路由器,该路由器就会每隔10分钟发送通告报文,报文的生命周期是30分钟。这说明主机的默认表项是不会超时的,即使错过一份或两份通告报文。
9.7 小结
IP路由操作对于运行TCP/IP的系统来说是最基本的,不管是主机还是路由器。路由表项的内容很简单,包括:5bit标志、目的IP地址(主机、网络或默认)、下一站路由器的IP地址(间接路由)或者本地接口的IP地址(直接路由)及指向本地接口的指针。主机表项比网络表项具有更高的优先级,而网络表项比默认项具有更高的优先级。
系统产生的或转发的每份IP数据报都要搜索路由表,它可以被路由守护程序或ICMP重定向报文修改。系统在默认情况下不转发数据报,除非进行特殊的配置。用route命令可以进入静态路由,可以利用新ICMP路由器发现报文来初始化默认表项,并进行动态修改。主机在启动时只有一个简单的路由表,它可以被来自默认路由器的ICMP重定向报文动态修改。
在本章中,我们集中讨论了单个系统是如何利用路由表的。在下一章,我们将讨论路由器之间是如何交换路由信息的。