RFC8926:Geneve: Generic Network Virtualization Encapsulation,November 2020
摘要
网络虚拟化涉及具有各种功能的设备的协作,如软件和硬件隧道端点、传输结构和集中控制集群。由于它们在将系统的不同元素联系在一起方面的作用,隧道的要求受到所有这些组件的影响。因此,如果要跟上技术的发展,灵活性是隧道协议最重要的方面。本文档介绍了Geneve,这是一种封装协议,旨在识别和适应这些不断变化的功能和需求。
关于本备忘录
这是一份互联网标准跟踪文件。
本文档是互联网工程任务组(IETF)的成果。它代表了IETF社区的共识。它已接受公众审查,并已被互联网工程指导小组(IESG)批准出版。有关互联网标准的更多信息,请参阅RFC 7841的第2节。
有关本文档的当前状态、任何勘误表以及如何提供反馈的信息,请访问https://www.rfc-editor.org/info/rfc8926.
版权声明
版权所有(c)2020 IETF Trust和文件作者。保留所有权利。
本文件受BCP 78和IETF信托有关IETF文件的法律规定的约束(https://trustee.ietf.org/license-info)自本文件发布之日起生效。请仔细阅读这些文件,因为它们描述了您对本文件的权利和限制。从本文档中提取的代码组件必须包含《信托法律条款》第4.e节所述的简化BSD许可证文本,并且按照简化BSD许可证所述提供,不提供任何保证。
1、导言
长期以来,网络一直以各种隧道、标记和其他封装机制为特征。然而,网络虚拟化的出现引起了新的兴趣,并相应地增加了新协议的引入。这个领域中的大量协议——例如,从VLAN[IEEE802.1Q_2018]和MPLS[RFC3031]到最近的VXLAN(虚拟可扩展局域网)[RFC7348]和NVGRE(使用通用路由封装的网络虚拟化)[RFC7637]——经常引发人们对新封装格式的需求的质疑,尤其是网络虚拟化导致了它们的激增。请注意,上述协议列表并非详尽无遗。
虽然许多封装协议试图简单地划分underlay网络或桥接两个域,但网络虚拟化将传输网络视为在分布式系统的多个组件之间提供连接。在许多方面,该系统类似于机箱交换机,Underlay IP网络作为线路卡在边缘扮演背板和隧道端点的角色。从这个角度来看,对隧道协议的要求在所需元数据的数量和传输节点的作用方面存在显著差异。
“VL2:可扩展和灵活的数据中心网络”[VL2]和“NVO3数据平面要求”[NVO3-DATAPLANE]等工作描述了数据平面必须具备的一些属性,以支持网络虚拟化。然而,一个额外的定义要求是需要将元数据(例如系统状态)与分组数据一起携带;元数据的示例用例如下。使用一些元数据当然不是一个陌生的概念——几乎所有用于网络虚拟化的协议都有至少24位的标识符空间,作为在租户之间进行分区的一种方式。这通常被描述为克服12位VLAN的限制;当在该上下文或任何上下文中看到它是一个真正的租户标识符时,1600万个可能的条目是一个很大的数字。然而,现实情况是,元数据并不是专门用于识别租户的,对其他信息进行编码很快就会挤满空间。事实上,与用于在机箱交换机上的线卡之间交换元数据的标签相比,24位标识符开始看起来很小。这种元数据的用途几乎无穷无尽,从为简单的安全策略存储输入端口标识符,到为终止和重新封装Geneve流量的高级中间设备应用程序发送基于服务的上下文。
现有的隧道协议都试图解决这些新要求的不同方面,但通过改变控制平面实现和改进,这些协议很快就会过时。此外,软件和硬件组件以及控制器都有不同的优势和进化速度——这一事实应该被视为一种优势,而不是一种责任或限制。本文档描述了Geneve,这是一种协议,旨在通过为网络虚拟化提供隧道框架来避免这些问题,而不是对整个系统进行规定。
1.1、需求语言
本文档中的关键字“必须”、“禁止”、“需要”、“应”、“不应”、“宜”、“不宜”、“推荐”、“可以”和“可选”应按照BCP 14[RFC2119][RFC8174]中的描述进行解释,当且仅当它们以大写字母出现时,如图所示。
1.2、术语
三层网络虚拟化(Network Virtualization over Layer,NVO3)框架(NVO3:数据中心网络3层虚拟化架构)[RFC7365]定义了网络虚拟化中常用的许多概念。此外,以下术语在本文档中具有特殊意义:
校验和卸载:由许多NIC(网络接口控制器)实现的优化,可以在传输和接收时分别在硬件中计算和验证上层协议校验和。这通常包括IP和TCP/UDP校验和,否则这些校验和将由软件中的协议栈计算。
Clos网络:一种组合比单个交换机更大的网络结构的技术,同时保持连接点之间的无阻塞带宽。ECMP用于在构成结构的多个链路和交换机之间划分流量。有时被称为“leaf and spine”或“fat tree”拓扑。
ECMP:等成本多路径。一种路由机制,通过散列数据包报头从多个最佳下一跳路径中进行选择,以便更好地利用网络带宽,同时避免流中数据包的重新排序。
Geneve:通用网络虚拟化封装。本文档中描述的隧道协议。
LRO:Large Receive Offload,大型接收卸载。LSO的接收端等效功能,其中多个协议段(主要是TCP)被合并为更大的数据单元。
LSO:Large Segmentation Offload,大分段卸载。许多商用NIC提供的一种功能,允许将大于MTU的数据单元传递给NIC以提高性能,NIC负责创建大小小于或等于MTU的较小段,并使用正确的协议头。当具体指TCP/IP时,此功能通常被称为TSO(TCP分段卸载)。
Middlebox:在本文档中,术语“Middlebox”是指通常实现隧道端点功能、终止和重新封装Geneve流量的网络服务功能或服务插入设备。
NIC:Network Interface Controller,网络接口控制器。也称为“网络接口卡”或“网络适配器”。NIC可以是隧道端点或传输设备的一部分,可以处理或帮助处理Geneve数据包。
传输设备:构成underlay网络一部分的隧道路径上的转发元件(如路由器或交换机)。传输设备可能能够理解Geneve数据包格式,但不会发起或终止Geneve数据包。
隧道端点:对Geneve报文头中的数据包(如以太网帧或IP数据报)执行封装和解封装的组件。作为任何隧道元数据的最终消费者,隧道端点对解析和解释隧道头的要求最高。隧道端点可以由软件或硬件实现或两者的组合组成。隧道端点通常是网络虚拟化边缘(Network Virtualization Edge,NVE)的一个组件,但也可能存在于中间设备或构成NVO3网络的其他元素中。
VM:Virtual Machine,虚拟机。
2、设计要求
Geneve旨在支持数据中心环境的网络虚拟化用例。在这些情况下,通常会建立隧道,作为驻留在管理程序、物理交换机或中间设备或其他设备中的虚拟交换机之间的背板。任意IP网络都可以用作underlay,尽管使用ECMP链路组成的Clos网络是一种常见的选择,可以在所有连接点上提供一致的二等分带宽。NVO3框架[RFC7365]中描述了IP网络上网络虚拟化overlay的许多概念。图1显示了一个管理程序的示例,一个用于连接物理服务器的机架报文头交换机,以及一个使用Geneve隧道通过简化的Clos网络连接的WAN上行链路。这些隧道用于封装和转发来自连接组件的帧,如VM或物理链路。
图1:Geneve部署示例
为了支持网络虚拟化的需求,隧道协议应该能够利用underlay和overlay网络中每种设备的不同(和不断发展)功能。这导致对数据平面隧道协议提出了以下要求:
*数据平面具有通用性和可扩展性,足以支持当前和未来的控制平面。
*隧道组件可以在硬件和软件中有效地实现,而不会将功能限制在最低的公分母上。
*保持了现有IP结构的高性能。
这些要求将在以下小节中进一步描述。
2.1、控制平面独立性
尽管一些用于网络虚拟化的协议已经将控制平面作为隧道格式规范的一部分(最值得注意的是,VXLAN[RFC7348]规定了基于组播学习的控制平面),但这些规范在很大程度上被视为仅描述数据格式。VXLAN数据包格式实际上已经在其上构建了各种各样的控制平面。
确定数据格式有一个明显的优势:大多数协议只是表面上的不同,重复工作几乎没有什么优势。然而,对于控制平面来说,情况并非如此,因为控制平面在非常基本的方面是多样化的。鉴于需求、目标和部署场景的多样性,标准化的情况也不太清楚。
由于这一现实,Geneve是一种纯隧道格式规范,能够通过明确不选择任何一个来满足许多控制平面的需求。这同时促进了共享数据格式,并降低了未来控制平面增强导致过时的可能性。
2.2、数据平面可扩展性
要实现有效支持当前和未来控制平面所需的灵活性,需要一个选项基础设施,以允许定义、部署新的元数据类型,并最终确定或退役。选项还允许通过鼓励每个供应商的核心专业领域的独立开发来实现产品差异化,从而加快整体发展速度。到目前为止,实现选项的最常见机制是类型长度值(Type-Length-Value,TLV)格式。
应该指出的是,虽然选项可用于支持非线速控制数据包,但它们在数据包中对于隔离和引导转发同样重要。(例如,前面给出的关于基于输入端口的安全策略和终止/重新封装服务插入的示例都需要在数据包上放置标签。)因此,虽然为了简化数据路径,将可扩展性限制为仅控制数据包是可取的,但这不符合设计要求。
2.2.1、高效实施
软件灵活性和硬件性能之间经常存在难以解决的冲突。对于给定的一组功能,显然需要最大限度地提高性能。然而,这并不意味着今天不能以所需速度运行的新功能应该被禁止。因此,为了使协议被认为是可有效实现的,它应该具有一组可以跨平台合理处理的通用功能,以及一种在适当情况下处理更高级功能的优雅机制。
在协议中使用可变长度报头和选项通常会引发关于协议是否真的能在硬件中有效实现的问题。为了在Geneve的背景下回答这个问题,重要的是首先将“硬件”分为两类:隧道端点和传输设备。
隧道端点必须能够解析可变长度报文头,包括任何选项,并采取行动。由于这些设备积极参与该协议,因此它们受Geneve的影响最大。然而,由于隧道端点是数据的最终消费者,发射器可以根据接收器的能力定制其输出。
转发设备可能能够解释这些选项;然而,作为非终端设备,传输设备不会发起或终止Geneve数据包。因此,它们不得修改Geneve报文头,也不得插入或删除选项,因为这是隧道端点的责任。选项(如果存在于数据包中)必须仅由隧道端点生成和终止。转发设备参与解释选项是可选的。
此外,隧道端点或传输设备都可以使用NIC的卸载功能,如校验和卸载,来提高Geneve数据包处理的性能。Geneve可变长度报文头的存在不应阻止隧道端点和传输设备使用此类卸载功能。
2.3、标准IP结构的使用
IP显然巩固了其作为主要传输机制的地位,随着时间的推移,许多技术已经发展到使其强大、高效和廉价。因此,使用IP结构作为Geneve的传输网络是很自然的。幸运的是,使用IP封装和寻址足以实现通过标准交换和路由将数据包传递到网络中正确点的主要目标。
此外,几乎所有的underlay结构都旨在利用流量中的并行性,在多个链路上分散负载,而不会在单个流中引入重新排序。这些ECMP技术通常涉及解析和散列数据包中的地址和端口号,以选择出站链路。然而,使用隧道通常会导致ECMP性能不佳,因为如果没有对协议的额外了解,封装的流量在设计上就隐藏在结构中,只有隧道端点地址可用于哈希。
由于Geneve希望在这些现有结构上表现良好,因此有必要在隧道报头中暴露封装数据包的熵。最常见的技术是使用UDP源端口,这将在第3.3节中进一步讨论。
3、Geneve封装细节
Geneve数据包格式由一个封装在IPv4或IPv6上的UDP中的紧凑隧道头组成。一个小的固定隧道报文头提供控制信息以及基本级别的功能和互操作性,重点是简单性。然后,这个报文头后面是一组可变长度选项,以允许未来的创新。最后,有效载荷由指定类型的协议数据单元组成,例如以太网帧。第3.1节和第3.2节说明了通过以太网传输的Geneve数据包格式(例如)以及以太网有效载荷。
3.1、IPv4上的Geneve数据包格式
外层以太网报文头:
外层IPv4报文头:
外层UDP报文头:
Geneve报文头:
内层以太网报文头(示例载荷):
封装载荷:
帧校验和:
图2:IPv4上的通用数据包格式
3.2、IPv6上的通用数据包格式
外层以太网报文头:
外层IPv6报文头:
外层UDP报文头:
Geneve报文头:
内层以太网报文头(示例载荷):
封装载荷:
帧校验和:
图3:IPv6上的通用数据包格式
3.3、UDP报头
除了为执行ECMP的路由器提供熵之外,封装UDP(用户数据报协议:RFC768-User Datagram Protocol)[RFC0768]报头的使用还遵循以太网和IP的无连接语义。因此,报文头字段的解释如下:
源端口:由发起隧道端点选择的源端口。对于属于单个封装流的所有数据包,此源端口应该相同,以防止因使用不同路径而重新排序。为了促进流在多个链路上的均匀分布,应该使用封装的数据包报头的哈希来计算源端口,例如使用传统的5元组。由于端口表示流标识符而不是真正的UDP连接,因此可以使用整个16位范围来最大化熵。除了设置源端口外,对于IPv6,流标签还可以用于提供熵。有关在隧道用例中使用IPv6流标签的示例,请参阅[RFC6438]。
如果Geneve流量与同一IP地址上的其他UDP侦听器共享,隧道端点应实现一种机制,以确保由网络错误引起的ICMP返回流量被定向到正确的侦听器。这种机制的定义超出了本文的范围。
目的端口:IANA已将端口6081指定为Geneve的固定已知目的端口。虽然默认情况下应该使用众所周知的值,但建议实现使其可配置。所选端口用于标识Geneve数据包,不得像TCP那样对连接的不同端进行反转。控制平面有责任管理分配端口的任何重新配置及其由相应设备的解释。控制平面的定义超出了本文档的范围。
UDP长度:包括UDP报头的UDP数据包的长度。
UDP校验和:为了保护Geneve报文头、选项和有效载荷免受潜在数据损坏,当Geneve封装在IPv4中时,应按照[RFC0768]和[RFC1122]中的规定生成UDP校验和。为了保护IP报文头、Geneve报文头、选项和有效载荷免受潜在的数据损坏,当Geneve封装在IPv6中时,默认情况下必须按照[RFC0768]和[RFC8200]中的规定生成UDP校验和,但下一段中概述的某些条件除外。在接收到具有非零UDP校验和的此类数据包时,接收隧道端点必须验证校验和。如果校验和不正确,则必须丢弃数据包;否则,必须接受该数据包进行解封装。
在某些条件下,对于同时封装在IPv4和IPv6中的数据包,UDP校验和在传输时可能会设置为零[RFC8200]。有关在IPv4和IPv6中使用零UDP校验和时适用的其他要求,请参阅第4.3节。禁用UDP校验和是一个操作考虑因素,应考虑到数据包损坏的风险和影响。
3.4、隧道报文头字段
Ver(2位):当前版本号为0。必须丢弃版本未知的隧道端点接收到的数据包。解释具有未知版本号的Geneve数据包的传输设备必须将其视为具有未知有效载荷的UDP数据包。
Opt-Len(6位):选项字段的长度,以4字节的倍数表示,不包括8字节的固定隧道头。这导致Geneve报文头的最小总大小为8字节,最大为260字节。可以使用与基本Geneve报文头末尾的偏移量来找到有效载荷报文头的开头。
传输设备必须保持一致的转发行为,无论“Opt-Len”的值如何,包括ECMP链路选择。
O(1位):控制数据包。此数据包包含控制消息。控制消息在隧道端点之间发送。隧道端点不得转发有效载荷,传输设备不得尝试解释它。由于控制消息的频率较低,建议隧道端点将这些数据包定向到高优先级控制队列(例如,将数据包从转发专用集成电路(Application-Specific Integrated Circuit,ASIC)定向到通用CPU,或在NIC上分离出控制流量)。传输设备不得基于此位更改转发行为,例如ECMP链路选择。
C(1位):存在关键选项。一个或多个选项设置了关键位(见第3.5节)。如果设置了此位,则隧道端点必须解析选项列表以解释任何关键选项。在不支持选项解析的隧道端点上,必须根据基报文头中的“C”位丢弃数据包。如果未设置该位,隧道端点可能会使用“Opt-Len”剥离所有选项,并转发解封装的数据包。传输设备不得基于此位丢弃数据包。
Rsvd.(6位):保留字段,传输时必须为零,接收时必须忽略。
协议类型(16位):Geneve报文头后出现的协议数据单元的类型。这遵循Ethertype[ETYPES]约定,以太网本身由值0x6558表示。
虚拟网络标识符(VNI)(24位):虚拟网络中唯一元素的标识符。在许多情况下,这可能表示L2段;然而,控制平面定义了解封装数据包的转发语义。VNI可以用作ECMP转发决策的一部分,也可以用作在跨CPU负载平衡时区分封装数据包中包含的重叠地址空间的机制。
保留(8位):保留字段,传输时必须为零,接收时忽略。
3.5、隧道选项
图4:Geneve选项
基本Geneve报文头后面是Type-Length-Value格式的零个或多个选项。每个选项由一个4字节的选项头和根据类型解释的可变数量的选项数据组成。
选项类(16位):“Type”字段的命名空间。IANA创建了一个“Geneve Option Class”注册表,为有兴趣创建选项类型的组织、技术和供应商分配标识符。每个组织可以独立分配类型,以允许实验和快速创新。预计随着时间的推移,某些选项将变得众所周知,给定的实现可能会使用来自各种来源的选项类型。此外,IANA还保留了特定的范围供IETF审查和实验使用(见第7节)。
类型(8位):表示此选项中包含的数据格式的类型。选项主要旨在鼓励未来的可扩展性和创新,这些选项的标准化形式将在单独的文档中定义。
选项类型的高位表示这是一个关键选项。如果接收隧道端点无法识别该选项并且设置了此位,则必须丢弃数据包。如果在任何选项中设置了此位,则Geneve基头中的“C”位也必须设置。传输设备不得基于此位丢弃数据包。下图显示了“类型”字段中“C”位的位置:
图5:“类型”字段中的“C”位
丢弃具有“C”位集的未知选项的数据包的要求适用于整个隧道端点系统,而不是实现的特定组件。例如,在由转发ASIC和通用CPU组成的系统中,这并不意味着必须在ASIC中丢弃数据包。一种实现方式可以使用速率受限的控制信道将数据包发送到CPU,以进行慢速路径异常处理。
R(3位):保留供将来使用的选项控制标志。这些比特在传输时必须为零,在接收时必须忽略。
长度(5位):选项的长度,以4字节倍数表示,不包括选项头。每个选项的总长度可以在4到128个字节之间。“Length”字段中的值为0意味着该选项只有一个选项头,没有选项数据。如果处理选项的隧道端点接收到所有选项的总长度不等于基报文头中的“Opt-Len”的数据包,则这些数据包无效,必须静默丢弃。
可变长度选项数据:根据“类型”解释的选项数据。
3.5.1、选项处理
Geneve选项旨在由隧道端点发起和处理。然而,选项可能由隧道沿线的转发设备来解释。不解释Geneve报头(可能包括也可能不包括选项)的传输设备必须将Geneve数据包作为任何其他UDP数据包处理,并保持一致的转发行为。
在隧道端点中,选项的生成和解释由控制平面决定,这超出了本文的范围。然而,为了确保异构设备之间的互操作性,对选项和处理它们的设备提出了一些要求:
*接收隧道端点必须丢弃包含选项类型中设置了“C”位的未知选项的数据包。相反,传输设备不得因遇到未知选项(包括设置了“C”位的选项)而丢弃数据包。
*转发设备不得修改选项的内容及其顺序。
*如果隧道端点收到的Geneve数据包的“Opt-Len”(所有选项的总长度)超过了隧道端点的选项处理能力,则隧道端点必须丢弃此类数据包。在这种情况下,实现可能会对控制平面产生异常。控制平面有责任确保通信对等隧道端点具有处理选项总长度的处理能力。控制平面的定义超出了本文档的范围。
在设计Geneve选项时,重要的是要考虑该选项在未来将如何演变。一旦定义了一个选项,就可以合理地预期实现可能会依赖于特定的行为。因此,必须提前仔细描述未来任何变化的范围。
从架构上讲,选项是自我描述和独立的。这实现了选项处理的并行性,并降低了实现的复杂性。但是,控制平面可能会施加某些排序限制,如第4.5.1节所述。
更改定义为特定大小的选项的长度可能会导致意外的重大互操作性问题。特定选项被指定为具有固定长度(恒定)或可变长度(可能随时间或不同用例而变化)。此属性是选项定义的一部分,由“类型”表示。对于固定长度的选项,一些实现可能会选择忽略选项头中的“length”字段,而是根据与类型相关的已知长度进行解析。在这种情况下,重新定义长度不仅会影响所讨论选项的解析,还会影响后续的任何选项。因此,被定义为固定长度的选项不得被重新定义为不同的长度。相反,应该分配一个新的“类型”。选项类型的实际定义超出了本文档的范围。选项类型及其解释应由拥有选项类的实体定义。
选项可由NIC硬件利用卸载(如LSO和LRO)进行处理,如第4.6节所述。应仔细考虑第4.6节中概述的卸载能力如何影响选项的设计。
4、实施和部署考虑因素
4.1、适用性声明
Geneve是一种基于UDP的网络虚拟化overlay封装协议,旨在通过现有IP网络在NVE之间建立隧道。它适用于公共或私有数据中心环境,用于在现有Underlay IP网络上部署多租户overlay网络。
作为一种基于UDP的协议,Geneve遵守[RFC8085]中规定的UDP使用指南。这些指南的适用性取决于Underlay IP网络和Geneve有效载荷协议的性质(例如TCP/IP、IP/以太网)。
Geneve旨在部署在由单个运营商或相邻的一组合作网络运营商运营的数据中心网络环境中,该环境符合[RFC8085]中受控环境的定义。受控环境中的网络可以在特定条件下运行,而在一般的互联网中,这是不可能的。因此,在受控环境下运行的隧道协议的要求可能比一般互联网的要求限制性更小。
在本文档中,流量管理受控环境(TMCE)被定义为一种IP网络,该网络经过流量工程和/或其他管理(例如,通过使用流量速率限制器)以避免拥塞。TMCE的概念在[RFC8086]中进行了概述。第4.1节至第4.3节中的大部分文本基于适用于Geneve的[RFC8086]。
运营商有责任确保遵守本节中适用于其Geneve部署的指导方针/要求。
4.2、拥塞控制功能
Geneve本身不提供拥塞控制功能,而是依赖有效载荷协议流量进行拥塞控制。因此,Geneve必须用于拥堵控制的交通或TMCE内,以避免拥堵。TMCE的运营商可以通过仔细配置其网络、限制用户数据流量和根据路径容量管理流量工程来避免拥塞。
4.3、UDP校验和
当通过IPv4传输时,外部UDP校验和应与Geneve一起使用;这是为了在数据损坏的情况下为Geneve报文头、选项和有效载荷提供完整性(例如,避免将有效载荷错误传递给不同的租户系统)。UDP校验和提供了一种统计保证,即有效载荷在传输过程中没有损坏。从编码或加密的角度来看,这些完整性检查并不强,也不是为了检测物理层错误或恶意修改数据报而设计的(见[RFC8085]第3.4节)。在存在此类风险的部署中,运营商应使用其他数据完整性机制,如IPsec提供的机制(见第6.2节)。
如果Geneve数据包完整性由其他数据完整性机制(如IPsec或其他校验和)提供,或者满足第4.3.1节中的条件(a、b或c)之一,则操作员可以选择禁用UDP校验和并使用零UDP校验和。
默认情况下,当Geneve通过IPv6传输时,必须使用UDP校验和。如果满足第4.3.1节中的其他要求,则可以将隧道端点配置为使用零UDP校验和。
4.3.1、IPv6下的零UDP校验和处理
当Geneve在IPv6上使用时,UDP校验和用于保护IPv6报文头、UDP报文头和Geneve报文头、选项和有效载荷免受潜在数据损坏。因此,默认情况下,Geneve在通过IPv6传输时必须使用UDP校验和。如果满足以下条件之一,操作员可以选择在第4.1节所述的TMCE中配置零UDP校验和。
a.众所周知,数据包损坏的可能性极低(可能是基于对其underlay网络中设备类型的了解),运营商愿意冒未被发现的数据包损坏风险。
b.通过观测测量(可能是通过使用非零校验和的历史或当前流量)判断,数据包损坏程度相当低,运营商愿意冒未被检测到的损坏风险。
c.Geneve有效载荷携带的应用程序能够容忍错误传递或损坏的数据包(可能是通过更高层的校验和验证和/或通过重传的可靠性)。
此外,使用零UDP校验和的Geneve隧道实现必须满足以下要求:
1.在IPv6上使用UDP校验和必须是所有Geneve隧道的默认配置。
2.如果Geneve在IPv6上使用零UDP校验和,那么这样的隧道端点实现必须满足[RFC6936]第4节中规定的所有要求和[RFC6936]第5节中指定的要求1,因为它与Geneve有关。
3.解封装隧道的Geneve隧道端点应检查源和目标IPv6地址对于配置为接收零UDP校验和的Geneve通道是否有效,并丢弃此类检查失败的其他数据包。
4.封装隧道的Geneve隧道端点可以为使用零UDP校验和模式的每个Geneve隧道使用不同的IPv6源地址,以加强解封装器对IPv6源地址的检查(即,同一IPv6源地址不得与多个IPv6目的地址一起使用,无论该目的地址是单播还是组播地址)。当这不可能时,建议尽可能少地将每个源地址用于使用零UDP校验和的Geneve隧道。
请注意,对于要求3和4,只有当接收隧道端点知道封装隧道端点正在应用所指示的行为时,它才能应用这些检查。获得这种带外知识的一种可能性是通过控制平面的信令。控制平面的定义超出了本文档的范围。
5.应采取措施防止UDP校验和为零的IPv6上的Geneve流量逃逸到普通互联网中。此类措施的示例包括在Geneve网络的网关或边缘使用数据包过滤器和/或保持Geneve网络与承载一般互联网流量的网络的逻辑或物理分离。
上述要求不会改变[RFC8200]或[RFC6936]中规定的要求。
除了目标IPv6地址之外,使用源IPv6地址,以及建议在Geneve隧道之间不重复使用源IPv6位址,共同为IPv6报文头没有UDP校验和overlay提供了一些缓解措施。满足本节开头列出的三个条件中的至少一个的流量管理受控环境提供了额外的保证。
4.4、Geneve在IP中的封装
作为一种基于IP的隧道协议,Geneve与现有协议共享许多属性和技术。其中一些的应用将得到更详细的描述,尽管一般来说,适用于IP层或IP隧道的大多数概念通常也在Geneve的上下文中起作用。
4.4.1、IP分段化
建议使用路径MTU发现(IPV6 的路径 MTU 发现)(见[RFC1191]和[RFC8201])来防止或尽量减少分段。在传输网络上使用路径MTU发现为封装隧道端点提供了有关链路的软状态信息,根据其在虚拟化网络中的角色,该信息可用于防止或最小化分段。NVE可以保持这种状态(与隧道端点关联的隧道链路的MTU大小),因此,如果租户系统发送的大数据包在封装时超过了隧道链路的MTU大小,隧道端点可以丢弃这些数据包并向租户系统发送异常消息。如果隧道端点与路由或转发功能相关联和/或具有发送ICMP消息的能力,则封装隧道端点可以向租户系统发送所需的ICMP分段[RFC0792]或数据包太大[RFC4443]消息。在确定隧道链路的MTU大小时,必须假设选项的最大长度,因为每个数据包的选项可能会有所不同。[RFC3985]第5.3节提供了处理类似overlay封装服务(如伪线仿真边缘到边缘(PWE3))中分段的建议和指导。
请注意,某些实现可能无法支持IP报文头的分段或其他不太常见的功能,如选项和扩展报文头。[INTAREA-TUNNELS]第4.2节概述了IP隧道和ICMP消息使用中与MTU大小和分段相关的一些问题。
4.4.2、DSCP、ECN和TTL
在Geneve中封装IP(包括通过以太网)数据包时,在传输时将差分服务码点(Differentiated Services Code Point,DSCP)和显式拥塞通知(Explicit Congestion Notification,ECN)比特从内部报头传播到隧道,在接收时将其反向传播,需要考虑几个因素。
[RFC2983]为在内部和外部IP报头之间映射DSCP提供了指导。网络虚拟化通常与所描述的管道模型更为一致,其中隧道报文头上的DSCP值是基于策略设置的(该策略可以是固定值,一个基于内部流量类或其他一些用于对流量进行分组的机制)。统一模型的某些方面(通过在入口和出口处复制,将内部和外部DSCP值视为单个字段)也可能适用,例如基于传输标记在隧道出口处重新标记内部报文头的能力。然而,统一模型在概念上与网络虚拟化不一致,网络虚拟化试图在封装的流量和物理网络之间提供强有力的隔离。
[RFC6040]描述了在IP隧道上暴露ECN功能并将拥塞标记传播到内部数据包的机制。对于封装在Geneve中的IP数据包,必须遵循此行为。
尽管在隧道传输IP数据包时,统一或管道模型可用于处理TTL(或IPv6情况下的跳数限制),但管道模型与网络虚拟化更一致。[RFC2003]提供了处理内部IP报头和外部IP隧道之间TTL的指导;此模型类似于Pipe模型,建议与Geneve一起用于网络虚拟化应用程序。
4.4.3、广播和组播
Geneve隧道可以是两个隧道端点之间的点对点单播,也可以利用广播或组播寻址。在这方面不要求内部和外部寻址匹配。例如,在不支持组播的物理网络中,封装的组播流量可以被复制到多个单播隧道中,或者通过策略转发到单播位置(可能在那里复制)。
对于支持组播的物理网络,可能需要使用此功能来利用封装数据包的硬件复制。在这种情况下,可以在物理网络中分配与租户、封装的组播组或其他因素相对应的组播地址。这些组的分配是控制平面的一个组成部分,因此超出了本文的范围。
当使用物理组播时,具有异构功能的设备可能存在于同一组中。某些选项可能只能由组中的一部分设备解释。其他设备可以安全地忽略这些选项,除非将“C”位设置为将未知选项标记为关键。第3.4节中概述的要求适用于关键选项。
此外,[RFC8293]提供了可用于网络虚拟化overlay网络中的组播处理的各种机制的示例。
4.4.4、单向隧道
一般来说,Geneve隧道是一个单向的概念。IP不是面向连接的协议,两个隧道端点可以使用不同的路径相互通信,也可以让一侧根本不传输任何东西。由于Geneve是一种基于IP的协议,隧道层继承了这些相同的特性。
隧道可以封装一种面向连接的协议,如TCP,并在该层维护会话状态。此外,实现可能会将Geneve隧道建模为连接的双向链路,例如,提供虚拟端口的抽象。在这两种情况下,隧道的双向性都是在更高层处理的,不会影响Geneve本身的运行。
4.5、协议特征约束
Geneve旨在灵活地用于广泛的当前和未来应用。因此,可以对元数据的使用或协议的其他方面施加某些约束,以便针对特定用例进行优化。例如,一些应用程序可能会限制支持的选项类型,或强制执行选项的最大数量或长度。其他应用程序可能只处理某些封装的有效载荷类型,如以太网或IP。这些优化可以在全局(整个系统)或本地(例如,仅限于某些类别的设备或网络路径)实现。
这些约束可以通过控制平面显式地或根据应用程序的性质隐式地传达给隧道端点。由于Geneve被定义为与控制平面无关的数据平面协议,因此此类机制的定义超出了本文的范围。
4.5.1、约束选项
虽然Geneve选项很灵活,但控制平面可以限制选项TLV的数量以及隧道端点之间TLV的顺序和大小,使软件或硬件中的数据平面实现更容易处理(见[NVO3-ENCAP])。例如,可能有一些关键信息,如安全哈希,必须按照一定的顺序进行处理,以提供最低的延迟,或者可能有其他情况,由于协议语义,选项必须按照给定的顺序处理。
控制平面可以协商选项TLV的子集和某些TLV排序;它还可以限制数据包中存在的选项TLV的总数,例如,以容纳能够处理较少选项的硬件。因此,控制平面需要能够描述支持的TLV子集及其到隧道端点的顺序。在没有控制平面的情况下,可以使用替代配置机制来实现这一目的。这些机制超出了本文的范围。
4.6、NIC卸载
现代NIC目前提供各种卸载,以实现数据包的高效处理。许多卸载的实现只需要封装的数据包易于解析(例如,校验和卸载)。然而,LSO和LRO等优化涉及对选项本身的一些处理,因为它们必须在多个数据包中复制/合并。在这些情况下,最好不需要更改卸载逻辑来处理新选项的引入。为了实现这一点,对选项的定义施加了一些限制,以允许简单的处理规则:
*执行LSO时,NIC必须将整个Geneve报文头和所有选项(包括设备未知的选项)复制到每个结果段上,除非选项允许异常。相反,在执行LRO时,NIC可能会假设选项(包括未知选项)的二进制比较足以确保相等,并可能合并具有相等Geneve报文头的数据包。
*在卸载处理过程中,包括为了LRO而合并数据包时,不得对选项进行重新排序。
*执行卸载的NIC不得丢弃具有未知选项的数据包,包括标记为关键的数据包(除非明确配置为这样做)。
没有要求给定的Geneve实现使用上述示例中列出的卸载。然而,由于这些卸载目前广泛部署在商用NIC中,本文所述的规则旨在有效处理各种设备的当前和未来选项。
4.7、内部VLAN处理
Geneve能够封装各种协议;因此,给定的实现可能只支持一小部分可能性。然而,随着以太网的广泛部署,描述封装以太网帧内VLAN的行为是有用的。
与任何协议一样,对内部VLAN报文头的支持是可选的。在许多情况下,出于安全或实施考虑,可能不允许使用封装的VLAN。然而,在其他情况下,跨Geneve隧道中继VLAN帧可以证明是有用的。因此,在隧道端点进入或离开时对内部VLAN标签的处理基于隧道端点和/或控制平面的配置,并且没有明确定义为数据格式的一部分。
5、过渡考虑因素
仅从数据平面来看,Geneve与现有的IP网络兼容,因为它对大多数设备来说都是UDP数据包。然而,由于网络虚拟化环境中已经部署了许多隧道协议,因此存在过渡和共存的实际问题。
由于Geneve建立在用于网络虚拟化的最常见协议(VXLAN和NVGRE)提供的基础数据平面功能之上,因此将现有的控制平面移植到其上运行应该很简单,只需付出最小的努力。由于新旧数据包格式都支持相同的功能集,因此不需要进行硬转换;直接相互通信的隧道端点可以使用任何通用协议,即使在单个整体系统内也可能不同。由于传输设备主要基于IP报头转发数据包,因此所有协议似乎都是相似的,这些设备不会引入额外的互操作性问题。
为了协助这一过渡,强烈建议实现支持Geneve和现有隧道协议的同时操作,因为预计单个节点与其他节点的混合通信是常见的。最终,旧的协议可能会被淘汰,因为它们不再使用。
6、安全注意事项
由于Geneve被封装在UDP/IP数据包中,因此它没有任何固有的安全机制。因此,可以访问传输IP数据包的underlay网络的攻击者有能力窥探、更改或注入数据包。受损的隧道端点或传输设备也可能伪造隧道报头中的标识符,以访问其他租户拥有的网络。
在特定的安全域内,例如由单个服务提供商运营的数据中心,最常见和性能最高的安全机制是隔离受信任的组件。隧道流量可以通过单独的VLAN承载,并在任何不受信任的边界进行过滤。
当穿越不受信任的链接时,如通用互联网,应使用IPsec[RFC4301]等VPN技术对作为Geneve封装一部分形成的IP数据包进行身份验证和/或加密(见第6.1.1节)。
Geneve不会影响封装数据包的安全性。根据BCP 72[RFC3552]的指导方针,以下部分描述了可能适用于Geneve部署的潜在安全风险以及减轻此类风险的方法。还应注意的是,并非所有此类风险都适用于所有Geneve部署场景,即只有一个子集可能适用于某些部署。运营商必须根据其网络环境进行评估,确定适用于其特定环境的风险,并在适用的情况下使用适当的缓解方法。
6.1、机密性
Geneve是一种网络虚拟化overlay封装协议,旨在通过现有IP网络在NVE之间建立隧道。它可用于在公共或私有数据中心的现有Underlay IP网络上部署多租户overlay网络。overlay服务通常由服务提供商提供,例如云服务提供商或私有数据中心运营商。这可能是也可能不是与参考底图服务提供程序相同的提供程序。由于这种环境中多租户的性质,租户系统可能期望数据机密性,以确保其数据包数据在传输过程中不会被篡改(即主动攻击),也不会成为未经授权的监控目标(即被动攻击),例如被其他租户系统或underlay服务提供商篡改。数据中心内的受损网络节点或传输设备可以被动地监控NVE之间的Geneve数据包数据,或路由流量以进行进一步检查。租户可能希望overlay服务提供商提供数据机密性作为服务的一部分,或者租户可能会带来自己的数据机密性机制,如IPsec或TLS,以保护其租户系统之间的端到端数据。在underlay提供程序与overlay提供程序不同的情况下,overlay提供程序应提供加密保护,以确保有效载荷不会暴露在underlay。
如果运营商根据其风险分析确定其环境中需要数据机密性,例如在多租户环境中,则应使用加密机制对NVE之间的租户数据进行端到端加密。NVE可以使用现有的成熟加密机制,如IPsec、DTLS等。
6.1.1、数据中心间流量
客户驻地(私有数据中心)中的租户系统可能希望连接到公共云数据中心中租户overlay网络上的租户系统,或者租户可能希望其租户系统位于多个地理位置分离的数据中心以实现高可用性。在穿越公共网络时,应保护跨这种分离网络的租户系统之间的Geneve数据流量免受威胁。任何离开运营商安全域之外的数据中心网络的Geneve overlay数据都应该通过IPsec或其他VPN技术等加密机制进行保护,以保护NVE之间在不受信任的网络链路上地理隔离时的通信。数据中心之间采用的数据保护机制的规范超出了本文档的范围。
第4节中描述的关于受控环境的原则仍然适用于本节中概述的地理上分离的数据中心使用。
6.2、数据完整性
Geneve封装用于NVE之间,以在现有的Underlay IP网络上建立overlay隧道。在多租户数据中心中,流氓或受感染的租户系统可能会尝试发起被动攻击,如监视其他租户的流量,或主动攻击,如试图将未经授权的Geneve封装流量(如欺骗、重放等)注入网络。为了防止此类攻击,NVE不得将Geneve数据包传播到NVE之外的租户系统,并应采用数据包过滤机制,以免在不同租户网络中的租户系统之间转发未经授权的流量。NVE不得将来自租户系统的Geneve数据包解释为要封装的帧以外的数据包。
数据中心内的受损网络节点或传输设备可能会发起主动攻击,试图篡改NVE之间的Geneve数据包。恶意篡改Geneve报文头字段可能会导致来自一个租户的数据包被转发到另一个租户网络。如果运营商确定其环境中存在这种威胁的可能性,运营商可以选择在NVE之间采用数据完整性机制。为了防止此类风险,应在此类环境中使用数据完整性机制来保护Geneve数据包的完整性,包括NVE对之间通信的数据包头、选项和有效载荷。诸如IPsec之类的加密数据保护机制可用于提供数据完整性保护。数据中心运营商可以选择在其underlay网络中部署任何其他适用和支持的数据完整性机制,尽管非加密机制可能无法保护数据包的Geneve部分免受篡改。
6.3、NVE对等体的身份验证
数据中心环境中的流氓网络设备或受感染的NVE可能能够欺骗Geneve数据包,就像它来自合法的NVE一样。为了降低这种风险,运营商应使用IPsec等身份验证机制,以确保Geneve数据包在运营商确定欺骗或流氓设备是潜在威胁的环境中源自预期的NVE对等端。在某些可信环境中,可以使用其他更简单的源检查,如VLAN/MAC/IP地址的入口过滤、反向路径转发检查等,以确保Geneve数据包来自预期的NVE对等端。
6.4、转发设备选项解释
如果数据包中存在选项,则由隧道端点生成和终止。如第2.2.1节所述,转发设备可以解释这些选项。但是,如果数据包在隧道端点到隧道端点之间受到加密保护(例如,通过IPsec),传输设备将无法看到数据包中的Geneve报文头或选项。在这种情况下,传输设备必须像处理任何其他IP数据包一样处理Geneve数据包,并保持一致的转发行为。如果选项由转发设备解释,运营商必须确保转发设备是可信的,不会受到损害。确保这种信任的机制的定义超出了本文的范围。
6.5、组播/广播
在underlay网络不支持IP组播的典型数据中心网络中,可以使用多个单播隧道支持组播。与上述章节所述相同的安全要求可用于保护NVE对等体之间的Geneve通信。如果underlay网络支持IP组播,并且运营商选择将其用于隧道端点之间的组播流量,那么在这种环境中,运营商可以使用数据保护机制,例如具有组播扩展的IPsec[RFC5374],来保护Geneve NVE组之间的多传播流量。
6.6、控制平面通信
[RFC8014]中概述的网络虚拟化机构(Network Virtualization Authority,NVA)可以用作配置和管理Geneve NVE的控制平面。数据中心运营商应使用安全机制来保护NVA和NVE之间的通信,并使用身份验证机制来检测其管理域内的任何流氓或受损的NVE。控制平面通信的数据保护机制或NVA和NVE之间的身份验证机制超出了本文档的范围。
7、IANA注意事项
IANA已在“服务名称和传输协议端口号注册表”[IANA-SN]中分配UDP端口6081作为Geneve的已知目标端口:
服务名称:geneve
传输协议:UDP
受让人:IESG
联系人:IETF Chair
描述:Generic Network Virtualization Encapsulation(Geneve)
参考文献:[RFC8926]
端口号:6081
此外,IANA还为选项类别创建了一个名为“Geneve选项类别”的新子类别。此注册表已放置在IANA协议注册表[IANA-PR]中新的“网络虚拟化overlay(NVO3)”报文头下。“Geneve Option Class”注册表由16位十六进制值以及描述性字符串、受让人/联系信息和引用组成。新注册表的注册规则如下(如[RFC8126]所定义):
表1:Geneve选项类注册表范围
8、参考文献
8.1、规范性引用文件
[RFC0768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, DOI 10.17487/RFC0768, August 1980,.
[RFC0792] Postel, J., "Internet Control Message Protocol", STD 5, RFC 792, DOI 10.17487/RFC0792, September 1981,.
[RFC1122] Braden, R., Ed., "Requirements for Internet Hosts - Communication Layers", STD 3, RFC 1122, DOI 10.17487/RFC1122, October 1989,.
[RFC1191] Mogul, J. and S. Deering, "Path MTU discovery", RFC 1191, DOI 10.17487/RFC1191, November 1990,.
[RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003, DOI 10.17487/RFC2003, October 1996,.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997,.
[RFC4443] Conta, A., Deering, S., and M. Gupta, Ed., "Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification", STD 89, RFC 4443, DOI 10.17487/RFC4443, March 2006,.
[RFC6040] Briscoe, B., "Tunnelling of Explicit Congestion Notification", RFC 6040, DOI 10.17487/RFC6040, November 2010,.
[RFC6936] Fairhurst, G. and M. Westerlund, "Applicability Statement for the Use of IPv6 UDP Datagrams with Zero Checksums", RFC 6936, DOI 10.17487/RFC6936, April 2013,.
[RFC7365] Lasserre, M., Balus, F., Morin, T., Bitar, N., and Y. Rekhter, "Framework for Data Center (DC) Network Virtualization", RFC 7365, DOI 10.17487/RFC7365, October 2014,.
[RFC8085] Eggert, L., Fairhurst, G., and G. Shepherd, "UDP Usage Guidelines", BCP 145, RFC 8085, DOI 10.17487/RFC8085, March 2017,.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017,.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017,.
[RFC8200] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", STD 86, RFC 8200, DOI 10.17487/RFC8200, July 2017,.
[RFC8201] McCann, J., Deering, S., Mogul, J., and R. Hinden, Ed., "Path MTU Discovery for IP version 6", STD 87, RFC 8201, DOI 10.17487/RFC8201, July 2017,.
8.2、资料性引用
[ETYPES] IANA, "IEEE 802 Numbers",.
[IANA-PR] IANA, "Protocol Registries",.
[IANA-SN] IANA, "Service Name and Transport Protocol Port Number Registry",.
[IEEE.802.1Q_2018] IEEE, "IEEE Standard for Local and Metropolitan Area Networks--Bridges and Bridged Networks", DOI 10.1109/IEEESTD.2018.8403927, IEEE 802.1Q-2018, July 2018,.
[INTAREA-TUNNELS] Touch, J. and M. Townsley, "IP Tunnels in the Internet Architecture", Work in Progress, Internet-Draft, draft-ietf-intarea-tunnels-10, 12 September 2019,.
[NVO3-DATAPLANE] Bitar, N., Lasserre, M., Balus, F., Morin, T., Jin, L., and B. Khasnabish, "NVO3 Data Plane Requirements", Work in Progress, Internet-Draft, draft-ietf-nvo3-dataplane-requirements-03, 15 April 2014,.
[NVO3-ENCAP] Boutros, S., "NVO3 Encapsulation Considerations", Work in Progress, Internet-Draft, draft-ietf-nvo3-encap-05, 17 February 2020,.
[RFC2983] Black, D., "Differentiated Services and Tunnels", RFC 2983, DOI 10.17487/RFC2983, October 2000,.
[RFC3031] Rosen, E., Viswanathan, A., and R. Callon, "Multiprotocol Label Switching Architecture", RFC 3031, DOI 10.17487/RFC3031, January 2001,.
[RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC Text on Security Considerations", BCP 72, RFC 3552, DOI 10.17487/RFC3552, July 2003,.
[RFC3985] Bryant, S., Ed. and P. Pate, Ed., "Pseudo Wire Emulation Edge-to-Edge (PWE3) Architecture", RFC 3985, DOI 10.17487/RFC3985, March 2005,.
[RFC4301] Kent, S. and K. Seo, "Security Architecture for the Internet Protocol", RFC 4301, DOI 10.17487/RFC4301, December 2005,.
[RFC5374] Weis, B., Gross, G., and D. Ignjatic, "Multicast Extensions to the Security Architecture for the Internet Protocol", RFC 5374, DOI 10.17487/RFC5374, November 2008,.
[RFC6438] Carpenter, B. and S. Amante, "Using the IPv6 Flow Label for Equal Cost Multipath Routing and Link Aggregation in Tunnels", RFC 6438, DOI 10.17487/RFC6438, November 2011,.
[RFC7348] Mahalingam, M., Dutt, D., Duda, K., Agarwal, P., Kreeger, L., Sridhar, T., Bursell, M., and C. Wright, "Virtual eXtensible Local Area Network (VXLAN): A Framework for Overlaying Virtualized Layer 2 Networks over Layer 3 Networks", RFC 7348, DOI 10.17487/RFC7348, August 2014,.
[RFC7637] Garg, P., Ed. and Y. Wang, Ed., "NVGRE: Network Virtualization Using Generic Routing Encapsulation", RFC 7637, DOI 10.17487/RFC7637, September 2015,.
[RFC8014] Black, D., Hudson, J., Kreeger, L., Lasserre, M., and T. Narten, "An Architecture for Data-Center Network Virtualization over Layer 3 (NVO3)", RFC 8014, DOI 10.17487/RFC8014, December 2016,.
[RFC8086] Yong, L., Ed., Crabbe, E., Xu, X., and T. Herbert, "GRE-in-UDP Encapsulation", RFC 8086, DOI 10.17487/RFC8086, March 2017,.
[RFC8293] Ghanwani, A., Dunbar, L., McBride, M., Bannai, V., and R. Krishnan, "A Framework for Multicast in Network Virtualization over Layer 3", RFC 8293, DOI 10.17487/RFC8293, January 2018,.
[VL2] "VL2: A Scalable and Flexible Data Center Network", ACM SIGCOMM Computer Communication Review, DOI 10.1145/1594977.1592576, August 2009,.
致谢
作者希望感谢Puneet Agarwal、David Black、Sami Boutros、Scott Bradner、Martín Casado、Alissa Cooper、Roman Danyliw、Bruce Davie、Anoop Ghanwani、Benjamin Kaduk、Suresh Krishnan、Mirja Kühlewind、Barry Leiba、Daniel Migault、Greg Mirksy、Tal Mizrahi、Kathleen Moriarty、Magnus Nyström、Adam Roach、Sabrina Tanamal、Dave Thaler、Eric Vyncke、Magnus Westerlund以及NVO3工作组的许多其他成员的评论、意见和建议。
作者要感谢Sam Aldrin、Alia Atlas、Matthew Bocci、Benson Schliesser和Martin Vigoureux在整个过程中的指导。
***推荐阅读***