您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 揭阳分类信息网,免费分类信息发布

IPv6原理及在Linux操作系统上的应用与实践

2022/1/13 19:58:46发布91次查看
2017年11月26日,中共中央办公厅和国务院办公厅印发了《推荐互联网协议第六版(ipv6)规模部署行动计划》,并发出通知,要求各地区各部门结合实际认真贯彻落实。这条新闻传达了一个很重要的信息:这个是推进中国ipv6发展的战略总动员令。
本文将会从以下几个方面进一步介绍ipv6,包括有:
ipv6的基本概念ipv6在linux操作系统下的实现ipv6的实验ipv6的过渡技术介绍ipv6在linux平台下socket编程应该注意的问题实现简易版tgw支持ipv6雏形demo
值得说的是,目前我们接触得比较多的主流操作系统内核,已经很好地支持ipv6协议栈,例如:
windows: windows 7、windows 8.x、windows 10,默认开启ipv6linux: 内核2.6.x、内核3.x、内核4.x 已经支持ipv6(需要手动开启)
ios:ios9开始已经支持ipv6 only,2016年苹果已经强制要求app必须支持ipv6
本文提到的ipv6节点,没有特殊说明,一般指的是纯ipv6节点(ipv6 only),也就是只支持ipv6协议栈;ipv4节点,是指纯ipv4的节点,也就是只支持ipv4协议栈;如果节点支持ipv6和ipv4双栈,会指明是双栈节点。
ipv6的基本概念
众所周知,32位的ipv4地址已经耗竭,ipv6采用128位的地址长度拥有更大的地址空间。首先我们先来认识一下ipv6到底长成什么样子。
初识ipv6
图1 ipv6数据报文
上图是我们最熟悉的ping的ipv6版本icmpv6。可以看到,ipv6数据报文和ipv4有很大的差别:
数据链路层(l2)的type字段标识为 0x86dd,表示承载的上层协议是ipv6
ipv4对比:type字段为0x0800
ipv6的头部字段,和ipv4差别巨大(可以猜测到,ipv6和ipv4无法兼容)
ipv6的报文头部格式如下:
图2 ipv6报文头部(该图片来自互联网)
ipv6报文头部更精简了,字段更少了,对比起ipv4,有以下几个地方值得注意:
ipv6报文头部是定长(固定为40字节),ipv4报文头部是变长的。这个意味着,写代码处理ipv6数据报文的效率会提高很多:)ipv6中hop limit字段含义类似ipv4的ttl。ipv6中的traffic class字段含义类似ipv4中的tos(type of service)。ipv6的报文头部取消了校验和字段。取消这个字段也是对ipv4协议的一个改进。当ipv4报文在网路间传输,每经过一个路由器转发就是修改ttl字段,就需要重新计算校验和,而由于数据链路层l2和传输层l4的校验已经足够强壮,因此ipv6取消这个字段会提高路由器的转发效率。值得一提的是,在ipv6协议下,传输层l4协议udp、tcp是强制需要进行校验和的(ipv4是可选的)。ipv6报文头部中的next header字段表示“承载上一层的协议类型”或者“扩展头部类型”。这里的含义与ipv4有很大的差别,需要加以解释:
当ipv6数据报文承载的是上层协议icmpv6、tcp、udp等的时候,next header的值分别为58、6、17,这个时候和ipv4报文头部中的protocol字段很类似。
当不是以上3种协议类型的时候,ipv6报文头部紧接的是扩展头部。扩展头部是ipv6引入的一个新的概念,每个ipv6的数据报文可以承载0个或多个扩展头部,扩展头部通过链表的形式组织起来。当ipv6数据报文承载着扩展头部的时候,next header的数值为扩展头部的类型值。
为什么要引入扩展头部这个概念,这里也是ipv6对ipv4改进的一个方面,用扩展头部取代了ipv4的可选项信息,精简了ipv6的头部,增强了ipv6的扩展性。有同学会不会有疑问,ipv6的分片数据报文怎么处理?其实就是使用了ipv6扩展头部。我们来抓一个udp分片报文来看看。
图3 ipv6分片报文
当发送一个分片ipv6数据报文的时候,ipv6使用的是扩展头部的形式组织各个分片的信息,如图ipv6报文头部next header字段值为44表示存在扩展头部,扩展头部是ipv6分片数据信息。
对比ipv4,分片信息是记录在ipv4报文头部的分片字段中。
ipv6的扩展头部类型有很多种,除了上述的分片头部,还有路由头部、逐跳可选头部等,具体的可以参考rfc2460。
本章主要介绍了ipv6的一些很直观的认识,下面逐渐介绍ipv6上的基本知识和概念。
ipv6的地址语法
一个ipv6的地址使用冒号十六进制表示方法:128位的地址每16位分成一段,每个16位的段用十六进制表示并用冒号分隔开,例如:
一个普通公网ipv6地址:2001:0d12:0000:0000:02aa:0987:fe29:9871
ipv6地址支持压缩前导零的表示方法,例如上面的地址可以压缩表示为:
2001:d12:0:0:2aa:987:fe29:9871
为了进一步精简ipv6地址,当冒号十六进制格式中出现连续几段数值0的位段时,这些段可以压缩为双冒号的表示,例如上面的地址还可以进一步精简表示为:
2001:d12::2aa:987:fe29:9871
又例如ipv6的地址ff80:0:0:0:ff:3ba:891:67c2可以进一步精简表示为:
fe80::ff:3ba:891:67c2
这里值得注意的是,双冒号只能出现一次。
ipv6地址的号段划分和前缀表示法
ipv6拥有128位巨大的地址空间,对于那么大的空间,也不是随意的划分,而是使用按照bit位进行号段划分(与鹅厂内部一些的64位uin改造放号的zone划分算法)。
ipv6的地址结构如下图:
图4 ipv6地址结构
例如rfc4291中定义了n=48, m=16,也就是子网和接口id与各占64位
ipv6支持子网前缀标识方法,类似于ipv4的无分类域间路由cidr机制(注意:ipv6没有子网掩码mask的概念)。使用“ipv6地址/前缀长度”表示方法,例如:
2001:c3:0:2c6a::/64表示一个子网
而2001:c3:0:2c6a:c9b4:ff12:48bc:1a22/64表示该子网下的一个节点地址。
可以看到,一个ipv6的地址有子网前缀+接口id构成,子网前缀由地址分配和管理机构定义和分配,而接口id可以由各操作系统实现生成,生成算法后面的章节会介绍。
ipv6的地址类型
ipv6地址分三种类型
1、单播,对应于ipv4的普通公网和私网地址
2、组播,对应于ipv4的组播(多播)地址
3、任播,ipv6新增的地址概念类型
ipv6没有广播地址,用组播地址实现广播的功能。实际上我们工作和生活最可能最多接触的就是单播地址,接下来本文重点会讲解单播地址的种类。组播和任播地址有兴趣的同学自行查阅相关rfc和文献。
ipv6单播地址
注意,大家如果在网上搜索ipv6的地址,可能都是千篇一律的把所有“出现过”的单播地址介绍出来,其实有一些单播地址类型已经在相关的rfc中被废除或者不建议使用,而本节会指出这类地址。同时,在介绍单播地址的时候,尽量与ipv4中对应的或者相类似的概念做对比,加深理解。
ipv6单播地址有以下几种:
1、全球单播地址
图5 ipv6全球单播地址结构
前缀2000::/3,相当于ipv4的公网地址(ipv6的诞生根本上就是为了解决ipv4公网地址耗尽的问题)。这种地址在全球的路由器间可以路由。
2、链路本地地址
图6 链路本地地址结构
前缀fe80::/10,顾名思义,此类地址用于同一链路上的节点间的通信,主要用于自动配置地址和邻居节点发现过程。windows和linux支持或开启ipv6后,默认会给网卡接口自动配置一个链路本地地址。也就是说,一个接口一定有一个链路本地地址。如下图:
图7 linux下查看链路本地地址
图8 windows下查看链路本地地址
值得说的是,每个接口必须至少有一个链路本地地址;每个接口可以配置1个以上的单播地址,例如一个接口可以配置一个链路本地地址,同时也可以配置一个全球单播地址。
注意,很容易会把链路本地地址和ipv4的私网/内网地址对应起来,其实链路本地地址对应于ipv4的apipa地址,也就是169.254开头的地址(典型场景就是windows开启自动获取地址而获取失败后自动分配一个169.254的地址)。而ipv4私网对应于ipv6的什么地址,后面会介绍。
特别地,在ipv6 socket编程中,可以使用链路本地地址编程通信,但是需要增加一些额外的参数(这是一个小坑),在后面介绍编程的章节会介绍。
3、唯一本地地址
图9 唯一本地地址结构
前缀fc00::/7,相当于ipv4的私网地址(10.0.0.0、172.16.0.0、192.168.0.0),在rfc4193中新定义的一种解决私网需求的单播地址类型,用来代替废弃使用的站点本地地址。
可能看到这里,有同学会跳出来说:ipv6不是为了解决ipv4地址耗尽的问题吗,既然ipv6的地址空间那么大,可以为每一个网络节点分配公网ipv6的节点,那为什么ipv6还需要支持私网?这里需要谈谈对ipv6下私网支持的认识。
在ipv4中,利用nat技术私网内的网络节点可以使用统一的公网出口访问互联网资源,大大节省了ipv4公网地址的消耗(ipv6推进缓慢的原因之一)。另一方面,由于默认情况下私网内节点与外界通信的发起是单向的,网络访问仅仅能从私网内发起,外部发起的请求会被统一网关或者防火墙阻隔掉,这样的网络架构很好的保护了私网内的节点安全性和私密性。可以设想一下,如果鹅厂内部每台办公电脑都配置了ipv6的公网地址上网,是多么可怕的事情,每台办公电脑都会面临被黑客入侵的威胁(肉鸡真多)。
因此,在安全性和私密性要求下,ipv6中同样需要支持私网,并且也需要支持nat。在linux内核3.7版本开始加入对ipv6 nat的支持,实现的方式和ipv4下的差别不大(linux内核代码中变量和函数的命名几乎就是ctrl+c和ctrl+v过来的-_-||)。
4、站点本地地址
前缀fec9::/48,以前是用来部署私网的,但rfc3879中已经不建议使用这类地址,建议使用唯一本地地址。大家知道有这么一回事就可以了。网上还有很多文章还提到这种地址,但是没有说明这种地址已经不再使用。
5、特殊地址:回环地址
0:0:0:0:0:0:0:1或::1,等同于ipv4的127.0.0.1
6、过渡地址:内嵌ipv4地址的ipv6地址
就是在ipv6的某一些十六进制段内嵌这ipv4的地址,例如ipv6地址中64:ff9b::10.10.10.10,此ipv6地址最后4个字节内嵌一个ipv4的地址,这类地址主要用于ipv6/ipv4的过渡技术中。
一、ipv4兼容地址
0:0:0:0:0:0:w.x.y.z或::w.x.y.z(其中w.x.y.z是点分十进制的ipv4地址)。但在rfc4291中已经不推荐使用这类地址,大家知道有这么一回事就可以了。
二、过渡地址:ipv4映射地址
0:0:0:0:0:ffff:w.x.y.z或::ffff:w.x.y.z(其中w.x.y.z是点分十进制的ipv4地址),用于ipv6地址表示ipv4地址。主要用于某些场景下ipv6节点与ipv4节点通信,linux内核对这类地址很好地支持,在后面编程和内核分析的章节会分析使用过程。
三、过渡地址:特定过渡技术地址
6to4地址、isatap地址、teredo地址主要用于对应的过渡技术的地址,在后面介绍过渡技术的时候会介绍。
ipv6接口id生成算法
从前面的介绍中可以看出,ipv6单播地址是由前缀(64位)+接口id(64位)组成。接口id的生成算法主要有以下几种:
1、根据rfc4291定义,接口id可以从eui-64地址生成。
详细算法可以查看regli同学的ppt第14页。
2、为了可以具备某种程度的匿名信,接口id可以使用一个随机分配的,windows操作系统默认就是使用这种生成算法,linux下也是默认开启这个算法。
3、使用状态化的自动配置技术分配,例如dhcpv6分配。
4、手工配置。
ipv6地址配置
前面对ipv6的地址、前缀、接口等等做了介绍,接下来就是要介绍一个接口如何配置ipv6地址。ipv6一个比ipv4更厉害的方面,就是可以自动配置地址,甚至这个配置过程不需要dhcpv6(在ipv4中是dhcpv4)这样的地址配置协议。最典型的例子就是,只要开启了ipv6协议栈的操作系统,每个接口就能自动配置了链路本地地址,这个是和ipv4最重要的区别之一。
ipv6的地址配置有以下几种:
1、只要开启了ipv6协议栈,接口自动分配链路本地地址。
2、无状态自动配置地址(rfc2462),后面会有实验演示。
3、有状态自动配置地址,例如dhcpv6。
4、手动配置。
ipv6的域名解析
由于ipv6的地址扩展为128位,比ipv4的更难书写和记忆,因此ipv6下的dns变得尤为重要。ipv6的的dns资源记录类型为aaaa(又称作4a),用于解析指向ipv6地址的完全有效域名。下面是一个示例:
hostipv6.example.wechat in aaaa 2001:db8:1::1
ipv6下的域名解析可以认为是ipv4的扩展,详细可以查看rfc3596.
linux内核ipv6架构简析
本文后面主要的分析都是基于linux,会有涉及关于linux内核对ipv6的实现。主要是因为,现在ipv6的参考资料不多,除了与ipv6相关的rfc之外,还有少数可以参阅的ipv6国外文献,而linux内核一直都与跟随着ipv6的协议更新和变化,linux内核ipv6的实现是十分重要的参考材料之一。而且从事后台开发工作主要也是在linux平台下,熟悉linux下ipv6的实现也是为以后的工作做知识储备。
ps:客户端开发的同学可以参考各自平台的文档.............
linux在很早之前就已经开始支持ipv6,目前我们接触最多的linux内核版本都很好地支持ipv6,同时也是支持ipv4/ipv6双栈体系。在linux操作系统中,ipv4是默认必须开启,ipv6是可选编译和配置开启。
例如在编译内核的时候,需要选择ipv6编译选项才支持ipv6
图10 linux内核编译支持ipv6
当开启支持ipv6的linux的内核网络双栈的结构,如下图:
图11 linux内核双栈架构
linux内核中,ipv6协议栈与ipv4协议栈并行关系。ipv6和ipv4完全是两套不一样的代码实现。ipv6完整的协议栈逻辑模块包括:
1、网络层ipv6,核心逻辑:ipv6路由子系统
2、传输层tcp/udp实现:tcpv6、udpv6
揭阳分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录