IPV6 的概述
随着网络的发展,IPV4地址严重不足没了扩展IPV4地址空间,我们开放了IPV6,但是IPV6所带来的好处,不仅仅是扩大了地址空间,还有很多其他的问题:
- 增大了地址空间,因为 IPv6 的长度是128 bi t表示的
- 报文结构更加简化,设备处理起来,效率就更高
- 能够支持安全功能,在 IPv4 协议中是无法支持,即:IPv4 网络是不安全的,也不稳定
- 能够更换的支持 Qos,因为在报文结构中,引入了一个字段:flow label
- 对移动网络的支持更换,因为在IPv6中有任意播这种地址类型
- 支持便捷的地址自动配置方案:无状态自动配置、有状态自动配置
IPv6 地址格式
- IPv6 地址是通过 16 进制表示,叫冒分 16 进制,每一段是 4 个 16进制,一共是 8 段
- IPv6 地址也依然分为两部分:网络位+主机位,但是在IPv6中,称之为网络前缀+接口 ID
- 因为 IPv6 地址很长,所以为了方便,IPv6 存在一些地址的简写原则:
- 任何一段中,左边的0能省略,中间的 0 不能省略,右边的 0 不能省略
- 如果一个段,全是 0,可以用一个 0 表示
- 如果一个 IPv6 地址中,存在多个链路的段,都是 0,可以用 1 个双冒号表示“ :: ”
- 注意:双冒号在一个简写的 IPv6 地址中最多只能出现 1 次
IPv6 地址类型
IPv6 地址中,仅仅分为单播、组播、任意播
单播
未指定地址:IPv6 的 128 bit 全是 0;
回环地址: ::1 / 128 ,这种地址类似于 IPv4 中的 127.0.0.1
全球单播地址:相当于 IPv6 的公网 IP ,前面几个固定的 bit 是 001。所以,按照这个定义来说,理论上,全世界的IPv6主机地址,一共有2的125次方个,但是,现在国际机构允许售卖的公网IPv6地址,必须是掩码位 /48 的。但是运营商在申请到这些公网IPv6以后,售卖给中断企业用户的时候,肯定是在原来的IPv6基础上,进行了子网划分
唯一本地地址:相当于IPv6 的私网 IP,固定的前缀是 FC00::/7
链路本地地址( Link-local address):这种地址,用于在一个网段中,唯一标识一个接口,并且一个端口的 Link-local address地址可以自动形成,也可以手动配置,为什么会需要这样的一个地址呢?因为对于IPv6接口,一个端口是可以配置多个IPv6 地址的,同时一个 IPv6 地址,也可以同时配置在多个接口上的,所以仅仅通过 IPv6 地址,是无法识别唯一的标识一个接口的,所以才有了 link-local address,该类型的地址固定前缀是:FE80:: /10
注意:在不同类型 IPv6 地址中,有些地址的形成是需要依靠 interface-id ( 端口标识 )。但是官方规定,只要我们是用的 IPv6 地址的前面 3 个 bit 不是 000.那么该地址中所使用的 interface-ID 的规格,必须是长度为 64 bit 的格式,所以说上面我们所提到的=各种类型的 IPv6 单播地址,凡是用到了 interface-id ,都是格式为 64 bit 的
interface-id 的形成有三种方法:手动配置、系统软件生成、基于 IEEE EUI-64 的标准自动生成,第三种最常:该类型的方法,是基于端口的 MAC 地址来形成的,过程如下:
在原有的 MAC 地址的中间,插入一个固定的 2 个字节:FFFE
将原有的 MAC 地址左边的第 7 bit ,由 0 换成 1,此时形成了唯一的 64 bit 的 interface-id
最后我们需要知道的是 interface-id 仅仅是相当于 IPv6 地址中的主机位,还得需要一个 IPv6 的网络前缀,通常,都是由 IPv6 网段中的网关设备,主动发送自己的接口的 IPv6 网段,每个电脑收到这个网段以后,结合自己网课上的 interface-id ,从而形成了一个肯定没有冲突的 IPv6 地址
组播
只要 IPv6 的前面的 8 bit 是全 1,变成 16 进制后,就是 FF
组播地址也分为很多类型,比如公有组播地址,私有组播地址,链路组播地址,站点内组播地址
任何一个IPv6地址配置完成以后,都会自动形成一个“被请求节点组播地址”
形成过程是:一个固定的 104bit 的前缀,加上一个 IPv6 地址的后面 24 bit
固定的104bit前缀是:FF02 :: 1:FF00:0 /104
通常情况下,每个网段中的每个 IPv6 地址,对应的组播地址所表示的“组”,其中仅仅包含这个 IPv6 地址
任意播
本质上,就是一个IPv6单播地址,只不过将一个 IPv6 地址,同时分配给了多个具有相同的设备
IPv6报文类型
IPv6 报文头部分为两部分:固定头部 + 扩展头部 [ 固定头部 ,大小是 40 个字节 ]
虽然 IPv6 头部变长了,但是结构非常简单了,下面对常见的字段进行解析:
- version : 表示的是当前的 IP 协议的版本, 是 IPv6
- traffic - class : 流量类别,表示的是数据包的优先级,类似于 IPv4 头部中的 TOS ( type of service )
- dlow label :流标签,是 IPv6 相比较 IPv4 而言,新增加的字段,用于快速区分不同的数据流。在 IPv4 协议中,想要区分不同的数据流,我们需要确定 / 区分 每个数据流的 5个信息,俗称五元组( 源 IP - 目标 IP - 源端口 - 目标端口 - TCP/udp )在 IPv6中 ,引入了这个“ 流标签 ” 概念以后,在区分 IPv6 不同数据流的时候,仅仅依靠: 源 IPv6 地址 + 流标签。
- payload length : 负载长度,即表示 IPv6 头部后面的数据的长度。
- nextheader :下一个头部,指的是 IPv6 协议后面跟的是什么类型的协议 ,类似于 IPv4 中的 Protocol ID - 协议号
- hop limit :跳数限制,主要用于防止 IPv6 数据包成环,类似于 IPv4 头部中的 TTL ( time to live :存活时间)。即数据包在传输过程中,每经过一个路由器, hop limit 就会减少 1,当减少到 0 的时候 ,就直接被丢弃掉了。
- source address :源IPv6 地址
- destination address : 目标 IPv6 地址
- IPv6 固定头部后面,还有很多 “ 扩展头部 ” ,不同的扩展头部,实现的功能是完全不相同的,目前,RFC中定义了 6 个 IPv6 扩展头: 逐跳选项报头、目的选项报头、路由报头、分段报头、认证报头、封装安全净载报头。
IPv6协议之ICMPv6
在 IPv4 中, ICMPv4 更多的是进行线路的测试、路径的跟踪以及其他的报错信息的搜集和反馈。但是在 IPv6中 ,ICMPv6 的功能就非常多了,比如 ping ,tracert 、地址冲突检测 、IPv6 地址自动配置 、路径 MTU 发现机制 、邻居发现机制 、重定向功能。
ICMPv6 的 数据 ,在报文封装中,是位于 IPv6 头部后面, next - header 的取值是 58.
报文格式如下
报文中字段解释如下:
- type : 表示消息的类型 ,0 至 127 表示差错报文类型, 128 至 255 表示 消息报文类型
- Code:表示消息类型细分的类型
- Checksum :表示 ICMPv6 报文的校验和。
ICMPv6 错误报文的分类
ICMPv6 错误报文用于报告在转发 IPv6 数据包过程中出现的错误, ICMPv6 错误报文可以分为以下 4 种 :
- 目的不可达错误报文
- 在 IPv6 节点转发 IPv6 报文过程中,当设备发现目的地址不可达时,就发向发送报文的源节点发送 ICMPv6 目的不可达错误报文,同时报文中会携带引起该错误报文的具体原因。
- 目的不可达错误报文的 Type 字段值为 1 。根据错误具体原因又可以细分为 :
- Code = 0 :没有到达目标设备的路由
- Code = 1 :与目标设备的通信被管理策略禁止
- Code = 2 :未指定
- Code = 3 :目的 IP 地址不可达
- Code = 4 :目的端口不可达
- 数据包过大错误报文
- 在 IPv6 节点转发 IPv6 报文过程中, 发现报文超过出接口的链路 MTU 时,则向发送报文的源节点发送 ICMPv6 数据包过大错误报文,其中携带出接口的链路 MTU 值。数据包过大错误报文是 Path MTU 发现机制的基础。
- 数据包过大错误报文的 Type 字段值为 2 , Code 字段值为 0
- 时间超时报文
- 在 IPv6 报文收发过程中,当设备收到 Hop Limit 字段值等于 0 的数据包,或者当设备将 Hop Limit 字段值减少为 0 时, 会向发送报文的源节点发送 ICMPv6 超时错误报文。对于分段重组报文的操作,如果超过定时时间,也会产生一个 ICMPv6 超时报文
- 时间超时错误报文的 Type 字段值为 3 ,根据错误具体原因又可以细分为 :
- Code = 0 :在传输中超越了跳数限制
- Code = 1 :分片重组超时
- 参数错误报文
- 当目的节点收到一个 IPv6 报文时,会对报文进行有效性检查 ,如果发现问题会向报文的源节点回应一个 ICMPv6 参数错误报文。
- 参数错误报文的Type 字段值为 4 ,根据错误具体原因又可以细分为:
- Code = 0 :IPv6 基本头部或扩展头的某个字段有错误
- Code = 1 :IPv6 基本头部或扩展头的 Nextheader 值不可识别
- Code = 2 :扩展头中出现未知的选项
ICMPv6 信息报文的分类
ICMPv6 信息报文提供诊断功能和附加的主机功能,比如多播侦听发现和邻居发现。常见的 ICMPv6 信息报文主要包括回送请求报文 ( Echo Request )和回送应答报文 ( Echo Reply ,这两种报文也就是通常使用的 ping 报文。
- 回送请求报文:回送请求报文用于发送到目标节点,以使目标节点立刻发回一个回送应答报文。回送请求报文的 Type 字段值为 128 ,Code 字段值为 0。
- 回送应答报文:当收到一个回送请求报文时,ICMPv6 会用回送应答报文响应。回送应答报文的Type 字段值为 129 , Code 字段值为 0 。
ICMPv6之NDP
邻居发现协议 NDP ( Neighbor Discovery Protocol ) 是 IPv6 协议体系中一个重要的基础协议。邻居发现协议代替了 IPv4 中的 ARP ( Address Resolution Protocol )和 ICMP 路由器发现 ( Router Discovery ),它定义了使用 ICMPv6 报文实现地址解析,跟踪邻居状态,重复地址检测,路由发现以及重定向等功能。
地址解析
在 IPv4 中,当主机需要和目标主机通信时,必须先通过 ARP 协议获得目的主机的链路层地址。 IPv6 中,同样需要从IP 地址解析到链路层地址的功能。邻居发现协议实现了这个功能。
ARP 报文是直接封装在以太网报文中,以太网协议类型为 0x0866 ,普遍观点认为 ARP 定位为 2.5 层的协议。 ND 本身基于 ICMPv6 实现,以太网协议类型为 0x86DD ,即 IPv6 报文, IPv6下一个报头字段值为 58,表示 ICMPv6 报文,由于 ND 协议使用的所有报文均封装在 ICMPv6报文中,一般来说,ND 被看做第 3 层的协议在 3 层完成地址解析,主要带来以下几个好处:
- 地址解析在三层完成,不同的二层介质可以采用相同的地址解析协议。
- 可以使用三层的安全机制避免地址解析攻击
- 使用组播方式发送请求报文,减少了二层网络的性能压力
地址解析过程中使用了两种 ICMPv6 报文:邻居请求报文 NS ( Neighbor Solicitation )和邻居通过报文 NA ( Neighbor Advertisement )。
- NS 报文 : Type 字段值为 135 , Code 字段值为 0 ,在地址解析中的作用类似于 IPv4 中的 ARP请求报文。
- NA报文 : Type 字段值为 136, Code 字段值为 0 ,在地址解析中的作用类似于 IPv4 中的 ARP 应答报文
Host A 向 Host B 发送报文之前它必须要解析出 Host B 的链路层地址,所以 首先 Host A 会发送一个 NS 报文,其中 源地址为 Host A 的 IPv6 地址,目的地址为 Host B 的被请求节点组播地址,需要解析的目标 IP 为 Host B 的 IPv6 地址,这就表示 Host A 想要知道 2Host B 的链路层地址。同时需要指出的是,在 NS 报文的 Options 字段中还携带了 Host A 的链路层地址。
当 Host B 接收到了 NS 报文之后,就会回应 NA 报文,其中源地址 为 Host B 的 IPv6 地址 ,目的地址为 Host A 的IPv6 地址 ( 使用 NS 报文中的 Host A 的链路层地址进行单播 ),Host B 的链路层底子被放在 Options 字段中,这样就完成了一个地址解析的过程。
跟踪邻居状态
通过邻居或到达邻居的通信,会因为各种原因而中断,包括硬件故障、接口卡热插入等。如果目的地失效,则回复不可能的,通信失败;如果路径失效,则回复是可能的。因此节点需要维护一张邻居表,每个邻居都有相应的状态,状态之间可以迁移。
RFC2461 中定义了 5 种邻居状态,分别是 :未完成 ( Incomlete )、可达 ( Reachable )、陈旧 ( Stale )、延迟 ( Delay )、探查 ( Probe )。邻居状态之间具体迁移过程如下,其中 Empty 表示邻居表项为空:
下面以 A 、B 两个邻居节点之间互相通信过程中 A 节点的邻居状态变化为例 ( 假设 A、B 之间从未通信 ),说明邻居状态迁移的过程。
- A 先发送 NS 报文,并生成缓存条目,此时 ,邻居状态为 Incomplete .
- 若 B 回复 NA 报文,则邻居状态由 Incomplete 变为 Reachable ,否则固定时间后邻居状态由 Incomplete 变为 Empty ,即删除表项。
- 经过邻居可达时间,邻居状态由 Reachable 变为 Stale ,即位置是否可达
- 如果在 Reachable 状态, A 收到 B 的非请求 NA 报文,且报文中携带的 B 的链路层地址和表项中不同,则邻居状态马上变为 Stale .
- 在 Stale 状若 A 要向 B 发送数据,则邻居状态由 Stale 变为 Delay ,并发送 NS 请求。
- 在经过一段固定时间后,邻居状态由 Delay 变为 Probe ,其间若有 NA 应答,则邻居状态由 Delay 变为 Reachable 。
- 在 Probe 状态, A 每隔一段时间间隔发送单播 NS , 发送固定次数后,有应答则邻居状态变为 Reachable ,否则邻居状态变为 Empty ,即删除表项
重复地址检测
重复地址检测 DAD ( Duplicate Address Detect )是接口使用某个 IPv6 单播地址之前进行的,主要是为了探测是否有其它的节点使用了该地址。尤其是在地址自动配置的时候,进行 DAD 检测是很必要的。 一个 IPv6 单播地址在分配给一个接口之后通过重复检测之前称为实验地址 ( Tentative Address ),此时该接口不能能使用这个实验地址进行单播通信,但是仍然会加入两个组播组: ALL- NODES 组播组合实验地址所对应的 Solocited - Node 组播组
IPv6 重复地址检测技术和 IPv4 中的免费 ARP 类型: 节点向实验地址所对应的 Solicited - Node 组播组发送 NS 报文 。NS 报文中目标地址即为该实验地址。如果收到某个其他站点回应的重复地址检测原理如下图所示:
Host A 的 ipv6 地址 FC00::1 为新配地址 ,即 FC::1 为 Host 1 的实验地址。Host A 想 FC00::1的 Solicited - Node 组播组发送一个以 FC00::1 为请求的目标地址的 NS 报文进行重复地址检测, 由于 FC00::1并未正式指定,所以 NS 报文的源地址 为指定地址。当Host B 收到该 NS 报文后,有两种处理方法:
1、如果 Host B 发现 FC00::1 是自身的一个实验地址 ,则 Host B 放弃实验这个地址作为接口地址,并且不会发送 NA 报文
2、如果 Host B 发现 FC00::1 是一个正常使用的地址, Host B 会向 FF02::1发送一个 NA 报文,该消息中会包含 FC00::1.这样, Host A 收到这个消息后就会发现自身的试验地址是重复的。 Host A 上该试验地址不生效,被标识未 duplicated 状态。
路由发现
路由器发现功能用来发现与本地链路相连的设备,并获取与地址自动相关的前缀和其他配置参数,在 ipv6 中,ipv6 地址可以支持无状态的自动配置,即主机通过某种机制获取网络前缀信息,然后主机自己生成地址的接口标识部分。路由器发现功能是 ipv6 地址自动配置功能的基础,主要通过以下两种报文实现:
1、路由器通过 RA (Router Advertisement )报文:每台设备为了让二层网络上的主机和设备知道自己的存在,定时都会组播发送 RA 报文,RA 报文中会带有网络前缀信息,以及其他以下标志位信息。 RA 报文 的 Type 字段值为 134 。
2、 路由器请求 RS ( Router Solicitation )报文:很多情况下主机接入网络后希望尽快获取网络前缀进行通信,此时主机可以立刻发送 RS 报文 ,网络上的设备将回应 RA 报文,RS 报文的 Type 字段值为 133。
路由器发现功能如下图所示:
地址自动配置
ipv4 使用 DHCP 实现自动配置,包括 IP 地址,缺省网关等信息,简化了忘了管理, ipv6 地址增长为 128 位 ,且终端节点多,对于自动配置的需求更为迫切除保留了 DHCP 作为有状态自动外,还增加了无状态自动配置。ipv6无状态自动配置过程:
- 根据接口表示产生链路本地地址
- 发出邻居请求,进行重复地址检测
- 如地址冲突,则停止自动配置,需要手工配置
- 如不冲突,链路本地地址生效,节点具备本地链路通信能力
- 主机会发送 RS 报文( 或接收到设备定期发送 RA 报文 )
- 根据 RA 报文中的前缀信息和接口表示得到 ipv6 地址
默认路由器优先级和路由信息发现
当主机所在的链路中存在多个设备时,主机需要根据报文的目的地址选择转发设备,在这种情况下,设备通过发布默认路由优先级和特定路由信息给主机,提高主机根据不同的目的地址选择合适的转发设备的能力
在 RA 报文中,定义了默认路由优先级和路由信息两个字段,帮助主机在发送报文时选择合适的转发设备,主机收到包含路由信息的 RA 报文后,会更新自己的路由表,当主机箱其他设备发送报文时通过查询该列表的路由信息,选择合适的路由发送报文
主机收到包含默认设备优先级信息的 RA 报文后,会更新自己的默认路由列表,当主机向其他设备发送报文时,如果没有路由可选,则首先查询该列表,然后选择本链路内优先级最高的设备发送报文;如果该设备故障,主机根据优先级从高到低的顺序,依次选择其他设备。
重定向
当网关设备发现报文重其他网关设备转发更好,它就会发送重定向报文告知报文的发送者,让报文发送者选择另一个网关设备。重定向报文也承载在 icmpv6 报文中,其中 tpye 字段值为 137,报文中会携带更好地路径吓一跳地址和需要重定向转发的报文和目的地址等信息。
Host A 需要和 Host B 通信, Host A 的默认网关设备是 Router A ,当 Host A 发送报文给 Host B时报文会被送到 Router A,Router A接收到 Host A 发送的报文以后会发现实际上 Host A 直接发送给 Router B 更好,它将发送一个重定向报文给主机 A ,其中报文中更好地路径吓一跳地址为 Router B ,Destination Address 为 Host B , Host A 接收到了重定向报文之后,会在默认路由表中添加一个主机路由,以后发往 Host B 的报文就直接发送给 Router B。当设备收到一个报文后,只有在如下情况下,设备会向报文发送者发送重定向报文:
- 报文的目的地址不是一个组播地址
- 报文并非通过路由转发给设备
- 经过路由计算后,路由的吓一跳出接口是接收报文的接口
- 设备发现报文的最佳吓一跳 IP 地址和报文的源 IP 地址处于不同一网段
- 设备检测报文的源地址 ,发现自身的邻居表项中所有用改地址作为全球当博地址或链路本地地址的邻居存在
Path MTU
在 ipv4中,报文如果过大,必须要分片进行发送,所以在每个节点发送报文之前,设备都会根据发送接口的最大传输单元 MTU ( Maximum Transmission Unit )来对报文进行分片。但是在 ipv6 中,为了减少中间转发设备的处理压力,中间转发设备不对 ipv6 报文进行分片,报文的分片将在源节点进行。当中间转手设备的接口收到一个报文后,如果发现报文长度比转发接口的 MTU 值大,则会将其丢弃;同时将转发接口的 MTU 值通过icmpv6 报文的 “ Packet Too Big ”消息发送给源主机,源端主机以该值重新发送ipv6 报文,这样带来了额外流量开销。 PMTU 发现协议可以动态发现整体传输路径上各链路的 MTU 值,减少由于重传带来的额外流量开销 。
PMTU 协议时通过 icmpv6 的 Packet Too Big 报文来完成的。首先源阶段假设 PMTU 就是其出接口的 MTU ,发出一个试探性的报文,当转发路径上存在一个小于当前假设的 PMTU 时,转发设备就会向源节点发送 Packet Too Big 报文,并且携带自己的 MTU 值,此后源节点将 PMTU 的假设值更改未新收到的 MTU 值继续发送报文。如此反复,直到报文到达目的地之后,源节点就能知道达到目的地的 PMTU 了,工作工程如下:
整条传输路径需要通过4条链路,每条链路的 MTU 分别是 1500、1500、1400、1300,当源节点发送一个分片报文的时候,首先按照 PMTU 为 1500 进行分片并发送分片报文,当到达 MTU 为 1400 的出接口时,设备返回 Packet Too Big 错误,同时携带 MTU 值为 1400 的信息,源节点接收到之后会将报文重新按照 PMTU 为 1400 进行分片并再次发送一个分片报文,当分片报文到达 MTU 值为 1300 的出接口时, 同样返回 Packet Too Big 错误,携带 MTU 值为 1300 的信息。之后源节点重新按照 PMTU 值为 1300 进行分片并发送报文,最终到达目的地,这样就找到了该路径的 PMTU..
由于 IPV6 要求链路层所支持的最小 MTU 为 1280 ,所以 PMTU的值必须大于 1280,建议用 1500作为链路的 PMTU 值。