Networking · Network Virtualization

SRv6 Segment Lists as a Source-Routed Overlay

How a 128-bit IPv6 address doubles as a forwarding instruction, what the segment list in the routing header encodes, and why path state moves from the core to the edge.

An MPLS path is state in the network. Every label-switched router on the path holds an entry mapping an incoming label to an outgoing label and a next hop, and changing the path means changing entries along it. Segment routing inverts that: the path is written into the packet as a list of destinations, and the routers on the path hold only the state needed to reach each of those destinations individually. SRv6 goes further and makes each element of that list an IPv6 address, so the forwarding instruction and the destination are the same field.

A SID is an address that means something

A segment identifier in SRv6 is a 128-bit IPv6 address. It is routable in the ordinary sense: a packet addressed to it reaches the node that owns it, through whatever IPv6 routing the network already runs. What makes it a SID rather than a plain address is that the owning node has attached a behaviour to it. When a packet arrives with that address as its destination, the node does not deliver it to an application; it executes the behaviour and then, usually, forwards the packet to the next address in the list.

The address is therefore two things at once. It is a locator, the prefix that the routing system advertises so the packet reaches the right node, and it is a function, the part of the address that selects which behaviour to execute. Splitting the 128 bits into those two roles is a local decision: a deployment chooses a locator length, and the remaining bits identify the function and any arguments the function needs.

That split is what makes the scheme deployable without new routing protocols. The locator is advertised by the existing IPv6 routing, so a core router that knows nothing about segments forwards a packet to a SID exactly as it forwards any other IPv6 packet. Only the nodes that own SIDs need to understand them, and they need to understand only their own.

The segment list and the routing header

The list of segments is carried in an IPv6 routing header of type 4, defined in RFC 8754. The header contains a segment list, a segments-left counter, and a small set of flags. The list is stored in reverse path order: the entry at index zero is the final destination, and the entry at the highest index is the first node to be visited. The counter starts at that highest index, and the packet’s IPv6 destination address is set to the segment the counter currently points at.

The processing is a loop that the segment endpoints execute and the transit routers do not. A node receives a packet whose destination is one of its SIDs, checks that the destination equals the list entry the counter indicates, executes the behaviour, decrements the counter, and copies the next entry into the destination field. The packet continues toward the next segment. When the counter reaches zero the node executes the final behaviour, which is what delivers the payload: decapsulation, delivery to a table, or delivery to an interface.

The check that the destination matches the list entry is not a formality. Without it, a packet could carry a routing header naming arbitrary SIDs and cause a node to execute behaviours it never agreed to perform for that packet’s source. The verification binds the instruction to the packet’s declared path, and a mismatch is an error that the node reports rather than a behaviour it performs.

Two variants of the loop exist. In the uncompressed form, the counter is decremented and the next address is written into the destination field, so each segment is visited in turn. In the compressed form, a single 128-bit address carries several short segments packed into it, and the node advances within the address rather than to the next list entry, which keeps the header small when the segments are short and locally significant.

The behaviours that do the work of an overlay

The behaviours defined in RFC 8986 are the vocabulary of the data plane, and the set that matters for virtual networks is small.

An endpoint behaviour that pops the routing header and delivers the inner packet to a table is the decapsulation primitive: the packet arrived with a SID naming this node, the node strips the outer IPv6 header and the routing header, and the inner packet is processed as if it had arrived on an interface. A behaviour that does the same but delivers to a specific interface, or to a specific address family’s table, is the variant that keeps tenants separate.

A behaviour that forwards to an adjacency, optionally with a segment appended, is the underlay primitive: the node sends the packet out a specific link toward a specific neighbour. A behaviour that encapsulates an IP packet in an outer IPv6 header with a segment list is the ingress primitive: the first node builds the entire path and the rest of the network executes it.

Together those cover what a VXLAN fabric does with a VNI and a mapping table. The difference is where the mapping lives. In VXLAN, the ingress endpoint looks up the destination MAC in a table keyed by virtual network and remote endpoint, and the table is populated by a control plane. In SRv6, the ingress endpoint builds a segment list naming the nodes the packet must traverse, and the list itself is the path. The core holds no per-path state; it holds routes to locators, which it would hold anyway. The behaviours are drawn from a defined set rather than from a per-deployment policy table, unlike the table-driven data plane described in match-action pipelines and flow caching.

That is the property the architecture is built around. A path through the network is a list in the packet, so adding a path requires no configuration in the core, and a path can be computed by the ingress node from a policy it holds locally. The core’s state is proportional to the number of locators, not to the number of paths, which is the same argument that made overlays scale, applied one layer down.

The overhead, stated honestly

Each segment is a 128-bit address, and each hop that executes a segment requires the packet to carry the routing header. An uncompressed list of five segments is 80 bytes of segment list plus the routing header’s fixed fields, on top of an outer IPv6 header of 40 bytes. Compared with VXLAN’s 50 bytes over IPv4, the overhead is larger, and it grows with the length of the path.

The MTU consequence is direct. A path of n segments consumes roughly 40 + 8 + 16n bytes before the inner packet, and the inner MTU must be reduced by that amount. A deployment that uses long segment lists has to either raise the underlay MTU or reduce the inner one further than an encapsulation-based overlay would. This is the axis on which SRv6 loses to VXLAN, and it is why the compressed segment encoding exists: packing several short segments into one 128-bit address brings the overhead back toward the encapsulated schemes for paths whose segments are short and locally significant.

The second cost is the per-hop processing. Each segment endpoint must parse the routing header, verify the index, execute a behaviour, rewrite the destination address, and forward. That is more work per hop than a plain IPv6 forward, and it is performed at every segment rather than only at the tunnel endpoints. A path with many segments is a path with many nodes doing this work, so the scheme trades core state for per-hop computation. Where the segments are few and the paths are many, that is a good trade; where the paths are few and the segments are many, it is not.

Where the model breaks

The first failure is the interaction with the existing IPv6 routing. A locator must be advertised, and the advertisement must be understood by every router that might carry a packet to it. A network that runs SRv6 only at its edge but whose core is operated by someone else depends on that other party routing the locator prefixes, which is a business arrangement as much as a technical one. The scheme does not create reachability; it assumes it.

The second is the security model of source routing. A packet that names its own path can be used to reach nodes the sender could not otherwise reach, and the check that the destination matches the current segment is a protocol conformance check, not an authorization. Deployments filter on the source of packets carrying routing headers, and they limit which SIDs a node will execute for which sources. The header format provides no authentication of its own, so the protection is at the boundary.

The third is the reverse path. A segment list describes the forward direction, and the return traffic needs its own list or a different mechanism. Symmetric paths can be built by having each node record the reverse list as it forwards, which is what the routing header’s optional type-length-value entries can carry, but the recording is per-packet state at each hop and reintroduces the state the architecture was meant to remove. The operations that need this are the ones that already require per-flow state: a stateful firewall that admits a return packet because it saw the outbound one, a load balancer that remembers which backend a connection went to, a NAT that must translate the reply consistently. Those functions have to be placed on the segment list deliberately, at nodes that hold the state anyway, because a core node that only executes a forwarding behaviour has no memory in which to keep it. Asymmetric routing is the common outcome, and any stateful middlebox on the path has to account for it.

The fourth is that the scheme’s benefit is largest exactly where its assumptions are weakest. A single administrative domain that controls its core, has a large MTU, and needs many distinct paths gets the full benefit. A multi-domain deployment with a 1500-byte underlay and a mix of equipment gets the overhead without the state reduction. The decision is therefore a property of the deployment’s boundaries, not of the protocol, and the same reasoning applies to the choice between an encapsulated overlay and a routed one described in the overlay and underlay split.

References

  1. RFC 8402: Segment Routing Architecture — IETF
  2. RFC 8754: IPv6 Segment Routing Header (SRH) — IETF
  3. RFC 8986: Segment Routing over IPv6 (SRv6) Network Programming — IETF