10 mins read

SR-MPLS – TI-LFA

1. Intro

Loop-free alternate (LFA) and remote LFA have been used to provide fast-reroute protection for several years. With LFA, a point of local repair (PLR) determines whether or not a packet sent to one of its direct neighbors will reach its destination without looping back through the PLR. In a typical network topology, perhaps 40-60 percent of destinations can be protected by LFA.

Remote LFA (RLFA) expands on the concept of LFA by allowing the PLR to impose a single label to tunnel the packet to a repair tunnel endpoint from which the packet can reach its destination without looping back through the PLR. Using remote LFA, more destinations can be protected by the PLR compared to LFA. However, depending on the network topology, the percentage of destinations protected by remote LFA usually less than 100 percent.

Topology-independent loop-free alternate (TI-LFA) extends the concept of LFA and remote LFA by allowing the PLR to use deeper label stacks to construct backup paths. In addition, TI-LFA imposes the constraint that the backup path used by the PLR be the same path that a packet takes once the IGP converges for a given failure scenario. This path is referred to as the post-convergence path.

We will use the same test topology from the previous posts:

The initial config is simple:

2. Configuration

To enable TI-LFA for IS-IS configure the use-post-convergence-lfa statement at the [edit protocols isis backup-spf-options] hierarchy level. You can enable the creation of post-convergence backup paths for a given interface by configuring the post-convergence-lfa statement at the [edit protocols isis interface interface-name level level] hierarchy level.

### We will connect to the R1 router, and here we will check how R1 has connectivity to the R7 router. 

root@R1# run show route 17.0.0.7 

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

17.0.0.7/32        *[IS-IS/18] 00:01:02, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0

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

17.0.0.7/32        *[L-ISIS/14] 00:01:02, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 801007

### To enable TI-LFA we will configure the following: 

set protocols isis backup-spf-options use-post-convergence-lfa 

### Then enable backup paths on ge-0/0/2.0 to R3: 

set protocols isis interface ge-0/0/2.0 level 2 post-convergence-lfa 

### Notice we have a backup path in the inet.3 table: 

root@R1# run show route 17.0.0.7 

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

17.0.0.7/32        *[IS-IS/18] 00:00:08, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0

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

17.0.0.7/32        *[L-ISIS/14] 00:00:08, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 801007
                       to 17.1.2.2 via ge-0/0/1.0, Push 801007

### If we want a backup path also in the inet.0 table, then:

set protocols isis backup-spf-options use-source-packet-routing 

### Notice the backup path also in the inet.0 table:

root@R1# run show route 17.0.0.7                                            

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

17.0.0.7/32        *[IS-IS/18] 00:00:08, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0
                       to 17.1.2.2 via ge-0/0/1.0

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

17.0.0.7/32        *[L-ISIS/14] 00:00:08, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 801007
                       to 17.1.2.2 via ge-0/0/1.0, Push 801007

### Also the extensive view: 

root@R1# run show route 17.0.0.7 extensive 

inet.0: 43 destinations, 43 routes (43 active, 0 holddown, 0 hidden)
17.0.0.7/32 (1 entry, 1 announced)
TSI:
KRT in-kernel 17.0.0.7/32 -> {17.1.3.3}
IS-IS level 2, Prefix Sid 0xa252c60
        *IS-IS  Preference: 18
                Level: 2
                Next hop type: Router, Next hop index: 0
                Address: 0x7e83594
                Next-hop reference count: 5, key opaque handle: 0x0, non-key opaque handle: 0x0
                Kernel Table Id: 0
                Next hop: 17.1.3.3 via ge-0/0/2.0 weight 0x1, selected
                Session Id: 0
                Next hop: 17.1.2.2 via ge-0/0/1.0 weight 0xf000
                Session Id: 0
                State: <Active Int>
                Local AS: 64512 
                Age: 3:20       Metric: 30 
                Validation State: unverified 
                ORR Generation-ID: 0 
                Task: IS-IS
                Announcement bits (2): 0-KRT 3-IS-IS 
                AS path: I 
                Thread: junos-main 

inet.3: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden)

17.0.0.7/32 (1 entry, 1 announced)
        *L-ISIS Preference: 14
                Level: 2
                Next hop type: Router, Next hop index: 0
                Address: 0x7e8316c
                Next-hop reference count: 1, key opaque handle: 0x0, non-key opaque handle: 0x0
                Kernel Table Id: 0
                Next hop: 17.1.3.3 via ge-0/0/2.0 weight 0x1, selected
                Label operation: Push 801007
                Label TTL action: prop-ttl
                Load balance label: Label 801007: None; 
                Label element ptr: 0x7f65e78
                Label parent element ptr: 0x0
                Label element references: 3
                Label element child references: 0
                Label element lsp id: 0
                Session Id: 0
                Next hop: 17.1.2.2 via ge-0/0/1.0 weight 0xf000
                Label operation: Push 801007
                Label TTL action: prop-ttl
                Load balance label: Label 801007: None; 
                Label element ptr: 0x7f65e78
                Label parent element ptr: 0x0
                Label element references: 3
                Label element child references: 0
                Label element lsp id: 0
                Session Id: 0
                State: <Active Int>
                Local AS: 64512 
                Age: 3:20       Metric: 30 
                Validation State: unverified 
                ORR Generation-ID: 0 
                Task: IS-IS
                Announcement bits (1): 2-Resolve tree 1 
                AS path: I 
                Ext Data: Prefix-Sid: Index: 1007  Algo: 0 Flags:R:0,N:1,P:0,E:0 
                Thread: junos-main 

### While ge-0/0/2 is providing protection (to R7, R6, R3, etc), the ge-0/0/1 has no protection to R2 for example:

root@R1# run show route 17.0.0.2 

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

17.0.0.2/32        *[IS-IS/18] 00:37:32, metric 10
                    >  to 17.1.2.2 via ge-0/0/1.0

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

17.0.0.2/32        *[L-ISIS/14] 00:37:32, metric 10
                    >  to 17.1.2.2 via ge-0/0/1.0

### To configure protection for the ge-0/0/1 interface, do the same: 

set protocols isis interface ge-0/0/1.0 level 2 post-convergence-lfa

### Now R1 benefits of TI-LFA on the other link as well:

root@R1# run show route 17.0.0.2 

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

17.0.0.2/32        *[IS-IS/18] 00:00:01, metric 10
                    >  to 17.1.2.2 via ge-0/0/1.0
                       to 17.1.3.3 via ge-0/0/2.0

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

17.0.0.2/32        *[L-ISIS/14] 00:00:01, metric 10
                    >  to 17.1.2.2 via ge-0/0/1.0
                       to 17.1.3.3 via ge-0/0/2.0, Push 801002

We can basically see that the backup path is not that different. When the ge-0/0/2 interface to R3 is no longer available, the backup path is using the ge-0/0/1 to R2. Then R2 is left alone to do it’s usual forwarding to R7. This works because all ISIS links on all routers have the default metric (10) configured.

But let’s make it more complicated, on R2 we will in crease the metric to 100 on the following interfaces: ge-0/0/2 (to R3) and ge-0/0/3 (to R4). This is important, because R1 can’t just forward the packets to R2, because R2 will just want to send the packet back to R1 using the ge-0/0/1 (still has the default 10 metric), and this will create a loop. How will R1 solve this? See next:

### On R2 router, increase the metric to 100 for the links to R3 and R4, as described above: 

root@R2# show | compare 
[edit protocols isis interface ge-0/0/2.0]
+     level 2 metric 100;
[edit protocols isis interface ge-0/0/3.0]
+     level 2 metric 100;

root@R2# commit 
commit complete

### No additional action is needed, R1 automatically understands the issue. 
### For the backup path, R1 is still using the ge-0/0/1 interface to R2, but it will push one additional label: 

root@R1# run show route 17.0.0.7                                            

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

17.0.0.7/32        *[IS-IS/18] 00:01:32, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0
                       to 17.1.2.2 via ge-0/0/1.0, Push 29

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

17.0.0.7/32        *[L-ISIS/14] 00:01:32, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 801007
                       to 17.1.2.2 via ge-0/0/1.0, Push 801007, Push 29(top)

### R2 is receiving the packet with top label 29. Label 29 will send the packet out ge-0/0/2 to R3. 

root@R2# run show route table mpls.0 label 29             

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

29                 *[L-ISIS/14] 01:43:21, metric 0
                    >  to 17.2.3.3 via ge-0/0/2.0, Pop      
29(S=0)            *[L-ISIS/14] 01:43:21, metric 0
                    >  to 17.2.3.3 via ge-0/0/2.0, Pop  

Problem solved. By imposing multiple labels to the backup path, the R1 router is able to prevent a rooting loop. This would be the “Topology Independent” part of TI-LFA. The router is not restricted to the basic shortest path paradigm, using a label stack it is able to break free of the loop.

3. Node Protection

In the previous section we configured link protection, notice how the backup path gets the traffic around the R1-R3 link, but depending on the topology, it can end up back to R3. This actually happens in our case, the backup path is rerouting to a different interface on R3, but what if the entire R3 router is isolated?

Well, in this case we want to configure node protection. To determine the node-protecting post-convergence path, the cost of all the links leaving the neighbor is assumed to increase by a configurable amount. This means that we should configure a high cost to make those links less preferable. So, why not configure the max cost as follows:

### Configure node protection on R1: 

set protocols isis interface ge-0/0/2.0 level 2 post-convergence-lfa node-protection cost 16777215   

### This was easy: 

root@R1# run show route 17.0.0.7    

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

17.0.0.7/32        *[IS-IS/18] 00:00:05, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0
                       to 17.1.2.2 via ge-0/0/1.0, Push 801005, Push 31(top)

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

17.0.0.7/32        *[L-ISIS/14] 00:00:05, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 801007
                       to 17.1.2.2 via ge-0/0/1.0, Push 801007, Push 801005, Push 31(top)

### Notice how the top label is now 31. On R2, Label 31 is the Adj-SID to R4 router:  

root@R2# run show route table mpls.0 label 31 

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

31                 *[L-ISIS/14] 00:00:05, metric 0
                    >  to 17.2.4.4 via ge-0/0/3.0, Pop      
31(S=0)            *[L-ISIS/14] 00:00:05, metric 0
                    >  to 17.2.4.4 via ge-0/0/3.0, Pop 

### Back to R1. Also notice label 801005 which will be used by R4, it will send the packet to R5:    

17.0.0.7/32        *[L-ISIS/14] 00:00:05, metric 30
                    >  to 17.1.3.3 via ge-0/0/2.0, Push 801007
                       to 17.1.2.2 via ge-0/0/1.0, Push 801007, Push 801005, Push 31(top)  

### Hence, node protection, R3 is fully avoided by adding a longer label stack. 

### Note: the default maximum labels for the backup path is 3, you may want to increase this by using:

set protocols isis backup-spf-options use-post-convergence-lfa maximum-labels 8

External Resources:

Leave a Reply