> ## Content Index
> Fetch the complete content index at: https://www.pinglabz.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# MPLS Labels Explained: Format, Stacking, and Penultimate Hop Popping
- URL: https://www.pinglabz.com/mpls-labels-explained/
- Published: 2026-04-26T07:50:54.000Z
- Updated: 2026-08-24T17:16:43.000Z
- Description: 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.
- Author: Jaime
- Tags: MPLS, #Import 2026-08-01 19:54

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      |
+---------------------+-----+---+-------------+
```

Label

Bits20

Purpose

The label value, 0 to 1,048,575\. Locally significant per LSR.

EXP / Traffic Class

Bits3

Purpose

QoS priority; carries equivalent of DSCP top 3 bits across MPLS

S (Bottom of Stack)

Bits1

Purpose

1 if this is the bottom label; 0 if more labels follow below

TTL

Bits8

Purpose

Hop 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:

IPv4 Explicit Null

Label0

Use

Tells the egress LSR to pop the label and forward as IPv4\. Used in PHP scenarios where the egress wants to preserve EXP/TC info.

Router Alert

Label1

Use

Treats the packet specially (like IP Router Alert). Sent to control plane for inspection.

IPv6 Explicit Null

Label2

Use

Same as label 0 but for IPv6.

Implicit Null

Label3

Use

Used in LDP signaling to request PHP. The penultimate hop pops the label entirely instead of swapping.

Generic Associated Channel (GAL)

Label13

Use

Marks a packet as carrying an associated control channel (MPLS-TP OAM)

OAM Alert

Label14

Use

Operations, administration and maintenance traffic

Labels 16 to 1,048,575 are available for use as forwarding labels. Platforms differ on where dynamic allocation begins: Cisco IOS XE allocates from 16 upward by default, while IOS XR starts its dynamic range at 16000\. Check show mpls label range on the box rather than assuming.

## 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:

IP/MPLS forwarding

StackSingle label

Outer label purposeLDP/IGP transport

Inner label purposen/a

L3VPN (VPNv4)

StackTwo labels

Outer label purpose

LDP transport across MPLS core

Inner label purpose

VPN label identifying customer VRF

L3VPN with TE

StackThree labels

Outer label purposeRSVP-TE TE label

Inner label purpose

LDP transport (intermediate), VPN label (innermost)

L2VPN (pseudowire)

StackTwo labels

Outer label purposeLDP transport

Inner label purpose

Pseudowire label identifying the L2 circuit

SR-MPLS

StackVariable

Outer label purposeSegment list (path)

Inner label purposeService 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:

Adds one or more labels to the top of the stack

ActionPush

Where it happens

Ingress PE (encapsulating customer traffic)

Replaces the outermost label with a new one

ActionSwap

Where it happens

Every P router along the LSP

Removes the outermost label

ActionPop

Where it happens

Egress 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:

Uniform (default)

Ingress behavior

Copy IP TTL to MPLS label TTL minus 1

Egress behavior

Copy MPLS TTL back to IP TTL

Pipe

Ingress behaviorSet MPLS TTL to 255

Egress behavior

Decrement 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:

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](https://www.pinglabz.com/mpls/) and the [LDP article](https://www.pinglabz.com/ldp-mpls-label-distribution/).