In enterprise networking, a single physical router often needs to service multiple, distinct customers or departments (e.g., HR and Engineering) who use overlapping IP address spaces. In the hardware router world (Cisco, Juniper), this is solved using Virtual Routing and Forwarding (VRF) instances. A VRF acts like a completely separate, virtualized router inside the physical router, with its own isolated routing table.
Historically, achieving VRF-like isolation in Linux required deploying network namespaces (netns). While powerful, network namespaces are cumbersome for routing, as they completely isolate the processes; a routing daemon (like FRR or BIRD) would need to be spawned inside every single namespace.
Modern Linux kernels (v4.3+) introduced native L3 Master Device VRF support within the standard networking stack. This allows you to bind physical interfaces to virtual VRF master devices, creating isolated routing domains while allowing a single routing daemon to manage all VRFs simultaneously using the VRF-lite architecture.
This guide explains how to configure native Linux VRFs using iproute2 for network multi-tenancy.
Understanding the Linux VRF Architecture
The Linux VRF implementation operates via a master/slave interface hierarchy and policy routing rules:
- VRF Master Device: You create a virtual network interface (e.g.,
vrf-redorvrf-blue). This master device represents the isolated routing domain. - Routing Tables: Each VRF is automatically mapped to a specific Linux routing table ID (e.g., table 100 for
vrf-red). - Interface Binding: You enslave physical or VLAN interfaces (e.g.,
eth1) to the VRF master device. Any packet arriving oneth1is strictly confined to the routing table ofvrf-red. - L3 Domain Isolation: If
eth1(vrf-red) andeth2(vrf-blue) both have the IP address192.168.1.1/24, the Linux kernel will not complain about overlapping subnets, because they exist in parallel universes.
Step 1: Enabling VRF Support in the Kernel
Before configuring VRFs, you must ensure the underlying sysctl parameters allow VRF L3 domains to operate correctly, specifically regarding local traffic and strict Reverse Path Filtering (RPF).
Open the sysctl configuration file:
sudo nano /etc/sysctl.d/99-vrf.conf
Add the following configurations:
# Enable strict RPF to prevent cross-VRF spoofing
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
# Essential for VRF local traffic to route correctly
net.ipv4.tcp_l3mdev_accept=1
net.ipv4.udp_l3mdev_accept=1
Apply the settings:
sudo sysctl --system
Step 2: Creating the VRF Master Devices
We will create two isolated domains: vrf-red (using routing table 10) and vrf-blue (using routing table 20).
Use the ip command to create the master devices and associate them with their respective routing tables:
sudo ip link add dev vrf-red type vrf table 10
sudo ip link add dev vrf-blue type vrf table 20
Bring the VRF master interfaces up:
sudo ip link set dev vrf-red up
sudo ip link set dev vrf-blue up
Step 3: Enslaving Physical Interfaces to VRFs
Now, we bind the physical Ethernet interfaces to the VRF domains. Assume eth1 belongs to Customer Red and eth2 belongs to Customer Blue.
Warning: Enslaving an interface to a VRF instantly drops its existing IP addresses. You must re-add them after binding.
Bind the interfaces to the master devices:
sudo ip link set dev eth1 master vrf-red
sudo ip link set dev eth2 master vrf-blue
Now, assign the IP addresses. Notice we can use the exact same overlapping IP subnet on both interfaces without conflict:
sudo ip addr add 10.0.0.1/24 dev eth1
sudo ip addr add 10.0.0.1/24 dev eth2
Step 4: Managing Routing Within a VRF
If you type standard routing commands like ip route, you will only see the main routing table (the global or default VRF). To view or manipulate routes within a specific VRF, you must explicitly declare it.
To view the routing table for the Red customer:
ip route show vrf vrf-red
To add a default gateway specifically for the Blue customer:
sudo ip route add default via 10.0.0.254 vrf vrf-blue
Step 5: Executing Commands Inside a VRF Context
How do you test connectivity or run a service inside one of these isolated domains? The ip vrf exec command binds a process exclusively to the VRF’s L3 domain.
To ping a host from within the Red VRF:
sudo ip vrf exec vrf-red ping 10.0.0.5
To start a web server bound only to the Blue VRF:
sudo ip vrf exec vrf-blue python3 -m http.server 8080
To launch an interactive bash shell where all subsequent commands (ssh, curl, tcpdump) are trapped inside the Red VRF:
sudo ip vrf exec vrf-red bash
Conclusion
Native Linux VRF implementation via L3mdev radically simplifies the deployment of multi-tenant routers and firewalls. By elegantly mapping virtual interfaces to isolated routing tables without the heavy process-isolation overhead of full network namespaces, systems engineers can seamlessly integrate overlapping IP address spaces and complex BGP routing architectures directly into the core Linux networking stack.