6LoWPAN 的话题
撰写于:2016年1月25日
作者:silex Wi-Fi专家
上次,作为 IPv6 规范制定 20 周年的纪念,我(略带毒舌地)谈到了 IPv6 如今的现状与它在制定时所描绘的理想相去甚远,以及以 “面向嵌入式应用的 IPv6 子集规范” 为目标的 TACA 项目的失败。然而,关于 “IPv6 的小型轻量版本” 的话题,正从意想不到的方面逐渐升温。这次,我要讲讲(或许能)支撑 IoT 的一个关键术语 ——6LoWPAN。
什么是6LoWPAN
“6LoWPAN” 这个奇特的名称被认为是 “IPv6 over Low-Power Wireless Personal Area Networks” 的缩写,按照惯例读作 “six lowpan”。这是一项在 2007 年作为 RFC4944 实现标准化的技术规范,其目的是让 IPv6 协议在 IEEE802.15.4 无线 PAN 上运行。
IEEE802.15.4 此前在这个Blog中已经多次被提及,在外界它以 “Zigbee” 而为人所知。然而,“Zigbee” 是涵盖了应用配置文件等在内的产品规格体系的名称,而 802.15.4 是作为在其下层使用的无线标准独立存在的。并且,Zigbee 采用了不使用 TCP/IP 的独特通信体系(NWK/APS),因此可以说 “6LoWPAN” 和 “Zigbee” 远非相同的东西,甚至可以说是在相同的 802.15.4 这一基础之上相互对立的标准(※注)。
※注:不过,Zigbee 联盟也将包括 6LoWPAN 在内的基于 802.15.4 的 IPv6 整套规范定义为 “Zigbee IP(又名 920IP)”,所以并非一定是 “Zigbee 联盟和 6LoWPAN 相互对立”。但是,“所谓的 Zigbee(Zigbee Pro),即使用基于非 IP 的经典 Zigbee 配置文件的设备” 和 “Zigbee IP” 之间没有兼容性和相互连接性,也无法在同一个 PAN 中并存。
6LoWPAN 被创建的原因
TCP/IP 原本就是一种不依赖于特定数据通信方式(链路层)的通信规范。在一般情况下,以太网及其衍生类型(包括 WiFi)被广泛使用,但如果有需要,也可以通过使用串行线路的 SLIP 链路进行连接。而且,就像玩笑式的 RFC 的经典之作 RFC2549《IP over Avian Carriers》中所描述的那样,从 “理论上来说”,把 IP 数据报打印出来绑在信鸽身上进行交换,也能建立连接。在制定 IPv6 规范的时候,其目标同样是仅定义最低限度的 MAC 帧存储格式,就能在多种多样的数据链路层上运行。既然如此,为什么在让 IPv6 在 802.15.4 上运行时,仅仅 “定义 MAC 存储格式” 还不够呢?
最大的原因在于,802.15.4 的 MAC 帧最长仅为 127 字节,长度较短。在 IPv6 中,规定链路层的最短数据长度(minimum MTU)为 1280 字节,若保持 802.15.4 的原始规格,是无法满足 IPv6 的规格要求的。即便设置特例让 IPv6 在 127 字节的帧上运行,又会出现“ 通信効率が悪い”的问题。在 802.15.4 中使用加密的话,有效载荷长度仅有 81 字节,而在这当中如果再加上 40 字节的 IPv6 报头和 8 字节的 UDP 报头,那么剩余的分段长度就只有 33 字节了。实际上,帧长度中的 74% 都被报头占用了(使用 TCP 时情况更糟,会占用 21 字节,即 84%),不管怎么说,这样的效率实在是太低了。
深入到具体实现的细节中,还会出现各种各样的问题。在一般的 TCP/IP 中,MAC 地址和 IP(v6)地址之间的关联是通过广播进行的批量查询(ARP 或者 Multicast Neighbor Solicitiation)来解决的,但是在为了实现省电而将通信定时进行了时钟同步的 802.15.4 中,如果随意大量发送非同步的广播,那么省电的效果就会大打折扣。此外,802.15.4 支持串珠状的网状拓扑结构,而如何在 IP 上实现这一结构也成了一个问题。如果把网状连接点视为 IP 子网边界并对前缀进行分离,那么所有节点都共享相同前缀的链路本地地址(FE80::/10)就无法实现网状网络之间的连接了(※注)。如果把网状网络当作 IP 子网来处理,就必须获取全局 IPv6 地址,并将其设置为包含多级前缀的多网络结构。
※注:在制定 IPv6 的时候,曾定义了站点本地地址(FEC0::/10),想着 “说不定会有这种情况呢”,即可以在本地网络内划分子网。然而,围绕着对它的解释以及存在的意义,在 IETF 内部引发了混乱的讨论,最终在 RFC3879(2004 年)中宣布将其废止。
也就是说,即便直接按照 IPv6 的规范在 802.15.4 的 MAC 层上实现,“从理论上来说应该是可以运行的”,但无论是数据效率还是电力效率都会极其低下,而且为了实现网状连接,获取和管理 IPv6 地址是必不可少的,所以很难将其当作实用产品来使用。可以说,6LoWPAN 就像是作为 “中间件” 介入到 802.15.4 的 MAC 层和 IPv6 层之间,是为了协调理想与现实而制定的规范。
RFC4944
6LoWPAN 的原始规范 RFC4944 有 1684 行,30 页,66K 字节,作为 4000 系列的 RFC,属于非常简短的一类。不过,后来又发布了 RFC6282(报头压缩扩展)和 RFC6775(邻居发现扩展)这两个 RFC 作为追加规范,把这些全部加起来的话,就相当于有 6116 行,数量也相当可观了。另外,作为网状网络控制协议,还定义了 RFC6550 RPL(Routing Protocol for Low-Power and Lossy Networks)(※注),单这一项就有 8796 行,157 页,352K 字节,篇幅相当长。
※注:不过,RFC6550 RPL 归根结底是 “IPv6 的网状网络路由控制协议” 这样的定义,从概念上来说它与 6LoWPAN 并没有直接的依存关系。
为了解决上述问题,6LoWPAN 实现了以下功能。
- 数据包的分割与重组
- 报头压缩
- 支持邻居发现
- 支持网状网络
在 RFC4944/6LoWPAN 的数据包中,MAC 报头和 IPv6 报头之间会插入 6LoWPAN 的报头。6LoWPAN 报头开头的 8 比特是识别码,这个被称为“分发(Dispatch)”,分发最短为 8 比特。不过根据开头比特的模式,除了识别码之外还包含其他信息,根据需要还可能会接着出现可变长度的“报头”。

802.15.4 / 6LoWPAN 帧的结构
请注意,802.15.4 的 MAC 报头结构与 802.3 和 802.11 有很大不同。
MAC 地址可在 64 比特的 EUI-64 格式和 16 比特的简易格式中进行选择,
不存在与 802.3 中 “TYPE” 相当的字段,也不附带 802.2 的 LLC /SNAP。
IPv6 具有特征性的 “链式报头(Next Header)” 结构在 6LoWPAN 中并未被采用。此外,也不存在表示有效载荷的标识符,存在这样一个 “默认规定”,即在 IPv6、HC1 或者 IPHC 分发之后必然会附有有效载荷。从这方面似乎也能隐约看出,追求理想(是不是追求过头了呢?)的 IPv6 与无奈贴合现实而形成的 6LoWPAN 在其形成过程中的差异。
分割和重组
在 6LoWPAN 中,帧的分割与重组是通过名为 “First Fragment “和 “Subsequent Fragments“ 的分发来实现的。数据报的最大长度为 11 比特,即 2K 字节,并附有一个 16 比特的标识符(tag),只有从第二个开始的后续分片才附有 8 比特的偏移量(每个计数单位对应 8 字节,255 乘以 8 得到最大值 2040 字节)。

RFC4944 First Fragment 分发

RFC4944 Subsequent Fragments 分发

RFC2460 IPv6 Fragment Header (比较参考)
与 IPv6 的分片报头(FH)“固定长度 8 字节、标识符为 32 比特、始终带有 13 比特的偏移量且分段最大长度 = 8 字节 ×13 比特 = 64K 字节” 相比,可能会让人觉得 “难道仅仅是为了节省那 3 到 4 个字节就制定了新的规范吗!”。不过,如果是基于 IPv6 的数据包分割,那么第二个、第三个及之后的分片也总是会附有 IPv6 报头。这在未压缩的情况下是 48 字节(IPv6 + FH),即使经过压缩,每个数据包也会消耗大约 10 到 20 字节,这可不是闹着玩的。而与此相对,在 6LoWPAN 的分割与重组中,仅最初的分片带有 IPv6 报头即可,所以在分割与重组时的效率提升幅度超过了 “6LoWPAN 分片报头和 IPv6 分片报头长度的差异”。

6LoWPAN 实现的 IPv6 分割示例
报头压缩
在 RFC4944 中规定了名为 HC1 的报头压缩分发方式,不过后来发布了功能更强大的 RFC6282 IPHC(IPv6 Header Compression),因此 HC1 的规范已被列为 “不被推荐使用” 了。
HC1 是无状态(Stateless)的,它通过在分发中的标志位来指示 “重复的信息” 以及 “在大多数情况下可确定的” 信息,从而将这些信息省略掉。所谓 “重复的信息”,是因为在 IPv6 报头中占据较大篇幅的发送和接收地址的低 64 比特,在很多情况下(链路本地地址或者无状态自动配置地址)是可以从 MAC 地址推导出来的。

RFC4944 HC1 IPv6 压缩报头及分发
在 HC1 中,将发送方和接收方的 IPv6 地址上下各 64 比特分割成两部分,然后分别用 2 比特(分别为 SRC/DST)来表示其是否可以省略。例如,在链路本地前缀加上 MAC 地址的情况下,上下两部分都可以省略。对于无状态地址的情况,只会附加高位 64 比特的前缀,而低位 64 比特则是从 MAC 地址推导得出的,就是这样一种情形。
然而,在 HC1 的地址表示方式中,除了链路本地前缀之外,高位前缀是无法省略的,而且地址的低位也并非总是与 MAC 地址一致。暂且不说在 6LoWPAN 网络内部的情况,当通过路由器与外部地址进行通信时,几乎百分之百不会一致。另外,有人指出 HC1 存在缺点,比如它将分发前半部分的 8 比特用作固定模式,因此效率低下,所以后来追加制定了 RFC6282 IPHC 。IPHC 将分发标识符缩短至 3 比特,从而提高了填充效率(※注),并且还支持有状态(Stateful)的地址压缩。
※注:虽说如此,但这样节省下来的也不到 1 个字节,仅仅只有 5 比特而已!

RFC6282 IPHC IPv6 压缩报头及分发
SAC/DAC 比特分别表示源地址和目的地址的类型,当值为 0 时是直接表示(Stateless),值为 1 时是间接表示(Stateful)。所谓间接表示,具体来说,使用 4 位的上下文索引值(SCI/DCI)来指示最多 16 种预先共享的地址前缀(※注)。当分发中的 CID 为 1 时,4 + 4 = 8 比特的 SCI/DCI 值会附加在 DAM 字段的紧接其后的位置,但当 CID 为 0 时,则将其解释为 SCI = DCI = 0。在 IPv6 通信的大部分情况都集中在 “终端节点(自身)” 和 “服务器” 这两点的情况下,比如如果共享 “SC [0]= 自身,DC [0]= 服务器” 这样的上下文前提条件,那么 IPv6 报头就能够被压缩至最短的 16 比特。
※ 注:RFC6282 中明确指出,关于上下文的内容以及共享方式 “不予规定(上下文如何共享和维护不在本规范范围内)”,不过这一点在 RFC6775 中另有定义。
SAC/DAC 与 SAM/DAM 的组合如下所示。当链路本地地址或者采用 128 比特全地址表示的情况时,xAC = 0;而在基于上下文来共享前缀的情况下,则使用 xAC = 1。当 xAC = 1 且 xAM = 00 时的 “零地址” 属于特殊的映射情况,这大概是为了对在 ICMPv6 邻居解析中经常使用的零地址进行压缩。
xAC=0 后续信息
xAM=00 IPv6 地址 128 比特
xAM=01 IPv6 地址低位 64 比特(高位前缀 = 链路本地地址)
xAM=10 IPv6 地址低位 16 比特(高位前缀 = 链路本地地址)
xAM=11 无(高位 = 链路本地地址,低位 = 由 MAC 地址生成)
xAC=1 后续信息
xAM=00 无(零地址)
xAM=01 IPv6 地址低位 64 比特(高位前缀 = 引用自上下文)
xAM=10 IPv6 地址低位 16 比特(高位前缀 = 引用自上下文)
xAM=11 无(高位前缀 = 引用自上下文,低位 = 由 MAC 地址生成)
从这张表格中也可以看出,RFC6282 相当复杂。虽说仅仅因为它不是可变长度的比特格式就已经算是稍微好一点了,但要是认真进行编码的话,if 语句和 switch-case 语句会层层嵌套;而且,为了发挥出最大效率,还需要根据具体用途对选项组合进行优化。有趣的是,这与 IPv6 的原型 RFC188x 形成了鲜明对比,RFC188x 旨在提高实现效率,而并非追求一定的填充效率(※注)。
※注:例如,IPv6 的 “链式报头” 长度是以 8 字节为单位的,当有剩余空间时,不是将其截断,而是用零进行填充。此外,报头的 length 字段采用了一种特殊的表示方式,即 “当值为 0 时,表示最短值 8”,由于最小值是 0,所以在检查报头长度时,只需判断最大值即可,当时还曾以 “这样就能减少一个 if 语句” 而引以为豪。不过,这种特殊规格不仅没有被应用于 ICMPv6 选项部分的长度字段,在其他协议中也很少有采用的例子。看起来比起 “能减少一个 if 语句”,“直观易懂” 更受大家欢迎。这大概也是 “保持简单、愚蠢(K.I.S.S,Keep It Simple, Stupid)” 原则的一个例子吧。
邻居发现(Neighbor Discovery)
正如之前提到的,在普通的 LAN 或 WiFi 中,通常会通过广播来实现邻居发现。然而,在 802.15.4 网络中,广播是被避免使用的。
实际上,IPv6 从一开始就被设计成即使在原本不支持广播的网络(NBMA:Non-Broadcast Multiple Access)中也能运行。在 NBMA 网络中,其前提是默认路由器掌握着节点列表,节点通过向默认路由器发送单播查询来进行地址的邻居解析(RFC1970 Section 3.2)。
6LoWPAN 的邻居发现基本上也是作为 NBMA 来实现的。也就是说,6LoWPAN 节点(6LN)必定有一个默认路由器,并且邻居查询必定是针对默认路由器进行的。明确禁止(MUST NOT)6LN 使用多播进行同时查询。
然而,RFC4944 和 RFC6775 对于 IPv6 默认路由器与 802.15.4 网络拓扑之间的关系都没有明确说明。如果是简单的星型连接,我们可以知道处于星形中心位置的 PAN 协调器也能充当 IPv6 路由器。但在带有串联多级连接的簇状树形结构中,究竟是由中继节点(802.15.4 路由器)来负责邻居解析,还是每次都要追溯到 PAN 协调器,这一点并不清楚。
星型拓扑结构的示例
FFD(Full Function Device)充当微微网(Piconet)协调器(红色),在其周围连接着RFD(Reduced Function Device)。
簇树拓扑结构的示例
两个微微网由充当路由器角色的FFD(橙色标识)连接起来,并且微微网 A 中还存在通过路由器连接的 RFD。在此需要注意的是,这里所说的 “路由器” 是 802.15.4/Zigbee 领域的术语,它并不一定等同于 6LoWPAN 的路由器(6LR)。
为了应对前面提到的诸如 “地址缩短上下文的共享方法” 等 6LoWPAN 的特殊情况,RFC6775 对 ICMPv6 邻居发现功能进行了一些扩展,增加了若干附加选项。RFC4944 是为了让现有的 IPv6 协议栈在 802.15.4 网络上运行的纯粹的中间件规范,而 RFC6775 通过新增这些选项,可以说制定了 “面向 6LoWPAN 的 IPv6 扩展规范”。
Address Registration Option (ARO)
Type=33 的 Neighbor Discovery 选项。该选项被添加到来自 6LoWPAN 节点(6LN)的Neighbor Solicitation 中,用于向 6LoWPAN 路由器(6LR)告知 6LN 的存活状态。
6LoWPAN Context Option (6CO)
Type=34 的Neighbor Discovery选项。由 6LoWPAN 路由器(6LR)通知给 6LoWPAN 节点(6LN),用于传达在 RFC6282 中规定的基于上下文的缩短地址表示的共享信息。
Authoritative Border Router Option (ABRO)
Type=35 的Neighbor Discovery 选项。由 6LoWPAN 路由器(6LR)通知给 6LoWPAN 节点(6LN),用于告知具有上层网络连接的边界路由器(6LBR:6LoWPAN 边界路由器)的IP 地址。
网状网络
在 RFC4944 中定义了 “6LoWPAN 网状网络报头”,可以将网状网络内最初的发送方和最终接收方的 MAC 地址嵌入到数据包中。然而,在 RFC4944 中明确指出,对于发送方究竟如何得知最终接收方的 MAC 地址,以及接收到该数据包的中间节点究竟如何选择下一个中继目标这些问题“不予规定”。“仅仅提供基本机制,至于如何运用该机制则取决于具体实现(或者在追加规范中明确说明)”,这就是 RFC4944 的基本立场。
RFC4944 网状网络报头:V/F 标志用于指示后续的originator(V),final(F)address是 16 比特(值为 1 时)或 64 比特(值为 0 时)地址 。
在 RFC6775 中,支持两种模型:一种是将网状结构隐藏在链路层,把它当作平面网络来处理的“Mesh-Under”;另一种是将网状结构当作 IPv6 网络来处理的 “Route-Over”。在 Mesh-Under 模式下的路由选择会使用嵌入在 6LoWPAN 帧中的 RFC4944 网状网络报头,而在 Router-Over 模式下,我想应该会使用基于 IPv6 的路由机制(例如 RFC6550 中规定的 RPL 路由协议)。不过,RFC6775 中并没有对这些方面进行明确说明,让人感觉条理不太清晰(RFC6775 中的图示也很少,整体给人一种不太友好的印象)。
IPv4 和 6LoWPAN
“在 6LoWPAN 上运行 IPv4 协议” 这听起来确实是本末倒置,但从道理上来说,只要确定了与 IPv4 对应的调度识别代码,那么让 IPv6 和 IPv4 混合使用也是有可能的(※注)。经查询发现,在 2008 年似乎曾有过一项名为 draft-elpro-ipv4-lowpan-00 的提案,不过该提案一直停留在草案 0 版,没有更新且已失效,很可能是以近乎被忽视的方式被搁置了。
※注:如前所述,由于 802.15.4 的 MAC 层没有TYPE 字段,所以调度代码就成为了 IPv4 和 IPv6 的标识符。在 draft-elpro-ipv4-lowpan 提案中,将 01000100(0x44)定义为 LOWPAN_HC4 调度代码,并且通过额外的 8 比特标志字段来定义后续 IPv4 报头的压缩规则。
WiFi 和 6LoWPAN
对于我们 Wi-Fi 阵营来说,802.15.4/6LoWPAN既是“竞争的对手”,也是“未来可能共存的伙伴”。6虽然在 Wi-Fi 上实现 6LoWPAN 也并非不可能,但对于凭借较大的帧尺寸以及通过帧聚合来实现提速的 Wi-Fi 而言,仅仅削减大约 40 字节左右的报头长度,或者在链路层进行帧的分割与重组,几乎没有什么好处。正因为如此,“无需特殊处理就能运行 TCP/IP” 曾是 Wi-Fi 的优势之一。然而,随着 6LoWPAN 的出现,IPv6 也能够在 802.15.4 和 Bluetooth LE 上运行,这使得 Wi-Fi 再也不能安于现状、无所作为了。
这其实也是一件好事。曾经,Zigbee 的协议规范、蓝牙的协议规范以及 Wi-Fi 的 TCP/IP 完全是没有任何互操作性、处于不同世界的存在,然而,由于 6LoWPAN 的出现,它们之间变得可以相互连接,并且也能够协同工作了。比如说,工业领域使用 802.15.4,家庭环境中使用蓝牙,办公场所使用 Wi-Fi,不同的物理层根据不同的用途被分别使用,与此同时,基于相同 IPv6 协议的相同应用程序也能够以相同的方式运行,这样一来它们或许就能够共存了。这恰恰就是 20 年前 IPv6 所憧憬的 “下一代互联网应有的模样”…… 但究竟能否如此理想地实现功能区分,(就像 USB 和以太网那样)会不会出现某一种规格标准凭借着数量和价格上近乎压倒性的优势去战胜其他标准,这实在是非常难以预测的事情。
总结
尽管 IPv6 一直被称为 “21 世纪的互联网标准”,但在长达 20 年的时间里却一直默默无闻、毫无建树。然而,当人们开始说(也许)连接着数亿乃至数十亿节点的物联网(IoT)时代即将到来的时候,IPv6 又重新受到了关注。不过,在 IoT 的世界里,需要兼容数据包长度为 127 字节的 IEEE802.15.4 以及 39 字节的 Bluetooth LE,这与按照 “更快、更高效” 的理念设计出来的 IPv6 存在着一些微妙的不匹配之处。
可以说,6LoWPAN 是让 IPv6 所宣扬的理想与现实相互磨合的产物。然而,“通过省略 IP 报头的冗余信息来缩小尺寸” 这类做法,就如同过去在低速串行线路上所做的事情一样(参考 1990 年的RFC1144 CSLIP)。而 “在帧长较短” 且 “没有广播” 的架构上搭载 TCP/IP 这一点,又让人想起了在 53 字节固定信元长度的ISDN ATM 上实现虚拟LAN大约在 1992 年)的情况,不禁让人深切地感叹“历史总是在重演”啊。
虽然 6LoWPAN 就像是这样一种有些笨拙、可以说是 “「不那么优雅的发明」”,但在 IoT 领域中,它却被视为一个有力的候选方案。正如前面已经提到的,Zigbee IP 采用了 6LoWPAN 技术,而且由谷歌公司主导的面向 IoT 的网状网络标准の Thread 也是基于6LoWPAN 的。此外,就在不久前发布的 IPv6 over Bluetooth LE (RFC7688) 同样采用了 6LoWPAN。这样看来,在 802.3 不兼容的低功耗无线通信规范上实现 IPv6 时,无论好坏,6LoWPAN 作为事实上的标准,其地位似乎已经确立了。
那么,6LoWPAN 会成为支撑 IoT 时代的重要基石吗?以 6LoWPAN 为基石,IPv6 终于能够实现历经 20 年之久所期待的 “下一代互联网” 吗?就像已经多次提到的那样,预测未来实在是非常困难的事情。毕竟,“连接着数亿乃至数十亿节点的 IoT ” 这样的未来是否真的会到来,我们根本无法确定。就算这样的未来实现了,到底IPv6/6LoWPAN 会成为主流,还是继续通过 NAPT 来补充使用十进制 4 位数的 IPv4 地址,这也不得而知。虽然我们可以梳理出技术层面上的利害得失,但市场往往会受到技术利害得失以外的诸多因素的强烈影响(※注)。毕竟,如果市场真的是依据 “技术上的利害得失” 来选择产品规格的话,那么 IPv4 早在 10 年前就应该已经被淘汰了(笑)。
※注:比如 “iPhone 将其作为标准功能搭载” 或者 “SoftBank 免费发放支持该技术的设备” 之类的情况…… 从这个意义上来说,iPhone 连无线芯片都没有搭载的 802.15.4 技术就显得 “有些不利” 了。Android 和 iOS 何时会支持 6LoWPAN,苹果公司会在多大程度上积极支持 6LoWPAN 应用程序(它将如何与苹果公司独有的 IoT 规格 HomeKit 共存等),这些也将成为关注点之一。