Sunday, December 13, 2015

Configuring LDP - Label Distribution Protocol

In this blogtorial we will go over the basics of LDP, discuss how LDP adjacencies are formed, and also take a look at LDP packets on the wire to gain better understanding of the inner workings of LDP.

LDP stands for Label Distribution Protocol and it is used by routers to share label information about prefixes. For more information regarding LDP check out RFC 5036. At a high glance, LDP first uses UDP hello messages to discover neighbors on the shared segment and then forms a TCP peering with the LDP neighbor to share the label to prefix mapping information. We will see this in detail (packet captures) later in this blogtorial. 

Here is a simple topology to follow along.


As always let's get the interfaces configured on all routers.

 R1#  sh run int gig1.12  
 interface GigabitEthernet1.12  
  description connected to r2 from r1  
  encapsulation dot1Q 12  
  ip address 12.12.12.1 255.255.255.0
 end  

 R1#sh run int lo100  
 interface Loopback100  
  description loopback of r1  
  ip address 10.10.10.1 255.255.255.255  
 end  

 R2#sh run int gig1.12  
 interface GigabitEthernet1.12  
  description connected to r1 from r2  
  encapsulation dot1Q 12  
  ip address 12.12.12.2 255.255.255.0  
 end  

 R2#sh run int gig1.23  
 interface GigabitEthernet1.23  
  description connected to r3 from r2  
  encapsulation dot1Q 23  
  ip address 23.23.23.2 255.255.255.0  
 end  
 
 R2#sh run int lo100  
 interface Loopback100  
  ip address 10.10.10.2 255.255.255.255  
 end  

 R3#sh run int gig1.23  
 interface GigabitEthernet1.23  
  description connected to r2 from r3  
  encapsulation dot1Q 23  
  ip address 23.23.23.3 255.255.255.0  
 end  
 
 R3#sh run int gig1.34  
 interface GigabitEthernet1.34  
  description connected to r4 from r3  
  encapsulation dot1Q 34  
  ip address 34.34.34.3 255.255.255.0  
 end  
 
 R3#sh run int lo100  
 interface Loopback100  
  description loopback on r3  
  ip address 10.10.10.3 255.255.255.0  
 end  

 R4#sh run int gi1.34  
 interface GigabitEthernet1.34  
  description connected to r3 from r4  
  encapsulation dot1Q 34  
  ip address 34.34.34.4 255.255.255.0  
 end  

 R4#sh run int lo100  
 interface Loopback100  
  ip address 10.10.10.4 255.255.255.255  
 end  

At this point you should have L3 connectivity between the adjacent routers. Let's enable OSPF on all the links and advertise the loopbacks. It is important to advertise the loopbacks into OSPF because LDP uses loopbacks to do the TCP peering. If the routers cannot reach each others loopbacks then LDP adjacency will not form.

On all routers ...

 router ospf 1  
 network 0.0.0.0 255.255.255.255 area 0  

Now you should have full reachability. Let's verify.

 R1#ping 10.10.10.2 source lo100
 Type escape sequence to abort.  
 Sending 5, 100-byte ICMP Echos to 10.10.10.2, timeout is 2 seconds:  
 !!!!!  
 Success rate is 100 percent (5/5), round-trip min/avg/max = 3/4/5 ms  

 R3#ping 10.10.10.2 sou lo100  
 Type escape sequence to abort.  
 Sending 5, 100-byte ICMP Echos to 10.10.10.2, timeout is 2 seconds:  
 Packet sent with a source address of 10.10.10.3  
 !!!!!  
 Success rate is 100 percent (5/5), round-trip min/avg/max = 4/4/5 ms  

 R3#ping 10.10.10.4 sou lo100  
 Type escape sequence to abort.  
 Sending 5, 100-byte ICMP Echos to 10.10.10.4, timeout is 2 seconds:  
 Packet sent with a source address of 10.10.10.3  
 !!!!!  
 Success rate is 100 percent (5/5), round-trip min/avg/max = 3/3/5 ms  

I will do a capture on R1 as I enable LDP, so we can see the LDP process on the wire. 

 R1#conf t  
 R1(config)#int gig1.12 
!!--Enable LDP  
 R1(config-subif)#mpls ip
!!--Optionally setting the transport address that the routers use for TCP peering  
 R1(config-subif)#mpls ldp discovery transport-address 10.10.10.1  
 R1(config-subif)#end  

 R2#conf t  
 R2(config)#int gig1.12  
 R2(config-subif)#mpls ip 
!!--Optionally setting the transport address that the routers use for TCP peering 
 R2(config-subif)#mpls ldp discovery transport-address 10.10.10.2  
 R2(config-subif)#end  
 R2#conf t  
 R2(config)#int gig1.23  
 R2(config-subif)#mpls ip  
 R2(config-subif)#mpls ldp discovery transport-address 10.10.10.2  
 R2(config-subif)#end  

 R3#conf t  
 R3(config)#int gig1.23  
 R3(config-subif)#mpls ip  
 R3(config-subif)#mpls ldp discovery transport-address 10.10.10.3  
 R3(config-subif)#end  
 R3#conf t  
 R3(config)#int gig1.34  
 R3(config-subif)#mpls ip  
 R3(config-subif)#mpls ldp discovery transport-address 10.10.10.3  
 R3(config-subif)#end  
 
 R4#conf t  
 R4(config)#int gig1.34  
 R4(config-subif)#mpls ip  
 R4(config-subif)#mpls ldp discovery transport-address 10.10.10.4  
 R4(config-subif)#end  
 R4#  

As a side note, you can also enable LDP on all IGP interfaces by using "mpls ldp autoconfig" under OSPF configuration. This assigns a label for every prefix in the OSPF database and also forms LDP neighbor on the OSPF enabled interfaces. You should generally also turn on "mpls ldp sync" under OSPF configuration so if you loose LDP neighbor on an OSPF enabled interface then that interface is essentially taken out of the OSPF topology. 

After enabling LDP, R1 first sends UDP LDP hello messages so other routers on the shared segment can discover R1.


Once R2 and R1 exchange hellos, the TCP connection / LDP adjacency between the routers are formed and the labels can be exchanged.

  • Packets 4,5,7 is the TCP 3 way handshake between R1 and R2. In this PCAP, R2 is initiating the LDP adjacency.
  • Packet 8 is the LDP initialization message where various parameters are negotiated / advertised. For more information on this, please see RFC 5036
  • Packets 11 and 12 contains label to prefix mapping information. We will dig a little bit deeper into these packet in a bit.
First let's observe the LFIB which is equivalent to the CEF table and take a closer look into what these values actually means.

 R1#show mpls forwarding-table  
 Local   Outgoing  Prefix      Bytes Label  Outgoing  Next Hop  
 Label   Label   or Tunnel Id   Switched   interface  
 16     Pop Label 10.10.10.2/32  0       Gi1.12   12.12.12.2  
 17     35     10.10.10.3/32  0       Gi1.12   12.12.12.2  
 18     27     10.10.10.4/32  0       Gi1.12   12.12.12.2  
 19     Pop Label 23.23.23.0/24  0       Gi1.12   12.12.12.2  
 20     36     34.34.34.0/24  0       Gi1.12   12.12.12.2  
 21     No Label  172.20.36.0/24  0       Gi2    172.20.37.253  
  • Local label is the label assigned by the local router to a certain prefix. 
  • Outgoing label or remote label is advertised by the peer on what label to use when sending to the particular prefix. 
    • If it states "Pop Label" that means that the PEER router is directly connected and that the local router should send the packet as a native packet and not as a packet with labels. We will look at this in packet captures below.
    • If it states "No Label" that means MPLS is not running on that particular interface or there is something wrong with LDP on that interface. In this case, I do not have LDP/MPLS enabled on 172.20.37.0/24 interface. 
When I trace to 10.10.10.4 from R1 I am "pushing" label 27 on the packet because that is the label that R2 advertised for 10.10.10.4 as seen by the command 'show mpls forwarding-table' above. 
 R1#traceroute 10.10.10.4  
 Type escape sequence to abort.  
 Tracing the route to 10.10.10.4  
 VRF info: (vrf in name/id, vrf out name/id)  
  1 12.12.12.2 [MPLS: Label 27 Exp 0] 5 msec 5 msec 5 msec  
  2 23.23.23.3 [MPLS: Label 33 Exp 0] 20 msec 19 msec 21 msec  
  3 34.34.34.4 20 msec * 5 msec  

Let's now take a look at the actual packet capture when the Labels were exchanged between R1 and R2. 


There is a special type of label ... which is HEX 0x03 or implicit-null which means that the prefix is directly connected to the peer and it instructs the router that the packet should be sent as a native rather than with labels. In this case 10.10.10.2 is directly connected to R2 therefore R1 should send the packet natively. You will see these prefixes with pop label as their outgoing label on the "show mpls forwarding-table".

In R1 if you look at the 'show mpls forwarding-table' you will see that 10.10.10.2 outgoing label states 'Pop Label'.

 R1#show mpls ldp bind 10.10.10.2 32  
  lib entry: 10.10.10.2/32, rev 4  
     local binding: label: 16  
     remote binding: lsr: 10.10.10.2:0, label: imp-null  

Let's also take a look at the actual packet capture of the traceroute from R1 and see the packets on the wire. 


As the packets traverse from R1 to R4 ... here is how the labels are pushed, swapped and popped.

 R1#show mpls forwarding-table
 Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
 Label      Label      or Tunnel Id     Switched      interface
 16         Pop Label  10.10.10.2/32    0             Gi1.12     12.12.12.2
 17         35         10.10.10.3/32    0             Gi1.12     12.12.12.2
 18         27         10.10.10.4/32    0             Gi1.12     12.12.12.2 <-- PUSH label 27
 19         Pop Label  23.23.23.0/24    0             Gi1.12     12.12.12.2
 20         36         34.34.34.0/24    0             Gi1.12     12.12.12.2
 21         No Label   172.20.36.0/24   0             Gi2        172.20.37.253

 R2#show mpls forwarding-table  
 Local   Outgoing  Prefix      Bytes Label  Outgoing  Next Hop  
 Label   Label   or Tunnel Id   Switched   interface  
 18     Pop Label 10.10.10.1/32  0       Gi1.12   12.12.12.1  
 27     33     10.10.10.4/32  768      Gi1.23   23.23.23.3  <-- SWAP label 27 with 33
 35     No Label  10.10.10.3/32  0       Gi1.23   23.23.23.3  
 36     Pop Label 34.34.34.0/24  0       Gi1.23   23.23.23.3  

 R3#show mpls forwarding-table  
 Local   Outgoing  Prefix      Bytes Label  Outgoing  Next Hop  
 Label   Label   or Tunnel Id   Switched   interface  
 23     Pop Label 10.10.10.2/32  0       Gi1.23   23.23.23.2  
 30     Pop Label 12.12.12.0/24  1412     Gi1.23   23.23.23.2  
 33     Pop Label 10.10.10.4/32  1392     Gi1.34   34.34.34.4  <-- POP label 33 as the prefix is directly connected to the neighbor
 35     18     10.10.10.1/32  0       Gi1.23   23.23.23.2  

R4#show mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
51         23         10.10.10.2/32    0             Gi1.34     34.34.34.3
52         30         12.12.12.0/24    0             Gi1.34     34.34.34.3
53         35         10.10.10.1/32    0             Gi1.34     34.34.34.3
61         No Label   10.10.10.3/32    0             Gi1.34     34.34.34.3
62         Pop Label  23.23.23.0/24    0             Gi1.34     34.34.34.3


Debug and show commands to help with trouleshooting/verification ...
  • show mpls forwarding-table
  • show mpls ldp bindings
  • show mpls ldp neighbor 
Many more articles to come so ....

Please subscribe/comment/+1 if you like my posts as it keeps me motivated to write more and spread the knowledge.