Route leaking between multiple VRFs
In this example, routing leaking between three VRFs in a star topology is configured. This allows the solution to be scaled to more VRFs without building full mesh, one-to-one connections between each pair of VRFs. VLAN subinterfaces are created on VDOM links to connect each VRF to the central VRF, allowing routes to be leaked from a VRF to the central VRF, and then to the other VRFs. Static routes are used for route leaking in this example.
For instructions on creating route leaking between two VRFs, see Route leaking between VRFs with BGP.
Physical topology:
Logical topology:
In this example, a specific route is leaked from each of the VRFs to each of the other VRFs. VLAN subinterfaces are created based on VDOM links to connect each VRF to the core VRF router.
Multi-VDOM mode is enabled so that NP VDOM links can be used. The setup could be configured without enabling multi-VDOM mode by manually creating non‑NP VDOM links, but this is not recommended as the links are not offloaded to the NPU.
After VDOMs are enabled, all of the configuration is done in the root VDOM.
To configure the FortiGate:
-
Enable multi-VDOM mode:
config system global set vdom-mode multi-vdom end
If the FortiGate has an NP, the VDOM links will be created:
# show system interface config system interface ... edit "npu0_vlink0" set vdom "root" set type physical next edit "npu0_vlink1" set vdom "root" set type physical next ... end
If multi-VDOM mode is not used, the VDOM links can be manually created:
config system vdom-link edit <name of vdlink> next end
-
Allow interface subnets to use overlapping IP addresses:
config vdom edit root config system settings set allow-subnet-overlap enable end
-
Configure the inter-connecting VLAN subinterfaces between VRF based on VDOM-LINK:
config system interface edit "vlink0_Vlan_10" set vdom "root" set vrf 10 set ip 10.1.1.1 255.255.255.252 set allowaccess ping https ssh http set alias "vlink0_Vlan_10" set role lan set interface "npu0_vlink0" set vlanid 10 next edit "vlink1_Vlan_10" set vdom "root" set vrf 31 set ip 10.1.1.2 255.255.255.252 set allowaccess ping https ssh http set alias "vlink1_Vlan_10" set role lan set interface "npu0_vlink1" set vlanid 10 next edit "vlink0_Vlan_11" set vdom "root" set vrf 11 set ip 11.1.1.1 255.255.255.252 set allowaccess ping https ssh http set alias "vlink0_Vlan_11" set role lan set interface "npu0_vlink0" set vlanid 11 next edit "vlink1_Vlan_11" set vdom "root" set vrf 31 set ip 11.1.1.2 255.255.255.252 set allowaccess ping https ssh http set alias "vlink1_Vlan_11" set role lan set interface "npu0_vlink1" set vlanid 11 next edit "vlink0_Vlan_12" set vdom "root" set vrf 12 set ip 12.1.1.1 255.255.255.252 set allowaccess ping https ssh http set alias "vlink0_Vlan_12" set role lan set interface "npu0_vlink0" set vlanid 12 next edit "vlink1_Vlan_12" set vdom "root" set vrf 31 set ip 12.1.1.2 255.255.255.252 set allowaccess ping https ssh http set alias "vlink1_Vlan_12" set role lan set interface "npu0_vlink1" set vlanid 12 next end
-
Configure a zone to allow intrazone traffic between VLANs in the central VRF:
config system zone edit "Core-VRF-Router" set intrazone allow set interface "vlink1_Vlan_10" "vlink1_Vlan_11" "vlink1_Vlan_12" next end
-
Add allow policies for the VRF31 core router:
config firewall policy edit 0 set name "any_to_core_vrf31" set srcintf "any" set dstintf "Core-VRF-Router" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all next edit 0 set name "core_vrf31_to_any" set srcintf "Core-VRF-Router" set dstintf "any" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all next end
-
Configure VRF10, VRF11, and VRF12 on the Internal and WAN VLAN sub-interfaces:
config system interface edit "Internal_VRF10" set vdom "root" set vrf 10 set ip 172.16.10.1 255.255.255.0 set allowaccess ping https ssh http set alias "Internal_VRF10" set role lan set interface "internal" set vlanid 10 next edit "Internal_VRF11" set vdom "root" set vrf 11 set ip 172.16.11.1 255.255.255.0 set allowaccess ping https ssh http set alias "Internal_VRF11" set role lan set interface "internal" set vlanid 11 next edit "Internal_VRF12" set vdom "root" set vrf 12 set ip 172.16.12.1 255.255.255.0 set allowaccess ping https ssh http set alias "Internal_VRF12" set role lan set interface "internal" set vlanid 12 next edit "wan1_VRF10" set vdom "root" set vrf 10 set ip 202.100.10.1 255.255.255.0 set allowaccess ping set alias "wan1_VRF10" set role wan set interface "wan1" set vlanid 10 next edit "wan1_VRF11" set vdom "root" set vrf 11 set ip 202.100.11.1 255.255.255.0 set allowaccess ping set alias "wan1_VRF11" set role wan set interface "wan1" set vlanid 11 next edit "wan1_VRF12" set vdom "root" set vrf 12 set ip 202.100.12.1 255.255.255.0 set allowaccess ping set alias "wan1_VRF12" set role wan set interface "wan1" set vlanid 12 next end
-
Configure static routing and route leaking between each VRF and Core-VRF-Router:
config router static edit 1 set dst 172.16.10.0 255.255.255.0 set gateway 10.1.1.1 set device "vlink1_Vlan_10" set comment "VRF31_Core_Router" next edit 2 set dst 172.16.11.0 255.255.255.0 set gateway 11.1.1.1 set device "vlink1_Vlan_11" set comment "VRF31_Core_Router" next edit 3 set dst 172.16.12.0 255.255.255.0 set gateway 12.1.1.1 set device "vlink1_Vlan_12" set comment "VRF31_Core_Router" next edit 4 set dst 172.16.11.0 255.255.255.0 set gateway 10.1.1.2 set device "vlink0_Vlan_10" set comment "VRF10_Route_Leaking" next edit 5 set dst 172.16.12.0 255.255.255.0 set gateway 10.1.1.2 set device "vlink0_Vlan_10" set comment "VRF10_Route_Leaking" next edit 6 set dst 172.16.10.0 255.255.255.0 set gateway 11.1.1.2 set device "vlink0_Vlan_11" set comment "VRF11_Route_Leaking" next edit 7 set dst 172.16.12.0 255.255.255.0 set gateway 11.1.1.2 set device "vlink0_Vlan_11" set comment "VRF11_Route_Leaking" next edit 8 set dst 172.16.10.0 255.255.255.0 set gateway 12.1.1.2 set device "vlink0_Vlan_12" set comment "VRF12_Route_Leaking" next edit 9 set dst 172.16.11.0 255.255.255.0 set gateway 12.1.1.2 set device "vlink0_Vlan_12" set comment "VRF12_Route_Leaking" next edit 10 set gateway 202.100.10.254 set device "wan1_VRF10" set comment "VRF10_Default_Route" next edit 11 set gateway 202.100.11.254 set device "wan1_VRF11" set comment "VRF11_Default_Route" next edit 12 set gateway 202.100.12.254 set device "wan1_VRF12" set comment "VRF12_Default_Route" next end
In the GUI, go to Network > Static Routes to view the static routes:
-
Configure firewall policies for VRF10, VRF11, and VRF12
config firewall policy edit 6 set name "VRF10_to_Internet_Policy" set srcintf "Internal_VRF10" set dstintf "wan1_VRF10" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all set nat enable next edit 7 set name "VRF10_to_VRF_Leaking_Route" set srcintf "Internal_VRF10" set dstintf "vlink0_Vlan_10" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all next edit 8 set name "VRF_Leaking_Route_to_VRF10" set srcintf "vlink0_Vlan_10" set dstintf "Internal_VRF10" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all next edit 9 set name "VRF11_to_Internet_Policy" set srcintf "Internal_VRF11" set dstintf "wan1_VRF11" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all set nat enable next edit 10 set name "VRF11_to_VRF_Leaking_Route" set srcintf "Internal_VRF11" set dstintf "vlink0_Vlan_11" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all next edit 11 set name "VRF_Leaking_Route_to_VRF11" set srcintf "vlink0_Vlan_11" set dstintf "Internal_VRF11" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all next edit 12 set name "VRF12_to_Internet_Policy" set srcintf "Internal_VRF12" set dstintf "wan1_VRF12" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all set nat enable next edit 13 set name "VRF12_to_VRF_Leaking_Route" set uuid 92bccf8e-b27b-51eb-3c56-6d5259af6299 set srcintf "Internal_VRF12" set dstintf "vlink0_Vlan_12" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all next edit 14 set name "VRF_Leaking_Route_to_VRF12" set srcintf "vlink0_Vlan_12" set dstintf "Internal_VRF12" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set logtraffic all next end
In the GUI, go to Policy & Objects > Firewall Policy to view the policies.
To check the results:
-
On the FortiGate, check the routing table to see each VRF:
# get router info routing-table all Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP 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, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area * - candidate default Routing table for VRF=0 C 10.6.30.0/24 is directly connected, mgmt Routing table for VRF=10 S* 0.0.0.0/0 [10/0] via 202.100.10.254, wan1_VRF10 C 10.1.1.0/30 is directly connected, vlink0_Vlan_10 C 172.16.10.0/24 is directly connected, Internal_VRF10 S 172.16.11.0/24 [10/0] via 10.1.1.2, vlink0_Vlan_10 S 172.16.12.0/24 [10/0] via 10.1.1.2, vlink0_Vlan_10 C 202.100.10.0/24 is directly connected, wan1_VRF10 Routing table for VRF=11 S* 0.0.0.0/0 [10/0] via 202.100.11.254, wan1_VRF11 C 11.1.1.0/30 is directly connected, vlink0_Vlan_11 S 172.16.10.0/24 [10/0] via 11.1.1.2, vlink0_Vlan_11 C 172.16.11.0/24 is directly connected, Internal_VRF11 S 172.16.12.0/24 [10/0] via 11.1.1.2, vlink0_Vlan_11 C 202.100.11.0/24 is directly connected, wan1_VRF11 Routing table for VRF=12 S* 0.0.0.0/0 [10/0] via 202.100.12.254, wan1_VRF12 C 12.1.1.0/30 is directly connected, vlink0_Vlan_12 S 172.16.10.0/24 [10/0] via 12.1.1.2, vlink0_Vlan_12 S 172.16.11.0/24 [10/0] via 12.1.1.2, vlink0_Vlan_12 C 172.16.12.0/24 is directly connected, Internal_VRF12 C 202.100.12.0/24 is directly connected, wan1_VRF12 Routing table for VRF=31 C 10.1.1.0/30 is directly connected, vlink1_Vlan_10 C 11.1.1.0/30 is directly connected, vlink1_Vlan_11 C 12.1.1.0/30 is directly connected, vlink1_Vlan_12 S 172.16.10.0/24 [10/0] via 10.1.1.1, vlink1_Vlan_10 S 172.16.11.0/24 [10/0] via 11.1.1.1, vlink1_Vlan_11 S 172.16.12.0/24 [10/0] via 12.1.1.1, vlink1_Vlan_12
-
From the FW10-PC:
# ifconfig ens32 ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.16.10.100 netmask 255.255.255.0 broadcast 172.16.10.255 inet6 fe80::dbed:c7fe:170e:e61c prefixlen 64 scopeid 0x20<link> ether 00:0c:29:2a:3a:17 txqueuelen 1000 (Ethernet) RX packets 1632 bytes 160001 (156.2 KiB) RX errors 0 dropped 52 overruns 0 frame 0 TX packets 2141 bytes 208103 (203.2 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.16.10.1 0.0.0.0 UG 100 0 0 ens32 172.16.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32 192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
-
Ping a public IP address through VRF10:
# ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=113 time=4.33 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=113 time=4.17 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=113 time=4.04 ms ^C --- 8.8.8.8 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 4.049/4.188/4.336/0.117 ms
-
Ping the internet gateway through VRF10:
# ping 202.100.10.254 PING 202.100.10.254 (202.100.10.254) 56(84) bytes of data. 64 bytes from 202.100.10.254: icmp_seq=1 ttl=254 time=0.294 ms 64 bytes from 202.100.10.254: icmp_seq=2 ttl=254 time=0.225 ms 64 bytes from 202.100.10.254: icmp_seq=3 ttl=254 time=0.197 ms ^C --- 202.100.10.254 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.197/0.238/0.294/0.044 ms
-
Ping the FW11-PC on VRF11 from VRF10:
# ping 172.16.11.100 PING 172.16.11.100 (172.16.11.100) 56(84) bytes of data. 64 bytes from 172.16.11.100: icmp_seq=1 ttl=61 time=0.401 ms 64 bytes from 172.16.11.100: icmp_seq=2 ttl=61 time=0.307 ms 64 bytes from 172.16.11.100: icmp_seq=3 ttl=61 time=0.254 ms 64 bytes from 172.16.11.100: icmp_seq=4 ttl=61 time=0.277 ms 64 bytes from 172.16.11.100: icmp_seq=5 ttl=61 time=0.262 ms ^C --- 172.16.11.100 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 3999ms rtt min/avg/max/mdev = 0.254/0.300/0.401/0.054 ms
-
-
On the FortiGate, sniff traffic between VRF10 and VRF11:
# diagnose sniffer packet any "icmp and host 172.16.11.100" 4 l 0 interfaces=[any] filters=[icmp and host 172.16.11.100] 10.086656 Internal_VRF10 in 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.086705 vlink0_Vlan_10 out 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.086706 npu0_vlink0 out 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.086711 vlink1_Vlan_10 in 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.086739 vlink1_Vlan_11 out 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.086740 npu0_vlink1 out 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.086744 vlink0_Vlan_11 in 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.086929 Internal_VRF11 out 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.086930 internal out 172.16.10.100 -> 172.16.11.100: icmp: echo request 10.087053 Internal_VRF11 in 172.16.11.100 -> 172.16.10.100: icmp: echo reply 10.087061 vlink0_Vlan_11 out 172.16.11.100 -> 172.16.10.100: icmp: echo reply 10.087062 npu0_vlink0 out 172.16.11.100 -> 172.16.10.100: icmp: echo reply 10.087066 vlink1_Vlan_11 in 172.16.11.100 -> 172.16.10.100: icmp: echo reply 10.087071 vlink1_Vlan_10 out 172.16.11.100 -> 172.16.10.100: icmp: echo reply 10.087072 npu0_vlink1 out 172.16.11.100 -> 172.16.10.100: icmp: echo reply 10.087076 vlink0_Vlan_10 in 172.16.11.100 -> 172.16.10.100: icmp: echo reply 10.087176 Internal_VRF10 out 172.16.11.100 -> 172.16.10.100: icmp: echo reply 10.087177 internal out 172.16.11.100 -> 172.16.10.100: icmp: echo reply ^C 20 packets received by filter 0 packets dropped by kernel