LDP Conditional Advertisement

Key Terms

This will be a short article on configuring conditional label advertisement in LDP. We’ll start with defining some key terms regarding how LDP advertises labels by default.

LDP operates in downstream unsolicited mode. This means that the LSR doesn’t wait for its LDP neighbor to request a label for a FEC. Instead, the LSR sends bindings for all routes that it has to all of its LDP neighbors.

In comparison, RSVP-TE operates in downstream on demand mode. This is because labels are only advertised when requestsed using a PATH message. A router won’t advertise a label for a FEC “on its own.” It only does so when the headend requests the path be setup.

LDP also operates in liberal retention mode, meaning each router stores all labels received by all neighbors, even if the neighbor is not currently the next-hop for the route.

You can view all stored labels in the FIB, by using the command show mpls ldp bindings. You can view the in-use labels in the LFIB, by using show mpls forwarding. These are the labels advertised by the next-hop for the route. The relationship between the FIB and LFIB is roughly similar to the way the BGP table stores all routes from all neighbors, but only the best route is sent to the RIB.

Optimizing label allocation

By default LDP will allocate a label for every IGP prefix, including connected interfaces that are part of the IGP. Often this is not really necessary, because in most topologies, every LSP will be terminating on the loopback of the egress PE. It is not really necessary to have a label for the IP of a physical interface, because the physical interface itself is never the destination of an LSP.

Lab

We’ll use the L3VPN lab topology from the RD/RT articles:

Refer to that article here if you want a reference to set up the base configs. We will use OSPF and enable LDP on all core interfaces.

Let’s examine the FIB of P3:

P3#show mpls ldp bindings 
  lib entry: 1.1.1.1/32, rev 2
        local binding:  label: 16
        remote binding: lsr: 1.1.1.1:0, label: imp-null
        remote binding: lsr: 2.2.2.2:0, label: 24000
  lib entry: 2.2.2.2/32, rev 10
        local binding:  label: 17
        remote binding: lsr: 2.2.2.2:0, label: imp-null
        remote binding: lsr: 1.1.1.1:0, label: 18
  lib entry: 3.3.3.3/32, rev 4
        local binding:  label: imp-null
        remote binding: lsr: 1.1.1.1:0, label: 16
        remote binding: lsr: 2.2.2.2:0, label: 24001
  lib entry: 10.1.3.0/24, rev 6
        local binding:  label: imp-null
        remote binding: lsr: 1.1.1.1:0, label: imp-null
        remote binding: lsr: 2.2.2.2:0, label: 24002
  lib entry: 10.2.3.0/24, rev 8
        local binding:  label: imp-null
        remote binding: lsr: 1.1.1.1:0, label: 17
        remote binding: lsr: 2.2.2.2:0, label: imp-null

The bindings for 10.1.3.0/24 and 10.2.3.0/24 serve no purpose in our topology. The LSPs for the L3VPN traffic terminate on the PE1 and PE2 loopbacks, so storing the labels for these /24s is just a waste of memory.

We can control the advertisement of labels in LDP. To do this we have to configure the router to stop advertising all labels, and configure the router to only advertise labels matching an ACL. This is a little confusing at first, but makes sense if you think about the fact that LDP advertises all labels by default. So if you simply advertise the labels matching the ACL, you are still advertising all other labels. It makes more sense once you see the config:

#PE1
ip access-list standard LOOPBACKS
 permit 1.1.1.1
!
ip access-list standard NEIGHBORS
 permit any
!
mpls ldp advertise-labels for LOOPBACKS to NEIGHBORS


#P3
ip access-list standard LOOPBACKS
 permit 1.1.1.1
 permit 2.2.2.2
 permit 3.3.3.3
!
ip access-list standard NEIGHBORS
 permit any
!
mpls ldp advertise-labels for LOOPBACKS to NEIGHBORS
no mpls ldp advertise-labels

#PE2
ipv4 access-list LOOPBACKS
 permit ipv4 host 2.2.2.2 any
!
ipv4 access-list NEIGHBORS
 permit ipv4 any any
!
mpls ldp address-family ipv4 label local advertise for LOOPBACKS to NEIGHBORS
mpls ldp address-family ipv4 label local advertise disable

Let’s examine the LIB on P3:

P3#show mpls ldp bindings 
  lib entry: 1.1.1.1/32, rev 2
        local binding:  label: 16
        remote binding: lsr: 1.1.1.1:0, label: imp-null
  lib entry: 2.2.2.2/32, rev 10
        local binding:  label: 17
        remote binding: lsr: 2.2.2.2:0, label: imp-null
  lib entry: 3.3.3.3/32, rev 4
        local binding:  label: imp-null
  lib entry: 10.1.3.0/24, rev 6
        local binding:  label: imp-null
  lib entry: 10.2.3.0/24, rev 8
        local binding:  label: imp-null

Now there are no remote bindings for the /24s, but there are still local bindings. There is a better way that we can configure this, which is to limit the local label allocation to only /32 prefixes. Right now we still allocate labels for all prefixes, but limit which bindings we advertise. The benefit of limiting local allocation is that it is a more elegant solution as well.

#PE1
mpls ldp advertise-labels
no mpls ldp advertise-labels for LOOPBACKS to NEIGHBORS
mpls ldp label
 allocate global host-routes

#P3
mpls ldp advertise-labels
no mpls ldp advertise-labels for LOOPBACKS to NEIGHBORS
mpls ldp label
 allocate global host-routes

#PE2
no mpls ldp address-family ipv4 label local advertise for LOOPBACKS to NEIGHBORS
no mpls ldp address-family ipv4 label local advertise disable
mpls ldp address-family ipv4 label local allocate for host-routes

Now there are no local bindings for the /24s, and we didn’t have to configure and maintain ACLs!

P3#show mpls ldp bindings 
  lib entry: 1.1.1.1/32, rev 2
        local binding:  label: 16
        remote binding: lsr: 1.1.1.1:0, label: imp-null
        remote binding: lsr: 2.2.2.2:0, label: 24000
  lib entry: 2.2.2.2/32, rev 10
        local binding:  label: 17
        remote binding: lsr: 2.2.2.2:0, label: imp-null
        remote binding: lsr: 1.1.1.1:0, label: 18
  lib entry: 3.3.3.3/32, rev 4
        local binding:  label: imp-null
        remote binding: lsr: 1.1.1.1:0, label: 16
        remote binding: lsr: 2.2.2.2:0, label: 24001
  lib entry: 10.1.3.0/24, rev 11
        no local binding
  lib entry: 10.2.3.0/24, rev 12
        no local binding

Do you notice anything else that is different? Now PE1 and PE2 advertise labels for all /32s, not just their own. (Of course, we controlled the ACLs, so we could have added all /32s to the prefix list). This is allows for FRR (fast re-route), which isn’t a possibility in this particular topology, but could be in other topologies. A router should advertise labels for all /32s for which it is a next-hop in its neighbor’s RIB. Additionally the router should advertise labels for /32s which it could become the neighbor’s nexthop upon link or node failure in the network. Therefore it’s probably easiest to just let each router advertise labels for all /32s altogether, instead of maintaining an ACL of all necessary loopbacks.

IGP Prefix Suppression

While there are no bindings for the /24s any more, they are still in the routing table. The IGP still advertises them, but did you know that we can get rid of these as well?

Currently PE2 has 10.1.3.0/24 in its routing table, but there’s no need for it:

RP/0/0/CPU0:PE2#show route ospf
Thu Jul 21 03:30:51.970 UTC

O    1.1.1.1/32 [110/3] via 10.2.3.3, 3d11h, GigabitEthernet0/0/0/0
O    3.3.3.3/32 [110/2] via 10.2.3.3, 3d11h, GigabitEthernet0/0/0/0
O    10.1.3.0/24 [110/2] via 10.2.3.3, 00:23:42, GigabitEthernet0/0/0/0

Using the prefix-suppression feature in OSPF, we can tell the router to suppress the subnets for the transit links, and only advertise the loopbacks.

#PE1, P3, PE2
router ospf 1
 prefix-suppression

The /24 is no longer in PE2’s routing table:

RP/0/0/CPU0:PE2#show route ospf
Thu Jul 21 03:34:30.535 UTC

O    1.1.1.1/32 [110/3] via 10.2.3.3, 3d11h, GigabitEthernet0/0/0/0
O    3.3.3.3/32 [110/2] via 10.2.3.3, 3d11h, GigabitEthernet0/0/0/0

You might wonder, how does PE2 know to use 10.2.3.3 for the next hop if 10.2.3.0/24 is no longer advertised in OSPF? The answer is that P3 advertises the IP address of its interface in the router LSA:

show ospf data router adv-router 3.3.3.3
<snip>
Link connected to: a Stub Network
     (Link ID) Network/subnet number: 3.3.3.3
     (Link Data) Network Mask: 255.255.255.255
      Number of TOS metrics: 0
       TOS 0 Metrics: 1

    Link connected to: another Router (point-to-point)
     (Link ID) Neighboring Router ID: 2.2.2.2
     
      Number of TOS metrics: 0
       TOS 0 Metrics: 1

PE2 uses the interface address it learns from this LSA as the nexthop in its own RIB for prefixes reachable via P3. When you have dozens of transit links, this can make a big difference to the aesthetic of the routing table, and can ease troubleshooting.

Last updated