Skip to main content
  1. Network Articles/
  2. MPLS Articles/

What Is LDP

Table of Contents

What Is LDP

LDP (Label Distribution Protocol, RFC 5036) distributes MPLS labels to neighbouring routers. The routes themselves come from OSPF or IS-IS; LDP carries only the mapping that says “this is the label I use for that prefix”. This article explains how LDP finds a neighbour, builds a session and advertises labels, then follows a full establishment packet by packet in an IOS XR (XRd) lab. Label operations are covered in MPLS Label Operations (push / swap / pop) and PHP.

The three stages of LDP

LDP works in three stages.

StageTransportWhat happens
DiscoveryUDP 646, sent to 224.0.0.2Hellos find neighbouring LSRs
SessionTCP 646A TCP connection is opened to the peer and parameters are agreed
AdvertisementThe same TCP connectionAddresses and label mappings are sent

Only the Hello is multicast. Once the peer is known, everything moves to a unicast TCP connection. The side with the higher transport address opens the connection; the lower one listens.

The LDP Identifier

LDP identifies a peer by its LDP Identifier, six octets written as <LSR Id>:<label space>.

The first four octets identify the router and are normally set to the same value as the router ID. The last two are the label space number, where 0 means a single label space for the whole platform. A non-zero value is used when label spaces are kept per interface.

LDP messages

RFC 5036 defines eleven messages. The Type is two octets and each message has its own number.

MessageTypeRole
Notification0x0001Reports an error or the end of a session
Hello0x0100Finds neighbours. The only message sent over UDP
Initialization0x0200Proposes the session parameters
KeepAlive0x0201Keeps the session alive
Address0x0300Announces the IP addresses the router owns
Address Withdraw0x0301Withdraws an announced address
Label Mapping0x0400Announces a prefix-to-label mapping
Label Request0x0401Requests a label (used by Downstream-on-Demand)
Label Abort Request0x0402Cancels an outstanding request
Label Withdraw0x0403Withdraws a label that was advertised
Label Release0x0404Returns a label that was received

The withdraw and release messages are used when a route disappears or a session goes down.

Address is needed because the LDP Identifier and the IP address a label is attached to are different things. The receiver uses the list learned from Address to work out which LDP peer a given next hop belongs to.

How labels are advertised

The IOS XR default is Downstream-Unsolicited: a router advertises its labels without waiting to be asked. The alternative, Downstream-on-Demand, advertises only on request and uses Label Request. The difference between the modes is covered in a separate article.

When a session comes up, the router first sends Address with its own addresses, then one Label Mapping for every prefix it holds. After that only changes are sent, and KeepAlive maintains the connection.

Discovery and Session are counted differently

Of the three stages, Discovery is per link and Session is per peer. The two do not correspond, so the numbers diverge as soon as there is more than one link.

ItemDiscoverySession
UnitOne per interfaceOne per LDP peer
Address usedThe interface IP addressThe transport address, normally a loopback
TransportUDP 646 multicastTCP 646 unicast
How the peer is chosenFound by multicastConnect to the transport address learned from Hello
RoleLearn which LSR is next doorBuild a reliable channel for carrying labels
Time before it is declared downHello hold time, 15 secondsSession hold time, 180 seconds

Connect PE1 and P1 with two links and there are two Discoveries but one Session. LDP identifies a peer by its LDP Identifier, which is a label space. When the label space is :0, one per platform, the same label is valid whichever link it arrived on, so there is no reason to split the session.

The asymmetry matters operationally. Losing one link does not bring the session down. One Discovery Source disappears and the TCP connection continues over what remains, so labels are not redistributed on every link failure. Conversely, when every link goes down the Discovery Sources reach zero and the session ends.

Lab verification

Lab setup

CE1 — PE1 — P1 — P2 — PE2 — CE2 are connected in a line. PE1 / P1 / P2 / PE2 in AS 65001 form the MPLS network, distributing routes with OSPF (area 0, network point-to-point on every link) and labels with LDP. CE3 and CE4 are customers in VRF CUST-A.

RouterRoleLo0Links
CE1Customer side (AS 65101), advertises 192.168.1.0/241.1.1.1/32Gi0/0/0/0 10.1.2.1
PE1Ingress / egress LSR (AS 65001)2.2.2.2/32Gi0/0/0/0 10.1.2.2 / Gi0/0/0/1 10.2.3.2
P1Transit LSR3.3.3.3/32Gi0/0/0/0 10.2.3.3 / Gi0/0/0/1 10.3.4.3
P2Transit LSR4.4.4.4/32Gi0/0/0/0 10.3.4.4 / Gi0/0/0/1 10.4.5.4
PE2Ingress / egress LSR (AS 65001)5.5.5.5/32Gi0/0/0/0 10.4.5.5 / Gi0/0/0/1 10.5.6.5
CE2Customer side (AS 65102), advertises 192.168.6.0/246.6.6.6/32Gi0/0/0/0 10.5.6.6
CE3Customer side in VRF CUST-A (AS 65107), advertises 192.168.7.0/247.7.7.7/32Gi0/0/0/0 10.2.7.7 (PE1 Gi0/0/0/2)
CE4Customer side in VRF CUST-A (AS 65108), advertises 192.168.8.0/248.8.8.8/32Gi0/0/0/0 10.5.8.8 (PE2 Gi0/0/0/2)

The single link PE1 - P1 is captured to follow the LDP exchange packet by packet.

Verification steps

STEPChangeWhat it shows
0Initial stateSteady-state Hellos and KeepAlives, the LDP Identifiers and the bindings
1Remove interface Gi0/0/0/1 from mpls ldp on PE1, then put it backA full establishment captured in one pcap
2Configure LDP authentication on PE1 onlyThe session cannot come up while the Hellos keep flowing
3Remove the authenticationThe state returns to that of STEP 0
4Add a second PE1 - P1 linkDiscovery grows to two while the Session stays at one

STEP 0: Initial state

The neighbour as seen from PE1. Its own LDP Identifier is 2.2.2.2:0 and the peer is 3.3.3.3:0.

STEP 0 PE1 show mpls ldp discovery
Local LDP Identifier: 2.2.2.2:0
Discovery Sources:
  Interfaces:
    GigabitEthernet0/0/0/1 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 10 14:56:38.298 (08:28:02 ago)

xmit/recv means Hellos are being sent and received. The hold time is 15 seconds; if no Hello arrives within it, the neighbour is considered lost.

The session side is TCP. show mpls ldp neighbor detail shows both ends of the connection.

STEP 0 PE1 show mpls ldp neighbor detail (excerpt)
Peer LDP Identifier: 3.3.3.3:0
  TCP connection: 3.3.3.3:63514 - 2.2.2.2:646
  Graceful Restart: No
  Session Holdtime: 180 sec
  State: Oper; Msgs sent/rcvd: 590/590; Downstream-Unsolicited
  Up time: 08:28:01
  LDP Discovery Sources:
    IPv4: (1)
      GigabitEthernet0/0/0/1
    IPv6: (0)
  Addresses bound to this peer:
    IPv4: (3)
      3.3.3.3        10.2.3.3       10.3.4.3       
    IPv6: (0)
  Peer holdtime: 180 sec; KA interval: 60 sec; Peer state: Estab

P1 connected from port 63514 and PE1 is listening on 646. The transport addresses are 3.3.3.3 and 2.2.2.2, so the higher one, P1, is the side that connects. Addresses bound to this peer is the list learned from the Address message.

The labels advertised and received appear in show mpls ldp bindings.

STEP 0 PE1 show mpls ldp bindings (first two entries)
2.2.2.2/32, rev 7
	Local binding: label: ImpNull
	Remote bindings: (1 peers)
	    Peer                Label    
	    -----------------   ---------
	    3.3.3.3:0           24002   
3.3.3.3/32, rev 11
	Local binding: label: 24000
	Remote bindings: (1 peers)
	    Peer                Label    
	    -----------------   ---------
	    3.3.3.3:0           ImpNull 

For its own Loopback0, 2.2.2.2/32, PE1 advertises ImpNull (implicit-null): it is the egress, so it asks the previous hop to remove the label.

In the capture, Hellos flow every five seconds as UDP 646 multicast and KeepAlives every sixty seconds as TCP 646 unicast.

STEP 1: Take LDP down and bring it back

interface GigabitEthernet0/0/0/1 was removed from mpls ldp on PE1 and put back 49 seconds later. The syslog holds exactly one down and one up.

STEP 1 PE1 show logging (excerpt)
RP/0/RP0/CPU0:Sep 10 23:30:49.514 UTC: mpls_ldp[1178]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 3.3.3.3:0 is DOWN (LDP IPv4 disabled on interface) 
RP/0/RP0/CPU0:Sep 10 23:31:38.596 UTC: mpls_ldp[1178]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 3.3.3.3:0 is UP (IPv4 connection) 

The capture holds the whole establishment in consecutive frames. No.39 through No.47 are one round.

STEP 1 PE1 - P1 capture (TCP and LDP, Hellos filtered out)
39	58.809799000	3.3.3.3	2.2.2.2	28509 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1
41	58.830371000	2.2.2.2	3.3.3.3	646 → 28509 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1240 WS=1
42	58.833393000	3.3.3.3	2.2.2.2	28509 → 646 [ACK] Seq=1 Ack=1 Win=16384 Len=0
43	58.834409000	3.3.3.3	2.2.2.2	Initialization Message 
44	58.939718000	2.2.2.2	3.3.3.3	Initialization Message Keep Alive Message 
45	58.943971000	3.3.3.3	2.2.2.2	Keep Alive Message 
46	59.021589000	2.2.2.2	3.3.3.3	Address Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message 
47	59.024623000	3.3.3.3	2.2.2.2	Address Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message Label Mapping Message 

The TCP three-way handshake completes, Initialization flows in both directions, KeepAlive confirms it, and Address plus Label Mapping follow. From the SYN to the label advertisement takes 0.2 seconds.

Inside the Initialization are the LDP Identifier and the session parameters.

STEP 1 No.43 Initialization (tshark -V excerpt)
Internet Protocol Version 4, Src: 3.3.3.3, Dst: 2.2.2.2
    Version: 1
    PDU Length: 68
    LSR ID: 3.3.3.3
    Label Space ID: 0
        Message Type: Initialization Message (0x200)
                Session Protocol Version: 1
                Session KeepAlive Time: 180
                Session Max PDU Length: 0
Download the pcap of the packet in the tshark output above (No.43 Initialization)

Session KeepAlive Time: 180 is the hold time being proposed. The lower of the two values is used, and a third of it, 60 seconds, becomes the KeepAlive interval.

No.46 is an Address plus eight Label Mappings inside a single TCP segment.

Download the pcap of the packet mentioned above (No.46, Address + 8 Label Mappings)

A Notification is sent when the session goes down. No.12 carried two of them.

STEP 1 No.12 Notification (tshark -V excerpt)
        Message Type: Notification Message (0x1)
                ..00 0000 0000 0000 0000 0000 0000 1001 = Status Data: Hold Timer Expired (0x9)
        Message Type: Notification Message (0x1)
                ..00 0000 0000 0000 0000 0000 0000 1010 = Status Data: Shutdown (0xA)
Download the pcap of the packet in the tshark output above (No.12 Notification)

Six messages were observed in this capture, and their Type values match the RFC 5036 definitions.

Observed messageType
Notification0x0001
Hello0x0100
Initialization0x0200
KeepAlive0x0201
Address0x0300
Label Mapping0x0400

Label Request, Label Abort Request, Label Withdraw, Label Release and Address Withdraw were not observed in this lab.

STEP 2: Configure authentication on one side only

LDP authentication was configured on PE1 only. This state shows clearly that Discovery and Session are separate stages.

STEP 2 PE1 show mpls ldp discovery
Local LDP Identifier: 2.2.2.2:0
Discovery Sources:
  Interfaces:
    GigabitEthernet0/0/0/1 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 10 23:31:38.337 (00:14:27 ago)

Hellos are not authenticated, so the state stays xmit/recv and the peer’s LDP Identifier is still visible. Even so there are no neighbours, because the TCP connection cannot be built. The capture holds nothing but retransmitted SYNs.

STEP 2 PE1 - P1 capture (TCP 646)
9	11.273014000	2.2.2.2	3.3.3.3	646 → 28509 [FIN, ACK] Seq=1 Ack=19 Win=15867 Len=0
11	11.279687000	3.3.3.3	2.2.2.2	28509 → 646 [FIN, ACK] Seq=19 Ack=2 Win=15867 Len=0
16	13.302019000	3.3.3.3	2.2.2.2	29559 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1
18	15.303119000	3.3.3.3	2.2.2.2	[TCP Retransmission] 29559 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1
21	19.303361000	3.3.3.3	2.2.2.2	[TCP Retransmission] 29559 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1
28	27.303824000	3.3.3.3	2.2.2.2	[TCP Retransmission] 29559 → 646 [SYN] Seq=0 Win=16384 Len=0 MSS=1240 WS=1

PE1 discards the SYNs it receives, and the syslog gives the reason.

STEP 2 PE1 show logging (excerpt)
RP/0/RP0/CPU0:Sep 10 23:41:19.620 UTC: mpls_ldp[1178]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 3.3.3.3:0 is DOWN (Session MD5 password changed) 
RP/0/RP0/CPU0:Sep 10 23:41:21.652 UTC: tcp[134]: %IP-TCP-3-BADAUTH : Invalid MD5 digest from 3.3.3.3:29559 to 2.2.2.2:646 for vrf:default (0x60000000) 

LDP authentication is an MD5 signature on the TCP connection, so the failure happens at the TCP stage and not a single LDP message is exchanged. Configuring authentication itself is covered in a separate article.

STEP 3: Remove the authentication

Removing the configuration brings the session back and the bindings return to eight entries, the same state as STEP 0.

STEP 4: Add a second PE1 - P1 link

PE1 Gi0/0/0/3 and P1 Gi0/0/0/2 were connected as 10.2.13.0/24 with OSPF and LDP enabled on both. The OSPF cost of the second link is 100, so forwarding still takes the first one.

PE1 now has two Discovery Sources.

STEP 4 PE1 show mpls ldp discovery
Local LDP Identifier: 2.2.2.2:0
Discovery Sources:
  Interfaces:
    GigabitEthernet0/0/0/1 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 11 02:59:52.792 (00:10:03 ago)

    GigabitEthernet0/0/0/3 : xmit/recv
      VRF: 'default' (0x60000000)
      LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
          Hold time: 15 sec (local:15 sec, peer:15 sec)
          Established: Sep 11 02:59:52.883 (00:10:03 ago)

Both point at the same peer, 3.3.3.3:0, with the same transport address. The session, meanwhile, is still a single one.

STEP 4 PE1 show mpls ldp neighbor detail (excerpt)
Peer LDP Identifier: 3.3.3.3:0
  TCP connection: 3.3.3.3:54016 - 2.2.2.2:646
  Graceful Restart: No
  Session Holdtime: 180 sec
  State: Oper; Msgs sent/rcvd: 22/21; Downstream-Unsolicited
  Up time: 00:09:50
  LDP Discovery Sources:
    IPv4: (2)
      GigabitEthernet0/0/0/1
      GigabitEthernet0/0/0/3
    IPv6: (0)
  Addresses bound to this peer:
    IPv4: (4)
      3.3.3.3        10.2.3.3       10.2.13.3      10.3.4.3       
    IPv6: (0)
  Peer holdtime: 180 sec; KA interval: 60 sec; Peer state: Estab

There is one Peer LDP Identifier and one TCP connection, and beneath them LDP Discovery Sources: IPv4: (2) lists both interfaces. Two Discoveries collapsing into one Session is readable from this single screen. Addresses bound to this peer grew from three to four because the Address message carried 10.2.13.3, the address of the second link.

Putting OSPF beside LDP makes the difference in counting clear.

ProtocolAdjacencies with P1 seen from PE1
OSPF2, one per link
LDP Discovery2, one Hello per link
LDP Session1, one per peer

Capturing both links at once separates what flows where.

LinkHello (UDP 646)Packets on TCP 646
First (10.2.3.0/24)6512
Second (10.2.13.0/24)640

Hellos flow on both links and TCP only on the first. LDP is enabled on the second link and the neighbour is visible there, but the session is already established over the first one, so it goes unused. Which link is chosen is settled when the session comes up.

Captures

The single link PE1 - P1 was captured, with no filter.

STEP 0 steady state

STEP 1 teardown and establishment

STEP 2 authentication mismatch

STEP 4 first link (10.2.3.0/24)

STEP 4 second link (10.2.13.0/24)

Verification config and show output

The following file types were collected from all eight routers at every STEP, split per router. The verification config is these ..._run.txt files (the final state is the one from the last STEP).

FileContents
..._show.txtshow version / show interface description / show route and the OSPF, LDP, MPLS forwarding and BGP set
..._log.txtshow logging limited to that STEP
..._run.txtshow running-config at that STEP (the verification config for that STEP)
..._trace.txtLDP and LSD traces on the four core routers

STEP 0: Initial state

Routershowsyslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

STEP 1: Take LDP down and bring it back

Routershowsyslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

STEP 2: Configure authentication on one side only

Routershowsyslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

STEP 3: Remove the authentication (final state)

Routershowsyslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-
STEP 4: Add a second PE1 - P1 link
Routershowsyslogrunning-configtrace
CE1showlogrun-
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun-
CE3showlogrun-
CE4showlogrun-

References

RFCTitleSummary
RFC 5036LDP SpecificationDiscovery (section 2.4), the session establishment state machine (2.5.4), port 646 for both TCP and UDP (3.10.1) and the message Type values.
RFC 3031Multiprotocol Label Switching ArchitectureWhere a label distribution protocol fits.

Book: Luc De Ghein, MPLS Fundamentals (Cisco Press, 2006), Chapter 4

Related articles