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

LDP Label Advertisement Control (Filtering)

Table of Contents

LDP Label Advertisement Control (Filtering)

By default LDP allocates and advertises a label for every prefix the IGP knows. What is actually needed is only the /32 loopbacks that BGP uses as next hops. This article explains the three points at which label advertisement can be restricted, then confirms in an IOS XR (XRd) lab that restricting them does not break forwarding. The basics of LDP are covered in What Is LDP.

What is being filtered

When MPLS carries a packet, the transport label the ingress PE pushes belongs to the LSP towards the BGP next hop, which is the remote PE’s loopback. The core link subnets are traversed, but they are never a next hop, so they do not need a label.

LDP advertises all of them anyway because the specification does not say what to advertise. Section 2.6.3 of RFC 5036 defines Downstream Unsolicited and Downstream on Demand, which is when labels are advertised; no filtering mechanism exists in the protocol. What to advertise is a purely local policy decision for each implementation.

There are three reasons to restrict it: a smaller label table, fewer LDP messages, and no unintended LSPs.

The three control points

A label flows in this order: allocated in the local LIB, advertised to the peer, accepted by the peer. IOS XR can stop it at each of those three places.

Control point Where it stops Effect
label allocate Before allocation No local label is created. The LIB itself shrinks
label advertise On advertisement The label exists but is not sent. Can differ per peer
label remote accept On reception What arrives is discarded. Decided by the receiver alone

Use label allocate to shrink your own label table, label advertise to hide labels from a particular peer, and label remote accept when you cannot rely on the other end being configured.

All three live under label in the address-family ipv4 of mpls ldp, split into local (what I allocate and advertise) and remote (what I accept). The filter takes an IP access list, not a route policy, and a peer is named by its LDP Identifier (3.3.3.3:0, including the label space).

IOS XR syntax (XRd 26.1.1)
mpls ldp
 address-family ipv4
  label
   local
    allocate for <access-list>            ← stop before allocation
    advertise
     to <LDP Id> for <access-list>        ← decide per peer what to send
   remote
    accept
     from <LDP Id> for <access-list>      ← discard on reception

allocate for also accepts the keyword host-routes, which means “/32 only” without writing an access list.

Relaxing a filter requires a session reset

A label that has been withdrawn is not re-advertised automatically when the filter is removed. LDP does not refresh advertisements periodically, even in Downstream Unsolicited mode, so deleting an advertise filter does not restore the peer’s LIB. Use clear mpls ldp neighbor <peer> to re-establish the session.

Tightening a filter takes effect immediately (a Label Withdraw is sent), while relaxing one does not. When an LSP fails to come back after a filter is loosened, suspect this asymmetry rather than the configuration.

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.

MPLS-FILTER lab
  CE1 ------ PE1 ------ P1 ------ P2 ------ PE2 ------ CE2
(AS 65101)    |                               |    (AS 65102)
           vrf CUST-A                    vrf CUST-A
              └────── iBGP vpnv4 (between Lo0) ──────┘
Router Lo0 Role Link Subnet
CE1 1.1.1.1 AS 65101, 192.168.1.0/24 CE1 - PE1 10.1.2.0/24 (VRF)
PE1 2.2.2.2 Ingress/egress LSR, vrf CUST-A PE1 - P1 10.2.3.0/24
P1 3.3.3.3 Transit LSR P1 - P2 10.3.4.0/24
P2 4.4.4.4 Transit LSR P2 - PE2 10.4.5.0/24
PE2 5.5.5.5 Ingress/egress LSR, vrf CUST-A PE2 - CE2 10.5.6.0/24 (VRF)
CE2 6.6.6.6 AS 65102, 192.168.2.0/24

The global OSPF knows seven prefixes: four /32 loopbacks and three /24 core links. The PE - CE links sit in the VRF, so they never enter the global OSPF and never get a label in the first place.

Overview of the test

STEP Change What it shows
0 Initial state All seven prefixes carry a label. ping and traceroute succeed
1 label allocate restricted to /32 (all four core routers) The LIB shrinks from 7 to 4. ping and traceroute are unchanged
2 label advertise restricted for PE1 only PE1’s remote bindings drop while P2, which was not filtered, is unaffected
3 Remove the sending filter, add label remote accept P1 sends the labels but PE1 does not keep them
4 Remove everything (final state) Back to the STEP 0 state

Reachability is measured at every STEP from CE1 with ping 192.168.2.1 source 192.168.1.1 count 50 timeout 1 and traceroute.

STEP 0: every prefix gets a label by default

P1’s local bindings. Four /32 loopbacks and three /24 links, seven labels in total.

STEP 0 P1 show mpls ldp bindings local
RP/0/RP0/CPU0:P1#show mpls ldp bindings local
Sat Sep 12 02:38:02.240 UTC

2.2.2.2/32, rev 12
	Local binding: label: 24002
3.3.3.3/32, rev 2
	Local binding: label: ImpNull
4.4.4.4/32, rev 9
	Local binding: label: 24000
5.5.5.5/32, rev 14
	Local binding: label: 24003
10.2.3.0/24, rev 25
	Local binding: label: ImpNull
10.3.4.0/24, rev 27
	Local binding: label: ImpNull
10.4.5.0/24, rev 29
	Local binding: label: 24001

The forwarding table shows in figures that the /24 label is unused: label 24001 for 10.4.5.0/24 has switched 0 bytes.

STEP 0 P1 show mpls forwarding
RP/0/RP0/CPU0:P1#show mpls forwarding
Sat Sep 12 02:38:03.103 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
24000  Pop         4.4.4.4/32         Gi0/0/0/1    10.3.4.4        17265       
24001  Pop         10.4.5.0/24        Gi0/0/0/1    10.3.4.4        0           
24002  Pop         2.2.2.2/32         Gi0/0/0/0    10.2.3.2        1615        
24003  24003       5.5.5.5/32         Gi0/0/0/1    10.3.4.4        69570       

STEP 1: stop before allocation (label allocate)

All four core routers get an access list permitting only the /32 loopbacks, plus allocate for.

Configuration committed on P1 in STEP 1
ipv4 access-list LDP-LOOPBACKS
 10 permit ipv4 host 2.2.2.2 any
 20 permit ipv4 host 3.3.3.3 any
 30 permit ipv4 host 4.4.4.4 any
 40 permit ipv4 host 5.5.5.5 any
!
mpls ldp
 address-family ipv4
  label
   local
    allocate for LDP-LOOPBACKS

The local bindings drop to four and the /24 entries disappear.

STEP 1 P1 show mpls ldp bindings local
RP/0/RP0/CPU0:P1#show mpls ldp bindings local
Sat Sep 12 02:45:17.334 UTC

2.2.2.2/32, rev 12
	Local binding: label: 24002
3.3.3.3/32, rev 2
	Local binding: label: ImpNull
4.4.4.4/32, rev 9
	Local binding: label: 24000
5.5.5.5/32, rev 14
	Local binding: label: 24003

Label 24001 is gone from the forwarding table as well, leaving only the three loopback entries.

STEP 1 P1 show mpls forwarding
RP/0/RP0/CPU0:P1#show mpls forwarding
Sat Sep 12 02:45:18.667 UTC
Local  Outgoing    Prefix             Outgoing     Next Hop        Bytes       
Label  Label       or ID              Interface                    Switched    
------ ----------- ------------------ ------------ --------------- ------------
24000  Pop         4.4.4.4/32         Gi0/0/0/1    10.3.4.4        24167       
24002  Pop         2.2.2.2/32         Gi0/0/0/0    10.2.3.2        34825       
24003  24003       5.5.5.5/32         Gi0/0/0/1    10.3.4.4        101594      

Forwarding is unaffected

This is the central point of the article. The traceroute from CE1 to CE2 traverses exactly the same label stack as in STEP 0.

STEP 1 CE1 traceroute
RP/0/RP0/CPU0:CE1#traceroute 192.168.2.1 source 192.168.1.1
Sat Sep 12 02:49:06.719 UTC

Type escape sequence to abort.
Tracing the route to 192.168.2.1

 1  10.1.2.2 5 msec  4 msec  4 msec 
 2  10.2.3.3 [MPLS: Labels 24003/24005 Exp 0] 14 msec  22 msec  14 msec 
 3  10.3.4.4 [MPLS: Labels 24003/24005 Exp 0] 15 msec  15 msec  16 msec 
 4  10.4.5.5 [MPLS: Label 24005 Exp 0] 16 msec  15 msec  15 msec 
 5  10.5.6.6 16 msec  *  17 msec 

The two-label stack of transport label 24003 (towards 5.5.5.5/32) and VPN label 24005 is preserved, and PHP still removes the transport label at P2. Ping was lossless at every STEP.

STEP Prefixes in the LIB (P1) CE1 → CE2 ping
0 7 100% (50/50)
1 4 100% (50/50)
2 4 100% (50/50)
3 4 100% (50/50)
4 7 100% (50/50)

Removing 40% of the labels does not drop a single packet.

STEP 2: stop on advertisement (label advertise)

P1 restricts what it advertises to PE1 only to 5.5.5.5/32. Nothing towards P2 changes.

Configuration committed on P1 in STEP 2
ipv4 access-list LDP-PE2-ONLY
 10 permit ipv4 host 5.5.5.5 any
!
mpls ldp
 address-family ipv4
  label
   local
    advertise
     to 2.2.2.2:0 for LDP-PE2-ONLY

Both routers peer with the same P1, yet PE1 receives one label and P2 still receives four. The Labels column shows it.

STEP 2 PE1 show mpls ldp neighbor brief
RP/0/RP0/CPU0:PE1#show mpls ldp neighbor brief
Sat Sep 12 02:53:32.502 UTC

Peer               GR  NSR  Up Time     Discovery   Addresses     Labels    
                                        ipv4  ipv6  ipv4  ipv6  ipv4   ipv6 
-----------------  --  ---  ----------  ----------  ----------  ------------
3.3.3.3:0          N   N    00:18:17    1     0     3     0     1      0    
STEP 2 P2 show mpls ldp neighbor brief (not filtered)
RP/0/RP0/CPU0:P2#show mpls ldp neighbor brief
Sat Sep 12 02:52:41.600 UTC

Peer               GR  NSR  Up Time     Discovery   Addresses     Labels    
                                        ipv4  ipv6  ipv4  ipv6  ipv4   ipv6 
-----------------  --  ---  ----------  ----------  ----------  ------------
3.3.3.3:0          N   N    00:54:50    1     0     3     0     4      0    
5.5.5.5:0          N   N    00:49:38    1     0     2     0     4      0    

The moment the configuration is committed, P1 sends three Label Withdraw messages to PE1. This is No.1832 in the attached capture.

STEP 2 No.1832 Label Withdrawal x3 (P1 → PE1, tshark -V extract)
Internet Protocol Version 4, Src: 3.3.3.3, Dst: 2.2.2.2
Label Distribution Protocol
    Version: 1
    PDU Length: 90
    LSR ID: 3.3.3.3
    Label Space ID: 0
        Message Type: Label Withdrawal Message (0x402)
                    FEC Element Length: 32
                    Prefix: 3.3.3.3
        Message Type: Label Withdrawal Message (0x402)
                    FEC Element Length: 32
                    Prefix: 4.4.4.4
        Message Type: Label Withdrawal Message (0x402)
                    FEC Element Length: 32
                    Prefix: 2.2.2.2
Download the pcap of the packet in the tshark output above (No.1832 Label Withdrawal)

PE1 stopped holding those labels because P1 stopped sending them.

STEP 3: stop on reception (label remote accept)

The sending filter is removed and PE1 now filters what it accepts. Because a withdrawn label is not re-advertised on its own, the session is reset with clear mpls ldp neighbor 2.2.2.2 before the receive filter is applied.

Configuration committed on PE1 in STEP 3
ipv4 access-list LDP-PE2-ONLY
 10 permit ipv4 host 5.5.5.5 any
!
mpls ldp
 address-family ipv4
  label
   remote
    accept
     from 3.3.3.3:0 for LDP-PE2-ONLY

Seen from PE1 the result is indistinguishable from STEP 2: Labels is again 1.

STEP 3 PE1 show mpls ldp neighbor brief
RP/0/RP0/CPU0:PE1#show mpls ldp neighbor brief
Sat Sep 12 03:02:00.308 UTC

Peer               GR  NSR  Up Time     Discovery   Addresses     Labels    
                                        ipv4  ipv6  ipv4  ipv6  ipv4   ipv6 
-----------------  --  ---  ----------  ----------  ----------  ------------
3.3.3.3:0          N   N    00:04:00    1     0     3     0     1      0    

The difference is visible on the wire. P1 sends all four Label Mappings. This is No.2867 in the attached capture.

STEP 3 No.2867 Label Mapping x4 (P1 → PE1, tshark -V extract)
Internet Protocol Version 4, Src: 3.3.3.3, Dst: 2.2.2.2
Label Distribution Protocol
    Version: 1
    PDU Length: 118
    LSR ID: 3.3.3.3
    Label Space ID: 0
        Message Type: Label Mapping Message (0x400)
                    FEC Element Length: 32
                    Prefix: 3.3.3.3
        Message Type: Label Mapping Message (0x400)
                    FEC Element Length: 32
                    Prefix: 4.4.4.4
        Message Type: Label Mapping Message (0x400)
                    FEC Element Length: 32
                    Prefix: 2.2.2.2
        Message Type: Label Mapping Message (0x400)
                    FEC Element Length: 32
                    Prefix: 5.5.5.5
Download the pcap of the packet in the tshark output above (No.2867 Label Mapping)

The mappings for 2.2.2.2, 3.3.3.3 and 4.4.4.4 do arrive; PE1 discards them because they do not match the access list. The counters look the same, but no bandwidth and no message processing has been saved. When you control the advertising side, stopping it there is the better option.

Where it is stopped LDP messages When to use it
advertise (sender) Not sent When you manage the advertising router
remote accept (receiver) Sent, then discarded When you cannot rely on the other end, or want the receiver to decide

STEP 4: removing everything restores the original state

With all access lists and filters removed, the LIB returns to seven prefixes. During the teardown PE1 sends a Label Request and P1 replies with seven Label Mappings (No.3745 and No.3755 in the capture).

STEP 4 P1 show mpls ldp bindings summary
RP/0/RP0/CPU0:P1#show mpls ldp bindings summary
Sat Sep 12 03:07:12.304 UTC

LIB Summary:
  Total Prefix   : 7 
  Revision No    : Current:38, Advertised:38
  Local Bindings : 7
      NULL    : 3 (implicit:3, explicit:0)
      Non-NULL: 4 (lowest:24000, highest:24003)
  Remote Bindings: 14
Download the pcap of P1 re-advertising all seven labels (No.3755 Label Mapping)

The running-config of the final STEP is identical, line for line, to the lab’s start-up configuration.

Design notes

  • Filter on what BGP uses as a next hop. Besides the PE loopbacks, include any address other PEs reference, such as a route reflector or an inter-AS next hop. Omitting one means no LSP towards that PE and a VPN that fails in one direction
  • allocate shrinks the LIB, but the router still knows the routes. Total Prefix in show mpls ldp bindings summary keeps the pre-filter count and reports (N unresolved), so prefixes without a label are still tracked
  • Relaxing a filter takes effect only after the session is reset (see above). Include clear mpls ldp neighbor in the maintenance procedure

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 interface description, the show mpls ldp bindings set, show mpls forwarding and more
..._log.txt show logging restricted to that STEP. A marker is written with logmsg at the start of each STEP and its timestamp passed to show logging start
..._run.txt show running-config at that STEP (the verification config)
..._ping.txt ping (50 packets, 1 second timeout) and traceroute for that STEP
..._trace.txt show mpls ldp trace binding / peer / discovery and others (core routers only)
..._commit.cfg Only the configuration actually committed in that STEP, for the routers that were changed

STEP 0: initial state

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

STEP 1: label allocate restricted to /32 (all four core routers)

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

STEP 2: label advertise restricted for PE1 only

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

STEP 3: remove the sending filter, add label remote accept

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

STEP 4: remove everything (final state)

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

The full capture between PE1 and P1. It contains everything from the Label Withdraw of STEP 1 to the labels being restored in STEP 4.

Download the full capture between PE1 and P1

References

Source What was checked
RFC 5036 LDP Specification Section 2.6.3 (Downstream Unsolicited / on Demand), and the confirmation that no label advertisement filter is specified in the RFC
IOS XR MPLS Configuration Guide Syntax of label allocate, label advertise and label remote accept

The lab ran on XRd 26.1.1 under Cisco Modeling Labs.