Skip to content

Source routing, segments, and the two data planes

S1·E1Thirty-one boxes, one budget line · NVIDIA briefing room, design review with a Dell account team

S1·E1Understand~25 minsources checked todayverified against RFC 8402, RFC 8754, RFC 8660, RFC 8986, RFC 9800, RFC 9602, RFC 9855 re-read 2026-09-07

Before you read: what do you already know?

3 quick questions. Wrong answers are fine and expected; trying first makes the lesson stick.

After this lesson you can

  • State what a segment is and where per-flow state lives in a Segment Routing domain.
  • Map PUSH, NEXT and CONTINUE onto both data planes and name the field that carries the active segment in each.
  • Name the three RFC 8754 node roles and say which of them needs no SRv6 support at all.
  • Compare SR-MPLS and SRv6 on header cost, transit requirements and global label coordination.

Episode 1 — Thirty-one boxes, one budget line

The situation · NVIDIA briefing room, design review with a Dell account team

The network lead puts a topology printout on the table, notebook open beside it. Thirty-one boxes, a third past refresh, and a nightly job that has to carry a day of imaging studies to the disaster-recovery archive before the radiologists log in. Cutover is six weeks out; the budget covers one line item of three. She asks the only question she came with: if we do SRv6, how many of these do we replace this year? The Dell SE - coffee cold since the PM’s roadmap deck, which said “not announced” twice - opens the spreadsheet where he keeps every promise this account has been made.

Segment Routing exists because the older answer to traffic engineering kept state everywhere. RFC 8402, the root architecture both data planes reference, says a node “steers a packet through an SR Policy instantiated as an ordered list of instructions called ‘segments’”, and that SR “supports per-flow explicit routing while maintaining per-flow state only at the ingress nodes to the SR domain.”[1] The sender writes the path onto the packet; nobody in the middle holds a tunnel to refresh.

Her question has an answer she will like. RFC 8754 names three node roles, and the transit node does nothing SR-specific - it forwards an ordinary IPv6 packet on its destination address.[2] Her SR-MPLS architect counters with cost instead: four bytes for a label, sixteen for a segment.[14][2]

The path is data the sender writes, not state the network keeps.

Both objections come apart in the same drawing, so start with what a segment is.

1Source routing, without the 1990s baggage

Segment Routing starts from one design choice: the sender decides the path. RFC 8402, Proposed Standard, July 2018, is the root document, and everything else in this course normatively references it.[1] Its opening sentence is worth memorising because it is the whole model: “Segment Routing (SR) leverages the source routing paradigm. A node steers a packet through an SR Policy instantiated as an ordered list of instructions called ‘segments’.”[1]

The second sentence is the one that sells it: “SR supports per-flow explicit routing while maintaining per-flow state only at the ingress nodes to the SR domain.”[1] That is the difference between SR and RSVP-TE. In an RSVP-TE network every router on the path holds state for every tunnel that crosses it. In an SR network the ingress node writes the instruction list onto the packet and every other router forwards on what it reads. Nothing to refresh, nothing to re-signal, nothing to leak when a router reloads.

A segment is an instruction, not a tunnel. The instruction can be topological (“go to node 5 by the shortest path”) or a service (“look this packet up in VRF blue”). RFC 8402 splits the instantiation of that idea in two, and the definitions are verbatim: “SR-MPLS: the instantiation of SR on the MPLS data plane” and “SRv6: the instantiation of SR on the IPv6 data plane.”[1] The SID definitions follow the same shape: an SR-MPLS SID is “an MPLS label or an index value into an MPLS label space explicitly associated with the segment”, while an SRv6 SID is “an IPv6 address explicitly associated with the segment.”[1]

That last phrase is where most of the confusion in this course comes from and where most of its power lives. An SRv6 SID is a real IPv6 address. It is routable, it appears in a routing table, you can ping it, and an ACL can match it.[4]

2PUSH, NEXT, CONTINUE - one table you will redraw for customers

RFC 8402 defines three primitives and then says exactly how each one is realised in both data planes. PUSH inserts a segment at the top of the list: the outermost label in SR-MPLS, the first segment in the SRH in SRv6.[1] NEXT is verbatim: “In SR-MPLS, NEXT is implemented as a POP of the top label. In SRv6, NEXT is implemented as the copy of the next segment from the SRH to the destination address of the IPv6 header.”[1] CONTINUE is verbatim too: “In SR-MPLS, the CONTINUE operation is implemented as a SWAP of the top label. In SRv6, this is the plain IPv6 forwarding action of a regular IPv6 packet according to its destination address.”[1]

Behind all three sits the single most useful sentence in the document: “Active Segment: … In the MPLS data plane, it is the top label. In the IPv6 data plane, it is the destination address.”[1] If a learner only remembers one line from this module, make it that one. Every later mechanism - endpoint behaviors, compression, service SIDs - is a variation on “what do I do when my own address shows up as the destination”.[4]

Primitive SR-MPLS SRv6
PUSH Impose a label on the stack Insert the segment list and set the DA to the first segment
NEXT POP the top label Copy Segment List[Segments Left] into the IPv6 DA
CONTINUE SWAP the top label Plain IPv6 forwarding on the DA
Active segment Top label IPv6 destination address
[1][2]
Rendering diagram…
Diagram source (Mermaid)
flowchart LR
  SRC["SR source node\nPUSH"] --> T1["transit router\nCONTINUE = plain IPv6 forwarding"]
  T1 --> E1["segment endpoint\nNEXT = copy next SID into DA"]
  E1 --> T2["transit router\nCONTINUE"]
  T2 --> E2["last segment endpoint\ndecapsulate and deliver"]
  E2 --> DST["inner packet to the service"]
The three primitives in path order. Only the two endpoint boxes need SRv6 code; both transit boxes are ordinary IPv6 routers.

3The taxonomy, and the SRGB problem SRv6 does not have

RFC 8402 defines the segment types once, for both data planes: IGP-Prefix Segment (the Prefix-SID), IGP-Node Segment (Node-SID), IGP-Anycast Segment, and IGP-Adjacency Segment (Adj-SID), including parallel adjacencies and LAN adjacency segments.[1] BGP segments - the BGP Prefix Segment and the BGP peering segments used for egress peer engineering - are section 4, and the Binding Segment is section 5.[1] None of that vocabulary changes when you switch data planes, which is the honest answer to a customer asking whether SR-MPLS knowledge transfers. It does. The SR Policy model transfers too: RFC 9256 identifies a policy by the tuple headend, color, endpoint, where “the color is an unsigned non-zero 32-bit integer value that associates the SR Policy with an intent or objective.”[7] Color is not QoS and not a VLAN.

What does change is label coordination. In SR-MPLS the SRGB is “a local property of a node” identifying reserved local labels for global segments, and the spec says “using identical SRGBs on all nodes within the SR domain is strongly recommended.”[1] Anyone who has run a multi-vendor SR-MPLS design has spent a meeting on that recommendation. In SRv6 the SRGB is simply “the set of global SRv6 SIDs in the SR domain” and the SRLB is “a set of local IPv6 addresses reserved for local SRv6 SIDs.”[1] There is no range to negotiate, because the identifiers are addresses and you already have an address plan.

Address space is the SRv6 version of that conversation instead. RFC 9602 (October 2024) had IANA assign 5f00::/16 for “Segment Routing (SRv6) SIDs”, allocation date 2024-04, so that packets carrying SIDs can be identified and filtered at a domain edge and the domain can “fail closed”.[8] It is available, not mandatory - and in practice you will meet ULA blocks: fcbb::/16 in Cumulus Linux[10] and fcbb:bbbb:1:: style locators in FRR’s own output examples.[15]

4Three node roles: who actually needs SRv6

RFC 8754 section 3 names exactly three roles: the SR source node, the transit node and the SR segment endpoint node.[2] The source node imposes the segment list. The segment endpoint node is the one whose local SID matches the destination address, and it runs the endpoint processing that decrements Segments Left and copies the next segment into the destination address.[2] The transit node does nothing SR-specific at all: it is an IPv6 router forwarding an IPv6 packet on the destination address.[2]

That is the single most valuable architectural fact for a Dell OEM conversation, and it is why the lab for this lesson deliberately puts a vrnetlab/dell_sonic:4.5.1 node in the middle of the path. Dell’s published Enterprise SONiC Distribution Compatibility Matrix 4.4.0 contains no occurrence of SRv6 or segment routing in its feature rows, and whether 4.5.x adds any is unverified because the 4.5 matrix sits behind the Dell Digital Locker login.[12] None of that stops the node from being a legitimate hop, because a transit node is only required to forward IPv6.[2][11]

The same logic explains the architecture NVIDIA documents on the switch side, verbatim: “The NICs connected to the switch fabric perform SRv6 origination and termination, and the switches act as SRv6-aware nodes.”[10] The endpoints are the interesting devices; the fabric mostly routes.

2 segments · 80 B overhead
Host A · ConnectX + LinuxSR source nodesource · PUSHDA fcbb:bbbb:2::1SL 1Dell switch Atransit — IPv6 forwarding onlytransitDA ?SL ?R2 · Linux endpointfirst segmentendpointDA ?SL ?Dell switch Btransit — IPv6 forwarding onlytransitDA ?SL ?PE3 · Linux endpointlast segment — decapsulationendpointDA ?SL ?CE · VM in vrf100inner packet delivereddeliveredDA ?SL ?
hop 1 / 6
Dell transit (no SRv6 in the middle) · Full SRH

1. Host A · ConnectX + Linux

SR source nodePUSH

Encapsulate: outer Destination Address = the first segment, fcbb:bbbb:2::1. The SRH carries 2 entries in reverse — Segment List[0] = fcbb:bbbb:3::100, the LAST segment of the policy.

Ordinary Linux encapsulation on a ConnectX host: seg6_enabled on the data interface, then one route with the segment list. Two segments here, not three — the overhead readout changes with n.

Packet state after this hop
Destination Address fcbb:bbbb:2::1
Segments Left 1
SRH Last Entry 1 · Hdr Ext Len 4 · Routing Type 4
Encapsulation overhead 80 B

FAE angle: seg6_enabled is 0 by default on every interface — set it on "all" AND on the specific data interface. It is the single most common reason a first SRv6 lab silently drops everything.

sysctl -w net.ipv6.conf.all.seg6_enabled=1 net.ipv6.conf.eth1.seg6_enabled=1
ip -6 route add 2001:db8:beef::/64 encap seg6 mode encap \
  segs fcbb:bbbb:2::1,fcbb:bbbb:3::100 dev eth1
Full SRH

H.Encaps / ip -6 route … mode encap. All n segments ride in the SRH, stored in reverse: Segment List[0] holds the LAST segment of the policy. Segments Left = n-1, Last Entry = n-1, Hdr Ext Len = 2n. Overhead 40 + 8 + 16n.

Same path, three encodings: full SRH 80 B · reduced 64 B · uSID 40 B. The IPv6 floor is 1280 octets, so this is the number the MTU conversation turns on.

Two Dell switches with zero SRv6 support, two Linux endpoints, two segments. The deployment most customers can actually build today.

Walk one packet across the Dell-transit topology and predict the destination address at each hop before revealing it. Then switch to the bf3-spectrum-host topology and see the same roles with NVIDIA parts in them.

5What it costs: 4 bytes a label against 16 bytes a segment

The comparison table below is the one to have ready. Every row is sourced, and the row customers fight about is the header cost.

Dimension SR-MPLS SRv6
Segment encoding MPLS label or index into a label space 128-bit IPv6 address
Header Label stack IPv6 header plus Routing Header type 4 (SRH)
Active segment Top label IPv6 destination address
NEXT POP top label Copy Segment List[SL] into the DA
CONTINUE SWAP top label Plain IPv6 forwarding on the DA
Per-segment cost 4 bytes 16 bytes, or 0 extra when it fits an existing compressed carrier
Transit node requirement Must be MPLS-capable Must be IPv6-capable only
Global identifier coordination SRGB should be identical domain-wide None; SIDs are addresses
Standards baseline RFC 8402 plus RFC 8660 RFC 8402 plus RFC 8754 plus RFC 8986, and now RFC 9800
[1][2][3][4][5][14]

The arithmetic behind the cost row: an outer IPv6 header is 40 bytes, the SRH base is 8 bytes, and each segment adds 16 bytes.[2] So a three-segment encapsulation costs 96 bytes of overhead where a three-label MPLS stack costs 12, because each MPLS label stack entry is 4 octets.[14] Against RFC 8200’s floor - “IPv6 requires that every link in the Internet have an MTU of 1280 octets or greater” - that is real budget, and it is spent on every packet.[6]

Two things close the gap and both are recent enough that customer documentation has not caught up. RFC 9800 (June 2025, Standards Track) specifies compressed segment list encoding and updates RFC 8754, which is what lets several segments share the 128 bits you were already paying for.[5] And RFC 9855 (October 2025) finally made TI-LFA a Proposed Standard, which retires the “we do not deploy pre-standard features” objection that had blocked it for years.[9] Lesson 2 spends the MTU budget byte by byte; lesson 4 gets most of it back.

Episode 1 closes — Two boxes circled, not thirty-one

How it ended

You redraw her topology with the three roles marked. Two nodes become segment endpoints because their SIDs appear in the list; everything else stays transit and needs only the IPv6 forwarding it already does.[2] On cost you stay honest: 96 bytes for three uncompressed segments against 12 for three labels, with RFC 9800 compression as the design point, not the worst case.[2][14][5]

What you say to her: “You buy endpoints, not a core. The middle of your network only has to route IPv6.”[2]

She writes it on page one. The SE writes something else: a pilot on their own core next change window - and it needs a fourth segment to steer around a box past refresh.

Lab

Read-only on the Dell lab hardware. No firmware writes, no mode changes, no mlxconfig set operations - this lesson only reads.

  1. Pre-flight inventory on both hosts. Record hostname, kernel, adapter and PCIe address:
    uname -r
    lspci | grep -i mellanox
    ip -6 addr show
    Expected: a ConnectX or BlueField-3 device and at least one IPv6-capable data interface. If IPv6 is disabled on the data interface, note it - that is itself the answer to “can we run SRv6 here” and lesson 2 will need it enabled.
  2. Establish the same IPv6 baseline across the real link between the two hosts and capture one ping on the receiver:
    ping6 -c 3 <peer link-local or GUA>
    sudo tcpdump -ni <ifname> -vv ip6 and icmp6
    Expected: clean echo request and reply with no extension headers.
  3. Record MTU on both ends and on the BlueField-3 Arm side as well, since the Arm has its own interfaces and its own kernel:
    ip -6 link show
    Expected: a table of three MTU values. Note the port and PCIe naming you see here; module 2 reuses exactly these names when it pushes an SRH from the NIC.
  4. Write the one-paragraph answer you would give a customer who asks whether their existing switch has to change. Ground it in RFC 8754 section 3.2 and say plainly what you verified today: two hosts, one IPv6 path, no SR anywhere, and it already forwards.[2]
  5. Optional, customer lab only: repeat the baseline across an NVIDIA switch to confirm that a hop with no SRv6 configuration is a legitimate transit node.[2][10] Still read-only.

Retrieval check

10 questions from memory. Answer before looking anything up; misses become flashcards.

Explain it to a Dell SE

Explain to a Dell SE in four sentences what a segment is, where the active segment lives in an SRv6 packet, and why the customer does not need to upgrade every switch in the path.

14 flashcards for this lesson — 0 in deck. Spaced review lives at /review.

Sources

Facts in this lesson were checked against RFC 8402, RFC 8754, RFC 8660, RFC 8986, RFC 9800, RFC 9602, RFC 9855 re-read 2026-09-07. Dates are when each page was fetched.

  1. RFC 8402 - Segment Routing Architecture · fetched 2026-09-07
  2. RFC 8754 - IPv6 Segment Routing Header (SRH) · fetched 2026-09-07
  3. RFC 8660 - Segment Routing with the MPLS Data Plane · fetched 2026-09-07
  4. RFC 8986 - SRv6 Network Programming · fetched 2026-09-07
  5. RFC 9800 - Compressed SRv6 Segment List Encoding · fetched 2026-09-07
  6. RFC 8200 - Internet Protocol Version 6 (IPv6) Specification · fetched 2026-09-07
  7. RFC 9256 - Segment Routing Policy Architecture · fetched 2026-09-07
  8. RFC 9602 - SRv6 SIDs in the IPv6 Addressing Architecture · fetched 2026-09-07
  9. RFC 9855 - Topology Independent Fast Reroute Using Segment Routing · fetched 2026-09-07
  10. Segment Routing | Cumulus Linux 5.18 · fetched 2026-09-07
  11. Containerlab - Dell Enterprise SONiC (dell_sonic kind) · fetched 2026-09-07
  12. Dell Enterprise SONiC Distribution Compatibility Matrix Release 4.4.0 · fetched 2026-09-07
  13. iproute2 man source - ip-route.8.in · fetched 2026-09-07
  14. RFC 3032 - MPLS Label Stack Encoding · fetched 2026-09-07
  15. FRR documentation - Zebra (SRv6 locators) · fetched 2026-09-07

The same idea elsewhere

Other lessons that cover this ground, sometimes from another course's angle.