Wednesday, August 1, 2018

Segment Routing and LDP islands interconnection between IOS XE and JUNOS

Intro


Given the new trends of transport protocol named Segment Routing I decide to make some labbing involving IOS XE and JUNOS devices running standard MPLS framework with LDP underlay and then to try smoothly move from LDP to SR.
Segment Routing with IPv6 extended headers currently is not feasible and easily achievable, so only choice left is MPLS dataplane, which also helps to interwork with LDP control and dataplane.

With the simple topology consisting of three IOS XE and three JUNOS routers the target is to have L3VPN connectivity from R1 Loopback1 11.11.11.11/32 to R6 lo0.1 66.66.66.66/32 in vrf CE1.

/31-s subnets for inter-links are derived from 10.0.0.0/24. ISIS configured as Level2 only. Loopbacks are added as passive interfaces. In initial configuration LDP is deployed accross the network. BGP is in AS1 with R2 and R4 as route-reflectors and other routers as clients serving VPNv4 AFI/SAFI for L3VPN connectivity.


General topology:
























In the next section LDP will be completely disabled on R1 leaving only Segment Routing MPLS. R2 and R3 will interconnect SR and LDP islands, so running both protocols and serving as mapping servers to pass R4/5/6 loopbacks to SR only network (R1).



SR/LDP topology:



























For LDP island to reach SR island SRMS (Segment Routing Mapping Server) comes into play. Manual mappings on one or more routers for redundancy (even not on the data path) gives ISIS ability to advertise prefixes with the related labels for the MPLS dataplane to do the right action of label operation (pop/push/swap). For example SRMS advertises R4 loopback with the SID label 16004 in SR domain. Checking R1 MPLS forwarding table shows prefix with the correct label to be impositioned.


R1#sh mpls forwarding-table 4.4.4.4   
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop   
Label      Label      or Tunnel Id     Switched      interface             
16004      16004      4.4.4.4/32       0             Gi1.12     10.0.0.1
    



CEF also programmed with the label push:


R1#sh ip cef 4.4.4.4/32 det
4.4.4.4/32, epoch 2
  sr local label info: global/16004 [0x1B]
  nexthop 10.0.0.1 GigabitEthernet1.12 label 16004() 







LDP only network


Standard LDP label operations for packet from R1 to R6 via R2&R4 and for packet from R6 to R1 via R5&R3.


























Let's check R1 FIB. For the R6 Lo0 outgoing label to be pushed is 24:

R1#sh mpls forwarding-table 6.6.6.6
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop  
Label      Label      or Tunnel Id     Switched      interface            
22         24         6.6.6.6/32       0             Gi1.12     10.0.0.1 



R2 will swap label 24 to label 299856:

R2#sh mpls forwarding-table 6.6.6.6
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop  
Label      Label      or Tunnel Id     Switched      interface            
24         299856     6.6.6.6/32       12588         Gi1.24     10.0.0.5 
  




Finally R4 will pop label as PHP router and forward pure data to R6:


root@R4# run show route table mpls.0 label 299856   

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

299856             *[LDP/9] 21:29:18, metric 1
                    > to 10.0.0.9 via ge-0/0/0.46, Pop   






For the connectivity between emulated CE-s let's check VPN label allocation on R1 and R6.
From R1 to R6 two labels should be pushed, bottom VPN label 299840 and top transport label 20 or 24.
From R6 to R1 bottom VPN label is 25 and top transport label is 299792 or 299824.




R1#sh ip ro vrf CE1 66.66.66.66

Routing Table: CE1
Routing entry for 66.66.66.66/32
  Known via "bgp 1", distance 200, metric 0, type internal
  Last update from 6.6.6.6 1d17h ago
  Routing Descriptor Blocks:
  * 6.6.6.6 (default), from 2.2.2.2, 1d17h ago
      Route metric is 0, traffic share count is 1
      AS Hops 0
      MPLS label: 299840



R1#sh ip cef vrf CE1 66.66.66.66
66.66.66.66/32
  nexthop 10.0.0.1 GigabitEthernet1.12 label 24(elc,) 299840()
  nexthop 10.0.0.3 GigabitEthernet1.13 label 20(elc,) 299840()





root@R6# run show route table CE1 11.11.11.11/32

CE1.inet.0: 2 destinations, 3 routes (2 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

11.11.11.11/32     *[BGP/170] 1d 17:24:55, MED 0, localpref 100, from 2.2.2.2
                      AS path: ?, validation-state: unverified
                    > to 10.0.0.8 via ge-0/0/0.46, Push 25, Push 299792(top)
                      to 10.0.0.10 via ge-0/0/0.56, Push 25, Push 299824(top)





LDP and SR hybrid network

 

Now it's time for the Segment Routing configuration on IOS XE.
First of all NODE SID-s must be assigned to routers:

R1#sh run | s segment
segment-routing mpls
 !
 connected-prefix-sid-map
  address-family ipv4
   1.1.1.1/32 absolute 16001 range 1
  exit-address-family


R2#sh run | s segment
segment-routing mpls
 !
 connected-prefix-sid-map
  address-family ipv4
   2.2.2.2/32 absolute 16002 range 1
  exit-address-family



R3#sh run | s segment
segment-routing mpls
 !
 connected-prefix-sid-map
  address-family ipv4
   3.3.3.3/32 absolute 16003 range 1
  exit-address-family 


Activation of SR gives nice log message in console :
07:50:40.312: %SR-6-SR_STATE_LOG: Segment Routing MPLS ENABLED 




SRMS (Segment Routing Mapping Server) functionality for the LDP interworking can be added to any of the router in SR domain:

segment-routing mpls
 !
 mapping-server
  !
  prefix-sid-map
   address-family ipv4
    4.4.4.4/32 absolute 16004 range 1
    5.5.5.5/32 absolute 16005 range 1
    6.6.6.6/32 absolute 16006 range 1
   exit-address-family
!
router isis 1
segment-routing prefix-sid-map advertise-local


For ISIS to start use of SR MPLS one simple line should be added:


router isis 1
 segment-routing mpls






 






















So from this point SR is active in network in parallel with LDP. Two transport protocols gives two different labels per the same FEC and both can be used without any consequences:


R1#sh mpls forwarding-table 6.6.6.6
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop   
Label      Label      or Tunnel Id     Switched      interface             
22         24         6.6.6.6/32       0             Gi1.12     10.0.0.1   
           20         6.6.6.6/32       0             Gi1.13     10.0.0.3   
16006      16006      6.6.6.6/32       0             Gi1.12     10.0.0.1   
           16006      6.6.6.6/32       0             Gi1.13     10.0.0.3   




R1#traceroute mpls ipv4 6.6.6.6/32
 

Tracing MPLS Label Switched Path to 6.6.6.6/32, timeout is 2 seconds
Type escape sequence to abort.
 

  0 10.0.0.0 MRU 1500 [Labels: 24 Exp: 0]
L 1 10.0.0.1 MRU 1500 [Labels: 299856 Exp: 0] 15 ms
L 2 4.4.4.4 MRU 1522 [Labels: implicit-null Exp: 0] 59 ms
! 3 6.6.6.6 5 ms



LDP is preffered by default. For the SR to override LDP preference next configuration can be added for the target router "sr-label-preferred" (In my virtual environment somehow it doesn't influence SR preference, so LDP was just completely disabled on R1):

 
R1#sh run | s segment
segment-routing mpls
 !
 set-attributes
  address-family ipv4
   sr-label-preferred




R1#sh isis segment-routing
 ISIS protocol is registered with MFI
 ISIS MFI Client ID:0x63
 Tag 1 - Segment-Routing:
   SR State:SR_ENABLED
   Number of SRGB:1
   SRGB Start:16000, Range:8000, srgb_handle:0x7F2D1539C7B8, srgb_state: created
   Address-family IPv4 unicast SR is configured
     Operational state:Enabled
     Receive is enabled
     Advertise local is disabled
     Explicit null is disabled
     SR label preferred is enabled




R1#trace mpls ipv4 6.6.6.6/32
Tracing MPLS Label Switched Path to 6.6.6.6/32, timeout is 2 seconds

Type escape sequence to abort.
  0 10.0.0.0 MRU 1500 [Labels: 16006 Exp: 0]
L 1 10.0.0.1 MRU 1500 [Labels: 299856 Exp: 0] 12 ms
L 2 4.4.4.4 MRU 1522 [Labels: implicit-null Exp: 0] 62 ms
! 3 6.6.6.6 3 ms




R1#trace vrf CE1 66.66.66.66 probe 1
Type escape sequence to abort.
Tracing the route to 66.66.66.66
VRF info: (vrf in name/id, vrf out name/id)
  1 10.0.0.3 [MPLS: Labels 16006/299840 Exp 0] 5 msec
  2 10.0.0.5 [MPLS: Labels 299856/299840 Exp 0] 5 msec
  3 10.0.0.11 [MPLS: Label 299840 Exp 0] 79 msec
  4 66.66.66.66 3 msec



And from R6 back to R1:

root@R6# run traceroute routing-instance CE1 11.11.11.11
 traceroute to 11.11.11.11 (11.11.11.11), 30 hops max, 40 byte packets
 1  10.0.0.10 (10.0.0.10)  4.039 ms 10.0.0.8 (10.0.0.8)  2.811 ms  2.862 ms
     MPLS Label=299792 CoS=0 TTL=1 S=0
     MPLS Label=25 CoS=0 TTL=1 S=1
 2  10.0.0.6 (10.0.0.6)  5.460 ms  6.734 ms 10.0.0.4 (10.0.0.4)  4.834 ms
     MPLS Label=16 CoS=0 TTL=1 S=0
     MPLS Label=25 CoS=0 TTL=1 S=1
 3  11.11.11.11 (11.11.11.11)  9.722 ms  7.675 ms  5.061 ms








The interesting thing worth to have attention is that FEC 1.1.1.1/32 have SR Node SID 16001 advertised by itself as well as LDP Label 16 advertised by R2 and R3 for LDP dataplane reachability. Because of this LSP from LDP island swaps label with 16 and not 16001.




R2#sh mpls forwarding-table 1.1.1.1
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop   
Label      Label      or Tunnel Id     Switched      interface             
16         Pop Label  1.1.1.1/32       106904        Gi1.12     10.0.0.0   
16001      Pop Label  1.1.1.1/32       106904        Gi1.12     10.0.0.0
   







Final SR/LDP dataplane

 

 


















So how to get from R1 Lo1 to R6 lo0.1 and vice versa. Let's check all the related tables.






R1#sh ip ro vrf CE1 66.66.66.66

Routing Table: CE1
Routing entry for 66.66.66.66/32
  Known via "bgp 1", distance 200, metric 0, type internal
  Last update from 6.6.6.6 1d21h ago
  Routing Descriptor Blocks:
  * 6.6.6.6 (default), from 2.2.2.2, 1d21h ago
      Route metric is 0, traffic share count is 1
      AS Hops 0
      MPLS label: 299840
      MPLS Flags: MPLS Required







R1#sh bgp vpnv4 unicast vrf CE1 66.66.66.66/32
BGP routing table entry for 1:1:66.66.66.66/32, version 13
Paths: (2 available, best #2, table CE1)
  Not advertised to any peer
  Local
    6.6.6.6 (metric 30) (via default) from 2.2.2.2 (2.2.2.2)
      Origin IGP, localpref 100, valid, internal, best
      Extended Community: RT:1:1
      Originator: 6.6.6.6, Cluster list: 2.2.2.2
      mpls labels in/out nolabel/299840
      rx pathid: 0, tx pathid: 0x0





R1#sh ip ro 6.6.6.6
Routing entry for 6.6.6.6/32
  Known via "isis", distance 115, metric 30, type level-2
--- output ommited ---
    10.0.0.1, from 6.6.6.6, 00:24:49 ago, via GigabitEthernet1.12, merge-labels
      Route metric is 30, traffic share count is 1
      MPLS label: 16006
      MPLS Flags: NSF





R1#sh ip cef 6.6.6.6 det
6.6.6.6/32, epoch 2, per-destination sharing
  sr local label info: global/16006 [0x3B]
  1 RR source [no flags]
  nexthop 10.0.0.1 GigabitEthernet1.12 label 16006()





Two labels has been discovered, one for VPN (299840) and one for transport (16006), so R1 is pushing both of them on top of IP packet and passes it to R2, which check FIB and swaps transport label with the other one (299856).

 
R2#sh mpls forwarding-table labels 16006
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop   
Label      Label      or Tunnel Id     Switched      interface             
16006      299856     6.6.6.6/32       28770         Gi1.24     10.0.0.5   




R4 running JUNOS inspects it's mpls.0 table and popping top label, leaving VPN label intact.


root@R4# run show route table mpls.0 label 299856

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

299856             *[LDP/9] 1d 02:37:57, metric 1
                    > to 10.0.0.9 via ge-0/0/0.46, Pop     
299856(S=0)        *[LDP/9] 1d 02:37:57, metric 1
                    > to 10.0.0.9 via ge-0/0/0.46, Pop   
  





Packet arrives to R6 with the VPN label only and after popping it pure IP packet lends in routing-instance (VRF)  CE1.




root@R6# run show route table mpls.0 label 299840

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

299840             *[VPN/170] 1d 21:37:00
                      receive table CE1.inet.0, Pop    
 





Same things happens on the way back, R6 pushes two labels, R5 swaps transport label, R3 pops it and brings packet with VPN label only to R1.



root@R6# run show route table CE1.inet.0 11.11.11.11/32

CE1.inet.0: 2 destinations, 3 routes (2 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

11.11.11.11/32     *[BGP/170] 1d 21:38:19, MED 0, localpref 100, from 2.2.2.2
                      AS path: ?, validation-state: unverified
                    > to 10.0.0.10 via ge-0/0/0.56, Push 25, Push 299824(top)





R1#sh mpls forwarding-table labels 25
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop   
Label      Label      or Tunnel Id     Switched      interface             
25         Pop Label  11.11.11.11/32[V]   \
                                       10332         aggregate/CE1 





 

Remarks




* One issue worth to be mentioned is that upon enabling SR FIB in R2 and R3 wasn't programmed sucessfully and only interface triggering with shutdown/no shutdown gives correct label operation order ("No Label" and "drop" breaks dataplane in MPLS environment):


R2#sh mpls for
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop   
Label      Label      or Tunnel Id     Switched      interface             
16004      No Label   4.4.4.4/32       0             drop      
16006      No Label   6.6.6.6/32       0             drop    



R3#sh mpls for
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop   
Label      Label      or Tunnel Id     Switched      interface             
16005      No Label   5.5.5.5/32       0             drop      
16006      No Label   6.6.6.6/32       0             drop