MPLS Labels Explained: Format, Stacking, and Penultimate Hop Popping

MPLS labels byte-by-byte: 20-bit label, EXP/TC, S bit, TTL. The label stack model, reserved labels, Penultimate Hop Popping, TTL handling, and what labels look like in Wireshark.

MPLS labels are 32-bit shim headers inserted between the data link layer and the IP header. They carry the label value, traffic class (formerly EXP), the bottom-of-stack bit, and TTL. Multiple labels can be stacked. If you understand the label format and how the stack works, the rest of MPLS becomes mechanics.

This article walks through the byte-level format, the label stack, special reserved labels, Penultimate Hop Popping (PHP), and how labels look on the wire in real packet captures. If you are studying for CCIE Service Provider, troubleshooting an MPLS-VPN packet, or trying to figure out why show mpls forwarding-table shows what it shows, this is the byte reference.

The Label Format

+---------------------+-----+---+-------------+
|        Label        | EXP | S |     TTL     |
| 20 bits             | 3   | 1 | 8 bits      |
+---------------------+-----+---+-------------+
FieldBitsPurpose
Label20The label value, 0 to 1,048,575. Locally significant per LSR.
EXP / Traffic Class3QoS priority; carries equivalent of DSCP top 3 bits across MPLS
S (Bottom of Stack)11 if this is the bottom label; 0 if more labels follow below
TTL8Hop count, decremented at each LSR; mirrors IP TTL

Total 32 bits = 4 bytes per label. The shim header is inserted in the frame between the Layer 2 header (Ethernet, etc.) and the Layer 3 payload (IP).

Reserved Labels

The first 16 label values (0-15) are reserved for special meanings. Three matter in practice:

LabelNameUse
0IPv4 Explicit NullTells the egress LSR to pop the label and forward as IPv4. Used in PHP scenarios where the egress wants to preserve EXP/TC info.
1Router AlertTreats the packet specially (like IP Router Alert). Sent to control plane for inspection.
2IPv6 Explicit NullSame as label 0 but for IPv6.
3Implicit NullUsed in LDP signaling to request PHP. The penultimate hop pops the label entirely instead of swapping.
13OAM AlertOperations and management traffic
14Generic AlertReserved for new features

Labels 16 to 1,048,575 are available for use as forwarding labels. Different platforms may reserve some additional ranges (e.g. Cisco IOS reserves the first ~16,000 for specific features), so customer-installed labels typically start at 16,000 or higher.

The Label Stack

Multiple labels can be pushed onto a single packet. The stack is a sequence of label entries with the S bit indicating which is the bottom. Reading from outer to inner:

+--------+--------+--------+---------+
| Outer  | Middle | Inner  | IP/payld|
| S=0    | S=0    | S=1    |         |
+--------+--------+--------+---------+
   First popped or swapped
                         Last popped, payload exposed

Common scenarios:

ServiceStackOuter label purposeInner label purpose
IP/MPLS forwardingSingle labelLDP/IGP transportn/a
L3VPN (VPNv4)Two labelsLDP transport across MPLS coreVPN label identifying customer VRF
L3VPN with TEThree labelsRSVP-TE TE labelLDP transport (intermediate), VPN label (innermost)
L2VPN (pseudowire)Two labelsLDP transportPseudowire label identifying the L2 circuit
SR-MPLSVariableSegment list (path)Service label or none

Each LSR along the path looks at the outermost label, performs swap/pop/push as configured, and forwards. P routers in the core typically only swap the outer transport label. The inner labels are invisible to them.

Label Actions: Push, Swap, Pop

Each LSR can perform three operations on the label stack:

ActionEffectWhere it happens
PushAdds one or more labels to the top of the stackIngress PE (encapsulating customer traffic)
SwapReplaces the outermost label with a new oneEvery P router along the LSP
PopRemoves the outermost labelEgress PE (decapsulating); also penultimate hop in PHP

The forwarding table entry tells the LSR which action to perform for each (incoming label, incoming interface) tuple. Verify with:

R1# show mpls forwarding-table
Local      Outgoing   Prefix          Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id    Switched      interface
17         18         10.10.10.0/24   123456       Gi0/0/1     10.0.12.2
18         Pop Label  10.20.20.0/24   78901        Gi0/0/2     10.0.13.3
19         No Label   10.30.30.0/24   45678        Gi0/0/0     10.0.14.4

"Pop Label" means PHP - this LSR pops the label and forwards the unlabeled packet. "No Label" means the next hop is not running MPLS for this prefix.

Penultimate Hop Popping (PHP)

The egress PE has the work of looking up which VRF a customer packet belongs to (based on the inner VPN label) and forwarding it to the customer. If it also had to look up the outer transport label, that is two label lookups instead of one.

Penultimate Hop Popping optimizes this. The penultimate (second-to-last) LSR pops the outer label before forwarding to the egress PE. The egress PE receives a packet with only the inner VPN label, performs one label lookup, and forwards to the customer.

Signaling: the egress PE advertises label "implicit null" (label 3) to its upstream neighbors via LDP. This is a request to pop the label rather than swap it. The penultimate router sees implicit null in the LDP table and pops accordingly.

PHP is enabled by default in most Cisco IOS XE deployments. Verify with:

P1# show mpls forwarding-table 10.10.10.10 32
Local      Outgoing   Prefix          Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id    Switched      interface
17         Pop Label  10.10.10.10/32  123456       Gi0/0/2     10.0.PE2.PE2

The "Pop Label" outgoing label confirms PHP for the egress PE's loopback (10.10.10.10/32).

Disable PHP if you want the egress PE to see the outer label (e.g. to preserve EXP/TC bits across the boundary):

! On the egress PE
mpls ldp explicit-null

This advertises "explicit null" (label 0 for IPv4, label 2 for IPv6) instead of implicit null. The penultimate router still pops one level of stack, but the egress PE sees an explicit null label - useful for QoS preservation.

TTL Handling

The MPLS label has its own TTL. Two modes for handling it at ingress and egress:

ModeIngress behaviorEgress behavior
Uniform (default)Copy IP TTL to MPLS label TTL minus 1Copy MPLS TTL back to IP TTL
PipeSet MPLS TTL to 255Decrement IP TTL by 1 (the entire MPLS path counts as one hop)

Uniform mode lets traceroute work as expected through the MPLS network - each LSR appears as a hop. Pipe mode hides the MPLS topology - the customer sees one big "hop" across the entire MPLS network, which is what service providers usually want for security reasons.

Configure with:

! Pipe mode (hide MPLS topology)
mpls ip propagate-ttl no

! Uniform mode (default; show MPLS topology)
mpls ip propagate-ttl

EtherType and Encapsulation

On Ethernet, an MPLS-encapsulated frame has:

FieldValue
EtherType (unicast)0x8847
EtherType (multicast)0x8848

An Ethernet frame with EtherType 0x8847 carries one or more MPLS labels followed by the payload (typically IP). The receiver parses the labels until S=1, then treats the remainder as the underlying protocol.

Show Commands

! All MPLS forwarding entries
Router# show mpls forwarding-table

! For a specific prefix
Router# show mpls forwarding-table 10.10.10.0 24

! LDP-assigned labels per prefix
Router# show mpls ldp bindings

! Per-interface MPLS state
Router# show mpls interfaces

! IP-to-label mapping in CEF
Router# show ip cef 10.10.10.0/24
10.10.10.0/24, version 123, ...
  via 10.0.12.2, GigabitEthernet0/0/0
    push label 17, ...

The CEF output shows the label being pushed for each prefix. This is what actually drives forwarding. LDP populates the binding table; CEF uses the bindings to populate the forwarding-information base; packets follow the FIB.

In a Packet Capture

An MPLS-labeled frame in Wireshark shows as:

Ethernet II, Src: ..., Dst: ..., Type: MPLS (0x8847)
MPLS Label, Exp: 0, S: 0, TTL: 64        <-- outer
    MPLS Label: 17
MPLS Label, Exp: 0, S: 1, TTL: 64        <-- inner (S=1 = bottom)
    MPLS Label: 1234
Internet Protocol Version 4, Src: ..., Dst: ...

Wireshark parses the label stack automatically. The S=1 on the inner label terminates the stack; everything after is parsed as IP (or whatever the inner protocol indicates).

Summary

MPLS labels are 32-bit shim headers (20-bit label, 3-bit EXP/TC, 1-bit S, 8-bit TTL) that sit between the data link header and the payload. Stacks of labels enable services like L3VPN (two-label stack) and traffic engineering. Penultimate Hop Popping optimizes egress PE work by having the second-to-last LSR pop the outer label.

Master the label format, the three actions (push/swap/pop), the reserved labels (especially implicit null for PHP), and the stack model. The rest of MPLS is mechanics built on these foundations. Bookmark this article alongside the MPLS cluster pillar and the LDP article.

Read next

© 2025 Ping Labz. All rights reserved.