Tag Archive: VRF


This article further continues on earlier experiments. While using internal tunnels gave a logically ‘simple’ point-to-point network seen from a layer 3 point of view, it came with the drawback of complex header calculations, resulting in CPU hogging on devices capable of hardware switching. Using some route-maps to choose VRFs for flows proved interesting, but only in particular use cases. It didn’t make the troubleshooting any easier.

There is a better method for dealing with inter-VRF routing on a local device, but it requires a very different logic. Up until now, my articles described how to be able to select a next-hop inside another VRF. Route leaking using BGP, however, leverages a features of BGP that has been described in my blog before: the import and export of routing information in different VRFs.

How does it work? Well, since the BGP process can’t differentiate between VRFs based on names, but instead uses route-targets to uniquely identify routing tables, it’s the route target that matters. Usually, for MPLS-VPN, these numbers differ per VRF. This time, use the same number for two VRFs:

VRF-RouteLeaking1This will tell BGP later on to use the same routing table for both VRFs. Now if you configure BGP…

VRF-RouteLeaking2

… There’s still a separate configuration per VRF. How does the exchange happen? Well: for all routes that are known inside the BGP process. This means any routes from any BGP peer in one of the VRFs are automatically learned in both VRFs. But for static and connected routes, and routes from other routing protocols, you can do a controlled redistribution using route-maps or prefix lists. This way only the routes that need to be known in the other VRF are added.

VRF-RouteLeaking3

The routing table with automatically show routes pointing to different VRFs. On top of that, the forwarding does not require any headers to be added or removed to the packets, so it can be put directly into CEF, allowing for hardware forwarding. And for completeness: the BGP neighborships here are just for illustration of what happens, but no neighborship is required for this to function. BGP just needs to run on the device as a process.

Of course, this is just a simple setup. More complexity can always be added, as you can even use route-maps to set the route targets for some routes.

This article is not really written with knowledge usable for a production network in mind. It’s more of an “I have not failed. I’ve just found 10,000 ways that won’t work.” kind of article.

I’m currently in a mailing group with fellow network engineers who are setting up GRE tunnels to each others home networks over the public internet. Over those networks we speak (external) BGP towards each other and each engineer announces his own private address range. With around 10 engineers so far and a partial mesh of tunnels, it gives a useful topology to troubleshoot and experiment with. Just like the real internet, you don’t know what happens day-to-day, neighborships may go down or suddenly new ones are added, and other next-hops may become more interesting for some routes suddenly.

SwitchRouting1

But of course it requires a device at home capable of both GRE and BGP. A Cisco router will do, as will Linux with Quagga and many other industrial routers. But the only device I currently have running 24/7 is my WS-C3560-8PC switch. Although it has an IP Services IOS, is already routing and can do GRE and BGP, it doesn’t do NAT. Easy enough: allow GRE through on the router that does the NAT in the home network. Turns out the old DD-WRT version I have on my current router doesn’t support it. Sure I can replace it but it would cost me a new router and it would not be a challenge.

SwitchRouting2

Solution: give the switch a direct public IP address and do the tunnels from there. After all, the internal IP addresses are encapsulated in GRE for transport so NAT is required for them. Since the switch already has a default route towards the router, set up host routes (a /32) per remote GRE endpoint. However, this still introduces asymmetric routing: the provider subnet is a connected subnet for the switch, so incoming traffic will go through the router and outgoing directly from the switch to the internet without NAT. Of course that will not work.

SwitchRouting3

So yet another problem to work around. This can be solved for a large part using Policy-Based Routing (PBR): on the client VLAN interface, redirect all traffic not meant for a private range towards the router. But again, this has complications: the routing table does not reflect the actual routing being done, more administrative overhead, and all packets originated from the local switch will still follow the default (the 3560 switch does not support PBR for locally generated packets).

Next idea: it would be nice to have an extra device that can do GRE and BGP directly towards the internet and my switch can route private range packets towards it. But the constraint is no new device. So that brings me to VRFs: split the current 3560 switch in two: one routing table for the internal routing (vrf MAIN), one for the GRE tunnels (vrf BGP). However, to connect the two VRFs on the same physical device I would need to loop a cable from one switchport to another, and I only have 8 ports. The rest would work out fine: point private ranges from a VLAN interface in one VRF to a next-hop VLAN interface over that cable in another VRF. That second VRF can have a default route towards the internet and set up GRE tunnels. The two VRFs would share one subnet.

SwitchRouting4

Since I don’t want to deal with that extra cable, would it be possible to route between VRFs internally? I’ve tried similar actions before, but those required a route-map and a physical incoming interface. I might as well use PBR if I go that way. Internal interfaces for routing between VRFs exist on ASR series, but not my simple 8-port 3560. But what if I replace the cable with tunnel interfaces? Is it possible to put both endpoints in different VRFs? Yes, the 15.0(2) IOS supports it!

SwitchRouting5

The tunnel interfaces have two commands that are useful for this:

  • vrf definition : just like on any other layer 3 interface, it specifies the routing table of the packets in the interface (in the tunnel).
  • tunnel vrf :  specifies the underlying VRF from which the packets will be sent, after GRE encapsulation.

With these two commands, it’s possible to have tunnels in one VRF transporting packets for another VRF. The concept is vaguely similar to MPLS-VPN,  where your intermediate (provider) routers only have one routing table which is used to transport packets towards routers that have the VRF-awareness (provider-edge).

interface Vlan2
ip address 192.168.2.1 255.255.255.0
interface Vlan3
ip address 192.168.3.1 255.255.255.0
interface Tunnel75
vrf forwarding MAIN
ip address 192.168.7.5 255.255.255.252
tunnel source Vlan2
tunnel destination 192.168.3.1
interface Tunnel76
vrf forwarding BGP
ip address 192.168.7.6 255.255.255.252
tunnel source Vlan3
tunnel destination 192.168.2.1

So I configure two tunnel interfaces, both in the main routing table. Source and destination are two IP addresses locally configured on the router.  I chose VLAN interface, loopbacks will likely work as well. Inside the tunnels, one is set to the first VRF, the other to the second. One of the VRFs may be shared with the main (outside tunnels) routing table, but it’s not a requirement. Configure both tunnel interfaces as two sides of a point-to-point connection and they come up. Ping works, and even MTU 1500 works over the tunnels, despite the show interface command showing an MTU of only 1476!

Next, I set up BGP to be VRF-aware. Logically, there are two ‘routers’, one of which is the endpoint for the GRE tunnels, and another one which connects to it behind it for internal routing. Normally if it were two physical routers, I would set up internal BGP between them since I’m already using that protocol. But there’s no difference here: you can make the VRFs speak BGP to each other using one single configuration.

router bgp 65000
address-family ipv4 vrf MAIN
neighbor 192.168.7.6 remote-as 65000
network 192.168.0.0 mask 255.255.248.0
neighbor 192.168.7.6 activate
exit-address-family
address-family ipv4 vrf BGP
bgp router-id 192.168.7.6
neighbor 192.168.7.5 remote-as 65000
neighbor 192.168.7.5 activate
exit-address-family

A few points did surface: you need to specify the neighbors (the IP addresses of the local device in the different VRFs) under the correct address families. You also need to specify a route distinguisher under the VRF as it is required for VRF-aware BGP. And maybe the most ironic: you need a bgp router-id set inside the VRF address-family so it differs from the other VRF (the highest interface IP address by default), otherwise the two ‘BGP peers’ will notice the duplicate router-id and it will not work. But after all of that, BGP comes up and routes are exchanged between the two VRFs! For the GRE tunnels towards the internet, the tunnel vrf command is required in the GRE tunnels so they use the correct routing table for routing over the internet.

So what makes this not production-worthy? The software-switching.

The ASIC can only do a set number of actions in a certain sequence without punting towards the switch CPU. Doing a layer 2 CAM table lookup or a layer 3 RIB lookup is one thing. But receiving a packet, have the RIB pointing it to a GRE tunnel, encapsulate, decapsulate and RIB lookup of another VRF is too much. It follows the expected steps in the code accordingly, the IOS software does not ‘see’ what the point is and does not take shortcuts. GRE headers are actually calculated for each packet traversing the ‘internal tunnel’ link. I’ve done a stress test and the CPU would max out at 100% at… 700 kBps, about 5,6 Mbps. So while this is a very interesting configuration and it gives an ideal situation to learn more, it’s just lab stuff.

So that’s the lesson, as stated in the beginning: how not to do it. Can you route between VRFs internally on a Cisco switch or router (not including ASR series)? Yes. Would you want to do it? No!

VRF-aware internet breakout.

For this article, let’s continue on a previous one: a basic VRF topology.

VRF

Only this time, at router R1, there’s an extra interface (G0/4), which is used as an internet breakout. You’ve received two public static IP’s on top of the static IP of the router, which you can use. This time, the manager asks that all users connect towards the internet behind one IP address, and that the voice gateway has a static public IP address as well. This gives a problem right away: users and voice server are in a seperate VRF. And an interface can’t be part of more than one VRF. So what do we do with our single internet breakout? Solution: some VRF manipulation, clever placing of the NAT commands, and policy-based routing (PBR). For clarity: towards the ISP we will use 198.15.0.0/30, a point-to-point link, and the two public addresses from the ISP will be 198.15.0.4/31.

First stretching the concept of VRF a bit: an interface can’t be part of more than one VRF, but it can be added to the routing table of multiple VRF. Note that the configuration below is done on a 12.x IOS. 15.x requires different vrf commands (without ‘ip’ in front of it).

R1(config)#interface g0/4
R1(config-if)#ip policy route-map RM-Internet
R1(config-if)#ip vrf receive VOICE
R1(config-if)#ip vrf receive LAN
R1(config-if)#ip address 198.15.0.2 255.255.255.252
R1(config-if)#ip nat outside
R1(config-if)#exit
R1(config)#ip route vrf VOICE 0.0.0.0 0.0.0.0 g0/4 198.15.0.1
R1(config)#ip route vrf LAN 0.0.0.0 0.0.0.0 g0/4 198.15.0.1

The PBR command ‘ip policy’ needs to go first, otherwise ‘ip vrf receive’ will not be accepted and a message “% Need to enable Policy Based Routing on the interface first” will show. The latter places the interface into the VRF routing tables. Together with the default routes for those VRF, it allows for outgoing traffic from both VRF towards the internet.

Now where to place the NAT? Usually this is done in the outside interface. Except, since both VRF have overlapping IP ranges, it can’t always be done there. Instead, on the inside interfaces, inside the VRF, the translation must be made so it’s a unique outside address before it reaches the outside interface.

R1(config)#interface g0/1
R1(config-if)#ip vrf forwarding LAN
R1(config-if)#ip address 172.16.1.1 255.255.255.0
R1(config-if)#ip nat inside
R1(config-if)#exit
R1(config)#interface g0/3
R1(config-if)#ip vrf forwarding VOICE
R1(config-if)#ip address 172.20.1.1 255.255.255.252
R1(config-if)#ip nat inside
R1(config-if)#exit
R1(config)#ip access-list standard AL4-NAT-LAN
R1(config-std-nacl)#permit 172.16.1.0 0.0.0.255
R1(config-std-nacl)#exit
R1(config)#ip nat pool PL-NAT-LAN 198.15.0.4 198.15.0.4 netmask 255.255.255.255
R1(config)#ip nat inside source list AL4-NAT-LAN pool PL-NAT-LAN vrf LAN overload
R1(config)#ip nat inside source static 172.20.1.2 198.15.0.5 vrf VOICE

This gives the users on the LAN an external IP address of 198.15.0.4 and the voice server a static NAT of 198.15.0.5. But while that works for outgoing traffic, incoming traffic still has an issue. How does the router know in which VRF to place the incoming traffic? That’s where the PBR comes into play.

R1(config)#ip access-list extended AL4-IN-LAN
R1(config-ext-nacl)#permit ip any host 198.15.0.4
R1(config-ext-nacl)#exit
R1(config)#ip access-list extended AL4-IN-VOICE
R1(config-ext-nacl)#permit ip any host 198.15.0.5
R1(config-ext-nacl)#exit
R1(config)#route-map RM-IN permit 3
R1(config-route-map)#match ip address AL4-IN-LAN
R1(config-route-map)#set vrf LAN
R1(config-route-map)#route-map RM-IN permit 6
R1(config-route-map)#match ip address AL4-IN-VOICE
R1(config-route-map)#set vrf VOICE
R1(config-route-map)#exit

The above creates a route-map that refers to two ACLs. The goal is simple: if incoming traffic has destination IP addres 198.15.0.4 (NAT for user LAN), then it’s placed in the LAN VRF. If it has 198.15.0.5 (static NAT voice server) as destination IP address, it is placed in the VOICE VRF.

All the above together allow each VRF to use the same internet uplink. The routing table of a VRF looks normal:

R1#show ip route vrf LAN

Gateway of last resort is 198.15.0.1 to network 0.0.0.0

172.16.0.0/24 is subnetted, 1 subnets
C       172.16.1.0 is directly connected, GigabitEthernet0/1
172.20.0.0/30 is subnetted, 1 subnets
C       172.20.1.0 is directly connected, GigabitEthernet0/2
10.0.0.0/16 is subnetted, 1 subnets
O       10.0.0.0 [110/2] via 172.20.1.2, 17:42:38, GigabitEthernet0/2
198.15.0.0/30 is subnetted, 1 subnets
C       198.15.0.0 is directly connected, GigabitEthernet0/4
S*   0.0.0.0/0 [1/0] via 198.15.0.1, GigabitEthernet0/4

This is very useful in an environment with multiple VRF and one internet breakout. However, this can also be used in other cases, such as an MPLS-VPN environment, which Darren covers in detail on his blog.

MPLS, part II: VRF-aware MPLS-VPN.

Where MPLS part I explains the basics of labeling packets, it’s not giving any advantage over normal routing, apart from faster table lookups. But extensions to MPLS allow for more. In this article I’ll explain MPLS-VPN, and more specifically a Virtual Private Routed Network (VPRN).

A VPRN is a routed (layer 3) network over an MPLS cloud, that is VRF-aware, or customer-aware. This means several different routing instances (VRFs, remember?) can share the same MPLS cloud. How is this achieved when there’s only a point-to-point link between routers with one IP address? After all, an interface can only be assigned to one VRF. Solution: by adding a second MPLS label to the data: the ‘outer’ label (the one closest to the layer 2 header) is used to specify the destination router, the ‘inner’ label (closest to the original layer 3 header) is used to specify to which VRF a packet belongs. The outer label workings are identical to standard MPLS: these are learned by LDP and matched with a prefix in the routing table. But for the inner label, a VRF-aware process needs to run on each router that can handle label information and propagate it to other routers. That process is Multiprotocol-BGP, or MP-BGP.

MPLS-VPN-Header

The outer label is used to route the packet through the MPLS cloud, and the last router(s) use the inner label to see to which VRF a packet belongs. Let’s look at the configuration to understand it more. First, the basic setup:

MPLS-VPN-VRF

Notice the router names, as these are often used in MPLS terminology.

  • The Customer Edge router a router that directly connects to a customer network. It’s usually the demarcation point, where the equipment governed by the MPLS provider begins. Contrary to the name, the CE itself is often managed by the provider as well.
  • The Provider Edge router is the ‘first’ router (seen from a customer site point of view) that has MPLS enabled interfaces. It’s where the labels are applied for the first time.
  • A Provider router is a router completely internal to the MPLS cloud, having only MPLS enabled interfaces.

The connection between CE and PE is a point-to-point so a /30 subnet is logical. Routing between CE and PE is done using a simple routing protocol, like RIP, OSPF, EIGRP or even static or standard BGP. The only notable part is that the PE router has to use a VRF to place the customer in. Below an example configuration:

Router-CE(config)#interface G0/1
Router-CE(config-if)#ip address 10.1.0.1 255.255.255.252
Router-CE(config-if)#exit
Router-CE(config)#router ospf 1
Router-CE(config-router)#network 10.1.0.0 0.0.0.3 area 0

Router-PE(config)#vrf definition VRF
Router-PE(config-vrf)#address-family ipv4
Router-PE(config-vrf-af)#exit
Router-PE(config-vrf)#exit
Router-PE(config)#interface G0/1
Router-PE(config-if)#vrf forwarding VRF
Router-PE(config-if)#ip address 10.1.0.2 255.255.255.252
Router-PE(config-if)#exit
Router-PE(config)#router ospf 2 vrf VRF
Router-PE(config-router)#network 10.1.0.0 0.0.0.3 area 0
*Mar  1 00:06:20.991: %OSPF-5-ADJCHG: Process 2, Nbr 10.1.0.1 on GigabitEthernet0/1 from LOADING to FULL, Loading Done

If you happen to run a router on an IOS before 15.0, the commands for the VRF change: it becomes ‘ip vrf VRF’ to define a VRF, without the need to specify an address family, as 12.x IOS versions aren’t VRF aware for IPv6. On the interface, the command is ‘ip vrf forwarding VRF’.

So far so good. Now on to activating MPLS between the PE and the P router, and making sure the routers learn the MPLS topology:

Router-PE(config)#interface G0/2
Router-PE(config-if)#mpls ip
Router-PE(config-if)#ip address 10.0.0.1 255.255.255.252
Router-PE(config-if)#ip ospf network point-to-point
Router-PE(config-if)#exit
Router-PE(config)#interface Loopback0
Router-PE(config-if)#ip address 10.0.1.1
Router-PE(config-if)#exit
Router-PE(config)#router ospf 1
Router-PE(config-router)#network 10.0.0.0 0.0.1.255 area 0

Router-P(config)#interface G0/1
Router-P(config-if)#mpls ip
Router-P(config-if)#ip address 10.0.0.2 255.255.255.252
Router-P(config-if)#ip ospf network point-to-point
Router-P(config-if)#exit
Router-P(config)#interface Loopback0
Router-P(config-if)#ip address 10.0.1.2 255.255.255.255
Router-P(config-if)#exit
Router-P(config)#router ospf 1
Router-P(config-router)#network 10.0.0.0 0.0.1.255 area 0
*Mar  1 00:02:29.023: %OSPF-5-ADJCHG: Process 1, Nbr 10.0.0.1 on GigabitEthernet0/2 from LOADING to FULL, Loading Done
*Mar  1 00:02:33.127: %LDP-5-NBRCHG: LDP Neighbor 10.0.0.1:0 (1) is UP

The ‘ip ospf network point-to-point’ is not really needed but used to reduce OSPF overhead. The loopbacks are needed for BGP later on.

Up until this point, we have MPLS in the default VRF and a separate VRF per customer for routing, but no routing of the VRFs over the MPLS. To exchange the inner labels needed to specify the VRF, MP-BGP between PE and P is configured:

Router-PE(config)#router bgp 65000
Router-PE(config-router)#neighbor 10.0.1.2 remote-as 65000
Router-PE(config-router)#neighbor 10.0.1.2 update-source Loopback0
Router-PE(config-router)#no address-family ipv4
Router-PE(config-router)#address-family vpnv4
Router-PE(config-router-af)#neighbor 10.0.1.2 activate
Router-PE(config-router-af)#neighbor 10.0.1.2 send-community extended

Router-P(config)#router bgp 65000
Router-P(config-router)#neighbor 10.0.1.1 remote-as 65000
Router-P(config-router)#neighbor 10.0.1.1 update-source Loopback0
Router-P(config-router)#no address-family ipv4
Router-P(config-router)#address-family vpnv4
Router-P(config-router-af)#neighbor 10.0.1.1 activate
Router-P(config-router-af)#neighbor 10.0.1.1 send-community extended
*Mar  1 00:11:31.879: %BGP-5-ADJCHANGE: neighbor 10.0.1.1 Up

Again some explanation. First off, BGP neighbors always need to be defined under the main process, after which they need to be activated for a specific address-family. The ‘no address-family ipv4’ command means that no conventional routing information for the default VRF will be exchanged (we already have OSPF for that). The ‘address-family vpnv4’ activates the VPRN capability, and the label exchange for VRFs. In this process, the neighbor is activated. The ‘send-community extended’ means BGP will exchange the community Path Attributes (PA), in which the label information is present. The loopbacks are used to connect to each other, not only for redundancy in case a physical interface should go down, but also because LDP does not exchange labels with another router on a connected subnet for that subnet. This means that if the directly connected interfaces are used as BGP neighbors, the BGP process can’t figure out the labeling properly.

So VRF-aware MPLS is running now, but on each PE router it needs to be specified which VRF needs to be injected in the MPLS cloud. MP-BGP does this using import and export of routing tables. For MP-BGP, a route needs to be uniquely identified, and explained to which VRF it belongs. This is done with a Route Distinguisher (RD) and Route Target (RT). Both are 64 bits, and usually in the format AS:nn, or the first 32 bits the AS number and the last 32 bits a unique chosen number.

  • RD uniquely identifies a route. Inside MP-BGP, a route is prepended with its RD, e.g. 65000:1:192.168.1.0/24. This way, if the route exists twice (in different VRFs), it’s still unique because the RD part of the prefix is different.
  • RT specifies to which VRF a route belongs. It handles the import and export of routes from a VRF to the BGP process. In its basic form, it’s the same number as the RD, and the same at all PE routers for a certain client.

Configuration of these parameters is done inside the VRF:

Router-PE(config)#vrf definition VRF
Router-PE(config-vrf)#rd 65000:1
Router-PE(config-vrf)#route-target both 65000:1

Now that the VRF can be used in the BGP process, it is imported in the process as following:

Router-PE(config)#router bgp 65000
Router-PE(config-router)#address-family ipv4 vrf VRF
Router-PE(config-router-af)#redistribute ospf 2

The redistribution, of course, needs to be mutual between OSPF and BGP, so a few more lines of configuration are needed to complete everything:

Router-PE(config)#router ospf 2 vrf VRF
Router-PE(config-router)#redistribute bgp 65000 subnets

MPLS-VPN-Forwarding

And now everything is completed: the PE router learns routes from the P router by OSPF, and redistributes it into BGP to propagate them over the MPLS cloud. From this point on, configuration is modular: on another PE router, the configuration is likewise. Adding a P router isn’t any different from the P router in this example, the processes and parameters are the same each time. Do remember that routers don’t advertise iBGP-learned routes to other iBGP peers, so the PE and P routers need to form a full mesh, unless you’re using route reflectors or confederations.

VRF explained.

This is one of those ‘nice to know in case I ever need it’ kind of topics for me. VRF stands for virtual routing and forwarding, and it is a technique to divide the routing table on a router into multiple virtual tables.

How does this work, and more importantly, why would you need it? Well, it is useful to provide complete separation of networks on the same router, so this router can be shared between different services, departments or clients. For example the following network:

VRF

Say you have to design an office, with desks and IP Phones. You already have one gigabit switch on stock, and the budget allows a 100 Mbps PoE switch. The manager insists on gigabit connections towards the desktops, and he insists that the voice network and data network are completely separated, with voice using static routes and the LAN using dynamic routing. However, you only get one router for the office itself. (This wouldn’t be good redundant design, that aside.) A good choice here is to connect all IP Phones to the PoE switch and all desktops to the gigabit switch, and connect both to the router. But since complete separation is needed, you can’t have any routing between the two. This is where VRF comes into play.

I’ll explain while showing the configuration. First, define VRF instances. Since there needs to be separation between IP Phones and desktops here, I’ll make two instances: VOICE and LAN.

router(config)#ip vrf VOICE
router(config-vrf)#exit
router(config)#ip vrf LAN
router(config-vrf)#exit

This separates the router into two, logical routers. Actually three instances, the default instance is still there, but it’s best not to use that one since it gets confusing. Next is assigning interfaces to their VRF. Let’s assume the PoE Voice switch is connected on Gigabit 0/0, and the gigabit switch on Gigabit 0/1. On Gigabit 0/2, there’s an uplink to the server subnets, and on Gigabit 0/3, there’s an uplink to the voice gateway.

R1(config)#interface g0/0
R1(config-if)#ip vrf forwarding VOICE
R1(config-if)#ip address 172.16.1.1 255.255.255.0
R1(config-if)#no shutdown
R1(config-if)#exit
R1(config)#interface g0/1
R1(config-if)#ip vrf forwarding LAN
R1(config-if)#ip address 172.16.1.1 255.255.255.0
R1(config-if)#no shutdown
R1(config-if)#exit
R1(config)#interface g0/2
R1(config-if)#ip vrf forwarding LAN
R1(config-if)#ip address 172.20.1.1 255.255.255.252
R1(config-if)#no shutdown
R1(config-if)#exit
R1(config)#interface g0/3
R1(config-if)#ip vrf forwarding VOICE
R1(config-if)#ip address 172.20.1.1 255.255.255.252
R1(config-if)#no shutdown
R1(config-if)#exit

You may have noticed something odd here: overlapping IP addresses and subnets on the interfaces. This is what VRF is all about: you can consider VOICE and LAN as two different routers. And one router will not complain if another router have the same IP address, unless they’re directly connected. But since VOICE and LAN do not share interfaces, as odd as this may sound, they are not connected to each other.

To further demonstrate the point, let’s add a static route to the VOICE router, and set up OSPF on the LAN router:

R1(config)#ip route vrf VOICE 10.0.0.0 255.255.252.0 172.20.1.2
R1(config)#router ospf 1 vrf LAN
R1(config-router)#network 0.0.0.0 255.255.255.255 area 0
R1(config-router)#passive-interface g0/0
%Interface specified does not belong to this process
R1(config-router)#passive-interface g0/1
R1(config-router)#exit

OSPF routing is also set up on router R3, towards the server subnets. Note that R2 and R3 do not need to have VRF configured. To them, they are connecting to the router VOICE and LAN, respectively. Also, when in the OSPF configuration context, I can’t put the Gigabit 0/0 interface in passive, as it’s not part of the LAN router.

And now the final point that clarifies the VRF concept: the routing tables.

R1#show ip route vrf VOICE

Routing Table: VOICE
Codes: C – connected, S – static, R – RIP, M – mobile, B – BGP
D – EIGRP, EX – EIGRP external, O – OSPF, IA – OSPF inter area
N1 – OSPF NSSA external type 1, N2 – OSPF NSSA external type 2
E1 – OSPF external type 1, E2 – OSPF external type 2
i – IS-IS, su – IS-IS summary, L1 – IS-IS level-1, L2 – IS-IS level-2
ia – IS-IS inter area, * – candidate default, U – per-user static route
o – ODR, P – periodic downloaded static route

Gateway of last resort is not set

172.16.0.0/24 is subnetted, 1 subnets
C       172.16.1.0 is directly connected, FastEthernet0/0
172.20.0.0/30 is subnetted, 1 subnets
C       172.20.1.0 is directly connected, FastEthernet2/0
10.0.0.0/22 is subnetted, 1 subnets
S       10.0.0.0 [1/0] via 172.20.1.2

R1#show ip route vrf LAN

Routing Table: LAN
Codes: C – connected, S – static, R – RIP, M – mobile, B – BGP
D – EIGRP, EX – EIGRP external, O – OSPF, IA – OSPF inter area
N1 – OSPF NSSA external type 1, N2 – OSPF NSSA external type 2
E1 – OSPF external type 1, E2 – OSPF external type 2
i – IS-IS, su – IS-IS summary, L1 – IS-IS level-1, L2 – IS-IS level-2
ia – IS-IS inter area, * – candidate default, U – per-user static route
o – ODR, P – periodic downloaded static route

Gateway of last resort is not set

172.16.0.0/24 is subnetted, 1 subnets
C       172.16.1.0 is directly connected, FastEthernet0/1
172.20.0.0/30 is subnetted, 1 subnets
C       172.20.1.0 is directly connected, FastEthernet1/0
10.0.0.0/16 is subnetted, 1 subnets
O       10.0.0.0 [110/2] via 172.20.1.2, 00:04:04, FastEthernet1/0

Different (logical) routers, different routing tables. So by using VRF, you can have a complete separation of your network, overlapping IP space, and increase security too!