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

MPLS OAM (LSP Ping and LSP Traceroute)

Table of Contents

MPLS OAM (LSP Ping and LSP Traceroute)

An ordinary ping only tests the IP path. It pushes no label, so it succeeds even when the LSP is broken. The tool that tests the MPLS data plane is LSP Ping (RFC 8029). This article explains how it works, then observes the actual packets in an IOS XR (XRd) lab. Label distribution is covered in What Is LDP.

Why IP ping is not enough

When MPLS carries a packet, the ingress PE pushes a transport label. An IP ping, by contrast, is sent without a label, so it tests the IGP path and nothing else. If label forwarding is broken, the IP ping still succeeds and the routing table shows nothing wrong.

As the title of RFC 8029 — “Detecting Multiprotocol Label Switched (MPLS) Data-Plane Failures” — says, the mechanism targets data-plane failures: the case where the control plane (LDP) claims the LSP exists while forwarding is broken.

How LSP Ping works

LSP Ping sends an MPLS echo request with the label of the LSP under test. The receiving router answers with an MPLS echo reply.

Element Contents
Destination address 127/8 (section 2.1), so that a diagnostic packet whose LSP broke and fell back to IP forwarding never leaves the network. With 16M addresses it also lets the sender vary the address to exercise ECMP paths
Target FEC Stack The TLV carrying which FEC is being tested. The first element corresponds to the top of the label stack. An IPv4 prefix distributed by LDP is Sub-Type 1
Reply Mode How to answer. 2 = reply via an IPv4/IPv6 UDP packet is the usual one; 1 does not reply, 3 uses Router Alert, 4 uses an application-level control channel
Return Code The result. 3 = the replying router is an egress for that FEC, 4 = no mapping for that FEC, 8 = label switched

The Target FEC Stack is the key part. Forwarding on the label alone cannot reveal that a transit LSR has confused it with the label of another FEC. Carrying “the FEC this label is supposed to serve” alongside the packet lets the receiver detect the mismatch.

LSP Traceroute

LSP Traceroute increments the TTL in the label stack one at a time. The LSR where the TTL expires answers, so the state of each hop becomes visible. The reply carries the label used at that hop and the MRU (maximum receive unit).

An ordinary IP traceroute shows neither which label each core LSR uses nor where PHP happens.

Lab topology

A non-redundant chain. OSPF and LDP run in the core (PE1 - P1 - P2 - PE2), and CE1 and CE2 attach to the PEs through VRF CUST-A, reachable over VPNv4. LSP Ping starts at PE1 and tests the FEC of PE2’s loopback (5.5.5.5/32).

MPLS-FILTER lab
  CE1 ------ PE1 ------ P1 ------ P2 ------ PE2 ------ CE2
(AS 65101)    |    ↑ LDP dropped here in STEP 2  |   (AS 65102)
           vrf CUST-A                        vrf CUST-A
              └────── iBGP vpnv4 (between Lo0) ──────┘
Router Lo0 Role
CE1 1.1.1.1 AS 65101, 192.168.1.0/24
PE1 2.2.2.2 Ingress/egress LSR. Where LSP Ping starts
P1 3.3.3.3 Transit LSR
P2 4.4.4.4 Transit LSR (PHP)
PE2 5.5.5.5 Ingress/egress LSR. The FEC under test
CE2 6.6.6.6 AS 65102, 192.168.2.0/24

Overview of the test

STEP Change What it shows
0 Initial state LSP Ping is unavailable. IOS XR needs it enabled explicitly
1 Enable mpls oam on all four core routers ping mpls and traceroute mpls succeed. The packets are examined in the capture
2 Drop LDP between PE1 and P1 with an ACL LSP Ping fails while IP ping still succeeds
3 Remove everything (final state) Back to the STEP 0 state

STEP 0: not available by default on IOS XR

Without it enabled, ping mpls never runs.

STEP 0 PE1 (mpls oam not enabled)
RP/0/RP0/CPU0:PE1#ping mpls ipv4 5.5.5.5/32
Sat Sep 12 08:40:54.133 UTC
% MPLS Embedded Management Subsystem is not running.
To enable, use 'mpls oam' global config command.

The subsystem that handles OAM is not running. The configuration is a single line, applied to all four core routers (the responders need it too).

Configuration committed on PE1 in STEP 1
RP/0/RP0/CPU0:PE1#show configuration commit changes last 1
Sat Sep 12 08:41:28.848 UTC
!! Building configuration...
!! IOS XR Configuration 26.1.1
mpls oam
!
end

STEP 1: testing a healthy LSP

Once enabled it succeeds. Adding verbose prints the Return Code for each reply. The legend of result characters is printed every time, and it is what to read when something fails.

STEP 1 PE1 ping mpls ipv4 5.5.5.5/32 repeat 2 verbose
RP/0/RP0/CPU0:PE1#ping mpls ipv4 5.5.5.5/32 repeat 2 verbose
Sat Sep 12 08:49:30.733 UTC

Sending 2, 100-byte MPLS Echos to 5.5.5.5/32,
      timeout is 2 seconds, send interval is 0 msec:

Codes: '!' - success, 'Q' - request not sent, '.' - timeout,
  'L' - labeled output interface, 'B' - unlabeled output interface, 
  'D' - DS Map mismatch, 'F' - no FEC mapping, 'f' - FEC mismatch,
  'M' - malformed request, 'm' - unsupported tlvs, 'N' - no rx label, 
  'P' - no rx intf label prot, 'p' - premature termination of LSP, 
  'R' - transit router, 'I' - unknown upstream index,
  'X' - unknown return code, 'x' - return code 0

Type escape sequence to abort.

!      size 100, reply addr 10.4.5.5, return code 3 
!      size 100, reply addr 10.4.5.5, return code 3 

Success rate is 100 percent (2/2), round-trip min/avg/max = 15/16/17 ms

return code 3 is RFC 8029’s “the replying router is an egress for that FEC”.

Traceroute shows the label at each hop

Traceroute prints the same legend and then one line per hop. L marks a hop that forwards with a label, ! marks arrival.

STEP 1 PE1 traceroute mpls ipv4 5.5.5.5/32
RP/0/RP0/CPU0:PE1#traceroute mpls ipv4 5.5.5.5/32
Sat Sep 12 08:49:30.974 UTC

Tracing MPLS Label Switched Path to 5.5.5.5/32, timeout is 2 seconds

Codes: '!' - success, 'Q' - request not sent, '.' - timeout,
  'L' - labeled output interface, 'B' - unlabeled output interface, 
  'D' - DS Map mismatch, 'F' - no FEC mapping, 'f' - FEC mismatch,
  'M' - malformed request, 'm' - unsupported tlvs, 'N' - no rx label, 
  'P' - no rx intf label prot, 'p' - premature termination of LSP, 
  'R' - transit router, 'I' - unknown upstream index,
  'X' - unknown return code, 'x' - return code 0

Type escape sequence to abort.

  0 10.2.3.2 MRU 1500 [Labels: 24003 Exp: 0]
L 1 10.2.3.3 MRU 1500 [Labels: 24003 Exp: 0] 10 ms
L 2 10.3.4.4 MRU 1500 [Labels: implicit-null Exp: 0] 12 ms
! 3 10.4.5.5 13 ms

Hop 2 shows implicit-null, which is P2 popping the label with PHP, readable straight from the output. The MRU is shown for each hop as well.

Inside the packets

No.912 in the attached capture is the echo request PE1 sent.

STEP 1 No.912 MPLS Echo Request (PE1 → 127.0.0.1, tshark -V extract)
    Type: MPLS label switched packet (0x8847)
MultiProtocol Label Switching Header, Label: 24003, Exp: 0, S: 1, TTL: 255
Internet Protocol Version 4, Src: 10.2.3.2, Dst: 127.0.0.1
User Datagram Protocol, Src Port: 3503, Dst Port: 3503
    Message Type: MPLS Echo Request (1)
    Reply Mode: Reply via an IPv4/IPv6 UDP packet (2)
    Return Code: No return code (0)
        Type: Target FEC Stack (1)
        FEC Element 1: LDP IPv4 prefix
            Type: LDP IPv4 prefix (1)
            IPv4 Prefix: 5.5.5.5
            Prefix Length: 32
Download the pcap of the packet in the tshark output above (No.912 Echo Request)

The destination is 127.0.0.1, the UDP source and destination ports are both 3503, and the packet carries label 24003 with TTL 255. The Target FEC Stack holds the FEC under test (5.5.5.5/32). The Return Code is 0 because this is a request.

Here is the echo reply that came back (No.913).

STEP 1 No.913 MPLS Echo Reply (PE2 → PE1, tshark -V extract)
Internet Protocol Version 4, Src: 10.4.5.5, Dst: 10.2.3.2
User Datagram Protocol, Src Port: 3503, Dst Port: 3503
    Message Type: MPLS Echo Reply (2)
    Reply Mode: Reply via an IPv4/IPv6 UDP packet (2)
    Return Code: Replying router is an egress for the FEC at stack depth RSC (3)
    Return Subcode: 1
Download the pcap of the packet in the tshark output above (No.913 Echo Reply)

The reply carries no label; it comes back as plain IP. Reply Mode 2 is doing exactly what it says. The Return Code is 3, matching what the CLI verbose printed.

The traceroute TTLs are visible too. LSP Ping sends with TTL 255, while traceroute increments 1, 2, 3.

Packet TTL
No.912-920 (LSP Ping x5) 255
No.922 1
No.924 2
No.926 3
Download the pcap of the TTL=1 echo request (No.922)

STEP 2: what a broken LSP looks like

An ACL on PE1’s interface towards P1 drops LDP only. OSPF and IP reachability are untouched.

Configuration committed on PE1 in STEP 2
RP/0/RP0/CPU0:PE1#show configuration commit changes last 1
Sat Sep 12 08:49:57.370 UTC
!! Building configuration...
!! IOS XR Configuration 26.1.1
ipv4 access-list BLOCK-LDP
 10 deny udp any any eq ldp
 20 deny tcp any any eq ldp
 30 deny tcp any eq ldp any
 40 permit ipv4 any any
!
interface GigabitEthernet0/0/0/1
 ipv4 access-group BLOCK-LDP ingress
!
end

The LDP session drops and the label is lost, so LSP Ping cannot even send the echo request.

STEP 2 PE1 ping mpls ipv4 5.5.5.5/32 repeat 2 verbose
RP/0/RP0/CPU0:PE1#ping mpls ipv4 5.5.5.5/32 repeat 2 verbose
Sat Sep 12 09:00:01.017 UTC

Sending 2, 100-byte MPLS Echos to 5.5.5.5/32,
      timeout is 2 seconds, send interval is 0 msec:

Codes: '!' - success, 'Q' - request not sent, '.' - timeout,
  'L' - labeled output interface, 'B' - unlabeled output interface, 
  'D' - DS Map mismatch, 'F' - no FEC mapping, 'f' - FEC mismatch,
  'M' - malformed request, 'm' - unsupported tlvs, 'N' - no rx label, 
  'P' - no rx intf label prot, 'p' - premature termination of LSP, 
  'R' - transit router, 'I' - unknown upstream index,
  'X' - unknown return code, 'x' - return code 0

Type escape sequence to abort.

Q      size 100, Unable to send echo request packet
Q      size 100, Unable to send echo request packet

Success rate is 0 percent (0/2)

Q is “request not sent” from the legend. At the same time, the IP ping is lossless.

STEP 2 PE1 IP ping (same destination)
RP/0/RP0/CPU0:PE1#ping 5.5.5.5 source 2.2.2.2 count 50 timeout 1
Sat Sep 12 08:54:03.788 UTC
Type escape sequence to abort.
Sending 50, 100-byte ICMP Echos to 5.5.5.5 timeout is 1 seconds:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Success rate is 100 percent (50/50), round-trip min/avg/max = 9/21/76 ms

To the same destination, IP ping is 100% and LSP Ping is 0%. The VPN traffic carried over MPLS (CE1 - CE2) is fully lost at this point as well.

STEP CE1 → CE2 ping PE1 → PE2 IP ping LSP Ping
0 100% (50/50) 100% not available
1 100% (50/50) 100% 100%
2 0% (0/50) 100% 0%
3 100% (50/50) 100% 100%

A data-plane-only failure cannot be built in a lab

What this test produced is a control-plane failure: the LDP session is down, so show mpls ldp neighbor reveals the cause. The state LSP Ping really targets — control plane healthy, forwarding broken — could not be created by configuration.

Using static labels on IOS XR to override the label LDP allocated (24003 on P1) does commit, but the entry ends up as Discrepancy and is never programmed into the LFIB.

Result of trying to override the LDP label with mpls static
Label   VRF             Type         Prefix           RW Configured   Status   
------- --------------- ------------ ---------------- --------------- -------- 
24003   default         X-Connect    N/A              Yes             Discrepancy

XR detects the conflict with the LDP-managed label and refuses it. A misconfiguration therefore cannot drive the control plane and the data plane apart. The failures LSP Ping finds originate outside the configuration, such as a forwarding entry that failed to be written to hardware — which is exactly why a tool is needed for faults that show cannot reveal.

Design notes

  • On IOS XR, mpls oam must already be there. Enabling it after trouble starts is too late, so make it part of the standard core configuration
  • The responders need it too. Enabling it only on the initiator leaves transit LSRs and the egress unable to answer
  • Q (request not sent) means the label is missing locally. Nothing reached the peer, so start with your own show mpls ldp neighbor and show mpls forwarding
  • A successful LSP Ping does not guarantee VPN reachability. LSP Ping tests the transport LSP; the VPN label is pushed separately

Verification configs and show output

At every STEP the following was collected from all six routers, split per router. The verification config is the ..._run.txt file (the final state is the one from the last STEP).

File Contents
..._show.txt show version, show mpls forwarding, the show mpls ldp set
..._log.txt show logging restricted to that STEP
..._run.txt show running-config at that STEP (the verification config)
..._ping.txt ping (50 packets, 1 second timeout) and traceroute for that STEP
..._oam.txt ping mpls and traceroute mpls results for that STEP (PE1, PE2, P1, P2)
..._trace.txt show mpls ldp trace outputs (core routers only)
..._commit.cfg Only the configuration actually committed in that STEP, for the routers that were changed

STEP 0: initial state (mpls oam not enabled)

Router show syslog running-config ping OAM trace commit
CE1 show log run ping - - -
PE1 show log run ping oam trace -
P1 show log run ping oam trace -
P2 show log run ping oam trace -
PE2 show log run ping oam trace -
CE2 show log run ping - - -

STEP 1: enable mpls oam on all four core routers

Router show syslog running-config ping OAM trace commit
CE1 show log run ping - - -
PE1 show log run ping oam trace cfg
P1 show log run ping oam trace cfg
P2 show log run ping oam trace cfg
PE2 show log run ping oam trace cfg
CE2 show log run ping - - -

STEP 2: drop LDP between PE1 and P1 with an ACL

Router show syslog running-config ping OAM trace commit
CE1 show log run ping - - -
PE1 show log run ping oam trace cfg
P1 show log run ping oam trace -
P2 show log run ping oam trace -
PE2 show log run ping oam trace -
CE2 show log run ping - - -

STEP 3: remove everything (final state)

Router show syslog running-config ping OAM trace commit
CE1 show log run ping - - -
PE1 show log run ping oam trace cfg
P1 show log run ping oam trace cfg
P2 show log run ping oam trace cfg
PE2 show log run ping oam trace cfg
CE2 show log run ping - - -

The full capture between PE1 and P1, containing the MPLS echo requests and replies from every STEP.

Download the full capture between PE1 and P1

References

Source What was checked
RFC 8029 Detecting Multiprotocol Label Switched (MPLS) Data-Plane Failures Section 2.1 (why 127/8 is used), section 2.2 (Router Alert Option), section 3 (Target FEC Stack, Reply Mode, Return Code), sections 3.4.2 and 4 (traceroute by incrementing the TTL). Obsoletes RFC 4379, 6424, 6829 and 7537

UDP port 3503 is a value measured in the capture, not quoted from the RFC text. The lab ran on XRd 26.1.1 under Cisco Modeling Labs.