RFC 9914

Root-Initiated Routing State in the Routing Protocol for Low-Power and Lossy Networks (RPL)

๐Ÿ“… published April 2026, from ietf

RFC 9914: Root-Initiated Routing State in the Routing Protocol for Low-Power and Lossy Networks (RPL) ๐ŸŽ€

okay bestie, title block first ๐Ÿ’… this one is a Standards Track doc from April 2026, so it's the real deal โœจ

  • Authors: P. Thubert, Ed. (Independent), R.A. Jadhav (AccuKnox), and M. Richardson (Sandelman) ๐Ÿซถ
  • From: the Internet Engineering Task Force (IETF) ๐ŸŒˆ
  • ISSN: 2070-1721
  • It updates RFC 6550, RFC 6553, and RFC 8138 ๐Ÿ”ฅ

Abstract โœจ

okay so RPL (that's RFC 6550) lets data packets get routed along a Destination-Oriented Directed Acyclic Graph (DODAG) ๐Ÿงš the catch is that the default route setup leans on hop-by-hop forwarding along the DODAG, and that's not always the most efficient vibe ๐Ÿ™ˆ this doc introduces DAO Projection, which lets an RPL Root or an external controller install optimized routes inside the RPL domain ๐Ÿ’– DAO Projections can make optimized unicast or multicast routes that don't strictly follow the DODAG shape, so you get better routing efficiency, reliability, availability, and resource utilization โœจ two flavours of Projected Routes (P-Routes) get specced here, Storing Mode and Non-Storing Mode ๐Ÿฆ‹ it also walks through the signaling needed to set up, maintain, and remove these routes ๐Ÿ’… and yes, it updates RFCs 6550, 6553, and 8138 ๐Ÿซถ

Status of This Memo ๐Ÿ“œ

This is an Internet Standards Track document ๐Ÿ”ฅ

It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community ๐Ÿ’œ it got public review and was approved for publication by the Internet Engineering Steering Group (IESG) โœจ if you want more 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/rfc9914 ๐ŸŒธ

Copyright (c) 2026 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 in effect on the publication date ๐Ÿ“œ please read those carefully, because they spell out your rights and restrictions for this doc ๐Ÿ™ˆ and if you extract Code Components from here, they must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Revised BSD License ๐Ÿซถ

Table of Contents ๐Ÿ—‚๏ธ

   1.  Introduction
   2.  Terminology
     2.1.  Requirements Language
     2.2.  Terms and Concepts
     2.3.  Glossary
     2.4.  Domain Terms
       2.4.1.  Projected Route
       2.4.2.  Projected DAO
       2.4.3.  Path
       2.4.4.  Routing Stretch
       2.4.5.  Track
   3.  Context and Goal
     3.1.  RPL Applicability
     3.2.  Multi-Topology Routing and Loop Avoidance
     3.3.  Requirements
       3.3.1.  Loose Source Routing
       3.3.2.  Forward Routes
     3.4.  On Tracks
       3.4.1.  Building Tracks with RPL
       3.4.2.  Tracks and RPL Instances
     3.5.  Path Signaling
       3.5.1.  Using Storing Mode Segments
       3.5.2.  Using Non-Storing Mode Joining Tracks
     3.6.  Complex Tracks
     3.7.  Scope and Expectations
       3.7.1.  External Dependencies
       3.7.2.  Relationship to Other IETF Specifications
   4.  Extending and Amending Existing RFCs
     4.1.  Extending RFC 6550
       4.1.1.  Projected DAO
       4.1.2.  Projected DAO Acknowledgment
       4.1.3.  Via Information Option
       4.1.4.  Sibling Information Option
       4.1.5.  P-DAO Request
       4.1.6.  Amending the RPI
       4.1.7.  Additional Flag in the RPL DODAG Configuration Option
     4.2.  Extending RFC 6553
     4.3.  Extending RFC 8138
   5.  New RPL Control Messages and Options
     5.1.  New P-DAO Request Control Message
     5.2.  New PDR-ACK Control Message
     5.3.  Via Information Options
     5.4.  Sibling Information Option
   6.  Root-Initiated Routing State
     6.1.  RPL Network Setup
     6.2.  Requesting a Track
     6.3.  Identifying a Track
     6.4.  Installing a Track
       6.4.1.  Signaling a Projected Route
       6.4.2.  Installing a Track Segment with a Storing Mode P-Route
       6.4.3.  Installing a Protection Path with a Non-Storing Mode
               P-Route
     6.5.  Tearing Down a P-Route
     6.6.  Maintaining a Track
       6.6.1.  Maintaining a Track Segment
       6.6.2.  Maintaining a Protection Path
     6.7.  Encapsulating and Forwarding Along a Track
     6.8.  Compression of RPL Artifacts
   7.  Less-Constrained Variations
     7.1.  Storing Mode Main DODAG
     7.2.  A Track as a Full DODAG
   8.  Profiles
   9.  Backwards Compatibility
   10. Security Considerations
   11. IANA Considerations
     11.1.  RPL DODAG Configuration Option Flag
     11.2.  Elective 6LoWPAN Routing Header Type
     11.3.  Critical 6LoWPAN Routing Header Type
     11.4.  Registry for RPL Option Flags
     11.5.  RPL Control Codes
     11.6.  RPL Control Message Options
     11.7.  Registry for Projected DAO Request Flags
     11.8.  Registry for Projected DAO Request Acknowledgment
             (PDR-ACK) Flags
     11.9.  Registry for PDR-ACK Acceptance Status Values
     11.10. Registry for PDR-ACK Rejection Status Values
     11.11. Registry for Via Information Options Flags
     11.12. Registry for Sibling Information Option Flags
     11.13. Destination Advertisement Object Flag
     11.14. Destination Advertisement Object Acknowledgment Flag
     11.15. ICMPv6 Error Code
     11.16. RPL Rejection Status Values
   12. References
     12.1.  Normative References
     12.2.  Informative References
   Acknowledgments
   Authors' Addresses

1. Introduction ๐Ÿงš

okay so RPL [RPL] is a Distance Vector protocol and it's honestly perfect for low-energy Internet of Things (IoT) networks ๐ŸŒธ where the constrained nodes can't keep the full view of the topology, and stretched paths are totally acceptable (way better than the signaling and state overhead of keeping shortest paths up to date) ๐Ÿ’… RPL is also anisotropic, which means how it works depends on which way the links point, either down from the Root or up towards it ๐Ÿฆ‹ the default route gets advertised down, while more-specific paths get advertised up along a limited set of links โœจ

RPL forms Destination-Oriented Directed Acyclic Graphs (DODAGs) ๐ŸŒˆ and the Root is often the border router that connects the RPL domain to the IP backbone ๐Ÿซถ routers inside the DODAG route up along the graph toward the Root for the default route, and down toward destinations inside the RPL domain for more-specific routes ๐Ÿ’– this spec expects a pre-existing RPL Instance with an associated DODAG and RPL Root, which we call the main Instance, main DODAG, and main Root ๐ŸŽ€ the main Instance runs in RPL Non-Storing Mode of Operation (MOP) ๐Ÿ”ฅ

Here's the new bit ๐Ÿ‘‘ an abstract routing function called a Path Computation Element (PCE) (it could live in a central controller or be collocated with the main Root) teams up with the main Root to compute extra paths between nodes in the main Instance โœจ in Non-Storing Mode, the base topology info that gets passed to the PCE (aka the knowledge of the main DODAG) is already sitting at the Root ๐Ÿงš this spec adds protocol extensions that enrich the Root's topology info with sibling relationships that are usable but aren't used to form the main DODAG ๐Ÿ’œ

Based on usage, path length, and what resources are available (like battery levels and reservable buffers in the nodes), the PCE has global visibility and can optimize the computed routes for application needs ๐Ÿ’… that includes providing path redundancy ๐Ÿ™ˆ this spec also adds extensions that let the Root project (advertise from a remote location) those computed paths into the RPL domain as Projected Routes (a.k.a. P-Routes) on behalf of the PCE ๐Ÿฆ‹

A P-Route can be installed in either Storing or Non-Storing Mode ๐ŸŒˆ which can lead to hybrid situations where the P-Route's Mode is different from the RPL main Instance's Mode ๐Ÿซถ P-Routes can be stand-alone segments that shrink the size of the Source Routing Headers (SRHs), using loose source routing operations down the main RPL DODAG โœจ a P-Route can also be a protection path, and you can combine and interleave P-Routes to form a recovery graph called a Track ๐Ÿ’– a Track is signaled as a separate RPL Instance associated with a main RPL Instance, and the RPL routers that form the Track are also members of the main DODAG ๐ŸŽ€ the Track gives you underlay shortcuts using its own RIB, which is separate from the main Instance's RIB and has a higher precedence ๐Ÿ‘‘

2. Terminology ๐Ÿ’–

2.1. Requirements Language ๐Ÿ”‘

okay this part is the key words bit, so pay attention ๐Ÿ™ˆ 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 ๐Ÿ”ฅ

Also, the terms "Extends" and "Amends" are used as per [NEW-TAGS], Section 3 โœจ

2.2. Terms and Concepts โœจ

okay bestie, before we get into the spicy stuff, here are the reads this doc keeps referencing ๐Ÿ“š keep them open in another tab ๐Ÿ’–:

  • "RPL: IPv6 Routing Protocol for Low-Power and Lossy Networks" [RPL]
  • "An Architecture for IPv6 over the Time-Slotted Channel Hopping Mode of IEEE 802.15.4 (6TiSCH)" [RFC9030]
  • "Deterministic Networking Architecture" [RFC8655]
  • "Using RPI Option Type, Routing Header for Source Routes, and IPv6-in-IPv6 Encapsulation in the RPL Data Plane" [RFC9008]
  • "Reliable and Available Wireless (RAW) Architecture" [RAW-ARCH]
  • "Terms Used in Routing for Low-Power and Lossy Networks" [RFC7102]

the 6TiSCH, DetNet, and RAW architectures all use "Track" and "recovery graph" for the same idea, just in different environments ๐Ÿงš this document says "Track" for that concept, and it only builds Tracks that are DODAGs, meaning all links are oriented from ingress to egress. this spec also uses "segment" and "protection path," which the RAW architecture defines too ๐Ÿฆ‹

compared to routing trees, RPL DODAGs are usually built to offer redundancy and to adapt forwarding on the fly to the state of the Low-Power and Lossy Network (LLN) links ๐ŸŒธ

Heads up: plain forwarding over DODAGs doesn't give redundancy for every node, since at least the node nearest to the Root doesn't have an alternate feasible successor. ๐Ÿ™ˆ

RAW fixes that gap by defining protection paths that can be interleaved to form new paths, which can be activated dynamically upon failures โœจ this needs extra control so the routing decision happens early enough along the Track to route around the failure ๐Ÿ’…

RAW only uses single-ended DODAGs, meaning they can be reversed into another DODAG by reversing all the links. The ingress of the Track is the Root of the DODAG, and the egress is the Root of the reversed DODAG ๐Ÿ”ฅ from the RAW point of view, single-ended DODAGs are special Tracks with only forward links, and they can be used to provide protection services by defining destination-oriented protection paths within the DODAG ๐Ÿ‘‘

2.3. Glossary ๐Ÿ’…

here's the abbreviation cheat sheet, because there are a LOT ๐Ÿซถ

   6LoRH:       6LoWPAN Routing Header

   6LR:         6LoWPAN Router (e.g., a RPL router in an LLN)

   ARQ:         Automatic Repeat Request (in other words, retries)

   CMO:         Control Message Option

   DAG:         Directed Acyclic Graph

   DAO:         Destination Advertisement Object

   DIO:         DODAG Information Object

   DODAG:       Destination-Oriented Directed Acyclic Graph.  A DAG with
                only one vertex (i.e., node) that has no outgoing edge
                (i.e., link).

   FEC:         Forward Error Correction

   GUA:         Global Unicast Address

   HARQ:        Hybrid Automatic Repeat Request (combines FEC and ARQ)

   LLN:         Low-Power and Lossy Network

   MOP:         Mode of Operation

   NSM-VIO:     Non-Storing Mode Via Information Option.  Source-routed
                VIO used in Non-Storing Mode P-DAO messages.

   P-DAO:       Projected DAO

   P-DAO-ACK:   Projected DAO Acknowledgment

   P-DAO-REQ:   Projected DAO Request

   P-Route:     Projected Route

   PCE:         Path Computation Element

   PDR-ACK      Projected DAO Request Acknowledgment

   PLR:         Point of Local Repair

   RAL:         RPL-Aware Leaf

   RAN:         RPL-Aware Node (either a RPL router or a RPL-Aware Leaf)

   RH:          Routing Header

   RIB:         Routing Information Base (i.e., the routing table)

   RPI:         RPL Packet Information

   RPL:         Routing Protocol for Low-Power and Lossy Networks

   RTO:         RPL Target Option

   RUL:         RPL-Unaware Leaf

   SIO:         Sibling Information Option

   SLO:         Service Level Objective

   SM-VIO:      Storing Mode Via Information Option.  Strict VIO used in
                Storing Mode P-DAO messages.

   SRH:         Source Routing Header (i.e., IPv6 RH type 3); see
                Section 2.4.5.7.2.

   SRH-6LoRH:   Source Routing Header 6LoRH.  A compressed form of SRH
                defined in "IPv6 over Low-Power Wireless Personal Area
                Network (6LoWPAN) Routing Header" [RFC8138].

   TIO:         Transit Information Option

   ULA:         Unique Local Address

   VIO:         Via Information Option.  It can be an SM-VIO or NSM-VIO.

2.4. Domain Terms ๐Ÿ“

everything in the next few sections is the vocab this spec runs on, so let's get it down ๐Ÿ“

2.4.1. Projected Route ๐ŸŒˆ

a RPL P-Route is a RPL route that a PCE computes remotely, and that a RPL Root installs and maintains on the PCE's behalf ๐Ÿงš it gets installed as state that signals destinations (i.e., Targets) are reachable via, or along, a sequence of nodes ๐Ÿ’–

2.4.2. Projected DAO ๐ŸŽ€

a Projected DAO (P-DAO) is a DAO message that is used to install a P-Route โœจ

2.4.3. Path ๐Ÿ›ฃ๏ธ

quoting (non-normatively) the definition of path in Section 1.3.3 of [INT-ARCH], here's what they said ๐Ÿ’…

   |  At a given moment, all the IP datagrams from a particular source
   |  host to a particular destination host will typically traverse the
   |  same sequence of gateways.  We use the term "path" for this
   |  sequence.  Note that a path is uni-directional; it is not unusual
   |  to have different paths in the two directions between a given host
   |  pair.

for a longer, more modern definition of path, see Section 3.1.1 of [RAW-ARCH] ๐Ÿฆ‹

so the general idea of a path is a linear sequence of nodes, not a multi-dimensional graph ๐Ÿซถ in this document, you observe a path by following one copy of a packet that's injected into a Track and possibly replicated along the way ๐Ÿ”ฅ

2.4.4. Routing Stretch ๐ŸŒธ

RPL is anisotropic, which means it's directional, or more precisely, polar ๐Ÿงญ RPL does not behave the same way "downwards" (Root towards leaves) with multicast DODAG Information Object (DIO) messages that form the DODAG, as it does "upwards" (leaves towards Root) with unicast DAO messages that follow the DODAG ๐Ÿ˜ญ traditional IGPs operate the same way in all directions, which is why they're called isotropic ๐Ÿ’œ

the term "routing stretch" describes the length of a path compared to the length of the shortest path ๐Ÿ“ in RPL that shortest path can be a pretty abstract concept, since the metrics are statistical and dynamic and the idea of distance changes with the Objective Function ๐ŸŒˆ

the RPL DODAG optimizes Point-to-Multipoint (P2MP) paths (from the Root) and Multipoint-to-Point (MP2P) paths (towards the Root), but Point-to-Point (P2P) traffic has to follow that same DODAG ๐Ÿ’€ following the DODAG, the RPL datapath goes through a common parent in Storing Mode and through the Root in Non-Storing Mode ๐Ÿ™ˆ this usually means more hops and more latency than the minimum possible for a directional (i.e., forward) P2P path that an isotropic protocol would compute, and we call this elongated path stretched ๐Ÿ“

2.4.5. Track ๐Ÿฆ‹

the Track idea is inherited from the 6TiSCH architecture [RFC9030], and it's the same thing as a recovery graph in the RAW architecture [RAW-ARCH] ๐Ÿ’– a Track is a networking graph you can follow to transport packets with equivalent treatment. Unlike other definitions of a path (see Section 1.3.3 of [INT-ARCH] and Section 3.1.1 of [RAW-ARCH], a Track is not necessarily linear ๐ŸŒˆ it can contain multiple paths that fork and rejoin, and that may enable RAW Packet Replication, Elimination, and Ordering Functions (PREOF) ๐Ÿ”ฅ

Figure 1 shows how the DODAG maps onto the generic Track concept ๐Ÿงš the DODAG Root acts as the ingress for the Track, and protection paths and segments map onto it too. Segments here are forward-only, meaning they're directional and progress towards the destination. East is drawn on the left, since the packets are forwarded East-West ๐Ÿ‘‘

   North East                                   North West

          A ==> B ==> C -=- F ==> G ==> H     T1
        /              \   /              \ /
      I                  O                 E -=- T2
        \              /   \              / \
          P ==> Q ==> R -=- T ==> U ==> V     T3

   South East                                   South West

         I: ingress
         E: egress
         T1, T2, T3: external targets

                    Figure 1: A Track and Its Components

some things to note from the diagram ๐Ÿ‘€

  • I ==> A ==> B ==> C: a segment to targets F and O
  • I --> F --> E: a protection path to targets T1, T2, T3
  • I, A, B, C, F, G, H, E: a path to T1, T2, T3

this spec builds Tracks that are DODAGs oriented towards a Track ingress, and packets go forward from the Track ingress to one of the possible multiple Track egress nodes, which is also down the DODAG ๐Ÿ’…

a Track can be strictly connected, meaning its vertices are adjacent, or loosely connected, meaning its vertices are connected using segments associated with the same Track ๐Ÿซถ

2.4.5.1. TrackID ๐Ÿ’–

a RPLInstanceID (typically of a Local Instance) identifies a Track using the namespace owned by the Track ingress ๐ŸŽ€ for Local Instances, the TrackID is associated with the IPv6 address of the Track ingress that's used as the DODAGID, and together they form a unique identification of the Track (see the definition of DODAGID in Section 2 of [RPL]) โœจ

2.4.5.2. Namespace ๐Ÿงš

"namespace" is the word for the scope of the TrackID ๐ŸŒธ the TrackID is locally significant within its namespace. For Local Instances, the namespace is identified by the DODAGID for the Track, and the tuple (DODAGID, TrackID) is globally unique. For Global Instances, the namespace is the whole RPL domain ๐ŸŒ

2.4.5.3. Complex Track ๐Ÿฆ‹

a Complex Track is a Track that can be traversed via more than one path (e.g., a DODAG) ๐Ÿ‘‘

2.4.5.4. Stand Alone ๐Ÿ™ˆ

"stand alone" refers to a segment or a protection path that's installed with a single P-DAO that fully defines the path ๐Ÿ”ฅ e.g., a stand-alone segment is installed with a single Storing Mode Via Information Option (SM-VIO) all the way between the ingress and egress ๐Ÿ’œ

2.4.5.5. Stitching ๐Ÿซถ

this spec uses "stitching" to mean that one Track is piped into another, so traffic coming out of the first Track gets injected into the other Track ๐Ÿงต

2.4.5.6. Protection Path ๐Ÿ›ก๏ธ

the protection path concept is defined in the RAW architecture [RAW-ARCH] as an end-to-end forward serial path โœจ with this spec, the Root of the main DODAG installs a protection path using a Non-Storing Mode P-DAO message, e.g., I --> F --> E in Figure 1 ๐Ÿ’…

the Non-Storing Mode Via Information Option (NSM-VIO) can only signal sequences of nodes, so it takes one Non-Storing Mode P-DAO message per protection path to signal the structure of a Complex Track ๐Ÿ˜ญ

each NSM-VIO with the same TrackID but a different SegmentID signals a different protection path that the Track ingress adds to the topology ๐ŸŒˆ

2.4.5.7. Segment ๐Ÿ›ฃ๏ธ

okay so a segment is a serial path made of a strict sequence of nodes, and a P-Route gets installed along it, like I ==> A ==> B ==> C in Figure 1 โœจ. With this spec, the Root of the main DODAG typically installs a segment using Storing Mode P-DAO messages ๐Ÿ’…. Segments are the topological edge of a Track, joining the loose steps along the protection paths that build a Complex Track ๐Ÿงฉ. The same segment can be reused by more than one protection path when those paths overlap, which is so efficient ๐Ÿซถ.

Since this spec only builds DODAGs, every segment runs from ingress (East) to egress (West) ๐Ÿงญ. The general Track model in the RAW architecture [RAW-ARCH] is different: it allows North/South segments that can be bidirectional too ๐Ÿฆ‹.

2.4.5.7.1. Section of a Segment ๐Ÿงฉ

A section of a segment is a continuous subset of a segment that may be replaced while the segment itself stays put ๐ŸŒธ. Picture the segment A=>B=>C=>D=>E=>F. Say the link from C to D is misbehaving ๐Ÿ™ˆ. The section B=>C=>D=>E may be swapped for B=>C'=>D'=>E to route around the problem, and the segment becomes A=>B=>C'=>D'=>E=>F. Iconic rerouting, no cap ๐Ÿ’œ.

2.4.5.7.2. Segment Routing and SRH ๐ŸŒˆ

In a Non-Storing Mode RPL domain, the IPv6 Routing Header used for source routing is the RPL Source Route Header defined in [RFC6554] ๐ŸŽ€. This spec works in that context and uses the acronym SRH to mean IPv6 RH type 3. That's different from IPv6 RH type 4, which [RFC8754] defines for Segment Routing over IPv6 (SRv6) operation, so don't mix them up bestie ๐Ÿ’€.

If the network is a 6LoWPAN network, the expectation is that the SRH gets compressed and encoded as a 6LoWPAN Routing Header (6LoRH), as specified in Section 5 of [RFC8138] ๐Ÿ“.

This spec uses "Segment Routing" generically to mean using source routing to hop over segments ๐Ÿงš. So forwarding along segments, as described below, can be seen as a form of Segment Routing [RFC8402] that leverages the RPL Source Route Header for its operation โญ.

Outside of LLNs, the RPL network may be less constrained and operated in Storing Mode, as discussed in Section 7.1 ๐ŸŒค๏ธ. In that case, this specification could be extended to accommodate the SRv6 RH ๐Ÿ‘‘.

3. Context and Goal ๐ŸŽ€

3.1. RPL Applicability ๐ŸŒธ

RPL is optimized for situations where power is scarce, bandwidth is constrained, and transmissions are unreliable ๐Ÿ”‹. That's the vibe of an IoT LLN, which is where RPL is typically used today ๐Ÿ’–. It also fits situations with high relative mobility between nodes (a.k.a. swarming), like a variable set of vehicles moving with similar global motion or a platoon of drones ๐Ÿš. This spec is different: it only applies when the platoon has a relatively stable topology, where segments can be given reliability and availability for a certain lifetime; see [RAW-ARCH] ๐Ÿฆ‹.

To get there, RPL is mainly designed to minimize the control plane activity (the relative amount of routing protocol exchanges versus data traffic) and the amount of state each node keeps ๐Ÿง . RPL does not need to converge, and it gives connectivity to most nodes most of the time, which is honestly a mood ๐Ÿ˜Œ.

RPL may form multiple topologies called Instances โœจ. Instances can be created to enforce various optimizations through Objective Functions, or to reach out through different Root nodes ๐ŸŒˆ. The Objective Function concept lets the routing protocol adapt to the use case, like the type, speed, and quality of the LLN links ๐ŸŽฏ.

RPL Instances operate in parallel and are unaware of one another ๐Ÿ™ƒ. Still, you can define a model where, if a route can't be found in the current Instance A where a packet is being forwarded, the router may look up the routing table (the RIB) in Instance B and forward along Instance B if the route is there ๐Ÿ‘€. To avoid loops, this must happen in a way where the Instances themselves form a Directed Acyclic Graph (DAG) that leads to the last resort Instance, which is the "lowest" one if Instance A counts as "higher" than Instance B ๐Ÿชœ. This spec uses underlay Tracks as the "lower" Instances, with the main Instance being the "highest" of all ๐Ÿ‘‘.

The RPL Root picks the RPL Instance used to forward a packet coming from the backbone into the RPL domain, and it sets the related RPL information in the packets ๐ŸŽฏ. Each Instance creates its own routing table (a RIB) in participating nodes, and the RIB tied to the Instance must be used end to end in the RPL domain ๐Ÿ”. To make that work, RPL tags packets with the Instance ID in a Hop-by-Hop extension header ๐Ÿท๏ธ. 6TiSCH uses RPL for its distributed routing operations ๐Ÿค–.

To cut down on routing exchanges, RPL uses an anisotropic Distance Vector approach ๐Ÿงญ. It doesn't need global knowledge of the topology, and it only optimizes routes to and from the RPL Root, which means P2P paths are allowed to get stretched ๐Ÿ˜ฌ. RPL installs its routes proactively, but it only maintains them lazily, either in reaction to actual traffic or as a slow background activity ๐Ÿข.

That's simple and efficient when traffic mostly goes to or from one central node, like control traffic between routers and a controller in a Software-Defined Networking (SDN) infrastructure or an Autonomic Control Plane (ACP) ๐ŸŽ€.

But stretch in P2P routing hurts both reliability and latency, because it adds delay and more chances of loss ๐Ÿ’”. So [RPL] isn't a good fit for the use cases in the RAW use cases document [RFC9450], which demand high availability and reliability and therefore need both short and diverse paths ๐Ÿ˜ญ.

3.2. Multi-Topology Routing and Loop Avoidance ๐Ÿ”„

RPL first forms a default route in each node toward the Root, and those routes together coalesce into a DAG oriented upward โฌ†๏ธ. Then RPL builds routes to destinations signaled as Targets, going in the reverse direction down the same DODAG โฌ‡๏ธ. A RPL Instance can be operated in either RPL Storing or Non-Storing MOP ๐Ÿงฉ. The default route toward the Root is maintained aggressively and may change while a packet is on its way without causing loops, so the packet still reaches the Root ๐Ÿ’ช.

In Non-Storing Mode, each node advertises itself as a Target directly to the Root, and it indicates the parents that may be used to reach itself ๐Ÿ“ฃ. Recursively, the Root builds and maintains an image of the whole DODAG in memory and uses that abstraction to compute source route paths for packets heading down the DODAG to their destinations ๐Ÿง . When a node changes its point(s) of attachment to the DODAG, it takes a single unicast packet to the Root along the default route to update it, and connectivity to that node is restored immediately โšก. This mode is preferable where internet connectivity is dominant, or when the Root controls the network activity in the nodes, which is the case in this specification ๐Ÿ‘‘.

In Storing Mode, routing information percolates upward, and each node keeps the routes to the subDAG of its descendants down the DODAG ๐Ÿชด. Maintenance is lazy: it's either reactive when traffic arrives or a slow background process ๐ŸŒ. Packets flow via the common parent, so routing stretch is reduced compared to the Non-Storing MOP, which means better P2P connectivity ๐Ÿค. The trade-off is that a new route takes longer to reach the Root, since the Distance Vector protocol operates hop by hop, and connectivity from the Internet to the node is restored more slowly after node movement ๐Ÿ˜ฉ.

Either way, the Target nodes inject RPL routes in a distributed fashion ๐ŸŒ. To complement RPL and eliminate routing stretch, this spec adds a hybrid mode that combines Storing and Non-Storing operations to build and project routes onto the nodes where they should be installed ๐Ÿช„. This spec uses the term "P-Route" for those routes ๐Ÿ’œ.

In the simplest mode of this spec, Storing Mode P-Routes can be deployed to complete the path between the hops described in the loose SRH in the main DODAG ๐Ÿงฉ. In that case, all the routes (source routed and P-Routes) belong to the Routing Information Base (RIB) for the main Instance ๐Ÿ“š. Storing Mode P-Routes are called segments in this spec ๐Ÿ›ฃ๏ธ.

A set of P-Routes can also be projected to form a dotted-line underlay of the main Instance and provide Traffic-Engineered paths for an application ๐Ÿฆ‹. In that case, the P-Routes are installed in Non-Storing Mode, and the set of P-Routes is called a Track ๐ŸŽ€. A Track has its own RPL Instance and, like any RPL Instance, its own RIB ๐Ÿ—‚๏ธ. So each Track defines a routing topology in the RPL domain ๐Ÿ—บ๏ธ. As with the main DODAG, segments tied to the Track Instance may be deployed to establish the complete path between loose source routing hops, using segments expressed as Storing Mode P-Routes ๐Ÿงต.

Routing in a multi-topology domain may cause loops unless strict rules are applied ๐Ÿšซ. This spec defines two strict orders to keep loops away when P-Routes are used in a RPL domain: one between forwarding methods, and one between RPL Instances, which are routing topologies ๐Ÿ”.

The first order is strict and complete, and it relates to the forwarding method and, more specifically, to where the information used in the next-hop computation came from ๐Ÿ“ถ. The possible forwarding methods are: 1) to a direct next hop, 2) to an indirect neighbor via a common neighbor, 3) along a segment, and 4) along a nested Track ๐Ÿชœ. The methods are strictly ordered as listed above; see more in Section 6.7 ๐Ÿ’…. A forwarding method may leverage any of the lower-order ones, but never a higher-order one. For example, when forwarding a packet along a segment, the router may use direct or indirect neighbors, but it cannot use a Track ๐Ÿ™…โ€โ™€๏ธ. The lower-order methods have strict precedence, so the router will always prefer a direct neighbor over an indirect one, or a segment within the current RPL Instance over another Track ๐Ÿฅ‡.

The second order is strict and partial, and it applies between RPL Instances ๐Ÿงฉ. It lets the RPL node detect an error in the state installed by the PCE, for example after a desynchronization ๐Ÿšจ. That order must be defined by the administrator of the RPL domain, and it defines a DODAG of underlay RPL Instances with the main Instance as the Root ๐ŸŒณ. The relation between RPL Instances may be represented as a DODAG of Instances where the main Instance is the Root ๐ŸŒณ. The rule is that a RPL Instance may leverage another RPL Instance as an underlay if and only if that other Instance is one of its descendants in the graph ๐ŸŽ€. Supporting this method is OPTIONAL for nested Tracks and REQUIRED between a Track Instance and the main Instance ๐Ÿ”‘. It may be done using network management or future extensions to this specification ๐Ÿ› ๏ธ. When the DODAG of underlay Instances isn't provided, RPL nodes consider by default that all Track Instances are children of the main Instance, and they don't try to validate the order for nested Tracks, trusting the PCE implicitly ๐Ÿซก. As a result, a packet being forwarded along the main Instance may be encapsulated in any Track, but a packet that was forwarded along a Track MUST NOT be forwarded along the default route of the main Instance ๐Ÿšซ๐Ÿ’ฅ.

3.3. Requirements ๐Ÿ“‹

3.3.1. Loose Source Routing

Okay so a RPL node in a super constrained LLN usually runs the Non-Storing MOP ๐Ÿงš (see Figure 2). In that mode, each node tells the Root about its parent-child relationship with a Destination Advertisement Object (DAO) that gets unicast straight from the node to the Root. Then the Root typically stitches that info together recursively to build a source-routed path down the DODAG to a destination ๐Ÿ”—.

                 +-----+
                 |     | Border Router
                 |     |  (RPL Root)
                 +-----+                      ^     |        |
                    |                         | DAO | ACK    |
              o    o   o    o                 |     |        | Strict
          o o   o  o   o  o  o o   o          |     |        | Source
         o  o o  o o    o   o   o  o  o       |     |        | Route
         o   o    o  o     o  o    o  o  o    |     |        |
        o  o   o  o   o         o   o o       |     v        v
        o          o             o     o
                          LLN

                Figure 2: RPL Non-Storing Mode of Operation

Because the Non-Storing DAO messages spell out the parent-child relationships, the Root gets a map of the whole network ๐Ÿ—บ๏ธ. Just know that the map only covers the structure of the DODAG the Root is the destination of, so it's not the full picture for everything. A packet generated inside the domain always reaches the Root, and from there the Root can apply source routing info to reach the destination if that destination is also in the DODAG. Same deal for a packet coming from outside the domain for a destination that's supposed to be in a RPL domain: it reaches the Root first. ๐Ÿ˜ฌ The result is that the wireless bandwidth near the Root becomes the bottleneck for everything going to or within the domain, and the Root is a single point of failure for all connectivity to nodes in its domain. Big yikes ๐Ÿ’€.

The RPL Root must add a Source Routing Header to all downward packets. As the network grows, the Source Routing Header gets bigger along with the depth of the network ๐Ÿ“. In some use cases, a RPL network forms long lines along physical structures like streets with lighting ๐Ÿ’ก. Keeping packets small is great for the energy budget, both for the current transmission and indirectly, since it cuts down on frame loss and the energy wasted on retries (e.g., ARQ over one hop at Layer 2 or end to end at upper layers) ๐Ÿ”‹. Smaller packets also lower the chances of fragmentation, which is highly detrimental to LLN operation, especially when fragments get forwarded but never recovered. See [RFC8930] compared to [RFC8931] for more details ๐Ÿ“š.

A limited amount of well-targeted routing state would let the source routing operate as loose instead of strict, and it would reduce the routing information overhead in packets ๐ŸŽฏ. Each node's capacity to store routing state is limited, so deciding which route gets installed where can only be optimized with global knowledge of the system. The Root or an associated PCE might have that knowledge, through means that are outside the scope of this specification ๐Ÿง .

Since the Root is on path for all packets in Non-Storing Mode, it can figure out the number of P2P packets in its RPL domain per source and destination, the latency, and how much energy and bandwidth gets used to reach itself and then head back down. That includes possible fragmentation when larger packets get encapsulated ๐Ÿ•ต๏ธโ€โ™€๏ธ. Enabling a shorter path that doesn't traverse the Root for select P2P sources and destinations can improve latency, lower the use of constrained resources, free up bandwidth at the bottleneck near the Root, improve the delivery ratio, and reduce latency for those P2P flows. That's a global win for all flows, since the load on the Root goes down ๐ŸŒˆ.

To limit the need for RPL Source Route Headers in deep networks, one option is to store routing state associated with the main DODAG in select RPL routers down the path ๐Ÿชœ. The Root may elide the sequence of routers that is installed in the network from its RPL Source Route Header. That makes the header loose, instead of strict as in [RPL] ๐Ÿ’œ.

3.3.2. Forward Routes

[RPL] optimizes P2MP routes from the Root, MP2P routes towards the Root, and routes from and to the outside of the RPL domain when the Root also serves as the border router ๐Ÿšช. All routes are installed North-South (a.k.a. up/down) along the RPL DODAG โฌ†๏ธโฌ‡๏ธ. Peer-to-Peer forward routes in a RPL network will generally be elongated (stretched) rather than direct (optimized), since routing between two nodes always happens via a common parent. Check out Figure 3 ๐Ÿ™ˆ:

                 ------+---------
                       |          Internet
                    +-----+
                    |     | Border Router
                    |     |  (RPL Root)
                    +-----+
                       X
                 ^    v   o    o
             ^ o   o  v   o  o  o o   o
            ^  o o  o v    o   o   o  o  o
            ^   o    o  v     o  o    o  o  o
           S  o   o  o   D         o   o o
           o          o             o     o
                             LLN

       Figure 3: Routing Stretch Between S and D via Common Parent X
                          Along North-South Paths

As described in [RFC9008], the amount of stretch depends on the MOP ๐Ÿ“:

  • In Non-Storing Mode, all packets routed within the DODAG flow all the way up to the Root of the DODAG. If the destination is in the same DODAG, the Root must encapsulate the packet to place an RH that has the strict source route information down the DODAG to the destination. This happens even if the destination is relatively close to the source and the Root is relatively far off ๐Ÿ˜ญ.
  • In Storing Mode, unless the destination is a child of the source, the packets follow the default route up the DODAG as well. If the destination is in the same DODAG, they will eventually reach a common parent that has a route to the destination. At worst, the common parent may also be the Root. From that common parent, the packet follows a path down the DODAG that is optimized for the Objective Function that was used to build the DODAG ๐ŸŒณ.

Here's the tea โ˜•: it's often beneficial to enable direct P2P routes if either the RPL route presents a stretch from the shortest path or the new route is engineered with a different objective. This is even more critical in Non-Storing Mode than in Storing Mode, because the routing stretch is wider ๐Ÿ“๐Ÿ”ฅ. That's why earlier IETF work came along: the "Reactive Discovery of Point-to-Point Routes in Low-Power and Lossy Networks" [RFC6997], which specifies a distributed method for establishing optimized P2P routes ๐Ÿ› ๏ธ. This specification proposes an alternative based on centralized route computation ๐Ÿง โœจ.

                    +-----+
                    |     | Border Router
                    |     |  (RPL Root)
                    +-----+
                       |
                 o    o   o    o
             o o   o  o   o  o  o o   o
            o  o o  o o    o   o   o  o  o
            o   o    o  o     o  o    o  o  o
           S>>A>>>B>>C>>>D         o   o o
           o          o             o     o
                             LLN

            Figure 4: More Direct Forward Route Between S and D

The requirement is to install additional routes in the RPL routers. The goal is to reduce the stretch of some P2P routes and keep their characteristics within a given Service Level Objective (SLO), e.g., in terms of latency and/or reliability ๐ŸŽฏ๐Ÿ’–.

3.4. On Tracks

3.4.1. Building Tracks with RPL

The concept of a Track came from the 6TiSCH architecture [RFC9030] as a collection of potential protection paths that use redundant forwarding solutions along the way ๐Ÿ›ค๏ธ. A Track can be a DODAG, or a more complex structure that is only partially acyclic (e.g., per packet) ๐ŸŒ€.

With this specification, a Track is shaped as a DODAG, and following the directed edges leads to a Track ingress โžก๏ธ. Storing Mode P-DAO messages follow the direction of the edges to set up routes for traffic that flows the other way, towards the Track egress(es) ๐Ÿ”. If there is a single Track egress, the Track is reversible, so another DODAG can be formed by reversing the direction of each edge ๐Ÿ”„. A node at the ingress of more than one segment in a Track may use one or more of those segments to forward a packet inside the Track ๐Ÿงšโ€โ™€๏ธ.

A RPL Track is a collection of (one or more) parallel loose source-routed sequences of nodes, ordered from ingress to egress, each forming a protection path ๐Ÿ›ก๏ธ. The nodes in a Track are directly connected, reachable via existing Tracks as illustrated in Section 3.5.2.3, or joined with strict segments of other nodes as shown in Section 3.5.1.3. The protection paths are expressed in RPL Non-Storing Mode and require an encapsulation to add a RPL Source Route Header, whereas the segments are expressed in RPL Storing Mode ๐Ÿ’….

A path provides only one path between the ingress and egress. It comprises exactly one protection path 1๏ธโƒฃ. A stand-alone segment implicitly defines a path from its ingress to egress ๐Ÿฆ‹.

A Complex Track forms a graph that provides a collection of potential paths for redundancy for the packets ๐Ÿ•ธ๏ธโœจ. That can look like a collection of protection paths that may be parallel or interleaved at certain points, or like a more generic DODAG ๐Ÿซถ.

3.4.2. Tracks and RPL Instances โœจ

okay so bestie, let's talk about how Tracks hang out with RPL Instances ๐Ÿ’– Section 5.1 of [RPL] is where the RPL Instance and its encoding live, and it's giving very organized ๐ŸŽ€ There can be up to 128 Global RPL Instances, and each of those can have one or more DODAGs ๐ŸŒˆ Then there can be 64 Local RPL Instances, which have their own namespace indexed by a DODAGID. That DODAGID is either a Unique Local Address (ULA) or a Global Unicast Address (GUA) of the Root of the DODAG ๐Ÿงš The most significant bit, bit 0, gets set to 1 to signal a Local RPLInstanceID, as shown in Figure 5. So by extension, this spec writes the RPLInstanceID as one single integer between 128 and 191, which covers both the Local RPLInstanceID in 0..63 (in the rightmost bits) and bit 0 being set ๐Ÿฆ‹

        0 1 2 3 4 5 6 7
       +-+-+-+-+-+-+-+-+
       |1|D|   ID      |  Local RPLInstanceID in 0..63
       +-+-+-+-+-+-+-+-+
        |  |
         \  \
          \   Bit 1 is set to 0 in TrackIDs
           Bit 0 set to 1 signals a Local RPLInstanceID

                Figure 5: Local RPLInstanceID Encoding

A Track typically forms an underlay to the main Instance, and it's associated with a Local RPL Instance. The RPLInstanceID from that Local Instance is used as the TrackID ๐Ÿ‘‘ When a packet gets placed on a Track, it's IP-in-IP encapsulated with a RPL Option containing RPL Packet Information (RPI) that signals the RPLInstanceID. The encapsulating source IP address and RPI Instance are set to the Track ingress IP address and Local RPLInstanceID, respectively. More on this in Section 6.3 ๐Ÿ’…

A Track typically offers service protection across several protection paths. As a degraded form of a Track, a path made of a single protection path (so, offering no protection) can be used as an alternative to a segment for forwarding along a RPL Instance. In that case, instead of following native routes along the Instance, the packets get encapsulated to signal a more-specific source-routed path between the loose hops in the encapsulated Source Routing Header ๐Ÿซถ

If the encapsulated packet follows a Global Instance, then the protection path may be part of that Global Instance as well, for example the Global Instance of the main DODAG. This can only be done for Global Instances, because the ingress node that encapsulates the packets over the protection path is not the Root of the Instance. So the source address of the encapsulated packet can't be used to determine the Track along the way ๐Ÿ˜ญ


3.5. Path Signaling ๐ŸŒธ

okay so this is where it gets spicy ๐Ÿ”ฅ This specification lets you set up a P-Route along either a protection path or a segment. A P-Route is installed and maintained by the Root of the main DODAG using an extended RPL DAO message called a P-DAO, and a Track is made of one or more P-Routes combined together ๐Ÿ’œ To explain the techniques for installing a P-Route, this section uses the simple case of the path in Figure 6. So the goal is to build a path from node A to E for packets heading to E's neighbors F and G, going along A, B, C, D, and E instead of going via the Root ๐Ÿฆ‹

                             /===> F
A ===> B ===> C ===> D===> E <
                             \===> G

                     Figure 6: Reference Track

A P-DAO message for a Track signals the TrackID in the RPLInstanceID field. In the case of a Local RPL Instance, the address of the Track ingress is used as the source to encapsulate packets along the Track. The Track gets signaled in the DODAGID field of the P-DAO Base Object; see Figure 8 ๐ŸŽ€

This specification introduces the Via Information Option (VIO) to signal a sequence of hops in a protection path or a segment in the P-DAO messages. It can be used in either Storing Mode (SM-VIO) or Non-Storing Mode (NSM-VIO). One P-DAO message contains a single VIO, which is associated to one or more RPL Target Options. Those Targets signal the destination IPv6 addresses that can be reached along the Track (see more in Section 5.3) โœจ

Before we dive deeper into Track and segment signaling and operation, this section gives examples of how route projection works through variations of one simple example. The example shows host routes, though RPL Targets can also be prefixes ๐Ÿงš

Conventionally, we use ==> to represent a strict hop and --> for a loose hop. We use "-to-", like in C==>D==>E-to-F, to represent comma-separated Targets. For instance, F is a Target for segment C==>D==>E. In the example below, A is the Track ingress and E is the Track egress. C is a stitching point. F and G are "external" Targets for the Track and become reachable from A via Track A (ingress) to E (egress and implicit Target in Non-Storing Mode), leading to F and G (explicit Targets) ๐ŸŒˆ

In general, the desired outcome is as follows:

  • Targets are E, F, and G
  • P-DAO 1 signals C==>D==>E
  • P-DAO 2 signals A==>B==>C
  • P-DAO 3 signals F and G via the A-->E Track

P-DAO 3 may be omitted if P-DAOs 1 and 2 signal F and G as Targets ๐Ÿ’…

Loose sequences of hops are expressed in Non-Storing Mode, which is why P-DAO 3 contains an NSM-VIO. With this specification:

  • The DODAGID to be used by the ingress as the source address is signaled in the DAO Base Object (see Figure 8).
  • The via list in the VIO is encoded as an SRH-6LoRH (see Figure 16), and it starts with the address of the first-hop node after the ingress node in the loose hop sequence.
  • The via list ends with the address of the egress node.
Note 1: The egress of a Non-Storing Mode P-Route is implicitly a target. It is not listed in the RPL Target Options, but it is still accounted for as if it was. The only exception is when the egress is the only address listed in the VIO, in which case it would indicate via itself, which would be nonsensical.
Note 2: By design, the list of nodes in a VIO in Non-Storing Mode is exactly the list that shows in the encapsulation SRH. So in the cases detailed below, if the Mode of the P-DAO is Non-Storing, then the VIO row can be read as indicating the SRH as well ๐Ÿ™ˆ

3.5.1. Using Storing Mode Segments ๐Ÿ“

A==>B==>C and C==>D==>E are segments of the same Track. Note that Storing Mode signaling imposes strict continuity in a segment, since the P-DAO is passed hop by hop, as a classical DAO is, along the reverse datapath that it signals. One benefit of strict routing is that loops are avoided along the Track ๐Ÿ”ฅ

3.5.1.1. Stitched Segments ๐Ÿฆ‹

In this formulation:

  • P-DAO 1 signals C==>D==>E-to-F,G
  • P-DAO 2 signals A==>B==>C-to-F,G

Storing Mode P-DAO 1 is sent to E. When it's successfully acknowledged, Storing Mode P-DAO 2 is sent to C, like this:

        +====================+==============+==============+
        | Field              | P-DAO 1 to E | P-DAO 2 to C |
        +====================+==============+==============+
        | Mode               | Storing      | Storing      |
        +====================+--------------+--------------+
        | Track ingress      | A            | A            |
        +====================+--------------+--------------+
        | (DODAGID, TrackID) | (A, 129)     | (A, 129)     |
        +====================+--------------+--------------+
        | SegmentID          | 1            | 2            |
        +====================+--------------+--------------+
        | VIO                | C, D, E      | A, B, C      |
        +====================+--------------+--------------+
        | Targets            | F, G         | F, G         |
        +====================+--------------+--------------+

                      Table 1: P-DAO Messages

As a result, the RIBs are set as follows:

      +======+=============+=========+=============+==========+
      | Node | Destination | Origin  | Next Hop(s) | TrackID  |
      +======+=============+=========+=============+==========+
      | E    | F, G        | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | D    | E           | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | F, G        | P-DAO 1 | E           | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | C    | D           | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | F, G        | P-DAO 1 | D           | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | B    | C           | P-DAO 2 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | F, G        | P-DAO 2 | C           | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | A    | B           | P-DAO 2 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | F, G        | P-DAO 2 | B           | (A, 129) |
      +------+-------------+---------+-------------+----------+

                        Table 2: RIB Settings
Note: The " sign is used throughout the tables in this document to indicate the same value as in the row above.

Packets originating at A and going to F or G do not require encapsulation, as the RPI can be placed in the native header chain. For packets that it routes, A must encapsulate to add the RPI that signals the TrackID. The outer headers of the packets forwarded along the Track have the following settings:

+========+=====================+==========================+=========+
| Header | IPv6 Source Address |     IPv6 Destination     | TrackID |
|        |                     |         Address          |  in RPI |
+========+=====================+==========================+=========+
| Outer  |          A          |          F or G          |   (A,   |
|        |                     |                          |   129)  |
+--------+---------------------+--------------------------+---------+
| Inner  |      Any but A      |          F or G          |   N/A   |
+--------+---------------------+--------------------------+---------+

                   Table 3: Packet Header Settings

As an example, say A has a packet for F. Using the RIB in Table 2:

  • From P-DAO 2: A forwards to B, and B forwards to C.
  • From P-DAO 1: C forwards to D, and D forwards to E.
  • From Neighbor Cache Entry: E delivers the packet to F.

3.5.1.2. External Routes

okay so, we're treating F and G as destinations that live outside the Track as a DODAG, which is a total vibe (see Section 4.1.1 of [RFC9008] ๐Ÿ’…). Then we apply the encapsulation rules for that situation (more in Section 6.7) โœจ

In this setup we set up the protection path explicitly. The upside is that intermediate hops store way less routing state ๐Ÿงš, but the trade-off is bigger packets, since they have to carry source routing info ๐Ÿ“ฆ

  • P-DAO 1 signals C==>D==>E-to-E
  • P-DAO 2 signals A==>B==>C-to-E
  • P-DAO 3 signals F and G via the A-->E-to-F,G Track

Storing Mode P-DAOs 1 and 2 and Non-Storing Mode P-DAO 3 get sent to E, C, and A, respectively, like this ๐Ÿ‘€

    +====================+==============+==============+==============+
    |                    | P-DAO 1 to E | P-DAO 2 to C | P-DAO 3 to A |
    +====================+==============+==============+==============+
    | Mode               | Storing      | Storing      | Non-Storing  |
    +====================+--------------+--------------+--------------+
    | Track ingress      | A            | A            | A            |
    +====================+--------------+--------------+--------------+
    | (DODAGID, TrackID) | (A, 129)     | (A, 129)     | (A, 129)     |
    +====================+--------------+--------------+--------------+
    | SegmentID          | 1            | 2            | 3            |
    +====================+--------------+--------------+--------------+
    | VIO                | C, D, E      | A, B, C      | E            |
    +====================+--------------+--------------+--------------+
    | Targets            | E            | E            | F, G         |
    +====================+--------------+--------------+--------------+

                          Table 4: P-DAO Messages

Quick heads-up ๐Ÿ™ˆ: E is NOT an implicit Target in Storing Mode, so it needs to be added in the RPL Target Option (RTO) for P-DAOs 1 and 2. And E isn't an implicit Target for P-DAO 3 either, because E is the only entry in the VIO. Plot twist, but it makes sense once you see it ๐ŸŽ€

So the RIBs end up looking like this ๐ŸŒธ

      +======+=============+=========+=============+==========+
      | Node | Destination | Origin  | Next Hop(s) | TrackID  |
      +======+=============+=========+=============+==========+
      | E    | F, G        | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | D    | E           | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | C    | D           | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | E           | P-DAO 1 | D           | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | B    | C           | P-DAO 2 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | E           | P-DAO 2 | C           | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | A    | B           | P-DAO 2 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | E           | P-DAO 2 | B           | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | F, G        | P-DAO 3 | E           | (A, 129) |
      +------+-------------+---------+-------------+----------+

                         Table 5: RIB Settings

Packets from A to E don't need encapsulation ๐Ÿฆ‹. In the tables below, that's why E only shows up as an IPv6 destination address when the IPv6 source address X is different from A. On the flip side, encapsulation is ALWAYS done when the IPv6 destination address is F or G ๐Ÿ”ฅ. Any other destination address doesn't match this P-Route, so it's not subject to encapsulation.

The outer headers on packets forwarded along the Track are set like this ๐Ÿ’œ

+========+=====================+==========================+=========+
| Header |     IPv6 Source     | IPv6 Destination Address | TrackID |
|        |       Address       |                          |  in RPI |
+========+=====================+==========================+=========+
| Outer  |          A          |            E             |   (A,   |
|        |                     |                          |   129)  |
+--------+---------------------+--------------------------+---------+
| Inner  |          X          | Either F or G.  If X!=A, |   N/A   |
|        |                     | E is also permitted.     |         |
+--------+---------------------+--------------------------+---------+

                    Table 6: Packet Header Settings

Let's walk through an example ๐Ÿงšโ€โ™€๏ธ Say A has a packet for F. Using the RIB in Table 5:

  • From P-DAO 3: A encapsulates the packet and sends it down the Track signaled by P-DAO 3, with the outer header above. Now the packet destination is E.
  • From P-DAO 2: A forwards to B, and B forwards to C.
  • From P-DAO 1: C forwards to D, and D forwards to E. E decapsulates the packet.
  • From Neighbor Cache Entry: E delivers packets to F or G.

3.5.1.3. Segment Routing

Okay this one is giving โœจ segments. Protection paths get leveraged to combine segments and form a graph ๐Ÿ•ธ๏ธ. Packets are source routed from one segment to the next to adapt the path ๐Ÿฆ‹

  • P-DAO 1 signals C==>D==>E-to-E
  • P-DAO 2 signals A==>B-to-B,C
  • P-DAO 3 signals F and G via the A-->C-->E-to-(E),F,G Track

Storing Mode P-DAOs 1 and 2 and Non-Storing Mode P-DAO 3 get sent to E, B, and A, respectively, like so ๐Ÿ’…

    +====================+==============+==============+==============+
    |                    | P-DAO 1 to E | P-DAO 2 to B | P-DAO 3 to A |
    +====================+==============+==============+==============+
    | Mode               | Storing      | Storing      | Non-Storing  |
    +====================+--------------+--------------+--------------+
    | Track ingress      | A            | A            | A            |
    +====================+--------------+--------------+--------------+
    | (DODAGID, TrackID) | (A, 129)     | (A, 129)     | (A, 129)     |
    +====================+--------------+--------------+--------------+
    | SegmentID          | 1            | 2            | 3            |
    +====================+--------------+--------------+--------------+
    | VIO                | C, D, E      | A, B         | C, E         |
    +====================+--------------+--------------+--------------+
    | Targets            | E            | B, C         | F, G         |
    +====================+--------------+--------------+--------------+

                          Table 7: P-DAO Messages

Note the segment can end at the loose hop (like in the P-DAO 1 example) or at the previous hop (like P-DAO 2 does) ๐ŸŒˆ. Both options work on any segment joined by a loose protection path. P-DAO 1 creates more signaling, since E is the segment egress when D could've been. The perk is that it double-checks the connectivity between D and E still exists ๐Ÿซถ

So the RIBs look like this ๐Ÿ“

      +======+=============+=========+=============+==========+
      | Node | Destination | Origin  | Next Hop(s) | TrackID  |
      +======+=============+=========+=============+==========+
      | E    | F, G        | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | D    | E           | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | C    | D           | P-DAO 1 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | E           | P-DAO 1 | D           | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | B    | C           | P-DAO 2 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | A    | B           | P-DAO 2 | Neighbor    | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | C           | P-DAO 2 | B           | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | E, F, G     | P-DAO 3 | C, E        | (A, 129) |
      +------+-------------+---------+-------------+----------+

                         Table 8: RIB Settings

Packets originated at A to E don't need an encapsulation, but they DO carry an SRH via C ๐ŸŽ€. The outer headers of packets forwarded along the Track are set like this:

+========+=====================+==========================+=========+
| Header |     IPv6 Source     | IPv6 Destination Address | TrackID |
|        |       Address       |                          |  in RPI |
+========+=====================+==========================+=========+
| Outer  |          A          |     C until C then E     |   (A,   |
|        |                     |                          |   129)  |
+--------+---------------------+--------------------------+---------+
| Inner  |          X          | Either F or G.  If X!=A, |   N/A   |
|        |                     | E is also permitted.     |         |
+--------+---------------------+--------------------------+---------+

                    Table 9: Packet Header Settings

Example time ๐Ÿฆ‹ Say A has a packet for F. Using the RIB in Table 8:

  • From P-DAO 3: A encapsulates the packet the Track signaled by P-DAO 3, with the outer header above. Now the destination in the IPv6 header is C, and an SRH signals that the final destination is E.
  • From P-DAO 2: A forwards to B, and B forwards to C.
  • From P-DAO 3: C processes the SRH and sets the destination in the IPv6 header to E.
  • From P-DAO 1: C forwards to D, and D forwards to E. E decapsulates the packet.
  • From the Neighbor Cache Entry: E delivers packets to F or G.

3.5.2. Using Non-Storing Mode Joining Tracks

In this formulation, we've got:

  • P-DAO 1 signals C==>D==>E-to-(E),F,G
  • P-DAO 2 signals A==>B==>C-to-(C),E,F,G

A==>B==>C and C==>D==>E are Tracks expressed as Non-Storing Mode P-DAOs ๐Ÿ’–

3.5.2.1. Stitched Tracks

Okay so bestie, let's talk about stitched Tracks โœจ๐ŸŽ€. Non-Storing Mode P-DAO 1 and 2 get sent to C and A, respectively, like this ๐Ÿ’…:

        +====================+==============+==============+
        |                    | P-DAO 1 to C | P-DAO 2 to A |
        +====================+==============+==============+
        | Mode               | Non-Storing  | Non-Storing  |
        +====================+--------------+--------------+
        | Track ingress      | C            | A            |
        +====================+--------------+--------------+
        | (DODAGID, TrackID) | (C, 131)     | (A, 131)     |
        +====================+--------------+--------------+
        | SegmentID          | 1            | 1            |
        +====================+--------------+--------------+
        | VIO                | D, E         | B, C         |
        +====================+--------------+--------------+
        | Targets            | F, G         | E, F, G      |
        +====================+--------------+--------------+

                      Table 10: P-DAO Messages

So the RIBs end up looking like this ๐Ÿฆ‹ (where "ND" means the address was discovered by IPv6 Neighbor Discovery [RFC4861] [RFC8505] or some equivalent method, iykyk):

      +======+=============+=========+=============+==========+
      | Node | Destination | Origin  | Next Hop(s) | TrackID  |
      +======+=============+=========+=============+==========+
      | E    | F, G        | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | D    | E           | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | C    | D           | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | "    | E, F, G     | P-DAO 1 | D, E        | (C, 131) |
      +------+-------------+---------+-------------+----------+
      | B    | C           | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | A    | B           | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | "    | C, E, F, G  | P-DAO 2 | B, C        | (A, 131) |
      +------+-------------+---------+-------------+----------+

                        Table 11: RIB Settings

Packets originated at A to E, F, and G could be generated with the RPI and the SRH and no encapsulation ๐ŸŒธ. Alternatively, A MAY generate a native packet to the target and then encapsulate it with an RPI and an SRH indicating the source-routed path leading to E, just like it would for a packet it routes coming from another node ๐Ÿงš. This is effectively the same case as packets generated by the Root in a RPL network in Non-Storing Mode, see Section 8.1.3 of [RFC9008] ๐Ÿ’œ. The latter is often preferred, ngl, because it leads to a single code path, and when the destination is F or G, it doesn't need to understand and process the RPI or the SRH ๐Ÿ™ˆ. Either way, the packets to E, F, or G carry an SRH via B and C, and when they reach C, C needs to encapsulate them again to add an SRH via D and E. The encapsulating headers of packets forwarded along the Track between C and E have these settings:

+========+=====================+==========================+=========+
| Header | IPv6 Source Address |     IPv6 Destination     | TrackID |
|        |                     |         Address          |  in RPI |
+========+=====================+==========================+=========+
| Outer  |          C          |     D until D then E     |   (C,   |
|        |                     |                          |   131)  |
+--------+---------------------+--------------------------+---------+
| Inner  |          X          |        E, F, or G        |   N/A   |
+--------+---------------------+--------------------------+---------+

           Table 12: Packet Header Settings Between C and E

Let's do an example, say A has a packet for F ๐Ÿ’–. Using the RIB in Table 11:

  • From P-DAO 2: A encapsulates the packet with a destination of F in the Track signaled by P-DAO 2. The outer header has source A, destination B, an SRH that indicates C as the next loose hop, and an RPI indicating a TrackID of 131 from A's namespace, which is distinct from a TrackID of 131 from C's ๐Ÿซถ.
  • From the SRH: Packets forwarded by B have source A, destination C, a consumed SRH, and an RPI indicating a TrackID of 131 from A's namespace. C decapsulates ๐Ÿ”ฅ.
  • From P-DAO 1: C encapsulates the packet with a destination of F in the Track signaled by P-DAO 1. The outer header has source C, destination D, an SRH that indicates E as the next loose hop, and an RPI indicating a TrackID of 131 from C's namespace. E decapsulates ๐Ÿ‘‘.

3.5.2.2. External Routes

Here's the setup for this one ๐ŸŒˆ:

  • P-DAO 1 signals C==>D==>E-to-(E)
  • P-DAO 2 signals A==>B==>C-to-(C),E
  • P-DAO 3 signals F and G via the A-->E-to-F,G Track

Non-Storing Mode P-DAO 1 gets sent to C, and Non-Storing Mode P-DAOs 2 and 3 get sent to A, like so ๐Ÿ’…:

 +====================+==============+==============+==============+
 |                    | P-DAO 1 to C | P-DAO 2 to A | P-DAO 3 to A |
 +====================+==============+==============+==============+
 | Mode               | Non-Storing  | Non-Storing  | Non-Storing  |
 +====================+--------------+--------------+--------------+
 | Track ingress      | C            | A            | A            |
 +====================+--------------+--------------+--------------+
 | (DODAGID, TrackID) | (C, 131)     | (A, 129)     | (A, 141)     |
 +====================+--------------+--------------+--------------+
 | SegmentID          | 1            | 1            | 1            |
 +====================+--------------+--------------+--------------+
 | VIO                | D, E         | B, C         | E            |
 +====================+--------------+--------------+--------------+
 | Targets            |              | E            | F, G         |
 +====================+--------------+--------------+--------------+

                       Table 13: P-DAO Messages

Note in the table above that E is an implicit Target in P-DAO 1, and so is C in P-DAO 2 ๐Ÿ‘€. As Non-Storing Mode egress node addresses, they are not listed in the respective RTOs.

So the RIBs get set up like this ๐ŸŽ€:

      +======+=============+=========+=============+==========+
      | Node | Destination | Origin  | Next Hop(s) | TrackID  |
      +======+=============+=========+=============+==========+
      | E    | F, G        | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | D    | E           | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | C    | D           | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | "    | E           | P-DAO 1 | D, E        | (C, 131) |
      +------+-------------+---------+-------------+----------+
      | B    | C           | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | A    | B           | ND      | Neighbor    | Any      |
      +------+-------------+---------+-------------+----------+
      | "    | C, E        | P-DAO 2 | B, C        | (A, 129) |
      +------+-------------+---------+-------------+----------+
      | "    | F, G        | P-DAO 3 | E           | (A, 141) |
      +------+-------------+---------+-------------+----------+

                        Table 14: RIB Settings

The encapsulating headers of packets forwarded along the Track between C and E have these settings ๐Ÿฆ‹:

+========+=====================+==========================+=========+
| Header | IPv6 Source Address |     IPv6 Destination     | TrackID |
|        |                     |         Address          |  in RPI |
+========+=====================+==========================+=========+
| Outer  |          C          |     D until D then E     |   (C,   |
|        |                     |                          |   131)  |
+--------+---------------------+--------------------------+---------+
| Middle |          A          |            E             |   (A,   |
|        |                     |                          |   141)  |
+--------+---------------------+--------------------------+---------+
| Inner  |          X          |        E, F, or G        |   N/A   |
+--------+---------------------+--------------------------+---------+

                   Table 15: Packet Header Settings

Okay, example time ๐Ÿงš. Say A has a packet for F, and we use the RIB in Table 14:

  • From P-DAO 3: A encapsulates the packet with a destination of F in the Track signaled by P-DAO 3. The outer header has source A, destination E, and an RPI indicating a TrackID of 141 from A's namespace. This recurses with the following ๐ŸŒ€.
  • From P-DAO 2: A encapsulates the packet with a destination of E in the Track signaled by P-DAO 2. The outer header has source A, destination B, an SRH that indicates C as the next loose hop, and an RPI indicating a TrackID of 129 from A's namespace.
  • From the SRH: Packets forwarded by B have source A, destination C, a consumed SRH, and an RPI indicating a TrackID of 129 from A's namespace. C decapsulates ๐Ÿ’œ.
  • From P-DAO 1: C encapsulates the packet with a destination of E in the Track signaled by P-DAO 1. The outer header has source C, destination D, an SRH that indicates E as the next loose hop, and an RPI indicating a TrackID of 131 from C's namespace. E decapsulates โœจ.

3.5.2.3. Segment Routing โœจ

okay so this is where it all clicks ๐Ÿ’– here's what's going on in this formulation:

  • P-DAO 1 signals C==>D==>E-to-(E)
  • P-DAO 2 signals A==>B-to-C
  • P-DAO 3 signals F and G via the A-->C-->E-to-(E),F,G Track

bestie, the Non-Storing Mode setup is: P-DAO 1 gets sent to C, and P-DAO 2 and P-DAO 3 both get sent to A. look at how neat this table is ๐Ÿฆ‹

                  +====================+==============+==============+==============+
                  |                    | P-DAO 1 to C | P-DAO 2 to A | P-DAO 3 to A |
                  +====================+==============+==============+==============+
                  | Mode               | Non-Storing  | Non-Storing  | Non-Storing  |
                  +====================+--------------+--------------+--------------+
                  | Track ingress      | C            | A            | A            |
                  +====================+--------------+--------------+--------------+
                  | (DODAGID, TrackID) | (C, 131)     | (A, 129)     | (A, 141)     |
                  +====================+--------------+--------------+--------------+
                  | SegmentID          | 1            | 1            | 1            |
                  +====================+--------------+--------------+--------------+
                  | VIO                | D, E         | B            | C, E         |
                  +====================+--------------+--------------+--------------+
                  | Targets            |              | C            | F, G         |
                  +====================+--------------+--------------+--------------+

                                    Table 16: P-DAO Messages

so once everything is set, the RIBs look like this ๐Ÿ‘‘

  +======+=============+=========+=============+==========+
  | Node | Destination | Origin  | Next Hop(s) | TrackID  |
  +======+=============+=========+=============+==========+
  | E    | F, G        | ND      | Neighbor    | Any      |
  +------+-------------+---------+-------------+----------+
  | D    | E           | ND      | Neighbor    | Any      |
  +------+-------------+---------+-------------+----------+
  | C    | D           | ND      | Neighbor    | Any      |
  +------+-------------+---------+-------------+----------+
  | "    | E           | P-DAO 1 | D, E        | (C, 131) |
  +------+-------------+---------+-------------+----------+
  | B    | C           | ND      | Neighbor    | Any      |
  +------+-------------+---------+-------------+----------+
  | A    | B           | ND      | Neighbor    | Any      |
  +------+-------------+---------+-------------+----------+
  | "    | B, C        | P-DAO 2 | C           | (A, 129) |
  +------+-------------+---------+-------------+----------+
  | "    | E, F, G     | P-DAO 3 | C, E        | (A, 141) |
  +------+-------------+---------+-------------+----------+

                     Table 17: RIB Settings

now the encapsulating headers ๐ŸŽ€ for packets zooming along the Track between A and B, the settings are:

  +========+=====================+==========================+=========+
  | Header | IPv6 Source Address |     IPv6 Destination     | TrackID |
  |        |                     |         Address          |  in RPI |
  +========+=====================+==========================+=========+
  | Outer  |          A          |     B until D then E     |   (A,   |
  |        |                     |                          |   129)  |
  +--------+---------------------+--------------------------+---------+
  | Middle |          A          |            C             |   (A,   |
  |        |                     |                          |   141)  |
  +--------+---------------------+--------------------------+---------+
  | Inner  |          X          |        E, F, or G        |   N/A   |
  +--------+---------------------+--------------------------+---------+

                Table 18: Packet Header Settings

and for the Track between B and C:

  +========+=====================+==========================+=========+
  | Header | IPv6 Source Address |     IPv6 Destination     | TrackID |
  |        |                     |         Address          |  in RPI |
  +========+=====================+==========================+=========+
  | Outer  |          A          |            C             |   (A,   |
  |        |                     |                          |   141)  |
  +--------+---------------------+--------------------------+---------+
  | Inner  |          X          |        E, F, or G        |   N/A   |
  +--------+---------------------+--------------------------+---------+

                Table 19: Packet Header Settings

and for the Track between C and E:

  +========+=====================+==========================+=========+
  | Header | IPv6 Source Address |     IPv6 Destination     | TrackID |
  |        |                     |         Address          |  in RPI |
  +========+=====================+==========================+=========+
  | Outer  |          C          |     D until D then E     |   (C,   |
  |        |                     |                          |   131)  |
  +--------+---------------------+--------------------------+---------+
  | Middle |          A          |            E             |   (A,   |
  |        |                     |                          |   141)  |
  +--------+---------------------+--------------------------+---------+
  | Inner  |          X          |        E, F, or G        |   N/A   |
  +--------+---------------------+--------------------------+---------+

                Table 20: Packet Header Settings

let's walk through an example, because it's giving clarity ๐Ÿงš say A has a packet for F. using Table 18:

  • From P-DAO 3: A encapsulates the packet with a destination of F in the Track signaled by P-DAO 3. The outer header has source A, destination C, an SRH that indicates E as the next loose hop, and an RPI indicating a TrackID of 141 from A's namespace. This recurses with the following.
  • From P-DAO 2: A encapsulates the packet with a destination of C in the Track signaled by P-DAO 2. The outer header has source A, destination B, and an RPI indicating a TrackID of 129 from A's namespace. B decapsulates forwards to C based on a sibling connected route.
  • From the SRH: C consumes the SRH and makes the destination E.
  • From P-DAO 1: C encapsulates the packet with a destination of E in the Track signaled by P-DAO 1. The outer header has source C, destination D, an SRH that indicates E as the next loose hop, and an RPI indicating a TrackID of 131 from C's namespace. E decapsulates.

3.6. Complex Tracks ๐Ÿงฉ

bestie, this is the reliability glow-up ๐Ÿซถ to boost the reliability of the P2P transmission, this specification lets you build a bunch of protection paths between the same ingress and egress Nodes, then bundle them together under the same TrackID, as shown in Figure 7. protection paths can be interleaved at the edges of loose hops, or they can just stay parallel.

the segments that join the loose hops of a protection path get installed with the same TrackID as that protection path. but each protection path and each segment has its own P-RouteID, so you can manage them separately (main character energy ๐Ÿ‘‘). two protection paths in the same Track can cross at a common node that's a member of a segment of each protection path, or they can be joined by additional segments. the final path of a packet might end up being a mix of interleaving those two (or more) protection paths. in that case, the common node has more than one next hop in its RIB for the Track, but there's no specific signal in the packet saying which segment to follow. so a next hop that can reach the loose hop gets selected โœจ

                      < Controller Plane Functions >

                            Southbound API

        _-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-
      _-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-._-

                           +----------+
                           | RPL Root |
                           +----------+


              (           main  DODAG                  )

       (                    all around                             )

       <-    Protection path 1   via      B,   E              ->
       <--- Segment 1 A,B ---> <------- Segment 2 C,D,E ------->



                  FWD  --   Relay --    FWD  --    FWD           Target 1
              /-- Node   --  Node   --  Node   --  Node \       /
           --/    (A)        (B) \      (C)        (D)   \     /
     Track                        \                       Track
     Ingress                    Segment 5                Egress -- Target
       (I)                           \                 --  (E)       2
           \                        \                 /        \
            \ FWD   --   FWD  --   Relay --   FWD  --/          \
              Node    -- Node   -- Node    -- Node               Target 3
              (F)        (G)       (H)        (J)



       <------ Segment 3 F,G,H ------> <---- Segment 4 J,E ---->
       <-      Protection path 2  via     H,   E              ->

       <--- Segment 1 A,B ---> <- S5-> <---- Segment 4 J,E ---->
       <-      Protection path 3  via   B,    H,    E         ->


                                                                       )
        (

                  (                                   )

                         Figure 7: Segments and Tracks

quick heads-up, though ๐Ÿ™ˆ this spec lets you build segments inside a protection path (like segment 2 above, which lives within protection path 1) AND inter-protection-path segments (North-South, like segment 5 above, which joins protection paths 1 and 2). BUT it doesn't signal which inter-protection-path segments are available to the ingress, so North-South segments and the related path redundancy functions are currently limited. the only option available right now is defining overlapping protection paths like Figure 7 shows: protection path 3 is congruent with protection path 1 until node B, and congruent with protection path 2 from node H onward, which abstracts segment 5 as a forward segment ๐Ÿ’€


3.7. Scope and Expectations ๐ŸŽ€

3.7.1. External Dependencies ๐ŸŒธ

okay so this spec expects the main DODAG to run in RPL Non-Storing Mode so it can keep the exchanges with the Root going. based on its full picture of the parent-child relationships, the Root can build an abstracted view of the whole DODAG topology. this document adds the ability for nodes to advertise extra sibling information to add to the Root's topological awareness, which gets passed on to the PCE so it can build more/better paths that traverse those siblings ๐Ÿฆ‹

P-Routes need resources, ngl. they need routing table space in the routers and bandwidth on the links. the amount of state installed in each node must be computed to fit within that node's memory, and the amount of rerouted traffic must fit within what the transmission links can handle. the methods used to learn node capabilities and the resources available in the devices and the network are out of scope for this document. same goes for capturing and reporting LLN link capacity and reliability statistics. those can be fetched from the nodes through network management functions or other forms of telemetry, such as Operations, Administration, and Maintenance (OAM) ๐Ÿ“

3.7.2. Relationship to Other IETF Specifications ๐Ÿ’…

(the rest of this one is coming in the next part, bestie ๐Ÿซถ)

3.7.2.1. Extending 6TiSCH

okay so the 6TiSCH architecture [RFC9030] is giving centralized ๐Ÿ’…. It's kinda like the DetNet architecture [RFC8655], where the device resources and capabilities get exposed to an external controller, and that controller installs routing states into the network based on its own Objective Functions that live over in that external entity ๐Ÿงšโœจ.

3.7.2.2. Mapping to DetNet

bestie, listen ๐Ÿ‘‚ DetNet forwarding nodes only understand the simple 1-to-1 forwarding sublayer transport operation along a segment, whereas the more sophisticated relay nodes can also handle service sublayer functions like Replication and Elimination ๐Ÿ”ฅ.

One possible mapping between DetNet and this specification is to signal the relay nodes as the hops of a protection path, and the forwarding nodes as the hops in a segment that joins the relay nodes, as illustrated in Figure 7 ๐Ÿฆ‹.

3.7.2.3. Leveraging PCE

With DetNet and 6TiSCH, the part of the controller that's responsible for computing routes is a PCE ๐Ÿง . The PCE computes its routes based on its own Objective Functions, as described in [RFC4655], and it typically controls the routes using the PCE Communication Protocol (PCEP) [RFC5440]. While this specification expects a PCE, and while PCEP might effectively be used between the Root and the PCE, the control protocol between the PCE and the Root is out of scope ๐Ÿ™ˆ.

This specification also expects a single PCE with a full view of the network. Distributing the PCE function for a large network is out of scope ๐ŸŒธ. This specification uses the RPL Root as a proxy to the PCE. The PCE may be collocated with the Root or may reside in an external Controller. In the latter case, the protocol between the Root and the PCE is out of scope and gets mapped to RPL inside the DODAG. One possible control protocol between the Root and external PCE is for the Root to transmit the information it received in the RPL DAOs, including all the SIOs that detail the parent/child and sibling information, to the PCEs ๐Ÿ’œ.

The algorithm to compute the paths, the protocol used by the PCE, and the metrics and link statistics involved in the computation are also out of scope. The effectiveness of the route computation by the PCE depends on the quality of the metrics that are reported from the RPL network. Which metrics are used and how they're reported are out of scope, but the expectation is that they're mostly of a long-term, statistical nature and give visibility on link throughput, latency, stability, and availability over relatively long periods ๐Ÿ“Š.

3.7.2.4. Providing for RAW

A recovery graph as in the RAW architecture [RAW-ARCH] can be composed of forward East-West directional segments and North-South bidirectional segments. This enables additional path diversity, using PREOF to select the protection paths to be used for a given datagram. It gives a dynamic balance between the reliability and availability requirements of the flows and the need to conserve energy and spectrum โšก. This specification prepares for RAW by setting up the Tracks, but it only forms DODAGs, which are composed of aggregated end-to-end loose source-routed protection paths, joined by strict routed segments, all oriented forward ๐ŸŽ€.

The RAW architecture defines a data plane extension of the PCE called the Point of Local Repair (PLR) that adapts the use of the path redundancy within a Track to defeat the diverse causes of packet loss. The PLR controls the forwarding operation of the packets within a Track. This specification can use a PLR but doesn't impose one, and it doesn't provide the policies that would select which packets are routed through which path within a Track (in other words, how the PLR may use the path redundancy within the Track). By default, the use of the available redundancy is limited to simple load balancing, and all the segments are forward unidirectional only ๐Ÿงฉ.

A Track may be set up to reduce the load around the Root or to enable urgent traffic to flow more directly. This specification does not provide the policies that would decide which flows are routed through which Track. In a Non-Storing Mode RPL Instance, the main DODAG provides a default route via the Root, and the Tracks provide more-specific routes to the Track Targets ๐ŸŒˆ.

4. Extending and Amending Existing RFCs โœจ

This section explains which changes are extensions and which are amendments to existing specifications. It's expected that extensions to existing specifications will not cause existing code on legacy 6LRs to malfunction, as the extensions will simply be ignored. New code is required for an extension. Those 6LRs will be unable to function in the new mechanisms and may also make the P-DAOs impossible to install ๐Ÿ˜ญ. Amendments to existing specifications are situations where semantic changes are required to existing code, and where new unit tests may be required to confirm that legacy operations will continue unaffected ๐Ÿงช.

4.1. Extending RFC 6550 ๐Ÿ’–

This specification Extends RPL [RPL] to enable the Root to install forward routes inside a main DODAG that is operated as Non-Storing Mode. The Root issues a P-DAO message (see Section 4.1.1) to the Track ingress. The P-DAO message contains a new VIO that installs a strict or a loose sequence of hops to form a Track segment or a protection path, respectively ๐Ÿ›ค๏ธ.

The Projected DAO Request (P-DAO-REQ) is a new message detailed in Section 5.1. As per Section 6 of [RPL], if a node receives this message and it doesn't understand this new code, it discards the message. When the Root initiates communication to a node that it has not communicated with before, and that it has not ascertained to implement this specification (by means such as capabilities), then the Root SHOULD request a Projected DAO Request Acknowledgment (PDR-ACK) ๐Ÿ™‹โ€โ™€๏ธ.

A P-DAO-REQ message enables a Track ingress to request the Track from the Root. The resulting Track is also a DODAG for which the Track ingress is the Root, and the owner is the address that serves as the DODAGID and is authoritative for the associated namespace from which the TrackID is selected. In the context of this specification, the installed route appears as a more-specific route to the Track Targets, and the Track ingress forwards the packets toward the Targets via the Track using normal longest match IP forwarding ๐ŸŽฏ.

To ensure that the P-DAO-REQ and P-DAO messages can flow at most times, it is RECOMMENDED that the nodes involved in a Track maintain multiple parents in the main DODAG, advertise them all to the Root, and use them in turn to retry similar packets. It is also RECOMMENDED that the Root uses diverse source route paths to retry similar messages to the nodes in the Track ๐Ÿ”.

4.1.1. Projected DAO ๐Ÿฆ„

Section 6 of [RPL] introduces the RPL Control Message Options (CMOs), including the RPL Target Option (RTO) and Transit Information Option (TIO), which can be placed in RPL messages such as the DAO. A DAO message signals routing information to one or more Targets indicated in the RTOs, and it provides one and only one via-node in the TIO, with the via-node being the tunnel endpoint to reach the targets ๐Ÿš‡.

This document Amends the specification of the DAO to create the P-DAO message. This Amended DAO is signaled with a new "Projected DAO" (P) flag; see Figure 8 ๐Ÿท๏ธ.

A P-DAO is a special DAO message generated by the Root to install a P-Route formed of multiple hops in its DODAG. This provides an RPL-based method to install the Tracks as a collection of multiple P-Routes, as expected by the 6TiSCH architecture [RFC9030] ๐Ÿงต.

The Root MUST source the P-DAO message with its address that serves as the DODAGID for the main DODAG. The receiver MUST NOT accept a P-DAO message that is not sent by the Root of its DODAG, and it MUST ignore such messages silently ๐Ÿ™…โ€โ™€๏ธ.

The 'P' flag is encoded in bit position 2 of the Flags field in the DAO Base Object. The Root MUST set it to 1 in a P-DAO message. Otherwise, it MUST be set to 0. It is set to 0 in legacy implementations as specified, respectively, in Sections 20.11 and 6.4 of [RPL] ๐Ÿ“œ.

The P-DAO is a part of control plane signaling and should not be stuck behind high traffic levels. The expectation is that the P-DAO message be sent at a high QoS level, above that of data traffic, typically with the Network Control precedence ๐Ÿšฆ.

    0                   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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    TrackID    |K|D|P|  Flags  |   Reserved    | DAOSequence   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                                                               +
   |                   DODAGID field is set to the                 |
   +               IPv6 address of the Track ingress               +
   |              used to source encapsulated packets              |
   +                                                               +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Option(s)...
   +-+-+-+-+-+-+-+-+

                    Figure 8: Projected DAO Base Object

New fields:

  • TrackID: The Local or Global RPLInstanceID of the DODAG that serves as the Track (see more in Section 6.3) ๐ŸŽ€.
  • P: 1-bit flag. The P flag is set to 1 by the Root to signal a P-DAO; otherwise, it is set to 0 ๐Ÿ’–.

The D flag is set to 1 to signal that the DODAGID field is present. It may be set to 0 if and only if the destination address of the Projected DAO Acknowledgment (P-DAO-ACK) message is set to the IPv6 address that serves as the DODAGID, and it MUST be set to one otherwise, meaning that the DODAGID field MUST then be present ๐Ÿซถ.

In RPL Non-Storing Mode, the TIO and RTO are combined in a DAO message to inform the DODAG Root of all the edges in the DODAG, which are formed by the directed parent-child relationships. The DAO message signals to the Root that a given parent can be used to reach a given child. The P-DAO message generalizes the DAO to signal to the Track ingress that a Track, for which the sender is the Root, can be used to reach children and siblings of the Track egress. In both cases, options may be factorized, and multiple RTOs may be present to signal a collection of children that can be reached through the parent or the Track, respectively ๐Ÿ‘‘.

4.1.2. Projected DAO Acknowledgment โœจ

okay so this doc also Amends the DAO-ACK message ๐Ÿ’… The new P flag is how it says "hey, this one's the projected kind" ๐Ÿฆ‹

The P-DAO-ACK message looks like this, per Figure 9:

    0                   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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    TrackID    |D|P| Reserved  |  DAOSequence  |    Status     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                                                               +
   |                   DODAGID field is set to the                 |
   +               IPv6 address of the Track ingress               +
   |              used to source encapsulated packets              |
   +                                                               +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Option(s)...
   +-+-+-+-+-+-+-+-+

                      Figure 9: P-DAO-ACK Base Object

Here's the new stuff:

  • TrackID: the Local or Global RPLInstanceID of the DODAG that serves as the Track (more in Section 6.3).
  • P: 1-bit flag. The Root sets the P flag to 1 to signal a P-DAO. Otherwise, it's set to 0.

The D flag is set to 1 to signal that the DODAGID field is present. It may be set to 0 if and only if the source address of the P-DAO-ACK message is set to the IPv6 address that serves as the DODAGID, and it MUST be set to one otherwise, meaning that the DODAGID field MUST then be present. So D is basically a "is the DODAGID here?" check, and the rules are super specific ๐Ÿซถ


4.1.3. Via Information Option ๐ŸŒธ

This document Extends the CMO to create new objects called Via Information Options (VIOs) ๐Ÿงš VIOs are the multi-hop alternative to the TIOs (more in Section 5.3). There are two flavours:

  • Storing Mode VIO (SM-VIO): the stateful one. It installs a strict hop-by-hop P-Route called a Track segment.
  • Non-Storing Mode VIO (NSM-VIO): installs a loose source-routed P-Route called a protection path at the Track ingress. The Track ingress uses that state to encapsulate an IP-in-IP packet with a new Routing Header (RH) to the Track egress (more in Section 6.7).

A P-DAO contains one or more RTOs to indicate the Target (destinations) that can be reached via the P-Route, followed by exactly one VIO that signals the sequence of nodes to be followed (more in Section 6). There are two modes of operation for the P-Routes: Storing Mode and Non-Storing Mode (more in Sections 6.4.2 and 6.4.3, respectively). โœจ


4.1.4. Sibling Information Option ๐Ÿ‘ฏโ€โ™€๏ธ

This specification Extends the CMO to create the Sibling Information Option (SIO). A RPL-Aware Node (RAN) uses the SIO to advertise a selection of its candidate neighbors as siblings to the Root (more in Section 5.4). The SIO goes in DAO messages that are sent directly to the main Root, including multicast DAO (see Section 9.10 of [RPL]).

This specification Amends rules 1 and 2 listed in Section 9.10 of [RPL] for the multicast DAO operation. Here's the before and after ๐Ÿ‘€

OLD:

|  1.  A node MAY multicast a DAO message to the link-local scope
|      all-RPL-nodes multicast address.
|
|  2.  A multicast DAO message MUST be used only to advertise
|      information about the node itself, i.e., prefixes directly
|      connected to or owned by the node, such as a multicast group
|      that the node is subscribed to or a global address owned by
|      the node

NEW:

|  1.  A multicast DAO message MUST be used only to advertise
|      information about the node (using the Target Option) and
|      direct Link Neighbors such as learned by Neighbor Discovery
|      (using the SIO).
|
|  2.  The multicast DAO may be used to enable direct and indirect
|      (via a common neighbor) P2P communication without needing the
|      DODAG to relay the packets.  The multicast DAO exposes the
|      sender's addresses as Targets in RTOs and the sender's
|      neighbors addresses as siblings in SIOs; this tells the
|      sender's neighbors that the sender is willing to act as a
|      relay between those of its neighbors that are too far apart.

4.1.5. P-DAO Request ๐Ÿ™‹โ€โ™€๏ธ

The set of RPL Control Messages is Extended to include the P-DAO-REQ and PDR-ACK. These two new RPL Control Messages let a RAN request the establishment of a Track between itself (as the Track ingress Node) and a Track egress. The node makes its request by sending a new P-DAO-REQ message to the Root. The Root confirms with a new PDR-ACK message back to the requester RAN (see Section 5.1 for more). Request, confirm, done ๐Ÿ’–


4.1.6. Amending the RPI ๐ŸŽ€

Sending a packet within a RPL Local Instance requires the presence of the abstract RPI described in Section 11.2 of [RPL] in the outer IPv6 header chain (see [RFC9008]). The RPI carries a Local RPLInstanceID that, together with either the source or the destination address in the IPv6 header, indicates the RPL Instance that the packet follows.

This specification Amends [RPL] to create a new flag that signals when a packet is forwarded along a P-Route:

  • Projected-Route P: 1-bit flag. It's set to 1 in the RPI that is added in the encapsulation when a packet is sent over a Track. It's set to 0 when a packet is forwarded along the main DODAG (as a Track), including when the packet follows a segment that joins loose hops of the main DODAG. The flag is not mutable en route. ๐Ÿ”’

The encoding of the P flag in native format is shown in Section 4.2, while the compressed format is indicated in Section 4.3.


4.1.7. Additional Flag in the RPL DODAG Configuration Option ๐ŸŒˆ

The DODAG Configuration option is defined in Section 6.7.6 of [RPL]. Its purpose is extended to distribute configuration information affecting the construction and maintenance of the DODAG, plus operational parameters for RPL on the DODAG, through the DODAG. This option was originally designed with four bit positions reserved for future use as Flags. ๐Ÿ“

    0                   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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Type = 0x04 |Opt Length = 14|D| | | |A|       ...           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                     +
                                   |4 bits |

            Figure 10: DODAG Configuration Option (Partial View)

This specification Amends [RPL] to define the new "Projected Routes Support" (D) flag. The D flag is encoded in bit position 0 of the reserved Flags in the DODAG Configuration option (this is the most significant bit). It's set to 0 in legacy implementations, as specified in Sections 20.14 and 6.7.6 of [RPL] respectively.

The D flag is set to 1 to indicate that this specification is enabled in the network, and that the Root will install the requested Tracks when feasible upon receiving a P-DAO-REQ message. ๐Ÿฆ‹

Section 4.1.2 of [RFC9008] Amends [RPL] to indicate that the definition of the Flags applies to MOP values from zero (0) to six (6) only. For a MOP value of 7, the implementation MUST consider that the Root accepts P-DAO-REQ messages and will install P-Routes. ๐Ÿ”ฅ

The RPL DODAG Configuration option is typically placed in a DIO message. The DIO message propagates down the DODAG to form and then maintain its structure. The DODAG Configuration option is copied unmodified from parents to children.

[RPL] states that:

Nodes other than the DODAG root MUST NOT modify this information when propagating the DODAG Configuration option.

So a legacy parent propagates the D flag as set by the Root, and when the D flag is set to 1, it's transparently flooded to all the nodes in the DODAG. Main character flag, no edits allowed ๐Ÿ‘‘


4.2. Extending RFC 6553 ๐Ÿงš

"The Routing Protocol for Low-Power and Lossy Networks (RPL) Option for Carrying RPL Information in Data-Plane Datagrams" [RFC6553] describes the RPL Option for use among RPL routers to include the abstract RPI described in Section 11.2 of [RPL] in data packets.

The RPL Option is commonly called the RPI, even though the RPI is really the abstract information that gets transported in the RPL Option. [RFC9008] updated the Option Type from 0x63 to 0x23. ๐Ÿ’œ

This specification Extends the RPL Option to encode the P flag as follows:

    0                   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
                                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                   |  Option Type  |  Opt Data Len |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |O|R|F|P|0|0|0|0| RPLInstanceID |          SenderRank           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         (sub-TLVs)                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                    Figure 11: Amended RPL Option Format

The fields, one by one ๐Ÿ’…

  • Option Type: 0x23 or 0x63; see [RFC9008].
  • Opt Data Len: See [RFC6553].
  • O, R, and F flags: See [RFC6553]. These flags MUST be set to 0 by the sender, and MUST be ignored by the receiver if the P flag is set.
  • Projected-Route P: 1-bit flag as defined in Section 4.1.6.
  • RPLInstanceID: See [RFC6553]. Indicates the TrackID if the P flag is set, as discussed in Section 4.1.1.
  • SenderRank: See [RFC6553]. This field MUST be set to 0 by the sender, and MUST be ignored by the receiver if the P flag is set. ๐Ÿซถ

4.3. Extending RFC 8138 โœจ

okay so the 6LoWPAN Routing Header spec [RFC8138] is giving new dispatch vibes ๐Ÿฆ‹. It brings in a new 6LoWPAN [RFC6282] dispatch type for route-over topologies, and it's initially built to cover what RPL data packet compression needs ๐Ÿ’–.

Section 4 of [RFC8138] shows the generic 6LoRH formats in two flavours. Elective ones can be ignored and skipped if the router doesn't get them ๐Ÿ™ˆ. Critical ones make the packet get dropped if the router can't process them ๐Ÿ’€. The 'E' flag tells you which flavour you've got. Elective 6LoRHs have a fixed size so they can be skipped, while Critical 6LoRHs can signal their size in variable forms, which lets them do extra optimizations โœจ.

When compression as described in [RFC8138] is in play, the Root of the main DODAG that sets up the Track builds the compressed Routing Header (SRH-6LoRH) for the Track ingress ๐Ÿซถ. That way the ingress doesn't have to deal with optimizing SRH-6LoRH encoding in constrained code ๐Ÿ˜ญ. The SRH-6LoRH gets signaled in the NSM-VIO, and it's written so the Track ingress can drop it straight into the packet encapsulation as is ๐ŸŒธ.

Section 6.3 of [RFC8138] has the formats for the 6LoWPAN RH of type 5 (RPI-6LoRH), which compresses the RPI for normal RPL operation ๐Ÿ“. Honestly the RPI-6LoRH isn't a great fit for P-Routes. The 'O', 'R', and 'F' flags aren't used there, and the Rank is unknown and ignored ๐Ÿ™…โ€โ™€๏ธ.

This specification Extends [RFC8138] to add a brand-new 6LoRH, the P- RPI-6LoRH ๐Ÿ‘‘. It can be used in either Elective or Critical 6LoRH form, see Tables 22 and 23 respectively ๐Ÿ’œ. The new 6LoRH MUST be used as a Critical 6LoRH, unless an SRH-6LoRH is present and controls the routing decision. In that case it MAY be used in Elective form โญ.

The P-RPI-6LoRH is designed to compress the RPI along RPL P-Routes ๐Ÿงš. Here's the format:

     0                   1                   2
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |1|0|E| Length  |  6LoRH Type   | RPLInstanceID |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                    Figure 12: P-RPI-6LoRH Format

6LoRH Type: IANA has defined the value 8 for both the Elective and Critical forms ๐ŸŒˆ.

Elective 'E': See [RFC8138]. The 'E' flag is set to 1 to indicate an Elective 6LoRH, meaning that it can be ignored when forwarding ๐ŸŽ€.

RPLInstanceID: In the context of this specification, the RPLInstanceID field signals the TrackID; see Sections 3.4 and 6.3 ๐Ÿฆ‹.

Section 6.8 details how a Track ingress leverages the P-RPI-6LoRH header as part of the encapsulation of a packet to place it into a Track ๐Ÿ’….


5. New RPL Control Messages and Options

5.1. New P-DAO Request Control Message

the P-DAO-REQ message is sent by a node in the main DODAG to the Root ๐Ÿ”ฅ. It's a request to establish or refresh a Track where the node sending the P-DAO-REQ is the Track ingress. It also signals whether or not an acknowledgment called PDR-ACK is requested ๐Ÿ’–. A positive PDR-ACK means the Track was built and the Root commits to keeping it around for the negotiated lifetime ๐Ÿซถ.

The main Root MAY indicate to the Track ingress that the Track was terminated before its time. To do that, it MUST use an asynchronous PDR-ACK with a negative status ๐Ÿ˜ญ. A status of "Transient Failure" (see Section 11.10) means the P-DAO-REQ can be retried after a reasonable time that depends on the deployment ๐ŸŒธ. Other negative status values mean a permanent error. The attempt must be abandoned until a corrective action is taken at the application layer or through network management ๐Ÿ™…โ€โ™€๏ธ.

The Track ingress for the requested Track is indicated in the source IPv6 address of the P-DAO-REQ, and the TrackID is indicated in the message itself โœจ. At least one RPL Target Option MUST be present in the message ๐Ÿ‘‘. If more than one RPL Target Option is present, the Root will provide a Track that reaches the first listed Target and a subset of the other Targets. The details of the subset selection are out of scope ๐Ÿงš. The RTO signals the Track egress (see more in Section 6.2) ๐Ÿ“.

The RPL Control Code for the P-DAO-REQ is 0x09 ๐Ÿ’œ. The format of the P-DAO-REQ Base Object is:

  0                   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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |    TrackID    |K|R|   Flags   |  ReqLifetime  |  PDRSequence  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |   Option(s)...
 +-+-+-+-+-+-+-+-+

                 Figure 13: New P-DAO Request Format

TrackID: 8-bit field. In the context of this specification, the TrackID field signals the RPLInstanceID of the DODAG formed by the Track; see Sections 3.4 and 6.3. To allocate a new Track, the ingress Node must provide a value that is not in use at this time ๐ŸŽ€.

K: The 'K' flag is set to indicate that the recipient is expected to send a PDR-ACK back ๐Ÿ’….

R: The 'R' flag is set to request a Complex Track for redundancy ๐Ÿ›ก๏ธ.

Flags: Reserved. The Flags field MUST be initialized to zero by the sender and MUST be ignored by the receiver ๐ŸŒˆ.

ReqLifetime: 8-bit unsigned integer. The requested lifetime for the Track, expressed in Lifetime Units (obtained from the DODAG Configuration option). The value of 255 (0xFF) represents infinity (never time out) โ™พ๏ธ.

A P-DAO-REQ with a fresher PDRSequence refreshes the lifetime. A ReqLifetime of 0 indicates that the Track MUST be destroyed, e.g., when the application that requested the Track terminates ๐Ÿ’€.

PDRSequence: 8-bit wrapping sequence number, obeying the operation in Section 7.2 of [RPL] ๐Ÿ”. The PDRSequence is used to correlate a PDR-ACK message with the P-DAO-REQ message that triggered it. It is incremented at each P-DAO-REQ message and echoed in the PDR-ACK by the Root ๐Ÿซถ.

5.2. New PDR-ACK Control Message

The new PDR-ACK is sent as a response to a P-DAO-REQ message with the 'K' flag set ๐Ÿ’Œ. The RPL Control Code for the PDR-ACK is 0x0A ๐Ÿ“. Its format is:

  0                   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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |    TrackID    |     Flags     | Track Lifetime|  PDRSequence  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | PDR-ACK Status|                Reserved                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |  Option(s)...
 +-+-+-+-+-+-+-+

             Figure 14: New PDR-ACK Control Message Format

TrackID: Set to the TrackID indicated in the TrackID field of the P-DAO-REQ messages that this replies to ๐Ÿฆ‹.

Flags: Reserved. The Flags field MUST be initialized to zero by the sender and MUST be ignored by the receiver ๐ŸŒธ.

Track Lifetime: Indicates the remaining lifetime for the Track, expressed in Lifetime Units. The value of 255 (0xFF) represents infinity. The value of zero (0x00) indicates that the Track was destroyed or not created ๐Ÿ’€.

PDRSequence: 8-bit wrapping sequence number. It is incremented at each P-DAO-REQ message and echoed in the PDR-ACK ๐Ÿ”.

PDR-ACK Status: 8-bit field indicating the completion. The PDR-ACK Status is substructured as shown in Figure 15 ๐Ÿ‘‘:

        0 1 2 3 4 5 6 7
       +-+-+-+-+-+-+-+-+
       |E|R|  Value    |
       +-+-+-+-+-+-+-+-+

                     Figure 15: PDR-ACK Status Format

E: 1-bit flag. Set to indicate a rejection. When not set, a Value field that is set to 0 indicates Success/Unqualified Acceptance, and other values indicate "not an outright rejection" ๐Ÿ™Œ.

R: 1-bit flag. Reserved; MUST be set to 0 by the sender and MUST be ignored by the receiver ๐Ÿซง.

Status Value: 6-bit unsigned integer. Values depend on the setting of the 'E' flag; see Tables 28 and 29 ๐Ÿงš.

Reserved: The Reserved field MUST be initialized to zero by the sender and MUST be ignored by the receiver โœจ.

5.3. Via Information Options โœจ

okay bestie, VIOs are giving main character energy ๐Ÿฆ‹. A VIO signals the ordered list of IPv6 Via Addresses that makes up the hops of either a protection path (using Non-Storing Mode) or a segment (using Storing Mode) of a Track ๐Ÿ›ค๏ธ. A Storing Mode P-DAO carries one SM-VIO, and a Non-Storing Mode P-DAO carries one NSM-VIO ๐Ÿ’….

The validity of a VIO is set by its Segment Lifetime field โณ. A P-DAO message that has a VIO with a Segment Lifetime of 0 is called a No-Path P-DAO ๐Ÿ™ˆ.

A VIO has one or more SRH-6LoRH headers. Each one is made of an SRH-6LoRH head plus a collection of compressed Via Addresses ๐ŸŽ€. The only exception is a Non-Storing Mode No-Path P-DAO, which doesn't include an SRH-6LoRH header at all ๐Ÿ’€.

For an SM-VIO, or when [RFC8138] isn't used in the data packets, the Root MUST use only one SRH-6LoRH per Via Information Option ๐Ÿซถ. The compression is the same for all the addresses, as shown in Figure 16, just to keep things simple ๐ŸŒธ.

For an NSM-VIO, if [RFC8138] is in use in the main DODAG, the Root SHOULD optimize the size of the NSM-VIO when using different SRH-6LoRH Types would make the VIO shorter overall ๐Ÿงš. That means more than one SRH-6LoRH may show up ๐ŸŒˆ.

Here's the format of the VIO ๐Ÿ‘‘:

        0                   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
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Option Type  | Option Length |     Flags     |   P-RouteID   |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       | Seg. Sequence | Seg. Lifetime |        SRH-6LoRH head         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       .           Via Address 1 (compressed by RFC 8138)              .
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       .                              ....                             .
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       .           Via Address n (compressed by RFC 8138)              .
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       .              Additional SRH-6LoRH header(s)                   .
       |                                                               |
       .                              ....                             .

                           Figure 16: VIO Format

Now let's go field by field, it's the best bit ๐Ÿ“โœจ

  • Option Type: 0x0F for SM-VIO and 0x10 for NSM-VIO (see Table 26) ๐Ÿ”ข.
  • Option Length: an 8-bit unsigned integer giving the length in octets of the option. It doesn't count the Option Type and Length fields (see Section 6.7.1 of [RPL]). It's variable, depending on how many Via Addresses there are and what compression gets applied ๐Ÿ“.
  • Flags: an 8-bit field ๐Ÿšฉ. No flag is defined in this specification, so the field MUST be set to 0 by the sender and MUST be ignored by the receiver ๐Ÿ™…โ€โ™€๏ธ.
  • P-RouteID: an 8-bit field that identifies a component of a Track or the main DODAG, as indicated by the TrackID field ๐Ÿ†”. A value of 0 signals a path, meaning one segment or protection path on its own ๐Ÿ›ฃ๏ธ. In an SM-VIO, the P-RouteID indicates a SegmentID. In an NSM-VIO, it indicates the ID of a protection path that is added (or updated) to the overall topology of the Track ๐Ÿ—บ๏ธ.
  • Segment Sequence: an 8-bit unsigned integer ๐Ÿ”. It follows the operation in Section 7.2 of [RPL], and its initial value is 255 ๐Ÿ’ฏ.
    • When the Root of the DODAG needs to refresh or update a segment in a Track, it increments the Segment Sequence for that segment on its own ๐Ÿ”„.
    • The segment info in the VIO deprecates any state for the segment indicated by the P-RouteID within the indicated Track, and gives the new info about the segment ๐Ÿงน.
    • A VIO with a Segment Sequence that isn't as fresh as the current one gets ignored ๐Ÿฅฑ.
    • A VIO for a given DODAGID with the same (TrackID, P-RouteID, Segment Sequence) counts as a retry. It MUST NOT change the segment, and it MUST be propagated or answered as the first copy ๐Ÿ”‚.
  • Segment Lifetime: an 8-bit unsigned integer โŒ›. It's the length of time, in Lifetime Units (taken from the Configuration option), that the segment is usable. The clock starts when a new Segment Sequence is seen ๐Ÿ•ฐ๏ธ. The value 255 (0xFF) means infinity โ™พ๏ธ, and the value zero (0x00) indicates a loss of reachability ๐Ÿ’”.
  • SRH-6LoRH head: the first 2 bytes of the (first) SRH-6LoRH, as shown in Figure 6 of [RFC8138] ๐Ÿงฉ. For example, a 6LoRH of type 4 means the Via Addresses are given in full with no compression ๐Ÿ™Œ.
  • Via Address: an IPv6 ULA or GUA of a node along the segment ๐Ÿ“. The VIO has one or more IPv6 Via Addresses, listed in datapath order from ingress to egress ๐Ÿšถโ€โ™€๏ธ. The list is written in the compressed form that the preceding SRH-6LoRH header signals ๐Ÿ—œ๏ธ.
    • In a Storing Mode P-DAO that updates or removes a section of a segment that already exists, the list in the SM-VIO might only cover the section being updated. At the extreme, the SM-VIO updates just one node, and then it only has one IPv6 address ๐ŸŽฏ. In every other case, the list in the VIO MUST be complete ๐Ÿ“‹.
    • For an SM-VIO, the list is a sequential (strict) path through direct neighbors. The complete list starts at the ingress and ends at the egress, and the nodes listed in the VIO, including the egress, MAY be considered implicit Targets ๐Ÿค.
    • For an NSM-VIO, the complete list can be loose and leaves out the ingress node. It starts at the first loose hop and ends at a Track egress. The Track egress MUST be considered an implicit Target, so it MUST NOT be signaled in an RPL Target Option ๐Ÿšซ. Iconic behavior, honestly ๐Ÿ‘‘๐Ÿ’–.

5.4. Sibling Information Option ๐Ÿงš

Okay so the Sibling Information Option (SIO) is basically a cheat sheet for the Root ๐Ÿ’…. It tells the Root about siblings it could use to build P-Routes. You can drop one or more SIOs into DAO messages that head up to the Root in Non-Storing Mode ๐Ÿฆ‹.

Before a router advertises a neighbor, it MUST have an active Address Registration from that sibling per [RFC8505] for an address (ULA or GUA) that works as an identifier for the node. If this router also registers an address to that sibling, and the link behaves similarly in both directions, then only the router with the lowest Interface ID in its registered address needs to report the SIO, with the 'B' flag set. The Root will assume symmetry from there ๐Ÿ‘€โœจ

The SIO has a flag (B) that gets set when similar performance can be expected in both directions. It's basically telling the routing that the info for one direction is valid for both ๐Ÿ”ฅ If the SIO is effectively received from both sides, then the 'B' flag MUST be ignored. The policy that describes the performance criteria and how they get asserted is out of scope ๐Ÿ™ˆ Without an external protocol to assert the link quality, the flag SHOULD NOT be set.

Here's what the SIO looks like ๐ŸŽ€

        0                   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
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Option Type  | Option Length |S|B|Flags|Comp.|    Opaque     |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |            Step in Rank       |          Reserved             |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       +                                                               +
       .                                                               .
       .       Sibling DODAGID (if the D flag is not set)              .
       .                                                               .
       +                                                               +
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       +                                                               +
       .                                                               .
       .                     Sibling Address                           .
       .                                                               .
       +                                                               +
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                Figure 17: Sibling Information Option Format

Now let's go field by field ๐Ÿ’–

  • Option Type: 0x11 for SIO (see Table 26).
  • Option Length: an 8-bit unsigned integer, giving the length in octets of the option. It doesn't include the Option Type and Length fields (see Section 6.7.1 of [RPL]).
  • Reserved for Flags: MUST be set to 0 by the sender and MUST be ignored by the receiver.
  • B: a 1-bit flag that gets set to show that the connectivity to the sibling is bidirectional and roughly symmetrical ๐Ÿฆ‹ In that case, only one of the siblings needs to report the SIO for the hop. If 'B' is not set, then the SIO only shows connectivity from the sibling to this node, and it doesn't give any info on the hop from this node to the sibling.
  • S: a 1-bit flag that gets set to show that the sibling belongs to the same DODAG. When it's not set, the Sibling DODAGID is indicated.
  • Flags: Reserved. The Flags field MUST be initialized to zero by the sender and MUST be ignored by the receiver.
  • Comp.: the Compression Type, a 3-bit unsigned integer ๐Ÿงฉ This is the SRH-6LoRH Type as defined in Figure 7 in Section 5.1 of [RFC8138] that matches the compression used for the Sibling Address and its DODAGID if present. The Compression reference is the Root of the main DODAG.
  • Opaque: MAY be used to carry info that the node and the Root both understand, e.g., a particular representation of the link properties, such as a proprietary Link Quality Information for packets received from the sibling. In some scenarios, like Industrial Alliances that use RPL for a particular use or environment, this field MAY be redefined to fit the needs of the case ๐ŸŒˆ
  • Step in Rank: a 16-bit unsigned integer. This is the Step in Rank [RPL] computed by the Objective Function between this node and the sibling. It reflects the abstract Rank increment that would be computed by the Objective Function if the sibling were the preferred parent โญ
  • Reserved: The Reserved field MUST be initialized to zero by the sender and MUST be ignored by the receiver
  • Sibling DODAGID: 2 to 16 bytes. This is the DODAGID of the sibling in a compressed form [RFC8138], as indicated by the Compression Type field. This field is present if and only if the 'D' flag is not set.
  • Sibling Address: 2 to 16 bytes. This is an IPv6 address of the sibling with a scope that MUST make it reachable from the Root, e.g., it cannot be a Link Local Address. The IPv6 address is encoded in the compressed form [RFC8138] indicated by the Compression Type field ๐Ÿซถ

An SIO MAY be immediately followed by a DAG Metric Container. In that case, the DAG Metric Container gives extra metrics for the hop from the Sibling to this node ๐Ÿ“


6. Root-Initiated Routing State ๐Ÿ‘‘

6.1. RPL Network Setup ๐ŸŒธ

To avoid the need for Path MTU Discovery by 6LoWPAN endpoints, 6LoWPAN links are normally defined with an MTU of 1280 (see Section 4 of [6LoWPAN]). Injecting packets into a Track typically involves an IP-in-IP encapsulation and additional IPv6 extension headers ๐Ÿ˜ญ That can cause fragmentation if the resulting packets go over the MTU defined for the RPL domain.

Fragmentation is possible in a 6LoWPAN LLN (for example, using [6LoWPAN], [RFC8930], and/or [RFC8931]), but it is RECOMMENDED to define an MTU larger than 1280 between the RPL routers that form the main DODAG. That gives room for the extra headers while still exposing 1280 to the 6LoWPAN endpoint stacks ๐Ÿ’…โœจ

6.2. Requesting a Track ๐Ÿฆ‹

This specification introduces the P-DAO-REQ message. An LLN node uses it to request the formation of a new Track for which the LLN node is the ingress ๐Ÿงš Note that the namespace for the TrackID is owned by the ingress node. Without a P-DAO-REQ, there must be some procedure for the Root to assign TrackIDs in that namespace while avoiding collisions (see more in Section 6.3).

The P-DAO-REQ signals the desired TrackID and the duration for which the Track should be established. When a P-DAO-REQ comes in, the Root MAY install the Track as requested. If it does, it answers with a PDR-ACK indicating the granted Track Lifetime ๐Ÿ’– All the segments MUST be of the same mode, either Storing or Non-Storing. All the segments MUST be created with the same TrackID and the same DODAGID signaled in the P-DAO.

The Root designs the Track however it sees fit and updates or changes the segments over time to serve the Track as needed ๐Ÿ”ฅ There's no protocol element to notify the requesting Track ingress when changes happen deeper down the Track, so they're transparent to the Track ingress ๐Ÿ™ˆ If the main Root can't maintain an expected service level, then it needs to tear down the Track completely. The Segment Lifetime in the P-DAO messages does not need to line up with the Requested Lifetime in the P-DAO-REQ, or between P-DAO messages for different segments. For example, the Root may use shorter lifetimes for the segments and renew or change them during the lifetime of the Track. All the components (protection paths and segments) of a Track MUST be destroyed (or have their lifetime elapsed) before the TrackID can be reused.

When the Track Lifetime is relatively close to elapsing (meaning on the order of the trip time from the node to the Root), the requesting node SHOULD resend a P-DAO-REQ using the TrackID in the PDR-ACK to extend the lifetime of the Track. Otherwise, the Track will time out, and the Root will tear down the whole structure ๐Ÿ˜ฑ

If the Track fails and can't be restored, the Root notifies the requesting node asynchronously with a PDR-ACK. That PDR-ACK has a Track Lifetime of 0, which means the Track has failed, plus a PDR-ACK Status that gives the reason for the fault ๐Ÿ’€

6.3. Identifying a Track ๐Ÿฆ‹

okay so RPL has this thing called an Instance ๐ŸŒธ that signals one individual routing topology, and you can have multiple topologies chilling in the same network at once. The RPLInstanceID gets tagged in the RPI of every packet so everyone knows which topology that packet is actually following ๐Ÿ’…

Here's how this spec leverages the Instance model โœจ

  • The main Root MAY use P-DAO messages to add better routes in the main Instance, as long as they fit the routing objectives in that Instance ๐Ÿ‘‘

So the main Root MAY install a segment along a path down the main DODAG, and that segment runs in Non-Storing Mode. This enables loose source routing and shrinks the Routing Header (see Section 3.3.1 ๐Ÿ“ฆ). The main Root MAY also install a protection path across the main DODAG to complement the routing topology ๐Ÿ›ก๏ธ

When the main Root adds a P-Route to the RPL main DODAG, it MUST set the RPLInstanceID field of the P-DAO Base Object (see Section 6.4.1 of [RPL]) to the RPLInstanceID of the main DODAG, and it MUST NOT use the DODAGID field. A P-Route gives a longer match to the Target Address than the default route via the main Root, so it's the one that gets preferred ๐Ÿ†

  • The main Root MAY also use P-DAO messages to install a Track as an independent routing topology (say, Traffic Engineered) so it gets particular routing characteristics from ingress to egress endpoints ๐Ÿšฆ To do that, the main Root MUST set up a Local RPL Instance (see Section 5 of [RPL]), and the Local RPLInstanceID serves as the TrackID. The TrackID MUST be unique for the IPv6 ULA or GUA of the Track ingress that serves as the DODAGID for the Track.

This way, a Track is uniquely identified by the tuple (DODAGID, TrackID), where the TrackID is always represented with the 'D' flag set to 0 (see also Section 5.1 of [RPL]). That 'D' flag set to 0 means that when it shows up in an RPI, the source address of the IPv6 packet is what signals the DODAGID ๐Ÿงญ

The P-DAO Base Object MUST indicate the tuple (DODAGID, TrackID) that identifies the Track as shown in Figure 8, and the P-RouteID that identifies the P-Route MUST be signaled in the VIO as shown in Figure 16 ๐Ÿ–ผ๏ธ

The Track ingress is the Root of the DODAGID formed by the Local RPL Instance. It owns the namespace of its TrackIDs, so it can pick any unused value to request a new Track with a P-DAO-REQ. In a particular deployment where P-DAO-REQs aren't used, a portion of the namespace can be administratively delegated to the main Root, meaning the main Root is authoritative for assigning the TrackIDs for the Tracks it creates ๐Ÿ—‚๏ธ

With this spec, the main Root knows about all the active Tracks, so it can also pick any unused value to form Tracks without a P-DAO-REQ. To avoid a collision where the main Root and the Track ingress pick the same value at the same time, it is RECOMMENDED that the Track ingress starts allocating the ID value of the Local RPLInstanceID (see Section 5.1 of [RPL]) used as TrackIDs with the value 0 incrementing, while the Root starts with 63 decrementing ๐Ÿซถ


6.4. Installing a Track ๐Ÿš‚

A path can be installed by a single P-Route that signals the sequence of consecutive nodes, either in Storing Mode as a single-segment Track or in Non-Storing Mode as a single-protection-path Track. A single-protection-path Track can be installed as a loose Non-Storing Mode P-Route, in which case the next loose entry must recursively be reached over a path ๐Ÿ›ค๏ธ

A Complex Track can be installed as a collection of P-Routes with the same DODAGID and TrackID. The ingress of a Non-Storing Mode P-Route is the owner and Root of the DODAGID. The ingress of a Storing Mode P-Route must be either the owner of the DODAGID or a hop of a protection path of the same Track. In the latter case, the Targets of the P-Route must include the next hop of the protection path if there is one, to ensure forwarding continuity. In the case of a Complex Track, each segment is maintained independently and asynchronously by the Root, with its own lifetime that may be shorter, the same, or longer than that of the Track โณ

A route along a Track for which the TrackID is not the RPLInstanceID of the main DODAG MUST be installed with a higher precedence than the routes along the main DODAG, meaning that:

  • The longest match MUST be the prime comparison for routing. ๐Ÿ‘‘
  • For an equal-length match, the route along the Track MUST be preferred over the one along the main DODAG. ๐Ÿฅ‡
  • There SHOULD NOT be two different Tracks leading to the same Target from same ingress node, unless there's a policy for selecting which packets use which Track. Such a policy is out of scope ๐Ÿ™…
  • A packet that was routed along a Track MUST NOT be routed along the main DODAG again. If the destination is not reachable as a neighbor by the node where the packet exits the Track, then the packet MUST be dropped ๐Ÿ’€

6.4.1. Signaling a Projected Route ๐Ÿ”ญ

This specification adds a capability where the Root of a main DODAG installs a Track as a collection of P-Routes, using a P-DAO message for each individual protection path or segment. The P-DAO signals a collection of Targets in one or more RTOs. Those Targets can be reached via a sequence of routers indicated in a VIO ๐ŸŒˆ

Like a classical DAO message, a P-DAO causes a change of state only if it is "new" per Section 9.2.2 ("Generation of DAO Messages") of the RPL specification [RPL]. This is determined using the Segment Sequence information from the VIO, as opposed to the Path Sequence from a TIO. Also, a Segment Lifetime of 0 in a VIO indicates that the P-Route associated to the segment is to be removed. There are two Modes of operation for the P-Routes: Storing and Non-Storing ๐Ÿงฉ

A P-DAO message MUST be sent from the address of the Root that serves as the DODAGID for the main DODAG. It MUST contain either exactly one sequence of one or more RTOs followed by one VIO, or any number of sequences of one or more RTOs followed by one or more TIOs. The former is the normal expression for this specification, whereas the latter corresponds to the variation for less-constrained environments described in Section 7.2 ๐ŸŒธ

A P-DAO that creates or updates a protection path MUST be sent to a GUA or a ULA of the ingress of the protection path. It MUST contain the full list of hops in the protection path, unless the protection path is being removed. A P-DAO that creates a new Track segment MUST be sent to a GUA or a ULA of the segment egress and MUST signal the full list of hops in a segment. A P-DAO that updates (including deletes) a section of a segment MUST be sent to the first node after the modified segment and MUST signal the full list of hops in the section, starting at the node that immediately precedes the modified section ๐Ÿซง

In Non-Storing Mode, as discussed in Section 6.4.3, the Root sends the P-DAO to the Track ingress, where the source routing state is applied. In Storing Mode, the P-DAO is sent to the last node on the installed path and forwarded in the reverse direction, installing a Storing Mode state at each hop, as discussed in Section 6.4.2. In both cases, the Track ingress is the owner of the Track, and it generates the P-DAO-ACK when the installation is successful ๐ŸŽ€

If the 'K' flag is present in the P-DAO, the P-DAO MUST be acknowledged using a P-DAO-ACK that is sent back to the address of the Root from which the P-DAO was received. In most cases, the first node of the protection path, segment, or updated section of the segment is the node that sends the acknowledgment. The exception to the rule is when an intermediate node in a segment fails to forward a Storing Mode P-DAO to the previous node in the SM-VIO ๐Ÿ’Œ

In a No-Path Non-Storing Mode P-DAO, the SRH-6LoRH MUST NOT be present in the NSM-VIO. The state in the ingress is erased regardless. In all other cases, a VIO MUST contain at least one Via Address, and a Via Address MUST NOT be present more than once, which would create a loop ๐Ÿ”

A node that processes a VIO MAY verify whether any of these conditions happen. When one does, it MUST ignore the P-DAO and reject it with an RPL rejection status of "Error in VIO" in the DAO-ACK (see Section 11.16). ๐Ÿšซ

Errors, other than those discussed explicitly, that prevent the installation of the route are acknowledged with an RPL rejection status of "Unqualified Rejection" in the P-DAO-ACK ๐Ÿ’…

6.4.2. Installing a Track Segment with a Storing Mode P-Route โœจ

okay so, as Figure 18 shows, a Storing Mode P-DAO installs a route along the segment signaled by the SM-VIO, pointing at the Targets listed in the Target Options ๐ŸŽ€. The segment gets included in a DODAG named by the P-DAO Base Object. That could be the main DODAG, or a Track tied to a Local RPL Instance ๐Ÿฆ‹.

        ------+---------
              |          Internet
              |
           +-----+
           |     | Border Router
           |     |  (RPL Root)
           +-----+                      | P-  ^                   |
              |                         | DAO | P-DAO-ACK         |
        o    o   o    o                 |     |                   |
    o o   o  o Ingress  o  o  o         |  ^       | Projected    .
     o  o o  o    o  \\  o  o    o        |  | P-DAO | Route        .
     o   o    o  o    \\  o    o  o  o    | ^        |              .
    o  o   o  o   o    Egress   o o       v | P-DAO  v              .
    o          o   LLN   o   o     o                                |
        o o   o        o     o              Loose Source Route Path |
     o       o      o    o                                          v

                   Figure 18: Projecting a Route

So here's the vibe ๐Ÿ’…. The Root sends a unicast P-DAO to the Track egress router of the routing segment being installed. Respect ๐Ÿ™Œ. That P-DAO carries an SM-VIO with a strict sequence of Via Addresses. The SM-VIO comes after one or more RTOs that show which Targets the Track leads to. It also has a Segment Lifetime, which is how long the state should hang around ๐Ÿ•ฐ๏ธ.

The Root sends the P-DAO straight to the egress node of the segment ๐ŸŽฏ. In that P-DAO, the destination IP address matches the last Via Address in the SM-VIO. That's how the egress knows it's the egress ๐Ÿ˜ญ. Same energy for the ingress node: it sees that it matches the first Via Address in the SM-VIO, so it knows its role too ๐Ÿซถ.

The egress node is the only node on the path that doesn't install a route when it gets the P-DAO. It's expected to already route to the Target(s) using its existing tables ๐Ÿ’œ. If one of the Targets isn't known, the node MUST answer the Root with a P-DAO-ACK. That P-DAO-ACK lists the unreachable Target(s) in an RTO and uses a rejection status of "Unreachable Target" ๐Ÿ’€.

If the egress can reach every Target, it forwards the P-DAO with the content unchanged to its predecessor in the segment. That predecessor is listed in the VIOs ๐Ÿ”ฅ. The message keeps getting passed along the routers in the P-DAO, unchanged, but in reverse order, going from egress all the way back to ingress ๐ŸŒˆ.

The predecessor address used as the destination of the propagated DAO message is found in the Via Address list. You grab the entry right before the one holding the address of the node that's propagating, which becomes the source of the message ๐Ÿ“.

When a propagated DAO arrives, every router except the egress router MUST install a route toward the DAO Target(s) through its successor in the SM-VIO ๐Ÿงš. Now here's the tea โ˜•. If a router can't store routes to all the Targets in a P-DAO, it MUST reject the P-DAO. It does that by sending a P-DAO-ACK to the Root with a rejection status of "Out of Resources", and it does NOT forward the DAO to its predecessor in the list ๐Ÿ™…โ€โ™€๏ธ.

The router MAY install extra routes toward the Via Addresses that appear after its own address in the SM-VIO, if there are any. But if there's a conflict or not enough resources, the route(s) to the Target(s) MUST be installed in priority. Targets come first, always ๐Ÿ‘‘.

If a router can't reach its predecessor in the SM-VIO, the router MUST send the P-DAO-ACK to the Root with a rejection status of "Predecessor Unreachable" ๐Ÿ˜ต.

The whole thing keeps going until the P-DAO gets propagated to the ingress router of the segment. That ingress then sends a P-DAO-ACK back to the Root โœจ. The Root always, always expects a P-DAO-ACK. It'll come either from the Track ingress with a positive status, or from any node along the segment with a negative one ๐Ÿ’…. If the P-DAO-ACK never shows up, the Root may retry the DAO with the same TrackID, or it may tear down the route ๐Ÿฆ‹.


6.4.3. Installing a Protection Path with a Non-Storing Mode P-Route

As Figure 19 shows, a Non-Storing Mode P-DAO installs a source-routed path inside the Track named by the P-DAO Base Object. That path heads toward the Targets listed in the Target Options ๐ŸŒธ. This source-routed path needs a Source Routing Header, which means IP-in-IP encapsulation is needed to add the SRH to an existing packet ๐ŸŽ. The P-DAO goes to the Track ingress. The ingress creates a tunnel tied to the Track, and connected routes run over that tunnel to the Targets in the RTO ๐Ÿš‡.

The tunnel encapsulation MUST include a Routing Header built from the addresses in the VIO, in the same order ๐Ÿซถ. The content of the NSM-VIO, starting at the first SRH-6LoRH header, MUST be used verbatim by the Track ingress when it encapsulates a packet to forward over the Track. No edits, bestie ๐Ÿ™…โ€โ™€๏ธ.

           ------+---------
                 |          Internet
                 |
              +-----+
              |     | Border Router
              |     |  (RPL Root)
              +-----+                    | P-  ^ P-DAO-ACK
                 |        Track          | DAO |
           o    o   o    Ingress         V     |
       o o   o  o   o  o     X   o                X Source-
      o  o o  o o    o   o     X    o  o          X Routed
      o   o    o  o     o   o    X     o          X Segment
     o  o   o  o   o  o    o  o    X              X
                                 Egress
        o  o  o  o           o     |
                                 Target
       o       o     LLN          o
     o          o             o     o

              Figure 19: Projecting a Non-Storing Route

Here's the order of operations, and it's important ๐Ÿ“‹. The next entry in the source-routed path must be either a neighbor of the previous entry, or reachable as a Target through another P-Route. That other route can be Storing or Non-Storing ๐Ÿงฉ. This means the nested P-Route has to be installed before the loose sequence is. P-Routes must be installed from last to first along the datapath. For example, a segment of a Track must be installed before any protection path of that same Track that uses it. Stitched segments must be installed in order, from last to first, so they can reach the Targets ๐Ÿชก.

If the next entry in the loose sequence is reachable over a Storing Mode P-Route, it MUST be the Target of a segment and also the ingress of a next segment. Both of those need to already be set up. The segments belong to the same Track, so there's no need for an extra encapsulation ๐Ÿ’–. For example, in Section 3.5.1.3, segments A==>B-to-C and C==>D==>E-to-F must be installed with Storing Mode P-DAO messages 1 and 2. Only then can the Track A-->C-->E-to-F that joins them be installed with Non-Storing Mode P-DAO 3 ๐ŸŒˆ.

Now the other case. If it's reachable over a Non-Storing Mode P-Route, the next loose source-routed hop of the inner Track is a Target of a previously installed Track. It's also the ingress of a next Track ๐Ÿงšโ€โ™€๏ธ. That one needs de- and re-encapsulation when the outer Tracks switch, since they're the ones joining the loose hops. Section 3.5.2.3 shows this off: Non-Storing Mode P-DAOs 1 and 2 install strict Tracks, and Non-Storing Mode P-DAO 3 joins them as a super Track ๐Ÿ‘‘. In that situation, packets get double IP-in-IP encapsulation ๐ŸŽ€.


6.5. Tearing Down a P-Route

A P-DAO with a lifetime of 0 counts as a No-Path DAO ๐Ÿงน. Its whole job is cleaning up existing state. It's not refreshing anything or installing anything new ๐Ÿซง. To tear down a Track, the Root must tear down every Track segment and protection path that makes it up, one by one ๐Ÿ’….

The protection path state of a Track lives only on the ingress node. So the Root cleans up a protection path by sending an NSM-VIO to the ingress. That NSM-VIO has the TrackID and the P-RouteID of the protection path being removed, a Segment Lifetime of 0, and a newer Segment Sequence ๐Ÿ—‘๏ธ. The SRH-6LoRH with Via Addresses in the NSM-VIO isn't needed. It SHOULD NOT be placed in the message, and it MUST be ignored by the receiver ๐Ÿ™ˆ. When the ingress gets that NSM-VIO, it removes all the state for that Track, if there is any. Then it replies positively anyway ๐Ÿ’–.

To clean up a section of a segment, the Root sends an SM-VIO to the last node of the segment. That SM-VIO has an updated TrackID and P-RouteID, a Segment Lifetime of 0, and a newer Segment Sequence ๐Ÿงผ. The Via Addresses in the SM-VIO show which section is being changed, going from the first impacted node to the last one ๐Ÿ—บ๏ธ. That section can be the whole segment, if the whole thing is getting removed. It can also be a run of one or more nodes that a segment update has bypassed ๐Ÿฆ‹.

The No-Path P-DAO gets forwarded normally along the reverse list. That happens even if an intermediate node doesn't find any segment state to clean up ๐ŸŒธ. The result is that existing segment state gets cleaned up, if there is any. It's not refreshed, and nothing new gets installed โœจ.


6.6. Maintaining a Track

Repathing a Track segment or protection path may cause jitter and packet misordering ๐Ÿ˜ฌ. For critical flows that need timely and/or in-order delivery, it might be necessary to deploy PREOF [RAW-ARCH] over a highly redundant Track ๐Ÿ”. This specification lets a Track use more than one protection path, plus 1+N packet redundancy ๐Ÿ’œ.

This section gives the steps for making sure no packet gets lost because of the operation itself ๐Ÿ›Ÿ. It works by installing the new section from its last node back to the first. That way, when an intermediate node installs a route along the new section, every downstream node in that section has already set up its own ๐Ÿชœ. The disabled section gets removed as well, once the in-flight packets have been forwarded along the new section ๐Ÿšš.

6.6.1. Maintaining a Track Segment

To change a section of a segment between the first node and a second downstream node (these can be the ingress and egress, respectively), while keeping those nodes in the segment, the Root sends an SM-VIO to the second node ๐Ÿซถ. That SM-VIO lists the sequence of nodes in the new section of the segment. It carries the TrackID and the P-RouteID of the segment being updated, plus a newer Segment Sequence ๐ŸŽ€. The P-DAO travels from the second node back to the first. On the way, it updates the state on the nodes that the old and new sections have in common, and it creates state on the new nodes ๐ŸŒˆ.

When the state gets updated on an intermediate node, that node might still get packets that were in flight from the ingress over the old section of the segment. Since the rest of the segment is already updated, those packets get forwarded along the new version of the segment from that node onward ๐Ÿš€.

After a reasonable amount of time, the Root tears down the remaining section(s) of the old segments, as described in Section 6.5. That lets the deprecated sections drain their traffic ๐ŸŒŠ๐Ÿ’…

6.6.2. Maintaining a Protection Path โœจ

Okay so this bit is all about adding and swapping protection paths on a Track ๐Ÿ›ค๏ธ. The Root can add a protection path by sending a Non-Storing Mode P-DAO to the ingress, using the same TrackID and a brand new SegmentID ๐Ÿ’–. If the protection path is loose, the segments that join the hops must be created first ๐Ÿงฉ.

It's giving smart planning here. You should add the new protection path before you remove the old one that's getting super lossy ๐Ÿซถ. Dropping a Track before its replacement is installed would reroute the traffic via the Root ๐Ÿ˜ญ. That can push the latency past acceptable thresholds and overload the network near the Root. It can also cause loops with stitched Tracks: packets that can't get into the second Track might get routed back and reinjected at the ingress of the first Track ๐ŸŒ€. Not me getting caught in a loop ๐Ÿ’€.

You can also update a protection path by sending a Non-Storing Mode P-DAO to the ingress with the same SegmentID, an incremented Segment Sequence, and the new complete list of hops in the NSM-VIO ๐Ÿฆ‹. Updating a live protection path means changing one or more of the intermediate loose hops. That involves laying out new segments from and to the new loose hops before the NSM-VIO goes out for the new protection path ๐Ÿงš.

Packets already in flight over the old version of the protection path still follow the old source route path over the old segments ๐Ÿ“ฆ. After a reasonable time, the Root tears down those segments as described in Section 6.5, so the deprecated segments can drain their traffic ๐ŸŒธ.


6.7. Encapsulating and Forwarding Along a Track ๐ŸŽ€

When a packet gets injected into a Track, the ingress router must encapsulate it using IP-in-IP. The encapsulation adds the Source Routing Header, with the final destination set to the Track egress ๐Ÿ’….

All properties of a Track's operations are inherited from the main Instance that was used to install the Track ๐Ÿ‘‘. For example, whether compression per [RFC8138] is used depends on whether it's used in the RPL main DODAG. You check that by setting the 'T' flag [RFC9035] in the RPL Configuration option ๐Ÿ“.

When the Track ingress places a packet in a Track, it wraps the packet with an extra IPv6 header, a Routing Header, and an IPv6 Hop-by-Hop Option Header that contains the RPI, like this:

  • In the uncompressed form, the source of the packet is the address that this router uses as the DODAGID for the Track. The destination is the first Via Address in the NSM-VIO. The RH is an SRH [RFC6554] that contains the list of the remaining Via Addresses, ending with the Track egress โœจ.
  • In a network where 6LoWPAN header compression [RFC6282] is in use, it is preferred to implement "IPv6 over Low-Power Wireless Personal Area Network (6LoWPAN) Paging Dispatch" [RFC8025] and compress the RPL artifacts as indicated in [RFC8138] ๐ŸŒˆ.

In that case, the RPL Source Route Header is an exact copy of the (chain of) SRH-6LoRH found in the NSM-VIO, also ending with the Track egress. The RPI-6LoRH is appended next, followed by an IP-in-IP 6LoRH header that indicates the ingress router in the Encapsulator Address field. See a similar case in Figure 20 of [RFC8138] ๐Ÿฆ‹.

To signal the Track in the packet, this specification borrows the RPL forwarding model like so ๐Ÿ’œ:

  • In the data packets, the Track DODAGID and the TrackID MUST be respectively signaled as the IPv6 source address, and the RPLInstanceID field of the RPI MUST be placed in the outer chain of IPv6 headers ๐Ÿซถ.

The RPI carries a Local RPLInstanceID called the TrackID. Together with the DODAGID, that tells you which Track the packet is being forwarded along ๐Ÿ›ค๏ธ.

The 'D' flag in the RPLInstanceID MUST be set to 0 to indicate that the source address in the IPv6 header is set to the DODAGID. (See more in Section 6.3.)

  • This specification conforms to the principles of [RFC9008] when it comes to packet forwarding and encapsulation along a Track, as follows:
    • With this specification, the Track is a RPL DODAG. From the perspective of that DODAG, the Track ingress is the Root, and the Track egress is a RPL-Aware 6LR. Neighbors of the Track egress that can be reached via the Track, but are external to it, are external destinations and are treated as RPL-Unaware Leaves (RULs). The encapsulation rules in [RFC9008] apply ๐ŸŒธ.
    • If the Track ingress is the originator of the packet and the Track egress is the destination of the packet, there is no need for an encapsulation ๐Ÿ™ˆ.
    • So the Track ingress must encapsulate the traffic that it did not originate, and it must include an RPI in the encapsulation to signal the TrackID ๐Ÿ”ฅ.

A packet that is being routed over the RPL Instance associated to a first Non-Storing Mode Track MAY be placed recursively in a second Track to cover one loose hop of the first Track. This is discussed in more detail in Section 3.5.2.3. On the other hand, a Storing Mode segment must be strict, and a packet that is placed in a Storing Mode segment MUST follow that segment till the segment egress ๐Ÿง .

It's known that a packet is forwarded along a Track by the source address and the RPI in the encapsulation ๐Ÿ”. The TrackID is used to identify the RIB entries associated to that Track. On intermediate nodes, those correspond to the P-Routes for the segments of the Track that the forwarding router is aware of. Packet processing uses this precedence: 1) self-delivery or Routing Header handling when one is present, 2) delivery to direct neighbors, 3) delivery to indirect neighbors, 4) routing along a segment along the Track, and 5) injecting the packet in another Track, as a last resort ๐Ÿ‘‘.

To make that happen, the packet handling logic MUST happen in the following order ๐Ÿ’…:

  • If the destination of the packet is self:
    1. If the header chain contains a RPL Source Route Header that is not fully consumed, then the packet is forwarded along the Track as prescribed by [RFC6554], meaning the next entry in the Routing Header becomes the destination ๐Ÿฆ‹.
    2. Otherwise, if the packet was encapsulated, then the packet is decapsulated and the forwarding process recurses. Else, the packet is delivered to the stack โœจ.
  • Otherwise, the packet is forwarded as follows:
    1. If the destination of the packet is a direct neighbor, e.g., installed by IPv6 Neighbor Discovery, then the packet MUST be forwarded to that neighbor ๐Ÿ’–.
    2. Else, if the destination of the packet is an indirect neighbor, e.g., installed by a multicast DAO message from a common neighbor (see Section 4.1.4), then the packet MUST be forwarded to the common neighbor ๐Ÿซถ.
    3. Else, if there is a RIB entry for the same Track (e.g., installed by an SM-VIO in a DAO message with the destination as the target) and the next hop in the RIB entry is a direct neighbor, then the packet is passed to that neighbor ๐Ÿงš.
    4. Else, if there is a RIB entry for the different Track (e.g., installed by an NSM-VIO in a DAO message with the destination as the target), then the packet is encapsulated to be forwarded along that Track and the forwarding process recurses. Otherwise, the packet is dropped ๐ŸŒ€.
    5. To avoid loops, and unlike packets that were not encapsulated, a packet that was decapsulated from a Track MUST NOT be routed along the default route of the main DODAG. That would mean the end-to-end path is uncontrolled ๐Ÿ™…. The node that discovers the fault MUST discard the packet ๐Ÿ—‘๏ธ.

The node that drops a packet in any of the steps above MUST send an ICMPv6 error message [RFC4443] to the Root, with a new code "Error in P-Route" (see Section 11.15) ๐Ÿšจ. The Root can then repair things by updating the broken segment and/or Tracks. In the case of a broken segment, the Root removes the leftover sections of the segment using SM-VIOs with a lifetime of 0, which indicates the section where one or more nodes are being removed (see Section 6.6) ๐Ÿงน.

In case of a permanent forwarding error along a source route path, the node that fails to forward SHOULD send an ICMP error with the code "Error in Source Routing Header" back to the source of the packet, as described in Section 11.2.2.3 of [RPL] ๐Ÿ“จ. When this message arrives, the encapsulating node SHOULD stop using the source route path for a reasonable period of time, which depends on the deployment. It SHOULD also send an ICMP message with the code "Error in P-Route" to the Root ๐Ÿซถ. Failure to follow these steps may result in packet loss and wasted resources along the source route path that's broken ๐Ÿ˜ญ.

Either way, the ICMP message MUST be throttled in case of consecutive occurrences. It MUST be sourced at the ULA or GUA that is used in this Track for the source node, so the Root can figure out where the error happened ๐Ÿ”.

The portion of the invoking packet that gets sent back in the ICMP message SHOULD record at least up to the RH if one is present. The hop of the RH SHOULD be consumed by this node, so the destination in the IPv6 header is the next hop that this node could not reach. If a 6LoRH [RFC8138] is used to carry the IPv6 routing information in the outer header, then the whole 6LoRH information SHOULD be present in the ICMP message ๐Ÿ’œ.

6.8. Compression of RPL Artifacts โœจ

Okay so when the main DODAG in a 6LoWPAN LLN runs in Non-Storing Mode and the data packets get squished with [RFC8138] ๐Ÿ—œ๏ธ, a typical packet circulating in the main DODAG looks like this. This example is the case where IP-in-IP encapsulation is needed (see Table 19 of [RFC9008]) ๐ŸŽ€:

   +-+ ... -+- ... -+- ... -+-+- ... +-+-+-+ ... +-+-+ ... -+ ... +-...
   |11110001|  SRH- | RPI-  | IP-in-IP | NH=1      |11110CPP| UDP | UDP
   | Page 1 | 6LoRH | 6LoRH |  6LoRH   |LOWPAN_IPHC| UDP    | hdr |Payld
   +-+ ... -+- ... -+- ... -+-+- ... +-+-+-+ ... +-+-+ ... -+ ... +-...
                                        <=        RFC 6282      =>
             <================ Inner packet ==================== = =

Figure 20: A Packet as Forwarded Along the Main DODAG

Since there's no page switch between the encapsulated packet and the encapsulation, the first octet of the compressed packet (the one that acts as the page selector) gets removed at encapsulation ๐Ÿซถ. So the inner packet used in the descriptions below starts with the SRH-6LoRH and is exactly the packet in Figure 20, from the second octet onward.

When the inner packet gets encapsulated to go in the Track, the first header the ingress sticks at the head of it is an IP-in-IP 6LoRH header ๐Ÿ’–. In that header, the encapsulator address (which maps to the IPv6 source address in the uncompressed form) holds a GUA or ULA IPv6 address of the ingress node that acts as the DODAGID for the Track. It's expressed in compressed form, using the DODAGID of the main DODAG as the reference for the compression. If the address is compressed to 2 bytes, the Length field (shown in Figure 21) ends up as 3, meaning the SRH-6LoRH as a whole is 5 octets long ๐Ÿงš.

    0                   1                   2
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-     ...     -+
   |1|0|1| Length  | 6LoRH Type 6  |  Hop Limit    | Track DODAGID |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-     ...     -+

Figure 21: The IP-in-IP 6LoRH Header

At the head of the resulting bytes, the Track ingress then adds a P-RPI-6LoRH header to carry the RPI in its compressed form, as shown in Figure 12 ๐ŸŒˆ. The RPI carries the TrackID as RPLInstanceID. Combined with the IP-in-IP 6LoRH header, this lets you identify the Track without any ambiguity ๐Ÿ”ฅ.

Then the SRH-6LoRH goes at the head of the resulting bytes, as a verbatim copy of the content of the SM-VIO that signaled the selected protection path ๐Ÿ‘‘.

    0                   1
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5  ..         ..        ..
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-    -+-    -+ ... +-    -+
   |1|0|0|  Size   |6LoRH Type 0..4| Hop1 | Hop2 |     | HopN |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-    -+-    -+ ... +-    -+
                                             Where N = Size + 1

Figure 22: The SRH-6LoRH Header

The resulting encapsulated packet, which is in compressed form per [RFC8138], looks like Figure 23 ๐Ÿ’…:

   +-+ ... -+-+-+- ... -+-+-+- ... -+-+-+-+-+- ... +-+-+-+-+-+-+- ...
   | Page 1 |  SRH-6LoRH  | P-RPI-6LoRH | IP-in-IP 6LoRH | Inner Packet
   +-+ ... -+-+-+- ... -+-+-+- ... -+-+-+-+-+- ... +-+-+-+-+-+-+- ...

    Signals :  Loose Hops :    TrackID  :  Track DODAGID :

Figure 23: A Packet as Forwarded Along a Track


7. Less-Constrained Variations ๐Ÿฆ‹

7.1. Storing Mode Main DODAG

Okay so this spec expects the main DODAG to be operated in Non-Storing Mode ๐Ÿ’…. The reasons are mostly about LLN operations, power, and spectrum conservation ๐Ÿ”‹:

  • In Non-Storing Mode, the Root already knows the DODAG topology, so the extra topological info gets reduced to the siblings ๐Ÿง .
  • The downward routes get updated with unicast messages to the Root. That means the Root can reach back to the LLN nodes after a repair faster than in Storing Mode. The Root also gets to control the use of path diversity in the DODAG to reach the LLN nodes. For both reasons, Non-Storing Mode gives the Root better capabilities to maintain the P-Routes ๐Ÿ‘‘.
  • When the main DODAG runs in Non-Storing Mode, P-Routes enable loose source routing, which is only an advantage in that mode. Storing Mode doesn't use Source Routing Headers and doesn't get the same benefits from this capability ๐Ÿ™ˆ.

On the other hand, RPL is a Layer 3 routing protocol, so its applicability goes beyond LLNs to a generic IP network ๐ŸŒˆ. RPL needs fewer resources than alternative IGPs like OSPF, IS-IS, the Enhanced Interior Gateway Routing Protocol (EIGRP), BABEL, or RIP when it uses routing stretch instead of the shortest path routes to a destination that those protocols compute. P-Routes add the capability to install the shortest and/or constrained routes to special destinations, as discussed in Appendix A.9.4 of "An Autonomic Control Plane (ACP)" [RFC8994] โœจ.

In a powered and wired network, when there's enough memory to store the needed routes, RPL Storing Mode is a better trade-off than Non-Storing Mode ๐Ÿ’–. It reduces the routing stretch and lowers the load on the Root. In that case, the control path between the Root and the RPL nodes can be maintained more aggressively and with more redundancy than in LLNs, and the nodes can be reached to maintain the P-Routes at most times, for finer and more reactive control ๐Ÿฆ‹.

This section specifies the additions needed to support P-Routes when the main DODAG runs in Storing Mode. As long as the RPI can be processed adequately by the data plane, the changes in this specification are limited to the DAO message ๐Ÿซถ. The Track structure, routes, and forwarding operations stay the same. Since there's no capability negotiation, the expectation is that all the nodes in the network support this specification in the same fashion, or are configured the same way through management ๐Ÿงฉ.

In Storing Mode, the Root misses the Child-to-Parent relationship that forms the main DODAG, as well as the sibling information. To fill that gap, the nodes in the network MUST send additional DAO messages that are unicast to the Root, just like Non-Storing DAO messages are ๐Ÿ’Œ.

In the DAO message, the originating router advertises a set of neighbor nodes using SIOs, no matter where the advertised node sits in the DODAG relative to this router ๐Ÿ—บ๏ธ.

The DAO message MUST be formed as follows:

  • The originating router is identified by the source address of the DAO. That address MUST be the one this router registers to the neighbor routers, so the Root can correlate the DAOs from those routers when they advertise this router as their neighbor. The DAO contains one or more sequences of one TIO and one or more SIOs. There's no RPL Target Option, so the Root doesn't get confused into adding a Storing Mode route to the Target ๐Ÿ™….
  • The TIO is formed as in Storing Mode, and the Parent Address is not present. The Path Sequence and Path Lifetime fields are aligned with the values used in the Address Registration of the node(s) advertised in the SIO, as explained in Section 9.1 of [RFC9010]. Having similar values in all nodes lets you factorize the TIO for multiple SIOs, as done in [RPL] ๐Ÿงฉ.
  • The TIO is followed by one or more SIOs that provide an address (ULA or GUA) of the advertised neighbor node ๐Ÿ“.

Now, the RPL routing information headers may not be supported on all types of routed network infrastructures, especially not in high-speed routers ๐Ÿ˜ฌ. When the RPI isn't supported in the data plane, there cannot be Local RPL Instances, and RPL can only operate as a single topology (the main DODAG). The RPL Instance is the one that runs the main DODAG, and the ingress node that encapsulates the RPL Instance is not the Root. The routes along the Tracks are alternate routes to those available along the main DODAG. They MAY conflict with routes to children and MUST take precedence in the routing table ๐Ÿšฆ. The Targets MUST be adjacent to the Track egress to avoid loops that may form if the packet is reinjected in the main DODAG ๐Ÿ”.

7.2. A Track as a Full DODAG

This specification builds Tracks with parallel or interleaved protection paths, as opposed to a more complex DODAG with interconnections at any place desirable ๐ŸŒธ. The reason for that limitation is constrained node operations, plus the capability to store a large amount of topological information and compute complex paths ๐Ÿง :

  • With this specification, the node in the LLN has no topological awareness and doesn't need to maintain dynamic information about link quality and availability ๐Ÿ™Œ.
  • The Root has complete topological information and statistical metrics that let it, or its PCE, perform a global optimization of all Tracks in its DODAG. Based on that information, the Root computes the protection path and produces the source route paths ๐Ÿ‘‘.
  • The node just selects one of the proposed paths and applies the associated pre-computed Routing Header in the encapsulation. This takes the load off both computing a path and dealing with the compressed form of the Routing Header ๐Ÿ’….

The RAW architecture [RAW-ARCH] actually expects the PLR at the Track ingress to react to changes in the forwarding conditions along the Track and reroute packets to maintain the required degree of reliability ๐Ÿ”ฅ. To do that, the PLR needs the full richness of a DODAG to form any path that could meet the SLO.

This section specifies the additions needed to turn the Track into a full DODAG and enable the main Root to provide the necessary topological information to the Track ingress โœจ. The expectation is that the PLR's metrics will be in a different order than the PCE's metrics, because of the difference in timescale between routing and forwarding; see more in [RAW-ARCH]. It follows that the PLR will learn the metrics it needs from an alternate source, e.g., OAM frames ๐ŸŒŠ.

To pass the topological information to the ingress, the Root uses a P-DAO message that contains sequences of Targets and TIOs that collectively represent the Track, expressed in the same fashion as in classical Non-Storing Mode ๐ŸŽ€. The difference is that the Root is the source as opposed to the destination, and the Root can report information on many Targets, possibly the full Track, with one P-DAO ๐Ÿฆ‹.

Note that the Path Sequence and Lifetime in the TIO are selected by the Root, and that the Target/Transit information tuples in the P-DAO are not those the Root received in the DAO messages about the said Targets ๐Ÿ™ˆ. The Track may follow sibling routes and does not need to be congruent with the main DODAG ๐Ÿ’œ.

8. Profiles โœจ

Okay bestie, this section is basically a menu ๐Ÿ“. Not every implementation needs every single piece of this spec, so these profiles let you pick your lane, build only what your use case needs, and tell everyone what your implementation can and can't do ๐Ÿ’….

Profiles 0 to 2 run in the main Instance. They don't need Local RPL Instances or the indication of the RPL Instance in the data plane ๐Ÿงš. Profile 3 and up use Local RPL Instances to build arbitrary Tracks rooted at the Track ingress, and the TrackID comes from the Track ingress's namespace ๐Ÿฆ‹.

Profiles 0 and 1 are REQUIRED for every implementation that may be used in LLNs ๐Ÿซถ. Profile 1 uses Storing Mode to shrink the RPL Source Route Header in the most common LLN deployments ๐ŸŒธ. Profile 2 is RECOMMENDED in a high-speed (e.g., wired) environment to enable Traffic Engineering and network automation ๐Ÿ”ฅ. All the other profile and environment combinations are OPTIONAL ๐Ÿ’œ.

Profile 0: Profile 0 is the legacy support of [RPL] Non-Storing Mode, with default routing Northwards (up) and strict source routing Southwards (down the main DODAG) ๐ŸŽ€. It's the bare-minimum common functionality that every Track-supporting profile needs first. The other profiles level up Profile 0 with the extra capabilities this specification introduces โœจ.

Profile 1 (Storing Mode P-Route segments along the main DODAG): Profile 1 doesn't create new paths ๐Ÿ™ˆ. Compared to Profile 0, it mixes Storing and Non-Storing Modes so you balance the size of the Routing Header in the packet against the amount of state in the intermediate routers in a Non-Storing Mode RPL DODAG โญ.

Profile 2 (Non-Storing Mode P-Route segments along the main DODAG): Profile 2 extends Profile 0 with strict source-routed Non-Storing Mode P-Routes along the main DODAG ๐Ÿ‘‘. It's the same as Profile 1 but uses NSM-VIOs instead of SM-VIOs. It gives you the same SRH compression in packets down the main DODAG as Profile 1, but it needs an encapsulation so you can insert an additional SRH between the loose source routing hops ๐Ÿฆ‹. With Profile 2, the Tracks MUST be installed as subTracks of the main DODAG, and the main Instance MUST be used as the TrackID ๐Ÿ’–. Note that the ingress node encapsulates but is not the Root, because it doesn't own the DODAGID ๐Ÿซถ.

Profile 3: To form the best path possible, this profile needs an SIO so the Root knows about additional possible hops ๐Ÿงš. Profile 3 extends Profile 1 with extra Storing Mode P-Routes that install segments which don't follow the main DODAG ๐ŸŒˆ. If the segment ingress (in the SM-VIO) is the same as the IPv6 address of the Track ingress (in the Projected DAO Base Object), the P-DAO creates an implicit Track between the segment ingress and the segment egress ๐Ÿ’….

Profile 4: Profile 4 extends Profile 2 with strict source-routed Non-Storing Mode P-Routes that form forward Tracks inside the main DODAG. These Tracks don't have to follow it ๐Ÿฆ‹. A Track is formed as one or more strict source-routed paths between the Root (which is the Track ingress) and the Track egress, which is the last node ๐ŸŽ€.

Profile 5: Profile 5 combines Profile 4 with Profile 1 and enables loose source routing between the ingress and the egress of the Track ๐ŸŒธ. Just like Profile 1, Storing Mode P-Routes form the connections in the loose source route ๐Ÿ’œ.

Profile 6: Profile 6 combines Profile 4 with Profile 2 and enables loose source routing between the ingress and the egress of the Track ๐Ÿ”ฅ.

Profile 7: Profile 7 implements Profile 5 in a main DODAG that runs in Storing Mode, as presented in Section 7.1 โœจ. Just like Profiles 1 and 2, the TrackID is the RPLInstanceID of the main DODAG ๐Ÿ“. Longest match rules decide whether a packet is sent along the main DODAG or rerouted in a Track ๐Ÿงš.

Profile 8: Profile 8 is offered in preparation for the RAW work, and for use cases where an arbitrary node in the network can handle the same code complexity as the RPL Root in a traditional deployment ๐Ÿ‘‘. It gives the Track ingress full DODAG visibility, as specified in Section 7.2, in a Non-Storing Mode main DODAG ๐ŸŒˆ.

Profile 9: Profile 9 combines Profiles 7 and 8. It operates the Track as a full DODAG within a Storing Mode main DODAG, using only the main DODAG RPLInstanceID as the TrackID ๐Ÿ’–.


9. Backwards Compatibility ๐Ÿซถ

Good news: this spec can run in a mixed network, where some nodes support it and some don't ๐ŸŒธ. There are restrictions though, so read carefully ๐Ÿ‘€. All nodes that need to process a P-DAO MUST support this specification ๐Ÿ’…. As discussed in Section 3.7.1, how the Root learns node capabilities, and whether nodes support this specification, is out of scope ๐Ÿ™ˆ.

This specification defines the 'D' flag in the RPL DODAG Configuration option (see Section 4.1.7) so RPL nodes can request the creation of Tracks ๐ŸŽ€. The requester might not know whether the Track can actually be built, or whether enough nodes along the preferred paths support this specification ๐Ÿ˜ญ. So it makes sense to only set the 'D' flags in the DIO once the conditions for success are in place ๐Ÿงš. In particular, do it when every node that could be on the path of the Tracks has been upgraded ๐Ÿฆ‹.


10. Security Considerations ๐Ÿ’€

Heads up, this section is serious, so read it all ๐Ÿ™ˆ.

It's worth noting that per [RPL], every node in the LLN is RPL-aware and can inject any RPL-based attack into the network ๐Ÿ˜ญ. This specification uses messages that already exist in RPL [RPL], with optional secured versions. The same secured versions may be used with this specification, and whatever security is deployed for a given network also applies to the flows in this specification ๐Ÿ”.

The LLN nodes depend on the RPL Root and RANs for their operation ๐Ÿซถ. A trust model is necessary to make sure the right devices are acting in these roles, which helps avoid sinkhole attacks (as is done in Section 7 of [RFC7416]) ๐Ÿ•ณ๏ธ. This trust model could be, at a minimum, based on a Layer 2 secure joining and link-layer security ๐Ÿ”’. This is a generic 6LoWPAN requirement; see Req-5.1 in Appendix B.5 of [RFC8505] ๐ŸŒˆ.

In general, the Security Considerations in [RPL] and [RFC7416] apply to this specification as well. In particular, link-layer security is needed to prevent denial-of-service attacks, where a rogue router creates a high churn in the RPL network by constantly injecting forged P-DAO messages and using up all the available storage in the attacked routers ๐Ÿ’€.

When applied to radio LLNs such as IEEE Std 802.15.4, the lower-layer frame protection can be leveraged with an appropriate join protocol ๐Ÿ“ก. The 6TiSCH Constrained Join Protocol (CoJP) [RFC9031] uses the RPL Root as 6LBR ๐ŸŽ€. The join protocol could be extended to provide additional key material for pledges to 6LBR communication when additional end-to-end security is desired beyond the hop-by-hop security from the lower layer ๐Ÿ”‘.

With this specification, the Root MAY generate P-DAO messages, but other nodes MUST NOT do so ๐Ÿ‘‘. P-DAO-REQ messages MUST be sent to the Root ๐Ÿ’–. This specification expects that communication with the Root is authenticated, but it doesn't enforce which method is used ๐Ÿซถ.

Additionally, the trust model could include role validation (e.g., using a role-based authorization) to make sure a node that claims to be a RPL Root is entitled to do so ๐Ÿง. That trust should propagate from egress to ingress in the case of a Storing Mode P-DAO ๐Ÿ”—.

This specification suggests some validation of the VIO to prevent basic loops, i.e., by avoiding a node that appears twice ๐Ÿ”. But that's only minimal protection ๐Ÿ˜ฌ. Arguably, an attacker that can inject P-DAOs can reroute any traffic and rapidly deplete critical resources such as the spectrum and battery in the LLN ๐Ÿ”‹๐Ÿ’€.


11. IANA Considerations ๐Ÿ“‹

11.1. RPL DODAG Configuration Option Flag

IANA has assigned a flag in the "DODAG Configuration Option Flags for MOP 0..6" registry [RFC9008] under the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL] as follows โœจ:

      +============+==============================+===========+
      | Bit Number | Capability Description       | Reference |
      +============+==============================+===========+
      |     0      | Projected Routes Support (D) | RFC 9914  |
      +------------+------------------------------+-----------+

            Table 21: New DODAG Configuration Option Flag

IANA has added this RFC as an additional reference for MOP 7 in the "Mode of Operation" registry under the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL] ๐ŸŽ€.

11.2. Elective 6LoWPAN Routing Header Type

IANA has updated the "Elective 6LoWPAN Routing Header Type" registry [RFC8138] under the "IPv6 Low Power Personal Area Network Parameters" registry group [IANA-6LO] as follows ๐ŸŒธ:

                 +=======+=============+===========+
                 | Value | Description | Reference |
                 +=======+=============+===========+
                 |   8   | P-RPI-6LoRH | RFC 9914  |
                 +-------+-------------+-----------+

                    Table 22: New Elective 6LoWPAN
                         Routing Header Type

11.3. Critical 6LoWPAN Routing Header Type

IANA has updated the "Critical 6LoWPAN Routing Header Type" registry [RFC8138] under the "IPv6 Low Power Personal Area Network Parameters" registry group [IANA-6LO] as follows ๐Ÿงก:

                 +=======+=============+===========+
                 | Value | Description | Reference |
                 +=======+=============+===========+
                 |   8   | P-RPI-6LoRH | RFC 9914  |
                 +-------+-------------+-----------+

                    Table 23: New Critical 6LoWPAN
                         Routing Header Type

11.4. Registry for RPL Option Flags

IANA has created the "RPL Option Flags" registry for the 8-bit RPL Option flags field, as detailed in Figure 11, under the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL] ๐Ÿ—‚๏ธ. The bits are indexed from 0 (leftmost) to 7. Each bit is tracked with the following qualities ๐Ÿ‘‡:

  • Bit number (counting from bit 0 as the most significant bit)
  • Indication when set
  • Reference

The registration procedure is Standards Action [RFC8126]. The initial allocation is shown in Table 24 ๐Ÿ’…:

          +============+======================+===========+
          | Bit Number | Indication When Set  | Reference |
          +============+======================+===========+
          |     0      | Down (O)             | [RFC6553] |
          +------------+----------------------+-----------+
          |     1      | Rank-Error (R)       | [RFC6553] |
          +------------+----------------------+-----------+
          |     2      | Forwarding-Error (F) | [RFC6553] |
          +------------+----------------------+-----------+
          |     3      | Projected-Route (P)  | RFC 9914  |
          +------------+----------------------+-----------+
          |   4..255   | Unassigned           |           |
          +------------+----------------------+-----------+

                  Table 24: Initial P-DAO-REQ Flags

11.5. RPL Control Codes ๐Ÿ’Œ

IANA updated the "RPL Control Codes" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL], as shown in Table 25 ๐Ÿฆ‹:

+======+================================================+===========+
| Code | Description                                    | Reference |
+======+================================================+===========+
| 0x09 | Projected DAO Request (P-DAO-REQ)              | RFC 9914  |
+------+------------------------------------------------+-----------+
| 0x0A | Projected DAO Request                          | RFC 9914  |
|      | Acknowledgment (PDR-ACK)                       |           |
+------+------------------------------------------------+-----------+

                   Table 25: New RPL Control Codes

11.6. RPL Control Message Options ๐ŸŽ€

IANA updated the "RPL Control Message Options" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL], as shown in Table 26 โœจ:

+=======+==============================================+===========+
| Value | Meaning                                      | Reference |
+=======+==============================================+===========+
|  0x0F | Stateful Storing Mode VIO (SM-VIO)           | RFC 9914  |
+-------+----------------------------------------------+-----------+
|  0x10 | Source-Routed Non-Storing Mode VIO (NSM-VIO) | RFC 9914  |
+-------+----------------------------------------------+-----------+
|  0x11 | Sibling Information Option (SIO)             | RFC 9914  |
+-------+----------------------------------------------+-----------+

                  Table 26: RPL Control Message Options

11.7. Registry for Projected DAO Request Flags ๐ŸŒธ

IANA created the "Projected DAO Request (P-DAO-REQ) Flags" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL]. The bits are indexed from 0 (leftmost) to 7. Each bit is tracked with these qualities:

  • Bit number (counting from bit 0 as the most significant bit)
  • Capability description
  • Reference

The registration procedure is Standards Action [RFC8126]. The initial allocation is shown in Table 27 ๐Ÿ’…:

 +============+========================================+===========+
 | Bit Number | Capability Description                 | Reference |
 +============+========================================+===========+
 |     0      | PDR-ACK requested (K)                  | RFC 9914  |
 +------------+----------------------------------------+-----------+
 |     1      | Requested path should be redundant (R) | RFC 9914  |
 +------------+----------------------------------------+-----------+
 |   2..255   | Unassigned                             |           |
 +------------+----------------------------------------+-----------+

                     Table 27: Initial P-DAO-REQ Flags

11.8. Registry for Projected DAO Request Acknowledgment (PDR-ACK) Flags ๐Ÿฆ‹

IANA created the "Projected DAO Request Acknowledgment (PDR-ACK) Flags" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL]. The bits are indexed from 0 (leftmost) to 7. Each bit is tracked with these qualities:

  • Bit number (counting from bit 0 as the most significant bit)
  • Capability description
  • Reference

The registration procedure is Standards Action [RFC8126]. At the time of publication of this document, no bit has been assigned in this registry ๐Ÿฅน.

11.9. Registry for PDR-ACK Acceptance Status Values ๐Ÿงš

IANA created the "PDR-ACK Acceptance Status Values" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL]. Each value is tracked with these qualities:

  • Value
  • Meaning
  • Reference

The possible values are expressed as a 6-bit unsigned integer (0..63). The registration procedure is Standards Action [RFC8126]. The initial allocation is shown in Table 28 ๐Ÿซถ:

          +=======+========================+===========+
          | Value | Meaning                | Reference |
          +=======+========================+===========+
          |   0   | Unqualified Acceptance | RFC 9914  |
          +-------+------------------------+-----------+
          | 1..63 | Unassigned             |           |
          +-------+------------------------+-----------+

            Table 28: Acceptance Values of the PDR-ACK
                              Status

11.10. Registry for PDR-ACK Rejection Status Values ๐Ÿ’œ

IANA created the "PDR-ACK Rejection Status Values" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL]. Each value is tracked with these qualities:

  • Value
  • Meaning
  • Reference

The possible values are expressed as a 6-bit unsigned integer (0..63). The registration procedure is Standards Action [RFC8126]. The initial allocation is shown in Table 29 ๐ŸŒˆ:

           +=======+=======================+===========+
           | Value | Meaning               | Reference |
           +=======+=======================+===========+
           |   0   | Unqualified Rejection | RFC 9914  |
           +-------+-----------------------+-----------+
           |   1   | Transient Failure     | RFC 9914  |
           +-------+-----------------------+-----------+
           | 2..63 | Unassigned            |           |
           +-------+-----------------------+-----------+

             Table 29: PDR-ACK Rejection Status Values

11.11. Registry for Via Information Options Flags ๐Ÿ“

IANA created the "Via Information Options (VIO) Flags" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL]. The bits are indexed from 0 (leftmost) to 7. Each bit is tracked with these qualities:

  • Bit number (counting from bit 0 as the most significant bit)
  • Capability description
  • Reference

The registration procedure is Standards Action [RFC8126]. At the time of publication of this document, no bit has been assigned in this registry (see more in Section 5.3) ๐Ÿ‘€.

11.12. Registry for Sibling Information Option Flags ๐ŸŒท

IANA created the "Sibling Information Option (SIO) Flags" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL]. The bits are indexed from 0 (leftmost) to 4. Each bit is tracked with these qualities:

  • Bit number (counting from bit 0 as the most significant bit)
  • Capability description
  • Reference

The registration procedure is Standards Action [RFC8126]. The initial allocation is shown in Table 30 (see more in Figure 17) ๐Ÿ”ฅ:

+============+=========================================+===========+
| Bit Number | Capability Description                  | Reference |
+============+=========================================+===========+
|     0      | 'S' flag: Sibling in same DODAG as self | RFC 9914  |
+------------+-----------------------------------------+-----------+
|     1      | 'B' flag: Connectivity to the sibling   | RFC 9914  |
|            | is roughly symmetrical                  |           |
+------------+-----------------------------------------+-----------+
|    2..4    | Unassigned                              |           |
+------------+-----------------------------------------+-----------+

                     Table 30: Initial SIO Flags

11.13. Destination Advertisement Object Flag ๐ŸŒŸ

IANA updated the "Destination Advertisement Object (DAO) Flags" registry, which was created in Section 20.11 of [RPL], in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL], as shown in Table 31 (see more in Section 4.1.1) ๐Ÿงธ:

          +============+========================+===========+
          | Bit Number | Capability Description | Reference |
          +============+========================+===========+
          |     2      | Projected DAO (P)      | RFC 9914  |
          +------------+------------------------+-----------+

             Table 31: New Destination Advertisement Object
                               (DAO) Flag

11.14. Destination Advertisement Object Acknowledgment Flag ๐ŸŽ€

IANA updated the "Destination Advertisement Object (DAO) Acknowledgment Flags" registry, which was created in Section 20.12 of [RPL], in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL], as shown in Table 32 (see more in Section 4.1.2) ๐Ÿ’…:

     +============+==================================+===========+
     | Bit Number | Capability Description           | Reference |
     +============+==================================+===========+
     |     1      | Projected DAO Acknowledgment (P) | RFC 9914  |
     +------------+----------------------------------+-----------+

             Table 32: New Destination Advertisement Object
                          Acknowledgment Flag

11.15. ICMPv6 Error Code โš ๏ธ

In some cases, RPL will return an ICMPv6 error message when a message cannot be forwarded along a P-Route. Bestie, that's the main drama ๐Ÿ’€.

Per this specification, IANA updated the "Type 1 - Destination Unreachable" registry, in the "ICMPv6 'Code' Fields" registry, under the "Internet Control Message Protocol version 6 (ICMPv6) Parameters" registry group [IANA-ICMP], as shown in Table 33 ๐Ÿงšโ€โ™€๏ธ:

                +======+==================+===========+
                | Code | Name             | Reference |
                +======+==================+===========+
                |  9   | Error in P-Route | RFC 9914  |
                +------+------------------+-----------+

                    Table 33: New ICMPv6 Error Code

11.16. RPL Rejection Status Values ๐ŸŒˆ

IANA updated the "RPL Rejection Status" registry in the "Routing Protocol for Low Power and Lossy Networks (RPL)" registry group [IANA-RPL], as shown in Table 34 ๐Ÿฆ‹:

            +=======+=========================+===========+
            | Value | Meaning                 | Reference |
            +=======+=========================+===========+
            |   2   | Out of Resources        | RFC 9914  |
            +-------+-------------------------+-----------+
            |   3   | Error in VIO            | RFC 9914  |
            +-------+-------------------------+-----------+
            |   4   | Predecessor Unreachable | RFC 9914  |
            +-------+-------------------------+-----------+
            |   5   | Unreachable Target      | RFC 9914  |
            +-------+-------------------------+-----------+
            | 6..63 | Unassigned              |           |
            +-------+-------------------------+-----------+

                 Table 34: RPL Rejection Status Values

12. References ๐Ÿ“š

Okay bestie, here's the reading list ๐Ÿ“šโœจ Normative first, then the informative stuff ๐Ÿซถ

12.1. Normative References ๐Ÿ“š

12.2. Informative References ๐Ÿ”

Acknowledgments ๐Ÿซถ

The authors wish to acknowledge JP. Vasseur, Remy Liubing, James Pylakutty, and Patrick Wetterwald for their contributions to the ideas developed here. Many thanks to Dominique Barthel and S.V.R. Anand for their global contribution to 6TiSCH, RAW, and this RFC, as well as text suggestions that were incorporated. ๐Ÿ’–

Also, special thanks to Remous-Aris Koutsiamanis, Li Zhao, Dominique Barthel, and Toerless Eckert for their in-depth reviews, with many excellent suggestions that improved the readability and the content of the specification. ๐Ÿ™Œ Many thanks to Remous-Aris Koutsiamanis for his review during WG Last Call and to Maria Ines Robles for her thorough shepherd review. ๐ŸŒธ

Many thanks to Warren Kumari, Ran Chen, Murray Kucherawy, Roman Danyliw, Klaas Wierenga, Deb Cooley, ร‰ric Vyncke, Gunter Van de Velde, Sue Hares, and John Scudder for their comments and suggestions during the IETF Last Call and IESG review cycle. โœจ๐Ÿ‘‘

Authors' Addresses ๐Ÿ“ฎ

Pascal Thubert (editor)
Independent
06330 Roquefort-les-Pins
France
Email: pascal.thubert@gmail.com


Rahul Arvind Jadhav
AccuKnox
Kundalahalli Village, Whitefield
Bangalore 560037
Karnataka
India
Phone: +91-080-49160700
Email: rahul.ietf@gmail.com


Michael C. Richardson
Sandelman Software Works
Email: mcr+ietf@sandelman.ca
URI:   http://www.sandelman.ca/
๐Ÿ“ฆ where this page comes from