# Segment Routing with MPLS (SR-MPLS)


![Topology Diagram](/posts/2022/06/sr-mpls-basic/topology.png)

In this lab we explore Segment Routing (SR) using Multiprotocol Label Switching
as an encoding mechanism. 

Segment Routing, also known as "Source Packet Routing in Networking" 
([SPRING](https://datatracker.ietf.org/wg/spring/about/)), is a
method of routing in which ingress routers prepend instructions to
traffic that cause actions to be performed by transit nodes as it travels across
a network. This is sometimes as simple as a list of routers a packet must traverse
to reach its destination.

Clarence Filsfils writes in 
[_Segment Routing Part I_](https://www.goodreads.com/book/show/31840110-segment-routing-part-i) 
about how the inspiration for SR came from the relationship to driving a car.
Events like traffic accidents or construction could be simply avoided by 
listening to a traffic report and driving an alternate route.

Segment Routing provides the ability to encode instructions like this on a
per-packet basis and opens the door to a wide range of flexibility.
With such fine-grained control, new decisions are possible based on factors like
real-time optimal link utilization, congestion mitigation or any number of future 
software defined networking applications. Another benefit is simplification of 
the control plane by eliminating the need for additional protocols like Label
Distribution Protocol (LDP) and RSVP-TE. Interior routing protocols such as 
OSPF and IS-IS, are extended to perform the role of distributing global labels, 
known as Segment Identifiers (SIDs). It also supports the ability to compute 
Topology-Independent Loop-Free Alternates (TI-LFA) which provide practically
instantaneous failover paths without adversely affecting traffic while waiting
for route re-convergence.

Clearly this technology brings with it a broad range of new terminology and
possibilities that go way beyond the scope of a simple blog article. See 
[Additional Resources](#additional-resources) for more information about
Segment Routing.

Today we are going to focus on implementing a basic SR-MPLS network on three popular 
platforms: Cisco IOS-XE, Cisco IOS-XR and Juniper Junos OS

## Basic steps

1) Enable Segment Routing support
2) Define a common Segment Routing Global Block (SRGB)
3) Configure a global prefix SID
4) Verify forwarding

**Note:** This post contains the bare minimum configuration required to 
demonstrate Segment Routing. Other properties such as IGP costs, circuit-types, 
etc should also be considered.

## IOS-XR

### Enabling Segment Routing

The following configuration enables segment routing and defines the Segment
Routing Global Block (SRGB). Define the same block on every device throughout
the SR domain. 

```ios-xr
segment-routing
 global-block 16000 23999
!
```

*A quick note about the SRGB*: Although the SRGB defined above lists an explicit
range of MPLS labels, it is important to know that the actual transmission of
label information is always by reference to an index *not label*. For example,
index 1 based on the SRGB above indicates label 16001. However, if a different
range were to be defined on an adjacent router, say 32000 to 23999, index 1 
would refer to label 32001. This may cause undesirable effects.

For this reason it is **critically important** to define a unified SRGB across
all devices in the Segment Routing domain to ensure the meaning of each label
remains uniform within the global block.

### Configuring IS-IS

Wide metrics are required. Segment routing can be enabled with or without the
`sr-prefer` keyword. This option allows for migrating traditional MPLS networks
to segment routing. By omitting the `sr-prefer` keyword, the forwarding plane
will use any traditional MPLS labels before considering SR.

```ios-xr
router isis SRMPLS
 net 49.0000.5001.0001.0001.00
 address-family ipv4 unicast
  metric-style wide
  segment-routing mpls sr-prefer
 !
 interface Loopback0
  address-family ipv4 unicast
   prefix-sid absolute 16001 explicit-null
  !
 !
 interface GigabitEthernet0/0/0/0
  suppressed
  point-to-point
  address-family ipv4 unicast
  !
 !
 interface GigabitEthernet0/0/0/1
  suppressed
  point-to-point
  address-family ipv4 unicast
  !
 !
 interface GigabitEthernet0/0/0/2
  suppressed
  point-to-point
  address-family ipv4 unicast
  !
 !
 interface GigabitEthernet0/0/0/3
  suppressed
  point-to-point
  address-family ipv4 unicast
  !
 !
!
```

### Configuring the prefix SID

In the above example, the prefix SID (16001) for **Loopback0** is assigned under 
the IS-IS interface configuration. When defining the SID, you will have the
option to define it absolutely or by index. As mentioned previously, SIDs are
always communicated by reference to index. However, it is recommended to configure
the SID by absolute value whenever possible. While it is cosmetic, 
absolute values allow for easier verification versus cross-referencing
the SRGB with a configured index.

A quick note about **prefix suppression** (`suppressed`). While unrelated to SR,
this useful tool prevents these networks from appearing unnecessarily in the IGP. 
This reduces table size and limits update flooding allowing for more efficient
scaling. However, it is important to remember that any tool sets used on the router
to test connectivity (ping, traceroute, etc) will obviously need to be sourced
from a network that is advertised in the IGP, such as `Loopback0`.

### Verification

Verify MPLS forwarding is enabled on the expected interfaces:

```ios-xr
RP/0/0/CPU0:R1#sh mpls interfaces 
Sat Jun 18 05:04:54.306 UTC
Interface                  LDP      Tunnel   Static   Enabled 
-------------------------- -------- -------- -------- --------
GigabitEthernet0/0/0/0     No       No       No       Yes
GigabitEthernet0/0/0/1     No       No       No       Yes
GigabitEthernet0/0/0/2     No       No       No       Yes
GigabitEthernet0/0/0/3     No       No       No       Yes
```

Verify the MPLS LFIB is populated with the appropriate SIDs:

```ios-xr
RP/0/0/CPU0:R1#sh mpls forwarding 
Sat Jun 18 05:05:11.655 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
16002  Pop         SR Pfx (idx 2)     Gi0/0/0/0    10.1.12.2       648         
16003  Pop         SR Pfx (idx 3)     Gi0/0/0/1    10.1.13.3       0           
16004  16004       SR Pfx (idx 4)     Gi0/0/0/0    10.1.12.2       0           
       16004       SR Pfx (idx 4)     Gi0/0/0/1    10.1.13.3       0           
16005  Pop         SR Pfx (idx 5)     Gi0/0/0/2    10.1.15.5       648         
16006  16006       SR Pfx (idx 6)     Gi0/0/0/0    10.1.12.2       120         
16007  Pop         SR Pfx (idx 7)     Gi0/0/0/3    10.1.17.7       1306        
16008  16008       SR Pfx (idx 8)     Gi0/0/0/0    10.1.12.2       41800       
[abbreviated] 
```

Perform a traceroute and watch for the expected traffic labeling:

```ios-xr
RP/0/0/CPU0:R1#traceroute 10.0.255.8 source loop0
Sat Jun 18 05:05:56.722 UTC

Type escape sequence to abort.
Tracing the route to 10.0.255.8

 1  10.1.12.2 [MPLS: Label 16008 Exp 0] 9 msec  0 msec  0 msec 
 2  10.0.255.8 0 msec  0 msec  0 msec 
```

## IOS-XE

### Enabling Segment Routing

```ios-xe
segment-routing mpls
 global-block 16000 23999
 !
 connected-prefix-sid-map
  address-family ipv4
   10.0.255.6/32 absolute 16006 range 1 
  exit-address-family
 !
!
```

The top-level `segment-routing mpls` stanza contains configuration for the SRGB 
and any pre-defined prefix SIDs. The standard SR-MPLS global block range of 
16000 through 23999 is demonstrated here as well as the unique prefix SID for
this router's loopback address.

Again, configuring absolute instead indexed labels are recommended for the ease
of reference.

### Configuring IS-IS

```ios-xe
router isis SRMPLS
 net 49.0006.5001.0014.0000.00
 metric-style wide
 segment-routing mpls
!
```

Configuring IS-IS is straightforward. The example above shows a complete basic IS-IS
configuration for area `49.0006`. Wide metrics are required. The
`segment-routing mpls` statement enables SR-MPLS support for IOS-XE. The final
step is to verify that any other SR-MPLS neighbor interfaces are configured for
IS-IS.

```ios-xe
interface GigabitEthernet1
 ip router isis SRMPLS
!
```

No direct MPLS configuration is needed.

### Verification

Verify the expected interfaces are operational for MPLS. This should
automatically include any interfaces configured by an IGP running SR.

```ios-xe
R4# sh mpls interfaces 
Interface              IP            Tunnel   BGP Static Operational
GigabitEthernet1       No            No       No  No     Yes        
GigabitEthernet2       No            No       No  No     Yes        
GigabitEthernet3       No            No       No  No     Yes       
```

Verify the MPLS forwarding table contains local adjacency SIDs and any expected
prefix SIDs from the IS-IS neighbors:

```ios-xe
R4# sh mpls forwarding-table 
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop    
Label      Label      or Tunnel Id     Switched      interface              
16         Pop Label  10.2.24.2-A      0             Gi1        10.2.24.2   
17         Pop Label  10.2.24.2-A      0             Gi1        10.2.24.2   
18         Pop Label  10.4.46.6-A      0             Gi3        10.4.46.6   
19         Pop Label  10.3.34.3-A      0             Gi2        10.3.34.3   
20         Pop Label  10.3.34.3-A      0             Gi2        10.3.34.3   
21         Pop Label  10.4.48.8-A      0             Gi4        10.4.48.8   
16001      16001      10.0.255.1/32    0             Gi1        10.2.24.2   
           16001      10.0.255.1/32    0             Gi2        10.3.34.3   
16002      Pop Label  10.0.255.2/32    0             Gi1        10.2.24.2   
16003      Pop Label  10.0.255.3/32    0             Gi2        10.3.34.3   
16005      16005      10.0.255.5/32    0             Gi2        10.3.34.3   
16006      Pop Label  10.0.255.6/32    0             Gi3        10.4.46.6   
16007      16007      10.0.255.7/32    0             Gi2        10.3.34.3   
16008      Pop Label  10.0.255.8/32    0             Gi4        10.4.48.8  
```

Traceroute to confirm end-to-end MPLS forwarding:

```ios-xe
R6# traceroute 10.0.255.7 source loop0     
Type escape sequence to abort.
Tracing the route to 10.0.255.7
VRF info: (vrf in name/id, vrf out name/id)
  1 10.2.26.2 [MPLS: Label 16007 Exp 0] 4 msec
    10.4.46.4 [MPLS: Label 16007 Exp 0] 14 msec
    10.2.26.2 [MPLS: Label 16007 Exp 0] 14 msec
  2 10.3.34.3 [MPLS: Label 16007 Exp 0] 123 msec
    10.1.12.1 [MPLS: Label 16007 Exp 0] 18 msec
    10.3.34.3 [MPLS: Label 16007 Exp 0] 3 msec
  3 10.1.17.7 7 msec
    10.3.37.7 4 msec * 
```

The above traceroute shows an example of multiple paths to R7's loopback
(10.0.255.7). Each router uses the prefix SID (MPLS label 16007) to reach R7.

## Junos

```junos
chassis {
    network-services enhanced-ip;
}
```

The routing engine must be restarted before other SR configuration will
function:

```
root@R2> restart routing
```

Enable MPLS and ISO (for IS-IS) on each of the backbone interfaces:

```junos
ge-0/0/0 {
    description R1;
    unit 0 {
        family inet {
            address 10.1.12.2/24;
        }
        family iso;
        family mpls;
    }
}
ge-0/0/1 {
    description R4;
    unit 0 {
        family inet {
            address 10.2.24.2/24;
        }
        family iso;
        family mpls;
    }
}
ge-0/0/2 {
    description R6;                     
    unit 0 {
        family inet {
            address 10.2.26.2/24;
        }
        family iso;
        family mpls;
    }
}
ge-0/0/3 {
    description R8;
    unit 0 {
        family inet {
            address 10.2.28.2/24;
        }
        family iso;
        family mpls;
    }
}

protocols {
    mpls {
        interface ge-0/0/0.0;
        interface ge-0/0/1.0;
        interface ge-0/0/2.0;
        interface ge-0/0/3.0;
    }
}
```

Next configure basic IS-IS and Segment Routing:

```junos
protocols {
    isis {
        source-packet-routing {
            srgb start-label 16000 index-range 16999;
            node-segment ipv4-index 2;
        }
        interface ge-0/0/0.0
        interface ge-0/0/1.0
        interface ge-0/0/2.0
        interface ge-0/0/3.0
        interface lo0.0;
    }
}
```

Note the `index-range` versus an absolute label range (i.e. 16000-23999). The
`node-segment ipv4-index 2` statement configures this node's SID as 16002. The
identifier is based off the SRGB defined as the index-range.

### Verification

Verify the appropriate interfaces are MPLS enabled:

```junos
root@R2> show mpls interface 
Interface        State       Administrative groups (x: extended)
ge-0/0/0.0       Up         <none>
ge-0/0/1.0       Up         <none>
ge-0/0/2.0       Up         <none>
ge-0/0/3.0       Up         <none>
```

Validate the MPLS label table:

```junos
root@R2> show route table mpls.0 

mpls.0: 41 destinations, 41 routes (41 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

[abbreviated]   
16001              *[L-ISIS/14] 08:02:38, metric 20
                    >  to 10.1.12.1 via ge-0/0/0.0, Swap 0
16001(S=0)         *[L-ISIS/14] 07:43:41, metric 20
                    >  to 10.1.12.1 via ge-0/0/0.0, Pop      
16003              *[L-ISIS/14] 07:58:11, metric 20
                       to 10.1.12.1 via ge-0/0/0.0, Swap 16003
                    >  to 10.2.24.4 via ge-0/0/1.0, Swap 16003
16004              *[L-ISIS/14] 08:04:36, metric 20
                    >  to 10.2.24.4 via ge-0/0/1.0, Pop      
16004(S=0)         *[L-ISIS/14] 07:43:41, metric 20
                    >  to 10.2.24.4 via ge-0/0/1.0, Pop      
16005              *[L-ISIS/14] 07:58:10, metric 20
                    >  to 10.1.12.1 via ge-0/0/0.0, Swap 16005
16006              *[L-ISIS/14] 07:59:08, metric 20
                    >  to 10.2.26.6 via ge-0/0/2.0, Pop      
16006(S=0)         *[L-ISIS/14] 07:58:11, metric 20
                    >  to 10.2.26.6 via ge-0/0/2.0, Pop      
16007              *[L-ISIS/14] 07:58:50, metric 30
                    >  to 10.1.12.1 via ge-0/0/0.0, Swap 16007
16008              *[L-ISIS/14] 07:58:41, metric 10
                    >  to 10.2.28.8 via ge-0/0/3.0, Pop      
16008(S=0)         *[L-ISIS/14] 07:58:11, metric 10
                    >  to 10.2.28.8 via ge-0/0/3.0, Pop
```

Traceroute to confirm end-to-end MPLS forwarding:

```junos
root@R8> traceroute mpls segment-routing isis 10.0.255.5 source 10.0.255.8                
  Probe options: ttl 64, retries 3, wait 10, paths 16, exp 7, fanout 16
                 source 10.0.255.8

  ttl    Label  Protocol    Address          Previous Hop     Probe Status
    1    16005  ISIS        10.2.28.2        (null)           Success           
  FEC-Stack-Sent: ISIS 
  ttl    Label  Protocol    Address          Previous Hop     Probe Status
    2                       10.1.12.1        10.2.28.2        No reply          
    3                       10.0.255.5       (null)           Egress            
  FEC-Stack-Sent: ISIS 

  Path 1 via ge-0/0/0.0 destination 127.0.0.64

  ttl    Label  Protocol    Address          Previous Hop     Probe Status
    1    16005  ISIS        10.4.48.4        (null)           Success           
  FEC-Stack-Sent: ISIS 
  ttl    Label  Protocol    Address          Previous Hop     Probe Status
    2    16005  Unknown     10.3.34.3        10.4.48.4        Success           
  FEC-Stack-Sent: ISIS 
  ttl    Label  Protocol    Address          Previous Hop     Probe Status
    3        3  ISIS        10.3.35.5        10.3.34.3        Egress            
  FEC-Stack-Sent: ISIS 

  Path 2 via ge-0/0/1.0 destination 127.0.1.64
```

## Additional Resources

* [Source Packet Routing in Networking Working Group (IETF)](https://datatracker.ietf.org/doc/charter-ietf-spring/)
* [What is segment routing? (Juniper)](https://www.juniper.net/us/en/research-topics/what-is-segment-routing.html)
* [Segment Routing Overview and Migration Guidelines (Cisco)](https://www.cisco.com/c/en/us/support/docs/multiprotocol-label-switching-mpls/mpls/215215-segment-routing-overview-and-migration-g.html)
* [Segment Routing Part I](https://www.goodreads.com/book/show/31840110-segment-routing-part-i)
* [Segment Routing Part II: Traffic Engineering](https://www.goodreads.com/book/show/44048366-segment-routing-part-ii)

