Skip to main content
  1. Network Articles/
  2. MPLS Articles/

MPLS Labels and the Label Stack

Table of Contents

MPLS Labels and the Label Stack

An MPLS label is attached to a packet as a 4-byte label stack entry defined in RFC 3032. This article explains the contents of those 4 bytes, how several labels are stacked, and the label values that are reserved, then captures labeled packets in an IOS XR (XRd) lab to confirm it. The role of the label and terms such as LSR and LSP are covered in What Is MPLS.

Label Stack Entry Format

FieldBitsMeaning
Label20Label value, 0 to 1048575. Values 0 to 15 are reserved for special purposes (see below).
TC (Traffic Class)3Carries the QoS class. RFC 3032 only defined it as “experimental use” (EXP); RFC 5462 renamed it Traffic Class. IOS XR still calls it EXP in show output and configuration, and by default copies the IP Precedence (upper 3 bits of the DSCP) into it when the label is pushed.
S (Bottom of Stack)1Set to 1 only on the last (bottom) entry. The receiver uses it to find the end of the label stack.
TTL (Time to Live)8Same role as the IP TTL. The IP TTL is copied in when the first label is pushed, only the label TTL is decremented at each LSR, and it is written back to the IP TTL when the label is popped. A packet whose TTL reaches 0 is not forwarded.

Labels that IOS XR assigns dynamically start at 24000 by default (show mpls label range).

The Label Stack

Label stack entries sit right after the Layer 2 header and right before the Layer 3 header, as many as needed. The first is the top and the last is the bottom, and forwarding looks only at the top label.

On Ethernet, the EtherType 0x8847 (unicast) or 0x8848 (multicast) says that a label stack follows (RFC 3032 section 5). The label stack itself has no field that says whether the payload is IPv4 or IPv6 (section 2.2). The LSR that pops the last label tells the payload type from the bottom label value or from the first byte of the IP header (the version).

The depth of the stack depends on the application: one entry for IGP prefixes carried by LDP, two in MPLS VPN (one to reach the egress PE and one to identify the VPN), and one more on a traffic engineering backup path. The lab in this article observes both a global route (one entry) and an MPLS VPN route (two entries).

Reserved Labels (0 to 15)

Label values 0 to 15 are reserved for special purposes. RFC 3032 defines 0 to 3, and 4 to 15 are managed by IANA (Special-Purpose MPLS Label Values).

ValueNameMeaning
0IPv4 Explicit NULLThe receiving LSR pops this entry and forwards by the label beneath it, or by the IPv4 header if there is none. RFC 3032 allowed it only at the bottom; RFC 4182 removed that restriction.
1Router AlertLegal anywhere except the bottom. When on top, the packet is handed to software and the label is pushed back before forwarding.
2IPv6 Explicit NULLThe IPv6 counterpart of 0.
3Implicit NULLNever appears on the wire. The egress LSR distributes it to tell the previous LSR to pop the label (PHP).
4MPLS Network ActionsRFC 9994.
7Entropy Label Indicator (ELI)RFC 6790. Says that an entropy label for load balancing follows.
13Generic Associated Channel Label (GAL)RFC 5586. Control channel for OAM and similar.
14OAM AlertRFC 3429.
15Extension Label (XL)RFC 7274. Says that an extended special-purpose label follows.

The two you see every day are 0 and 3. The default is implicit-null (3): the egress LSR distributes 3 for its directly connected prefixes (such as loopbacks) and the previous LSR pops the label, so unlabeled IP packets flow on the link before the egress LSR. To deliver the TC value to the egress LSR, have it distribute explicit-null (0) instead. The previous LSR then swaps the label to 0, and the egress LSR reads the TC from label 0 before popping it. On IOS XR this is label local advertise explicit-null under mpls ldp.

Value distributed by the egress LSRAction at the previous LSRLink before the egress LSR
3 (implicit-null, default)PopNo label
0 (explicit-null)Swap to label 0Label 0

The label operations themselves are covered in MPLS Label Operations (push / swap / pop) and PHP.

Lab Verification

Lab Setup

CE1, PE1, P1, P2, PE2, and CE2 are connected in a row. PE1 / P1 / P2 / PE2 in AS 65001 form the MPLS network, with OSPF (area 0, every link network point-to-point) distributing routes and LDP distributing labels. CE1 and CE2 are customer routers without MPLS that exchange routes with the PEs over eBGP. PE1 and PE2 peer over iBGP between their Loopback0 addresses with next-hop-self, so the next hop of an external route is the PE’s own Loopback0. P1 and P2 do not run BGP.

In addition, CE3 is attached to PE1 and CE4 to PE2 in VRF CUST-A (RD / RT 65001:1), and VPNv4 is added to the PE1 - PE2 iBGP session. Traffic between CE3 and CE4 is carried by the MPLS VPN route and gets two labels. VRFs and VPNv4 are covered in the MPLS L3VPN series; this article looks only at the label stack.

RouterRoleLo0Links
CE1Customer side (AS 65101), advertises 192.168.1.0/241.1.1.1/32Gi0/0/0/0 10.1.2.1
PE1Ingress / egress LSR (AS 65001)2.2.2.2/32Gi0/0/0/0 10.1.2.2 / Gi0/0/0/1 10.2.3.2
P1Intermediate LSR3.3.3.3/32Gi0/0/0/0 10.2.3.3 / Gi0/0/0/1 10.3.4.3
P2Intermediate LSR4.4.4.4/32Gi0/0/0/0 10.3.4.4 / Gi0/0/0/1 10.4.5.4
PE2Ingress / egress LSR (AS 65001)5.5.5.5/32Gi0/0/0/0 10.4.5.5 / Gi0/0/0/1 10.5.6.5
CE2Customer side (AS 65102), advertises 192.168.6.0/246.6.6.6/32Gi0/0/0/0 10.5.6.6
CE3Customer side in VRF CUST-A (AS 65107), advertises 192.168.7.0/247.7.7.7/32Gi0/0/0/0 10.2.7.7 (PE1 Gi0/0/0/2)
CE4Customer side in VRF CUST-A (AS 65108), advertises 192.168.8.0/248.8.8.8/32Gi0/0/0/0 10.5.8.8 (PE2 Gi0/0/0/2)

CE1 pings 192.168.6.1 (global) and CE3 pings 192.168.8.1 (VPN) while we capture on the PE1 - P1 and P2 - PE2 links. The BGP next hop of both routes is PE2’s Loopback0 (5.5.5.5), so the top label PE1 pushes is the one P1 distributed for 5.5.5.5/32.

Steps

STEPActionWhat to confirm
0Initial state (default = implicit-null)Labeled packets (EtherType 0x8847) on PE1 - P1, one entry for the global route and two for the VPN route. The top label is removed on P2 - PE2
1label local advertise explicit-null on PE2Label 0 appears on P2 - PE2, on top of the VPN label for VPN traffic
2Remove STEP 1 (final state)Back to the same state as STEP 0

Inside a Labeled Packet (STEP 0)

For the BGP next hop 5.5.5.5 of 192.168.6.0/24, PE1 pushes label 24003, which it received from P1. In show mpls forwarding, the row for local label 24004 (PE1’s own label for 5.5.5.5/32) shows outgoing label 24003. The last row, 24005, is the VPN label PE1 assigned to 192.168.7.0/24 in VRF CUST-A ([V]).

PE1 show mpls forwarding (STEP 0)
RP/0/RP0/CPU0:PE1#show mpls forwarding
Wed Sep  9 22:23:28.677 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
24000  Pop         3.3.3.3/32         Gi0/0/0/1    10.2.3.3        1021        
24001  Pop         10.3.4.0/24        Gi0/0/0/1    10.2.3.3        0           
24002  24001       4.4.4.4/32         Gi0/0/0/1    10.2.3.3        0           
24003  24002       10.4.5.0/24        Gi0/0/0/1    10.2.3.3        0           
24004  24003       5.5.5.5/32         Gi0/0/0/1    10.2.3.3        3779        
24005  Unlabelled  192.168.7.0/24[V]  Gi0/0/0/2    10.2.7.7        2528

Dynamic labels start at 24000, as show mpls label range shows.

P2 show mpls label range (STEP 0)
RP/0/RP0/CPU0:P2#show mpls label range
Wed Sep  9 22:23:08.987 UTC
Range for dynamic labels: Min/Max: 24000/1048575

No.11 in the PE1 - P1 capture, taken while CE1 pinged 192.168.6.1, is a labeled echo request. The EtherType is 0x8847, the label 24003, TC (shown by tshark as Experimental Bits) 0, S = 1, TTL 254, and the IPv4 header follows right after the 4-byte label stack entry. The label TTL of 254 is the TTL 255 sent by CE1, decremented once by PE1 and copied in.

No.11 Echo request (PE1 -> P1) tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 0]
MultiProtocol Label Switching Header, Label: 24003, Exp: 0, S: 1, TTL: 254
    0000 0101 1101 1100 0011 .... .... .... = MPLS Label: 24003 (0x05dc3)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 192.168.6.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
Download the pcap of the packet in the tshark output above (No.11 Echo request)

No.11 in the STEP 1 capture on PE1 - P1 is a BGP KEEPALIVE from PE1 to PE2. Its IP DSCP is CS6, so the label TC is 6 as well. How TC is used is covered in MPLS QoS.

No.11 BGP KEEPALIVE (PE1 -> P1, STEP 1) tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 0]
MultiProtocol Label Switching Header, Label: 24003, Exp: 6, S: 1, TTL: 255
    0000 0101 1101 1100 0011 .... .... .... = MPLS Label: 24003 (0x05dc3)
    .... .... .... .... .... 110. .... .... = MPLS Experimental Bits: 6
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1111 = MPLS TTL: 255
Internet Protocol Version 4, Src: 2.2.2.2, Dst: 5.5.5.5
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0xc0 (DSCP: CS6, ECN: Not-ECT)
        1100 00.. = Differentiated Services Codepoint: Class Selector 6 (48)
Download the pcap of the packet in the tshark output above (No.11 BGP KEEPALIVE)

A Two-Entry Label Stack (STEP 0)

A ping from CE3 to 192.168.8.1 (CE4) is carried by a route in VRF CUST-A. For this destination PE1 pushes the VPN label 24005, distributed by PE2 over VPNv4, and on top of it 24003 to reach the egress PE2. The labels imposed {24003 24005} line of show cef vrf CUST-A is that two-entry stack.

PE1 show bgp vrf CUST-A 192.168.8.0/24 (STEP 0)
RP/0/RP0/CPU0:PE1#show bgp vrf CUST-A 192.168.8.0/24
Wed Sep  9 22:23:34.324 UTC
BGP routing table entry for 192.168.8.0/24, Route Distinguisher: 65001:1
Versions:
  Process           bRIB/RIB   SendTblVer
  Speaker                  7            7
Last Modified: Sep  9 22:18:42.774 for 00:04:51
Paths: (1 available, best #1)
  Advertised to CE peers (in unique update groups):
    10.2.7.7        
  Path #1: Received by speaker 0
  Advertised to CE peers (in unique update groups):
    10.2.7.7        
  65108, (received & used)
    5.5.5.5 (metric 4) from 5.5.5.5 (5.5.5.5)
      Received Label 24005 
      Origin IGP, metric 0, localpref 100, valid, internal, best, group-best, import-candidate, imported
      Received Path ID 0, Local Path ID 1, version 7
      Extended community: RT:65001:1 
      Source AFI: VPNv4 Unicast, Source VRF: CUST-A, Source Route Distinguisher: 65001:1
PE1 show cef vrf CUST-A 192.168.8.0/24 detail (STEP 0)
RP/0/RP0/CPU0:PE1#show cef vrf CUST-A 192.168.8.0/24 detail
Wed Sep  9 22:23:35.074 UTC
192.168.8.0/24, version 7, internal 0x5000001 0x30 (ptr 0x885197b0) [1], 0x0 (0x0), 0x208 (0x89a1a4b8)
 Updated Sep  9 22:18:42.823
 Prefix Len 24, traffic index 0, precedence n/a, priority 3
  gateway array (0x89726b60) reference count 1, flags 0x2038, source rib (7), 0 backups
                [1 type 1 flags 0x48441 (0x89a534b8) ext 0x0 (0x0)]
  LW-LDI[type=0, refc=0, ptr=0x0, sh-ldi=0x0]
  gateway array update type-time 1 Sep  9 22:18:42.823
 LDI Update time Sep  9 22:18:42.823
   via 5.5.5.5/32, 3 dependencies, recursive [flags 0x6000]
    path-idx 0 NHID 0x0 [0x8856f048 0x0]
    recursion-via-/32
    next hop VRF - 'default', table - 0xe0000000
    next hop 5.5.5.5/32 via 24004/0/21
     next hop 10.2.3.3/32 GigabitEthernet0/0/0/1 labels imposed {24003 24005}

    Load distribution: 0 (refcount 1)

    Hash  OK  Interface                 Address
    0     Y   recursive                 24004/0

No.50 in the PE1 - P1 capture is the echo request carrying that two-entry stack. The top entry 24003 has S = 0, the bottom entry 24005 has S = 1, and the IPv4 header follows the entry with S = 1. Both label TTLs are 254.

No.50 Echo request (PE1 -> P1, two labels) tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 0]
MultiProtocol Label Switching Header, Label: 24003, Exp: 0, S: 0, TTL: 254
    0000 0101 1101 1100 0011 .... .... .... = MPLS Label: 24003 (0x05dc3)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...0 .... .... = MPLS Bottom Of Label Stack: 0
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
MultiProtocol Label Switching Header, Label: 24005, Exp: 0, S: 1, TTL: 254
    0000 0101 1101 1100 0101 .... .... .... = MPLS Label: 24005 (0x05dc5)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
Internet Protocol Version 4, Src: 192.168.7.1, Dst: 192.168.8.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
Download the pcap of the packet in the tshark output above (No.50 Echo request, two labels)

No.45 in the P2 - PE2 capture is the same packet after P2 popped the top label. Only the VPN label 24005 remains, with TTL 252. When P2 popped the top label it wrote the current TTL (252) into the entry that became the new top (RFC 3032 section 2.4.2).

No.45 Echo request (P2 -> PE2, VPN label only) tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 0]
MultiProtocol Label Switching Header, Label: 24005, Exp: 0, S: 1, TTL: 252
    0000 0101 1101 1100 0101 .... .... .... = MPLS Label: 24005 (0x05dc5)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1100 = MPLS TTL: 252
Internet Protocol Version 4, Src: 192.168.7.1, Dst: 192.168.8.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
Download the pcap of the packet in the tshark output above (No.45 Echo request)

On PE2, local label 24005 corresponds to 192.168.8.0/24 in VRF CUST-A ([V]), and packets with that label are sent out the interface toward CE4. How VPN labels are distributed and what they mean is covered in the MPLS L3VPN series.

PE2 show mpls forwarding (STEP 0)
RP/0/RP0/CPU0:PE2#show mpls forwarding
Wed Sep  9 22:23:55.678 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
24000  24000       2.2.2.2/32         Gi0/0/0/0    10.4.5.4        6482        
24001  24001       3.3.3.3/32         Gi0/0/0/0    10.4.5.4        0           
24002  Pop         4.4.4.4/32         Gi0/0/0/0    10.4.5.4        742         
24003  24002       10.2.3.0/24        Gi0/0/0/0    10.4.5.4        0           
24004  Pop         10.3.4.0/24        Gi0/0/0/0    10.4.5.4        0           
24005  Unlabelled  192.168.8.0/24[V]  Gi0/0/0/2    10.5.8.8        2120

Implicit-Null Never Appears as a Label (STEP 0)

PE2, the egress LSR, distributes implicit-null (3) for its own Loopback0 (5.5.5.5/32). On P2, show mpls ldp bindings shows the value from PE2 as ImpNull and show mpls forwarding shows the outgoing action as Pop.

P2 show mpls ldp bindings 5.5.5.5/32 (STEP 0)
RP/0/RP0/CPU0:P2#show mpls ldp bindings 5.5.5.5/32
Wed Sep  9 22:23:07.909 UTC
5.5.5.5/32, rev 14
	Local binding: label: 24003
	Remote bindings: (2 peers)
	    Peer                Label    
	    -----------------   ---------
	    3.3.3.3:0           24003   
	    5.5.5.5:0           ImpNull
P2 show mpls forwarding (STEP 0)
RP/0/RP0/CPU0:P2#show mpls forwarding
Wed Sep  9 22:23:08.525 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
24000  24000       2.2.2.2/32         Gi0/0/0/0    10.3.4.3        6531        
24001  Pop         3.3.3.3/32         Gi0/0/0/0    10.3.4.3        762         
24002  Pop         10.2.3.0/24        Gi0/0/0/0    10.3.4.3        0           
24003  Pop         5.5.5.5/32         Gi0/0/0/1    10.4.5.5        5926

No.9 in the P2 - PE2 capture is the echo request from CE1 (one label) after P2 popped the label. The EtherType is 0x0800 and there is no label. The IP TTL is 252: the value decremented in the label was written back to the IP header when the label was popped.

No.9 Echo request (P2 -> PE2) tshark -V
    Type: IPv4 (0x0800)
    [Stream index: 0]
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 192.168.6.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 252
Download the pcap of the packet in the tshark output above (No.9 Echo request)

show mpls label table detail shows which reserved labels the router actually holds. The LSD (Label Switching Database) owns 0 (IPv4 Explicit NULL), 1 (Router Alert), 2 (IPv6 Explicit NULL), and 13 (GAL), and there is no 3. Implicit-null is a value carried by LDP; it appears neither in the label table nor on the wire.

P2 show mpls label table detail (STEP 0)
RP/0/RP0/CPU0:P2#show mpls label table detail
Wed Sep  9 22:23:09.108 UTC
Table Label   Owner                           State  Rewrite
----- ------- ------------------------------- ------ -------
0     0       LSD(A)                          InUse  Yes
0     1       LSD(A)                          InUse  Yes
0     2       LSD(A)                          InUse  Yes
0     13      LSD(A)                          InUse  Yes
0     24000   LDP(A)                          InUse  Yes
  (IPv4, vers:0, 'default':4U, 2.2.2.2/32)
0     24001   LDP(A)                          InUse  Yes
  (IPv4, vers:0, 'default':4U, 3.3.3.3/32)
0     24002   LDP(A)                          InUse  Yes
  (IPv4, vers:0, 'default':4U, 10.2.3.0/24)
0     24003   LDP(A)                          InUse  Yes
  (IPv4, vers:0, 'default':4U, 5.5.5.5/32)

Explicit-Null Appears on the Wire (STEP 1)

Configure label local advertise explicit-null on PE2.

PE2 (STEP 1)
mpls ldp
 address-family ipv4
  label local advertise explicit-null

The value P2 receives changes to ExpNullv4 and the outgoing action to Exp-Null-v4.

P2 show mpls ldp bindings 5.5.5.5/32 (STEP 1)
RP/0/RP0/CPU0:P2#show mpls ldp bindings 5.5.5.5/32
Wed Sep  9 22:27:36.443 UTC
5.5.5.5/32, rev 14
	Local binding: label: 24003
	Remote bindings: (2 peers)
	    Peer                Label    
	    -----------------   ---------
	    3.3.3.3:0           24003   
	    5.5.5.5:0           ExpNullv4
P2 show mpls forwarding (STEP 1)
RP/0/RP0/CPU0:P2#show mpls forwarding
Wed Sep  9 22:27:37.093 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
24000  24000       2.2.2.2/32         Gi0/0/0/0    10.3.4.3        11943       
24001  Pop         3.3.3.3/32         Gi0/0/0/0    10.3.4.3        1336        
24002  Pop         10.2.3.0/24        Gi0/0/0/0    10.3.4.3        0           
24003  Exp-Null-v4 5.5.5.5/32         Gi0/0/0/1    10.4.5.5        4526

In No.10 of the P2 - PE2 capture, the echo request from CE1 arrives with label 0. The label TTL is 252 while the IP TTL is still 254, which also shows that the IP TTL does not change while a label is present.

No.10 Echo request (P2 -> PE2, explicit-null) tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 0]
MultiProtocol Label Switching Header, Label: 0 (IPv4 Explicit-Null), Exp: 0, S: 1, TTL: 252
    0000 0000 0000 0000 0000 .... .... .... = MPLS Label: IPv4 Explicit-Null (0)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1100 = MPLS TTL: 252
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 192.168.6.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
Download the pcap of the packet in the tshark output above (No.10 Echo request)

On the VPN path, as in No.52, the stack has two entries: label 0 on top (S = 0) and the VPN label 24005 at the bottom (S = 1). RFC 3032 allowed explicit-null only at the bottom of the stack, but RFC 4182 removed that restriction: an explicit-null on top is simply popped and the packet is handled by the label beneath. PE2 pops label 0 and then forwards into VRF CUST-A by 24005.

No.52 Echo request (P2 -> PE2, explicit-null + VPN label) tshark -V
    Type: MPLS label switched packet (0x8847)
    [Stream index: 0]
MultiProtocol Label Switching Header, Label: 0 (IPv4 Explicit-Null), Exp: 0, S: 0, TTL: 252
    0000 0000 0000 0000 0000 .... .... .... = MPLS Label: IPv4 Explicit-Null (0)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...0 .... .... = MPLS Bottom Of Label Stack: 0
    .... .... .... .... .... .... 1111 1100 = MPLS TTL: 252
MultiProtocol Label Switching Header, Label: 24005, Exp: 0, S: 1, TTL: 254
    0000 0101 1101 1100 0101 .... .... .... = MPLS Label: 24005 (0x05dc5)
    .... .... .... .... .... 000. .... .... = MPLS Experimental Bits: 0
    .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1
    .... .... .... .... .... .... 1111 1110 = MPLS TTL: 254
Internet Protocol Version 4, Src: 192.168.7.1, Dst: 192.168.8.1
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0000 (0)
    000. .... = Flags: 0x0
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 254
Download the pcap of the packet in the tshark output above (No.52 Echo request, two labels)

Reverting (STEP 2)

Removing label local advertise explicit-null from PE2 returns P2’s value to ImpNull. Filtering P2’s LDP trace on 5.5.5.5/32 lists the history of the value received from PE2 changing 3 -> 0 -> 3. In both switches there is a 10-second gap between the withdrawal of the old value (Remove) and the arrival of the new one (Add), during which P2’s show mpls forwarding shows Unlabelled.

P2 show mpls ldp trace binding | include 5.5.5.5/32 (STEP 2)
RP/0/RP0/CPU0:P2#show mpls ldp trace binding | include "5.5.5.5/32"
Wed Sep  9 22:33:16.133 UTC
Sep  9 22:17:00.924 mpls/ldp/bndg 0/RP0/CPU0 t4062  [BNDG]:161: VRF(0x60000000): Prefix(5.5.5.5/32): Created, reason 3
Sep  9 22:17:00.925 mpls/ldp/bndg 0/RP0/CPU0 t4062  [BNDG]:221: VRF(0x60000000): Prefix(5.5.5.5/32): label 24003 (rev#14) assigned
Sep  9 22:17:05.919 mpls/ldp/bndg 0/RP0/CPU0 t4062  [BNDG]:279: VRF(0x60000000): Prefix(5.5.5.5/32): Add label 3 from peer 5.5.5.5:0
Sep  9 22:17:07.056 mpls/ldp/bndg 0/RP0/CPU0 t4062  [BNDG]:279: VRF(0x60000000): Prefix(5.5.5.5/32): Add label 24003 from peer 3.3.3.3:0
Sep  9 22:25:46.049 mpls/ldp/bndg 0/RP0/CPU0 t4062  [BNDG]:339: VRF(0x60000000): Prefix(5.5.5.5/32): Remove label 3 from peer 5.5.5.5:0
Sep  9 22:25:56.056 mpls/ldp/bndg 0/RP0/CPU0 t4062  [BNDG]:279: VRF(0x60000000): Prefix(5.5.5.5/32): Add label 0 from peer 5.5.5.5:0
Sep  9 22:29:56.056 mpls/ldp/bndg 0/RP0/CPU0 t4062  [BNDG]:339: VRF(0x60000000): Prefix(5.5.5.5/32): Remove label 0 from peer 5.5.5.5:0
Sep  9 22:30:06.049 mpls/ldp/bndg 0/RP0/CPU0 t4062  [BNDG]:279: VRF(0x60000000): Prefix(5.5.5.5/32): Add label 3 from peer 5.5.5.5:0

Download the whole STEP 0 capture on PE1 - P1

Download the whole STEP 0 capture on P2 - PE2

Download the whole STEP 1 capture on PE1 - P1

Download the whole STEP 1 capture on P2 - PE2

Configurations and show Output

At each STEP the following files were collected from all eight routers, one set per router. The ..._run.txt files are the configurations (the final state is STEP 2).

FileContents
..._show.txtshow version / show interface description / show route / show route ospf / show ospf / show ospf interface brief / show ospf neighbor / show ospf database / show mpls interfaces / show mpls ldp neighbor / show mpls ldp neighbor detail / show mpls ldp discovery / show mpls ldp interface / show mpls ldp bindings / show mpls ldp forwarding / show mpls ldp parameters / show mpls ldp summary / show mpls ldp statistics msg-counters / show mpls forwarding / show mpls forwarding detail / show mpls label range / show mpls label table detail / show cef <prefix> detail. PEs add the show bgp set (show bgp summary / show bgp / show bgp neighbors / per-peer advertised-routes / routes / received routes) and the VPN set (show vrf CUST-A detail / show route vrf CUST-A / show bgp vpnv4 unicast summary / show bgp vpnv4 unicast / show bgp vrf CUST-A summary / show bgp vrf CUST-A / show bgp vrf CUST-A <prefix> / show bgp vrf CUST-A neighbors / show cef vrf CUST-A <prefix> detail); CEs have only the BGP set
..._log.txtshow logging limited to that STEP (STEP 0 holds the full history since boot)
..._run.txtshow running-config at that STEP (the configuration for that STEP)
..._trace.txtCore routers only. show mpls ldp trace binding / peer / discovery / route / forwarding and show mpls lsd trace

STEP 0: initial state (implicit-null)

Routershowsyslogrunning-configtrace
CE1showlogrun
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun
CE3showlogrun
CE4showlogrun

STEP 1: label local advertise explicit-null on PE2

Routershowsyslogrunning-configtrace
CE1showlogrun
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace
PE2showlogruntrace
CE2showlogrun
CE3showlogrun
CE4showlogrun

STEP 2: explicit-null removed (final state)

Routershowsyslogrunning-configtrace
CE1showlogrun
PE1showlogruntrace
P1showlogruntrace
P2showlogruntrace / 5.5.5.5/32 only
PE2showlogruntrace
CE2showlogrun
CE3showlogrun
CE4showlogrun

References

RFCTitleSummary
RFC 3032MPLS Label Stack EncodingLabel stack entry format, reserved labels 0 to 3, TTL processing, EtherTypes.
RFC 5462Multiprotocol Label Switching (MPLS) Label Stack Entry: “EXP” Field Renamed to “Traffic Class” FieldRenames the EXP field to the Traffic Class field.
RFC 4182Removing a Restriction on the use of MPLS Explicit NULLAllows Explicit NULL anywhere in the stack, not only at the bottom.
RFC 3031Multiprotocol Label Switching ArchitecturePHP (section 3.16).

Reserved label registry: IANA Special-Purpose MPLS Label Values

Book: Luc De Ghein, MPLS Fundamentals (Cisco Press, 2006), Chapters 2 to 3

Related Articles