MPLS-TE Basics, Pt.4 (Routing)

In this final section we will steer traffic into our tunnel. As a reminder here is the topology:

We currently have tun1 up which creates an LSP from R1 to XR5, but traffic is not using this tunnel yet, as we saw in the last section (Pt. 3).

The simplest way to steer traffic into this tunnel is to create a static route to the destination pointing out the tunnel interface:

#R1
ip route 5.5.5.5 255.255.255.255 tunnel1
end

show ip route 5.5.5.5
Routing entry for 5.5.5.5/32
  Known via "static", distance 1, metric 0 (connected)
  Routing Descriptor Blocks:
  * directly connected, via Tunnel1
      Route metric is 0, traffic share count is 1

traceroute 5.5.5.5 probe 1
Type escape sequence to abort.
Tracing the route to 5.5.5.5
VRF info: (vrf in name/id, vrf out name/id)
  1 10.1.2.2 [MPLS: Label 17 Exp 0] 109 msec
  2 10.2.4.4 [MPLS: Label 16 Exp 0] 18 msec
  3 10.3.4.3 [MPLS: Label 24001 Exp 0] 8 msec
  4 10.3.5.5 6 msec

As you can see, now IP traffic destined to 5.5.5.5 is routed through the tunnel along the CSPF bestpath.

Autoroute Announce

A better approach is to use the autoroute announce feature under the tunnel interface. This essentially inserts the tunnel as a valid path to the IGP when the router locally runs SPF. The tunnel is not advertised to other routers, but instead the tunnel is a usable link from the perspective of the local router’s IGP process.

Let’s remove the static route and use this feature.

#R1
no ip route 5.5.5.5 255.255.255.255 tunnel1
!
int tun1
 tunnel mpls traffic-eng autoroute announce
end

show ip route 5.5.5.5
Routing entry for 5.5.5.5/32
  Known via "isis", distance 115, metric 40, type level-1
  Redistributing via isis
  Last update from 5.5.5.5 on Tunnel1, 00:00:03 ago
  Routing Descriptor Blocks:
  * 5.5.5.5, from 5.5.5.5, 00:00:03 ago, via Tunnel1
      Route metric is 40, traffic share count is 1

Notice that the route is now know via ISIS. The metric is 40 which seems odd, as the metric should be 50, right? (R1-R2=10, R2-R4=10, R4-XR3=10, XR3-XR5=10, XR5-Lo0=10).

  • (IGP cost of the path the tunnel takes)

The reason it is 40 is because, by deafult, the tunnel metric will be the IGP shortest metric to that destination, not the metric of the real path that the tunnel takes.

  • (IGP shortest path cost to 5.5.5.5/32, which the tunnel uses for its metric).

We can change the metric that the tunnel is announced as by using tunnel mpls traffic-eng autoroute metric.

R1(config-if)#tunnel mpls traffic-eng autoroute metric ?
  <1-4294967295>  Set tunnel metric for autoroutes
  absolute        Set metric for all autoroutes over tunnel
  relative        Adjust tunnel metric for autoroutes relative to IGP
  • absolute sets an explicit value for the tunnel metric.

  • relative can be a value from -10 to +10 and sets the tunnel metric to a value relative to the IGP bestpath to that destination. For example, if I use relative -5, the metric will now be 35.

So if the IGP sees a TE tunnel with cost 40, and IGP path with cost 40, why is traffic not load balanced? This is due to a very specific rule when it comes to load balancing with TE tunnels. If the destination (in this case 5.5.5.5) is in the IP forwarding path, then no load balancing occurs, only the tunnel is used. If the destination is not in the IP forwarding path and that path has an equal cost to a tunnel, then load balancing does occur.

How exactly can the destination not be in the IP forwarding path? If there is a destination beyond XR5, such as R6, and there is an IP path that does not take XR5, then it is possible to load balance traffic to R6 with the IP route and the TE tunnel.

Let’s experiment with this. Change the tunnel metric to a relative value of positive 5 and see what happens in the routing table.

#R1
int tun1
 tunnel mpls traffic-eng autoroute metric relative 5
end

show ip route 5.5.5.5
Routing entry for 5.5.5.5/32
  Known via "isis", distance 115, metric 40, type level-1
  Redistributing via isis
  Last update from 10.1.2.2 on GigabitEthernet1, 00:00:24 ago
  Routing Descriptor Blocks:
  * 10.1.2.2, from 5.5.5.5, 00:00:24 ago, via GigabitEthernet1
      Route metric is 40, traffic share count is 1

The routing entry is back to the IP route with a best path of 40. SPF evaluated the tunnel with a cost of 45 and the IGP path with cost 40 wins.

Let’s change the tunnel to a metric 5 below the IGP cost.

#R1
int tun1
 tunnel mpls traffic-eng autoroute metric relative -5
end

show ip route 5.5.5.5
Routing entry for 5.5.5.5/32
  Known via "isis", distance 115, metric 35, type level-1
  Redistributing via isis
  Last update from 5.5.5.5 on Tunnel1, 00:00:05 ago
  Routing Descriptor Blocks:
  * 5.5.5.5, from 5.5.5.5, 00:00:05 ago, via Tunnel1
      Route metric is 35, traffic share count is 1

The best path is tunnel1 again.

As a review, what happens if you remove the autoroute metric altogether?

Answer: The tunnel defaults to a metric equal to the IGP shortest path to the destination, which is 40. SPF sees two equal cost paths, but the IGP path contains the destination (5.5.5.5) so it is not eligible for load balancing. Only the tunnel is used.

#R1
int tun1
 no tunnel mpls traffic-eng autoroute metric 
end

show ip route 5.5.5.5
Routing entry for 5.5.5.5/32
  Known via "isis", distance 115, metric 35, type level-1
  Redistributing via isis
  Last update from 5.5.5.5 on Tunnel1, 00:00:05 ago
  Routing Descriptor Blocks:
  * 5.5.5.5, from 5.5.5.5, 00:00:05 ago, via Tunnel1
      Route metric is 35, traffic share count is 1

Forwarding Adjacency (FA)

We can take this one step further and advertise the tunnel into the IGP so other routers can use it in their path calculations. This feature is called forwarding adjacency, sometimes abreviated as FA. To do this, you need a bidirectional LSP in order to create a sort of p2p link from the IGP’s perspective. Right now we have a unidirectional LSP only - from R1 to XR5. The IGP on other routers will only use this “link” in calculations if there is an LSP in the opposite direction, from XR5 to R1. Let’s create this LSP on XR5 and advertise the tunnel into the IGP. This also gives us an opprotunity to configure a TE tunnel on XR.

#R1
int tun1
 tunnel mpls traffic-eng forwarding-adjacency

#XR5
int tunnel-te 1
 destination 1.1.1.1
 ipv4 unnumbered lo0
 path-option 1 dynamic
 forwarding-adjacency

#R1
show isis database R1.00-00 verbose


IS-IS Level-1 LSP R1.00-00
LSPID                 LSP Seq Num  LSP Checksum  LSP Holdtime/Rcvd      ATT/P/OL
R1.00-00            * 0x000000D2   0x0CF5                1021/*         0/0/0
<snip>
  Metric: 10         IS-Extended XR5.00
  IP Address:   1.1.1.1
<snip>

R1 now has a p2p connection to XR5. The default ISIS metric of an interface is 10, which is why the tunnel is advertised with a metric of 10.

Forwarding Adjacency with OSPF

OSPF has a few quirks when using forwarding adjacency that are worth pointing out.

When enabling forwarding-adjacency with OSPF on a tunnel interface, OSPF calculates the cost using the bandwidth as it would for a normal interface. The problem is that, by default, the tunnel bandwidth is very low, at least on the CSR1000v platform that I am using to test with.

R2#show int tun7 | in BW
  MTU 9996 bytes, BW 100 Kbit/sec, DLY 50000 usec,

The RSVP bandwidth reservation (tunnel mpls traffic-eng bandwidth) has nothing to do with the tunnel “physical line” bandwidth as seen by OSPF. You can either set the bandwidth of the tunnel using the normal bandwidth command, or just explicitly set the cost using ip ospf cost.

Secondly, the way you enable OSPF for the interface is a little counter-intuitive. You might think you can simply add tunnel mpls traffic-eng forwarding-adjacency and it will be advertised. But you also need to “advertise” the link into OSPF just like a regular interface. You either add ip ospf 1 area 0 to the tunnel interface, or add the unnumbered source of the tunnel (usually lo0) as a network statement under the ospf process.

If the loopback is already included in a network statement, the tunnel will also be advertised automatically. But if the loopback is activated for ospf via the interface command (as seen below) you will need to either do the same for the tunnel interface, or create a network statement matching the loopback.

R2#show run int tun7
!
int Lo0
 ip address 2.2.2.2 255.255.255.255
 ip ospf 1 area 0  ! Loopback activated for OSPF with the interface command
!
interface Tunnel7
 description R2_TO_R7
 ip unnumbered Loopback0
 ip ospf cost 1
 tunnel mode mpls traffic-eng
 tunnel destination 7.7.7.7
 tunnel mpls traffic-eng forwarding-adjacency
 tunnel mpls traffic-eng path-option 1 dynamic
 ip ospf 1 area 0  ! Or use the network statement below
!
router ospf 1
 network 2.2.2.2 0.0.0.0 area 0  ! Or activate the tun for OSPF explicitly as seen above

Achieving “unequal” cost load balancing using FA

By using FA, you can (arguably) achieve unequal-cost load balancing. I say arguably, because you are still using equal cost multipath, but the underlay is actually unequal cost.

For example, in the diagram below, R1 has two unequal paths to R7. The cost of all links is 100 (all links are 1G, using an auto-reference bandwidth of 100G).

If we create two bidirectional tunnels between R2/R7 and R3/R7, and announce them to the IGP using the same metric, we can create equal cost load balancing using an “unequal cost underlay.”

R2#show run int tun7
!
interface Tunnel7
 description R2_TO_R7
 ip unnumbered Loopback0
 ip ospf 1 area 0
 ip ospf cost 50
 tunnel mode mpls traffic-eng
 tunnel destination 7.7.7.7
 tunnel mpls traffic-eng forwarding-adjacency
 tunnel mpls traffic-eng path-option 1 dynamic

R3#show run int tun7
!
interface Tunnel7
 description R3_TO_R7
 ip unnumbered Loopback0
 ip ospf 1 area 0
 ip ospf cost 50
 tunnel mode mpls traffic-eng
 tunnel destination 7.7.7.7
 tunnel mpls traffic-eng forwarding-adjacency
 tunnel mpls traffic-eng path-option 1 dynamic

R7#show run int tun2
!
interface Tunnel2
 description R7_TO_R2
 ip unnumbered Loopback0
 ip ospf 1 area 0
 ip ospf cost 50
 tunnel mode mpls traffic-eng
 tunnel destination 2.2.2.2
 tunnel mpls traffic-eng forwarding-adjacency
 tunnel mpls traffic-eng path-option 1 dynamic

R7#show run int tun3
!
interface Tunnel3
 description R7_TO_R3
 ip unnumbered Loopback0
 ip ospf 1 area 0
 ip ospf cost 50
 tunnel mode mpls traffic-eng
 tunnel destination 3.3.3.3
 tunnel mpls traffic-eng forwarding-adjacency
 tunnel mpls traffic-eng path-option 1 dynamic

R1 has two equal cost paths to R7, with a cost of 151 for each. (100 to R2 or R3, 50 for the tunnel, 1 for the R7 loopback).

R1#show ip route 7.7.7.7
Routing entry for 7.7.7.7/32
  Known via "ospf 1", distance 110, metric 151, type intra area
  Last update from 10.1.2.2 on GigabitEthernet1, 00:00:13 ago
  Routing Descriptor Blocks:
  * 10.1.3.3, from 7.7.7.7, 00:00:13 ago, via GigabitEthernet2
      Route metric is 151, traffic share count is 1
    10.1.2.2, from 7.7.7.7, 00:00:13 ago, via GigabitEthernet1
      Route metric is 151, traffic share count is 1

Conclusion

This concludes the series which gave you an overview of the basics of MPLS-TE. We saw how the TED works and is populated by the IGP. We experimented with RSVP and saw how it creates a path and advertises the label for the tunnel. We saw how CSPF works and explored some options for steering traffic along a path that differs from the IGP best path. Finally, we saw how we can actually route traffic over our MPLS-TE tunnel.

Further Reading

MPLS Fundamentals, Luc De Ghein, Chapter 8

  • I would highly recommend this chapter. It covers everything you saw in this series, and more.

Last updated