RFC 8931
IPv6 over Low-Power Wireless Personal Area Network (6LoWPAN) Selective Fragment Recovery
๐ RFC 8931: IPv6 over Low-Power Wireless Personal Area Network (6LoWPAN) Selective Fragment Recovery ๐ฆ
bestie, this one is titled "IPv6 over 6LoWPAN Selective Fragment Recovery" and it's from the IETF ๐. It's a Standards Track doc (so it's a real, official spec, not just an idea) written by P. Thubert, Ed. from Cisco Systems ๐ผ. It came out in November 2020 ๐, and its ISSN is 2070-1721 ๐ข. The big news is that it updates RFC 4944 ๐, which is the original 6LoWPAN fragmentation spec, so this one is literally upgrading it. The doc doesn't say it obsoletes anything, so nothing is getting retired here ๐ โโ๏ธ.
Abstract โจ
okay so the whole pitch is this: this doc updates RFC 4944 with a protocol that forwards individual fragments across a route-over mesh and then recovers them end to end ๐ซถ. It also brings congestion control so the network doesn't get overwhelmed ๐ .
Status of This Memo ๐
This is an Internet Standards Track document. ๐ฅ
This document is a product of the Internet Engineering Task Force (IETF) ๐ธ. It represents the consensus of the IETF community, so a lot of people agreed on it. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) ๐. If you want more info on Internet Standards, check Section 2 of RFC 7841 ๐ง.
For the current status, any errata, and how to send feedback, go to https://www.rfc-editor.org/info/rfc8931 ๐.
Copyright Notice ๐
Copyright (c) 2020 IETF Trust and the persons identified as the document authors. All rights reserved. ๐
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stood on the publication date. Please actually read these, because they spell out your rights and restrictions for this doc ๐. Code Components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as the Simplified BSD License describes ๐.
Table of Contents ๐๏ธ
1. Introduction
2. Terminology
2.1. Requirements Language
2.2. Background
2.3. Other Terms
3. Updating RFC 4944
4. Extending RFC 8930
4.1. Slack in the First Fragment
4.2. Gap between Frames
4.3. Congestion Control
4.4. Modifying the First Fragment
5. New Dispatch Types and Headers
5.1. Recoverable Fragment Dispatch Type and Header
5.2. RFRAG Acknowledgment Dispatch Type and Header
6. Fragment Recovery
6.1. Forwarding Fragments
6.1.1. Receiving the First Fragment
6.1.2. Receiving the Next Fragments
6.2. Receiving RFRAG Acknowledgments
6.3. Aborting the Transmission of a Fragmented Packet
6.4. Applying Recoverable Fragmentation along a Diverse Path
7. Management Considerations
7.1. Protocol Parameters
7.2. Observing the Network
8. Security Considerations
9. IANA Considerations
10. References
10.1. Normative References
10.2. Informative References
Appendix A. Rationale
Appendix B. Requirements
Appendix C. Considerations on Congestion Control
Acknowledgments
Author's Address
1. Introduction ๐ธ
okay so in most Low-Power and Lossy Network (LLN) apps, the traffic is mostly tiny chunks of data, like a few bytes to a few tens of bytes at a time ๐ฆ. An IEEE Std 802.15.4 [IEEE.802.15.4] frame can carry a payload of 74 bytes or more, so fragmentation is usually not needed ๐. BUT (and this is the plot twist) a bunch of mission-critical apps do need to move bigger chunks, like firmware upgrades for LLN nodes or pulling logs off them ๐ฆ.
In the firmware case, the big chunk flows into the LLN node. In the logs case, it flows away from it ๐. Either way, we're talking about something around 10 KB or more, and an end-to-end reliable transport is required ๐ .
"Transmission of IPv6 Packets over IEEE 802.15.4 Networks" [RFC4944] is where the original 6LoWPAN datagram fragmentation mechanism for LLNs came from ๐ง. The big problem with that original design is that routing an IPv6 [RFC8200] packet across a route-over mesh means the packet gets reassembled at every hop ๐ญ. "An Architecture for IPv6 over the TSCH mode of IEEE 802.15.4" [6TiSCH] says this can add latency along a path and eat into critical resources like memory and battery ๐. To help with that, it recommends using a 6LoWPAN Fragment Forwarding (6LFF) technique ๐.
"On Forwarding 6LoWPAN Fragments over a Multihop IPv6 Network" [RFC8930] lays out the generic behavior that all 6LFF techniques, this spec included, follow, and it also covers the caveats ๐. The main thing is that the routing info is fully in the first fragment, which always goes first ๐. In this spec, the first fragment is identified by a Sequence of 0, instead of by a dispatch type like in [RFC4944] โจ. A state gets formed and then used to forward all the next fragments along that same path ๐ค๏ธ. The Datagram_Tag is only locally significant to the Layer 2 source of the packet, and it gets swapped at each hop (see Section 6) ๐. This spec encodes the Datagram_Tag in 1 byte, which will saturate if more than 256 datagrams transit in fragmented form over a single hop at the same time ๐. That's not realistic as of this writing ๐. If it ever happens in a new 6LoWPAN technology, a node will need to use several link-layer addresses to increase its indexing capacity ๐งฉ.
"Virtual reassembly buffers in 6LoWPAN" [LWIG-FRAG] proposes a 6LFF technique that's compatible with [RFC4944] without needing a new protocol ๐ซง. But just adding that capability to the local implementation of the original 6LoWPAN fragmentation wouldn't fix the inherent fragility of fragmentation (see [RFC8900]) ๐ฉ. The two issues it wouldn't fix are resources getting locked up on the reassembling endpoint, and wasted transmissions when a single fragment gets lost in a whole datagram ๐ฅฒ.
[Kent] compares the unreliable delivery of fragments with a mechanism it calls "selective acknowledgments," which recovers the loss of a fragment individually ๐คฏ. The paper shows the benefits you can get from that method, see Figures 1, 2, and 3 in Section 2.3 of [Kent] ๐. [RFC4944] has no selective recovery, so the whole datagram fails when one fragment doesn't reach the reassembling endpoint ๐. Constrained memory stays blocked on that endpoint until it times out, which can make later packets get lost because there are no buffers left for them ๐ต.
It gets worse when fragments are forwarded over multiple hops, since a loss at an intermediate hop won't be discovered by either the fragmenting or the reassembling endpoints ๐. When that happens, the source keeps sending fragments and wastes even more network resources, because the datagram can never arrive in full, and that might even add to the condition that caused the loss ๐. [RFC4944] has no congestion control, so it can't avoid piling onto a saturation that may have caused the fragment loss in the first place ๐ฆ. It also has no signaling to abort a multi-fragment transmission at any time from either end, and if forwarding fragments is implemented, there's no way to clean up the related state in the network ๐งน.
This spec gives you a method to forward fragments over, typically, a few hops in a route-over 6LoWPAN mesh, plus a selective acknowledgment to recover individual fragments between 6LoWPAN endpoints ๐ฆ. The method can help limit congestion loss in the network and meets the requirements in Appendix B ๐. Flow control is out of scope, because the endpoints are expected to be able to store the full datagram ๐ฆ. Deployments are expected to be managed and homogeneous, and moving over incrementally requires a flag day ๐ณ๏ธ.
2. Terminology ๐ง
2.1. Requirements Language ๐
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. โจ
2.2. Background ๐
This doc uses 6LoWPAN terms and concepts from "IPv6 over Low-Power Wireless Personal Area Networks (6LoWPANs): Overview, Assumptions, Problem Statement, and Goals" [RFC4919], "Transmission of IPv6 Packets over IEEE 802.15.4 Networks" [RFC4944], and "Problem Statement and Requirements for IPv6 over Low-Power Wireless Personal Area Network (6LoWPAN) Routing" [RFC6606] ๐ง.
[RFC8930] talks about the generic concept of a Virtual Reassembly Buffer (VRB). It also specifies behaviors and caveats shared by a big family of 6LFF techniques, including the mechanism in this doc, which fully inherits from that spec ๐ซถ. It defines some terms this doc uses too: Compressed Form, Datagram_Tag, Datagram_Size, Fragment_Offset, and 6LoWPAN Fragment Forwarding endpoint (usually just shortened to "endpoint") ๐ท๏ธ.
Past experience with fragmentation has shown that misassociated or lost fragments can lead to poor network behavior and, sometimes, trouble at the application layer ๐ฌ. Go read "IPv4 Reassembly Errors at High Data Rates" [RFC4963] and follow its references if you want more ๐. That experience is what led to "Path MTU Discovery for IP version 6" [RFC8201], which limits fragmentation over the Internet ๐. For UDP specifically, "UDP Usage Guidelines" [RFC8085] has valuable extra info ๐ป.
"The Benefits of Using Explicit Congestion Notification (ECN)" [RFC8087] has useful info on the potential benefits and pitfalls of using ECN ๐ฆ.
Quoting "Multiprotocol Label Switching Architecture" [RFC3031]:
| With MPLS, "packets are "labeled" before they are forwarded [along | a Label Switched Path (LSP)]. At subsequent hops, there is no | further analysis of the packet's network layer header. Rather, | the label is used as an index into a table which specifies the | next hop, and a new label".
[RFC8930] borrows the MPLS idea to forward fragments that don't actually have a network-layer header, since fragmentation happens below IP ๐ช. This spec makes that reversible, so the reverse path can be followed as well ๐.
2.3. Other Terms ๐ซง
This specification uses the following terms:
- RFRAG: Recoverable Fragment ๐งฉ
- RFRAG-ACK: Recoverable Fragment Acknowledgment ๐
- RFRAG Acknowledgment Request: An RFRAG with the Acknowledgment Request flag ("X" flag) set. ๐โโ๏ธ
- NULL bitmap: Refers to a bitmap with all bits set to zero. 0๏ธโฃ
- FULL bitmap: Refers to a bitmap with all bits set to one. 1๏ธโฃ
- Reassembling endpoint: The receiving endpoint. ๐ฅ
- Fragmenting endpoint: The sending endpoint. ๐ค
- Forward direction: The direction of a path, which is followed by the RFRAG. โก๏ธ
- Reverse direction: The reverse direction of a path, which is taken by the RFRAG-ACK. โฌ ๏ธ
3. Updating RFC 4944 ๐
okay bestie, so this section is basically about how RFC 4944 fragmentation gets upgraded for route-over LLNs ๐ The big glow-up is that fragments can now be forwarded end to end across a 6LoWPAN LLN, and if one gets lost on the way, it can be recovered on its own instead of redoing the whole datagram ๐ฆ A new fragment format shows up, and the new dispatch types are defined in Section 5 โจ
[RFC8138] lets the packet shrink en route by removing consumed hops from a compressed Routing Header ๐ ngl that means Fragment_Offset and Datagram_Size (from Section 5.1) also have to change along the way, and that's a pain to do in the uncompressed form ๐ญ So this spec puts those fields in compressed form so they can be modified en route easily ๐ (more in Section 4.4 ๐ซถ)
and here's the consistency part ๐ To match Section 2 of [RFC6282], for the fragmentation mechanism in Section 5.3 of [RFC4944], any header that can't fit inside the first fragment MUST NOT be compressed when you use the fragmentation mechanism described here ๐ธ
4. Extending RFC 8930 ๐
this spec implements the generic 6LFF technique from [RFC8930] and adds end-to-end fragment recovery and congestion control on top ๐
4.1. Slack in the First Fragment ๐ง
[RFC8930] allows a refragmentation operation at intermediate nodes, where the trailing bytes of a fragment can be left in the VRB and added as the heading bytes of the next fragment โจ That solves the case where the outgoing fragment needs more space than the incoming one. This can happen when 6LoWPAN header compression is less efficient on the outgoing link, or when the Link MTU gets reduced ๐ซ
this spec cannot allow that refragmentation operation ๐ โโ๏ธ because fragments are recovered end to end based on a sequence number. The Fragment_Size MUST be tailored to fit the minimal MTU along the path, and the first fragment that contains a 6LoWPAN compressed header MUST have enough slack so a less-efficient compression at the next hops still fits within the Link MTU ๐
for example, if the fragmenting endpoint is also the 6LoWPAN compression endpoint, it'll elide the Interface ID (IID) of the source IPv6 address when it matches the link-layer address [RFC6282] ๐ฆ In that case it MUST leave slack in the first fragment, as if the MTU on the first hop were 8 bytes less, so the next hop can expand the IID within the same fragment within MTU ๐ธ
4.2. Gap between Frames ๐
[RFC8930] requires a configurable interval of time between transmissions to the same next hop, and in particular between fragments of the same datagram โณ On half duplex interfaces, this inter-frame gap makes sure the next hop is done forwarding the previous frame and is ready to receive the next one ๐ง
in a mesh running at a single frequency with omnidirectional antennas, a larger inter-frame gap is needed to protect the frame against hidden terminal collisions with the previous frame of the same flow, which is still moving along a common path ๐
the inter-frame gap is useful even for unfragmented datagrams ๐ but it becomes a necessity for fragments, which are typically generated in a fast sequence and all sent over the exact same path ๐ญ
4.3. Congestion Control ๐ฅ
the inter-frame gap is the only protection that [RFC8930] imposes by default ๐ฅบ this document lets you group fragments into windows and request intermediate acknowledgments, so the number of in-flight fragments can be bounded ๐ It also adds an ECN mechanism that can protect the network by adapting the window size, the fragment size, and/or the inter-frame gap โจ
this spec lets the fragmenting endpoint apply a congestion control mechanism to tune those parameters, but the mechanism itself is out of scope ๐โโ๏ธ Usually, most datagrams only need a few fragments, and only the last fragment gets acknowledged ๐ A basic implementation of the fragmenting endpoint is NOT REQUIRED to vary the window size, the inter-frame gap duration, or the size of a fragment in the middle of a datagram's transmission ๐ It MAY ignore the ECN signal, or simply reset the window to 1 (see Appendix C) until the end of that datagram once congestion is detected ๐ซถ
an intermediate node that experiences congestion MAY set the ECN bit in a fragment, and the reassembling endpoint echoes the ECN bit at most once at the next opportunity to acknowledge back ๐
the size of the fragments is typically computed from the Link MTU to maximize the size of the resulting frames ๐ง The size of the window and the duration of the inter-frame gap SHOULD be configurable, to reduce the chances of congestion and to follow the general recommendations in [RFC8930], respectively โจ
4.4. Modifying the First Fragment ๐ฆ
the compression of the hop limit, of the source and destination addresses in the IPv6 header, and of the Routing Header (all in the first fragment) may change en route in a route-over mesh LLN ๐ If the size of the first fragment is modified, the intermediate node MUST adapt the Datagram_Size, encoded in the Fragment_Size field, to reflect that difference ๐
the intermediate node MUST also save the difference in Datagram_Size of the first fragment in the VRB and add it to the Fragment_Offset of all the subsequent fragments it forwards for that datagram ๐ธ In the case of a Source Routing Header 6LoWPAN Routing Header (SRH-6LoRH) [RFC8138] being consumed and therefore reduced, that difference is negative, meaning the Fragment_Offset gets decremented by the number of bytes that were consumed ๐ญ
5. New Dispatch Types and Headers ๐
this document specifies an alternative to the 6LoWPAN fragmentation sub-layer [RFC4944] that emulates a Link MTU up to 2048 bytes for the upper layer ๐ That upper layer can be the 6LoWPAN header compression sub-layer defined in "Compression Format for IPv6 Datagrams over IEEE 802.15.4-Based Networks" [RFC6282] โจ This spec also provides reliable transmission of fragments over a multi-hop 6LoWPAN route-over mesh network, plus minimal congestion control to reduce the chances of congestion loss ๐ฅ
a 6LoWPAN Fragment Forwarding [RFC8930] technique derived from MPLS lets individual fragments be forwarded across a 6LoWPAN route-over mesh without reassembly at each hop ๐ง The Datagram_Tag is used as a label. It's locally unique to the node that owns the source link-layer address of the fragment, so together the link-layer address and the label can identify the fragment globally within the datagram's lifetime ๐ฆ A node may build the Datagram_Tag in its own locally significant way, as long as the chosen Datagram_Tag stays unique to that particular datagram for its lifetime ๐ธ So the label doesn't need to be globally unique, but it MUST be swapped at each hop as the source link-layer address changes ๐
in the following sections, a Datagram_Tag extends the semantics defined in "Fragmentation Type and Header" (see Section 5.3 of [RFC4944]) ๐ซถ The Datagram_Tag is a locally unique identifier for the datagram from the sender's perspective, which means it identifies a datagram uniquely in the network when associated with the datagram's source ๐ As the datagram gets forwarded, the source changes, and the Datagram_Tag MUST be swapped as detailed in [RFC8930] ๐ฅบ
this specification extends [RFC4944] with two new dispatch types, one for RFRAG and one for the RFRAG-ACK that comes back ๐ The new 6LoWPAN dispatch types are taken from [RFC8025], as indicated in Table 1 of Section 9 ๐
5.1. Recoverable Fragment Dispatch Type and Header
Okay so, here's the vibe: if the packet is compressed, the size and offset of each fragment are measured against the compressed form of the packet, not the uncompressed native one. Main character energy for the compressed version ๐ โจ
The fragment header in Figure 1 is the same for every fragment, even though Fragment_Offset is doing double duty ๐ฆ. It has a length, an offset, and a Sequence field. You might think that's redundant because the offset could be computed as Sequence times length, but it's not! The spot a fragment occupies in the reassembly buffer has nothing to do with its Sequence value or the order it arrives in ๐. This is what lets you split fragments when the MTU shrinks. Look at fragment Sequence 5 getting retried end to end as the smaller fragments Sequences 13 and 14 in Section 6.2. Iconic ๐
The first fragment is the one with Sequence 0. It carries its Fragment_Size and the Datagram_Size of the compressed packet before it got fragmented. Every other fragment carries its Fragment_Size and Fragment_Offset instead ๐. The last fragment shows up when its Fragment_Offset plus its Fragment_Size add up to the stored Datagram_Size of the packet, which is identified by the sender's link-layer address and the Datagram_Tag ๐ธ.
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 0 1 0 0|E| Datagram_Tag |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|X| Sequence| Fragment_Size | Fragment_Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
X set == Ack-Request
Figure 1: RFRAG Dispatch Type and Header
Here's what each field does ๐:
X: 1 bit, Ack-Request. When it's set, the fragmenting endpoint needs an RFRAG Acknowledgment from the reassembling endpoint.E: 1 bit, Explicit Congestion Notification. The source of the fragment clears this flag, and intermediate routers set it to signal that the fragment ran into congestion along its path ๐.Fragment_Size: a 10-bit unsigned integer giving the size of this fragment, in a unit that depends on the link-layer technology. Unless a more specific specification says otherwise, that unit is the byte, which means fragments can be up to 1023 bytes โญ.Datagram_Tag: 8 bits. An identifier for the datagram that's locally unique to the link-layer sender ๐ง.Sequence: a 5-bit unsigned integer, the sequence number of the fragment in the acknowledgment bitmap. Fragments are numbered [0..N], where N is in [0..31]. A Sequence of 0 marks the first fragment in a datagram, but non-zero values don't tell you where the fragment sits in the reassembly buffer ๐.Fragment_Offset: a 16-bit unsigned integer. When it's set to a non-zero value, what it means depends on the Sequence field, like this ๐ฅ:- For a first fragment (Sequence of 0), this field gives the
Datagram_Sizeof the compressed datagram, so the reassembling endpoint can allocate a suitably sized buffer for reception and reassembly. The fragment may be stored for local reassembly. Or it may be routed based on the destination IPv6 address. In that case, a VRB state must be installed, as described in Section 6.1.1. - When the Sequence isn't 0, this field gives the offset of the fragment within the compressed form of the datagram. The fragment may go into a local reassembly buffer, or it may be forwarded based on an existing VRB, as described in Section 6.1.2.
- For a first fragment (Sequence of 0), this field gives the
A Fragment_Offset set to 0 is an abort signal ๐ซ. All the state about the datagram should get cleaned up once the fragment is processed. What happens next depends on whether a VRB already exists for this datagram and whether the next hop is still reachable:
- If a VRB already exists and the next hop is still reachable, the fragment gets forwarded along the associated LSP as described in Section 6.1.2, without checking the Sequence field.
- Otherwise, if the Sequence is 0, the fragment is routed as described in Section 6.1.1, but no state is kept afterwards. In that case, the session gets aborted if it exists, and the packet is forwarded too, to clean up the next hops along the path indicated by the IPv6 header (which may include a Routing Header) ๐งน.
- Otherwise (the Sequence is non-zero and either no VRB exists or the next hop is unavailable), the fragment can't be forwarded or routed. It gets discarded, and an abort RFRAG-ACK is sent back to the source, as described in Section 6.1.2 ๐.
Recoverable Fragments are sequenced, and an RFRAG Acknowledgment uses a bitmap to show which fragments arrived. Each received fragment sets the bit that matches its sequence number ๐ฆ.
The reassembling endpoint isn't required to check that received fragments are consecutive and non-overlapping. This is especially handy when the MTU changes and a fragment Sequence gets retried with a smaller Fragment_Size, while the rest of the original fragment gets retried under new Sequence values ๐ซถ. The fragmenting endpoint knows the datagram is fully received once the acknowledged fragments cover the whole datagram. That's what a FULL bitmap means โจ.
5.2. RFRAG Acknowledgment Dispatch Type and Header
This specification also defines a 4-byte RFRAG Acknowledgment Bitmap ๐. The reassembling endpoint uses it to selectively confirm individual fragments. Each offset in the bitmap maps one to one with a sequence number, and it tells you whether that fragment was acknowledged, like in Figure 2 ๐:
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RFRAG Acknowledgment Bitmap |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^ ^
| | bitmap indicating whether:
| +----- Fragment with Sequence 9 was received
+----------------------- Fragment with Sequence 0 was received
Figure 2: RFRAG Acknowledgment Bitmap Encoding
Figure 3 is an example bitmap. It shows that every fragment from Sequence 0 to 20 arrived, except fragments 1, 2, and 16. Those got lost, so they must be retried ๐ญ.
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1|0|0|1|1|1|1|1|1|1|1|1|1|1|1|1|0|1|1|1|1|0|0|0|0|0|0|0|0|0|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 3: Example RFRAG Acknowledgment Bitmap
The RFRAG Acknowledgment Bitmap rides inside an RFRAG Acknowledgment header, shown in Figure 4 ๐ง:
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 0 1 0 1|E| Datagram_Tag |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RFRAG Acknowledgment Bitmap (32 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 4: RFRAG Acknowledgment Dispatch Type and Header
Here's the breakdown ๐:
E: 1 bit, Explicit Congestion Notification Echo. When it's set, the fragmenting endpoint learns that at least one of the acknowledged fragments arrived with an Explicit Congestion Notification. That means the path the fragments took is congested. See Appendix C for more details ๐.Datagram_Tag: 8 bits, an identifier for the datagram that's locally unique to the link-layer recipient ๐ธ.RFRAG Acknowledgment Bitmap: setting the bit at offset x means fragment x was received, as shown in Figure 2. A NULL bitmap means the fragmentation process is aborted ๐ซ. A FULL bitmap means the fragmentation process is complete, since every fragment reached the reassembling endpoint ๐.
6. Fragment Recovery โจ
okay so the RFRAG header is basically the carrier for a fragment, and it can optionally ask for an RFRAG-ACK ๐ that says "yep, got these fragments" ๐ซถ. An RFRAG-ACK is a standalone fragment header with no 6LoWPAN payload, and it travels back to the fragmenting endpoint. Every hop that did an MPLS-like operation on the fragments undoes it for the RFRAG-ACK by sending a frame from the next hop back to the previous hop, using the link-layer address it has stored in the VRB ๐ฆ. The Datagram_Tag in the RFRAG-ACK is unique to the reassembling endpoint, and that's enough for an intermediate hop to find the VRB holding the Datagram_Tag the previous hop used, plus the Layer 2 info tied to it (interface and link-layer address). the way that's so clever ๐ญ๐ฅ
The fragmenting endpoint (the node doing the 6LoWPAN-level fragmenting) is also the one in charge of how many acknowledgments you get, because it sets the Ack-Request flag in the RFRAG packets ๐.
The fragmenting endpoint may set the Ack-Request flag on any fragment to do congestion control by capping the number of outstanding fragments, which means fragments that have been sent but whose reception or loss hasn't been positively confirmed by the reassembling endpoint ๐ธ. The cap is the Window-Size. It's configurable and may change when ECN notification shows up ๐
. When the reassembling endpoint gets a fragment with Ack-Request set, it MUST send an RFRAG-ACK back to the originator to confirm reception of all the fragments it has received so far ๐.
The Ack-Request ("X") marks the end of a window ๐. This flag MUST be set on the last fragment if the fragmenting endpoint wants to run an automatic repeat request (ARQ) process for the datagram, and it MAY be set on any intermediate fragment for congestion control reasons ๐ง.
This ARQ process MUST be protected by a Retransmission Timeout (RTO) timer ๐. The fragment carrying the "X" flag MAY be retried after a timeout, for a configurable number of times (see Section 7.1), with an exponential backoff โณ. Once the retries run out, the fragmenting endpoint may either abort the transmission of the datagram, or resend the first fragment with an "X" flag set. That second option is a glow-up move ๐: it establishes a new path for the datagram and gets the list of fragments that were received over the old path in the acknowledgment bitmap. And if the fragmenting endpoint knows an underlying link-layer mechanism already protects the fragments, it may skip the RFRAG Acknowledgment mechanism entirely and never set the Ack-Request bit ๐.
The reassembling endpoint MAY issue unsolicited acknowledgments ๐ฆ. An unsolicited acknowledgment tells the fragmenting endpoint that it can start sending again if it had hit its maximum number of outstanding fragments. It can also let the fragmenting endpoint know that the reassembling endpoint aborted the processing of one particular datagram ๐.
The RFRAG Acknowledgment carries an ECN indication for congestion control (see Appendix C) โจ. When the reassembling endpoint of a fragment with the "E" (ECN) flag set gets it, it MUST echo that info at most once, by setting the "E" (ECN) flag in the next RFRAG-ACK ๐ซง.
To protect the datagram, the fragmenting endpoint sends a controlled number of fragments, and it puts an RFRAG Acknowledgment Request on the last fragment of each window ๐ฏ. The reassembling endpoint MUST acknowledge a fragment whose acknowledgment request bit is set ๐. If any fragment right before an acknowledgment request is still missing, the reassembling endpoint MAY intentionally delay its acknowledgment so in-transit fragments have time to arrive ๐ข. Heads up though: that can mess up the round-trip time computation, so delaying the acknowledgment should be configurable and not enabled by default โ ๏ธ.
Once enough fragments have arrived to cover the whole datagram, the reassembling endpoint rebuilds the packet, passes it up to the upper layer, sends an RFRAG-ACK on the reverse path with a FULL bitmap, and arms a short timer, for example on the order of an average round-trip time in the network โฑ๏ธ. The FULL bitmap is used instead of a bitmap that only acknowledges the fragments received, so the intermediate nodes know the datagram is fully received ๐ซถ. While the timer runs, the reassembling endpoint absorbs the fragments still in flight for that datagram without creating new state, and it acknowledges the ones bearing an Ack-Request with an FRAG Acknowledgment and the FULL bitmap ๐ง. If fragments with a matching source and Datagram-Tag keep arriving after the timer expires, the reassembling endpoint aborts the communication ๐.
Acknowledgments can eat up precious resources, so the use of unsolicited acknowledgments SHOULD be configurable and not enabled by default ๐ .
Here's the vibe: streamlining how fragments get forwarded generally cuts latency over the LLN mesh, which leaves room for retries inside the existing upper-layer reliability mechanisms ๐ธ. The fragmenting endpoint protects transmission over the LLN mesh with a retry timer configured for a particular use case, and that timer may be adjusted dynamically, for example using the method in [RFC6298] ๐. The upper-layer retry mechanism is expected to follow the recommendations in [RFC8085], and if it does, a single round of fragment recovery should fit inside the upper-layer recovery timers ๐.
Fragments MUST be sent round-robin style: the sender MUST send all the fragments for the first time before it retries any lost fragment, and lost fragments MUST be retried in sequence, oldest first ๐. This lets the receiver acknowledge fragments that got delayed in the network before they're retried ๐.
When a single radio frequency is used by contiguous hops, the fragmenting endpoint SHOULD insert a delay between the frames (for example, the ones carrying fragments) that go to the same next hop ๐. That delay SHOULD cover multiple transmissions, so a frame can progress a few hops and dodge hidden terminal issues ๐ฆ. This precaution is not required on channel hopping technologies such as Time-Slotted Channel Hopping (TSCH) [RFC6554], where nodes communicating at Layer 2 are scheduled to send and receive, respectively, and different hops operate on different channels ๐ง.
6.1. Forwarding Fragments
This spec builds on [RFC8930] and proposes a Virtual Reassembly Buffer technique to forward fragments without reconstructing the whole datagram in the middle ๐.
The IPv6 header MUST be placed in full in the first fragment so the routing decision can happen ๐. The first fragment gets routed and creates an LSP from the fragmenting endpoint to the reassembling endpoint ๐ฃ๏ธ. The next fragments get label switched along that LSP, which means they can only follow the path the first fragment set up. They can't take an alternate route ๐
โโ๏ธ. The Datagram_Tag carries the label, and the label gets swapped at each hop ๐.
If the first fragment is too large for the path MTU, it'll keep failing and never set up an LSP ๐ฉ. In that case, the fragmenting endpoint MAY retry the same datagram with a smaller Fragment_Size, and when it does, it MUST abort the original attempt and use a new Datagram_Tag for the new attempt ๐.
6.1.1. Receiving the First Fragment
In route-over mode, the source and destination link-layer addresses in a frame change at each hop ๐บ๏ธ. The label the sender forms and puts in the Datagram_Tag is tied to the source link-layer address, and it's only valid (and temporarily unique) for that source link-layer address ๐๏ธ.
When an intermediate router gets the first fragment (the one with a Sequence of 0), it creates a VRB and the matching LSP state, indexed by the incoming interface, the previous-hop link-layer address, and the Datagram_Tag ๐ฆ. Then it forwards the fragment along the IPv6 route matching the destination IPv6 address in the IPv6 header, until it reaches the reassembling endpoint, as prescribed by [RFC8930] โ๏ธ. The LSP state lets the router match the next incoming fragments of a datagram to the abstract forwarding info of the next interface, source and next-hop link-layer addresses, and the swapped Datagram_Tag ๐งฉ.
The router also builds a reverse LSP state, indexed by the interface to the next hop, the link-layer address the router uses as source for that datagram, and the swapped Datagram_Tag ๐. This reverse state lets the router match the tuple (interface, destination link-layer address, Datagram_Tag) found in an RFRAG-ACK to the abstract forwarding info (previous interface, previous link-layer address, Datagram_Tag) used to send the RFRAG-ACK back to the fragmenting endpoint ๐ซ.
6.1.2. Receiving the Next Fragments
When an intermediate router gets the next fragment (one with a non-zero Sequence), it looks up an LSP indexed by the tuple (incoming interface, previous-hop link-layer address, Datagram_Tag) found in the fragment ๐. If it finds one, the router forwards the fragment using the associated VRB, as prescribed by [RFC8930] ๐.
If the router can't find a VRB for that tuple, it builds an RFRAG-ACK to abort the transmission of the packet ๐ซ. The resulting message has the following info:
- The source and destination link-layer addresses are swapped from the ones found in the fragment, and the same interface is used
- The
Datagram_Tagis set to theDatagram_Tagfound in the fragment - A
NULLbitmap is used to signal the abort condition
At this point the router is all set and can send the RFRAG-ACK back to the previous router ๐ซก. The RFRAG-ACK should normally be forwarded all the way to the source, using the reverse LSP state in the VRBs of the intermediate routers, as described in the next section ๐ค๏ธ.
[RFC8930] says the reassembling endpoint stores "the actual packet data from the fragments received so far, in a form that makes it possible to detect when the whole packet has been received and can be processed or forwarded" ๐. How that's computed is implementation specific, but it relies on receiving all the bytes up to the Datagram_Size indicated in the first fragment ๐งฎ. An implementation may receive overlapping fragments as the result of retries after an MTU change ๐.
6.2. Receiving RFRAG Acknowledgments โจ
okay so when an RFRAG-ACK shows up, the router looks for a reverse LSP ๐ง that matches the interface and the destination link-layer address of the frame it came in on, plus the Datagram_Tag inside the RFRAG-ACK. If it finds one, it forwards the fragment using the associated VRB, just like [RFC8930] says, except it uses the reverse LSP so the RFRAG-ACK flows back to the fragmenting endpoint. main character routing ๐
If the reverse LSP is not found, the router MUST silently drop the RFRAG-ACK message. no drama, just gone ๐ซฅ
Either way, if the RFRAG-ACK says the fragment was entirely received (the FULL bitmap), the router arms a short timer. When that timer goes off, the VRB and all the associated states are destroyed ๐. Until the timer runs out, fragments of that datagram can still show up. This happens if the RFRAG-ACK got lost on the way back and the source retried the last fragment ๐. In that case, the router generates an RFRAG-ACK with a FULL bitmap back to the fragmenting endpoint if an acknowledgment was requested. If not, it silently drops the fragment.
This specification does not provide a method to discover the number of hops or the minimal value of MTU along those hops. In a typical case, the MTU is constant and is the same across the network ๐ธ. But should the minimal MTU along the path decrease, it is possible to retry a long fragment (say a Sequence of 5) with several shorter fragments that use a Sequence not used before (e.g., 13 and 14). Fragment 5 is marked as abandoned and will not be retried anymore ๐ซถ. Note that when this mechanism is in place, it is hard to predict the total number of fragments that will be needed or the final shape of the bitmap that would cover the whole packet. This is why the FULL bitmap is used when the reassembling endpoint gets the whole datagram, regardless of which fragments were actually used to do so. Intermediate nodes will know unambiguously that the process is complete โจ. Note that Path MTU Discovery is out of scope for this document.
6.3. Aborting the Transmission of a Fragmented Packet
A reset is signaled on the forward path with a pseudo fragment that has the Fragment_Offset set to 0. The sender of a reset SHOULD also set the Sequence and Fragment_Size fields to 0 ๐.
When the fragmenting endpoint or a router on the path decides that a packet should be dropped and the fragmentation process aborted, it generates a reset pseudo fragment and forwards it down the fragment path ๐ฅ.
Each router along the path forwards the pseudo fragment in turn, based on the VRB state. If an acknowledgment is not requested, the VRB and all associated states are destroyed ๐งน.
When the reassembling endpoint receives the pseudo fragment, it cleans up all resources for the packet associated with the Datagram_Tag. If an acknowledgment is requested, the reassembling endpoint responds with a NULL bitmap ๐.
On the other hand, the reassembling endpoint might need to abort the processing of a fragmented packet for internal reasons. For instance, it might be out of reassembly buffers, it might already be using all 256 possible values of the Datagram_Tag, or it might keep receiving fragments long after a reasonable time, even though it thinks this packet is already fully reassembled and was passed to the upper layer ๐ค. In that case, the reassembling endpoint SHOULD indicate so to the fragmenting endpoint with a NULL bitmap in an RFRAG-ACK.
The RFRAG-ACK is forwarded all the way back to the source of the packet, and it cleans up all resources on the path ๐งผ. Upon an acknowledgment with a NULL bitmap, the fragmenting endpoint MUST abort the transmission of the fragmented datagram, with one exception. In the particular case of the first fragment, it MAY decide to retry via an alternate next hop instead ๐ฆ.
6.4. Applying Recoverable Fragmentation along a Diverse Path
Everything above can be read with the assumption of a serial path between a source and a destination ๐ค๏ธ. But the IPv6 over the TSCH mode of IEEE 802.15.4e (6TiSCH) architecture (see Section 4.5.3 of [6TiSCH]) defines the concept of a Track. A Track can be a complex path between a source and a destination, with Packet ARQ, Replication, Elimination, and Overhearing (PAREO) along the Track ๐. This specification can be used along any subset of the complex Track where the first fragment is flooded. The last RFRAG Acknowledgment is flooded on that same subset in the reverse direction. Intermediate RFRAG Acknowledgments can be flooded on any sub-subset of that reverse subset that reaches back to the source ๐ซง.
7. Management Considerations โญ
This specification extends [RFC8930] and requires the same parameters in the reassembling endpoint and on intermediate nodes. There is no new parameter, because echoing ECN is always on ๐ฅ. These parameters typically include the reassembly timeout at the reassembling endpoint, an inactivity cleanup timer on the intermediate nodes, and the number of messages that can be processed in parallel in all nodes.
The configuration settings introduced by this specification only apply to the fragmenting endpoint, which is in full control of the transmission. LLNs vary a lot. They can have thousands of nodes in a mesh, they can run in speeds from 10 Kbps to several Mbps at the PHY layer, they can have very different traffic densities, and they can want very different optimizations. For example, the selection of a Routing Protocol for LLNs (RPL) [RFC6550] Objective Function [RFC6552] impacts the shape of the routing graph ๐ธ๏ธ.
For that reason, only very generic guidance can be given on the settings of the fragmenting endpoint. The same goes for whether complex algorithms are needed to perform congestion control or to estimate the round-trip time ๐ค. To cover the most complex use cases, this specification enables the fragmenting endpoint to vary the fragment size, the window size, and the inter-frame gap based on the number of losses, the observed variations of the round-trip time, and the setting of the ECN bit ๐.
7.1. Protocol Parameters ๐
okay bestie, the management system SHOULD be capable of providing the parameters in this section โจ and an implementation MUST abide by those parameters and, like, never exceed the minimum and maximum configured boundaries ๐ โโ๏ธ no exceptions!!
an implementation should look at the generic recs from the IETF on congestion control and rate management for IP datagrams in [RFC8085] ๐ซถ an implementation may do congestion control by using a dynamic value of Window_Size, adapting Fragment_Size, and possibly lowering the load by adding an inter-frame gap that's longer than it needs to be ๐ in a big network where nodes fight over bandwidth, a larger Fragment_Size uses less bandwidth but also hurts fluidity and has a higher chance of getting lost in transmission ๐ญ
these are controlled by the following parameters:
inter-frame gap
the inter-frame gap is the minimum amount of time between transmissions โฑ๏ธ it controls how fast fragments get sent, the ratio of air time, and how much memory intermediate nodes use for a particular datagram ๐ง it can be used as flow control, congestion control, and/or collision control, which is honestly so versatile ๐ it MUST be set at a minimum to a value that protects the propagation of one transmission against collision with the next [RFC8930] ๐ฅ in a wireless network that uses the same frequency along a path, this might be the time for a frame to make its way over multiple hops (more on that in Section 4.2) ๐ฆ it SHOULD be augmented beyond this as needed to protect the network against congestion โจ
MinFragmentSize
MinFragmentSize is the minimum value for the Fragment_Size ๐ it MUST be lower than the minimum value of smallest 1-hop MTU that can be encountered along the path ๐
OptFragmentSize
OptFragmentSize is the value for the Fragment_Size that the fragmenting endpoint should start with ๐ธ it is greater than or equal to MinFragmentSize and less than or equal to MaxFragmentSize ๐ for the first fragment, it must account for the expansion of the IPv6 addresses and of the Hop Limit field within the MTU ๐ง for all fragments, it's a balance between the expected fluidity and the overhead of link-layer and 6LoWPAN headers โ๏ธ for a small MTU, the idea is to keep it close to the maximum, but for larger MTUs it might make sense to keep it short enough that the duty cycle of the transmitter stays bounded, e.g., to transmit at least 10 frames per second ๐
MaxFragmentSize
MaxFragmentSize is the maximum value for the Fragment_Size ๐ซ it MUST be lower than the maximum value of the smallest 1-hop MTU that can be encountered along the path ๐ a large value ups the chances of buffer bloat and transmission loss, so be careful!! ๐ฌ the value MUST be less than 512 if the unit that is defined for the PHY layer is the byte ๐ฅ
Window_Size
Window_Size MUST be at least 1 and less than 33 ๐ฆ
- If the round-trip time is known, the
Window_SizeSHOULD be set to the round-trip time divided by the time per fragment, which is the time to transmit a fragment plus the inter-frame gap ๐งฎ
Otherwise:
- A
window_sizeof 32 means that only the last fragment is acknowledged in each round ๐ซง this is the RECOMMENDED value in a half-duplex LLN, where the fragment acknowledgment eats roughly the same bandwidth on the same links as the fragments themselves ๐ - If it's set to a smaller value, more acks get generated ๐ฌ in a full-duplex network, the load on the forward path will be lower, and a small value of 3 SHOULD be configured ๐
an implementation may do its own estimate of the RTO or use a configured one โณ the ARQ process is controlled by the following parameters:
MinARQTimeOut
MinARQTimeOut is the minimum amount of time a node should wait for an RFRAG Acknowledgment before it takes the next action ๐ฐ๏ธ it MUST be more than the maximum expected round-trip time in the respective network ๐
OptARQTimeOut
OptARQTimeOut is the initial value of the RTO, which is the amount of time that a fragmenting endpoint should wait for an RFRAG Acknowledgment before it takes the next action ๐ฏ it is greater than or equal to MinARQTimeOut and less than or equal to MaxARQTimeOut ๐ see Appendix C for recs on computing the round-trip time ๐ by default, a value of 3 times the maximum expected round-trip time in the respective network is RECOMMENDED โจ
MaxARQTimeOut
MaxARQTimeOut is the maximum amount of time a node should wait for the RFRAG Acknowledgment before it takes the next action โฐ it must cover the longest expected round-trip time and be several times less than the timeout that covers the recomposition buffer at the reassembling endpoint, which is typically on the order of the minute ๐ซ an upper bound can be estimated so the datagram is either fully transmitted or dropped before an upper layer decides to retry it ๐
MaxFragRetries
MaxFragRetries is the maximum number of retries for a particular fragment ๐ a default value of 3 is RECOMMENDED ๐
an upper bound can be estimated so the datagram is either fully transmitted or dropped before an upper layer decides to retry it ๐ธ
MaxDatagramRetries
MaxDatagramRetries is the maximum number of retries from scratch for a particular datagram ๐ช a default value of 1 is RECOMMENDED ๐ an upper bound can be estimated so the datagram is either fully transmitted or dropped before an upper layer decides to retry it ๐ซถ
an implementation may be capable of doing congestion control based on ECN, see Appendix C ๐ this is controlled by the following parameter:
UseECN
UseECN indicates whether the fragmenting endpoint should react to ECN ๐ฆ the fragmenting endpoint may react to ECN by varying the Window_Size between MinWindowSize and MaxWindowSize, varying the Fragment_Size between MinFragmentSize and MaxFragmentSize, and/or increasing or reducing the inter-frame gap ๐๏ธ with this specification, if UseECN is set and a fragmenting endpoint detects a congestion, it may apply a congestion control method until the end of the datagram ๐ whereas if UseECN is reset, the endpoint does not react to congestion ๐
โโ๏ธ future specifications may provide additional parameters and capabilities ๐ฎ
7.2. Observing the Network ๐
the management system should monitor the number of retries and ECN settings that can be observed from the perspective of the fragmenting endpoint with respect to the reassembling endpoint, and reciprocally ๐ it may then tune the optimum size of Fragment_Size and of Window_Size, OptFragmentSize, and OptWindowSize, respectively, at the fragmenting endpoint toward a particular reassembling endpoint, which applies to the next datagrams ๐ it will preferably tune the inter-frame gap to increase the spacing between fragments of the same datagram and reduce the buffer bloat in the intermediate node that holds one or more fragments of that datagram ๐ซงโจ
8. Security Considerations ๐
this document specifies an instantiation of a 6LFF technique and inherits from the generic description in [RFC8930] ๐ก๏ธ the considerations in the Security Considerations section of [RFC8930] equally apply to this document ๐ซก
in addition to the threats detailed there, an attacker that is on path can prematurely end the transmission of a datagram by sending an RFRAG Acknowledgment to the fragmenting endpoint ๐ฑ it can also cause extra transmissions of fragments by resetting bits in the RFRAG Acknowledgment Bitmap, and of RFRAG Acknowledgments by forcing the Ack-Request bit in fragments that it forwards ๐จ
as indicated in [RFC8930], secure joining and link-layer security are REQUIRED to protect against those attacks, because the fragmentation protocol does not include any native security mechanisms ๐ this is non-negotiable, bestie ๐
this specification does not recommend a particular algorithm for estimating the duration of the RTO that covers the detection of the loss of a fragment with the "X" flag set ๐ซฃ regardless, an attacker on the path may slow down or discard packets, which in turn can affect the throughput of fragmented packets ๐ฅ
compared to [RFC4944], this specification reduces the Datagram_Tag to 8 bits, and the tag wraps faster than with [RFC4944] ๐ but for a constrained network where a node is expected to hold only one or a few large packets in memory, 256 is still a large number ๐ข also, the acknowledgment mechanism lets you clean up state rapidly once the packet is fully transmitted or aborted ๐งน
the abstract Virtual Recovery Buffer from [RFC8930] may be used to perform a Denial-of-Service (DoS) attack against the intermediate routers, since the routers need to maintain state per flow ๐ง the particular VRB implementation technique described in [LWIG-FRAG] allows realigning which data goes in which fragment, which causes the intermediate node to store a portion of the data and adds an attack vector that is not present with this specification ๐ฌ with this specification, the data transported in each fragment is conserved, and the state to keep does not include any data that would not fit in the previous fragment ๐
9. IANA Considerations ๐ธ
this document allocates two patterns for a total of four dispatch values for Recoverable Fragments from the "Dispatch Type Field" registry that was created by [RFC4944] and reformatted by "IPv6 over Low-Power Wireless Personal Area Network (6LoWPAN) Paging Dispatch" [RFC8025] ๐๏ธ
+-------------+------+----------------------------------+-----------+
| Bit Pattern | Page | Header Type | Reference |
+-------------+------+----------------------------------+-----------+
| 11 10100x | 0 | RFRAG - Recoverable Fragment | RFC 8931 |
+-------------+------+----------------------------------+-----------+
| 11 10100x | 1-14 | Unassigned | |
+-------------+------+----------------------------------+-----------+
| 11 10100x | 15 | Reserved for Experimental Use | RFC 8025 |
+-------------+------+----------------------------------+-----------+
| 11 10101x | 0 | RFRAG-ACK - RFRAG | RFC 8931 |
| | | Acknowledgment | |
+-------------+------+----------------------------------+-----------+
| 11 10101x | 1-14 | Unassigned | |
+-------------+------+----------------------------------+-----------+
| 11 10101x | 15 | Reserved for Experimental Use | RFC 8025 |
+-------------+------+----------------------------------+-----------+
Table 1: Additional Dispatch Value Bit Patterns ๐
10. References ๐
10.1. Normative References
Okay bestie, these are the must-read sources the spec builds on ๐โจ Here are the exact details so you can look them up:
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC4919] Kushalnagar, N., Montenegro, G., and C. Schumacher, "IPv6
over Low-Power Wireless Personal Area Networks (6LoWPANs):
Overview, Assumptions, Problem Statement, and Goals",
RFC 4919, DOI 10.17487/RFC4919, August 2007,
<https://www.rfc-editor.org/info/rfc4919>.
[RFC4944] Montenegro, G., Kushalnagar, N., Hui, J., and D. Culler,
"Transmission of IPv6 Packets over IEEE 802.15.4
Networks", RFC 4944, DOI 10.17487/RFC4944, September 2007,
<https://www.rfc-editor.org/info/rfc4944>.
[RFC6282] Hui, J., Ed. and P. Thubert, "Compression Format for IPv6
Datagrams over IEEE 802.15.4-Based Networks", RFC 6282,
DOI 10.17487/RFC6282, September 2011,
<https://www.rfc-editor.org/info/rfc6282>.
[RFC6298] Paxson, V., Allman, M., Chu, J., and M. Sargent,
"Computing TCP's Retransmission Timer", RFC 6298,
DOI 10.17487/RFC6298, June 2011,
<https://www.rfc-editor.org/info/rfc6298>.
[RFC6606] Kim, E., Kaspar, D., Gomez, C., and C. Bormann, "Problem
Statement and Requirements for IPv6 over Low-Power
Wireless Personal Area Network (6LoWPAN) Routing",
RFC 6606, DOI 10.17487/RFC6606, May 2012,
<https://www.rfc-editor.org/info/rfc6606>.
[RFC8025] Thubert, P., Ed. and R. Cragie, "IPv6 over Low-Power
Wireless Personal Area Network (6LoWPAN) Paging Dispatch",
RFC 8025, DOI 10.17487/RFC8025, November 2016,
<https://www.rfc-editor.org/info/rfc8025>.
[RFC8138] Thubert, P., Ed., Bormann, C., Toutain, L., and R. Cragie,
"IPv6 over Low-Power Wireless Personal Area Network
(6LoWPAN) Routing Header", RFC 8138, DOI 10.17487/RFC8138,
April 2017, <https://www.rfc-editor.org/info/rfc8138>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8200] Deering, S. and R. Hinden, "Internet Protocol, Version 6
(IPv6) Specification", STD 86, RFC 8200,
DOI 10.17487/RFC8200, July 2017,
<https://www.rfc-editor.org/info/rfc8200>.
[RFC8930] Watteyne, T., Ed., Thubert, P., Ed., and C. Bormann, "On
Forwarding 6LoWPAN (IPv6 over Low-Power Wireless Personal
Area Network) Fragments over a Multi-Hop IPv6 Network",
RFC 8930, DOI 10.17487/RFC8930, November 2020,
<https://www.rfc-editor.org/info/rfc8930>.
10.2. Informative References
These ones are the extra reading for the curious ๐ง They give background and context, and you don't need them to get the core spec:
[6TiSCH] Thubert, P., "An Architecture for IPv6 over the TSCH mode
of IEEE 802.15.4", Work in Progress, Internet-Draft,
draft-ietf-6tisch-architecture-29, 27 August 2020,
<https://tools.ietf.org/html/draft-ietf-6tisch-
architecture-29>.
[IEEE.802.15.4]
IEEE, "IEEE Standard for Low-Rate Wireless Networks",
IEEE Standard 802.15.4-2015,
DOI 10.1109/IEEESTD.2016.7460875, April 2016,
<http://ieeexplore.ieee.org/document/7460875/>.
[Kent] Kent, C. and J. Mogul, "Fragmentation Considered Harmful",
SIGCOMM '87: Proceedings of the ACM workshop on Frontiers
in computer communications technology, pp. 390-401,
DOI 10.1145/55483.55524, August 1987,
<http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-
87-3.pdf>.
[LWIG-FRAG]
Bormann, C. and T. Watteyne, "Virtual reassembly buffers
in 6LoWPAN", Work in Progress, Internet-Draft, draft-ietf-
lwig-6lowpan-virtual-reassembly-02, 9 March 2020,
<https://tools.ietf.org/html/draft-ietf-lwig-6lowpan-
virtual-reassembly-02>.
[RFC2914] Floyd, S., "Congestion Control Principles", BCP 41,
RFC 2914, DOI 10.17487/RFC2914, September 2000,
<https://www.rfc-editor.org/info/rfc2914>.
[RFC3031] Rosen, E., Viswanathan, A., and R. Callon, "Multiprotocol
Label Switching Architecture", RFC 3031,
DOI 10.17487/RFC3031, January 2001,
<https://www.rfc-editor.org/info/rfc3031>.
[RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, "The Addition
of Explicit Congestion Notification (ECN) to IP",
RFC 3168, DOI 10.17487/RFC3168, September 2001,
<https://www.rfc-editor.org/info/rfc3168>.
[RFC4963] Heffner, J., Mathis, M., and B. Chandler, "IPv4 Reassembly
Errors at High Data Rates", RFC 4963,
DOI 10.17487/RFC4963, July 2007,
<https://www.rfc-editor.org/info/rfc4963>.
[RFC5033] Floyd, S. and M. Allman, "Specifying New Congestion
Control Algorithms", BCP 133, RFC 5033,
DOI 10.17487/RFC5033, August 2007,
<https://www.rfc-editor.org/info/rfc5033>.
[RFC5681] Allman, M., Paxson, V., and E. Blanton, "TCP Congestion
Control", RFC 5681, DOI 10.17487/RFC5681, September 2009,
<https://www.rfc-editor.org/info/rfc5681>.
[RFC6550] Winter, T., Ed., Thubert, P., Ed., Brandt, A., Hui, J.,
Kelsey, R., Levis, P., Pister, K., Struik, R., Vasseur,
JP., and R. Alexander, "RPL: IPv6 Routing Protocol for
Low-Power and Lossy Networks", RFC 6550,
DOI 10.17487/RFC6550, March 2012,
<https://www.rfc-editor.org/info/rfc6550>.
[RFC6552] Thubert, P., Ed., "Objective Function Zero for the Routing
Protocol for Low-Power and Lossy Networks (RPL)",
RFC 6552, DOI 10.17487/RFC6552, March 2012,
<https://www.rfc-editor.org/info/rfc6552>.
[RFC6554] Hui, J., Vasseur, JP., Culler, D., and V. Manral, "An IPv6
Routing Header for Source Routes with the Routing Protocol
for Low-Power and Lossy Networks (RPL)", RFC 6554,
DOI 10.17487/RFC6554, March 2012,
<https://www.rfc-editor.org/info/rfc6554>.
[RFC7554] Watteyne, T., Ed., Palattella, M., and L. Grieco, "Using
IEEE 802.15.4e Time-Slotted Channel Hopping (TSCH) in the
Internet of Things (IoT): Problem Statement", RFC 7554,
DOI 10.17487/RFC7554, May 2015,
<https://www.rfc-editor.org/info/rfc7554>.
[RFC7567] Baker, F., Ed. and G. Fairhurst, Ed., "IETF
Recommendations Regarding Active Queue Management",
BCP 197, RFC 7567, DOI 10.17487/RFC7567, July 2015,
<https://www.rfc-editor.org/info/rfc7567>.
[RFC8085] Eggert, L., Fairhurst, G., and G. Shepherd, "UDP Usage
Guidelines", BCP 145, RFC 8085, DOI 10.17487/RFC8085,
March 2017, <https://www.rfc-editor.org/info/rfc8085>.
[RFC8087] Fairhurst, G. and M. Welzl, "The Benefits of Using
Explicit Congestion Notification (ECN)", RFC 8087,
DOI 10.17487/RFC8087, March 2017,
<https://www.rfc-editor.org/info/rfc8087>.
[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,
<https://www.rfc-editor.org/info/rfc8201>.
[RFC8900] Bonica, R., Baker, F., Huston, G., Hinden, R., Troan, O.,
and F. Gont, "IP Fragmentation Considered Fragile",
BCP 230, RFC 8900, DOI 10.17487/RFC8900, September 2020,
<https://www.rfc-editor.org/info/rfc8900>.
Appendix A. Rationale ๐ธ
Okay so large packets in Wireless Sensor Networks aren't the everyday vibe, but there are actually a bunch of uses for them ๐ฆ These usages might not be the most typical or make up the biggest chunk of traffic over the LLN. Still, the functionality they support can be so important that it's worth extra care to get large packets across the LLN properly ๐
The list of those usages includes:
Towards the LLN node:
- Firmware update ๐ฅ: For example, a new version of the LLN node software is downloaded from a system manager over unicast or multicast services. Such a reflashing operation typically involves updating a large number of similar LLN nodes over a relatively short period of time.
- Packages of commands ๐ฆ: A number of commands or a full configuration can be packaged as a single message to ensure consistency and enable atomic execution or complete rollback. Until such commands are fully received and interpreted, the intended operation will not take effect.
From the LLN node:
- Waveform captures ๐: A number of consecutive samples are measured at a high rate for a short time and then are transferred from a sensor to a gateway or an edge server as a single large report.
- Data logs ๐งพ: LLN nodes may generate large logs of sampled data for later extraction. LLN nodes may also generate system logs to assist in diagnosing problems on the node or network.
- Large data packets ๐: Rich data types might require more than one fragment.
Uncontrolled firmware download or waveform upload can easily result in a massive increase of the traffic and saturate the network. Not it. ๐
When a fragment is lost in transmission, the lack of recovery in the original fragmentation system of RFC 4944 implies that all fragments would need to be resent. That further contributes to the congestion that caused the initial loss and potentially leads to congestion collapse ๐
This saturation may lead to excessive radio interference or random early discard (leaky bucket) in relaying nodes. Additional queuing and memory congestion may result while waiting for a low-power next hop to emerge from its sleep state ๐ญ
Considering that RFC 4944 defines an MTU as 1280 bytes, and that in most incarnations (except 802.15.4g) an IEEE Std 802.15.4 frame can limit the link-layer payload to as few as 74 bytes, a packet might be fragmented into at least 18 fragments at the 6LoWPAN shim layer. Taking into account the worst-case header overhead for 6LoWPAN Fragmentation and Mesh Addressing headers will increase the number of required fragments to around 32. This level of fragmentation is much higher than what's traditionally experienced over the Internet with IPv4 fragments. At the same time, the use of radios increases the probability of transmission loss, and mesh-under techniques compound that risk over multiple hops โจ
Mechanisms such as TCP or application-layer segmentation could be used to support end-to-end reliable transport. One option to support bulk data transfer over a frame-size-constrained LLN is to set the Maximum Segment Size to fit within the link maximum frame size. However, doing so can add significant header overhead to each 802.15.4 frame and cause extraneous acknowledgments across the LLN compared to the method in this specification ๐
Appendix B. Requirements โจ
okay bestie, so for one-hop stuff a bunch of LLN link layers already have a local acknowledgment mechanism that's honestly enough to spot and recover lost fragments ๐ฆ. But in a multi-hop setup, an end-to-end fragment recovery mechanism can be a really good sidekick to hop-by-hop Medium Access Control (MAC) recovery ๐. So this doc brings in a simple protocol to recover individual fragments between 6LFF endpoints that might be multiple hops away ๐ธ.
The method is built around these LLN requirements, and it's giving very specific vibes ๐:
- Number of fragments: the recovery mechanism must support highly fragmented packets, with a maximum of 32 fragments per packet ๐ง.
- Minimum acknowledgment overhead: the radio is half duplex, and there's silent time spent in the various medium access mechanisms, so an acknowledgment eats up roughly as many resources as a data fragment ๐ญ. The new end-to-end fragment recovery mechanism should be able to acknowledge multiple fragments in a single message, and it should not require an acknowledgment at all if fragments are already protected at a lower layer ๐ .
- Controlled latency: the recovery mechanism must succeed or give up within the time boundary imposed by the recovery process of the upper-layer protocols โฐ.
- Optional congestion control: when lots of concurrent flows aggregate, the radio network can get saturated and tip into congestion collapse ๐. The recovery mechanism should provide means for controlling the number of fragments in transit over the LLN ๐ซถ.
Appendix C. Considerations on Congestion Control ๐
So a multi-hop LLN is a super sensitive environment, because a large population of its nodes has limited queuing capabilities ๐ฅบ. That's why this document recommends a simple and conservative approach to congestion control, based on TCP congestion avoidance ๐.
Congestion on the forward path is assumed in case of packet loss, and packet loss is assumed upon timeout โณ. This document lets you control the number of outstanding fragments, meaning the ones that have been transmitted, haven't been acknowledged yet, and are still covered by the ARQ timer ๐ฆ.
Congestion on the forward path can also be indicated by an ECN mechanism ๐ธ. Whether and how ECN [RFC3168] is carried out over the LoWPAN is out of scope, though ๐. What this document does provide is a way for the destination endpoint to echo an ECN indication back to the fragmenting endpoint in an acknowledgment message, as shown in Figure 4 in Section 5.2 ๐.
Echoing ECN at the reassembling endpoint is mandatory ๐ฅ. The fragmenting side, though, only gets minimalistic behavior in this spec. If an "E" flag is received, the window SHOULD be reduced at least by 1 and at max to 1 โจ. Halving the window for each "E" flag received could be a good compromise, but it needs further experimentation ๐งช. A very simple implementation may just reset the window to 1, so the fragments are sent and acknowledged one by one ๐.
Also, any action taken upon detecting congestion only applies to the transmission of one datagram ๐ . The next datagram starts with the configured Window_Size again ๐ท.
The exact use of the Acknowledgment Request flag and of the window is left to implementation ๐ซง. An optimistic implementation could send all the fragments up to Window_Size, setting the Acknowledgment Request "X" flag only on the last fragment ๐. Then it waits for the bitmap, which means a gap of half a round-trip time, and resends the losses ๐ค. A pessimistic implementation could set the "X" flag on the first fragment to check that the path works, and only open the window upon receiving the RFRAG-ACK ๐ข. It could then set an "X" flag again on the second fragment and use the window as a credit to send up to Window_Size before it gets blocked ๐. In that case, if the RFRAG-ACK comes back before the window starves, the gating factor is the inter-frame gap โญ. If the RFRAG-ACK doesn't arrive in time, the Window_Size is the gating factor, and the transmission of the datagram is delayed ๐ฉ.
Now here's the plot twist ๐ญ: even though the inter-frame gap can be used as a flow control or congestion control measure, it also plays a critical role in wireless collision avoidance ๐ฆ. When a mesh operates on the same channel over multiple hops, forwarding one fragment over a certain hop may collide with forwarding the next fragment, which is following over a previous hop but sits in the same interference domain ๐ฅ. To prevent this, the fragmenting endpoint is required to pace individual fragments within a transmit window with an inter-frame gap ๐ฐ๏ธ. This makes sure a given fragment is only sent once the previous fragment has had a chance to progress beyond the interference domain of this hop ๐. For 6TiSCH [6TiSCH], which operates over the Time-Slotted Channel Hopping (TSCH) mode of operation of IEEE 802.15.4 [RFC7554], a fragment is forwarded over a different channel at a different time ๐ถ. So it makes full sense to transmit the next fragment as soon as the previous fragment has had its chance to be forwarded at the next hop ๐.
Depending on the setting of the Window_Size and the inter-frame gap, how the window is used, and the number of hops, the Window_Size may or may not become the gating factor that blocks transmission ๐คทโโ๏ธ. If the sender uses the Window_Size as a credit:
- a conservative Window_Size of, say, 3 will be the gating factor that limits the transmission rate of the sender, and causes transmission gaps longer than the inter-frame gap, as soon as the number of hops exceeds 3 in a TSCH network and 5-9 in a single frequency mesh ๐. The more hops, the more the starving window will add to the latency of the transmission ๐ต.
- Aligning the Window-Size to the round-trip time divided by the time per fragment is recommended, because it lines the Window-Size up with the time it takes to get the RFAG_ACK back before the window starves โฑ๏ธ. A Window-Size higher than that increases the chances of congestion but doesn't improve the forward throughput ๐. Since the RFRAG-ACK takes the same path as the fragment, with the assumption that it travels at roughly the same speed, an inter-frame gap that separates fragments by 2 hops leads to a Window_Size that is roughly the number of hops ๐ง .
- Setting the Window-Size to 32 minimizes the cost of the acknowledgment in a constrained network and frees bandwidth for the fragments in a half-duplex network ๐. Using it increases the risk of congestion if a bottleneck forms, but it optimizes the use of resources under normal conditions ๐ซ. When it's used, the only protection for the network is the inter-frame gap, which must be chosen wisely to prevent a bottleneck from forming ๐ก๏ธ.
From the standpoint of a source 6LoWPAN endpoint, an outstanding fragment is one that was sent but for which no explicit acknowledgment has been received yet ๐ฌ. That means the fragment might still be on the path, received but not yet acknowledged, or the acknowledgment might be on its way back ๐. It's also possible that either the fragment or the acknowledgment was lost on the way ๐ฟ.
From the fragmenting endpoint's standpoint, all outstanding fragments might still be in the network and contributing to its congestion ๐ซ๏ธ. There's an assumption, though, that after a certain amount of time, a frame is either received or lost, so it's no longer causing congestion โ . That amount of time can be estimated based on the round-trip time between the 6LoWPAN endpoints โ. For lack of a more adapted technique, the method detailed in "Computing TCP's Retransmission Timer" [RFC6298] may be used for that computation ๐งฎ.
This specification provides the necessary tools for the fragmenting endpoint to take congestion control actions and protect the network, but it leaves the implementation free to select which action to take ๐๏ธ. The plan is to use it to build experience and specify the congestion control actions more precisely in one or more future specifications ๐ฎ. "Congestion Control Principles" [RFC2914] and "Specifying New Congestion Control Algorithms" [RFC5033] offer hints and wisdom that should help along the way ๐.
[RFC7567] and [RFC5681] go deeper on why congestion control is needed and how TCP handles it ๐ค. Basically, the goal here is to manage the number of fragments in the network ๐ฏ. That's achieved by reducing the number of outstanding fragments over a congested path, which means throttling the sources ๐ฐ.
Acknowledgments ๐ซถ
The author would like to thank Michel Veillette, Dario Tedeschi, Laurent Toutain, Carles Gomez Montenegro, Thomas Watteyne, and Michael Richardson for their in-depth reviews and comments ๐. Many thanks also to Roman Danyliw, Peter Yee, Colin Perkins, Tirumaleswar Reddy.K, รric Vyncke, Warren Kumari, Magnus Westerlund, Erik Nordmark, and especially Benjamin Kaduk and Mirja Kรผhlewind for their careful reviews and help during the IETF Last Call and IESG review process ๐. Thanks to Jonathan Hui, Jay Werb, Christos Polyzois, Soumitri Kolavennu, Pat Kinney, Margaret Wasserman, Richard Kelsey, Carsten Bormann, and Harry Courtice for their various contributions in the long process that led to this document ๐ธ.
Author's Address ๐ฆ
Pascal Thubert (editor)
Cisco Systems, Inc.
Building D
45 Allee des Ormes - BP1200
06254 MOUGINS - Sophia Antipolis
France
Phone: +33 497 23 26 34
Email: pthubert@cisco.com
๐ฆ where this page comes from
- ietf: rfc8931 2020-11
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms