Multiprotocol Label Switching () forwards packets on a short label instead of the destination address. In plain IP forwarding each router repeats the longest-match lookup in its own routing table; MPLS classifies a packet once, where it enters, and every later router reads only the label. It carries provider backbones and the layer 3 virtual private networks (VPNs) built on them. After reading, you can decode a label stack entry in hex, read a real Label Distribution Protocol (LDP) binding table, say what a "-free core" keeps, and explain the two labels of a packet.

One decision at the edge, labels after it

(RFC) 3031, of January 2001, says it in one sentence: "In MPLS, the assignment of a particular packet to a particular FEC is done just once, as the packet enters the network" (RFC 3031, section 2.1). A forwarding equivalence class (FEC) is a group of packets forwarded the same way, over the same path with the same treatment (section 2.2). Later hops never read the network layer header; the label indexes a table giving the next hop and a new label. Such a router is a label switching router (LSR), and the method suits any network layer protocol, hence "multiprotocol" (section 2.1).

A label is "a short, fixed length, locally significant identifier which is used to identify a FEC" (RFC 3031, section 3.1). A label-switched path (LSP) runs from the LSP ingress, which pushes the label, to the LSP egress (section 3.15). The lookup on the top label yields a next hop and one operation: swap the top label, pop it, or swap it and push more (section 3.10), and "THE NEXT HOP IS ALWAYS TAKEN FROM THE NHLFE" (section 3.13), the Next Hop Label Forwarding Entry. MPLS computes no paths: the protocols in dynamic routing compared still do.

Thirty-two bits: the label stack entry

Each label stack entry is 4 octets (RFC 3032, section 2.1), placed after the link layer header and before the network layer header, top of stack first. RFC 3032 called the 3-bit field EXP (experimental use); RFC 5462 renamed it Traffic Class (TC): "This three-bit field is used to carry traffic class information" (RFC 5462, section 2.1).

FieldBitsWhat it carries
Label20The label value, 0 to 1048575
Traffic Class, formerly EXP3Traffic class
S, bottom of stack11 on the last entry, 0 on the others
Time to Live8Decremented at each hop

No field names the protocol underneath; the egress infers it from the bottom label (RFC 3032, section 2.2). On , ethertype 0x8847 marks MPLS unicast (section 5), as in the Ethernet frame, field by field.

A worked example: label 17, TC 0, S 0, Time to Live () 64, on top of label 100048, TC 5, S 1, TTL 64. Each entry equals label × 4096 + TC × 512 + S × 256 + TTL. The top is 17 × 4096 + 64 = 69696, or 0x00011040; the bottom is 409796608 + 2560 + 256 + 64 = 409799488, or 0x186D0B40. Computed, then checked by tcpdump on a frame built around the stack:

Entry 1 (top, transport label): label=17 tc=0 s=0 ttl=64
  bits  (label|TC|S|TTL): 00000000000000010001 000 0 01000000
  hex   : 00 01 10 40   (0x00011040)
Entry 2 (bottom, VPN label): label=100048 tc=5 s=1 ttl=64
  bits  (label|TC|S|TTL): 00011000011011010000 101 1 01000000
  hex   : 18 6D 0B 40   (0x186D0B40)
Stack bytes (8 octets = 4 x 2 entries): 00 01 10 40 18 6D 0B 40
  network layer header starts at offset 8 of the label stack
$ tcpdump -nn -e -v -x -r lse-check.pcap
12:31:53.000000 02:00:00:00:00:01 > 02:00:00:00:00:02, ethertype MPLS unicast (0x8847), length 54: MPLS (label 17, tc 0, ttl 64)
	(label 100048, tc 5, [S], ttl 64)
	(tos 0x0, ttl 64, id 1, offset 0, flags [none], proto ICMP (1), length 32)
    192.0.2.1 > 192.0.2.3: ICMP echo request, id 1, seq 1, length 12
	0x0000:  0001 1040 186d 0b40 4500 0020 0001 0000

The dump's first eight octets are the stack, and 4500 starts the IPv4 header. Twenty bits give 1048576 values, 1048560 of them from 16 up. The packing is a few lines of struct in the Python playground.

Labels 0 to 15

RFC 7274 renamed the low values "special-purpose labels" (RFC 7274, Abstract). The Internet Assigned Numbers Authority () registry, last updated 30 June 2026 (IANA, Special-Purpose MPLS Label Values):

ValueNameDefined in
0IPv4 Explicit NULL LabelRFC 3032
1Router Alert LabelRFC 3032
2IPv6 Explicit NULL LabelRFC 3032
3Implicit NULL LabelRFC 3032
4MPLS Network ActionsRFC 9994
5 to 6Unassigned
7Entropy Label Indicator (ELI)RFC 6790
8 to 12Unassigned
13Generic Associated Channel LabelRFC 5586
14OAM Alert Label (operations, administration and maintenance)RFC 3429
15Extension Label (XL)RFC 7274, RFC 9017

Implicit NULL "never actually appears in the encapsulation": a router that would swap to it pops instead (RFC 3032, section 2.1). Explicit NULL, once legal only at the bottom, may occur anywhere in the stack since RFC 4182 (RFC 4182, Abstract).

Penultimate hop popping, seen in a lab

The next-to-last router pops the top label "only if this is specifically requested by the egress node, OR if the next node in the LSP does not support MPLS", so that the egress does a single lookup (RFC 3031, section 3.16). The egress asks for this penultimate hop popping (PHP) by advertising Implicit NULL (section 4.1.5).

A lab on 19 October 2026 shows the signalling: routers pe1, p and pe2 in Linux network namespaces, FRRouting 8.4.4 with and LDP, loopbacks 192.0.2.1, 192.0.2.2 and 192.0.2.3. The kernel had no MPLS (zebra logged Disabling MPLS support (no kernel support)), so labels were exchanged but never installed or used.

mplsPE1# show mpls ldp binding
AF   Destination          Nexthop         Local Label Remote Label  In Use
ipv4 192.0.2.1/32         192.0.2.2       imp-null    16                no
ipv4 192.0.2.2/32         192.0.2.2       16          imp-null         yes
ipv4 192.0.2.3/32         192.0.2.2       18          17               yes
ipv4 198.51.100.0/31      192.0.2.2       imp-null    imp-null          no
ipv4 198.51.100.2/31      192.0.2.2       17          imp-null         yes

mplsP# show mpls ldp binding
AF   Destination          Nexthop         Local Label Remote Label  In Use
ipv4 192.0.2.1/32         192.0.2.1       16          imp-null         yes
ipv4 192.0.2.1/32         192.0.2.3       16          16                no
ipv4 192.0.2.2/32         192.0.2.1       imp-null    16                no
ipv4 192.0.2.2/32         192.0.2.3       imp-null    17                no
ipv4 192.0.2.3/32         192.0.2.1       17          18                no
ipv4 192.0.2.3/32         192.0.2.3       17          imp-null         yes

Follow 192.0.2.3/32, pe2's loopback. pe1's local label is 18, p's is 17: labels are local. pe1 uses the 17 that p sent, so traffic for pe2 leaves pe1 with 17 pushed. pe2 sent p imp-null, so p pops instead of swapping. On p, the no lines for 192.0.2.1/32 and 192.0.2.3/32 are labels kept from the neighbour that is not the next hop.

The BGP-free core, stated exactly

RFC 3031 states the idea: "it is desirable to avoid distributing the BGP routes to routers which are not BGP Border Routers" (RFC 3031, section 4.6). The ingress border router pushes L1, bound by the far border router to the BGP prefix, then L2, bound by the interior next hop to that border router's address (section 4.6). Interior routers switch on L2, which belongs to an address the interior gateway protocol () carries, so, by reasoning from the RFC, only the ingress needs the BGP route.

For VPNs, where provider edge (PE) routers face customers and provider (P) routers form the core, RFC 4364 says "the P routers need only maintain routes to the PE routers and the ASBRs", the autonomous system border routers (RFC 4364, section 15), and each PE must put a /32 route for itself into the backbone's IGP (section 5), OSPF or Intermediate System to Intermediate System (IS-IS). In the lab, p holds O>* 192.0.2.3/32 [110/10] via 198.51.100.3, ep2.

RFC 5565 names the idea and corrects the name: "That is something of a misnomer, though, since the crucial aspect of this scenario is not that the interior nodes don't run BGP, but that they don't maintain the external routing information" (RFC 5565, section 1). So the core does not go without a routing table: it keeps interior routes to every edge and drops external and VPN routes.

Layer 3 VPNs and their two labels

RFC 4364 (February 2006) defines BGP/MPLS IP VPNs: "Data packets are tunneled through the backbone, so that the core routers do not need to know the VPN routes" (RFC 4364, Abstract). Customer Edge (CE) devices attach to PE routers (section 1.2), and each PE keeps "VPN Routing and Forwarding tables" (VRFs) (section 3).

Two VPNs with no site in common may overlap, for instance when both number from 10.0.0.0/8 out of private address space (section 1.3). The route distinguisher (RD) separates them: 8 bytes in front of the 4-byte IPv4 address make a 12-byte VPN-IPv4 address, and "An RD is simply a number, and it does not contain any inherent information" (section 4.1). Route targets (RTs), carried as BGP extended communities, decide which VRFs import a route, and a route has one RD but may have several route targets (section 4.3.1).

The ingress PE pushes the VPN route label that BGP sent with the route, then a tunnel label to the egress PE (sections 1 and 5): the computed stack above has that shape, 17 from the lab over an illustrative 100048. With PHP the packet reaches the egress PE with the VPN route label alone (section 5), which picks the customer circuit or the virtual routing and forwarding () table to search.

Who hands out the labels

LDP (RFC 5036, October 2007) distributes labels "to support MPLS forwarding along normally routed paths" (RFC 5036, Abstract). Hellos go over UDP port 646 to the all-routers group; sessions use TCP port 646 (sections 1.2 and 3.10.1). The six-octet LDP identifier is the router ID plus two zero octets (section 2.2.2), printed 192.0.2.2:0. The higher address opens the session (section 2.5.2): p (192.0.2.2) connected to pe1 (192.0.2.1). FRRouting uses downstream unsolicited distribution with liberal retention (FRRouting documentation, LDP), hence p's unused lines above. A captured hello:

$ tcpdump -nn -v -c 1 -r lab-ldp-pe1-p-20261019.pcap
12:30:09.746900 IP (tos 0xc0, ttl 1, id 41112, offset 0, flags [DF], proto UDP (17), length 70)
    198.51.100.0.646 > 224.0.0.2.646:
	LDP, Label-Space-ID: 192.0.2.1:0, pdu-length: 38
	  Hello Message (0x0100), length: 28, Message ID: 0x00000001, Flags: [ignore if unknown]
	    Common Hello Parameters TLV (0x0400), length: 4, Flags: [ignore and don't forward if unknown]
	      Hold Time: 15s, Flags: [Link Hello]
	    IPv4 Transport Address TLV (0x0401), length: 4, Flags: [ignore and don't forward if unknown]
	      IPv4 Transport Address: 192.0.2.1

Note the IP TTL of 1, the 15-second hold time and the loopback as transport address.

RSVP-TE (RFC 3209, December 2001), the traffic engineering extensions to the Resource Reservation Protocol, sets up explicit routes with downstream-on-demand labels, and every node keeps state per LSP (RFC 3209, sections 1.1 and 2.2).

Segment Routing: the path in the stack

Segment Routing (SR), RFC 8402 of July 2018, changes who writes the stack, not how it is forwarded: "A segment is encoded as an MPLS label. An ordered list of segments is encoded as a stack of labels", with no change to the forwarding plane (RFC 8402, Abstract). Segments are still signalled, by , OSPF or BGP in the distributed case (section 1). An index into the SR Global Block (SRGB), which must not overlap the special-purpose labels, gives the label (RFC 8660, sections 2.3 and 2.4): in an illustrative SRGB of 16000 to 23999, index 3 is label 16003. RFC 9994, June 2026, carries network actions in the stack and holds label 4 (RFC 9994, Abstract).

TTL and traceroute

At the first push, "the TTL field of the label stack entry MUST BE set to the value of the IP TTL field" (RFC 3032, section 2.4.3). RFC 3443 names two models: Uniform shows every LSR to nodes outside the tunnel, and the Pipe Model makes the network act like a circuit, showing only ingress and egress (RFC 3443, section 2.2). Linux's ip_ttl_propagate defaults to 1, Uniform (The Linux Kernel documentation, MPLS Sysfs variables).

RFC 4950 lets a router append the incoming label stack to an Internet Control Message Protocol () Time Exceeded or Destination Unreachable (RFC 4950, sections 3 and 5); the probes themselves are in ICMP, ping and traceroute. The RFC's sample:

      2  192.0.2.9 (192.0.2.9)  0.861 ms  0.718 ms  0.679 ms

        MPLS Label=100048 Exp=0 TTL=1 S=1

That entry encodes as 0x186D0101. Linux traceroute prints it with -e as MPLS:L=label,E=exp_use,S=stack_bottom,T=TTL (traceroute(8)).

What labels cost the IP packet

The labels are not a link layer tag: "the Frame Payload consists of the label stack entries and the IP datagram", while 802.1Q headers stay outside it (RFC 3032, section 3.1). On a link left at Ethernet's 1500-byte payload, the largest IP datagram is 1496 with one label, 1492 with two, 1488 with three (section 3.2). A too-big IPv4 packet with Don't Fragment set "MUST NOT be forwarded" (section 3.4), and Path Maximum Transmission Unit () Discovery then needs the ICMP reply to reach the source (section 3.6). The MTU / MSS calculator counts 4 octets per mpls entry; unless the link payload was raised, those octets come out of the IP datagram.

How it fails or is attacked

A label carries no proof of its writer: "If labeled packets are accepted from untrusted sources, the result may be that packets are routed in an illegitimate manner" (RFC 3032, section 7). The defence is at the edge: backbone devices should refuse labelled packets from devices outside the backbone (RFC 4364, section 6). VPN separation is not encryption (section 13.1), and "Deliberate or inadvertent misconfiguration may result in severe security leaks" (RFC 4381, section 5.1).

An unauthorised LDP speaker can open a session and consume state, and hello or SYN floods can exhaust a router (RFC 5920, section 4.1.4). RFC 4364 asks that BGP and LDP never peer with untrusted routers and use TCP authentication with the Message-Digest Algorithm (section 13.2), the trust problem BGP and the routing chokepoint covers for BGP. The Generalized TTL Security Mechanism () checks that LDP packets came from a connected link (RFC 6720, Abstract).

A packet with an invalid incoming label "MUST be discarded" unless forwarding it unlabelled is known to be harmless (RFC 3031, section 3.18), so, by reasoning, a lost binding in a core without BGP routes is a black hole, not a reroute. RFC 8029's MPLS echo request checks the data plane against the control plane (RFC 8029, Abstract), and the Pipe Model keeps traceroute from revealing the core (RFC 4950, section 6).

How to see it

FRRouting shows the control plane with show mpls ldp neighbor, show mpls ldp discovery and show mpls ldp binding, and installed labels with show mpls table (FRRouting documentation, Zebra), which stays empty without kernel support, as in the lab. The lab's LDP configuration on p:

mpls ldp
 router-id 192.0.2.2
 address-family ipv4
  discovery transport-address 192.0.2.2
  interface ep1
  exit
  interface ep2
  exit
 exit-address-family
 exit
mplsPE1# show mpls ldp neighbor
AF   ID              State       Remote Address    Uptime
ipv4 192.0.2.2       OPERATIONAL 192.0.2.2       00:00:16

Linux recognises no label until net.mpls.platform_labels is above its default of 0 (MPLS Sysfs variables). ip -f mpls route show lists label routes (ip(8)); ip route add 198.51.100.0/30 encap mpls 200/300 via 192.0.2.1 dev eth0 pushes two labels on an IP route, after the manual's example with documentation addresses, not run here (ip-route(8)). In tcpdump each mpls primitive moves the filter 4 octets deeper (pcap-filter(7)): mpls 17 and mpls 100048 matched the computed frame, and port 646 captures LDP.

What to remember

  • MPLS assigns a packet to a FEC once, at the ingress; later LSRs forward on a label that means something only between two neighbours.
  • A label stack entry is 32 bits: label 20, Traffic Class 3 (once EXP), bottom of stack 1, TTL 8.
  • Labels 0 to 15 are special-purpose; Implicit NULL (3) never appears on the wire, and advertising it asks the previous hop to pop.
  • A "BGP-free core" keeps IGP routes to every PE and drops external and VPN routes; RFC 5565 calls the name a misnomer.
  • A layer 3 VPN packet carries a tunnel label over a VPN route label; RDs separate overlapping prefixes, route targets choose VRFs.
  • LDP follows the IGP, RSVP-TE keeps per-LSP state, and Segment Routing writes the path into the stack without changing MPLS forwarding.
  • Each label takes 4 octets of the frame payload; accept labelled packets only from trusted neighbours.

Sources