Segment Routing Introduction

Segment Routing (SR) is also known as SPRING (Source Packet Routing in Networking). Two flavours of SR exist:

  • SR with MPLS
  • SRv6 (IPv6 Segment Routing Header (SRH))

I will only cover SR with MPLS in this post.

If you know MPLS it will be fairly easy to learn about SR. If we quickly look at the name of the feature and break it down, it will make sense what its all about.


A segment is nothing but an instruction. And with MPLS as data plane this directly translates into a label.


We route based on the segments (labels).

Types of Segments

SR has two overall types of segments. At least if we’re talking about basic SR. They are:

  • Prefix-SID
    • Globally unique
  • Adj-SID

A Prefix-SID (Segment Identifier) is a label for a prefix. Unless explicitly advertised, the Prefix-SID is globally unique. For the prefix of the loopback interface in the below example, a special flag is set making this a Node-SID. This value is globally unique just like the IP address of the interface has to be.

Adj-SID (Adjacency-SID) is a label for a specific link. This label value is typically locally unique, but could be globally unique. One reason to do this would be to reuse the label throughout the network thereby cutting down on SID list depth. The benefit is that platforms are dependent on the depth at which they can handle a SID list. This means the number of labels that makes up the MSD (Maximum SID Depth). The MSD is also advertised in the IGP to avoid using nodes that cannot handle the number of SIDs for a packet.

To ensure the global uniqueness of the labels assigned for Prefix-SIDs a special range of 8000 labels has been allocated for use with SR. We call this range the SRGB (Segment Routing Global Block). It starts at 16000. This is for Cisco implementations at least. Other vendors may choose to use a different range. It is recommended that the SRGB stays the same within the routing domain.

Labels for Adj-SIDs are allocated from the dynamic pool that LDP, BGP, and RSVP-TE also use, meaning any label excluding values 0-15 and 16000-23999.

Control Plane

With SR we have no need for LDP. To distribute the labels new TLVs have been defined for ISIS and new Opaque LSAs have been defined for OSPF. We have the complete picture of the topology within our level or area, hence there is no need for the extra complexity that LDP would otherwise introduce when dealing with MPLS. With all the labels distributed by the IGP, there is no use for a signaling protocol to do TE (Traffic Engineering). SR-TE is a matter of specifying a TE policy and run CSPF (Constraint-based Shortest Path First) or simply defining an ERO. All is done at the headend with no interaction with any of the other routers. This is also true for TI-LFA (Topology Independent LFA (Loop Free Alternate)).

For quick reference here are some of the TLVs and LSAs for SR:

ISIS TLVs for Segment Routing

TLV Description/SubTLV
22 Extended IS reachability

31 - Adjacency Segment Identifier
135 Extended IP reachability

3 - Prefix Segment Identifier
242 Router Capability

2 - Segment Routing Capability

OSPF LSAs for Segment Routing

LSA Description/Opaque Type/SubTLV
Opaque Type 10 Extended Prefix Opaque LSA (type 7)

2 - Prefix SID Sub-TLV

Extended Link Opaque LSA (type 8)

2 - Adj-SID Sub-TLV

Data Plane

With all the labels in our LSDB it is easy to create a label stack or SID list as we call it with SR. This happens at the source router - our ingress PE for example. Forwarding works like we’re used to with MPLS including features like PHP.


I’ll use the following topology:


All routers are running XRv and I use ISIS.

Looking at XRV1 configuration:

router isis 1
 is-type level-2-only
 net 49.3345.0001.0001.0001.00
 address-family ipv4 unicast
  metric-style wide
  advertise passive-only
  segment-routing mpls
 interface Loopback0
  address-family ipv4 unicast
   prefix-sid absolute 16001
 interface GigabitEthernet0/0/0/0
  address-family ipv4 unicast
 interface GigabitEthernet0/0/0/1
  address-family ipv4 unicast

Here we see a simple ISIS configuration with just two commands to enable SR! First SR is actived for ISIS. this will activate the new TLVs and enable MPLS on all non-passive interfaces. Next we define a prefix-SID for Loopback0. Here i’ve used an absolute value. This will however be translated into an index in the LSDB:

RP/0/0/CPU0:XRV1#show isis database  XRV1.00-00 verbose
Sun May 26 19:26:25.768 UTC

IS-IS 1 (Level-2) Link State Database
LSPID                 LSP Seq Num  LSP Checksum  LSP Holdtime  ATT/P/OL
XRV1.00-00          * 0x0000002c   0xb5fb        1197            0/0/0
  Area Address:   49.3345
  NLPID:          0xcc
  Hostname:       XRV1
  IP Address:
  Router Cap:, D:0, S:0
    Segment Routing: I:1 V:0, SRGB Base: 16000 Range: 8000
  Metric: 10         IS-Extended XRV2.00
    Interface IP Address:
    Neighbor IP Address:
    ADJ-SID: F:0 B:1 V:1 L:1 S:0 weight:0 Adjacency-sid:24000
    ADJ-SID: F:0 B:0 V:1 L:1 S:0 weight:0 Adjacency-sid:24001
  Metric: 10         IS-Extended XRV4.00
    Interface IP Address:
    Neighbor IP Address:
    ADJ-SID: F:0 B:1 V:1 L:1 S:0 weight:0 Adjacency-sid:24002
    ADJ-SID: F:0 B:0 V:1 L:1 S:0 weight:0 Adjacency-sid:24003
  Metric: 0          IP-Extended
    Prefix-SID Index: 1, Algorithm:0, R:0 N:1 P:0 E:0 V:0 L:0

Here we have the LSP (Link State Packet) for XRV1. If we start with the Router Cap: section. This is where SR appears for the first time in this LSP. This is an SR capable router that has the default SRGB configured. The flags used for this TLV are:

Router Capability Flags

Flag Description
I:1 IPv4 capable
V:0 (no) IPv6 capable

A wireshark capture focusing on the router capability:


Next we see som Adj-SIDs using labels from 24000 and above.

Adj-SID Flags

Flag Description
F:0 address-family IPv4
B:1 eligible for Backup
V:1 adj SID has a value
L:1 Local significance
S:0 Set of adjacencies
Weight:1 Amount of load balancing (N/A yet)

Wireshark of the Adj-SID SubTLV:


In the last TLV we see the Prefix-SID. Note that although I used an absolute value to define the SID the LSDB will always use the index value!

Adj-SID Flags

Flag Description
R:0 not Re-advertised
N:1 Node SID
P:0 PHP on
E:0 Explicit null off
V:0 index
L:0 global significance

Wireshark of the Prefix-SID SubTLV:


We can verify if the interfaces have been enabled for MPLS:

RP/0/0/CPU0:XRV1#sh mpls int
Sun May 26 19:40:55.089 UTC
Interface                  LDP      Tunnel   Static   Enabled
-------------------------- -------- -------- -------- --------
GigabitEthernet0/0/0/0     No       No       No       Yes
GigabitEthernet0/0/0/1     No       No       No       Yes

Looks good. Note that we don’t use LDP at all. The interfaces are simply enabled for MPLS.

We can also look at the LFIB for verification:

RP/0/0/CPU0:XRV1#sh mpls forwarding
Sun May 26 19:43:11.209 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
16002  Pop         SR Pfx (idx 2)     Gi0/0/0/1       0           
16003  16003       SR Pfx (idx 3)     Gi0/0/0/1       0           
16004  Pop         SR Pfx (idx 4)     Gi0/0/0/0       232200      
16005  16005       SR Pfx (idx 5)     Gi0/0/0/0       9408        
24000  Pop         SR Adj (idx 1)     Gi0/0/0/1       0           
24001  Pop         SR Adj (idx 3)     Gi0/0/0/1       0           
24002  Pop         SR Adj (idx 1)     Gi0/0/0/0       0           
24003  Pop         SR Adj (idx 3)     Gi0/0/0/0       0           

And finally a traceroute to verify the data plane. This I’ll do from the loopbacks of XRV1 to XRV5. This should give us a SID list of 16005.

RP/0/0/CPU0:XRV1#traceroute source lo0
Sun May 26 19:51:09.037 UTC

Type escape sequence to abort.
Tracing the route to

 1 [MPLS: Label 16005 Exp 0] 29 msec  0 msec  0 msec
 2 9 msec  *  9 msec

It might not be that obvious for this path, but had we taken the longer path through XRV2, the trace will look like this: (I’ve shutdown the link towards XRV4 on XRV1)

RP/0/0/CPU0:XRV1#traceroute source lo0
Sun May 26 19:52:49.790 UTC

Type escape sequence to abort.
Tracing the route to

 1 [MPLS: Label 16005 Exp 0] 39 msec  19 msec  9 msec
 2 [MPLS: Label 16005 Exp 0] 9 msec  39 msec  39 msec
 3 59 msec  *  29 msec

Notice the same value used on the first and second hops. This isn’t random. All routers use this label value to reach XRV5’s loopback0 interface.

If we configure a metric of 20 on the link between XRV1 and XRV2, we should end up with some load sharing. I choose 20, because the default metric value for a link with ISIS is 10.

router isis 1
 interface GigabitEthernet0/0/0/0
  address-family ipv4 unicast
   metric 20

Verify using the routing table:

RP/0/0/CPU0:XRV1#sh route
Sun May 26 19:55:46.238 UTC

Routing entry for
  Known via "isis 1", distance 115, metric 30, labeled SR, type level-2
  Installed May 26 19:55:00.571 for 00:00:45
  Routing Descriptor Blocks, from, via GigabitEthernet0/0/0/0
      Route metric is 30, from, via GigabitEthernet0/0/0/1
      Route metric is 30
  No advertising protos.

Note the labeled SR statement of this route.

And the LFIB:

RP/0/0/CPU0:XRV1#sh mpls forwarding prefix
Sun May 26 19:56:50.673 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
16005  16005       SR Pfx (idx 5)     Gi0/0/0/0       0           
       16005       SR Pfx (idx 5)     Gi0/0/0/1       0           

Still we only use label 16005 and now we even have load balancing with SR!


To sum up SR is a new way of using MPLS with fewer protocols involved. No need for LDP as the IGP handles the distribution of labels for us. Since all routers know all the labels, each router can indenpendently build a SIB list to select the path they want to used throughout the network. Configuring SR takes only a few commands under the IGP and we use the verification commands we’re used to making things much simpler.

If you’re looking to deploy a new MPLS network I would strongly advise to go with SR if your boxes have this feature.

I hope you enjoyed this post.

Jacob Zartmann avatar
Jacob Zartmann
Passionate Network Engineer thriving for challenges and knowledge.