%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D'}}}%%
flowchart LR
subgraph FRAG1["First Fragment (FRAG1) Header"]
direction LR
Disp["11000<br/>000<br/>5 bits<br/>Dispatch"]
Size["Datagram<br/>Size<br/>11 bits<br/>(0-2047 bytes)"]
Tag["Datagram<br/>Tag<br/>16 bits<br/>(Unique ID)"]
Pay["Payload<br/>Variable<br/>(Headers + Data)"]
end
Disp --> Size --> Tag --> Pay
style Disp fill:#2C3E50,stroke:#16A085,color:#fff
style Size fill:#16A085,stroke:#2C3E50,color:#fff
style Tag fill:#E67E22,stroke:#2C3E50,color:#fff
style Pay fill:#7F8C8D,stroke:#2C3E50,color:#fff
962 6LoWPAN Fragmentation and Reassembly
962.1 Learning Objectives
By the end of this chapter, you will be able to:
- Explain Fragmentation Need: Understand why IPv6’s 1280-byte MTU requires fragmentation over 802.15.4
- Analyze Fragment Headers: Parse FRAG1 and FRAGN header formats
- Calculate Reliability Impact: Compute end-to-end delivery rates for fragmented packets
- Implement Reassembly: Design buffer management for fragment collection
- Avoid Fragmentation Pitfalls: Apply best practices to minimize fragmentation overhead
962.2 Prerequisites
Before diving into this chapter, you should be familiar with:
- 6LoWPAN Overview: Basic understanding of 6LoWPAN’s purpose
- 6LoWPAN Header Compression: IPHC compression mechanics
- IEEE 802.15.4 Fundamentals: Frame size constraints (127 bytes max)
962.3 The Fragmentation Problem
Problem: IPv6 requires a 1280-byte minimum MTU, but 802.15.4 frames are only 127 bytes.
Solution: 6LoWPAN fragments large IPv6 packets across multiple 802.15.4 frames.
962.3.1 Fragmentation Thresholds
802.15.4 Max Frame Size: 127 bytes
MAC Header: ~21 bytes (addressing, sequence, FCS)
Security Header (if AES-128): ~21 bytes
Usable Payload (no security): 102 bytes
Usable Payload (with AES-128): 81 bytes
When Fragmentation Triggers:
- Compressed IPv6/UDP header (6 bytes) + Application payload > 102 bytes
- Example: 6-byte header + 97-byte CoAP payload = 103 bytes -> REQUIRES FRAGMENTATION
962.4 Fragment Header Formats
962.4.1 First Fragment (FRAG1)
FRAG1 header format: 5-bit dispatch (11000), 11-bit datagram size, 16-bit unique tag, followed by compressed headers and first payload chunk.
962.4.2 Subsequent Fragments (FRAGN)
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D'}}}%%
flowchart LR
subgraph FRAGN["Subsequent Fragment (FRAGN) Header"]
direction LR
Disp2["11100<br/>000<br/>5 bits<br/>Dispatch"]
Size2["Datagram<br/>Size<br/>11 bits"]
Tag2["Datagram<br/>Tag<br/>16 bits"]
Off["Offset<br/>/8 bytes<br/>8 bits<br/>(0-2040)"]
Pay2["Payload<br/>Variable"]
end
Disp2 --> Size2 --> Tag2 --> Off --> Pay2
style Disp2 fill:#2C3E50,stroke:#16A085,color:#fff
style Size2 fill:#16A085,stroke:#2C3E50,color:#fff
style Tag2 fill:#E67E22,stroke:#2C3E50,color:#fff
style Off fill:#E67E22,stroke:#2C3E50,color:#fff
style Pay2 fill:#7F8C8D,stroke:#2C3E50,color:#fff
FRAGN header format: 5-bit dispatch (11100), 11-bit size, 16-bit tag matching FRAG1, 8-bit offset (position/8, max 255 x 8 = 2040 bytes), followed by payload chunk.
962.5 Fragmentation Example
Scenario: Fragmenting a 307-byte packet
Original packet: 7-byte compressed header + 300-byte payload = 307 bytes
802.15.4 payload available: 102 bytes
Fragment 1:
FRAG1 header: 4 bytes (11000 + size=307 + tag=0x5A3C)
Compressed headers: 7 bytes (IPHC + NHC)
Payload chunk 1: 91 bytes
Total: 4 + 7 + 91 = 102 bytes
Fragment 2:
FRAGN header: 5 bytes (11100 + size=307 + tag=0x5A3C + offset=91/8=11)
Payload chunk 2: 97 bytes
Total: 5 + 97 = 102 bytes
Fragment 3:
FRAGN header: 5 bytes (offset=188/8=23)
Payload chunk 3: 97 bytes
Total: 102 bytes
Fragment 4:
FRAGN header: 5 bytes (offset=285/8=35)
Payload chunk 4: 22 bytes (final chunk)
Total: 27 bytes
Total: 91 + 97 + 97 + 22 = 307 bytes
Overhead: 4 + 5 + 5 + 5 = 19 bytes (6.2% overhead)
962.6 Fragmentation Overhead Summary
| Packet Size | Fragments | Header Overhead | Overhead % |
|---|---|---|---|
| 102 bytes | 1 | 0 bytes | 0% |
| 307 bytes | 4 | 19 bytes | 6.2% |
| 512 bytes | 6 | 29 bytes | 5.7% |
| 1280 bytes | 14 | 69 bytes | 5.4% |
962.7 Reliability Impact: The Fragment Loss Problem
Critical Challenge: If ANY fragment is lost, the ENTIRE IPv6 packet must be discarded and retransmitted.
962.7.1 Reliability Calculation
With 5% per-fragment loss rate:
1 fragment: (0.95)^1 = 95.0% success
4 fragments: (0.95)^4 = 81.5% success
12 fragments: (0.95)^12 = 54.0% success
20 fragments: (0.95)^20 = 35.8% success
Best practice: Keep packets under 102 bytes to avoid fragmentation!
The Trap: Sending standard IPv6 packets (1280+ bytes) to 6LoWPAN devices without considering fragmentation overhead.
The Math That Hurts:
Standard IPv6 MTU: 1280 bytes
6LoWPAN fragment payload: ~97 bytes (after FRAGN header)
Fragments needed: ceiling(1280 / 97) = 14 fragments
Per-fragment loss rate: 5% (typical wireless)
All 14 must succeed: 0.95^14 = 48.8%
More than half of all packets FAIL to deliver!
Real-World Impact: - CoAP block-wise transfer degrades to single-fragment blocks - DTLS handshakes (typically 1000+ bytes) require 10+ fragments - Firmware updates become extremely unreliable
The Fix: 1. Application layer: Use CoAP block-wise transfer with 64-byte blocks 2. Transport layer: Keep DTLS records small (disable extensions) 3. Network layer: Configure IPv6 path MTU discovery 4. Border router: Fragment toward 6LoWPAN, reassemble toward internet
962.8 Knowledge Check: Fragmentation Reliability
962.9 Reassembly Process
962.9.1 Reassembly Steps
- Receive FRAG1: Allocate reassembly buffer (full datagram size), start 60-second timer
- Store fragments: Place payload at correct offset (derived from offset field x 8)
- Track completion: Mark which bytes have been received using bitmap
- Receive final fragment: When all bytes filled, pass complete packet to IPv6 layer
- Timeout handling: If timer expires before completion, discard all fragments
962.9.2 Memory Requirements
Per concurrent fragmented packet:
- Reassembly buffer: Up to 2047 bytes (11-bit size limit)
- Fragment bitmap: 256 bits (track which 8-byte chunks received)
- Metadata: Tag, size, timer, source address
- Total: ~2.3 KB per concurrent reassembly
Typical device (4 KB RAM):
- Can handle 1-2 concurrent fragmentations
- Important: Limit application payload sizes!
962.9.3 Code Example: Reassembly Implementation
// Contiki-NG: 6LoWPAN fragmentation buffer management
#include "net/ipv6/sicslowpan.h"
#define SICSLOWPAN_REASS_CONTEXTS 3 // Concurrent reassembly contexts
#define SICSLOWPAN_FRAGMENT_TIMEOUT 60 // Seconds
// Reassembly context structure
struct sicslowpan_frag_buf {
uint16_t datagram_size; // Total IPv6 packet size (e.g., 1200 bytes)
uint16_t datagram_tag; // Fragment group identifier
uint8_t *reassembly_buffer; // Buffer holding fragments as they arrive
uint8_t *bitmap; // Track which fragments received
clock_time_t timeout; // When to discard incomplete datagram
};
static struct sicslowpan_frag_buf frag_contexts[SICSLOWPAN_REASS_CONTEXTS];
// Allocate buffer for new fragmented datagram
int sicslowpan_fragment_alloc(uint16_t datagram_size, uint16_t datagram_tag) {
int i;
// Find free reassembly context
for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
if(frag_contexts[i].datagram_size == 0) {
// Allocate buffer for full IPv6 packet
frag_contexts[i].reassembly_buffer = malloc(datagram_size);
if(frag_contexts[i].reassembly_buffer == NULL) {
printf("ERROR: Out of memory for reassembly (need %u bytes)\n", datagram_size);
return -1; // Out of memory!
}
frag_contexts[i].datagram_size = datagram_size;
frag_contexts[i].datagram_tag = datagram_tag;
frag_contexts[i].timeout = clock_time() + SICSLOWPAN_FRAGMENT_TIMEOUT * CLOCK_SECOND;
return i;
}
}
printf("ERROR: No free reassembly context (all %d in use)\n", SICSLOWPAN_REASS_CONTEXTS);
return -1; // All contexts in use
}
// Timeout handler - discard incomplete datagrams
void sicslowpan_fragment_timeout_check(void) {
int i;
for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
if(frag_contexts[i].datagram_size > 0 &&
clock_time() > frag_contexts[i].timeout) {
printf("Timeout: Discarding incomplete datagram tag=%u\n",
frag_contexts[i].datagram_tag);
// Free resources
free(frag_contexts[i].reassembly_buffer);
free(frag_contexts[i].bitmap);
frag_contexts[i].datagram_size = 0;
}
}
}962.10 Avoiding Fragmentation: Best Practices
962.10.1 Payload Size Guidelines
| Payload Size | Fragments | Reliability | Recommendation |
|---|---|---|---|
| 0-60 bytes | 1 | 95%+ | Sweet spot |
| 60-100 bytes | 1-2 | 90%+ | Acceptable |
| 100-200 bytes | 2-3 | 80-90% | Caution |
| 200-500 bytes | 3-6 | 60-80% | Avoid if possible |
| 500+ bytes | 6+ | <60% | Use different approach |
962.10.2 Alternative Approaches
1. Application-Layer Segmentation (CoAP Block-Wise Transfer)
Split large data into 64-byte CoAP blocks:
- Each block fits in single 802.15.4 frame
- CoAP handles acknowledgment per block
- Selective retransmission (only failed blocks)
- Much more reliable than fragmentation
2. Border Router Handling
Sensor -> [Small packets] -> Border Router
Border Router -> [Reassemble/Fragment] -> Internet
Keep 6LoWPAN side small, let border router handle
internet-size packets on the Ethernet side.
3. Use Different Protocol for Large Data
- Wi-Fi for camera sensors (if power permits)
- NB-IoT/LTE-M for occasional large uploads
- 6LoWPAN only for small telemetry
Multicast + Fragmentation = Disaster: - Each receiver has different fragment loss patterns - Sender can’t retransmit (no ACKs in multicast) - If 10 receivers all miss different fragments, 100% packet loss
Rule: NEVER use fragmentation with multicast! Keep multicast payloads under 60 bytes.
962.11 Summary
This chapter explored 6LoWPAN’s fragmentation and reassembly mechanism:
- Fragmentation is necessary because IPv6 requires 1280-byte MTU but 802.15.4 frames are only 127 bytes
- FRAG1 and FRAGN headers carry size, tag, and offset for reassembly tracking
- Reliability drops exponentially with fragment count: 12 fragments at 85.7% per-fragment success yields only 54% overall
- Memory requirements are significant: each concurrent reassembly needs full datagram buffer allocation
- Best practice: Keep payloads under 60-100 bytes to avoid fragmentation entirely
- Alternatives: CoAP block-wise transfer, border router handling, or different protocols for large data
962.12 What’s Next
Continue to:
- 6LoWPAN Routing with RPL: Mesh networking and route optimization
- 6LoWPAN Deployment: Real-world deployment scenarios