14 mins read

RSVP – LDP Tunneling

1. Intro

You can run LDP over LSPs established by RSVP, effectively tunneling the LDP-established LSP through the one established by RSVP. To do so:

  • enable LDP on the lo0.0 interface.
  • configure the LSPs over which you want LDP to operate by including the ldp-tunneling statement.

To demonstrate LDP tunneling we will use the following topology:

LDP tunneling

As we see in the diagram, we have 2 LDP islands. Routers R1, R2, R3 and R4 have LDP configured between them and fully operational. Similarly, Routers R5, R6, R7 and R8 also have LDP configured and operational.

The issue here is that on links R3-to-R6 and R4-to-R5 there is no LDP configured. We will use RSVP with ldp-tunneling to bridge together the two LDP islands.

To test end-to-end connectivity we have configured a Cust-A VRF. We will not show the BGP/VRF configuration, instead we will focus on LDP and RSVP configuration:

### LDP is configured as described, for example see R3 config:

set protocols ldp interface ge-0/0/1.0
set protocols ldp interface ge-0/0/3.0
set protocols ldp interface ge-0/0/4.0

### LDP is Operational: 

root@R3# run show ldp session 
  Address                           State       Connection  Hold time  Adv. Mode
17.0.0.1                            Operational Open          24         DU
17.0.0.2                            Operational Open          24         DU
17.0.0.4                            Operational Open          24         DU

### If we check the inet.3 table, we only see loopbacks from our side of the network: 

root@R1# run show route table inet.3    

inet.3: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.2/32        *[LDP/9] 02:19:42, metric 1
                    >  to 17.1.2.2 via ge-0/0/1.0
17.0.0.3/32        *[LDP/9] 02:18:07, metric 1
                    >  to 17.1.3.3 via ge-0/0/2.0
17.0.0.4/32        *[LDP/9] 02:17:21, metric 1
                    >  to 17.1.2.2 via ge-0/0/1.0, Push 301648 

### We only have connectivity with our side of the network: 

root@R1# run show route table Cust-A.inet     

Cust-A.inet.0: 8 destinations, 8 routes (4 active, 0 holddown, 4 hidden)
+ = Active Route, - = Last Active, * = Both

192.168.1.0/24     *[Direct/0] 2w0d 01:22:09
                    >  via lo0.100
192.168.1.1/32     *[Local/0] 2w0d 01:22:09
                       Local via lo0.100
192.168.2.0/24     *[BGP/170] 00:02:04, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                    >  to 17.1.2.2 via ge-0/0/1.0, Push 17

root@R1# run ping 192.168.2.1 routing-instance Cust-A 
PING 192.168.2.1 (192.168.2.1): 56 data bytes
64 bytes from 192.168.2.1: icmp_seq=0 ttl=64 time=2.632 ms
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=2.420 ms
^C
--- 192.168.2.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 2.420/2.526/2.632/0.106 ms

### BGP has the prefixes from the other side of the network, but next-hops are unusable: 

root@R1# run show route table Cust-A.inet hidden 

Cust-A.inet.0: 8 destinations, 8 routes (4 active, 0 holddown, 4 hidden)
+ = Active Route, - = Last Active, * = Both

192.168.7.0/24      [BGP/170] 00:03:07, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                       Unusable
192.168.8.0/24      [BGP/170] 00:03:07, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                       Unusable

2. LDP tunneling configuration

We will configure RSVP with ldp-tunneling, in no particular order, we will start with R4:

### Activate LDP on lo0.0 and configure the RSVP LSP with ldp-tunneling: 

root@R4# show |compare 
[edit protocols ldp]
+    interface lo0.0;
[edit protocols mpls]
+    label-switched-path R4-to-R5 {
+        to 17.0.0.5;
+        ldp-tunneling;
+    }

[edit]
root@R4# commit 
commit complete

### The config was also applied on R5, and the RSVP LSPs are UP:

root@R4# run show rsvp session 
Ingress RSVP: 1 sessions
To              From            State   Rt Style Labelin Labelout LSPname 
17.0.0.5        17.0.0.4        Up       0  1 FF       -        3 R4-to-R5
Total 1 displayed, Up 1, Down 0

Egress RSVP: 1 sessions
To              From            State   Rt Style Labelin Labelout LSPname 
17.0.0.4        17.0.0.5        Up       0  1 FF       3        - R5-to-R4
Total 1 displayed, Up 1, Down 0

### Because we configured ldp-tunneling, now we have a new LDP session: 

root@R4# run show ldp neighbor extensive 
Address                             Interface       Label space ID     Hold time
17.2.4.2                            ge-0/0/3.0      17.0.0.2:0           12
  Local Transport address: 17.0.0.4, Transport address: 17.0.0.2, Configuration sequence: 6
  Up for 02:30:39
  Reference count: 1
  Hold time: 15, Proposed local/peer: 15/15
  Hello flags: none
  Neighbor types: discovered
Address                             Interface       Label space ID     Hold time
17.3.4.3                            ge-0/0/4.0      17.0.0.3:0           14
  Local Transport address: 17.0.0.4, Transport address: 17.0.0.3, Configuration sequence: 2
  Up for 02:30:39
  Reference count: 1
  Hold time: 15, Proposed local/peer: 15/15
  Hello flags: none
  Neighbor types: discovered
Address                             Interface       Label space ID     Hold time
17.0.0.5                            lo0.0           17.0.0.5:0           44
  Local Transport address: 17.0.0.4, Transport address: 17.0.0.5, Configuration sequence: 3
  Up for 00:07:13
  Reference count: 2
  Hold time: 45, Proposed local/peer: 45/45
  Hello interval: 15
  Hello flags: targeted, request send targeted
  Neighbor types: configured-tunneled

root@R4# run show ldp session 
  Address                           State       Connection  Hold time  Adv. Mode
17.0.0.2                            Operational Open          25         DU
17.0.0.3                            Operational Open          25         DU
17.0.0.5                            Operational Open          25         DU

### Notice the neighbor type is configured-tunneled instead of the usual 'discovered':

root@R4# run show ldp session 17.0.0.5 extensive 
Address: 17.0.0.5, State: Operational, Connection: Open, Hold time: 26
  Session ID: 17.0.0.4:0--17.0.0.5:0
  Next keepalive in 6 seconds
  Passive, Maximum PDU: 4096, Hold time: 30, Neighbor count: 1
  Neighbor types: configured-tunneled
  Keepalive interval: 10, Connect retry interval: 1
  Local address: 17.0.0.4, Remote address: 17.0.0.5
  Up for 00:05:14
  Capabilities advertised: none
  Capabilities received: none
  Protection: disabled
  Session flags: none
  Local - Restart: disabled, Helper mode: enabled
  Remote - Restart: disabled, Helper mode: enabled
  Local maximum neighbor reconnect time: 120000 msec
  Local maximum neighbor recovery time: 240000 msec
  Local Label Advertisement mode: Downstream unsolicited
  Remote Label Advertisement mode: Downstream unsolicited
  Negotiated Label Advertisement mode: Downstream unsolicited
  MTU discovery: disabled
  Nonstop routing state: Not in sync
  Next-hop addresses received:
    17.0.0.5
    17.5.6.5
    17.5.8.5
    128.49.225.118
  Queue depth: 0
Message type               Total                     Last 5 seconds
                       Sent      Received          Sent      Received
Initialization            1             1             0             0
Keepalive                32            32             0             0
Notification              0             0             0             0
Address                   1             1             0             0
Address withdraw          0             0             0             0
Label mapping             7             8             0             0
Label request             0             0             0             0
Label withdraw            0             0             0             0
Label release             0             0             0             0
Label abort               0             0             0             0

### Because we completed the LDP path, now we have new destinations in the inet.3 table:

root@R4# run show route table inet.3 

inet.3: 13 destinations, 17 routes (6 active, 0 holddown, 10 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.1/32        *[LDP/9] 00:09:05, metric 1
                    >  to 17.2.4.2 via ge-0/0/3.0, Push 301616
                       to 17.3.4.3 via ge-0/0/4.0, Push 303216
17.0.0.2/32        *[LDP/9] 00:09:05, metric 1
                    >  to 17.2.4.2 via ge-0/0/3.0
17.0.0.3/32        *[LDP/9] 00:09:05, metric 1
                    >  to 17.3.4.3 via ge-0/0/4.0
17.0.0.5/32        *[RSVP/7/1] 00:09:05, metric 1000
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
                    [LDP/9] 00:09:05, metric 1
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
17.0.0.7/32        *[LDP/9] 00:09:05, metric 1
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
17.0.0.8/32        *[LDP/9] 00:09:05, metric 1
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5

### Interestingly, we have also some hidden routes, in this scenario, they are often called 'shortcuts':

root@R4# run show route table inet.3 hidden 

inet.3: 13 destinations, 17 routes (6 active, 0 holddown, 10 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.5/32         [OSPF] 00:10:32, metric 1000
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
17.0.0.7/32         [OSPF] 00:10:32, metric 3000
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
17.0.0.8/32         [OSPF] 00:10:32, metric 2000
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
17.5.6.0/24         [OSPF] 00:10:32, metric 3000
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
17.5.8.0/24         [OSPF] 00:10:32, metric 2000
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
17.6.8.0/24         [OSPF] 00:10:32, metric 4000
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5
17.7.8.0/24         [OSPF] 00:10:32, metric 3000
                    >  to 17.4.5.5 via ge-0/0/2.0, label-switched-path R4-to-R5

### Note: These hidden routes are transparently created by Junos to support LDP tunneling. Junos enables the IGP shortcuts feature, which ensures that these IS-IS routes are resolved through RSVP LSPs. As this feature is not configured manually but by Junos itself (for LDP tunneling support) they are hidden so that they are not used to resolve BGP next-hops. 

### We have routes in inet.3 also on R2. 

root@R2# run show route table inet.3 

inet.3: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.1/32        *[LDP/9] 02:39:35, metric 1
                    >  to 17.1.2.1 via ge-0/0/1.0
17.0.0.3/32        *[LDP/9] 00:13:48, metric 1
                    >  to 17.1.2.1 via ge-0/0/1.0, Push 299968
                       to 17.2.3.3 via ge-0/0/2.0
                       to 17.2.4.4 via ge-0/0/3.0, Push 302112
17.0.0.4/32        *[LDP/9] 02:37:14, metric 1
                    >  to 17.2.4.4 via ge-0/0/3.0
17.0.0.5/32        *[LDP/9] 00:13:48, metric 1
                    >  to 17.2.4.4 via ge-0/0/3.0, Push 302208
17.0.0.7/32        *[LDP/9] 00:13:48, metric 1
                    >  to 17.2.4.4 via ge-0/0/3.0, Push 302240
17.0.0.8/32        *[LDP/9] 00:13:48, metric 1
                    >  to 17.2.4.4 via ge-0/0/3.0, Push 302224

### MP-BGP is now ok: 

root@R2# run show route table Cust-A.inet    

Cust-A.inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

192.168.1.0/24     *[BGP/170] 00:10:02, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                    >  to 17.1.2.1 via ge-0/0/1.0, Push 16
192.168.2.0/24     *[Direct/0] 00:03:56
                    >  via lo0.100
192.168.2.1/32     *[Local/0] 00:03:56
                       Local via lo0.100
192.168.7.0/24     *[BGP/170] 00:02:12, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                    >  to 17.2.4.4 via ge-0/0/3.0, Push 16, Push 302192(top)
192.168.8.0/24     *[BGP/170] 00:02:12, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                    >  to 17.2.4.4 via ge-0/0/3.0, Push 16, Push 302176(top)

### And ping works between the two sides of the network:

root@R2# run ping 192.168.8.1 routing-instance Cust-A 
PING 192.168.8.1 (192.168.8.1): 56 data bytes
64 bytes from 192.168.8.1: icmp_seq=0 ttl=62 time=4.275 ms
64 bytes from 192.168.8.1: icmp_seq=1 ttl=62 time=4.087 ms
64 bytes from 192.168.8.1: icmp_seq=2 ttl=62 time=5.206 ms
^C
--- 192.168.8.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 4.087/4.523/5.206/0.489 ms

### We can see the labeled icmp packets over the R4-to-R5 link: 

14:57:25.821254 MPLS (label 302144, exp 0, ttl 63) (label 17, exp 0, [S], ttl 64) IP 192.168.8.1 > 192.168.2.1: ICMP echo reply, id 22634, seq 63334, length 64
14:57:25.823948 MPLS (label 302048, exp 0, ttl 63) (label 16, exp 0, [S], ttl 64) IP 192.168.2.1 > 192.168.8.1: ICMP echo request, id 22634, seq 63335, length 64

3. Config is not complete

We are not quite done yet, some prefixes are still missing, R1 has no connection to R7. This is because we only configured the R4-to-R5 link, the R3-to-R6 link was not yet configured with ldp-tunneling. As a result, even on the R2 and R4 routers some prefixes are missing:

To conclude, full end to end path, is based on the underlying IGP protocol. Configuring one LSP with ldp-tunneling between the two LDP islands is not enough, because the IGP protocol (OSPF in our case) is using both links (R4-R5 and R3-R6) to reach different destination, so we must configure ldp-tunneling on both links.

### Let's configure the LSP between R3 and R6: 

set protocols ldp interface lo0.0
set protocols mpls label-switched-path R3-to-R6 to 17.0.0.6
set protocols mpls label-switched-path R3-to-R6 ldp-tunneling
set protocols mpls label-switched-path R3-to-R6 primary PATH-TO-R6
set protocols mpls path PATH-TO-R6 17.0.0.4
set protocols mpls path PATH-TO-R6 17.0.0.5
set protocols mpls path PATH-TO-R6 17.0.0.6

### As you can see, for testing purposes, we will set a custom path between R3 and R6. 
### We are actually using R3-R4-R5-R6, and R5 is configured the same: 

### RSVP is sessions are UP: 

root@R3# run show rsvp session 
Ingress RSVP: 1 sessions
To              From            State   Rt Style Labelin Labelout LSPname 
17.0.0.6        17.0.0.3        Up       0  1 FF       -   302256 R3-to-R6
Total 1 displayed, Up 1, Down 0

Egress RSVP: 1 sessions
To              From            State   Rt Style Labelin Labelout LSPname 
17.0.0.3        17.0.0.6        Up       0  1 FF       3        - R6-to-R3
Total 1 displayed, Up 1, Down 0

Transit RSVP: 0 sessions
Total 0 displayed, Up 0, Down 0

### We know this already, R3 know what IGP shortcuts to calculate: 

root@R3# run show route table inet.3 hidden 

inet.3: 16 destinations, 21 routes (7 active, 0 holddown, 13 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.5/32         [OSPF] 00:04:29, metric 3000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6
17.0.0.6/32         [OSPF] 00:04:29, metric 1000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6
17.0.0.7/32         [OSPF] 00:04:29, metric 2000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6
17.0.0.8/32         [OSPF] 00:04:29, metric 3000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6
17.5.6.0/24         [OSPF] 00:04:29, metric 3000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6
17.5.8.0/24         [OSPF] 00:04:29, metric 4000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6
17.6.7.0/24         [OSPF] 00:04:29, metric 2000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6
17.6.8.0/24         [OSPF] 00:04:29, metric 3000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6
17.7.8.0/24         [OSPF] 00:04:29, metric 3000
                    >  to 17.3.4.4 via ge-0/0/4.0, label-switched-path R3-to-R6

### Now R1 has all prefixes: 

root@R1# run show route table inet.3    

inet.3: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.2/32        *[LDP/9] 03:31:38, metric 1
                    >  to 17.1.2.2 via ge-0/0/1.0
17.0.0.3/32        *[LDP/9] 03:30:03, metric 1
                    >  to 17.1.3.3 via ge-0/0/2.0
17.0.0.4/32        *[LDP/9] 03:29:17, metric 1
                    >  to 17.1.2.2 via ge-0/0/1.0, Push 301648
17.0.0.5/32        *[LDP/9] 01:05:51, metric 1
                    >  to 17.1.2.2 via ge-0/0/1.0, Push 301712
17.0.0.6/32        *[LDP/9] 00:01:35, metric 1
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 303296
17.0.0.7/32        *[LDP/9] 00:00:15, metric 1
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 303344
17.0.0.8/32        *[LDP/9] 00:00:15, metric 1
                       to 17.1.2.2 via ge-0/0/1.0, Push 301728
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 303360

### R2 also has all the routes now: 

root@R2# run show route table inet.3 

inet.3: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.1/32        *[LDP/9] 03:35:31, metric 1
                    >  to 17.1.2.1 via ge-0/0/1.0
17.0.0.3/32        *[LDP/9] 01:09:44, metric 1
                    >  to 17.1.2.1 via ge-0/0/1.0, Push 299968
                       to 17.2.3.3 via ge-0/0/2.0
                       to 17.2.4.4 via ge-0/0/3.0, Push 302112
17.0.0.4/32        *[LDP/9] 03:33:10, metric 1
                    >  to 17.2.4.4 via ge-0/0/3.0
17.0.0.5/32        *[LDP/9] 01:09:44, metric 1
                    >  to 17.2.4.4 via ge-0/0/3.0, Push 302208
17.0.0.6/32        *[LDP/9] 00:05:29, metric 1
                       to 17.1.2.1 via ge-0/0/1.0, Push 300064
                    >  to 17.2.3.3 via ge-0/0/2.0, Push 303296
                       to 17.2.4.4 via ge-0/0/3.0, Push 302272
17.0.0.7/32        *[LDP/9] 00:04:08, metric 1
                       to 17.1.2.1 via ge-0/0/1.0, Push 300096
                    >  to 17.2.3.3 via ge-0/0/2.0, Push 303344
                       to 17.2.4.4 via ge-0/0/3.0, Push 302240
17.0.0.8/32        *[LDP/9] 01:09:44, metric 1
                    >  to 17.2.4.4 via ge-0/0/3.0, Push 302224

### The Cust-A VRF has all routes:

root@R1# run show route table Cust-A.inet   

Cust-A.inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

192.168.1.0/24     *[Direct/0] 2w0d 02:37:50
                    >  via lo0.100
192.168.1.1/32     *[Local/0] 2w0d 02:37:50
                       Local via lo0.100
192.168.2.0/24     *[BGP/170] 01:11:35, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                    >  to 17.1.2.2 via ge-0/0/1.0, Push 17
192.168.7.0/24     *[BGP/170] 00:07:19, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 16, Push 303344(top)
192.168.8.0/24     *[BGP/170] 01:11:35, localpref 100, from 17.0.0.4
                      AS path: I, validation-state: unverified
                    >  to 17.1.2.2 via ge-0/0/1.0, Push 16, Push 301728(top)
                       to 17.1.3.3 via ge-0/0/2.0, Push 16, Push 303360(top)

### All pings are working now: 

root@R1# run ping 192.168.7.1 routing-instance Cust-A 
PING 192.168.7.1 (192.168.7.1): 56 data bytes
64 bytes from 192.168.7.1: icmp_seq=0 ttl=60 time=7.315 ms
64 bytes from 192.168.7.1: icmp_seq=1 ttl=60 time=7.000 ms
^C
--- 192.168.7.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 7.000/7.158/7.315/0.157 ms

### With TCPDUMP we can see the packets on our custom path R3-R4-R5-R6:
### Capture was made on R4-R5 link:

15:45:57.462216 MPLS (label 302208, exp 0, ttl 62) (label 302976, exp 0, ttl 63) (label 16, exp 0, [S], ttl 64) IP 192.168.1.1 > 192.168.7.1: ICMP echo request, id 35461, seq 7, length 64
15:45:57.465030 MPLS (label 302288, exp 0, ttl 62) (label 303216, exp 0, ttl 63) (label 16, exp 0, [S], ttl 64) IP 192.168.7.1 > 192.168.1.1: ICMP echo reply, id 35461, seq 7, length 64

### One label is for the RSVP LSP, the other is for LDP.

External Resources: