
In the previous parts of this series, I mentioned the typical methods for assigning labels is static binding, LDP, and BGP Labeled Unicast (BGP-LU). There is another one I haven’t talked about yet, and that’s Segment Routing (SR). SR is relatively new to MPLS, but is the future of MPLS in my opinion.
In the most basic sense, SR is just an alternative to LDP and BGP-LU to help along label imposition. SR really is so much more than that, but the implementation in VyOS is just for label assignment at the moment.
What is Segment Routing
Segment Routing was created primarily to solve an issue with MPLS Traffic Engineering (MPLS-TE) at large scale, and that’s the massive state created with RSVP signaled tunnels. When doing MPLS-TE, a head-end router will signal across every hop saying “I’d like to take this path, please honor it”. This causes not just the head-end to need to know about the tunnel, but every mid-point router (P routers) need to also keep state for that tunnel. This may not sound bad, but imagine if you had many tunnels, the state created would be extensive.
Segment Routing aimed to solve that in a simpler way. Instead of signaling across the entire network, the head-end would simply insert a stack of labels (a label is called Segment Identifiers or SID in SR), and traffic would just be forwarded to the next label in the stack, with each hop popping its own label so it can be forward to the next hop.
That may not be very clear, but that’s okay. VyOS doesn’t currently support any kind of traffic engineering features. We can still use it to assign labels. If nothing else, it’ll allow us to use OSPF to both advertise our loopbacks, and assign labels. That eliminates the need for LDP as an additional protocol, which decreases our failure domain.
Segment Routing Concepts
In the earlier posts of this series, I mentioned how labels are locally significant to routers. That’s not fully true with SR. SR has the concept of both global and local labels, each with their own specific uses.
Segment Identifiers
In SR, labels are referred to as Segment Identifiers or SIDs. There are a few types of SIDs in SR:
- Prefix SID – A SID that is attached to a host prefix, generally a /32.
- Node SID – A specific Prefix SID that defines a node within SR. This will typically be attached to a loopback that is used for the IGP router-id. A Node SID will be differentiated in the control plane by the setting of the ‘N’ flag.
- AnyCast SID – A specific Prefix SID that is attached to multiple LSRs, allowing for ECMP within an MPLS environment, which is a common shortcoming in traditional MPLS-TE. An Anycast SID defines a group of nodes, and not a single node, so it should have the ‘N’ flag unset.
- Adjacency SID – This is the locally significant SID in SR. It is defined between directly connected interfaces. The addition of Adjacency SIDs allows for more granular traffic engineering in the case you have multiple paths to reach a node SID.
- Binding SID – Binding SIDs are assigned to Segment Routing Traffic Engineering (SR-TE) policies to help steer traffic into the policies.
NOTE: We talked about a lot of different SIDs, but the only SID that we’ll be touching on moving forward is the Node SID due to the lack of SR-TE functions in VyOS.
Global and Local Blocks
There’s 2 blocks that labels will be assigned from; the Segment Routing Global Block (SRGB) and Segment Routing Local Block (SRLB).
- SRGB – The SRGB defines the globally significant block of labels available for assignment to Prefix SIDs.
- SRLB – The SRLB defines the locally significant block of labels available for assignment to Adjecency SIDs.
NOTE: You have a wide range (16-1048575) to configure as your blocks, but you’ll need them to be the same on every device so a block isn’t outside of the range. You also need to ensure the SRGB and SRLB do not overlap.
Let’s build a lab to see some of these concepts in practice.
Topology
We’re going to use the same topology we used for the L3VPN article here with 2 PE routers, 2 P routers, and 2 CE routers.

Network Info
We’re going to use most of the same values for the L3VPN lab, but we need to decide what we’re going to use for our Node SIDs.
Like we’ve done in part 1 and 2, all MPLS devices are interconnected using IPs based on a device number. In this case we’ll use the last octet of the loopbacks (e.g. PE1 and P1 are connected with the 10.1.2.0/24 network; P1 and P2 will connect using the 10.2.3.0/24 network, and P2 and PE2 will connect using 10.3.4.0/24)
- Loopbacks:
- PE1 – 10.0.0.1/32
- P1 – 10.0.0.2/32
- P2 – 10.0.0.3/32
- PE2 – 10.0.0.4/32
- VRF:
- Name – A
- RD – 65000:1
- RT – 65000:1
- CE Network Info:
- CE1 Peering Subnet – 172.16.0.0/30
- CE2 Peering Subnet – 172.16.0.4/30
- CE1 Client Subnet – 10.0.1.0/24
- CE2 Client Subnet – 10.0.2.0/24
- CE1 ASN – 65001
- CE2 ASN – 65002
- Node SIDs
- PE1 – 16001
- P1 – 16002
- P2 – 16003
- P2 – 16004
Let’s build (mostly) the same OSPF peerings we created in Part 2:
PE1:
set interfaces loopback lo address '10.0.0.1/32'
set interfaces ethernet eth0 address '10.1.2.1/24'
set protocols ospf interface lo area '0'
set protocols ospf interface eth0 area '0'
set protocols ospf interface eth0 network 'point-to-point'
P1:
set interfaces loopback lo address '10.0.0.2/32'
set interfaces ethernet eth0 address '10.1.2.2/24'
set interfaces ethernet eth1 address '10.2.3.2/24'
set protocols ospf interface lo area '0'
set protocols ospf interface eth0 area '0'
set protocols ospf interface eth1 area '0'
set protocols ospf interface eth0 network 'point-to-point'
set protocols ospf interface eth1 network 'point-to-point'
P2:
set interfaces loopback lo address '10.0.0.3/32'
set interfaces ethernet eth0 address '10.3.4.3/24'
set interfaces ethernet eth1 address '10.2.3.3/24'
set protocols ospf interface lo area '0'
set protocols ospf interface eth0 area '0'
set protocols ospf interface eth1 area '0'
set protocols ospf interface eth0 network 'point-to-point'
set protocols ospf interface eth1 network 'point-to-point'
PE2:
set interfaces loopback lo address '10.0.0.4/32'
set interfaces ethernet eth0 address '10.3.4.4/24'
set protocols ospf interface lo area '0'
set protocols ospf interface eth0 area '0'
set protocols ospf interface eth0 network 'point-to-point'
One thing you may notice is that we’re not using dummy interfaces any more. This is because FRR requires that the interface used for our Node SID is of type loopback. If you try to use a dummy interface, the commit will fail when trying to configure SR.
Let’s check OSPF:
vyos@PE1# run show ip route ospf
O 10.0.0.1/32 [110/1] via 0.0.0.0, dum0 onlink, weight 1, 1d18h26m
O>* 10.0.0.2/32 [110/65536] via 10.1.2.2, eth0, weight 1, 00:00:21
O>* 10.0.0.3/32 [110/65537] via 10.1.2.2, eth0, weight 1, 00:00:21
O>* 10.0.0.4/32 [110/65538] via 10.1.2.2, eth0, weight 1, 00:00:21
It looks good!
Let’s configure Segment Routing.
set protocols ospf parameters opaque-lsa
set protocols ospf segment-routing prefix 10.0.0.1/32 index value '1'
Just a few commands are needed to enable Segment Routing using OSPF.
Let’s look over theses a little bit.
The set protocols ospf parameters opaque-lsa command enables Opaque LSAs, which are used to carry extensible information inside of OSPF, allowing for additional services to traverse OSPF. The most common use for these are traditional RSVP signaled tunnels. Here, our SR information, including SIDs will be carried in Opaque LSAs.
The set protocols ospf segment-routing prefix 10.0.0.1/32 index value '1'command is used to create our Node SID. The index value adds the number to your SRGB values. So “index value 1” sets the SID to 16001 (16000 + 1).
NOTE: We could have defined our SRGB and SRLB here, but the defaults used are the same you’ll find on other implementations, keeping them default is best for interoperability.
- Default SR Blocks:
- SRGB – 16000-23999
- SRLB – 15000-15999
You’ll likely need to restart OSPF on all of your SR speaking devices (PE1, P1, P2, and PE2).
vyos@PE1# run restart ospf
WARNING: This is a potentially unsafe function!
You may lose the connection to the router or active configuration after
running this command. Use it at your own risk!
Continue? [y/N] y
[edit]
vyos@PE1#
Let’s see if we have all of our labels.
vyos@PE1# run show mpls table
Inbound Label Type Nexthop Outbound Label
----------------------------------------------------
15000 SR (OSPF) 10.1.2.2 implicit-null
15001 SR (OSPF) 10.1.2.2 implicit-null
16002 SR (OSPF) 10.1.2.2 implicit-null
16003 SR (OSPF) 10.1.2.2 16003
16004 SR (OSPF) 10.1.2.2 16004
Yep, we have all of our our nodes SIDs (SIDs 1600x). We also have some Adjacency SIDs (you can identify them by their blocks).
Let’s look at a packet capture for one of the Opaque LSAs

This is the LSA for 10.0.0.1/32 (Node SID 16001). You can see the ‘N’ flag I mentioned previously announcing that this is a Node SID.
We can see the same information in the LSA from the router as well.
Opaque-Type 7 (Extended Prefix Opaque LSA)
Opaque-ID 0x1
Opaque-Info: 24 octets of data
Extended Prefix TLV: Length 20
Route Type: 1
Address Family: 0x0
Flags: 0x40
Address: 10.0.0.1/32
Prefix SID Sub-TLV: Length 8
Algorithm: 0
Flags: 0x0
MT-ID:0x0
Index: 1
NOTE: 0x40 is the N flag.
NOTE: The SRBG and SRLB were announced in a separate LSA, so the router knows index 1 actually means 16001.
SR looks good, let’s add some VPNv4 and VRF config like we did in part 2 of this series (see part 2 for detailed explanation of this config).
VRF Config
set vrf name A table '101'
set vrf name A protocols bgp address-family ipv4-unicast export vpn
set vrf name A protocols bgp address-family ipv4-unicast import vpn
set vrf name A protocols bgp address-family ipv4-unicast label vpn export 'auto'
set vrf name A protocols bgp address-family ipv4-unicast rd vpn export '65000:1'
set vrf name A protocols bgp address-family ipv4-unicast route-target vpn both '65000:1'
set vrf name A protocols bgp system-as '65000'
VPNv4 Config
PE1:
set protocols bgp address-family ipv4-vpn
set protocols bgp neighbor 10.0.0.4 address-family ipv4-vpn
set protocols bgp neighbor 10.0.0.4 remote-as '65000'
set protocols bgp neighbor 10.0.0.4 update-source 'dum0'
set protocols bgp system-as '65000'
PE2:
set protocols bgp address-family ipv4-vpn
set protocols bgp neighbor 10.0.0.1 address-family ipv4-vpn
set protocols bgp neighbor 10.0.0.1 remote-as '65000'
set protocols bgp neighbor 10.0.0.1 update-source 'dum0'
set protocols bgp system-as '65000'
PE to CE Config
PE1:
set interfaces ethernet eth2 address '172.16.0.1/30'
set interfaces ethernet eth2 vrf 'A'
set vrf name A protocols bgp address-family ipv4-unicast network 172.16.0.0/30
set vrf name A protocols bgp neighbor 172.16.0.2 address-family ipv4-unicast
set vrf name A protocols bgp neighbor 172.16.0.2 remote-as '65001'
PE2:
set interfaces ethernet eth2 address '172.16.0.5/30'
set interfaces ethernet eth2 vrf 'A'
set vrf name A protocols bgp address-family ipv4-unicast network 172.16.0.4/30
set vrf name A protocols bgp neighbor 172.16.0.6 address-family ipv4-unicast
set vrf name A protocols bgp neighbor 172.16.0.6 remote-as '65002'
CE1:
set interfaces dummy dum0 address '10.0.1.1/24'
set interfaces ethernet eth0 address '172.16.0.2/30'
set protocols bgp address-family ipv4-unicast redistribute connected
set protocols bgp neighbor 172.16.0.1 address-family ipv4-unicast
set protocols bgp neighbor 172.16.0.1 remote-as '65000'
set protocols bgp system-as '65001'
CE2:
set interfaces dummy dum0 address '10.0.2.1/24'
set interfaces ethernet eth0 address '172.16.0.6/30'
set protocols bgp address-family ipv4-unicast redistribute connected
set protocols bgp neighbor 172.16.0.5 address-family ipv4-unicast
set protocols bgp neighbor 172.16.0.5 remote-as '65000'
set protocols bgp system-as '65002'
Let’s make sure we have routes between the CE routers.
vyos@CE1# run show ip bgp
Network Next Hop Metric LocPrf Weight Path
*> 10.0.1.0/24 0.0.0.0 0 32768 ?
*> 10.0.2.0/24 172.16.0.1 0 0 65000 65002 ?
Yep, looks good, let’s look at the traffic through packet captures.
Traffic Analysis
Let’s initiate a single ping between CE1 and CE2.
vyos@CE1# run ping 10.0.2.1 source-address 10.0.1.1 count 1
64 bytes from 10.0.2.1: icmp_seq=1 ttl=62 time=10.9 ms
PE1 to P1

You can see just like in part 2 of this series, we have 2 labels in our packet. The top label is the transport label, and the bottom label is the VPN label.
Reminder: We can use “show ip route” to show us what labels should get imposed.
vyos@PE1# run show ip route vrf A
VRF A:
B> 10.0.2.0/24 [200/0] via 10.0.0.4 (vrf default) (recursive), label 80, weight 1, 00:22:48
* via 10.1.2.2, eth0 (vrf default), label 16004/80, weight 1, 00:22:48
Let’s look at the next hop between P1 and P2.
P1 to P2

We can see that we have pretty much the same packet as before. Now is a good time to talk a little about how SR differs a little from the Push-Swap-Pop function of MPLS we saw previously.
Push-Swap-Pop in SR
The Push-Swap-Pop process of MPLS has been altered a little with SR to allow for the Traffic Engineering function of SR. A new concept called Push-Continue-Next was introduced.
- Push:
- A label is pushed onto the packet as it enters the first LSR of the LSP.
- Continue:
- If a router receives the packet, and it does not own the label, it simply forwards the packet.
- Next:
- If a router receives the packet and is the owner of the label, the label will be popped and sent to the next label in the stack.
Since we’re not doing any traffic engineering, we don’t have additional transport labels.
Let’s get back to analysis:
P2 to PE2

This hop should receive an implicit-null advertisement from PE2 stating to pop the transport label. We can see that in the packet capture with the transport label being missing.
Let’s check out the MPLS Table for P2 to see it there as well.
vyos@P2# run show mpls table
Inbound Label Type Nexthop Outbound Label
----------------------------------------------------
16004 SR (OSPF) 10.3.4.4 implicit-null
You can see that label 16004 has an implicit-null.
Conclusion
That’s it for this one. Segment Routing’s promise is really in Traffic Engineering, but it can be interesting to see it in action.
NOTE: VyOS currently considers Segment Routing experimental. I did notice some issues that would cause frequent requirements to restart the OSPF Process, so it may not be something you want to deploy in production at this time.






Leave a Reply