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).
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 receptionallocate 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.
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.
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: 24001The forwarding table shows in figures that the /24 label is unused: label 24001 for 10.4.5.0/24 has switched 0 bytes.
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.
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-LOOPBACKSThe local bindings drop to four and the /24 entries disappear.
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: 24003Label 24001 is gone from the forwarding table as well, leaving only the three loopback entries.
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.
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.
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-ONLYBoth routers peer with the same P1, yet PE1 receives one label and P2 still receives four. The Labels column shows it.
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 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.
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.2PE1 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.
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-ONLYSeen from PE1 the result is indistinguishable from STEP 2: Labels is again 1.
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.
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.5The 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).
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: 14The 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
allocateshrinks the LIB, but the router still knows the routes.Total Prefixinshow mpls ldp bindings summarykeeps 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 neighborin 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 P1References
| 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.
- What Is MPLS
- MPLS Labels and the Label Stack
- MPLS Label Operations (push / swap / pop) and PHP
- MPLS TTL Processing and MTU
- What Is LDP
- LDP Label Distribution Modes and Label Spaces
- LDP-IGP Synchronization and LDP Session Protection
- LDP Label Advertisement Control (Filtering)
- LDP Session Authentication (TCP MD5)
- MPLS OAM (LSP Ping and LSP Traceroute)
- What Is MPLS TE (RSVP-TE)
- MPLS TE CSPF and Path Constraints (Bandwidth, Affinity, TE Metric)
- Steering Traffic into MPLS TE Tunnels