MPLS Fundamentals
Traditional IP routing makes a completely independent forwarding decision at every router a packet traverses — each hop performs a routing table lookup, selects a next-hop, and forwards the packet. This works, but it is computationally expensive, does not easily support traffic engineering, and makes it difficult to build scalable VPN services across a shared network infrastructure. Multiprotocol Label Switching (MPLS) solves all three problems by replacing per-hop IP lookups with fast label swapping: the ingress router classifies the packet once, assigns a short fixed-length label, and every subsequent router in the MPLS domain simply swaps or pops that label and forwards — no IP lookup required in the core.
The result is a forwarding plane that is faster, more scalable, and far more versatile than pure IP routing. MPLS is the foundation of modern service-provider networks and enterprise WAN designs: it enables Layer 3 VPNs (L3VPN/BGP-MPLS VPN) that carry hundreds of customer VRFs over a shared backbone, Traffic Engineering (MPLS-TE) that routes traffic along explicitly controlled paths regardless of the IGP shortest path, and QoS-aware forwarding through the EXP (experimental/TC) bits in the label header. For a conceptual overview before this lab, see MPLS Overview.
This lab covers the foundational layer that all of these advanced
services depend on: how labels are structured, how the
Label Distribution Protocol (LDP) discovers
neighbours and distributes label bindings, how the
Label Forwarding Information Base (LFIB) is built
and used to forward labelled packets, the roles of PE, P, and CE
routers in a service-provider architecture, and how to configure
and verify basic MPLS label switching on a Cisco IOS backbone using
the essential verification commands
show mpls ldp neighbor and
show mpls forwarding-table.
Before starting this lab, ensure you are comfortable with IGP routing fundamentals at OSPF Single-Area Configuration and OSPF Multi-Area Configuration — MPLS requires a working IGP in the core before LDP can distribute labels. For VRF concepts that underpin MPLS VPNs, see VRF-Lite Configuration. For BGP that carries VPN routing information over MPLS, see BGP Basics & eBGP.
1. MPLS Core Concepts
The MPLS Label
An MPLS label is a 32-bit value inserted between the Layer 2 header (Ethernet, Frame Relay, ATM) and the Layer 3 IP header. It is sometimes called the "shim header" because it shims between L2 and L3. Multiple labels can be stacked — the label stack is processed from the top (outermost) label downward.
MPLS Label Format (32 bits per label):
┌────────────────────────────┬─────┬───┬──────────┐
│ Label Value (20 bits) │ TC │ S │ TTL │
│ (0 – 1,048,575) │(3b) │(1b)│ (8 bits) │
└────────────────────────────┴─────┴───┴──────────┘
Label Value : 20-bit forwarding identifier. Values 0–15 are reserved.
Common reserved labels:
0 = IPv4 Explicit NULL (pop label, forward as IPv4)
2 = IPv6 Explicit NULL
3 = Implicit NULL (signals PHP — pop the label)
TC (3 bits) : Traffic Class — formerly called EXP (experimental).
Carries QoS/DSCP markings for MPLS-aware queuing.
S (1 bit) : Bottom-of-Stack flag. Set to 1 on the LAST (innermost)
label in the stack. Zero on all other labels.
After popping a label where S=1, the next header is IP.
TTL (8 bits): Time-to-Live — decremented at each label swap hop,
same function as IP TTL. Prevents forwarding loops.
Packet structure with one MPLS label:
┌─────────────┬──────────────────┬───────────────────────────┐
│ L2 Header │ MPLS Label(s) │ IP Header + Payload │
│ (Ethernet) │ [Label|TC|S|TTL]│ │
└─────────────┴──────────────────┴───────────────────────────┘
Packet structure with a two-label stack (e.g., MPLS VPN):
┌─────────────┬──────────────────┬──────────────────┬────────┐
│ L2 Header │ Outer Label │ Inner Label │ IP │
│ │ [transport lbl] │ [VPN lbl] S=1 │ Pkt │
└─────────────┴──────────────────┴──────────────────┴────────┘
↑ swapped by P routers ↑ used by egress PE
MPLS Forwarding Operations
| Operation | Performed By | Description | Analogy |
|---|---|---|---|
| PUSH (impose) | Ingress LSR (typically the ingress PE router) | Classify an incoming unlabelled IP packet, look up the FEC, push one or more MPLS labels onto the packet, and forward it into the MPLS domain | Adding a mailing label to a parcel at the post office entrance |
| SWAP | Transit LSR (P routers in the core) | Replace the incoming top label with a new outgoing label and forward out the correct interface. No IP lookup — label swap is the entire forwarding decision | Swapping the routing sticker at a sorting depot |
| POP (dispose) | Egress LSR or penultimate LSR (PHP) | Remove the top label from the stack. If S=1 (bottom of stack), the next header is IP and the router forwards based on the IP header. If S=0, the next label becomes the new top and is processed | Removing the routing sticker at the final sorting depot before delivery |
Forwarding Equivalence Class (FEC)
A Forwarding Equivalence Class (FEC) is a group of packets that receive identical MPLS forwarding treatment — they are all assigned the same label and follow the same Label Switched Path (LSP). In basic MPLS, each IGP prefix in the routing table corresponds to one FEC. The ingress router maps an incoming IP packet to a FEC by looking up the destination IP in the routing table, then assigns the label associated with that FEC. All packets destined for the same prefix share the same label and the same LSP through the MPLS core.
Label Switched Path (LSP)
An LSP is the end-to-end unidirectional path through the MPLS network that packets belonging to a particular FEC follow. LSPs are unidirectional — forward and reverse traffic uses separate LSPs. In LDP-based MPLS, LSPs are built hop-by-hop as each router receives label bindings from its downstream neighbours and advertises its own bindings to its upstream neighbours. The ingress router has a complete view of the LSP only in the sense that it knows the first label to push — the path is determined by the label bindings at each successive hop following the IGP's shortest path.
MPLS Tables — LIB, LFIB, and FIB
| Table | Full Name | Contents | Show Command | Used For |
|---|---|---|---|---|
| LIB | Label Information Base | All label bindings received from all LDP neighbours for all prefixes — including bindings that are not currently being used for forwarding (non-best-path neighbours) | show mpls ldp bindings |
Control-plane database. Contains every label binding received from every LDP peer. The router selects the best binding (from the next-hop peer according to the IGP) to install into the LFIB |
| LFIB | Label Forwarding Information Base | The active forwarding entries used for label-switched packet forwarding — incoming label, operation (swap/pop), outgoing label, and outgoing interface. Only best-path entries from the LIB are installed here | show mpls forwarding-table |
Data-plane forwarding table. Used by the router's hardware/software to forward labelled packets without any IP lookup. The direct equivalent of the IP routing table for labelled traffic |
| FIB | Forwarding Information Base | Derived from the IP routing table — contains IP prefixes with their next-hop and the outgoing label to push for each prefix (for unlabelled packets arriving at the ingress PE) | show ip cef / show mpls forwarding-table |
Used at the ingress LSR to classify unlabelled IP packets into FECs and push the correct label before forwarding into the MPLS domain |
Penultimate Hop Popping (PHP)
PHP is an MPLS optimisation where the penultimate (second-to-last) router in the LSP — the P router immediately before the egress PE — pops the transport label rather than the egress PE itself. This saves the egress PE from having to perform two lookups: a label lookup (LFIB) to pop the transport label and then an IP lookup (or VPN label lookup) to forward the packet. By popping the transport label one hop early, the egress PE receives an already-unlabelled IP packet (or a packet with only the VPN/inner label remaining) and performs only a single lookup. PHP is signalled by the egress PE advertising label value 3 (Implicit NULL) for its own prefixes — when the penultimate router sees label 3 as the next-hop label, it pops the top label rather than swapping it.
2. Label Distribution Protocol (LDP)
LDP Overview
LDP (RFC 5036) is the most common label distribution protocol for basic MPLS forwarding. It runs between directly connected MPLS-enabled routers and distributes label bindings for all IGP prefixes in the routing table. Each router independently generates a local label for every prefix in its routing table and advertises those bindings to all LDP neighbours — this is called Liberal Label Retention: bindings from all peers are stored in the LIB even if only the best-path peer's binding is installed in the LFIB.
LDP Session Establishment Process
Phase 1 — LDP Discovery (Hello):
─────────────────────────────────────────────────────────────
● Router sends UDP Hello messages to 224.0.0.2 (All Routers
multicast) on port 646 every 5 seconds (hello interval)
● Hello messages contain the router's LDP Router ID
(highest IP on a loopback, or highest interface IP if no loopback)
● Adjacent routers on the same subnet receive the Hello and
learn each other's LDP Router IDs → become LDP "basic discovery" peers
Phase 2 — TCP Session Setup:
─────────────────────────────────────────────────────────────
● The router with the higher LDP Router ID initiates a TCP
connection to the other router on port 646
● Both routers must be able to reach each other's LDP Router ID
(typically the loopback) — if there is no route to the peer's
LDP Router ID, the TCP session fails even if the Hellos succeeded
● TCP session establishes → LDP Initialisation messages exchanged
(protocol version, label space, keepalive timer)
Phase 3 — Label Binding Distribution:
─────────────────────────────────────────────────────────────
● After session UP, each router sends Label Mapping messages
for every prefix in its IP routing table
● Each Label Mapping message contains: prefix, local label
● Peer stores all received bindings in its LIB
● The binding from the next-hop peer (per IGP) for each prefix
is installed in the LFIB as the outgoing label
Ongoing:
─────────────────────────────────────────────────────────────
● Keepalive messages sent every 60 seconds (default hold time 180s)
● New prefixes added to the IGP trigger new Label Mapping messages
● Withdrawn prefixes trigger Label Withdraw messages
● Session failure → all bindings from that peer removed from LIB
LDP Router ID Selection
| Priority | Source | Notes |
|---|---|---|
| 1 (highest) | Manually configured: mpls ldp router-id [intf] force |
Best practice — always pin to the loopback interface to ensure stability. Without force, the change only takes effect when the current LDP session resets |
| 2 | Highest IP address on an active loopback interface | Default selection if no manual configuration. Stable as long as the loopback does not go down |
| 3 (lowest) | Highest IP address on any active non-loopback interface | Avoid — physical interface IP addresses can change and flap, causing LDP Router ID changes that reset all LDP sessions |
3. MPLS Network Roles — PE, P, and CE Routers
MPLS Service-Provider Network Architecture:
Customer A Site 1 SP MPLS Core Customer A Site 2
┌───────────┐ ┌──────────────────────────────────────┐ ┌───────────┐
│ CE-A1 │───│ PE1 ────── P1 ────── PE2 │──│ CE-A2 │
│(IOS router│ │(Gi0/0) (Gi0/1)(Gi0/0)(Gi0/1)(Gi0/0) │ │(IOS router│
│ no MPLS) │ │ │ │ no MPLS) │
└───────────┘ │ ────── P2 ────── │ └───────────┘
└──────────────────────────────────────┘
┌────────┬──────────────────────────────────────────────────────────────┐
│ Role │ Description │
├────────┼──────────────────────────────────────────────────────────────┤
│ CE │ Customer Edge router. Owned by the customer or SP. │
│ │ Connects to the PE router using standard IP routing │
│ │ (static, OSPF, EIGRP, or BGP). Has NO knowledge of MPLS — │
│ │ it sends and receives plain IP packets. Does not run LDP. │
│ │ The CE-PE link is outside the MPLS domain. │
├────────┼──────────────────────────────────────────────────────────────┤
│ PE │ Provider Edge router. The boundary between the customer │
│ │ network and the MPLS core. Runs BOTH standard IP routing │
│ │ (toward CE) and MPLS label switching (toward P routers). │
│ │ Performs PUSH on ingress (imposes labels on CE traffic) │
│ │ and POP on egress (removes labels, forwards IP to CE). │
│ │ In L3VPN, PE routers run MP-BGP to exchange VPN routes │
│ │ and maintain per-VRF routing tables. LDP runs on all │
│ │ interfaces facing the MPLS core (not the CE-facing links). │
├────────┼──────────────────────────────────────────────────────────────┤
│ P │ Provider (core) router. Fully inside the MPLS domain. │
│ │ Performs only SWAP operations — receives a labelled packet, │
│ │ swaps the top label, and forwards. Has no knowledge of │
│ │ customer VRFs, BGP VPN routes, or CE prefixes. Only │
│ │ needs to know how to swap transport labels — the IGP and │
│ │ LDP provide all necessary information. P routers have a │
│ │ significantly smaller routing table than PE routers │
│ │ (no VPN/customer routes) which is one of MPLS's key │
│ │ scalability benefits. │
└────────┴──────────────────────────────────────────────────────────────┘
Label operations across the topology for traffic from CE-A1 to CE-A2:
CE-A1 PE1 P1 PE2 CE-A2
──────────────────────────────────────────────────────────────
IP pkt → PUSH labels → SWAP top lbl → POP top lbl → IP pkt
[VPN][Trans] [Trans'] [VPN only]
↑ two-label stack ↑ PHP: P1 already
(transport + VPN) popped transport
Label Operations Summary by Router Role
| Router Role | MPLS Operation | Runs LDP? | Runs IGP? | Runs MP-BGP? | Knows Customer Routes? |
|---|---|---|---|---|---|
| CE | None — plain IP | No | Toward PE only | Optional (eBGP to PE) | Its own routes only |
| PE | PUSH (ingress) / POP (egress) | Yes (core-facing) | Yes (full IGP) | Yes (VPN route exchange) | Yes (per-VRF tables) |
| P | SWAP | Yes (all core interfaces) | Yes (full IGP) | No | No (only SP loopbacks/links) |
4. Lab Topology
CE-A1 MPLS Core CE-A2
┌──────┐ 192.168.1.0/30 ┌──────┐ 10.0.12.0/30 ┌──────┐ 192.168.2.0/30
│ │──────────────────►│ │────────────────►│ │────────────────►
│ CE1 │ .1 .2 │ PE1 │ .1 .2 │ P1 │ .1 .2
│ │ Gi0/0 Gi0/0 │ │ Gi0/1 Gi0/0 │ │ Gi0/1 Gi0/0
└──────┘ └──────┘ └──────┘
Gi0/2 .1 Gi0/2 .1
10.0.14.0/30 10.0.24.0/30
Gi0/2 .2 Gi0/2 .2
┌──────┐ ┌──────┐
│ P2 │─────────────────│ PE2 │──── CE2
│ │ 10.0.23.0/30 │ │ 192.168.3.0/30
└──────┘ .1 .2 └──────┘
Gi0/1 Gi0/0
Loopback addresses (used as LDP Router IDs and BGP update sources):
┌────────┬───────────────────┬────────────────┐
│ Router │ Loopback0 │ Role │
├────────┼───────────────────┼────────────────┤
│ PE1 │ 1.1.1.1/32 │ PE router │
│ P1 │ 2.2.2.2/32 │ P router │
│ P2 │ 3.3.3.3/32 │ P router │
│ PE2 │ 4.4.4.4/32 │ PE router │
│ CE1 │ 10.10.10.10/32 │ CE (no MPLS) │
│ CE2 │ 10.20.20.20/32 │ CE (no MPLS) │
└────────┴───────────────────┴────────────────┘
IGP: OSPF Area 0 on all SP routers (PE1, P1, P2, PE2)
OSPF redistributes all loopback and link addresses
LDP: Enabled on all core-facing interfaces (PE1-P1, PE1-P2,
P1-PE2, P2-PE2 links) and loopbacks
CE routing: Static routes on CE1/CE2 pointing to PE routers
5. Step 1 — Base IP and OSPF Configuration
MPLS requires a fully working IGP before LDP can build LSPs. Configure OSPF Area 0 on all SP routers, advertise all loopback and link addresses, and verify full IP reachability before enabling MPLS. The CE routers use only static routes — they have no OSPF or MPLS.
PE1 Base Configuration
PE1>en PE1#conf t PE1(config)#hostname PE1 ! ── Loopback (LDP Router ID) ────────────────────────────── PE1(config)#interface Loopback0 PE1(config-if)# ip address 1.1.1.1 255.255.255.255 PE1(config-if)# no shutdown PE1(config-if)#exit ! ── CE1-facing interface (NOT in OSPF, NOT MPLS enabled) ── PE1(config)#interface gi0/0 PE1(config-if)# ip address 192.168.1.2 255.255.255.252 PE1(config-if)# description To-CE1 PE1(config-if)# no shutdown PE1(config-if)#exit ! ── Core-facing interface toward P1 ────────────────────── PE1(config)#interface gi0/1 PE1(config-if)# ip address 10.0.12.1 255.255.255.252 PE1(config-if)# description To-P1 PE1(config-if)# no shutdown PE1(config-if)#exit ! ── Core-facing interface toward P2 ────────────────────── PE1(config)#interface gi0/2 PE1(config-if)# ip address 10.0.14.1 255.255.255.252 PE1(config-if)# description To-P2 PE1(config-if)# no shutdown PE1(config-if)#exit ! ── OSPF — advertise loopback and core links only ───────── ! ── CE-facing Gi0/0 is passive (not in the SP OSPF domain) ─ PE1(config)#router ospf 1 PE1(config-router)# router-id 1.1.1.1 PE1(config-router)# network 1.1.1.1 0.0.0.0 area 0 PE1(config-router)# network 10.0.12.0 0.0.0.3 area 0 PE1(config-router)# network 10.0.14.0 0.0.0.3 area 0 PE1(config-router)# passive-interface gi0/0 PE1(config-router)#exit PE1(config)#end
P1 Base Configuration
P1>en P1#conf t P1(config)#hostname P1 P1(config)#interface Loopback0 P1(config-if)# ip address 2.2.2.2 255.255.255.255 P1(config-if)# no shutdown P1(config-if)#exit P1(config)#interface gi0/0 P1(config-if)# ip address 10.0.12.2 255.255.255.252 P1(config-if)# description To-PE1 P1(config-if)# no shutdown P1(config-if)#exit P1(config)#interface gi0/1 P1(config-if)# ip address 192.168.2.1 255.255.255.252 P1(config-if)# description To-PE2 P1(config-if)# no shutdown P1(config-if)#exit P1(config)#interface gi0/2 P1(config-if)# ip address 10.0.24.1 255.255.255.252 P1(config-if)# description To-PE2-via-P2 P1(config-if)# no shutdown P1(config-if)#exit P1(config)#router ospf 1 P1(config-router)# router-id 2.2.2.2 P1(config-router)# network 2.2.2.2 0.0.0.0 area 0 P1(config-router)# network 10.0.12.0 0.0.0.3 area 0 P1(config-router)# network 192.168.2.0 0.0.0.3 area 0 P1(config-router)# network 10.0.24.0 0.0.0.3 area 0 P1(config-router)#exit P1(config)#end
PE2 Base Configuration
PE2>en PE2#conf t PE2(config)#hostname PE2 PE2(config)#interface Loopback0 PE2(config-if)# ip address 4.4.4.4 255.255.255.255 PE2(config-if)# no shutdown PE2(config-if)#exit PE2(config)#interface gi0/0 PE2(config-if)# ip address 192.168.2.2 255.255.255.252 PE2(config-if)# description To-P1 PE2(config-if)# no shutdown PE2(config-if)#exit PE2(config)#interface gi0/1 PE2(config-if)# ip address 10.0.24.2 255.255.255.252 PE2(config-if)# description To-P2 PE2(config-if)# no shutdown PE2(config-if)#exit PE2(config)#interface gi0/2 PE2(config-if)# ip address 192.168.3.1 255.255.255.252 PE2(config-if)# description To-CE2 PE2(config-if)# no shutdown PE2(config-if)#exit PE2(config)#router ospf 1 PE2(config-router)# router-id 4.4.4.4 PE2(config-router)# network 4.4.4.4 0.0.0.0 area 0 PE2(config-router)# network 192.168.2.0 0.0.0.3 area 0 PE2(config-router)# network 10.0.24.0 0.0.0.3 area 0 PE2(config-router)# passive-interface gi0/2 PE2(config-router)#exit PE2(config)#end
Verify OSPF Before Enabling MPLS
! ── All four SP routers should see all loopbacks in OSPF ── PE1#show ip ospf neighbor Neighbor ID Pri State Dead Time Address Interface 2.2.2.2 1 FULL/BDR 00:00:34 10.0.12.2 Gi0/1 3.3.3.3 1 FULL/BDR 00:00:31 10.0.14.2 Gi0/2 PE1#show ip route ospf | include O O 2.2.2.2/32 [110/2] via 10.0.12.2, Gi0/1 O 3.3.3.3/32 [110/2] via 10.0.14.2, Gi0/2 O 4.4.4.4/32 [110/3] via 10.0.12.2, Gi0/1 O 10.0.24.0/30 [110/2] via 10.0.12.2, Gi0/1 O 192.168.2.0/30 [110/2] via 10.0.12.2, Gi0/1 O 10.0.23.0/30 [110/2] via 10.0.14.2, Gi0/2 ! ── Critical: ping PE2's loopback from PE1 ─────────────── PE1#ping 4.4.4.4 source lo0 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 4.4.4.4, timeout is 2 seconds: Packet sent with a source address of 1.1.1.1 !!!!! Success rate is 100 percent (5/5)
6. Step 2 — Enable MPLS and LDP
Enabling MPLS on IOS requires two things: a global
mpls ip command to enable label switching, and
mpls ip on each interface where you want MPLS
forwarding and LDP to run. The LDP Router ID should be manually
pinned to the stable loopback interface. The
mpls label protocol ldp command is the default on
modern IOS — it is shown here for clarity.
Enable MPLS on PE1
PE1#conf t ! ── Step 1: Set LDP Router ID to Loopback0 ─────────────── ! ── "force" resets the LDP session immediately ──────────── PE1(config)#mpls ldp router-id Loopback0 force ! ── Step 2: Set label protocol to LDP (default, explicit) ─ PE1(config)#mpls label protocol ldp ! ── Step 3: Enable MPLS on each CORE-FACING interface ───── ! ── Do NOT enable mpls ip on the CE-facing interface Gi0/0 PE1(config)#interface gi0/1 PE1(config-if)# mpls ip PE1(config-if)#exit PE1(config)#interface gi0/2 PE1(config-if)# mpls ip PE1(config-if)#exit PE1(config)#end
mpls ip command on an interface does two things
simultaneously: it enables MPLS forwarding on the interface
(the router will accept and forward labelled packets on this
interface) and it enables LDP on the interface (the router will
send LDP Hello messages and attempt to establish LDP sessions
with neighbours discovered on this interface). The CE-facing
interface (Gi0/0) must not have
mpls ip — CE routers do not run MPLS and cannot
process labelled packets. Traffic from CE1 arrives as plain IP
on Gi0/0, PE1 performs the PUSH operation and forwards the
labelled packet out Gi0/1 or Gi0/2 into the core.
Enable MPLS on P1, P2, and PE2
! ── P1: enable MPLS on all interfaces (pure core router) ── P1#conf t P1(config)#mpls ldp router-id Loopback0 force P1(config)#mpls label protocol ldp P1(config)#interface gi0/0 P1(config-if)# mpls ip P1(config-if)#exit P1(config)#interface gi0/1 P1(config-if)# mpls ip P1(config-if)#exit P1(config)#interface gi0/2 P1(config-if)# mpls ip P1(config-if)#exit P1(config)#end ! ── PE2: same as PE1 — only core-facing interfaces ──────── PE2#conf t PE2(config)#mpls ldp router-id Loopback0 force PE2(config)#mpls label protocol ldp PE2(config)#interface gi0/0 PE2(config-if)# mpls ip PE2(config-if)#exit PE2(config)#interface gi0/1 PE2(config-if)# mpls ip PE2(config-if)#exit ! ── gi0/2 faces CE2 — do NOT enable mpls ip ────────────── PE2(config)#end ! ── P2: similar to P1, enable on all core interfaces ────── P2#conf t P2(config)#mpls ldp router-id Loopback0 force P2(config)#mpls label protocol ldp P2(config)#interface gi0/0 P2(config-if)# mpls ip P2(config-if)#exit P2(config)#interface gi0/1 P2(config-if)# mpls ip P2(config-if)#exit P2(config)#end
7. Step 3 — Verify LDP Neighbour Relationships
show mpls ldp neighbor
PE1#show mpls ldp neighbor
Peer LDP Ident: 2.2.2.2:0; Local LDP Ident 1.1.1.1:0
TCP connection: 2.2.2.2.646 - 1.1.1.1.37221
State: Oper; Msgs sent/rcvd: 47/46; Downstream
Up time: 00:12:33
LDP discovery sources:
GigabitEthernet0/1, Src IP addr: 10.0.12.2
Addresses bound to peer LDP Ident:
10.0.12.2 2.2.2.2 10.0.24.1
192.168.2.1
Peer LDP Ident: 3.3.3.3:0; Local LDP Ident 1.1.1.1:0
TCP connection: 3.3.3.3.646 - 1.1.1.1.41803
State: Oper; Msgs sent/rcvd: 45/44; Downstream
Up time: 00:12:29
LDP discovery sources:
GigabitEthernet0/2, Src IP addr: 10.0.14.2
Addresses bound to peer LDP Ident:
10.0.14.2 3.3.3.3 10.0.23.1
show mpls ldp neighbor detail
PE1#show mpls ldp neighbor detail
Peer LDP Ident: 2.2.2.2:0; Local LDP Ident 1.1.1.1:0
TCP connection: 2.2.2.2.646 - 1.1.1.1.37221
Password: not required, none, in use
State: Oper; Msgs sent/rcvd: 47/46; Downstream; Last TIB rev sent 18
Up time: 00:12:33; UID: 3; Peer Id 0;
LDP discovery sources:
GigabitEthernet0/1, Src IP addr: 10.0.12.2
holdtime: 15000 ms, hello interval: 5000 ms
Addresses bound to peer LDP Ident:
10.0.12.2 2.2.2.2 10.0.24.1
192.168.2.1
Peer holdtime: 180000 ms; KA interval: 60000 ms; Peer state: estab
Capabilities Sent:
[ICCP (type 0x0405) MajVer 1 MinVer 0]
[Dynamic Announcement (0x0B)]
[mLDP Point-to-Multipoint (0x0507)]
[mLDP Multipoint-to-Multipoint (0x0508)]
Capabilities Received:
[ICCP (type 0x0405) MajVer 1 MinVer 0]
[Dynamic Announcement (0x0B)]
show mpls ldp discovery
PE1#show mpls ldp discovery
Local LDP Identifier:
1.1.1.1:0
Discovery Sources:
Interfaces:
GigabitEthernet0/1 (ldp): xmit/recv
LDP Id: 2.2.2.2:0
GigabitEthernet0/2 (ldp): xmit/recv
LDP Id: 3.3.3.3:0
show mpls ldp discovery confirms which interfaces
are sending and receiving LDP Hello messages. xmit/recv
means the interface is both sending Hellos and receiving them
from a peer — a healthy bidirectional discovery. If an interface
shows only xmit (transmitting but not receiving),
the neighbour is not responding — check whether mpls ip
is configured on the remote end's corresponding interface. See
also show interfaces to
confirm the interface is up/up before troubleshooting LDP.
8. Step 4 — Verify Label Bindings and Forwarding
show mpls ldp bindings — The Label Information Base (LIB)
PE1#show mpls ldp bindings
lib entry: 1.1.1.1/32, rev 4
local binding: label: imp-null ← PE1 advertises imp-null for itself
remote binding: lsr: 2.2.2.2:0, label: 16
remote binding: lsr: 3.3.3.3:0, label: 22
lib entry: 2.2.2.2/32, rev 6
local binding: label: 16
remote binding: lsr: 2.2.2.2:0, label: imp-null ← P1 owns 2.2.2.2
remote binding: lsr: 3.3.3.3:0, label: 20
lib entry: 3.3.3.3/32, rev 8
local binding: label: 17
remote binding: lsr: 2.2.2.2:0, label: 21
remote binding: lsr: 3.3.3.3:0, label: imp-null ← P2 owns 3.3.3.3
lib entry: 4.4.4.4/32, rev 10
local binding: label: 18
remote binding: lsr: 2.2.2.2:0, label: 17 ← P1's label for PE2
remote binding: lsr: 3.3.3.3:0, label: 23 ← P2's label for PE2
lib entry: 10.0.12.0/30, rev 12
local binding: label: imp-null
remote binding: lsr: 2.2.2.2:0, label: imp-null
lib entry: 10.0.14.0/30, rev 14
local binding: label: imp-null
remote binding: lsr: 3.3.3.3:0, label: imp-null
show mpls forwarding-table — The LFIB
PE1#show mpls forwarding-table
Local Outgoing Prefix Bytes Label Outgoing Next Hop
Label Label or VC or Tunnel Id Switched interface
16 Pop Label 2.2.2.2/32 0 Gi0/1 10.0.12.2
17 Pop Label 3.3.3.3/32 0 Gi0/2 10.0.14.2
18 17 4.4.4.4/32 24680 Gi0/1 10.0.12.2
23 4.4.4.4/32 0 Gi0/2 10.0.14.2
No Label 192.168.1.0/30 0 Gi0/0 192.168.1.1
show mpls forwarding-table — Per-Prefix Detail
! ── Query a specific prefix ───────────────────────────────
PE1#show mpls forwarding-table 4.4.4.4/32 detail
Local Outgoing Prefix Bytes Label Outgoing Next Hop
Label Label or VC or Tunnel Id Switched interface
18 17 4.4.4.4/32 24680 Gi0/1 10.0.12.2
MAC/Encaps=14/18, MRU=1496, Label Stack{17}
00001A2B3C4D00001A2B3C4E8847 00011000
No output feature configured
23 4.4.4.4/32 0 Gi0/2 10.0.14.2
MAC/Encaps=14/18, MRU=1496, Label Stack{23}
00001A2B3C5500001A2B3C568847 00017000
No output feature configured
8847 in the hex string is the Ethernet
EtherType for MPLS unicast, confirming this is correctly encoded
as an MPLS-labelled Ethernet frame.
show mpls ldp bindings — Verify a Specific Prefix
! ── Check bindings for PE2's loopback specifically ────────
PE1#show mpls ldp bindings 4.4.4.4 32
lib entry: 4.4.4.4/32, rev 10
local binding: label: 18
remote binding: lsr: 2.2.2.2:0, label: 17
remote binding: lsr: 3.3.3.3:0, label: 23
! ── Verify from P1's perspective (label swap) ─────────────
P1#show mpls forwarding-table 4.4.4.4/32
Local Outgoing Prefix Bytes Label Outgoing Next Hop
Label Label or VC or Tunnel Id Switched interface
17 Pop Label 4.4.4.4/32 24680 Gi0/1 192.168.2.2
! ── P1 swaps incoming label 17 to "Pop Label" ─────────────
! ── This means P1 is the PENULTIMATE hop for PE2's loopback
! ── P1 received imp-null from PE2 for 4.4.4.4/32, so P1 pops
! ── PE2 receives unlabelled IP packet for 4.4.4.4/32 ───────
! ── Full LSP trace from PE1 to PE2's loopback: ────────────
! ── PE1: local=18, outgoing=17 via Gi0/1 (SWAP 18→17 to P1)
! ── P1: local=17, outgoing=Pop via Gi0/1 (POP, forward IP to PE2)
! ── PE2: receives unlabelled IP, delivers to Loopback0 ─────
Trace the Complete LSP with traceroute
! ── traceroute from PE1 to PE2 loopback — shows MPLS labels ─ PE1#traceroute 4.4.4.4 source loopback0 Type escape sequence to abort. Tracing the route to 4.4.4.4 VRF info: (vrf in name/id, vrf out name/id) 1 10.0.12.2 [MPLS: Label 17 Exp 0] 4 msec 4 msec 4 msec 2 192.168.2.2 4 msec 4 msec 4 msec ! ── Hop 1: P1 (10.0.12.2) — labelled packet with label 17 ── ! ── Hop 2: PE2 (192.168.2.2) — no label shown (PHP: P1 popped) ! ── Total 2 hops — LSP is working end to end ──────────────── ! ── Standard "mpls" traceroute option for more detail ────── PE1#traceroute mpls ipv4 4.4.4.4/32 source 1.1.1.1 Tracing MPLS Label Switched Path to 4.4.4.4/32, timeout is 2 seconds Codes: '!' - success, 'Q' - request not sent, '.' - timeout, 'L' - labeled output, 'B' - unlabeled output, 'D' - DS Map mismatch, 'F' - no FEC mapping, 'f' - FEC mismatch, 'M' - malformed request, 'm' - unsupported tlvs, 'N' - no rx label, 'P' - no rx intf label prot, 'p' - premature termination of LSP, 'R' - transit router, 'I' - unknown upstream index, 'X' - unknown return code, 'x' - return code 0 Type escape sequence to abort. 0 1.1.1.1 MRU 1496 [Labels: 17 Exp: 0] L 1 10.0.12.2 MRU 1496 [Labels: implicit-null Exp: 0] 4 msec 4 msec 4 msec ! 2 192.168.2.2 3 msec 3 msec 4 msec
traceroute mpls ipv4) is the
definitive LSP verification tool. The L code
at hop 1 confirms the packet traversed a labelled segment.
The ! code at hop 2 (PE2) confirms successful
delivery. The [Labels: implicit-null Exp: 0] at
P1 confirms PHP is occurring — P1 is popping the label before
forwarding to PE2. If the LSP were broken, you would see
. (timeout) or B (unlabelled
output at a router that should be label-switching) indicating
where in the path the label forwarding fails.
9. Step 5 — CE Router Configuration and End-to-End Verification
CE routers connect to PE routers using standard IP routing. They have no MPLS configuration — they are completely unaware of the MPLS core. Traffic from CE1 to CE2 enters the MPLS domain at PE1 (PUSH), is label-switched across the core by P routers (SWAP), and exits at PE2 (POP) as plain IP delivered to CE2. See Static Route Configuration for CE router routing toward the PE.
CE1 Configuration
CE1>en CE1#conf t CE1(config)#hostname CE1 CE1(config)#interface gi0/0 CE1(config-if)# ip address 192.168.1.1 255.255.255.252 CE1(config-if)# description To-PE1 CE1(config-if)# no shutdown CE1(config-if)#exit CE1(config)#interface Loopback0 CE1(config-if)# ip address 10.10.10.10 255.255.255.255 CE1(config-if)# no shutdown CE1(config-if)#exit ! ── Static default route toward PE1 ────────────────────── CE1(config)#ip route 0.0.0.0 0.0.0.0 192.168.1.2 CE1(config)#end ! ── CE1 has no mpls configuration at all ───────────────── CE1#show mpls interfaces ! ── (empty output — correct for CE router) ───────────────
Configure PE1 to Route CE1's Prefix into OSPF
! ── On PE1: configure the CE1-facing interface and ──────── ! ── redistribute or statically advertise CE1's prefix ───── ! ── Add a static route for CE1's loopback ──────────────── PE1(config)#ip route 10.10.10.10 255.255.255.255 192.168.1.1 ! ── Redistribute into OSPF so the SP core knows about it ── PE1(config)#router ospf 1 PE1(config-router)# redistribute static subnets PE1(config-router)#exit PE1(config)#end ! ── Verify CE1's prefix appears in OSPF on other SP routers P1#show ip route 10.10.10.10 O E2 10.10.10.10/32 [110/20] via 10.0.12.1, Gi0/0
Verify End-to-End Forwarding
! ── Check the forwarding table for CE1's prefix on PE2 ──── PE2#show mpls forwarding-table 10.10.10.10/32 Local Outgoing Prefix Bytes Label Outgoing Next Hop Label Label or VC or Tunnel Id Switched interface 25 16 10.10.10.10/32 0 Gi0/0 192.168.2.1 ! ── PE2 has local label 25 for CE1's prefix ─────────────── ! ── It will swap incoming label 25 to label 16 toward P1 ── ! ── which eventually reaches PE1 and then CE1 ──────────── ! ── Trace from CE2 (if configured) to CE1 loopback ──────── CE2#traceroute 10.10.10.10 source loopback0 1 192.168.3.1 2 msec ← PE2 (egress PE, plain IP) 2 192.168.2.1 [MPLS: Label 16 Exp 0] 4 msec ← P1 (MPLS core) 3 10.0.12.1 4 msec ← PE1 (ingress PE, PHP popped) 4 192.168.1.1 2 msec ← CE1 ! ── The MPLS label appears only on the core hop ────────── ! ── CE routers on both ends see no MPLS labels ───────────
10. Complete Verification Command Reference
| Command | What It Shows | Key Fields to Check |
|---|---|---|
show mpls ldp neighbor |
All established LDP sessions — peer LDP ID, TCP connection endpoints, session state, uptime, discovery interface | State: Oper = session fully up and exchanging labels. Peer LDP Ident = peer's LDP Router ID (should be the loopback). Discovery sources = interface where Hello was received |
show mpls ldp neighbor detail |
Adds hello/keepalive timers, negotiated capabilities, and session statistics to the basic neighbour output | Hello holdtime (15s default), KA interval (60s default), capabilities — mismatched timers prevent session establishment |
show mpls ldp discovery |
Interfaces sending and receiving LDP Hello messages and the LDP Router IDs discovered on each interface | xmit/recv = bidirectional — healthy. xmit only = peer not responding. No output for an interface = mpls ip not configured on that interface |
show mpls ldp bindings |
The full Label Information Base — local labels allocated for every prefix, plus all remote bindings received from all LDP peers | local binding: imp-null = this router signals PHP for this prefix (its own prefixes). remote binding: imp-null from a peer = that peer is the prefix owner (penultimate hop should pop). Numeric labels = normal swap entries |
show mpls forwarding-table |
The active Label Forwarding Information Base — all installed label forwarding entries with incoming label, outgoing operation, prefix, byte counters, exit interface, and next-hop | Pop Label = PHP occurring at this router (penultimate hop). No Label = packet exits unlabelled (egress PE toward CE). Numeric outgoing label = label swap. Bytes Label Switched counter confirms traffic is actually using the entry |
show mpls forwarding-table [prefix] detail |
Per-prefix LFIB detail including label stack, MRU, and raw L2 encoding | Label Stack{N} confirms the exact outgoing label value. MRU confirms adequate MTU for labelled frames (standard MTU minus 4 bytes per label) |
show mpls interfaces |
All interfaces with MPLS enabled — interface name, IP status, MPLS operational status, LDP status | Yes in the LDP column = LDP enabled and running on the interface. No = interface has mpls ip but LDP is not running (check if LDP is globally enabled) |
show mpls interfaces detail |
Adds MTU, label stack depth, and per-interface MPLS feature flags | MTU should accommodate at least one label (1504 bytes minimum for standard 1500-byte Ethernet — ideally 1508+ for VPN label stacks) |
show ip cef [prefix] detail |
CEF (Cisco Express Forwarding) entry for a prefix — shows the outgoing label that will be pushed for unlabelled IP packets destined for this prefix at the ingress PE | nexthop ... GiX/Y label [N] = label N will be pushed when forwarding to this prefix. Confirms the FIB-to-LFIB connection at the ingress PE |
traceroute mpls ipv4 [prefix]/[len] |
MPLS LSP traceroute — sends MPLS echo requests along the LSP to verify each hop and confirm the end-to-end LSP is intact | L = labelled output (expected at all core hops). ! = successful delivery. . = timeout (broken LSP at this hop). B = unlabelled output at a hop that should be label-switching (MPLS not enabled on that interface) |
MPLS Troubleshooting Quick Reference
| Symptom | Likely Cause | Diagnosis & Fix |
|---|---|---|
LDP session not forming (show mpls ldp neighbor empty) |
mpls ip not configured on the interface, or no route to peer's LDP Router ID (loopback) |
Verify show mpls ldp discovery — is the Hello being sent/received? Check show ip route [peer-loopback] — the LDP TCP session is established between loopback addresses. If no route to peer loopback, OSPF is not advertising it or the loopback is missing from OSPF network statements |
| LDP session stuck in non-Oper state | LDP Router ID is a physical interface IP that is flapping, or mismatched LDP parameters (transport address, hello timers) | Pin LDP Router ID with mpls ldp router-id Loopback0 force. Check show mpls ldp neighbor detail for timer mismatches. Verify both ends can reach each other's LDP transport address (TCP connection field) |
Prefix missing from show mpls forwarding-table |
Prefix not in the IP routing table, or no label binding received from the next-hop LDP peer for this prefix | Verify the prefix is in show ip route first. Then check show mpls ldp bindings [prefix] — is there a remote binding from the next-hop peer? If the LDP session is up but the binding is missing, the prefix may not be in the peer's routing table |
| MPLS traceroute shows B (unlabelled output) at a core hop | mpls ip not enabled on the outgoing interface of a P or PE router, so the packet is forwarded as plain IP rather than with a label |
On the router where B appears, run show mpls interfaces to find which interface is missing mpls ip. Add mpls ip to the interface in question |
| MTU/fragmentation issues — traffic fails for large packets only | MPLS label header adds 4 bytes per label to every packet. If the underlying link MTU is 1500 bytes and MPLS adds a 4-byte label, packets up to 1500 bytes after labelling will exceed the MTU and be fragmented or dropped | Increase interface MTU on all MPLS core links to at least 1504 bytes (one label) or 1508+ bytes (VPN label stack). Use ip mtu to set IP MTU and mpls mtu for the MPLS-specific MTU. Verify with show mpls forwarding-table [prefix] detail — the MRU field shows the maximum labelled packet size |
Key Points & Exam Tips
- MPLS labels are 32-bit shim headers inserted between L2 and L3. Each label has four fields: 20-bit label value, 3-bit TC (QoS), 1-bit S (bottom-of-stack), and 8-bit TTL. The S bit identifies the last label in the stack — after popping an S=1 label, the next header is IP. Reserved labels 0 (IPv4 Explicit NULL) and 3 (Implicit NULL / PHP signal) are critical to understand.
- The three MPLS forwarding operations: PUSH (ingress PE — impose label on unlabelled IP packet), SWAP (P routers — replace top label, no IP lookup), POP (egress PE or penultimate P router for PHP). The entire forwarding efficiency of MPLS comes from P routers performing only label swaps without any IP routing table lookups.
- LDP (RFC 5036) uses UDP multicast Hellos to discover neighbours on the same subnet (port 646, multicast 224.0.0.2), then establishes a TCP session between LDP Router IDs for label binding exchange. The TCP session is between loopback addresses — if there is no route to the peer's loopback, the TCP session fails even when the Hello is received. Always pin the LDP Router ID to the loopback with
mpls ldp router-id Loopback0 force. - The three MPLS tables: LIB (Label Information Base) — all received label bindings from all peers, shown by
show mpls ldp bindings; LFIB (Label Forwarding Information Base) — active forwarding entries for labelled packets, shown byshow mpls forwarding-table; FIB — IP forwarding table extended with outgoing labels for unlabelled ingress traffic, shown byshow ip cef. - PHP (Penultimate Hop Popping) is signalled by the egress PE advertising label value 3 (Implicit NULL) for its own prefixes. The penultimate P router sees imp-null as the outgoing label and pops instead of swapping, so the egress PE receives an already-unlabelled IP packet and needs only one forwarding lookup instead of two. In
show mpls forwarding-table, PHP shows as "Pop Label" in the outgoing label column. - PE routers sit at the boundary between the customer network and the MPLS core — they PUSH labels on ingress and POP labels on egress. They run LDP toward the core, IGP throughout the SP network, and MP-BGP for VPN route exchange. P routers are pure label-switching devices in the core — they only SWAP labels and have no knowledge of customer VRFs or routes. CE routers are outside the MPLS domain entirely — they run plain IP toward their PE with no MPLS configuration.
- The IOS command to enable MPLS is
mpls ip— applied both globally (optional in modern IOS) and on each interface that should participate in MPLS forwarding and LDP. Do not enablempls ipon CE-facing interfaces — CE routers cannot process labelled packets. OSPF (or another IGP) must be fully functional across the SP core before LDP will build LSPs — LDP builds LSPs following the IGP's shortest paths. - On the exam: know the difference between the LIB (all bindings,
show mpls ldp bindings) and the LFIB (active forwarding,show mpls forwarding-table); know that "State: Oper" inshow mpls ldp neighbormeans the session is fully up; know that "Pop Label" in the forwarding table indicates PHP; know what "imp-null" means (a router advertising it for its own prefixes, signalling the upstream peer to perform PHP); and understand why P routers do not need to carry customer/VPN routes.