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:

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.
VPLS is a LAN emulation service that can be run over an MPLS backbone. I do not have a ton of free devices on hand and so my acual lab will only consist of two CE devices even though it supports more than two. VPLS runs over an MPLS core constructed by RSVP-TE or LDP LSP tunnels. VPLS itself requires either LDP (RFC 4762) or BGP (RFC 4761) as the VC singnalling protocol. Note that when LDP is used, this is a targeted LDP session and has nothing to do with the protocol you use for the LSPs itself. To prove this I will be using RSVP-TE LSP tunnels with LDP and BGP on top.
Part one of this series will use LDP as the VC signalling protocol. Part two will use BGP.
I was originally going to include Cisco’s IOS as well, but you need a 6500 or 7600 and I don’t have a spare. The 7200 platform does not support VPLS.
This the the topology I’m going to use:

R2 and R3 are P routers. R1 is a Junos PE and R8 is a Netiron PE. R6 and R10 are both CPEs
The actual P router config is standard RSVP-TE which I have covered extensively on this site already. The CPE’s have both been configured to be in the same subnet (10.0.0.0/24)
PE Config
Junos
darreno> show configuration interfaces fe-0/0/2
encapsulation ethernet-vpls;
unit 0 {
family vpls;
}
darreno> show configuration protocols ldp
interface lo0.1;
darreno> show configuration routing-instances
MELLOWD-VPLS {
instance-type vpls;
interface fe-0/0/2.0;
protocols {
vpls {
vpls-id 150;
neighbor 8.8.8.8;
}
}
}
On Junos you need to enable LDP on the loopback interface, even when running RSVP. You need to ensure VPLS encapsulation is on the physical interface. Finally you need to create the VPLS instance and tie this all together. You specify neighbours under the process. This actually creates the targeted LDP sessions (i.e. there is no need to specify a T-LDP session separately)
PE Config
Netiron
Brocade’s Netiron config is actually very simple compared to the above
router mpls mpls-interface ve2 vpls MELLOWD-VPLS 150 vpls-peer 1.1.1.1 vpls-mtu 1500 vlan 550 tagged ethe 3/19
That’s it. When you enable rsvp on an interface, and then set up a VPLS with a neighbour, it automatically sets up a T-LDP session with it’s peer. Under the VLAN I’ve said tagged eth 3/19 as it’ll be receiving tagged frames from the CPE router.
Verification
Control Plane
Let’s check to see if the session is actually up:
darreno> show vpls connections
Layer-2 VPN connections:
Legend for connection status (St)
[deleted for brevity]
Legend for interface status
Up -- operational
Dn -- down
Instance: MELLOWD-VPLS
VPLS-id: 150
Neighbor Type St Time last up # Up trans
8.8.8.8(vpls-id 150) rmt Up Mar 8 13:52:45 2013 1
Remote PE: 8.8.8.8, Negotiated control-word: No
Incoming label: 800000, Outgoing label: 983040
Negotiated PW status TLV: No
Local interface: vt-0/2/0.1048579, Status: Up, Encapsulation: ETHERNET
Description: Intf - vpls MELLOWD-VPLS neighbor 8.8.8.8 vpls-id 150
SSH@XMR_R8# show mpls vpls id 150 VPLS MELLOWD-VPLS, Id 150, Max mac entries: 8192 Routing Interface Id 150 Total vlans: 1, Tagged ports: 1 (1 Up), Untagged ports 0 (0 Up) IFL-ID: n/a Vlan 550 L2 Protocol: NONE Tagged: ethe 3/19 VC-Mode: Raw Total VPLS peers: 1 (1 Operational) Peer address: 1.1.1.1, State: Operational, Uptime: 55 min Tnnl in use: tnl2(299984)[RSVP] Peer Index:0 Local VC lbl: 983040, Remote VC lbl: 800000 Local VC MTU: 1500, Remote VC MTU: 1500 Local VC-Type: Ethernet(0x05), Remote VC-Type: Ethernet(0x05) CPU-Protection: OFF Local Switching: Enabled Extended Counter: ON Multicast Snooping: Disabled
Both sessions are up. Both see the others VC labels. Can we show that LDP is actually used?
darreno> show ldp neighbor Address Interface Label space ID Hold time 8.8.8.8 lo0.1 8.8.8.8:0 36
SSH@XMR_R8#sh mpls ldp neighbor Number of link neighbors: 0 Number of targeted neighbors: 1 Nbr Transport Interface Nbr LDP ID Max Hold Time Left 1.1.1.1 (targeted) 1.1.1.1:0 45 42
Verification
Data Plane
So can our CPE’s ping each others?
R10#ping 10.0.0.6 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 10.0.0.6, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 1/3/12 ms
USER6:R6> ping 10.0.0.10 rapid count 5 PING 10.0.0.10 (10.0.0.10): 56 data bytes !!!!! --- 10.0.0.10 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 1.368/1.460/1.755/0.148 ms
No problems there. It’s always handy to check MAC addresses learned over the VPLS. We can check like so:
darreno> show route forwarding-table family vpls
Routing table: MELLOWD-VPLS.vpls
VPLS:
Destination Type RtRef Next hop Type Index NhRef Netif
default perm 0 rjct 1007 1
fe-0/0/2.0 user 0 comp 1150 2
vt-0/2/0.1048579 user 0 comp 1258 2
00:12:f2:93:a9:00/48 dynm 0 indr 262142 5
10.0.4.14 Push 983040, Push 299920(top) 1233 2 ae1.13
00:13:19:22:8f:91/48 dynm 0 ucst 1146 4 fe-0/0/2.0
00:90:69:a5:13:f1/48 dynm 0 ucst 1146 4 fe-0/0/2.0
8c:b6:4f:63:46:b8/48 dynm 0 indr 262142 5
10.0.4.14 Push 983040, Push 299920(top) 1233 2 ae1.13
SSH@XMR_R8#sh mac vpls 150 Total MAC entries for VPLS 150: 4 (Local: 1, Remote: 3) VPLS MAC Address L/R/IB Port Vlan(In-Tag)/Peer ISID Age Type ==== =========== ====== ==== ================= ==== === ==== 150 8cb6.4f63.46b8 L 3/19 550 NA 70 NA 150 0a0a.0009.0004 R 3/7 1.1.1.1 NA 250 NA 150 0013.1922.8f91 R 3/7 1.1.1.1 NA 0 NA 150 0090.69a5.13f1 R 3/7 1.1.1.1 NA 70 NA
Both outputs show local and remote locations of MAC addresses. Both also show the neighbour ID of who has the directly connected MAC address.
Management over the VPLS
A handy new feature on the Netiron is the ability to have a layer3 interface over the VPLS. This can be handy when you need to manage the CPE devices. While in the past you may need to have a ‘break-in’ interface also attached to the VPLS, you can now do it directly on the Netiron.
interface ve 150 ip address 10.0.0.8/24 ! router mpls vpls MELLOWD-VPLS 150 router-interface ve 150
This essentially works like in SVI interface on a vlan. Let’s check if we have communication:
SSH@XMR_R8#ping 10.0.0.10 Sending 1, 16-byte ICMP Echo to 10.0.0.10, timeout 5000 msec, TTL 64 Type Control-c to abort Reply from 10.0.0.10 : bytes=16 time=1ms TTL=255 Success rate is 100 percent (1/1), round-trip min/avg/max=1/1/1 ms. SSH@XMR_R8#ping 10.0.0.6 Sending 1, 16-byte ICMP Echo to 10.0.0.6, timeout 5000 msec, TTL 64 Type Control-c to abort Reply from 10.0.0.6 : bytes=16 time=1ms TTL=64 Success rate is 100 percent (1/1), round-trip min/avg/max=1/1/1 ms.
This is part two of my blog started here: http://mellowd.co.uk/ccie/?p=3300
This time each CPE is going to be connected to a VRF on the PE router. I’m only using one customer for this post, but this is regular L3VPN so scale as you see fit.
Major issue with the Netiron. It doesn’t support the VPNV6 adress family :( – I’m using the latest 5.4b code and nothing. So this means this is a Junos/IOS lab only
CPE config
All the CPEs are running BGP with their directly connected PE routers. All are advertising reachability to their IPv6 loopback addresses to their PE router. I’m only showing R6′s config as the others are the same with different addresses:
interfaces {
ae1 {
unit 36 {
vlan-id 36;
family inet6 {
address 2001:db8:36::6/64;
}
}
lo0 {
unit 6 {
family inet6 {
address 2001:db8:6666::6666/128;
}
}
}
}
protocols {
bgp {
group PROVIDER {
family inet6 {
unicast;
}
export LOOPBACK;
neighbor 2001:db8:36::3 {
peer-as 100;
}
}
}
}
policy-options {
policy-statement LOOPBACK {
from {
protocol direct;
route-filter 2001:db8:6666::6666/128 exact;
}
then accept;
}
}
routing-options {
router-id 6.6.6.6;
autonomous-system 65123 loops 2;
}
You’ll need to statically define your router-id for all sites. If a router is running ONLY IPv6, or your VRF ONLY has a IPv6 address, then the router has no IPv4 address to choose it’s router-id from. This will be a common theme throughout as you’ll also need to set router-ids in IPv6-only VRF instances.
PE config
Junos
First we need to set up the VRF to the customer and run BGP. We then need to enable the VPNV6 family in BGP. I’m going to remove the old IPv6 unicast config used in part one of this series.
USER3:R3> show configuration protocols
mpls {
ipv6-tunneling;
interface ae1.13;
}
bgp {
group 6VPE {
family inet6-vpn {
unicast;
}
peer-as 100;
neighbor 4.4.4.4;
}
}
USER3:R3> show configuration routing-instances
CUSTOMER1 {
instance-type vrf;
interface fe-0/0/3.36;
route-distinguisher 3.3.3.3:1;
vrf-target target:100:1;
routing-options {
router-id 3.3.3.3;
}
protocols {
bgp {
group EXTERNAL {
advertise-peer-as;
family inet6 {
unicast;
}
neighbor 2001:db8:36::6 {
peer-as 65123;
}
}
}
}
}
IPv6 address family running with the customer. VPNv6 address family running with IOS PE R4. Note that I have to use ‘advertise-peer-as’ on R3 as Junos will not advertise a route to an AS that already has the AS number in the path by default.
IOS
The main issue with IOS is that I cannot statically definate a BGP router-id if I’m ONLY running IPv6. BGP requires a router-id on the x.x.x.x format. IOS does not give me the option to hard-code a router-id under the BGP process for the VRF, or the ipv6 unicast address family. So I had to enable the ipv4 address-family under the VRF and define a loopback address in the VRF to use as the router-id. Very silly indeed.
vrf definition CUSTOMER1 rd 4.4.4.4:100 ! address-family ipv4 exit-address-family ! address-family ipv6 route-target export 100:1 route-target import 100:1 exit-address-family ! interface Loopback4 vrf forwarding CUSTOMER1 ip address 4.4.4.4 255.255.255.255 ! router bgp 100 bgp router-id vrf auto-assign no bgp default ipv4-unicast bgp log-neighbor-changes neighbor 3.3.3.3 remote-as 100 neighbor 3.3.3.3 update-source Loopback0 ! address-family vpnv6 neighbor 3.3.3.3 activate neighbor 3.3.3.3 send-community extended exit-address-family ! address-family ipv6 vrf CUSTOMER1 no synchronization neighbor 2001:DB8:47::7 remote-as 65123 neighbor 2001:DB8:47::7 activate exit-address-family
VRF assigned to the CE-PE link. IPv6 unicast running with the CPE and VPNv6 running with the Junos PE R3 router.
Verification
Let’s first check if our VPNv6 sessions are up:
7200_SRD_R4#show bgp vpnv6 unicast all neighbors 3.3.3.3 | include state|fam$
BGP state = Established, up for 03:09:47
Address family VPNv6 Unicast: advertised and received
For address family: VPNv6 Unicast
Connection state is ESTAB, I/O status: 1, unread input bytes: 0
USER3:R3> show bgp neighbor 4.4.4.4 | match "Estab|NLRI" Type: Internal State: Established Flags:NLRI for restart configured on peer: inet6-vpn-unicast NLRI advertised by peer: inet6-vpn-unicast NLRI for this session: inet6-vpn-unicast
Sessions are up and running the VPNv6 family.
Can the CE’s ping each other from their IPv6 loopbacks?
USER7:R7> ping 2001:db8:6666::6666 source 2001:db8:7777::7777 rapid count 5 PING6(56=40+8+8 bytes) 2001:db8:7777::7777 --> 2001:db8:6666::6666 !!!!! --- 2001:db8:6666::6666 ping6 statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/std-dev = 1.520/1.726/1.997/0.195 ms
USER6:R6> ping 2001:db8:7777::7777 source 2001:db8:6666::6666 rapid count 5 PING6(56=40+8+8 bytes) 2001:db8:6666::6666 --> 2001:db8:7777::7777 !!!!! --- 2001:db8:7777::7777 ping6 statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/std-dev = 1.533/1.706/1.968/0.147 ms
No problems there :)
I wanted to test 6PE and 6VPE interoperability with the three major vendors. As always I’m stuck with IOS only in the Cisco world for now, but what can I do. This test will run over a Junos MPLS core. All my MPLS labs thus far has been using RSVP, so let’s change this to LDP for now just to mix things up a bit.
6PE allows you to run IPv6 transport over a IPv4 MPLS core. MPLS does not have native label support for IPv6 addresses, at least yet. This means if you need to transport IPv6 traffic over your MPLS core, you need to tunnel it over IPv4. 6PE is one of those ways. 6VPE is essentially MPLS layer 3 VPN for IPv6 over an IPv4 as opposed to 6PE which is simple IPv6 over an IPv4 MPLS core.
6PE
There is no need to worry about CPE kit for now. I’ll simply have an IPv6 loopback address on R3, R4, and R8. These PE routers will peer over MP-BGP over the IPv4-only core.
R3 – Junos
interfaces {
ae1 {
unit 13 {
vlan-id 13;
family inet {
address 10.0.4.13/30;
}
family inet6;
family mpls;
}
lo0 {
unit 3 {
family inet {
address 3.3.3.3/32;
}
family inet6 {
address 2001:db8:3333::3333/128;
}
}
}
}
protocols {
mpls {
ipv6-tunneling;
interface ae1.13;
}
bgp {
group 6PE {
family inet6 {
labeled-unicast {
explicit-null;
}
}
export LOOPBACK;
peer-as 100;
neighbor 4.4.4.4;
neighbor 8.8.8.8;
}
}
ldp {
interface ae1.13;
}
}
policy-options {
policy-statement LOOPBACK {
from {
protocol direct;
route-filter 2001:db8:3333::3333/128 exact;
}
then accept;
}
}
routing-options {
autonomous-system 100;
}
Junos requires you to active the family inet6 address family on the core-facing interface, even if no address is applied. LDP is configured. BGP has been configured with family inet6 address family only. You also need to send labelled unicast as well as explicit-null. Junos will not commit if you leave this out.
I’ve then redistributed my IPv6 loopback address into BGP.
R4 – IOS
interface Loopback6 no ip address ipv6 address 2001:DB8:4444::4444/128 ! interface Loopback0 ip address 4.4.4.4 255.255.255.255 ip ospf 1 area 0 ! interface FastEthernet1/0.24 encapsulation dot1Q 24 ip address 10.0.4.9 255.255.255.252 ip ospf network point-to-point mpls ip ! router bgp 100 no bgp default ipv4-unicast bgp log-neighbor-changes neighbor 3.3.3.3 remote-as 100 neighbor 3.3.3.3 update-source Loopback0 neighbor 8.8.8.8 remote-as 100 neighbor 8.8.8.8 update-source Loopback0 ! address-family ipv6 no synchronization network 2001:DB8:4444::4444/128 neighbor 3.3.3.3 activate neighbor 3.3.3.3 send-label neighbor 8.8.8.8 activate neighbor 8.8.8.8 send-label exit-address-family
IOS is a bit easier. Create my loopback, IPv6 unicast BGP sessions with send-label configured, and advertise IPv6 loopback.
R8 – Netiron
interface loopback 1 ip ospf area 0 ip address 8.8.8.8/32 ipv6 address 2001:db8:8888::8888/128 ! router bgp local-as 100 next-hop-mpls neighbor 3.3.3.3 remote-as 100 neighbor 3.3.3.3 update-source 8.8.8.8 neighbor 4.4.4.4 remote-as 100 neighbor 4.4.4.4 update-source 8.8.8.8 address-family ipv6 unicast network 2001:db8:8888::8888/128 neighbor 3.3.3.3 activate neighbor 3.3.3.3 send-label neighbor 4.4.4.4 activate neighbor 4.4.4.4 send-label exit-address-family ! router mpls mpls-interface ve2 ldp-enable
Very similar to IOS here.
Verification
First let’s see if each of our boxes has the IPv6 routes to the others loopbacks:
USER3:R3> show route 2001:db8:4444::4444/128
inet6.0: 9 destinations, 10 routes (9 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
2001:db8:4444::4444/128
*[BGP/170] 00:19:31, MED 0, localpref 100, from 4.4.4.4
AS path: I
> to 10.0.4.14 via ae1.13, Push 16, Push 300016(top)
USER3:R3> show route 2001:db8:8888::8888/128
inet6.0: 9 destinations, 10 routes (9 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
2001:db8:8888::8888/128
*[BGP/170] 21:40:12, MED 0, localpref 100, from 8.8.8.8
AS path: I
> to 10.0.4.14 via ae1.13, Push 794624, Push 300048(top)
7200_SRD_R4#show ipv6 route 2001:DB8:3333::3333/128
Routing entry for 2001:DB8:3333::3333/128
Known via "bgp 100", distance 200, metric 0, type internal
Route count is 1/1, share count 0
Routing paths:
3.3.3.3%default indirectly connected
MPLS Required
Last updated 00:20:47 ago
7200_SRD_R4#show ipv6 route 2001:DB8:8888::8888/128
Routing entry for 2001:DB8:8888::8888/128
Known via "bgp 100", distance 200, metric 0, type internal
Route count is 1/1, share count 0
Routing paths:
8.8.8.8%default indirectly connected
MPLS Required
Last updated 00:21:00 ago
SSH@XMR_R8#show ipv6 route 2001:db8:3333::3333/128
Type Codes - B:BGP C:Connected I:ISIS L:Local O:OSPF R:RIP S:Static
BGP Codes - i:iBGP e:eBGP
ISIS Codes - L1:Level-1 L2:Level-2
OSPF Codes - i:Inter Area 1:External Type 1 2:External Type 2
STATIC Codes - d:DHCPv6
Type IPv6 Prefix Next Hop Router Interface Dis/Metric Uptime src-vrf
Bi 2001:db8:3333::3333/128
:: LDP (5) 200/0 8m3s -
label information: 2(OUT)
SSH@XMR_R8#show ipv6 route 2001:db8:4444::4444/128
Type Codes - B:BGP C:Connected I:ISIS L:Local O:OSPF R:RIP S:Static
BGP Codes - i:iBGP e:eBGP
ISIS Codes - L1:Level-1 L2:Level-2
OSPF Codes - i:Inter Area 1:External Type 1 2:External Type 2
STATIC Codes - d:DHCPv6
Type IPv6 Prefix Next Hop Router Interface Dis/Metric Uptime src-vrf
Bi 2001:db8:4444::4444/128
:: LDP (3) 200/0 7m25s -
label information: 16(OUT)
Control plane looks fine. Routes are installed with next-hops associated with labels. Let’s see if data actually flows:
USER3:R3> ping 2001:db8:4444::4444 source 2001:db8:3333::3333 rapid count 5 PING6(56=40+8+8 bytes) 2001:db8:3333::3333 --> 2001:db8:4444::4444 !!!!! --- 2001:db8:4444::4444 ping6 statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/std-dev = 1.262/1.399/1.789/0.196 ms
7200_SRD_R4#ping 2001:DB8:8888::8888 source lo6 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 2001:DB8:8888::8888, timeout is 2 seconds: Packet sent with a source address of 2001:DB8:4444::4444 !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 0/0/0 ms
SSH@XMR_R8#ping ipv6 2001:db8:3333::3333 source 2001:db8:8888::8888 count 5 Sending 5, 16-byte ICMPv6 Echo to 2001:db8:3333::3333 timeout 5000 msec, Hop Limit 64 Type Control-c to abort Reply from 2001:db8:3333::3333: bytes=16 time=1ms Hop Limit=64 Reply from 2001:db8:3333::3333: bytes=16 time<1ms Hop Limit=64 Reply from 2001:db8:3333::3333: bytes=16 time<1ms Hop Limit=64 Reply from 2001:db8:3333::3333: bytes=16 time<1ms Hop Limit=64 Reply from 2001:db8:3333::3333: bytes=16 time<1ms Hop Limit=64 Success rate is 100 percent (5/5), round-trip min/avg/max=0/0/1 ms.
All looks good to me.
You can find part 2 here: hhttp://mellowd.co.uk/ccie/?p=3546
My first of a series of posts for MPLS interoperability between Cisco’s IOS, Juniper’s Junos, and Brocade’s Netiron code. This post will use the same core I set up before:

L3 VPN is one of the more common applications for MPLS. This post will show a very basic three customer site. I’ll leave off all the advanced stuff for another post.
All three customers are connected to different PE routers. The PE and CE devices will run a routing protocol between then and advertise their loopback addresses to the core. This will emulate the customers LAN ranges.
I’m going to run BGP on R5 and R6 as the CE-PE routing protocol and OSPF on R7. The customer is running AS #65123 and the provider AS #100.
PE MP-BGP
The first thing we need to do is set up our MP-BGP peering between our PE routers. Let’s start off with IOS as it’s what most people know:
router bgp 100 no bgp default ipv4-unicast neighbor 3.3.3.3 remote-as 100 neighbor 3.3.3.3 update-source Loopback0 neighbor 8.8.8.8 remote-as 100 neighbor 8.8.8.8 update-source Loopback0 ! address-family vpnv4 neighbor 3.3.3.3 activate neighbor 3.3.3.3 send-community extended neighbor 8.8.8.8 activate neighbor 8.8.8.8 send-community extended exit-address-family
Junos:
USER3:R3> show configuration routing-options
autonomous-system 100;
USER3:R3> show configuration protocols bgp
group L3VPN {
type internal;
local-address 3.3.3.3;
family inet-vpn {
unicast;
}
neighbor 4.4.4.4;
neighbor 8.8.8.8;
}
Netiron:
router bgp local-as 100 neighbor 3.3.3.3 remote-as 100 neighbor 3.3.3.3 update-source 8.8.8.8 neighbor 4.4.4.4 remote-as 100 neighbor 4.4.4.4 update-source 8.8.8.8 ! address-family vpnv4 unicast neighbor 3.3.3.3 activate neighbor 3.3.3.3 send-community extended neighbor 4.4.4.4 activate neighbor 4.4.4.4 send-community extended exit-address-family
Netiron is very similar to IOS when it comes to IGP/BGP. On all three we have simply created a vpnv4 BGP session between all three PE routers. We are not running the regular IPv4 address family on these sessions. Let’s confirm.
IOS:
7200_SRD_R4#sh bgp vpnv4 unicast all summary | beg Nei Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 3.3.3.3 4 100 46 43 18 0 0 00:19:06 0 8.8.8.8 4 100 26 23 18 0 0 00:18:59 0
Junos:
USER3:R3> show bgp summary Groups: 1 Peers: 2 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending bgp.l3vpn.0 0 0 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State 4.4.4.4 100 43 48 0 1 19:58 Establ bgp.l3vpn.0: 0/0/0/0 8.8.8.8 100 3285 3241 0 0 1d 0:25:07 Establ bgp.l3vpn.0: 0/0/0/0
Netiron:
SSH@XMR_R8#sh ip bgp vpnv4 sum | beg AS# Neighbor Address AS# State Time Rt:Accepted Filtered Sent ToSend 3.3.3.3 100 ESTAB 1d 0h26m 2 0 0 0 4.4.4.4 100 ESTAB 0h20m43s 0 0 0 0
All of our vpn4 sessions are now up.
CE-PE – R3-R6 – Junos
R6 is a regular BGP config so I’m not pasting it here. It is simply peering with AS #100 and advertising it’s loopback address. On Junos, you configure any ce-pe protocol under the routing instance you make for your customer:
USER3:R3> show configuration routing-instances
CUSTOMER1 {
description "Our First Customer";
instance-type vrf;
interface fe-0/0/3.36;
route-distinguisher 3.3.3.3:1;
vrf-target target:100:1;
protocols {
bgp {
group EXTERNAL {
neighbor 10.0.2.13 {
family inet {
unicast;
}
peer-as 65123;
}
}
}
}
}
USER3:R3> show bgp summary instance CUSTOMER1 Groups: 1 Peers: 1 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending CUSTO.inet.0 1 1 0 0 0 0 CUSTOM.mdt.0 0 0 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State 10.0.2.13 65123 93 98 0 0 40:54 Establ CUSTOMER1.inet.0: 1/1/1/0
USER3:R3> show route table CUSTOMER1 6.6.6.6
CUSTOMER1.inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
6.6.6.6/32 *[BGP/170] 00:30:52, localpref 100
AS path: 65123 I
> to 10.0.2.13 via fe-0/0/3.36
CE-PE – R4-R7 – IOS
R7 is a simple OSPF config over area 0 advertising it’s loopback interface. The PE router is configured like so:
ip vrf CUS1 rd 4.4.4.4:1 route-target export 100:1 route-target import 100:1 ! interface FastEthernet1/0.47 encapsulation dot1Q 47 ip vrf forwarding CUS1 ip address 10.0.2.18 255.255.255.252 ip ospf network point-to-point ip ospf 2 area 0 ! router ospf 2 vrf CUS1 redistribute bgp 100 subnets ! router bgp 100 ! address-family ipv4 vrf CUS1 no synchronization redistribute ospf 2 vrf CUS1 exit-address-family
7200_SRD_R4#sh ip ospf neighbor fa0/0.47 Neighbor ID Pri State Dead Time Address Interface 7.7.7.7 0 FULL/ - 00:00:39 10.0.2.17 FastEthernet1/0.47
7200_SRD_R4#sh ip route vrf CUS1 7.7.7.7
Routing Table: CUS1
Routing entry for 7.7.7.7/32
Known via "ospf 2", distance 110, metric 1, type intra area
Redistributing via bgp 100
Advertised by bgp 100
Last update from 10.0.2.17 on FastEthernet1/0.47, 00:32:06 ago
Routing Descriptor Blocks:
* 10.0.2.17, from 7.7.7.7, 00:32:06 ago, via FastEthernet1/0.47
Route metric is 1, traffic share count is 1
CE-PE – R8-R5 – Netiron
Standard config on the CE router once again. PE router configured as follows:
vrf CUS1 rd 8.8.8.8:1 address-family ipv4 route-target export 100:1 route-target import 100:1 exit-address-family exit-vrf ! interface ve35 vrf forwarding CUS1 ip address 10.0.2.2/30 ! router bgp address-family ipv4 unicast vrf CUS1 neighbor 10.0.2.1 remote-as 65123 exit-address-family
SSH@XMR_R8#show ip bgp vrf CUS1 summary | beg AS# Neighbor Address AS# State Time Rt:Accepted Filtered Sent ToSend 10.0.2.1 65123 ESTAB 0h18m57s 1 0 4 0
SSH@XMR_R8#sh ip route vrf CUS1 5.5.5.5 | beg Des
Destination Gateway Port Cost Type Uptime src-vrf
1 5.5.5.5/32 10.0.2.1 ve 35 20/0 Be 10m58s -
At this point each PE router is running their PE-CE protocol with their CE peer and learning the loopback address. Without configuring anything else, do we see any of the routes from the other PE devices?
USER3:R3> show route table CUSTOMER1 7.7.7.7
CUSTOMER1.inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
7.7.7.7/32 *[BGP/170] 00:31:46, MED 1, localpref 100, from 4.4.4.4
AS path: ?
> to 10.0.4.14 via ae1.13, label-switched-path TO-R4
USER3:R3> show route table CUSTOMER1 5.5.5.5
CUSTOMER1.inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
5.5.5.5/32 *[BGP/170] 00:21:03, localpref 100, from 8.8.8.8
AS path: 65123 I
> to 10.0.4.14 via ae1.13, label-switched-path TO-R8
Junos sees both loopbacks. Note too that the next-hops are both via LSPs. One to R4 and one to R8.
SSH@XMR_R8#show ip route vrf CUS1 6.6.6.6
Type Codes - B:BGP D:Connected I:ISIS O:OSPF R:RIP S:Static; Cost - Dist/Metric
BGP Codes - i:iBGP e:eBGP
ISIS Codes - L1:Level-1 L2:Level-2
OSPF Codes - i:Inter Area 1:External Type 1 2:External Type 2 s:Sham Link
STATIC Codes - d:DHCPv6
Destination Gateway Port Cost Type Uptime src-vrf
1 6.6.6.6/32 DIRECT lsp TO-R3 200/0 Bi 42m12s -
SSH@XMR_R8#show ip route vrf CUS1 7.7.7.7
Type Codes - B:BGP D:Connected I:ISIS O:OSPF R:RIP S:Static; Cost - Dist/Metric
BGP Codes - i:iBGP e:eBGP
ISIS Codes - L1:Level-1 L2:Level-2
OSPF Codes - i:Inter Area 1:External Type 1 2:External Type 2 s:Sham Link
STATIC Codes - d:DHCPv6
Destination Gateway Port Cost Type Uptime src-vrf
1 7.7.7.7/32 DIRECT lsp TO-R4 200/1 Bi 33m17s -
Netiron also sees both with a next-hop of each respective LSP.
7200_SRD_R4#sh ip route vrf CUS1 6.6.6.6
Routing Table: CUS1
Routing entry for 6.6.6.6/32
Known via "bgp 100", distance 200, metric 0
Tag 65123, type internal
Redistributing via ospf 2
Advertised by ospf 2 subnets
Last update from 3.3.3.3 00:46:36 ago
Routing Descriptor Blocks:
* 3.3.3.3 (default), from 3.3.3.3, 00:46:36 ago
Route metric is 0, traffic share count is 1
AS Hops 1
Route tag 65123
MPLS Required
7200_SRD_R4#
7200_SRD_R4#sh ip route vrf CUS1 5.5.5.5
Routing Table: CUS1
Routing entry for 5.5.5.5/32
Known via "bgp 100", distance 200, metric 0
Tag 65123, type internal
Redistributing via ospf 2
Advertised by ospf 2 subnets
Last update from 8.8.8.8 00:24:47 ago
Routing Descriptor Blocks:
* 8.8.8.8 (default), from 8.8.8.8, 00:24:47 ago
Route metric is 0, traffic share count is 1
AS Hops 1
Route tag 65123
MPLS Required
IOS has the routes, but there is an issue. IOS does not use the RSVP-TE tunnels for anything unless we tell it to. We can prove this to R5 like so:
7200_SRD_R4#sh ip cef vrf CUS1 5.5.5.5 detail
5.5.5.5/32, epoch 0
recursive via 8.8.8.8 label 500000
nexthop 10.0.4.10 FastEthernet1/0.24
Traffic would never hit the other PE routers. We need to ensure IOS actually uses these tunnels:
7200_SRD_R4#conf t 7200_SRD_R4(config)#int tun 0 7200_SRD_R4(config-if)#tunnel mpls traffic-eng autoroute announce 7200_SRD_R4(config-if)#int tun 1 7200_SRD_R4(config-if)#tunnel mpls traffic-eng autoroute announce
7200_SRD_R4#sh ip cef vrf CUS1 5.5.5.5 detail
5.5.5.5/32, epoch 0
recursive via 8.8.8.8 label 500000
nexthop 8.8.8.8 Tunnel1
So now our PE routers have all the required routes. They have also correctly installed these routes to go over the RSVP-TE tunnels. There is another issue to resolve though, and that’s the fact that R5 and R6 are in the same AS number. Remember with BGP, it uses the AS-PATH as a loop prevention mechanism. Therefore if R5 received a BGP update from it’s PE router with it’s own AS number in the path, that route will get dropped.
I can configure both CE routers to accept routes with their own AS number in like so:
USER5:R5> show configuration routing-options autonomous-system 65123 loops 2;
R5 now sees R6′s route:
USER5:R5> show route 6.6.6.6
inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
6.6.6.6/32 *[BGP/170] 00:03:04, localpref 100
AS path: 100 65123 I
> to 10.0.2.2 via ae1.35
But R6 still does not see R5′s route:
USER6:R6> show route 5.5.5.5 USER6:R6>
The reason why is more clear from R3, the PE’s perspective. Is R3 even advertising that route?
USER3:R3> show route advertising-protocol bgp 10.0.2.13 CUSTOMER1.inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 7.7.7.7/32 Self ? * 10.0.2.16/30 Self ?
No it isn’t. Let’s go back to the Netiron and see if it was advertising everything over:
SSH@XMR_R8#sh ip bgp vrf CUS1 neighbors 10.0.2.1 advertised-routes
There are 4 routes advertised to neighbor 10.0.2.1
Status A:AGGREGATE B:BEST b:NOT-INSTALLED-BEST E:EBGP I:IBGP L:LOCAL
Prefix Next Hop MED LocPrf Weight Status
1 10.0.2.12/30 10.0.2.2 0 BI
AS_PATH: 100
2 10.0.2.16/30 10.0.2.2 0 0 BI
AS_PATH: 100
3 7.7.7.7/32 10.0.2.2 1 0 BI
AS_PATH: 100
4 6.6.6.6/32 10.0.2.2 0 BI
AS_PATH: 100 65123
The Netiron was always sending everything. Initially R5 was simply dropping those updates. As an optimisation, Junos will not bother advertising a route with the same AS path as the session as it knows the other side will just drop it. So why bother time advertising it to begin with? You need to specifically tell Junos to advertise under these circumstances:
USER3:R3# set routing-instances CUSTOMER1 protocols bgp group EXTERNAL advertise-peer-as
R6 now received the route:
USER6:R6> show route 5.5.5.5
inet.0: 13 destinations, 14 routes (13 active, 0 holddown, 1 hidden)
+ = Active Route, - = Last Active, * = Both
5.5.5.5/32 *[BGP/170] 00:00:20, localpref 100
AS path: 100 65123 I
> to 10.0.2.14 via ae1.36
That’s it for part one. If I don’t split this post I’ll never get it finished. If you’ve made it this far, congratulations! :)
You can find part 2 over here: http://mellowd.co.uk/ccie/?p=3456
Comments