What is MPLS penultimate hop popping, and how do you recognize it in the LFIB? The useful answer connects the forwarding table to the packet on the wire—not just the expansion of the abbreviation.
Short answer: PHP means that the router immediately before an LSP's egress removes the top label and forwards the packet to that egress using the forwarding action already selected for the incoming label.[1]
The LFIB, or Label Forwarding Information Base, contains the installed information used for label forwarding; Cisco's show mpls forwarding-table displays it.[4]
In a conventional MPLS L3VPN, removing the outer transport label still leaves the VPN label for the egress PE to process.[3]
PHP explained: remove the transport label, not the service
An LSP is a label-switched path, and “penultimate” means the next-to-last router on that particular path.[1] The transport label has completed its job once that router has selected the egress as the next hop, so PHP removes it before the final link.[1] The architectural benefit is avoiding an extra transport-label lookup at the egress, which can instead process the exposed inner label or native network-layer packet.[1] Do not turn that explanation into an unsupported claim that every modern router is faster with PHP; this is a forwarding behavior, not a throughput benchmark.
Popping one label does not mean removing the entire stack. If another label remains, the packet remains MPLS-labeled; if the popped label was the only one, the network-layer packet is exposed.[1] That distinction is central to understanding why PHP does not break an MPLS VPN.[3]
Implicit null: why label 3 should not appear on the wire
The implicit-null value is 3, but it is a signaling instruction rather than a label transmitted in the packet's label stack.[2] When a downstream binding specifies implicit null, the upstream router pops the label instead of swapping it to the value 3.[2] The penultimate router does not merely guess its role from the topology: RFC 3031 describes PHP as requested by the downstream egress, with the relevant capability considerations.[1]
Keep these two observations separate:
| Observation | Meaning |
|---|---|
A label binding says implicit-null |
The downstream node requests popping instead of replacement with label 3.[2] |
| The forwarding action says pop | The installed action removes the top label and uses the selected next hop.[1] |
| A capture has one fewer label on the final transport hop | Consistent with PHP; check the expected stack and forwarding state as well.[1] |
| An explicit-null label appears | This is not implicit null: IPv4 explicit null is 0 and IPv6 explicit null is 2.[2] |
For the simplest single-label IP example, explicit null retains a label on the final link for the egress to remove; implicit null removes that label one hop earlier.[2] This article's worked VPN example uses implicit null, not an explicit-null configuration.
What does the LFIB contain?
Think of an LFIB entry as incoming label → forwarding action → next hop/interface; the RFC architecture expresses the lookup through an Incoming Label Map and a Next Hop Label Forwarding Entry.[1] The action can replace the top label, pop it, or replace it and push additional labels.[1] For an initially unlabeled packet, the ingress first classifies it into a forwarding equivalence class and selects the label-imposition action; it is not looking up an incoming label that does not yet exist.[1]
Use this reading checklist when inspecting a router:
| Field to inspect | Question to answer |
|---|---|
| Local/incoming label | Which label does this router expect to receive? |
| Outgoing label or action | Will it swap, pop, or impose a further stack? |
| Prefix/FEC or service context | Which destination or service is associated with this entry? |
| Next hop and outgoing interface | Where will the packet actually go? |
| Counters, where provided | Does a controlled test appear to use this entry? |
These are a troubleshooting checklist, not a promise that every platform prints identical columns. Cisco's documented example includes local and outgoing tags, prefix, switched bytes, outgoing interface and next hop, including a Pop tag action.[4]
Packet walk: PE-A → P1 → P2 → PE-B
The following is an invented teaching example, not captured router output or an executed lab. Labels and router names are arbitrary; the leftmost label is the top of the stack. The example follows the transport-plus-VPN-label forwarding model in RFC 4364.[3]
Assume PE-B advertises a VPN route with service label 24000, P1 advertises transport label 16000 toward PE-A, P2 advertises transport label 17000 toward P1, and PE-B requests implicit null for the transport FEC.
| Link | Illustrative stack before the IP packet | Action just performed |
|---|---|---|
| PE-A → P1 | 16000 / 24000 |
PE-A imposes transport and VPN labels |
| P1 → P2 | 17000 / 24000 |
P1 swaps the outer transport label |
| P2 → PE-B | 24000 |
P2 pops only the outer transport label |
| PE-B → CE | No MPLS labels in this example | PE-B processes the VPN label and sends the IP packet toward the customer |
P2's conceptual forwarding entry is incoming 17000 → pop → PE-B. P2 does not need a customer-prefix lookup merely because it popped the transport label: it already selected the next hop from the incoming label's forwarding entry.[1]
PE-B then processes the VPN label; depending on label allocation, that label may identify forwarding information directly or select a VRF in which an IP lookup is needed.[3]
Therefore, “the VPN label is always a VRF ID” is too simplistic.[3]
Verification and troubleshooting without guessing
On a suitable Cisco IOS/IOS XE MPLS platform, start with this read-only command; availability and detailed syntax depend on the platform and software image.[4]
show mpls forwarding-table
Do not paste the example's label values into a production configuration. Use the labels actually learned and installed in your network.
- Choose the exact destination and direction. For this example, track transport toward PE-B separately from the customer VPN route.
- Find the transport forwarding entry on the proposed penultimate router. Record the local label, outgoing action, interface and next hop.
- Compare the downstream binding with the installed action. An implicit-null binding should result in a pop rather than a swap to label 3.[2]
- Check the packet at the final transport link. In this two-label VPN example, expect the VPN label to remain, not a native customer IP packet.[3]
- Verify the egress service action and return path separately. Do not use a successful PE loopback test as your only acceptance test for a customer flow.
If the action is not what you expected
- A numeric outgoing label rather than pop: inspect the selected path and downstream binding first. Do not assume every router one physical hop from a PE is necessarily performing PHP for every LSP.
- A binding exists but traffic still fails: correlate the installed LFIB entry, chosen next hop and counters; a label learned by the control plane must be installed for use in forwarding.[4]
- PHP is correct but the VPN still fails: move to the egress VPN label, VRF route and customer-facing forwarding state rather than changing PHP blindly.
- Only large packets fail: include MTU and label-stack overhead in the investigation; MPLS encapsulation affects the packet size a link must carry.[2]
These steps are an operational method, not results from a live router test.
Common interview traps
- “The penultimate router swaps to label 3.” No: implicit null causes a pop and is not carried in the packet.[2]
- “PHP removes both labels in an L3VPN.” No: removing the outer transport label leaves the VPN label in the conventional stack discussed here.[3]
- “Popping means the P router routes the customer IP packet.” Not in this example: the next hop is obtained from the forwarding action for the removed label.[1]
- “Labels are end-to-end identifiers with the same value everywhere.” MPLS label interpretation has local scope; do not expect the same transport label number on every hop.[1]
- “PHP is mandatory for every MPLS path.” The architecture explicitly recognizes cases where it is unsupported or undesirable.[1]
A 30-second interview answer
“PHP moves removal of the outer LSP label to the next-to-last router, so the egress can process the remaining label or IP packet directly.[1] Implicit null, value 3, requests that pop but is never transmitted as a packet label.[2] I verify the incoming-label entry, outgoing action and next hop in the LFIB, then check the stack on the final link.[1][4] In an MPLS L3VPN, I expect the VPN label to remain after the transport label is popped.”[3]
Related reading
- RD vs RT in MPLS L3VPN: differences and examples
- MPLS L3VPN basics: VRFs, route targets and provider transport
- MPLS L3VPN route target troubleshooting
Summary and practice question
PHP removes the top label before the egress; the LFIB tells you the installed label action and where the packet goes next.[1][4] The key VPN distinction is that transport can end while the service label still needs processing.[3]
Preparing for a network engineering interview? Sketch the four-router example, hide the table, and explain what remains after every hop. Then answer the follow-up: “Why does P2 not need the customer's route to perform PHP?”
Sources
- [1] https://www.rfc-editor.org/rfc/rfc3031.txt
- [2] https://www.rfc-editor.org/rfc/rfc3032.txt
- [3] https://www.rfc-editor.org/rfc/rfc4364
- [4] https://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst9500/software/release/17-7/configuration_guide/mpls/b_177_mpls_9500_cg/configuring_mpls_static_labels.pdf
Post a Comment