How MPLS labels actually work
MPLS forwards on a short label instead of an IP address. Once you know what push, swap and pop do, most of it follows.
A router doing IP forwarding looks up a destination in a routing table and finds the longest matching prefix. MPLS instead attaches a fixed-length label and forwards on that — a simple exact match rather than a longest-prefix search.
Speed was the original motivation and stopped being the interesting one years ago. What kept MPLS is everything the label makes possible: VPNs, traffic engineering, and carrying non-IP traffic across an IP core.
The three actions
- Push — impose a label. The ingress router does this.
- Swap — replace the top label with the one the next hop expects.
- Pop — remove the top label.
Labels are locally significant. Each router advertises which label it wants to receive for a destination, so the value changes at every hop and means nothing on its own. A label of 16001 on one link and 200 on the next can be the same path.
Penultimate hop popping
The router before the last one usually pops the transport label rather than swapping it. The egress then receives an unlabelled packet and does one lookup instead of two.
It works through implicit null — label 3, which never actually travels in a packet. The egress advertises it, and advertising it is the instruction to the previous hop to pop.
The alternative is explicit null, label 0 for IPv4 or 2 for IPv6. That is a real label that stays on the stack to the very end, preserving the traffic class bits for quality of service. You pay an extra lookup at the egress for it.
The two-label VPN stack
This is the part worth understanding properly. An L3VPN packet carries two labels:
- The transport label on top, which gets the packet across the core.
- The service or VPN label underneath, which tells the egress router which VRF the packet belongs to.
The core routers only ever see the transport label. They have no knowledge of the VPN at all — which is precisely what makes the design scale, because adding a customer changes nothing in the middle of the network.
Penultimate hop popping removes only the transport label. The service label survives, arrives at the egress, and picks the VRF. That is why PHP does not break VPNs, a question that comes up every time somebody meets both ideas in the same week.
Frequently asked questions
Why do MPLS labels change at every hop?
Because they are locally significant. Each router advertises the label it wants to receive for a destination, so a label value only has meaning on the link it was advertised on.
Does penultimate hop popping break MPLS VPNs?
No. Only the transport label is popped. The service label underneath survives to the egress, which uses it to choose the VRF.
What is the difference between implicit and explicit null?
Implicit null (label 3) never appears in a packet — advertising it asks the previous hop to pop. Explicit null (0 or 2) is a real label that stays on the stack so the traffic class bits reach the last hop.
Why does the core not know about the VPNs?
Because core routers only see the transport label. That is what makes the design scale — adding a customer touches the edge routers and nothing in the middle.
Open the label stack visualizer →