Segment Routing using BGP

Segment Routing using BGP is quite straightforward. It uses BGP-LU with an additional attribute called BGP Prefix-SID which signals the index value.

If you aren’t familiar with BGP-LU, it is a separate address family (ipv4 labeled-unicast) which adds a label to an ipv4 advertisement in the NLRI. When a router advertises a BGP-LU route, it adds its local label so that the peer knows what label to push onto traffic that matches that route. This is very similar to LDP advertising its local label bindings for prefixes to directly connected neighbors.

Here’s a pcap of the advertisement of the prefix SID for 2.2.2.2/32. This was advertised by R2 itself, so it advertises label 3 (implicit null) for its local label binding.

As you can see above, the label advertisement is still present in the NLRI as in regular BGP-LU. BGP for SR simply adds the path attribute called BGP Prefix-SID. This means that BGP for SR is fully interoperable with regular BGP-LU. If a BGP peer does not understand the optional, transitive PA called BGP Prefix-SID, it simply ignores this and allocates a random dynamic label. The BGP Prefix-SID value is simply a “hint” to install a local label with the value of SRGB+index. However if the peer is not running SRGB, it can simply allocate a dynamic label instead.

When using BGP for SR, you give up features such as FRR because you do not have adjacency information like you do with SR for intra-area IGP.

To use SR for BGP you must define the SRGB globally. BGP will not use the IGP’s SRGB reservation. However the global SRGB can overlap with the IGP SRGB if you are also using SR with an IGP. Defining the SRGB globally is necessary for BGP to map the label index value of a received route to a local label that will be installed in the LFIB.

To advertise an SR /32 prefix SID into BGP, you simply apply a route policy to the BGP network statement that sets the label-index value in IOS-XR. In IOS-XE you add the command segment-routing mpls under BGP, and BGP will automatically associate /32 network statements with the index value found under the connected-prefix-sid-map.

Here is the configuration for IOS-XR:

segment-routing mpls global-block 16000 23999
!
route-policy SID($SID)
 set label-index $SID
end-policy
!
router bgp 100
 address-family ipv4 unicast
  network 1.1.1.1/32 route-policy SID(1)

Here is the configuration for IOS-XE:

segment-routing mpls
 global-block 16000 23999
 !
 connected-prefix-sid-map
  address-family ipv4
   10.2.2.2/32 index 102 range 1 
  exit-address-family
 !
!
router bgp 100
 address-family ipv4
  network 10.2.2.2 mask 255.255.255.255
  segment-routing mpls

SR for BGP can be a great way for an organization to achieve an end-to-end LSP with a consistent label value across multiple IGP domains, such as in a Unified MPLS design.

Lab

In this lab we’ll configure Inter-Area L3VPN Option C using segment routing. This is slightly more complex than Unified MPLS and allows us to practice this design again.

We’ll re-use the topology from the Option C article:

SP1 runs OSPF internally, and SP2 runs ISIS internally. Router R2 at both SPs is the route-reflector for both ipv4 labeled-unicast and vpnv4 unicast. We’ll imagine that SP1 and SP2 are merging and wish to combine their SR domains into one. Both SPs will use the default SRGB. SP1 indexes will be 10X and SP2 indexes will be 20X, where X is the router number.

Here are the startup configs. Only the SR-enabled IGP is configured for each SP so far.

#SP1_XR1
hostname SP1_XR1
!
vrf CUSTOMER
 address-family ipv4 unicast
  import route-target
   100:1
   200:1
  !
  export route-target
   100:1
  !
 !
!
interface Loopback0
 ipv4 address 10.1.1.1 255.255.255.255
!
interface GigabitEthernet0/0/0/0
 vrf CUSTOMER
 ipv4 address 100.64.0.1 255.255.255.252
!
interface GigabitEthernet0/0/0/1
 ipv4 address 10.1.2.1 255.255.255.0
!
route-policy PASS
  pass
end-policy
!
router ospf 1
 segment-routing mpls
 area 0
  interface Loopback0
   prefix-sid index 101
  !
  interface GigabitEthernet0/0/0/1
   network point-to-point
  !
 !
!
router bgp 100
 bgp router-id 100.100.100.1
 address-family ipv4 unicast
 !
 address-family vpnv4 unicast
 !
 neighbor 10.2.2.2
  remote-as 100
  update-source Loopback0
  address-family vpnv4 unicast
  !
 !
 vrf CUSTOMER
  rd 100:1
  address-family ipv4 unicast
  !
  neighbor 100.64.0.2
   remote-as 65000
   address-family ipv4 unicast
    route-policy PASS in
    route-policy PASS out
   !
  !
 !
!
end

#SP1_R2
hostname SP1_R2
!
interface Loopback0
 ip address 10.2.2.2 255.255.255.255
!
interface GigabitEthernet1
 ip address 10.1.2.2 255.255.255.0
 ip ospf network point-to-point
!
interface GigabitEthernet2
 ip address 10.2.3.2 255.255.255.0
 ip ospf network point-to-point
!
segment-routing mpls
 !
 connected-prefix-sid-map
  address-family ipv4
   10.2.2.2/32 index 102 range 1 
  exit-address-family
 !
!
router ospf 1
 segment-routing mpls
 network 10.0.0.0 0.255.255.255 area 0
!
router bgp 100
 bgp router-id interface Loopback0
 bgp log-neighbor-changes
 neighbor 10.1.1.1 remote-as 100
 neighbor 10.1.1.1 update-source Loopback0
 neighbor 10.3.3.3 remote-as 100
 neighbor 10.3.3.3 update-source Loopback0
 neighbor 20.2.2.2 remote-as 200
 neighbor 20.2.2.2 ebgp-multihop 255
 neighbor 20.2.2.2 update-source Loopback0
 !
 address-family vpnv4
  neighbor 10.1.1.1 activate
  neighbor 10.1.1.1 send-community extended
  neighbor 10.1.1.1 route-reflector-client
  neighbor 10.3.3.3 activate
  neighbor 10.3.3.3 send-community extended
  neighbor 10.3.3.3 route-reflector-client
  neighbor 20.2.2.2 activate
  neighbor 20.2.2.2 send-community extended
  neighbor 20.2.2.2 next-hop-unchanged
 exit-address-family

#SP1_R3
hostname SP1_R3
!
interface Loopback0
 ip address 10.3.3.3 255.255.255.255
!
interface GigabitEthernet1
 ip address 10.2.3.3 255.255.255.0
 ip ospf network point-to-point
!
interface GigabitEthernet2
 ip address 100.1.1.1 255.255.255.252
 negotiation auto
 mpls bgp forwarding
!
segment-routing mpls
 !
 connected-prefix-sid-map
  address-family ipv4
   10.3.3.3/32 index 103 range 1 
  exit-address-family
 !
!
router ospf 1
 segment-routing mpls
 network 10.0.0.0 0.255.255.255 area 0
!
router bgp 100
 bgp router-id 100.100.100.3
 bgp log-neighbor-changes
 neighbor 10.2.2.2 remote-as 100
 neighbor 10.2.2.2 update-source Loopback0
 neighbor 10.2.2.2 send-label
 neighbor 100.1.1.2 remote-as 200
 neighbor 100.1.1.2 send-label

#SP2_XR1
hostname SP2_XR1
!
interface Loopback0
 ipv4 address 20.1.1.1 255.255.255.255
!
interface GigabitEthernet0/0/0/0
 ipv4 address 100.1.1.2 255.255.255.252
!
interface GigabitEthernet0/0/0/1
 ipv4 address 10.1.2.1 255.255.255.0
!
route-policy PASS
  pass
end-policy
!
router static
 address-family ipv4 unicast
  100.1.1.1/32 GigabitEthernet0/0/0/0
 !
!
router isis 1
 is-type level-2-only
 net 49.0001.0000.0000.0001.00
 address-family ipv4 unicast
  metric-style wide
  segment-routing mpls
 !
 interface Loopback0
  address-family ipv4 unicast
   prefix-sid index 201
  !
 !
 interface GigabitEthernet0/0/0/1
  point-to-point
  address-family ipv4 unicast
  !
 !
!
router bgp 200
 bgp router-id 200.200.200.1
 address-family ipv4 unicast
 !
 neighbor 100.1.1.1
  remote-as 100
  address-family ipv4 unicast
   route-policy PASS in
   route-policy PASS out
  !
  address-family ipv4 labeled-unicast
   route-policy PASS in
   route-policy PASS out
  !
 !
!
end

#SP2_R2
hostname SP2_R2
!
interface Loopback0
 ip address 20.2.2.2 255.255.255.255
 ip router isis 
!
interface GigabitEthernet1
 ip address 10.1.2.2 255.255.255.0
 ip router isis 
 isis network point-to-point 
!
interface GigabitEthernet2
 ip address 10.2.3.2 255.255.255.0
 ip router isis 
 isis network point-to-point 
!
segment-routing mpls
 !
 connected-prefix-sid-map
  address-family ipv4
   20.2.2.2/32 index 202 range 1 
  exit-address-family
 !
!
router isis
 net 49.0001.0000.0000.0002.00
 is-type level-2-only
 metric-style wide
 segment-routing mpls
!
router bgp 200
 bgp router-id interface Loopback0
 bgp log-neighbor-changes
 neighbor 10.2.2.2 remote-as 100
 neighbor 10.2.2.2 ebgp-multihop 255
 neighbor 10.2.2.2 update-source Loopback0
 neighbor 20.3.3.3 remote-as 200
 neighbor 20.3.3.3 update-source Loopback0
 !
 address-family vpnv4
  neighbor 10.2.2.2 activate
  neighbor 10.2.2.2 send-community extended
  neighbor 10.2.2.2 next-hop-unchanged
  neighbor 20.3.3.3 activate
  neighbor 20.3.3.3 send-community extended
  neighbor 20.3.3.3 route-reflector-client
 exit-address-family

#SP2_R3
hostname SP2_R3
!
vrf definition CUSTOMER
 rd 200:1
 route-target export 200:1
 route-target import 200:1
 route-target import 100:1
 !
 address-family ipv4
 exit-address-family
!
interface Loopback0
 ip address 20.3.3.3 255.255.255.255
 ip router isis 
!
interface GigabitEthernet1
 ip address 10.2.3.3 255.255.255.0
 ip router isis 
 isis network point-to-point 
!
interface GigabitEthernet2
 vrf forwarding CUSTOMER
 ip address 100.64.1.1 255.255.255.252
!
segment-routing mpls
 !
 connected-prefix-sid-map
  address-family ipv4
   20.3.3.3/32 index 203 range 1 
  exit-address-family
 !
!
router isis
 net 49.0001.0000.0000.0003.00
 is-type level-2-only
 metric-style wide
 segment-routing mpls
!
router bgp 200
 bgp router-id 200.200.200.3
 bgp log-neighbor-changes
 neighbor 20.2.2.2 remote-as 200
 neighbor 20.2.2.2 update-source Loopback0
 !
 address-family vpnv4
  neighbor 20.2.2.2 activate
  neighbor 20.2.2.2 send-community extended
 exit-address-family
 !
 address-family ipv4 vrf CUSTOMER
  neighbor 100.64.1.2 remote-as 65001
  neighbor 100.64.1.2 activate
 exit-address-family

Each SP needs to advertise the RR loopback and PE loopback. The RRs peer with each other to exchange vpnv4 routes, and the PEs must have reachability to each other for the end-to-end LSP. Each router will advertise its loopback into BGP-LU with the prefix-SID index set.

#SP1_XR1
segment-routing global-block 16000 23999
!
route-policy SID($SID)
 set label-index $SID
end-policy
!
router bgp 100
 address-family ipv4 unicast
  network 10.1.1.1/32 route-policy SID(101)
  allocate-label all
 neighbor 10.2.2.2
  address-family ipv4 labeled-unicast

#SP1_R2
segment-routing mpls
 global-block 16000 23999
!
router bgp 100
 address-family ipv4
  network 10.2.2.2 mask 255.255.255.255
  segment-routing mpls
  neighbor 10.1.1.1 send-label
  neighbor 10.1.1.1 route-reflector-client
  neighbor 10.3.3.3 send-label
  neighbor 10.3.3.3 route-reflector-client
  no neighbor 20.2.2.2 activate

#SP1_R3
segment-routing mpls
 global-block 16000 23999
!
router bgp 100
 neighbor 10.2.2.2 remote-as 100
 neighbor 10.2.2.2 update-source lo0
 neighbor 10.2.2.2 send-label
 neighbor 10.2.2.2 next-hop-self


#SP2_XR1
segment-routing global-block 16000 23999
!
router bgp 200
 address-family ipv4 unicast
  allocate-label all
 neighbor 20.2.2.2
  update-source lo0
  remote-as 200
  address-family ipv4 labeled-unicast
   next-hop-self

#SP2_R2
segment-routing mpls
 global-block 16000 23999
!
router bgp 200
 neighbor 20.1.1.1 remote-as 200
 neighbor 20.1.1.1 update-source Lo0
 address-family ipv4
  segment-routing mpls
  network 20.2.2.2 mask 255.255.255.255
  neighbor 20.1.1.1 send-label
  neighbor 20.1.1.1 route-reflector-client
  neighbor 20.3.3.3 send-label
  neighbor 20.3.3.3 route-reflector-client
  no neighbor 10.2.2.2 activate

#SP2_R3
segment-routing mpls
 global-block 16000 23999
!
router bgp 200
 address-family ipv4
  segment-routing mpls
  network 20.3.3.3 mask 255.255.255.255
  neighbor 20.2.2.2 send-label

We can see that we have end-to-end reachability now, with consistent label values across both domains.

CE1#traceroute 10.1.2.1 source lo0 probe 1
Type escape sequence to abort.
Tracing the route to 10.1.2.1
VRF info: (vrf in name/id, vrf out name/id)
  1 100.64.0.1 2 msec
  2 10.1.2.2 [AS 65001] [MPLS: Labels 16103/16203/17 Exp 0] 17 msec
  3 10.2.3.3 [MPLS: Labels 16203/17 Exp 0] 24 msec
  4 100.1.1.2 [MPLS: Labels 16203/17 Exp 0] 16 msec
  5 10.1.2.2 [AS 65001] [MPLS: Labels 16203/17 Exp 0] 17 msec
  6 100.64.1.1 [MPLS: Label 17 Exp 0] 24 msec
  7 100.64.1.2 158 msec

Let’s analyze this SR BGP advertisement process. We’ll use SP1_R2 specifically to look at the process in-depth.

First SP1_R2 advertises its own loopback into BGP-LU. By activiating segment-routing mpls under the ipv4 address-family, SP1_R2 will add the prefix-SID index of 102 to the BGP advertisement. The prefix-SID index is found under the segment-routing mpls connected-prefix-sid-map stanza.

#SP1_R2
segment-routing mpls
 global-block 16000 23999
 !
 connected-prefix-sid-map
  address-family ipv4
   10.2.2.2/32 index 102 range 1 
  exit-address-family
 !
!
router bgp 100
 address-family ipv4
  network 10.2.2.2 mask 255.255.255.255
  segment-routing mpls

SP1_R2#show bgp ipv4 unicast 10.2.2.2/32 
BGP routing table entry for 10.2.2.2/32, version 2
Paths: (1 available, best #1, table default)
  Advertised to update-groups:
     1          2         
  Refresh Epoch 1
  Local
    0.0.0.0 from 0.0.0.0 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, weight 32768, valid, sourced, local, best
      
      mpls labels in/out imp-null/nolabel
      rx pathid: 0, tx pathid: 0x0
      Updated on Aug 24 2022 03:01:13 UTC

SP1_R2 advertises the prefix with an implicit-null value (3). This is received at SP1_R3. SP1_R3 sees the prefix-SID index value, and because the SRGB is defined globally, the BGP process on SP1_R3 allocates label 16102. This is the same as the label it has allocated using the IGP. However, it is necessary for BGP to allocate the same label so that when SP1_R3 advertises the route to SP2_XR1, it advertises with label 16102. If the SRGB was not defined globally, the BGP process on SP1_R3 would allocate a random dynamic label in addition to the SR label that is already allocated for this prefix.

SP1_R3#show bgp ipv4 unicast 10.2.2.2/32 
BGP routing table entry for 10.2.2.2/32, version 2
Paths: (1 available, best #1, table default, RIB-failure(17))
Net local label from RIB
  Advertised to update-groups:
     3         
  Refresh Epoch 1
  Local
    10.2.2.2 (metric 2) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      sr-labelindex 0x66
      mpls labels in/out 16102/imp-null
      rx pathid: 0, tx pathid: 0x0
      Updated on Aug 24 2022 03:02:45 UTC
  • The label allocated by SP1_R3 is 16102.

SP1_R3 advertises 10.2.2.2/32 to SP2_XR1 with the label value as 16102 and the label index value as 102. The label value and label index value are completely separate. The label value is the label the local router expects to receive. It is the advertising router’s local label binding for that prefix. It does not have to be a label in the SRGB, but in this case, because SP1_R3 is running SR, it did allocate an SRGB label. The label index value is simply an attribute is that is passed along with the route. It does not change from when SP1_R2 advertised the route. If SP1_R3 allocated label 24018, this would be the label present in the NLRI, and the prefix-SID index value would still be 102.

Here is a pcap of the advertisement to SP2_XR1:

SP2_XR1 receives this route and also allocates label 16102 for 10.2.2.2/32. Because SP2_XR1 has the SRGB defined globally, it “honors” to label index present on the route and allocates its local label from its own SRGB.

RP/0/0/CPU0:SP2_XR1#show mpls forwarding 
Wed Aug 24 13:17:01.855 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
16101  16101       SR Pfx (idx 101)   Gi0/0/0/0    100.1.1.1       1688        
16102  16102       SR Pfx (idx 102)   Gi0/0/0/0    100.1.1.1       6914000     
16202  Pop         SR Pfx (idx 202)   Gi0/0/0/1    10.1.2.2        123719      
16203  16203       SR Pfx (idx 203)   Gi0/0/0/1    10.1.2.2        1430        
24000  Pop         SR Adj (idx 1)     Gi0/0/0/1    10.1.2.2        0           
24001  Pop         SR Adj (idx 3)     Gi0/0/0/1    10.1.2.2        0           
24002  Pop         100.1.1.1/32       Gi0/0/0/0    100.1.1.1       12860100

SP2_XR1 advertises this to SP2_R2 via iBGP. SP2_XR1 includes its own local label of 16102 and keeps the prefix-SID index value unchanged. SP2_XR1 also sets the next-hop to itself because the gi0/0/0/0 link is not participating or redistributed into the IGP.

SP2_R2 also allocates the same local label of 16102 for 10.2.2.2/32 by looking at the prefix-SID index value on the route. BGP is able to reserve 16102 because the SRGB is defined globally on the router.

SP2_R2#show mpls forwarding-table 
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop    
Label      Label      or Tunnel Id     Switched      interface              
16         Pop Label  10.2.3.3-A       0             Gi2        10.2.3.3    
17         Pop Label  10.1.2.1-A       0             Gi1        10.1.2.1    
16101      16101      10.1.1.1/32      0             Gi1        10.1.2.1    
16102      16102      10.2.2.2/32      0             Gi1        10.1.2.1    
16201      Pop Label  20.1.1.1/32      1856          Gi1        10.1.2.1    
16203      Pop Label  20.3.3.3/32      1486          Gi2        10.2.3.3    

A  - Adjacency SID

Conclusion

  • SR for BGP simply uses BGP-LU with an additional optional, transitive Path Attribute called BGP Prefix-SID

  • The BGP Prefix-SID is a hint for the peer to locally allocate a label of SRGB+index. For this to work, the SRGB has to be defined globally, as BGP won’t use the IGP’s SRGB block.

  • The label value in the BGP-LU NLRI is no different from how it usually works. It is the advertising router’s local label binding for that prefix.

  • To inject a BGP-LU route with the BGP Prefix-SID attribute set, you use a route-policy on the network statement on IOS-XR, and the keyword segment-routing mpls under the BGP ipv4 address-family on IOS-XE.

Last updated