Label Distribution Protocol (LDP)
Module Introduction
Before you start the hands-on part of this module, you should load the appropriate configuration and verify that the testbed is up and running by executing the corresponding robot file:
student@tour:~/trainings_resources/robot$ robot mpls_ldp/mpls_ldp_setup.robot
We use IS-IS as IGP for the examples and exercises in this module. The choice of IGP is not important for understanding and configuration of LDP. However, if you prefer to run OSPF instead, you can alternatively load the setup using the
|
In order to get a better understanding, the lab setup is shown in the picture below.

LDP Overview
The MPLS architecture does not mandate a single control plane protocol, allowing network operators the flexibility to choose one that best fits their needs.
Label Distribution Protocol (LDP), defined in RFC 5036, is the most widely used protocol for label distribution in MPLS networks. LDP is a simple signaling protocol used by Label Switching Routers to automatically establish Label Switched Paths across a network.
As its name suggests, LDP is focused solely on distributing label bindings and does not make routing decisions. Instead, it relies on an underlying IGP such as OSPF or IS-IS for routing information. Consequently, LDP-signaled LSPs always follow the IGP-determined shortest path and are constrained to a single autonomous system.
A router will only install a label binding from a peer if that peer is the next hop on the shortest IGP path to the destination. This tight coupling with the IGP means that during IGP reconvergence, traffic may be briefly blackholed or looped.
RBFS supports dual-stack operation, allowing LDP to exchange label bindings over both IPv4 and IPv6 networks.
LDP exchanges information using a common packet structure. The LDP header includes the LDP Identifier. An LDP packet can contain one or more LDP messages, each defined by a message type. Within each message, a type-length-value encoding scheme is used.
There are four categories of LDP messages:
-
Discovery messages (Hello messages) are used to announce and maintain the presence of an LSR in a network.
-
Session messages are used to establish, maintain, and terminate sessions between LDP peers. There are two main session messages, the Initialization and the Keepalive message.
-
Advertisement messages are used to create, change, and delete label mappings for FECs. This group includes the Label Mapping, Label Request, and Label Withdraw message.
-
Error Handling messages (or Notification messages) are used to provide advisory information and to signal error information.
LDP Peers
Two LSRs that use LDP to exchange label bindings are called LDP peers. An LDP peer is identified by an LDP identifier, which is a 6-octet value composed of a 4-octet router ID and a 2-octet label space ID. The label space refers to a range of labels used by the local LSR. There are two types of label spaces:
-
Per-interface label space: Used for interfaces that require interface-specific resources for label allocation, such as ATM VCIs.
-
Per-platform label space: Used when interfaces can share the same label space across the entire platform (e.g., Ethernet interfaces). The per-platform label space always sets the last octet of the LDP identifier to zero, e.g., 192.168.0.1:0.
LDP uses a discovery mechanism to find potential LDP peers. In the basic discovery mechanism, an LSR periodically sends Hello messages as UDP packets to the well-known LDP port 646, using the all routers on this subnet multicast address (224.0.0.2). The LDP Hello message includes the LDP identifier of the label space and the transport address to be used for the LDP session.
Once an LDP neighbor is discovered, an LDP session is established over TCP port 646. This involves exchanging Initialization messages to negotiate session parameters.
There is always one LDP session between two label spaces. If per-platform label space is used, there is only one LDP session between two LSRs independent of the number of links between them. However, for each link there might be a LDP Hello adjacencies. |
Configure LDP in instance default. Activate LDP on all three interfaces (hostif-0/0/1/0, hostif-0/0/2/0, and lo-0/0/0/0). Are there any LDP neighbors and LDP sessions?
Click to reveal the answer
cfg> set instance default protocol ldp router-id 192.168.0.1
cfg> set instance default protocol ldp interface hostif-0/0/1/0
cfg> set instance default protocol ldp interface hostif-0/0/2/0
cfg> set instance default protocol ldp interface lo-0/0/0/0
cfg> commit
After configuring the LDP interfaces, we can see that there are two LDP neighbors. The exchange of Hello messages have revealed the LSP ID and the transport IP address of both neighbors:
cfg> show ldp neighbor
Instance: default
Interface/Peer LDP ID Transport IP Up Since Expires
hostif-0/0/1/0 192.168.0.2:0 192.168.0.2 Tue Apr 25 11:40:25 in 12s
hostif-0/0/2/0 192.168.0.3:0 192.168.0.3 Tue Apr 25 11:40:25 in 12s
The transport IP address is used to setup the LDP session via TCP:
cfg> show ldp session
Instance: default
LDP ID Peer IP State Up/Down FECRcvd FECSent
192.168.0.2:0 192.168.0.2 Non-Existent Never - -
192.168.0.3:0 192.168.0.3 Non-Existent Never - -
Although the LDP discovery process was successful in finding LDP neighbors, the LDP session establishment failed due to missing TCP authentication which is an optional feature.
Configure for both LDP neighbors TCP session authentication with type MD5, key-id 11 and password rtbrick.
Click to reveal the answer
cfg> set instance default tcp authentication LDP
cfg> set instance default tcp authentication LDP type MD5
cfg> set instance default tcp authentication LDP key1-id 11
cfg> set instance default tcp authentication LDP key1-encrypted-text $21e4946e31b406de98b3077aef03ed5a7
cfg> set instance default protocol ldp session ipv4 192.168.0.2 authentication-id LDP
cfg> set instance default protocol ldp session ipv4 192.168.0.3 authentication-id LDP
cfg> commit
cfg> show ldp session
Instance: default
LDP ID Peer IP State Up/Down FECRcvd FECSent
192.168.0.2:0 192.168.0.2 Operational 0d:00h:01m:02s 7 9
192.168.0.3:0 192.168.0.3 Operational 0d:00h:01m:04s 7 9
In addition to the basic discovery mechanism, LDP also supports an extended discovery mechanism that enables LDP sessions between non-directly connected LSRs. In this mechanism, an LSR periodically sends LDP Targeted Hello messages to a specific unicast IP address. These Targeted Hellos are sent as UDP packets addressed to the well-known LDP discovery port.
Configure a targeted LDP session to peer 192.168.0.4 using the targeted-neighbor
keyword. Set the source address to the loopback address of R1 and re-use the authentication parameters configured in the last exercise.
Click to reveal the answer
cfg> set instance default protocol ldp targeted-neighbor ipv4 192.168.0.4 192.168.0.1
cfg> set instance default protocol ldp session ipv4 192.168.0.4 authentication-id LDP
cfg> commit
cfg> show ldp neighbor
Instance: default
Interface/Peer LDP ID Transport IP Up Since Expires
192.168.0.4 192.168.0.4:0 192.168.0.4 Thu May 15 08:40:13 in 35s
hostif-0/0/1/0 192.168.0.2:0 192.168.0.2 Thu May 15 08:35:59 in 10s
hostif-0/0/2/0 192.168.0.3:0 192.168.0.3 Thu May 15 08:35:59 in 10s
cfg> show ldp session
Instance: default
LDP ID Peer IP State Up/Down FECRcvd FECSent
192.168.0.2:0 192.168.0.2 Operational 0d:00h:04m:24s 7 10
192.168.0.3:0 192.168.0.3 Operational 0d:00h:04m:27s 7 10
192.168.0.4:0 192.168.0.4 Operational 0d:00h:00m:06s 8 10
LDP Label Exchange
LDP uses a Type Length Value (TLV) format to encode information which is carried in LDP messages, e.g., the Address List TLV that contains a list of all addresses of the LSR. These addresses are compared with the next hop addresses in the unicast routing table to select the correct LSR for packet forwarding.
cfg> show ldp address instance default ipv4
Instance: default, LDP Identifier: 192.168.0.2:0, AFI: ipv4
172.16.0.2
192.168.0.2
172.16.0.13
172.16.0.25
Instance: default, LDP Identifier: 192.168.0.3:0, AFI: ipv4
192.168.0.3
172.16.0.6
172.16.0.14
172.16.0.29
The LDP label mapping messages contain at least two TLVs, the FEC TLV and the Label TLV which result in a database that contains label bindings, i.e., a mapping between FECs and labels.

cfg> show ldp binding
Instance: default, AFI: ipv4
Prefix In Label Out Label LDP ID Status
192.168.0.1/32 - 3 - Best
20010 0 192.168.0.2:0 Non-best
20009 0 192.168.0.3:0 Non-best
20006 0 192.168.0.4:0 Non-best
192.168.0.2/32 3 20004 192.168.0.2:0 Best
20001 0 192.168.0.3:0 Non-best
20004 0 192.168.0.4:0 Non-best
192.168.0.3/32 3 20001 192.168.0.3:0 Best
20001 0 192.168.0.2:0 Non-best
20003 0 192.168.0.4:0 Non-best
192.168.0.4/32 20003 20006 192.168.0.3:0 Best
20007 0 192.168.0.2:0 Best
3 0 192.168.0.4:0 Non-best
192.168.0.5/32 20006 20005 192.168.0.2:0 Best
20007 0 192.168.0.3:0 Non-best
20002 0 192.168.0.4:0 Non-best
192.168.0.6/32 20002 20002 192.168.0.3:0 Best
20004 0 192.168.0.2:0 Non-best
20001 0 192.168.0.4:0 Non-best
Instance: default, AFI: ipv6
Prefix In Label Out Label LDP ID Status
fc00:c0a8::192:168:0:1/128 - 3 - Best
20005 0 192.168.0.4:0 Non-best
fc00:c0a8::192:168:0:2/128 3 0 192.168.0.2:0 Best
fc00:c0a8::192:168:0:3/128 3 0 192.168.0.3:0 Best
fc00:c0a8::192:168:0:4/128 3 20003 192.168.0.4:0 Best
The show ldp binding
command offers useful options such as sent
or received
to view only the label bindings that were advertised to other LDP peers or learned from LDP peers. In addition, the output can be restricted to a particular LDP peer using the ldp-id <peer>
filter.
By default, RBFS supports IPv4/IPv6 dual-stack operation. As shown in the CLI output above, label bindings for an IPv6 prefix FEC were learned. If single-stack operation is desired, you need to disable the dual-stack functionality and one of the address families.
On R1, disable IPv4/IPv6 dual-stack operation by turning off the dual-stack-interop setting in general, and specifically disabling the IPv6 address family.
Click to reveal the answer
cfg> set instance default protocol ldp dual-stack-interop disable
cfg> set instance default protocol ldp address-family ipv6 status disable
cfg> commit
By default, RBFS only advertises label binding for loopback addresses to it’s neighbors. Some LDP implementations also advertise bindings for directly connected interfaces. If you want to have he same behavior, you need to redistribute these interfaces into LDP.
Configure LDP to redistribute all directly connected interfaces. Hint, redistribution is done on a per-address family basis.
Click to reveal the answer
cfg> set instance default protocol ldp address-family ipv4 redistribute direct
cfg> commit
cfg> show ldp binding
Instance: default, AFI: ipv4
Prefix In Label Out Label LDP ID Status
172.16.0.0/30 - label:3 - Best
172.16.0.1/32 - label:3 - Best
label:20076 - 192.168.0.3:0 Non-best
label:20069 - 192.168.0.2:0 Non-best
<...>
The LDP label bindings are combined with the result of the IGP SPF calculation to create the best path to each destination:
cfg> show ldp route
Instance: default, AFI: ipv4, SAFI: labeled-unicast
Prefix/Label Advertised label Received label Next Hop Interface Metric
192.168.0.1/32 3 - - - -
192.168.0.2/32 20004 - 172.16.0.2 hostif-0/0/1/0 100
192.168.0.3/32 20001 - 172.16.0.6 hostif-0/0/2/0 100
192.168.0.4/32 20006 20067 172.16.0.2 hostif-0/0/1/0
20066 172.16.0.6 hostif-0/0/2/0 300
192.168.0.5/32 20005 20065 172.16.0.2 hostif-0/0/1/0 200
192.168.0.6/32 20002 20071 172.16.0.6 hostif-0/0/2/0 200
Instance: default, AFI: ipv6, SAFI: labeled-unicast
Prefix/Label Advertised label Received label Next Hop Interface Metric
fc00:c0a8::192:168:0:1/1283 - - - -
Instance: default, AFI: mpls, SAFI: unicast
Prefix/Label Advertised label Received label Next Hop Interface Metric
20001 - - 172.16.0.6 hostif-0/0/2/0 -
20001,bos:1 - - 172.16.0.6 hostif-0/0/2/0 -
20002 - 20071 172.16.0.6 hostif-0/0/2/0 -
20002,bos:1 - 20071 172.16.0.6 hostif-0/0/2/0 -
20004 - - 172.16.0.2 hostif-0/0/1/0 -
20004,bos:1 - - 172.16.0.2 hostif-0/0/1/0 -
20005 - 20065 172.16.0.2 hostif-0/0/1/0 -
20005,bos:1 - 20065 172.16.0.2 hostif-0/0/1/0 -
20006 - 20066 172.16.0.6 hostif-0/0/2/0
20067 172.16.0.2 hostif-0/0/1/0 -
20006,bos:1 - 20066 172.16.0.6 hostif-0/0/2/0
20067 172.16.0.2 hostif-0/0/1/0 -
The resulting routes are either of type ipv4/ipv6 labeled-unicast or mpls unicast. If the device is an ingress LER, then the labeled-unicast routes are used, i.e., an IPv4 or IPV6 FEC is associated with a LDP-established LSP. In this case the label referred to as Received label is used, because this is the one learned from the downstream neighbor. The labels shown in column Advertised label are the labels allocated by the local router and advertised to its neighbors and are for information only and not relevant during ipv4/ipv6 labeled-unicast route lookup.
If the device is a transit LSR, then the mpls unicast routes are used, i.e., the incoming labeli (see column Prefix/Label) is swapped with the corrsponding label from column Received label.
The resulting entries are used to populate the routing table:
cfg> show route ipv4 labeled-unicast source ldp
Instance: default, AFI: ipv4, SAFI: labeled-unicast
Prefix/Label Source Pref Next Hop Interface Label
192.168.0.2/32 ldp 9 172.16.0.2 hostif-0/0/1/0 -
192.168.0.3/32 ldp 9 172.16.0.6 hostif-0/0/2/0 -
192.168.0.4/32 ldp 9 172.16.0.2 hostif-0/0/1/0 20067
172.16.0.6 hostif-0/0/2/0 20066
192.168.0.5/32 ldp 9 172.16.0.2 hostif-0/0/1/0 20065
192.168.0.6/32 ldp 9 172.16.0.6 hostif-0/0/2/0
cfg> show route mpls label 20002 detail
Instance: default, AFI: mpls, SAFI: unicast
20002
Source: ldp, Preference: 9
Next Hop: 172.16.0.6
Covering prefix: 172.16.0.6/32
Next Hop type: mpls transit, Next Hop action: None
Resolved in: default-ipv4-labeled-unicast
Egress interface: hostif-0/0/2/0, NextHop MAC: 7a:00:3f:c0:00:02
MPLS-Label: 20071
LDP Settings
Loop Detection
LDP provides an optional loop detection mechanism that can be configured to help prevent routing loops. This mechanism uses two additional TLVs: the Hop Count TLV and the Path Vector TLV. The Hop Count TLV contains the number of LSRs that the message has traversed, while the Path Vector TLV includes a list of these LSRs.
When an LSR receives a Label Mapping or Label Request message from its next hop that either contains a Hop Count TLV exceeding the configured maximum value, or a Path Vector TLV that includes its own LSR ID or exceeds the maximum allowable length, it detects a potential loop. In this case, the LSR considers the message looped and discards it.
Enable LDP loop detection using the set instance default protocol ldp loop-detection
command hierarchy. Set the vector-length
to 16 and the hop-count
limit to 32.
Click to reveal the answer
cfg> set instance default protocol ldp loop-detection status enable
cfg> set instance default protocol ldp loop-detection vector-length 16
cfg> set instance default protocol ldp loop-detection hop-count 32
cfg> commit
cfg> show ldp summary
Instance: default
<...>
Capabilities:
IPv6 address family: - , Graceful restart: False
Loop detection: True
Hop count: 32, Vector length: 16
<...>
After configuring LDP loop detection on all LSRs in the network, we can reset a LDP session and inspect the Label Mapping messages:
2025-05-15T10:25:08.039487+0000 7a:fc:da:c0:00:01 > 7a:77:1f:c0:00:01, ethertype IPv4 (0x0800), length 137: (tos 0xc0, ttl 253, id 3563, offset 0, flags [none], proto TCP (6), length 123)
192.168.0.4.58342 > 192.168.0.1.646: Flags [P.], seq 78804:78867, ack 12250, win 2983, options [nop,nop,md5 shared secret not supplied with -M, can't check - 56f2ae61e34451d618c64cde81d23583], length 63
LDP, Label-Space-ID: 192.168.0.4:0, pdu-length: 59
Label Mapping Message (0x0400), length: 49, Message ID: 0x00000112, Flags: [ignore if unknown]
FEC TLV (0x0100), length: 8, Flags: [ignore and don't forward if unknown]
Prefix FEC (0x02): IPv4 prefix 192.168.0.1/32
Generic Label TLV (0x0200), length: 4, Flags: [ignore and don't forward if unknown]
Label: 20006
Hop Count TLV (0x0103), length: 1, Flags: [ignore and don't forward if unknown]
Hop Count: 4 (1)
Path Vector TLV (0x0104), length: 16, Flags: [ignore and don't forward if unknown]
Path Vector: 192.168.0.1, 192.168.0.3, 192.168.0.6, 192.168.0.4 (2)
1 | After activating the loop detection feature, the hop count TLV is added to the label binding indicating how many LSRs this binding has traversed. |
2 | The path vector TLV represents a list of all LSRs, that this label binding messages has traversed. |
IGP Synchronization
The main purpose of LDP is to establish MPLS LSPs along the shortest path to a destination, as determined by the IGP. Many MPLS services rely on the existence of an end-to-end LSP, which requires all links along the IGP shortest path from the ingress LER to the egress LER to have operational LDP sessions and to have exchanged label bindings.
If any link along this path lacks an operational LDP session, traffic may be blackholed. This is because the IGP continues to forward traffic along what it sees as the best path, even though the corresponding LSP is incomplete.
To prevent this, the IGP (such as OSPF or IS-IS) can advertise the affected link with a maximum metric, effectively removing it from the IGP’s best path calculation until LDP becomes operational. This process is known as LDP IGP synchronization.
Enable ldp-synchronization
on both core interface on router R1 in the IGP configuration.
Click to reveal the answer
cfg> set instance default protocol isis interface hostif-0/0/1/0 ldp-synchronization enable
cfg> set instance default protocol isis interface hostif-0/0/2/0 ldp-synchronization enable
cfg> set instance default protocol ldp igp-synchronization hold-timer 5
cfg> commit
Now, that we have activated LDP IGP synchronization, let’s have a quick check: From the following output, we can see that the link metric for neighbor R2 is 100.
cfg> show isis database level-2 lsp id 1921.6800.0001.00-00
<...>
IS Reachability TLVs (22):
IS neighbor: 1921.6800.0002.00 Metric: 100 (1)
IS neighbor: 1921.6800.0003.00 Metric: 100
<...>
cfg> clear ldp session instance default peer ldp-id 192.168.0.2:0
LDP session cleared for peer 192.168.0.2
cfg> show isis database level-2 lsp id 1921.6800.0001.00-00
<...>
IS Reachability TLVs (22):
IS neighbor: 1921.6800.0002.00 Metric: 16777214 (2)
IS neighbor: 1921.6800.0003.00 Metric: 100
<...>
1 | Metric to reach IS-IS neighbor R2 is 100. |
2 | IS-IS metric is increased to maximum value during LDP session outage. |
After clearing the LDP session, the metric is adjusted in IS-IS as long as the LDP session is not fully operational.
LDP Timer
Hello messages and keepalive messages are sent periodically and it is possible to adjust the corresponding intervals. In general, the default values are suitable for most networks and are designed to ensure stability and interoperability. Adjustments may be justified in special cases, e.g., if faster convergence is required.
The Hello interval and hold-time used in LDP discovery are encoded in Hello messages, so peers can adapt. The Keepalive timer is not negotiated. It is local to each LSR, and affects how quickly each side considers the TCP session dead if no keepalive or other message is received. If keepalive timer values differ, a LSR might tear down the session sooner than the LDP peer expects, leading to unexpected session resets or flapping. Thus, it is very important to keep LDP timers consistent across peers unless there is a specific need to change them.
On R1, set the LDP hello interval to 10s and the hold-time to 30s using the set instance default protocol ldp timer
command hierarchy. In addition, set the session keepalive interval to 15s and the timeout to 45s.
Click to reveal the answer
cfg> set instance default protocol ldp timer hello interval 10
cfg> set instance default protocol ldp timer hello hold-time 30
cfg> set instance default protocol ldp timer session keepalive-interval 15
cfg> set instance default protocol ldp timer session keepalive-timeout 45
cfg> commit
cfg> show ldp summary
<...>
Timers:
Adjacency:
Hello: 10s, Holdtime: 30s
Targeted adjacency:
Hello: 15s, Holdtime: 45s
Session:
Keepalive: 15s, Holdtime: 45s
<...>
Summary
This module outlined the operation and configuration of Label Distribution Protocol (LDP). You should be able to understand how LDP sessions are established and how LDP bindings are exchanged.
If you have completed the exercise, you can check the results by executing
student@tour:~/trainings_resources/robot$ robot mpls_ldp/mpls_ldp_verify.robot