Saturday, August 23, 2014

Comparing Cisco IOS label per-prefix , per-vrf and connected-aggregate

In a previous posts, we discussed LDP Protocol Label Distribution Modes, and how are they propagated throughout the network,and also in Junos, how the PE Router assigns label per interface and how to change this behavior. In this post, we’ll get a little bit specific on HOW are these labels created even before they’re propagated to the network and also how we can manipulate the label creation process to better suite our needs.
In Cisco’s IOS by default, the label allocation is per-prefix meaning that every single prefix by default gets it’s own label, but this behavior can be changed since we have two other modes to allocate labels. Here’s a list of all supported modes on IOS
per-prefix (Default)
per-vrf
vrf-conn-aggr
Now let’s see how the three of them work by examining the below topology



The default setup is pretty normal, we have two CEs that are connected through a Service provider with L3VPN. OSPF is running as a PE-CE Routing protocol between the Service Provider and the customer branches.

Let’s check the MP-BGP label allocations on PE6 for CE3 and CE4

R6#show ip bgp vpnv4 all labels
   Network          Next Hop      In label/Out label
Route Distinguisher: 100:1 (a)
   1.1.1.1/32       13.13.13.13     nolabel/19
   3.3.3.3/32       10.3.6.3        24/nolabel
   4.4.4.4/32       10.4.6.4        27/nolabel
   10.1.13.0/24     13.13.13.13     nolabel/20
   10.3.4.0/24      10.3.6.3        28/nolabel
   10.3.6.0/24      0.0.0.0         29/nolabel(a)
   10.4.6.0/24      0.0.0.0         30/nolabel(a)
   44.44.44.44/32   10.4.6.4        31/nolabel
   66.66.66.66/32   0.0.0.0         32/nolabel(a)
   130.130.130.130/32
                    13.13.13.13     nolabel/21


R6#show mpls forwarding-table vrf a
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
24         No Label   3.3.3.3/32[V]    0             Fa1/0      10.3.6.3
27         No Label   4.4.4.4/32[V]    0             Fa1/1      10.4.6.4
28         No Label   10.3.4.0/24[V]   0             Fa1/0      10.3.6.3
29         No Label   10.3.6.0/24[V]   0             aggregate/a
30         No Label   10.4.6.0/24[V]   0             aggregate/a
31         No Label   44.44.44.44/32[V]   \
                                       0             Fa1/1      10.4.6.4
32         Pop Label  66.66.66.66/32[V]   \
                                       0             aggregate/a

Now this seems to be pretty straight forward. Four labels are being generated and the Four of them are different.
Labels 29,30,32: Are labels for the directly connected interfaces to PE6 in VRF a. Notice the (a) at the end if each line
Labels 24,27,28,31: Are the OSPF routes received by PE6 and redistributed to the MP-BGP

You can imagen if you’re a large service provider having thousands of customers and each customer has thousands of routes, that can pretty much put a burden on your network control plane resources (“ not really the case in higher end routers”).

Now let’s see what we can do about this. First, let’s tell PE6 to allocate one label for all prefixes in VRF a

R6(config)#mpls label mode all-vrfs protocol bgp-vpnv4 per-vrf

This is a global command, which affects all the VRFs on the PE router, if you want to selectively assign for a specific VRF, you can type it like this instead

R6(config)#mpls label mode vrf a protocol bgp-vpnv4 per-vrf

Now let’s check and see how are the labels allocated this time

R6#show ip bgp vpnv4 all labels
   Network          Next Hop      In label/Out label
Route Distinguisher: 100:1 (a)
   1.1.1.1/32       13.13.13.13     nolabel/19
   3.3.3.3/32       10.3.6.3        IPv4 VRF Aggr:16/nolabel
   4.4.4.4/32       10.4.6.4        IPv4 VRF Aggr:16/nolabel
   10.1.13.0/24     13.13.13.13     nolabel/20
   10.3.4.0/24      10.3.6.3        IPv4 VRF Aggr:16/nolabel
   10.3.6.0/24      0.0.0.0         IPv4 VRF Aggr:16/nolabel(a)
   10.4.6.0/24      0.0.0.0         IPv4 VRF Aggr:16/nolabel(a)
   44.44.44.44/32   10.4.6.4        IPv4 VRF Aggr:16/nolabel
   66.66.66.66/32   0.0.0.0         IPv4 VRF Aggr:16/nolabel(a)
   130.130.130.130/32
                    13.13.13.13     nolabel/21

R6#show mpls forwarding-table vrf a
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
16         Pop Label  IPv4 VRF[V]      0             aggregate/a

You can see that all the prefix inside vrf a now has the label 16. Now any other  PE in the network will only need to allocate label 16 to reach all the networks in PE6 vrf a
One interesting application for that would be putting the entire Internet 500,000 prefix (BGP) routing table in a VRF.

now let’s see the effect of the final option on our hands , the connected and aggregate label assignment

R6(config)#mpls label mode all-vrfs protocol bgp-vpnv4 vrf-conn-aggr

Let’s check the label assignment now

R6#show ip bgp vpnv4 all labels
   Network          Next Hop      In label/Out label
Route Distinguisher: 100:1 (a)
   1.1.1.1/32       13.13.13.13     nolabel/19
   3.3.3.3/32       10.3.6.3        22/nolabel
   4.4.4.4/32       10.4.6.4        23/nolabel
   10.1.13.0/24     13.13.13.13     nolabel/20
   10.3.4.0/24      10.3.6.3        25/nolabel
   10.3.6.0/24      0.0.0.0         IPv4 VRF Aggr:16/nolabel(a)
   10.4.6.0/24      0.0.0.0         IPv4 VRF Aggr:16/nolabel(a)
   44.44.44.44/32   10.4.6.4        26/nolabel
   66.66.66.66/32   0.0.0.0         IPv4 VRF Aggr:16/nolabel(a)
   130.130.130.130/32
                    13.13.13.13     nolabel/21

R6#show mpls forwarding-table vrf a
Local      Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label      Label      or Tunnel Id     Switched      interface
16         Pop Label  IPv4 VRF[V]      0             aggregate/a
22         No Label   3.3.3.3/32[V]    0             Fa1/0      10.3.6.3
23         No Label   4.4.4.4/32[V]    0             Fa1/1      10.4.6.4
25         No Label   10.3.4.0/24[V]   0             Fa1/0      10.3.6.3
26         No Label   44.44.44.44/32[V]   \
                                       0             Fa1/1      10.4.6.4

We can see that label 16 is now assigned for all the connected interfaces in PE6 vrf a, whilst all prefix learned via PE-CE ospf has a label assigned independently. Note that this will also assign a single label for all BGP aggregate routes.


Saturday, August 9, 2014

Juniper JunOS L3-VPN vrf-table-label

vrf-table-label introduces several features that changes JunOS behavior with L3-VPNs. But first let’s review the default behavior of JunOS regarding label allocation and some other QoS and Filtering Features.
By default, JunOS allocates labels per customer interface “next-hop” in L3-VPNs, meaning that if a PE has two connected CE routers with two Ethernet interfaces under the same VRF. JunOS will allocate one label for each CE interface. Also any routing updates received from this interface or static routes that points to the CE interface will have the same VPN Label. If there’s a loopback interface that is configured under this L3-VPN; it will always have a different label.

vrf-table-label will create a label for all the routes present on a PE VRF, thus; conserving resources for label allocations. Instead of having a label for each next-hop and for loopback interfaces, the ingress PE will allocate one label for the whole VRF

From a security perspective, JunOS doesn’t export (Redistribute)  direct interface prefix of a CE customer as a VPNV4 update to other PEs unless this interface has a dynamic routing protocol running between it and the CE, or there’s a static route pointing to a certain prefix and using this interface as a next-hop.
This behavior can be overridden when using vrf-table-label

On an egress PE router, if the PE-CE link is a point to point interface, then there will be no need to do an IP lookup. In case it is a shared medium or a multi-access network, a secondary lookup is needed to resolve which destination CE is exactly needed to forward the packet to. For JunOS to do this, a hardware card called Tunnel Service PIC is needed to achieve this. If there’s no TS PIC installed, vrf-table-label creates a logical “LSI” Label Switched Interface for that VRF and it is used by Egress PE router to receive VPN labeled packets, after removing that label, a secondary IP lookup takes place on the logical LSI interface, which can also be used to filter traffic and apply QoS features before doing the ARP lookup on the shared medium.

Now for the good part, let’s see before and after configuring vrf-table-label on a PE router

As shown below in the diagram, we have PE1 that connects CE-A1 and CE-B1 while CE-B2 is connected to PE3. The PE-CE routing protocol







The protocol running between PE1 – CEA1 is OSPF and between PE1 and CE-B1 is static. Both are exported to VRF B on PE1 and exchanged via VPNv4 with PE3.
Here’s what the configuration looks like on PE1

admin@PE1> show configuration routing-instances B
instance-type vrf;
interface ge-0/0/0.0;
interface ge-0/0/1.0;
interface lo0.30;
route-distinguisher 20.20.1.1:2;
vrf-import B-Import;
vrf-export B-Export;
vrf-table-label;
routing-options {
    static {
        route 30.3.3.3/32 next-hop 30.0.2.2;
    }
}
protocols {
    ospf {
        export EXPORTB-BGP-TO-OSPF;
        area 0.0.0.0 {
            interface lo0.30;
            interface ge-0/0/0.0;
        }
    }
}

 
admin@PE1> show configuration policy-options policy-statement B-Export
term 1 {
    from protocol direct;
    then {
        community add B;
        accept;
    }
}
term 2 {
    from protocol ospf;
    then {
        community add B;
        accept;
    }
}
term 3 {
    from protocol static;
    then {
        community add B;
        accept;
    }
}

Now let’s check what PE3 has in VRF B routing table

admin@PE3> show route table B.inet.0 protocol bgp   

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

20.20.1.1/32       *[BGP/170] 00:00:08, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 299984, Push 300352(top)
30.0.1.0/24        *[BGP/170] 00:00:08, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 300000, Push 300352(top)
30.0.2.0/24        *[BGP/170] 00:00:08, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 300016, Push 300352(top)
30.1.1.1/32        *[BGP/170] 00:00:08, MED 1, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 300000, Push 300352(top)
30.3.3.3/32        *[BGP/170] 00:00:08, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 300016, Push 300352(top)

As shown in the above output, we can see PE1 VPN loopback interface. We can also see the exported static and OSPF routes from PE1 along with the directly connected interfaces between PE1 and both CEs.

Now notice how inner VPN labels are being pushed to reach networks on PE1, this is the default behavior of Junos when it comes to VPN label assignment as mentioned earlier

1.      Label 299984 is being pushed to reach PE1 VPN B loopback
2.      Label 300000 is being pushed  to reach CE-A1 directly connected interface and loopback
3.      Label 300016 is being pushed  to reach CE-B1 directly connected interface and loopback

Now let’s remove the static routing and OSPF between PE1 and it’s CEs. This is what will the export policy look like


admin@PE1# show policy-options policy-statement B-Export              
term 1 {
    from protocol direct;
    then {
        community add B;
        accept;
    }
}
 Now let’s check PE2 VPN B table again

admin@PE3> show route table B.inet.0 protocol bgp
 B.inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden)+ = Active Route, - = Last Active, * = Both 20.20.1.1/32       *[BGP/170] 00:11:50, localpref 100, from 20.20.1.1                      AS path: I                    > to 20.3.4.4 via ge-0/0/0.0, Push 299984, Push 300352(top)

Notice that now we can only see PE1 VPN loopback prefix even though the links between PE1 and CEs fall under direct routes, it’s not exported. Now let’s enable vrf-table-label and check if we get CE directly connected routes again on PE3
 admin@PE1# show routing-instances B
instance-type vrf;
interface ge-0/0/0.0;
interface ge-0/0/1.0;
interface lo0.30;
route-distinguisher 20.20.1.1:2;
vrf-import B-Import;
vrf-export B-Export;
vrf-table-label;

let’s check PE3 VPN B table again

admin@PE3> show route table B.inet.0 protocol bgp
 B.inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
 20.20.1.1/32       *[BGP/170] 00:02:54, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 16, Push 300352(top)
30.0.1.0/24        *[BGP/170] 00:02:54, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 16, Push 300352(top)
30.0.2.0/24        *[BGP/170] 00:02:54, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 16, Push 300352(top)

Now you can see that the direct routes has been exported without the need of having a next-hop or an IGP with the CE routers. You’ll also notice that the inner VPN label being pushed is 16 regardless of the prefix origin interface.

Let’s enable exporting static and OSPF to MP-BGP again on PE1 and check the routes received on PE3

admin@PE1> show configuration policy-options policy-statement B-Export
term 1 {
    from protocol direct;
    then {
        community add B;
        accept;
    }
}
term 2 {
    from protocol ospf;
    then {
        community add B;
        accept;
    }
}
term 3 {
    from protocol static;
    then {
        community add B;
        accept;
    }
}


 B.inet.0: 10 destinations, 10 routes (10 active, 0 holddown, 0 hidden)+ = Active Route, - = Last Active, * = Both
 20.20.1.1/32       *[BGP/170] 00:17:02, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 16, Push 300352(top)
30.0.1.0/24        *[BGP/170] 00:17:02, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 16, Push 300352(top)
30.0.2.0/24        *[BGP/170] 00:17:02, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 16, Push 300352(top)
30.1.1.1/32        *[BGP/170] 00:01:14, MED 1, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 16, Push 300352(top)
30.3.3.3/32        *[BGP/170] 00:01:14, localpref 100, from 20.20.1.1
                      AS path: I
                    > to 20.3.4.4 via ge-0/0/0.0, Push 16, Push 300352(top)
 

Back to PE1, let’s check the Label Switched interface and see what we’ve got there

admin@PE1> show interfaces lsi
Physical interface: lsi, Enabled, Physical link is Up
  Interface index: 4, SNMP ifIndex: 4
  Type: Software-Pseudo, Link-level type: LSI, MTU: 1496, Speed: Unlimited
  Device flags   : Present Running
  Link flags     : None
  Last flapped   : Never
    Input packets : 0
    Output packets: 0
   Logical interface lsi.0 (Index 72) (SNMP ifIndex 526)
    Flags: Point-To-Point SNMP-Traps Encapsulation: LSI-NULL
    Input packets : 0
    Output packets: 0    Security: Zone: Null
    Protocol inet, MTU: 1496
      Flags: None
    Protocol iso, MTU: 1496
      Flags: Is-Primary
    Protocol inet6, MTU: 1496
      Flags: Is-Primary

Indeed an logical LSI has been created with unit 0. Let’s ping from PE3 to PE1 loopback and see if there’s any traffic passing through it

admin@PE3> ping 20.20.1.1 routing-instance B rapid count 10
PING 20.20.1.1 (20.20.1.1): 56 data bytes
!!!!!!!!!!
--- 20.20.1.1 ping statistics ---
10 packets transmitted, 10 packets received, 0% packet loss
round-trip min/avg/max/stddev = 11.965/13.287/14.027/0.873 ms
  admin@PE1> show interfaces lsi
Physical interface: lsi, Enabled, Physical link is Up
  Interface index: 4, SNMP ifIndex: 4
  Type: Software-Pseudo, Link-level type: LSI, MTU: 1496, Speed: Unlimited
  Device flags   : Present Running
  Link flags     : None
  Last flapped   : Never
    Input packets : 0
    Output packets: 0
   Logical interface lsi.0 (Index 72) (SNMP ifIndex 510)
    Flags: Point-To-Point SNMP-Traps Encapsulation: LSI-NULL
    Input packets : 10
    Output packets: 0
    Security: Zone: Null
    Protocol inet, MTU: 1496
      Flags: None
    Protocol iso, MTU: 1496
      Flags: Is-Primary
    Protocol inet6, MTU: 1496
      Flags: Is-Primary


Hopfully that clears up what the vrf-table-label command do