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