I put together a beginners MPLS book for Juniper. I’ve noticed, when interviewing candidates, that often they have a good knowledge of routing protocols, but lack in MPLS. This is to be expected unless they’ve worked at an ISP. The book is targeted towards those users.

J-net

https://www.juniper.net/us/en/community/junos/training-certification/day-one/networking-technologies-series/mpls-enterprise-engineers/

Amazon

http://www.amazon.com/dp/B00IU1KCJ0
http://www.amazon.co.uk/dp/B00IU1KCJ0

iTunes

https://itunes.apple.com/us/book/day-one-mpls-for-enterprise/id836201741?mt=11

Vervante (Print version)

http://store.vervante.com/c/v/V4081705490.html

Tagged with:  

L2VPN on Junos using CCC/Martini/Kompella

On August 27, 2013, in JNCIE, Juniper, by Darren

There are three main ways to provide a point to point L2 link over MPLS on Junos. Below I’ll give a brief description and show how to configure all three.

For the below descriptions I’ll be using this simple topology. All these devices are running as logical-systems on a single MX5.
L2vpn L2VPN on Junos using CCC/Martini/Kompella

CE Configs

My two CE devices will be configured the same for all three types below:
CE T1:

root@MX5:T1> show configuration interfaces ge-1/1/0
unit 0 {
    family inet {
        address 2.2.2.1/24;
    }
}

CE BB:

root@MX5:BB> show configuration interfaces ge-1/1/3
unit 0 {
    family inet {
        address 2.2.2.2/24;
    }
}

CCC

Circuit Cross-Connect is a legacy type of L2 point to point link found in Junos. CCC over MPLS requires a unique RSVP LSP per circuit per direction. It needs a unique LSP as there is no VC (inner) label. Any frames going over an LSP belongs to a specific circuit.

L2vpnCCC L2VPN on Junos using CCC/Martini/Kompella

Customers frames in either direction is encapsulated into another L2 frame with an RSVP label. This label determines which circuit the frame belongs to on the other side via the configuration.
CCC Header L2VPN on Junos using CCC/Martini/Kompella

The core network has already been set up with OSPF/RSVP/MPLS so I won’t go over that. I’ll concentrate on the PE boxes themselves. I need to create a regular RSVP LSP each way. The CCC config sits under the protocols connections stanza
R3

interfaces {
    ge-1/1/1 {
        encapsulation ethernet-ccc;
        unit 0 {
            family ccc;
        }
    }
}
protocols {
    rsvp {
        interface all;
    }
    mpls {
        label-switched-path TO-R6 {
            to 6.6.6.6;
            no-cspf;
        }
        interface all;
    }
    ospf {
        area 0.0.0.0 {
            interface all;
        }
    }
    connections {
        remote-interface-switch R6 {
            interface ge-1/1/1.0;
            transmit-lsp TO-R6;
            receive-lsp TO-R3;
        }
    }
}

R6 has a similar config back to R3. To confirm on the PE we can view via show connections:

root@MX5:R3> show connections | find R6
R6                                rmt-if      Up      Aug 26 16:41:00           2
  ge-1/1/1.0                        intf  Up
  TO-R6                             tlsp  Up
  TO-R3                             rlsp  Up

Finally we can test from the CE device:

root@MX5:T1> ping 2.2.2.2 rapid count 10
PING 2.2.2.2 (2.2.2.2): 56 data bytes
!!!!!!!!!!
--- 2.2.2.2 ping statistics ---
10 packets transmitted, 10 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.464/0.490/1.041/0.081 ms

Martini

Martini allows you to use the same LSP for multiple circuits. The circuits can be multiplexed as there is a second MPLS label in the stack. The bottom label is the VC label and it tells the PE what L2VPN the frame belongs to. Martini uses LDP to signal the VC label. Note that transport labels can use either LDP or RSVP. If using RSVP, you need to enable LDP on the loopback interfaces of both PE routers. Of course you still need at least two LSPs are LSPs are unidirectional.

The frame header will now contain an RSVP/LDP transport label as well as an LDP-signalled VC label. This allows the PEs to multiplex multiple circuits over the same LSP.
Martini Header L2VPN on Junos using CCC/Martini/Kompella

Martini is also configured under the protocols stanza.
This is R6′s config:

interfaces {
    ge-1/1/2 {
        encapsulation ethernet-ccc;
        unit 0 {
            family ccc;
        }
    }
}
protocols {
    rsvp {
        interface all;
    }
    mpls {
        label-switched-path TO-R3 {
            to 3.3.3.3;
            no-cspf;
        }
        interface all;
    }
    ospf {
        area 0.0.0.0 {
            interface all;
        }
    }
    ldp {
        interface lo0.6;
    }
    l2circuit {
        neighbor 3.3.3.3 {
            interface ge-1/1/2.0 {
                virtual-circuit-id 1;
            }
        }
    }
}

R3 and R6 should have a targeted LDP session and the circuit should be up:

root@MX5:R6> show ldp neighbor
Address            Interface          Label space ID         Hold time
3.3.3.3            lo0.6              3.3.3.3:0                39

root@MX5:R6> show l2circuit connections | find Neigh
Neighbor: 3.3.3.3
    Interface                 Type  St     Time last up          # Up trans
    ge-1/1/2.0(vc 1)          rmt   Up     Aug 26 17:28:31 2013           1
      Remote PE: 3.3.3.3, Negotiated control-word: Yes (Null)
      Incoming label: 299840, Outgoing label: 299904
      Negotiated PW status TLV: No
      Local interface: ge-1/1/2.0, Status: Up, Encapsulation: ETHERNET

All looks good. Check from CE to CE again:

root@MX5:T1> ping 2.2.2.2 rapid count 10
PING 2.2.2.2 (2.2.2.2): 56 data bytes
!!!!!!!!!!
--- 2.2.2.2 ping statistics ---
10 packets transmitted, 10 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.468/0.498/0.720/0.074 ms

Kompella

Kompella also uses a two label stack as Martini. The VC label is signaled via BGP. Once again your transport underneath can be either RSVP or LDP. Kompella has a lot more configuration than the above two, however as it uses BGP it means you can just add the l2vpn address family to your existing BGP deployment.

Kompella Header L2VPN on Junos using CCC/Martini/Kompella

I’ll show R3′s config here:

interfaces {
    ge-1/1/1 {
        encapsulation ethernet-ccc;
        unit 0 {
            family ccc;
        }
    }
}
protocols {
    rsvp {
        interface all;
    }
    mpls {
        label-switched-path TO-R6 {
            to 6.6.6.6;
            no-cspf;
        }
        interface all;
    }
    bgp {
        group iBGP {
            local-address 3.3.3.3;
            family l2vpn {
                signaling;
            }
            peer-as 100;
            neighbor 6.6.6.6;
        }
    }
    ospf {
        area 0.0.0.0 {
            interface all;
        }
    }
}
routing-instances {
    CUS1 {
        instance-type l2vpn;
        interface ge-1/1/1.0;
        route-distinguisher 100:100;
        vrf-target target:100:1;
        protocols {
            l2vpn {
                encapsulation-type ethernet;
                interface ge-1/1/1.0;
                site T1 {
                    site-identifier 1;
                    interface ge-1/1/1.0;
                }
            }
        }
    }
}
routing-options {
    autonomous-system 100;
}

Kompella uses a routing-instance exactly like a regular L3VPN in Junos. This includes the RD and RT. We can check the BGP session:

root@MX5:R3> show bgp summary
Groups: 1 Peers: 1 Down peers: 0
Table          Tot Paths  Act Paths Suppressed    History Damp State    Pending
bgp.l2vpn.0
                       1          1          0          0          0          0
Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
6.6.6.6                 100         35         35       0       0       13:52 Establ
  bgp.l2vpn.0: 1/1/1/0
  CUS1.l2vpn.0: 1/1/1/0

Final confirmation is to ping from CE to CE:

root@MX5:T1> ping 2.2.2.2 rapid count 10
PING 2.2.2.2 (2.2.2.2): 56 data bytes
!!!!!!!!!!
--- 2.2.2.2 ping statistics ---
10 packets transmitted, 10 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.469/0.497/0.714/0.072 ms

Conclusion

  • CCC cannot multiplex multiple circuits over the same LSP, hence once you start ramping up your circuits it’s not at all scalable.
  • CCC however is supported on Juniper’s EX3200 range which gives you a cheap option to offer L2VPN over MPLS
  • Martini and Kompella both multiplex over the same LSP by signalling VC labels
  • Martini is simple to configure and makes sense if you’re a small ISP offering a couple of links here and there, especially if you’re already running LDP
  • Kompella is a lot more complicated to configure, however it runs off the back of BGP. This means that you can use your existing BGP topology to run L3VPN/L2VPN/MGVPN/etc with a single signalling protocol.
  • BGP also scales incredibly well so its the best option for larger deployments.
Tagged with:  

The Cisco ME3600X and ME3800X series support both VPLS and H-VPLS. MPLS features require an expensive license. If you are currenlty joining a few leased lines together into a VPLS you don’t always need the more expensive MPLS license.

Any carrier circuit terminating on the Cisco ME can be placed into a bridge-group based on the dot1q tag. This can then be passed along or re-written to a new vlan tag into a Brocade XMR port which stick that frame into a VPLS. Why not just terminate the carrier circuit directly onto the XMR? I’ve recently had to do this because the XMR line cards we have do not support H-QoS. More and more carriers are aggregating many B end circuits into single high-bandwidth A end gig links. I need to be able to shape traffic outbound on a per-vlan basis, and within that queue give priority to certain queues. The ME3600X can do H-QoS and its exactly the reason I’m using it.

Let’s show a quick diagram so we know what we are talking about. Click the image for the full image:
Carrier Ports 2 300x195 ME3600X Bridge Group into a Brocade VPLS for H QoS

On the right I have two SRX210s and an 1841 sending tagged traffic into the carrier network. That carrier network is multiplexing all three circuits into a single link on the A end. That goes into the ME3600X. From the ME3600X it goes off to a Brocade XMR. That Brocade is connected to another Brocade over the MPLS core and finally to another 1841 on the other side.

On the ME3600X I could easily span each vlan over to the XMR and have the XMR VPLS them back. The issue with that is that if hosts behind SRX is sending a ton of traffic to a host at SRX2, why waste bandwidth hairpinning traffic over to the XMR when it could be done at the ME3600X?

In other words, instead of doing this:
VPLS PIN1 ME3600X Bridge Group into a Brocade VPLS for H QoS

We do something like this:
ME3400 PIN ME3600X Bridge Group into a Brocade VPLS for H QoS

Now you may be asking, why not just get this carrier to stick them in the VPLS? That could work if all these links were coming from the same carrier, but often they aren’t.

ME3600X EVC config

ethernet evc TESTLAB
!
interface GigabitEthernet0/1
 description Link to Carrier
 switchport trunk allowed vlan none
 switchport mode trunk
 service instance 1 ethernet TESTLAB
  description SRX1
  encapsulation dot1q 2000
  rewrite ingress tag pop 1 symmetric
  bridge-domain 150
 !
 service instance 2 ethernet TESTLAB
  description SRX2
  encapsulation dot1q 2001
  rewrite ingress tag pop 1 symmetric
  bridge-domain 150
 !
 service instance 3 ethernet TESTLAB
  description 1841
  encapsulation dot1q 2002 second-dot1q 100
  rewrite ingress tag pop 2 symmetric
  bridge-domain 150
 !
interface GigabitEthernet0/24
 description Link to XMR
 switchport trunk allowed vlan none
 switchport mode trunk
 service instance 150 ethernet
  description VPLS Core
  encapsulation dot1q 150
  rewrite ingress tag pop 1 symmetric
  bridge-domain 150
 !
end

I have three service instances configured on gi0/1 – each matching the vlan id that the carrier is using for transport. Notice that I can match on both an outer and inner tag that I’m originating from the 1841. Gi0/24 is the port connected to the XMR and that’s in the same bridge-group with a vlan tag of 150.

On the XMR side I’m simply matching on vlan 150 and placing those frames in the VPLS.

Brocade Config

vpls DARREN-TESTING 3200
  vpls-peer 172.10.10.1
  vlan 150
   tagged ethe 2/20

Connectivity verification

All my CPEs are running OSPF on their WAN links. I’ve also hard-coded their MAC addresses so it’ll be easy to see in this post.

darreno@JR1> show ospf neighbor
Address          Interface              State     ID               Pri  Dead
10.0.0.4         ge-0/0/1.2000          Full      4.4.4.4            1    39
10.0.0.3         ge-0/0/1.2000          2Way      3.3.3.3            1    34
10.0.0.2         ge-0/0/1.2000          Full      2.2.2.2          128    32

SRX1 has three neighbours. Fully adjacent with the DR and BDR. This means I get get to the remote VPLS 1841. Let’s take a look at the mac address table for the VPLS on the PE connected to the ME3600x:

SSH@pe2#sh mac vpls 3200

Total MAC entries for VPLS 3200: 5 (Local: 3, Remote: 2)

VPLS       MAC Address    L/R Port  Vlan(In-Tag)/Peer ISID      Age
====       ===========    === ====  ================= ====      ===
3200       0000.1111.0000 L   2/20  150               NA        0
3200       0000.2222.0000 L   2/20  150               NA        0
3200       0000.3333.0000 L   2/20  150               NA        0
3200       0000.4444.0000 R   1/10  172.10.10.1       NA        0

The MAC’s for SRX1, SRX2, and the first 1841 are all via tag 150 out interface 2/20. The remote 1841′s MAC is learned via the remote PE router.

We should see all four MACs on thee ME3600X out their respective tagged ports:

ME3600X#show mac address-table bridge-domain 150 | begin DYNAMIC
 150    0000.1111.0000    DYNAMIC     Gi0/1+Efp1
 150    0000.2222.0000    DYNAMIC     Gi0/1+Efp2
 150    0000.3333.0000    DYNAMIC     Gi0/1+Efp3
 150    0000.4444.0000    DYNAMIC     Gi0/24+Efp150

The ME3600X is also telling us which service instance under the physical port it’s learning the MAC address from.

QoS Config

Let’s assume the the circuit tagged with vlan 2000 has only got 5Mb, lan 2001 has 10Mb, and vlan 2001 has 15Mb. I want to shape each EVC to their respective speed, and then give priority to DSCP EF packets. I also want to police that queue to 50% to ensure that priority queue cannot hog the link.

class-map match-all EF
 match dscp ef
!
policy-map QoS
 class EF
  priority
  police cir percent 50
   conform-action transmit
   exceed-action drop
 class class-default
  queue-limit percent 100
!
policy-map VLAN2000
 class class-default
  shape average 5000000
   service-policy QoS
policy-map VLAN2001
 class class-default
  shape average 10000000
   service-policy QoS
policy-map VLAN2002
 class class-default
  shape average 15000000
   service-policy QoS

Each policy is then attached to the service instance itself. I’ll use service instance 1 as an example here:

interface GigabitEthernet0/1
 service instance 1 ethernet TESTLAB
  description SRX1
  encapsulation dot1q 2000
  rewrite ingress tag pop 1 symmetric
  service-policy output VLAN2000
  bridge-domain 150

Each service instance can have an individual policy. So we have broken up the physical port into many virtual circuits. Each VC has their own shaper and priority queue.

QoS Verification

If you apply the policy as above, you can’t use show policy-map interface anymore. Instead you need to use show ethernet service instance policy-map

ME3600X#show ethernet service instance policy-map
  GigabitEthernet0/1: EFP 1

  Service-policy output: VLAN2000

    Class-map: class-default (match-any)
      8 packets, 644 bytes
      5 minute offered rate 0000 bps, drop rate 0000 bps
      Match: any
  Traffic Shaping
    Average Rate Traffic Shaping
    Shape 5000 (kbps)
      Output Queue:
        Default Queue-limit 49152 bytes
        Tail Packets Drop: 0
        Tail Bytes Drop: 0

      Service-policy : QoS

        Class-map: EF (match-all)
          0 packets, 0 bytes
          5 minute offered rate 0000 bps, drop rate 0000 bps
          Match:  dscp ef (46)
          Strict Priority
          police:
            cir percent 50 % bc 250 ms
            cir 2500000 bps, bc 78000 bytes
            conform-action transmit
            exceed-action drop
          conform: 0 (packets) 0 (bytes)
          exceed: 0 (packets) 0 (bytes)
          conform: 0 bps, exceed: 0 bps
          Queue-limit current-queue-depth 0 bytes
              Output Queue:
                Default Queue-limit 49152 bytes
                Tail Packets Drop: 0
                Tail Bytes Drop: 0

        Class-map: class-default (match-any)
          8 packets, 644 bytes
          5 minute offered rate 0000 bps, drop rate 0000 bps
          Match: any
          Queue-limit 100 percent
          Queue-limit current-queue-depth 0 bytes
              Output Queue:
                Default Queue-limit 49152 bytes
                Tail Packets Drop: 0
                Tail Bytes Drop: 0

OSPF packets are going through and that’s being matched by class-default. We can force some EF traffic by pinging with a TOS value:

darreno@JR2> ping 10.0.0.1 rapid tos 184
PING 10.0.0.1 (10.0.0.1): 56 data bytes
!!!!!
--- 10.0.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 3.766/4.635/7.131/1.269 ms
ME3600X#show ethernet service instance policy-map
  GigabitEthernet0/1: EFP 1

  Service-policy output: VLAN2000

    Class-map: class-default (match-any)
      328 packets, 26028 bytes
      5 minute offered rate 2000 bps, drop rate 0000 bps
      Match: any
  Traffic Shaping
    Average Rate Traffic Shaping
    Shape 5000 (kbps)
      Output Queue:
        Default Queue-limit 49152 bytes
        Tail Packets Drop: 0
        Tail Bytes Drop: 0

      Service-policy : QoS

        Class-map: EF (match-all)
          5 packets, 530 bytes
          5 minute offered rate 0000 bps, drop rate 0000 bps
          Match:  dscp ef (46)
          Strict Priority
          police:
            cir percent 50 % bc 250 ms
            cir 2500000 bps, bc 78000 bytes
            conform-action transmit
            exceed-action drop
          conform: 5 (packets) 510 (bytes)
          exceed: 0 (packets) 0 (bytes)
          conform: 0 bps, exceed: 0 bps
          Queue-limit current-queue-depth 0 bytes
              Output Queue:
                Default Queue-limit 49152 bytes
                Tail Packets Drop: 0
                Tail Bytes Drop: 0

        Class-map: class-default (match-any)
          323 packets, 25498 bytes
          5 minute offered rate 2000 bps, drop rate 0000 bps
          Match: any
          Queue-limit 100 percent
          Queue-limit current-queue-depth 0 bytes
              Output Queue:
                Default Queue-limit 49152 bytes
                Tail Packets Drop: 0
                Tail Bytes Drop: 0

There we see the five EF packets.

So there you have it. Not too difficult at all to get the basics working.

Tagged with:  

Carrier Supporting Carrier

On May 6, 2013, in CCIE, by Darren

CSC, or Carrier Supporting Carrier, takes inter-AS L3 VPN to the next level. Let’s say that you are an ISP and you are offering L3VPN MPLS services to your customers in England. You take over another ISP located in say, Australia, and two of your UK customers are also located in Australia. They would like their offices in both locations connected over the MPLS cloud.

It would be very expensive to run a new line between those locations. You do, however, still want to provide L3VPN services to your customers. The is where CSC comes in. CSC allows another ISP to connect both sides of your ISP network together. It also ensures the the core ISP doesn’t learn about any of your customer prefixes, as it doesn’t need to.

Let’s take the following diagram into consideration. (click the image for full size)
Screen Shot 2013 05 04 at 21.01.11 1024x214 Carrier Supporting Carrier
Routers 1, 7, 14, 6, 9, and 8 are all part of ISP2. There are three routers located in each geographical location. Routers 2, 3, 15, and 5 are part of the core carrier. This network stretches to both locations. The rest are customer routers injecting their loopback addresses into OSPF to test.

The core carrier is running IS-IS and LDP. ISP100 is running OSPF and LDP. I won’t go into the regular IGP+LDP config as is pretty straightforward.

With CSC, there are a few new terms to deal with. R14 and R8 are going to be regular PE routers for our ISP. R1 and R6 are going to be called CSC-CE (Customer Supporting Carrier – Customer Edge) routers. R2 and R5 are going to be CSC-PE (Customer Supporting Carrier – Provider Edge) routers. All other ISP routers are simply core routers.

The terminology above assumes that you are speaking in regards to being the core carrier (ISP 500 in this case). That is, ISP500′s edge routers are ‘PE’ and R1 and R6 is the customer’s (ISP) PE routers (Called CE in this case)

It’s a little confusing, depending on which view you take, but it’s really not that difficult.

Initial R14/R8 config – regular PE

The first thing we can start off with is to ensure R14′s PE config is correct. I am running OSPF with the CE routers and learning routes from them:

vrf definition CUS1
 rd 14.14.14.14:1
 route-target export 100:1
 route-target import 100:1
 !
 address-family ipv4
 exit-address-family
!
vrf definition CUS2
 rd 14.14.14.14:2
 route-target export 100:2
 route-target import 100:2
 !
 address-family ipv4
 exit-address-family
!
interface FastEthernet1/1
 vrf forwarding CUS1
 ip address 10.14.16.14 255.255.255.0
 ip ospf network point-to-point
 ip ospf 3 area 0
!
interface FastEthernet2/0
 vrf forwarding CUS2
 ip address 10.14.15.14 255.255.255.0
 ip ospf network point-to-point
 ip ospf 2 area 0

R8 has a similar config on the other side so I won’t put it here.

CSC-PE config

R2 and R5 are going to act as PE routers for the core carrier. They will have their AS200 facing interfaces in a VRF. R2 and R5 will be running regular VPNv4 BGP with each other.
csc pe Carrier Supporting Carrier
R2:

vrf definition CSC_AS100
 rd 2.2.2.2:500
 route-target export 500:100
 route-target import 500:100
 !
 address-family ipv4
 exit-address-family
!
interface FastEthernet1/0
 vrf forwarding CSC_AS100
 ip address 10.1.2.2 255.255.255.0
!
router bgp 500
 no bgp default ipv4-unicast
 neighbor 5.5.5.5 remote-as 500
 neighbor 5.5.5.5 update-source Loopback0
 !
 address-family vpnv4
  neighbor 5.5.5.5 activate
  neighbor 5.5.5.5 send-community extended
 exit-address-family

Once again, R5 has a similar config on the other side so I’m not putting it here.

CSC-CE

Eventually we need R14 and R8 to peer with each other via VPNv4.
csc pe customer Carrier Supporting CarrierThis is much like option C in the inter-AS config in which two PE routers peer with each other even though they are not directly connected in the same AS. In order to do so we need each of them to have a valid route to each other. As R1 and R6 each have routes to their local PE device, they need to learn routes from the other side through the core carrier. To do this I’ll be running BGP to the core carrier. I also need to ensure that I’m sending and receiving labeled BGP routes and the end LSP has to be end to end. No part of the path can be unlabelled. I need to advertise the PE’s (R14 and R8) loopback are advertised over to the core carrier:

interface FastEthernet1/0
 ip address 10.1.2.1 255.255.255.0
 mpls bgp forwarding
!
router bgp 100
 bgp log-neighbor-changes
 neighbor 10.1.2.2 remote-as 500
 !
 address-family ipv4
  network 14.14.14.14 mask 255.255.255.255
  neighbor 10.1.2.2 activate
  neighbor 10.1.2.2 allowas-in 1
  neighbor 10.1.2.2 send-label
  no auto-summary
 exit-address-family

I’ll need to allowas-in 1 as both sides are running the same AS number. Without it, the CSC-CE routers would reject the BGP update.

I then need to ensure the CSC-CE routers are redistributing those learned prefixes into the IGP:

router ospf 1
 redistribute bgp 100 subnets

R6 again has a similar config.

The end result of it so far is that R8 and R14 should now be able to ping each other from their respective loopbacks:

R8#ping 14.14.14.14 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 14.14.14.14, timeout is 2 seconds:
Packet sent with a source address of 8.8.8.8
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 32/45/56 ms
R8#traceroute 14.14.14.14 so lo0

Type escape sequence to abort.
Tracing the route to 14.14.14.14

  1 10.8.9.9 [MPLS: Label 24 Exp 0] 56 msec 44 msec 32 msec
  2 10.6.9.6 [MPLS: Label 24 Exp 0] 60 msec 24 msec 60 msec
  3 10.5.6.5 [MPLS: Label 16 Exp 0] 44 msec 44 msec 48 msec
  4 10.5.13.13 [MPLS: Labels 20/34 Exp 0] 48 msec 44 msec 44 msec
  5 10.3.13.3 [MPLS: Labels 19/34 Exp 0] 44 msec 44 msec 40 msec
  6 10.1.2.2 [MPLS: Label 34 Exp 0] 40 msec 44 msec 44 msec
  7 10.1.2.1 [MPLS: Label 19 Exp 0] 44 msec 44 msec 28 msec
  8 10.1.7.7 [MPLS: Label 18 Exp 0] 56 msec 32 msec 12 msec
  9 10.7.14.14 52 msec *  72 msec

Which they can.

PE config – continued

Now that the PE routers have connectivity to each other, we can set up the VPNv4 BGP session:

router bgp 100
 no bgp default ipv4-unicast
 neighbor 8.8.8.8 remote-as 100
 neighbor 8.8.8.8 update-source Loopback0
 !
 address-family vpnv4
  neighbor 8.8.8.8 activate
  neighbor 8.8.8.8 send-community extended
 exit-address-family

Is the session up?

R14#show bgp vpnv4 unicast all summary
BGP router identifier 14.14.14.14, local AS number 100
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
8.8.8.8         4          100       4       4        1    0    0 00:00:50        0

Yes, but no prefixes learnt. We still need to redistribute between our vrf aware OSPF processes and BGP:

router ospf 3 vrf CUS1
 redistribute bgp 100 subnets
!
router ospf 2 vrf CUS2
 redistribute bgp 100 subnets
!
router bgp 100
 !
address-family ipv4 vrf CUS1
  redistribute ospf 3 vrf CUS1
 exit-address-family
!
address-family ipv4 vrf CUS2
  redistribute ospf 2 vrf CUS2
 exit-address-family

Verification

As always with these types of configs, we need to ensure both the control and data planes are working correctly. First let’s see the control plane update of R16′s loopback over to R11. The PE router of R14 should be learning this as a vrf prefix:

R14#show ip route vrf CUS1 16.16.16.16

Routing Table: CUS1
Routing entry for 16.16.16.16/32
  Known via "ospf 3", distance 110, metric 2, type intra area
  Redistributing via bgp 100
  Advertised by bgp 100
  Last update from 10.14.16.16 on FastEthernet1/1, 00:18:35 ago
  Routing Descriptor Blocks:
  * 10.14.16.16, from 16.16.16.16, 00:18:35 ago, via FastEthernet1/1
      Route metric is 2, traffic share count is 1

This prefix is converted into a VPNv4 prefix and advertised over to R8:

R8#show bgp vpnv4 un rd 14.14.14.14:1 16.16.16.16
BGP routing table entry for 14.14.14.14:1:16.16.16.16/32, version 3
Paths: (1 available, best #1, no table)
  Not advertised to any peer
  Local
    14.14.14.14 (metric 1) from 14.14.14.14 (14.14.14.14)
      Origin incomplete, metric 2, localpref 100, valid, internal, best
      Extended Community: RT:100:1 OSPF DOMAIN ID:0x0005:0x000000030200
        OSPF RT:0.0.0.0:2:0 OSPF ROUTER ID:10.14.16.14:0
      mpls labels in/out nolabel/27

This should end up in the correct vrf table:

R8#show ip route vrf CUS1 16.16.16.16

Routing Table: CUS1
Routing entry for 16.16.16.16/32
  Known via "bgp 100", distance 200, metric 2, type internal
  Redistributing via ospf 2
  Advertised by ospf 2 subnets
  Last update from 14.14.14.14 00:07:03 ago
  Routing Descriptor Blocks:
  * 14.14.14.14 (default), from 14.14.14.14, 00:07:03 ago
      Route metric is 2, traffic share count is 1
      AS Hops 0
      MPLS label: 27
      MPLS Flags: MPLS Required

Finally R11 should receive that as on OSPF route:

R11#show ip route 16.16.16.16
Routing entry for 16.16.16.16/32
  Known via "ospf 1", distance 110, metric 2
  Tag Complete, Path Length == 1, AS 100, , type extern 2, forward metric 1
  Last update from 10.8.11.8 on FastEthernet1/0, 00:06:38 ago
  Routing Descriptor Blocks:
  * 10.8.11.8, from 10.8.11.8, 00:06:38 ago, via FastEthernet1/0
      Route metric is 2, traffic share count is 1
      Route tag 3489661028

So our control plane is all good so far. Let’s check our data plane forwarding:

R11#ping 16.16.16.16 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 16.16.16.16, timeout is 2 seconds:
Packet sent with a source address of 11.11.11.11
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 44/57/76 ms


R11#traceroute 16.16.16.16 so lo0

Type escape sequence to abort.
Tracing the route to 16.16.16.16

  1 10.8.11.8 8 msec 12 msec 12 msec
  2 10.8.9.9 [MPLS: Labels 24/27 Exp 0] 52 msec 56 msec 48 msec
  3 10.6.9.6 [MPLS: Labels 24/27 Exp 0] 56 msec 48 msec 48 msec
  4 10.5.6.5 [MPLS: Labels 16/27 Exp 0] 56 msec 40 msec 68 msec
  5 10.5.13.13 [MPLS: Labels 20/34/27 Exp 0] 52 msec 44 msec 52 msec
  6 10.3.13.3 [MPLS: Labels 19/34/27 Exp 0] 56 msec 48 msec 40 msec
  7 10.2.3.2 [MPLS: Labels 34/27 Exp 0] 52 msec 52 msec 40 msec
  8 10.1.2.1 [MPLS: Labels 19/27 Exp 0] 44 msec 44 msec 48 msec
  9 10.1.7.7 [MPLS: Labels 18/27 Exp 0] 52 msec 40 msec 60 msec
 10 10.14.16.14 [MPLS: Label 27 Exp 0] 40 msec 44 msec 36 msec
 11 10.14.16.16 44 msec *  52 msec

No problems there :)

Carrier Supporing Carrier Supporting Carrier

So let’s be silly and go a step further. What if our final customer is actually another ISP offering L3VPN to it’s customers? Let’s change our topology slightly(click the image for full size)
Screen Shot 2013 05 06 at 19.14.59 1024x208 Carrier Supporting Carrier

I’m not going to show all the config here as it’s simply too much to fit into a blog post. However the config itself is pretty much like so. You’ll need to click the image for the larger version:
cscsc 1024x327 Carrier Supporting Carrier

R10 and R15 are our final CE routers. Once all is configured does it all actually work?

R10#traceroute 15.15.15.15 so lo0

Type escape sequence to abort.
Tracing the route to 15.15.15.15

  1 10.10.11.11 12 msec 12 msec 8 msec
  2 10.8.11.8 [MPLS: Labels 16/17 Exp 0] 72 msec 48 msec 68 msec
  3 10.8.9.9 [MPLS: Labels 22/24/17 Exp 0] 36 msec 80 msec 44 msec
  4 10.6.9.6 [MPLS: Labels 20/24/17 Exp 0] 52 msec 56 msec 52 msec
  5 10.5.6.5 [MPLS: Labels 23/24/17 Exp 0] 64 msec 52 msec 52 msec
  6 10.5.13.13 [MPLS: Labels 20/23/24/17 Exp 0] 48 msec 60 msec 52 msec
  7 10.3.13.3 [MPLS: Labels 19/23/24/17 Exp 0] 56 msec 56 msec 48 msec
  8 10.2.3.2 [MPLS: Labels 23/24/17 Exp 0] 56 msec 44 msec 56 msec
  9 10.1.2.1 [MPLS: Labels 19/24/17 Exp 0] 48 msec 48 msec 64 msec
 10 10.1.7.7 [MPLS: Labels 16/24/17 Exp 0] 56 msec 52 msec 60 msec
 11 10.7.14.14 [MPLS: Labels 24/17 Exp 0] 44 msec 56 msec 56 msec
 12 10.15.16.16 [MPLS: Label 17 Exp 0] 56 msec 56 msec 44 msec
 13 10.15.16.15 56 msec *  76 msec

It does indeed. At this point we are up to a four label stack in AS500. If we were running RSVP-TE and FRR we would have even more labels sitting on top.

There is a much easier way to do this of course. The original Customer Carrier could just buy some some or virtual leased line or VPLS from AS500 and they would be directly connected over the same subnet. They could then run MPLS over that link and as far as anyone cares R1 and R6 would be directly connected to each other.

But of course this is a topic on the CCIE SP after all…

Tagged with:  

I wanted to replicate the VRF using PBR post I did over here. Anyne who has used Junos will tell you that their version of PBR, while more powerful, is a lot more complicated that Cisco’s offering.

Let’s use the following topology:
Junos PBR VRF Selection Using Filter Based Forwarding   Junos

R3 is going to be my source. It will have multiple interfaces configured. When I send traffic off to R2, I would like R2 to decide which VRF the packet should go into based on the source address used by R3. R2 and R4 are going to be simple ISP PE devices. R1 and R5 are going to be in VRF’s CUS1 and CUS5 respectively.

Configuration

CPE config

All the CPE routers have their loopback configured and have a static route pointing to their connected PE.
All the CPEs are configured simiraily. I’m only going to show the configuration of one.

USER3:R3> show configuration interfaces
ae1 {
    unit 12 {
        vlan-id 12;
        family inet {
            address 10.0.4.5/30;
        }
    }
}
lo0 {
    unit 3 {
        family inet {
            address 3.3.3.3/32;
        }
    }
}

USER3:R3> show configuration routing-options
static {
    route 0.0.0.0/0 next-hop 10.0.4.6;
}

PE Config

R4 is a regular PE so nothing special:

USER4:R4> show configuration
interfaces {
    fe-0/0/3 {
        unit 24 {
            vlan-id 24;
            family inet {
                address 10.0.4.9/30;
            }
            family mpls;
        }
    }
    ae1 {
        unit 34 {
            vlan-id 34;
            family inet {
                address 10.0.2.5/30;
            }
        }
        unit 45 {
            vlan-id 45;
            family inet {
                address 10.0.8.9/30;
            }
        }
    }
    lo0 {
        unit 4 {
            family inet {
                address 4.4.4.4/32;
            }
        }
    }
}
protocols {
    mpls {
        interface fe-0/0/3.24;
    }
    bgp {
        group L3VPN {
            local-address 4.4.4.4;
            family inet-vpn {
                unicast;
            }
            peer-as 100;
            neighbor 2.2.2.2;
        }
    }
    ospf {
        area 0.0.0.0 {
            interface fe-0/0/3.24;
            interface lo0.4;
        }
    }
    ldp {
        interface fe-0/0/3.24;
    }
}
routing-instances {
    CUS1 {
        instance-type vrf;
        interface ae1.34;
        route-distinguisher 100:1;
        vrf-target target:100:1;
        routing-options {
            static {
                route 1.1.1.1/32 next-hop 10.0.2.6;
            }
        }
    }
    CUS5 {
        instance-type vrf;
        interface ae1.45;
        route-distinguisher 100:5;
        vrf-target target:100:5;
        routing-options {
            static {
                route 5.5.5.5/32 next-hop 10.0.8.10;
            }
        }
    }
}
routing-options {
    autonomous-system 100;
}

As you can see, R4 has a static route to R1 and R5 in each respective VRF. That information is then sent off to R2 as an MP-BGP update.

R2 is where all the magic happens. I need to ensure that packets coming into interface fe-0/0/3.12 via R3 is put into various VRFs based on the source address. I also need to ensure that R2 is able to get back to either these addresses over the VRF, even though interface fe-0/0/3.12 is not in a VRF.

First, let’s create a firewall filter that will match and move packets to the right VRF:

USER2:R2> show configuration firewall
family inet {
    filter VRF_FBF {
        term CUS1 {
            from {
                address {
                    192.168.1.1/32;
                }
            }
            then {
                routing-instance CUS1;
            }
        }
        term CUS5 {
            from {
                address {
                    192.168.5.5/32;
                }
            }
            then {
                routing-instance CUS5;
            }
        }
        term ANY {
            then accept;
        }
    }
}

If a packet comes in with a source address of 192.168.1.1/32, send that off to the CUS1 vrf. If it comes in with a source address of 192.168.5.5/32, send that off to the CUS2 vrf. I’ve then got a catch-all to ensure any other packets are not dropped. Once that filter is created. I need to apply it inbound in my interface:

USER2:R2> show configuration interfaces fe-0/0/3.12
vlan-id 12;
family inet {
    filter {
        input VRF_FBF;
    }
    address 10.0.4.6/30;
}

This is great for packets coming into R2 from R3, but what about getting back? I could create static routes in each VRF, but the actual link between R2 and R3 is not in any VRF. i.e. the next-hops will not be able to be resolved. I could have a static route pointing to the default/global vrf, but I could also use a rib-group to get that interface into both vrfs.

Let’s try the second option. I wanted to get 10.0.4.4/30 into both VRFs. I also want to ensure only this link gets into the vrf and not all the others.

USER2:R2> show configuration policy-options
policy-statement R2-R3-LINK {
    term 1 {
        from {
            route-filter 10.0.4.4/30 exact;
        }
        then accept;
    }
    term 2 {
        then reject;
    }
}

USER2:R2> show configuration routing-options rib-groups
GLOBAL_TO_VRF {
    import-rib [ inet.0 CUS1.inet.0 CUS5.inet.0 ];
    import-policy R2-R3-LINK;
}

USER2:R2> show configuration routing-options interface-routes
rib-group inet GLOBAL_TO_VRF;

The above says to match 10.0.4.4/30 and nothing else. That is applied to interface-routes which calls a rib-group. That rib-group states that when the interface route is placed in the default/global RIB, place it in CUS1 and CUS5′s RIB at the same time.

Verification

The end result of this is from from R2′s perspective, in the CUS1 RIB I should see R1′s address, R3′s 192.168.1.1/32 address, the R2-R3 link, and the R4-R1 link:

USER2:R2> show route table CUS1

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

1.1.1.1/32         *[BGP/170] 01:17:21, localpref 100, from 4.4.4.4
                      AS path: I
                    > to 10.0.4.9 via ae1.24, Push 299792
10.0.2.4/30        *[BGP/170] 01:17:21, localpref 100, from 4.4.4.4
                      AS path: I
                    > to 10.0.4.9 via ae1.24, Push 299792
10.0.4.4/30        *[Direct/0] 00:56:02
                    > via fe-0/0/3.12
192.168.1.1/32     *[Static/5] 00:56:02
                    > to 10.0.4.5 via fe-0/0/3.12

If we check CUS5′s RIB, I should see R5′s address, R3′s 192.168.5.5/32 address, the R2-R3 link again, and the R4-R5 link:

USER2:R2> show route table CUS5

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

5.5.5.5/32         *[BGP/170] 01:23:36, localpref 100, from 4.4.4.4
                      AS path: I
                    > to 10.0.4.9 via ae1.24, Push 299808
10.0.4.4/30        *[Direct/0] 00:58:51
                    > via fe-0/0/3.12
10.0.8.8/30        *[BGP/170] 01:23:36, localpref 100, from 4.4.4.4
                      AS path: I
                    > to 10.0.4.9 via ae1.24, Push 299808
192.168.5.5/32     *[Static/5] 00:58:51
                    > to 10.0.4.5 via fe-0/0/3.12

So our control plane is working perfectly fine. Let’s check our data plane for the final verification:

USER3:R3> ping 1.1.1.1 source 192.168.1.1 rapid
PING 1.1.1.1 (1.1.1.1): 56 data bytes
!!!!!
--- 1.1.1.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.252/1.466/1.823/0.211 ms

USER3:R3> ping 1.1.1.1 source 192.168.5.5 rapid
PING 1.1.1.1 (1.1.1.1): 56 data bytes
.....
--- 1.1.1.1 ping statistics ---
5 packets transmitted, 0 packets received, 100% packet loss

R3 to R1 is working as expected. Let’s check R3 to R5:

USER3:R3> ping 5.5.5.5 source 192.168.5.5 rapid
PING 5.5.5.5 (5.5.5.5): 56 data bytes
!!!!!
--- 5.5.5.5 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.262/1.358/1.577/0.115 ms

USER3:R3> ping 5.5.5.5 source 192.168.1.1 rapid
PING 5.5.5.5 (5.5.5.5): 56 data bytes
.....
--- 5.5.5.5 ping statistics ---
5 packets transmitted, 0 packets received, 100% packet loss

No problems there.

Tagged with:  

© 2009-2014 Darren O'Connor All Rights Reserved