NPTv6 在路由器上把一侧 IPv6 前缀换成另一侧前缀,地址一一对应,不改端口。前缀变化对伪首部校验和的影响,由地址里另一个 16 位的补码调整抵消。规范是 2011 年 6 月的 RFC 6296,属实验性,不是标准轨道。第 1 节写明,IETF 不建议在 IPv6 使用网络地址翻译。

实验性规范,并且不建议把它当成默认做法

一个可独立引用的定义句:NPTv6 是无状态、与传输层无关的 IPv6 到 IPv6 网络前缀翻译。它提供与 IPv4 NAPT 相关的地址独立性,并在内部前缀和外部前缀之间保持地址的一一对应,从而保留网络层的端到端可达性(RFC 6296 摘要)。

同一份状态说明写明:这不是互联网标准轨道规范,发布目的是检验、实验性实现和评估。2026 年 10 月 20 日查阅的 RFC 元数据 把状态标成 EXPERIMENTAL,没有列出取代它或被它更新的 RFC。

第 1 节还有一句:出于 RFC 2993 和第 5 节所讨论的原因,IETF 不建议在 IPv6 使用网络地址翻译技术。若仍然实现翻译,这份规范给出的机制在架构上少于「只把传统有状态 NAT 搬到 IPv6」。2026 年 10 月 20 日没有重读 RFC 2993,因此不转述那份文档的理由,只保留 RFC 6296 自己写在第 1 节的这句。

关键词按 RFC 2119 解释。第 1.3 节没有加上后来常见的「只在全大写时才算」。下文里的大写要求对应原文的大写词。第 3.5 节有一处小写 must,不把它升成大写。

调整量写在前缀之外的 16 位

一个可独立引用的定义句:校验和中立是指:翻译 IPv6 前缀时对地址做的改动,被同一地址里其他部分的改动抵消,从而用标准互联网校验和算法算出的 IPv6 伪首部校验和不变。使用该校验和的传输层因此不必改头(RFC 6296 第 2.6 节)。

第 3.1 节规定配置时的算法。内部前缀和外部前缀先补成相同长度,较短的一侧用 0 延长。二者再各用 0 延长到 /64,对各自的 16 位字做一的补码和,然后取差:内部减去外部。这个差叫做 adjustment,在配置不变的期间保持不变。

出站改的是源地址,入站改的是目的地址。

方向地址的哪一个字段两步改写
内部到外部源地址内部前缀换成外部前缀;再把 adjustment 用一的补码加法加到指定的 16 位上
外部到内部目的地址外部前缀换成内部前缀;再从同一位置减去 adjustment
加或减之后得到 0xFFFF该 16 位改写成 0

出站还有一条先于改写的丢弃:内部子网号没有映射时,例如是 0xFFFF,或者根本没有映射,丢掉该数据报。这应当产生一条 ICMP 目的地不可达。原文的 SHOULD 打在这条 ICMP 上。

指定的 16 位取决于前缀长度:

  • 内部和外部前缀是 /48 或更短时,adjustment 必须加到或减自地址的第 48 到 63 位。实现必须实现这种 /48 映射。这两句在第 3.4 节是大写 MUST。这一段不改接口标识。
  • 长于 48 位时,第 3.5 节用小写 must 要求加到或减自第 64–79、80–95、96–111 或 112–127 位中的一个字。为了一致,这些字必须按这个顺序检查,选第一个起初不是 0xFFFF 的。后一句是大写 MUST。实现应当实现更长前缀的映射,这是 SHOULD。

使用 /48 外部前缀时,第 4.2 节要求:网络不得用 0xFFFF 标一个仍期望被翻译的子网。这是 MUST NOT。

第 6 节另有一条必须:遵守这份规范的 NPTv6 翻译器不得做端口映射。出口 NAPT 会改传输标识,并因此更新校验和。NPTv6 的调整落在地址内部。TCP 校验和 盖住的伪首部含地址;前缀一换,材料就变了。第 2.6 节的意图是让这份和在翻译前后相同,从而不必去改校验和字段。某一实现是否真的没有改那个字段,本文没有测量。

例子里的减法,和第 3.1 节方向相反

第 3.6 节印出一组 /48。内部前缀 FD01:0203:0405::/48,外部前缀 2001:0DB8:0001::/48。内部地址 FD01:0203:0405:0001::1234 被写成外部地址 2001:0DB8:0001:D550::1234。

原文给出的步骤是:FD01:0203:0405 的一的补码校验和是 0xFCF5,2001:0DB8:0001 的是 0xD245。用一的补码算术,0xD245 − 0xFCF5 = 0xD54F。子网 0x0001 + 0xD54F = 0xD550。因为结果不是 0xFFFF,不改成 0x0000。

这组数字把外部前缀的校验和减去内部前缀的校验和。第 3.1 节却把 adjustment 定义成内部减去外部。两句的方向相反。2026 年 10 月 20 日检索 勘误,没有一条已验证的勘误改写这个方向。本文不把其中一句改成另一句,也不判断哪一句被实现采用。

按第 3.6 节印出的两个地址,只把发生变化的四个 16 位字做一的补码加法,两端的回卷和都是 0x030B。这是对印出数字的核对,不是原文另给的公式,也没有运行附录 B 的代码。

回程那一句有一条已验证的技术勘误。勘误 3033(Verified,2011-12-06)把例子里的目的地址从 2001:0DB8:0001:D550::0001 改为 2001:0DB8:0001:D550::1234,再映射回 FD01:0203:0405:0001::1234。勘误不改 0xD550 和 0x0001 那几步算术。

更长前缀还有一句丢弃。第 3.7 节写:翻译器在做地址映射时若发现接口标识全为 0,必须丢掉该数据报,并应当产生 ICMPv6 参数问题。勘误 8757 主张这里的「全 0」应改成「全 1」。2026 年 10 月 20 日它的状态仍是 Reported,不是 Verified。本文不采用尚未验证的改写。

没有每流状态,也不等于防火墙

一个可独立引用的定义句:按本文的用法,NPTv6 翻译器不维持按节点或按流的状态。入站和出站都只凭 IPv6 头里的信息做算法翻译(RFC 6296 第 2.5 节)。

因此多个按同一配置工作的翻译器不必交换动态状态。原文把不对称路由、负载分担和故障切换写成由此可以做到。这是该节的推论,不是 2026 年 10 月的测量。

第 4.3 节要求必须支持发夹:内部接口上收到、目的地址匹配本站点外部前缀的数据报,要翻译后向内转发。概念上是先按第 3.2 节离开,再按第 3.3 节回来。本文不提供打开发夹或编写前缀的步骤。

第 7 节写明:这种双向算法映射允许从外部直接向内部节点建立连接。规范建议翻译器同时实现防火墙功能,并指向 RFC 6092,包括能够打开或关掉的配置。2026 年 10 月 20 日没有重读 RFC 6092,因此不描述那份防火墙。翻译算法本身没有策略。不要把「做了 NPTv6」读成「已经有状态防火墙」。

第 1.2 节还写:NPTv6 在途中修改 IP 头,因此与保护 IP 头完整性的机制不兼容,例子是 IPsec 认证头。它又用 “in many cases” 写:由于不改写传输层头,许多情况下不会干扰对整个 IP 载荷的加密。本文不把这句收成「所以 ESP 一定不受影响」。

唯一本地地址 可以当作内部前缀。第 1.2 节同时说,若期望 ULA 阻止来自该范围之外的访问,NPTv6 会盖过这个期望。只有被配置进翻译器的那个前缀会被翻译。fd 开头本身不证明翻译正在发生。

NAT64 与 DNS64 处理的是 IPv6 与 IPv4 之间的到达。NPTv6 两侧都是 IPv6。2026 年 10 月 20 日没有重读 NAT64 那组 RFC,因此不把两类翻译的字段并成一张表。

隧道若包住的是翻译之后的包,内层看到的是外部形式;若包住的是翻译之前的包,内层仍是内部形式,直到翻译器。某一 VPN 先封装还是先翻译,本文没有测量。本文不提供把 NPTv6 放进隧道的步骤。

核对清单

  1. 状态是实验性:RFC 6296 不是标准轨道。第 1 节写明 IETF 不建议在 IPv6 使用网络地址翻译。2026 年 10 月 20 日没有重读它所引的 RFC 2993;
  2. 不改端口:遵守规范的翻译器不得做端口映射。校验和中立靠的是地址里另一个 16 位,不是去改传输层校验和字段;
  3. adjustment 的方向有两句:第 3.1 节是内部减外部。第 3.6 节的例子印的是 0xD245 − 0xFCF5。没有已验证勘误统一这两句;
  4. 回程地址以勘误 3033 为准:例子里的外部形式是 2001:0DB8:0001:D550::1234。勘误 8757 仍未验证,不把「全 0 必须丢弃」改成「全 1」;
  5. 不是防火墙:无每流状态,并允许外部直接连入。防火墙是第 7 节建议另做的功能。本文没有重读 RFC 6092。