计算机应用研究
APPLICATION RESEARCH OF COMPUTERS
2000 Vol.17 No.3 P.24-26




实现IPv4网络向下一代IPv6网络迁移的通用隧道方法
陆魁军
摘　要：隧道技术是实现IPv4网络向IPv6网络平滑迁移的有效方法，论述了在配置型隧道及自动型隧道中所使用的一般性技术思想，提出了在使用IPv4隧道传输IPv6数据报时可能遇到的问题及相应解决方法。
关键词：IPv4网络 IPv6 隧道 数据报
　　自90年代以来，Internet的网络规模以爆炸性的速度持续增长，从而造成IPv4的地址日益短缺。在这样的环境下，IETF在90年代中期推出了第6版IP协议?IPv6。IPv6与IPv4并不兼容，但它与几乎所有的Internet协议(包括TCP、UDP、ICMP、OSPF、BGP、DNS等)兼容或基本兼容，同时，地址长度由IPv4的32bit增加到128bit(即16字节),从而一劳永逸地解决了IPv4的有限地址空间问题。尽管IPv6与IPv4并不兼容，我们还是可以利用适当的技术手段来建立基于IPv4网络基础设施的IPv6传输系统，隧道技术就是架构这种IPv6传输网络的一种有效方法。
1　IPv6数据报结构
　　IPv6数据报的格式如图1所示。

图1　IPv6数据报的格式
　　在图1中，Ver(版本)字段的值为6，表明这是IPv6的报头；Prio(优先级)指示传输优先级，取值范围为0～15，IPv6支持视频、音频等实时性较强的数据报的传输，这些数据报被授予较大的值，优先级较高。
　　Flow Label(流标号)用于报源主机和目标主机建立一个伪连接，从而提供类似于虚电路的功能。
　　Payload Length标明数据部分长度(不包括报头)；Hop Limit(路由段数上限)字段类似于IPv4的Time to Live字段，每经过一个路由器本字段减1。
　　Next Header(下一报头类型)：当存在扩展报头时，本字段指示下一扩展报头(而不是本报头)的类型；否则指数据部分中运输层协议的报头类型。
　　与IPv4相比，IPv6要求所有主机或路由器支持576字节的数据报，对过长数据包，中间路由器一般不再执行计算繁琐且效率低下的数据报分段工作，而是直接丢弃，并向报源主机发回ICMP错误报告，由报源主机分段并重发。此外，由于链路层及运输层往往计算校验和，IPv6省掉了IPv4所具有的校验和字段，省去耗时的校验和计算可大大提高路由器的转发速度。
　　然而，有些省掉的字段偶尔还有需要的时候，因而IPv6引入了可选“扩展报头”的概念，共有6种扩展报头：Hop-by-hop选项、路由选项、分段选项、鉴别验证选项、数据部分加密传输选项、目标选项。
　　花费数年甚至数十年时间构建起来的IPv4网络不可能一夜之间全部废弃而更新为IPv6网络，因此，通常的做法是使用隧道技术，利用IPv4网络为隧道沟通IPv6主机或路由器，并建立这类隧道型IPv6孤岛，图2示出了这种基于IPv4隧道的IPv6网络的一个例子，这里大的云状网络是IPv6网络，小的云状网络是IPv4网络，IPv4网络用作隧道连通IPv6/IPv4双协议路由器，实现IPv6主机之间的数据通信。随着IPv6网络的发展，一些孤岛相互连接而成为较大的群岛，并在最终全部互连成为IPv6型的Internet新大陆。

图2　利用IPv4网络为隧互联IPv6主机或路由器
　　以下几节就隧道实现的通用技术思想作逐一论述。
2　网络节点、地址、隧道分类
　　IPv6/IPv4节点：是指实现了IPv4及IPv6两种网络层协议的主机或路由器。
　　IPv6节点：指IPv6单协议节点或IPv6/IPv4双协议节点。
　　IPv4节点：指IPv4单协议节点或IPv6/IPv4双协议节点。
　　兼容于IPv4的IPv6地址： 16个字节的IPv6地址中，高位6个字(共96位)为全0，即0:0:0:0:0:0,低位32位则是IPv4地址。如下所示：

　　拥有这类地址的节点通常是IPv6/IPv4节点，反之，IPv4/IPv6节点则不一定使用兼容于IPv4的IPv6地址，它也可以使用单一IPv6地址。
　　单一IPv6地址：高位6个字(96位)非全0的IPv6地址。
　　基于IPv4网络的IPv6隧道：使用IPv4数据报格式封装IPv6数据报，如图3所示，以便使用IPv4网络基础设施来传送IPv6数据报。共有两种不同的隧道传送方法：

图3　IPv6数据报至IPv4数据报的封装与解封
　　(1)配置型隧道传送方法：当封装节点(即隧道首节点)通过IPv4隧道转发IPv6数据报时，隧道的尾节点IPv4地址从封装节点自身存储的配置信息中获取，而不是从数据报的IPv6目的地址中提取出来。
　　(2)自动型隧道传送方法：当数据报目的地址是IPv4兼容的IPv6地址时才可以使用本方法。隧道首节点根据IPv6数据报头部的IPv6目的地址(其中包含IPv4地址)决定隧道的尾节点IPv4地址，即：IPv6地址去掉其高位96位后剩下的IPv4地址。
3　IPv6/IPv4节点地址配置
　　IPv6/IPv4节点既能与IPv4节点进行IPv4格式数据报通信，又能与IPv6节点进行IPv6格式的数据报通信。同时，IPv6/IPv4节点具有IPv4及IPv6双重IP地址。这两个地址可以是无关的，也可以是相关的(即兼容于IPv4的IPv6地址)。使用自动型地址配置方法的节点必须使用兼容于IPv4的IPv6地址(相关型地址)，该单个IPv6地址具有一址两用的功能。
　　IPv6/IPv4节点可以使用下述方法来获得其IPv6地址：
　　(1)无状态IPv6地址配置机制。
　　(2)用于IPv6的DHCP协议。
　　(3)当使用自动型隧道传送方法时，可以先使用IPv4的地址获取机制，如BOOTP、DHCP、RARP等协议来获得其IPv4地址，然后通过添加高位96位0来映射为IPv6地址。本方法在尚未部署IPv6路由器及地址配置服务器的环境下显得特别有用。
4　两种隧道传送方法共用的隧道机制
　　用IPv4格式封装IPv6数据报时，封装节点(即隧道首节点)首先需要加上一个IPv4报头，除此之外，封装节点还需处理一些更复杂的事情：
　　(1)决定在什么情况下进行数据报分段，什么情况下报告“数据报太长”的“ICMP错误”报文给数据报的报源节点。
　　(2)如何把隧道中间节点返回的IPv4“ICMP错误”报文转换为IPv6的“ICMP错误”报文，并向报源IPv6主机报告。
4.1　隧道MTU及数据报分段
　　封装节点较直观而简单的做法是：把IPv6数据报的IPv4封装看作IPv6层使用了具有很大MTU(65,535-20)的链路层，这里65,535字节是IPv4数据报的最大尺寸，20字节是IPv4报头的大小，IPv4的MTU是指包括IPv4报头长度的允许传输的最大IPv4数据报长度， IPv6的MTU是指包括IPv6报头长度的允许传输的最大IPv6数据报长度。对不大于65,515的IPv6数据报，封装节点直接用IPv4封装并允许分段，随后转发至隧道中；对大于65,515的数据报，隧道封装节点则丢弃并向报源主机报告“数据报太长的IPv6型ICMP错误”，此后由报源主机以不大于65,515的长度重发该数据报。然而，重发的数据报仍然很长，在穿越IPv4网络构成的隧道时仍可能在沿途路由器上因数据报太长而分段。例如，假设隧道首节点的IPv4 MTU为1,500字节，隧道中间的一个路由器的IPv4 MTU为1,000字节(它的MTU在全隧道中最小)。报源主机发送了一个68K字节(包括IPv6报头长度)的IPv6数据报后，封装节点会予以丢弃并发回IPv6的ICMP数据报。接着，报源主机重发较小的总长为65,515字节的IPv6数据报；封装节点收到后把此数据报分段成多个1,500字节的IPv4数据报，并在隧道中转发；这些数据报在隧道中间MTU为1,000字节的路由器上会进一步分段成1,000字节的IPv4数据报。
　　所以，这种简单做法会导致效率低下，这主要体现在以下两方面：
　　(1)会导致比所需更多的分段，而IPv4层的分段会引起性能下降，因为一个分段后的报片丢失，就会引起包含所有报片的原始数据报的重传。
　　(2)组成一个隧道中IPv4数据报的所有分段后报片，需要在隧道尾节点处重装成为原始数据报，对于路由器这类尾节点，就需要附加内存存储各报片，以便全部到达后重装。
　　隧道首节点较好的做法是使用IPv4的“隧道全程MTU探寻”协议，把探寻结果记为MTU4，并记：MTU6=(MTU4-IPv4的报头长度)。此后，封装节点中的IPv6协议可把IPv4隧道看成是一个能承载最大数据报长为MTU6的数据链路层，在向报源主机发送“数据报太长”的ICMP报文时，附上MTU6的信息。例如，对上面提到过的例子，封装节点在丢弃该68K字节的数据报后，会要求报源主机重发MTU6=980字节的IPv6数据报。
　　IPv6要求网络的最小MTU为576字节，隧道首节点中的IPv6层不能发送比576字节更小的数据报，但IPv4网络的隧道全程MTU可能小于(576+IPv4报头长度)。这时数据报分段在隧道中间就会不可避免地发生。因此，上面的“隧道全程MTU探寻”协议并不能完全去除数据报的分段现象。
　　对于大于上述MTU6的IPv6数据报，隧道首节点可使用以下算法来决定：用IPv4转发(根据需要分段或不分段)，或丢弃并发回IPv6的“ICMP数据报太长”报文，由报源节点重发更小的数据报。
if(MTU4-20)≤ 576 then 
　　if　数据报长度 > 576 then
　　　　丢弃，并发回IPv6 ICMP报文“数据报太长”
　　　　(其中期望的MTU=576)
　　else /* 数据报长度≤576 */
　　　　用IPv4封装并允许分段，隧道首节点或中间节点根据需要会进行IPv4分段
　　endif
else /* (MTU4-20)> 576 */ 
　　if　数据报长度 > MTU4-20 then
　　　　丢弃，并发回IPv6 ICMP报文“数据报太长”
　　　　(其中期望的MTU=MTU4-20) 
　　else /* 数据报长度≤MTU4-20 */
　　　　　发送该数据报并置“禁止分段”标志。
　　endif
endif
4.2　路由段数限制值(Hop limit)
　　整个IPv4隧道的IPv6路由段数定为1，IPv6数据报在穿越整个隧道时，报头中的Hop limit字段减1，从而对IPv6网络用户隐去了隧道的存在。
4.3　IPv4报头的构造
　　当封装节点用IPv4数据报格式封装IPv6数据报时，它按如下方法设置IPv4报头的各个字段：
　　・Version(版本)：4。
　　・IP报头长度：5(4字节为单位)。
　　・Type of service(服务类型)：0。
　　・Total length(IPv4数据报总长度)：被封装IPv6报头的“Payload Length"字段值加上IPv6报头(包括扩展报头)及IPv4报头长度，后两项之和常常是60字节。
　　・Identification(标识)：封装节点为每个IPv4数据报产生一个唯一值。
　　・Flags(标志位)：按照4.1节的方法，若允许分段，则置DF←0, MF按是否是最后一个报文段置相应值；若不允许分段则置DF←1, MF←0。
　　・Fragment offset(本报文段数据部分在原始分段前报文的数据部分中的相对偏移值)：对每个报文段按实际偏移值设置。
　　・Time to live(寿命)：按具体某一实现所确定的值填写。
　　・Protocol(协议)：41，即IPv6的协议类型值。
　　・Header checksum(报头校验和)：按IPv4报头校验和的计算结果填写。
　　・源地址：封装节点发出本数据报所用网络接口的IPv4地址。
　　・目的地址：隧道尾节点的IPv4地址。
4.4　IPv4 ICMP错误的处理方法
　　隧道封装节点可能会收到隧道中间IPv4路由器的IPv4 ICMP出错报文，这些报文是对发到隧道中的数据报错误的响应信息。
　　隧道首节点中的IPv6协议根据隧道全程MTU及数据报长度来决定是否向报源主机发回一个IPv6的ICMP“数据报太长”错误信息。
　　IPv4的“ICMP错误”报文可以附带上一定长度的引起错误的原始数据报的一部分，对“ICMP错误”报文的处理依赖于所携带的原始数据报有多长。很多以前的路由器只附上出错数据报IPv4报头以后8 字节的内容；这8个字节还不足以包含IPv6报头(作为IPv4报头后的数据)的地址字段。较现代的路由器可以包括在IPv4报头以后的足够的数据，足以包括整个IPv6报头，甚至其后的IPv6数据。如果“ICMP错”报文包括足够的数据，封装节点可从中提取IPv6数据报，并据此产生IPv6的“ICMP错”报文，发回到IPv6报源节点。
5　结束语
　　与IPv4相比，IPv6具有以下技术优势：支持约3×1038个IP地址；路由表占用更小的存储空间；路由器可以更快速地处理数据报；更好的网络安全性；更好地支持实时数据，等等。隧道技术一方面保护现有IPv4网络的投资，同时又使IPv4网络向IPv6的顺利迁移成为可能；目前，使用隧道技术创建的IPv6主干网6Bone已经开通，它是一个在Internet上运行的IPv6实验网络。相信在不久的将来，更多的基于隧道技术的IPv6网络会被建立并融入广袤的Internet世界中。
陆魁军(浙江大学计算机系 杭州 310027)
参考文献
1 Gilligan R.and Nordmark E.,Transition Mechanism for IPv6 Hosts and Routers. RFC1933 of IETF, 1996
2 Stevens W. and Thomas M., Advanced Sockets API for IPv6, RFC2292 of IETF，1998
3 Tanenbaum, A. Computer Network, (3rd Version), USA, Prentice Hall Inc. 1996
收稿日期：1999年10月19日
