Theoretical foundations and architecture
A Forwarding Equivalence Class (FEC) is the fundamental traffic aggregation unit in MPLS. A FEC represents a set of IP packets forwarded over the same path with the same forwarding treatment. In transport MPLS, every core router loopback (e.g., PE2 10.255.0.2/32) constitutes a distinct FEC. Every LSR independently allocates a Local Label from its private label space for each FEC and advertises it to peers via Label Mapping messages. Upon receipt, peers store these mappings in the LIB as Remote Labels. By resolving the IGP next hop towards the FEC, the LSR selects the matching Remote Label as its Outgoing Label and commits the entry into the hardware LFIB. This stitches together an end-to-end Label Switched Path (LSP). If an intermediate LSR fails to bind a label for that FEC, the LSP breaks, inducing blackholing.
FEC: what exactly is bound to a label
A FEC (Forwarding Equivalence Class) is a class of packets that all LSRs forward in the same way. In transport MPLS over LDP a FEC is almost always an IP prefix from the IGP: the Prefix FEC in a Label Mapping message contains the address family, the length and the prefix itself. Besides it, LDP has the Wildcard FEC (all FECs, used in Label Withdraw/Release), the Typed Wildcard (RFC 5918) and the pseudowire elements PWid FEC 128 and Generalized PWid FEC 129 for L2VPN. For a transport LSP the loopback /32 prefixes are enough: they are the BGP VPN next hops, so labels for link /30 subnets are usually not needed in the core.
Label Mapping: what is carried
A Label Mapping message (0x0400) contains the FEC TLV and the Label TLV (Generic Label, 20 bits) plus optional TLVs (Hop Count, Path Vector). The LSR picks the local label from its pool: on IOS-XE the default range starts at 16, on Huawei dynamic labels start at 1024 (16-1023 are reserved for static LSPs), on Junos dynamic LDP labels start at roughly 299776. Values 0-15 are reserved: 0 - IPv4 explicit null, 1 - router alert, 2 - IPv6 explicit null, 3 - implicit null, 7 - ELI, 13 - GAL, 14 - OAM alert. Implicit null never appears in a packet: the egress only signals label 3, and the penultimate LSR performs a pop (PHP), so the egress receives a packet with the inner content already exposed.
LIB, RIB and LFIB: three tables
- LIB (Label Information Base) stores all local bindings and all bindings received from every neighbor (liberal retention by default).
- RIB is the IGP table; for each prefix it gives the next hop (a link address) and the interface.
- LFIB is the forwarding table: incoming label -> operation (swap/pop) -> outgoing label, interface, next hop.
Algorithm: for a FEC take the IGP next hop, find the LDP neighbor that owns this address (through the Address message), and take from the LIB the binding of that neighbor. If there is no binding, the LFIB entry stays Pop/No Label. Hence the typical failures: the neighbor exists, the binding exists, but the LFIB is empty because the next hop belongs to a neighbor address that was not published in Address, or because the IGP next hop is not an LDP neighbor (a link without mpls ip).
A continuous LSP and exact FEC matching
An LSP is continuous if every LSR on the path has a binding from its IGP next hop. A single gap is enough to break the LSP. Per RFC 5036 an LSR looks up a FEC by an exact match with a RIB entry. That is why summarizing loopbacks on an ABR/ASBR breaks the LSP: the egress advertises a label for 10.255.0.2/32, but the transit nodes have only 10.255.0.0/24 in the RIB, there is no exact match, and the label is not used. The cure is not to summarize PE loopbacks or, where supported, to enable longest-match (on Junos longest-match under protocols ldp).
What No Label and Pop Label mean
For an egress FEC, Cisco show mpls forwarding-table shows the Outgoing Label Pop Label on the penultimate node: this is PHP, the LIB got the imp-null label from the egress. The value No Label means that there is no label from the IGP next hop for the prefix: the packet leaves as plain IP without a label. For ordinary IP traffic this goes unnoticed, but L3VPN traffic with a VPN label on the outside is lost at the first node without a label, because the P router does not know the customer prefixes.
Example of a continuous LSP on the lab topology
FEC 10.255.0.2/32. PE2 advertises implicit null (3) for its own loopback. P1 picks a local label (for example 18), and its LFIB reads: in 18 -> pop -> PE2. PE1 receives label 18 from P1 and picks local label 21; the PE1 LFIB: ingress, push 18 towards P1. A packet PE1 -> PE2 carries the single label 18 in the core, and arrives at PE2 without a transport label. The concrete numbers depend on the allocation order and the software version, while the structure is always the same: egress - implicit null, transit - swap or pop, ingress - push.
Controlling the set of FECs
By default IOS-XE allocates labels for all IGP prefixes, Junos only for the loopback and the prefixes allowed by egress-policy, Huawei for host routes (lsp-trigger defaults to host). Restricting by prefix-list (Cisco: mpls ldp label allocate global prefix-list; Huawei: lsp-trigger ip-prefix; Junos: egress-policy) reduces the LFIB and the label-exchange attack surface. But every BGP next hop and RR address that needs a label must stay in the list: otherwise the ingress cannot build the LSP and L3VPN traffic disappears.