LDP Session Protection

LDP session protection is a feature which automatically creates targeted LDP neighborships for all directly connected neighbors. When this feature is turned on, each directly connected neighbor has two discovery methods - one through the dynamic discovery on the interface, and one through the targeted LDP session.

What is the benefit of this? If the interface used to reach the LDP neighbor goes down, by default the LDP session goes down and all label bindings are lost. When the interface comes back up, both IGP and LDP have to reconverge. However, LDP neighbors can be multiple hops away by using a targeted session. (Remember that LDP uses a TCP session which is multihop-capable). When you turn on session protection and the interface used to reach the directly connected neighbor goes down, the targeted session to that same neighbor stays up as long as there is an alternative path to reach that neighbor.

While this interface is down, you won’t actually use the label bindings for traffic, because that neighbor is no longer directly connected and no longer a nexthop for prefixes in the RIB. The IGP takes care of that part (reconvergence). But when the directly connected interface comes back up, you don’t have to rebuild the label bindings database for the neighbor and reconverge on LDP, because the session stayed up the entire time.

The benefit of session protection is mostly seen when links are flapping up and down. You have to continuously reconverge on the IGP, but when using LDP session protection, LDP does not have to continually rebuild the session and LIB as long as there is an alternative route to the neighbor.

In this article, we’ll first lab targeted sessions only. You might be used to using targeted sessions with Martini circuits (which forms targeted LDP sessions automatically based on neighbor statements in L2VPNs). We can also form targeted sessions manually. After we explore manual targeted sessions, we’ll enable session protection, which is essentially just automatic target session for all dynamically discovered neighbors.

Lab - Targeted LDP Sessions (Manual)

We’ll re-use the lab from the LDP/IGP Sync article, but with no LDP authentication.

Let’s first configure a targeted LDP session between PE1 and P4.

#PE1
mpls ldp neighbor 4.4.4.4 targeted

PE1 begins sending UDP/646 Hellos directly to 4.4.4.4. This is the same Hello message that would be multicast on a link to discover neighbors. But instead it is unicast to the specifed neighbor IP since this is a targeted session.

Notice that P4 is rejecting the UDP connection. This is because P4 is not accepting targeted sessions. We have two options to get the targeted session up. We can configure P4 to accept all targeted LDP sessions (unconditionally or based on an ACL of permitted LDP peers) or configure P4 for a targeted session specifically to PE1. Let’s first allow incoming targeted LDP sessions on P4.

#P4
mpls ldp address-family ipv4 discovery targeted-hello accept

PE1 and P4 now form a neighborship session and exchange label bindings:

We can see that the neighbor is discovered via a targeted Hello as opposed to discovered on an interface. PE1 lists itself as active and P4 lists itself as passive indicating their roles in initiating the targeted session.

PE1#show mpls ldp neighbor 4.4.4.4
    Peer LDP Ident: 4.4.4.4:0; Local LDP Ident 1.1.1.1:0
        TCP connection: 4.4.4.4.15630 - 1.1.1.1.646
        State: Oper; Msgs sent/rcvd: 14/14; Downstream
        Up time: 00:01:13
        LDP discovery sources:
          
        Addresses bound to peer LDP Ident:
          10.2.4.4        10.3.4.4        10.4.5.4        4.4.4.4

RP/0/0/CPU0:P4#show mpls ldp neighbor 1.1.1.1
Thu Jul 28 14:18:59.388 UTC

Peer LDP Identifier: 1.1.1.1:0
  TCP connection: 1.1.1.1:646 - 4.4.4.4:15630
  Graceful Restart: No
  Session Holdtime: 180 sec
  State: Oper; Msgs sent/rcvd: 15/15; Downstream-Unsolicited
  Up time: 00:02:03
  LDP Discovery Sources:
    IPv4: (1)
      
    IPv6: (0)
  Addresses bound to this peer:
    IPv4: (2)
      1.1.1.1        10.1.3.1       
    IPv6: (0)

Let’s remove the unconditional targeted-hello acceptance on P4 (which brings the session down), then configure 1.1.1.1 as an explicit peer on P4.

#P4
no mpls ldp address-family ipv4 discovery target-hello accept
commit

mpls ldp address-family ipv4 neighbor 1.1.1.1 targeted

PE1 now lists itself as active, passive. I’m assuming this refers to the fact that it is configured to explicity form a session with 1.1.1.1, but it is currently the passive endpoint in the TCP connection. Notice the connection uses a random port on P4 (since P4 initiated the connection) and port 646 on PE1.

PE1#show mpls ldp neighbor 4.4.4.4
    Peer LDP Ident: 4.4.4.4:0; Local LDP Ident 1.1.1.1:0
        TCP connection: 4.4.4.4.61782 - 1.1.1.1.646
        State: Oper; Msgs sent/rcvd: 13/13; Downstream
        Up time: 00:00:19
        LDP discovery sources:
          
        Addresses bound to peer LDP Ident:
          10.2.4.4        10.3.4.4        10.4.5.4        4.4.4.4


RP/0/0/CPU0:P4#show mpls ldp neighbor 1.1.1.1
Thu Jul 28 14:22:08.115 UTC

Peer LDP Identifier: 1.1.1.1:0
  TCP connection: 1.1.1.1:646 - 4.4.4.4:61782
  Graceful Restart: No
  Session Holdtime: 180 sec
  State: Oper; Msgs sent/rcvd: 13/13; Downstream-Unsolicited
  Up time: 00:00:09
  LDP Discovery Sources:
    IPv4: (1)
      Targeted Hello (4.4.4.4 -> 1.1.1.1, active)
    IPv6: (0)
  Addresses bound to this peer:
    IPv4: (2)
      1.1.1.1        10.1.3.1

Lab - LDP Session Protection

LDP session protection is essentially just automatic targeted sessions to your directly connected neighbors. Let’s enable session protection on all PE/P routers.

#PE1, P3, P5 (IOS-XE routers)
mpls ldp session protection
 
#P4, PE3 (IOS-XR routers)
mpls ldp session protection

Optionally you can configure a duration, which limits how long the session stays up after the directly connected neighbor is lost. By default the duration is infinite. If it is up for longer than say, 30 mins, you may want to just let LDP bring the session down and let LDP fully reconverge once the interface is back up.

You can also use the for keyword to specify an ACL to limit which LDP peers you enable session protection for.

Configuring LDP session protection automatically enables the acceptance of targeted Hellos. It also automatically creates a targeted session to every automatically discovered neighbor. (Neighbors are discoverged automatically on an interface by multicasting Hellos to 224.0.0.2 on UDP/646 and receiving replies to the same multicast IP from neighbors).

Let’s look at the LDP neighbor table on PE1:

PE1#show mpls ldp neighbor 
    Peer LDP Ident: 3.3.3.3:0; Local LDP Ident 1.1.1.1:0
        TCP connection: 3.3.3.3.27763 - 1.1.1.1.646
        State: Oper; Msgs sent/rcvd: 1677/1677; Downstream
        Up time: 1d00h
        LDP discovery sources:
          
          
        Addresses bound to peer LDP Ident:
          10.1.3.3        10.3.4.3        10.3.5.3        3.3.3.3         
    Peer LDP Ident: 4.4.4.4:0; Local LDP Ident 1.1.1.1:0
        TCP connection: 4.4.4.4.61782 - 1.1.1.1.646
        State: Oper; Msgs sent/rcvd: 48/47; Downstream
        Up time: 00:30:01
        LDP discovery sources:
          Targeted Hello 1.1.1.1 -> 4.4.4.4, active, passive
        Addresses bound to peer LDP Ident:
          10.2.4.4        10.3.4.4        10.4.5.4        4.4.4.4

Notice that the session to P3 has two discovery sources now. 1) The interface and 2) the targeted Hello. The targeted session we manually created to P4 still only has a single discovery source. Nothing has changed with that LDP neighbor. In fact, you could say that any regular targeted session already has session protection. In this sense, if you were to manually configure targeted sessions between all directly connected neighbors, you would have accomplished the same thing as turning on session protection.

If we take a pcap on the link between PE1 and P3, we see three Hellos. Two are to P3. One is the targeted session using the loopbacks as the src/dst, and one is sourced from Gi2 to 224.0.0.2. The third Hello is the targeted manual session between PE1 and P4.

Let’s shut down the link between P3 and P5 and see what happens. First we examine the remote label bindings for P5, and the existing neighbor session.

P3#show mpls ldp bindings neighbor 5.5.5.5  
  lib entry: 1.1.1.1/32, rev 10
        remote binding: lsr: 5.5.5.5:0, label: 16
  lib entry: 2.2.2.2/32, rev 21
        remote binding: lsr: 5.5.5.5:0, label: 22
  lib entry: 3.3.3.3/32, rev 2
        remote binding: lsr: 5.5.5.5:0, label: 17
  lib entry: 4.4.4.4/32, rev 17
        remote binding: lsr: 5.5.5.5:0, label: 20
  lib entry: 5.5.5.5/32, rev 13
        remote binding: lsr: 5.5.5.5:0, label: imp-null
  lib entry: 10.1.3.0/24, rev 4
        remote binding: lsr: 5.5.5.5:0, label: 18
  lib entry: 10.2.4.0/24, rev 19
        remote binding: lsr: 5.5.5.5:0, label: 21
  lib entry: 10.3.4.0/24, rev 6
        remote binding: lsr: 5.5.5.5:0, label: 19
  lib entry: 10.3.5.0/24, rev 8
        remote binding: lsr: 5.5.5.5:0, label: imp-null
  lib entry: 10.4.5.0/24, rev 15
        remote binding: lsr: 5.5.5.5:0, label: imp-null

P3#show mpls ldp neighbor 5.5.5.5        
    Peer LDP Ident: 5.5.5.5:0; Local LDP Ident 3.3.3.3:0
        TCP connection: 5.5.5.5.19070 - 3.3.3.3.646
        State: Oper; Msgs sent/rcvd: 2324/2325; Downstream
        Up time: 1d09h
        LDP discovery sources:
          GigabitEthernet3, Src IP addr: 10.3.5.5
          Targeted Hello 3.3.3.3 -> 5.5.5.5, active, passive
        Addresses bound to peer LDP Ident:
          10.3.5.5        10.4.5.5        5.5.5.5

We shutdown Gi3 of P3, and see that the neighbor is still up, and we still have the remote label bindings for the peer.

P3(config)#int gi3
P3(config-if)#shut
P3(config-if)#end
P3#show mpls ldp neighbor 
*Jul 29 00:24:17.683: %LINK-5-CHANGED: Interface GigabitEthernet3, changed state to administratively down
*Jul 29 00:24:18.683: %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet3, changed state to down
P3#show mpls ldp neighbor 5.5.5.5
    Peer LDP Ident: 5.5.5.5:0; Local LDP Ident 3.3.3.3:0
        TCP connection: 5.5.5.5.19070 - 3.3.3.3.646
        State: Oper; Msgs sent/rcvd: 2326/2326; Downstream
        Up time: 1d09h
        LDP discovery sources:
          Targeted Hello 3.3.3.3 -> 5.5.5.5, active, passive
        Addresses bound to peer LDP Ident:
          10.3.5.5        10.4.5.5        5.5.5.5         

P3#show mpls ldp bindings neighbor 5.5.5.5
  lib entry: 1.1.1.1/32, rev 10
        remote binding: lsr: 5.5.5.5:0, label: 16
  lib entry: 2.2.2.2/32, rev 21
        remote binding: lsr: 5.5.5.5:0, label: 22
  lib entry: 3.3.3.3/32, rev 2
        remote binding: lsr: 5.5.5.5:0, label: 17
  lib entry: 4.4.4.4/32, rev 17
        remote binding: lsr: 5.5.5.5:0, label: 20
  lib entry: 5.5.5.5/32, rev 13
        remote binding: lsr: 5.5.5.5:0, label: imp-null
  lib entry: 10.1.3.0/24, rev 4
        remote binding: lsr: 5.5.5.5:0, label: 18
  lib entry: 10.2.4.0/24, rev 19
        remote binding: lsr: 5.5.5.5:0, label: 21
  lib entry: 10.3.4.0/24, rev 6
        remote binding: lsr: 5.5.5.5:0, label: 19
  lib entry: 10.3.5.0/24, rev 23
        remote binding: lsr: 5.5.5.5:0, label: imp-null
  lib entry: 10.4.5.0/24, rev 15
        remote binding: lsr: 5.5.5.5:0, label: imp-null

P3#show mpls forwarding-table 5.5.5.5
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop    
Label      Label      or Tunnel Id     Switched      interface              
17         24002      5.5.5.5/32       0             Gi2        10.3.4.4

The label bindings are retained because the targeted session to P5 is still up. However, none of these label bindings are actually in use in the LFIB, since P5 is not a nexthop for any prefixes in the RIB. We see this above with P5’s own loopback. The nexthop is P4 via Gi2 with the label that P4 advertised for this prefix.

So the only benefit to session protection is that when we bring the link back up, we will re-discover the neighbor on the interface, but not have to exchange label binding information. Let’s enable Gi3 again and take a pcap on the link.

P3(config)#int gi3
P3(config-if)#no shut
P3(config-if)#end

*Jul 29 00:27:08.524: %LINK-3-UPDOWN: Interface GigabitEthernet3, changed state to up
P3#show mpls ldp neighbor 5.5.5.5
    Peer LDP Ident: 5.5.5.5:0; Local LDP Ident 3.3.3.3:0
        TCP connection: 5.5.5.5.19070 - 3.3.3.3.646
        State: Oper; Msgs sent/rcvd: 2332/2331; Downstream
        Up time: 1d09h
        LDP discovery sources:
          Targeted Hello 3.3.3.3 -> 5.5.5.5, active, passive
          GigabitEthernet3, Src IP addr: 10.3.5.5
        Addresses bound to peer LDP Ident:
          10.3.5.5        10.4.5.5        5.5.5.5         
P3#
*Jul 29 00:27:08.546: %LDP-5-SP: 5.5.5.5:0: session recovery succeeded
*Jul 29 00:27:09.524: %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet3, changed state to up
P3#
*Jul 29 00:27:09.553: %CLNS-5-ADJCHANGE: ISIS: Adjacency to P5 (GigabitEthernet3) Up, new adjacency

  • LDP only needs to rediscover the neighbor and maintain it using the multicasted Hello. ISIS has to completely reconverge.

  • P3 has allocated a new label for the 10.3.5.0/24 prefix, since that link flapped. This is the only label information exchanged by LDP during this process. The targeted session now uses the connected interface again. The targeted session simply follows the IGP path.

Pop quiz! What happens if one router configures session protection, and the other router simply accepts targeted hellos (without configuring session protection)? Does the feature fully work on both routers? Only one? None? Think this through on your own, and then we will test it out.

We’ll test this scenario between P3 and P4. Let’s turn session protection off on P4, verify that the targeted session is down on P3, and then accept targeted hellos on P4.

#P4
no mpls ldp session protection

P3#show mpls ldp neighbor 4.4.4.4
    Peer LDP Ident: 4.4.4.4:0; Local LDP Ident 3.3.3.3:0
        TCP connection: 4.4.4.4.41040 - 3.3.3.3.646
        State: Oper; Msgs sent/rcvd: 732/732; Downstream
        Up time: 10:27:54
        LDP discovery sources:
          GigabitEthernet2, Src IP addr: 10.3.4.4
        Addresses bound to peer LDP Ident:
          10.2.4.4        10.3.4.4        10.4.5.4        4.4.4.4

When using session protection, an LDP neighborship uses a single TCP connection but two discovery methods for maintaining the neighbor’s aliveness. Above we can see that the existing TCP session between 3.3.3.3 and 4.4.4.4 stays up. P4 just stops responding to the targeted hellos from 3.3.3.3. It only responds to the multicasted Hellos it sees on the interface connecting to P3. Therefore the only discovery source is now the interface (Gi2).

Let’s accept targeted hellos on P4 now.

#P4
mpls ldp address-family ipv4 discovery targeted hello accept

P3#show mpls ldp neighbor 4.4.4.4
    Peer LDP Ident: 4.4.4.4:0; Local LDP Ident 3.3.3.3:0
        TCP connection: 4.4.4.4.41040 - 3.3.3.3.646
        State: Oper; Msgs sent/rcvd: 734/734; Downstream
        Up time: 10:29:37
        LDP discovery sources:
          GigabitEthernet2, Src IP addr: 10.3.4.4
          Targeted Hello 3.3.3.3 -> 4.4.4.4, active
        Addresses bound to peer LDP Ident:
          10.2.4.4        10.3.4.4        10.4.5.4        4.4.4.4

The target session is seen as a discovery source on P3 again.

RP/0/0/CPU0:P4#show mpls ldp neighbor 3.3.3.3
Fri Jul 29 00:39:47.896 UTC

Peer LDP Identifier: 3.3.3.3:0
  TCP connection: 3.3.3.3:646 - 4.4.4.4:41040
  Graceful Restart: No
  Session Holdtime: 180 sec
  State: Oper; Msgs sent/rcvd: 734/735; Downstream-Unsolicited
  Up time: 10:30:12
  LDP Discovery Sources:
    IPv4: (2)
      GigabitEthernet0/0/0/1
      Targeted Hello (4.4.4.4 -> 3.3.3.3, passive)
    IPv6: (0)
  Addresses bound to this peer:
    IPv4: (4)
      3.3.3.3        10.1.3.3       10.3.4.3       10.3.5.3       
    IPv6: (0)

The output above on P4 looks identical to when ldp session protection was enabled. Let’s bounce Gi2 on P3, which connects to P4, and take a pcap.

P3(config)#int gi2
P3(config-if)#shut
P3(config-if)#end
P3#
*Jul 29 00:40:16.238: %LDP-5-SP: 4.4.4.4:0: session hold up initiated

*Jul 29 00:40:18.228: %LINK-5-CHANGED: Interface GigabitEthernet2, changed state to administratively down
*Jul 29 00:40:19.229: %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet2, changed state to down
P3#show mpls ldp neighbor 4.4.4.4
    Peer LDP Ident: 4.4.4.4:0; Local LDP Ident 3.3.3.3:0
        TCP connection: 4.4.4.4.41040 - 3.3.3.3.646
        State: Oper; Msgs sent/rcvd: 736/735; Downstream
        Up time: 10:30:57
        LDP discovery sources:
          Targeted Hello 3.3.3.3 -> 4.4.4.4, active
        Addresses bound to peer LDP Ident:
          10.2.4.4        10.3.4.4        10.4.5.4        4.4.4.4

This works just as if P4 was configured for mpls ldp session protection. Notice that P3 did not actually send its own ISIS Hello until 60 seconds after the interface came up. Why is this? We left the sync delay set to 60 on this interface from the previous article!

P3#show run int gi2
interface GigabitEthernet2
 ip address 10.3.4.3 255.255.255.0
 ip router isis 
 negotiation auto
 mpls ip
 mpls ldp igp sync delay 60

Conclusion

The LDP Session Protection feature retains label bindings when a directly connected interface to an LDP neighbor goes down. It does this by forming a target LDP session to evey dynamically discovered neighbor. If the link to a neighbor goes down, the IGP routes around the failure, and the targeted session (being multihop in nature) remains up. When the directly connected interface goes up, the neighbors do not need to exchange label bindings again.

Whether you should actually implement this in your environment is up for debate. There is some overhead added with this feature, as every dynamically discovered neighbor needs to be maintained twice. Once using the interface multicast Hello (as normal), and once using a targeted Hello. This doubles the amount of LDP Hello traffic in your network. The benefit is quite minor too. The IGP has to converge anyways, so exchanging label bindings is not too big of a deal in my eyes.

The real benefit, I believe, comes when you do not have LDP/IGP sync enabled. When a link flaps, without either LDP sync or Session Protection enabled, you risk the IGP converging slightly faster, and IP routing VPN traffic before LDP comes up. Using Session Protection to retain label bindings prevents the need for LDP/IGP sync in this scenario. The LDP session is by default already converged before the IGP does.

However, I would argue that using only LDP/IGP sync is better than using only Session Protection. This is because if a link flaps on a stub router which only has one link to the MPLS network, then you have to reconverge on LDP anyways when the link comes back up. So if the targeted LDP session is lost, Session Protection does nothing, and you need LDP/IGP sync to prevent blackholing VPN traffic. Therefore I would personally recommend to only use LDP/IGP sync and not worry about enabling Session Protection.

Last updated