Sunday, November 20, 2016

CCIE SPv4 - MPLS - Label Filtering Techniques

Software versions:
IOS XE 15.5
IOS XR 5.3

The topology for this demo:
This post we will cover the various label filtering techniques available. There are several different methods, we'll start with the most basic and progressively get more difficult. First let's list and define the different methods and look at them individually.


mpls ldp label allocate global host-route
--Allocates labels for only host-routes or /32 prefixes

mpls ldp label allocate global prefix-list
--Allocates labels for any prefixes matched in the prefix-list

mpls ldp advertise-labels
--Used to control which labels are advertised to which LDP neighbors
--"No" will prevent the distribution of any locally assigned labels

mpls ldp advertise-labels for/to
--Specifies which destinations should have their labels advertised
--For = prefix(es); To = to who

mpls ldp advertise-labels interface
--configure label advertisement for a /32 prefix constructed from the IP address of G1

mpls ldp advertise-labels vrf
--Into which VRF you will be advertising labels in

mpls ldp neighbor labels accept ACL
--The specified ACL is used to filter label bindings advertised by the specified neighbor
---If the prefix part of the label binding is permitted by the ACL
----The router will accept the binding. 
---If the prefix is denied
----The router will not accept or store the binding.

Since this post is all about filtering, we need to see the before and after so see the difference. We'll start of by using the most basic implementation of global host routes.

To begin, we will see what R3 is advertising for it's transit links to R4 and XR4.
R3#sh mpls ldp bindings 10.3.4.0 24
  lib entry: 10.3.4.0/24, rev 166
        local binding:  label: imp-null
        remote binding: lsr: 192.168.1.14:0, label: 24002   <----- this is the SP binding
        remote binding: lsr: 192.168.1.4:0, label: imp-null
R3#sh mpls ldp bindings 10.14.3.0 24
  lib entry: 10.14.3.0/24, rev 178
        local binding:  label: 301
        remote binding: lsr: 192.168.1.14:0, label: imp-null

        remote binding: lsr: 192.168.1.4:0, label: 25   <---- this is the SP binding

As you can see below, all the /24 prefixes are the transit links between the routers.
R3#show mpls forwarding-table | in /24
16         Pop Label  10.4.5.0/24      0             Gi1.34     10.3.4.4
17         20         10.5.6.0/24      0             Gi1.34     10.3.4.4
18         17         10.1.12.0/24     0             Gi1.34     10.3.4.4
19         21         10.11.14.0/24    0             Gi1.34     10.3.4.4
20         22         10.12.13.0/24    0             Gi1.34     10.3.4.4
21         23         10.12.16.0/24    0             Gi1.34     10.3.4.4
22         24         10.13.2.0/24     0             Gi1.34     10.3.4.4
23         18         10.1.15.0/24     0             Gi1.34     10.3.4.4
24         25         10.14.3.0/24     0             Gi1.34     10.3.4.4
25         26         10.14.15.0/24    0             Gi1.34     10.3.4.4
26         27         10.15.16.0/24    0             Gi1.34     10.3.4.4
27         19         10.2.6.0/24      0             Gi1.34     10.3.4.4
28         28         10.16.2.0/24     0             Gi1.34     10.3.4.4
29         29         10.16.5.0/24     0             Gi1.34     10.3.4.4
33         16         10.1.11.0/24     0             Gi1.34     10.3.4.4

301        Pop Label  10.15.4.0/24     0             Gi1.34     10.3.4.4


Now let's enable host route filtering and see the differnece

IOS
mpls ldp label

 allocate global host-routes

XR
mpls ldp
 address-family ipv4
  label
   local

    allocate for host-routes

The result:
R3#sh mpls ldp bindings 10.3.4.0 24
  lib entry: 10.3.4.0/24, rev 185
        no local binding
        remote binding: lsr: 192.168.1.4:0, label: imp-null
R3#sh mpls ldp bindings 10.14.3.0 24
  lib entry: 10.14.3.0/24, rev 192
        no local binding

        remote binding: lsr: 192.168.1.4:0, label: 25

RP/0/0/CPU0:XR4#sh mpls ldp bindings 10.14.3.0/24
Sun Nov 20 13:38:53.270 UTC
10.14.3.0/24, rev 0 (no route)
        No local binding
        Remote bindings: (2 peers)
            Peer                Label
            -----------------   ---------
            192.168.1.11:0      24012

            192.168.1.15:0      24008

After rolling out the above commands to all IOS and XR routers, this is our forwarding table.

R3#show mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
31         24020      192.168.1.1/32   0             Gi1.143    10.14.3.14
32         24012      192.168.1.2/32   0             Gi1.143    10.14.3.14
34         24004      192.168.1.5/32   0             Gi1.143    10.14.3.14
35         24005      192.168.1.6/32   0             Gi1.143    10.14.3.14
36         24000      192.168.1.11/32  0             Gi1.143    10.14.3.14
37         24021      192.168.1.12/32  0             Gi1.143    10.14.3.14
38         24022      192.168.1.13/32  0             Gi1.143    10.14.3.14
39         Pop Label  192.168.1.14/32  0             Gi1.143    10.14.3.14
40         24006      192.168.1.15/32  0             Gi1.143    10.14.3.14
41         24013      192.168.1.16/32  0             Gi1.143    10.14.3.14
42         Pop Label  192.168.1.4/32   0             Gi1.34     10.3.4.4

Only /32 host routes are shown in the forwarding table.

We maintain the SP binding as it uses tLDP to main that. the binding for the local transit link has been removed. Now let's remove the host routes config and use a prefix list to permit only the loopback subnet. This will only allow the 192.168.1.0/24, our loopback prefix to have label allocation.

IOS
ip prefix-list LDP_LOOPBACKS seq 5 permit 192.168.1.0/24 le 32
mpls ldp label
 allocate global prefix-list LDP_LOOPBACKS

XR
ipv4 access-list LDP_LOOPBACKS
 10 permit ipv4 192.168.1.0 0.0.0.255 any
!
mpls ldp
 address-family ipv4
  label
   local
    allocate for LDP_LOOPBACKS

The results:
R3#show mpls ldp bindings 10.3.4.0 24
nothing!
R3#show mpls ldp bindings 10.14.3.0 24
nothing!

R3#show mpls ldp bindings 192.168.1.3 32
  lib entry: 192.168.1.3/32, rev 147
        local binding:  label: imp-null
        remote binding: lsr: 192.168.1.14:0, label: 24001
        remote binding: lsr: 192.168.1.4:0, label: 32

R3#sh mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
31         24020      192.168.1.1/32   0             Gi1.143    10.14.3.14
32         24012      192.168.1.2/32   0             Gi1.143    10.14.3.14
34         24004      192.168.1.5/32   372           Gi1.143    10.14.3.14
35         24005      192.168.1.6/32   0             Gi1.143    10.14.3.14
36         24000      192.168.1.11/32  0             Gi1.143    10.14.3.14
37         24021      192.168.1.12/32  0             Gi1.143    10.14.3.14
38         24022      192.168.1.13/32  0             Gi1.143    10.14.3.14
39         Pop Label  192.168.1.14/32  0             Gi1.143    10.14.3.14
40         24006      192.168.1.15/32  186           Gi1.143    10.14.3.14
41         24013      192.168.1.16/32  0             Gi1.143    10.14.3.14

42         Pop Label  192.168.1.4/32   0             Gi1.34     10.3.4.4

As you can see it's working as expected.

The next step in the process is to control what labels are advertised to what peers, this gets a bit into the weeds so lets break down the logic first, then the config. Lets say that XR3 and R6 are LSP endpoints. R3 is the ingress PE for those LSPs. We want to configure XR4 so that R3 only has label bindings for R6 and XR3. We'll take a look at this on XR first then IOS. R3s link to R4 is shutdown. When you configure the LDP part, make sure you tell what system wide label range R3 should use with the :0 option.

XR
ipv4 access-list PERMIT_XR3_R6_LOOPBACKS
 10 permit ipv4 host 192.168.1.13 any
 20 permit ipv4 host 192.168.1.6 any
!
mpls ldp
 address-family ipv4
  label
   local
    advertise
     to 192.168.1.3:0 for PERMIT_XR3_R6_LOOPBACKS

When I went to verify this on R3, I was still seeing the whole LFIB DB being advertised, I double checked my configs, then I noticed on XR4, I had a targeted LDP session to R3, R3 has one to XR4. Therefore, the session was being maintained. Make sure you disable SP or tLDP sessions prior to this. This is considered to be outgoing label filtering.

R3#show mpls ldp bindings neighbor 192.168.1.14
  lib entry: 192.168.1.6/32, rev 150
        remote binding: lsr: 192.168.1.14:0, label: 24005
  lib entry: 192.168.1.13/32, rev 153
        remote binding: lsr: 192.168.1.14:0, label: 24022

The forwarding table is fully populated still, but no labels are allocated for anything except R6 and XR3.
R3#sh mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
16         No Label   10.12.13.0/24    0             Gi1.143    10.14.3.14
17         No Label   10.12.16.0/24    0             Gi1.143    10.14.3.14
18         No Label   10.4.5.0/24      0             Gi1.143    10.14.3.14
19         No Label   10.13.2.0/24     0             Gi1.143    10.14.3.14
35         24005      192.168.1.6/32   0             Gi1.143    10.14.3.14
36         No Label   192.168.1.11/32  0             Gi1.143    10.14.3.14
37         No Label   192.168.1.12/32  0             Gi1.143    10.14.3.14
38         24022      192.168.1.13/32  0             Gi1.143    10.14.3.14

Let's trace to XR1s loopback and then XR3 and R6 to see the difference. 

As you can see, this uses IGP to get to XR1. Which is expected since XR1's loopback doesn't have a label assocated outbound
R3#traceroute 192.168.1.11 num
Type escape sequence to abort.
Tracing the route to 192.168.1.11
VRF info: (vrf in name/id, vrf out name/id)
  1 10.14.3.14 2 msec 1 msec 0 msec
  2 10.11.14.11 2 msec *  2 msec

We have no issues with label forwarding to R6, the expected result
R3#traceroute 192.168.1.6 num
Type escape sequence to abort.
Tracing the route to 192.168.1.6
VRF info: (vrf in name/id, vrf out name/id)
  1 10.14.3.14 [MPLS: Label 24005 Exp 0] 4 msec 3 msec 4 msec
  2 10.14.15.15 [MPLS: Label 24011 Exp 0] 3 msec 15 msec 30 msec
  3 10.15.16.16 [MPLS: Label 24008 Exp 0] 4 msec 3 msec 6 msec
  4 10.16.5.5 [MPLS: Label 34 Exp 0] 15 msec 15 msec 15 msec
  5 10.5.6.6 16 msec

We have no issues with label forwarding to XR3, the expected result
R3#traceroute 192.168.1.16 num
Type escape sequence to abort.
Tracing the route to 192.168.1.16
VRF info: (vrf in name/id, vrf out name/id)
  1 10.14.3.14 2 msec 1 msec 0 msec
  2 10.14.15.15 [MPLS: Label 24014 Exp 0] 3 msec 3 msec 2 msec
  3 10.15.16.16 3 msec


Currently, R3's connection to R4 is shutdown. Let's pretend that R3 is only connected to XR4. In reality XR4 should never have a need to learn a label from R3, 192.168.1.3/32 from any other router, even R4 if the link was enabled.

RP/0/0/CPU0:XR4#sh mpls ldp bindings 192.168.1.3/32
Sun Nov 20 14:46:56.320 UTC
192.168.1.3/32, rev 35
        Local binding: label: 24001
        Remote bindings: (3 peers)
            Peer                Label
            -----------------   ---------
            192.168.1.3:0       ImpNull
            192.168.1.11:0      24010
            192.168.1.15:0      24002

We can filter this out so that XR1 and XR5 label advertisements will be filtered inbound. This can be done on XR1 and XR5 as well outbound.

XR
ipv4 access-list R3_LOOPBACK
 10 deny ipv4 host 192.168.1.3 any
 20 permit ipv4 any any
!
mpls ldp
 address-family ipv4
  label
   remote
    accept
     from 192.168.1.11:0 for R3_LOOPBACK
     from 192.168.1.15:0 for R3_LOOPBACK

Now we are only learning about R3s loopback from R3.
RP/0/0/CPU0:XR4#sh mpls ldp bindings 192.168.1.3/32
Sun Nov 20 14:49:55.008 UTC
192.168.1.3/32, rev 35
        Local binding: label: 24001
        Remote bindings: (1 peers)
            Peer                Label
            -----------------   ---------
            192.168.1.3:0       ImpNull


Let's see the outbound and inbound configuration on IOS now, very similar, I'll enable the link between R3 and R4 and shutdown the link between R3 and XR4.

IOS
mpls ldp advertise-labels for R6_XR3_LOOPBACK to R3
ip access-list standard R3
 permit 192.168.1.3
ip access-list standard R6_XR3_LOOPBACK
 permit 192.168.1.13
 permit 192.168.1.6

There is a problem when I verify this on R3, it receives everything, I made sure to disable tLDP and Session protection so we know that won't affect us. The problem is that XE assumes you want to advertise all label with all prefixes to all peers until you tell it otherwise. The fix, disable label advertisement.

R4(config)#no mpls ldp advertise-labels

R3#sh mpls ldp bindings neighbor 192.168.1.4
  lib entry: 192.168.1.6/32, rev 150
        remote binding: lsr: 192.168.1.4:0, label: 34
  lib entry: 192.168.1.13/32, rev 153
        remote binding: lsr: 192.168.1.4:0, label: 37

It's working now! But, R4 is no longer learning any labels. Fix one problem and introduce another, To remedy this issue, we need to get fancy on R4 to advertise labels but for only a specific set of /32 prefixes, to maintain the previous rollout.

IOS
no mpls ldp advertise-labels
mpls ldp advertise-labels for R6_XR3_LOOPBACK to R3_PERMIT
mpls ldp advertise-labels for ANY to NOT_R3

ip access-list standard ANY
 permit any
ip access-list standard NOT_R3
 deny   192.168.1.3
 permit any
ip access-list standard R3_PERMIT
 permit 192.168.1.3
ip access-list standard R6_XR3_LOOPBACK
 permit 192.168.1.13
 permit 192.168.1.6

R3#sh mpls ldp bindings neighbor 192.168.1.4
  lib entry: 192.168.1.6/32, rev 343
        remote binding: lsr: 192.168.1.4:0, label: 34
  lib entry: 192.168.1.13/32, rev 346
        remote binding: lsr: 192.168.1.4:0, label: 37

The filtering is clearly working, we only see R6 and XR3s loopbacks on R3.
There is a handy show command on the LSR that is doing the filtering to see what is being filtered.

R4#show mpls ldp bindings 192.168.1.3 32 advertisement-acls
Advertisement spec:
        Prefix acl = R6_XR3_LOOPBACK; Peer acl = R3_PERMIT
        Prefix acl = ANY; Peer acl = NOT_R3

  lib entry: 192.168.1.3/32, rev 60
        Advert acl(s): Prefix acl ANY; Peer acl NOT_R3

We need to make sure that R5 is also seeing advertisements from R4. As well we also need to make sure R4 is also populating it's forwarding table.

R4#show mpls forwarding-table
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
16         40         192.168.1.16/32  0             Gi1.45     10.4.5.5
17         39         192.168.1.15/32  0             Gi1.45     10.4.5.5
18         38         192.168.1.14/32  0             Gi1.45     10.4.5.5

R5#sh mpls ldp bindings neighbor 192.168.1.4
  lib entry: 10.4.5.4/32, rev 186
        remote binding: lsr: 192.168.1.4:0, label: imp-null
  lib entry: 192.168.1.1/32, rev 36
        remote binding: lsr: 192.168.1.4:0, label: 25
  lib entry: 192.168.1.2/32, rev 38
        remote binding: lsr: 192.168.1.4:0, label: 24
  lib entry: 192.168.1.3/32, rev 40
        remote binding: lsr: 192.168.1.4:0, label: 40


The next feature we'll take a look at is the neighbor labels accept feature, which is an inbound label filtering technique. We will look at this from R6 and accept only labels from R5 and R2 for R3 and XR3. Since we are using those PEs as LSP endpoints for our demos. Lets first verify that we infact are learning everything in from both R5 and R2

R6#sh mpls ldp bind neighbor 192.168.1.5
  lib entry: 192.168.1.1/32, rev 36
        remote binding: lsr: 192.168.1.5:0, label: 30
  lib entry: 192.168.1.2/32, rev 38
        remote binding: lsr: 192.168.1.5:0, label: 31
  lib entry: 192.168.1.3/32, rev 40
        remote binding: lsr: 192.168.1.5:0, label: 32

R6#sh mpls ldp bind neighbor 192.168.1.2
  lib entry: 192.168.1.1/32, rev 36
        remote binding: lsr: 192.168.1.2:0, label: 30
  lib entry: 192.168.1.2/32, rev 38
        remote binding: lsr: 192.168.1.2:0, label: imp-null
  lib entry: 192.168.1.3/32, rev 40
        remote binding: lsr: 192.168.1.2:0, label: 31
  lib entry: 192.168.1.4/32, rev 42

Now let's filter down to only the binding for R3 and XR3.

R6:
mpls ldp neighbor 192.168.1.5 labels accept R3_XR3_PERMIT
mpls ldp neighbor 192.168.1.2 labels accept R3_XR3_PERMIT
!
ip access-list standard R3_XR3_PERMIT
 permit 192.168.1.13
 permit 192.168.1.3

R6#sh mpls ldp bind neighbor 192.168.1.5
  lib entry: 192.168.1.3/32, rev 40
        remote binding: lsr: 192.168.1.5:0, label: 32
  lib entry: 192.168.1.13/32, rev 52
        remote binding: lsr: 192.168.1.5:0, label: 37

R6#sh mpls ldp bind neighbor 192.168.1.2
  lib entry: 192.168.1.3/32, rev 40
        remote binding: lsr: 192.168.1.2:0, label: 31
  lib entry: 192.168.1.13/32, rev 52
        remote binding: lsr: 192.168.1.2:0, label: 37

R6#sh mpls forwarding-table 192.168.1.3
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
33         32         192.168.1.3/32   0             Gi1.56     10.5.6.5

R6#sh mpls forwarding-table 192.168.1.13
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
38         37         192.168.1.13/32  0             Gi1.26     10.2.6.2

As you can see it's working as expected, let's also verify the ACL for incrementing hits.
R6#sh ip access-lists
Standard IP access list R3_XR3_PERMIT
    20 permit 192.168.1.13 (5 matches)
    10 permit 192.168.1.3 (5 matches)

R6#traceroute 192.168.1.3 so lo0 num
Type escape sequence to abort.
Tracing the route to 192.168.1.3
VRF info: (vrf in name/id, vrf out name/id)
  1 10.5.6.5 [MPLS: Label 32 Exp 0] 2 msec 1 msec 9 msec
  2 10.4.5.4 [MPLS: Label 40 Exp 0] 20 msec 20 msec 20 msec
  3 10.3.4.3 21 msec *  2 msec

R6#traceroute 192.168.1.13 so lo0 num
Type escape sequence to abort.
Tracing the route to 192.168.1.13
VRF info: (vrf in name/id, vrf out name/id)
  1 10.2.6.2 [MPLS: Label 37 Exp 0] 2 msec 1 msec 1 msec
  2 10.13.2.13 2 msec *  3 msec

Thanks for stopping by!
Rob Riker, CCIE #50693

No comments:

Post a Comment