...
Feature | Support | Comment |
---|
BGP | + |
Code Block |
---|
| /routing bgp template
add name=bgp-template1 vrf=vrf1
/routing bgp vpls
add name=bgp-vpls1 site-id=10 vrf=vrf1
/routing bgp vpn
add label-allocation-policy=per-vrf vrf=vrf1 |
|
E-mail | + |
Code Block |
---|
| /tool e-mail
set address=192.168.88.1 vrf=vrf1 |
|
IP Services | + | VRF is supported for telnet , www , ssh , www-ssl , api , winbox , api-ssl services. The ftp service does not support changing the VRF. Code Block |
---|
| /ip service
set telnet vrf=vrf1 |
|
L2TP Client | + |
Code Block |
---|
| /interface l2tp-client
add connect-to=192.168.88.1@vrf1 name=l2tp-out1 user=l2tp-client |
|
MPLS | + |
Code Block |
---|
| /mpls ldp
add vrf=vrf1 |
|
Netwatch | + |
Code Block |
---|
| /tool netwatch
add host=192.168.88.1@vrf1 |
|
NTP | + |
Code Block |
---|
| /system ntp client
set vrf=vrf1
/system ntp server
set vrf=vrf1 |
|
OSPF | + |
Code Block |
---|
| /routing ospf instance
add disabled=no name=ospf-instance-1 vrf=vrf1 |
|
ping | + |
Code Block |
---|
| /ping 192.168.88.1 vrf=vrf1 |
|
RADIUS | + |
Code Block |
---|
| /radius add address=192.168.88.1@vrf1
/radius incoming set vrf=vrf1 |
|
RIP | + |
Code Block |
---|
| /routing rip instance
add name=rip-instance-1 vrf=vrf1 |
|
RPKI | + |
Code Block |
---|
| /routing rpki
add vrf=vrf1 |
|
SNMP | + |
Code Block |
---|
| /snmp
set vrf=vrf1 |
|
EoIP | + |
Code Block |
---|
| /interface eoip
add remote-address=192.168.1.1@vrf1 |
|
IPIP | + |
Code Block |
---|
| /interface ipip
add remote-address=192.168.1.1@vrf1 |
|
GRE | + |
Code Block |
---|
| /interface gre
add remote-address=192.168.1.1@vrf1 |
|
SSTP-client | + |
Code Block |
---|
| /interface sstp-client
add connect-to=192.168.1.1@vrf1 |
|
OVPN-client | + |
Code Block |
---|
| /interface ovpn-client
add connect-to=192.168.1.1@vrf1 |
|
L2TP-ether | + |
Code Block |
---|
| /interface l2tp-ether
add connect-to=192.168.2.2@vrf |
|
VXLAN | + |
Code Block |
---|
| /interface vxlan
add vni=10 vrf=vrf1 |
fetch |
Fetch | + | Code Block |
---|
| /tool/fetch
address=10.155.28.236@vrf1 mode=ftp src-path=my_file.pcap user=admin password="" |
|
Examples
Simple VRF-Lite setup
...
DNS | + Starting from RouterOS v7.15 | |
...
...
|
DHCP-Relay | + Starting from RouterOS v7.15 | Code Block |
---|
| /ip dhcp-relay set dhcp-server-vrf=vrf1 | If dhcp-client is in vrf - special parameter in "ip dhcp-relay" configuration is not needed |
VRF interfaces in firewall
Warning |
---|
Before RouterOS version 7.14, firewall filter rules with the property in/out-interface would apply to interfaces within a VRF instance. Starting from RouterOS version 7.14, these rules no longer target individual interfaces within a VRF, but rather the VRF interface as a whole. |
Started from version 7.14 when interfaces are added in VRF - virtual VRF interface is created automatically. If it is needed to match traffic which belongs to VRF interface, VRF virtual interface should be used in firewall filters, for example:
Code Block |
---|
|
/ip vrf add interfaces=ether5 name=vrf5
/ip firewall filter add chain=input in-interface=vrf5 action=accept |
If there are several interfaces in one VRF but it is needed to match only one of these interfaces - marks should be used. For example:
Code Block |
---|
|
/ip vrf add interface=ether15,ether16 vrf=vrf1516
/ip firewall mangle
add action=mark-connection chain=prerouting connection-state=new in-interface=ether15 new-connection-mark=input_allow passthrough=yes
/ip firewall filter
add action=accept chain=input connection-mark=input_allow |
Examples
Simple VRF-Lite setup
Let's consider a setup where we need two customer VRFs that require access to the internet:
Code Block |
---|
|
/ip address
add address=172.16.1.2/24 interface=public
add address=192.168.1.1/24 interface=ether1
add address=192.168.2.1/24 interface=ether2
/ip route
add gateway=172.16.1.1
# add VRF configuration
/ip vrf
add name=cust_a interface=ether1 place-before 0
add name=cust_b interface=ether2 place-before 0
# add vrf routes
/ip route
add gateway=172.16.1.1@main routing-table=cust_a
add gateway=172.16.1.1@main routing-table=cust_b
# masquerade local source
/ip firewall nat add chain=srcnat out-interface=public action=masquerade |
It might be necessary to ensure that packets coming in the "public" interface can actually reach the correct VRF.
This can be solved by marking new connections originated by the VRF customers and steering the traffic by routing marks of incoming packets on the "public" interface.
Code Block |
---|
|
# mark new customer connections
/ip firewall mangle
add action=mark-connection chain=prerouting connection-state=new new-connection-mark=\
cust_a_conn src-address=192.168.1.0/24 passthrough=no
add action=mark-connection chain=prerouting connection-state=new new-connection-mark=\
cust_b_conn src-address=192.168.2.0/24 passthrough=no
# mark routing
/ip firewall mangle
add action=mark-routing chain=prerouting connection-mark=cust_a_conn \
in-interface=public new-routing-mark=cust_a
add action=mark-routing chain=prerouting connection-mark=cust_b_conn \
in-interface=public new-routing-mark=cust_b |
Static inter-VRF routes
In general, it is recommended that all routes between VRF should be exchanged using BGP local import and export functionality. If that is not enough, static routes can be used to achieve this so-called route leaking.
There are two ways to install a route that has a gateway in a different routing table than the route itself.
The first way is to explicitly specify the routing table in the gateway field when adding a route. This is only possible when leaking a route and gateway from the "main" routing table to a different routing table (VRF). Example:
Code Block |
---|
|
# add route to 5.5.5.0/24 in 'vrf1' routing table with gateway in the main routing table
add dst-address=5.5.5.0/24 gateway=10.3.0.1@main routing-table=vrf1 |
The second way is to explicitly specify the interface in the gateway field. The interface specified can belong to a VRF instance. Example:
Code Block |
---|
|
# add route to 5.5.5.0/24 in the main routing table with gateway at 'ether2' VRF interface
add dst-address=5.5.5.0/24 gateway=10.3.0.1%ether2 routing-table=main
# add route to 5.5.5.0/24 in the main routing table with 'ptp-link-1' VRF interface as gateway
add dst-address=5.5.5.0/24 gateway=ptp-link-1 routing-table=main |
As can be observed, there are two variations possible - to specify gateway as ip_address%interface or to simply specify an interface. The first should be used for broadcast interfaces in most cases. The second should be used for point-to-point interfaces, and also for broadcast interfaces, if the route is a connected route in some VRF. For example, if you have an address 1.2.3.4/24
on interface ether2 that is put in a VRF, there will be a connected route to 1.2.3.0/24
in that VRF's routing table. It is acceptable to add a static route 1.2.3.0/24
in a different routing table with an interface-only gateway, even though ether2 is a broadcast interface:
Code Block |
---|
|
add dst-address=1.2.3.0/24 gateway=ether2 routing-table=main
|
Static VRF-Lite Connected route leaking
Sometimes it is necessary to access directly connected resources from another vrf. In our example setup we have two connected networks each in its own VRF. And we want to allow client1 to be able to access client2.
Code Block |
---|
|
+-----------------+
|+-vrf1-+ +-vrf2-+|
client1(*.2)-------||ip *.1| |ip *.1||-------client2(*.2)
(10.11.0.0/24) |+------+ +------+| (10.12.0.0/24)
+-----------------+ |
Code Block |
---|
|
/ip address
add address=10.11.0.1/24 interface=sfp-sfpplus1
add address=10.12.0.1/24 interface=sfp-sfpplus2
# add VRF configuration
/ip vrf
add name=vrfTest1 interface=sfp-sfpplus1 place-before 0
add name=vrfTest2 interface=sfp-sfpplus2 place-before 0
|
We can say that connected network is reachable on specific vrf by setting gateway "interface@vrf"
Code Block |
---|
|
# add vrf routes
/ip route
add dst-address=10.11.0.0/24 gateway="sfp-sfpplus1@vrfTest1" routing-table=vrfTest2
add dst-address=10.12.0.0/24 gateway="sfp-sfpplus2@vrfTest2" routing-table=vrfTest1
|
Verify routes and reachability:
Code Block |
---|
|
[admin@CCR2004_2XS] /ip/route> print detail
Flags: D - dynamic; X - disabled, I - inactive, A - active;
c - connect, s - static, r - rip, b - bgp, o - ospf, i - is-is, d - dhcp, v - vpn, m - modem, y - bgp-mpls-vpn; H - hw-offloaded; + - ecmp
DAc dst-address=111.11.0.0/24 routing-table=vrfTest1 gateway=sfp-sfpplus1@vrfTest1 immediate-gw=sfp-sfpplus1 distance=0 scope=10 suppress-hw-offload=no
local-address=111.11.0.1%sfp-sfpplus1@vrfTest1
1 As dst-address=111.12.0.0/24 routing-table=vrfTest1 pref-src="" gateway=vrfTest2 immediate-gw=vrfTest2 distance=1 scope=30 target-scope=10
suppress-hw-offload=no
2 As dst-address=111.11.0.0/24 routing-table=vrfTest2 pref-src="" gateway=vrfTest1 immediate-gw=vrfTest1 distance=1 scope=30 target-scope=10
suppress-hw-offload=no
DAc dst-address=111.12.0.0/24 routing-table=vrfTest2 gateway=sfp-sfpplus2@vrfTest2 immediate-gw=sfp-sfpplus2 distance=0 scope=10 suppress-hw-offload=no
local-address=111.12.0.1%sfp-sfpplus2@vrfTest2
|
Code Block |
---|
|
[admin@cl2] > /ping 111.11.0.2 src-address=111.12.0.2
SEQ HOST SIZE TTL TIME STATUS
0 111.11.0.2 |
It might be necessary to ensure that packets coming in the "public" interface can actually reach the correct VRF.
This can be solved by marking new connections originated by the VRF customers and steering the traffic by routing marks of incoming packets on the "public" interface.
Code Block |
---|
|
# mark new customer connections
/ip firewall mangle
add action=mark-connection chain=prerouting connection-state=new new-connection-mark=\
cust_a_conn src-address=192.168.1.0/24 passthrough=no
add action=mark-connection chain=prerouting connection-state=new new-connection-mark=\
cust_b_conn src-address=192.168.2.0/24 passthrough=no
# mark routing
/ip firewall mangle
add action=mark-routing chain=prerouting connection-mark=cust_a_conn \
in-interface=public new-routing-mark=cust_a
add action=mark-routing chain=prerouting connection-mark=cust_b_conn \
in-interface=public new-routing-mark=cust_b |
Static VRF-Lite Connected route leaking
Sometimes it is necessary to access directly connected resources from another vrf. In our example setup we have two connected networks each in its own VRF. And we want to allow client1 to be able to access client2.
Code Block |
---|
|
+-----------------+
56 64 67us |+-vrf1-+ +-vrf2-+|
client1(*.2)-------||ip *.1| |ip *.1||-------client2(*.2)
(101 111.11.0.0/24) |+------+ +------+| (10.12.0.0/24)
2 56 64 61us +-----------------+
sent=2 received=2 packet-loss=0% min-rtt=61us avg-rtt=64u
|
Note |
---|
Keep in mind that trying to leak overlapping networks will not work. |
But now what if we want to access routers local address located in another vrf?
Code Block |
---|
|
[admin@cl2] > /ping 111/ip address
add address=10.11.0.1/24 interface=sfp-sfpplus1
add src-address=10111.12.0.1/24 interface=sfp-sfpplus2
# add VRF configuration
/ip vrf
add name=vrfTest1 interface=sfp-sfpplus1 place-before 0
add name=vrfTest2 interface=sfp-sfpplus2 place-before 0
|
We can say that connected network is reachable on specific vrf by setting gateway "interface@vrf"
Code Block |
---|
|
# add vrf routes
/ip route
add dst-address=10.11.0.0/24 gateway="sfp-sfpplus1@vrfTest1" routing-table=vrfTest2
add dst-address=10.12.0.0/24 gateway="sfp-sfpplus2@vrfTest2" routing-table=vrfTest1
|
Verify routes and reachability:
Code Block |
---|
|
[admin@CCR2004_2XS] /ip/route> print detail
Flags: D - dynamic; X - disabled, I - inactive, A - active;
c - connect, s - static, r - rip, b - bgp, o - ospf, i - is-is, d - dhcp, v - vpn, m - modem, y - bgp-mpls-vpn; H - hw-offloaded; + - ecmp
DAc dst-address=111.11.0.0/24 routing-table=vrfTest1 gateway=sfp-sfpplus1@vrfTest1 immediate-gw=sfp-sfpplus1 distance=0 scope=10 suppress-hw-offload=no
2
SEQ HOST SIZE TTL TIME STATUS local-address=111.11.0.1%sfp-sfpplus1@vrfTest1
1 As dst-address=111.12.0.0/24 routing-table=vrfTest1 pref-src="" gateway=vrfTest2 immediate-gw=vrfTest2 distance=1 scope=30 target-scope=10
suppress-hw-offload=no
2 As 0 dst-address=111.11.0.0/24 routing-table=vrfTest2 pref-src="" gateway=vrfTest1 immediate-gw=vrfTest1 distance=1 scope=30 target-scope=10
1 suppress-hw-offload=no
DAc dst-address=111.12.0.0/24 routing-table=vrfTest2 gateway=sfp-sfpplus2@vrfTest2 immediate-gw=sfp-sfpplus2 distance=0 scope=10 suppress-hw-offload=no
local-address=111.12.0.1%sfp-sfpplus2@vrfTest2
|
Code Block |
---|
|
[admin@cl2] > /ping 111.11.0.2 src-address=111.12.0.2
timeout SEQ HOST SIZE TTL TIME STATUS
1 111.11.0.1
0 111.11.0.2 timeout 56 64 67us
1 111.11.0.2 56 64 61us
sent=2 received=20 packet-loss=0% min-rtt=61us avg-rtt=64u
|
Note |
---|
Keep in mind that trying to leak overlapping networks will not work. |
...
Approach with "interface@vrf" gateways works only when router is forwarding packets. To access local vrf addresses we need to route to the vrf interface.
Code Block |
---|
|
# add vrf routes
/ip route
add dst-address=10.11.0.0/24 gateway=vrfTest1@vrfTest1 routing-table=vrfTest2
add dst-address=10.12.0.0/24 gateway=vrfTest2@vrfTest2 routing-table=vrfTest1
|
Code Block |
---|
|
[admin@cl2] > /ping 111.11.0.1 src-address=111.12.0.2
SEQ HOST SIZE TTL TIME STATUS
0 111.11.0.1 56 64 67us
1 111.11.0.1 timeout 56 64 61us
sent=2 received=2 packet-loss=0%
1 111.11.0.1 timeout
sent=2 received=0 packet-loss=100%
|
Approach with "interface@vrf" gateways works only when router is forwarding packets. To access local vrf addresses we need to route to the vrf interface.
Code Block |
---|
|
# add vrf routes
/ip route
add dst-address=10.11.0.0/24 gateway=vrfTest1 routing-table=vrfTest2
add dst-address=10.12.0.0/24 gateway=vrfTest2 routing-table=vrfTest1
|
Dynamic Vrf-Lite route leaking
With large enough setups static route leaking is not sufficient. Let's consider we have the same setup as in static route leaking example plus ipv6 addresses, just for demonstration.
Code Block |
---|
|
/ip address
add address=10.11.0.1/24 interface=sfp-sfpplus1
add address=10.12.0.1/24 interface=sfp-sfpplus2
# add VRF configuration
/ip vrf
add name=vrfTest1 interface=sfp-sfpplus1 place-before 0
add name=vrfTest2 interface=sfp-sfpplus2 place-before 0
/ipv6 address
add address=2001:1::1 advertise=no interface=sfp-sfpplus1
add address=2001:2::1 advertise=no interface=sfp-sfpplus2
|
We can use BGP VPN to leak local routes without actually establishing BGP session.
Code Block |
---|
|
/routing bgp vpn
add export.redistribute=connected .route-targets=1:1 import.route-targets=1:2 label-allocation-policy=per-vrf name=bgp-mpls-vpn-1 \
route-distinguisher=1.2.3.4:1 vrf=vrfTest1
add export.redistribute=connected .route-targets=1:2 import.route-targets=1:1 label-allocation-policy=per-vrf name=bgp-mpls-vpn-2 \
route-distinguisher=1.2.3.4:1 vrf=vrfTest2 |
Note |
---|
Be careful with import/export route targets, if not set up properly local vrf routes from itself will be imported. |
Now we can see that connected routes between VRFs are exchanged
Code Block |
---|
|
[admin@CCR2004_2XS] > /routing route print where dst-address in 111.0.0.0/8 && afi=ip4
...
Ac afi=ip4 contribution=active dst-address=111.11.0.0/24 routing-table=vrfTest1 gateway=sfp-sfpplus1@vrfTest1 immediate-gw=sfp-sfpplus1 distance=0 scope=10
belongs-to="connected" local-address=111.11.0.1%sfp-sfpplus1@vrfTest1
debug.fwp-ptr=0x202421E0
Ay afi=ip4 contribution=best-candidate dst-address=111.12.0.0/24 routing-table=vrfTest1 label=17 gateway=vrfTest2@vrfTest2 immediate-gw=sfp-sfpplus2
distance=200 scope=40 target-scope=10 belongs-to="bgp-mpls-vpn-1-bgp-mpls-vpn-2-connected-export-import"
bgp.ext-communities=rt:1:2 .atomic-aggregate=no .origin=incomplete
debug.fwp-ptr=0x202425A0
Ay afi=ip4 contribution=best-candidate dst-address=111.11.0.0/24 routing-table=vrfTest2 label=16 gateway=vrfTest1@vrfTest1 immediate-gw=sfp-sfpplus1
distance=200 scope=40 target-scope=10 belongs-to="bgp-mpls-vpn-2-bgp-mpls-vpn-1-connected-export-import"
bgp.ext-communities=rt:1:1 .atomic-aggregate=no .origin=incomplete
debug.fwp-ptr=0x202424E0
Ac afi=ip4 contribution=active dst-address=111.12.0.0/24 routing-table=vrfTest2 gateway=sfp-sfpplus2@vrfTest2 immediate-gw=sfp-sfpplus2 distance=0 scope=10
belongs-to="connected" local-address=111.12.0.1%sfp-sfpplus2@vrfTest2
debug.fwp-ptr=0x20242240
|
And IPv6 too:
Code Block |
---|
|
[admin@CCR2004_2XS] /routing/route> print detail where dst-address in 2001::/8 && afi=ip6
...
Ac afi=ip6 contribution=active dst-address=2001:1::/64 routing-table=vrfTest1 gateway=sfp-sfpplus1@vrfTest1 immediate-gw=sfp-sfpplus1 distance=0 scope=10
belongs-to="connected" local-address=2001:1::1%sfp-sfpplus1@vrfTest1
debug.fwp-ptr=0x20242300
Ay afi=ip6 contribution=active dst-address=2001:2::/64 routing-table=vrfTest1 label=17 gateway=vrfTest2@vrfTest2 immediate-gw=sfp-sfpplus2 distance=200
scope=40 target-scope=10 belongs-to="bgp-mpls-vpn-1-bgp-mpls-vpn-2-connected-export-import"
bgp.ext-communities=rt:1:2 .atomic-aggregate=no .origin=incomplete
debug.fwp-ptr=0x202425A0
Ay afi=ip6 contribution=active dst-address=2001:1::/64 routing-table=vrfTest2 label=16 gateway=vrfTest1@vrfTest1 immediate-gw=sfp-sfpplus1 distance=200
scope=40 target-scope=10 belongs-to="bgp-mpls-vpn-2-bgp-mpls-vpn-1-connected-export-import"
bgp.ext-communities=rt:1:1 .atomic-aggregate=no .origin=incomplete
debug.fwp-ptr=0x202424E0
Ac afi=ip6 contribution=active dst-address=2001:2::/64 routing-table=vrfTest2 gateway=sfp-sfpplus2@vrfTest2 immediate-gw=sfp-sfpplus2 distance=0 scope=10
belongs-to="connected" local-address=2001:2::1%sfp-sfpplus2@vrfTest2
debug.fwp-ptr=0x20242360 |
Code Block |
---|
|
[admin@cl2] > /ping 111.11.0.1 src-address=111.12.0.2
SEQ HOST SIZE TTL TIME STATUS
0 111.11.0.1 56 64 67us
1 111.11.0.1 56 64 61us
sent=2 received=2 packet-loss=0% min-rtt=61us avg-rtt=64u
|
Dynamic Vrf-Lite route leaking (old workaround)
...