Defining and Using VRFs
This tutorial explains the various ways you can define and use VRFs implemented in the VRF configuration module.
To use VRFs in your networking labs:
Add vrf module to all nodes that have VRF instances
Define VRFs in network topology or within individual nodes
Attach device interfaces to VRFs with the vrf link or interface (node-to-link attachment) attribute.
This document starts with an easy walk through simple VRF designs and gets progressively more complex, ending with overlapping and common services VPNs. Topologies described in this document were tested on Cisco IOSv and Arista vEOS; source files are available on GitHub.
Simple Isolated VRFs
Let’s start with two isolated VRFs: red and blue. We could ignore all details (route distinguishers and route targets); netlab will auto-generate all required values.
vrfs:
red:
blue:
nodes:
rtr:
module: [ vrf ]
A VRF without an rd attribute gets an auto-generated RD. The AS part of the RD is the value of bgp.as or vrf.as attribute. The system default value of vrf.as attribute is 65000, which means that without additional parameters our VRFs get RD values 65000:1 (red) and 65000:2 (blue).
netlab uses simple isolated VRFs as the default connectivity model:
A VRF without an export attribute gets a single export route target equal to the VRF RD.
Likewise, a VRF without an import attribute gets a single import route target equal to VRF RD.
The final data structure describing VRFs in our lab topology is thus:
vrfs:
blue:
export:
- '65000:2'
import:
- '65000:2'
rd: '65000:2'
red:
export:
- '65000:1'
import:
- '65000:1'
rd: '65000:1'
Notes:
Auto-generated RD values are assigned to VRFs in the original order (red before blue).
Attributes in netlab-generated YAML files are sorted alphabetically (blue before red).
RD/RT values (N:N) should be in single or double quotes to ensure PyYAML module treats them as strings.
Specifying RD and RT Values
You can specify any subset of RD/RT values in VRF definitions, and the rest of the values will be auto-generated. For example, you could specify RD in the red VRF and RT in the blue VRF:
vrfs:
red:
rd: "1:1"
blue:
import: [ "2:2" ]
Notes:
You MUST use quotes around RD/RT values. PyYAML interprets “1:1” as number 11.
If you plan to extend the lab configuration with import/export route maps, set import and export attributes to empty lists.
Please note that the RT values are not used to generate RD. While the red VRF gets the desired import/export route targets, the RD for VRF blue is auto-generated, resulting in the following setup that might not be what you’re looking for:
vrfs:
blue:
export:
- '65000:1'
import:
- '2:2'
rd: '65000:1'
red:
export:
- '1:1'
import:
- '1:1'
rd: '1:1'
Using VRFs on Interfaces
All you have to do to make an interface part of a VRF is to use vrf attribute in interface (node-to-link attachment) data. The value of the vrf attribute is the VRF name, for example:
vrfs:
red:
nodes:
rtr:
module: [ vrf ]
h1:
h2:
links:
- rtr: { vrf: red }
h1:
- rtr: { vrf: red }
h2:
Notes:
The node with a VRF interface must use the vrf module
A vrf attribute specified on a link is inherited by all interfaces attached to that link – an ideal scenario for a VRF Lite core link:
vrfs:
red:
blue:
module: [ vrf,ospf ]
nodes:
pe1:
pe2:
links:
- name: PE-to-PE link in VRF red
vrf: red
pe1:
pe2:
EBGP Sessions with CE-Routers
If you want to use EBGP sessions with CE-routers within a VRF you have to:
Add bgp configuration module to PE- and CE-routers
Specify different AS numbers for PE- and CE-routers (IBGP VRF sessions will not work)
Add PE-to-CE links to VRFs on the PE-routers.
The following topology builds a simple single-VRF network with EBGP running between PE- and CE-routers:
vrfs:
blue:
module: [ vrf,ospf,bgp ]
bgp.as: 65000
nodes:
pe1:
pe2:
cb1:
module: [ bgp ]
bgp.as: 65101
cb2:
module: [ bgp ]
bgp.as: 65102
links:
- pe1: { vrf: blue }
cb1:
- pe2: { vrf: blue }
cb1:
- pe1: { vrf: blue }
cb2:
- pe2: { vrf: blue }
cb2:
- pe1:
pe2:
Notes:
The EBGP sessions between PE1 and PE2, and CB1 and CB2 will be configured within the VRF address family on PE1 and PE2.
A global IPv4/IPv6 IBGP session will be configured between PE1 and PE2.
The global IBGP session will not carry VPNv4 prefixes unless you add mpls.vpn (see example below) module to PE1 and PE2.
Behind the scenes, the VRF configuration module removes EBGP neighbors reachable through VRF interfaces from the global list of BGP neighbors on the PE-routers (so they won’t be configured as part of the BGP routing process) and adds them to VRF data structure:
nodes:
pe1:
vrfs:
blue:
af:
ipv4: true
bgp:
neighbors:
- as: 65101
ifindex: 3
ipv4: 10.1.0.9
name: cb1
type: ebgp
- as: 65102
ifindex: 4
ipv4: 10.1.0.17
name: cb2
type: ebgp
export:
- '65000:2'
import:
- '65000:2'
rd: '65000:2'
vrfidx: 101
The BGP neighbors specified in the VRF data structure are then configured within the VRF BGP address family.
Running OSPF with CE-Routers
OSPF is enabled on all internal (intra-AS) interfaces on every node with ospf configuration module. To disable OSPF on an individual link or interface, set link/interface ospf attribute to False.
The VRF configuration module removes OSPF data from VRF interfaces and recreates a list of OSPF interface within VRF data structure. The VRF interfaces are thus not included in the global OSPF process, and the VRF configuration templates create per-VRF OSPF processes as needed.
The VRF configuration templates also configure an automatic two-way redistribution between BGP and OSPF when it finds OSPF-enabled VRF interfaces and bgp.as defined in the node data.
For example, the following topology enables OSPF between PE- and CE-routers in VRF red:
vrfs:
red:
module: [ vrf,ospf,bgp ]
bgp.as: 65000
nodes:
pe1:
pe2:
cr1:
module: [ ospf ]
cr2:
module: [ ospf ]
links:
- pe1: { vrf: red }
pe2: { vrf: red }
cr1:
ospf.cost: 10
- pe1: { vrf: red }
cr2:
ospf.cost: 10
- pe2: { vrf: red }
cr2:
ospf.cost: 10
The resulting Cisco IOS configuration includes BGP routing, OSPF routing and two-way redistribution:
router bgp 65000
address-family ipv4 vrf red
redistribute connected
redistribute ospf 100
!
router ospf 100 vrf red
router-id 10.0.0.1
redistribute bgp 65000 subnets
!
interface Loopback100
ip ospf 100 area 0.0.0.0
!
interface GigabitEthernet0/1
! pe1 -> [pe2,cr1]
ip ospf 100 area 0.0.0.0
ip ospf cost 10
!
interface GigabitEthernet0/2
! pe1 -> cr2
ip ospf 100 area 0.0.0.0
ip ospf network point-to-point
ip ospf cost 10
VPNv4 Prefixes
If you want to carry VPNv4 (or VPNv6) prefixes, you have to enable mpls.vpn (and a MPLS label protocol, such as mpls.ldp).
The following example expands the EBGP Sessions with CE-Routers configuration:
vrfs:
blue:
module: [ vrf,ospf,bgp,mpls ]
bgp.as: 65000
nodes:
pe1:
mpls:
vpn: true
ldp: true
pe2:
mpls:
vpn: true
ldp: true
cb1:
module: [ bgp ]
bgp.as: 65101
cb2:
module: [ bgp ]
bgp.as: 65102
cb3:
module: [ bgp ]
bgp.as: 65103
cb4:
module: [ bgp ]
bgp.as: 65104
links:
- pe1:
pe2:
- pe1: { vrf: blue }
cb1:
- pe2: { vrf: blue }
cb1:
- pe1: { vrf: blue }
cb2:
- pe2: { vrf: blue }
cb2:
- pe1: { vrf: blue }
cb3:
- pe2: { vrf: blue }
cb4: