Tip
This is the documentation for the 23.11 version. Looking for the documentation of the latest version? Have a look here.
Virtual Routing and Forwarding¶
Virtual Routing and Forwarding (VRF) is a feature which uses isolated L3 domains with alternate routing tables for specific interfaces and dynamic routing purposes.
When a VRF route table is created and assigned to interfaces, those interfaces effectively belong to a separate virtual “router” on its own layer 3 domain. A VRF entry may also be assigned to dynamic routing instances (e.g. BGP, OSPF) so that they may handle routing for that VRF.
A new VRF does not have any routes by default. Any traffic using an interface in a VRF not matching a route is dropped, so by default hosts attached to interfaces using a VRF cannot reach other interfaces.
Note
Adding an interface to a VRF automatically adds a route for the subnet on that interface and removes its automatic interface route from the default routing table.
When routing packets, TNSR consults the contents of the VRF route table for the interface the packet enters (ingress). The VRF route table may contain entries for destinations which direct traffic to egress through an interface in the same VRF or even a different VRF.
Note
To egress through a different VRF, add entries to the VRF route table which
use a next-hop located in a different VRF. If the destination is a directly
connected network on another interface add a route with the next hop as
0.0.0.0
along with the target interface. This must be added in both
directions. See the example in Communicate Between VRFs.
To egress through a different VRF using a router reachable through the other VRF, the next hop would be the target router IP address in the other VRF along with the target interface.
Adding a default route to a VRF will cause all traffic that doesn’t match any other route in the VRF to take that default route. This happens even if the destination is local to the firewall but on an interface not in the same VRF.
If an interface or routing daemon is not configured for a specific VRF, TNSR
uses the default VRF. For IPv4, the default VRF routing table is ipv4-VRF:0
.
For IPv6, the default is ipv6-VRF:0
. Though this default VRF has separate
tables for IPv4 and IPv6, user-defined VRF route tables use the same name for
IPv4 and IPv6.
Identical routes can have different destination paths in separate VRFs, and identical networks can even be directly connected to multiple interfaces in different VRFs, provided that the route table entries do not result in traffic crossing into a conflicting VRF.
Tip
For minor differences in routing on local hosts or interfaces that do not require the isolation inherent to VRFs, consider using ACL-Based Forwarding for policy routing instead of using VRFs.
Managing VRFs¶
A VRF must be created before it can be used by TNSR. To create a VRF, start in
config
mode and use the route table <name>
command, which enters
config-route-table
mode. The VRF name must be between 2
and 15
characters in length. From within config-route-table
mode, the new route
table requires a non-zero ID.
tnsr(config)# route table myroutes
tnsr(config-route-table)# id 10
tnsr(config-route-table)#
For more information about options available in this mode, see Managing Routes.
Utilizing VRFs¶
To utilize VRFs, specify them on interfaces and in dynamic routing daemons as needed.
Warning
For a service on TNSR to utilize VRFs the application must be aware of VRFs and be capable of using them directly. Currently the only services on TNSR which can utilize VRFs are dynamic routing daemons (BGP, OSPF, OSPF6, RIP).
Interfaces¶
To set a VRF on an interface, use the vrf <vrf-name>
command from within
config-interface
mode.
tnsr(config)# interface LAN
tnsr(config-interface)# vrf myroutes
tnsr(config-interface)#
See also
See Interface Configuration Options for more on configuring interface options.
Dynamic Routing¶
Use of VRF entries varies by dynamic routing types. Look in the type-specific sections of Dynamic Routing for details about using VRFs.
VRF Examples¶
Alternate Default Route¶
This brief example demonstrates the basics of creating and using a VRF with static routing.
First, create a new route table for the VRF:
tnsr(config)# route table myroutes
tnsr(config-route-table)# description My VRF
tnsr(config-route-table)# id 10
tnsr(config-route-table)# exit
Next, add a default route to the new table:
tnsr(config)# route table myroutes
tnsr(config-route-table)# route 0.0.0.0/0
tnsr(config-rttbl4-next-hop)# next-hop 0 via 203.0.113.1 WAN
tnsr(config-rttbl4-next-hop)# exit
tnsr(config-route-table)# exit
Warning
The interface containing the alternate gateway must be included after the IP address of the alternate gateway.
Finally, assign the route table to an interface as a VRF:
tnsr(config)# interface LAN2
tnsr(config-interface)# vrf myroutes
tnsr(config-interface)# exit
tnsr(config)#
Traffic entering the LAN2 interface will now use the default route specified in this VRF route table instead of the default route in the default VRF route table.
Note
This will break communication between the LAN2 interface and other local interfaces. Continue on to the next example for information on how to work around that limitation.
Communicate Between VRFs¶
As mentioned previously, hosts on interfaces in different VRFs cannot communicate directly by default since the interface routes for other VRFs are not present. This communication can be allowed if needed by adding manual route table entries for the interfaces to the source and destination VRFs.
Directly Connected Networks¶
Building on the previous example, consider another local interface named LAN1
(10.27.0.0/24
) which uses the default route table (ipv4-VRF:0
) while
LAN2 (10.27.1.0/24
) uses the myroutes
VRF.
Note
Though this example is between the default table and a VRF, the procedure is the same when communicating between two different VRFs.
First, add a route to the default route table which allows LAN1 to reach LAN2:
tnsr(config)# route table ipv4-VRF:0
tnsr(config-route-table)# route 10.27.1.0/24
tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 LAN2
tnsr(config-rttbl4-next-hop)# exit
tnsr(config-route-table)# exit
Next, add a route to the myroutes
VRF which allows LAN2 to reach LAN1:
tnsr(config)# route table myroutes
tnsr(config-route-table)# route 10.27.0.0/24
tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 LAN1
tnsr(config-rttbl4-next-hop)# exit
tnsr(config-route-table)# exit
When viewing the route table, the additional interface routes are now present:
tnsr(config)# show route table myroutes
Route Table myroutes AF: ipv4 ID: 10
-----------------------------------------
0.0.0.0/0 via 203.0.113.1 WAN weight 1 preference 0
10.27.0.0/24 via LAN1 weight 1 preference 0
10.27.1.1/24 via LAN2 weight 1 preference 0
Clients in LAN1 and LAN2 can now freely communicate despite the interfaces utilizing separate VRFs.
Routed Networks¶
The previous example is for hosts directly connected to both VRFs. If a
destination is reachable through a router in the other VRF, then instead of
0.0.0.0
, use the target router IP address in the other VRF or configure
the route to look up the destination from the other table.
The following examples build off the previous example, but there is an alternate
router at 10.27.1.5
on the LAN2 interface through which clients can reach
the 10.200.1.0/24
subnet:
tnsr(config)# route table myroutes
tnsr(config-route-table)# route 10.200.1.0/24
tnsr(config-rttbl4-next-hop)# next-hop 0 via 10.27.1.5
tnsr(config-rttbl4-next-hop)# exit
tnsr(config-route-table)# exit
This next example references the remote router address directly in the default route table:
tnsr(config)# route table ipv4-VRF:0
tnsr(config-route-table)# route 10.200.1.0/24
tnsr(config-rttbl4-next-hop)# next-hop 0 via 10.27.1.5 LAN2
tnsr(config-rttbl4-next-hop)# exit
tnsr(config-route-table)# exit
This example uses the alternate route table lookup method instead:
tnsr(config)# route table ipv4-VRF:0
tnsr(config-route-table)# route 10.200.1.0/24
tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 next-hop-table myroutes
tnsr(config-rttbl4-next-hop)# exit
tnsr(config-route-table)# exit
Both methods work, but the second form is more general and requires hard coding less information.