Theoretical foundations and architecture

LDP (Label Distribution Protocol, RFC 5036) binds IGP destination prefixes (FECs) to MPLS labels. Its operation comprises two distinct phases: Discovery and Session establishment. In the Discovery phase, routers send UDP Hello packets (destination port 646) to the All-Routers multicast group 224.0.0.2 on local interfaces. The Hello packet announces the sender's LDP Identifier (LSR-ID:Label Space, e.g., 10.255.0.1:0) and the designated Transport Address. Once mutually discovered, the routers transition to Phase Two: the router with the higher transport address opens a TCP connection to port 646 of the peer's Transport Address (by default the LSR-ID, usually Loopback0). Over this TCP connection, they negotiate parameters via Initialization messages, exchange Keepalives, and distribute Label Mappings. Crucial troubleshooting fact: if UDP hellos succeed but an ACL blocks TCP 646 or the loopback transport address is unreachable via IGP, the LDP session will remain stuck in Non-Operational state.

Two phases: UDP discovery and TCP session

LDP (RFC 5036) works in two independent phases. First the nodes find each other over UDP 646: Hello messages are sent to 224.0.0.2 (all routers on this subnet) with TTL 1, so only over directly connected links (basic/link discovery). Then one of the nodes opens TCP 646 to the neighbor's transport address, and over this TCP channel flow Initialization, KeepAlive, Address, Label Mapping, Label Withdraw/Release and Notification messages. UDP Hello is not protected in any way and knows nothing about labels, so seeing a neighbor in show mpls ldp discovery does not yet mean a working session.

LDP Identifier and transport address

The LDP Identifier is 6 bytes: a 4-byte LSR-ID (usually the Loopback0 address, 10.255.0.1 in our lab) and a 2-byte label space ID. Ethernet uses the platform-wide label space, so the identifier is always 10.255.0.1:0. The transport address is the address to which neighbors send TCP. It is carried in the optional IPv4 Transport Address TLV inside the Hello; if the TLV is absent, the Hello source address (the interface address) is used. On Cisco the transport address equals the LSR-ID by default, on Junos it is the router-id (transport-address router-id), on Huawei it is the LSR-ID (mpls lsr-id). Consequence: the LSR-ID loopback must be reachable through the IGP in both directions. A typical failure: Hellos arrive, discovery sees the neighbor, but TCP never comes up because the loopback is not advertised in OSPF/IS-IS or sits in a VRF.

Hello: parameters and timers

The Hello carries the Common Hello Parameters TLV: hold time (seconds), the T flag (targeted hello) and the R flag (a request to reply with a targeted hello). A hold value of 0 means "default" (15 s for link and 45 s for targeted per the RFC), 0xFFFF means infinity. The send interval is usually hold/3. Practical values: link hello 5 s / hold 15 s on Cisco, Junos and Huawei; targeted hello on Cisco 10 s / hold 90 s (per show mpls ldp parameters), per the RFC 15 s / 45 s. A Hello adjacency lives as long as Hellos keep arriving; the session is closed when the last adjacency with that neighbor disappears or the KeepAlive hold expires. That is why two parallel links between the same pair of LSRs produce two adjacencies and a single TCP session.

Who opens TCP: active and passive

The transport addresses of the two nodes are compared as unsigned numbers. The node with the higher address is active: it opens the TCP connection to port 646 of the passive node (the local port is ephemeral). The passive node only listens on 646. So for the pair 10.255.0.1 and 10.255.0.11 the active side is P1 (10.255.0.11) and PE1 is passive. This affects troubleshooting: ACLs or CoPP must permit TCP from an ephemeral port to 646, and in the reverse direction from 646 to the ephemeral port. If a race opens two connections, the RFC requires keeping only one.

Session initialization: states

Session states per RFC 5036: NON EXISTENT, INITIALIZED, OPENREC, OPENSENT, OPERATIONAL. The active node sends Initialization (protocol version 1, KeepAlive time, the A flag - DU or DoD, the D flag - loop detection, Path Vector Limit, Max PDU Length - 4096 by default, Receiver LDP Identifier). The passive node checks that it received its own LDP ID, replies with Initialization + KeepAlive; after KeepAlive from the active node both sides are OPERATIONAL, and the exchange of Address and Label Mapping starts immediately. With incompatible parameters a Notification is sent (for example Bad LDP Identifier or Session Rejected) and the node enables backoff: on Cisco the interval grows from 15 to 120 s (mpls ldp backoff). The negotiated KeepAlive hold defaults to 180 s (interval 60 s) on Cisco and 30 s (interval 10 s) on Junos.

Message types

Hello (0x0100) is carried over UDP. Over TCP: Initialization (0x0200), KeepAlive (0x0201), Address (0x0300) and Address Withdraw (0x0301), Label Mapping (0x0400), Label Request (0x0401), Label Withdraw (0x0402), Label Release (0x0403), Label Abort Request (0x0404), Notification (0x0001). The Address message matters: it tells all interface addresses of the neighbor so that the LSR can map the IGP next hop (a link address) to an LDP neighbor. Without the Address message bindings arrive but are not used.

Targeted LDP

A targeted Hello is sent as unicast to a specific address (not TTL 1), so the neighbor does not have to be directly connected. Uses: L2VPN pseudowires (VPWS/VPLS over LDP), LDP session protection, LDP over an RSVP-TE tunnel. The receiving side must allow targeted hellos (mpls ldp discovery targeted-hello accept on Cisco, the lo0 interface in protocols ldp and, if needed, strict-targeted-hellos on Junos; on Huawei mpls ldp remote-peer is configured on the initiator). The R flag in the Hello asks the peer to answer with a targeted hello of its own.