Inter-VRF Routing over VRF Lite

Inter-VRF routing enables controlled route exchange between isolated VRF (Virtual Routing and Forwarding) instances, providing segmentation with selective connectivity.

Use Case

Applicability

  • Multi-Tenant Cloud: Customer isolation with controlled access to shared services
  • Enterprise Segmentation: Separation of Production / Development / Testing environments
  • Service Provider: Carrier VPN with partial route leaking
  • Security Zones: DMZ, Internal, Management with selective access

Benefits

  1. Network Isolation: Full isolation of routing tables between tenants
  2. Selective Connectivity: Controlled access to shared services (DNS, monitoring)
  3. IP Overlap: Different VRFs can use identical IP ranges
  4. Flexible Policy: Granular control through route-maps and prefix-lists
  5. Scalability: Support for many VRFs on a single router

Network Topology

Basic topology (3 VRFs)

                    ┌─────────────────────────────────┐
                    │       VyOS Router               │
                    │                                 │
                    │  ┌────────────────────────┐     │
                    │  │   VRF PRODUCTION       │     │
                    │  │   RD: 65000:100        │     │
                    │  │   10.100.0.0/16        │     │
                    │  └──────────┬─────────────┘     │
                    │             │ Route Leak        │
                    │  ┌──────────┴─────────────┐     │
                    │  │   VRF SHARED           │     │
                    │  │   RD: 65000:999        │     │
                    │  │   10.255.0.0/24        │     │
                    │  │   (DNS, NTP, Monitor)  │     │
                    │  └──────────┬─────────────┘     │
                    │             │ Route Leak        │
                    │  ┌──────────┴─────────────┐     │
                    │  │   VRF DEVELOPMENT      │     │
                    │  │   RD: 65000:200        │     │
                    │  │   10.200.0.0/16        │     │
                    │  └────────────────────────┘     │
                    │                                 │
                    │  eth1 ─ PRODUCTION             │
                    │  eth2 ─ DEVELOPMENT            │
                    │  eth3 ─ SHARED                 │
                    └─────────────────────────────────┘

Yandex Cloud Multi-Tenant

┌──────────────────────────────────────────┐
│      Yandex Cloud VPC                    │
│                                          │
│  ┌────────────────────────────────────┐  │
│  │       VyOS Gateway                 │  │
│  │                                    │  │
│  │  VRF CUSTOMER-A ◄──┐               │  │
│  │  (10.1.0.0/16)     │               │  │
│  │                    │               │  │
│  │  VRF CUSTOMER-B ◄──┼─► SHARED     │  │
│  │  (10.2.0.0/16)     │    SERVICES  │  │
│  │                    │    (DNS/NTP) │  │
│  │  VRF CUSTOMER-C ◄──┘               │  │
│  │  (10.3.0.0/16)                     │  │
│  └────────────────────────────────────┘  │
│                                          │
│  Customer A Subnet ◄─── eth1            │
│  Customer B Subnet ◄─── eth2            │
│  Customer C Subnet ◄─── eth3            │
│  Shared Services   ◄─── eth4            │
└──────────────────────────────────────────┘

Requirements

Minimum requirements

  • VyOS 1.4 (Sagitta) or newer
  • VRF support (FRRouting)
  • BGP or static routing for route import/export
  • Unique Route Distinguisher (RD) for each VRF

Network parameters (example)

VRFRDRT ImportRT ExportNetworks
PRODUCTION65000:10065000:100, 65000:99965000:10010.100.0.0/16
DEVELOPMENT65000:20065000:200, 65000:99965000:20010.200.0.0/16
SHARED65000:99965000:100, 65000:20065000:99910.255.0.0/24

VRF Configuration

Creating VRF instances

configure

# VRF PRODUCTION
set vrf name PRODUCTION table '100'
set vrf name PRODUCTION description 'Production environment - Customer A'

# VRF DEVELOPMENT
set vrf name DEVELOPMENT table '200'
set vrf name DEVELOPMENT description 'Development environment - Customer B'

# VRF SHARED
set vrf name SHARED table '999'
set vrf name SHARED description 'Shared services - DNS, NTP, Monitoring'

commit

Assigning interfaces to VRFs

configure

# eth1 - PRODUCTION
set interfaces ethernet eth1 address '10.100.1.1/24'
set interfaces ethernet eth1 description 'PRODUCTION network'
set interfaces ethernet eth1 vrf 'PRODUCTION'

# eth2 - DEVELOPMENT
set interfaces ethernet eth2 address '10.200.1.1/24'
set interfaces ethernet eth2 description 'DEVELOPMENT network'
set interfaces ethernet eth2 vrf 'DEVELOPMENT'

# eth3 - SHARED
set interfaces ethernet eth3 address '10.255.0.1/24'
set interfaces ethernet eth3 description 'SHARED services'
set interfaces ethernet eth3 vrf 'SHARED'

commit
save

BGP Configuration for Inter-VRF Routing

BGP base configuration

configure

# BGP AS number
set protocols bgp system-as '65000'
set protocols bgp parameters router-id '192.168.255.1'

commit

VRF PRODUCTION BGP configuration

configure

# BGP for VRF PRODUCTION
set protocols bgp address-family ipv4-unicast vrf PRODUCTION rd '65000:100'
set protocols bgp address-family ipv4-unicast vrf PRODUCTION route-target export '65000:100'
set protocols bgp address-family ipv4-unicast vrf PRODUCTION route-target import '65000:100'
set protocols bgp address-family ipv4-unicast vrf PRODUCTION route-target import '65000:999'

# Announce PRODUCTION networks
set protocols bgp address-family ipv4-unicast vrf PRODUCTION network '10.100.0.0/16'

# Redistribute connected
set protocols bgp address-family ipv4-unicast vrf PRODUCTION redistribute connected

commit

VRF DEVELOPMENT BGP configuration

configure

# BGP for VRF DEVELOPMENT
set protocols bgp address-family ipv4-unicast vrf DEVELOPMENT rd '65000:200'
set protocols bgp address-family ipv4-unicast vrf DEVELOPMENT route-target export '65000:200'
set protocols bgp address-family ipv4-unicast vrf DEVELOPMENT route-target import '65000:200'
set protocols bgp address-family ipv4-unicast vrf DEVELOPMENT route-target import '65000:999'

# Announce DEVELOPMENT networks
set protocols bgp address-family ipv4-unicast vrf DEVELOPMENT network '10.200.0.0/16'
set protocols bgp address-family ipv4-unicast vrf DEVELOPMENT redistribute connected

commit

VRF SHARED BGP configuration

configure

# BGP for VRF SHARED
set protocols bgp address-family ipv4-unicast vrf SHARED rd '65000:999'
set protocols bgp address-family ipv4-unicast vrf SHARED route-target export '65000:999'
set protocols bgp address-family ipv4-unicast vrf SHARED route-target import '65000:100'
set protocols bgp address-family ipv4-unicast vrf SHARED route-target import '65000:200'

# Announce SHARED services
set protocols bgp address-family ipv4-unicast vrf SHARED network '10.255.0.0/24'
set protocols bgp address-family ipv4-unicast vrf SHARED redistribute connected

commit
save

Understanding Route Targets

Route Target (RT) controls the import/export of routes between VRFs:

  • PRODUCTION:

    • Export 65000:100: Tag routes with 65000:100
    • Import 65000:100: Import routes tagged with 65000:100 (its own)
    • Import 65000:999: Import routes from the SHARED VRF
  • SHARED:

    • Export 65000:999: Tag shared services routes
    • Import 65000:100, 65000:200: Import from PRODUCTION and DEVELOPMENT

Result: PRODUCTION sees SHARED but does NOT see DEVELOPMENT (and vice versa).

Alternative: Static Route Leaking

If BGP is not required, you can use static routes with VRF:

configure

# In VRF PRODUCTION: route to SHARED via eth3
set vrf name PRODUCTION protocols static route 10.255.0.0/24 next-hop 10.255.0.1 vrf 'SHARED'

# In VRF SHARED: routes back to PRODUCTION and DEVELOPMENT
set vrf name SHARED protocols static route 10.100.0.0/16 next-hop 10.100.1.1 vrf 'PRODUCTION'
set vrf name SHARED protocols static route 10.200.0.0/16 next-hop 10.200.1.1 vrf 'DEVELOPMENT'

commit
save

Note: Static route leaking is simpler but less flexible than BGP with RT.

Yandex Cloud Integration

Scenario: Multi-Tenant Gateway in Yandex Cloud

configure

# Management interface
set interfaces ethernet eth0 address dhcp
set interfaces ethernet eth0 description 'Yandex Cloud management'

# Customer A (VRF CUSTOMER-A)
set vrf name CUSTOMER-A table '101'
set vrf name CUSTOMER-A description 'Tenant A - E-commerce'

set interfaces ethernet eth1 address '10.1.1.1/24'
set interfaces ethernet eth1 description 'Customer A subnet'
set interfaces ethernet eth1 vrf 'CUSTOMER-A'

# Customer B (VRF CUSTOMER-B)
set vrf name CUSTOMER-B table '102'
set vrf name CUSTOMER-B description 'Tenant B - Analytics'

set interfaces ethernet eth2 address '10.2.1.1/24'
set interfaces ethernet eth2 description 'Customer B subnet'
set interfaces ethernet eth2 vrf 'CUSTOMER-B'

# Shared Services (DNS, NTP, Yandex Monitoring)
set vrf name SHARED-SERVICES table '999'
set vrf name SHARED-SERVICES description 'Shared: DNS, NTP, Monitoring'

set interfaces ethernet eth4 address '10.255.1.1/24'
set interfaces ethernet eth4 description 'Shared services'
set interfaces ethernet eth4 vrf 'SHARED-SERVICES'

# BGP for route leaking
set protocols bgp system-as '65000'
set protocols bgp parameters router-id '10.255.255.1'

# CUSTOMER-A VRF BGP
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-A rd '65000:101'
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-A route-target export '65000:101'
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-A route-target import '65000:101'
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-A route-target import '65000:999'
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-A redistribute connected

# CUSTOMER-B VRF BGP
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-B rd '65000:102'
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-B route-target export '65000:102'
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-B route-target import '65000:102'
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-B route-target import '65000:999'
set protocols bgp address-family ipv4-unicast vrf CUSTOMER-B redistribute connected

# SHARED-SERVICES VRF BGP
set protocols bgp address-family ipv4-unicast vrf SHARED-SERVICES rd '65000:999'
set protocols bgp address-family ipv4-unicast vrf SHARED-SERVICES route-target export '65000:999'
set protocols bgp address-family ipv4-unicast vrf SHARED-SERVICES route-target import '65000:101'
set protocols bgp address-family ipv4-unicast vrf SHARED-SERVICES route-target import '65000:102'
set protocols bgp address-family ipv4-unicast vrf SHARED-SERVICES redistribute connected

commit
save

Yandex Cloud Firewall between VRFs

configure

# Allow only DNS and NTP from customers to shared
set firewall ipv4-name CUSTOMER-TO-SHARED default-action 'drop'
set firewall ipv4-name CUSTOMER-TO-SHARED rule 10 action 'accept'
set firewall ipv4-name CUSTOMER-TO-SHARED rule 10 protocol 'udp'
set firewall ipv4-name CUSTOMER-TO-SHARED rule 10 destination port '53'
set firewall ipv4-name CUSTOMER-TO-SHARED rule 10 description 'Allow DNS'

set firewall ipv4-name CUSTOMER-TO-SHARED rule 20 action 'accept'
set firewall ipv4-name CUSTOMER-TO-SHARED rule 20 protocol 'udp'
set firewall ipv4-name CUSTOMER-TO-SHARED rule 20 destination port '123'
set firewall ipv4-name CUSTOMER-TO-SHARED rule 20 description 'Allow NTP'

# Apply to VRF
set vrf name CUSTOMER-A ip protocol all export 'CUSTOMER-TO-SHARED'
set vrf name CUSTOMER-B ip protocol all export 'CUSTOMER-TO-SHARED'

commit
save

VK Cloud Integration

Configuration for VK Cloud

configure

# VK Cloud management (OpenStack Neutron)
set interfaces ethernet eth0 address dhcp
set interfaces ethernet eth0 description 'VK Cloud management'

# VRF configuration is similar to Yandex Cloud

# VK Cloud specifics:
# 1. Security Groups instead of VyOS firewall (or a combination)
# 2. Floating IP only for management
# 3. MTU 1450 for tenant networks

set interfaces ethernet eth1 mtu '1450'
set interfaces ethernet eth2 mtu '1450'
set interfaces ethernet eth4 mtu '1450'

commit
save

VK Cloud Security Groups

Create Security Groups in the VK Cloud Console for each tenant:

Customer-A SG:

  • Allow DNS (UDP 53) to Shared Services subnet
  • Allow NTP (UDP 123) to Shared Services subnet
  • Deny all other to Shared Services

Customer-B SG:

  • Allow DNS (UDP 53) to Shared Services subnet
  • Allow NTP (UDP 123) to Shared Services subnet
  • Deny all other to Shared Services

Configuration Verification

VRF verification

# List VRFs
show vrf

# Expected output:
# VRF name          table     description
# --------          -----     -----------
# CUSTOMER-A        101       Tenant A - E-commerce
# CUSTOMER-B        102       Tenant B - Analytics
# SHARED-SERVICES   999       Shared: DNS, NTP, Monitoring

# Details of a specific VRF
show vrf PRODUCTION

Verifying interfaces in a VRF

# Interfaces by VRF
show interfaces

# IP addresses in a specific VRF
ip vrf exec PRODUCTION ip addr show

# Routing table of a specific VRF
show ip route vrf PRODUCTION
show ip route vrf SHARED

BGP VRF verification

# BGP summary for all VRFs
show bgp vrf all summary

# BGP routes in a specific VRF
show bgp vrf PRODUCTION ipv4 unicast
show bgp vrf SHARED ipv4 unicast

# Route Distinguisher and Route Target
vtysh
show bgp vrf all
show bgp ipv4 vpn
exit

Route Leaking verification

# VRF PRODUCTION should see SHARED (10.255.0.0/24)
show ip route vrf PRODUCTION

# Expected output:
# B>* 10.255.0.0/24 [200/0] via 10.255.0.1 (vrf SHARED), 00:10:00

# VRF SHARED should see PRODUCTION and DEVELOPMENT
show ip route vrf SHARED

# Expected output:
# B>* 10.100.0.0/16 [200/0] via 10.100.1.1 (vrf PRODUCTION), 00:10:00
# B>* 10.200.0.0/16 [200/0] via 10.200.1.1 (vrf DEVELOPMENT), 00:10:00

Connectivity test between VRFs

# Ping from PRODUCTION VRF to SHARED services
ip vrf exec PRODUCTION ping 10.255.0.10 count 4

# Ping from PRODUCTION to DEVELOPMENT (should NOT work - no route leak)
ip vrf exec PRODUCTION ping 10.200.1.10 count 4
# Expected result: "Network is unreachable"

# Traceroute into another VRF
ip vrf exec PRODUCTION traceroute 10.255.0.10

DNS Test (if DNS is in the SHARED VRF)

# DNS server in SHARED VRF: 10.255.0.53

# Test from PRODUCTION VRF
ip vrf exec PRODUCTION nslookup example.com 10.255.0.53

Troubleshooting

Problem 1: A VRF does not see routes from another VRF

Symptoms:

show ip route vrf PRODUCTION
# No routes from the SHARED VRF

Causes and solutions:

  1. Incorrect Route Target:

    # Check RT configuration
    vtysh
    show running-config | grep "route-target"
    
    # PRODUCTION must import 65000:999
    # SHARED must export 65000:999
    
    # Fix
    configure
    set protocols bgp address-family ipv4-unicast vrf PRODUCTION route-target import '65000:999'
    commit
  2. BGP not running for the VRF:

    show bgp vrf PRODUCTION summary
    # Should show the BGP process
    
    # If not, check the configuration
    show configuration commands | grep "vrf PRODUCTION"
  3. No network announcement:

    vtysh
    show bgp vrf SHARED ipv4 unicast
    
    # There should be routes to announce
    # Add a network statement
    configure
    set protocols bgp address-family ipv4-unicast vrf SHARED network '10.255.0.0/24'
    commit

Problem 2: Interface is not assigned to a VRF

Symptoms:

show interfaces ethernet eth1
# No VRF in the output

Solution:

configure
set interfaces ethernet eth1 vrf 'PRODUCTION'
commit

# IMPORTANT: After VRF assignment the interface will go down/up
# All IP addresses are preserved

Problem 3: IP overlap between VRFs causes issues

Symptoms: CUSTOMER-A and CUSTOMER-B use 10.0.0.0/8, and packets go to the wrong place

Solution: This is normal for VRFs, but proper configuration is required:

# Verify that interfaces are in the correct VRFs
show vrf

# Ensure that routing table numbers are unique
show configuration commands | grep "table"

# ALWAYS test connectivity by specifying the VRF
ip vrf exec CUSTOMER-A ping 10.0.0.1
ip vrf exec CUSTOMER-B ping 10.0.0.1
# Different destinations, despite the identical IP

Problem 4: Performance issues

Symptoms: Slow throughput between VRFs

Causes:

  • Routing through the kernel, not hardware offload
  • Firewall processing

Solution:

# Check firewall rules
show firewall statistics

# Simplify firewall rules
# Use connection tracking
set firewall ipv4-name VRF-TO-VRF rule 1 action 'accept'
set firewall ipv4-name VRF-TO-VRF rule 1 state established 'enable'
set firewall ipv4-name VRF-TO-VRF rule 1 state related 'enable'
commit

Best Practices

1. VRF Naming Convention

# Use descriptive names
VRF PRODUCTION        # Not VRF-1
VRF CUSTOMER-ACME     # Not VRF-CUST-001
VRF SHARED-SERVICES   # Not VRF-SHARED

2. Route Distinguisher (RD) Planning

# Format: AS:NN
# AS = your AS number (or 65000 for private)
# NN = unique VRF number

# Numbering scheme:
# 65000:100-199  = Production VRFs
# 65000:200-299  = Development VRFs
# 65000:300-399  = Testing VRFs
# 65000:900-999  = Shared/Management VRFs

3. Route Target Design

Hub-and-Spoke (our example):

PRODUCTION → SHARED (import 999)
DEVELOPMENT → SHARED (import 999)
SHARED → ALL (import 100, 200)

Full Mesh (all VRFs see each other):

ALL VRF → (import * export *)

Partial Mesh: Use route-maps to filter specific prefixes.

4. Security between VRFs

# Use a firewall even between VRFs
set firewall ipv4-name VRF-ISOLATION default-action 'drop'
set firewall ipv4-name VRF-ISOLATION rule 10 action 'accept'
set firewall ipv4-name VRF-ISOLATION rule 10 destination address '10.255.0.53'
set firewall ipv4-name VRF-ISOLATION rule 10 destination port '53'
set firewall ipv4-name VRF-ISOLATION rule 10 protocol 'udp'

# Apply
set vrf name PRODUCTION ip protocol all export 'VRF-ISOLATION'
commit

5. Logging and Monitoring

# BGP logging
vtysh
conf t
log syslog informational
bgp log-neighbor-changes
exit
exit

# Monitor VRF routing tables
watch -n 5 'show ip route vrf PRODUCTION; show ip route vrf SHARED'

# BGP VRF monitoring
watch -n 5 'show bgp vrf all summary'

6. Documentation

Document the VRF topology:

# /etc/vyos/vrf-topology.yaml
vrf_topology:
  PRODUCTION:
    table: 100
    rd: "65000:100"
    rt_export: "65000:100"
    rt_import: ["65000:100", "65000:999"]
    interfaces: ["eth1"]
    networks: ["10.100.0.0/16"]
    access_to: ["SHARED"]

  SHARED:
    table: 999
    rd: "65000:999"
    rt_export: "65000:999"
    rt_import: ["65000:100", "65000:200"]
    interfaces: ["eth3"]
    networks: ["10.255.0.0/24"]
    services: ["DNS: 10.255.0.53", "NTP: 10.255.0.123"]

Advanced Configuration

Route-Maps for Selective Filtering

configure

# Prefix-list: allow only the DNS server
set policy prefix-list ALLOW-DNS-ONLY rule 10 action 'permit'
set policy prefix-list ALLOW-DNS-ONLY rule 10 prefix '10.255.0.53/32'

# Route-map: apply the prefix-list
set policy route-map FILTER-SHARED-IMPORT rule 10 action 'permit'
set policy route-map FILTER-SHARED-IMPORT rule 10 match ip address prefix-list 'ALLOW-DNS-ONLY'

# Apply the route-map to BGP import
# (requires FRR vtysh)
vtysh
conf t
router bgp 65000
address-family ipv4 unicast vrf PRODUCTION
import vrf route-map FILTER-SHARED-IMPORT
exit
exit
exit
exit

VRF with MPLS (for L3VPN)

# Enable MPLS on interfaces
set interfaces ethernet eth0 mpls

# LDP
set protocols mpls ldp interface 'eth0'
set protocols mpls ldp router-id '192.168.255.1'

# BGP VPNv4
vtysh
conf t
router bgp 65000
address-family vpnv4 unicast
neighbor 192.168.255.2 activate
exit
exit
exit

References

Reviewed by OpenNix LLC · Last updated on